private void ParseJoint(idLexer lexer, idMD5Joint joint, ref idJointQuaternion defaultPose)
        {
            //
            // parse name
            //
            joint.Name = lexer.ReadToken().ToString();

            //
            // parse parent
            //
            int parentIndex = lexer.ParseInt();

            if (parentIndex >= 0)
            {
                if (parentIndex >= (_joints.Length - 1))
                {
                    lexer.Error("Invalid parent for joint '{0}'", joint.Name);
                }

                joint.Parent = _joints[parentIndex];
            }

            //
            // parse default pose
            //
            float[] tmp = lexer.Parse1DMatrix(3);
            defaultPose.Translation = new Vector3(tmp[0], tmp[1], tmp[2]);

            tmp = lexer.Parse1DMatrix(3);
            defaultPose.Quaternion   = new Quaternion(tmp[0], tmp[1], tmp[2], 0);
            defaultPose.Quaternion.W = idHelper.CalculateW(defaultPose.Quaternion);
        }
        /// <summary>
        /// Used for initial loads, reloadModel, and reloading the data of purged models.
        /// </summary>
        /// <remarks>
        /// Upon exit, the model will absolutely be valid, but possibly as a default model.
        /// </remarks>
        public override void Load()
        {
            if (this.Disposed == true)
            {
                throw new ObjectDisposedException(this.GetType().Name);
            }

            if (_purged == false)
            {
                Purge();
            }

            _purged = false;

            idLexer lexer = new idLexer(LexerOptions.AllowPathNames | LexerOptions.NoStringEscapeCharacters);

            if (lexer.LoadFile(Name) == false)
            {
                MakeDefault();
                return;
            }

            lexer.ExpectTokenString(VersionString);

            int     version = lexer.ParseInt();
            int     count   = 0;
            idToken token;

            if (version != Version)
            {
                lexer.Error("Invalid version {0}. Should be version {1}", version, Version);
            }

            //
            // skip commandline
            //
            lexer.ExpectTokenString("commandline");
            lexer.ReadToken();

            // parse num joints
            lexer.ExpectTokenString("numJoints");

            count = lexer.ParseInt();

            _joints      = new idMD5Joint[count];
            _defaultPose = new idJointQuaternion[count];

            idJointMatrix[] poseMat3 = new idJointMatrix[count];

            // parse num meshes
            lexer.ExpectTokenString("numMeshes");
            count = lexer.ParseInt();

            if (count < 0)
            {
                lexer.Error("Invalid size: {0}", count);
            }

            _meshes = new idMD5Mesh[count];

            //
            // parse joints
            //
            lexer.ExpectTokenString("joints");
            lexer.ExpectTokenString("{");

            int jointCount = _joints.Length;

            for (int i = 0; i < jointCount; i++)
            {
                idMD5Joint        joint = _joints[i] = new idMD5Joint();
                idJointQuaternion pose  = new idJointQuaternion();

                ParseJoint(lexer, joint, ref pose);

                poseMat3[i]             = idJointMatrix.Zero;
                poseMat3[i].Rotation    = Matrix.CreateFromQuaternion(pose.Quaternion);
                poseMat3[i].Translation = pose.Translation;

                if (joint.Parent != null)
                {
                    int parentIndex = GetJointIndex(joint.Parent);

                    pose.Quaternion = Quaternion.CreateFromRotationMatrix(poseMat3[i].ToMatrix()
                                                                          * Matrix.Transpose(poseMat3[parentIndex].ToMatrix()));
                    pose.Translation = Vector3.Transform(poseMat3[i].ToVector3() - poseMat3[parentIndex].ToVector3(),
                                                         Matrix.Transpose(poseMat3[parentIndex].ToMatrix()));
                }

                _defaultPose[i] = pose;
            }

            lexer.ExpectTokenString("}");

            int meshCount = _meshes.Length;

            for (int i = 0; i < meshCount; i++)
            {
                lexer.ExpectTokenString("mesh");

                _meshes[i] = new idMD5Mesh();
                _meshes[i].Parse(lexer, poseMat3);
            }

            //
            // calculate the bounds of the model
            //
            CalculateBounds(poseMat3);

            // set the timestamp for reloadmodels
            idConsole.Warning("TODO: fileSystem->ReadFile( name, NULL, &timeStamp );");
        }
