NL3D::CShapeBank Class Reference

#include <shape_bank.h>


Detailed Description

A CShapeBank handle all the instance of the shapes and the cache management system. There is a default cache. If the shape is not linked explicitly to any cache it is linked to the default cache. The comportement of this cache is to not do any cache. When the release is called on the last reference to a shape linked to this cache, the shape is removed instantly. This is the behavior of all newly created cache before we call the setShapeCacheSize method.

NB: ShapeCacheName is case-sensitive but shapeName are not (all entry are lwrcased)

Author:
Matthieu Besson

Nevrax France

Date:
2000

Definition at line 63 of file shape_bank.h.

Shape/Instances.

typedef NLMISC::CSmartPtr<
IShape
PShape
typedef std::map< std::string,
PShape
TShapeMap
typedef std::map< std::string,
CWaitingShape
TWaitingShapesMap
bool processWSUploadTexture (CWaitingShape &rWS, uint32 &nTotalUploaded, ITexture *pText)
 return true if the texture is entirely uploaded

uint32 _MaxUploadPerFrame
IDriver_pDriver
TShapeMap ShapeMap
TWaitingShapesMap WaitingShapes

Shape/Caches.

typedef std::map< std::string,
CShapeCache
TShapeCacheMap
typedef std::map< std::string,
std::string > 
TShapeCacheNameMap
typedef std::map< IShape *,
CShapeInfo
TShapeInfoMap
void checkShapeCache (CShapeCache *pShpCache)
CShapeCachegetShapeCachePtrFromShapeCacheName (const std::string &shapeCacheName)
CShapeCachegetShapeCachePtrFromShapeName (const std::string &shapeName)
CShapeCachegetShapeCachePtrFromShapePtr (IShape *pShp)
std::string * getShapeNameFromShapePtr (IShape *pShp)
IShapegetShapePtrFromShapeName (const std::string &pShpName)
TShapeCacheMap ShapeCacheNameToShapeCache
TShapeCacheNameMap ShapeNameToShapeCacheName
TShapeInfoMap ShapePtrToShapeInfo

Public Types

State of a shape
enum  TShapeState {
  NotPresent, Present, AsyncLoad_Error, AsyncLoad_Shape,
  AsyncLoad_Texture, AsyncLoad_Ready, AsyncLoad_Delete
}

Public Member Functions

 CShapeBank ()
 ~CShapeBank ()
Instance Management
void add (const std::string &shapeName, IShape *shape)
 Add directly a shape to the bank. If the shape name is already used do nothing.

IShapeaddRef (const std::string &shapeName)
 Add a reference to a shape and return the instance created.

void cancelLoadAsync (const std::string &shapeName)
 Add directly a shape to the bank. If the shape name is already used do nothing.

IShapegetShape (const std::string &shapeName)
TShapeState isPresent (const std::string &shapeName)
 Return TRUE if the shape is present in the bank. Process the waiting shapes.

bool isShapeWaiting ()
 Add directly a shape to the bank. If the shape name is already used do nothing.

void load (const std::string &shapeName)
 Load the corresponding file from disk and add it to the bank.

void loadAsync (const std::string &shapeName, IDriver *pDriver, const NLMISC::CVector &position, bool *bSignal, uint selectedTexture)
void processWaitingShapes ()
 processWaitingShapes must be done one time per frame

void release (IShape *pShp)
void setMaxBytesToUpload (uint32 MaxUploadPerFrame)
 Setup the maximum number of bytes to upload for a frame (texture upload from RAM to VRAM).

Shape cache management
void addShapeCache (const std::string &shapeCacheName)
 Add a new ShapeCache. If already exist do nothing.

sint getShapeCacheFreeSpace (const std::string &shapeCacheName) const
 return free cache space (maxSize-nbCurrentInCache)

bool isShapeCache (const std::string &shapeCacheName) const
 true if the shape cache exist

void linkShapeToShapeCache (const std::string &shapeName, const std::string &shapeCacheName)
 Link a shape to a ShapeCache. The ShapeCache must exist and must not contains the shape.

void removeShapeCache (const std::string &shapeCacheName)
void reset ()
void setShapeCacheSize (const std::string &shapeCacheName, sint32 maxSize)
 Set the shapeCache shapeCacheName the new size.(delete shapes if maxsize<shapeCacheSize).

Tools
void preLoadShapes (const std::string &shapeCacheName, const std::vector< std::string > &listFile, const std::string &wildCardNotLwr, NLMISC::IProgressCallback *progress=NULL, bool flushTextures=false, IDriver *drv=NULL)


Member Typedef Documentation

typedef NLMISC::CSmartPtr<IShape> NL3D::CShapeBank::PShape [private]
 

Definition at line 167 of file shape_bank.h.

typedef std::map<std::string,CShapeCache> NL3D::CShapeBank::TShapeCacheMap [private]
 

Definition at line 232 of file shape_bank.h.

typedef std::map<std::string,std::string> NL3D::CShapeBank::TShapeCacheNameMap [private]
 

Definition at line 231 of file shape_bank.h.

typedef std::map<IShape*,CShapeInfo> NL3D::CShapeBank::TShapeInfoMap [private]
 

Definition at line 233 of file shape_bank.h.

typedef std::map<std::string, PShape> NL3D::CShapeBank::TShapeMap [private]
 

Definition at line 168 of file shape_bank.h.

typedef std::map< std::string, CWaitingShape > NL3D::CShapeBank::TWaitingShapesMap [private]
 

Definition at line 192 of file shape_bank.h.


Member Enumeration Documentation

enum NL3D::CShapeBank::TShapeState
 

NotPresent : Not present in the bank Present : Present in the bank and ready to be used AsyncLoad_Error : Asynchronous loading failed AsyncLoad_Shape : Asynchronous loading is currently loading the .shape file, textures and lightmaps AsyncLoad_Texture : Asynchronous loading is currently uploading textures and lightmaps to VRAM

Enumeration values:
NotPresent 
Present 
AsyncLoad_Error 
AsyncLoad_Shape 
AsyncLoad_Texture 
AsyncLoad_Ready 
AsyncLoad_Delete 

Definition at line 75 of file shape_bank.h.


Constructor & Destructor Documentation

NL3D::CShapeBank::CShapeBank  ) 
 

