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

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