[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 |
|
---|
| 11 | using namespace xmlw;
|
---|
| 12 |
|
---|
| 13 | MeshExploder::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 |
|
---|
| 30 | MeshExploder::~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 |
|
---|
| 53 | struct Tri
|
---|
| 54 | {
|
---|
| 55 | unsigned short origMeshIndex;
|
---|
| 56 | Vector pos;
|
---|
| 57 | Vector normal;
|
---|
| 58 | };
|
---|
| 59 |
|
---|
| 60 | void 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 |
|
---|
| 201 | void 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 |
|
---|
| 283 | void 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 |
|
---|
| 300 | void 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 |
|
---|
| 354 | void 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 |
|
---|
| 443 | void 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 |
|
---|
| 457 | void 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 | } |
---|