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 + -
显示快捷键?