source: GTP/trunk/App/Demos/Illum/pathmap/Mesh.cpp @ 2197

Revision 2197, 20.5 KB checked in by szirmay, 17 years ago (diff)
Line 
1#include "dxstdafx.h"
2#include ".\mesh.h"
3#include "SubMesh.h"
4#include "PathMapEffect.h"
5#include "TriangleMesh.h"
6#include "MeshExploder.h"
7#include "L.h"
8#include "FlexVertex.h"
9#include "xmlParser.h"
10#include <vector>
11#include <fstream>
12
13Mesh::Mesh(PathMapEffect*       pathMapEffect,
14                        DWORD fileFormat,
15                        LPCWSTR xFileName,
16                        LPCWSTR ogreFileName,
17                        int prmAtlasSize,
18                        const char* name,
19                        unsigned int nDesiredPartitions,
20                        bool generateUV,
21                        bool generateTBN)
22{
23        this->pathMapEffect = pathMapEffect;
24        LPDIRECT3DDEVICE9 device = pathMapEffect->device;
25
26        this->prmAtlasSize = prmAtlasSize;
27        strcpy(this->name, name);
28
29        if(ogreFileName)
30                wcscpy(this->ogreFileName, ogreFileName);
31        else
32                this->ogreFileName[0] = 0;
33
34        LPD3DXBUFFER materialBuffer, shaderBuffer;
35        DWORD nSubsets;
36
37        HRESULT hr = S_FALSE;
38
39        wchar_t** materialNames;
40
41
42        if(fileFormat == OgreXMLMesh)
43        {
44                hr = loadMeshFromOgreXML(       xFileName,
45                                                0,
46                                                device,
47                                                &materialBuffer,        //material
48                                                &shaderBuffer,          //shadrr
49                                                &nSubsets,
50                                                pathMapEffect->xMaterials,
51                                                materialNames,
52                                                &mesh);
53        }
54        else
55        {
56                hr = D3DXLoadMeshFromX( xFileName,
57                                                        D3DXMESH_MANAGED,
58                                                        device,
59                                                        NULL,                           //adjacency
60                                                        &materialBuffer,        //material
61                                                        &shaderBuffer,          //shader
62                                                        &nSubsets,
63                                                        &mesh);
64        }
65        if(hr != S_OK)
66        {
67                 MessageBox(NULL, xFileName, L"Could not load mesh file!", MB_OK);
68                 return;
69        }
70
71        DWORD fvf = mesh->GetFVF();
72        fvf |= D3DFVF_NORMAL;
73        DWORD nTexCoords = fvf & D3DFVF_TEXCOUNT_MASK;
74        nTexCoords += D3DFVF_TEX1;
75        fvf &= ~D3DFVF_TEXCOUNT_MASK;
76        fvf |= nTexCoords;
77        fvf |= D3DFVF_TEXCOORDSIZE2(nTexCoords / D3DFVF_TEX1);
78        //add a texcoord sets for prm, bump mapping
79//      setVertexFormat(D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX4 | D3DFVF_TEXCOORDSIZE2(0) | D3DFVF_TEXCOORDSIZE2(1) |
80//                              D3DFVF_TEXCOORDSIZE3(2) | D3DFVF_TEXCOORDSIZE3(3));
81        setVertexFormat(fvf);
82
83        if(generateTBN)
84                computeTangentFrame();
85        mesh->OptimizeInplace(D3DXMESHOPT_ATTRSORT, NULL, NULL, NULL, NULL);
86
87        D3DXMATERIAL* materialArray = (D3DXMATERIAL*)materialBuffer->GetBufferPointer();
88        D3DXEFFECTINSTANCE* shaderArray = (D3DXEFFECTINSTANCE*)shaderBuffer->GetBufferPointer();
89
90        if(nDesiredPartitions != 1 || generateUV)
91        {
92                //check is this already exists, load if it does
93                char sname[256];
94                sprintf(sname, "%s/%s.x", LC::c-pathMapEffect->meshDirectory, name);
95
96                LPD3DXMESH processedMesh;
97                LPD3DXBUFFER processedMaterialBuffer;
98                LPD3DXBUFFER processedShaderBuffer;
99                HRESULT processedMeshExists S_FALSE;
100                if(!pathMapEffect->SEGMENTMESHES)
101                {
102                        processedMeshExists = D3DXLoadMeshFromX(
103                                L::l+sname,
104                                D3DXMESH_MANAGED,
105                                device,
106                                NULL,                           //adjacency
107                                &processedMaterialBuffer,       //material
108                                &processedShaderBuffer,         //shader
109                                &nSubsets,
110                                &processedMesh);
111                }
112
113                if(processedMeshExists == S_OK)
114                {
115                        mesh->Release();
116                        materialBuffer->Release();
117                        shaderBuffer->Release();
118                        mesh = processedMesh;
119                        materialBuffer = processedMaterialBuffer;
120                        shaderBuffer = processedShaderBuffer;
121                        materialArray = (D3DXMATERIAL*)materialBuffer->GetBufferPointer();
122                        shaderArray = (D3DXEFFECTINSTANCE*)shaderBuffer->GetBufferPointer();
123                }
124                else
125                {
126                        MeshExploder mex(device, mesh, materialArray, materialNames, shaderArray, nDesiredPartitions);
127                        mex.explode();
128
129                        //mex.saveFragMeshes();
130
131                        if(generateUV)
132                                mex.generateAtlas(prmAtlasSize);
133                        mex.merge();
134                        mex.saveComposedMesh(name);
135                        mex.saveComposedMeshToOgreXML(name);
136
137                        mesh->Release();
138                        materialArray = mex.composedMaterials;
139                        shaderArray = mex.composedShaders;
140                        mesh = mex.composedMesh;
141                }
142        }
143
144        for(int dili=0; materialNames[dili]; dili++)
145                delete [] materialNames[dili];
146        delete [] materialNames;
147
148        nSubsets = nDesiredPartitions;
149
150        //create #subset submeshes
151        for(int iSubset=0; iSubset<nSubsets; iSubset++)
152        {
153                SubMesh* subMesh = new SubMesh(this, iSubset, materialArray[iSubset]);
154                subMeshes.push_back(subMesh);
155                //set submesh textures from material and shader properties
156                D3DXEFFECTDEFAULT* paramArray = shaderArray[iSubset].pDefaults;
157                int nParams = shaderArray[iSubset].NumDefaults;
158                for(int iParams=0; iParams < nParams; iParams++)
159                {
160                        float bumpScale = 1.0;
161                        char bumpFileName[256]; bumpFileName[0] = '\0';
162                        if(strcmp(paramArray[iParams].pParamName, "bumpFileName") == 0)
163                        {
164                                strcpy(bumpFileName, paramArray[iParams].pParamName);
165                        }
166                        if(strcmp(paramArray[iParams].pParamName, "bumpScale") == 0)
167                        {
168                                bumpScale = *(float*)paramArray[iParams].pValue;
169                        }
170                        subMesh->loadBumpMap(bumpFileName, bumpScale);
171                }
172        }
173
174
175        mesh->OptimizeInplace(D3DXMESHOPT_ATTRSORT, NULL, NULL, NULL, NULL);
176        DWORD nAttributes;
177        mesh->GetAttributeTable(NULL, &nAttributes);
178        D3DXATTRIBUTERANGE* subsetRanges = new D3DXATTRIBUTERANGE[nAttributes];
179        mesh->GetAttributeTable(subsetRanges, &nAttributes);
180
181        std::vector<SubMesh*>::iterator iSubMesh = subMeshes.begin();
182        int i =0;
183        while(iSubMesh != subMeshes.end())
184        {
185                (*iSubMesh)->buildRayTraceMesh(subsetRanges[i].FaceStart*3, subsetRanges[i].FaceCount*3);
186                iSubMesh++;
187                i++;
188        }
189        delete subsetRanges;
190
191        materialBuffer->Release();
192        shaderBuffer->Release();
193
194        buildEdgeVertexBuffer();
195}
196
197Mesh::~Mesh(void)
198{
199        std::vector<SubMesh*>::iterator i = subMeshes.begin();
200        while(i != subMeshes.end())
201        {
202                delete *i;
203                i++;
204        }
205        mesh->Release();
206        if(edgeVertexBuffer)
207                edgeVertexBuffer->Release();
208}
209
210
211HRESULT Mesh::setVertexFormat(DWORD fvf)
212{
213        LPDIRECT3DDEVICE9 device = pathMapEffect->device;
214        LPD3DXMESH tempMesh;
215
216        //clone the mesh to the appropriate format
217    HRESULT hr = mesh->CloneMeshFVF( mesh->GetOptions(),
218                                  fvf ,
219                                  device, &tempMesh );
220        if(hr == S_OK)
221        {
222                //forget he old mesh
223                mesh->Release();
224                //use the cloned mesh
225                mesh = tempMesh;
226        }
227        return hr;
228}
229
230HRESULT Mesh::partitionMesh(unsigned int nDesiredPartitions, LPD3DXBUFFER& partitioningBuffer, unsigned int& nPartitions)
231{
232        LPD3DXMESH tempMesh;
233
234        LPD3DXBUFFER partitionResultAdjacency;
235        float maxStretchApplied;
236
237        HRESULT hr;
238/*      hr = D3DXUVAtlasPartition(
239                        mesh,                                           //LPD3DXMESH pMesh,
240                        nDesiredPartitions,                     //UINT dwMaxChartNumber,
241                        1.0f,                                           //FLOAT fMaxStretch,
242                        1,                                                      //DWORD dwTextureIndex,
243                        NULL,                                           //CONST DWORD * pdwAdjacency,
244                        NULL,                                           //CONST CHAR * pcFalseEdges,
245                        NULL,                                           //FLOAT * pfIMTArray,
246                        NULL,                                           //LPD3DXUVATLASCB pCallback,
247                        0.1f,                                           //FLOAT fCallbackFrequency,
248                        NULL,                                           //LPVOID pUserContent,
249                        &tempMesh,                                      //LPD3DXMESH * ppMeshOut,
250                        &partitioningBuffer,            //LPD3DXBUFFER ppFacePartitioning,
251                        NULL,                                           //LPD3DXBUFFER * ppVertexRemapArray,
252                        &partitionResultAdjacency,      //LPD3DXBUFFER * ppPartitionResultAdjacency,
253                        &maxStretchApplied,                     //FLOAT * pfMaxStretchOut,
254                        &nPartitions                            //UINT * pdwNumChartsOut
255        );*/
256
257        if(hr == S_OK)
258        {
259                //forget he old mesh
260                mesh->Release();
261                mesh = tempMesh;
262        }
263        else
264                return hr;
265        partitionResultAdjacency->Release();
266
267        return S_OK;
268}
269
270HRESULT Mesh::computeTangentFrame()
271{
272        LPD3DXMESH tempMesh;
273        HRESULT hr =
274                D3DXComputeTangentFrameEx(
275                        mesh,                                   //  ID3DXMesh * pMesh,
276                        D3DDECLUSAGE_TEXCOORD,  // DWORD dwTextureInSemantic,
277                        0,                                              //  DWORD dwTextureInIndex,
278                        D3DDECLUSAGE_TEXCOORD,  // DWORD dwUPartialOutSemantic,
279                        2,                                              // DWORD dwUPartialOutIndex,
280                        D3DDECLUSAGE_TEXCOORD,  // DWORD dwVPartialOutSemantic,
281                        3,                                              // DWORD dwVPartialOutIndex,
282                        D3DDECLUSAGE_NORMAL,    // DWORD dwNormalOutSemantic,
283                        0,                                              // DWORD dwNormalOutIndex,
284                        (D3DXTANGENT_WRAP_UV
285        //                      | D3DXTANGENT_DONT_ORTHOGONALIZE | D3DXTANGENT_DONT_NORMALIZE_PARTIALS)
286                        )& !( D3DXTANGENT_CALCULATE_NORMALS ), // DWORD dwOptions,
287                        NULL,                                   // CONST DWORD * pdwAdjacency,
288                        0.2,                                    // FLOAT fPartialEdgeThreshold,
289                        0.0,                                    // FLOAT fSingularPointThreshold,
290                        0.2,                                    // FLOAT fNormalEdgeThreshold,
291                        &tempMesh,                                      // ID3DXMesh ** ppMeshOut,
292                        NULL                                    // ID3DXBuffer ** ppVertexMapping
293                );
294
295        if(hr == S_OK)
296        {
297                //forget he old mesh
298                mesh->Release();
299                mesh = tempMesh;
300        }
301        else
302                return hr;
303
304        LPDIRECT3DVERTEXBUFFER9 vertexBuffer;
305        mesh->GetVertexBuffer(&vertexBuffer);
306        FlexVertexArray vertexData(mesh->GetNumBytesPerVertex());
307        D3DVERTEXELEMENT9 elem[64];     mesh->GetDeclaration(elem);      FlexVertex::setFormat(elem);
308        vertexBuffer->Lock(0,mesh->GetNumVertices()*mesh->GetNumBytesPerVertex(),vertexData.getDataPointerReference(),0);
309
310        for(unsigned int u=0; u < mesh->GetNumVertices(); u++ )
311                vertexData[u].tex1() = (vertexData[u].tex1() * (prmAtlasSize - 4) + D3DXVECTOR2(2.0,2.0)) / (float)prmAtlasSize;
312
313        vertexBuffer->Unlock();
314        vertexBuffer->Release();
315
316        return hr;
317}
318
319void Mesh::buildEdgeVertexBuffer()
320{
321        LPDIRECT3DDEVICE9 device = pathMapEffect->device;
322
323        LPD3DXMESH pMesh = this->mesh;
324        DWORD* pAdj = new DWORD[3 * pMesh->GetNumFaces()];
325        for(int r=0; r<pMesh->GetNumFaces()*3; r++)
326                pAdj[r] = 0xffff;
327        pMesh->ConvertPointRepsToAdjacency(NULL, pAdj);
328
329        LPDIRECT3DVERTEXBUFFER9 vertexBuffer;
330        pMesh->GetVertexBuffer(&vertexBuffer);
331        FlexVertexArray vertexData(mesh->GetNumBytesPerVertex());
332        D3DVERTEXELEMENT9 elem[64];     mesh->GetDeclaration(elem);      FlexVertex::setFormat(elem);
333        vertexBuffer->Lock(0,pMesh->GetNumVertices()*pMesh->GetNumBytesPerVertex(),vertexData.getDataPointerReference(),0);
334        LPDIRECT3DINDEXBUFFER9 indexBuffer;
335        pMesh->GetIndexBuffer(&indexBuffer);
336        unsigned short* indexData;
337        indexBuffer->Lock(0,pMesh->GetNumFaces()*3*sizeof(unsigned short),(void**)&indexData,0);
338
339        DWORD* attributeArray;
340        mesh->LockAttributeBuffer(0, &attributeArray);
341
342        int countEdges = 0;
343        for(int u=0; u<pMesh->GetNumFaces(); u++)
344                for(int t=0; t<3; t++)
345                        if(pAdj[u * 3 + t] >= pMesh->GetNumFaces())
346                                countEdges++;
347
348        if(countEdges == 0)
349        {
350                edgeVertexBuffer = NULL;
351                nEdges = 0;
352                vertexBuffer->Unlock();
353                indexBuffer->Unlock();
354                SAFE_RELEASE(vertexBuffer);
355                SAFE_RELEASE(indexBuffer);
356                return;
357        }
358
359        device->CreateVertexBuffer(2 * countEdges * pMesh->GetNumBytesPerVertex(),
360                D3DUSAGE_WRITEONLY, pMesh->GetFVF(), D3DPOOL_DEFAULT,
361                &edgeVertexBuffer, NULL);
362        FlexVertexArray pevData(mesh->GetNumBytesPerVertex());
363        edgeVertexBuffer->Lock(0, 0, pevData.getDataPointerReference(), 0);
364
365        int DBLATLASSIZE = prmAtlasSize * 2;
366        int ATLASSIZE = prmAtlasSize;
367
368        std::vector<SubMesh*>::iterator iSubMesh = subMeshes.begin()-1;
369        DWORD prevAttribute = 0xffffffff;
370
371        int iEdge = 0;
372        for(int u=0; u<pMesh->GetNumFaces(); u++)
373        {
374                if(attributeArray[u] != prevAttribute)
375                {
376                        prevAttribute = attributeArray[u];
377                        iSubMesh++;
378                        (*iSubMesh)->edgeStartIndex = iEdge;
379                        (*iSubMesh)->edgeCount = 0;
380                }
381                for(int t=0; t<3; t++)
382                {
383                        if(pAdj[u * 3 + t] >= pMesh->GetNumFaces())
384                        {
385                                unsigned short edge0 = indexData[u * 3 + t];
386                                unsigned short edge1 = indexData[u * 3 + (t+1)%3];
387                                unsigned short inner = indexData[u * 3 + (t+2)%3];
388
389                                //push vertex edge0, edge1
390                                //pevData[iEdge * 2] = vertexData[edge0];
391                                //pevData[iEdge * 2 + 1] = vertexData[edge1];
392                                pevData.assign(iEdge * 2, vertexData[edge0]);
393                                pevData.assign(iEdge * 2 + 1, vertexData[edge1]);
394                               
395                                D3DXVECTOR2 ediff =  vertexData[edge1].tex1() - vertexData[edge0].tex1();
396                                if(fabsf(ediff.x) > fabsf(ediff.y))
397                                {
398                                        if(vertexData[inner].tex1().y <= vertexData[edge0].tex1().y +
399                                                (vertexData[inner].tex1().x - vertexData[edge0].tex1().x) *
400                                                (vertexData[edge1].tex1().y - vertexData[edge0].tex1().y) /
401                                                (vertexData[edge1].tex1().x - vertexData[edge0].tex1().x))
402                                        {
403                                                pevData[iEdge * 2].tex1().y += 1.0/DBLATLASSIZE;
404                                                pevData[iEdge * 2 + 1].tex1().y += 1.0/DBLATLASSIZE;
405                                        }
406                                        else
407                                        {
408                                                pevData[iEdge * 2].tex1().y -= 1.0/DBLATLASSIZE;
409                                                pevData[iEdge * 2 + 1].tex1().y -= 1.0/DBLATLASSIZE;
410                                        }
411                                        D3DXVECTOR2 edgeDirUnitExt(1.0f, (vertexData[edge1].tex1().y - vertexData[edge0].tex1().y) /
412                                                (vertexData[edge1].tex1().x - vertexData[edge0].tex1().x));
413                                        edgeDirUnitExt *= 1.0/ATLASSIZE;
414                                        if(vertexData[edge1].tex1().x > vertexData[edge0].tex1().x)
415                                        {
416                                                pevData[iEdge * 2].tex1() -= edgeDirUnitExt;
417                                                pevData[iEdge * 2 + 1].tex1() += edgeDirUnitExt;
418                                        }
419                                        else
420                                        {
421                                                pevData[iEdge * 2].tex1() += edgeDirUnitExt;
422                                                pevData[iEdge * 2 + 1].tex1() -= edgeDirUnitExt;
423                                        }
424                                }
425                                else
426                                {
427                                        if(vertexData[inner].tex1().x <= vertexData[edge0].tex1().x +
428                                                (vertexData[inner].tex1().y - vertexData[edge0].tex1().y) *
429                                                (vertexData[edge1].tex1().x - vertexData[edge0].tex1().x) /
430                                                (vertexData[edge1].tex1().y - vertexData[edge0].tex1().y))
431                                        {
432                                                pevData[iEdge * 2].tex1().x += 1.0/DBLATLASSIZE;
433                                                pevData[iEdge * 2 + 1].tex1().x += 1.0/DBLATLASSIZE;
434                                        }
435                                        else
436                                        {
437                                                pevData[iEdge * 2].tex1().x -= 1.0/DBLATLASSIZE;
438                                                pevData[iEdge * 2 + 1].tex1().x -= 1.0/DBLATLASSIZE;
439                                        }
440                                        D3DXVECTOR2 edgeDirUnitExt((vertexData[edge1].tex1().x - vertexData[edge0].tex1().x) /
441                                                (vertexData[edge1].tex1().y - vertexData[edge0].tex1().y), 1.0f);
442                                        edgeDirUnitExt *= 1.0/ATLASSIZE;
443                                        if(vertexData[edge1].tex1().y > vertexData[edge0].tex1().y)
444                                        {
445                                                pevData[iEdge * 2].tex1() -= edgeDirUnitExt;
446                                                pevData[iEdge * 2 + 1].tex1() += edgeDirUnitExt;
447                                        }
448                                        else
449                                        {
450                                                pevData[iEdge * 2].tex1() += edgeDirUnitExt;
451                                                pevData[iEdge * 2 + 1].tex1() -= edgeDirUnitExt;
452                                        }
453                                }
454
455                                iEdge++;
456                                (*iSubMesh)->edgeCount++;
457                        }
458                }
459        }
460        nEdges = iEdge;
461
462        edgeVertexBuffer->Unlock();
463        vertexBuffer->Unlock();
464        indexBuffer->Unlock();
465        SAFE_RELEASE(vertexBuffer);
466        SAFE_RELEASE(indexBuffer);
467        mesh->UnlockAttributeBuffer();
468
469        delete pAdj;
470}
471
472void Mesh::saveMesh()
473{
474        D3DXMATERIAL * materials = new D3DXMATERIAL[subMeshes.size()];
475        D3DXEFFECTINSTANCE * shaders = new D3DXEFFECTINSTANCE[subMeshes.size()];
476
477        std::vector<SubMesh*>::iterator iSubMesh = subMeshes.begin();
478        int i =0;
479        while(iSubMesh != subMeshes.end())
480        {
481                materials[i] = (*iSubMesh)->material;
482                addShaderString(shaders[i], "bumpFileName",  (*iSubMesh)->bumpFileName);
483                iSubMesh++;
484                i++;
485        }
486
487        char sname[256];
488        printf(sname, "%s_partitioned.x", name);
489        D3DXSaveMeshToX(L::l+sname,     //LPCTSTR pFilename,
490                                        mesh,   //LPD3DXMESH pMesh,
491                                        NULL,   //CONST DWORD * pAdjacency,
492                                        materials,      //CONST D3DXMATERIAL * pMaterials,
493                                        shaders,        //CONST D3DXEFFECTINSTANCE * pEffectInstances,
494                                        subMeshes.size(),       //DWORD NumMaterials,
495                                        D3DXF_FILEFORMAT_TEXT   //DWORD Format
496                                        );
497
498        delete materials;
499        delete shaders;
500}
501
502void Mesh::addShaderString(D3DXEFFECTINSTANCE& e, LPCSTR name, LPCSTR value)
503{
504        for(int i=0; i<e.NumDefaults; i++)
505        {
506                if(strcmp(e.pDefaults[i].pParamName, name) == 0)
507                {
508                        delete e.pDefaults[i].pValue;
509                        e.pDefaults[i].Type = D3DXEDT_STRING;
510                        e.pDefaults[i].NumBytes = strlen(name) + 1;
511                        e.pDefaults[i].pValue = new char[e.pDefaults[i].NumBytes];
512                        strcpy((LPSTR)e.pDefaults[i].pValue, value);
513                        return;
514                }
515        }
516        D3DXEFFECTDEFAULT* oldDefaults = e.pDefaults;
517        D3DXEFFECTDEFAULT* newDefaults = new D3DXEFFECTDEFAULT[e.NumDefaults+1];
518       
519        for(int u=0; u<e.NumDefaults; u++)
520        {
521                newDefaults[u] = oldDefaults[u];
522        }
523        delete oldDefaults;
524
525        newDefaults[e.NumDefaults].Type = D3DXEDT_STRING;
526        newDefaults[e.NumDefaults].NumBytes = strlen(name) + 1;
527        newDefaults[e.NumDefaults].pValue = new char[e.pDefaults[i].NumBytes];
528        strcpy((LPSTR)newDefaults[e.NumDefaults].pValue, value);
529        newDefaults[e.NumDefaults].pParamName = new char[strlen(name)+1];
530        strcpy((LPSTR)newDefaults[e.NumDefaults].pParamName, name);
531        e.NumDefaults++;
532}
533
534const char* Mesh::getName()
535{
536        return name;
537}
538
539HRESULT Mesh::loadMeshFromOgreXML(
540                        LPCWSTR filename,
541                        DWORD options,
542                        LPDIRECT3DDEVICE9 device,
543                        LPD3DXBUFFER *materialBuffer,
544                        LPD3DXBUFFER *shaderBuffer,
545                        DWORD *nMaterials,
546                        XMLNode& xMaterials,
547                        wchar_t**& materialNames,
548                LPD3DXMESH *ppMesh)
549{
550
551        XMLNode xMainNode=XMLNode::openFileHelper(filename, L"mesh");
552
553        DWORD nVertices = _wtoi( xMainNode/L"sharedGeometry"|L"vertexCount" );
554
555        XMLNode xSubmeshesNode = xMainNode/L"submeshes";
556
557        DWORD nSubMeshes = xSubmeshesNode.nChildNode(L"submesh");
558
559        DWORD nFaces = 0;
560        for(int u=0; u < nSubMeshes; u++)
561        {
562                nFaces += _wtoi(xSubmeshesNode.getChildNode(L"submesh", u)/L"faces"|L"count");
563        }
564
565        DWORD fvf = 0;
566
567        XMLNode xVertexBufferNode = xMainNode/L"sharedGeometry"/L"vertexbuffer";
568
569        if( wcscmp( xVertexBufferNode|L"positions", L"true" ) == 0)
570                fvf |= D3DFVF_XYZ;
571        if( wcscmp( xVertexBufferNode|L"normals", L"true" ) == 0)
572                fvf |= D3DFVF_NORMAL;
573        if( wcscmp( xVertexBufferNode|L"colours_diffuse", L"true" ) == 0)
574                fvf |= D3DFVF_DIFFUSE;
575        if( wcscmp( xVertexBufferNode|L"colours_specular", L"true" ) == 0)
576                fvf |= D3DFVF_SPECULAR;
577
578        DWORD nTexCoords = _wtoi( xVertexBufferNode|L"texture_coords" );
579        fvf |= D3DFVF_TEX1 * nTexCoords;
580
581        HRESULT hr = D3DXCreateMeshFVF(
582                nFaces,         //DWORD NumFaces,
583        nVertices,              //DWORD NumVertices,
584        options,                //DWORD Options,
585        fvf,                    //DWORD FVF,
586        device,
587        ppMesh);                        //LPD3DXMESH* ppMesh);
588
589        LPD3DXMESH pMesh = *ppMesh;
590
591        LPDIRECT3DVERTEXBUFFER9 vertexBuffer;
592        pMesh->GetVertexBuffer(&vertexBuffer);
593        FlexVertexArray vertexData(pMesh->GetNumBytesPerVertex());
594        D3DVERTEXELEMENT9 elem[64];     pMesh->GetDeclaration(elem);     FlexVertex::setFormat(elem);
595        vertexBuffer->Lock(0,pMesh->GetNumVertices()*pMesh->GetNumBytesPerVertex(),vertexData.getDataPointerReference(),0);
596        LPDIRECT3DINDEXBUFFER9 indexBuffer;
597        pMesh->GetIndexBuffer(&indexBuffer);
598        unsigned short* indexData;
599        indexBuffer->Lock(0,pMesh->GetNumFaces()*3*sizeof(unsigned short),(void**)&indexData,0);
600        DWORD* attributeArray;
601        pMesh->LockAttributeBuffer(0, &attributeArray);
602
603        for(int ivi=0; ivi < nVertices; ivi++)
604        {
605                XMLNode xVertexNode = xVertexBufferNode.getChildNode(L"vertex", ivi);
606                XMLNode xVertexPositionNode = xVertexNode/L"position";
607                D3DXVECTOR3 dvipos(
608                        _wtof( xVertexPositionNode|L"x" ),
609                        _wtof( xVertexPositionNode|L"y" ),
610                        _wtof( xVertexPositionNode|L"z" )
611                        );
612                vertexData[ivi].pos() = dvipos;
613
614                XMLNode xVertexNormalNode = xVertexNode/L"normal";
615                D3DXVECTOR3 dvinormal(
616                        _wtof( xVertexNormalNode|L"x" ),
617                        _wtof( xVertexNormalNode|L"y" ),
618                        _wtof( xVertexNormalNode|L"z" )
619                        );
620                vertexData[ivi].normal() = dvinormal;
621
622                for(int tuxi=0; tuxi < nTexCoords; tuxi++)
623                {
624                        XMLNode xVertexTexNode = xVertexNode.getChildNode(L"texcoord", tuxi);
625                        D3DXVECTOR2 dvitex(
626                                _wtof( xVertexTexNode|L"u" ),
627                                _wtof( xVertexTexNode|L"v" )
628                                );
629                        vertexData[ivi].tex(tuxi) = dvitex;
630                }
631        }
632
633        D3DXCreateBuffer(sizeof(D3DXMATERIAL) * nSubMeshes, materialBuffer);
634        D3DXCreateBuffer(sizeof(D3DXEFFECTINSTANCE) * nSubMeshes, shaderBuffer);
635
636        D3DXMATERIAL* materialArray = (D3DXMATERIAL*)(*materialBuffer)->GetBufferPointer();
637        D3DXEFFECTINSTANCE* shaderArray = (D3DXEFFECTINSTANCE*)(*shaderBuffer)->GetBufferPointer();
638
639        *nMaterials = nSubMeshes;
640
641        materialNames = new wchar_t*[nSubMeshes+1];
642        materialNames[nSubMeshes] = NULL;
643
644        unsigned int indexBufferFiller = 0;
645        for(int fifi=0; fifi < nSubMeshes; fifi++)
646        {
647                attributeArray[indexBufferFiller/3] = fifi;
648
649                XMLNode xSubMeshNode = xSubmeshesNode.getChildNode(L"submesh", fifi);
650
651                D3DXMATERIAL mat;
652                mat.pTextureFilename = LC::c.clone(
653                        (
654                        xMaterials.getChildNodeWithAttribute(L"material", L"name",
655                        xSubMeshNode|L"material")|L"texture"
656                        ));
657
658                materialNames[fifi] = L::cloneW( xSubMeshNode|L"material" );
659                materialArray[fifi] = mat;
660
661                D3DXEFFECTINSTANCE efi;
662                efi.NumDefaults = 0;
663                efi.pDefaults = NULL;
664                efi.pEffectFilename = NULL;
665                shaderArray[fifi] = efi;
666
667                XMLNode xSubMeshFacesNode = xSubMeshNode/L"faces";
668                unsigned int nSubMeshFaces = _wtoi( xSubMeshFacesNode|L"count" );
669                for(int fido=0; fido<nSubMeshFaces; fido++)
670                {
671                        XMLNode xFaceNode = xSubMeshFacesNode.getChildNode(L"face", fido);
672                        indexData[indexBufferFiller++] = _wtoi( xFaceNode|L"v1" );
673                        indexData[indexBufferFiller++] = _wtoi( xFaceNode|L"v2" );
674                        indexData[indexBufferFiller++] = _wtoi( xFaceNode|L"v3" );
675                }
676        }
677
678        vertexBuffer->Unlock();
679        indexBuffer->Unlock();
680        vertexBuffer->Release();
681        indexBuffer->Release();
682        pMesh->UnlockAttributeBuffer();
683
684        return S_OK;
685}
686
687const DWORD Mesh::DirectXMesh(0);
688const DWORD Mesh::OgreXMLMesh(1);
689
690void Mesh::saveSceneInfo(std::ofstream& psf)
691{
692        psf << "mesh " << name << '\n';
693        psf << "{\n";
694        psf << "\togrefile " << LC::c-ogreFileName << '\n';
695        psf << "\tpathmapresolution " << prmAtlasSize  << '\n';
696        psf << "\tdivide 1\n";
697        psf << "}\n";
698}
Note: See TracBrowser for help on using the repository browser.