vrshoot

annotate libs/assimp/BaseImporter.cpp @ 0:b2f14e535253

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 01 Feb 2014 19:58:19 +0200
parents
children
rev   line source
nuclear@0 1 /*
nuclear@0 2 ---------------------------------------------------------------------------
nuclear@0 3 Open Asset Import Library (assimp)
nuclear@0 4 ---------------------------------------------------------------------------
nuclear@0 5
nuclear@0 6 Copyright (c) 2006-2012, assimp team
nuclear@0 7
nuclear@0 8 All rights reserved.
nuclear@0 9
nuclear@0 10 Redistribution and use of this software in source and binary forms,
nuclear@0 11 with or without modification, are permitted provided that the following
nuclear@0 12 conditions are met:
nuclear@0 13
nuclear@0 14 * Redistributions of source code must retain the above
nuclear@0 15 copyright notice, this list of conditions and the
nuclear@0 16 following disclaimer.
nuclear@0 17
nuclear@0 18 * Redistributions in binary form must reproduce the above
nuclear@0 19 copyright notice, this list of conditions and the
nuclear@0 20 following disclaimer in the documentation and/or other
nuclear@0 21 materials provided with the distribution.
nuclear@0 22
nuclear@0 23 * Neither the name of the assimp team, nor the names of its
nuclear@0 24 contributors may be used to endorse or promote products
nuclear@0 25 derived from this software without specific prior
nuclear@0 26 written permission of the assimp team.
nuclear@0 27
nuclear@0 28 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
nuclear@0 29 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
nuclear@0 30 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
nuclear@0 31 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
nuclear@0 32 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
nuclear@0 33 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
nuclear@0 34 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
nuclear@0 35 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
nuclear@0 36 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
nuclear@0 37 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
nuclear@0 38 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
nuclear@0 39 ---------------------------------------------------------------------------
nuclear@0 40 */
nuclear@0 41
nuclear@0 42 /** @file BaseImporter.cpp
nuclear@0 43 * @brief Implementation of BaseImporter
nuclear@0 44 */
nuclear@0 45
nuclear@0 46 #include "AssimpPCH.h"
nuclear@0 47 #include "BaseImporter.h"
nuclear@0 48 #include "FileSystemFilter.h"
nuclear@0 49
nuclear@0 50 #include "Importer.h"
nuclear@0 51
nuclear@0 52 using namespace Assimp;
nuclear@0 53
nuclear@0 54 // ------------------------------------------------------------------------------------------------
nuclear@0 55 // Constructor to be privately used by Importer
nuclear@0 56 BaseImporter::BaseImporter()
nuclear@0 57 : progress()
nuclear@0 58 {
nuclear@0 59 // nothing to do here
nuclear@0 60 }
nuclear@0 61
nuclear@0 62 // ------------------------------------------------------------------------------------------------
nuclear@0 63 // Destructor, private as well
nuclear@0 64 BaseImporter::~BaseImporter()
nuclear@0 65 {
nuclear@0 66 // nothing to do here
nuclear@0 67 }
nuclear@0 68
nuclear@0 69 // ------------------------------------------------------------------------------------------------
nuclear@0 70 // Imports the given file and returns the imported data.
nuclear@0 71 aiScene* BaseImporter::ReadFile(const Importer* pImp, const std::string& pFile, IOSystem* pIOHandler)
nuclear@0 72 {
nuclear@0 73 progress = pImp->GetProgressHandler();
nuclear@0 74 ai_assert(progress);
nuclear@0 75
nuclear@0 76 // Gather configuration properties for this run
nuclear@0 77 SetupProperties( pImp );
nuclear@0 78
nuclear@0 79 // Construct a file system filter to improve our success ratio at reading external files
nuclear@0 80 FileSystemFilter filter(pFile,pIOHandler);
nuclear@0 81
nuclear@0 82 // create a scene object to hold the data
nuclear@0 83 ScopeGuard<aiScene> sc(new aiScene());
nuclear@0 84
nuclear@0 85 // dispatch importing
nuclear@0 86 try
nuclear@0 87 {
nuclear@0 88 InternReadFile( pFile, sc, &filter);
nuclear@0 89
nuclear@0 90 } catch( const std::exception& err ) {
nuclear@0 91 // extract error description
nuclear@0 92 mErrorText = err.what();
nuclear@0 93 DefaultLogger::get()->error(mErrorText);
nuclear@0 94 return NULL;
nuclear@0 95 }
nuclear@0 96
nuclear@0 97 // return what we gathered from the import.
nuclear@0 98 sc.dismiss();
nuclear@0 99 return sc;
nuclear@0 100 }
nuclear@0 101
nuclear@0 102 // ------------------------------------------------------------------------------------------------
nuclear@0 103 void BaseImporter::SetupProperties(const Importer* /*pImp*/)
nuclear@0 104 {
nuclear@0 105 // the default implementation does nothing
nuclear@0 106 }
nuclear@0 107
nuclear@0 108 // ------------------------------------------------------------------------------------------------
nuclear@0 109 void BaseImporter::GetExtensionList(std::set<std::string>& extensions)
nuclear@0 110 {
nuclear@0 111 const aiImporterDesc* desc = GetInfo();
nuclear@0 112 ai_assert(desc != NULL);
nuclear@0 113
nuclear@0 114 const char* ext = desc->mFileExtensions;
nuclear@0 115 ai_assert(ext != NULL);
nuclear@0 116
nuclear@0 117 const char* last = ext;
nuclear@0 118 do {
nuclear@0 119 if (!*ext || *ext == ' ') {
nuclear@0 120 extensions.insert(std::string(last,ext-last));
nuclear@0 121 ai_assert(ext-last > 0);
nuclear@0 122 last = ext;
nuclear@0 123 while(*last == ' ') {
nuclear@0 124 ++last;
nuclear@0 125 }
nuclear@0 126 }
nuclear@0 127 }
nuclear@0 128 while(*ext++);
nuclear@0 129 }
nuclear@0 130
nuclear@0 131 // ------------------------------------------------------------------------------------------------
nuclear@0 132 /*static*/ bool BaseImporter::SearchFileHeaderForToken(IOSystem* pIOHandler,
nuclear@0 133 const std::string& pFile,
nuclear@0 134 const char** tokens,
nuclear@0 135 unsigned int numTokens,
nuclear@0 136 unsigned int searchBytes /* = 200 */,
nuclear@0 137 bool tokensSol /* false */)
nuclear@0 138 {
nuclear@0 139 ai_assert(NULL != tokens && 0 != numTokens && 0 != searchBytes);
nuclear@0 140 if (!pIOHandler)
nuclear@0 141 return false;
nuclear@0 142
nuclear@0 143 boost::scoped_ptr<IOStream> pStream (pIOHandler->Open(pFile));
nuclear@0 144 if (pStream.get() ) {
nuclear@0 145 // read 200 characters from the file
nuclear@0 146 boost::scoped_array<char> _buffer (new char[searchBytes+1 /* for the '\0' */]);
nuclear@0 147 char* buffer = _buffer.get();
nuclear@0 148
nuclear@0 149 const unsigned int read = pStream->Read(buffer,1,searchBytes);
nuclear@0 150 if (!read)
nuclear@0 151 return false;
nuclear@0 152
nuclear@0 153 for (unsigned int i = 0; i < read;++i)
nuclear@0 154 buffer[i] = ::tolower(buffer[i]);
nuclear@0 155
nuclear@0 156 // It is not a proper handling of unicode files here ...
nuclear@0 157 // ehm ... but it works in most cases.
nuclear@0 158 char* cur = buffer,*cur2 = buffer,*end = &buffer[read];
nuclear@0 159 while (cur != end) {
nuclear@0 160 if (*cur)
nuclear@0 161 *cur2++ = *cur;
nuclear@0 162 ++cur;
nuclear@0 163 }
nuclear@0 164 *cur2 = '\0';
nuclear@0 165
nuclear@0 166 for (unsigned int i = 0; i < numTokens;++i) {
nuclear@0 167 ai_assert(NULL != tokens[i]);
nuclear@0 168
nuclear@0 169
nuclear@0 170 const char* r = strstr(buffer,tokens[i]);
nuclear@0 171 if (!r)
nuclear@0 172 continue;
nuclear@0 173 // We got a match, either we don't care where it is, or it happens to
nuclear@0 174 // be in the beginning of the file / line
nuclear@0 175 if (!tokensSol || r == buffer || r[-1] == '\r' || r[-1] == '\n') {
nuclear@0 176 DefaultLogger::get()->debug(std::string("Found positive match for header keyword: ") + tokens[i]);
nuclear@0 177 return true;
nuclear@0 178 }
nuclear@0 179 }
nuclear@0 180 }
nuclear@0 181 return false;
nuclear@0 182 }
nuclear@0 183
nuclear@0 184 // ------------------------------------------------------------------------------------------------
nuclear@0 185 // Simple check for file extension
nuclear@0 186 /*static*/ bool BaseImporter::SimpleExtensionCheck (const std::string& pFile,
nuclear@0 187 const char* ext0,
nuclear@0 188 const char* ext1,
nuclear@0 189 const char* ext2)
nuclear@0 190 {
nuclear@0 191 std::string::size_type pos = pFile.find_last_of('.');
nuclear@0 192
nuclear@0 193 // no file extension - can't read
nuclear@0 194 if( pos == std::string::npos)
nuclear@0 195 return false;
nuclear@0 196
nuclear@0 197 const char* ext_real = & pFile[ pos+1 ];
nuclear@0 198 if( !ASSIMP_stricmp(ext_real,ext0) )
nuclear@0 199 return true;
nuclear@0 200
nuclear@0 201 // check for other, optional, file extensions
nuclear@0 202 if (ext1 && !ASSIMP_stricmp(ext_real,ext1))
nuclear@0 203 return true;
nuclear@0 204
nuclear@0 205 if (ext2 && !ASSIMP_stricmp(ext_real,ext2))
nuclear@0 206 return true;
nuclear@0 207
nuclear@0 208 return false;
nuclear@0 209 }
nuclear@0 210
nuclear@0 211 // ------------------------------------------------------------------------------------------------
nuclear@0 212 // Get file extension from path
nuclear@0 213 /*static*/ std::string BaseImporter::GetExtension (const std::string& pFile)
nuclear@0 214 {
nuclear@0 215 std::string::size_type pos = pFile.find_last_of('.');
nuclear@0 216
nuclear@0 217 // no file extension at all
nuclear@0 218 if( pos == std::string::npos)
nuclear@0 219 return "";
nuclear@0 220
nuclear@0 221 std::string ret = pFile.substr(pos+1);
nuclear@0 222 std::transform(ret.begin(),ret.end(),ret.begin(),::tolower); // thanks to Andy Maloney for the hint
nuclear@0 223 return ret;
nuclear@0 224 }
nuclear@0 225
nuclear@0 226 // ------------------------------------------------------------------------------------------------
nuclear@0 227 // Check for magic bytes at the beginning of the file.
nuclear@0 228 /* static */ bool BaseImporter::CheckMagicToken(IOSystem* pIOHandler, const std::string& pFile,
nuclear@0 229 const void* _magic, unsigned int num, unsigned int offset, unsigned int size)
nuclear@0 230 {
nuclear@0 231 ai_assert(size <= 16 && _magic);
nuclear@0 232
nuclear@0 233 if (!pIOHandler) {
nuclear@0 234 return false;
nuclear@0 235 }
nuclear@0 236 union {
nuclear@0 237 const char* magic;
nuclear@0 238 const uint16_t* magic_u16;
nuclear@0 239 const uint32_t* magic_u32;
nuclear@0 240 };
nuclear@0 241 magic = reinterpret_cast<const char*>(_magic);
nuclear@0 242 boost::scoped_ptr<IOStream> pStream (pIOHandler->Open(pFile));
nuclear@0 243 if (pStream.get() ) {
nuclear@0 244
nuclear@0 245 // skip to offset
nuclear@0 246 pStream->Seek(offset,aiOrigin_SET);
nuclear@0 247
nuclear@0 248 // read 'size' characters from the file
nuclear@0 249 union {
nuclear@0 250 char data[16];
nuclear@0 251 uint16_t data_u16[8];
nuclear@0 252 uint32_t data_u32[4];
nuclear@0 253 };
nuclear@0 254 if(size != pStream->Read(data,1,size)) {
nuclear@0 255 return false;
nuclear@0 256 }
nuclear@0 257
nuclear@0 258 for (unsigned int i = 0; i < num; ++i) {
nuclear@0 259 // also check against big endian versions of tokens with size 2,4
nuclear@0 260 // that's just for convinience, the chance that we cause conflicts
nuclear@0 261 // is quite low and it can save some lines and prevent nasty bugs
nuclear@0 262 if (2 == size) {
nuclear@0 263 uint16_t rev = *magic_u16;
nuclear@0 264 ByteSwap::Swap(&rev);
nuclear@0 265 if (data_u16[0] == *magic_u16 || data_u16[0] == rev) {
nuclear@0 266 return true;
nuclear@0 267 }
nuclear@0 268 }
nuclear@0 269 else if (4 == size) {
nuclear@0 270 uint32_t rev = *magic_u32;
nuclear@0 271 ByteSwap::Swap(&rev);
nuclear@0 272 if (data_u32[0] == *magic_u32 || data_u32[0] == rev) {
nuclear@0 273 return true;
nuclear@0 274 }
nuclear@0 275 }
nuclear@0 276 else {
nuclear@0 277 // any length ... just compare
nuclear@0 278 if(!memcmp(magic,data,size)) {
nuclear@0 279 return true;
nuclear@0 280 }
nuclear@0 281 }
nuclear@0 282 magic += size;
nuclear@0 283 }
nuclear@0 284 }
nuclear@0 285 return false;
nuclear@0 286 }
nuclear@0 287
nuclear@0 288 #include "ConvertUTF/ConvertUTF.h"
nuclear@0 289
nuclear@0 290 // ------------------------------------------------------------------------------------------------
nuclear@0 291 void ReportResult(ConversionResult res)
nuclear@0 292 {
nuclear@0 293 if(res == sourceExhausted) {
nuclear@0 294 DefaultLogger::get()->error("Source ends with incomplete character sequence, transformation to UTF-8 fails");
nuclear@0 295 }
nuclear@0 296 else if(res == sourceIllegal) {
nuclear@0 297 DefaultLogger::get()->error("Source contains illegal character sequence, transformation to UTF-8 fails");
nuclear@0 298 }
nuclear@0 299 }
nuclear@0 300
nuclear@0 301 // ------------------------------------------------------------------------------------------------
nuclear@0 302 // Convert to UTF8 data
nuclear@0 303 void BaseImporter::ConvertToUTF8(std::vector<char>& data)
nuclear@0 304 {
nuclear@0 305 ConversionResult result;
nuclear@0 306 if(data.size() < 8) {
nuclear@0 307 throw DeadlyImportError("File is too small");
nuclear@0 308 }
nuclear@0 309
nuclear@0 310 // UTF 8 with BOM
nuclear@0 311 if((uint8_t)data[0] == 0xEF && (uint8_t)data[1] == 0xBB && (uint8_t)data[2] == 0xBF) {
nuclear@0 312 DefaultLogger::get()->debug("Found UTF-8 BOM ...");
nuclear@0 313
nuclear@0 314 std::copy(data.begin()+3,data.end(),data.begin());
nuclear@0 315 data.resize(data.size()-3);
nuclear@0 316 return;
nuclear@0 317 }
nuclear@0 318
nuclear@0 319 // UTF 32 BE with BOM
nuclear@0 320 if(*((uint32_t*)&data.front()) == 0xFFFE0000) {
nuclear@0 321
nuclear@0 322 // swap the endianess ..
nuclear@0 323 for(uint32_t* p = (uint32_t*)&data.front(), *end = (uint32_t*)&data.back(); p <= end; ++p) {
nuclear@0 324 AI_SWAP4P(p);
nuclear@0 325 }
nuclear@0 326 }
nuclear@0 327
nuclear@0 328 // UTF 32 LE with BOM
nuclear@0 329 if(*((uint32_t*)&data.front()) == 0x0000FFFE) {
nuclear@0 330 DefaultLogger::get()->debug("Found UTF-32 BOM ...");
nuclear@0 331
nuclear@0 332 const uint32_t* sstart = (uint32_t*)&data.front()+1, *send = (uint32_t*)&data.back()+1;
nuclear@0 333 char* dstart,*dend;
nuclear@0 334 std::vector<char> output;
nuclear@0 335 do {
nuclear@0 336 output.resize(output.size()?output.size()*3/2:data.size()/2);
nuclear@0 337 dstart = &output.front(),dend = &output.back()+1;
nuclear@0 338
nuclear@0 339 result = ConvertUTF32toUTF8((const UTF32**)&sstart,(const UTF32*)send,(UTF8**)&dstart,(UTF8*)dend,lenientConversion);
nuclear@0 340 } while(result == targetExhausted);
nuclear@0 341
nuclear@0 342 ReportResult(result);
nuclear@0 343
nuclear@0 344 // copy to output buffer.
nuclear@0 345 const size_t outlen = (size_t)(dstart-&output.front());
nuclear@0 346 data.assign(output.begin(),output.begin()+outlen);
nuclear@0 347 return;
nuclear@0 348 }
nuclear@0 349
nuclear@0 350 // UTF 16 BE with BOM
nuclear@0 351 if(*((uint16_t*)&data.front()) == 0xFFFE) {
nuclear@0 352
nuclear@0 353 // swap the endianess ..
nuclear@0 354 for(uint16_t* p = (uint16_t*)&data.front(), *end = (uint16_t*)&data.back(); p <= end; ++p) {
nuclear@0 355 ByteSwap::Swap2(p);
nuclear@0 356 }
nuclear@0 357 }
nuclear@0 358
nuclear@0 359 // UTF 16 LE with BOM
nuclear@0 360 if(*((uint16_t*)&data.front()) == 0xFEFF) {
nuclear@0 361 DefaultLogger::get()->debug("Found UTF-16 BOM ...");
nuclear@0 362
nuclear@0 363 const uint16_t* sstart = (uint16_t*)&data.front()+1, *send = (uint16_t*)(&data.back()+1);
nuclear@0 364 char* dstart,*dend;
nuclear@0 365 std::vector<char> output;
nuclear@0 366 do {
nuclear@0 367 output.resize(output.size()?output.size()*3/2:data.size()*3/4);
nuclear@0 368 dstart = &output.front(),dend = &output.back()+1;
nuclear@0 369
nuclear@0 370 result = ConvertUTF16toUTF8((const UTF16**)&sstart,(const UTF16*)send,(UTF8**)&dstart,(UTF8*)dend,lenientConversion);
nuclear@0 371 } while(result == targetExhausted);
nuclear@0 372
nuclear@0 373 ReportResult(result);
nuclear@0 374
nuclear@0 375 // copy to output buffer.
nuclear@0 376 const size_t outlen = (size_t)(dstart-&output.front());
nuclear@0 377 data.assign(output.begin(),output.begin()+outlen);
nuclear@0 378 return;
nuclear@0 379 }
nuclear@0 380 }
nuclear@0 381
nuclear@0 382 // ------------------------------------------------------------------------------------------------
nuclear@0 383 void BaseImporter::TextFileToBuffer(IOStream* stream,
nuclear@0 384 std::vector<char>& data)
nuclear@0 385 {
nuclear@0 386 ai_assert(NULL != stream);
nuclear@0 387
nuclear@0 388 const size_t fileSize = stream->FileSize();
nuclear@0 389 if(!fileSize) {
nuclear@0 390 throw DeadlyImportError("File is empty");
nuclear@0 391 }
nuclear@0 392
nuclear@0 393 data.reserve(fileSize+1);
nuclear@0 394 data.resize(fileSize);
nuclear@0 395 if(fileSize != stream->Read( &data[0], 1, fileSize)) {
nuclear@0 396 throw DeadlyImportError("File read error");
nuclear@0 397 }
nuclear@0 398
nuclear@0 399 ConvertToUTF8(data);
nuclear@0 400
nuclear@0 401 // append a binary zero to simplify string parsing
nuclear@0 402 data.push_back(0);
nuclear@0 403 }
nuclear@0 404
nuclear@0 405 // ------------------------------------------------------------------------------------------------
nuclear@0 406 namespace Assimp
nuclear@0 407 {
nuclear@0 408 // Represents an import request
nuclear@0 409 struct LoadRequest
nuclear@0 410 {
nuclear@0 411 LoadRequest(const std::string& _file, unsigned int _flags,const BatchLoader::PropertyMap* _map, unsigned int _id)
nuclear@0 412 : file(_file), flags(_flags), refCnt(1),scene(NULL), loaded(false), id(_id)
nuclear@0 413 {
nuclear@0 414 if (_map)
nuclear@0 415 map = *_map;
nuclear@0 416 }
nuclear@0 417
nuclear@0 418 const std::string file;
nuclear@0 419 unsigned int flags;
nuclear@0 420 unsigned int refCnt;
nuclear@0 421 aiScene* scene;
nuclear@0 422 bool loaded;
nuclear@0 423 BatchLoader::PropertyMap map;
nuclear@0 424 unsigned int id;
nuclear@0 425
nuclear@0 426 bool operator== (const std::string& f) {
nuclear@0 427 return file == f;
nuclear@0 428 }
nuclear@0 429 };
nuclear@0 430 }
nuclear@0 431
nuclear@0 432 // ------------------------------------------------------------------------------------------------
nuclear@0 433 // BatchLoader::pimpl data structure
nuclear@0 434 struct Assimp::BatchData
nuclear@0 435 {
nuclear@0 436 BatchData()
nuclear@0 437 : next_id(0xffff)
nuclear@0 438 {}
nuclear@0 439
nuclear@0 440 // IO system to be used for all imports
nuclear@0 441 IOSystem* pIOSystem;
nuclear@0 442
nuclear@0 443 // Importer used to load all meshes
nuclear@0 444 Importer* pImporter;
nuclear@0 445
nuclear@0 446 // List of all imports
nuclear@0 447 std::list<LoadRequest> requests;
nuclear@0 448
nuclear@0 449 // Base path
nuclear@0 450 std::string pathBase;
nuclear@0 451
nuclear@0 452 // Id for next item
nuclear@0 453 unsigned int next_id;
nuclear@0 454 };
nuclear@0 455
nuclear@0 456 // ------------------------------------------------------------------------------------------------
nuclear@0 457 BatchLoader::BatchLoader(IOSystem* pIO)
nuclear@0 458 {
nuclear@0 459 ai_assert(NULL != pIO);
nuclear@0 460
nuclear@0 461 data = new BatchData();
nuclear@0 462 data->pIOSystem = pIO;
nuclear@0 463
nuclear@0 464 data->pImporter = new Importer();
nuclear@0 465 data->pImporter->SetIOHandler(data->pIOSystem);
nuclear@0 466 }
nuclear@0 467
nuclear@0 468 // ------------------------------------------------------------------------------------------------
nuclear@0 469 BatchLoader::~BatchLoader()
nuclear@0 470 {
nuclear@0 471 // delete all scenes wthat have not been polled by the user
nuclear@0 472 for (std::list<LoadRequest>::iterator it = data->requests.begin();it != data->requests.end(); ++it) {
nuclear@0 473
nuclear@0 474 delete (*it).scene;
nuclear@0 475 }
nuclear@0 476 data->pImporter->SetIOHandler(NULL); /* get pointer back into our posession */
nuclear@0 477 delete data->pImporter;
nuclear@0 478 delete data;
nuclear@0 479 }
nuclear@0 480
nuclear@0 481
nuclear@0 482 // ------------------------------------------------------------------------------------------------
nuclear@0 483 unsigned int BatchLoader::AddLoadRequest (const std::string& file,
nuclear@0 484 unsigned int steps /*= 0*/, const PropertyMap* map /*= NULL*/)
nuclear@0 485 {
nuclear@0 486 ai_assert(!file.empty());
nuclear@0 487
nuclear@0 488 // check whether we have this loading request already
nuclear@0 489 std::list<LoadRequest>::iterator it;
nuclear@0 490 for (it = data->requests.begin();it != data->requests.end(); ++it) {
nuclear@0 491
nuclear@0 492 // Call IOSystem's path comparison function here
nuclear@0 493 if (data->pIOSystem->ComparePaths((*it).file,file)) {
nuclear@0 494
nuclear@0 495 if (map) {
nuclear@0 496 if (!((*it).map == *map))
nuclear@0 497 continue;
nuclear@0 498 }
nuclear@0 499 else if (!(*it).map.empty())
nuclear@0 500 continue;
nuclear@0 501
nuclear@0 502 (*it).refCnt++;
nuclear@0 503 return (*it).id;
nuclear@0 504 }
nuclear@0 505 }
nuclear@0 506
nuclear@0 507 // no, we don't have it. So add it to the queue ...
nuclear@0 508 data->requests.push_back(LoadRequest(file,steps,map,data->next_id));
nuclear@0 509 return data->next_id++;
nuclear@0 510 }
nuclear@0 511
nuclear@0 512 // ------------------------------------------------------------------------------------------------
nuclear@0 513 aiScene* BatchLoader::GetImport (unsigned int which)
nuclear@0 514 {
nuclear@0 515 for (std::list<LoadRequest>::iterator it = data->requests.begin();it != data->requests.end(); ++it) {
nuclear@0 516
nuclear@0 517 if ((*it).id == which && (*it).loaded) {
nuclear@0 518
nuclear@0 519 aiScene* sc = (*it).scene;
nuclear@0 520 if (!(--(*it).refCnt)) {
nuclear@0 521 data->requests.erase(it);
nuclear@0 522 }
nuclear@0 523 return sc;
nuclear@0 524 }
nuclear@0 525 }
nuclear@0 526 return NULL;
nuclear@0 527 }
nuclear@0 528
nuclear@0 529 // ------------------------------------------------------------------------------------------------
nuclear@0 530 void BatchLoader::LoadAll()
nuclear@0 531 {
nuclear@0 532 // no threaded implementation for the moment
nuclear@0 533 for (std::list<LoadRequest>::iterator it = data->requests.begin();it != data->requests.end(); ++it) {
nuclear@0 534 // force validation in debug builds
nuclear@0 535 unsigned int pp = (*it).flags;
nuclear@0 536 #ifdef _DEBUG
nuclear@0 537 pp |= aiProcess_ValidateDataStructure;
nuclear@0 538 #endif
nuclear@0 539 // setup config properties if necessary
nuclear@0 540 ImporterPimpl* pimpl = data->pImporter->Pimpl();
nuclear@0 541 pimpl->mFloatProperties = (*it).map.floats;
nuclear@0 542 pimpl->mIntProperties = (*it).map.ints;
nuclear@0 543 pimpl->mStringProperties = (*it).map.strings;
nuclear@0 544
nuclear@0 545 if (!DefaultLogger::isNullLogger())
nuclear@0 546 {
nuclear@0 547 DefaultLogger::get()->info("%%% BEGIN EXTERNAL FILE %%%");
nuclear@0 548 DefaultLogger::get()->info("File: " + (*it).file);
nuclear@0 549 }
nuclear@0 550 data->pImporter->ReadFile((*it).file,pp);
nuclear@0 551 (*it).scene = data->pImporter->GetOrphanedScene();
nuclear@0 552 (*it).loaded = true;
nuclear@0 553
nuclear@0 554 DefaultLogger::get()->info("%%% END EXTERNAL FILE %%%");
nuclear@0 555 }
nuclear@0 556 }
nuclear@0 557
nuclear@0 558
nuclear@0 559
nuclear@0 560