Ogre::MeshPtr CMapLoader::LoadModel(const char * path) { MapResource<Ogre::MeshPtr> res; Ogre::MeshPtr pMesh; // Check if this model was already loaded pMesh = Ogre::MeshManager::getSingleton().getByName(path); if(!pMesh.isNull()) return pMesh; sectionitem_t * item = LoadItem(path, &res.map); if(item == NULL) return Ogre::MeshPtr(NULL); pMesh = Ogre::MeshManager::getSingleton().createManual(path, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); Ogre::DataStreamPtr stream(new Ogre::MemoryDataStream(item->data, item->size, false, true)); Ogre::MeshSerializer serializer; serializer.importMesh(stream, pMesh.getPointer()); // No need to keep this in memory mapUnloadItem(item); // Track this resource res.data = pMesh; meshes.push_back(res); return pMesh; }
bool OgreMeshAsset::DeserializeFromData(const u8 *data_, size_t numBytes, bool allowAsynchronous) { PROFILE(OgreMeshAsset_LoadFromFileInMemory); /// Force an unload of this data first. Unload(); /// @todo Duplicate allowAsynchronous code in OgreMeshAsset and TextureAsset. if ((OGRE_THREAD_SUPPORT == 0) || !assetAPI->Cache() || assetAPI->IsHeadless() || IsAssimpFileType() || assetAPI->GetFramework()->HasCommandLineParameter("--noAsyncAssetLoad") || assetAPI->GetFramework()->HasCommandLineParameter("--no_async_asset_load")) /**< @todo Remove support for the deprecated underscore version at some point. */ { allowAsynchronous = false; } QString cacheDiskSource; if (allowAsynchronous) { cacheDiskSource = assetAPI->Cache()->FindInCache(Name()); if (cacheDiskSource.isEmpty()) allowAsynchronous = false; } // Asynchronous loading // 1. AssetAPI allows a asynch load. This is false when called from LoadFromFile(), LoadFromCache() etc. // 2. We have a rendering window for Ogre as Ogre::ResourceBackgroundQueue does not work otherwise. Its not properly initialized without a rendering window. // 3. The Ogre we are building against has thread support. if (allowAsynchronous) { // We can only do threaded loading from disk, and not any disk location but only from asset cache. // local:// refs will return empty string here and those will fall back to the non-threaded loading. // Do not change this to do DiskCache() as that directory for local:// refs will not be a known resource location for ogre. QFileInfo fileInfo(cacheDiskSource); std::string sanitatedAssetRef = fileInfo.fileName().toStdString(); //! \todo - Should we set this somewhere for async path?: ogreMesh->setAutoBuildEdgeLists(false); loadTicket_ = Ogre::ResourceBackgroundQueue::getSingleton().load(Ogre::MeshManager::getSingleton().getResourceType(), sanitatedAssetRef, OgreRenderer::OgreRenderingModule::CACHE_RESOURCE_GROUP, false, 0, 0, this); return true; } if (!data_) { LogError("OgreMeshAsset::DeserializeFromData: Cannot deserialize from null input data"); return false; } // Synchronous loading if (ogreMesh.isNull()) { ogreMesh = Ogre::MeshManager::getSingleton().createManual( AssetAPI::SanitateAssetRef(this->Name()).toStdString(), Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); if (ogreMesh.isNull()) { LogError("OgreMeshAsset::DeserializeFromData: Failed to create mesh " + Name()); return false; } ogreMesh->setAutoBuildEdgeLists(false); } // Convert file to Ogre mesh using assimp if (IsAssimpFileType()) { #ifdef ASSIMP_ENABLED emit ExternalConversionRequested(this, data_, numBytes); return true; #else LogError(QString("OgreMeshAsset::DeserializeFromData: cannot convert " + Name() + " to Ogre mesh. OpenAssetImport is not enabled.")); return false; #endif } try { std::vector<u8> tempData(data_, data_ + numBytes); #include "DisableMemoryLeakCheck.h" Ogre::DataStreamPtr stream(new Ogre::MemoryDataStream((void*)&tempData[0], numBytes, false)); #include "EnableMemoryLeakCheck.h" Ogre::MeshSerializer serializer; serializer.importMesh(stream, ogreMesh.getPointer()); // Note: importMesh *adds* submeshes to an existing mesh. It doesn't replace old ones. } catch (Ogre::Exception &e) { LogError(QString("OgreMeshAsset::DeserializeFromData: Ogre::MeshSerializer::importMesh failed when loading asset '" + Name() + "': ") + e.what()); if(IsAssimpFileType()) LogError(QString("OgreMeshAsset::DeserializeFromData: cannot convert " + Name() + " to Ogre mesh. OpenAssetImport is not enabled.")); return false; } if (GenerateMeshData()) { // We did a synchronous load, must call AssetLoadCompleted here. assetAPI->AssetLoadCompleted(Name()); return true; } else return false; }
bool OgreMeshResource::SetData(Foundation::AssetPtr source) { if (!source) { OgreRenderingModule::LogError("Null source asset data pointer"); return false; } if (!source->GetSize()) { OgreRenderingModule::LogError("Zero sized mesh asset"); return false; } try { if (ogre_mesh_.isNull()) { ogre_mesh_ = Ogre::MeshManager::getSingleton().createManual( id_, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); if (ogre_mesh_.isNull()) { OgreRenderingModule::LogError("Failed to create mesh " + id_); return false; } ogre_mesh_->setAutoBuildEdgeLists(false); } Ogre::DataStreamPtr stream(new Ogre::MemoryDataStream((void*)source->GetData(), source->GetSize(), false)); Ogre::MeshSerializer serializer; serializer.importMesh(stream, ogre_mesh_.getPointer()); // Generate tangents to mesh try { unsigned short src, dest; if (!ogre_mesh_->suggestTangentVectorBuildParams(Ogre::VES_TANGENT, src, dest)) ogre_mesh_->buildTangentVectors(Ogre::VES_TANGENT, src, dest); } catch (...) {} // Generate extremity points to submeshes, 1 should be enough try { for(uint i = 0; i < ogre_mesh_->getNumSubMeshes(); ++i) { Ogre::SubMesh *smesh = ogre_mesh_->getSubMesh(i); if (smesh) smesh->generateExtremes(1); } } catch (...) {} // Assign default materials that won't complain original_materials_.clear(); for (uint i = 0; i < ogre_mesh_->getNumSubMeshes(); ++i) { Ogre::SubMesh* submesh = ogre_mesh_->getSubMesh(i); if (submesh) { original_materials_.push_back(submesh->getMaterialName()); submesh->setMaterialName("UnlitTextured"); } } } catch (Ogre::Exception &e) { OgreRenderingModule::LogError("Failed to create mesh " + id_ + ": " + std::string(e.what())); RemoveMesh(); return false; } OgreRenderingModule::LogDebug("Ogre mesh " + id_ + " created"); return true; }
AssetLoadState OgreMeshAsset::DeserializeFromData(const u8 *data_, size_t numBytes) { PROFILE(OgreMeshAsset_LoadFromFileInMemory); assert(data_); if (!data_) return ASSET_LOAD_FAILED; // Force an unload of this data first. Unload(); if (OGRE_THREAD_SUPPORT != 0) { // We can only do threaded loading from disk, and not any disk location but only from asset cache. // local:// refs will return empty string here and those will fall back to the non-threaded loading. // Do not change this to do DiskCache() as that directory for local:// refs will not be a known resource location for ogre. QString cacheDiskSource = assetAPI->GetAssetCache()->GetDiskSource(QUrl(Name())); if (!cacheDiskSource.isEmpty()) { QFileInfo fileInfo(cacheDiskSource); std::string sanitatedAssetRef = fileInfo.fileName().toStdString(); loadTicket_ = Ogre::ResourceBackgroundQueue::getSingleton().load(Ogre::MeshManager::getSingleton().getResourceType(), sanitatedAssetRef, OgreRenderer::OgreRenderingModule::CACHE_RESOURCE_GROUP, false, 0, 0, this); return ASSET_LOAD_PROCESSING; } } if (ogreMesh.isNull()) { ogreMesh = Ogre::MeshManager::getSingleton().createManual( OgreRenderer::SanitateAssetIdForOgre(this->Name().toStdString()), Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); if (ogreMesh.isNull()) { LogError("Failed to create mesh " + Name().toStdString()); return ASSET_LOAD_FAILED; } ogreMesh->setAutoBuildEdgeLists(false); } std::vector<u8> tempData(data_, data_ + numBytes); #include "DisableMemoryLeakCheck.h" Ogre::DataStreamPtr stream(new Ogre::MemoryDataStream((void*)&tempData[0], numBytes, false)); #include "EnableMemoryLeakCheck.h" Ogre::MeshSerializer serializer; serializer.importMesh(stream, ogreMesh.getPointer()); // Note: importMesh *adds* submeshes to an existing mesh. It doesn't replace old ones. // Generate tangents to mesh try { unsigned short src, dest; ///\bug Crashes if called for a mesh that has null or zero vertices in the vertex buffer, or null or zero indices in the index buffer. if (!ogreMesh->suggestTangentVectorBuildParams(Ogre::VES_TANGENT, src, dest)) ogreMesh->buildTangentVectors(Ogre::VES_TANGENT, src, dest); } catch (...) {} // Generate extremity points to submeshes, 1 should be enough try { for(uint i = 0; i < ogreMesh->getNumSubMeshes(); ++i) { Ogre::SubMesh *smesh = ogreMesh->getSubMesh(i); if (smesh) smesh->generateExtremes(1); } } catch (...) {} try { // Assign default materials that won't complain SetDefaultMaterial(); // Set asset references the mesh has //ResetReferences(); } catch (Ogre::Exception &e) { LogError("Failed to create mesh " + this->Name().toStdString() + ": " + std::string(e.what())); Unload(); return ASSET_LOAD_FAILED; } //internal_name_ = SanitateAssetIdForOgre(id_); LogDebug("Ogre mesh " + this->Name().toStdString() + " created"); return ASSET_LOAD_SUCCESFULL; }