modelloadermdl.cpp

来自「骨骼动画....把魔兽模型解出的代码..」· C++ 代码 · 共 2,345 行 · 第 1/5 页

CPP
2,345
字号
//+-----------------------------------------------------------------------------
//| Included files
//+-----------------------------------------------------------------------------
#include "ModelLoaderMdl.h"


//+-----------------------------------------------------------------------------
//| Global objects
//+-----------------------------------------------------------------------------
MODEL_LOADER_MDL ModelLoaderMdl;


//+-----------------------------------------------------------------------------
//| Constructor
//+-----------------------------------------------------------------------------
MODEL_LOADER_MDL::MODEL_LOADER_MDL()
{
	RegisterMdlLoader("Version", LoadVersion);
	RegisterMdlLoader("Model", LoadModel);
	RegisterMdlLoader("Sequences", LoadSequences);
	RegisterMdlLoader("GlobalSequences", LoadGlobalSequences);
	RegisterMdlLoader("Textures", LoadTextures);
	RegisterMdlLoader("Materials", LoadMaterials);
	RegisterMdlLoader("TextureAnims", LoadTextureAnimations);
	RegisterMdlLoader("Geoset", LoadGeosets);
	RegisterMdlLoader("GeosetAnim", LoadGeosetAnimations);
	RegisterMdlLoader("Bone", LoadBones);
	RegisterMdlLoader("Light", LoadLights);
	RegisterMdlLoader("Helper", LoadHelpers);
	RegisterMdlLoader("Attachment", LoadAttachments);
	RegisterMdlLoader("PivotPoints", LoadPivotPoints);
	RegisterMdlLoader("ParticleEmitter", LoadParticleEmitters);
	RegisterMdlLoader("ParticleEmitter2", LoadParticleEmitters2);
	RegisterMdlLoader("RibbonEmitter", LoadRibbonEmitters);
	RegisterMdlLoader("EventObject", LoadEventObjects);
	RegisterMdlLoader("Camera", LoadCameras);
	RegisterMdlLoader("CollisionShape", LoadCollisionShapes);
}


//+-----------------------------------------------------------------------------
//| Destructor
//+-----------------------------------------------------------------------------
MODEL_LOADER_MDL::~MODEL_LOADER_MDL()
{
	MdlLoaderMap.clear();
}


//+-----------------------------------------------------------------------------
//| Saves a model to a buffer
//+-----------------------------------------------------------------------------
BOOL MODEL_LOADER_MDL::Save(MODEL& Model, CONST std::string& FileName, BUFFER& Buffer)
{
	TOKEN_OUT_STREAM TokenStream;

	CurrentFileName = FileName;
	TokenStream.SetFileName(FileName);

	Model.GenerateObjectIds();
	Model.WrapPivotPoints();

	if(!SaveVersion(Model, TokenStream)) return FALSE;
	if(!SaveModel(Model, TokenStream)) return FALSE;
	if(!SaveSequences(Model, TokenStream)) return FALSE;
	if(!SaveGlobalSequences(Model, TokenStream)) return FALSE;
	if(!SaveTextures(Model, TokenStream)) return FALSE;
	if(!SaveMaterials(Model, TokenStream)) return FALSE;
	if(!SaveTextureAnimations(Model, TokenStream)) return FALSE;
	if(!SaveGeosets(Model, TokenStream)) return FALSE;
	if(!SaveGeosetAnimations(Model, TokenStream)) return FALSE;
	if(!SaveBones(Model, TokenStream)) return FALSE;
	if(!SaveLights(Model, TokenStream)) return FALSE;
	if(!SaveHelpers(Model, TokenStream)) return FALSE;
	if(!SaveAttachments(Model, TokenStream)) return FALSE;
	if(!SavePivotPoints(Model, TokenStream)) return FALSE;
	if(!SaveParticleEmitters(Model, TokenStream)) return FALSE;
	if(!SaveParticleEmitters2(Model, TokenStream)) return FALSE;
	if(!SaveRibbonEmitters(Model, TokenStream)) return FALSE;
	if(!SaveEventObjects(Model, TokenStream)) return FALSE;
	if(!SaveCameras(Model, TokenStream)) return FALSE;
	if(!SaveCollisionShapes(Model, TokenStream)) return FALSE;

	if(!TokenStream.Save(Buffer)) return FALSE;

	return TRUE;
}


