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

Revision 2197, 18.6 KB checked in by szirmay, 17 years ago (diff)
Line 
1#include "dxstdafx.h"
2#include ".\meshexploder.h"
3#include "TriangleMesh.h"
4#include "Vector.hpp"
5#include "L.h"
6#include <vector>
7#include <fstream>
8#include "xmlwriter.h"
9#include "FlexVertex.h"
10
11using namespace xmlw;
12
13MeshExploder::MeshExploder(LPDIRECT3DDEVICE9 device, LPD3DXMESH originalMesh, D3DXMATERIAL* originalMaterials, wchar_t** materialNames, D3DXEFFECTINSTANCE* originalShaders, unsigned int nPieces)
14{
15        this->device = device;
16        this->originalMesh = originalMesh;
17        this->originalMaterials = originalMaterials;
18        this->originalShaders = originalShaders;
19        this->nPieces = nPieces;
20
21        this->materialNames = materialNames;
22
23        fragmentMeshes = NULL;
24        fragmentAttribIndices = NULL;
25        composedMaterials = NULL;
26        composedShaders = NULL;
27        composedMaterialNames = NULL;
28}
29
30MeshExploder::~MeshExploder(void)
31{
32        if(fragmentMeshes)
33        {
34                for(int f=0; f<nPieces; f++)
35                {
36                        fragmentMeshes[f]->Release();
37                }
38                delete [] fragmentMeshes;
39        }
40        if(fragmentAttribIndices)
41                delete [] fragmentAttribIndices;
42
43        //we need these as output
44/*      if(composedMaterials)
45                delete [] composedMaterials;
46        if(composedShaders)
47                delete [] composedShaders;*/
48
49        if(composedMaterialNames)
50                delete [] composedMaterialNames;
51}
52
53struct Tri
54{
55        unsigned short origMeshIndex;
56        Vector pos;
57        Vector normal;
58};
59
60void MeshExploder::explode()
61{
62        fragmentMeshes = new LPD3DXMESH[nPieces];
63        fragmentAttribIndices = new DWORD[nPieces];
64
65        originalMesh->OptimizeInplace(D3DXMESHOPT_ATTRSORT, NULL, NULL, NULL, NULL);
66
67        LPDIRECT3DVERTEXBUFFER9 vertexBuffer;
68        originalMesh->GetVertexBuffer(&vertexBuffer);
69
70        FlexVertexArray vertexData(originalMesh->GetNumBytesPerVertex());
71        D3DVERTEXELEMENT9 elem[64];     originalMesh->GetDeclaration(elem);      FlexVertex::setFormat(elem);
72        vertexBuffer->Lock(0,originalMesh->GetNumVertices()*originalMesh->GetNumBytesPerVertex(),vertexData.getDataPointerReference(),0);
73
74        LPDIRECT3DINDEXBUFFER9 indexBuffer;
75        originalMesh->GetIndexBuffer(&indexBuffer);
76       
77        DWORD nSubsets;
78        originalMesh->GetAttributeTable(NULL, &nSubsets);
79        D3DXATTRIBUTERANGE* subsetRanges = new D3DXATTRIBUTERANGE[nSubsets];
80        originalMesh->GetAttributeTable(subsetRanges, &nSubsets);
81
82        unsigned int piecesToGo =  nPieces;
83        unsigned int facesToGo =  originalMesh->GetNumFaces();
84        int iPiece=0;
85
86        for(int iSubset=0; iSubset<nSubsets; iSubset++)
87        {
88
89                unsigned int nTris = subsetRanges[iSubset].FaceCount;
90
91                unsigned int pcsPerSubset = piecesToGo * nTris / facesToGo;
92                while(piecesToGo - pcsPerSubset < nSubsets - 1 - iSubset )
93                        pcsPerSubset--;
94                if(pcsPerSubset < 1)
95                        pcsPerSubset = 1;
96                piecesToGo -= pcsPerSubset;
97                facesToGo -= nTris;
98
99                unsigned short* indexData;
100                indexBuffer->Lock(subsetRanges[iSubset].FaceStart*3*sizeof(unsigned short),
101                                                nTris*3*sizeof(unsigned short),
102                                                (void**)&indexData,0);
103
104                Tri* tris = new Tri[nTris];
105                //partition to small meshes
106                for(int g=0; g<nTris; g++)
107                {
108                        tris[g].origMeshIndex = g;
109                        tris[g].pos =   (vertexData[indexData[g * 3]].pos() +
110                                                        vertexData[indexData[g * 3 + 1]].pos() +
111                                                        vertexData[indexData[g * 3 + 2]].pos()) * 0.33333333333333;
112                        tris[g].normal =        (vertexData[indexData[g * 3]].normal() +
113                                                        vertexData[indexData[g * 3 + 1]].normal() +
114                                                        vertexData[indexData[g * 3 + 2]].normal());
115                        tris[g].normal.normalize();
116                }
117
118                int* slabNTris = new int[pcsPerSubset];
119                clusterTrisKMeans(tris, nTris, pcsPerSubset, slabNTris);
120                int triClusterStart = 0;
121
122                for(int ict=0; ict<pcsPerSubset; ict++)
123                {
124                        // count vertices
125                        unsigned short* ill = new unsigned short[originalMesh->GetNumVertices()];
126                        for(int zzz=0; zzz<originalMesh->GetNumVertices(); zzz++)
127                                ill[zzz] = 0;
128                        for(int rmi = triClusterStart; rmi<triClusterStart + slabNTris[ict]; rmi++)
129                        {
130                                ill[indexData[tris[rmi].origMeshIndex*3]] = 1;
131                                ill[indexData[tris[rmi].origMeshIndex*3+1]] = 1;
132                                ill[indexData[tris[rmi].origMeshIndex*3+2]] = 1;
133                        }
134
135                        int nVertices = 0;
136                        for(int ccc=0; ccc<originalMesh->GetNumVertices(); ccc++)
137                                if(ill[ccc])
138                                        nVertices++;
139
140                        LPD3DXMESH fragMesh;
141                        // create new mesh
142                        HRESULT dhre = D3DXCreateMeshFVF(
143                                slabNTris[ict],
144                                nVertices,
145                                0,
146                                originalMesh->GetFVF(),
147                                device,
148                                &fragMesh);
149                        // fill with tris
150                        LPDIRECT3DVERTEXBUFFER9 svertexBuffer;
151                        fragMesh->GetVertexBuffer(&svertexBuffer);
152                        FlexVertexArray svertexData(fragMesh->GetNumBytesPerVertex());
153                        svertexBuffer->Lock(0, nVertices * fragMesh->GetNumBytesPerVertex(),svertexData.getDataPointerReference(),0);
154                        LPDIRECT3DINDEXBUFFER9 sindexBuffer;
155                        fragMesh->GetIndexBuffer(&sindexBuffer);
156                        unsigned short* sindexData;
157                        sindexBuffer->Lock(0,slabNTris[ict]*3*sizeof(unsigned short),(void**)&sindexData,0);
158
159                        int ufi = 0;
160                        for(int ifi=0; ifi<originalMesh->GetNumVertices(); ifi++)
161                                if(ill[ifi])
162                                {
163                                        //svertexData[ufi] = vertexData[ifi];
164                                        svertexData.assign(ufi, vertexData[ifi]);
165                                        ill[ifi] = ufi;
166                                        ufi++;
167                                }
168                                else
169                                        ill[ifi] = 0xffff;
170
171                        for(int trifi=0; trifi<slabNTris[ict]; trifi++)
172                        {
173                                sindexData[trifi*3] = ill[indexData[tris[trifi+triClusterStart].origMeshIndex*3]];
174                                sindexData[trifi*3+1] = ill[indexData[tris[trifi+triClusterStart].origMeshIndex*3+1]];
175                                sindexData[trifi*3+2] = ill[indexData[tris[trifi+triClusterStart].origMeshIndex*3+2]];
176                        }
177
178                        svertexBuffer->Unlock();
179                        sindexBuffer->Unlock();
180                        svertexBuffer->Release();
181                        sindexBuffer->Release();
182
183                        triClusterStart += slabNTris[ict];
184
185                        fragmentMeshes[iPiece] = fragMesh;
186                        fragmentAttribIndices[iPiece] = iSubset;
187                        iPiece++;
188                }
189
190                indexBuffer->Unlock();
191        }
192
193        vertexBuffer->Unlock();
194        vertexBuffer->Release();
195        indexBuffer->Release();
196
197        delete subsetRanges;
198}
199
200
201void MeshExploder::clusterTrisKMeans(Tri* triArray, int nTris, int nClusters, int* clusterLenghts)
202{
203        Tri* centroids = new Tri[nClusters];
204        std::vector<Tri>* result = new std::vector<Tri>[nClusters];
205
206        //initial clusters: uniform length
207        for(unsigned int i=0; i<nClusters; i++)
208                clusterLenghts[i] = nTris / nClusters;
209        clusterLenghts[nClusters - 1] = nTris - (nClusters - 1) * (nTris / nClusters);
210        for(unsigned int iKMeans = 0; iKMeans < 128; iKMeans++)
211        {
212                //find centroids
213                unsigned int iTri = 0;
214                for(unsigned int i=0; i<nClusters; i++)
215                {
216                        centroids[i].pos = Vector::RGBBLACK;
217                        centroids[i].normal = Vector::RGBBLACK;
218                        for(unsigned int iTriInCluster=0; iTriInCluster < clusterLenghts[i]; iTriInCluster++, iTri++)
219                        {
220                                centroids[i].pos += triArray[iTri].pos;
221                                centroids[i].normal += triArray[iTri].normal;
222                        }
223                        centroids[i].pos *= 1.0f / (float)clusterLenghts[i];
224                        centroids[i].normal.normalize();
225                }
226               
227                for(unsigned int i=0; i<nClusters; i++)
228                        result[i].clear();
229
230                //sort radions to centroids
231                iTri = 0;
232                for(unsigned int i=0; i<nClusters; i++)
233                {
234                        for(unsigned int iTriInCluster=0; iTriInCluster < clusterLenghts[i]; iTriInCluster++, iTri++)
235                        {
236                                unsigned int minimumDistanceClusterIndex = 0;
237                                float minimumDistance = FLT_MAX;
238                                for(unsigned int u=0; u<nClusters; u++)
239                                {
240                                        float dirDist = (triArray[iTri].normal * centroids[u].normal);
241                                        float dist = (triArray[iTri].pos - centroids[u].pos).norm() * pow(2.0, 1.0 - (double)dirDist);
242                                        if(dist < minimumDistance)
243                                        {
244                                                minimumDistanceClusterIndex = u;
245                                                minimumDistance = dist;
246                                        }
247                                }
248                                result[minimumDistanceClusterIndex].push_back( triArray[iTri] );
249                        }
250                }
251                //refill bushStarters, set cluster lengths
252                iTri = 0;
253                for(unsigned int i=0; i<nClusters; i++)
254                {
255                        clusterLenghts[i] = result[i].size();
256                        for(unsigned int iTriInCluster=0; iTriInCluster < clusterLenghts[i]; iTriInCluster++, iTri++)
257                        {
258                                triArray[iTri] = result[i].at(iTriInCluster);
259                        }
260                }
261                //eliminate empty clusters
262                for(unsigned int i=1; i<nClusters; i++)
263                {
264                        if(clusterLenghts[i] == 0)
265                        {
266                                clusterLenghts[i] = clusterLenghts[i-1] >> 1;
267                                clusterLenghts[i-1] -= clusterLenghts[i-1] >> 1;
268                        }
269                }
270                for(int i=nClusters - 1; i >= 0; i--)
271                {
272                        if(clusterLenghts[i] == 0)
273                        {
274                                clusterLenghts[i] = clusterLenghts[i+1] >> 1;
275                                clusterLenghts[i+1] -= clusterLenghts[i+1] >> 1;
276                        }
277                }
278        }
279        delete [] centroids;
280        delete [] result;
281}
282
283void MeshExploder::saveFragMeshes()
284{
285        for(int i=0; i<nPieces; i++)
286        {
287                char sname[256];
288                sprintf(sname, "media/explode_fragment%d.x", i);
289                HRESULT hr = D3DXSaveMeshToX(L::l+sname,        //LPCTSTR pFilename,
290                                                fragmentMeshes[i],      //LPD3DXMESH pMesh,
291                                                NULL,   //CONST DWORD * pAdjacency,
292                                                NULL,   //CONST D3DXMATERIAL * pMaterials,
293                                                NULL,   //CONST D3DXEFFECTINSTANCE * pEffectInstances,
294                                                0,      //DWORD NumMaterials,
295                                                D3DXF_FILEFORMAT_TEXT   //DWORD Format
296                                                );
297        }
298}
299
300void MeshExploder::generateAtlas(int atlasSize)
301{
302        for(int i=0; i<nPieces; i++)
303        {
304
305                LPD3DXMESH tempMesh;
306
307                float maxStretchApplied;
308                unsigned int nCharts;
309
310                HRESULT hr =
311                        D3DXUVAtlasCreate(
312                                fragmentMeshes[i],              //      LPD3DXMESH pMesh,
313                                0,                      //      UINT dwMaxChartNumber,
314                                1.0f,           //      FLOAT fMaxStretch,
315                                atlasSize - 4,          //      UINT dwWidth,
316                                atlasSize - 4,          //      UINT dwHeight,
317                                2.0f,           //      FLOAT fGutter,
318                                (originalMesh->GetFVF() & D3DFVF_TEXCOUNT_MASK) / D3DFVF_TEX1 - 1,      //      DWORD dwTextureIndex,
319                                NULL,           //      CONST DWORD * pdwAdjacency,
320                                NULL,           //      CONST CHAR * pcFalseEdges,
321                                NULL,           //      FLOAT * pfIMTArray,
322                                NULL,           //      LPD3DXUVATLASCB pCallback,
323                                0.001f,         //      FLOAT fCallbackFrequency,
324                                NULL,           //      LPVOID pUserContent,
325                                0,      // options
326                                &tempMesh,      //      LPD3DXMESH * ppMeshOut,
327                                NULL,           //      LPD3DXBUFFER * ppFacePartitioning,
328                                NULL,           //      LPD3DXBUFFER * ppVertexRemapArray,
329                                &maxStretchApplied,     //      FLOAT * pfMaxStretchOut,
330                                &nCharts                        //      UINT * pdwNumChartsOut
331                        );
332
333                if(hr == S_OK)
334                {
335                        //forget the old mesh
336                        fragmentMeshes[i]->Release();
337                        fragmentMeshes[i] = tempMesh;
338                }
339
340                LPDIRECT3DVERTEXBUFFER9 vertexBuffer;
341                fragmentMeshes[i]->GetVertexBuffer(&vertexBuffer);
342                FlexVertexArray vertexData(fragmentMeshes[i]->GetNumBytesPerVertex());
343                D3DVERTEXELEMENT9 elem[64];     fragmentMeshes[i]->GetDeclaration(elem);         FlexVertex::setFormat(elem);
344                vertexBuffer->Lock(0,fragmentMeshes[i]->GetNumVertices()*fragmentMeshes[i]->GetNumBytesPerVertex(),vertexData.getDataPointerReference(),0);
345
346                for(unsigned int u=0; u < fragmentMeshes[i]->GetNumVertices(); u++ )
347                        vertexData[u].tex1() = (vertexData[u].tex1() * (atlasSize - 4) + D3DXVECTOR2(2.0,2.0)) / (float)atlasSize;
348
349                vertexBuffer->Unlock();
350                vertexBuffer->Release();
351        }
352}
353
354void MeshExploder::merge()
355{
356        int sumVertices=0;
357        int sumFaces=0;
358        for(int i=0; i<nPieces; i++)
359        {
360                sumVertices += fragmentMeshes[i]->GetNumVertices();
361                sumFaces += fragmentMeshes[i]->GetNumFaces();
362        }
363
364        composedMaterials = new D3DXMATERIAL[nPieces];
365        composedShaders = new D3DXEFFECTINSTANCE[nPieces];
366        composedMaterialNames = new wchar_t*[nPieces];
367
368        for(int t=0; t<nPieces; t++)
369        {
370                composedMaterials[t] = originalMaterials[fragmentAttribIndices[t]];
371                composedShaders[t] = originalShaders[fragmentAttribIndices[t]];
372                composedMaterialNames[t] = materialNames[fragmentAttribIndices[t]];
373        }
374
375        HRESULT dhre = D3DXCreateMeshFVF(
376                sumFaces,
377                sumVertices,
378                0,
379                originalMesh->GetFVF(),
380                device,
381                &composedMesh);
382
383        LPDIRECT3DVERTEXBUFFER9 composedVertexBuffer;
384        composedMesh->GetVertexBuffer(&composedVertexBuffer);
385        FlexVertexArray composedVertexData(composedMesh->GetNumBytesPerVertex());
386        D3DVERTEXELEMENT9 elem[64];     composedMesh->GetDeclaration(elem);      FlexVertex::setFormat(elem);
387        composedVertexBuffer->Lock(0,composedMesh->GetNumVertices()*composedMesh->GetNumBytesPerVertex(),composedVertexData.getDataPointerReference(),0);
388
389        LPDIRECT3DINDEXBUFFER9 composedIndexBuffer;
390        composedMesh->GetIndexBuffer(&composedIndexBuffer);
391        unsigned short* composedIndexData;
392        composedIndexBuffer->Lock(0,
393                                                composedMesh->GetNumFaces()*3*sizeof(unsigned short),
394                                                (void**)&composedIndexData,0);
395
396        DWORD* composedAttributeData;
397        composedMesh->LockAttributeBuffer(0, &composedAttributeData);
398
399        int vertexOffset = 0;
400        int faceOffset = 0;
401
402        for(int f=0; f<nPieces; f++)
403        {
404                LPDIRECT3DVERTEXBUFFER9 fragmentVertexBuffer;
405                fragmentMeshes[f]->GetVertexBuffer(&fragmentVertexBuffer);
406                FlexVertexArray fragmentVertexData(fragmentMeshes[f]->GetNumBytesPerVertex());
407                fragmentVertexBuffer->Lock(0,fragmentMeshes[f]->GetNumVertices()*fragmentMeshes[f]->GetNumBytesPerVertex(),fragmentVertexData.getDataPointerReference(),0);
408
409                LPDIRECT3DINDEXBUFFER9 fragmentIndexBuffer;
410                fragmentMeshes[f]->GetIndexBuffer(&fragmentIndexBuffer);
411                unsigned short* fragmentIndexData;
412                fragmentIndexBuffer->Lock(0,
413                                                        fragmentMeshes[f]->GetNumFaces()*3*sizeof(unsigned short),
414                                                        (void**)&fragmentIndexData,0);
415
416                for(int iv=0; iv<fragmentMeshes[f]->GetNumVertices(); iv++)
417                        composedVertexData.assign(iv + vertexOffset, fragmentVertexData[iv]);
418                        //composedVertexData[iv + vertexOffset] = fragmentVertexData[iv];
419                for(int ic=0; ic<fragmentMeshes[f]->GetNumFaces(); ic++)
420                {
421                        composedAttributeData[ic + faceOffset] = f;
422                        composedIndexData[(ic + faceOffset) * 3] = fragmentIndexData[ic * 3] + vertexOffset;
423                        composedIndexData[(ic + faceOffset) * 3 + 1] = fragmentIndexData[ic * 3 + 1] + vertexOffset;
424                        composedIndexData[(ic + faceOffset) * 3 + 2] = fragmentIndexData[ic * 3 + 2] + vertexOffset;
425                }
426                fragmentVertexBuffer->Unlock();
427                fragmentVertexBuffer->Release();
428                fragmentIndexBuffer->Unlock();
429                fragmentIndexBuffer->Release();
430
431                vertexOffset += fragmentMeshes[f]->GetNumVertices();
432                faceOffset += fragmentMeshes[f]->GetNumFaces();
433        }
434
435        composedMesh->UnlockAttributeBuffer();
436
437        composedVertexBuffer->Unlock();
438        composedVertexBuffer->Release();
439        composedIndexBuffer->Unlock();
440        composedIndexBuffer->Release();
441}
442
443void MeshExploder::saveComposedMesh(LPCSTR name)
444{
445        char sname[256];
446        sprintf(sname, "processedMeshes/%s.x", name);
447        HRESULT hr = D3DXSaveMeshToX(L::l+sname,        //LPCTSTR pFilename,
448                                        composedMesh,   //LPD3DXMESH pMesh,
449                                        NULL,   //CONST DWORD * pAdjacency,
450                                        composedMaterials,      //CONST D3DXMATERIAL * pMaterials,
451                                        composedShaders,        //CONST D3DXEFFECTINSTANCE * pEffectInstances,
452                                        nPieces,        //DWORD NumMaterials,
453                                        D3DXF_FILEFORMAT_TEXT   //DWORD Format
454                                        );
455}
456
457void MeshExploder::saveComposedMeshToOgreXML(LPCSTR name)
458{
459        char sname[256];
460        sprintf(sname, "processedMeshes/%s.mesh.xml", name);
461
462        std::ofstream f(sname);
463        XmlStream xml(f);
464
465        DWORD mfvf = composedMesh->GetFVF();
466        unsigned int nTexCoords = ( mfvf & D3DFVF_TEXCOUNT_MASK) / D3DFVF_TEX1;
467
468        xml << tag("mesh");
469        xml << tag("sharedgeometry")
470                << attr("vertexcount") << composedMesh->GetNumVertices();
471               
472                xml << tag("vertexbuffer");
473                if(mfvf & D3DFVF_XYZ)
474                        xml << attr("positions") << "true";
475                else
476                        xml << attr("positions") << "false";
477                if(mfvf & D3DFVF_NORMAL)
478                        xml << attr("normals") << "true";
479                else
480                        xml << attr("normals") << "false";
481                if(mfvf & D3DFVF_DIFFUSE)
482                        xml << attr("colours_diffuse") << "true";
483                else
484                        xml << attr("colours_diffuse") << "false";
485                if(mfvf & D3DFVF_SPECULAR)
486                        xml << attr("colours_specular") << "true";
487                else
488                        xml << attr("colours_specular") << "false";
489                xml << attr("texture_coords") << nTexCoords;
490
491        LPDIRECT3DVERTEXBUFFER9 composedVertexBuffer;
492        composedMesh->GetVertexBuffer(&composedVertexBuffer);
493        FlexVertexArray composedVertexData(composedMesh->GetNumBytesPerVertex());
494        D3DVERTEXELEMENT9 elem[64];     composedMesh->GetDeclaration(elem);      FlexVertex::setFormat(elem);
495        composedVertexBuffer->Lock(0,composedMesh->GetNumVertices()*composedMesh->GetNumBytesPerVertex(),composedVertexData.getDataPointerReference(),0);
496
497        LPDIRECT3DINDEXBUFFER9 composedIndexBuffer;
498        composedMesh->GetIndexBuffer(&composedIndexBuffer);
499        unsigned short* composedIndexData;
500        composedIndexBuffer->Lock(0,
501                                                composedMesh->GetNumFaces()*3*sizeof(unsigned short),
502                                                (void**)&composedIndexData,0);
503
504        DWORD* composedAttributeData;
505        composedMesh->LockAttributeBuffer(0, &composedAttributeData);
506
507        for(int xvi = 0; xvi < composedMesh->GetNumVertices(); xvi++)
508        {
509                xml << tag("vertex");
510                        if(mfvf & D3DFVF_XYZ)
511                        {
512                                xml << tag("position");
513                                        xml << attr("x") << composedVertexData[xvi].pos().x;
514                                        xml << attr("y") << composedVertexData[xvi].pos().y;
515                                        xml << attr("z") << composedVertexData[xvi].pos().z;
516                                xml << endtag();
517                        }
518                        if(mfvf & D3DFVF_NORMAL)
519                        {
520                                xml << tag("normal");
521                                        xml << attr("x") << composedVertexData[xvi].normal().x;
522                                        xml << attr("y") << composedVertexData[xvi].normal().y;
523                                        xml << attr("z") << composedVertexData[xvi].normal().z;
524                                xml << endtag();
525                        }
526                        if(mfvf & D3DFVF_DIFFUSE)
527                        {
528                                char colval[256];
529                                D3DCOLOR dc = composedVertexData[xvi].diffuse();
530                                unsigned char* pdc = (unsigned char*)&dc;
531                                sprintf(colval, "%f %f %f %f",
532                                        pdc[3],
533                                        pdc[0],
534                                        pdc[1],
535                                        pdc[2]
536                                        );
537                                xml << tag("colours_diffuse");
538                                        xml << attr("value") << colval;
539                                xml << endtag();
540                        }
541                        if(mfvf & D3DFVF_SPECULAR)
542                        {
543                                char colval[256];
544                                D3DCOLOR dc = composedVertexData[xvi].specular();
545                                unsigned char* pdc = (unsigned char*)&dc;
546                                sprintf(colval, "%f %f %f %f",
547                                        pdc[3],
548                                        pdc[0],
549                                        pdc[1],
550                                        pdc[2]
551                                        );
552                                xml << tag("colours_specular");
553                                        xml << attr("value") << colval;
554                                xml << endtag();
555                        }
556                        for(int taxi=0; taxi<nTexCoords; taxi++)
557                        {
558                                xml << tag("texcoord");
559                                        xml << attr("u") << composedVertexData[xvi].tex(taxi).x;
560                                        xml << attr("v") << composedVertexData[xvi].tex(taxi).y;
561                                xml << endtag();
562                        }
563
564                xml << endtag();
565        }
566
567        xml << endtag(); // end vertexbuffer
568        xml << endtag(); // end sharedgeometry
569
570        xml << tag("submeshes");
571        int faceOffset = 0;
572        for(int xai = 0; xai < nPieces; xai++)
573        {
574                xml << tag("submesh")
575                        << attr("material") << LC::c-composedMaterialNames[xai]
576                        << attr("use32bitindexes") << "true"
577                        << attr("usesharedvertices") << "true"
578                        << attr("operationtype") << "triangle_list";
579                       
580                        xml << tag("faces")
581                                << attr("count") << fragmentMeshes[xai]->GetNumFaces();
582                        for(int ic = 0; ic < fragmentMeshes[xai]->GetNumFaces(); ic++)
583                        {
584                                xml << tag("face")
585                                        << attr("v1") << composedIndexData[(ic + faceOffset) * 3]
586                                        << attr("v2") << composedIndexData[(ic + faceOffset) * 3 + 1]
587                                        << attr("v3") << composedIndexData[(ic + faceOffset) * 3 + 2];
588                                xml << endtag();
589                        }
590                        faceOffset += fragmentMeshes[xai]->GetNumFaces();
591                        xml << endtag();
592                xml << endtag();                       
593        }
594        xml << endtag(); // submeshes
595        xml << tag("submeshnames");
596        xml << endtag();
597
598        composedMesh->UnlockAttributeBuffer();
599
600        composedVertexBuffer->Unlock();
601        composedVertexBuffer->Release();
602        composedIndexBuffer->Unlock();
603        composedIndexBuffer->Release();
604}
Note: See TracBrowser for help on using the repository browser.