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

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