// Internal creation internal BonePose(ModelBone bone, ModelBoneCollection bones, BonePose[] anims) { // Set the values according to the bone index = bone.Index; name = bone.Name; defaultMatrix = bone.Transform; if (bone.Parent != null) { parent = anims[bone.Parent.Index]; } anims[index] = this; // Recurse on children List <BonePose> childList = new List <BonePose>(); foreach (ModelBone child in bone.Children) { BonePose newChild = new BonePose( bones[child.Index], bones, anims); childList.Add(newChild); } children = new BonePoseCollection(childList); }
/// <summary> /// Gets the current transform for the given BonePose object in the animation. /// This is only called when a bone pose is affected by the current animation. /// </summary> /// <param name="pose">The BonePose object querying for the current transform in /// the animation.</param> /// <returns>The current transform of the bone.</returns> public virtual Matrix GetCurrentBoneTransform(BonePose pose) { AnimationChannelCollection channels = animation.AnimationChannels; BoneKeyframeCollection channel = channels[pose.Name]; int boneIndex = channel.GetIndexByTime(elapsedTime); return(channel[boneIndex].Transform); }
/// <summary> /// Returns the current transform for a bone. /// </summary> /// <param name="pose">The bone.</param> /// <returns>The bone's current transform.</returns> public override Matrix GetCurrentBoneTransform(BonePose pose) { BoneKeyframeCollection channel = base.AnimationSource.AnimationChannels[ pose.Name]; int curIndex = channel.GetIndexByTime(base.ElapsedTime); if (interpMethod == InterpolationMethod.None) { return(channel[curIndex].Transform); } int nextIndex = curIndex + 1; if (nextIndex >= channel.Count) { return(channel[curIndex].Transform); } // Numerator of the interpolation factor double interpNumerator = (double)(ElapsedTime - channel[curIndex].Time); // Denominator of the interpolation factor double interpDenom = (double)(channel[nextIndex].Time - channel[curIndex].Time); // The interpolation factor, or amount to interpolate between the current // and next frame double interpAmount = interpNumerator / interpDenom; curTransform = channel[curIndex].Transform; nextTransform = channel[nextIndex].Transform; if (interpMethod == InterpolationMethod.Linear) { Matrix.Lerp(ref curTransform, ref nextTransform, (float)interpAmount, out transform); } else { Util.SlerpMatrix(ref curTransform, ref nextTransform, (float)interpAmount, out transform); } return(transform); }
/// <summary> /// Gets the current bone transform. /// </summary> /// <param name="pose">The pose.</param> /// <returns>The current transform of the bone.</returns> public Matrix GetCurrentBoneTransform(BonePose pose) { if (controllerDict.Count == 0) { return(pose.DefaultTransform); } Matrix transform = new Matrix(); Matrix m; foreach (KeyValuePair <IAnimationController, float> k in controllerDict) { if (k.Key.ContainsAnimationTrack(pose)) { m = k.Key.GetCurrentBoneTransform(pose); transform += k.Value * m; } else { transform += k.Value * pose.DefaultTransform; } } return(transform); }
/// <summary> /// Returns true if the animation contains a track for the given BonePose. /// </summary> /// <param name="pose">The BonePose to test for track existence.</param> /// <returns>True if the animation contains a track for the given BonePose.</returns> public bool ContainsAnimationTrack(BonePose pose) { return(animation.AnimationChannels.AffectsBone(pose.Name)); }
/// <summary> /// Returns true if the controller can affect the bone. /// </summary> /// <param name="pose">The bone.</param> /// <returns>True if the controller can affect the bone.</returns> public bool ContainsAnimationTrack(BonePose pose) { return(true); }