//+-----------------------------------------------------------------------------
//| Loads a model from a buffer
//+-----------------------------------------------------------------------------
BOOL MODEL_LOADER_MDL::Load(MODEL& Model, CONST std::string& FileName, BUFFER& Buffer)
{
	std::string Token;
	TOKEN_IN_STREAM TokenStream;
	std::map<std::string, MDL_LOADER>::iterator i;

	CurrentFileName = FileName;
	TokenStream.SetFileName(FileName);

	if(!TokenStream.Load(Buffer)) return FALSE;

	while(!TokenStream.Eof())
	{
		Token = TokenStream.ReadWord();

		Common.RemoveWhiteSpace(Token);
		if(Token == "") break;

		i = MdlLoaderMap.find(Token);
		if(i == MdlLoaderMap.end())
		{
			Error.SetMessage("Unable to load \"" + FileName + "\", unknown group \"" + Token + "\"!");
			return FALSE;
		}

		TokenStream.SetGroup(Token);
		if(!(i->second(Model, TokenStream))) return FALSE;
	}

	Model.ConnectNodes();
	Model.UnwrapPivotPoints();

	return TRUE;
}


//+-----------------------------------------------------------------------------
//| Registers an mdl loader
//+-----------------------------------------------------------------------------
VOID MODEL_LOADER_MDL::RegisterMdlLoader(CONST std::string& Name, MDL_LOADER Loader)
{
	MdlLoaderMap.insert(std::make_pair(Name, Loader));
}


//+-----------------------------------------------------------------------------
//| Saves the model version
//+-----------------------------------------------------------------------------
BOOL MODEL_LOADER_MDL::SaveVersion(MODEL& Model, TOKEN_OUT_STREAM& TokenStream)
{
	TokenStream.WriteLine("//+-----------------------------------------------------------------------------");
	TokenStream.WriteLine("//| " + Common.GetFileName(CurrentFileName));
	TokenStream.WriteLine("//| Generated by " + EDITOR_NAME);
	TokenStream.WriteLine("//| " + GetCurrentDate());
	TokenStream.WriteLine("//| http://Magos.TheJeffFiles.com/War3ModelEditor/");
	TokenStream.WriteLine("//+-----------------------------------------------------------------------------");

	TokenStream.WriteLine("Version {");
	TokenStream.WriteTab();
	TokenStream.WriteWord("FormatVersion ");
	TokenStream.WriteInt(Model.Data().Info.Version);
	TokenStream.WriteLine(",");
	TokenStream.WriteLine("}");

	return TRUE;
}