Definition at line 44 of file shape_bank.cpp.

References addShapeCache().

00045 {
00046         // Default cache creation
00047         addShapeCache( "default" );
00048         _MaxUploadPerFrame = 16*1024;
00049 }

NL3D::CShapeBank::~CShapeBank  ) 
 

Definition at line 53 of file shape_bank.cpp.

00054 {
00055 }


Member Function Documentation

void NL3D::CShapeBank::add const std::string &  shapeName,
IShape shape
 

Add directly a shape to the bank. If the shape name is already used do nothing.

Definition at line 527 of file shape_bank.cpp.

References getShapeCachePtrFromShapeCacheName(), getShapeCachePtrFromShapeName(), NL3D::CShapeBank::CShapeInfo::pShpCache, ShapeMap, ShapeNameToShapeCacheName, ShapePtrToShapeInfo, NL3D::CShapeBank::CShapeInfo::sShpName, and NLMISC::strlwr().

Referenced by NL3D::GetDummyMeshFromBank(), load(), NL3D::CPSMesh::newElement(), and processWaitingShapes().

00528 {
00529         string  shapeName= strlwr(shapeNameNotLwr);
00530 
00531         // Is the shape name already used ?
00532         TShapeMap::iterator smIt = ShapeMap.find( shapeName );
00533         if( smIt == ShapeMap.end() )
00534         {
00535                 // No ok so lets add the smart pointer
00536                 CSmartPtr<IShape> spShape = pShp;
00537                 ShapeMap[shapeName] = spShape;
00538 
00539                 // create the shape info
00540                 CShapeInfo siTemp;
00541                 siTemp.sShpName = shapeName;
00542                 siTemp.pShpCache = getShapeCachePtrFromShapeName( shapeName );
00543                 // Is the shape has a valid shape cache ? 
00544                 if( siTemp.pShpCache == NULL )
00545                 {
00546                         // No -> link to default (which do the UpdateShapeInfo)
00547                         siTemp.pShpCache = getShapeCachePtrFromShapeCacheName( "default" );
00548                         // Add the shape to the default shape cache
00549                         ShapePtrToShapeInfo[pShp]= siTemp;
00550                         ShapeNameToShapeCacheName[shapeName]= "default";
00551                 }
00552                 else
00553                 {
00554                         // Yes -> add or replace the shape info
00555                         ShapePtrToShapeInfo[pShp] = siTemp;
00556                 }
00557         }
00558 }

IShape * NL3D::CShapeBank::addRef const std::string &  shapeName  ) 
 

Add a reference to a shape and return the instance created.

Definition at line 59 of file shape_bank.cpp.

References NL3D::CShapeBank::CShapeCache::Elements, getShapeNameFromShapePtr(), getShapePtrFromShapeName(), nlassert, ShapePtrToShapeInfo, and NLMISC::strlwr().

Referenced by NL3D::CScene::createInstance(), NL3D::GetDummyMeshFromBank(), preLoadShapes(), NL3D::CPSConstraintMesh::update(), and NL3D::CScene::updateWaitingInstances().

00060 {       
00061         string  shapeName= strlwr(shapeNameNotLwr);
00062 
00063         // If the shape is inserted in a shape cache remove it
00064         TShapeInfoMap::iterator scfpmIt = ShapePtrToShapeInfo.find( getShapePtrFromShapeName( shapeName ) );
00065         if( scfpmIt != ShapePtrToShapeInfo.end() )
00066         {
00067                 if( !scfpmIt->second.isAdded )
00068                 {
00069                         // The shape is not inserted into a cache
00070                         return getShapePtrFromShapeName( shapeName );
00071                 }
00072         }
00073         scfpmIt->second.isAdded = false;
00074         CShapeCache *pShpCache = scfpmIt->second.pShpCache;
00075         nlassert( pShpCache != NULL );
00076         // Search the shape cache for the shape we want to remove
00077         list<IShape*>::iterator lsIt = pShpCache->Elements.begin();
00078         while(lsIt != pShpCache->Elements.end())
00079         {
00080                 string *sTemp = getShapeNameFromShapePtr(*lsIt);
00081                 if( *sTemp == shapeName )
00082                 {
00083                         // Ok the shape cache contains the shape remove it and return
00084                         pShpCache->Elements.erase( lsIt );                              
00085                         return getShapePtrFromShapeName( shapeName );
00086                 }
00087                 ++lsIt;
00088         }
00089         nlassert( false );
00090         return getShapePtrFromShapeName( shapeName );
00091 }

void NL3D::CShapeBank::addShapeCache const std::string &  shapeCacheName  ) 
 

Add a new ShapeCache. If already exist do nothing.

Definition at line 562 of file shape_bank.cpp.

References ShapeCacheNameToShapeCache.

Referenced by NL3D::CShapeBankUser::addShapeCache(), CShapeBank(), and reset().

00563 {
00564         TShapeCacheMap::iterator scmIt = ShapeCacheNameToShapeCache.find( shapeCacheName );
00565         if( scmIt == ShapeCacheNameToShapeCache.end() )
00566         {
00567                 // Not found so add it          
00568                 ShapeCacheNameToShapeCache.insert(TShapeCacheMap::value_type(shapeCacheName,CShapeCache()));
00569         }
00570 }

void NL3D::CShapeBank::cancelLoadAsync const std::string &  shapeName  ) 
 

Add directly a shape to the bank. If the shape name is already used do nothing.

Definition at line 497 of file shape_bank.cpp.

References NLMISC::strlwr(), and WaitingShapes.

Referenced by NL3D::CInstanceGroup::stopAddToSceneAsync().

00498 {
00499         string  shapeName= strlwr(shapeNameNotLwr);
00500 
00501         TWaitingShapesMap::iterator wsmmIt = WaitingShapes.find(shapeName);
00502         if (wsmmIt != WaitingShapes.end())
00503         {
00504                 wsmmIt->second.RefCnt -= 1;
00505                 if (wsmmIt->second.RefCnt == 0)
00506                 {
00507                         // nlinfo("unloadasync %s", shapeName);
00508                         CAsyncFileManager3D::getInstance().cancelLoadMesh (shapeName);
00509                         // TODO : Cancel the texture upload
00510                         WaitingShapes.erase (wsmmIt); // Delete the waiting shape
00511                 }
00512         }
00513 }

