ソースコードの関係上、長いトピックになってしまいました。
アニメーションするには、モデルをフレーム単位で読みこまなくてはいけないらしく、それをトピック名にもある、
D3DXLoadMeshHierarchyFromX()関数を呼べばやってくれるそうなのですが・・・。
そのためにはID3DXAllocateHierarchyクラスを継承して自分で実装しなければならない・・・。などなど、
いろいろネットを見ながらやっていたのですが、詰まってしまったので質問させて頂きます。
CMyAllocateHierarchy allocHierarchy;
LPD3DXFRAME pRootFrame;
LPD3DXANIMATIONCONTROLLER pAnimeCon;
D3DXLoadMeshHierarchyFromX( "tiny.x", // Xファイル名
D3DXMESH_MANAGED,
g_pd3dDev,
&allocHierarchy,
NULL,
&pRootFrame,
&pAnimeCon );
子フレームとの階層構造はできているのですが、子フレームのpMeshContainerもNULLのままです。
一切メッシュが読み込めていないことになるのですが、原因がさっぱりわかりません。
CMyAllocateHierarchyは、上記で言ったID3DXAllocateHierarchyを継承した独自クラスです。
実際に階層構造の構築、メッシュコンテナの読み込みを行なっています。
ソースは下に書きます。
[CMyAllocateHierarchy.h]
#pragma once
#include<d3dx9.h>
class CMyAllocHierarchy:
public ID3DXAllocateHierarchy
{
public:
CMyAllocHierarchy(void);
virtual ~CMyAllocHierarchy(void);
STDMETHOD(CreateFrame)(THIS_ LPCSTR name, LPD3DXFRAME *ppnewFrame);
STDMETHOD(CreateMeshContainer)(THIS_
LPCSTR name,
CONST D3DXMESHDATA *pMeshData,
CONST D3DXMATERIAL *pMaterials,
CONST D3DXEFFECTINSTANCE *pEffectInstances,
DWORD NumMaterials,
CONST DWORD *pAdjacency,
LPD3DXSKININFO pSkinInfo,
LPD3DXMESHCONTAINER *ppNewMeshContainer);
STDMETHOD(DestroyFrame)(THIS_ LPD3DXFRAME pFrameToFree);
STDMETHOD(DestroyMeshContainer)(THIS_ LPD3DXMESHCONTAINER pMeshContainerToFree);
};
#include "MyAllocHierarchy.h"
#include"Inline.h"
CMyAllocHierarchy::CMyAllocHierarchy(void)
{
}
CMyAllocHierarchy::~CMyAllocHierarchy(void)
{
}
/*==========================================
// フレームを動的確保する
==========================================*/
HRESULT CMyAllocHierarchy::CreateFrame(THIS_ LPCSTR name, LPD3DXFRAME *ppnewFrame)
{
LPD3DXFRAME frame = new D3DXFRAME;
ZeroMemory(frame, sizeof(D3DXFRAME));
frame->Name = new char[strlen(name)+1];
strcpy_s(frame->Name, strlen(name)+1, name);
*ppnewFrame = frame;
return D3D_OK;
}
/*==========================================
// メッシュコンテナを動的確保する
==========================================*/
HRESULT CMyAllocHierarchy::CreateMeshContainer(THIS_
LPCSTR name,
CONST D3DXMESHDATA *pMeshData,
CONST D3DXMATERIAL *pMaterials,
CONST D3DXEFFECTINSTANCE *pEI,
DWORD NumMaterials,
CONST DWORD *pAdjacency,
LPD3DXSKININFO pSkinInfo,
LPD3DXMESHCONTAINER *ppNewMeshContainer)
{
LPD3DXMESHCONTAINER con = new D3DXMESHCONTAINER;
// ZeroMemory(con, sizeof(D3DXMESHCONTAINER));
con->Name = new char[strlen(name)+1];
strcpy_s(con->Name, strlen(name)+1, name);
/*S メッシュ読み込み------------------------*/
if(pMeshData->Type == D3DXMESHTYPE_MESH)
{
con->MeshData.pMesh = pMeshData->pMesh;
con->MeshData.pMesh->AddRef();
}
else if(pMeshData->Type == D3DXMESHTYPE_PMESH)
{
con->MeshData.pPMesh = pMeshData->pPMesh;
con->MeshData.pPMesh->AddRef();
}
else
{
con->MeshData.pPatchMesh = pMeshData->pPatchMesh;
con->MeshData.pPatchMesh->AddRef();
}
/*E メッシュ読み込み------------------------*/
/*S マテリアル読み込み------------------------*/
con->NumMaterials = NumMaterials;
con->pMaterials = new D3DXMATERIAL[NumMaterials];
for(unsigned int i=0; i<NumMaterials; ++i){
con->pMaterials[i].MatD3D = pMaterials[i].MatD3D;
con->pMaterials[i].pTextureFilename = new char[strlen(pMaterials[i].pTextureFilename)+1];
strcpy_s(con->pMaterials[i].pTextureFilename, strlen(pMaterials[i].pTextureFilename)+1, pMaterials[i].pTextureFilename);
}
/*E マテリアル読み込み------------------------*/
/*S エフェクト読み込み------------------------*/
// ファイル名読み込み
con->pEffects = new D3DXEFFECTINSTANCE;
if(pEI->pEffectFilename == NULL)
con->pEffects->pEffectFilename = NULL;
else
{
con->pEffects->pEffectFilename = new char[strlen(pEI->pEffectFilename)+1];
strcpy_s(con->pEffects->pEffectFilename, strlen(pEI->pEffectFilename)+1, pEI->pEffectFilename);
}
// 存在するエフェクトをすべて読み込み
con->pEffects->NumDefaults = pEI->NumDefaults;
con->pEffects->pDefaults = new D3DXEFFECTDEFAULT[pEI->NumDefaults];
for(unsigned int i=0; i<pEI->NumDefaults; ++i){
con->pEffects->pDefaults[i].pParamName = new char[strlen(pEI->pDefaults[i].pParamName)+1];
strcpy_s(con->pEffects->pDefaults[i].pParamName, strlen(pEI->pDefaults[i].pParamName)+1, pEI->pDefaults[i].pParamName);
con->pEffects->pDefaults[i].NumBytes = pEI->pDefaults[i].NumBytes;
con->pEffects->pDefaults[i].Type = pEI->pDefaults[i].Type;
if(pEI->pDefaults[i].Type <= D3DXEDT_DWORD)
{
con->pEffects->pDefaults[i].pValue = new DWORD[pEI->pDefaults[i].NumBytes];
memcpy( con->pEffects->pDefaults[i].pValue, pEI->pDefaults[i].pValue, pEI->pDefaults[i].NumBytes );
}
}
/*E エフェクト読み込み------------------------*/
/*S 隣接ポリゴンインデックスの読み込み------------------------*/
con->pAdjacency = new DWORD[pMeshData->pMesh->GetNumFaces()*3];
memcpy(con->pAdjacency, pAdjacency, sizeof(DWORD)*pMeshData->pMesh->GetNumFaces()*3);
/*E 隣接ポリゴンインデックスの読み込み------------------------*/
/*S スキン読み込み------------------------*/
if(pSkinInfo)
{
con->pSkinInfo = pSkinInfo;
con->pSkinInfo->AddRef();
}
/*E スキン読み込み------------------------*/
*ppNewMeshContainer = con;
return D3D_OK;
}
/*==========================================
// フレームを開放する。この中でメッシュコンテナも開放している
// 再帰的にこのメソッドを読んでいるので、引数にルートフレームを渡してやるとすべて削除される。
==========================================*/
HRESULT CMyAllocHierarchy::DestroyFrame(THIS_ LPD3DXFRAME pFrameToFree)
{
DeleteArray(pFrameToFree->Name);
if(pFrameToFree->pMeshContainer)
DestroyMeshContainer(pFrameToFree->pMeshContainer);
if(pFrameToFree->pFrameSibling)
DestroyFrame(pFrameToFree->pFrameSibling);
if(pFrameToFree->pFrameFirstChild)
DestroyFrame(pFrameToFree->pFrameFirstChild);
Delete(pFrameToFree);
return D3D_OK;
}
/*==========================================
// メッシュコンテナの開放
==========================================*/
HRESULT CMyAllocHierarchy::DestroyMeshContainer(THIS_ LPD3DXMESHCONTAINER pMeshContainerToFree)
{
DeleteArray(pMeshContainerToFree->Name);
Release(pMeshContainerToFree->MeshData.pMesh);
// マテリアル開放
for(unsigned int i=0; i<pMeshContainerToFree->NumMaterials; ++i){
DeleteArray(pMeshContainerToFree->pMaterials[i].pTextureFilename);
}
DeleteArray(pMeshContainerToFree->pMaterials);
// エフェクト開放
for(unsigned int i=0; i<pMeshContainerToFree->pEffects->NumDefaults; ++i){
DeleteArray(pMeshContainerToFree->pEffects->pDefaults[i].pParamName);
DeleteArray(pMeshContainerToFree->pEffects->pDefaults[i].pValue);
}
DeleteArray(pMeshContainerToFree->pEffects->pEffectFilename);
DeleteArray(pMeshContainerToFree->pEffects->pDefaults);
Delete(pMeshContainerToFree->pEffects);
// スキン開放
DeleteArray(pMeshContainerToFree->pAdjacency);
Release(pMeshContainerToFree->pSkinInfo);
return D3D_OK;
}
メッシュの情報はどこへ行ってしまったのでしょうか・・・?
もう一つわからないのが、CMyAllocHierarchy::CreateFrame()は何度も(全フレーム分)通っているのに対し、
CMyAllocHierarchy::CreateMeshContainer()は一度しか通らないということです。
メッシュコンテナはフレーム単位で読み込まれるものではないのでしょうか?
何か自分が根本的に勘違いしているような気もするのですが・・・ご教授のほどよろしくお願いします。