skinned meshes are the bane of my existence

Started by
2 comments, last by ianic 20 years ago
hey peeps I am attempting to generate a skinned Mesh based around the d3d example. The code used is a cut down version someone posted a while ago which I’ve add to my attempt at a so called engine. Upon running the code generates a black blob, it should be tiny, grrr! Here is the haphazard code for the gods to decipher… /* * File name: game.cpp * Description: Game code * * */ #include "./game.h" /* include file for game */ //#include "./skinnedMesh.h" /* Convention on return value: 0 means error; 1 means OK */ /*-------------------------------------------------------------------------*\ entry point \*-------------------------------------------------------------------------*/ int CGame :: gameMain(HWND hWnd, MSG * msg) { if ( gameInit(hWnd) ) { gameLoop(hWnd, msg); gameCleanUp(); return 1; } return 0; } /*-------------------------------------------------------------------------*\ Game initialisation \*-------------------------------------------------------------------------*/ int CGame :: gameInit(HWND hWnd) { /* TO DO: add relevant code */ // Initialise graphics module m_cGraphics = CGraphics(); m_cSkinnedMesh = CSkinnedMesh(); if( m_cGraphics.graphicsModuleInit(hWnd)&& m_cSkinnedMesh.Load(&m_cGraphics, "./tiny.x")) { ShowCursor(FALSE); /* hide mouse cursor */ return 1; } return 0; } /*-------------------------------------------------------------------------*\ Game shut-down \*-------------------------------------------------------------------------*/ int CGame :: gameCleanUp() { /* TO DO: add relevant code */ m_cGraphics.graphicsCleanUp(); // release graphics objects ShowCursor(TRUE); /* show mouse cursor */ return 1; } /*-------------------------------------------------------------------------*\ Game loop \*-------------------------------------------------------------------------*/ int CGame :: gameLoop(HWND hWnd, MSG * msg) { /* TO DO: add relevant code */ /* main game loop */ ZeroMemory( msg, sizeof(*msg) ); /* retrieve messages (for e.g. user interaction devices) */ while( msg->message != WM_QUIT ) /* drop out of loop if "quit" message received */ { if( PeekMessage( msg, NULL, 0U, 0U, PM_REMOVE ) ) /* Note: PeekMessage() does not wait for message to be placed in queue before returning (whereas GetMessage() does wait) */ { TranslateMessage( msg ); /* translate keyboard message */ DispatchMessage( msg ); /* dispatch message to window procedure (via Windows) */ } /* game processing */ gameProc(hWnd); } return 1; } /*-------------------------------------------------------------------------*\ Game processing \*-------------------------------------------------------------------------*/ int CGame :: gameProc(HWND hWnd) { /* Terminate if user has pressed the Esc key */ if ( IS_KEY_DOWN(VK_ESCAPE) ) PostMessage(hWnd, WM_DESTROY, 0, 0); else { /* TO DO: add relevant code */ // Clear the backbuffer and the zbuffer m_cGraphics.g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(255,255,255), 1.0f, 0 ); // Render scene if( SUCCEEDED( m_cGraphics.g_pd3dDevice->BeginScene() ) ) { // Set / update object surface materials and light sources m_cGraphics.setLights(); // Set / update matrices of transformation pipeline m_cGraphics.setTransfPipe(); m_cGraphics.setMaterials(); m_cSkinnedMesh.UpdateMatrices(); m_cSkinnedMesh.DrawFrame(); // End the scene m_cGraphics.g_pd3dDevice->EndScene(); } // Present the backbuffer contents to the display m_cGraphics.g_pd3dDevice->Present( NULL, NULL, NULL, NULL ); //m_cGraphics.render(); } return 1; } CGame::CGame(HWND hWnd, MSG * msg) { gameMain( hWnd, msg); } CGame::~CGame(void) { //Free(); } ------------------------------------------------------------------- /* * File name: graphics.cpp * Description: This sets up a simple rendering pipeline. * *_________________________________________________________________________*/ /*--------------------------------------------------------------------------*\ * NOTE: This file contains API-specific functions * \*--------------------------------------------------------------------------*/ #include <Windows.h> #include <d3dx9.h> #include "graphics.h" /*----------------------------------------------------------------------------\ * | * TYPE DEFINITIONS AND | * DECLARATION OF API OBJECTS USED BY THE APPLICATION | * | *----------------------------------------------------------------------------*/ // define custom vertex type (contains vertex position and normal) struct CUSTOMVERTEX { D3DXVECTOR3 position; // vertex position D3DXVECTOR3 normal; // surface normal at vertex }; // define custom FVF (describes custom vertex structure) #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_NORMAL) /*----------------------------------------------------------------------------\ * | * TRANSFORMATION PIPELINE CODE | * | *----------------------------------------------------------------------------*/ /* Sets the world, view, and projection transformation matrices. Parameter list z none */ VOID CGraphics :: setTransfPipe() { // Set / update world matrix. Parameters: // . orientation defaults to zero units about the world x and z axes, // but set as 45 deg. angle about the world y-axis. // . position defaults to zero units along the world x, y, and z axes. // . scale defaults to identity in the x, y, and z axes of world. D3DXMatrixRotationY( &matWorld, timeGetTime()/1000.0f); g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld ); // Set / update view matrix. Parameters: // . viewpoint set to zero units along the world x-axis, three units up along // the world y-axis, five units back along the world z-axis. // . look-at point set as origin of world. // . view-up direction defined as approximately in y-direction of world. D3DXVECTOR3 vEyePt( 0.0f,3.0f,-5.0f ); D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f ); D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f ); D3DXMATRIXA16 matView; D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec ); g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView ); // Set / update projection matrix. Parameters: // . projection type set as perspective transform from 3D view space to // 2D viewport space. // . field of view defined by: // * angle along vertical set as pi/4, // * aspect ratio set as 1 // * near and far clipping planes (resp.) set as 1 and 100 units from viewpoint. D3DXMATRIXA16 matProj; D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, 1.0f, 1.0f, 100.0f ); g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj ); } /*----------------------------------------------------------------------------\ * | * ILLUMINATION AND SHADING CODE | * | *----------------------------------------------------------------------------*/ /* Sets the object surface materials. Parameter list none */ VOID CGraphics :: setMaterials() { /* g_pPmesh->SetNumFaces((DWORD)(g_numFaces / g_reductionFactor)); // Meshes are divided into subsets, one for each material. Render them in // a loop for( DWORD i=0; iSetMaterial( &g_pMeshMaterials ); g_pd3dDevice->SetTexture( 0, g_pMeshTextures ); // Draw the mesh subset g_pPmesh->DrawSubset( i ); } */ } /* Sets the light sources. Parameter list none */ VOID CGraphics :: setLights() {/* // Set / update light source properties. Parameters: // . type set to directional light // * direction: parallel to <1, 1, 1>. // . colour set to white. // Also enable lighting by setting the D3DRS_LIGHTING renderstate. D3DXVECTOR3 vecDir; D3DLIGHT9 light; ZeroMemory( &light, sizeof(D3DLIGHT9) ); light.Type = D3DLIGHT_DIRECTIONAL; light.Diffuse.r = 1.0f; light.Diffuse.g = 1.0f; light.Diffuse.b = 1.0f; vecDir = D3DXVECTOR3(1.0f, 1.0f, 1.0f); D3DXVec3Normalize( (D3DXVECTOR3*)&light.Direction, &vecDir ); light.Range = 1000.0f; g_pd3dDevice->SetLight( 0, &light ); // set light source ID g_pd3dDevice->LightEnable( 0, TRUE ); // activate light source g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE ); // enable lighting. // Turn ambient light on. g_pd3dDevice->SetRenderState( D3DRS_AMBIENT, 0xffffffff);*/ } /*—————————————————————————-\ * | * RENDERING PIPELINE CODE | * | *—————————————————————————-*/ /* Passes the specification of the world through the graphics pipeline, and draws the scene. Parameter list none */ VOID CGraphics :: render() { long currentTime = GetTickCount(); /*if (( currentTime - g_startTime) > 2000) { // halve the number of polygons shown g_reductionFactor = g_reductionFactor * 2; if (g_reductionFactor > 128) { // go back to maximum polygons and switch fillMode g_reductionFactor = 1; if (g_fillMode == D3DFILL_WIREFRAME) { g_fillMode = D3DFILL_SOLID; g_cullMode = D3DCULL_CCW; } else { g_fillMode = D3DFILL_WIREFRAME; g_cullMode = D3DCULL_NONE; } g_pd3dDevice->SetRenderState(D3DRS_FILLMODE , g_fillMode ); // if in wire frame mode, do not do back-face culling g_pd3dDevice->SetRenderState(D3DRS_CULLMODE , g_cullMode); } g_startTime = currentTime; }*/ } /*—————————————————————————-\ * | * INITIALISATION AND CLEAN UP | * | *—————————————————————————-*/ /* Initialises the graphics module of the application. Parameter list hWnd: handle of window */ int CGraphics :: graphicsModuleInit(HWND hWnd) { // Initialise Direct3D if( SUCCEEDED( initialiseD3D( hWnd ) ) ) { // Create scene geometry /*if( SUCCEEDED( initialiseWorld() ) ) return 1; else return 0;*/ return 1; } else return 0; } /* Initialises Direct3D. Parameter list hWnd: handle of window */ HRESULT CGraphics :: initialiseD3D( HWND hWnd ) { // Create D3D object if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) ) return E_FAIL; // Set temporary structure with parameters which will be used to create the // rendering device (fitted with a z buffer) D3DPRESENT_PARAMETERS d3dpp; ZeroMemory( &d3dpp, sizeof(d3dpp) ); d3dpp.Windowed = TRUE; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; d3dpp.EnableAutoDepthStencil = TRUE; d3dpp.AutoDepthStencilFormat = D3DFMT_D16; // Create rendering device object if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pd3dDevice ) ) ) { return E_FAIL; } /* Initial state of rendering device normally set here. For example, you may turn off face culling, and turn on wireframe mode or the z buffer algorithm. */ // Face culling is off g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE ); // z buffer is on g_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE ); return S_OK; } /* Initialises the world: mesh geometry (and possibly materials) Parameter list hWnd: handle of window */ HRESULT CGraphics :: initialiseWorld() { } /* Release objects Parameter list none */ VOID CGraphics :: graphicsCleanUp() { if( g_pd3dDevice != NULL ) g_pd3dDevice->Release(); if( g_pD3D != NULL ) g_pD3D->Release(); } CGraphics::CGraphics(void) { // API objects used by the application g_pD3D = NULL; // pointer to D3D object g_pd3dDevice = NULL; // pointer to rendering device object g_pVB = NULL; // pointer to vertex buffer object // } CGraphics::~CGraphics(void) { //Free(); } LPDIRECT3DDEVICE9 CGraphics :: GetDevice(){ return g_pd3dDevice; } ———————————————————————————– #include ".\skinnedmesh.h" // CAllocateHeirarchy HRESULT CAllocateHeirarchy::AllocateName(LPCSTR pName, LPTSTR* pNewName) { UINT nLength; if (pName) { nLength = lstrlen(pName) + 1; *pNewName = new TCHAR[nLength]; if (!(*pNewName)) return E_OUTOFMEMORY; memcpy(*pNewName, pName, nLength*sizeof(TCHAR)); } else { *pNewName = NULL; } return S_OK; } HRESULT CAllocateHeirarchy::CreateFrame(LPCSTR pName, LPD3DXFRAME* ppNewFrame) { HRESULT hr; SFrame *pFrame; *ppNewFrame = NULL; pFrame = new SFrame; if (!pFrame) { delete pFrame; return E_OUTOFMEMORY; } hr = AllocateName(pName, &pFrame->Name); if (FAILED(hr)) { delete pFrame; return hr; } D3DXMatrixIdentity(&pFrame->TransformationMatrix); D3DXMatrixIdentity(&pFrame->m_matCombination); pFrame->pMeshContainer = NULL; pFrame->pFrameSibling = NULL; pFrame->pFrameFirstChild = NULL; *ppNewFrame = pFrame; pFrame = NULL; return S_OK; } HRESULT CAllocateHeirarchy::CreateMeshContainer(LPCSTR pName, LPD3DXMESHDATA pMeshData, LPD3DXMATERIAL pMaterials, LPD3DXEFFECTINSTANCE pEffectInstances, DWORD dwNumMaterials, DWORD* pAdjacency, LPD3DXSKININFO pSkinInfo, LPD3DXMESHCONTAINER* ppNewMeshContainer) { HRESULT hr; SMeshContainer* pMeshContainer = NULL; UINT nNumFaces; UINT nMaterial; UINT nBone, nBones; LPDIRECT3DDEVICE9 pDevice = NULL; LPD3DXMESH pMesh = NULL; *ppNewMeshContainer = NULL; if (pMeshData->Type != D3DXMESHTYPE_MESH) { return E_FAIL; } pMesh = pMeshData->pMesh; if (pMesh->GetFVF() == 0) { return E_FAIL; } pMeshContainer = new SMeshContainer; if (pMeshContainer == NULL) { return E_OUTOFMEMORY; } memset(pMeshContainer, 0, sizeof(SMeshContainer)); hr = AllocateName(pName, &pMeshContainer->Name); if (FAILED(hr)) { return hr; } pMesh->GetDevice(&pDevice); nNumFaces = pMesh->GetNumFaces(); if (!(pMesh->GetFVF() & D3DFVF_NORMAL)) { pMeshContainer->MeshData.Type = D3DXMESHTYPE_MESH; hr = pMesh->CloneMeshFVF( pMesh->GetOptions(), pMesh->GetFVF() | D3DFVF_NORMAL, pDevice, &pMeshContainer->MeshData.pMesh ); if (FAILED(hr)) { SAFE_RELEASE(pDevice); return hr; } pMesh = pMeshContainer->MeshData.pMesh; D3DXComputeNormals( pMesh, NULL ); } else { pMeshContainer->MeshData.pMesh = pMesh; pMeshContainer->MeshData.Type = D3DXMESHTYPE_MESH; pMesh->AddRef(); } pMeshContainer->NumMaterials = max(1, dwNumMaterials); pMeshContainer->pMaterials = new D3DXMATERIAL[pMeshContainer->NumMaterials]; pMeshContainer->m_ppTextures = new LPDIRECT3DTEXTURE9[pMeshContainer->NumMaterials]; pMeshContainer->pAdjacency = new DWORD[nNumFaces*3]; if ((pMeshContainer->pAdjacency == NULL) || (pMeshContainer->pMaterials == NULL)) { SAFE_RELEASE(pDevice); return E_OUTOFMEMORY; } memcpy(pMeshContainer->pAdjacency, pAdjacency, sizeof(DWORD) * nNumFaces*3); memset(pMeshContainer->m_ppTextures, 0, sizeof(LPDIRECT3DTEXTURE9) * pMeshContainer->NumMaterials); if (dwNumMaterials > 0) { memcpy(pMeshContainer->pMaterials, pMaterials, sizeof(D3DXMATERIAL) * dwNumMaterials); for (nMaterial = 0; nMaterial < dwNumMaterials; nMaterial++) { if (pMeshContainer->pMaterials[nMaterial].pTextureFilename != NULL) { if( FAILED( D3DXCreateTextureFromFile( pDevice, pMeshContainer->pMaterials[nMaterial].pTextureFilename, &pMeshContainer->m_ppTextures[nMaterial] ) ) ) pMeshContainer->m_ppTextures[nMaterial] = NULL; pMeshContainer->pMaterials[nMaterial].pTextureFilename = NULL; } } } else { pMeshContainer->pMaterials[0].pTextureFilename = NULL; memset(&pMeshContainer->pMaterials[0].MatD3D, 0, sizeof(D3DMATERIAL9)); pMeshContainer->pMaterials[0].MatD3D.Diffuse.r = 0.5f; pMeshContainer->pMaterials[0].MatD3D.Diffuse.g = 0.5f; pMeshContainer->pMaterials[0].MatD3D.Diffuse.b = 0.5f; pMeshContainer->pMaterials[0].MatD3D.Specular = pMeshContainer->pMaterials[0].MatD3D.Diffuse; } if (pSkinInfo != NULL) { pMeshContainer->pSkinInfo = pSkinInfo; pSkinInfo->AddRef(); pMeshContainer->m_pOrigMesh = pMesh; pMesh->AddRef(); nBones = pSkinInfo->GetNumBones(); pMeshContainer->m_pBoneOffsetMatrices = new D3DXMATRIX[nBones]; if (pMeshContainer->m_pBoneOffsetMatrices == NULL) { SAFE_RELEASE(pDevice); return E_OUTOFMEMORY; } for (nBone = 0; nBone < nBones; nBone++) { pMeshContainer->m_pBoneOffsetMatrices[nBone] = *(pMeshContainer->pSkinInfo->GetBoneOffsetMatrix(nBone)); } hr = m_pSkinnedMeshPtr->GenerateSkinnedMesh(pMeshContainer); if (FAILED(hr)) { SAFE_RELEASE(pDevice); return hr; } } *ppNewMeshContainer = pMeshContainer; pMeshContainer = NULL; SAFE_RELEASE(pDevice); if (pMeshContainer != NULL) { DestroyMeshContainer(pMeshContainer); } return hr; } HRESULT CAllocateHeirarchy::DestroyFrame(LPD3DXFRAME pFrameToFree) { SAFE_DELETE_ARRAY(pFrameToFree->Name); SAFE_DELETE(pFrameToFree); return S_OK; } HRESULT CAllocateHeirarchy::DestroyMeshContainer(LPD3DXMESHCONTAINER pMeshContainerToFree) { UINT nMaterial; SMeshContainer* pMeshContainer = (SMeshContainer*)pMeshContainerToFree; SAFE_DELETE_ARRAY(pMeshContainer->Name); SAFE_DELETE_ARRAY(pMeshContainer->pAdjacency); SAFE_DELETE_ARRAY(pMeshContainer->pMaterials); SAFE_DELETE_ARRAY(pMeshContainer->m_pBoneOffsetMatrices); if (pMeshContainer->m_ppTextures != NULL) { for (nMaterial = 0; nMaterial < pMeshContainer->NumMaterials; nMaterial++) { SAFE_RELEASE(pMeshContainer->m_ppTextures[nMaterial]); } } SAFE_DELETE_ARRAY(pMeshContainer->m_ppTextures); SAFE_DELETE_ARRAY(pMeshContainer->m_ppBoneMatrixPtrs); SAFE_RELEASE(pMeshContainer->m_pBoneCombinationBuf); SAFE_RELEASE(pMeshContainer->MeshData.pMesh); SAFE_RELEASE(pMeshContainer->pSkinInfo); SAFE_RELEASE(pMeshContainer->m_pOrigMesh); SAFE_DELETE(pMeshContainer); return S_OK; } // CSkinnedMesh CSkinnedMesh::CSkinnedMesh() : m_cAlloc(this) { m_pGraphics=NULL; // m_pFrameRoot=NULL; } CSkinnedMesh::~CSkinnedMesh() { //Free(); } bool CSkinnedMesh::Load(CGraphics *pGraphics, char *pFilename) { if(!(m_pGraphics=pGraphics)) return false; if(!m_pGraphics->GetDevice()) return false; if(FAILED(D3DXLoadMeshHierarchyFromX(pFilename, D3DXMESH_MANAGED, m_pGraphics->GetDevice(), &m_cAlloc, NULL, &m_pGraphics->m_pFrameRoot, &m_pAnimControl))) return false; if(!MapBonesToFrame()) return false; return true; } bool CSkinnedMesh::Free(void) { // D3DXFrameDestroy(m_pFrameRoot, &m_cAlloc); SAFE_RELEASE(m_pAnimControl); return true; } bool CSkinnedMesh::UpdateMatrices(LPD3DXFRAME pFrameBase, LPD3DXMATRIX pParentMatrix) { SFrame *pFrame; if(!pFrameBase) pFrameBase=m_pGraphics->m_pFrameRoot; pFrame = (SFrame*)pFrameBase; if (pParentMatrix) D3DXMatrixMultiply(&pFrame->m_matCombination, &pFrame->TransformationMatrix, pParentMatrix); else pFrame->m_matCombination = pFrame->TransformationMatrix; if (pFrame->pFrameSibling != NULL) { UpdateMatrices(pFrame->pFrameSibling, pParentMatrix); } if (pFrame->pFrameFirstChild != NULL) { UpdateMatrices(pFrame->pFrameFirstChild, &pFrame->m_matCombination); } return true; } bool CSkinnedMesh::DrawMeshContainer(LPD3DXMESHCONTAINER pMeshContainerBase, LPD3DXFRAME pFrameBase) { SMeshContainer* pMeshContainer = (SMeshContainer*)pMeshContainerBase; SFrame* pFrame = (SFrame*)pFrameBase; UINT nAttrib; LPD3DXBONECOMBINATION pBoneComb; UINT nMatrixIndex; UINT nPaletteEntry; D3DXMATRIXA16 matTemp; if(!m_pGraphics) return false; if(!m_pGraphics->GetDevice()) return false; m_pGraphics->GetDevice()->SetSoftwareVertexProcessing(TRUE); if (pMeshContainer->m_dwNumInfl == 1) m_pGraphics->GetDevice()->SetRenderState(D3DRS_VERTEXBLEND, D3DVBF_0WEIGHTS); else m_pGraphics->GetDevice()->SetRenderState(D3DRS_VERTEXBLEND, pMeshContainer->m_dwNumInfl - 1); if (pMeshContainer->m_dwNumInfl) m_pGraphics->GetDevice()->SetRenderState(D3DRS_INDEXEDVERTEXBLENDENABLE, TRUE); // for each attribute group in the mesh, calculate the set of matrices in the palette and then draw the mesh subset pBoneComb = reinterpret_cast<LPD3DXBONECOMBINATION>(pMeshContainer->m_pBoneCombinationBuf->GetBufferPointer()); for (nAttrib = 0; nAttrib < pMeshContainer->m_dwNumAttributeGroups; nAttrib++) { // first calculate all the world matrices for (nPaletteEntry = 0; nPaletteEntry < pMeshContainer->m_dwNumPaletteEntries; ++nPaletteEntry) { nMatrixIndex = pBoneComb[nAttrib].BoneId[nPaletteEntry]; if (nMatrixIndex != UINT_MAX) { D3DXMatrixMultiply( &matTemp, &pMeshContainer->m_pBoneOffsetMatrices[nMatrixIndex], pMeshContainer->m_ppBoneMatrixPtrs[nMatrixIndex] ); m_pGraphics->GetDevice()->SetTransform( D3DTS_WORLDMATRIX( nPaletteEntry ), &matTemp ); } } // setup the material of the mesh subset - REMEMBER to use the original pre-skinning attribute id to get the correct material id m_pGraphics->GetDevice()->SetMaterial( &pMeshContainer->pMaterials[pBoneComb[nAttrib].AttribId].MatD3D ); m_pGraphics->GetDevice()->SetTexture( 0, pMeshContainer->m_ppTextures[pBoneComb[nAttrib].AttribId] ); // finally draw the subset with the current world matrix palette and material state pMeshContainer->MeshData.pMesh->DrawSubset( nAttrib ); } // reset blending state m_pGraphics->GetDevice()->SetRenderState(D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE); m_pGraphics->GetDevice()->SetRenderState(D3DRS_VERTEXBLEND, 0); // m_pGraphics->GetDevice()->SetSoftwareVertexProcessing(FALSE); return true; } bool CSkinnedMesh::DrawFrame(LPD3DXFRAME pFrame) { LPD3DXMESHCONTAINER pMeshContainer; if(!pFrame) pFrame=m_pGraphics->m_pFrameRoot; pMeshContainer = pFrame->pMeshContainer; while (pMeshContainer != NULL) { DrawMeshContainer(pMeshContainer, pFrame); pMeshContainer = pMeshContainer->pNextMeshContainer; } if (pFrame->pFrameSibling != NULL) { DrawFrame(pFrame->pFrameSibling); } if (pFrame->pFrameFirstChild != NULL) { DrawFrame(pFrame->pFrameFirstChild); } return true; } bool CSkinnedMesh::MapBonesToFrame(LPD3DXFRAME pFrame) { if(!pFrame) pFrame = m_pGraphics->m_pFrameRoot; if(pFrame->pMeshContainer) { if(!MapBonesToMesh(pFrame->pMeshContainer)) return false; } if(pFrame->pFrameSibling) { if(!MapBonesToFrame(pFrame->pFrameSibling)) return false; } if(pFrame->pFrameFirstChild) { if(!MapBonesToFrame(pFrame->pFrameFirstChild)) return false; } return true; } bool CSkinnedMesh::MapBonesToMesh(LPD3DXMESHCONTAINER pMeshContainerBase) { UINT nBone, nBones; SFrame *pFrame; SMeshContainer *pMeshContainer = (SMeshContainer*)pMeshContainerBase; if (pMeshContainer->pSkinInfo != NULL) { nBones = pMeshContainer->pSkinInfo->GetNumBones(); pMeshContainer->m_ppBoneMatrixPtrs = new D3DXMATRIX*[nBones]; if (pMeshContainer->m_ppBoneMatrixPtrs == NULL) return false; for (nBone = 0; nBone < nBones; nBone++) { pFrame = (SFrame*)D3DXFrameFind(m_pGraphics->m_pFrameRoot, pMeshContainer->pSkinInfo->GetBoneName(nBone)); if (!pFrame) return false; pMeshContainer->m_ppBoneMatrixPtrs[nBone] = &pFrame->m_matCombination; } } return true; } HRESULT CSkinnedMesh::GenerateSkinnedMesh(SMeshContainer *pMeshContainer) { LPDIRECT3DINDEXBUFFER9 pIB; HRESULT hr = S_OK; DWORD dwNumMaxFaceInfl; DWORD dwFlags = D3DXMESHOPT_VERTEXCACHE; if (!pMeshContainer->pSkinInfo) return hr; SAFE_RELEASE(pMeshContainer->MeshData.pMesh); SAFE_RELEASE(pMeshContainer->m_pBoneCombinationBuf); hr = pMeshContainer->m_pOrigMesh->GetIndexBuffer(&pIB); if (FAILED(hr)) return hr; hr = pMeshContainer->pSkinInfo->GetMaxFaceInfluences(pIB, pMeshContainer->m_pOrigMesh->GetNumFaces(), &dwNumMaxFaceInfl); pIB->Release(); if (FAILED(hr)) return hr; // 12 entry palette guarantees that any triangle (4 independent influences per vertex of a tri) // can be handled dwNumMaxFaceInfl = min(dwNumMaxFaceInfl, 12); pMeshContainer->m_dwNumPaletteEntries = min(256, pMeshContainer->pSkinInfo->GetNumBones()); dwFlags |= D3DXMESH_SYSTEMMEM; hr = pMeshContainer->pSkinInfo->ConvertToIndexedBlendedMesh( pMeshContainer->m_pOrigMesh, dwFlags, pMeshContainer->m_dwNumPaletteEntries, pMeshContainer->pAdjacency, NULL, NULL, NULL, &pMeshContainer->m_dwNumInfl, &pMeshContainer->m_dwNumAttributeGroups, &pMeshContainer->m_pBoneCombinationBuf, &pMeshContainer->MeshData.pMesh); if (FAILED(hr)) return hr; return S_OK; } hope this makes sence and someone can solve or give hints on re-writing thanx </i>
Advertisement
it works i was been stupid, sorry to bother you guy,

tiny was just out of view.

another qustion though....

should the rootframe be translated by the world position?

and how do i incorporate the .bmp

thanx
AFAIK you should use the World Transformation Matrix

For the Skin you need to load it with D3DXCreateTextureFromFile and SetTexture on the appropriate subset.

the texture file name is in D3DXMATERIAL

[edited by - hexskillz on April 4, 2004 12:45:09 PM]
cheers HexSkillz

This topic is closed to new replies.

Advertisement