void NL3D::CShapeBank::checkShapeCache CShapeCache pShpCache  )  [private]
 

Definition at line 747 of file shape_bank.cpp.

References NL3D::CShapeBank::CShapeCache::Elements, getShapeNameFromShapePtr(), NL3D::CShapeBank::CShapeCache::MaxSize, ShapeMap, ShapePtrToShapeInfo, and sint.

Referenced by release(), removeShapeCache(), reset(), and setShapeCacheSize().

00748 {
00749         if( pShpCache != NULL )
00750         while( (sint)pShpCache->Elements.size() > pShpCache->MaxSize )
00751         {
00752                 // Suppress the last shape of the cache
00753                 IShape *pShp = pShpCache->Elements.back();
00754                 // Physical suppression because we own the last smart pointer on the shape
00755                 ShapeMap.erase(*getShapeNameFromShapePtr(pShp));
00756                 // delete information associated with the shape
00757                 ShapePtrToShapeInfo.erase( pShp );
00758                 // remove from queue
00759                 pShpCache->Elements.pop_back();
00760         }
00761 }

IShape * NL3D::CShapeBank::getShape const std::string &  shapeName  ) 
 

Return the IShape from the bank. Unlike addRef, no reference is added. Thus the returning shape sould be used temporarily

Returns:
NULL if shape not found or not loaded (if being async loaded still return NULL)

Definition at line 413 of file shape_bank.cpp.

References ShapeMap, and NLMISC::strlwr().

Referenced by NL3D::CShapeBankUser::getShape().

00414 {
00415         string  shapeName= strlwr(shapeNameNotLwr);
00416         
00417         // Is the shape is found in the shape map so return Present
00418         TShapeMap::iterator smIt = ShapeMap.find (shapeName);
00419         if( smIt != ShapeMap.end() )
00420                 return smIt->second;
00421 
00422         return NULL;
00423 }

sint NL3D::CShapeBank::getShapeCacheFreeSpace const std::string &  shapeCacheName  )  const
 

return free cache space (maxSize-nbCurrentInCache)

Definition at line 633 of file shape_bank.cpp.

References ShapeCacheNameToShapeCache, and sint.

Referenced by preLoadShapes().

00634 {
00635         TShapeCacheMap::const_iterator scmIt = ShapeCacheNameToShapeCache.find( shapeCacheName );
00636         if( scmIt != ShapeCacheNameToShapeCache.end() )
00637         {
00638                 return scmIt->second.MaxSize - scmIt->second.Elements.size();
00639         }
00640         return 0;
00641 }

CShapeBank::CShapeCache * NL3D::CShapeBank::getShapeCachePtrFromShapeCacheName const std::string &  shapeCacheName  )  [private]
 

Definition at line 711 of file shape_bank.cpp.

References ShapeCacheNameToShapeCache.

Referenced by add(), getShapeCachePtrFromShapeName(), linkShapeToShapeCache(), removeShapeCache(), reset(), and setShapeCacheSize().

00712 {
00713         TShapeCacheMap::iterator scmIt = ShapeCacheNameToShapeCache.find( shapeCacheName );
00714         if( scmIt != ShapeCacheNameToShapeCache.end())
00715         {
00716                 return &(scmIt->second);
00717         }
00718         return NULL;
00719 }

CShapeBank::CShapeCache * NL3D::CShapeBank::getShapeCachePtrFromShapeName const std::string &  shapeName  )  [private]
 

Definition at line 735 of file shape_bank.cpp.

References getShapeCachePtrFromShapeCacheName(), and ShapeNameToShapeCacheName.

Referenced by add().

00736 {
00737         TShapeCacheNameMap::iterator scnIt = ShapeNameToShapeCacheName.find( shapeName );
00738         if( scnIt != ShapeNameToShapeCacheName.end() )
00739         {
00740                 return getShapeCachePtrFromShapeCacheName(scnIt->second);
00741         }
00742         return NULL;
00743 }

CShapeBank::CShapeCache * NL3D::CShapeBank::getShapeCachePtrFromShapePtr IShape pShp  )  [private]
 

Definition at line 687 of file shape_bank.cpp.

References ShapePtrToShapeInfo.

Referenced by release().

00688 {
00689         TShapeInfoMap::iterator scfpmIt = ShapePtrToShapeInfo.find( pShp );
00690         if( scfpmIt != ShapePtrToShapeInfo.end() )
00691         {
00692                 return scfpmIt->second.pShpCache;
00693         }
00694         return NULL;
00695 }

string * NL3D::CShapeBank::getShapeNameFromShapePtr IShape pShp  )  [private]
 

Definition at line 723 of file shape_bank.cpp.

References ShapePtrToShapeInfo.

Referenced by addRef(), checkShapeCache(), and release().

00724 {
00725         TShapeInfoMap::iterator scfpmIt = ShapePtrToShapeInfo.find( pShp );
00726         if( scfpmIt != ShapePtrToShapeInfo.end() )
00727         {
00728                 return &(scfpmIt->second.sShpName);
00729         }
00730         return NULL;
00731 }

IShape * NL3D::CShapeBank::getShapePtrFromShapeName const std::string &  pShpName  )  [private]
 

Definition at line 699 of file shape_bank.cpp.

References ShapeMap.

Referenced by addRef(), and linkShapeToShapeCache().

00700 {
00701         TShapeMap::iterator smIt = ShapeMap.find(pShpName);
00702         if( smIt != ShapeMap.end() )
00703         {
00704                 return (IShape*)(smIt->second);
00705         }
00706         return NULL;
00707 }

CShapeBank::TShapeState NL3D::CShapeBank::isPresent const std::string &  shapeName  ) 
 

Return TRUE if the shape is present in the bank. Process the waiting shapes.

Definition at line 397 of file shape_bank.cpp.

References NotPresent, Present, ShapeMap, NLMISC::strlwr(), and WaitingShapes.

Referenced by NL3D::CScene::createInstance(), NL3D::CScene::createInstanceAsync(), NL3D::GetDummyMeshFromBank(), preLoadShapes(), NL3D::CPSConstraintMesh::update(), and NL3D::CScene::updateWaitingInstances().

