⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xloadercharacter.cpp

📁 X文件读取插件
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*************************************************************************/
/*	File : XLoader.cpp				 				 					 */
/*																		 */	
/*	DirectX .X files loader												 */	
/*																		 */	
/*	Virtools SDK 														 */	 
/*	Copyright (c) Virtools 2000, All Rights Reserved.					 */	
/*************************************************************************/
#include "XLoader.h"
#include "InitGuid.h"

char *RemoveX3DS(char *name);

/* {3CF169CE-FF7C-44ab-93C0-F78F62D172E2} */
DEFINE_GUID(TID_XSkinMeshHeader,
0x3CF169CE, 0xFF7C, 0x44ab, 0x93, 0xc0, 0xF7, 0x8F, 0x62, 0xD1, 0x72, 0xE2);

/* {6F0D123B-BAD2-4167-A0D0-80224F25FABB} */
DEFINE_GUID(TID_SkinWeights,
0x6F0D123B, 0xBAD2, 0x4167, 0xA0, 0xD0, 0x80, 0x22, 0x4F, 0x25, 0xFA, 0xBB);



//********************************************************************************
//********************************************************************************
//*************** PLUGIN DECLARATION  ********************************************
//********************************************************************************
//********************************************************************************


#define X_PLUGIN_VERSION		0x0000001
#define X_READER_GUID			CKGUID(0x31011515,0x71af1e3f)
CKPluginInfo g_PluginInfos;

/*************************************************
Returns the number of plugins in this DLL (1)
**************************************************/
int 	CKGetPluginInfoCount() { 
	if (VxGetOs() == VXOS_WINNT4) return 0;
	return 1;
 }

/*************************************************
Returns info about this plugin
**************************************************/
CKPluginInfo* CKGetPluginInfo(int index)
{
	// Not Valid under Win NT 4
	if (VxGetOs() == VXOS_WINNT4) return 0;
	g_PluginInfos.m_GUID=X_READER_GUID;
	g_PluginInfos.m_Extension="X";
	g_PluginInfos.m_Description="Microsoft DirectX";
	g_PluginInfos.m_Author="Virtools";
	g_PluginInfos.m_Summary="DirectX File Reader";
	g_PluginInfos.m_Version=X_PLUGIN_VERSION;
	g_PluginInfos.m_InitInstanceFct=NULL;	// 
	g_PluginInfos.m_Type=CKPLUGIN_MODEL_READER;	// Plugin Type
	return &g_PluginInfos; 
}

CKDataReader* CKGetReader(int index)
{
	return new CKXReader();
}


//********************************************************************************
//********************************************************************************
//************* READER IMPLEMENTATION ********************************************
//********************************************************************************
//********************************************************************************

CKPluginInfo* CKXReader::GetReaderInfo() {
	return &g_PluginInfos;
}

//------- Returns the name of a LPDIRECTXFILEOBJECT 
XString GetFileObjectName(LPDIRECTXFILEOBJECT obj)
{
	if (!obj) return XString("");

	
	DWORD NameSize = 0;

	if (FAILED(obj->GetName(NULL,&NameSize)))
		return XString("");
	if (!NameSize) 
		return XString("");
	NameSize++;
	XString Temp(NameSize);
	if (FAILED(obj->GetName(Temp.Str(),&NameSize)))
		return XString("");
	return Temp;
}

/*************************************************************
 Main Loading function  
*************************************************************/
CKERROR CKXReader::Load(CKContext* context,CKSTRING FileName,CKObjectArray *array,CKDWORD LoadFlags,CKCharacter *carac)
{
	if(!array) return CKERR_INVALIDPARAMETER;
	if(!FileName) return CKERR_INVALIDPARAMETER;

	HRESULT hr = S_OK;

	m_Context = context;
	m_LoadFlags = LoadFlags;
	m_Character = carac;
	m_FileName = FileName;
	m_AnimationLength = 0;


	// Create the XFile object
	if (DXFILE_OK != DirectXFileCreate(&m_XFile)) return CKERR_NOTIMPLEMENTED;
	
	// Create the XFile enumerator
	if (FAILED(m_XFile->CreateEnumObject(FileName,DXFILELOAD_FROMFILE,&m_XFileEnumerator))) {
		CleanUp();
		return CKERR_INVALIDFILE;
	}

	// Create the exporter object
	m_VirtoolsExport = new Export2Virtools(context); 

    // Register templates for d3drm and patch extensions.
    if( FAILED( hr = m_XFile->RegisterTemplates( (VOID*)D3DRM_XTEMPLATES,
                                                 D3DRM_XTEMPLATE_BYTES ) ) )
    {
		CleanUp();
		return CKERR_INVALIDFILE;
    }	

	m_CreationOptions = CK_OBJECTCREATION_NONAMECHECK; 
	if (LoadFlags & (CK_LOAD_AS_DYNAMIC_OBJECT)) 
		 m_CreationOptions = CK_OBJECTCREATION_OPTIONS(m_CreationOptions|CK_OBJECTCREATION_DYNAMIC);
	m_VirtoolsExport->SetObjectsCreationOptions(m_CreationOptions);

	m_3dObjectsClass =  m_Character ? CKCID_BODYPART : ((m_LoadFlags & CK_LOAD_ASCHARACTER)!=0) ? CKCID_BODYPART : CKCID_3DOBJECT; 
	
	LPDIRECTXFILEDATA pXData = NULL;

    // Enumerate top level objects.
    // Top level objects are always data object.
    while (SUCCEEDED(m_XFileEnumerator->GetNextDataObject(&pXData)))
    {
        HRESULT hr = LoadFileData(pXData,NULL);
        SAFERELEASE(pXData);
    }
    if (FAILED(hr)) {
		CleanUp();
		return CKERR_INVALIDFILE;
	}
	if (m_VirtoolsExport->GetGlobalAnimation())
		m_VirtoolsExport->GetGlobalAnimation()->SetLength(m_AnimationLength);

	//---- There are some meshes without a frame 
	if (m_MeshHashTable.Size() && !m_FrameHashTable.Size()) {
		XCKObjectsHashTableIt Begin = m_MeshHashTable.Begin();
		XCKObjectsHashTableIt End = m_MeshHashTable.End();

		for (;Begin!=End;++Begin) {
			CKMesh* m = (CKMesh*)*Begin;
			CK3dEntity* NewFrame = NULL;
			if (CharacterMode()) 
				NewFrame = (CK3dEntity*)m_VirtoolsExport->AddCharacterBodyPart((char *)m->GetName());
			else 
				NewFrame = (CK3dEntity*)m_VirtoolsExport->Add3dObject((char *)m->GetName());

			NewFrame->SetCurrentMesh(m);
		}
	}

	//--- No character was given
	//--- but one should be created... 
	if (!m_Character) {
		if ((m_LoadFlags & CK_LOAD_ASCHARACTER)) {
			CKPathSplitter Splitter(FileName);
			m_VirtoolsExport->CreateCharacter(Splitter.GetName());
		}
	} 

	BOOL AnimationOnly = FALSE;
	//--- Only animations were asked...
	if ((m_LoadFlags & CK_LOAD_ANIMATION) && !(m_LoadFlags & CK_LOAD_GEOMETRY)) {
		// we are loading animations and need to find the entities
		// to which they apply
		m_VirtoolsExport->ResolveAnimationsTargets(m_Character);
		AnimationOnly = TRUE;
	}

	//-- Generate the list of objects in the array
	m_VirtoolsExport->GenerateObjects(array,AnimationOnly);

	return CK_OK;
}

#define RELEASEEXIT(ErrorCode,ToRelease) {\
SAFERELEASE(ToRelease);\
return ErrorCode;\
}\


/*********************************************
 Loads a 3DEntity transformation Matrix
*********************************************/
HRESULT CKXReader::LoadTransformationMatrix(LPDIRECTXFILEDATA CurData,CK3dEntity* Parent)
{
	VxMatrix* Mat;
	DWORD Size = 0;

    HRESULT hr = CurData->GetData(NULL, &Size, (void **)&Mat);
	if (SUCCEEDED(hr) && Parent) {
		Parent->SetLocalMatrix(*Mat,TRUE);
	}
	return hr;
}

