/// <summary> /// Build a Node hierachy into the scene property 'mainScene' from a Hand object /// </summary> /// <param name="hand"></param> private void CreateNodeHierarchy(Hand hand, Scene handScene) { Node rootNode = handScene.RootNode = new Node(); Node handNode = new Node(); handNode.Name = GetNodeHandName(hand.Id.ToString()); rootNode.Children.Add(handNode); NodeAnimationChannel bonetest = new NodeAnimationChannel(); bonetest.NodeName = GetNodeHandName(hand.Id.ToString()); handScene.Animations[0].NodeAnimationChannels.Add(bonetest); foreach (Finger finger in hand.Fingers) { Node fingerNode = handNode; foreach (Leap.Bone.BoneType boneType in (Leap.Bone.BoneType[])Enum.GetValues(typeof(Leap.Bone.BoneType))) { string fingerType = finger.Type.ToString(); //Add a node hierarchy fingerNode = AddChildBone(fingerType, boneType.ToString(), hand, fingerNode); //Fill the NodeAnimChannel NodeAnimationChannel bone = new NodeAnimationChannel(); bone.NodeName = GetNodeBoneName(fingerType, boneType.ToString(), hand); handScene.Animations[0].NodeAnimationChannels.Add(bone); } } }
public static Animation CopyAnimationInto(Animation animSource, Animation animTarget) { foreach (NodeAnimationChannel animChan in animSource.NodeAnimationChannels) { NodeAnimationChannel copyChannel = new NodeAnimationChannel(); copyChannel.NodeName = animChan.NodeName; copyChannel.PostState = animChan.PostState; copyChannel.PreState = animChan.PreState; //copyChannel.ScalingKeys = animChan.ScalingKeys.Add(animChan.) animChan.ScalingKeys.ForEach((item) => { copyChannel.ScalingKeys.Add(new VectorKey(item.Time, item.Value)); }); animChan.RotationKeys.ForEach((item) => { copyChannel.RotationKeys.Add(new QuaternionKey(item.Time, item.Value)); }); animChan.PositionKeys.ForEach((item) => { copyChannel.PositionKeys.Add(new VectorKey(item.Time, item.Value)); }); animTarget.NodeAnimationChannels.Add(copyChannel); } return animTarget; }
/// <summary> /// Creates an Assimp.NodeAnimationChannel from the given NodeAnimationChannel list and Assimp.Node.<br /> /// Adds the Assimp.NodeAnimationChannel to the given Assimp.Animation /// </summary> /// <param name="node"></param> /// <param name="channel"></param> private static void CreateNodeAnimationChannels(Assimp.Animation animation, List<NodeAnimationChannel> sourceNodeAnimationChannels, Node node) { NodeAnimationChannel nodeAnimationChannel = new NodeAnimationChannel(); nodeAnimationChannel = sourceNodeAnimationChannels[animation.NodeAnimationChannelCount]; nodeAnimationChannel.NodeName = node.Name; animation.NodeAnimationChannels.Add(nodeAnimationChannel); for (int i = 0; i < node.ChildCount; i++) CreateNodeAnimationChannels(animation, sourceNodeAnimationChannels, node.Children[i]); }
/// <summary> /// Build a Node hierachy into the scene property 'mainScene' from a Hand object /// </summary> /// <param name="hand"></param> private void CreateNodeHierarchy(Hand hand) { Node root = this.mainScene.RootNode; Node handNode = new Node(); handNode.Name = GetNodeName(hand.Id.ToString()); root.Children.Add(handNode); foreach (Finger finger in hand.Fingers) { Node fingerNode = new Node(); foreach (Bone.BoneType boneType in (Bone.BoneType[])Enum.GetValues(typeof(Bone.BoneType))) { //Add a node hierarchy fingerNode = AddChildBone(boneType.ToString(), fingerNode); //Fill the NodeAnimChannel NodeAnimationChannel bone = new NodeAnimationChannel(); bone.NodeName = GetNodeName(boneType.ToString()); anim.NodeAnimationChannels.Add(bone); } } }
/// <summary> /// Constructs a new Animation. /// </summary> /// <param name="animation">Unmanaged AiAnimation.</param> internal Animation(AiAnimation animation) { _name = animation.Name.GetString(); _duration = animation.Duration; _ticksPerSecond = animation.TicksPerSecond; //Load node animations if(animation.NumChannels > 0 && animation.Channels != IntPtr.Zero) { AiNodeAnim[] nodeAnims = MemoryHelper.MarshalArray<AiNodeAnim>(animation.Channels, (int) animation.NumChannels, true); _channels = new NodeAnimationChannel[nodeAnims.Length]; for(int i = 0; i < _channels.Length; i++) { _channels[i] = new NodeAnimationChannel(nodeAnims[i]); } } //Load mesh animations if(animation.NumMeshChannels > 0 && animation.MeshChannels != IntPtr.Zero) { AiMeshAnim[] meshAnims = MemoryHelper.MarshalArray<AiMeshAnim>(animation.MeshChannels, (int) animation.NumMeshChannels, true); _meshChannels = new MeshAnimationChannel[meshAnims.Length]; for(int i = 0; i < _meshChannels.Length; i++) { _meshChannels[i] = new MeshAnimationChannel(meshAnims[i]); } } }
void TestAnimationChannel(NodeAnimationChannel netChannel, NodeAnim sharpChannel) { Assert.AreEqual(netChannel.NodeName, sharpChannel.NodeName); Assert.AreEqual(netChannel.PositionKeyCount, sharpChannel.PositionKeys.Length); for(int i=0; i<netChannel.PositionKeyCount; i++) { Assert.AreEqual(netChannel.PositionKeys[i].Time, sharpChannel.PositionKeys[i].Time); MathAssert.AreEqual(netChannel.PositionKeys[i].Value, sharpChannel.PositionKeys[i].Value); } Assert.AreEqual(netChannel.RotationKeyCount, sharpChannel.RotationKeys.Length); for (int i = 0; i < netChannel.RotationKeyCount; i++) { Assert.AreEqual(netChannel.RotationKeys[i].Time, sharpChannel.RotationKeys[i].Time); MathAssert.AreEqual(netChannel.RotationKeys[i].Value, sharpChannel.RotationKeys[i].Value); } Assert.AreEqual(netChannel.ScalingKeyCount, sharpChannel.ScalingKeys.Length); for (int i = 0; i < netChannel.ScalingKeyCount; i++) { Assert.AreEqual(netChannel.ScalingKeys[i].Time, sharpChannel.ScalingKeys[i].Time); MathAssert.AreEqual(netChannel.ScalingKeys[i].Value, sharpChannel.ScalingKeys[i].Value); } }
/// <summary> /// Convert AssimpAnimation, positions and rotation, in Matrix3D (Absolute) /// </summary> /// <param name="finMat">Matrix</param> /// <param name="pNodeAnim">Assimp Node data</param> /// <param name="parentMatrix">Matrix of the parent Node</param> /// <returns></returns> private Matrix3D GetAbsoluteMatrix(out Matrix4x4 finMat, NodeAnimationChannel pNodeAnim, Matrix4x4 parentMatrix) { Assimp.Quaternion rot = pNodeAnim.RotationKeys.ElementAtOrDefault(Session.CurrentSession.CurrentProject.CurrentModel3D.Animation.Tick).Value; Matrix4x4 rotMatrix = rot.GetMatrix(); Assimp.Vector3D pos = pNodeAnim.PositionKeys.ElementAtOrDefault(Session.CurrentSession.CurrentProject.CurrentModel3D.Animation.Tick).Value; Matrix4x4 transMatrix = Matrix4x4.FromTranslation(pos); Matrix4x4 nodeTrans = rotMatrix * transMatrix; finMat = nodeTrans * parentMatrix; return matrixConverter.AssimpMatrixtoMatrix3D(finMat); }
/** * This function will Initialize (names, size, ect...) * the mChannels array in Animation newly created class. * @param skeleton Skeleton Fetch on the kinect stream */ private void InitAnimBones(Scene scene, Skeleton skeleton) { Animation newAnim = new Animation(); //We set 0 by defaults but it should be interesting to check tickpersecond for a skeleton record newAnim.TicksPerSecond = 0; newAnim.DurationInTicks = 0; scene.Animations.Add(newAnim); //this.animList.Add(new Tuple<Int32, Animation>(skeleton.TrackingId, newAnim)); foreach (Joint joint in skeleton.Joints) { NodeAnimationChannel bone = new NodeAnimationChannel(); bone.NodeName = joint.JointType.ToString(); newAnim.NodeAnimationChannels.Add(bone); } }
/** * Kinect Joint Conversion to NodeAnim */ private void KinectJointToNode(Scene mainScene, Joint joint, NodeAnimationChannel matchedNode, double time) { VectorKey keyframePos = new VectorKey(); keyframePos.Value.X = joint.Position.X; keyframePos.Value.Y = joint.Position.Y; keyframePos.Value.Z = joint.Position.Z; keyframePos.Time = time; QuaternionKey keyframeRot = new QuaternionKey(); if (joint.JointType == JointType.HipCenter) { keyframeRot.Value = new Quaternion(0, (float)3, (float)1.3); } else { keyframeRot.Value.X = 0; keyframeRot.Value.Y = 0; keyframeRot.Value.Z = 0; } keyframeRot.Time = time; //We set last_assimp_joint node that we will reuse for calculate localPosition/Rotation the next step string prevNodeName = mainScene.RootNode.FindNode(matchedNode.NodeName).Parent.Name; VectorKey prevKeyframePos = new VectorKey(); bool find = false; /* * TODO: We could refactor that code to avoid to go through all joint each time * we need to look for a specific joint */ foreach (Joint j in currentJoinCol) { if (prevNodeName == "") find = true; if (j.JointType.ToString() == prevNodeName) { prevKeyframePos.Value.X = j.Position.X; prevKeyframePos.Value.Y = j.Position.Y; prevKeyframePos.Value.Z = j.Position.Z; find = true; break; } } if (find == false) throw new Exception(); if (prevNodeName != "") keyframePos.Value -= prevKeyframePos.Value; keyframePos.Value.X *= 17; keyframePos.Value.Y *= 17; keyframePos.Value.Z *= 17; matchedNode.PositionKeys.Add(keyframePos); matchedNode.RotationKeys.Add(keyframeRot); }
/** * Convert a KinectJoint into a NodeAnimationChannel and add it in an Animation. * This method also take care if there NodeJoint already exist or not in the Animation * and create it if not (In fact some kinect joint can appear wheareas they didnt exist before) * @param joint The KinectJoint which will be converted * @param curAnim The animation in which the converted kinectJoint will be added */ private void AddJointAtTimeframeEnd(Scene scene, Joint joint, Animation curAnim, double time) { //We try to find the KinectJoint in the Assimp recorder (curAnim) // \todo Apparently .toString() on a enumerate is obsolete, so need to check on that NodeAnimationChannel matchedNode = (from nodeAnimTmp in curAnim.NodeAnimationChannels where nodeAnimTmp.NodeName == joint.JointType.ToString() select nodeAnimTmp).First(); //If we dont, we add it in the Channel if (matchedNode == null) { NodeAnimationChannel newAnimJoint = new NodeAnimationChannel(); newAnimJoint.NodeName = joint.JointType.ToString(); curAnim.NodeAnimationChannels.Add(newAnimJoint); matchedNode = newAnimJoint; } this.KinectJointToNode(scene, joint, matchedNode, time); }
/// <summary> /// Convert Assimp animation Data in Matrix3D Data /// </summary> /// <param name="finMat">Matrix</param> /// <param name="pNodeAnim">Assimp Node data</param> /// <param name="parentMatrix">Matrix of the parent Node</param> /// <returns></returns> private Matrix3D GetActualMatrix(out Matrix4x4 finMat, NodeAnimationChannel pNodeAnim, Matrix4x4 parentMatrix, int frame) { Assimp.Quaternion rot = pNodeAnim.RotationKeys.ElementAtOrDefault(frame).Value; Matrix4x4 rotMatrix = rot.GetMatrix(); Assimp.Vector3D pos = pNodeAnim.PositionKeys.ElementAtOrDefault(frame).Value; Matrix4x4 transMatrix = Matrix4x4.FromTranslation(pos); Matrix4x4 nodeTrans = rotMatrix * transMatrix; finMat = nodeTrans * parentMatrix; return matrixConverter.AssimpMatrixtoMatrix3D(finMat); }
/// <summary> /// Stack a new matrix on the current one from information /// available inside the NodeAnimationChannels /// </summary> /// <param name="finMat"></param> /// <param name="nodeAnim"></param> /// <param name="frameIndex"></param> private Matrix4x4 StackMatrix(Matrix4x4 parentMatrix, NodeAnimationChannel nodeAnim, int frameIndex) { Assimp.Quaternion rot = nodeAnim.RotationKeys[frameIndex].Value; Matrix4x4 rotMatrix = rot.GetMatrix(); Assimp.Vector3D pos = nodeAnim.PositionKeys[frameIndex].Value; Matrix4x4 transMatrix = Matrix4x4.FromTranslation(pos); Matrix4x4 nodeTrans = rotMatrix * transMatrix; return nodeTrans * parentMatrix; }