public static void LerpToMatrix(float amount, ref FrameTransformation t1, ref FrameTransformation t2, out Math.Matrix result) { float invAmount = 1.0f - amount; result = t1._original; // TODO: right now we're doing a naive interpolation, // which will work, but doesn't look as good as breaking // apart the matrix into components (rotation, scale, translation) // and interpolating the individual components with lerp/slerp result.M11 = t1._original.M11 * invAmount + t2._original.M11 * amount; result.M12 = t1._original.M12 * invAmount + t2._original.M12 * amount; result.M13 = t1._original.M13 * invAmount + t2._original.M13 * amount; result.M14 = t1._original.M14 * invAmount + t2._original.M14 * amount; result.M21 = t1._original.M21 * invAmount + t2._original.M21 * amount; result.M22 = t1._original.M22 * invAmount + t2._original.M22 * amount; result.M23 = t1._original.M23 * invAmount + t2._original.M23 * amount; result.M24 = t1._original.M24 * invAmount + t2._original.M24 * amount; result.M31 = t1._original.M31 * invAmount + t2._original.M31 * amount; result.M32 = t1._original.M32 * invAmount + t2._original.M32 * amount; result.M33 = t1._original.M33 * invAmount + t2._original.M33 * amount; result.M34 = t1._original.M34 * invAmount + t2._original.M34 * amount; result.M41 = t1._translation.X * invAmount + t2._translation.X * amount; result.M42 = t1._translation.Y * invAmount + t2._translation.Y * amount; result.M43 = t1._translation.Z * invAmount + t2._translation.Z * amount; }
/// <summary> /// Applies the animation to a model /// </summary> /// <returns>True if the animation is still playing, false otherwise</returns> public bool Animate(ModelResource model, int timeSinceStart, int timeSinceLastFrame, bool loop, bool absolute) { if (model == null) { throw new ArgumentNullException("model"); } if (model.Meshes.Length != _numMeshes) { throw new ArgumentException("The model is not compatible with this animation"); } bool stillPlaying = false; for (int i = 0; i < model.Meshes.Length; i++) { int frame1, frame2; float percent; getFrames(timeSinceStart, i, out frame1, out frame2, out percent); if (frame1 >= 0) { stillPlaying = true; } if (frame1 >= 0 && frame2 >= 0) { if (_animationFrames[i][frame1].Transform != null && _animationFrames[i][frame2].Transform != null) { Math.Matrix animatedTransform; FrameTransformation.LerpToMatrix(percent, ref _animationFrames[i][frame1].Transform, ref _animationFrames[i][frame2].Transform, out animatedTransform); //model.Meshes[i].AnimatedTransformMatrix = animatedTransform; model.Meshes[i].SetTransform(animatedTransform); //model.Meshes[i].SetTransform(_animationFrames[i][frame1].Transform.Original); model.Meshes[i].AnimatedTransformIsAbsolute = absolute; } // TODO: interpolate FrameSectionVertices[] v = _animationFrames[i][frame1].Vertices; if (v != null) { for (int j = 0; j < v.Length; j++) { if (model.Meshes[i].sections[v[j].SectionIndex].AnimatedVertices == null) { model.Meshes[i].sections[v[j].SectionIndex].AnimatedVertices = new float[model.Meshes[i].sections[v[j].SectionIndex].vertices.Length]; Array.Copy(model.Meshes[i].sections[v[j].SectionIndex].vertices, model.Meshes[i].sections[v[j].SectionIndex].AnimatedVertices, model.Meshes[i].sections[v[j].SectionIndex].vertices.Length); } float[] dest = model.Meshes[i].sections[v[j].SectionIndex].AnimatedVertices; float[] source = v[j].Vertices; for (int k = 0; k < source.Length / 3; k++) { const int stride = 3 + 3 + 2; dest[k * stride + 0] = source[k * 3 + 0]; dest[k * stride + 1] = source[k * 3 + 1]; dest[k * stride + 2] = source[k * 3 + 2]; } } } float[] boundingBox = _animationFrames[i][frame1].BoundingBox; if (boundingBox != null) { // TODO: interpolate the bounding boxes model.Meshes[i].SetAABB(new AxisAlignedBoundingBox(boundingBox)); } } /*if (frame.Vertices != null) * { * for (int j = 0; j < frame.Vertices.Length; j++) * { * float[] dest = model.Meshes[i].sections[frame.Vertices[j].SectionIndex].vertices; * float[] source = frame.Vertices[j].Vertices; * * if (frame.Vertices[j].Delta) * { * for (int k = 0; k < source.Length / 3; k++) * { * const int stride = 3 + 3 + 2; * dest[k * stride + 0] += source[k * 3 + 0]; * dest[k * stride + 1] += source[k * 3 + 1]; * dest[k * stride + 2] += source[k * 3 + 2]; * } * * //model.Meshes[i].VerticesModifiedWithDelta = true; * } * else * { * for (int k = 0; k < source.Length / 3; k++) * { * const int stride = 3 + 3 + 2; * dest[k * stride + 0] = source[k * 3 + 0]; * dest[k * stride + 1] = source[k * 3 + 1]; * dest[k * stride + 2] = source[k * 3 + 2]; * } * } * } * }*/ //model.Meshes[i].AnimatedTransformMatrix = transform;// *model.Meshes[i].TransformMatrix; } return(stillPlaying); }