module Codec.GlTF.Animation ( AnimationIx(..) , Animation(..) , AnimationSamplerIx(..) , AnimationSampler(..) , AnimationSamplerInterpolation(..) , pattern LINEAR , pattern STEP , pattern CUBICSPLINE , AnimationChannel(..) , AnimationChannelTarget(..) , AnimationChannelTargetPath(..) , pattern TRANSLATION , pattern ROTATION , pattern SCALE , pattern WEIGHTS ) where import Codec.GlTF.Prelude import Codec.GlTF.Accessor (AccessorIx) import Codec.GlTF.Node (NodeIx) newtype AnimationIx = AnimationIx { unAnimationIx :: Int } deriving (Eq, Ord, Show, FromJSON, ToJSON, Generic) -- | A keyframe animation. data Animation = Animation { channels :: Vector AnimationChannel , samplers :: Vector AnimationSampler , name :: Maybe Text , extensions :: Maybe Object , extras :: Maybe Value } deriving (Eq, Show, Generic) instance FromJSON Animation instance ToJSON Animation newtype AnimationSamplerIx = AnimationSamplerIx { unAnimationSamplerIx :: Int } deriving (Eq, Ord, Show, FromJSON, ToJSON, Generic) -- | Combines input and output accessors with an interpolation algorithm -- to define a keyframe graph (but not its target). data AnimationSampler = AnimationSampler { input :: AccessorIx -- ^ The values represent time in seconds with @time[0] >= 0.0@, -- and strictly increasing values. , interpolation :: AnimationSamplerInterpolation , output :: AccessorIx -- ^ The index of an accessor containing keyframe output values. , extensions :: Maybe Object , extras :: Maybe Value } deriving (Eq, Show, Generic) instance FromJSON AnimationSampler where parseJSON = withObject "AnimationSampler" \o -> do input <- o .: "input" interpolation <- o .:? "interpolation" .!= LINEAR output <- o .: "output" extensions <- o .:? "extensions" extras <- o .:? "extras" pure AnimationSampler{..} instance ToJSON AnimationSampler newtype AnimationSamplerInterpolation = AnimationSamplerInterpolation { unAnimationSamplerInterpolation :: Text } deriving (Eq, Ord, Show, FromJSON, ToJSON, Generic) pattern LINEAR :: AnimationSamplerInterpolation pattern LINEAR = AnimationSamplerInterpolation "LINEAR" pattern STEP :: AnimationSamplerInterpolation pattern STEP = AnimationSamplerInterpolation "STEP" pattern CUBICSPLINE :: AnimationSamplerInterpolation pattern CUBICSPLINE = AnimationSamplerInterpolation "CUBICSPLINE" -- | Targets an animation's sampler at a node's property. data AnimationChannel = AnimationChannel { sampler :: AnimationSamplerIx , target :: AnimationChannelTarget , extensions :: Maybe Object , extras :: Maybe Value } deriving (Eq, Show, Generic) instance FromJSON AnimationChannel instance ToJSON AnimationChannel -- | The index of the node and TRS property that an animation channel targets. data AnimationChannelTarget = AnimationChannelTarget { node :: Maybe NodeIx , path :: AnimationChannelTargetPath , extensions :: Maybe Object , extras :: Maybe Value } deriving (Eq, Show, Generic) instance FromJSON AnimationChannelTarget instance ToJSON AnimationChannelTarget -- | The name of the node's TRS property to modify, or the @weights@ of -- the Morph Targets it instantiates. -- For the @translation@ property, the values that are provided by -- the sampler are the translation along the x, y, and z axes. -- For the @rotation@ property, the values are a quaternion in -- the order (x, y, z, w), where w is the scalar. -- For the @scale@ property, the values are the scaling factors -- along the x, y, and z axes.", newtype AnimationChannelTargetPath = AnimationChannelTargetPath { unAnimationChannelTargetPath :: Text } -- XXX: T/R/S/weights/any deriving (Eq, Ord, Show, FromJSON, ToJSON, Generic) pattern TRANSLATION :: AnimationChannelTargetPath pattern TRANSLATION = AnimationChannelTargetPath "translation" pattern ROTATION :: AnimationChannelTargetPath pattern ROTATION = AnimationChannelTargetPath "rotation" pattern SCALE :: AnimationChannelTargetPath pattern SCALE = AnimationChannelTargetPath "scale" pattern WEIGHTS :: AnimationChannelTargetPath pattern WEIGHTS = AnimationChannelTargetPath "weights"