modelloadermdl.cpp
来自「骨骼动画....把魔兽模型解出的代码..」· C++ 代码 · 共 2,345 行 · 第 1/5 页
CPP
2,345 行
//+-----------------------------------------------------------------------------
BOOL MODEL_LOADER_MDL::SaveCamera(MODEL_CAMERA& Camera, TOKEN_OUT_STREAM& TokenStream)
{
TokenStream.WriteWord("Camera ");
TokenStream.WriteString(Camera.Data().Name);
TokenStream.WriteLine(" {");
TokenStream.WriteTab();
TokenStream.WriteWord("FieldOfView ");
TokenStream.WriteFloat(Camera.Data().FieldOfView);
TokenStream.WriteLine(",");
TokenStream.WriteTab();
TokenStream.WriteWord("FarClip ");
TokenStream.WriteFloat(Camera.Data().FarDistance);
TokenStream.WriteLine(",");
TokenStream.WriteTab();
TokenStream.WriteWord("NearClip ");
TokenStream.WriteFloat(Camera.Data().NearDistance);
TokenStream.WriteLine(",");
TokenStream.WriteTab();
TokenStream.WriteWord("Position ");
TokenStream.WriteVector3(Camera.Data().Source);
TokenStream.WriteLine(",");
while(TRUE)
{
if(Camera.Data().SourceTranslation.IsStatic())
{
if(Camera.Data().SourceTranslation.GetVector3() == D3DXVECTOR3(0.0f, 0.0f, 0.0f)) break;
}
if(Camera.Data().SourceTranslation.Save(TokenStream)) return FALSE;
break;
}
TokenStream.WriteTab();
TokenStream.WriteLine("Target {");
TokenStream.WriteTab(2);
TokenStream.WriteWord("Position ");
TokenStream.WriteVector3(Camera.Data().Target);
TokenStream.WriteLine(",");
while(TRUE)
{
if(Camera.Data().TargetTranslation.IsStatic())
{
if(Camera.Data().TargetTranslation.GetVector3() == D3DXVECTOR3(0.0f, 0.0f, 0.0f)) break;
}
if(Camera.Data().TargetTranslation.Save(TokenStream, 2)) return FALSE;
break;
}
while(TRUE)
{
if(Camera.Data().Rotation.IsStatic())
{
if(Camera.Data().Rotation.GetScalar() == 0.0f) break;
}
if(Camera.Data().Rotation.Save(TokenStream, 2)) return FALSE;
break;
}
TokenStream.WriteTab();
TokenStream.WriteLine("}");
TokenStream.WriteLine("}");
return TRUE;
}
//+-----------------------------------------------------------------------------
//| Saves the model collision shapes
//+-----------------------------------------------------------------------------
BOOL MODEL_LOADER_MDL::SaveCollisionShapes(MODEL& Model, TOKEN_OUT_STREAM& TokenStream)
{
INT i;
if(Model.Data().CollisionShapeContainer.GetSize() <= 0) return TRUE;
for(i = 0; i < Model.Data().CollisionShapeContainer.GetTotalSize(); i++)
{
if(Model.Data().CollisionShapeContainer.ValidIndex(i))
{
if(!SaveCollisionShape(*(Model.Data().CollisionShapeContainer[i]), TokenStream)) return FALSE;
}
}
return TRUE;
}
//+-----------------------------------------------------------------------------
//| Saves a model collision shape
//+-----------------------------------------------------------------------------
BOOL MODEL_LOADER_MDL::SaveCollisionShape(MODEL_COLLISION_SHAPE& CollisionShape, TOKEN_OUT_STREAM& TokenStream)
{
std::list<D3DXVECTOR3>::iterator i;
TokenStream.WriteWord("CollisionShape ");
TokenStream.WriteString(CollisionShape.Data().Name);
TokenStream.WriteLine(" {");
if(!SaveBaseData(&CollisionShape.Data(), TokenStream)) return FALSE;
switch(CollisionShape.Data().Type)
{
case COLLISION_SHAPE_TYPE_BOX:
{
if(CollisionShape.Data().VertexList.size() != 2)
{
Error.SetMessage("Collision shape boxes needs exactly 2 vertices!");
return FALSE;
}
TokenStream.WriteTab(1);
TokenStream.WriteLine("Box,");
break;
}
case COLLISION_SHAPE_TYPE_SPHERE:
{
if(CollisionShape.Data().VertexList.size() != 1)
{
Error.SetMessage("Collision shape spheres needs exactly 1 vertex!");
return FALSE;
}
TokenStream.WriteTab(1);
TokenStream.WriteLine("Sphere,");
break;
}
}
if(CollisionShape.Data().VertexList.size() > 0)
{
TokenStream.WriteTab(1);
TokenStream.WriteWord("Vertices ");
TokenStream.WriteInt(static_cast<INT>(CollisionShape.Data().VertexList.size()));
TokenStream.WriteLine(" {");
i = CollisionShape.Data().VertexList.begin();
while(i != CollisionShape.Data().VertexList.end())
{
TokenStream.WriteTab(2);
TokenStream.WriteVector3(*i);
TokenStream.WriteLine(",");
i++;
}
TokenStream.WriteTab(1);
TokenStream.WriteLine("}");
}
if(CollisionShape.Data().BoundsRadius > 0.0f)
{
TokenStream.WriteTab(1);
TokenStream.WriteWord("BoundsRadius ");
TokenStream.WriteFloat(CollisionShape.Data().BoundsRadius);
TokenStream.WriteLine(",");
}
TokenStream.WriteLine("}");
return TRUE;
}
//+-----------------------------------------------------------------------------
//| Loads the model version
//+-----------------------------------------------------------------------------
BOOL MODEL_LOADER_MDL::LoadVersion(MODEL& Model, TOKEN_IN_STREAM& TokenStream)
{
std::string Token;
if(!TokenStream.ExpectChar('{')) return FALSE;
while(!TokenStream.Eof())
{
Token = TokenStream.ReadWord();
if(Token == "") break;
if(Token == "}")
{
return TRUE;
}
else if(Token == "FormatVersion")
{
Model.Data().Info.Version = TokenStream.ReadInt();
if(!TokenStream.ExpectChar(',')) return FALSE;
}
else
{
Error.SetMessage("Unable to load \"" + CurrentFileName + "\", unknown token \"" + Token + "\" in \"Version\"!");
return FALSE;
}
}
Error.SetMessage("Unable to load \"" + CurrentFileName + "\", unexpected EOF reached!");
return FALSE;
}
//+-----------------------------------------------------------------------------
//| Loads the model info
//+-----------------------------------------------------------------------------
BOOL MODEL_LOADER_MDL::LoadModel(MODEL& Model, TOKEN_IN_STREAM& TokenStream)
{
std::string Token;
Model.Data().Info.Name = TokenStream.ReadString();
if(!TokenStream.ExpectChar('{')) return FALSE;
while(!TokenStream.Eof())
{
Token = TokenStream.ReadWord();
if(Token == "") break;
if(Token == "}")
{
return TRUE;
}
else if(Token == "NumGeosets")
{
Model.Data().GeosetContainer.Reserve(TokenStream.ReadInt());
if(!TokenStream.ExpectChar(',')) return FALSE;
}
else if(Token == "NumGeosetAnims")
{
Model.Data().GeosetAnimationContainer.Reserve(TokenStream.ReadInt());
if(!TokenStream.ExpectChar(',')) return FALSE;
}
else if(Token == "NumHelpers")
{
Model.Data().HelperContainer.Reserve(TokenStream.ReadInt());
if(!TokenStream.ExpectChar(',')) return FALSE;
}
else if(Token == "NumBones")
{
Model.Data().BoneContainer.Reserve(TokenStream.ReadInt());
if(!TokenStream.ExpectChar(',')) return FALSE;
}
else if(Token == "NumLights")
{
Model.Data().LightContainer.Reserve(TokenStream.ReadInt());
if(!TokenStream.ExpectChar(',')) return FALSE;
}
else if(Token == "NumAttachments")
{
Model.Data().AttachmentContainer.Reserve(TokenStream.ReadInt());
if(!TokenStream.ExpectChar(',')) return FALSE;
}
else if(Token == "NumEvents")
{
Model.Data().EventObjectContainer.Reserve(TokenStream.ReadInt());
if(!TokenStream.ExpectChar(',')) return FALSE;
}
else if(Token == "NumParticleEmitters")
{
Model.Data().ParticleEmitterContainer.Reserve(TokenStream.ReadInt());
if(!TokenStream.ExpectChar(',')) return FALSE;
}
else if(Token == "NumParticleEmitters2")
{
Model.Data().ParticleEmitter2Container.Reserve(TokenStream.ReadInt());
if(!TokenStream.ExpectChar(',')) return FALSE;
}
else if(Token == "NumRibbonEmitters")
{
Model.Data().RibbonEmitterContainer.Reserve(TokenStream.ReadInt());
if(!TokenStream.ExpectChar(',')) return FALSE;
}
else if(Token == "BlendTime")
{
Model.Data().Info.BlendTime = TokenStream.ReadInt();
if(!TokenStream.ExpectChar(',')) return FALSE;
}
else if(Token == "MinimumExtent")
{
if(!TokenStream.ReadVector3(Model.Data().Info.Extent.Min)) return FALSE;
if(!TokenStream.ExpectChar(',')) return FALSE;
}
else if(Token == "MaximumExtent")
{
if(!TokenStream.ReadVector3(Model.Data().Info.Extent.Max)) return FALSE;
if(!TokenStream.ExpectChar(',')) return FALSE;
}
else if(Token == "BoundsRadius")
{
Model.Data().Info.Extent.Radius = TokenStream.ReadFloat();
if(!TokenStream.ExpectChar(',')) return FALSE;
}
else if(Token == "AnimationFile")
{
Model.Data().Info.AnimationFile = TokenStream.ReadString();
if(!TokenStream.ExpectChar(',')) return FALSE;
}
else
{
Error.SetMessage("Unable to load \"" + CurrentFileName + "\", unknown token \"" + Token + "\" in \"Model\"!");
return FALSE;
}
}
Error.SetMessage("Unable to load \"" + CurrentFileName + "\", unexpected EOF reached!");
return FALSE;
}
//+-----------------------------------------------------------------------------
//| Loads the model sequences
//+-----------------------------------------------------------------------------
BOOL MODEL_LOADER_MDL::LoadSequences(MODEL& Model, TOKEN_IN_STREAM& TokenStream)
{
INT NrOfSequences;
std::string Token;
MODEL_SEQUENCE* Sequence;
NrOfSequences = TokenStream.ReadInt();
if(!TokenStream.ExpectChar('{')) return FALSE;
while(!TokenStream.Eof())
{
Token = TokenStream.ReadWord();
if(Token == "") break;
if(Token == "}")
{
return TRUE;
}
else if(Token == "Anim")
{
Sequence = new MODEL_SEQUENCE();
if(Sequence == NULL)
{
Error.SetMessage("Unable to load \"" + CurrentFileName + "\", memory allocation failed!");
return FALSE;
}
if(!LoadSequence((*Sequence), TokenStream))
{
delete Sequence;
return FALSE;
}
if(!Model.AddSequence(Sequence))
{
delete Sequence;
return FALSE;
}
}
else
{
Error.SetMessage("Unable to load \"" + CurrentFileName + "\", unknown token \"" + Token + "\" in \"Sequence\"!");
return FALSE;
}
}
Error.SetMessage("Unable to load \"" + CurrentFileName + "\", unexpected EOF reached!");
return FALSE;
}
//+-----------------------------------------------------------------------------
//| Loads a model sequence
//+-----------------------------------------------------------------------------
BOOL MODEL_LOADER_MDL::LoadSequence(MODEL_SEQUENCE& Sequence, TOKEN_IN_STREAM& TokenStream)
{
std::string Token;
Sequence.Data().Name = TokenStream.ReadString();
if(!TokenStream.ExpectChar('{')) return FALSE;
while(!TokenStream.Eof())
{
Token = TokenStream.ReadWord();
if(Token == "") break;
if(Token == "}")
{
return TRUE;
}
else if(Token == "Interval")
{
if(!TokenStream.ReadVector2(Sequence.Data().Interval)) return FALSE;
if(!TokenStream.ExpectChar(',')) return FALSE;
}
else if(Token == "Rarity")
{
Sequence.Data().Rarity = TokenStream.ReadFloat();
if(!TokenStream.ExpectChar(',')) return FALSE;
}
else if(Token == "MoveSpeed")
{
Sequence.Data().MoveSpeed = TokenStream.ReadFloat();
if(!TokenStream.ExpectChar(',')) return FALSE;
}
else if(Token == "MinimumExtent")
{
if(!TokenStream.ReadVector3(Sequence.Data().Extent.Min)) return FALSE;
if(!TokenStream.ExpectChar(',')) return FALSE;
}
else if(Token == "MaximumExtent")
{
if(!TokenStream.ReadVector3(Sequence.Data().Extent.Max)) return FALSE;
if(!TokenStream.ExpectChar(',')) return FALSE;
}
else if(Token == "BoundsRadius")
{
Sequence.Data().Extent.Radius = TokenStream.ReadFloat();
if(!TokenStream.ExpectChar(',')) return FALSE;
}
else if(Token == "NonLooping,")
{
Sequence.Data().NonLooping = TRUE;
}
else
{
Error.SetMessage("Unable to load \"" + CurrentFileName + "\", unknown token \"" + Token + "\" in \"Sequences.Anim\"!");
return FALSE;
}
}
return SkipGroup(TokenStream);
}
//+-----------------------------------------------------------------------------
//| Loads the global model sequences
//+-----------------------------------------------------------------------------
BOOL MODEL_LOADER_MDL::LoadGlobalSequences(MODEL& Model, TOKEN_IN_STREAM& TokenStream)
{
INT i;
INT TempDuration;
INT NrOfGlobalSequences;
MODEL_GLOBAL_SEQUENCE* GlobalSequence;
NrOfGlobalSequences = TokenStream.ReadInt();
Model.Data().GlobalSequenceContainer.Reserve(NrOfGlobalSequences);
if(!TokenStream.ExpectChar('{')) return FALSE;
for(i = 0; i < NrOfGlobalSequences; i++)
{
if(!TokenStream.ExpectWord("Duration")) return FALSE;
TempDuration = TokenStream.ReadInt();
if(!TokenStream.ExpectChar(',')) return FALSE;
GlobalSequence = new MODEL_GLOBAL_SEQUENCE();
if(GlobalSequence == NULL)
{
Error.SetMessage("Unable to load \"" + CurrentFileName + "\", memory allocation failed!");
return FALSE;
}
GlobalSequence->Data().Duration = TempDuration;
if(!Model.AddGlobalSequence(GlobalSequence))
{
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?