D3DXLoadMeshHierarchyFromX()について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
atori
記事: 43
登録日時: 13年前

D3DXLoadMeshHierarchyFromX()について

#1

投稿記事 by atori » 12年前

DirectXにおける、Xファイルのアニメーションに関しての質問になります。
ソースコードの関係上、長いトピックになってしまいました。

アニメーションするには、モデルをフレーム単位で読みこまなくてはいけないらしく、それをトピック名にもある、
D3DXLoadMeshHierarchyFromX()関数を呼べばやってくれるそうなのですが・・・。

そのためにはID3DXAllocateHierarchyクラスを継承して自分で実装しなければならない・・・。などなど、
いろいろネットを見ながらやっていたのですが、詰まってしまったので質問させて頂きます。

コード:

CMyAllocateHierarchy		allocHierarchy;
LPD3DXFRAME					pRootFrame;
LPD3DXANIMATIONCONTROLLER	pAnimeCon;

D3DXLoadMeshHierarchyFromX( "tiny.x",			// Xファイル名
							D3DXMESH_MANAGED,
							g_pd3dDev,
							&allocHierarchy,
							NULL,
							&pRootFrame,
							&pAnimeCon );
このヘルパー関数を呼んだのですが、pRootFrame->pMeshContainerがNULLのままで終わってしまいます。
子フレームとの階層構造はできているのですが、子フレームの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);
};


[CMyAllocateHierarchy.cpp]

コード:

#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::CreateMeshContainer()は通っています。
メッシュの情報はどこへ行ってしまったのでしょうか・・・?

もう一つわからないのが、CMyAllocHierarchy::CreateFrame()は何度も(全フレーム分)通っているのに対し、
CMyAllocHierarchy::CreateMeshContainer()は一度しか通らないということです。
メッシュコンテナはフレーム単位で読み込まれるものではないのでしょうか?

何か自分が根本的に勘違いしているような気もするのですが・・・ご教授のほどよろしくお願いします。
Done is better than perfect.(Mark Elliot Zuckerberg)

atori
記事: 43
登録日時: 13年前

Re: D3DXLoadMeshHierarchyFromX()について

#2

投稿記事 by atori » 12年前

なんとか自分で解決出来ました。
というよりもメッシュコンテナはしっかり入っていたようです。
私の早とちりでした。
Done is better than perfect.(Mark Elliot Zuckerberg)

閉鎖

“C言語何でも質問掲示板” へ戻る