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); }
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; }
/// <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 );"); }