📄 xloadercharacter.cpp
字号:
/*************************************************************************/
/* 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 + -