#include <coarse_mesh_build.h>
The build method take an array of CMeshGeom an a bitmap. This class will compute a single texture used to map every coarse mesh passed in the array.
Each mesh geom should be a coarse mesh.
The uv texture coodinates of those coarse meshes will be adjusted to fit in a single texture.
Nevrax France
Definition at line 62 of file coarse_mesh_build.h.
Public Member Functions | |
| bool | build (const std::vector< CCoarseMeshDesc > &coarseMeshes, std::vector< NLMISC::CBitmap > &bitmaps, CStats &stats, float mulArea) |
Private Types | |
| typedef std::map< std::string, CBitmapDesc > | MapBitmapDesc |
Private Member Functions | |
| bool | buildBitmap (const std::vector< CCoarseMeshDesc > &coarseMeshes, std::vector< NLMISC::CBitmap > &bitmaps, CStats &stats, MapBitmapDesc &desc, float mulArea) |
| void | expand (NLMISC::CBitmap &bitmap) |
| void | remapCoordinates (const std::vector< CCoarseMeshDesc > &coarseMeshes, const MapBitmapDesc &desc, uint outputBitmapCount) |
|
|
Definition at line 132 of file coarse_mesh_build.h. Referenced by build(), buildBitmap(), and remapCoordinates(). |
|
||||||||||||||||||||
|
The build method. This method will build a single texture and adjuste the UV texture coordinates of each mesh geom.
Definition at line 39 of file coarse_mesh_build.cpp. References buildBitmap(), MapBitmapDesc, and remapCoordinates().
00040 {
00041 // 1. build the bitmap
00042 MapBitmapDesc desc;
00043 if (buildBitmap (coarseMeshes, bitmaps, stats, desc, mulArea)==false)
00044 return false;
00045
00046 // 2. remap coordinates
00047 remapCoordinates (coarseMeshes, desc, bitmaps.size ());
00048
00049 // 3. ok
00050 return true;
00051 }
|
|
||||||||||||||||||||||||
|
Definition at line 70 of file coarse_mesh_build.cpp. References NL3D::CCoarseMeshBuild::CBitmapDesc::Bitmaps, NLMISC::CBitmap::convertToType(), expand(), NL3D::CCoarseMeshBuild::CBitmapDesc::FactorU, NL3D::CCoarseMeshBuild::CBitmapDesc::FactorV, NL3D::ITexture::generate(), NLMISC::CBitmap::getHeight(), NL3D::CMeshBase::getMaterial(), NL3D::CMeshGeom::getNbMatrixBlock(), NL3D::CMeshGeom::getNbRdrPass(), NLMISC::getPowerOf2(), NL3D::CMeshGeom::getRdrPassMaterial(), NL3D::ITexture::getShareName(), NL3D::CMaterial::getTexture(), NLMISC::CBitmap::getWidth(), NL3D::CInsertedBitmap::Height, height, MapBitmapDesc, NL3D::CCoarseMeshBuild::CBitmapDesc::Name, nlassert, NLMISC::raiseToNextPowerOf2(), NLMISC::CBitmap::resample(), NL3D::ITexture::selectTexture(), sint, NLMISC::strlwr(), NL3D::ITexture::supportSharing(), NL3D::CCoarseMeshBuild::CStats::TextureUsed, NLMISC::toString(), NL3D::CInsertedBitmap::U, uint, uint32, NL3D::CInsertedBitmap::V, v, NL3D::CInsertedBitmap::Width, and width. Referenced by build().
00071 {
00072 // Total area used by texture
00073 uint totalArea=0;
00074
00075 // ***************************************************************************
00076
00077 // 1. scan each bitmap: calc the area of the bitmap and it its name in the maps sorted by area
00078 typedef std::multimap<uint, CBitmapDesc*> MapAreaBitmap;
00079 MapAreaBitmap mapArea;
00080 uint mesh;
00081 for (mesh=0; mesh<coarseMeshes.size(); mesh++)
00082 {
00083 // Geom mesh pointer
00084 CMeshGeom *meshGeom=coarseMeshes[mesh].MeshGeom;
00085
00086 // Base mesh pointer
00087 const CMeshBase *meshBase=coarseMeshes[mesh].MeshBase;
00088
00089 // For each matrix block
00090 uint matrixBlock;
00091 uint nbMatrixBlock=meshGeom->getNbMatrixBlock();
00092 for (matrixBlock=0; matrixBlock<nbMatrixBlock; matrixBlock++)
00093 {
00094 // For each render pass
00095 uint renderPass;
00096 uint numRenderPass=meshGeom->getNbRdrPass(matrixBlock);
00097 for (renderPass=0; renderPass<numRenderPass; renderPass++)
00098 {
00099 // Render pass material
00100 uint32 matId=meshGeom->getRdrPassMaterial(matrixBlock, renderPass);
00101
00102 // Checks
00103 nlassert (matId<meshBase->getNbMaterial());
00104
00105 // Get the material
00106 const CMaterial &material=meshBase->getMaterial(matId);
00107
00108 // Get the texture
00109 ITexture *texture=material.getTexture(0);
00110 if (texture)
00111 {
00112 // For each bitmaps
00113 uint i;
00114 std::string name;
00115 for (i=0; i<bitmaps.size (); i++)
00116 {
00117 // Select the good slot
00118 texture->selectTexture (i);
00119
00120 // Get its name
00121 if (texture->supportSharing())
00122 {
00123 // Get sharing name
00124 name+=strlwr(texture->getShareName());
00125 }
00126 else
00127 {
00128 // Build a name
00129 name+=toString ((uint)texture);
00130 }
00131 }
00132
00133 // Already added ?
00134 if (desc.find (name)==desc.end())
00135 {
00136 // Add it..
00137
00138 // Insert it in the maps
00139 MapBitmapDesc::iterator ite = desc.insert (MapBitmapDesc::value_type (name, CBitmapDesc ())).first;
00140
00141 // Descriptor for this texture
00142 CBitmapDesc &descBitmap = ite->second;
00143
00144 // Backup original size
00145 uint originalWidth;
00146 uint originalHeight;
00147
00148 // For each bitmaps
00149 uint i;
00150 descBitmap.Bitmaps.resize (bitmaps.size ());
00151 for (i=0; i<bitmaps.size (); i++)
00152 {
00153 // Select the good slot
00154 texture->selectTexture (i);
00155
00156 // Generate the texture
00157 texture->generate();
00158
00159 // Convert to RGBA
00160 texture->convertToType (CBitmap::RGBA);
00161
00162 // First texture ?
00163 if (i == 0)
00164 {
00165 // Backup original size
00166 originalWidth = texture->getWidth();
00167 originalHeight = texture->getHeight();
00168 }
00169
00170 // Resample, if needed
00171 if (i != 0)
00172 {
00173 // New size
00174 if ( ( originalWidth != texture->getWidth () ) || originalHeight != texture->getHeight () )
00175 {
00176 texture->resample (originalWidth, originalHeight);
00177 }
00178 }
00179
00180 // Copy the texture
00181 descBitmap.Bitmaps[i] = *texture;
00182
00183 // Expand the texture
00184 expand (descBitmap.Bitmaps[i]);
00185 }
00186
00187 // Texture area
00188 uint area = descBitmap.Bitmaps[0].getWidth() * descBitmap.Bitmaps[0].getHeight();
00189 descBitmap.Name = name;
00190 descBitmap.FactorU = (float)originalWidth;
00191 descBitmap.FactorV = (float)originalHeight;
00192
00193 // Insert in the map area
00194 mapArea.insert (MapAreaBitmap::value_type(area, &(ite->second)));
00195
00196 // Sum area if added
00197 totalArea+=area;
00198 }
00199 }
00200 }
00201 }
00202 }
00203
00204 // ***************************************************************************
00205
00206 // 2. Calc the best area for the dest texture and resize the bitmap
00207
00208 // Total area used by the textures + a little more
00209 uint newArea=getPowerOf2 (raiseToNextPowerOf2 (totalArea));
00210 while ((1<<newArea)<(sint)(mulArea*(float)totalArea))
00211 {
00212 newArea++;
00213 }
00214
00215 // Calc width and height with HEIGHT==WIDTH or HEIGHT=2*WIDTH
00216 uint width=1<<(newArea/2);
00217 uint height=1<<(newArea/2 + (newArea&1));
00218
00219 // Resize the bitmap and set the pixel format
00220 uint i;
00221 for (i=0; i<bitmaps.size (); i++)
00222 bitmaps[i].resize (width, height, CBitmap::RGBA);
00223
00224 // Checks
00225 if (totalArea==0)
00226 {
00227 // No texture, ok computed.
00228 stats.TextureUsed=1;
00229
00230 return true;
00231 }
00232
00233 // ***************************************************************************
00234
00235 // 3. Place each texture in the bitmap in uncreasing order
00236 typedef std::multimap<sint, CInsertedBitmap> mapInsertedBitmap;
00237
00238 // For each texture
00239 MapAreaBitmap::iterator ite=mapArea.end();
00240
00241 // Inserted bitmap desc
00242 mapInsertedBitmap inserted;
00243
00244 // Max texture height
00245 uint maxTexHeight=0;
00246
00247 do
00248 {
00249 ite--;
00250 nlassert (ite!=mapArea.end());
00251
00252 // Size of the texture
00253 uint widthTex=ite->second->Bitmaps[0].getWidth();
00254 uint heightTex=ite->second->Bitmaps[0].getHeight();
00255
00256 // Some checks
00257 nlassert (bitmaps.size () == ite->second->Bitmaps.size ());
00258
00259 // Width and height max
00260 uint widthMax=width-widthTex;
00261 uint heightMax=height-heightTex;
00262
00263 // Test against others..
00264 bool enter=false;
00265
00266 // For each row and each column
00267 for (uint v=0; v<heightMax; v++)
00268 {
00269 for (uint u=0; u<widthMax; u++)
00270 {
00271 // Test against others..
00272 enter=true;
00273
00274 // Get the first to test
00275 mapInsertedBitmap::iterator toTest=inserted.lower_bound ((sint)v-(sint)maxTexHeight);
00276 while (toTest!=inserted.end())
00277 {
00278 // Make a test ?
00279 if ((sint)(v+heightTex)<=(toTest->first))
00280 {
00281 // Ok, end test
00282 break;
00283 }
00284
00285 // Test it
00286 uint otherU=toTest->second.U;
00287 uint otherV=toTest->second.V;
00288 uint otherWidth=toTest->second.Width;
00289 uint otherHeight=toTest->second.Height;
00290 if ((v<otherV+otherHeight) && (v+heightTex>otherV) &&
00291 (u<otherU+otherWidth) && (u+widthTex>otherU))
00292 {
00293 // Collision
00294 enter=false;
00295 u=toTest->second.U+otherWidth-1;
00296 break;
00297 }
00298
00299 // Next to test
00300 toTest++;
00301 }
00302
00303 // Enter ?
00304 if (enter)
00305 {
00306 // Ok, enter
00307
00308 // Insert an inserted descriptor
00309 CInsertedBitmap descInserted;
00310 descInserted.Width=widthTex;
00311 descInserted.Height=heightTex;
00312 descInserted.U=u;
00313 descInserted.V=v;
00314 inserted.insert (mapInsertedBitmap::value_type (v, descInserted));
00315
00316 // Max height
00317 if (heightTex>maxTexHeight)
00318 maxTexHeight=heightTex;
00319
00320 // Blit in the texture
00321 uint i;
00322 for (i=0; i<bitmaps.size (); i++)
00323 {
00324 // Check..
00325 nlassert ( (ite->second->Bitmaps[0].getWidth () == ite->second->Bitmaps[i].getWidth ()) &&
00326 (ite->second->Bitmaps[0].getHeight () == ite->second->Bitmaps[i].getHeight ()) );
00327
00328 // Blit it
00329 bitmaps[i].blit (&(ite->second->Bitmaps[i]), u, v);
00330 }
00331
00332 // Set the U and V texture coordinates
00333 ite->second->U=(float)(u+1)/(float)width;
00334 ite->second->V=(float)(v+1)/(float)height;
00335
00336 // Set ratio
00337 ite->second->FactorU /= (float)width;
00338 ite->second->FactorV /= (float)height;
00339
00340 // End
00341 break;
00342 }
00343
00344 // next..
00345 }
00346
00347 // Enter ?
00348 if (enter)
00349 break;
00350 }
00351
00352 // Not enter ?
00353 if (!enter)
00354 // Texture too small..
00355 return false;
00356 }
00357 while (ite!=mapArea.begin());
00358
00359 // Some stats
00360 stats.TextureUsed=(float)totalArea/(float)(width*height);
00361
00362 return true;
00363 }
|
|
|
Definition at line 367 of file coarse_mesh_build.cpp. References NLMISC::CBitmap::blit(), NLMISC::CBitmap::getHeight(), NLMISC::CBitmap::getPixels(), NLMISC::CBitmap::getWidth(), height, NLMISC::CBitmap::resize(), uint, uint32, and width. Referenced by buildBitmap().
00368 {
00369 // Get size
00370 uint width=bitmap.getWidth();
00371 uint height=bitmap.getHeight();
00372
00373 // Valid size ?
00374 if ((width!=0) && (height!=0))
00375 {
00376 // Copy the bitmap
00377 CBitmap copy=bitmap;
00378
00379 // Resize the bitmap
00380 bitmap.resize (width+2, height+2);
00381
00382 // Copy old bitmap
00383 bitmap.blit (©, 1, 1);
00384
00385 // Make a top and bottom border
00386 uint32 *topSrc=(uint32*)&(copy.getPixels()[0]);
00387 uint32 *topDest=((uint32*)&(bitmap.getPixels()[0]))+1;
00388 memcpy (topDest, topSrc, 4*width);
00389 uint32 *bottomSrc=topSrc+width*(height-1);
00390 uint32 *bottomDest=((uint32*)&(bitmap.getPixels()[0]))+(width+2)*(height+1)+1;
00391 memcpy (bottomDest, bottomSrc, 4*width);
00392
00393 // Make a left and right border
00394 uint32 *leftSrc=(uint32*)&(copy.getPixels()[0]);
00395 uint32 *leftDest=((uint32*)&(bitmap.getPixels()[0]))+width+2;
00396 uint32 *rightSrc=leftSrc+width-1;
00397 uint32 *rightDest=leftDest+width+1;
00398 uint i;
00399 for (i=0; i<height; i++)
00400 {
00401 // Copy the borders
00402 *leftDest=*leftSrc;
00403 *rightDest=*rightSrc;
00404
00405 // Move pointers
00406 leftDest+=width+2;
00407 rightDest+=width+2;
00408 leftSrc+=width;
00409 rightSrc+=width;
00410 }
00411
00412 // Make corners
00413
00414 // Left top
00415 *(uint32*)&(bitmap.getPixels()[0])=*(uint32*)&(copy.getPixels()[0]);
00416
00417 // Rigth top
00418 *(((uint32*)&(bitmap.getPixels()[0]))+width+1)=*(((uint32*)&(copy.getPixels()[0]))+width-1);
00419
00420 // Rigth bottom
00421 *(((uint32*)&(bitmap.getPixels()[0]))+(width+2)*(height+2)-1)=*(((uint32*)&(copy.getPixels()[0]))+width*height-1);
00422
00423 // Left bottom
00424 *(((uint32*)&(bitmap.getPixels()[0]))+(width+2)*(height+1))=*(((uint32*)&(copy.getPixels()[0]))+width*(height-1));
00425 }
00426 }
|
|
||||||||||||||||
|
Definition at line 430 of file coarse_mesh_build.cpp. References NL3D::CCoarseMeshBuild::CBitmapDesc::FactorU, NL3D::CCoarseMeshBuild::CBitmapDesc::FactorV, NL3D::CMeshBase::getMaterial(), NL3D::CMeshGeom::getNbMatrixBlock(), NL3D::CMeshGeom::getNbRdrPass(), NL3D::CPrimitiveBlock::getNumQuad(), NL3D::CPrimitiveBlock::getNumTri(), NL3D::CPrimitiveBlock::getQuadPointer(), NL3D::CMeshGeom::getRdrPassMaterial(), NL3D::CMeshGeom::getRdrPassPrimitiveBlock(), NL3D::ITexture::getShareName(), NL3D::CVertexBuffer::getTexCoordPointer(), NL3D::CMaterial::getTexture(), NL3D::CPrimitiveBlock::getTriPointer(), NL3D::CMeshGeom::getVertexBuffer(), index, MapBitmapDesc, nlassert, NL3D::ITexture::selectTexture(), NLMISC::strlwr(), NL3D::ITexture::supportSharing(), NLMISC::toString(), NL3D::CCoarseMeshBuild::CBitmapDesc::U, uint, uint32, and NL3D::CCoarseMeshBuild::CBitmapDesc::V. Referenced by build().
00431 {
00432 // 1. scan each bitmap: calc the area of the bitmap and it its name in the maps sorted by area
00433 typedef std::multimap<float, CBitmapDesc> MapAreaBitmap;
00434 MapAreaBitmap mapArea;
00435 uint mesh;
00436 for (mesh=0; mesh<coarseMeshes.size(); mesh++)
00437 {
00438 // Geom mesh pointer
00439 CMeshGeom *meshGeom=coarseMeshes[mesh].MeshGeom;
00440
00441 // Base mesh pointer
00442 const CMeshBase *meshBase=coarseMeshes[mesh].MeshBase;
00443
00444 // The vertex buffer
00445 CVertexBuffer &vertexBuffer=const_cast<CVertexBuffer&> (meshGeom->getVertexBuffer());
00446
00447 // For each matrix block
00448 uint matrixBlock;
00449 uint nbMatrixBlock=meshGeom->getNbMatrixBlock();
00450 for (matrixBlock=0; matrixBlock<nbMatrixBlock; matrixBlock++)
00451 {
00452 // For each render pass
00453 uint renderPass;
00454 uint numRenderPass=meshGeom->getNbRdrPass(matrixBlock);
00455 for (renderPass=0; renderPass<numRenderPass; renderPass++)
00456 {
00457 // Render pass material
00458 uint32 matId=meshGeom->getRdrPassMaterial(matrixBlock, renderPass);
00459
00460 // Checks
00461 nlassert (matId<meshBase->getNbMaterial());
00462
00463 // Get the material
00464 const CMaterial &material=meshBase->getMaterial(matId);
00465
00466 // Get the texture
00467 ITexture *texture=material.getTexture(0);
00468 if (texture)
00469 {
00470 // Get its name
00471 std::string name;
00472 uint i;
00473 for (i=0; i<outputBitmapCount; i++)
00474 {
00475 // Select the good slot
00476 texture->selectTexture (i);
00477
00478 // Get its name
00479 if (texture->supportSharing())
00480 {
00481 // Get sharing name
00482 name+=strlwr(texture->getShareName());
00483 }
00484 else
00485 {
00486 // Build a name
00487 name+=toString ((uint)texture);
00488 }
00489 }
00490
00491 // Find the texture
00492 MapBitmapDesc::const_iterator ite=desc.find (name);
00493 nlassert (ite!=desc.end());
00494
00495 // Descriptor ref
00496 const CBitmapDesc& descBitmap=ite->second;
00497
00498 // Get primitives
00499 const CPrimitiveBlock &primitiveBlock=meshGeom->getRdrPassPrimitiveBlock(matrixBlock,renderPass);
00500
00501 // Set of vertex to remap
00502 std::set<uint> vertexToRemap;
00503
00504 // Remap triangles
00505 uint index;
00506 const uint32 *indexPtr=primitiveBlock.getTriPointer();
00507 uint32 numIndex=3*primitiveBlock.getNumTri();
00508 for (index=0; index<numIndex; index++)
00509 vertexToRemap.insert (indexPtr[index]);
00510
00511 // Remap quad
00512 indexPtr=primitiveBlock.getQuadPointer();
00513 numIndex=4*primitiveBlock.getNumQuad();
00514 for (index=0; index<numIndex; index++)
00515 vertexToRemap.insert (indexPtr[index]);
00516
00517 // Remap the vertex
00518 std::set<uint>::iterator iteRemap=vertexToRemap.begin();
00519 while (iteRemap!=vertexToRemap.end())
00520 {
00521 // Remap the vertex
00522 float *UVCoordinate=(float*)vertexBuffer.getTexCoordPointer(*iteRemap);
00523 UVCoordinate[0]=UVCoordinate[0]*descBitmap.FactorU+descBitmap.U;
00524 UVCoordinate[1]=UVCoordinate[1]*descBitmap.FactorV+descBitmap.V;
00525
00526 // Next vertex
00527 iteRemap++;
00528 }
00529 }
00530 }
00531 }
00532 }
00533 }
|
1.3.6