Exemplo n.º 1
0
        /*
         * template AnimationKey
         * {
         *     DWORD keyType;
         *     DWORD nKeys;
         *     array TimedFloatKeys keys[nKeys];
         * }
         *
         *
         * template TimedFloatKeys
         * {
         *     DWORD time;
         *     FloatKeys tfkeys;
         * }
         *
         * template FloatKeys
         * {
         *     DWORD nValues;
         *     array float values[nValues];
         * }
         */
        /// <summary>
        ///  Imports a key frame list associated with an animation channel
        /// </summary>
        /// <param name="keyType">The type of animation keys used by the current channel</param>
        /// <returns>The list of key frames for the given key type in the current channel</returns>
        private AnimationKeyframe[] ImportAnimationKey(out int keyType)
        {
            // These keys can be rotation (0),scale(1),translation(2), or matrix(3 or 4) keys.
            keyType = tokens.SkipName().NextInt();
            // Number of frames in channel
            int numFrames = tokens.NextInt();

            AnimationKeyframe[] frames = new AnimationKeyframe[numFrames];
            // Find the ticks per millisecond that defines how fast the animation should go
            double ticksPerMS = animTicksPerSecond == null ? DEFAULT_TICKS_PER_SECOND / 1000.0
                : (double)animTicksPerSecond / 1000.0;

            // fill in the frames
            for (int i = 0; i < numFrames; i++)
            {
                // Create a timespan object that represents the time that the current keyframe
                // occurs
                TimeSpan time = new TimeSpan(0, 0, 0, 0,
                                             (int)(tokens.NextInt() / ticksPerMS));
                // The number of keys that represents the transform for this keyframe.
                // Quaternions (rotation keys) have 4,
                // Vectors (scale and translation) have 3,
                // Matrices have 16
                int    numKeys   = tokens.NextInt();
                Matrix transform = new Matrix();
                if (numKeys == 16)
                {
                    transform = tokens.NextMatrix();
                }
                else if (numKeys == 4)
                {
                    Vector4    v = tokens.NextVector4();
                    Quaternion q = new Quaternion(
                        new Vector3(-v.Y, -v.Z, -v.W),
                        v.X);


                    transform = Matrix.CreateFromQuaternion(q);
                }
                else if (numKeys == 3)
                {
                    Vector3 v = tokens.NextVector3();

                    if (keyType == 1)
                    {
                        Matrix.CreateScale(ref v, out transform);
                    }
                    else
                    {
                        Matrix.CreateTranslation(ref v, out transform);
                    }
                }
                tokens.SkipToken();
                frames[i] = new AnimationKeyframe(time, transform);
            }
            tokens.SkipToken();
            return(frames);
        }
Exemplo n.º 2
0
            // "This template is instantiated on a per-mesh basis. Within a mesh, a sequence of n
            // instances of this template will appear, where n is the number of bones (X file frames)
            // that influence the vertices in the mesh. Each instance of the template basically defines
            // the influence of a particular bone on the mesh. There is a list of vertex indices, and a
            // corresponding list of weights.
            // template SkinWeights
            // {
            //     STRING transformNodeName;
            //     DWORD nWeights;
            //     array DWORD vertexIndices[nWeights];
            //     array float weights[nWeights];
            //     Matrix4x4 matrixOffset;
            // }
            // - The name of the bone whose influence is being defined is transformNodeName,
            // and nWeights is the number of vertices affected by this bone.
            // - The vertices influenced by this bone are contained in vertexIndices, and the weights for
            // each of the vertices influenced by this bone are contained in weights.
            // - The matrix matrixOffset transforms the mesh vertices to the space of the bone. When concatenated
            // to the bone's transform, this provides the world space coordinates of the mesh as affected by the bone."
            // (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/
            //  directx9_c/dx9_graphics_reference_x_file_format_templates.asp)
            //


            // Reads in a bone that contains skin weights.  It then adds one bone weight
            //  to every vertex that is influenced by ths bone, which contains the name of the bone and the
            //  weight.
            public void ImportSkinWeights()
            {
                isSkinned = true;
                string boneName = tokens.SkipName().NextString();
                // an influence is an index to a vertex that is affected by the current bone
                int          numInfluences = tokens.NextInt();
                List <int>   influences    = new List <int>();
                List <float> weights       = new List <float>();

                for (int i = 0; i < numInfluences; i++)
                {
                    influences.Add(tokens.NextInt());
                }
                for (int i = 0; i < numInfluences; i++)
                {
                    weights.Add(tokens.NextFloat());
                    if (weights[i] == 0)
                    {
                        influences[i] = -1;
                    }
                }
                influences.RemoveAll(delegate(int i) { return(i == -1); });
                weights.RemoveAll(delegate(float f) { return(f == 0); });

                // Add the matrix that transforms the vertices to the space of the bone.
                // we will need this for skinned animation.
                Matrix blendOffset = tokens.NextMatrix();

                ContentUtil.ReflectMatrix(ref blendOffset);
                skinTransformDictionary.Add(boneName, blendOffset);
                SkinTransformContent trans = new SkinTransformContent();

                trans.BoneName  = boneName;
                trans.Transform = blendOffset;
                skinTransforms.Add(trans);
                // end of skin weights
                tokens.SkipToken();

                // add a new name/weight pair to every vertex influenced by the bone
                for (int i = 0; i < influences.Count; i++)
                {
                    skinInfo[influences[i]].Add(new BoneWeight(boneName,
                                                               weights[i]));
                }
            }