public AnimMeshPose(AnimMeshPose copyFrom) { Position = copyFrom.Position; Rotation = copyFrom.Rotation; AngularVelocity = copyFrom.AngularVelocity; Velocity = copyFrom.Velocity; BoneNum = copyFrom.BoneNum; FrameNum = copyFrom.FrameNum; }
public void BuildPerFrameFKPoses() { perFrameFKPoses = new AnimMeshPose[NumFrames, NumBones]; var parentPoints = new Point3D[64]; var parentRotations = new Quaternion[64]; parentPoints[0] = new Point3D(0, 0, 0); parentRotations[0] = new Quaternion(0, 0, 0, 1); for (var frame = 0; frame < NumFrames; ++frame) { for (var jointNum = 0; jointNum < skeletonDef.GetLength(0); ++jointNum) { var parentIndex = skeletonDef[jointNum]; var parentPos = parentPoints[parentIndex]; var parentRot = parentRotations[parentIndex]; // The world position of the child joint is the local position of the child joint rotated by the // world rotation of the parent and then offset by the world position of the parent. var pose = perFramePoses[frame, jointNum]; var m = Matrix3D.Identity; m.Rotate(parentRot); var thisPos = m.Transform(pose.Position); thisPos.Offset(parentPos.X, parentPos.Y, parentPos.Z); // The world rotation of the child joint is the world rotation of the parent rotated by the local rotation of the child. var poseRot = pose.Rotation; poseRot.Normalize(); var thisRot = Quaternion.Multiply(parentRot, poseRot); thisRot.Normalize(); var fkPose = new AnimMeshPose { Position = thisPos, Rotation = thisRot }; perFrameFKPoses[frame, jointNum] = fkPose; parentPoints[parentIndex + 1] = fkPose.Position; parentRotations[parentIndex + 1] = fkPose.Rotation; } } }
public void BuildPerFramePoses() { perFramePoses = new AnimMeshPose[NumFrames, NumBones]; foreach (var pose in MeshPoses) { if (pose != null && pose.FrameNum <= NumFrames) { perFramePoses[pose.FrameNum, pose.BoneNum] = pose; } } for (var bone = 0; bone < NumBones; ++bone) { AnimMeshPose prevPose = null; for (var frame = 0; frame < NumFrames; ++frame) { if (perFramePoses[frame, bone] == null) { var frameDiff = frame - prevPose.FrameNum; var avCoeff = frameDiff / 131072.0; var rotDelta = new Quaternion(prevPose.AngularVelocity.X * avCoeff, prevPose.AngularVelocity.Y * avCoeff, prevPose.AngularVelocity.Z * avCoeff, prevPose.AngularVelocity.W * avCoeff); var velCoeff = frameDiff / 512.0; var posDelta = new Point3D(prevPose.Velocity.X * velCoeff, prevPose.Velocity.Y * velCoeff, prevPose.Velocity.Z * velCoeff); var pose = new AnimMeshPose { BoneNum = bone, FrameNum = frame, Position = new Point3D(prevPose.Position.X + posDelta.X, prevPose.Position.Y + posDelta.Y, prevPose.Position.Z + posDelta.Z), Rotation = new Quaternion(prevPose.Rotation.X + rotDelta.X, prevPose.Rotation.Y + rotDelta.Y, prevPose.Rotation.Z + rotDelta.Z, prevPose.Rotation.W + rotDelta.W), AngularVelocity = prevPose.AngularVelocity, Velocity = prevPose.Velocity }; perFramePoses[frame, bone] = pose; } prevPose = perFramePoses[frame, bone]; } } }