//+-----------------------------------------------------------------------------
//| Saves the model info
//+-----------------------------------------------------------------------------
BOOL MODEL_LOADER_MDL::SaveModel(MODEL& Model, TOKEN_OUT_STREAM& TokenStream)
{
	TokenStream.WriteWord("Model ");
	TokenStream.WriteString(Model.Data().Info.Name);
	TokenStream.WriteLine(" {");

	if(Model.Data().GeosetContainer.GetSize() > 0)
	{
		TokenStream.WriteTab();
		TokenStream.WriteWord("NumGeosets ");
		TokenStream.WriteInt(Model.Data().GeosetContainer.GetSize());
		TokenStream.WriteLine(",");
	}

	if(Model.Data().GeosetAnimationContainer.GetSize() > 0)
	{
		TokenStream.WriteTab();
		TokenStream.WriteWord("NumGeosetAnims ");
		TokenStream.WriteInt(Model.Data().GeosetAnimationContainer.GetSize());
		TokenStream.WriteLine(",");
	}

	if(Model.Data().HelperContainer.GetSize() > 0)
	{
		TokenStream.WriteTab();
		TokenStream.WriteWord("NumHelpers ");
		TokenStream.WriteInt(Model.Data().HelperContainer.GetSize());
		TokenStream.WriteLine(",");
	}

	if(Model.Data().BoneContainer.GetSize() > 0)
	{
		TokenStream.WriteTab();
		TokenStream.WriteWord("NumBones ");
		TokenStream.WriteInt(Model.Data().BoneContainer.GetSize());
		TokenStream.WriteLine(",");
	}

	if(Model.Data().LightContainer.GetSize() > 0)
	{
		TokenStream.WriteTab();
		TokenStream.WriteWord("NumLights ");
		TokenStream.WriteInt(Model.Data().LightContainer.GetSize());
		TokenStream.WriteLine(",");
	}

	if(Model.Data().AttachmentContainer.GetSize() > 0)
	{
		TokenStream.WriteTab();
		TokenStream.WriteWord("NumAttachments ");
		TokenStream.WriteInt(Model.Data().AttachmentContainer.GetSize());
		TokenStream.WriteLine(",");
	}

	if(Model.Data().EventObjectContainer.GetSize() > 0)
	{
		TokenStream.WriteTab();
		TokenStream.WriteWord("NumEvents ");
		TokenStream.WriteInt(Model.Data().EventObjectContainer.GetSize());
		TokenStream.WriteLine(",");
	}

	if(Model.Data().ParticleEmitterContainer.GetSize() > 0)
	{
		TokenStream.WriteTab();
		TokenStream.WriteWord("NumParticleEmitters ");
		TokenStream.WriteInt(Model.Data().ParticleEmitterContainer.GetSize());
		TokenStream.WriteLine(",");
	}

	if(Model.Data().ParticleEmitter2Container.GetSize() > 0)
	{
		TokenStream.WriteTab();
		TokenStream.WriteWord("NumParticleEmitters2 ");
		TokenStream.WriteInt(Model.Data().ParticleEmitter2Container.GetSize());
		TokenStream.WriteLine(",");
	}

	if(Model.Data().RibbonEmitterContainer.GetSize() > 0)
	{
		TokenStream.WriteTab();
		TokenStream.WriteWord("NumRibbonEmitters ");
		TokenStream.WriteInt(Model.Data().RibbonEmitterContainer.GetSize());
		TokenStream.WriteLine(",");
	}

	TokenStream.WriteTab();
	TokenStream.WriteWord("BlendTime ");
	TokenStream.WriteInt(Model.Data().Info.BlendTime);
	TokenStream.WriteLine(",");

	if(Model.Data().Info.Extent.Min != D3DXVECTOR3(0.0f, 0.0f, 0.0f))
	{
		TokenStream.WriteTab();
		TokenStream.WriteWord("MinimumExtent ");
		TokenStream.WriteVector3(Model.Data().Info.Extent.Min);
		TokenStream.WriteLine(",");
	}

	if(Model.Data().Info.Extent.Max != D3DXVECTOR3(0.0f, 0.0f, 0.0f))
	{
		TokenStream.WriteTab();
		TokenStream.WriteWord("MaximumExtent ");
		TokenStream.WriteVector3(Model.Data().Info.Extent.Max);
		TokenStream.WriteLine(",");
	}

	if(Model.Data().Info.Extent.Radius > 0.0f)
	{
		TokenStream.WriteTab();
		TokenStream.WriteWord("BoundsRadius ");
		TokenStream.WriteFloat(Model.Data().Info.Extent.Radius);
		TokenStream.WriteLine(",");
	}

	if(Model.Data().Info.AnimationFile != "")
	{
		TokenStream.WriteTab();
		TokenStream.WriteWord("AnimationFile ");
		TokenStream.WriteString(Model.Data().Info.AnimationFile);
		TokenStream.WriteLine(",");
	}

	TokenStream.WriteLine("}");

	return TRUE;
}


//+-----------------------------------------------------------------------------
//| Saves the model sequences
//+-----------------------------------------------------------------------------
BOOL MODEL_LOADER_MDL::SaveSequences(MODEL& Model, TOKEN_OUT_STREAM& TokenStream)
{
	INT i;

	if(Model.Data().SequenceContainer.GetSize() <= 0) return TRUE;

	TokenStream.WriteWord("Sequences ");
	TokenStream.WriteInt(Model.Data().SequenceContainer.GetSize());
	TokenStream.WriteLine(" {");

	for(i = 0; i < Model.Data().SequenceContainer.GetTotalSize(); i++)
	{
		if(Model.Data().SequenceContainer.ValidIndex(i))
		{
			if(!SaveSequence(*(Model.Data().SequenceContainer[i]), TokenStream)) return FALSE;
		}
	}

	TokenStream.WriteLine("}");

	return TRUE;
}