00398 {
00399         string  shapeName= strlwr(shapeNameNotLwr);
00400 
00401         // Is the shape is found in the shape map so return Present
00402         TShapeMap::iterator smIt = ShapeMap.find (shapeName);
00403         if( smIt != ShapeMap.end() )
00404                 return Present;
00405         // Look in the waiting shapes
00406         TWaitingShapesMap::iterator wsmmIt = WaitingShapes.find (shapeName);
00407         if (wsmmIt != WaitingShapes.end())
00408                 return wsmmIt->second.State; // AsyncLoad_*
00409         return NotPresent;
00410 }

bool NL3D::CShapeBank::isShapeCache const std::string &  shapeCacheName  )  const
 

true if the shape cache exist

Definition at line 765 of file shape_bank.cpp.

References ShapeCacheNameToShapeCache.

Referenced by preLoadShapes().

00766 {
00767         return ShapeCacheNameToShapeCache.find(shapeCacheName) != ShapeCacheNameToShapeCache.end();
00768 }

bool NL3D::CShapeBank::isShapeWaiting  ) 
 

Add directly a shape to the bank. If the shape name is already used do nothing.

Definition at line 517 of file shape_bank.cpp.

References WaitingShapes.

00518 {
00519         if (WaitingShapes.size() == 0)
00520                 return false;
00521         else
00522                 return true;
00523 }

void NL3D::CShapeBank::linkShapeToShapeCache const std::string &  shapeName,
const std::string &  shapeCacheName
 

Link a shape to a ShapeCache. The ShapeCache must exist and must not contains the shape.

Definition at line 645 of file shape_bank.cpp.

References getShapeCachePtrFromShapeCacheName(), getShapePtrFromShapeName(), NL3D::CShapeBank::CShapeInfo::isAdded, NL3D::CShapeBank::CShapeInfo::pShpCache, ShapeNameToShapeCacheName, ShapePtrToShapeInfo, and NLMISC::strlwr().

Referenced by NL3D::CShapeBankUser::linkShapeToShapeCache(), and preLoadShapes().

00646 {
00647         string  shapeName= strlwr(shapeNameNotLwr);
00648 
00649         bool    canSet= true;
00650         while(1)
00651         {
00652                 // Shape exist?
00653                 IShape  *shapePtr= getShapePtrFromShapeName(shapeName);
00654                 if(shapePtr == NULL)
00655                         // No, but still link the shape name to the shapeCache name.
00656                         break;
00657                 // Is the shape cache exist ?
00658                 CShapeCache *shapeCachePtr = getShapeCachePtrFromShapeCacheName( shapeCacheName );
00659                 if( shapeCachePtr == NULL )
00660                         // abort, since cannot correctly link to a valid shapeCache
00661                         return;
00662 
00663                 // Try to set to the same shape Cache as before?
00664                 CShapeInfo      &shapeInfo= ShapePtrToShapeInfo[shapePtr];
00665                 if( shapeCachePtr ==  shapeInfo.pShpCache)
00666                         // abort, since same cache name / cache ptr
00667                         return;
00668 
00669                 // If The shape is In the cache of an other Shape Cache, abort.
00670                 if( shapeInfo.isAdded )
00671                         // Abort, because impossible.
00672                         return;
00673                 
00674                 // Is the shape is present ?
00675                 // Yes -> Update the ShapeInfo
00676                 shapeInfo.pShpCache= shapeCachePtr;
00677 
00678                 break;
00679         }
00680 
00681         // change the cache name of the shape
00682         ShapeNameToShapeCacheName[shapeName] = shapeCacheName;
00683 }

void NL3D::CShapeBank::load const std::string &  shapeName  ) 
 

Load the corresponding file from disk and add it to the bank.

Definition at line 427 of file shape_bank.cpp.

References add(), NLMISC::CIFile::close(), NL3D::CShapeStream::getShapePointer(), nlwarning, NLMISC::CIFile::open(), NLMISC::IStream::serial(), ShapeMap, NLMISC::strlwr(), and WaitingShapes.

Referenced by NL3D::CScene::createInstance(), preLoadShapes(), and NL3D::CPSConstraintMesh::update().

00428 {
00429         string  shapeName= strlwr(shapeNameNotLwr);
00430 
00431         TShapeMap::iterator smIt = ShapeMap.find(shapeName);
00432         if( smIt == ShapeMap.end() )
00433         {
00434                 // If we are loading it asynchronously so we do not have to try to load it in sync mode
00435                 TWaitingShapesMap::iterator wsmmIt = WaitingShapes.find (shapeName);
00436                 if (wsmmIt != WaitingShapes.end())
00437                         return;
00438                 try
00439                 {
00440                         CShapeStream mesh;
00441                         CIFile meshfile;
00442                         if (meshfile.open(CPath::lookup(shapeName)))
00443                         {
00444                                 meshfile.serial( mesh );
00445                                 meshfile.close();
00446                         }
00447                         else
00448                         {
00449                                 nlwarning ("CShapeBank::load() : Can't open file %s", shapeName.c_str());
00450                         }
00451 
00452                         // Add the shape to the map.
00453                         add( shapeName, mesh.getShapePointer() );
00454                 }
00455                 catch(Exception &e)
00456                 {
00457                         nlwarning ("CShapeBank::load() : %s", e.what());
00458                         return;
00459                 }
00460         }       
00461 }

void NL3D::CShapeBank::loadAsync const std::string &  shapeName,
IDriver pDriver,
const NLMISC::CVector position,
bool *  bSignal,
uint  selectedTexture
 

Load the corresponding file from disk asynchronously and add it to the bank. The driver passed to this function is used to know if we have to load the textures.

Definition at line 465 of file shape_bank.cpp.

References NL3D::CShapeBank::CWaitingShape::RefCnt, ShapeMap, NL3D::CShapeBank::CWaitingShape::Signal, NLMISC::strlwr(), uint, and WaitingShapes.

Referenced by NL3D::CScene::createInstanceAsync().