/***************************************************************
 Loads a material (reference or data) and returns a pointer
 to the created CKMaterial
**************************************************************/
CKMaterial* CKXReader::LoadMaterial(LPDIRECTXFILEOBJECT CurObject)
{
	HRESULT hr = S_OK;
	CKMaterial* Material =  NULL; 

	if (m_LoadFlags & CK_LOAD_GEOMETRY) {
		LPDIRECTXFILEDATA CurData = NULL;
		LPDIRECTXFILEDATAREFERENCE CurDataRef = NULL;

		XString MaterialName = GetFileObjectName(CurObject);

		// Reference or data ? 
		if (SUCCEEDED(CurObject->QueryInterface(IID_IDirectXFileDataReference,(LPVOID *)&CurDataRef))) {
			// REFERENCE : we find the material from its name and return it
			
			if (SUCCEEDED(CurDataRef->Resolve(&CurData))) {
				MaterialName = GetFileObjectName(CurData);
				XCKObjectsHashTableIt it=m_MaterialHashTable.Find(MaterialName);
				Material = (it==m_MaterialHashTable.End()) ? NULL : (CKMaterial*)*it;
				SAFERELEASE(CurData);
			}
			SAFERELEASE(CurDataRef);
		}  else 
		if (SUCCEEDED(CurObject->QueryInterface(IID_IDirectXFileData,(LPVOID *)&CurData))) {
			// DATA : we have to create a material 

			VxColor*	Diffuse = 0;
			float*		Power = 0;
			VxColor*	Specular = 0;
			VxColor*	Emissive = 0;
			DWORD		Size = 0;

			//-- Load material data (if some of them are not here we fail...)
			if (FAILED(hr = CurData->GetData("faceColor",&Size, (void **)&Diffuse)))	RELEASEEXIT(NULL,CurData);
			if (FAILED(hr = CurData->GetData("power",&Size, (void **)&Power)))			RELEASEEXIT(NULL,CurData);
			if (FAILED(hr = CurData->GetData("specularColor",&Size, (void **)&Specular))) RELEASEEXIT(NULL,CurData);
			if (FAILED(hr = CurData->GetData("emissiveColor",&Size, (void **)&Emissive)))	RELEASEEXIT(NULL,CurData);
			

			//-- Copy the loaded material settings into a VirtoolsMat
			VirtoolsMaterial VirtoolsMat;
			XString TextureFileName;
			VirtoolsMat.m_Specular.a = 0;
			VirtoolsMat.m_Emissive.a = 0;
			VirtoolsMat.m_Diffuse = *Diffuse;
			memcpy(&VirtoolsMat.m_Specular,Specular,3*sizeof(float));
			memcpy(&VirtoolsMat.m_Emissive,Emissive,3*sizeof(float));
			VirtoolsMat.m_SpecularPower = *Power;
			
			//-- Transparent Material
			if (VirtoolsMat.m_Diffuse.a < 1.0f) {
				VirtoolsMat.m_AlphaBlending		= TRUE;
				VirtoolsMat.m_SrcBlendFactor	= VXBLEND_SRCALPHA;
				VirtoolsMat.m_DstBlendFactor	= VXBLEND_INVSRCALPHA;
				VirtoolsMat.m_ZWriteEnable		= FALSE;
			}

			//------- Is There a texture ? -------------
			LPDIRECTXFILEOBJECT	NextObject = NULL;
			LPDIRECTXFILEDATA	NextData = NULL;
			if (SUCCEEDED(CurData->GetNextObject(&NextObject)))  {
				if SUCCEEDED(NextObject->QueryInterface(IID_IDirectXFileData,(LPVOID *)&NextData)) {
					const GUID* DataType = NULL;
					if (SUCCEEDED(NextData->GetType(&DataType))) {
						if (TID_D3DRMTextureFilename == *DataType) {
							char** String = NULL;
							DWORD DataSize;
							if (SUCCEEDED(NextData->GetData("filename",&DataSize,(void**)&String))) {
								// Yes ! there is a texture : try to load it...
								if (String && *String) {
									TextureFileName = *String;
									VirtoolsMat.m_Texture = m_VirtoolsExport->AddTexture(*String,*String);
								}
							}
						}
					}
					SAFERELEASE(NextData);
				}
				SAFERELEASE(NextObject);
			}

			// Rename the material if necessary
			if (MaterialName=="") MaterialName = GetUnnamed();


			// If a material with this name already exists we 
			// compare the existing one parameters

⌨️ 快捷键说明

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