//----------------------------------------------------------------------------- // Name: CMultiAnimAllocateHierarchy::CreateMeshContainer() // Desc: Called by D3DX during the loading of a mesh hierarchy. At a minumum, // the app should allocate a D3DXMESHCONTAINER or a child of it and fill // in the members based on the parameters here. The app can further // customize the allocation behavior here. In our case, we initialize // m_amxBoneOffsets from the skin info for convenience reason. // Then we call ConvertToIndexedBlendedMesh to obtain a new mesh object // that's compatible with the palette size we have to work with. //----------------------------------------------------------------------------- HRESULT CMultiAnimAllocateHierarchy::CreateMeshContainer( THIS_ LPCSTR Name, CONST D3DXMESHDATA *pMeshData, CONST D3DXMATERIAL *pMaterials, CONST D3DXEFFECTINSTANCE *pEffectInstances, DWORD NumMaterials, CONST DWORD *pAdjacency, LPD3DXSKININFO pSkinInfo, LPD3DXMESHCONTAINER *ppNewMeshContainer ) { assert( m_pMA ); * ppNewMeshContainer = NULL; HRESULT hr = S_OK; MultiAnimMC * pMC = new MultiAnimMC; if( pMC == NULL ) { hr = E_OUTOFMEMORY; goto e_Exit; } ZeroMemory( pMC, sizeof( MultiAnimMC ) ); // if this is a static mesh, exit early; we're only interested in skinned meshes if( pSkinInfo == NULL ) { hr = S_OK; goto e_Exit; } // only support mesh type if( pMeshData->Type != D3DXMESHTYPE_MESH ) { hr = E_FAIL; goto e_Exit; } if( Name ) pMC->Name = (CHAR *) HeapCopy( (CHAR *) Name ); else pMC->Name = (CHAR *) HeapCopy( "<no_name>" ); // copy the mesh over pMC->MeshData.Type = pMeshData->Type; pMC->MeshData.pMesh = pMeshData->pMesh; pMC->MeshData.pMesh->AddRef(); // copy adjacency over { DWORD dwNumFaces = pMC->MeshData.pMesh->GetNumFaces(); pMC->pAdjacency = new DWORD[ 3 * dwNumFaces ]; if( pMC->pAdjacency == NULL ) { hr = E_OUTOFMEMORY; goto e_Exit; } CopyMemory( pMC->pAdjacency, pAdjacency, 3 * sizeof( DWORD ) * dwNumFaces ); } // ignore effects instances pMC->pEffects = NULL; // alloc and copy materials pMC->NumMaterials = max( 1, NumMaterials ); pMC->pMaterials = new D3DXMATERIAL [ pMC->NumMaterials ]; pMC->m_apTextures = new LPDIRECT3DTEXTURE9 [ pMC->NumMaterials ]; if( pMC->pMaterials == NULL || pMC->m_apTextures == NULL ) { hr = E_OUTOFMEMORY; goto e_Exit; } if( NumMaterials > 0 ) { CopyMemory( pMC->pMaterials, pMaterials, NumMaterials * sizeof( D3DXMATERIAL ) ); for( DWORD i = 0; i < NumMaterials; ++ i ) { if( pMC->pMaterials[ i ].pTextureFilename ) { // CALLBACK to get valid filename TCHAR sNewPath[ MAX_PATH ]; TCHAR tszTexName[ MAX_PATH ]; if( FAILED( DXUtil_ConvertAnsiStringToGenericCch( tszTexName, pMC->pMaterials[ i ].pTextureFilename, MAX_PATH ) ) ) pMC->m_apTextures[ i ] = NULL; else if( SUCCEEDED( DXUtil_FindMediaFileCch( sNewPath, MAX_PATH, tszTexName ) ) ) { // create the D3D texture if( FAILED( D3DXCreateTextureFromFile( m_pMA->m_pDevice, sNewPath, &pMC->m_apTextures[ i ] ) ) ) pMC->m_apTextures[ i ] = NULL; } else pMC->m_apTextures[ i ] = NULL; } else pMC->m_apTextures[ i ] = NULL; } } else // mock up a default material and set it { ZeroMemory( & pMC->pMaterials[ 0 ].MatD3D, sizeof( ParaMaterial ) ); pMC->pMaterials[ 0 ].MatD3D.Diffuse.r = 0.5f; pMC->pMaterials[ 0 ].MatD3D.Diffuse.g = 0.5f; pMC->pMaterials[ 0 ].MatD3D.Diffuse.b = 0.5f; pMC->pMaterials[ 0 ].MatD3D.Specular = pMC->pMaterials[ 0 ].MatD3D.Diffuse; pMC->pMaterials[ 0 ].pTextureFilename = NULL; } // save the skininfo object pMC->pSkinInfo = pSkinInfo; pSkinInfo->AddRef(); // Get the bone offset matrices from the skin info pMC->m_amxBoneOffsets = new Matrix4[ pSkinInfo->GetNumBones() ]; if( pMC->m_amxBoneOffsets == NULL ) { hr = E_OUTOFMEMORY; goto e_Exit; } { for( DWORD i = 0; i < pSkinInfo->GetNumBones(); ++ i ) pMC->m_amxBoneOffsets[ i ] = * (Matrix4 *) pSkinInfo->GetBoneOffsetMatrix( i ); } // // Determine the palette size we need to work with, then call ConvertToIndexedBlendedMesh // to set up a new mesh that is compatible with the palette size. // { UINT iPaletteSize = 0; m_pMA->m_pEffect->GetInt( "MATRIX_PALETTE_SIZE", (INT *) & iPaletteSize ); pMC->m_dwNumPaletteEntries = min( iPaletteSize, pMC->pSkinInfo->GetNumBones() ); } // generate the skinned mesh - creates a mesh with blend weights and indices hr = pMC->pSkinInfo->ConvertToIndexedBlendedMesh( pMC->MeshData.pMesh, D3DXMESH_MANAGED | D3DXMESHOPT_VERTEXCACHE, pMC->m_dwNumPaletteEntries, pMC->pAdjacency, NULL, NULL, NULL, &pMC->m_dwMaxNumFaceInfls, &pMC->m_dwNumAttrGroups, &pMC->m_pBufBoneCombos, &pMC->m_pWorkingMesh ); if( FAILED( hr ) ) goto e_Exit; // Make sure the working set is large enough for this mesh. // This is a bone array used for all mesh containers as a working // set during drawing. If one was created previously that isn't // large enough for this mesh, we have to reallocate. if( m_pMA->m_dwWorkingPaletteSize < pMC->m_dwNumPaletteEntries ) { if( m_pMA->m_amxWorkingPalette ) delete [] m_pMA->m_amxWorkingPalette; m_pMA->m_dwWorkingPaletteSize = pMC->m_dwNumPaletteEntries; m_pMA->m_amxWorkingPalette = new Matrix4[ m_pMA->m_dwWorkingPaletteSize ]; if( m_pMA->m_amxWorkingPalette == NULL ) { m_pMA->m_dwWorkingPaletteSize = 0; hr = E_OUTOFMEMORY; goto e_Exit; } } // ensure the proper vertex format for the mesh { DWORD dwOldFVF = pMC->m_pWorkingMesh->GetFVF(); DWORD dwNewFVF = ( dwOldFVF & D3DFVF_POSITION_MASK ) | D3DFVF_NORMAL | D3DFVF_TEX1 | D3DFVF_LASTBETA_UBYTE4; if( dwNewFVF != dwOldFVF ) { LPD3DXMESH pMesh; hr = pMC->m_pWorkingMesh->CloneMeshFVF( pMC->m_pWorkingMesh->GetOptions(), dwNewFVF, m_pMA->m_pDevice, &pMesh ); if( FAILED( hr ) ) goto e_Exit; pMC->m_pWorkingMesh->Release(); pMC->m_pWorkingMesh = pMesh; // if the loaded mesh didn't contain normals, compute them here if( ! ( dwOldFVF & D3DFVF_NORMAL ) ) { hr = D3DXComputeNormals( pMC->m_pWorkingMesh, NULL ); if( FAILED( hr ) ) goto e_Exit; } } } // Interpret the UBYTE4 as a Color. // The GeForce3 doesn't support the UBYTE4 decl type. So, we convert any // blend indices to a Color semantic, and later in the shader convert // it back using the D3DCOLORtoUBYTE4() intrinsic. Note that we don't // convert any data, just the declaration. D3DVERTEXELEMENT9 pDecl[ MAX_FVF_DECL_SIZE ]; D3DVERTEXELEMENT9 * pDeclCur; hr = pMC->m_pWorkingMesh->GetDeclaration( pDecl ); if( FAILED( hr ) ) goto e_Exit; pDeclCur = pDecl; while( pDeclCur->Stream != 0xff ) { if( ( pDeclCur->Usage == D3DDECLUSAGE_BLENDINDICES ) && ( pDeclCur->UsageIndex == 0 ) ) pDeclCur->Type = D3DDECLTYPE_D3DCOLOR; pDeclCur++; } hr = pMC->m_pWorkingMesh->UpdateSemantics( pDecl ); if( FAILED( hr ) ) goto e_Exit; e_Exit: if( FAILED( hr ) ) { if( pMC ) DestroyMeshContainer( pMC ); } else * ppNewMeshContainer = pMC; return hr; }
//--------------------------------- HRESULT CAllocateHierarchy::CreateMeshContainer (LPCSTR Name, const D3DXMESHDATA *pMeshData, \ const D3DXMATERIAL *pMaterials,const D3DXEFFECTINSTANCE *pEffectInstances, \ DWORD NumMaterials, const DWORD *pAdjacency, LPD3DXSKININFO pSkinInfo, \ LPD3DXMESHCONTAINER *ppNewMeshContainer) { DWORD i, j; D3DXMESHCONTAINER_DERIVED *pMeshContainer; LPD3DXMESH pMesh, pTempMesh; HRESULT hr = E_FAIL; *ppNewMeshContainer = NULL; //podporované su iba bezne meshe if (pMeshData->Type != D3DXMESHTYPE_MESH) return E_FAIL; //alokácia derivovanej štruktúry kvôli návratovej hodnote - LPD3DXMESHCONTAINER pMeshContainer = new D3DXMESHCONTAINER_DERIVED; if (pMeshContainer == NULL) return E_OUTOFMEMORY; pMesh = pMeshData->pMesh; pMesh->AddRef(); pMeshContainer->NumMaterials = max (1, NumMaterials); pMeshContainer->dwNumPaintings = 1; pMeshContainer->dwNumCoords = 1; if (m_localData.xmlTextures) { const char *szTemp; if (szTemp = g_pXML->Attr (m_localData.xmlTextures, "paint_num")) pMeshContainer->dwNumPaintings = (DWORD)atoi (szTemp); if (szTemp = g_pXML->Attr (m_localData.xmlTextures, "coord_num")) pMeshContainer->dwNumCoords = (DWORD)atoi (szTemp); } pMeshContainer->dwNumPaintings = max (1, pMeshContainer->dwNumPaintings); pMeshContainer->dwNumCoords = max (1, pMeshContainer->dwNumCoords); if (pMeshContainer->dwNumPaintings <= m_localData.dwUseThisPainting) m_localData.dwUseThisPainting = 0; // chyba, pozadovana painting-verzia nie je v xml definovana ////////////////////////////////////////////////////////////////////////// // mesh cloning - tangent, binormal, tex. koordinaty - pocitaju sa len pre modely s viac ako jednou texturovou vrstvou if (pMeshContainer->dwNumCoords > 1) { const DWORD dwRealNumCoords = (pMesh->GetFVF() & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT; const int intTexCoordsToAdd = pMeshContainer->dwNumCoords - dwRealNumCoords; DWORD dwVertexStride = pMesh->GetNumBytesPerVertex (); D3DVERTEXELEMENT9 meshDeclaration[MAX_FVF_DECL_SIZE]; if (SUCCEEDED (pMesh->GetDeclaration (meshDeclaration))) { DWORD dwNumDeclarations = 0; for (i=0; (i < MAX_FVF_DECL_SIZE) && (meshDeclaration[i].Stream != 0xFF); i++) dwNumDeclarations++; // pridanie deklaracie pre tangent meshDeclaration[dwNumDeclarations].Stream = 0; meshDeclaration[dwNumDeclarations].Offset = (WORD)dwVertexStride; meshDeclaration[dwNumDeclarations].Type = D3DDECLTYPE_FLOAT3; meshDeclaration[dwNumDeclarations].Method = D3DDECLMETHOD_DEFAULT; meshDeclaration[dwNumDeclarations].Usage = D3DDECLUSAGE_TANGENT; meshDeclaration[dwNumDeclarations].UsageIndex = 0; dwNumDeclarations++; // pridanie deklaracie pre binormal meshDeclaration[dwNumDeclarations].Stream = 0; meshDeclaration[dwNumDeclarations].Offset = (WORD)(dwVertexStride + 3*sizeof(float)); meshDeclaration[dwNumDeclarations].Type = D3DDECLTYPE_FLOAT3; meshDeclaration[dwNumDeclarations].Method = D3DDECLMETHOD_DEFAULT; meshDeclaration[dwNumDeclarations].Usage = D3DDECLUSAGE_BINORMAL; meshDeclaration[dwNumDeclarations].UsageIndex = 0; dwNumDeclarations++; // pridanie texturovych koordinatov for (int k=0; k<intTexCoordsToAdd; k++) { meshDeclaration[dwNumDeclarations].Stream = 0; meshDeclaration[dwNumDeclarations].Offset = (WORD)(dwVertexStride + 6*sizeof(float) + k*2*sizeof(float)); meshDeclaration[dwNumDeclarations].Type = D3DDECLTYPE_FLOAT2; meshDeclaration[dwNumDeclarations].Method = D3DDECLMETHOD_DEFAULT; meshDeclaration[dwNumDeclarations].Usage = D3DDECLUSAGE_TEXCOORD; meshDeclaration[dwNumDeclarations].UsageIndex = BYTE(k + dwRealNumCoords); dwNumDeclarations++; } // ukoncovaci element memset (&meshDeclaration[dwNumDeclarations], 0, sizeof(D3DVERTEXELEMENT9)); meshDeclaration[dwNumDeclarations].Stream = 0xFF; meshDeclaration[dwNumDeclarations].Type = D3DDECLTYPE_UNUSED; if (FAILED (pMesh->CloneMesh (pMesh->GetOptions(), meshDeclaration, g_pD3DDevice, &pTempMesh))) goto e_Exit; pMesh->Release (); pMesh = pTempMesh; } ////////////////////////////////////////////////////////////////////////// const DWORD dwVertexCount = pMesh->GetNumVertices (); dwVertexStride = pMesh->GetNumBytesPerVertex (); // uprava koordinatov, ak je to potrebne for (i=dwRealNumCoords; i < pMeshContainer->dwNumCoords; i++) { LPVOID pData; DWORD dwUseThisCoords = 0xFFFFFFFF,dwTexCoordOffsetSrc = 0xFFFFFFFF, dwTexCoordOffsetDst = 0xFFFFFFFF; if (m_localData.xmlTextures) { ezxml_t pTextureTag, pCoordsTag; const char *szTemp; char szCoordsTag[16]; if (pTextureTag = g_pXML->Child (m_localData.xmlTextures, "texture0")) { sprintf (szCoordsTag, "coords%u", i); if (pCoordsTag = g_pXML->Child (pTextureTag, szCoordsTag)) if (szTemp = g_pXML->Attr (pCoordsTag, "usecoords")) { dwUseThisCoords = (DWORD) atoi (szTemp); if (dwUseThisCoords >= i) dwUseThisCoords = 0; } } } if ((i > dwRealNumCoords) && (dwUseThisCoords == 0xFFFFFFFF)) dwUseThisCoords = 0; // ak je v xml definovany usecoords, tak kopirovat koordinaty if (dwUseThisCoords != 0xFFFFFFFF) { for (j=0; (j < MAX_FVF_DECL_SIZE) && (meshDeclaration[j].Stream != 0xFF); j++) if (meshDeclaration[j].Usage == D3DDECLUSAGE_TEXCOORD) if (meshDeclaration[j].UsageIndex == dwUseThisCoords) dwTexCoordOffsetSrc = meshDeclaration[j].Offset; else if (meshDeclaration[j].UsageIndex == i) dwTexCoordOffsetDst = meshDeclaration[j].Offset; if ((dwTexCoordOffsetSrc == 0xFFFFFFFF) || (dwTexCoordOffsetDst == 0xFFFFFFFF)) continue; // chyba if (SUCCEEDED (pMesh->LockVertexBuffer (0, &pData))) { LPBYTE pVertexData = (LPBYTE)pData; // kopirovanie koordinatov z vrstvy dwUseThisCoords for (j=0; j<dwVertexCount; j++) { memcpy ((pVertexData + dwTexCoordOffsetDst), (pVertexData + dwTexCoordOffsetSrc), 2*sizeof(float)); pVertexData += dwVertexStride; } pMesh->UnlockVertexBuffer (); } } } // vypocet tangent a binormal if (!CalculateMeshTangents (pMesh, 1)) g_pConsole->Message(MSG_CON_ERR, "MeshLoader: CalculateMeshTangents() function failed"); } ////////////////////////////////////////////////////////////////////////// // nacitanie informacii o materialoch a texturach z x suboru pMeshContainer->pMaterials = new D3DXMATERIAL[pMeshContainer->NumMaterials]; pMeshContainer->pTextures = new LPDIRECT3DTEXTURE9 [pMeshContainer->NumMaterials * pMeshContainer->dwNumCoords * pMeshContainer->dwNumPaintings]; pMeshContainer->p7MTmaterials = new DWORD [pMeshContainer->NumMaterials]; if ((pMeshContainer->pMaterials == NULL) || (pMeshContainer->pTextures == NULL) || \ (pMeshContainer->p7MTmaterials == NULL)) {hr = E_OUTOFMEMORY; goto e_Exit;} memset (pMeshContainer->pMaterials, 0, sizeof(D3DXMATERIAL) * pMeshContainer->NumMaterials); memset (pMeshContainer->pTextures, 0, sizeof(LPDIRECT3DTEXTURE9) * pMeshContainer->NumMaterials * pMeshContainer->dwNumCoords * pMeshContainer->dwNumPaintings); memset (pMeshContainer->p7MTmaterials, 0xFF, sizeof(DWORD) * pMeshContainer->NumMaterials); // nacitanie materialov if (NumMaterials > 0) { for (i=0; i<NumMaterials; i++) { pMeshContainer->pMaterials[i].MatD3D = pMaterials[i].MatD3D; // do x suboru sa neexportuje udaj o ambient zlozke materialov, upravit podla potreby pMeshContainer->pMaterials[i].MatD3D.Ambient = D3DXCOLOR (1.0f, 1.0f, 1.0f, 1.0f); // vypnut Power ak nie je zadana Specular zlozka D3DCOLORVALUE &colorSpec = pMeshContainer->pMaterials[i].MatD3D.Specular; if ((colorSpec.r == 0) && (colorSpec.g == 0) && (colorSpec.b == 0)) pMeshContainer->pMaterials[i].MatD3D.Power = 0.0f; // nacitanie 7mt materialu, ak je k danemu povrchu priradeny #define MATERIAL_FLOAT_TOLERANCE 0.001f for (j=0; j < m_localData.dw7mtMaterialsNum; j++) if (m_localData.Mesh7mtMaterials[j].sz7mtMaterialName != NULL) { // porovnanie textur ak su dostupne if ((m_localData.Mesh7mtMaterials[j].szTextureName != NULL) && (pMaterials[i].pTextureFilename != NULL)) if (stricmp (m_localData.Mesh7mtMaterials[j].szTextureName, pMaterials[i].pTextureFilename) != 0) continue; // porovnanie materialov if (fabs (m_localData.Mesh7mtMaterials[j].material.rDif - pMaterials[i].MatD3D.Diffuse.r) > MATERIAL_FLOAT_TOLERANCE) continue; if (fabs (m_localData.Mesh7mtMaterials[j].material.gDif - pMaterials[i].MatD3D.Diffuse.g) > MATERIAL_FLOAT_TOLERANCE) continue; if (fabs (m_localData.Mesh7mtMaterials[j].material.bDif - pMaterials[i].MatD3D.Diffuse.b) > MATERIAL_FLOAT_TOLERANCE) continue; if (fabs (m_localData.Mesh7mtMaterials[j].material.aDif - pMaterials[i].MatD3D.Diffuse.a) > MATERIAL_FLOAT_TOLERANCE) continue; if (fabs (m_localData.Mesh7mtMaterials[j].material.rSpec - pMaterials[i].MatD3D.Specular.r) > MATERIAL_FLOAT_TOLERANCE) continue; if (fabs (m_localData.Mesh7mtMaterials[j].material.gSpec - pMaterials[i].MatD3D.Specular.g) > MATERIAL_FLOAT_TOLERANCE) continue; if (fabs (m_localData.Mesh7mtMaterials[j].material.bSpec - pMaterials[i].MatD3D.Specular.b) > MATERIAL_FLOAT_TOLERANCE) continue; if (fabs (m_localData.Mesh7mtMaterials[j].material.rEm - pMaterials[i].MatD3D.Emissive.r) > MATERIAL_FLOAT_TOLERANCE) continue; if (fabs (m_localData.Mesh7mtMaterials[j].material.gEm - pMaterials[i].MatD3D.Emissive.g) > MATERIAL_FLOAT_TOLERANCE) continue; if (fabs (m_localData.Mesh7mtMaterials[j].material.bEm - pMaterials[i].MatD3D.Emissive.b) > MATERIAL_FLOAT_TOLERANCE) continue; if (fabs (m_localData.Mesh7mtMaterials[j].material.specPower - pMaterials[i].MatD3D.Power) > MATERIAL_FLOAT_TOLERANCE) continue; // materialy su zhodne char szBuf[MAX_PATH] = "materials\\models\\"; strcat (szBuf, m_localData.Mesh7mtMaterials[j].sz7mtMaterialName); // 7mt material loading pMeshContainer->p7MTmaterials[i] = g_pMaterialManager->LoadMaterial (szBuf); break; } // ####################################################### // naèítanie textúr if ((pMaterials[i].pTextureFilename != NULL) && (pMaterials[i].pTextureFilename[0] != 0)) { char szTag[16]; ezxml_t pTextureTag = NULL; DWORD dwTextureIdx = 0xFFFFFFFF; pMeshContainer->pMaterials[i].pTextureFilename = new char [strlen (pMaterials[i].pTextureFilename) + 1]; strcpy (pMeshContainer->pMaterials[i].pTextureFilename, pMaterials[i].pTextureFilename); if (FindTextureIndexTagByName (m_localData.xmlTextures, pMaterials[i].pTextureFilename, dwTextureIdx)) { sprintf (szTag, "texture%u", dwTextureIdx); pTextureTag = g_pXML->Child (m_localData.xmlTextures, szTag); } for (j=0; j < pMeshContainer->dwNumCoords; j++) // pre jednotlive koordinaty { char szBuf[MAX_PATH] = "textures\\models\\"; if (pTextureTag == NULL) // pouzit texturu z x-suboru { strcat (szBuf, pMaterials[i].pTextureFilename); pMeshContainer->pTextures[ i * pMeshContainer->dwNumCoords * pMeshContainer->dwNumPaintings + j*pMeshContainer->dwNumPaintings + m_localData.dwUseThisPainting] = g_TextureLoader.CreateTexture (szBuf); } else { // ziskanie nazvu textury z xml suboru ezxml_t pCoordsTag, pPaintingTag; sprintf (szTag, "coords%u", j); if (pCoordsTag = g_pXML->Child (pTextureTag, szTag)) { sprintf (szTag, "painting%u", m_localData.dwUseThisPainting); if (pPaintingTag = g_pXML->Child (pCoordsTag, szTag)) if (pPaintingTag->txt) { strcat (szBuf, pPaintingTag->txt); pMeshContainer->pTextures[ i * pMeshContainer->dwNumCoords * pMeshContainer->dwNumPaintings + j*pMeshContainer->dwNumPaintings + m_localData.dwUseThisPainting] = g_TextureLoader.CreateTexture (szBuf); } } } } } } } else // nastavenie defaultneho materialu - Diffuse = 0.8, Specular = Emissive = 0.0, Ambient = 1.0 { pMeshContainer->pMaterials[0].pTextureFilename = NULL; pMeshContainer->pMaterials[0].MatD3D.Ambient = D3DXCOLOR (1.0f, 1.0f, 1.0f, 1.0f); pMeshContainer->pMaterials[0].MatD3D.Diffuse = D3DXCOLOR (0.8f, 0.8f, 0.8f, 1.0f); pMeshContainer->pMaterials[0].MatD3D.Emissive = D3DXCOLOR (0.0f, 0.0f, 0.0f, 1.0f); pMeshContainer->pMaterials[0].MatD3D.Specular = pMeshContainer->pMaterials[0].MatD3D.Emissive; pMeshContainer->pMaterials[0].MatD3D.Power = 0.0f; } /* // alokovanie pamäte pre materiály, textúry pMeshContainer->pMaterials = new D3DXMATERIAL[pMeshContainer->NumMaterials]; pMeshContainer->pTextures = new LPDIRECT3DTEXTURE9[pMeshContainer->NumMaterials]; if ((pMeshContainer->pMaterials == NULL) || (pMeshContainer->pTextures == NULL)) {hr = E_OUTOFMEMORY; goto e_Exit;} //inicializácia textúr a materiálov memset(pMeshContainer->pTextures, 0, sizeof(LPDIRECT3DTEXTURE9) * pMeshContainer->NumMaterials); memset(pMeshContainer->pMaterials, 0, sizeof(D3DXMATERIAL) * pMeshContainer->NumMaterials); //ak sú dostupné materiály, tak sa kopírujú if (NumMaterials > 0) { for (UINT iMaterial = 0; iMaterial < NumMaterials; iMaterial++) { pMeshContainer->pMaterials[iMaterial].MatD3D = pMaterials[iMaterial].MatD3D; pMeshContainer->pMaterials[iMaterial].MatD3D.Ambient = D3DXCOLOR (1.0f, 1.0f, 1.0f, 1.0f); D3DCOLORVALUE &colorSpec = pMeshContainer->pMaterials[iMaterial].MatD3D.Specular; if ((colorSpec.r == 0) && (colorSpec.g == 0) && (colorSpec.b == 0)) pMeshContainer->pMaterials[iMaterial].MatD3D.Power = 0.0f; if (pMaterials[iMaterial].pTextureFilename != NULL) { wsprintf (szBuf, "textures\\models\\%s", pMaterials[iMaterial].pTextureFilename); pMeshContainer->pTextures[iMaterial] = g_TextureLoader.CreateTexture (szBuf); } } } else // ak nie je definovany žiaden materiál, potom sa nastavý defaultný { //Diffuse = Specular = 0.8, Ambient = 1.0 pMeshContainer->pMaterials[0].pTextureFilename = NULL; pMeshContainer->pMaterials[0].MatD3D.Ambient = D3DXCOLOR (1.0f, 1.0f, 1.0f, 1.0f); pMeshContainer->pMaterials[0].MatD3D.Diffuse = D3DXCOLOR (0.8f, 0.8f, 0.8f, 1.0f); pMeshContainer->pMaterials[0].MatD3D.Emissive = D3DXCOLOR (0.0f, 0.0f, 0.0f, 1.0f); pMeshContainer->pMaterials[0].MatD3D.Specular = pMeshContainer->pMaterials[0].MatD3D.Diffuse; pMeshContainer->pMaterials[0].MatD3D.Power = 5.0f; } */ ////////////////////////////////////////////////////////////////////////// // nacitanie skin infa if (m_localData.bLoadSkinInfo && (pSkinInfo != NULL)) { DWORD dwNumBones; pMeshContainer->pSkinInfo = pSkinInfo; pSkinInfo->AddRef(); // alokovanie pamate pre skin-info matice dwNumBones = pSkinInfo->GetNumBones(); if (dwNumBones > 0) { pMeshContainer->pBoneInverseMatrices = new D3DXMATRIX[dwNumBones]; pMeshContainer->ppBoneTransformMatrices = new D3DXMATRIX*[dwNumBones]; if ((pMeshContainer->pBoneInverseMatrices == NULL) || \ (pMeshContainer->ppBoneTransformMatrices == NULL)) {hr = E_OUTOFMEMORY; goto e_Exit;} // nacitanie bone-offset matic for (DWORD iBone=0; iBone < dwNumBones; iBone++) pMeshContainer->pBoneInverseMatrices[iBone] = *(pSkinInfo->GetBoneOffsetMatrix(iBone)); memset (pMeshContainer->ppBoneTransformMatrices, 0, sizeof(LPD3DXMATRIX) * dwNumBones); } ////////////////////////////////////////////////////////////////////////// // upravy pre shader skinning pMeshContainer->NumPaletteEntries = min(MAX_SKIN_BONES, pMeshContainer->pSkinInfo->GetNumBones()); if (FAILED (pMeshContainer->pSkinInfo->ConvertToIndexedBlendedMesh ( pMesh, D3DXMESH_MANAGED | D3DXMESHOPT_VERTEXCACHE, pMeshContainer->NumPaletteEntries, pAdjacency, NULL, NULL, NULL, &pMeshContainer->NumInfl, &pMeshContainer->NumAttributeGroups, &pMeshContainer->pBoneCombinationBuf, &pTempMesh))) goto e_Exit; pMesh->Release (); pMesh = pTempMesh; pTempMesh = NULL; } ////////////////////////////////////////////////////////////////////////// // optimalizacia #ifdef MAKE_MESH_OPTIMIZATION if (pAdjacency) { // pMesh->GenerateAdjacency () // ??? pMesh->OptimizeInplace ( \ D3DXMESHOPT_COMPACT | D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_VERTEXCACHE, \ pAdjacency, NULL, NULL, NULL); } #endif ////////////////////////////////////////////////////////////////////////// pMeshContainer->MeshData.pMesh = pMesh; pMeshContainer->MeshData.Type = D3DXMESHTYPE_MESH; *ppNewMeshContainer = pMeshContainer; return S_OK; e_Exit: pMesh->Release (); SAFE_DELETE (pMeshContainer) return hr; }