lambdacube-engine-0.2.1: Graphics/LambdaCube/Skeleton.hs
module Graphics.LambdaCube.Skeleton where
import Graphics.LambdaCube.Types
import Data.Map (Map)
import Data.Tree
import qualified Data.Vector as V
data Bone = Bone
{ bnPosition :: Vec3
, bnRotation :: U
}
deriving Show
data KeyFrame = KeyFrame
{ kfPosition :: Vec3
, kfRotation :: U
, kfTime :: FloatType
}
deriving Show
data Animation = Animation
{ anTracks :: V.Vector [KeyFrame]
, anLength :: FloatType
, anName :: String
}
deriving Show
data Skeleton = Skeleton
{ skBones :: V.Vector Bone
, skBoneTree :: Tree Int
, skAnimations :: Map String Animation
}
deriving Show
data PoseData = PoseData
{ pdJointMatrix :: Proj4
, pdInverseBindMatrix :: Proj4
, pdWorldMatrix :: Proj4
, pdSkinningMatrix :: Proj4
}
-- FIXME: remove Data.Vec.LinAlg.Transform3D dependency
{-
mat33ToMat44 (a:.b:.c:.()) = (h a):.(h b):.(h c):.(0:.0:.0:.1:.()):.()
where
h x = Vec.snoc 0 x
poseData :: Skeleton -> Animation -> FloatType -> Vector PoseData
poseData s a t = visit Nothing idPD $ skBoneTree s
where
bones = skBones s
idPD = V.replicate (V.length $ skBones s) $ PoseData idMat idMat idMat idMat
idMat = Vec.identity
visit p v (Node i []) = f p i v
visit p v (Node i l) = foldl' (visit $ Just i) (f p i v) l
f p i v = v // [(i,PoseData jm ibm wm sm)]
where
b = bones V.! i
rot = mat33ToMat44 $ quatToMat $ bnRotation b
trans = translation $ bnPosition b
jm = rot `multmm` trans
ibm = invertMat44 jm
wm = pwm `multmm` jm
sm = idMat
pwm = maybe idMat (\n -> pdWorldMatrix $ v V.! n) p
-}