00466 {
00467         string  shapeName= strlwr(shapeNameNotLwr);
00468 
00469         TShapeMap::iterator smIt = ShapeMap.find(shapeName);
00470         if (smIt != ShapeMap.end())
00471                 return;
00472         _pDriver = pDriver; // Backup the pointer to the driver for later use
00473         TWaitingShapesMap::iterator wsmmIt = WaitingShapes.find (shapeName);
00474         
00475         // First time this shape is loaded ?
00476         bool firstTime = wsmmIt == WaitingShapes.end();
00477 
00478         if (firstTime)
00479                 wsmmIt = WaitingShapes.insert (TWaitingShapesMap::value_type(shapeName, CWaitingShape())).first;
00480 
00481         // Add a reference to it
00482         CWaitingShape &rWS = wsmmIt->second;
00483 
00484         // Insert a new signal pointer
00485         rWS.Signal.insert (bSignal);
00486 
00487         // Add a signal
00488         rWS.RefCnt += 1;
00489 
00490         // Launch an async mesh loader the first time
00491         if (firstTime)
00492                 CAsyncFileManager3D::getInstance().loadMesh (shapeName, &(wsmmIt->second.ShapePtr), pDriver, position, selectedTexture);
00493 }

void NL3D::CShapeBank::preLoadShapes const std::string &  shapeCacheName,
const std::vector< std::string > &  listFile,
const std::string &  wildCardNotLwr,
NLMISC::IProgressCallback progress = NULL,
bool  flushTextures = false,
IDriver drv = NULL
 

PreLoad all shapes (.shape, .ps, .skel...) files from a list of files Shapes are Loaded if not present, assigned to the given cache, and fit in the cache Size as max possible. NB: crash if you try to load a non shape file (eg: a .dds etc...)

Parameters:
shapeCacheName name of a shapeCache created with addShapeCache()/setShapeCacheSize(). no-op if don't exist
fileList a list of file names. NB: CPath is used to load the shapes.
wildcard a filter string like: "*.shape", "??_HOM*.shape". NB: strlwr-ed internally
flushTextures if true, then textures are flushed in the driver drv

Definition at line 771 of file shape_bank.cpp.

References addRef(), NL3D::IShape::flushTextures(), getShapeCacheFreeSpace(), isPresent(), isShapeCache(), linkShapeToShapeCache(), load(), NLMISC::IProgressCallback::progress(), release(), NLMISC::strlwr(), NLMISC::testWildCard(), and uint.

Referenced by NL3D::CShapeBankUser::preLoadShapesFromBNP(), and NL3D::CShapeBankUser::preLoadShapesFromDirectory().

00773 {
00774         // Abort if cache don't exist.
00775         if(!isShapeCache(shapeCacheName))
00776                 return;
00777 
00778         // strlwr
00779         string wildCard= strlwr(wildCardNotLwr);
00780 
00781         // For all files
00782         for(uint i=0;i<listFile.size();i++)
00783         {
00784                 // Progress bar
00785                 if (progress)
00786                         progress->progress ((float)i/(float)listFile.size ());
00787 
00788                 string  fileName= CFile::getFilename(listFile[i]);
00789                 strlwr(fileName);
00790                 // if the file is ok for the wildCard, process it
00791                 if( testWildCard(fileName.c_str(), wildCard.c_str()) )
00792                 {
00793                         // link the shape to the shapeCache
00794                         linkShapeToShapeCache(fileName, shapeCacheName);
00795 
00796                         // If !present in the shapeBank
00797                         if( isPresent(fileName)==CShapeBank::NotPresent )
00798                         {
00799                                 // Don't load it if no more space in the cache
00800                                 if( getShapeCacheFreeSpace(shapeCacheName)>0 )
00801                                 {
00802                                         // load it.
00803                                         load(fileName);
00804 
00805                                         // If success
00806                                         if( isPresent(fileName)!=CShapeBank::NotPresent )
00807                                         {
00808                                                 // When a shape is first added to the bank, it is not in the cache. 
00809                                                 // add it and release it to force it to be in the cache.
00810                                                 IShape  *shp= addRef(fileName);
00811                                                 if(shp)
00812                                                 {
00813                                                         //nlinfo("Loading %s", CPath::lookup(fileName.c_str(), false, false).c_str());
00814                                                         if (flushTextures && drv)
00815                                                         {                                                       
00816                                                                 shp->flushTextures(*drv, 0);
00817                                                         }
00818                                                         release(shp);
00819                                                 }
00820                                         }
00821                                 }
00822                         }
00823                 }
00824         }
00825 
00826 }

void NL3D::CShapeBank::processWaitingShapes  ) 
 

processWaitingShapes must be done one time per frame

Definition at line 134 of file shape_bank.cpp.

References add(), AsyncLoad_Delete, AsyncLoad_Error, AsyncLoad_Ready, AsyncLoad_Shape, AsyncLoad_Texture, NL3D::CMaterial::getLightMap(), NL3D::CMeshBase::getMaterial(), NL3D::CMeshBase::getNbMaterial(), NL3D::CMaterial::getShader(), NL3D::CMaterial::getTexture(), NL3D::IDRV_MAT_MAXTEXTURES, NL3D::IDriver::isTextureExist(), nlstop, processWSUploadTexture(), NL3D::CShapeBank::CWaitingShape::RefCnt, NL3D::CShapeBank::CWaitingShape::ShapePtr, NL3D::CShapeBank::CWaitingShape::Signal, NL3D::CShapeBank::CWaitingShape::State, NL3D::CMaterial::texturePresent(), uint, uint32, uint8, NL3D::CShapeBank::CWaitingShape::UpTextLine, NL3D::CShapeBank::CWaitingShape::UpTextMipMap, NL3D::CShapeBank::CWaitingShape::UpTextProgress, and WaitingShapes.

Referenced by NL3D::CScene::updateWaitingInstances().

