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

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