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

Revision 2304, 18.8 KB checked in by szirmay, 18 years ago (diff)
RevLine 
[2197]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());
[2304]71        D3DVERTEXELEMENT9 elem[64];     originalMesh->GetDeclaration(elem);      vertexData.setFormat(elem);
[2197]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
[2304]310                unsigned int atlasIndex = (originalMesh->GetFVF() & D3DFVF_TEXCOUNT_MASK) / D3DFVF_TEX1 - 1;
311
[2197]312                HRESULT hr =
313                        D3DXUVAtlasCreate(
314                                fragmentMeshes[i],              //      LPD3DXMESH pMesh,
315                                0,                      //      UINT dwMaxChartNumber,
316                                1.0f,           //      FLOAT fMaxStretch,
317                                atlasSize - 4,          //      UINT dwWidth,
318                                atlasSize - 4,          //      UINT dwHeight,
319                                2.0f,           //      FLOAT fGutter,
[2304]320                                atlasIndex,     //      DWORD dwTextureIndex,
[2197]321                                NULL,           //      CONST DWORD * pdwAdjacency,
322                                NULL,           //      CONST CHAR * pcFalseEdges,
323                                NULL,           //      FLOAT * pfIMTArray,
324                                NULL,           //      LPD3DXUVATLASCB pCallback,
325                                0.001f,         //      FLOAT fCallbackFrequency,
326                                NULL,           //      LPVOID pUserContent,
327                                0,      // options
328                                &tempMesh,      //      LPD3DXMESH * ppMeshOut,
329                                NULL,           //      LPD3DXBUFFER * ppFacePartitioning,
330                                NULL,           //      LPD3DXBUFFER * ppVertexRemapArray,
331                                &maxStretchApplied,     //      FLOAT * pfMaxStretchOut,
332                                &nCharts                        //      UINT * pdwNumChartsOut
333                        );
334
335                if(hr == S_OK)
336                {
337                        //forget the old mesh
338                        fragmentMeshes[i]->Release();
339                        fragmentMeshes[i] = tempMesh;
340                }
[2304]341                else
342                {
343                        MessageBoxA( NULL, "Sorry!", "Impossible to create UVatlas, please increase PRM resolution!", MB_OK);
344                }
[2197]345
346                LPDIRECT3DVERTEXBUFFER9 vertexBuffer;
347                fragmentMeshes[i]->GetVertexBuffer(&vertexBuffer);
348                FlexVertexArray vertexData(fragmentMeshes[i]->GetNumBytesPerVertex());
[2304]349                D3DVERTEXELEMENT9 elem[64];     fragmentMeshes[i]->GetDeclaration(elem);         vertexData.setFormat(elem);
[2197]350                vertexBuffer->Lock(0,fragmentMeshes[i]->GetNumVertices()*fragmentMeshes[i]->GetNumBytesPerVertex(),vertexData.getDataPointerReference(),0);
351
352                for(unsigned int u=0; u < fragmentMeshes[i]->GetNumVertices(); u++ )
[2304]353                        vertexData[u].tex(atlasIndex) = (vertexData[u].tex(atlasIndex) * (atlasSize - 4) + D3DXVECTOR2(2.0,2.0)) / (float)atlasSize;
[2197]354
355                vertexBuffer->Unlock();
356                vertexBuffer->Release();
357        }
358}
359
360void MeshExploder::merge()
361{
362        int sumVertices=0;
363        int sumFaces=0;
364        for(int i=0; i<nPieces; i++)
365        {
366                sumVertices += fragmentMeshes[i]->GetNumVertices();
367                sumFaces += fragmentMeshes[i]->GetNumFaces();
368        }
369
370        composedMaterials = new D3DXMATERIAL[nPieces];
371        composedShaders = new D3DXEFFECTINSTANCE[nPieces];
372        composedMaterialNames = new wchar_t*[nPieces];
373
374        for(int t=0; t<nPieces; t++)
375        {
376                composedMaterials[t] = originalMaterials[fragmentAttribIndices[t]];
377                composedShaders[t] = originalShaders[fragmentAttribIndices[t]];
378                composedMaterialNames[t] = materialNames[fragmentAttribIndices[t]];
379        }
380
381        HRESULT dhre = D3DXCreateMeshFVF(
382                sumFaces,
383                sumVertices,
384                0,
385                originalMesh->GetFVF(),
386                device,
387                &composedMesh);
388
389        LPDIRECT3DVERTEXBUFFER9 composedVertexBuffer;
390        composedMesh->GetVertexBuffer(&composedVertexBuffer);
391        FlexVertexArray composedVertexData(composedMesh->GetNumBytesPerVertex());
[2304]392        D3DVERTEXELEMENT9 elem[64];     composedMesh->GetDeclaration(elem);      composedVertexData.setFormat(elem);
[2197]393        composedVertexBuffer->Lock(0,composedMesh->GetNumVertices()*composedMesh->GetNumBytesPerVertex(),composedVertexData.getDataPointerReference(),0);
394
395        LPDIRECT3DINDEXBUFFER9 composedIndexBuffer;
396        composedMesh->GetIndexBuffer(&composedIndexBuffer);
397        unsigned short* composedIndexData;
398        composedIndexBuffer->Lock(0,
399                                                composedMesh->GetNumFaces()*3*sizeof(unsigned short),
400                                                (void**)&composedIndexData,0);
401
402        DWORD* composedAttributeData;
403        composedMesh->LockAttributeBuffer(0, &composedAttributeData);
404
405        int vertexOffset = 0;
406        int faceOffset = 0;
407
408        for(int f=0; f<nPieces; f++)
409        {
410                LPDIRECT3DVERTEXBUFFER9 fragmentVertexBuffer;
411                fragmentMeshes[f]->GetVertexBuffer(&fragmentVertexBuffer);
412                FlexVertexArray fragmentVertexData(fragmentMeshes[f]->GetNumBytesPerVertex());
413                fragmentVertexBuffer->Lock(0,fragmentMeshes[f]->GetNumVertices()*fragmentMeshes[f]->GetNumBytesPerVertex(),fragmentVertexData.getDataPointerReference(),0);
414
415                LPDIRECT3DINDEXBUFFER9 fragmentIndexBuffer;
416                fragmentMeshes[f]->GetIndexBuffer(&fragmentIndexBuffer);
417                unsigned short* fragmentIndexData;
418                fragmentIndexBuffer->Lock(0,
419                                                        fragmentMeshes[f]->GetNumFaces()*3*sizeof(unsigned short),
420                                                        (void**)&fragmentIndexData,0);
421
422                for(int iv=0; iv<fragmentMeshes[f]->GetNumVertices(); iv++)
423                        composedVertexData.assign(iv + vertexOffset, fragmentVertexData[iv]);
424                        //composedVertexData[iv + vertexOffset] = fragmentVertexData[iv];
425                for(int ic=0; ic<fragmentMeshes[f]->GetNumFaces(); ic++)
426                {
427                        composedAttributeData[ic + faceOffset] = f;
428                        composedIndexData[(ic + faceOffset) * 3] = fragmentIndexData[ic * 3] + vertexOffset;
429                        composedIndexData[(ic + faceOffset) * 3 + 1] = fragmentIndexData[ic * 3 + 1] + vertexOffset;
430                        composedIndexData[(ic + faceOffset) * 3 + 2] = fragmentIndexData[ic * 3 + 2] + vertexOffset;
431                }
432                fragmentVertexBuffer->Unlock();
433                fragmentVertexBuffer->Release();
434                fragmentIndexBuffer->Unlock();
435                fragmentIndexBuffer->Release();
436
437                vertexOffset += fragmentMeshes[f]->GetNumVertices();
438                faceOffset += fragmentMeshes[f]->GetNumFaces();
439        }
440
441        composedMesh->UnlockAttributeBuffer();
442
443        composedVertexBuffer->Unlock();
444        composedVertexBuffer->Release();
445        composedIndexBuffer->Unlock();
446        composedIndexBuffer->Release();
447}
448
449void MeshExploder::saveComposedMesh(LPCSTR name)
450{
451        char sname[256];
452        sprintf(sname, "processedMeshes/%s.x", name);
453        HRESULT hr = D3DXSaveMeshToX(L::l+sname,        //LPCTSTR pFilename,
454                                        composedMesh,   //LPD3DXMESH pMesh,
455                                        NULL,   //CONST DWORD * pAdjacency,
456                                        composedMaterials,      //CONST D3DXMATERIAL * pMaterials,
457                                        composedShaders,        //CONST D3DXEFFECTINSTANCE * pEffectInstances,
458                                        nPieces,        //DWORD NumMaterials,
459                                        D3DXF_FILEFORMAT_TEXT   //DWORD Format
460                                        );
461}
462
463void MeshExploder::saveComposedMeshToOgreXML(LPCSTR name)
464{
465        char sname[256];
466        sprintf(sname, "processedMeshes/%s.mesh.xml", name);
467
468        std::ofstream f(sname);
469        XmlStream xml(f);
470
471        DWORD mfvf = composedMesh->GetFVF();
472        unsigned int nTexCoords = ( mfvf & D3DFVF_TEXCOUNT_MASK) / D3DFVF_TEX1;
473
474        xml << tag("mesh");
475        xml << tag("sharedgeometry")
476                << attr("vertexcount") << composedMesh->GetNumVertices();
477               
478                xml << tag("vertexbuffer");
479                if(mfvf & D3DFVF_XYZ)
480                        xml << attr("positions") << "true";
481                else
482                        xml << attr("positions") << "false";
483                if(mfvf & D3DFVF_NORMAL)
484                        xml << attr("normals") << "true";
485                else
486                        xml << attr("normals") << "false";
487                if(mfvf & D3DFVF_DIFFUSE)
488                        xml << attr("colours_diffuse") << "true";
489                else
490                        xml << attr("colours_diffuse") << "false";
491                if(mfvf & D3DFVF_SPECULAR)
492                        xml << attr("colours_specular") << "true";
493                else
494                        xml << attr("colours_specular") << "false";
495                xml << attr("texture_coords") << nTexCoords;
496
497        LPDIRECT3DVERTEXBUFFER9 composedVertexBuffer;
498        composedMesh->GetVertexBuffer(&composedVertexBuffer);
499        FlexVertexArray composedVertexData(composedMesh->GetNumBytesPerVertex());
[2304]500        D3DVERTEXELEMENT9 elem[64];     composedMesh->GetDeclaration(elem);      composedVertexData.setFormat(elem);
[2197]501        composedVertexBuffer->Lock(0,composedMesh->GetNumVertices()*composedMesh->GetNumBytesPerVertex(),composedVertexData.getDataPointerReference(),0);
502
503        LPDIRECT3DINDEXBUFFER9 composedIndexBuffer;
504        composedMesh->GetIndexBuffer(&composedIndexBuffer);
505        unsigned short* composedIndexData;
506        composedIndexBuffer->Lock(0,
507                                                composedMesh->GetNumFaces()*3*sizeof(unsigned short),
508                                                (void**)&composedIndexData,0);
509
510        DWORD* composedAttributeData;
511        composedMesh->LockAttributeBuffer(0, &composedAttributeData);
512
513        for(int xvi = 0; xvi < composedMesh->GetNumVertices(); xvi++)
514        {
515                xml << tag("vertex");
516                        if(mfvf & D3DFVF_XYZ)
517                        {
518                                xml << tag("position");
519                                        xml << attr("x") << composedVertexData[xvi].pos().x;
520                                        xml << attr("y") << composedVertexData[xvi].pos().y;
521                                        xml << attr("z") << composedVertexData[xvi].pos().z;
522                                xml << endtag();
523                        }
524                        if(mfvf & D3DFVF_NORMAL)
525                        {
526                                xml << tag("normal");
527                                        xml << attr("x") << composedVertexData[xvi].normal().x;
528                                        xml << attr("y") << composedVertexData[xvi].normal().y;
529                                        xml << attr("z") << composedVertexData[xvi].normal().z;
530                                xml << endtag();
531                        }
532                        if(mfvf & D3DFVF_DIFFUSE)
533                        {
534                                char colval[256];
535                                D3DCOLOR dc = composedVertexData[xvi].diffuse();
536                                unsigned char* pdc = (unsigned char*)&dc;
537                                sprintf(colval, "%f %f %f %f",
538                                        pdc[3],
539                                        pdc[0],
540                                        pdc[1],
541                                        pdc[2]
542                                        );
543                                xml << tag("colours_diffuse");
544                                        xml << attr("value") << colval;
545                                xml << endtag();
546                        }
547                        if(mfvf & D3DFVF_SPECULAR)
548                        {
549                                char colval[256];
550                                D3DCOLOR dc = composedVertexData[xvi].specular();
551                                unsigned char* pdc = (unsigned char*)&dc;
552                                sprintf(colval, "%f %f %f %f",
553                                        pdc[3],
554                                        pdc[0],
555                                        pdc[1],
556                                        pdc[2]
557                                        );
558                                xml << tag("colours_specular");
559                                        xml << attr("value") << colval;
560                                xml << endtag();
561                        }
562                        for(int taxi=0; taxi<nTexCoords; taxi++)
563                        {
564                                xml << tag("texcoord");
565                                        xml << attr("u") << composedVertexData[xvi].tex(taxi).x;
566                                        xml << attr("v") << composedVertexData[xvi].tex(taxi).y;
567                                xml << endtag();
568                        }
569
570                xml << endtag();
571        }
572
573        xml << endtag(); // end vertexbuffer
574        xml << endtag(); // end sharedgeometry
575
576        xml << tag("submeshes");
577        int faceOffset = 0;
578        for(int xai = 0; xai < nPieces; xai++)
579        {
580                xml << tag("submesh")
581                        << attr("material") << LC::c-composedMaterialNames[xai]
582                        << attr("use32bitindexes") << "true"
583                        << attr("usesharedvertices") << "true"
584                        << attr("operationtype") << "triangle_list";
585                       
586                        xml << tag("faces")
587                                << attr("count") << fragmentMeshes[xai]->GetNumFaces();
588                        for(int ic = 0; ic < fragmentMeshes[xai]->GetNumFaces(); ic++)
589                        {
590                                xml << tag("face")
591                                        << attr("v1") << composedIndexData[(ic + faceOffset) * 3]
592                                        << attr("v2") << composedIndexData[(ic + faceOffset) * 3 + 1]
593                                        << attr("v3") << composedIndexData[(ic + faceOffset) * 3 + 2];
594                                xml << endtag();
595                        }
596                        faceOffset += fragmentMeshes[xai]->GetNumFaces();
597                        xml << endtag();
598                xml << endtag();                       
599        }
600        xml << endtag(); // submeshes
601        xml << tag("submeshnames");
602        xml << endtag();
603
604        composedMesh->UnlockAttributeBuffer();
605
606        composedVertexBuffer->Unlock();
607        composedVertexBuffer->Release();
608        composedIndexBuffer->Unlock();
609        composedIndexBuffer->Release();
610}
Note: See TracBrowser for help on using the repository browser.