protected void WriteMorphKeyframe( BinaryWriter writer, VertexMorphKeyFrame keyFrame )
		{
			var start_offset = writer.Seek( 0, SeekOrigin.Current );
			WriteChunk( writer, MeshChunkID.AnimationMorphKeyframe, 0 );

			WriteFloat( writer, keyFrame.Time );
			var vBuffer = keyFrame.VertexBuffer;
			var vBufferPtr = vBuffer.Lock( BufferLocking.ReadOnly );
			WriteFloats( writer, vBuffer.VertexCount*3, vBufferPtr );
			vBuffer.Unlock();

			var end_offset = writer.Seek( 0, SeekOrigin.Current );
			writer.Seek( (int)start_offset, SeekOrigin.Begin );
			WriteChunk( writer, MeshChunkID.AnimationMorphKeyframe, (int)( end_offset - start_offset ) );
			writer.Seek( (int)end_offset, SeekOrigin.Begin );
		}
Example #2
0
        /// <summary>
        ///     As the 'apply' method but applies to specified VertexData instead of
        ///	    associated data.
        /// </summary>
        public void ApplyToVertexData(VertexData data, float time, float weight, List <Pose> poseList)
        {
            // Nothing to do if no keyframes
            if (keyFrameList.Count == 0)
            {
                return;
            }

            // Get keyframes
            KeyFrame kf1, kf2;
            ushort   firstKeyIndex;
            float    t = GetKeyFramesAtTime(time, out kf1, out kf2, out firstKeyIndex);

            if (animationType == VertexAnimationType.Morph)
            {
                VertexMorphKeyFrame vkf1 = (VertexMorphKeyFrame)kf1;
                VertexMorphKeyFrame vkf2 = (VertexMorphKeyFrame)kf2;

                if (targetMode == VertexAnimationTargetMode.Hardware)
                {
                    // If target mode is hardware, need to bind our 2 keyframe buffers,
                    // one to main pos, one to morph target texcoord
                    Debug.Assert(data.HWAnimationDataList.Count == 0,
                                 "Haven't set up hardware vertex animation elements!");

                    // no use for TempBlendedBufferInfo here btw
                    // NB we assume that position buffer is unshared
                    // VertexDeclaration::getAutoOrganisedDeclaration should see to that
                    VertexElement posElem =
                        data.vertexDeclaration.FindElementBySemantic(VertexElementSemantic.Position);
                    // Set keyframe1 data as original position
                    data.vertexBufferBinding.SetBinding(posElem.Source, vkf1.VertexBuffer);
                    // Set keyframe2 data as derived
                    data.vertexBufferBinding.SetBinding(data.HWAnimationDataList[0].TargetVertexElement.Source,
                                                        vkf2.VertexBuffer);
                    // save T for use later
                    data.HWAnimationDataList[0].Parametric = t;
                }
                else
                {
                    // If target mode is software, need to software interpolate each vertex

                    Mesh.SoftwareVertexMorph(t, vkf1.VertexBuffer, vkf2.VertexBuffer, data);
                }
            }
            else
            {
                // Pose

                VertexPoseKeyFrame vkf1 = (VertexPoseKeyFrame)kf1;
                VertexPoseKeyFrame vkf2 = (VertexPoseKeyFrame)kf2;

                // For each pose reference in key 1, we need to locate the entry in
                // key 2 and interpolate the influence
                List <PoseRef> poseRefList1 = vkf1.PoseRefs;
                List <PoseRef> poseRefList2 = vkf2.PoseRefs;
                foreach (PoseRef p1 in poseRefList1)
                {
                    float startInfluence = p1.Influence;
                    float endInfluence   = 0;
                    // Search for entry in keyframe 2 list (if not there, will be 0)
                    foreach (PoseRef p2 in poseRefList2)
                    {
                        if (p1.PoseIndex == p2.PoseIndex)
                        {
                            endInfluence = p2.Influence;
                            break;
                        }
                    }
                    // Interpolate influence
                    float influence = startInfluence + t * (endInfluence - startInfluence);
                    // Scale by animation weight
                    influence = weight * influence;
                    // Get pose
                    Debug.Assert(p1.PoseIndex <= poseList.Count);
                    Pose pose = poseList[p1.PoseIndex];
                    // apply
                    ApplyPoseToVertexData(pose, data, influence);
                }
                // Now deal with any poses in key 2 which are not in key 1
                foreach (PoseRef p2 in  poseRefList2)
                {
                    bool found = false;
                    foreach (PoseRef p1 in poseRefList1)
                    {
                        if (p1.PoseIndex == p2.PoseIndex)
                        {
                            found = true;
                            break;
                        }
                    }
                    if (!found)
                    {
                        // Need to apply this pose too, scaled from 0 start
                        float influence = t * p2.Influence;
                        // Scale by animation weight
                        influence = weight * influence;
                        // Get pose
                        Debug.Assert(p2.PoseIndex <= poseList.Count);
                        Pose pose = poseList[p2.PoseIndex];
                        // apply
                        ApplyPoseToVertexData(pose, data, influence);
                    }
                } // key 2 iteration
            }     // morph or pose animation
        }