Пример #1
0
        /// <summary>
        /// xna will use this function to read my own .xnb file
        /// </summary>
        /// <param name="reader"></param>
        public void Load(ContentReader reader)
        {
            //read the speed of animation
            AnimationSpeed = reader.ReadSingle();
            //first of all:it's bones count
            BonesCount = reader.ReadInt32();

            VmdAnimationFrames = new Dictionary <string, List <VmdKeyframe> >();
            for (int i = 0; i < BonesCount; i++)
            {
                //for each bone

                //1 bone name
                string             boneName         = reader.ReadString();
                List <VmdKeyframe> framesOfThisBone = new List <VmdKeyframe>();
                //2 keyframe count
                int keyframeCountOfThisBone = reader.ReadInt32();
                //3 get all frame of this bone and push them into VmdFrames
                for (int j = 0; j < keyframeCountOfThisBone; j++)
                {
                    //get pos and rotation
                    VmdKeyframe keyframe = new VmdKeyframe();
                    //read time
                    keyframe.Time     = reader.ReadSingle();
                    keyframe.Position = reader.ReadVector3();
                    keyframe.Rotation = reader.ReadQuaternion();
                    //push it into array
                    framesOfThisBone.Add(keyframe);
                }

                VmdAnimationFrames[boneName] = framesOfThisBone;
            }

            #region Face Frames
            //face frame count
            int faceFrameCount = reader.ReadInt32();
            //just a copy of sth
            VmdFaceFrames = new VmdFaceFrame[faceFrameCount];
            for (int i = 0; i < faceFrameCount; i++)
            {
                VmdFaceFrames[i].MorphName          = reader.ReadString();
                VmdFaceFrames[i].IndexOfFrame       = reader.ReadSingle();
                VmdFaceFrames[i].WeightOfBaseVertex = reader.ReadSingle();
            }
            #endregion
        }
Пример #2
0
        /// <summary>
        /// update animation
        /// change the customBoneTransformation
        /// </summary>
        /// <param name="gameTime"></param>
        private void UpdateAnimation(GameTime gameTime)
        {
            if (currentAnimation == null)
            {
                return;
            }
            //according the keyframes in the animation
            //change the customBoneTransformation

            //parameter:0.00005 is adjust for real situation in real world
            g_time += gameTime.ElapsedGameTime.Milliseconds * 0.00005f * currentAnimation.AnimationSpeed;
            //now we have tha animation
            //whether loop the animation
            if (g_time > 1.0f)
            {
                if (LoopAnimation)
                {
                    g_time = 0.0f;
                }
            }
            //check every bone and find their keyfram according to time
            for (int i = 0; i < bonesNameList.Count; i++)
            {
                //if not exist the current bone
                if (!currentAnimation.VmdAnimationFrames.ContainsKey(bonesNameList[i]))
                {
                    boneLocalTransform[i] = boneLocalPose[i];
                    continue;
                }
                List <VmdKeyframe> frames = currentAnimation.VmdAnimationFrames[bonesNameList[i]];
                if (frames == null)
                {
                    continue;//if we couldn't find the bone
                }
                //find the frame index
                int index = 0;
                while ((index < frames.Count) && (frames[index].Time < g_time))
                {
                    index++;
                }

                if (index == 0)
                {
                    Vector3    internalPos = frames[0].Position;
                    Quaternion internalRot = frames[0].Rotation;;
                    customBoneTransformation[i] = (new Transform(new Vector3(0, 0, 0), internalRot)) * (new Transform(internalPos, Quaternion.Identity));
                    //customBoneTransformation[i] = new Transform(internalPos, internalRot);
                    //customBoneTransformation[i] = Matrix.CreateFromQuaternion(internalRot) * Matrix.CreateTranslation(internalPos);
                }
                else if (index >= frames.Count)
                {
                    Vector3    internalPos = frames[frames.Count - 1].Position;
                    Quaternion internalRot = frames[frames.Count - 1].Rotation;
                    customBoneTransformation[i] = (new Transform(new Vector3(0, 0, 0), internalRot)) * (new Transform(internalPos, Quaternion.Identity));
                    //customBoneTransformation[i] = new Transform(internalPos, internalRot);
                    //customBoneTransformation[i] = Matrix.CreateFromQuaternion(internalRot) * Matrix.CreateTranslation(internalPos);
                }
                else
                {
                    //interpolate frame
                    //1 position
                    VmdKeyframe current = frames[index - 1];
                    VmdKeyframe next    = frames[index];
                    float       ratio   = (g_time - frames[index - 1].Time) /
                                          (frames[index].Time - frames[index - 1].Time);

                    Vector3    internalPos = current.Position * (1 - ratio) + ratio * next.Position;
                    Quaternion internalRot = Quaternion.Lerp(current.Rotation, next.Rotation, ratio);
                    //change customBoneTransformation
                    customBoneTransformation[i] = (new Transform(new Vector3(0, 0, 0), internalRot)) * (new Transform(internalPos, Quaternion.Identity));

                    //customBoneTransformation[i] = new Transform(internalPos, internalRot);
                    //customBoneTransformation[i] = Matrix.CreateFromQuaternion(internalRot) * Matrix.CreateTranslation(internalPos);
                }

                boneLocalTransform[i] = customBoneTransformation[i] * boneLocalPose[i];
            }
        }