📄 mload.cpp
字号:
//-----------------------------------------------------------------------------
// File: mload.cpp
//
// Copyright (c) 1999-2000 Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#include <windows.h>
#include <mmsystem.h>
#include <objbase.h>
#include <malloc.h> // _alloca
#include <stdio.h>
#include <d3d8.h>
#include <d3dx8.h>
#include "rmxfguid.h"
#include "rmxftmpl.h"
#include "eb_effect.h"
#include "shader_PaletteSkin.h"
HRESULT CalculateSum(SFrame *pframe, D3DXMATRIX *pmatCur, D3DXVECTOR3 *pvCenter,
UINT *pcVertices)
{
HRESULT hr = S_OK;
PBYTE pbPoints = NULL;
UINT cVerticesLocal = 0;
PBYTE pbCur;
D3DXVECTOR3 *pvCur;
D3DXVECTOR3 vTransformedCur;
UINT iPoint;
SMeshContainer *pmcCur;
SFrame *pframeCur;
UINT cVertices;
D3DXMATRIX matLocal;
D3DXMatrixMultiply(&matLocal, &pframe->matRot, pmatCur);
pmcCur = pframe->pmcMesh;
while (pmcCur != NULL)
{
DWORD fvfsize = D3DXGetFVFVertexSize(pmcCur->pMesh->GetFVF());
cVertices = pmcCur->pMesh->GetNumVertices();
hr = pmcCur->pMesh->LockVertexBuffer(0, &pbPoints);
if (FAILED(hr))
goto e_Exit;
for( iPoint=0, pbCur = pbPoints; iPoint < cVertices; iPoint++, pbCur += fvfsize)
{
pvCur = (D3DXVECTOR3*)pbCur;
if ((pvCur->x != 0.0) || (pvCur->y != 0.0) || (pvCur->z != 0.0))
{
cVerticesLocal++;
D3DXVec3TransformCoord(&vTransformedCur, pvCur, &matLocal);
pvCenter->x += vTransformedCur.x;
pvCenter->y += vTransformedCur.y;
pvCenter->z += vTransformedCur.z;
}
}
pmcCur->pMesh->UnlockVertexBuffer();
pbPoints = NULL;
pmcCur = pmcCur->pmcNext;
}
*pcVertices += cVerticesLocal;
pframeCur = pframe->pframeFirstChild;
while (pframeCur != NULL)
{
hr = CalculateSum(pframeCur, &matLocal, pvCenter, pcVertices);
if (FAILED(hr))
goto e_Exit;
pframeCur = pframeCur->pframeSibling;
}
e_Exit:
if (pbPoints != NULL)
{
pmcCur->pMesh->UnlockVertexBuffer();
}
return hr;
}
HRESULT CalculateRadius(SFrame *pframe, D3DXMATRIX *pmatCur, D3DXVECTOR3 *pvCenter,
float *pfRadiusSq)
{
HRESULT hr = S_OK;
PBYTE pbPoints = NULL;
PBYTE pbCur;
D3DXVECTOR3 *pvCur;
D3DXVECTOR3 vDist;;
UINT iPoint;
UINT cVertices;
SMeshContainer *pmcCur;
SFrame *pframeCur;
float fRadiusLocalSq;
float fDistSq;
D3DXMATRIX matLocal;
D3DXMatrixMultiply(&matLocal, &pframe->matRot, pmatCur);
pmcCur = pframe->pmcMesh;
fRadiusLocalSq = *pfRadiusSq;
while (pmcCur != NULL)
{
DWORD fvfsize = D3DXGetFVFVertexSize(pmcCur->pMesh->GetFVF());
cVertices = pmcCur->pMesh->GetNumVertices();
hr = pmcCur->pMesh->LockVertexBuffer(0, &pbPoints);
if (FAILED(hr))
goto e_Exit;
for( iPoint=0, pbCur = pbPoints; iPoint < cVertices; iPoint++, pbCur += fvfsize )
{
pvCur = (D3DXVECTOR3*)pbCur;
if ((pvCur->x == 0.0) && (pvCur->y == 0.0) && (pvCur->z == 0.0))
continue;
D3DXVec3TransformCoord(&vDist, pvCur, &matLocal);
vDist -= *pvCenter;
fDistSq = D3DXVec3LengthSq(&vDist);
if( fDistSq > fRadiusLocalSq )
fRadiusLocalSq = fDistSq;
}
pmcCur->pMesh->UnlockVertexBuffer();
pbPoints = NULL;
pmcCur = pmcCur->pmcNext;
}
*pfRadiusSq = fRadiusLocalSq;
pframeCur = pframe->pframeFirstChild;
while (pframeCur != NULL)
{
hr = CalculateRadius(pframeCur, &matLocal, pvCenter, pfRadiusSq);
if (FAILED(hr))
goto e_Exit;
pframeCur = pframeCur->pframeSibling;
}
e_Exit:
if (pbPoints != NULL)
{
pmcCur->pMesh->UnlockVertexBuffer();
}
return hr;
}
HRESULT CalculateBoundingSphere(SDrawElement *pdeCur)
{
HRESULT hr = S_OK;
D3DXVECTOR3 vCenter(0,0,0);
UINT cVertices = 0;
float fRadiusSq = 0;
D3DXMATRIX matCur;
D3DXMatrixIdentity(&matCur);
hr = CalculateSum(pdeCur->pframeRoot, &matCur, &vCenter, &cVertices);
if (FAILED(hr))
goto e_Exit;
if (cVertices > 0)
{
vCenter /= (float)cVertices;
D3DXMatrixIdentity(&matCur);
hr = CalculateRadius(pdeCur->pframeRoot, &matCur, &vCenter, &fRadiusSq);
if (FAILED(hr))
goto e_Exit;
}
pdeCur->fRadius = (float)sqrt((double)fRadiusSq);;
pdeCur->vCenter = vCenter;
e_Exit:
return hr;
}
HRESULT CShaderPaletteSkin::FindBones(SFrame *pframeCur, SDrawElement *pde)
{
HRESULT hr = S_OK;
SMeshContainer *pmcMesh;
SFrame *pframeChild;
pmcMesh = pframeCur->pmcMesh;
while (pmcMesh != NULL)
{
if (pmcMesh->m_pSkinMesh)
{
char** pBoneName = static_cast<char**>(pmcMesh->m_pBoneNamesBuf->GetBufferPointer());
for (DWORD i = 0; i < pmcMesh->m_pSkinMesh->GetNumBones(); ++i)
{
SFrame* pFrame = pde->FindFrame(pBoneName[i]);
pmcMesh->m_pBoneMatrix[i] = &(pFrame->matCombined);
}
}
pmcMesh = pmcMesh->pmcNext;
}
pframeChild = pframeCur->pframeFirstChild;
while (pframeChild != NULL)
{
hr = FindBones(pframeChild, pde);
if (FAILED(hr))
return hr;
pframeChild = pframeChild->pframeSibling;
}
return S_OK;
}
HRESULT CShaderPaletteSkin::LoadMeshHierarchy(const char* filePath)
{
TCHAR* pszFile = const_cast<TCHAR*>(filePath);
SDrawElement *pdeMesh = NULL;
HRESULT hr = S_OK;
LPDIRECTXFILE pxofapi = NULL;
LPDIRECTXFILEENUMOBJECT pxofenum = NULL;
LPDIRECTXFILEDATA pxofobjCur = NULL;
DWORD dwOptions;
int cchFileName;
if (pszFile == NULL)
return E_INVALIDARG;
pdeMesh = new SDrawElement();
delete pdeMesh->pframeRoot;
pdeMesh->pframeAnimHead = NULL;
pdeMesh->pframeRoot = new SFrame();
if (pdeMesh->pframeRoot == NULL)
{
hr = E_OUTOFMEMORY;
goto e_Exit;
}
dwOptions = 0;
cchFileName = strlen(pszFile);
if (cchFileName < 2)
{
hr = E_FAIL;
goto e_Exit;
}
hr = DirectXFileCreate(&pxofapi);
if (FAILED(hr))
goto e_Exit;
// Register templates for d3drm.
hr = pxofapi->RegisterTemplates((LPVOID)D3DRM_XTEMPLATES,
D3DRM_XTEMPLATE_BYTES);
if (FAILED(hr))
goto e_Exit;
// Create enum object.
hr = pxofapi->CreateEnumObject((LPVOID)pszFile,
DXFILELOAD_FROMFILE,
&pxofenum);
if (FAILED(hr))
goto e_Exit;
// Enumerate top level objects.
// Top level objects are always data object.
while (SUCCEEDED(pxofenum->GetNextDataObject(&pxofobjCur)))
{
hr = LoadFrames(pxofobjCur, pdeMesh, dwOptions, pdeMesh->pframeRoot);
GXRELEASE(pxofobjCur);
if (FAILED(hr))
goto e_Exit;
}
hr = FindBones(pdeMesh->pframeRoot, pdeMesh);
if (FAILED(hr))
goto e_Exit;
delete []pdeMesh->szName;
pdeMesh->szName = new char[cchFileName+1];
if (pdeMesh->szName == NULL)
{
hr = E_OUTOFMEMORY;
goto e_Exit;
}
memcpy(pdeMesh->szName, pszFile, cchFileName+1);
// delete the current mesh, now that the load has succeeded
DeleteSelectedMesh();
// link into the draw list
pdeMesh->pdeNext = m_pdeHead;
m_pdeHead = pdeMesh;
m_pdeSelected = pdeMesh;
m_pmcSelectedMesh = pdeMesh->pframeRoot->pmcMesh;
m_pframeSelected = pdeMesh->pframeRoot;
hr = CalculateBoundingSphere(pdeMesh);
if (FAILED(hr))
goto e_Exit;
m_pdeSelected->fCurTime = 0.0f;
m_pdeSelected->fMaxTime = 200.0f;
D3DXMatrixTranslation(&m_pdeSelected->pframeRoot->matRot,
-pdeMesh->vCenter.x, -pdeMesh->vCenter.y, -pdeMesh->vCenter.z);
m_pdeSelected->pframeRoot->matRotOrig = m_pdeSelected->pframeRoot->matRot;
e_Exit:
GXRELEASE(pxofobjCur);
GXRELEASE(pxofenum);
GXRELEASE(pxofapi);
if (FAILED(hr))
{
delete pdeMesh;
}
return hr;
}
HRESULT CShaderPaletteSkin::LoadAnimation(LPDIRECTXFILEDATA pxofobjCur, SDrawElement *pde,
DWORD options, SFrame *pframeParent)
{
HRESULT hr = S_OK;
SRotateKeyXFile *pFileRotateKey;
SScaleKeyXFile *pFileScaleKey;
SPositionKeyXFile *pFilePosKey;
SMatrixKeyXFile *pFileMatrixKey;
SFrame *pframeCur;
LPDIRECTXFILEDATA pxofobjChild = NULL;
LPDIRECTXFILEOBJECT pxofChild = NULL;
LPDIRECTXFILEDATAREFERENCE pxofobjChildRef = NULL;
const GUID *type;
DWORD dwSize;
PBYTE pData;
DWORD dwKeyType;
DWORD cKeys;
DWORD iKey;
DWORD cchName;
char *szFrameName;
pframeCur = new SFrame();
if (pframeCur == NULL)
{
hr = E_OUTOFMEMORY;
goto e_Exit;
}
pframeCur->bAnimationFrame = true;
pframeParent->AddFrame(pframeCur);
pde->AddAnimationFrame(pframeCur);
// Enumerate child objects.
// Child object can be data, data reference or binary.
// Use QueryInterface() to find what type of object a child is.
while (SUCCEEDED(pxofobjCur->GetNextObject(&pxofChild)))
{
// Query the child for it's FileDataReference
hr = pxofChild->QueryInterface(IID_IDirectXFileDataReference,
(LPVOID *)&pxofobjChildRef);
if (SUCCEEDED(hr))
{
hr = pxofobjChildRef->Resolve(&pxofobjChild);
if (SUCCEEDED(hr))
{
hr = pxofobjChild->GetType(&type);
if (FAILED(hr))
goto e_Exit;
if( TID_D3DRMFrame == *type )
{
if (pframeCur->pframeToAnimate != NULL)
{
hr = E_INVALIDARG;
goto e_Exit;
}
hr = pxofobjChild->GetName(NULL, &cchName);
if (FAILED(hr))
goto e_Exit;
if (cchName == 0)
{
hr = E_INVALIDARG;
goto e_Exit;
}
szFrameName = (char*)_alloca(cchName);
if (szFrameName == NULL)
{
hr = E_OUTOFMEMORY;
goto e_Exit;
}
hr = pxofobjChild->GetName(szFrameName, &cchName);
if (FAILED(hr))
goto e_Exit;
pframeCur->pframeToAnimate = pde->FindFrame(szFrameName);
if (pframeCur->pframeToAnimate == NULL)
{
hr = E_INVALIDARG;
goto e_Exit;
}
}
GXRELEASE(pxofobjChild);
}
GXRELEASE(pxofobjChildRef);
}
else
{
// Query the child for it's FileData
hr = pxofChild->QueryInterface(IID_IDirectXFileData,
(LPVOID *)&pxofobjChild);
if (SUCCEEDED(hr))
{
hr = pxofobjChild->GetType(&type);
if (FAILED(hr))
goto e_Exit;
if ( TID_D3DRMFrame == *type )
{
hr = LoadFrames(pxofobjChild, pde, options, pframeCur);
if (FAILED(hr))
goto e_Exit;
}
else if ( TID_D3DRMAnimationOptions == *type )
{
//ParseAnimOptions(pChildData,pParentFrame);
//i=2;
}
else if ( TID_D3DRMAnimationKey == *type )
{
hr = pxofobjChild->GetData( NULL, &dwSize, (PVOID*)&pData );
if (FAILED(hr))
goto e_Exit;
dwKeyType = ((DWORD*)pData)[0];
cKeys = ((DWORD*)pData)[1];
if (dwKeyType == 0)
{
if (pframeCur->m_pRotateKeys != NULL)
{
hr = E_INVALIDARG;
goto e_Exit;
}
pframeCur->m_pRotateKeys = new SRotateKey[cKeys];
if (pframeCur->m_pRotateKeys == NULL)
{
hr = E_OUTOFMEMORY;
goto e_Exit;
}
pframeCur->m_cRotateKeys = cKeys;
//NOTE x files are w x y z and QUATERNIONS are x y z w
pFileRotateKey = (SRotateKeyXFile*)(pData + (sizeof(DWORD) * 2));
for (iKey = 0;iKey < cKeys; iKey++)
{
pframeCur->m_pRotateKeys[iKey].dwTime = pFileRotateKey->dwTime;
pframeCur->m_pRotateKeys[iKey].quatRotate.x = pFileRotateKey->x;
pframeCur->m_pRotateKeys[iKey].quatRotate.y = pFileRotateKey->y;
pframeCur->m_pRotateKeys[iKey].quatRotate.z = pFileRotateKey->z;
pframeCur->m_pRotateKeys[iKey].quatRotate.w = pFileRotateKey->w;
pFileRotateKey += 1;
}
}
else if (dwKeyType == 1)
{
if (pframeCur->m_pScaleKeys != NULL)
{
hr = E_INVALIDARG;
goto e_Exit;
}
pframeCur->m_pScaleKeys = new SScaleKey[cKeys];
if (pframeCur->m_pScaleKeys == NULL)
{
hr = E_OUTOFMEMORY;
goto e_Exit;
}
pframeCur->m_cScaleKeys = cKeys;
pFileScaleKey = (SScaleKeyXFile*)(pData + (sizeof(DWORD) * 2));
for (iKey = 0;iKey < cKeys; iKey++)
{
pframeCur->m_pScaleKeys[iKey].dwTime = pFileScaleKey->dwTime;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -