//Xファイルからの3Dモデルデータをロード (詳細版、アニメーション制御可能) HRESULT MeshManager::LoadAnimeMeshFromX(DxAnimeMesh *mesh,const string& fName,const string& path) { //読み込み用アニメーションコントローラ LPD3DXANIMATIONCONTROLLER pAnimControllerTmp = NULL; string str = path + fName; //Xファイルからフレーム階層とアニメーション情報をロード if(FAILED(D3DXLoadMeshHierarchyFromX( str.c_str(), D3DXMESH_MANAGED, this->dev, this->hierarchy, NULL, &mesh->pFrameRoot, &pAnimControllerTmp))) { return E_FAIL; } //ファイル名の設置 mesh->file_name=fName; if(FAILED(LoadAnimeFromX(pAnimControllerTmp,mesh,fName,path))) { return E_FAIL; } SAFE_RELEASE(pAnimControllerTmp); return S_OK; }
bool XEnitity::Load(const std::string FileName) { m_FileName = FileName; MeshAllocation* pMeshAlloc = new MeshAllocation; HRESULT hr = D3DXLoadMeshHierarchyFromX(m_FileName.c_str(), D3DXMESH_MANAGED, m_d3ddev, pMeshAlloc, NULL, &m_pTopFrame, &m_pAnimCtrl); SAFE_DELETE(pMeshAlloc); if(FAILED(hr)) return false; m_NumAnimationSets = m_pAnimCtrl->GetNumAnimationSets(); if(m_pTopFrame) { SetupBoneMatrices((CUSTOM_FRAME*) m_pTopFrame); m_pBoneMatrices = new D3DXMATRIX[m_MaxBones]; memset(m_pBoneMatrices, 0, sizeof(D3DXMATRIX)*m_MaxBones); } return true; }
//-------------------------------------------------------------------------------------- // This function loads the mesh and LDPRT data. It also centers and optimizes the // mesh for the graphics card's vertex cache. //-------------------------------------------------------------------------------------- HRESULT LoadLDPRTData( IDirect3DDevice9* pd3dDevice, WCHAR* strFilePrefixIn ) { WCHAR str[MAX_PATH]; WCHAR strFileName[MAX_PATH]; WCHAR strFilePrefix[MAX_PATH]; HRESULT hr; // Load the mesh with D3DX and get back a ID3DXMesh*. For this // sample we'll ignore the X file's embedded materials since we know // exactly the model we're loading. See the mesh samples such as // "OptimizedMesh" for a more generic mesh loading example. swprintf_s( strFilePrefix, MAX_PATH, TEXT( "%s" ), strFilePrefixIn ); strFilePrefix[MAX_PATH - 1] = 0; swprintf_s( strFileName, MAX_PATH, TEXT( "%s.x" ), strFilePrefix ); strFileName[MAX_PATH - 1] = 0; V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, strFileName ) ); CAllocateHierarchy Alloc; // Delete existing resources if( g_pFrameRoot ) { D3DXFrameDestroy( g_pFrameRoot, &Alloc ); g_pFrameRoot = NULL; } // Create hierarchy V_RETURN( D3DXLoadMeshHierarchyFromX( str, D3DXMESH_MANAGED, pd3dDevice, &Alloc, NULL, &g_pFrameRoot, &g_pAnimController ) ); SetupBoneMatrixPointers( g_pFrameRoot, g_pFrameRoot ); return S_OK; }
void XSkinnedMesh::LoadModel( const string& fileName ) { BoneHierarchyLoader boneHierarchy; BoneFrame* frame = nullptr; // .x 파일로부터 본 계층 구조를 로드한다. auto hr = D3DXLoadMeshHierarchyFromX( fileName.c_str(), D3DXMESH_MANAGED, D3D9_DEVICE, &boneHierarchy, NULL, &frame, &_animation ); if (FAILED( hr )) { SAFE_DELETE( frame ); // assert } _rootBone = static_cast<Bone*>(frame); // bone matrices update SetMatrices(); UpdateMatrices( _rootBone, &_world ); SetupBoneMatrixPtr( _rootBone ); // render sphere //D3DXCreateSphere( D3D9_DEVICE, 2.0f, 10, 10, &_sphereMesh, NULL ); //LoadTexture( DEFAULT_TEX ); }
bool CDexModelXAni::LoadModelFile(const char* filename) { HRESULT hr; int64 mseconds = getTime()->GetTotalMillSeconds(); //从.X文件加载层次框架和动画数据 hr = D3DXLoadMeshHierarchyFromX(filename, D3DXMESH_MANAGED, DexGameEngine::getEngine()->GetDevice(), m_pAlloc, NULL, &m_pFrameRoot, &m_pAnimController); //最后一个参数:动画控制器 if (FAILED(hr)) return false; //建立各级框架的组合变换矩阵 SetupBoneMatrixPointers(m_pFrameRoot); int index = 4; if(m_pAnimController != NULL) { m_pAnimController->GetAnimationSet(index, &m_pAnimationSet1); m_pAnimController->SetTrackAnimationSet(0, m_pAnimationSet1); m_pAnimController->ResetTime(); } getLog()->BeginLog(); getLog()->Log(log_ok, "加载animation模型%s成功!用时:%d ms\n",filename, getTime()->GetTotalMillSeconds() - mseconds); getLog()->EndLog(); return true; }
bool CXModel::LoadXFile(char *file) { if(!m_device) return false; CD3DAllocate alh; // Load X mesh from a file. if(FAILED(D3DXLoadMeshHierarchyFromX(file, D3DXMESH_MANAGED, m_device, &alh, NULL, &m_root, &m_animControl))) return false; // Record max number of animation sets in the X model. if(m_animControl) m_numAnimations = m_animControl->GetMaxNumAnimationSets(); // Setup Bones. if(m_root) { SetupMatrices((stD3DFrameEx*)m_root, NULL); m_boneMatrices = new D3DXMATRIX[m_maxBones]; ZeroMemory(m_boneMatrices, sizeof(D3DXMATRIX)*m_maxBones); D3DXFrameCalculateBoundingSphere(m_root, &m_center, &m_radius); } // Set initialize animation. SetAnimation(0); return true; }
bool CXFileEntity::Load(const std::string &filename) { // Create our mesh hierarchy class to control the allocation of memory - only used temporarily CMeshHierarchy *memoryAllocator=new CMeshHierarchy; // To make it easier to find the textures change the current directory to the one containing the .x file // First though remember the current one to put it back afterwards std::string currentDirectory=CUtility::GetTheCurrentDirectory(); std::string xfilePath; CUtility::SplitPath(filename,&xfilePath,&m_filename); SetCurrentDirectory(xfilePath.c_str()); // This is the function that does all the .x file loading. We provide a pointer to an instance of our // memory allocator class to handle memory allocationm during the frame and mesh loading HRESULT hr = D3DXLoadMeshHierarchyFromX(filename.c_str(), D3DXMESH_MANAGED, m_d3dDevice, memoryAllocator, NULL, &m_frameRoot, &m_animController); delete memoryAllocator; memoryAllocator=0; SetCurrentDirectory(currentDirectory.c_str()); if (FAILED(hr)) return false; // if the x file contains any animation remember how many sets there are if(m_animController) m_numAnimationSets = m_animController->GetMaxNumAnimationSets(); // Bones for skining if(m_frameRoot) { // Set the bones up SetupBoneMatrices((D3DXFRAME_EXTENDED*)m_frameRoot, NULL); // Create the bone matrices array for use during FrameMove to hold the final transform m_boneMatrices = new D3DXMATRIX[m_maxBones]; ZeroMemory(m_boneMatrices, sizeof(D3DXMATRIX)*m_maxBones); // Calculate the Bounding Sphere for this model (used in CalculateInitialViewMatrix to position camera correctly) D3DXFrameCalculateBoundingSphere(m_frameRoot, &m_sphereCentre, &m_sphereRadius); } m_firstMesh->MeshData.pMesh->GetVertexBuffer(&vb.vb); m_firstMesh->MeshData.pMesh->GetIndexBuffer(&ib.ib); D3DVERTEXELEMENT9 pDecl[MAX_FVF_DECL_SIZE]; m_firstMesh->MeshData.pMesh->GetDeclaration(pDecl); renderSystem->CreateVertexDeclaration(&pDecl[0],&vb.declaration); // Получение данных о количестве вершин, индексов и полигонов dwNumVerticies = m_firstMesh->MeshData.pMesh->GetNumVertices(); dwNumIndecies = m_firstMesh->MeshData.pMesh->GetNumFaces()*3; dwNumFaces = m_firstMesh->MeshData.pMesh->GetNumFaces(); vb.vertexSize = (short)m_firstMesh->MeshData.pMesh->GetNumBytesPerVertex(); return true; }
void SKINNEDMESH::Load(char fileName[], IDirect3DDevice9 *Dev) { m_pDevice = Dev; BONE_HIERARCHY boneHierarchy; D3DXLoadMeshHierarchyFromX(fileName, D3DXMESH_MANAGED, m_pDevice, &boneHierarchy, NULL, &m_pRootBone, &m_pAnimControl); SetupBoneMatrixPointers((BONE*)m_pRootBone); }
void SKINNEDMESH::Load(char fileName[], IDirect3DDevice9 *Dev) { m_pDevice = Dev; BONE_HIERARCHY boneHierarchy; D3DXLoadMeshHierarchyFromX(fileName, D3DXMESH_MANAGED, m_pDevice, &boneHierarchy, NULL, &m_pRootBone, NULL); D3DXMATRIX i; UpdateMatrices((BONE*)m_pRootBone, D3DXMatrixIdentity(&i)); //Create Sphere D3DXCreateSphere(m_pDevice, 0.07f, 10, 10, &m_pSphereMesh, NULL); }
void SkinnedMesh::Load(char fileName[]) { BoneHierarchyLoader boneHierarchy; D3DXLoadMeshHierarchyFromX(fileName, D3DXMESH_MANAGED, g_pDevice, &boneHierarchy, NULL, &m_pRootBone, NULL); SetupBoneMatrixPointers((Bone*)m_pRootBone); //Update all the bones D3DXMATRIX i; D3DXMatrixIdentity(&i); UpdateMatrices((Bone*)m_pRootBone, &i); //Create Sphere D3DXCreateSphere(g_pDevice, 0.02f, 10, 10, &m_pSphereMesh, NULL); }
/** * @brief メッシュの読み込み * */ void AnimationManager::loadMeshHierarchyFromX(const acut::TString& meshFilePath) { try { // mesh 読み込み V_THROW(D3DXLoadMeshHierarchyFromX( meshFilePath.c_str(), D3DXMESH_MANAGED, DXUTGetD3D9Device(), &m_allocateHierarchy, NULL, reinterpret_cast<LPD3DXFRAME*>(&m_pRootFrame), &m_pAnimationController )); // ボーン変換行列へのポインタをセット V_THROW(this->setupBoneMatrixPointers(m_pRootFrame)); // animation controller の trackを全てFALSEにする DWORD numTracks = m_pAnimationController->GetMaxNumTracks(); DEBUG_OUTPUTF("m_pAnimationController->GetMaxNumTracks() : %d\n", numTracks); for (DWORD i = 0; i < numTracks; ++i) { V_THROW(m_pAnimationController->SetTrackEnable(i, FALSE)); } V_THROW(this->createAnimationSetList()); try { // tyny_4anim.xの場合 // 0: 手を振る Wave // 1: 走る Jog // 2: 歩く Walk // 3: ふらふらする Loiter V_THROW(m_pAnimationController->SetTrackAnimationSet(0, m_animationSetList.at(1))); V_THROW(m_pAnimationController->SetTrackEnable(0, TRUE)); } catch (std::out_of_range& ex) { acut::ExceptionHandler::handleException(ex); throw acut::Exception(__FILEW__, __LINE__, __FUNCTIONW__); } } catch (acut::Exception& ex) { acut::ExceptionHandler::handleException(ex); this->cleanup(); throw; } }
HRESULT CAnimationModel::InitDeviceObjects(LPDIRECT3DDEVICE9 pd3dDevice) { HRESULT hr = S_OK; if( NULL == pd3dDevice ) return E_INVALIDARG; m_pd3dDevice = pd3dDevice; m_pd3dDevice->AddRef(); // 커스텀 애니메신컨트롤러 를 생성 m_pAniController = new CAnimationController; // X파이을 읽어들여 애니메이션 가능한 모델을 만든다. if( NULL == m_pXFileName ) return E_FAIL; CAllocateHierarchy alloc; alloc.SetCreationFlag( TRUE ); alloc.SetDwFrame( 0 ); alloc.SetDwMeshContainer( 0 ); alloc.SetFrameVector( &vFrame ); alloc.SetMeshContainerVector( &vMeshContainer ); hr = D3DXLoadMeshHierarchyFromX( m_pXFileName , D3DXMESH_MANAGED , m_pd3dDevice , &alloc , NULL , &m_pFrameRoot , &m_pAniController->m_pAniController ); CHECK_FAILED( hr ); hr = SetupBoneMatrixPointers( m_pFrameRoot ); CHECK_FAILED( hr ); m_pAniController->InitDeviceObjects( m_pd3dDevice ); return hr; }
void cSkinnedMesh::Setup( char* szFolder, char* szFile ) { std::string sFullPath(szFolder); sFullPath += (std::string("/") + std::string(szFile)); cAllocateHierarchy ah; ah.SetFolder(szFolder); D3DXLoadMeshHierarchyFromX(sFullPath.c_str(), D3DXMESH_MANAGED, g_pD3DDevice, &ah, NULL, &m_pRoot, &m_pAnimController); SetupBoneMatrixPtrs((ST_BONE*)m_pRoot); }
HRESULT MoonSkinmesh::InitDeviceObjects() { HRESULT hr; AllocateHierarchy Alloc(this); string strMeshPath = MODEL_DIR(""); strMeshPath += _strMeshname; strMeshPath += "\\"; strMeshPath += _strMeshname; strMeshPath += ".x"; hr = D3DXLoadMeshHierarchyFromX(strMeshPath.c_str(), D3DXMESH_MANAGED, _pDevice, &Alloc, NULL, &_pFrameRoot, &_pAnimController); if(FAILED(hr)) return hr; hr = SetupBoneMatrixPointers(_pFrameRoot); if(FAILED(hr)) return hr; return S_OK; }
INT CLcXSkinSrc::Create(void* p1, void* p2, void*, void* ) { HRESULT hr; CLcXSkinAlloc Alloc(this); char* sFile = NULL; m_pDevice = (LPDIRECT3DDEVICE9)p1; sFile = (char*)p2; ::strcpy(m_sFile, sFile); WCHAR* wFile = new WCHAR[strlen(m_sFile)+1]; DXUtil_ConvertAnsiStringToWideCch(wFile, m_sFile, strlen(m_sFile)+1); hr = D3DXLoadMeshHierarchyFromX(wFile , D3DXMESH_MANAGED , m_pDevice , &Alloc , NULL , (LPD3DXFRAME*)&m_pFrameRoot , &m_pAC); delete[] wFile; if (FAILED(hr)) return hr; hr = FindBones(m_pFrameRoot); if (FAILED(hr)) return hr; hr = D3DXFrameCalculateBoundingSphere((const D3DXFRAME*)m_pFrameRoot, &m_ObjectCenter, &m_ObjectRadius); if (FAILED(hr)) return hr; return S_OK; }
SkinnedMesh::SkinnedMesh(std::string XFilename) { AllocMeshHierarchy allocMeshHierarchy; HR(D3DXLoadMeshHierarchyFromX(XFilename.c_str(), D3DXMESH_SYSTEMMEM, gd3dDevice, &allocMeshHierarchy, 0, /* ignore user data */ &mRoot, &mAnimCtrl)); // In this demo we assume that the input .X file contains only one // mesh. So search for that one and only mesh. D3DXFRAME* f = findNodeWithMesh(mRoot); if( f == 0 ) HR(E_FAIL); D3DXMESHCONTAINER* meshContainer = f->pMeshContainer; mSkinInfo = meshContainer->pSkinInfo; mSkinInfo->AddRef(); mNumBones = meshContainer->pSkinInfo->GetNumBones(); mFinalXForms.resize(mNumBones); mToRootXFormPtrs.resize(mNumBones, 0); buildSkinnedMesh(meshContainer->MeshData.pMesh); buildToRootXFormPtrArray(); }
//----------------------------------------------------------------------------- // The mesh class constructor. //----------------------------------------------------------------------------- Mesh::Mesh( char *name, char *path ) : Resource< Mesh >( name, path ) { // Create the list of reference points. m_frames = new LinkedList< Frame >; m_refPoints = new LinkedList< Frame >; // Load the mesh's frame hierarchy. AllocateHierarchy ah; D3DXLoadMeshHierarchyFromX( GetFilename(), D3DXMESH_MANAGED, Engine::GetInstance()->GetDevice(), &ah, NULL, (D3DXFRAME**)&m_firstFrame, &m_animationController ); // Disable all the animation tracks initially. if( m_animationController != NULL ) for( unsigned long t = 0; t < m_animationController->GetMaxNumTracks(); ++t ) m_animationController->SetTrackEnable( t, false ); // Invalidate the bone transformation matrices array. m_boneMatrices = NULL; m_totalBoneMatrices = 0; // Prepare the frame hierarchy. PrepareFrame( m_firstFrame ); // Allocate memory for the bone matrices. m_boneMatrices = new D3DXMATRIX[m_totalBoneMatrices]; // Create a static (non-animated) version of the mesh. m_staticMesh = new MeshContainer; ZeroMemory( m_staticMesh, sizeof( MeshContainer ) ); // Load the mesh. ID3DXBuffer *materialBuffer, *adjacencyBuffer; D3DXLoadMeshFromX( GetFilename(), D3DXMESH_MANAGED, Engine::GetInstance()->GetDevice(), &adjacencyBuffer, &materialBuffer, NULL, &m_staticMesh->NumMaterials, &m_staticMesh->originalMesh ); // Optimise the mesh for better rendering performance. m_staticMesh->originalMesh->OptimizeInplace( D3DXMESHOPT_COMPACT | D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_VERTEXCACHE, (DWORD*)adjacencyBuffer->GetBufferPointer(), NULL, NULL, NULL ); // Finished with the adjacency buffer, so destroy it. SAFE_RELEASE( adjacencyBuffer ); // Check if the mesh has any materials. if( m_staticMesh->NumMaterials > 0 ) { // Create the array of materials. m_staticMesh->materials = new Material*[m_staticMesh->NumMaterials]; // Get the list of materials from the material buffer. D3DXMATERIAL *materials = (D3DXMATERIAL*)materialBuffer->GetBufferPointer(); // Load each material into the array via the material manager. for( unsigned long m = 0; m < m_staticMesh->NumMaterials; m++ ) { // Ensure the material has a texture. if( materials[m].pTextureFilename ) { // Get the name of the material's script and load it. char *name = new char[strlen( materials[m].pTextureFilename ) + 5]; sprintf( name, "%s.txt", materials[m].pTextureFilename ); m_staticMesh->materials[m] = Engine::GetInstance()->GetMaterialManager()->Add( name, GetPath() ); SAFE_DELETE_ARRAY( name ); } else m_staticMesh->materials[m] = NULL; } } // Create the bounding volume around the mesh. BoundingVolumeFromMesh( m_staticMesh->originalMesh ); // Destroy the material buffer. SAFE_RELEASE( materialBuffer ); // Create a vertex array and an array of indices into the vertex array. m_vertices = new Vertex[m_staticMesh->originalMesh->GetNumVertices()]; m_indices = new unsigned short[m_staticMesh->originalMesh->GetNumFaces() * 3]; // Use the arrays to store a local copy of the static mesh's vertices and // indices so that they can be used by the scene manager on the fly. Vertex* verticesPtr; m_staticMesh->originalMesh->LockVertexBuffer( 0, (void**)&verticesPtr ); unsigned short *indicesPtr; m_staticMesh->originalMesh->LockIndexBuffer( 0, (void**)&indicesPtr ); memcpy( m_vertices, verticesPtr, VERTEX_FVF_SIZE * m_staticMesh->originalMesh->GetNumVertices() ); memcpy( m_indices, indicesPtr, sizeof( unsigned short ) * m_staticMesh->originalMesh->GetNumFaces() * 3 ); m_staticMesh->originalMesh->UnlockVertexBuffer(); m_staticMesh->originalMesh->UnlockIndexBuffer(); }
Face::Face(string filename) { m_pBaseMesh = NULL; m_pBlinkMesh = NULL; m_pFaceTexture = NULL; m_pFaceNormalMap = NULL; //Face Vertex Format D3DVERTEXELEMENT9 faceVertexDecl[] = { //1st Stream: Base Mesh {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0}, {0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0}, {0, 32, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0}, {0, 44, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0}, //2nd Stream {1, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 1}, {1, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 1}, {1, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1}, //3rd Stream {2, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 2}, {2, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 2}, {2, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2}, //4th Stream {3, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 3}, {3, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 3}, {3, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 3}, //5th Stream {4, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 4}, {4, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 4}, {4, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 4}, D3DDECL_END() }; //Create Face Vertex Declaration g_pDevice->CreateVertexDeclaration(faceVertexDecl, &m_pFaceVertexDecl); //Load Face Meshes FaceHierarchyLoader hierarchy; D3DXFRAME *root = NULL; D3DXLoadMeshHierarchyFromX(filename.c_str(), D3DXMESH_MANAGED, g_pDevice, &hierarchy, NULL, &root, NULL); //Extract Face Meshes ExtractMeshes(root); //Add tangents & binormal to base mesh AddTangentBinormal(&m_pBaseMesh); //PrintMeshDeclaration(m_pBaseMesh); //Destroy temporary hierarchy hierarchy.DestroyFrame(root); //Load textures D3DXCreateTextureFromFile(g_pDevice, "resources/face.jpg", &m_pFaceTexture); D3DXCreateTextureFromFile(g_pDevice, "resources/face_normal.tga", &m_pFaceNormalMap); }
bool SkinnedMesh::Init( std::wstring path ) { AllocateHierarchy Alloc; DWORD dwShaderFlags = D3DXFX_NOT_CLONEABLE; #if defined( DEBUG ) || defined( _DEBUG ) dwShaderFlags |= D3DXSHADER_DEBUG; #endif #ifdef DEBUG_VS dwShaderFlags |= D3DXSHADER_FORCE_VS_SOFTWARE_NOOPT; #endif #ifdef DEBUG_PS dwShaderFlags |= D3DXSHADER_FORCE_PS_SOFTWARE_NOOPT; #endif LPDIRECT3DDEVICE9 pD3DDevice = DDRenderer::GetInstance()->GetDevice(); WCHAR str[MAX_PATH] = L".\\Resources\\3DModel\\SkinnedMesh.fx"; // shader 파일 읽어서 등록 if ( FAILED( D3DXCreateEffectFromFile( pD3DDevice, str, NULL, NULL, dwShaderFlags, NULL, &m_pEffect, NULL ) ) ) { assert( false ); return false; } // shader 파일 이름 생성 std::wstring xfilePath = L".\\Resources\\3DModel\\"; xfilePath.append( path ); // 메시 불러오기 // 애니메이션 계층 구조 만들기 if ( FAILED( D3DXLoadMeshHierarchyFromX( xfilePath.c_str(), D3DXMESH_MANAGED, pD3DDevice, &Alloc, NULL, &m_pFrameRoot, &m_pAnimController ) ) ) { assert( false ); return false; } // 조심해! // 예제에서는 m_pBoneMatrices를 전역 변수로 사용하므로 // AllocateHierarchy에서 할당했으나 이제는 여기서 해준다. // 그런데 사이즈는 어떻게 가져오지... 아무튼 지금 애니메이션 안 나오는 문제는 여기 아님 delete[] m_pBoneMatrices; m_pBoneMatrices = new D3DXMATRIXA16[64]; if ( m_pBoneMatrices == nullptr ) { assert( false ); return false; } // 본 매트릭스 생성 if ( FAILED( SetupBoneMatrixPointers( m_pFrameRoot ) ) ) { assert( false ); return false; } if ( FAILED( D3DXFrameCalculateBoundingSphere( m_pFrameRoot, &m_vObjectCenter, &m_fObjectRadius ) ) ) { assert( false ); return false; } // Obtain the behavior flags D3DDEVICE_CREATION_PARAMETERS cp; pD3DDevice->GetCreationParameters( &cp ); m_dwBehaviorFlags = cp.BehaviorFlags; return true; }