S3DModel C3DOParser::Load(const std::string& name) { CFileHandler file(name); std::vector<unsigned char> fileBuf; if (!file.FileExists()) throw content_error("[3DOParser] could not find model-file " + name); if (!file.IsBuffered()) { fileBuf.resize(file.FileSize(), 0); if (file.Read(fileBuf.data(), fileBuf.size()) == 0) throw content_error("[3DOParser] failed to read model-file " + name); } else { fileBuf = std::move(file.GetBuffer()); } S3DModel model; model.name = name; model.type = MODELTYPE_3DO; model.textureType = 0; model.numPieces = 0; model.mins = DEF_MIN_SIZE; model.maxs = DEF_MAX_SIZE; model.FlattenPieceTree(LoadPiece(&model, 0, nullptr, &model.numPieces, fileBuf)); // set after the extrema are known model.radius = model.CalcDrawRadius(); model.height = model.CalcDrawHeight(); model.relMidPos = model.CalcDrawMidPos(); return model; }
S3DModel* C3DOParser::Load(const std::string& name) { CFileHandler file(name); std::vector<unsigned char> fileBuf; if (!file.FileExists()) { throw content_error("[3DOParser] could not find model-file " + name); } fileBuf.resize(file.FileSize(), 0); if (file.Read(&fileBuf[0], file.FileSize()) == 0) { throw content_error("[3DOParser] failed to read model-file " + name); } S3DModel* model = new S3DModel(); model->name = name; model->type = MODELTYPE_3DO; model->textureType = 0; model->numPieces = 0; model->mins = DEF_MIN_SIZE; model->maxs = DEF_MAX_SIZE; S3DOPiece* rootPiece = LoadPiece(model, 0, NULL, &model->numPieces, fileBuf); model->SetRootPiece(rootPiece); // set after the extrema are known model->radius = (model->maxs - model->mins ).Length() * 0.5f; model->height = (model->maxs.y - model->mins.y); model->relMidPos = (model->maxs + model->mins) * 0.5f; return model; }
S3DModel* CS3OParser::Load(const std::string& name) { CFileHandler file(name); if (!file.FileExists()) { throw content_error("[S3OParser] could not find model-file " + name); } unsigned char* fileBuf = new unsigned char[file.FileSize()]; file.Read(fileBuf, file.FileSize()); S3OHeader header; memcpy(&header, fileBuf, sizeof(header)); header.swap(); S3DModel* model = new S3DModel; model->name = name; model->type = MODELTYPE_S3O; model->numPieces = 0; model->tex1 = (char*) &fileBuf[header.texture1]; model->tex2 = (char*) &fileBuf[header.texture2]; model->mins = DEF_MIN_SIZE; model->maxs = DEF_MAX_SIZE; texturehandlerS3O->LoadS3OTexture(model); SS3OPiece* rootPiece = LoadPiece(model, NULL, fileBuf, header.rootPiece); model->SetRootPiece(rootPiece); model->radius = (header.radius <= 0.01f)? (model->maxs.y - model->mins.y): header.radius; model->height = (header.height <= 0.01f)? (model->radius + model->radius): header.height; model->relMidPos = float3(header.midx, header.midy, header.midz); model->relMidPos.y = std::max(model->relMidPos.y, 1.0f); // ? delete[] fileBuf; return model; }
C3DModelLoader::~C3DModelLoader() { // delete model cache for (unsigned int n = 1; n < models.size(); n++) { S3DModel* model = models[n]; assert(model != NULL); assert(model->GetRootPiece() != NULL); model->DeletePieces(model->GetRootPiece()); model->SetRootPiece(NULL); delete model; } for (ParserMap::const_iterator it = parsers.begin(); it != parsers.end(); ++it) { delete (it->second); } models.clear(); cache.clear(); parsers.clear(); if (GML::SimEnabled() && !GML::ShareLists()) { createLists.clear(); fixLocalModels.clear(); Update(); // delete remaining local models } }
S3DModel* CS3OParser::Load(const std::string& name) { CFileHandler file(name); if (!file.FileExists()) { throw content_error("[S3OParser] could not find model-file " + name); } std::vector<unsigned char> fileBuf(file.FileSize()); file.Read(&fileBuf[0], file.FileSize()); S3OHeader header; memcpy(&header, &fileBuf[0], sizeof(header)); header.swap(); S3DModel* model = new S3DModel(); model->name = name; model->type = MODELTYPE_S3O; model->numPieces = 0; model->tex1 = (char*) &fileBuf[header.texture1]; model->tex2 = (char*) &fileBuf[header.texture2]; model->mins = DEF_MIN_SIZE; model->maxs = DEF_MAX_SIZE; texturehandlerS3O->PreloadS3OTexture(model); SS3OPiece* rootPiece = LoadPiece(model, NULL, &fileBuf[0], header.rootPiece); model->SetRootPiece(rootPiece); // set after the extrema are known model->radius = (header.radius <= 0.01f)? (model->maxs - model->mins ).Length() * 0.5f: header.radius; model->height = (header.height <= 0.01f)? (model->maxs.y - model->mins.y) : header.height; model->relMidPos = float3(header.midx, header.midy, header.midz); return model; }
S3DModel* C3DOParser::Load(const string& name) { CFileHandler file(name); if (!file.FileExists()) { throw content_error("[3DOParser] could not find model-file " + name); } fileBuf = new unsigned char[file.FileSize()]; assert(fileBuf); const int readn = file.Read(fileBuf, file.FileSize()); if (readn == 0) { delete[] fileBuf; fileBuf = NULL; throw content_error("[3DOParser] Failed to read file " + name); } S3DModel* model = new S3DModel; model->name = name; model->type = MODELTYPE_3DO; model->textureType = 0; model->numPieces = 0; model->mins = DEF_MIN_SIZE; model->maxs = DEF_MAX_SIZE; model->radius = 0.0f; model->height = 0.0f; S3DOPiece* rootPiece = LoadPiece(model, 0, NULL, &model->numPieces); model->SetRootPiece(rootPiece); model->radius = (((model->maxs.x - model->mins.x) * 0.5f) * ((model->maxs.x - model->mins.x) * 0.5f)) + (((model->maxs.y - model->mins.y) * 0.5f) * ((model->maxs.y - model->mins.y) * 0.5f)) + (((model->maxs.z - model->mins.z) * 0.5f) * ((model->maxs.z - model->mins.z) * 0.5f)); model->radius = math::sqrt(model->radius); model->height = model->maxs.y - model->mins.y; // model->height = model->radius * 2.0f; model->relMidPos = (model->maxs - model->mins) * 0.5f; model->relMidPos.x = 0.0f; // ? model->relMidPos.z = 0.0f; // ? delete[] fileBuf; fileBuf = NULL; return model; }
C3DModelLoader::~C3DModelLoader() { // delete model cache for (unsigned int n = 1; n < models.size(); n++) { S3DModel* model = models[n]; assert(model != NULL); assert(model->GetRootPiece() != NULL); model->DeletePieces(model->GetRootPiece()); model->SetRootPiece(NULL); delete model; } models.clear(); cache.clear(); // get rid of Spring's native parsers delete parsers["3do"]; parsers.erase("3do"); delete parsers["s3o"]; parsers.erase("s3o"); delete parsers["obj"]; parsers.erase("obj"); if (!parsers.empty()) { // delete the shared Assimp parser ParserMap::iterator pi = parsers.begin(); delete pi->second; } parsers.clear(); if (GML::SimEnabled() && !GML::ShareLists()) { createLists.clear(); fixLocalModels.clear(); Update(); // delete remaining local models } }
S3DModel* C3DModelLoader::Load3DModel(std::string modelName) { GML_RECMUTEX_LOCK(model); // Load3DModel StringToLowerInPlace(modelName); // search in cache first ModelMap::iterator ci; ParserMap::iterator pi; if ((ci = cache.find(modelName)) != cache.end()) { return models[ci->second]; } const std::string modelPath = FindModelPath(modelName); if ((ci = cache.find(modelPath)) != cache.end()) { return models[ci->second]; } // not found in cache, create the model and cache it const std::string& fileExt = StringToLower(FileSystem::GetExtension(modelPath)); if ((pi = parsers.find(fileExt)) != parsers.end()) { IModelParser* p = pi->second; S3DModel* model = NULL; S3DModelPiece* root = NULL; try { model = p->Load(modelPath); } catch (const content_error& ex) { LOG_L(L_WARNING, "could not load model \"%s\" (reason: %s)", modelName.c_str(), ex.what()); goto dummy; } if ((root = model->GetRootPiece()) != NULL) { CreateLists(root); } AddModelToCache(model, modelName, modelPath); CheckModelNormals(model); return model; } LOG_L(L_ERROR, "could not find a parser for model \"%s\" (unknown format?)", modelName.c_str()); dummy: // crash-dummy S3DModel* model = new S3DModel(); model->type = MODELTYPE_3DO; model->numPieces = 1; // give it one dummy piece model->SetRootPiece(ModelTypeToModelPiece(MODELTYPE_3DO)); model->GetRootPiece()->SetCollisionVolume(new CollisionVolume("box", -UpVector, ZeroVector)); if (model->GetRootPiece() != NULL) { CreateLists(model->GetRootPiece()); } AddModelToCache(model, modelName, modelPath); return model; }