Example #3
0
        public bool LoadAnimation(string fileName)
        {
            idToken token;
            idLexer lexer = new idLexer(LexerOptions.AllowPathNames | LexerOptions.NoStringEscapeCharacters | LexerOptions.NoStringConcatination);

            if (lexer.LoadFile(fileName) == false)
            {
                return(false);
            }

            Clear();

            _name = fileName;

            lexer.ExpectTokenString(idRenderModel_MD5.VersionString);
            int version = lexer.ParseInt();

            if (version != idRenderModel_MD5.Version)
            {
                lexer.Error("Invalid version {0}.  Should be version {1}", version, idRenderModel_MD5.Version);
            }

            // skip the commandline
            lexer.ExpectTokenString("commandline");
            lexer.ReadToken();

            // parse num frames
            lexer.ExpectTokenString("numFrames");
            int frameCount = lexer.ParseInt();

            if (frameCount <= 0)
            {
                lexer.Error("Invalid number of frames: {0}", frameCount);
            }

            // parse num joints
            lexer.ExpectTokenString("numJoints");
            int jointCount = lexer.ParseInt();

            if (jointCount <= 0)
            {
                lexer.Error("Invalid number of joints: {0}", jointCount);
            }

            // parse frame rate
            lexer.ExpectTokenString("frameRate");
            _frameRate = lexer.ParseInt();

            if (_frameRate < 0)
            {
                lexer.Error("Invalid frame rate: {0}", _frameRate);
            }

            // parse number of animated components
            lexer.ExpectTokenString("numAnimatedComponents");
            _animatedComponentCount = lexer.ParseInt();

            if ((_animatedComponentCount < 0) || (_animatedComponentCount > (jointCount * 6)))
            {
                lexer.Error("Invalid number of animated components: {0}", _animatedComponentCount);
            }

            // parse the hierarchy
            _jointInfo = new JointAnimationInfo[jointCount];

            lexer.ExpectTokenString("hierarchy");
            lexer.ExpectTokenString("{");

            for (int i = 0; i < jointCount; i++)
            {
                token = lexer.ReadToken();

                _jointInfo[i]           = new JointAnimationInfo();
                _jointInfo[i].NameIndex = idR.AnimManager.GetJointIndex(token.ToString());

                // parse parent num
                _jointInfo[i].ParentIndex = lexer.ParseInt();

                if (_jointInfo[i].ParentIndex >= i)
                {
                    lexer.Error("Invalid parent num: {0}", _jointInfo[i].ParentIndex);
                }

                if ((i != 0) && (_jointInfo[i].ParentIndex < 0))
                {
                    lexer.Error("Animations may have only one root joint");
                }

                // parse anim bits
                _jointInfo[i].AnimationBits = (AnimationBits)lexer.ParseInt();

                if (((int)_jointInfo[i].AnimationBits & ~63) != 0)
                {
                    lexer.Error("Invalid anim bits: {0}", _jointInfo[i].AnimationBits);
                }

                // parse first component
                _jointInfo[i].FirstComponent = lexer.ParseInt();

                if ((_animatedComponentCount > 0) && ((_jointInfo[i].FirstComponent < 0) || (_jointInfo[i].FirstComponent >= _animatedComponentCount)))
                {
                    lexer.Error("Invalid first component: {0}", _jointInfo[i].FirstComponent);
                }
            }

            lexer.ExpectTokenString("}");

            // parse bounds
            lexer.ExpectTokenString("bounds");
            lexer.ExpectTokenString("{");

            _bounds = new idBounds[frameCount];

            for (int i = 0; i < frameCount; i++)
            {
                float[] tmp  = lexer.Parse1DMatrix(3);
                float[] tmp2 = lexer.Parse1DMatrix(3);

                _bounds[i] = new idBounds(
                    new Vector3(tmp[0], tmp[1], tmp[2]),
                    new Vector3(tmp2[0], tmp2[1], tmp2[2])
                    );
            }

            lexer.ExpectTokenString("}");

            // parse base frame
            _baseFrame = new idJointQuaternion[jointCount];

            lexer.ExpectTokenString("baseframe");
            lexer.ExpectTokenString("{");

            for (int i = 0; i < jointCount; i++)
            {
                float[] tmp  = lexer.Parse1DMatrix(3);
                float[] tmp2 = lexer.Parse1DMatrix(3);

                idCompressedQuaternion q = new idCompressedQuaternion(tmp2[0], tmp2[1], tmp2[2]);


                _baseFrame[i]             = new idJointQuaternion();
                _baseFrame[i].Translation = new Vector3(tmp[0], tmp[1], tmp[2]);
                _baseFrame[i].Quaternion  = q.ToQuaternion();
            }

            lexer.ExpectTokenString("}");

            // parse frames
            _componentFrames = new float[_animatedComponentCount * frameCount];
            int frameOffset = 0;

            for (int i = 0; i < frameCount; i++)
            {
                lexer.ExpectTokenString("frame");
                int count = lexer.ParseInt();

                if (count != i)
                {
                    lexer.Error("Expected frame number {0}", i);
                }

                lexer.ExpectTokenString("{");

                for (int j = 0; j < _animatedComponentCount; j++, frameOffset++)
                {
                    _componentFrames[frameOffset] = lexer.ParseFloat();
                }

                lexer.ExpectTokenString("}");
            }

            // get total move delta
            if (_animatedComponentCount == 0)
            {
                _totalDelta = Vector3.Zero;
            }
            else
            {
                int componentOffset = _jointInfo[0].FirstComponent;

                if ((_jointInfo[0].AnimationBits & AnimationBits.TranslationX) == AnimationBits.TranslationX)
                {
                    for (int i = 0; i < frameCount; i++)
                    {
                        _componentFrames[componentOffset + (_animatedComponentCount * i)] -= _baseFrame[0].Translation.X;
                    }

                    _totalDelta.X = _componentFrames[componentOffset + (_animatedComponentCount * (frameCount - 1))];
                    componentOffset++;
                }
                else
                {
                    _totalDelta.X = 0;
                }

                if ((_jointInfo[0].AnimationBits & AnimationBits.TranslationY) == AnimationBits.TranslationY)
                {
                    for (int i = 0; i < frameCount; i++)
                    {
                        _componentFrames[componentOffset + (_animatedComponentCount * i)] -= _baseFrame[0].Translation.Y;
                    }

                    _totalDelta.Y = _componentFrames[componentOffset + (_animatedComponentCount * (frameCount - 1))];
                    componentOffset++;
                }
                else
                {
                    _totalDelta.Y = 0;
                }

                if ((_jointInfo[0].AnimationBits & AnimationBits.TranslationZ) == AnimationBits.TranslationZ)
                {
                    for (int i = 0; i < frameCount; i++)
                    {
                        _componentFrames[componentOffset + (_animatedComponentCount * i)] -= _baseFrame[0].Translation.Z;
                    }

                    _totalDelta.Z = _componentFrames[componentOffset + (_animatedComponentCount * (frameCount - 1))];
                }
                else
                {
                    _totalDelta.Z = 0;
                }
            }

            _baseFrame[0].Translation = Vector3.Zero;

            // we don't count last frame because it would cause a 1 frame pause at the end
            _animLength = ((frameCount - 1) * 1000 + _frameRate - 1) / _frameRate;

            // done
            return(true);
        }