📄 xloadercharacter.cpp
字号:
if (TID_D3DRMMeshNormals == *DataType) {
//****** Load material list
LoadMeshNormals(NextData,&TransitionMesh);
} else
if (TID_SkinWeights == *DataType) {
//----- To load the skin data we need to
//----- have the appropriate number of
//----- virtools vertices computed
if (!Generated) {
TransitionMesh.GenerateVirtoolsData();
Generated = TRUE;
}
//****** Load bone info
LoadSkinBone(NextData,&TransitionMesh,Parent);
} else
if (TID_XSkinMeshHeader == *DataType) {
// No need to load this
}
}
SAFERELEASE(NextData);
}
SAFERELEASE(NextObject);
}
// Rename the mesh if necessary
if (MeshName=="")
if (Parent) {
MeshName = Parent->GetName();
MeshName << "_Mesh";
} else {
MeshName << GetUnnamed();
}
if (!Generated)
TransitionMesh.GenerateVirtoolsData();
// And finally create the mesh
CKMesh* Mesh = m_VirtoolsExport->AddMesh(&TransitionMesh,MeshName.CStr());
m_MeshHashTable.Insert(MeshName,Mesh);
if (Parent) {
if (Parent->GetMeshCount()) {
// A mesh has already been set on this entity
// we need to create a new frame to hold this one
CK3dEntity* NewFrame = NULL;
if (CharacterMode())
NewFrame = (CK3dEntity*)m_VirtoolsExport->AddCharacterBodyPart(MeshName.CStr());
else
NewFrame = (CK3dEntity*)m_VirtoolsExport->Add3dObject(MeshName.CStr());
NewFrame->SetParent(Parent,FALSE);
NewFrame->SetCurrentMesh(Mesh);
} else {
Parent->SetCurrentMesh(Mesh);
}
}
SAFERELEASE(CurData);
}
}
return hr;
}
/***************************************************
Loads an animation Set (group of sub animations)
****************************************************/
HRESULT CKXReader::LoadAnimationSet(LPDIRECTXFILEDATA CurData)
{
HRESULT hr = S_OK;
XString AnimationName = GetFileObjectName(CurData);
if (AnimationName=="") {
CKPathSplitter Splitter(m_FileName.Str());
AnimationName = Splitter.GetName();
}
m_VirtoolsExport->CreateGlobalAnimation(AnimationName.Str());
LPDIRECTXFILEDATA NextData = NULL;
LPDIRECTXFILEOBJECT NextObject = NULL;
// Enumerate child objects. (We're expecting to find animations
while (SUCCEEDED(CurData->GetNextObject(&NextObject))) {
// Query the child for it's FileData
if SUCCEEDED(NextObject->QueryInterface(IID_IDirectXFileData,(LPVOID *)&NextData)) {
const GUID* DataType = NULL;
if (SUCCEEDED(NextData->GetType(&DataType))) {
if (TID_D3DRMAnimation == *DataType) {
hr = LoadAnimation(NextData);
}
}
SAFERELEASE(NextData);
}
SAFERELEASE(NextObject);
}
return hr;
}
/**************************************************************
+ Adds a list of position keys to the animation
+ Only linear animation are supported in .x files so we directly
use the CKObjectAnimation AddPosition method instead of using CKAnimController
******************************************************************/
void CKXReader::LoadAnimationPositionKey(CKObjectAnimation* anim,DWORD KeyCount,DWORD* keys)
{
XFileVectorKey* vkeys = (XFileVectorKey*)keys;
for (DWORD i = 0; i< KeyCount; ++i,++vkeys) {
m_AnimationLength = max (m_AnimationLength,(float)vkeys->Time);
anim->AddPositionKey((float)vkeys->Time,&vkeys->Key);
}
}
/**************************************************************
+ Adds a list of rotation keys to the animation
+ Only linear animation are supported in .x files so we directly
use the CKObjectAnimation AddRtoationKey method instead of using CKAnimController
+ Warning .X file store quaternions in this order : w,x,y,z
******************************************************************/
void CKXReader::LoadAnimationRotationKey(CKObjectAnimation* anim,DWORD KeyCount,DWORD* keys)
{
XFileRotateKey* rkeys = (XFileRotateKey*)keys;
for (DWORD i = 0; i< KeyCount; ++i,++rkeys) {
m_AnimationLength = max (m_AnimationLength,(float)rkeys->Time);
VxQuaternion quat(rkeys->x,rkeys->y,rkeys->z,rkeys->w);
anim->AddRotationKey((float)rkeys->Time,&quat);
}
}
/**************************************************************
+ Adds a list of scale keys to the animation
+ Only linear animation are supported in .x files so we directly
use the CKObjectAnimation AddScaleKey method instead of using CKAnimController
******************************************************************/
void CKXReader::LoadAnimationScaleKey(CKObjectAnimation* anim,DWORD KeyCount,DWORD* keys)
{
XFileVectorKey* vkeys = (XFileVectorKey*)keys;
for (DWORD i = 0; i< KeyCount; ++i,++vkeys) {
m_AnimationLength = max (m_AnimationLength,(float)vkeys->Time);
anim->AddScaleKey((float)vkeys->Time,&vkeys->Key);
}
}
/**************************************************************
+ Adds a list of matrix keys to the animation
+ Matrix keys need to be converted to standard PRS keys
*****************************************************************/
void CKXReader::LoadAnimationMatrixKey(CKObjectAnimation* anim,DWORD KeyCount,DWORD* keys)
{
XFileMatrixKey* mkeys = (XFileMatrixKey*)keys;
for (DWORD i = 0; i< KeyCount; ++i,++mkeys) {
m_AnimationLength = max (m_AnimationLength,(float)mkeys->Time);
float time = (float)mkeys->Time;
VxMatrix Mat = mkeys->Key;
VxQuaternion q,qs;
VxVector p,s;
Vx3DDecomposeMatrixTotal(Mat,q,p,s,qs);
anim->AddRotationKey(time,&q);
anim->AddScaleKey(time,&s);
anim->AddPositionKey(time,&p);
// Matrix (especially coming from bipeds) may contain some shearing)
anim->AddScaleAxisKey(time,&qs);
}
}
/*********************************************************
***********************************************************/
HRESULT CKXReader::LoadAnimation(LPDIRECTXFILEDATA CurData)
{
LPDIRECTXFILEDATA NextData = NULL;
LPDIRECTXFILEDATAREFERENCE NextDataRef = NULL;
LPDIRECTXFILEOBJECT NextObject = NULL;
XString EntityName="";
CK3dEntity* Entity = NULL;
CKObjectAnimation* Animation = (CKObjectAnimation*)m_Context->CreateObject(CKCID_OBJECTANIMATION,NULL,m_CreationOptions);
// Enumerate child objects. (We're expecting to find animation keys and a reference
// to the animated frame
while (SUCCEEDED(CurData->GetNextObject(&NextObject))) {
// Query the child for it's FileData
if SUCCEEDED(NextObject->QueryInterface(IID_IDirectXFileData,(LPVOID *)&NextData)) {
const GUID* DataType = NULL;
// Enemerate animation keys
if (SUCCEEDED(NextData->GetType(&DataType))) {
if (TID_D3DRMAnimationKey == *DataType) {
DWORD* keyType = NULL;
DWORD* nKeys = NULL;
DWORD* keys = NULL;
DWORD Size;
NextData->GetData("keyType",&Size, (void **)&keyType);
NextData->GetData("nKeys",&Size, (void **)&nKeys);
NextData->GetData("keys",&Size, (void **)&keys);
if (*nKeys) {
switch (*keyType) {
case 0:LoadAnimationRotationKey(Animation,*nKeys,keys); break;
case 1:LoadAnimationScaleKey(Animation,*nKeys,keys); break;
case 2:LoadAnimationPositionKey(Animation,*nKeys,keys); break;
case 4:LoadAnimationMatrixKey(Animation,*nKeys,keys); break;
}
}
}
}
SAFERELEASE(NextData);
} else
if SUCCEEDED(NextObject->QueryInterface(IID_IDirectXFileDataReference,(LPVOID *)&NextDataRef)) {
//--- Get the reference to the target frame
if (SUCCEEDED(NextDataRef->Resolve(&NextData))) {
EntityName = GetFileObjectName(NextData);
XCKObjectsHashTableIt it=m_FrameHashTable.Find(EntityName);
Entity = (it==m_FrameHashTable.End()) ? NULL : (CK3dEntity*)*it;
SAFERELEASE(NextData);
}
SAFERELEASE(NextDataRef);
}
SAFERELEASE(NextObject);
}
//----------------------
//-- Set the target entity and add to exporter
Animation->SetName(EntityName.Str());
Animation->Set3dEntity(Entity);
m_VirtoolsExport->AddObjectAnimation(Animation);
return S_OK;
}
/*********************************************
Loads top level file data (frame , mesh,material,animation sets,etc..)
*********************************************/
HRESULT CKXReader::LoadFileData(LPDIRECTXFILEDATA CurData,CK3dEntity* Parent)
{
HRESULT hr = S_OK;
const GUID* DataType;
// Get the type of the object
hr = CurData->GetType(&DataType);
if (FAILED(hr)) return hr;
if (TID_D3DRMMaterial == *DataType) {
if (m_LoadFlags & CK_LOAD_GEOMETRY) {
LoadMaterial(CurData);
}
} else
if (TID_D3DRMMesh == *DataType) {
if (m_LoadFlags & CK_LOAD_GEOMETRY) {
hr = LoadMesh(CurData,Parent);
}
} else
if (TID_D3DRMFrameTransformMatrix == *DataType) {
if (m_LoadFlags & CK_LOAD_GEOMETRY) {
hr = LoadTransformationMatrix(CurData,Parent);
}
} else
if (TID_D3DRMAnimationSet == *DataType) {
hr = LoadAnimationSet(CurData);
} else
if (TID_D3DRMAnimation == *DataType) {
hr = LoadAnimation(CurData);
} else
if (TID_D3DRMFrame == *DataType) {
//------ A child frame -------
LPDIRECTXFILEDATA NextData = NULL;
LPDIRECTXFILEOBJECT NextObject = NULL;
CK3dEntity* NewFrame = NULL;
if (m_LoadFlags & CK_LOAD_GEOMETRY) {
XString FrameName = GetFileObjectName(CurData);
if (CharacterMode())
NewFrame = (CK3dEntity*)m_VirtoolsExport->AddCharacterBodyPart(FrameName.Str());
else
NewFrame = (CK3dEntity*)m_VirtoolsExport->Add3dObject(FrameName.Str());
m_FrameHashTable.Insert(FrameName,NewFrame);
NewFrame->SetParent(Parent);
}
// Enumerate child objects.
while (SUCCEEDED(CurData->GetNextObject(&NextObject))) {
// Query the child for it's FileData
if (SUCCEEDED(NextObject->QueryInterface(IID_IDirectXFileData,(LPVOID *)&NextData))) {
LoadFileData(NextData,NewFrame);
SAFERELEASE(NextData);
}
SAFERELEASE(NextObject);
}
} else {
// Unsuported Data Type
hr = S_OK;
}
return hr;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -