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::SerializeTo(std::vector<u8> &data, const QString &serializationParameters) const { UNREFERENCED_PARAM(serializationParameters); if (ogreMesh.isNull()) { LogWarning("OgreMeshAsset::SerializeTo: Tried to export non-existing Ogre mesh " + Name() + "."); return false; } try { Ogre::MeshSerializer serializer; QString tempFilename = assetAPI->GenerateTemporaryNonexistingAssetFilename(Name()); // Ogre has a limitation of not supporting serialization to a file in memory, so serialize directly to a temporary file, // load it up and delete the temporary file. serializer.exportMesh(ogreMesh.get(), tempFilename.toStdString()); bool success = LoadFileToVector(tempFilename.toStdString().c_str(), data); QFile::remove(tempFilename); // Delete the temporary file we used for serialization. return success; } catch(const std::exception &e) { LogError("OgreMeshAsset::SerializeTo: Failed to export Ogre mesh " + Name() + ": " + (e.what() ? QString(e.what()) : "")); } return false; }
bool AssetsManager::exportMesh(Ogre::MeshPtr mesh, const std::string& filePath) { if (filePath != "") { Ogre::MeshSerializer serializer; try { serializer.exportMesh(mesh.get(), filePath); S_LOG_INFO("Exported mesh " << filePath); } catch (const Ogre::Exception& ex) { S_LOG_FAILURE("Error when exporting mesh " << mesh->getName() << "to path " << filePath <<"." << ex); return false; } return true; } return false; }
int main(int argc, char** argv) { static Ogre::String s_strDefault = ""; Ogre::Root* lpRoot = new Ogre::Root(s_strDefault, s_strDefault, s_strDefault); CFBXLoader loader; if (argc > 1) { Ogre::DefaultHardwareBufferManager* lpBufferManager = new Ogre::DefaultHardwareBufferManager(); // needed because we don't have a rendersystem Ogre::MeshPtr lpMesh = Ogre::MeshManager::getSingleton().createManual("conversion", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); loader.convertFbxToMesh(argv[1], lpMesh.get()); Ogre::MeshSerializer nSerializer; nSerializer.exportMesh(lpMesh.get(), "test.mesh", Ogre::MESH_VERSION_1_8); delete lpBufferManager; } delete lpRoot; return 0; }
VALUE _export(int argc,VALUE *argv,VALUE self) { VALUE filename,opt,endian = Qnil,version = Qnil; rb_scan_args(argc, argv, "11",&filename,&opt); if(rb_obj_is_kind_of(opt,rb_cHash)) { endian = rb_hash_aref(opt,ID2SYM(rb_intern("endian"))); version = rb_hash_aref(opt,ID2SYM(rb_intern("version"))); } Ogre::MeshSerializer serial; serial.exportMesh(_self.get(), wrap<Ogre::String>(filename), wrapenum<Ogre::MeshVersion>(version), wrapenum<Ogre::MeshSerializer::Endian>(endian) ); return self; }
bool AssetsManager::exportMesh(Ogre::MeshPtr mesh, const std::string& filePath) { if (filePath != "") { Ogre::MeshSerializer serializer; try { std::string dirname(filePath); size_t end = dirname.find_last_of("/\\"); if (end != std::string::npos) { dirname = dirname.substr(0, end); } oslink::directory osdir(dirname); if (!osdir.isExisting()) { oslink::directory::mkdir(dirname.c_str()); } serializer.exportMesh(mesh.get(), filePath); S_LOG_INFO("Exported mesh " << filePath); } catch (const Ogre::Exception& ex) { S_LOG_FAILURE("Error when exporting mesh " << mesh->getName() << "to path " << filePath <<"." << ex); return false; } return true; } return false; }
void OgreExporter_c::ExportLevel(const WadLevel_c &level, const WadFile_c &file) { this->ExportLevelMaterials(level, file); Ogre::DefaultHardwareBufferManager hardwareBufferManager; Ogre::ManualObject manualMesh(level.GetName()); const LineDef_s *lineDefs = level.GetLineDefs(); const size_t numLineDefs = level.GetNumLineDefs(); const SideDef_s *sideDefs = level.GetSideDefs(); const Sector_s *sectors = level.GetSectors(); const Vertex_s *vertices = level.GetVertices(); for(size_t i = 0;i < numLineDefs; ++i) { if(lineDefs[i].iLeftSideDef >= 0) { const SideDef_s &leftSide = sideDefs[lineDefs[i].iLeftSideDef]; const Sector_s &leftSideSector = sectors[leftSide.iSector]; const SideDef_s &rightSide = sideDefs[lineDefs[i].iRightSideDef]; const Sector_s &rightSideSector = sectors[rightSide.iSector]; if(leftSide.uMiddleTexture.uName != '-') { this->ExportWallMesh(manualMesh, leftSideSector.iFloorHeight, leftSideSector.iCeilHeight, leftSide.uMiddleTexture, leftSide.iOffsetX, leftSide.iOffsety, vertices, lineDefs[i], file); } if(leftSide.uLowerTexture.uName != '-') { this->ExportWallMesh(manualMesh, leftSideSector.iFloorHeight, leftSideSector.iFloorHeight, leftSide.uLowerTexture, leftSide.iOffsetX, leftSide.iOffsety, vertices, lineDefs[i], file); } if(leftSide.uUpperTexture.uName != '-') { this->ExportWallMesh(manualMesh, rightSideSector.iCeilHeight, leftSideSector.iCeilHeight, leftSide.uUpperTexture, leftSide.iOffsetX, leftSide.iOffsety, vertices, lineDefs[i], file); } } if(lineDefs[i].iRightSideDef >= 0) { const SideDef_s &rightSide = sideDefs[lineDefs[i].iRightSideDef]; const Sector_s &rightSideSector = sectors[rightSide.iSector]; if(rightSide.uLowerTexture.uName != '-') { const SideDef_s &leftSide = sideDefs[lineDefs[i].iLeftSideDef]; const Sector_s &leftSideSector = sectors[leftSide.iSector]; this->ExportWallMesh(manualMesh, rightSideSector.iFloorHeight, leftSideSector.iFloorHeight, rightSide.uLowerTexture, rightSide.iOffsetX, rightSide.iOffsety, vertices, lineDefs[i], file); } if(rightSide.uMiddleTexture.uName != '-') { this->ExportWallMesh(manualMesh, rightSideSector.iFloorHeight, rightSideSector.iCeilHeight, rightSide.uMiddleTexture, rightSide.iOffsetX, rightSide.iOffsety, vertices, lineDefs[i], file); } if(rightSide.uUpperTexture.uName != '-') { const SideDef_s &leftSide = sideDefs[lineDefs[i].iLeftSideDef]; const Sector_s &leftSideSector = sectors[leftSide.iSector]; this->ExportWallMesh(manualMesh, leftSideSector.iCeilHeight, rightSideSector.iCeilHeight, rightSide.uUpperTexture, rightSide.iOffsetX, rightSide.iOffsety, vertices, lineDefs[i], file); } } } namespace fs = boost::filesystem; fs::path path(strLevelDirectory); std::string levelName = level.GetName(); levelName += ".mesh"; path /= levelName; Ogre::LogManager logManager; logManager.createLog("ogre.log", true, true, false); Ogre::ResourceGroupManager resourceGroupManager; Ogre::MeshManager meshManager; Ogre::LodStrategyManager logStrategyManager; Ogre::MeshPtr mesh = manualMesh.convertToMesh(level.GetName()); Ogre::MeshSerializer serializer; serializer.exportMesh(mesh.get(), path.string()); mesh.setNull(); resourceGroupManager.shutdownAll(); this->CreateResourcesCfg(); }
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; }
Ogre::Entity* ModelFile::GetModel( const ModelInfo& info ) { VectorTexForGen textures; Ogre::MeshPtr mesh = Ogre::MeshManager::getSingleton().create( info.data.name + "export", "General" ); Ogre::SkeletonPtr skeleton = Ogre::SkeletonManager::getSingleton().create( info.data.name + "export", "General" ); int number_of_bones = GetU8( 0x02 ); int number_of_parts = GetU8( 0x03 ); int offset_to_bones = GetU32LE( 0x0c ); int offset_to_parts = GetU32LE( 0x10 ); Ogre::Bone* root1 = skeleton->createBone( "0", 0 ); Ogre::Bone* root2 = skeleton->createBone( "1", 1 ); root1->addChild( root2 ); for( int i = 0; i < number_of_bones; ++i ) { Bone bone; bone.parent_id = ( i != 0 ) ? ( s8 )GetU8( offset_to_bones + i * 0x04 + 0x03 ) : -1; bone.length = ( s16 )GetU16LE( offset_to_bones + i * 0x04 + 0x00 ); m_Skeleton.push_back(bone); Ogre::Bone* bone1 = skeleton->createBone( Ogre::StringConverter::toString( i * 2 + 2 ), i * 2 + 2 ); Ogre::Bone* bone2 = skeleton->createBone( Ogre::StringConverter::toString( i * 2 + 3 ), i * 2 + 3 ); LOGGER->Log( "Add skeleton bone: bone_id = " + Ogre::StringConverter::toString( i ) + ", length = " + Ogre::StringConverter::toString( bone.length ) + ", parent = " + Ogre::StringConverter::toString( bone.parent_id ) + ".\n" ); if( bone.parent_id == -1 ) { skeleton->getBone( 1 )->addChild( bone1 ); } else { skeleton->getBone( bone.parent_id * 2 + 3 )->addChild( bone1 ); } bone1->addChild( bone2 ); } AnimationExtractor( skeleton, info, m_Skeleton ); // draw skeleton { //DrawSkeleton( m_Skeleton, mesh ); } for( int i = 0; i < number_of_parts; ++i ) { MeshExtractor( info.data, "ffix/field_model/" + info.data.name, this, offset_to_parts + i * 0x28, textures, mesh ); } // <OGRE> /////////////////////////////// skeleton->optimiseAllAnimations(); Ogre::SkeletonSerializer skeleton_serializer; skeleton_serializer.exportSkeleton( skeleton.getPointer(), "exported/models/field/units/" + info.data.name + ".skeleton" ); // Update bounds Ogre::AxisAlignedBox aabb( -999, -999, -999, 999, 999, 999 ); mesh->_setBounds( aabb, false ); mesh->_setBoundingSphereRadius( 999 ); mesh->setSkeletonName( "models/field/units/" + info.data.name + ".skeleton" ); Ogre::MeshSerializer ser; ser.exportMesh( mesh.getPointer(), "exported/models/field/units/" + info.data.name + ".mesh" ); // create and export textures for model //if (textures.size() > 0) { Vram* vram = new Vram(); File* tex = new File( "./data/field/5/1b/2/4/1.tim" ); LoadTimFileToVram( tex, 0, vram ); delete tex; tex = new File( "./data/field/5/1b/2/4/2.tim" ); LoadTimFileToVram( tex, 0, vram ); delete tex; vram->Save( "1.jpg" ); CreateTexture( vram, info.data, "exported/models/field/units/" + info.data.name + ".png", textures ); delete vram; } CreateMaterial( "ffix/field_model/" + info.data.name, "exported/models/field/units/" + info.data.name + ".material", ( textures.size() > 0 ) ? "models/field/units/" + info.data.name + ".png" : "", "", "" ); Ogre::SceneManager* scene_manager = Ogre::Root::getSingleton().getSceneManager( "Scene" ); Ogre::Entity* thisEntity = scene_manager->createEntity( info.data.name, "models/field/units/" + info.data.name + ".mesh" ); //thisEntity->setDisplaySkeleton(true); //thisEntity->setDebugDisplayEnabled(true); thisEntity->setVisible( false ); thisEntity->getAnimationState( info.animations_name[ 0 ] )->setEnabled(true); thisEntity->getAnimationState( info.animations_name[ 0 ] )->setLoop(true); Ogre::SceneNode* thisSceneNode = scene_manager->getRootSceneNode()->createChildSceneNode(); thisSceneNode->setPosition( 0, 0, 0 ); thisSceneNode->roll( Ogre::Radian( Ogre::Degree( 180.0f ) ) ); thisSceneNode->yaw( Ogre::Radian( Ogre::Degree( 120.0f ) ) ); thisSceneNode->pitch( Ogre::Radian( Ogre::Degree(90.0f ) ) ); thisSceneNode->attachObject( thisEntity ); return thisEntity; }
void MilkshapePlugin::doExportMesh(msModel* pModel) { // Create singletons Ogre::SkeletonManager skelMgr; Ogre::DefaultHardwareBufferManager defHWBufMgr; Ogre::LogManager& logMgr = Ogre::LogManager::getSingleton(); Ogre::MeshManager meshMgr; // // choose filename // OPENFILENAME ofn; memset (&ofn, 0, sizeof (OPENFILENAME)); char szFile[MS_MAX_PATH]; char szFileTitle[MS_MAX_PATH]; char szDefExt[32] = "mesh"; char szFilter[128] = "OGRE .mesh Files (*.mesh)\0*.mesh\0All Files (*.*)\0*.*\0\0"; szFile[0] = '\0'; szFileTitle[0] = '\0'; ofn.lStructSize = sizeof (OPENFILENAME); ofn.lpstrDefExt = szDefExt; ofn.lpstrFilter = szFilter; ofn.lpstrFile = szFile; ofn.nMaxFile = MS_MAX_PATH; ofn.lpstrFileTitle = szFileTitle; ofn.nMaxFileTitle = MS_MAX_PATH; ofn.Flags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST; ofn.lpstrTitle = "Export to OGRE Mesh"; if (!::GetSaveFileName (&ofn)) return /*0*/; logMgr.logMessage("Creating Mesh object..."); Ogre::MeshPtr ogreMesh = Ogre::MeshManager::getSingleton().create("export", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); logMgr.logMessage("Mesh object created."); bool foundBoneAssignment = false; // No shared geometry int i; int wh, numbones; int intweight[3], intbones[3]; size_t j; Ogre::Vector3 min, max, currpos; Ogre::Real maxSquaredRadius; bool first = true; for (i = 0; i < msModel_GetMeshCount (pModel); i++) { msMesh *pMesh = msModel_GetMeshAt (pModel, i); logMgr.logMessage("Creating SubMesh object..."); Ogre::SubMesh* ogreSubMesh = ogreMesh->createSubMesh(); logMgr.logMessage("SubMesh object created."); // Set material logMgr.logMessage("Getting SubMesh Material..."); int matIdx = msMesh_GetMaterialIndex(pMesh); if (matIdx == -1) { // No material, use blank ogreSubMesh->setMaterialName("BaseWhite"); logMgr.logMessage("No Material, using default 'BaseWhite'."); } else { msMaterial *pMat = msModel_GetMaterialAt(pModel, matIdx); ogreSubMesh->setMaterialName(pMat->szName); logMgr.logMessage("SubMesh Material Done."); } logMgr.logMessage("Setting up geometry..."); // Set up mesh geometry ogreSubMesh->vertexData = new Ogre::VertexData(); ogreSubMesh->vertexData->vertexCount = msMesh_GetVertexCount (pMesh); ogreSubMesh->vertexData->vertexStart = 0; Ogre::VertexBufferBinding* bind = ogreSubMesh->vertexData->vertexBufferBinding; Ogre::VertexDeclaration* decl = ogreSubMesh->vertexData->vertexDeclaration; // Always 1 texture layer, 2D coords #define POSITION_BINDING 0 #define NORMAL_BINDING 1 #define TEXCOORD_BINDING 2 decl->addElement(POSITION_BINDING, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION); decl->addElement(NORMAL_BINDING, 0, Ogre::VET_FLOAT3, Ogre::VES_NORMAL); decl->addElement(TEXCOORD_BINDING, 0, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES); // Create buffers Ogre::HardwareVertexBufferSharedPtr pbuf = Ogre::HardwareBufferManager::getSingleton(). createVertexBuffer(decl->getVertexSize(POSITION_BINDING), ogreSubMesh->vertexData->vertexCount, Ogre::HardwareBuffer::HBU_DYNAMIC, false); Ogre::HardwareVertexBufferSharedPtr nbuf = Ogre::HardwareBufferManager::getSingleton(). createVertexBuffer(decl->getVertexSize(NORMAL_BINDING), ogreSubMesh->vertexData->vertexCount, Ogre::HardwareBuffer::HBU_DYNAMIC, false); Ogre::HardwareVertexBufferSharedPtr tbuf = Ogre::HardwareBufferManager::getSingleton(). createVertexBuffer(decl->getVertexSize(TEXCOORD_BINDING), ogreSubMesh->vertexData->vertexCount, Ogre::HardwareBuffer::HBU_DYNAMIC, false); bind->setBinding(POSITION_BINDING, pbuf); bind->setBinding(NORMAL_BINDING, nbuf); bind->setBinding(TEXCOORD_BINDING, tbuf); ogreSubMesh->useSharedVertices = false; float* pPos = static_cast<float*>( pbuf->lock(Ogre::HardwareBuffer::HBL_DISCARD)); logMgr.logMessage("Doing positions and texture coords..."); for (j = 0; j < ogreSubMesh->vertexData->vertexCount; ++j) { logMgr.logMessage("Doing vertex " + Ogre::StringConverter::toString(j)); msVertex *pVertex = msMesh_GetVertexAt (pMesh, (int)j); msVertexEx *pVertexEx=msMesh_GetVertexExAt(pMesh, (int)j); msVec3 Vertex; msVertex_GetVertex (pVertex, Vertex); *pPos++ = Vertex[0]; *pPos++ = Vertex[1]; *pPos++ = Vertex[2]; // Deal with bounds currpos = Ogre::Vector3(Vertex[0], Vertex[1], Vertex[2]); if (first) { min = max = currpos; maxSquaredRadius = currpos.squaredLength(); first = false; } else { min.makeFloor(currpos); max.makeCeil(currpos); maxSquaredRadius = std::max(maxSquaredRadius, currpos.squaredLength()); } int boneIdx = msVertex_GetBoneIndex(pVertex); if (boneIdx != -1) { foundBoneAssignment = true; numbones = 1; intbones[0] = intbones[1] = intbones[2] = -1; intweight[0] = intweight[1] = intweight[2] = 0; for(wh = 0; wh < 3; ++wh) { intbones[wh] = msVertexEx_GetBoneIndices(pVertexEx, wh); if(intbones[wh] == -1) break; ++numbones; intweight[wh] = msVertexEx_GetBoneWeights(pVertexEx, wh); } // for(k) Ogre::VertexBoneAssignment vertAssign; vertAssign.boneIndex = boneIdx; vertAssign.vertexIndex = (unsigned int)j; if(numbones == 1) { vertAssign.weight = 1.0; } // single assignment else { vertAssign.weight=(Ogre::Real)intweight[0]/100.0; } ogreSubMesh->addBoneAssignment(vertAssign); if(numbones > 1) { // this somewhat contorted logic is because the first weight [0] matches to the bone assignment // located with pVertex. The next two weights [1][2] match up to the first two bones found // with pVertexEx [0][1]. The weight for the fourth bone, if present, is the unassigned weight for(wh = 0; wh < 3; wh++) { boneIdx = intbones[wh]; if(boneIdx == -1) break; vertAssign.boneIndex = boneIdx; vertAssign.vertexIndex = (unsigned int)j; if(wh == 2) { // fourth weight is 1.0-(sumoffirstthreeweights) vertAssign.weight = 1.0-(((Ogre::Real)intweight[0]/100.0)+ ((Ogre::Real)intweight[1]/100.0)+((Ogre::Real)intweight[2]/100.0)); } else { vertAssign.weight=(Ogre::Real)intweight[wh+1]; } ogreSubMesh->addBoneAssignment(vertAssign); } // for(k) } // if(numbones) } } pbuf->unlock(); float* pTex = static_cast<float*>( tbuf->lock(Ogre::HardwareBuffer::HBL_DISCARD)); logMgr.logMessage("Doing uvs, normals and indexes (v2)..."); // Aargh, Milkshape uses stupid separate normal indexes for the same vertex like 3DS // Normals aren't described per vertex but per triangle vertex index // Pain in the arse, we have to do vertex duplication again if normals differ at a vertex (non smooth) // WHY don't people realise this format is a pain for passing to 3D APIs in vertex buffers? float* pNorm = static_cast<float*>( nbuf->lock(Ogre::HardwareBuffer::HBL_DISCARD)); ogreSubMesh->indexData->indexCount = msMesh_GetTriangleCount (pMesh) * 3; // Always use 16-bit buffers, Milkshape can't handle more anyway Ogre::HardwareIndexBufferSharedPtr ibuf = Ogre::HardwareBufferManager::getSingleton(). createIndexBuffer(Ogre::HardwareIndexBuffer::IT_16BIT, ogreSubMesh->indexData->indexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY); ogreSubMesh->indexData->indexBuffer = ibuf; unsigned short *pIdx = static_cast<unsigned short*>( ibuf->lock(Ogre::HardwareBuffer::HBL_DISCARD)); for (j = 0; j < ogreSubMesh->indexData->indexCount; j+=3) { msTriangle *pTriangle = msMesh_GetTriangleAt (pMesh, (int)j/3); msTriangleEx *pTriangleEx=msMesh_GetTriangleExAt(pMesh, (int)j/3); word nIndices[3]; msTriangle_GetVertexIndices (pTriangle, nIndices); msVec3 Normal; msVec2 uv; int k, vertIdx; for (k = 0; k < 3; ++k) { vertIdx = nIndices[k]; // Face index pIdx[j+k] = vertIdx; // Vertex normals // For the moment, ignore any discrepancies per vertex msTriangleEx_GetNormal(pTriangleEx, k, &Normal[0]); msTriangleEx_GetTexCoord(pTriangleEx, k, &uv[0]); pTex[(vertIdx*2)]=uv[0]; pTex[(vertIdx*2)+1]=uv[1]; pNorm[(vertIdx*3)] = Normal[0]; pNorm[(vertIdx*3)+1] = Normal[1]; pNorm[(vertIdx*3)+2] = Normal[2]; } } // Faces nbuf->unlock(); ibuf->unlock(); tbuf->unlock(); // Now use Ogre's ability to reorganise the vertex buffers the best way Ogre::VertexDeclaration* newDecl = ogreSubMesh->vertexData->vertexDeclaration->getAutoOrganisedDeclaration( foundBoneAssignment, false); Ogre::BufferUsageList bufferUsages; for (size_t u = 0; u <= newDecl->getMaxSource(); ++u) bufferUsages.push_back(Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY); ogreSubMesh->vertexData->reorganiseBuffers(newDecl, bufferUsages); logMgr.logMessage("Geometry done."); } // SubMesh // Set bounds ogreMesh->_setBoundingSphereRadius(Ogre::Math::Sqrt(maxSquaredRadius)); ogreMesh->_setBounds(Ogre::AxisAlignedBox(min, max), false); // Keep hold of a Skeleton pointer for deletion later // Mesh uses Skeleton pointer for skeleton name Ogre::SkeletonPtr pSkel; if (exportSkeleton && foundBoneAssignment) { // export skeleton, also update mesh to point to it pSkel = doExportSkeleton(pModel, ogreMesh); } else if (!exportSkeleton && foundBoneAssignment) { // We've found bone assignments, but skeleton is not to be exported // Prompt the user to find the skeleton if (!locateSkeleton(ogreMesh)) return; } // Export logMgr.logMessage("Creating MeshSerializer.."); Ogre::MeshSerializer serializer; logMgr.logMessage("MeshSerializer created."); // Generate LODs if required if (generateLods) { // Build LOD depth list Ogre::Mesh::LodDistanceList distList; float depth = 0; for (unsigned short depthidx = 0; depthidx < numLods; ++depthidx) { depth += lodDepthIncrement; distList.push_back(depth); } ogreMesh->generateLodLevels(distList, lodReductionMethod, lodReductionAmount); } if (generateEdgeLists) { ogreMesh->buildEdgeList(); } if (generateTangents) { unsigned short src, dest; ogreMesh->suggestTangentVectorBuildParams(tangentSemantic, src, dest); ogreMesh->buildTangentVectors(tangentSemantic, src, dest, tangentsSplitMirrored, tangentsSplitRotated, tangentsUseParity); } // Export Ogre::String msg; msg = "Exporting mesh data to file '" + Ogre::String(szFile) + "'"; logMgr.logMessage(msg); serializer.exportMesh(ogreMesh.getPointer(), szFile); logMgr.logMessage("Export successful"); Ogre::MeshManager::getSingleton().remove(ogreMesh->getHandle()); if (!pSkel.isNull()) Ogre::SkeletonManager::getSingleton().remove(pSkel->getHandle()); if (exportMaterials && msModel_GetMaterialCount(pModel) > 0) { doExportMaterials(pModel); } }
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; }
void saveAsDotScene(const QString& path, QFile& file, Ogre::SceneManager* sceneManager) { Ogre::MeshSerializer* mMeshSerializer = new Ogre::MeshSerializer(); Ogre::MaterialSerializer* mMaterialSerializer = new Ogre::MaterialSerializer(); int idCounter = 3; if (!file.open(QIODevice::WriteOnly)) { /* show wrror message if not able to open file */ QMessageBox::warning(0, "Read only", "The file is in read only mode"); } else { Ogre::SceneManager::MovableObjectIterator iterator = sceneManager->getMovableObjectIterator("Entity"); QXmlStreamWriter* xmlWriter = new QXmlStreamWriter(); xmlWriter->setAutoFormatting(true); xmlWriter->setDevice(&file); xmlWriter->writeStartElement("scene"); xmlWriter->writeAttribute("formatVersion",""); xmlWriter->writeStartElement("nodes"); while(iterator.hasMoreElements()) { Ogre::Entity* e = static_cast<Ogre::Entity*>(iterator.getNext()); Ogre::Any any = e->getParentNode()->getUserAny(); Ogre::String widgetType(""); if(!any.isEmpty()){ widgetType = any_cast<Ogre::String>(any); } Ogre::String tmp(widgetType + ":" + e->getParentNode()->getName()); QString nodeName(tmp.c_str()); xmlWriter->writeStartElement("node"); xmlWriter->writeAttribute("name", nodeName); xmlWriter->writeAttribute("id", QString::number(idCounter++)); xmlWriter->writeStartElement("position"); xmlWriter->writeAttribute("x", QString::number(e->getParentNode()->getPosition().x)); xmlWriter->writeAttribute("y", QString::number(e->getParentNode()->getPosition().y)); xmlWriter->writeAttribute("z", QString::number(e->getParentNode()->getPosition().z)); xmlWriter->writeEndElement(); xmlWriter->writeStartElement("scale"); xmlWriter->writeAttribute("x", QString::number(e->getParentNode()->getScale().x)); xmlWriter->writeAttribute("y", QString::number(e->getParentNode()->getScale().y)); xmlWriter->writeAttribute("z", QString::number(e->getParentNode()->getScale().z)); xmlWriter->writeEndElement(); xmlWriter->writeStartElement("entity"); xmlWriter->writeAttribute("name", nodeName); xmlWriter->writeAttribute("meshFile", nodeName.toLower() + QString(".mesh") ); xmlWriter->writeAttribute("static", QString("false")); xmlWriter->writeEndElement(); const Mesh* mesh = e->getMesh().getPointer(); mMeshSerializer->exportMesh(mesh,String(path.toStdString() + nodeName.toLower().toStdString() + ".mesh" )); std::cout << "numeber" << mesh->getNumSubMeshes() << std::endl; for(int i = 0; i < e->getNumSubEntities(); i++){ Ogre::Material *mat = static_cast<Ogre::Material*> (Ogre::MaterialManager::getSingletonPtr()->getByName(e->getSubEntity(i)->getMaterialName()).getPointer()); //e->getMesh().get()->getSubMesh() if(mat->getTechnique(0)->getPass(0)->getNumTextureUnitStates() !=0){ Ogre::String str = mat->getTechnique(0)->getPass(0)->getTextureUnitState(0)->getTextureName(); Ogre::MaterialPtr mMatPtr =e->getSubEntity(i)->getMaterial() ; mMaterialSerializer->exportMaterial(mMatPtr , String(path.toStdString() + nodeName.toLower().toStdString() + QString::number(i).toStdString() + ".material" )); Ogre::TexturePtr* mTexPtr = new Ogre::TexturePtr(Ogre::TextureManager::getSingletonPtr()->getByName(str)); Ogre::Texture* mTex = mTexPtr->getPointer(); Ogre::PixelFormat pxf = mTex->getFormat(); Ogre::Image mImage; mTex->convertToImage(mImage); std::cout << str << std::endl; mImage.save(String(path.toStdString() + str)); } } //material file merge for(int i = 0; i < e->getNumSubEntities(); i++){ Ogre::Material *mat = static_cast<Ogre::Material*> (Ogre::MaterialManager::getSingletonPtr()->getByName(e->getSubEntity(i)->getMaterialName()).getPointer()); QString mMatFilePath = QString((path.toStdString() + nodeName.toLower().toStdString() + ".material").c_str()) ; QFile mFile(mMatFilePath); if (!mFile.open(QIODevice::Append)) { /* show wrror message if not able to open file */ QMessageBox::warning(0, "Read only", "The file is in read only mode"); } else{ QTextStream out(&mFile); QString mTempMatPath = QString((path + nodeName.toLower() + QString::number(i) + ".material")); QFile mTempMatFile(mTempMatPath); mTempMatFile.open(QIODevice::ReadOnly); QTextStream src(&mTempMatFile); mFile.write(src.readAll().toStdString().c_str()); mTempMatFile.remove(); } } xmlWriter->writeEndElement(); } xmlWriter->writeEndElement(); xmlWriter->writeEndDocument(); delete xmlWriter; } delete mMeshSerializer; delete mMaterialSerializer; }
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; }
Ogre::Entity* StageFile::GetModel( const StageInfo& info ) { //DumpSettings("exported/" + info.data.name + ".lua"); VectorTexForGen textures; Ogre::MeshPtr mesh = Ogre::MeshManager::getSingleton().create(info.data.name + "export", "General"); Ogre::SkeletonPtr skeleton = Ogre::SkeletonManager::getSingleton().create(info.data.name + "export", "General"); u32 number_of_files = GetU32LE(0); LOGGER->Log("Number of file " + IntToString(number_of_files) + "\n"); Ogre::Bone* root1 = skeleton->createBone( "0", 0 ); Ogre::Bone* root2 = skeleton->createBone( "1", 1 ); root1->addChild( root2 ); Ogre::Animation* anim = skeleton->createAnimation( "Idle", 1 ); Ogre::NodeAnimationTrack* track1 = anim->createNodeTrack( 0, root1 ); track1->removeAllKeyFrames(); Ogre::TransformKeyFrame* frame1 = track1->createNodeKeyFrame( 0 ); Ogre::Matrix3 matrix; matrix.FromEulerAnglesYXZ( Ogre::Radian( Ogre::Degree( 0 ) ), Ogre::Radian( Ogre::Degree( -90 ) ), Ogre::Radian( Ogre::Degree( 0 ) ) ); Ogre::Quaternion rot; rot.FromRotationMatrix( matrix ); frame1->setRotation( rot ); for (u32 i = 1; i < number_of_files - 1; ++i) { int offset_to_vertex = GetU32LE(0x04 + i * 0x04); MeshExtractor(info.data, "ffvii/battle_stage/" + info.data.name, this, offset_to_vertex, textures, mesh, Ogre::StringConverter::toString(i), 1); } // <OGRE> /////////////////////////////// skeleton->optimiseAllAnimations(); Ogre::SkeletonSerializer skeleton_serializer; skeleton_serializer.exportSkeleton(skeleton.getPointer(), "exported/models/ffvii/battle/stages/" + info.data.name + ".skeleton"); // Update bounds Ogre::AxisAlignedBox aabb(-999, -999, -999, 999, 999, 999); mesh->_setBounds(aabb, false); mesh->_setBoundingSphereRadius(999); mesh->setSkeletonName( "models/ffvii/battle/stages/" + info.data.name + ".skeleton" ); Ogre::MeshSerializer ser; ser.exportMesh(mesh.getPointer(), "exported/models/ffvii/battle/stages/" + info.data.name + ".mesh"); // create and export textures for model if( textures.size() > 0 ) { int number_of_files = GetU32LE( 0x00 ); int offset_to_texture = GetU32LE( number_of_files * 0x04 ); Vram* vram = Vram::MakeInstance().release(); LoadTimFileToVram( this, offset_to_texture, vram ); //vram->Save( "qqq" ); CreateTexture( vram, info.data, "exported/models/ffvii/battle/stages/" + info.data.name + ".png", textures ); delete vram; } CreateMaterial("ffvii/battle_stage/" + info.data.name, "exported/models/ffvii/battle/stages/" + info.data.name + ".material", "models/ffvii/battle/stages/" + info.data.name + ".png", "", ""); Ogre::SceneManager* scene_manager = Ogre::Root::getSingleton().getSceneManager( "Scene" ); Ogre::Entity* thisEntity = scene_manager->createEntity( info.data.name, "models/ffvii/battle/stages/" + info.data.name + ".mesh" ); //thisEntity->setDisplaySkeleton(true); //thisEntity->setDebugDisplayEnabled(true); thisEntity->setVisible(false); thisEntity->getAnimationState( "Idle" )->setEnabled( true ); thisEntity->getAnimationState( "Idle" )->setLoop( true ); Ogre::SceneNode* thisSceneNode = scene_manager->getRootSceneNode()->createChildSceneNode(); thisSceneNode->setPosition( 0, 0, 0 ); thisSceneNode->roll( Ogre::Radian( Ogre::Degree( 180.0f ) ) ); thisSceneNode->yaw( Ogre::Radian( Ogre::Degree( 120.0f ) ) ); thisSceneNode->pitch( Ogre::Radian( Ogre::Degree( 90.0f ) ) ); thisSceneNode->attachObject( thisEntity ); return thisEntity; }