00135 {
00136         uint32 nTotalUploaded = 0;
00137         TWaitingShapesMap::iterator wsmmIt = WaitingShapes.begin();
00138         while( wsmmIt != WaitingShapes.end() )
00139         {
00140                 // Backup next iterator
00141                 TWaitingShapesMap::iterator wsmmItNext = wsmmIt;
00142                 wsmmItNext++;
00143 
00144                 const string &shapeName = wsmmIt->first;
00145                 CWaitingShape &rWS = wsmmIt->second;
00146                 IShape *pShp = rWS.ShapePtr; // Take care this value is shared between thread so copy it in a local variable first
00147 
00148                 switch (rWS.State)
00149                 {
00150                         case AsyncLoad_Shape: // Check if we can pass to the AsyncLoad_Texture state
00151                                 if (pShp != NULL)
00152                                 {
00153                                         if (pShp == (IShape*)-1)
00154                                                 rWS.State = AsyncLoad_Error;
00155                                         else
00156                                                 rWS.State = AsyncLoad_Texture;
00157                                 }
00158                         break;
00159 
00160                         case AsyncLoad_Texture:
00161                         {
00162                                 // Setup all textures and lightmaps of the shape
00163                                 if (nTotalUploaded > _MaxUploadPerFrame)
00164                                         break;
00165 
00166                                 CMesh *pMesh = dynamic_cast<CMesh*>(pShp);
00167                                 if( pMesh != NULL )
00168                                 {
00169                                         uint8 j;
00170                                         uint32 i, CurrentProgress = 0;
00171                                         uint32 nNbMat = pMesh->getNbMaterial();
00172 
00173                                         for (i = 0; i < nNbMat; ++i)
00174                                         {
00175                                                 const CMaterial &rMat = pMesh->getMaterial(i);
00176                                                 // Parse all textures from this material and setup
00177                                                 for (j = 0; j < IDRV_MAT_MAXTEXTURES; ++j)
00178                                                 {
00179                                                         if (CurrentProgress >= rWS.UpTextProgress)
00180                                                         {
00181                                                                 if (rMat.texturePresent(j))
00182                                                                 {
00183                                                                         if ((!_pDriver->isTextureExist(*rMat.getTexture(j))) || 
00184                                                                                 (rWS.UpTextLine > 0) || (rWS.UpTextMipMap > 0))
00185                                                                         {
00186                                                                                 //_pDriver->setupTexture (*rMat.getTexture(j));
00187 
00188                                                                                 if (!processWSUploadTexture (rWS, nTotalUploaded, rMat.getTexture(j)))
00189                                                                                         break;
00190                                                                         }
00191                                                                 }
00192                                                                 ++rWS.UpTextProgress;
00193                                                         }
00194                                                         ++CurrentProgress;
00195                                                         if (nTotalUploaded > _MaxUploadPerFrame)
00196                                                                 break;
00197                                                 }
00198 
00199                                                 if (nTotalUploaded > _MaxUploadPerFrame)
00200                                                         break;
00201 
00202                                                 // Do the same with lightmaps
00203                                                 if (rMat.getShader() == CMaterial::LightMap)
00204                                                 {
00205                                                         uint j = 0; ITexture *pText = rMat.getLightMap (j);
00206                                                         while (pText != NULL)
00207                                                         {
00208                                                                 if (CurrentProgress >= rWS.UpTextProgress)
00209                                                                 {
00210                                                                         if ((!_pDriver->isTextureExist(*pText)) || 
00211                                                                                 (rWS.UpTextLine > 0) || (rWS.UpTextMipMap > 0))
00212                                                                         {
00213                                                                                 //_pDriver->setupTexture (*pText);
00214                                                                                 
00215                                                                                 if (!processWSUploadTexture (rWS, nTotalUploaded, pText))
00216                                                                                         break;
00217                                                                         }
00218                                                                         ++rWS.UpTextProgress;
00219                                                                 }
00220                                                                 ++CurrentProgress;
00221                                                                 ++j; pText = rMat.getLightMap (j);
00222                                                                 if (nTotalUploaded > _MaxUploadPerFrame)
00223                                                                         break;
00224                                                         }
00225                                                 }
00226                                                 if (nTotalUploaded > _MaxUploadPerFrame)
00227                                                         break;
00228                                         }
00229                                 }
00230                                 if (nTotalUploaded > _MaxUploadPerFrame)
00231                                         break;
00232 
00233                                 rWS.State = AsyncLoad_Ready;
00234                         }                               
00235                         break;
00236 
00237                         case AsyncLoad_Ready:
00238                                 add (wsmmIt->first, pShp);
00239                                 rWS.State = AsyncLoad_Delete;
00240                         break;
00241 
00242                         // The delete operation can take several frames to complete but this is not a problem
00243 
00244                         // For error do the same as delete but let the flag to error if a shape is asked just after 
00245                         // the error was found
00246 
00247                         case AsyncLoad_Error:
00248                         case AsyncLoad_Delete:
00249                                 rWS.RefCnt -= 1;
00250                                 if (rWS.RefCnt == 0)
00251                                 {
00252                                         // We have to signal if we are the last
00253                                         std::set<bool *>::iterator ite = rWS.Signal.begin();
00254                                         while (ite != rWS.Signal.end())
00255                                         {
00256                                                 bool *bSignal = *ite;
00257                                                 if (bSignal != NULL)
00258                                                 {
00259                                                         bool bFound = false;
00260                                                         TWaitingShapesMap::iterator wsmmIt2 = WaitingShapes.begin();
00261                                                         while (wsmmIt2 != WaitingShapes.end())
00262                                                         {
00263                                                                 const string &shapeName2 = wsmmIt2->first;
00264                                                                 if (shapeName2 != shapeName)
00265                                                                 {
00266                                                                         std::set<bool *>::iterator ite2 = wsmmIt2->second.Signal.begin();
00267                                                                         while (ite2 != wsmmIt2->second.Signal.end())
00268                                                                         {
00269                                                                                 if (*ite2 == bSignal)
00270                                                                                 {
00271                                                                                         bFound = true;
00272                                                                                         break;
00273                                                                                 }
00274                                                                                 ite2++;
00275                                                                         }
00276                                                                         if (ite2 != wsmmIt2->second.Signal.end())
00277                                                                                 break;
00278                                                                 }
00279                                                                 ++wsmmIt2;
00280                                                         }
00281                                                         if (!bFound)
00282                                                                 *bSignal = true;
00283                                                 }
00284 
00285                                                 // Next iterator
00286                                                 ite++;
00287                                         }
00288                                         WaitingShapes.erase (wsmmIt);
00289                                 }
00290                         break;
00291 
00292                         default:
00293                                 nlstop; // This must never happen
00294                         break;
00295                 }
00296 
00297                 wsmmIt = wsmmItNext;
00298         }
00299 }

bool NL3D::CShapeBank::processWSUploadTexture CWaitingShape rWS,
uint32 nTotalUploaded,
ITexture pText
[private]
 

return true if the texture is entirely uploaded

Definition at line 308 of file shape_bank.cpp.