//+-----------------------------------------------------------------------------
//| Saves a model sequence
//+-----------------------------------------------------------------------------
BOOL MODEL_LOADER_MDL::SaveSequence(MODEL_SEQUENCE& Sequence, TOKEN_OUT_STREAM& TokenStream)
{
	TokenStream.WriteTab();
	TokenStream.WriteWord("Anim ");
	TokenStream.WriteString(Sequence.Data().Name);
	TokenStream.WriteLine(" {");

	TokenStream.WriteTab(2);
	TokenStream.WriteWord("Interval ");
	TokenStream.WriteVector2(Sequence.Data().Interval);
	TokenStream.WriteLine(",");

	if(Sequence.Data().Rarity != 0.0f)
	{
		TokenStream.WriteTab(2);
		TokenStream.WriteWord("Rarity ");
		TokenStream.WriteFloat(Sequence.Data().Rarity);
		TokenStream.WriteLine(",");
	}

	if(Sequence.Data().MoveSpeed != 0.0f)
	{
		TokenStream.WriteTab(2);
		TokenStream.WriteWord("MoveSpeed ");
		TokenStream.WriteFloat(Sequence.Data().MoveSpeed);
		TokenStream.WriteLine(",");
	}

	if(Sequence.Data().NonLooping)
	{
		TokenStream.WriteTab(2);
		TokenStream.WriteLine("NonLooping,");
	}

	if(Sequence.Data().Extent.Min != D3DXVECTOR3(0.0f, 0.0f, 0.0f))
	{
		TokenStream.WriteTab(2);
		TokenStream.WriteWord("MinimumExtent ");
		TokenStream.WriteVector3(Sequence.Data().Extent.Min);
		TokenStream.WriteLine(",");
	}

	if(Sequence.Data().Extent.Max != D3DXVECTOR3(0.0f, 0.0f, 0.0f))
	{
		TokenStream.WriteTab(2);
		TokenStream.WriteWord("MaximumExtent ");
		TokenStream.WriteVector3(Sequence.Data().Extent.Max);
		TokenStream.WriteLine(",");
	}

	if(Sequence.Data().Extent.Radius > 0.0f)
	{
		TokenStream.WriteTab(2);
		TokenStream.WriteWord("BoundsRadius ");
		TokenStream.WriteFloat(Sequence.Data().Extent.Radius);
		TokenStream.WriteLine(",");
	}

	TokenStream.WriteTab();
	TokenStream.WriteLine("}");

	return TRUE;
}


//+-----------------------------------------------------------------------------
//| Saves the global model sequences
//+-----------------------------------------------------------------------------
BOOL MODEL_LOADER_MDL::SaveGlobalSequences(MODEL& Model, TOKEN_OUT_STREAM& TokenStream)
{
	INT i;

	if(Model.Data().GlobalSequenceContainer.GetSize() <= 0) return TRUE;

	TokenStream.WriteWord("GlobalSequences ");
	TokenStream.WriteInt(Model.Data().GlobalSequenceContainer.GetSize());
	TokenStream.WriteLine(" {");

	for(i = 0; i < Model.Data().GlobalSequenceContainer.GetTotalSize(); i++)
	{
		if(Model.Data().GlobalSequenceContainer.ValidIndex(i))
		{
			TokenStream.WriteTab();
			TokenStream.WriteWord("Duration ");
			TokenStream.WriteInt(Model.Data().GlobalSequenceContainer[i]->Data().Duration);
			TokenStream.WriteLine(",");
		}
	}

	TokenStream.WriteLine("}");

	return TRUE;
}


//+-----------------------------------------------------------------------------
//| Saves the model textures
//+-----------------------------------------------------------------------------
BOOL MODEL_LOADER_MDL::SaveTextures(MODEL& Model, TOKEN_OUT_STREAM& TokenStream)
{
	INT i;

	if(Model.Data().TextureContainer.GetSize() <= 0) return TRUE;

	TokenStream.WriteWord("Textures ");
	TokenStream.WriteInt(Model.Data().TextureContainer.GetSize());
	TokenStream.WriteLine(" {");

	for(i = 0; i < Model.Data().TextureContainer.GetTotalSize(); i++)
	{
		if(Model.Data().TextureContainer.ValidIndex(i))
		{
			if(!SaveTexture(*(Model.Data().TextureContainer[i]), TokenStream)) return FALSE;
		}
	}

	TokenStream.WriteLine("}");

	return TRUE;
}


//+-----------------------------------------------------------------------------
//| Saves a model texture
//+-----------------------------------------------------------------------------
BOOL MODEL_LOADER_MDL::SaveTexture(MODEL_TEXTURE& Texture, TOKEN_OUT_STREAM& TokenStream)
{
	TokenStream.WriteTab();
	TokenStream.WriteLine("Bitmap {");

	TokenStream.WriteTab(2);
	TokenStream.WriteWord("Image ");
	TokenStream.WriteString(Texture.Data().FileName);
	TokenStream.WriteLine(",");

	if(Texture.Data().ReplaceableId > 0)
	{
		TokenStream.WriteTab(2);
		TokenStream.WriteWord("ReplaceableId ");
		TokenStream.WriteInt(Texture.Data().ReplaceableId);
		TokenStream.WriteLine(",");
	}

	if(Texture.Data().WrapWidth)
	{
		TokenStream.WriteTab(2);
		TokenStream.WriteLine("WrapWidth,");

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?