00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "std3d.h"
00027
00028 #include "3d/async_file_manager_3d.h"
00029 #include "3d/shape.h"
00030 #include "3d/mesh.h"
00031 #include "3d/texture_file.h"
00032 #include "3d/scene_group.h"
00033
00034 #include "3d/instance_group_user.h"
00035
00036 #include "nel/misc/file.h"
00037 #include "nel/misc/path.h"
00038
00039
00040 using namespace std;
00041 using namespace NLMISC;
00042
00043 #define NL3D_MEM_INSTANCE NL_ALLOC_CONTEXT( 3dInst )
00044 #define NL3D_MEM_IG NL_ALLOC_CONTEXT( 3dIg )
00045
00046 namespace NL3D
00047 {
00048
00049 CAsyncFileManager3D *CAsyncFileManager3D::_Singleton = NULL;
00050
00051
00052
00053 CAsyncFileManager3D::CAsyncFileManager3D()
00054 {
00055 }
00056
00057
00058
00059 CAsyncFileManager3D &CAsyncFileManager3D::getInstance()
00060 {
00061 if (_Singleton == NULL)
00062 {
00063 _Singleton = new CAsyncFileManager3D();
00064 }
00065 return *_Singleton;
00066 }
00067
00068
00069
00070 void CAsyncFileManager3D::terminate ()
00071 {
00072 if (_Singleton != NULL)
00073 {
00074 delete &getInstance();
00075 _Singleton = NULL;
00076 }
00077 }
00078
00079
00080
00081 void CAsyncFileManager3D::loadMesh(const std::string& meshName, IShape **ppShp, IDriver *pDriver)
00082 {
00083 CAsyncFileManager::getInstance().addLoadTask(new CMeshLoad(meshName, ppShp, pDriver));
00084 }
00085
00086
00087
00088
00089 class CLoadMeshCancel : public NLMISC::CAsyncFileManager::ICancelCallback
00090 {
00091 public:
00092 CLoadMeshCancel (const std::string &meshName)
00093 : _MeshName(meshName)
00094 {}
00095
00096 private:
00097 std::string _MeshName;
00098
00099 bool callback(const NLMISC::IRunnable *prunnable) const
00100 {
00101 const CAsyncFileManager3D::CMeshLoad *pML = dynamic_cast<const CAsyncFileManager3D::CMeshLoad*>(prunnable);
00102 if (pML != NULL)
00103 {
00104 if (pML->MeshName == _MeshName)
00105 {
00106 return true;
00107 }
00108 }
00109 return false;
00110 }
00111 };
00112
00113 bool CAsyncFileManager3D::cancelLoadMesh(const std::string& sMeshName)
00114 {
00115 return CAsyncFileManager::getInstance().cancelLoadTask(CLoadMeshCancel(sMeshName));
00116 }
00117
00118
00119
00120 void CAsyncFileManager3D::loadIG (const std::string& IGName, CInstanceGroup **ppIG)
00121 {
00122 CAsyncFileManager::getInstance().addLoadTask(new CIGLoad(IGName, ppIG));
00123 }
00124
00125
00126
00127 void CAsyncFileManager3D::loadIGUser (const std::string& IGName, UInstanceGroup **ppIG)
00128 {
00129 CAsyncFileManager::getInstance().addLoadTask (new CIGLoadUser(IGName, ppIG));
00130 }
00131
00132
00133 void CAsyncFileManager3D::loadTexture (CTextureFile *textureFile, bool *pSgn)
00134 {
00135 nlassert(textureFile && pSgn);
00136 CAsyncFileManager::getInstance().addLoadTask(new CTextureLoad(textureFile, pSgn));
00137 }
00138
00139
00140 class CLoadTextureCancel : public NLMISC::CAsyncFileManager::ICancelCallback
00141 {
00142 public:
00143 CLoadTextureCancel (CTextureFile *ptextureFile)
00144 : _TextureFile(ptextureFile)
00145 {}
00146
00147 private:
00148 CTextureFile *_TextureFile;
00149
00150 bool callback(const NLMISC::IRunnable *prunnable) const
00151 {
00152 const CAsyncFileManager3D::CTextureLoad *pTL = dynamic_cast<const CAsyncFileManager3D::CTextureLoad*>(prunnable);
00153 if (pTL != NULL)
00154 {
00155 if (pTL->TextureFile == _TextureFile)
00156 {
00157 return true;
00158 }
00159 }
00160 return false;
00161 }
00162 };
00163
00164
00165
00166 bool CAsyncFileManager3D::cancelLoadTexture (CTextureFile *textFile)
00167 {
00168 return CAsyncFileManager::getInstance().cancelLoadTask(CLoadTextureCancel(textFile));
00169 }
00170
00171
00172
00173
00174 void CAsyncFileManager3D::loadFile (const std::string& sFileName, uint8 **ppFile)
00175 {
00176 CAsyncFileManager::getInstance().loadFile (sFileName, ppFile);
00177 }
00178
00179
00180
00181 void CAsyncFileManager3D::loadFiles (const std::vector<std::string> &vFileNames, const std::vector<uint8**> &vPtrs)
00182 {
00183 CAsyncFileManager::getInstance().loadFiles (vFileNames, vPtrs);
00184 }
00185
00186
00187
00188 void CAsyncFileManager3D::signal (bool *pSgn)
00189 {
00190 CAsyncFileManager::getInstance().signal(pSgn);
00191 }
00192
00193
00194
00195 void CAsyncFileManager3D::cancelSignal (bool *pSgn)
00196 {
00197 CAsyncFileManager::getInstance().cancelSignal(pSgn);
00198 }
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208 CAsyncFileManager3D::CMeshLoad::CMeshLoad(const std::string& sMeshName, IShape** ppShp, IDriver *pDriver)
00209 {
00210 _pDriver = pDriver;
00211 MeshName = sMeshName;
00212 _ppShp = ppShp;
00213 }
00214
00215
00216
00217 void CAsyncFileManager3D::CMeshLoad::run()
00218 {
00219 NL3D_MEM_INSTANCE
00220
00221
00222
00223
00224 typedef set<string> TAlreadyPresentTextureSet;
00225 TAlreadyPresentTextureSet AlreadyPresentTextureSet;
00226
00227 try
00228 {
00229
00230 CShapeStream mesh;
00231 CIFile meshfile;
00232 meshfile.setAsyncLoading (true);
00233 meshfile.setCacheFileOnOpen (true);
00234 meshfile.open (CPath::lookup(MeshName));
00235 meshfile.serial (mesh);
00236 meshfile.close ();
00237
00238
00239 if (mesh.getShapePointer() == NULL)
00240 {
00241 nlwarning ("Couldn't load '%s'", MeshName.c_str());
00242 *_ppShp = (IShape*)-1;
00243 delete this;
00244 return;
00245 }
00246
00247 CMeshBase *pMesh = dynamic_cast<CMeshBase *>(mesh.getShapePointer());
00248
00249
00250
00251
00252 if ((pMesh == NULL) || ((pMesh != NULL) && (_pDriver == NULL)))
00253 {
00254 if (_pDriver == NULL || mesh.getShapePointer() == NULL)
00255 {
00256 nlwarning ("mesh or driver is NULL for file '%s'", MeshName.c_str());
00257 }
00258
00259 *_ppShp = mesh.getShapePointer();
00260 delete this;
00261 return;
00262 }
00263
00264
00265 uint i, j;
00266 uint nNbMat = pMesh->getNbMaterial();
00267 ITexture *pText;
00268
00269 for(i = 0; i < nNbMat; ++i)
00270 {
00271 const CMaterial &rMat = pMesh->getMaterial(i);
00272
00273 for(j = 0; j < IDRV_MAT_MAXTEXTURES; ++j)
00274 if (rMat.texturePresent(j))
00275 {
00276 pText = rMat.getTexture (j);
00277
00278 CTextureFile *pTextFile = dynamic_cast<CTextureFile*>(pText);
00279
00280 if(pTextFile != NULL)
00281
00282 if( ! _pDriver->isTextureExist(*pTextFile) )
00283 {
00284
00285 TAlreadyPresentTextureSet::iterator aptmIt = AlreadyPresentTextureSet.find (pTextFile->getFileName());
00286
00287 if(aptmIt == AlreadyPresentTextureSet.end())
00288 {
00289
00290
00291 AlreadyPresentTextureSet.insert (pTextFile->getFileName());
00292
00293 pTextFile->setAsyncLoading (true);
00294 pTextFile->generate();
00295 pTextFile->setAsyncLoading (false);
00296 }
00297 }
00298 }
00299
00300
00301 if (rMat.getShader() == CMaterial::LightMap)
00302 {
00303 j = 0; pText = rMat.getLightMap (j);
00304 while (pText != NULL)
00305 {
00306 CTextureFile *pTextFile = dynamic_cast<CTextureFile*>(pText);
00307
00308 if(pTextFile != NULL)
00309
00310 if (!_pDriver->isTextureExist(*pTextFile))
00311 {
00312
00313 TAlreadyPresentTextureSet::iterator aptmIt = AlreadyPresentTextureSet.find (pTextFile->getFileName());
00314
00315 if(aptmIt == AlreadyPresentTextureSet.end())
00316 {
00317
00318 AlreadyPresentTextureSet.insert (pTextFile->getFileName());
00319 pTextFile->setAsyncLoading (true);
00320 pTextFile->generate();
00321 pTextFile->setAsyncLoading (false);
00322 }
00323 }
00324 ++j; pText = rMat.getLightMap (j);
00325 }
00326 }
00327 }
00328
00329 *_ppShp = mesh.getShapePointer();
00330 }
00331 catch(EPathNotFound &)
00332 {
00333 nlwarning ("Couldn't load '%s'", MeshName.c_str());
00334 *_ppShp = (IShape*)-1;
00335 delete this;
00336 return;
00337 }
00338 delete this;
00339 }
00340
00341
00342
00343
00344
00345
00346 CAsyncFileManager3D::CIGLoad::CIGLoad (const std::string &IGName, CInstanceGroup **ppIG)
00347 {
00348 _IGName = IGName;
00349 _ppIG = ppIG;
00350 }
00351
00352
00353 void CAsyncFileManager3D::CIGLoad::run (void)
00354 {
00355 try
00356 {
00357 CIFile igfile;
00358 igfile.setAsyncLoading (true);
00359 igfile.setCacheFileOnOpen (true);
00360 igfile.open (CPath::lookup (_IGName));
00361 CInstanceGroup *pIG = new CInstanceGroup();
00362 pIG->serial (igfile);
00363 igfile.close();
00364
00365 *_ppIG = pIG;
00366 }
00367 catch(EPathNotFound &)
00368 {
00369 nlwarning ("Couldn't load '%s'", _IGName.c_str());
00370 *_ppIG = (CInstanceGroup*)-1;
00371 delete this;
00372 return;
00373 }
00374 delete this;
00375 }
00376
00377
00378
00379
00380
00381
00382 CAsyncFileManager3D::CIGLoadUser::CIGLoadUser (const std::string &IGName, UInstanceGroup **ppIG)
00383 {
00384 _IGName = IGName;
00385 _ppIG = ppIG;
00386 }
00387
00388
00389 void CAsyncFileManager3D::CIGLoadUser::run (void)
00390 {
00391 NL3D_MEM_IG
00392 try
00393 {
00394 CInstanceGroupUser *pIG = new CInstanceGroupUser();
00395 if (pIG->init (_IGName))
00396 {
00397 *_ppIG = pIG;
00398 }
00399 else
00400 {
00401 nlwarning ("Couldn't init '%s'", _IGName.c_str());
00402 *_ppIG = (UInstanceGroup*)-1;
00403 delete this;
00404 return;
00405 }
00406 }
00407 catch(EPathNotFound &)
00408 {
00409 nlwarning ("Couldn't load '%s'", _IGName.c_str());
00410 *_ppIG = (UInstanceGroup*)-1;
00411 delete this;
00412 return;
00413 }
00414 delete this;
00415 }
00416
00417
00418
00419
00420
00421
00422 void CAsyncFileManager3D::CTextureLoad::run()
00423 {
00424
00425 TextureFile->setAsyncLoading (true);
00426 TextureFile->generate();
00427 TextureFile->setAsyncLoading (false);
00428
00429 *Signal= true;
00430
00431 delete this;
00432 }
00433
00434 }
00435
00436