References NLMISC::CBitmap::getHeight(), NLMISC::CBitmap::getMipMapCount(), NLMISC::CBitmap::getPixelFormat(), NL3D::ITexture::getReleasable(), NLMISC::CBitmap::getSize(), NLMISC::CBitmap::getWidth(), NL3D::ITexture::isTextureCube(), NL3D::ITexture::mipMapOn(), NL3D::ITexture::release(), NLMISC::CRect::set(), NL3D::ITexture::setReleasable(), NL3D::IDriver::setupTextureEx(), uint32, uint8, NL3D::IDriver::uploadTexture(), NL3D::IDriver::uploadTextureCube(), NL3D::CShapeBank::CWaitingShape::UpTextLine, and NL3D::CShapeBank::CWaitingShape::UpTextMipMap.

Referenced by processWaitingShapes().

00309 {
00310         CRect zeRect;
00311         uint32 nFace, nWeight = 0, nMipMap;
00312         
00313         if ((rWS.UpTextMipMap == 0) && (rWS.UpTextLine == 0))
00314         {
00315                 // Create the texture only and do not upload anything
00316                 bool isRel = pText->getReleasable ();
00317                 pText->setReleasable (false);
00318                 bool isAllUploaded = false;
00319                 _pDriver->setupTextureEx (*pText, false, isAllUploaded);
00320                 pText->setReleasable (isRel);
00321                 if (isAllUploaded)
00322                         return true;
00323         }
00324         
00325         if (pText->mipMapOn())
00326                 nMipMap = pText->getMipMapCount();
00327         else
00328                 nMipMap = 1;
00329         
00330         // Upload all mipmaps
00331         for (; rWS.UpTextMipMap < nMipMap; ++rWS.UpTextMipMap)
00332         {
00333                 uint32 nMM = rWS.UpTextMipMap;
00334                 // What is left to upload ?
00335                 nWeight = pText->getSize (nMM) - rWS.UpTextLine*pText->getWidth(nMM);
00336                 nWeight *= CBitmap::bitPerPixels[pText->getPixelFormat()]/8;
00337                 if (pText->isTextureCube())
00338                         nWeight *= 6;
00339 
00340                 // Setup rectangle
00341                 if ((nTotalUploaded + nWeight) > _MaxUploadPerFrame)
00342                 {
00343                         // We cannot upload the whole mipmap -> we have to cut it
00344                         uint32 nSizeToUpload = _MaxUploadPerFrame - nTotalUploaded;
00345                         uint32 nLineWeight = pText->getWidth(nMM)*CBitmap::bitPerPixels[pText->getPixelFormat()]/8;
00346                         if (pText->isTextureCube())
00347                                 nLineWeight *= 6;
00348                         uint32 nNbLineToUpload = nSizeToUpload / nLineWeight;
00349                         nNbLineToUpload = nNbLineToUpload / 4;
00350                         if (nNbLineToUpload == 0)
00351                                 nNbLineToUpload = 1;
00352                         nNbLineToUpload *= 4; // Upload 4 line by 4 line
00353                         uint32 nNewLine = rWS.UpTextLine + nNbLineToUpload;
00354                         if (nNewLine > pText->getHeight(nMM))
00355                                 nNewLine = pText->getHeight(nMM);
00356                         zeRect.set (0, rWS.UpTextLine, pText->getWidth(nMM), nNewLine);
00357                         rWS.UpTextLine = nNewLine;
00358                         if (rWS.UpTextLine == pText->getHeight(nMM))
00359                         {
00360                                 rWS.UpTextLine = 0;
00361                                 rWS.UpTextMipMap += 1;
00362                         }
00363                 }
00364                 else
00365                 {
00366                         // We can upload the whole mipmap (or the whole rest of the mipmap)
00367                         zeRect.set (0, rWS.UpTextLine, pText->getWidth(nMM), pText->getHeight(nMM));
00368                         rWS.UpTextLine = 0;
00369                 }
00370 
00371                 // Upload !
00372                 if (pText->isTextureCube())
00373                 {
00374                         for (nFace = 0; nFace < 6; ++nFace)
00375                                 _pDriver->uploadTextureCube (*pText, zeRect, (uint8)nMM, (uint8)nFace);
00376                 }
00377                 else
00378                 {
00379                         _pDriver->uploadTexture (*pText, zeRect, (uint8)nMM);
00380                 }
00381 
00382                 nTotalUploaded += nWeight;
00383                 if (nTotalUploaded > _MaxUploadPerFrame)
00384                         return false;
00385         }
00386 
00387         if (pText->getReleasable())
00388                 pText->release();
00389 
00390         rWS.UpTextMipMap = 0;
00391         rWS.UpTextLine = 0;
00392         return true;
00393 }

void NL3D::CShapeBank::release IShape pShp  ) 
 

Release a reference to a shape by its instance. If the shape has no more reference it is added to its own shape cache. When the shape cache is full the last entry is deleted.

Definition at line 95 of file shape_bank.cpp.

References checkShapeCache(), NL3D::CShapeBank::CShapeCache::Elements, getShapeCachePtrFromShapePtr(), getShapeNameFromShapePtr(), nlassert, nlwarning, ShapeMap, and ShapePtrToShapeInfo.

Referenced by NL3D::CScene::deleteInstance(), preLoadShapes(), NL3D::CPSConstraintMesh::releaseShapes(), and NL3D::CPSConstraintMesh::update().

00096 {
00097         // Do we have the last smartPtr on the shape ?
00098         string* str = getShapeNameFromShapePtr( pShp );
00099 
00100         if (str == NULL)
00101         {
00102                 nlwarning ("Trying to release a mesh that have not be added to the shape bank");
00103         }
00104         else
00105         {
00106                 TShapeMap::iterator smIt = ShapeMap.find( *str );
00107                 if( smIt != ShapeMap.end() )
00108                 {
00109                         if( smIt->second.getNbRef() == 1 )
00110                         {
00111                                 // Yes -> add the shape to its shapeCache
00112                                 CShapeCache *pShpCache = getShapeCachePtrFromShapePtr( pShp );
00113                                 pShpCache->Elements.push_front( pShp );
00114 
00115                                 TShapeInfoMap::iterator scfpmIt = ShapePtrToShapeInfo.find( pShp );
00116                                 if( scfpmIt != ShapePtrToShapeInfo.end() )
00117                                 {
00118                                         scfpmIt->second.isAdded = true;
00119                                 }
00120                                 
00121                                 // check the shape cache
00122                                 checkShapeCache(getShapeCachePtrFromShapePtr(pShp));
00123                         }
00124                 }
00125                 else
00126                 {
00127                         nlassert( false );
00128                 }
00129         }
00130 }

void NL3D::CShapeBank::removeShapeCache const std::string &  shapeCacheName  ) 
 

Remove a ShapeCache. All shapes in the shape cache are deleted. All links are redirected to the default ShapeCache

Definition at line 574 of file shape_bank.cpp.

References checkShapeCache(), getShapeCachePtrFromShapeCacheName(), NL3D::CShapeBank::CShapeCache::MaxSize, ShapeCacheNameToShapeCache, and ShapeNameToShapeCacheName.

Referenced by NL3D::CShapeBankUser::removeShapeCache().

00575 {
00576         if( shapeCacheName == "default" )
00577                 return;
00578 
00579         // Free the shape cache
00580         CShapeCache *pShpCache = getShapeCachePtrFromShapeCacheName( shapeCacheName );
00581         if( pShpCache == NULL )
00582                 return;
00583         pShpCache->MaxSize = 0;
00584         checkShapeCache( pShpCache );
00585 
00586         // Remove it
00587         ShapeCacheNameToShapeCache.erase( shapeCacheName );
00588 
00589         // All links are redirected to the default cache
00590         TShapeCacheNameMap::iterator scnIt = ShapeNameToShapeCacheName.begin();
00591         while( scnIt != ShapeNameToShapeCacheName.end() )       
00592         {
00593                 if( scnIt->second == shapeCacheName )
00594                         scnIt->second = "default";
00595                 ++scnIt;
00596         }
00597 }

void NL3D::CShapeBank::reset  ) 
 

Remove all ShapeCache and suppress all links (even the link to the default cache are removed)

Definition at line 601 of file shape_bank.cpp.

References addShapeCache(), checkShapeCache(), getShapeCachePtrFromShapeCacheName(), NL3D::CShapeBank::CShapeCache::MaxSize, nlstop, ShapeCacheNameToShapeCache, and ShapeNameToShapeCacheName.

Referenced by NL3D::CShapeBankUser::reset().

00602 {
00603         // Parse la map ShapeCacheNameToShapeCache pour supprimer tout les caches
00604         TShapeCacheMap::iterator scmIt = ShapeCacheNameToShapeCache.begin();
00605         while( scmIt != ShapeCacheNameToShapeCache.end() )
00606         {
00607                 CShapeCache *pShpCache = getShapeCachePtrFromShapeCacheName( scmIt->first );
00608                 if( pShpCache == NULL )
00609                         nlstop; // Should never happen
00610                 pShpCache->MaxSize = 0;
00611                 checkShapeCache( pShpCache );
00612 
00613                 ++scmIt;
00614         }
00615         ShapeNameToShapeCacheName.clear();
00616         ShapeCacheNameToShapeCache.clear();     
00617         addShapeCache( "default" );
00618 }

void NL3D::CShapeBank::setMaxBytesToUpload uint32  MaxUploadPerFrame  ) 
 

Setup the maximum number of bytes to upload for a frame (texture upload from RAM to VRAM).

Definition at line 302 of file shape_bank.cpp.

References uint32.

Referenced by NL3D::CScene::updateWaitingInstances().

00303 {
00304         _MaxUploadPerFrame = MaxUploadPerFrame;
00305 }

void NL3D::CShapeBank::setShapeCacheSize const std::string &  shapeCacheName,
sint32  maxSize
 

Set the shapeCache shapeCacheName the new size.(delete shapes if maxsize<shapeCacheSize).

Definition at line 622 of file shape_bank.cpp.

References checkShapeCache(), getShapeCachePtrFromShapeCacheName(), ShapeCacheNameToShapeCache, and sint32.

Referenced by NL3D::CShapeBankUser::setShapeCacheSize().

00623 {
00624         TShapeCacheMap::iterator scmIt = ShapeCacheNameToShapeCache.find( shapeCacheName );
00625         if( scmIt != ShapeCacheNameToShapeCache.end() )
00626         {
00627                 scmIt->second.MaxSize = maxSize;
00628                 checkShapeCache(getShapeCachePtrFromShapeCacheName(shapeCacheName));
00629         }
00630 }


Field Documentation

uint32 NL3D::CShapeBank::_MaxUploadPerFrame [private]
 

Definition at line 194 of file shape_bank.h.

IDriver* NL3D::CShapeBank::_pDriver [private]
 

Definition at line 203 of file shape_bank.h.

TShapeCacheMap NL3D::CShapeBank::ShapeCacheNameToShapeCache [private]
 

Definition at line 235 of file shape_bank.h.

Referenced by addShapeCache(), getShapeCacheFreeSpace(), getShapeCachePtrFromShapeCacheName(), isShapeCache(), removeShapeCache(), reset(), and setShapeCacheSize().

TShapeMap NL3D::CShapeBank::ShapeMap [private]
 

Definition at line 169 of file shape_bank.h.

Referenced by add(), checkShapeCache(), getShape(), getShapePtrFromShapeName(), isPresent(), load(), loadAsync(), and release().

TShapeCacheNameMap NL3D::CShapeBank::ShapeNameToShapeCacheName [private]
 

Definition at line 234 of file shape_bank.h.

Referenced by add(), getShapeCachePtrFromShapeName(), linkShapeToShapeCache(), removeShapeCache(), and reset().

TShapeInfoMap NL3D::CShapeBank::ShapePtrToShapeInfo [private]
 

Definition at line 236 of file shape_bank.h.

Referenced by add(), addRef(), checkShapeCache(), getShapeCachePtrFromShapePtr(), getShapeNameFromShapePtr(), linkShapeToShapeCache(), and release().

TWaitingShapesMap NL3D::CShapeBank::WaitingShapes [private]
 

Definition at line 193 of file shape_bank.h.

Referenced by cancelLoadAsync(), isPresent(), isShapeWaiting(), load(), loadAsync(), and processWaitingShapes().


The documentation for this class was generated from the following files:
Generated on Tue Mar 16 07:44:03 2004 for NeL by doxygen 1.3.6