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; }
// Call for an unload when list is already locked void OLMeshTracker::MakeUnLoadedLocked(Ogre::String meshName, Ogre::String stringParam, Ogre::Entity* entityParam) { // see if in the loading list. Remove if there. GenericQm* loadEntry = m_meshesToLoad->Find(meshName); if (loadEntry != NULL) { loadEntry->Abort(); m_meshesToLoad->Remove(meshName); } // see if in the serialize list. Mark for unload if it's there GenericQm* serialEntry = m_meshesToSerialize->Find(meshName); if (serialEntry != NULL) { serialEntry->stringParam = "unload"; } else { Ogre::MeshPtr meshP = Ogre::MeshManager::getSingleton().getByName(meshName); if (!meshP.isNull()) { if (meshP.useCount() == 1) { meshP->unload(); } else { LG::Log("OLMeshTracker::MakeUnLoaded: Didn't unload mesh because count = %d", meshP.useCount()); } } } }
//--------------------------------------------------------------------- void MeshElement::setMaterialName(const Ogre::String &name) { mMaterialName = name; if (mEntity) { // if this is "none",we will use the origin material of the mesh if (mMaterialName == "none") { if ( false == mMeshName.empty() ) { Ogre::MeshPtr currentMesh = Ogre::MeshManager::getSingleton().getByName(mMeshName); for ( unsigned short i=0; i<currentMesh->getNumSubMeshes(); ++i ) { mEntity->getSubEntity(i)->setMaterialName( currentMesh->getSubMesh(i)->getMaterialName() ); } } } else mEntity->setMaterialName(mMaterialName); } }
void ESKOgre::createFakeEntity(Ogre::SceneManager *mSceneMgr) { Ogre::MeshPtr msh = Ogre::MeshManager::getSingleton().createManual(name + "_skeleton", XENOVIEWER_RESOURCE_GROUP); msh->setSkeletonName(name); Ogre::SubMesh* sub = msh->createSubMesh(); const size_t nVertices = 3; const size_t nVertCount = 3; const size_t vbufCount = nVertCount*nVertices; float *vertices = (float *)malloc(sizeof(float)*vbufCount); for (size_t i = 0; i < nVertices; i++) { vertices[i*nVertCount] = 0.0; vertices[i*nVertCount + 1] = 0.0; vertices[i*nVertCount + 2] = 0.0; } const size_t ibufCount = 3; unsigned short *faces = (unsigned short *)malloc(sizeof(unsigned short) * ibufCount); for (size_t i = 0; i < ibufCount; i++) { faces[i] = i; } msh->sharedVertexData = new Ogre::VertexData(); msh->sharedVertexData->vertexCount = nVertices; Ogre::VertexDeclaration* decl = msh->sharedVertexData->vertexDeclaration; size_t offset = 0; decl->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_POSITION); offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3); Ogre::HardwareVertexBufferSharedPtr vbuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(offset, msh->sharedVertexData->vertexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY); vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true); Ogre::VertexBufferBinding* bind = msh->sharedVertexData->vertexBufferBinding; bind->setBinding(0, vbuf); Ogre::HardwareIndexBufferSharedPtr ibuf = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(Ogre::HardwareIndexBuffer::IT_16BIT, ibufCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY); ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true); sub->useSharedVertices = true; sub->indexData->indexBuffer = ibuf; sub->indexData->indexCount = ibufCount; sub->indexData->indexStart = 0; msh->_setBounds(Ogre::AxisAlignedBox(-100, -100, -100, 100, 100, 100)); msh->_setBoundingSphereRadius(100); msh->load(); free(faces); free(vertices); skeleton_entity = mSceneMgr->createEntity(name + "_skeleton"); skeleton_node = mSceneMgr->getRootSceneNode()->createChildSceneNode(); skeleton_node->attachObject(skeleton_entity); skeleton_node->setVisible(false); }
bool MilkshapePlugin::locateSkeleton(Ogre::MeshPtr& mesh) { // // choose filename // OPENFILENAME ofn; memset (&ofn, 0, sizeof (OPENFILENAME)); char szFile[MS_MAX_PATH]; char szFileTitle[MS_MAX_PATH]; char szDefExt[32] = "skeleton"; char szFilter[128] = "OGRE .skeleton Files (*.skeleton)\0*.skeleton\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_PATHMUSTEXIST | OFN_FILEMUSTEXIST; ofn.lpstrTitle = "Locate OGRE Skeleton (since you're not exporting it)"; if (!::GetOpenFileName (&ofn)) return false; // Strip off the path Ogre::String skelName = szFile; size_t lastSlash = skelName.find_last_of("\\"); skelName = skelName.substr(lastSlash+1); Ogre::String msg = "Linking mesh to skeleton file '" + skelName + "'"; Ogre::LogManager::getSingleton().logMessage(msg); // Create a dummy skeleton for Mesh to link to (saves it trying to load it) Ogre::SkeletonPtr pSkel = Ogre::SkeletonManager::getSingleton().create(skelName, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); Ogre::LogManager::getSingleton().logMessage("Dummy Skeleton object created for link."); mesh->_notifySkeleton(pSkel); return true; }
std::string AssetsManager::resolveFilePathForMesh(Ogre::MeshPtr meshPtr) { Ogre::ResourceGroupManager& manager = Ogre::ResourceGroupManager::getSingleton(); const std::multimap<std::string, std::string>& locations = EmberOgre::getSingleton().getResourceLocations(); for (std::multimap<std::string, std::string>::const_iterator I = locations.begin(); I != locations.end(); ++I) { std::string group = I->first; std::string fileName = meshPtr->getName(); Ogre::FileInfoListPtr files = manager.findResourceFileInfo(group, fileName, false); for (Ogre::FileInfoList::const_iterator J = files->begin(); J != files->end(); ++J) { if (J->filename == fileName) { return I->second + J->filename; } } } return ""; }
Indicator(const ObjectPtr &object, SceneManipulator *sceneManipulator) : mProxy(NULL) { assert(sceneManipulator); mUserAny = Ogre::Any(); mProxy = new ObjectProxy(object); // 根据光源位置来定节点位置 Ogre::Vector3 pos = VariantCast<Ogre::Vector3>(object->getProperty("position")); mIndicatorSceneNode = sceneManipulator->getIndicatorRootSceneNode()->createChildSceneNode(pos); Real radius = 5; int rings = 16; int segments = 16; Ogre::MeshPtr sphereMesh = createCommonSphere(radius, rings, segments); Ogre::MaterialPtr material = createPureColourMaterial( Ogre::ColourValue(1, 0, 0, 0.75) ); mIndicatorEntity = sceneManipulator->getSceneManager()->createEntity(mIndicatorSceneNode->getName(), sphereMesh->getName()); //david-<< //mIndicatorEntity->setNormaliseNormals(true); //david->> mIndicatorEntity->setMaterialName(material->getName()); setUserObject(mProxy); mIndicatorSceneNode->attachObject(mIndicatorEntity); // 选择时不考虑粒子系统的包围盒,用的是指示器的包围盒 ParticleSystemObject *particleSystemObject = static_cast<ParticleSystemObject *> (object.get()); Ogre::ParticleSystem *system = particleSystemObject->getParticleSystem(); if (system) system->setQueryFlags(0); // 根据光源类型来挂接模型 showIndicator(false); }
void MergeMesh::addMesh( Ogre::MeshPtr mesh ) { if( mesh->getSkeleton().isNull() ) { log( "Skipped: " + mesh->getName() + " has no skeleton" ); return; } if( m_BaseSkeleton.isNull() ) { m_BaseSkeleton = mesh->getSkeleton(); log( "Set: base skeleton (" + m_BaseSkeleton->getName()+")" ); } if( mesh->getSkeleton() != m_BaseSkeleton ) { log( "Skipped: " + mesh->getName() + " has other skeleton ("+ mesh->getSkeleton()->getName() +")" ); return; } m_Meshes.push_back( mesh ); }
// =============================================================================== // Someone wants to delete this mesh. Check to see if it's a shared mesh and decide if we // should actually delete it or not. void OLMeshTracker::DeleteMesh(Ogre::MeshPtr mesh) { Ogre::MeshManager::getSingleton().remove(mesh->getName()); }
Ogre::SkeletonPtr MilkshapePlugin::doExportSkeleton(msModel* pModel, Ogre::MeshPtr& mesh) { Ogre::LogManager &logMgr = Ogre::LogManager::getSingleton(); Ogre::String msg; // // choose filename // OPENFILENAME ofn; memset (&ofn, 0, sizeof (OPENFILENAME)); char szFile[MS_MAX_PATH]; char szFileTitle[MS_MAX_PATH]; char szDefExt[32] = "skeleton"; char szFilter[128] = "OGRE .skeleton Files (*.skeleton)\0*.skeleton\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 Skeleton"; if (!::GetSaveFileName (&ofn)) return Ogre::SkeletonPtr(); // Strip off the path Ogre::String skelName = szFile; size_t lastSlash = skelName.find_last_of("\\"); skelName = skelName.substr(lastSlash+1); // Set up logMgr.logMessage("Trying to create Skeleton object"); Ogre::SkeletonPtr ogreskel = Ogre::SkeletonManager::getSingleton().create(skelName, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); logMgr.logMessage("Skeleton object created"); // Complete the details // Do the bones int numBones = msModel_GetBoneCount(pModel); msg = "Number of bones: " + Ogre::StringConverter::toString(numBones); logMgr.logMessage(msg); int i; // Create all the bones in turn for (i = 0; i < numBones; ++i) { msBone* bone = msModel_GetBoneAt(pModel, i); Ogre::Bone* ogrebone = ogreskel->createBone(bone->szName); msVec3 msBonePos, msBoneRot; msBone_GetPosition(bone, msBonePos); msBone_GetRotation(bone, msBoneRot); Ogre::Vector3 bonePos(msBonePos[0], msBonePos[1], msBonePos[2]); ogrebone->setPosition(bonePos); // Hmm, Milkshape has chosen a Euler angle representation of orientation which is not smart // Rotation Matrix or Quaternion would have been the smarter choice // Might we have Gimbal lock here? What order are these 3 angles supposed to be applied? // Grr, we'll try our best anyway... Ogre::Quaternion qx, qy, qz, qfinal; qx.FromAngleAxis(Ogre::Radian(msBoneRot[0]), Ogre::Vector3::UNIT_X); qy.FromAngleAxis(Ogre::Radian(msBoneRot[1]), Ogre::Vector3::UNIT_Y); qz.FromAngleAxis(Ogre::Radian(msBoneRot[2]), Ogre::Vector3::UNIT_Z); // Assume rotate by x then y then z qfinal = qz * qy * qx; ogrebone->setOrientation(qfinal); Ogre::LogManager::getSingleton().stream() << "Bone #" << i << ": " << "Name='" << bone->szName << "' " << "Position: " << bonePos << " " << "Ms3d Rotation: {" << msBoneRot[0] << ", " << msBoneRot[1] << ", " << msBoneRot[2] << "} " << "Orientation: " << qfinal; } // Now we've created all the bones, link them up logMgr.logMessage("Establishing bone hierarchy.."); for (i = 0; i < numBones; ++i) { msBone* bone = msModel_GetBoneAt(pModel, i); if (strlen(bone->szParentName) == 0) { // Root bone msg = "Root bone detected: Name='" + Ogre::String(bone->szName) + "' Index=" + Ogre::StringConverter::toString(i); logMgr.logMessage(msg); } else { Ogre::Bone* ogrechild = ogreskel->getBone(bone->szName); Ogre::Bone* ogreparent = ogreskel->getBone(bone->szParentName); if (ogrechild == 0) { msg = "Error: could not locate child bone '" + Ogre::String(bone->szName) + "'"; logMgr.logMessage(msg); continue; } if (ogreparent == 0) { msg = "Error: could not locate parent bone '" + Ogre::String(bone->szParentName) + "'"; logMgr.logMessage(msg); continue; } // Make child ogreparent->addChild(ogrechild); } } logMgr.logMessage("Bone hierarchy established."); // Create the Animation(s) doExportAnimations(pModel, ogreskel); // Create skeleton serializer & export Ogre::SkeletonSerializer serializer; msg = "Exporting skeleton to " + Ogre::String(szFile); logMgr.logMessage(msg); serializer.exportSkeleton(ogreskel.getPointer(), szFile); logMgr.logMessage("Skeleton exported"); msg = "Linking mesh to skeleton file '" + skelName + "'"; Ogre::LogManager::getSingleton().logMessage(msg); mesh->_notifySkeleton(ogreskel); return ogreskel; }
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); } }
void CSaveSceneView::SceneNodeExplore(Ogre::SceneNode *SceneNode) { Ogre::Entity *Entity = NULL; Ogre::Camera *Camera = NULL; Ogre::Light *Light = NULL; Ogre::ParticleSystem *ParticleSystem = NULL; Ogre::ManualObject *ManualObject = NULL; Ogre::BillboardSet *BillboardSet = NULL; xmlTextWriterStartElement(m_XmlWriter, BAD_CAST "SceneNode"); Ogre::String SceneNodeName = SceneNode->getName(); xmlTextWriterWriteAttribute(m_XmlWriter, BAD_CAST "SceneNodeName", BAD_CAST SceneNodeName.c_str()); Ogre::SceneNode::ObjectIterator obji = SceneNode->getAttachedObjectIterator(); while (obji.hasMoreElements()) { Ogre::MovableObject* mobj = obji.getNext(); Ogre::String Type = mobj->getMovableType(); if (Type == "Entity") { Entity = (Ogre::Entity *)(mobj); Ogre::String EntityName = Entity->getName(); xmlTextWriterStartElement(m_XmlWriter, BAD_CAST "Entity"); xmlTextWriterWriteAttribute(m_XmlWriter, BAD_CAST "EntityName", BAD_CAST EntityName.c_str()); Ogre::MeshPtr Mesh = Entity->getMesh(); Ogre::String MeshName = Mesh->getName(); xmlTextWriterWriteAttribute(m_XmlWriter, BAD_CAST "MeshName", BAD_CAST MeshName.c_str()); xmlTextWriterEndElement(m_XmlWriter); } if (Type == "Camera") { Camera = (Ogre::Camera *)(mobj); Ogre::String CameraName = Camera->getName(); xmlTextWriterStartElement(m_XmlWriter, BAD_CAST "Camera"); xmlTextWriterWriteAttribute(m_XmlWriter, BAD_CAST "CameraName", BAD_CAST CameraName.c_str()); Ogre::Vector3 CameraPosition = Camera->getPosition(); xmlTextWriterWriteFormatAttribute(m_XmlWriter, BAD_CAST "XPosition", "%f",CameraPosition.x); xmlTextWriterWriteFormatAttribute(m_XmlWriter, BAD_CAST "YPosition", "%f",CameraPosition.y); xmlTextWriterWriteFormatAttribute(m_XmlWriter, BAD_CAST "ZPosition", "%f",CameraPosition.z); Ogre::Vector3 CameraDirection = Camera->getDirection(); xmlTextWriterWriteFormatAttribute(m_XmlWriter, BAD_CAST "XDirection", "%f",CameraDirection.x); xmlTextWriterWriteFormatAttribute(m_XmlWriter, BAD_CAST "YDirection", "%f",CameraDirection.y); xmlTextWriterWriteFormatAttribute(m_XmlWriter, BAD_CAST "ZDirection", "%f",CameraDirection.z); xmlTextWriterEndElement(m_XmlWriter); } if (Type == "Light") { Light = (Ogre::Light *)(mobj); } if (Type == "ParticleSystem") { ParticleSystem = (Ogre::ParticleSystem *)(mobj); } if (Type == "ManualObject") { ManualObject = (Ogre::ManualObject *)(mobj); } if (Type == "BillboardSet") { BillboardSet = (Ogre::BillboardSet *)(mobj); } } Ogre::Node::ChildNodeIterator nodei = SceneNode->getChildIterator(); while (nodei.hasMoreElements()) { Ogre::SceneNode* node = (Ogre::SceneNode*)(nodei.getNext()); // Add this subnode and its children... SceneNodeExplore(node); } xmlTextWriterEndElement(m_XmlWriter); //end SceneNode }
void NxMeshManager::SetPivotTransform( Ogre::MeshPtr mesh, const Nx::Vector3 & Position, const Nx::Quaternion & Rotation, const Nx::Vector3 & Scale ) { //from mesh magick / mit licence Nx::Matrix4 transform = Nx::Matrix4::IDENTITY; Nx::Vector3 translate = Nx::Vector3::ZERO; // Apply current transform to the mesh, to get the bounding box to // base te translation on. AxisAlignedBox aabb = getMeshAabb( mesh, transform); //if (alignment == "left") //{ // translate = Vector3(-aabb.getMinimum().x, 0, 0); //} //else if (alignment == "center") //{ // translate = Vector3(-aabb.getCenter().x, 0, 0); //} //else if (alignment == "right") //{ // translate = Vector3(-aabb.getMaximum().x, 0, 0); //} //Position .. only support pivot down / centered //translate = Vector3(0, -aabb.getMinimum().y, 0);// pivot down translate = Position; transform = Nx::Matrix4::getTrans(translate) * transform; //rotation transform = Nx::Matrix4(Rotation) * transform; //scale transform = Nx::Matrix4::getScale(Scale) * transform; // Check whether we have to flip vertex winding. // We do have to, if we changed our right hand base. // We can test it by using the cross product from X and Y and see, if it is a non-negative // projection on Z. Actually it should be exactly Z, as we don't do non-uniform scaling yet, // but the test is cheap either way. Nx::Matrix3 m3; transform.extract3x3Matrix(m3); if (m3.GetColumn(0).crossProduct(m3.GetColumn(1)).dotProduct(m3.GetColumn(2)) < 0) { LogMsg("SetPivotPosition : Flipping vertex winding ... " ); mFlipVertexWinding = true; } //mTransform = transform; NxMat4toOgre( mTransform, transform ) ; mBoundingBox.setNull(); if( mesh->sharedVertexData != NULL) { processVertexData( mesh->sharedVertexData); }else { LogMsg("mesh->sharedVertexData NULL"); } for( int i = 0; i < mesh->getNumSubMeshes(); i++ ) { SubMesh* submesh = mesh->getSubMesh(i); if( submesh->vertexData != NULL ) { LogMsg("SetPivotPosition : Processing vertex data ... " ); processVertexData(submesh->vertexData); }else { LogMsg("submesh->vertexData NULL"); } if (submesh->indexData != NULL) { LogMsg("SetPivotPosition : Processing Index data .." ); processIndexData(submesh->indexData); }else { LogMsg("submesh->indexData NULL"); } } //process pose for( unsigned short i = 0; i < mesh->getPoseCount(); ++i ) { Ogre::Pose * pose = mesh->getPose(i); Ogre::Matrix3 m3x3; mTransform.extract3x3Matrix(m3x3); Pose::VertexOffsetIterator it = pose->getVertexOffsetIterator(); while (it.hasMoreElements()) { Ogre::Vector3 offset = it.peekNextValue(); Ogre::Vector3 newOffset = m3x3 * offset; *it.peekNextValuePtr() = newOffset; it.moveNext(); } } mesh->_setBounds( mBoundingBox, false ); }
// Get the mesh information for the given mesh. // Code found on this forum link: http://www.ogre3d.org/wiki/index.php/RetrieveVertexData void CollisionTools::GetMeshInformation(const Ogre::MeshPtr mesh, size_t &vertex_count, Ogre::Vector3* &vertices, size_t &index_count, Ogre::uint32* &indices, const Ogre::Vector3 &position, const Ogre::Quaternion &orient, const Ogre::Vector3 &scale) { bool added_shared = false; size_t current_offset = 0; size_t shared_offset = 0; size_t next_offset = 0; size_t index_offset = 0; vertex_count = index_count = 0; // Calculate how many vertices and indices we're going to need for (unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i) { Ogre::SubMesh* submesh = mesh->getSubMesh( i ); // We only need to add the shared vertices once if(submesh->useSharedVertices) { if( !added_shared ) { vertex_count += mesh->sharedVertexData->vertexCount; added_shared = true; } } else { vertex_count += submesh->vertexData->vertexCount; } // Add the indices index_count += submesh->indexData->indexCount; } // Allocate space for the vertices and indices vertices = new Ogre::Vector3[vertex_count]; indices = new Ogre::uint32[index_count]; added_shared = false; // Run through the submeshes again, adding the data into the arrays for ( unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i) { Ogre::SubMesh* submesh = mesh->getSubMesh(i); Ogre::VertexData* vertex_data = submesh->useSharedVertices ? mesh->sharedVertexData : submesh->vertexData; if((!submesh->useSharedVertices)||(submesh->useSharedVertices && !added_shared)) { if(submesh->useSharedVertices) { added_shared = true; shared_offset = current_offset; } const Ogre::VertexElement* posElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION); Ogre::HardwareVertexBufferSharedPtr vbuf = vertex_data->vertexBufferBinding->getBuffer(posElem->getSource()); unsigned char* vertex = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); // There is _no_ baseVertexPointerToElement() which takes an Ogre::Ogre::Real or a double // as second argument. So make it float, to avoid trouble when Ogre::Ogre::Real will // be comiled/typedefed as double: // Ogre::Ogre::Real* pOgre::Real; float* pReal; for( size_t j = 0; j < vertex_data->vertexCount; ++j, vertex += vbuf->getVertexSize()) { posElem->baseVertexPointerToElement(vertex, &pReal); Ogre::Vector3 pt(pReal[0], pReal[1], pReal[2]); vertices[current_offset + j] = (orient * (pt * scale)) + position; } vbuf->unlock(); next_offset += vertex_data->vertexCount; } Ogre::IndexData* index_data = submesh->indexData; size_t numTris = index_data->indexCount / 3; Ogre::HardwareIndexBufferSharedPtr ibuf = index_data->indexBuffer; bool use32bitindexes = (ibuf->getType() == Ogre::HardwareIndexBuffer::IT_32BIT); Ogre::uint32* pLong = static_cast<Ogre::uint32*>(ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); unsigned short* pShort = reinterpret_cast<unsigned short*>(pLong); size_t offset = (submesh->useSharedVertices)? shared_offset : current_offset; if ( use32bitindexes ) { for ( size_t k = 0; k < numTris*3; ++k) { indices[index_offset++] = pLong[k] + static_cast<Ogre::uint32>(offset); } } else { for ( size_t k = 0; k < numTris*3; ++k) { indices[index_offset++] = static_cast<Ogre::uint32>(pShort[k]) + static_cast<Ogre::uint32>(offset); } } ibuf->unlock(); current_offset = next_offset; } }
Ogre::MeshPtr loadMesh(const Ogre::String& meshName, const Ogre::String& groupName, const Ogre::String& baseResourceName, const Ogre::String& baseGroupName) { // Load the mesh Ogre::MeshPtr mesh = loadCorrelativeResource( meshName, groupName, baseResourceName, baseGroupName, Ogre::MeshManager::getSingleton()); if (mesh.isNull()) { OGRE_EXCEPT(Ogre::Exception::ERR_ITEM_NOT_FOUND, "Unable to load mesh " + meshName, "loadMesh"); } // Try to resolve skeleton resource if (mesh->hasSkeleton() && mesh->getSkeleton().isNull()) { // resolve correlative with mesh Ogre::SkeletonPtr skeleton = loadCorrelativeResource( mesh->getSkeletonName(), groupName, mesh->getName(), mesh->getGroup(), Ogre::SkeletonManager::getSingleton()); if (skeleton.isNull()) { // resolve correlative with base resource skeleton = loadCorrelativeResource( mesh->getSkeletonName(), groupName, baseResourceName, baseGroupName, Ogre::SkeletonManager::getSingleton()); } if (skeleton.isNull()) { OGRE_EXCEPT(Ogre::Exception::ERR_ITEM_NOT_FOUND, "Unable to load skeleton " + mesh->getSkeletonName() + " for mesh " + mesh->getName(), "loadMesh"); } // Set to the actual name mesh->setSkeletonName(skeleton->getName()); } return mesh; }
void Renderer::FindClosestPolygon(Ogre::Entity* entity, float& closestDistance, Ogre::Vector3& position, Ogre::Vector3& normal) { closestDistance = std::numeric_limits<float>::max(); // default value (means // nothing detected) // Get transformation Ogre::SceneNode* parentNode = entity->getParentSceneNode(); Ogre::Vector3 parentPos; Ogre::Quaternion parentOrientation; Ogre::Vector3 parentScale; if (parentNode) { parentPos = parentNode->_getDerivedPosition(); parentOrientation = parentNode->_getDerivedOrientation(); parentScale = parentNode->_getDerivedScale(); } else { parentPos = Ogre::Vector3::ZERO; parentOrientation = Ogre::Quaternion::IDENTITY; parentScale = Ogre::Vector3::UNIT_SCALE; } // Handle animated entities bool isAnimated = entity->hasSkeleton(); if (isAnimated) { entity->addSoftwareAnimationRequest(false); entity->_updateAnimation(); } // Loop through each submesh Ogre::MeshPtr mesh = entity->getMesh(); for (uint i = 0; i < mesh->getNumSubMeshes(); ++i) { Ogre::SubMesh* subMesh = mesh->getSubMesh(i); // Ignore anything that isn't a triangle List if (subMesh->operationType != Ogre::RenderOperation::OT_TRIANGLE_LIST) continue; // Get the vertex data Ogre::VertexData* vertexData; if (subMesh->useSharedVertices) { if (isAnimated) vertexData = entity->_getSkelAnimVertexData(); else vertexData = mesh->sharedVertexData; } else { if (isAnimated) vertexData = entity->getSubEntity(i)->_getSkelAnimVertexData(); else vertexData = subMesh->vertexData; } // Get the size of one vertex const Ogre::VertexElement* posEl = vertexData->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION); Ogre::HardwareVertexBufferSharedPtr vBuff = vertexData->vertexBufferBinding->getBuffer(posEl->getSource()); uint vertexSize = vBuff->getVertexSize(); // Save pointer to first vertex short* pVertex = (short*)vBuff->lock(Ogre::HardwareBuffer::HBL_READ_ONLY); short* pStartVertex = pVertex; // Get the index buffer // If it is null then skip as it must be a point cloud Ogre::HardwareIndexBufferSharedPtr iBuff = subMesh->indexData->indexBuffer; if (iBuff.isNull()) continue; uint* pLong = (uint*)iBuff->lock(Ogre::HardwareBuffer::HBL_READ_ONLY); uint16_t* pShort = (uint16_t*)pLong; // Look through each vertex and check each triangle with the ray Ogre::Vector3 vertexPos; Ogre::Vector3 vertex1; Ogre::Vector3 vertex2; float* pReal; uint index; for (uint k = 0; k < subMesh->indexData->indexCount; k++) { // Read index value if (iBuff->getType() == Ogre::HardwareIndexBuffer::IT_32BIT) // if 32bit indexes { index = (uint)pLong[k]; } else { index = (uint)pShort[k]; } // Read referenced vertex pVertex = pStartVertex + (vertexSize * index); // calculate pointer posEl->baseVertexPointerToElement(pVertex, &pReal); // read vertex vertexPos = Ogre::Vector3(pReal[0], pReal[1], pReal[2]); // read position values // Apply world transformations if (parentNode) vertexPos = (parentOrientation * (vertexPos * parentScale)) + parentPos; // Figure out triangle and calculate the distance if it's the closest switch (k % 3) { case 0: vertex1 = vertexPos; break; case 1: vertex2 = vertexPos; break; case 2: RayToTriangleCheck(vertex1, vertex2, vertexPos, closestDistance, position, normal); break; default: break; } } iBuff->unlock(); vBuff->unlock(); } if (isAnimated) { entity->removeSoftwareAnimationRequest(false); } }
void MeshUtils::meshBuffersToArrays(const Ogre::MeshPtr& mesh, Ogre::Vector3* vertices, unsigned long* indices) { bool added_shared = false; size_t current_offset = 0; size_t shared_offset = 0; size_t next_offset = 0; size_t index_offset = 0; //const Ogre::Vector3 &position = ent->getParentNode()->_getDerivedPosition(); //const Ogre::Quaternion &orient = ent->getParentNode()->_getDerivedOrientation(); //const Ogre::Vector3 &scale = ent->getParentNode()->_getDerivedScale(); const Ogre::Vector3 &position = Ogre::Vector3::ZERO; const Ogre::Quaternion &orient = Ogre::Quaternion::IDENTITY; const Ogre::Vector3 &scale = Ogre::Vector3::UNIT_SCALE; Ogre::Mesh::SubMeshIterator itr = mesh->getSubMeshIterator(); while (itr.hasMoreElements()) { Ogre::SubMesh* submesh = itr.getNext(); Ogre::VertexData* vertex_data = submesh->useSharedVertices ? mesh->sharedVertexData : submesh->vertexData; if ((!submesh->useSharedVertices) || (submesh->useSharedVertices && !added_shared)) { if (submesh->useSharedVertices) { added_shared = true; shared_offset = current_offset; } const Ogre::VertexElement* posElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION); Ogre::HardwareVertexBufferSharedPtr vbuf = vertex_data->vertexBufferBinding->getBuffer(posElem->getSource()); unsigned char* vertex = static_cast<unsigned char*> (vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); // There is _no_ baseVertexPointerToElement() which takes an Ogre::Real or a double // as second argument. So make it float, to avoid trouble when Ogre::Real will // be comiled/typedefed as double: // Ogre::Real* pReal; float* pReal; for (size_t k = 0; k < vertex_data->vertexCount; ++k, vertex += vbuf->getVertexSize()) { posElem->baseVertexPointerToElement(vertex, &pReal); Ogre::Vector3 pt(pReal[0], pReal[1], pReal[2]); vertices[current_offset + k] = (orient * (pt * scale)) + position; //vertices[current_offset + k] = pt; } vbuf->unlock(); next_offset += vertex_data->vertexCount; } Ogre::IndexData* index_data = submesh->indexData; size_t numTris = index_data->indexCount / 3; Ogre::HardwareIndexBufferSharedPtr ibuf = index_data->indexBuffer; bool use32bitindexes = (ibuf->getType() == Ogre::HardwareIndexBuffer::IT_32BIT); unsigned long* pLong = static_cast<unsigned long*> (ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); unsigned short* pShort = reinterpret_cast<unsigned short*> (pLong); size_t offset = (submesh->useSharedVertices) ? shared_offset : current_offset; if (use32bitindexes) { for (size_t k = 0; k < numTris * 3; ++k) { indices[index_offset++] = pLong[k] + static_cast<unsigned long> (offset); } } else { for (size_t k = 0; k < numTris * 3; ++k) { indices[index_offset++] = static_cast<unsigned long> (pShort[k]) + static_cast<unsigned long> (offset); } } ibuf->unlock(); current_offset = next_offset; } }
Ogre::SceneNode *TutorialApplication::loadBSP(std::shared_ptr<l2p::UModel> m, bool ignoreNonVisible) { l2p::Name name = m->package->name; std::vector<float> vertex_data; std::vector<uint32_t> index_buf; l2p::Box bounds; // Build vertex and index buffer. for (auto ni = m->nodes.begin(), ne = m->nodes.end(); ni != ne; ++ni) { l2p::BSPNode &n = *ni; l2p::BSPSurface &s = m->surfaces[n.surface]; if (ignoreNonVisible && ignoreNode(m.get(), n, s)) continue; uint32_t vert_start = vertex_data.size() / 8; const Ogre::Vector3 uvec = ogre_cast(m->vectors[s.U]); const Ogre::Vector3 vvec = ogre_cast(m->vectors[s.V]); const Ogre::Vector3 base = ogre_cast(m->points[s.base]); int usize = 0; int vsize = 0; std::shared_ptr<l2p::UTexture> mat = s.material; if (mat) { usize = mat->USize; vsize = mat->VSize; } if (usize == 0 || vsize == 0) usize = vsize = 64; // Vertex buffer. if (n.num_verticies > 0) { l2p::Vector Normal = m->vectors[s.normal]; for (uint32_t vert_index = 0; vert_index < n.num_verticies; ++vert_index) { const l2p::Vector &pos = m->points[m->vertexes[n.vert_pool + vert_index].vertex]; const Ogre::Vector3 dist(ogre_cast(pos) - base); const Ogre::Vector2 tcoord((dist | uvec) / float(usize), (dist | vvec) / float(vsize)); bounds += pos; vertex_data.push_back(pos.X); vertex_data.push_back(pos.Y); vertex_data.push_back(pos.Z); vertex_data.push_back(Normal.X); vertex_data.push_back(Normal.Y); vertex_data.push_back(Normal.Z); vertex_data.push_back(tcoord.x); vertex_data.push_back(tcoord.y); } if (s.flags & l2p::PF_TwoSided) { for (uint32_t vert_index = 0; vert_index < n.num_verticies; ++vert_index) { const l2p::Vector &pos = m->points[m->vertexes[n.vert_pool + vert_index].vertex]; const Ogre::Vector3 dist(ogre_cast(pos) - base); const Ogre::Vector2 tcoord((dist | uvec) / float(usize), (dist | vvec) / float(vsize)); vertex_data.push_back(pos.X); vertex_data.push_back(pos.Y); vertex_data.push_back(pos.Z); vertex_data.push_back(Normal.X); vertex_data.push_back(Normal.Y); vertex_data.push_back(-Normal.Z); vertex_data.push_back(tcoord.x); vertex_data.push_back(tcoord.y); } } } // Index buffer. for (int verti = 2; verti < n.num_verticies; ++verti) { index_buf.push_back(vert_start); index_buf.push_back(vert_start + verti - 1); index_buf.push_back(vert_start + verti); } if (s.flags & l2p::PF_TwoSided) { for (int verti = 2; verti < n.num_verticies; ++verti) { index_buf.push_back(vert_start); index_buf.push_back(vert_start + verti); index_buf.push_back(vert_start + verti - 1); } } } if (vertex_data.size() == 0 || index_buf.size() == 0) return nullptr; Ogre::MeshPtr mesh = Ogre::MeshManager::getSingleton().createManual(Ogre::String(name) + Ogre::String(m->name), "General"); Ogre::VertexData *data = new Ogre::VertexData(); mesh->sharedVertexData = data; data->vertexCount = vertex_data.size() / 8; Ogre::VertexDeclaration *decl = data->vertexDeclaration; uint32_t offset = 0; decl->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_POSITION); offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3); decl->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_NORMAL); offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3); decl->addElement(0, offset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES); offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT2); Ogre::HardwareVertexBufferSharedPtr vbuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer( offset, data->vertexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY); vbuf->writeData(0, vbuf->getSizeInBytes(), &vertex_data.front(), true); data->vertexBufferBinding->setBinding(0, vbuf); // Setup index buffer. Ogre::HardwareIndexBufferSharedPtr ibuf = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer( Ogre::HardwareIndexBuffer::IT_32BIT, index_buf.size(), Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY); ibuf->writeData(0, ibuf->getSizeInBytes(), &index_buf.front(), true); Ogre::SubMesh *subMesh = mesh->createSubMesh(); subMesh->useSharedVertices = true; subMesh->indexData->indexBuffer = ibuf; subMesh->indexData->indexCount = index_buf.size(); subMesh->indexData->indexStart = 0; mesh->_setBounds(Ogre::AxisAlignedBox(bounds.min.X, bounds.min.Y, bounds.min.Z, bounds.max.X, bounds.max.Y, bounds.max.Z)); mesh->_setBoundingSphereRadius((std::max(bounds.max.X - bounds.min.X, std::max(bounds.max.Y - bounds.min.Y, bounds.max.Z - bounds.min.Z))) / 2.0); mesh->load(); Ogre::Entity *ent = mSceneMgr->createEntity(Ogre::String(name) + Ogre::String(m->name) + "E", Ogre::String(name) + Ogre::String(m->name)); ent->setUserAny(Ogre::Any(static_cast<l2p::UObject*>(m.get()))); ent->setMaterialName("StaticMesh/Default"); Ogre::SceneNode *node = mUnrealCordNode->createChildSceneNode(); node->attachObject(ent); return node; }
void BtOgreSoftBody::updateOgreMesh() { Ogre::Node *ogreNode = mEntity->getParentNode(); //printf("updateOgreMesh %d %s %s\n", internalId, mEntity->getName().c_str(), ogreNode->getName().c_str()); Ogre::MeshPtr mesh = mEntity->getMesh(); Ogre::Mesh::SubMeshIterator subMeshI = mesh->getSubMeshIterator(); Ogre::SubMesh* subMesh = NULL; Ogre::VertexData* vData = NULL; Ogre::VertexDeclaration* vDeclaration = NULL; const Ogre::VertexElement* vPosElement = NULL; bool isSharedVerticesAdded = false; unsigned short bufferIndex = 0; Ogre::HardwareVertexBufferSharedPtr vBuffer; // Can not do arithmetic operations on void* unsigned char* lockedMem = NULL; float* vPosition; btSoftBody::tNodeArray& btNodes = mSoftBody->m_nodes; //printf("Bullet nodes size %d\n", btNodes.size()); int ogreVertexIdx = 0; while (subMeshI.hasMoreElements()) { subMesh = subMeshI.getNext(); if (subMesh->useSharedVertices) { if (isSharedVerticesAdded) { continue; } vData = mesh->sharedVertexData; // We need to add shared vertices only once isSharedVerticesAdded = true; } else { vData = subMesh->vertexData; } vDeclaration = vData->vertexDeclaration; vPosElement = vDeclaration->findElementBySemantic(Ogre::VES_POSITION); bufferIndex = vPosElement->getSource(); vBuffer = vData->vertexBufferBinding->getBuffer(bufferIndex); // Lock the buffer before reading from it lockedMem = static_cast<unsigned char*>(vBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD)); // Read each vertex for (unsigned int i = 0; i < vData->vertexCount; ++i) { vPosElement->baseVertexPointerToElement(lockedMem, &vPosition); int idx = getBulletIndex(ogreVertexIdx); *vPosition++ = btNodes[idx].m_x.x(); *vPosition++ = btNodes[idx].m_x.y(); *vPosition = btNodes[idx++].m_x.z(); // Point to the next vertex lockedMem += vBuffer->getVertexSize(); ogreVertexIdx++; } vBuffer->unlock(); } btTransform transform = mSoftBody->getWorldTransform(); btQuaternion rot = transform.getRotation(); ogreNode->setOrientation(rot.w(), rot.x(), rot.y(), rot.z()); btVector3 pos = transform.getOrigin(); ogreNode->setPosition(pos.x(), pos.y(), pos.z()); }
void CSceletalAnimationView::EngineSetup(void) { Ogre::Root *Root = ((CSceletalAnimationApp*)AfxGetApp())->m_Engine->GetRoot(); Ogre::SceneManager *SceneManager = NULL; SceneManager = Root->createSceneManager(Ogre::ST_GENERIC, "Animation"); // // Create a render window // This window should be the current ChildView window using the externalWindowHandle // value pair option. // Ogre::NameValuePairList parms; parms["externalWindowHandle"] = Ogre::StringConverter::toString((long)m_hWnd); parms["vsync"] = "true"; CRect rect; GetClientRect(&rect); Ogre::RenderTarget *RenderWindow = Root->getRenderTarget("Mouse Input"); if (RenderWindow == NULL) { try { m_RenderWindow = Root->createRenderWindow("Mouse Input", rect.Width(), rect.Height(), false, &parms); } catch(...) { MessageBox("Cannot initialize\nCheck that graphic-card driver is up-to-date", "Initialize Render System", MB_OK | MB_ICONSTOP); exit(EXIT_SUCCESS); } } // Load resources Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); // Create the camera m_Camera = SceneManager->createCamera("Camera"); m_Camera->setNearClipDistance(0.5); m_Camera->setFarClipDistance(5000); m_Camera->setCastShadows(false); m_Camera->setUseRenderingDistance(true); m_Camera->setPosition(Ogre::Vector3(5.0, 5.0, 10.0)); Ogre::SceneNode *CameraNode = NULL; CameraNode = SceneManager->getRootSceneNode()->createChildSceneNode("CameraNode"); Ogre::Viewport* Viewport = NULL; if (0 == m_RenderWindow->getNumViewports()) { Viewport = m_RenderWindow->addViewport(m_Camera); Viewport->setBackgroundColour(Ogre::ColourValue(0.8f, 0.8f, 0.8f)); } // Alter the camera aspect ratio to match the viewport m_Camera->setAspectRatio(Ogre::Real(rect.Width()) / Ogre::Real(rect.Height())); m_Camera->lookAt(Ogre::Vector3(0.5, 0.5, 0.5)); m_Camera->setPolygonMode(Ogre::PolygonMode::PM_WIREFRAME); Ogre::ManualObject* ManualObject = NULL; ManualObject = SceneManager->createManualObject("Animation"); ManualObject->setDynamic(false); ManualObject->begin("BaseWhiteNoLighting", Ogre::RenderOperation::OT_TRIANGLE_LIST); //face 1 ManualObject->position(0, 0, 0);//0 ManualObject->position(1, 0, 0);//1 ManualObject->position(1, 1, 0);//2 ManualObject->triangle(0, 1, 2);//3 ManualObject->position(0, 0, 0);//4 ManualObject->position(1, 1, 0);//5 ManualObject->position(0, 1, 0);//6 ManualObject->triangle(3, 4, 5);//7 //face 2 ManualObject->position(0, 0, 1);//8 ManualObject->position(1, 0, 1);//9 ManualObject->position(1, 1, 1);//10 ManualObject->triangle(6, 7, 8);//11 ManualObject->position(0, 0, 1);//12 ManualObject->position(1, 1, 1);//13 ManualObject->position(0, 1, 1);//14 ManualObject->triangle(9, 10, 11);//15 //face 3 ManualObject->position(0, 0, 0);//16 ManualObject->position(1, 0, 0);//17 ManualObject->position(1, 0, 1);//18 ManualObject->triangle(12, 13, 14);//19 ManualObject->position(0, 0, 0); ManualObject->position(1, 0, 1); ManualObject->position(0, 1, 1); ManualObject->triangle(15, 16, 17); //face 4 ManualObject->position(1, 0, 0); ManualObject->position(1, 1, 0); ManualObject->position(1, 1, 1); ManualObject->triangle(18, 19, 20); ManualObject->position(1, 0, 0); ManualObject->position(1, 1, 1); ManualObject->position(1, 0, 1); ManualObject->triangle(21, 22, 23); //face 5 ManualObject->position(0, 1, 0); ManualObject->position(1, 1, 0); ManualObject->position(0, 1, 1); ManualObject->triangle(24, 25, 26); ManualObject->position(1, 1, 0); ManualObject->position(1, 1, 1); ManualObject->position(0, 1, 1); ManualObject->triangle(27, 28, 29); //face 6 ManualObject->position(0, 0, 0); ManualObject->position(0, 1, 1); ManualObject->position(0, 0, 1); ManualObject->triangle(30, 31, 32); ManualObject->position(0, 0, 0); ManualObject->position(0, 1, 0); ManualObject->position(0, 1, 1); ManualObject->triangle(33, 34, 35); ManualObject->end(); Ogre::MeshPtr MeshPtr = ManualObject->convertToMesh("Animation"); Ogre::SubMesh* sub = MeshPtr->getSubMesh(0); Ogre::SkeletonPtr Skeleton = Ogre::SkeletonManager::getSingleton().create("Skeleton", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); MeshPtr.getPointer()->_notifySkeleton(Skeleton); Ogre::Bone *Root1 = NULL; Ogre::Bone *Child1 = NULL; Ogre::Bone *Child2 = NULL; Root1 = Skeleton.getPointer()->createBone("Root"); Root1->setPosition(Ogre::Vector3(0.0, 0.0, 0.0)); Root1->setOrientation(Ogre::Quaternion::IDENTITY); Child1 = Root1->createChild(1); Child1->setPosition(Ogre::Vector3(4.0, 0.0, 0.0)); Child1->setOrientation(Ogre::Quaternion::IDENTITY); Child2 = Root1->createChild(2); Child2->setPosition(Ogre::Vector3(5.0, 0.0, 0.0)); Child2->setOrientation(Ogre::Quaternion::IDENTITY); Ogre::VertexBoneAssignment Assignment; Assignment.boneIndex = 0; Assignment.vertexIndex = 0; Assignment.weight = 1.0; Skeleton->setBindingPose(); sub->addBoneAssignment(Assignment); Assignment.vertexIndex = 1; sub->addBoneAssignment(Assignment); Assignment.vertexIndex = 2; sub->addBoneAssignment(Assignment); Ogre::Animation *Animation = MeshPtr->createAnimation("HandAnimation", 100.0); Ogre::NodeAnimationTrack *Track = Animation->createNodeTrack(0, Root1); Ogre::TransformKeyFrame *KeyFrame = NULL; for (float FrameTime = 0.0; FrameTime < 100.0; FrameTime += 0.1) { KeyFrame = Track->createNodeKeyFrame(FrameTime); KeyFrame->setTranslate(Ogre::Vector3(10.0, 0.0, 0.0)); } Root1->setManuallyControlled(true); Child1->setManuallyControlled(true); Child2->setManuallyControlled(true); MeshPtr->load(); MeshPtr.getPointer()->_notifySkeleton(Skeleton); // Ogre::SkeletonSerializer skeletonSerializer; // skeletonSerializer.exportSkeleton(Skeleton.get(), "C:\\Users\\Ilya\\Documents\\Visual Studio 2010\\Projects\\Recipes\\media\\models\\testskeleton.skeleton"); // Ogre::MeshSerializer ser; // ser.exportMesh(MeshPtr.get(), "C:\\Users\\Ilya\\Documents\\Visual Studio 2010\\Projects\\Recipes\\media\\models\\testskeleton.mesh"); Ogre::Entity *Entity = SceneManager->createEntity("Animation", "Animation"/*"testskeleton.mesh"*/); Ogre::SceneNode *SceneNode = SceneManager->getRootSceneNode()->createChildSceneNode(); SceneNode->attachObject(Entity); Entity->setDisplaySkeleton(true); m_AnimationState = Entity->getAnimationState("HandAnimation"); m_AnimationState->setEnabled(true); m_AnimationState->setLoop(true); m_Camera->setPolygonMode(Ogre::PolygonMode::PM_WIREFRAME); Root->renderOneFrame(); }
void PhysicsManager::getMeshInformation(Ogre::MeshPtr mesh,size_t &vertex_count,Vector3* &vertices, size_t &index_count, unsigned* &indices, const Ogre::Vector3 &position, const Ogre::Quaternion &orient,const Ogre::Vector3 &scale) { vertex_count = index_count = 0; bool added_shared = false; size_t current_offset = vertex_count; size_t shared_offset = vertex_count; size_t next_offset = vertex_count; size_t index_offset = index_count; size_t prev_vert = vertex_count; size_t prev_ind = index_count; // Calculate how many vertices and indices we're going to need for(int i = 0;i < mesh->getNumSubMeshes();i++) { SubMesh* submesh = mesh->getSubMesh(i); // We only need to add the shared vertices once if(submesh->useSharedVertices) { if(!added_shared) { VertexData* vertex_data = mesh->sharedVertexData; vertex_count += vertex_data->vertexCount; added_shared = true; } } else { VertexData* vertex_data = submesh->vertexData; vertex_count += vertex_data->vertexCount; } // Add the indices Ogre::IndexData* index_data = submesh->indexData; index_count += index_data->indexCount; } // Allocate space for the vertices and indices vertices = new Vector3[vertex_count]; indices = new unsigned[index_count]; added_shared = false; // Run through the submeshes again, adding the data into the arrays for(int i = 0;i < mesh->getNumSubMeshes();i++) { SubMesh* submesh = mesh->getSubMesh(i); Ogre::VertexData* vertex_data = submesh->useSharedVertices ? mesh->sharedVertexData : submesh->vertexData; if((!submesh->useSharedVertices)||(submesh->useSharedVertices && !added_shared)) { if(submesh->useSharedVertices) { added_shared = true; shared_offset = current_offset; } const Ogre::VertexElement* posElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION); Ogre::HardwareVertexBufferSharedPtr vbuf = vertex_data->vertexBufferBinding->getBuffer(posElem->getSource()); unsigned char* vertex = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); Ogre::Real* pReal; for(size_t j = 0; j < vertex_data->vertexCount; ++j, vertex += vbuf->getVertexSize()) { posElem->baseVertexPointerToElement(vertex, &pReal); Vector3 pt; pt.x = (*pReal++); pt.y = (*pReal++); pt.z = (*pReal++); pt = (orient * (pt * scale)) + position; vertices[current_offset + j].x = pt.x; vertices[current_offset + j].y = pt.y; vertices[current_offset + j].z = pt.z; } vbuf->unlock(); next_offset += vertex_data->vertexCount; } Ogre::IndexData* index_data = submesh->indexData; size_t numTris = index_data->indexCount / 3; unsigned short* pShort; unsigned int* pInt; Ogre::HardwareIndexBufferSharedPtr ibuf = index_data->indexBuffer; bool use32bitindexes = (ibuf->getType() == Ogre::HardwareIndexBuffer::IT_32BIT); if (use32bitindexes) pInt = static_cast<unsigned int*>(ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); else pShort = static_cast<unsigned short*>(ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); for(size_t k = 0; k < numTris; ++k) { size_t offset = (submesh->useSharedVertices)?shared_offset:current_offset; unsigned int vindex = use32bitindexes? *pInt++ : *pShort++; indices[index_offset + 0] = vindex + offset; vindex = use32bitindexes? *pInt++ : *pShort++; indices[index_offset + 1] = vindex + offset; vindex = use32bitindexes? *pInt++ : *pShort++; indices[index_offset + 2] = vindex + offset; index_offset += 3; } ibuf->unlock(); current_offset = next_offset; } }
//----------------------------------------------------------------------- void InstanceManager::unshareVertices(const Ogre::MeshPtr &mesh) { // Retrieve data to copy bone assignments const Mesh::VertexBoneAssignmentList& boneAssignments = mesh->getBoneAssignments(); Mesh::VertexBoneAssignmentList::const_iterator it = boneAssignments.begin(); Mesh::VertexBoneAssignmentList::const_iterator end = boneAssignments.end(); size_t curVertexOffset = 0; // Access shared vertices VertexData* sharedVertexData = mesh->sharedVertexData; for (size_t subMeshIdx = 0; subMeshIdx < mesh->getNumSubMeshes(); subMeshIdx++) { SubMesh *subMesh = mesh->getSubMesh(subMeshIdx); IndexData *indexData = subMesh->indexData; HardwareIndexBuffer::IndexType idxType = indexData->indexBuffer->getType(); IndicesMap indicesMap = (idxType == HardwareIndexBuffer::IT_16BIT) ? getUsedIndices<uint16>(indexData) : getUsedIndices<uint32>(indexData); VertexData *newVertexData = new VertexData(); newVertexData->vertexCount = indicesMap.size(); newVertexData->vertexDeclaration = sharedVertexData->vertexDeclaration->clone(); for (size_t bufIdx = 0; bufIdx < sharedVertexData->vertexBufferBinding->getBufferCount(); bufIdx++) { HardwareVertexBufferSharedPtr sharedVertexBuffer = sharedVertexData->vertexBufferBinding->getBuffer(bufIdx); size_t vertexSize = sharedVertexBuffer->getVertexSize(); HardwareVertexBufferSharedPtr newVertexBuffer = HardwareBufferManager::getSingleton().createVertexBuffer (vertexSize, newVertexData->vertexCount, sharedVertexBuffer->getUsage(), sharedVertexBuffer->hasShadowBuffer()); uint8 *oldLock = (uint8*)sharedVertexBuffer->lock(0, sharedVertexData->vertexCount * vertexSize, HardwareBuffer::HBL_READ_ONLY); uint8 *newLock = (uint8*)newVertexBuffer->lock(0, newVertexData->vertexCount * vertexSize, HardwareBuffer::HBL_NORMAL); IndicesMap::iterator indIt = indicesMap.begin(); IndicesMap::iterator endIndIt = indicesMap.end(); for (; indIt != endIndIt; ++indIt) { memcpy(newLock + vertexSize * indIt->second, oldLock + vertexSize * indIt->first, vertexSize); } sharedVertexBuffer->unlock(); newVertexBuffer->unlock(); newVertexData->vertexBufferBinding->setBinding(bufIdx, newVertexBuffer); } if (idxType == HardwareIndexBuffer::IT_16BIT) { copyIndexBuffer<uint16>(indexData, indicesMap); } else { copyIndexBuffer<uint32>(indexData, indicesMap); } // Store new attributes subMesh->useSharedVertices = false; subMesh->vertexData = newVertexData; // Transfer bone assignments to the submesh size_t offset = curVertexOffset + newVertexData->vertexCount; for (; it != end; ++it) { size_t vertexIdx = (*it).first; if (vertexIdx > offset) break; VertexBoneAssignment boneAssignment = (*it).second; boneAssignment.vertexIndex = static_cast<unsigned int>(boneAssignment.vertexIndex - curVertexOffset); subMesh->addBoneAssignment(boneAssignment); } curVertexOffset = newVertexData->vertexCount + 1; } // Release shared vertex data delete mesh->sharedVertexData; mesh->sharedVertexData = NULL; mesh->clearBoneAssignments(); }
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 MeshExtractor( const MeshData& mesh_data, const Ogre::String& material_name, File* file, int offset_to_data, VectorTexForGen& textures, const Ogre::MeshPtr& mesh ) { File* file12 = new File( "./data/field/5/1b/1/12/1" ); u32 offset_to_clut_tex = 4 + file12->GetU32LE( 4 + 4 ) & 0x00ffffff; LOGGER->Log( "offset_to_clut_tex = \"" + HexToString( offset_to_clut_tex, 8, '0' ) + "\".\n" ); u32 offset_to_tx_ty = offset_to_clut_tex + file12->GetU8( 4 + 7 ) * 4; LOGGER->Log( "offset_to_tx_ty = \"" + HexToString( offset_to_tx_ty, 8, '0' ) + "\".\n" ); int number_of_monochrome_textured_quads = file->GetU16LE( offset_to_data + 0x02 ); int number_of_monochrome_textured_triangles = file->GetU16LE( offset_to_data + 0x04 ); int number_of_shaded_textured_quads = file->GetU16LE( offset_to_data + 0x06 ); int number_of_shaded_textured_triangles = file->GetU16LE( offset_to_data + 0x08 ); int number_of_gradated_quads = file->GetU16LE( offset_to_data + 0x0a ); int number_of_gradated_triangles = file->GetU16LE( offset_to_data + 0x0c ); int number_of_monochrome_quads = file->GetU16LE( offset_to_data + 0x0e ); int number_of_monochrome_triangles = file->GetU16LE( offset_to_data + 0x10 ); u32 pointer_to_vertex_groups = file->GetU32LE( offset_to_data + 0x14 ); u32 pointer_to_vertex_data = file->GetU32LE( offset_to_data + 0x18 ); u32 pointer_to_mesh_data = file->GetU32LE( offset_to_data + 0x1c ); u32 pointer_to_texture_data = file->GetU32LE( offset_to_data + 0x20 ); Ogre::SubMesh* sub_mesh = mesh->createSubMesh(/* name */); sub_mesh->setMaterialName( material_name ); sub_mesh->useSharedVertices = false; sub_mesh->operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST; // Allocate and prepare vertex data sub_mesh->vertexData = new Ogre::VertexData(); sub_mesh->vertexData->vertexStart = 0; sub_mesh->vertexData->vertexCount = static_cast< size_t >( number_of_monochrome_textured_quads * 6 + number_of_monochrome_textured_triangles * 3/* + number_of_shaded_textured_quads * 6 + number_of_shaded_textured_triangles * 3 + number_of_gradated_quads * 6 + number_of_gradated_triangles * 3 + number_of_monochrome_quads * 6 + number_of_monochrome_triangles * 3*/ ); sub_mesh->indexData = new Ogre::IndexData(); sub_mesh->indexData->indexStart = 0; sub_mesh->indexData->indexCount = sub_mesh->vertexData->vertexCount; sub_mesh->indexData->indexBuffer = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer( Ogre::HardwareIndexBuffer::IT_16BIT, sub_mesh->indexData->indexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY ); u16* idata = static_cast< u16* >( sub_mesh->indexData->indexBuffer->lock( Ogre::HardwareBuffer::HBL_DISCARD ) ); u32 cur_index = 0; Ogre::VertexDeclaration* decl = sub_mesh->vertexData->vertexDeclaration; Ogre::VertexBufferBinding* bind = sub_mesh->vertexData->vertexBufferBinding; // 1st buffer decl->addElement( POSITION_BINDING, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION ); Ogre::HardwareVertexBufferSharedPtr vbuf0 = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer( decl->getVertexSize( POSITION_BINDING ), sub_mesh->vertexData->vertexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY ); bind->setBinding( POSITION_BINDING, vbuf0 ); // 2nd buffer decl->addElement( COLOUR_BINDING, 0, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE ); Ogre::HardwareVertexBufferSharedPtr vbuf1 = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer( decl->getVertexSize( COLOUR_BINDING ), sub_mesh->vertexData->vertexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY ); // Set vertex buffer binding so buffer 1 is bound to our colour buffer bind->setBinding( COLOUR_BINDING, vbuf1 ); // 3rd buffer decl->addElement( TEXTURE_BINDING, 0, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, 0 ); Ogre::HardwareVertexBufferSharedPtr vbuf2 = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer( decl->getVertexSize( TEXTURE_BINDING ), sub_mesh->vertexData->vertexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY ); bind->setBinding( TEXTURE_BINDING, vbuf2 ); float* pPos = static_cast< float* >( vbuf0->lock( Ogre::HardwareBuffer::HBL_DISCARD ) ); float* tPos = static_cast< float* >( vbuf2->lock( Ogre::HardwareBuffer::HBL_DISCARD ) ); Ogre::RenderSystem* rs = Ogre::Root::getSingleton().getRenderSystem(); std::vector<Ogre::RGBA> coloursVec(sub_mesh->vertexData->vertexCount); Ogre::RGBA* colours = coloursVec.data(); for( int i = 0; i < number_of_monochrome_textured_quads; ++i ) { int index_a = file->GetU16LE( pointer_to_mesh_data + 0x0 ); int index_b = file->GetU16LE( pointer_to_mesh_data + 0x2 ); int index_c = file->GetU16LE( pointer_to_mesh_data + 0x4 ); int index_d = file->GetU16LE( pointer_to_mesh_data + 0x6 ); Ogre::Vector3 a( ( s16 )file->GetU16LE( pointer_to_vertex_data + index_a * 0x8 + 0x0 ), ( s16 )file->GetU16LE( pointer_to_vertex_data + index_a * 0x8 + 0x2 ), ( s16 )file->GetU16LE( pointer_to_vertex_data + index_a * 0x8 + 0x4 ) ); Ogre::Vector3 b( ( s16 )file->GetU16LE( pointer_to_vertex_data + index_b * 0x8 + 0x0 ), ( s16 )file->GetU16LE( pointer_to_vertex_data + index_b * 0x8 + 0x2 ), ( s16 )file->GetU16LE( pointer_to_vertex_data + index_b * 0x8 + 0x4 ) ); Ogre::Vector3 c( ( s16 )file->GetU16LE( pointer_to_vertex_data + index_c * 0x8 + 0x0 ), ( s16 )file->GetU16LE( pointer_to_vertex_data + index_c * 0x8 + 0x2 ), ( s16 )file->GetU16LE( pointer_to_vertex_data + index_c * 0x8 + 0x4 ) ); Ogre::Vector3 d( ( s16 )file->GetU16LE( pointer_to_vertex_data + index_d * 0x8 + 0x0 ), ( s16 )file->GetU16LE( pointer_to_vertex_data + index_d * 0x8 + 0x2 ), ( s16 )file->GetU16LE( pointer_to_vertex_data + index_d * 0x8 + 0x4 ) ); a /= 512; b /= 512; c /= 512; d /= 512; int image_id = file->GetU8( pointer_to_mesh_data + 0x13 ); u16 blend = file12->GetU16LE( offset_to_clut_tex + image_id * 4 + 0 ); u16 clut = file12->GetU16LE( offset_to_clut_tex + image_id * 4 + 2 ); LOGGER->Log( "image_id = \"" + HexToString( image_id, 2, '0' ) + "\", clut = \"" + HexToString( clut, 4, '0' ) + "\", blend = \"" + HexToString( blend, 4, '0' ) + "\".\n" ); /* int clut_x = (clut & 0x003f) << 3; int clut_y = (clut & 0xffc0) >> 6; int bpp = (tpage >> 0x7) & 0x3; int vram_x = (tpage & 0xf) * 64; int vram_y = ((tpage & 0x10) >> 4) * 256; */ TexForGen texture; texture.palette_x = 128/*clut_x*/; texture.palette_y = 224/*clut_y*/; if( image_id == 1 ) { texture.texture_x = 768/*vram_x*/; } else { texture.texture_x = 832/*vram_x*/; } texture.texture_y = 256/*vram_y*/; texture.bpp = BPP_8/*bpp*/; AddTexture( texture, mesh_data, textures, LOGGER ); Ogre::Vector2 at( 0, 0 ); Ogre::Vector2 bt( 0, 0 ); Ogre::Vector2 ct( 0, 0 ); Ogre::Vector2 dt( 0, 0 ); u16 vertex1_uv = file->GetU16LE( pointer_to_mesh_data + 0x8 ); at.x = ( file->GetU8( pointer_to_texture_data + vertex1_uv * 2 + 0x0 ) + texture.start_x ) / ( float )mesh_data.tex_width; at.y = ( file->GetU8( pointer_to_texture_data + vertex1_uv * 2 + 0x1 ) + texture.start_y ) / ( float )mesh_data.tex_height; u16 vertex2_uv = file->GetU16LE( pointer_to_mesh_data + 0xa ); bt.x = ( file->GetU8( pointer_to_texture_data + vertex2_uv * 2 + 0x0 ) + texture.start_x ) / ( float )mesh_data.tex_width; bt.y = ( file->GetU8( pointer_to_texture_data + vertex2_uv * 2 + 0x1 ) + texture.start_y ) / ( float )mesh_data.tex_height; u16 vertex3_uv = file->GetU16LE( pointer_to_mesh_data + 0xc ); ct.x = ( file->GetU8( pointer_to_texture_data + vertex3_uv * 2 + 0x0 ) + texture.start_x ) / ( float )mesh_data.tex_width; ct.y = ( file->GetU8( pointer_to_texture_data + vertex3_uv * 2 + 0x1 ) + texture.start_y ) / ( float )mesh_data.tex_height; u16 vertex4_uv = file->GetU16LE( pointer_to_mesh_data + 0xe ); dt.x = ( file->GetU8( pointer_to_texture_data + vertex4_uv * 2 + 0x0 ) + texture.start_x ) / ( float )mesh_data.tex_width; dt.y = ( file->GetU8( pointer_to_texture_data + vertex4_uv * 2 + 0x1 ) + texture.start_y ) / ( float )mesh_data.tex_height; *pPos++ = a.x; *pPos++ = a.y; *pPos++ = a.z; *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z; *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z; *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z; *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z; *pPos++ = d.x; *pPos++ = d.y; *pPos++ = d.z; *tPos++ = at.x; *tPos++ = at.y; *tPos++ = ct.x; *tPos++ = ct.y; *tPos++ = bt.x; *tPos++ = bt.y; *tPos++ = bt.x; *tPos++ = bt.y; *tPos++ = ct.x; *tPos++ = ct.y; *tPos++ = dt.x; *tPos++ = dt.y; Ogre::ColourValue colour = Ogre::ColourValue( file->GetU8( pointer_to_mesh_data + 0x10 ) / 256.0f, file->GetU8( pointer_to_mesh_data + 0x11 ) / 256.0f, file->GetU8( pointer_to_mesh_data + 0x12 ) / 256.0f, 1.0f ); rs->convertColourValue( colour, colours + cur_index + 0 ); rs->convertColourValue( colour, colours + cur_index + 1 ); rs->convertColourValue( colour, colours + cur_index + 2 ); rs->convertColourValue( colour, colours + cur_index + 3 ); rs->convertColourValue( colour, colours + cur_index + 4 ); rs->convertColourValue( colour, colours + cur_index + 5 ); idata[ cur_index + 0 ] = cur_index + 0; idata[ cur_index + 1 ] = cur_index + 1; idata[ cur_index + 2 ] = cur_index + 2; idata[ cur_index + 3 ] = cur_index + 3; idata[ cur_index + 4 ] = cur_index + 4; idata[ cur_index + 5 ] = cur_index + 5; Ogre::VertexBoneAssignment vba; vba.weight = 1.0f; vba.vertexIndex = cur_index + 0; vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_a * 0x8 + 0x6 ) * 2 + 3; sub_mesh->addBoneAssignment( vba ); vba.vertexIndex = cur_index + 1; vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_c * 0x8 + 0x6 ) * 2 + 3; sub_mesh->addBoneAssignment( vba ); vba.vertexIndex = cur_index + 2; vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_b * 0x8 + 0x6 ) * 2 + 3; sub_mesh->addBoneAssignment( vba ); vba.vertexIndex = cur_index + 3; vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_b * 0x8 + 0x6 ) * 2 + 3; sub_mesh->addBoneAssignment( vba ); vba.vertexIndex = cur_index + 4; vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_c * 0x8 + 0x6 ) * 2 + 3; sub_mesh->addBoneAssignment( vba ); vba.vertexIndex = cur_index + 5; vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_d * 0x8 + 0x6 ) * 2 + 3; sub_mesh->addBoneAssignment( vba ); cur_index += 6; pointer_to_mesh_data += 0x18; } for( int i = 0; i < number_of_monochrome_textured_triangles; ++i ) { int index_a = file->GetU16LE( pointer_to_mesh_data + 0x0 ); int index_b = file->GetU16LE( pointer_to_mesh_data + 0x2 ); int index_c = file->GetU16LE( pointer_to_mesh_data + 0x4 ); Ogre::Vector3 a( ( s16 )file->GetU16LE( pointer_to_vertex_data + index_a * 0x8 + 0x0 ), ( s16 )file->GetU16LE( pointer_to_vertex_data + index_a * 0x8 + 0x2 ), ( s16 )file->GetU16LE( pointer_to_vertex_data + index_a * 0x8 + 0x4 ) ); Ogre::Vector3 b( ( s16 )file->GetU16LE( pointer_to_vertex_data + index_b * 0x8 + 0x0 ), ( s16 )file->GetU16LE( pointer_to_vertex_data + index_b * 0x8 + 0x2 ), ( s16 )file->GetU16LE( pointer_to_vertex_data + index_b * 0x8 + 0x4 ) ); Ogre::Vector3 c( ( s16 )file->GetU16LE( pointer_to_vertex_data + index_c * 0x8 + 0x0 ), ( s16 )file->GetU16LE( pointer_to_vertex_data + index_c * 0x8 + 0x2 ), ( s16 )file->GetU16LE( pointer_to_vertex_data + index_c * 0x8 + 0x4 ) ); a /= 512; b /= 512; c /= 512; int image_id = file->GetU8( pointer_to_mesh_data + 0x6 ); u16 blend = file12->GetU16LE( offset_to_clut_tex + image_id * 4 + 0 ); u16 clut = file12->GetU16LE( offset_to_clut_tex + image_id * 4 + 2 ); LOGGER->Log( "image_id = \"" + HexToString( image_id, 2, '0' ) + "\", clut = \"" + HexToString( clut, 4, '0' ) + "\", blend = \"" + HexToString( blend, 4, '0' ) + "\".\n" ); /* int clut_x = (clut & 0x003f) << 3; int clut_y = (clut & 0xffc0) >> 6; int bpp = (tpage >> 0x7) & 0x3; int vram_x = (tpage & 0xf) * 64; int vram_y = ((tpage & 0x10) >> 4) * 256; */ TexForGen texture; texture.palette_x = 128/*clut_x*/; texture.palette_y = 224/*clut_y*/; if( image_id == 1 ) { texture.texture_x = 768/*vram_x*/; } else { texture.texture_x = 832/*vram_x*/; } texture.texture_y = 256/*vram_y*/; texture.bpp = BPP_8/*bpp*/; AddTexture( texture, mesh_data, textures, LOGGER ); Ogre::Vector2 at( 0, 0 ); Ogre::Vector2 bt( 0, 0 ); Ogre::Vector2 ct( 0, 0 ); u16 vertex1_uv = file->GetU16LE( pointer_to_mesh_data + 0xc ); at.x = ( file->GetU8( pointer_to_texture_data + vertex1_uv * 2 + 0x0 ) + texture.start_x ) / ( float )mesh_data.tex_width; at.y = ( file->GetU8( pointer_to_texture_data + vertex1_uv * 2 + 0x1 ) + texture.start_y ) / ( float )mesh_data.tex_height; u16 vertex2_uv = file->GetU16LE( pointer_to_mesh_data + 0xe ); bt.x = ( file->GetU8( pointer_to_texture_data + vertex2_uv * 2 + 0x0 ) + texture.start_x ) / ( float )mesh_data.tex_width; bt.y = ( file->GetU8( pointer_to_texture_data + vertex2_uv * 2 + 0x1 ) + texture.start_y ) / ( float )mesh_data.tex_height; u16 vertex3_uv = file->GetU16LE( pointer_to_mesh_data + 0x10 ); ct.x = ( file->GetU8( pointer_to_texture_data + vertex3_uv * 2 + 0x0 ) + texture.start_x ) / ( float )mesh_data.tex_width; ct.y = ( file->GetU8( pointer_to_texture_data + vertex3_uv * 2 + 0x1 ) + texture.start_y ) / ( float )mesh_data.tex_height; *pPos++ = a.x; *pPos++ = a.y; *pPos++ = a.z; *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z; *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z; *tPos++ = at.x; *tPos++ = at.y; *tPos++ = ct.x; *tPos++ = ct.y; *tPos++ = bt.x; *tPos++ = bt.y; Ogre::ColourValue colour = Ogre::ColourValue( file->GetU8( pointer_to_mesh_data + 0x08 ) / 256.0f, file->GetU8( pointer_to_mesh_data + 0x09 ) / 256.0f, file->GetU8( pointer_to_mesh_data + 0x0a ) / 256.0f, 1.0f ); rs->convertColourValue( colour, colours + cur_index + 0 ); rs->convertColourValue( colour, colours + cur_index + 1 ); rs->convertColourValue( colour, colours + cur_index + 2 ); idata[ cur_index + 0 ] = cur_index + 0; idata[ cur_index + 1 ] = cur_index + 1; idata[ cur_index + 2 ] = cur_index + 2; Ogre::VertexBoneAssignment vba; vba.weight = 1.0f; vba.vertexIndex = cur_index + 0; vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_a * 0x8 + 0x6 ) * 2 + 3; sub_mesh->addBoneAssignment( vba ); vba.vertexIndex = cur_index + 1; vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_c * 0x8 + 0x6 ) * 2 + 3; sub_mesh->addBoneAssignment( vba ); vba.vertexIndex = cur_index + 2; vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_b * 0x8 + 0x6 ) * 2 + 3; sub_mesh->addBoneAssignment( vba ); cur_index += 3; pointer_to_mesh_data += 0x14; } vbuf0->unlock(); vbuf1->writeData( 0, vbuf1->getSizeInBytes(), colours, true ); vbuf2->unlock(); sub_mesh->indexData->indexBuffer->unlock(); // Optimize index data sub_mesh->indexData->optimiseVertexCacheTriList(); delete file12; }
void Utils::GetMeshInformation( const Ogre::MeshPtr mesh, size_t &vertexCount, Ogre::Vector3* &vertices, size_t &indexCount, unsigned* &indices) { bool addShared = false; size_t currentOffset = 0; size_t shared_offset = 0; size_t nextOffset = 0; size_t indexOffset = 0; vertexCount = indexCount = 0; for ( unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i) { Ogre::SubMesh* submesh = mesh->getSubMesh(i); if(submesh->useSharedVertices) { if( !addShared ) { vertexCount += mesh->sharedVertexData->vertexCount; addShared = true; } } else { vertexCount += submesh->vertexData->vertexCount; } indexCount += submesh->indexData->indexCount; } vertices = new Ogre::Vector3[vertexCount]; indices = new unsigned[indexCount]; addShared = false; for (unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i) { Ogre::SubMesh* submesh = mesh->getSubMesh(i); Ogre::VertexData* vertexData = submesh->useSharedVertices ? mesh->sharedVertexData : submesh->vertexData; if ((!submesh->useSharedVertices) || (submesh->useSharedVertices && !addShared)) { if(submesh->useSharedVertices) { addShared = true; shared_offset = currentOffset; } const Ogre::VertexElement* posElem = vertexData->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION); Ogre::HardwareVertexBufferSharedPtr vbuf = vertexData->vertexBufferBinding->getBuffer(posElem->getSource()); unsigned char* vertex = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); float* pReal; for( size_t j = 0; j < vertexData->vertexCount; ++j, vertex += vbuf->getVertexSize()) { posElem->baseVertexPointerToElement(vertex, &pReal); Ogre::Vector3 pt(pReal[0], pReal[1], pReal[2]); vertices[currentOffset + j] = pt; } vbuf->unlock(); nextOffset += vertexData->vertexCount; } Ogre::IndexData* indexData = submesh->indexData; size_t numTris = indexData->indexCount / 3; Ogre::HardwareIndexBufferSharedPtr ibuf = indexData->indexBuffer; bool use32bitindexes = (ibuf->getType() == Ogre::HardwareIndexBuffer::IT_32BIT); unsigned long* pLong = static_cast<unsigned long*>(ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); unsigned short* pShort = reinterpret_cast<unsigned short*>(pLong); size_t offset = (submesh->useSharedVertices)? shared_offset : currentOffset; if ( use32bitindexes ) { for ( size_t k = 0; k < numTris*3; ++k) { indices[indexOffset++] = pLong[k] + static_cast<unsigned long>(offset); } } else { for ( size_t k = 0; k < numTris*3; ++k) { indices[indexOffset++] = static_cast<unsigned long>(pShort[k]) + static_cast<unsigned long>(offset); } } ibuf->unlock(); currentOffset = nextOffset; } }
bool ModelBackgroundLoader::poll(const TimeFrame& timeFrame) { #if OGRE_THREAD_SUPPORT if (mState == LS_UNINITIALIZED) { //Start to load the meshes for (SubModelDefinitionsStore::const_iterator I_subModels = mModel.getDefinition()->getSubModelDefinitions().begin(); I_subModels != mModel.getDefinition()->getSubModelDefinitions().end(); ++I_subModels) { Ogre::MeshPtr meshPtr = static_cast<Ogre::MeshPtr> (Ogre::MeshManager::getSingleton().getByName((*I_subModels)->getMeshName())); if (meshPtr.isNull() || !meshPtr->isPrepared()) { try { Ogre::BackgroundProcessTicket ticket = Ogre::ResourceBackgroundQueue::getSingleton().prepare(Ogre::MeshManager::getSingleton().getResourceType(), (*I_subModels)->getMeshName(), Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, false, 0, 0, createListener()); if (ticket) { addTicket(ticket); } } catch (const std::exception& ex) { S_LOG_FAILURE("Could not load the mesh " << (*I_subModels)->getMeshName() << " when loading model " << mModel.getName() << "." << ex); continue; } } } mState = LS_MESH_PREPARING; return poll(timeFrame); } else if (mState == LS_MESH_PREPARING) { if (areAllTicketsProcessed()) { mState = LS_MESH_PREPARED; return poll(timeFrame); } } else if (mState == LS_MESH_PREPARED) { for (SubModelDefinitionsStore::const_iterator I_subModels = mModel.getDefinition()->getSubModelDefinitions().begin(); I_subModels != mModel.getDefinition()->getSubModelDefinitions().end(); ++I_subModels) { Ogre::MeshPtr meshPtr = static_cast<Ogre::MeshPtr> (Ogre::MeshManager::getSingleton().getByName((*I_subModels)->getMeshName())); if (!meshPtr.isNull()) { if (!meshPtr->isLoaded()) { #if OGRE_THREAD_SUPPORT == 1 Ogre::BackgroundProcessTicket ticket = Ogre::ResourceBackgroundQueue::getSingleton().load(Ogre::MeshManager::getSingleton().getResourceType(), meshPtr->getName(), Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, false, 0, 0, createListener()); if (ticket) { // meshPtr->setBackgroundLoaded(true); addTicket(ticket); } #else if (!timeFrame.isTimeLeft()) { return false; } try { meshPtr->load(); } catch (const std::exception& ex) { S_LOG_FAILURE("Could not load the mesh " << meshPtr->getName() << " when loading model " << mModel.getName() << "." << ex); continue; } #endif } } } mState = LS_MESH_LOADING; return poll(timeFrame); } else if (mState == LS_MESH_LOADING) { if (areAllTicketsProcessed()) { mState = LS_MESH_LOADED; return poll(timeFrame); } } else if (mState == LS_MESH_LOADED) { for (SubModelDefinitionsStore::const_iterator I_subModels = mModel.getDefinition()->getSubModelDefinitions().begin(); I_subModels != mModel.getDefinition()->getSubModelDefinitions().end(); ++I_subModels) { Ogre::MeshPtr meshPtr = static_cast<Ogre::MeshPtr> (Ogre::MeshManager::getSingleton().getByName((*I_subModels)->getMeshName())); if (!meshPtr.isNull()) { if (meshPtr->isLoaded()) { Ogre::Mesh::SubMeshIterator subMeshI = meshPtr->getSubMeshIterator(); while (subMeshI.hasMoreElements()) { Ogre::SubMesh* submesh(subMeshI.getNext()); Ogre::MaterialPtr materialPtr = static_cast<Ogre::MaterialPtr> (Ogre::MaterialManager::getSingleton().getByName(submesh->getMaterialName())); if (materialPtr.isNull() || !materialPtr->isPrepared()) { // S_LOG_VERBOSE("Preparing material " << materialPtr->getName()); Ogre::BackgroundProcessTicket ticket = Ogre::ResourceBackgroundQueue::getSingleton().prepare(Ogre::MaterialManager::getSingleton().getResourceType(),submesh->getMaterialName(), Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, false, 0, 0, createListener()); if (ticket) { addTicket(ticket); } } } } } for (PartDefinitionsStore::const_iterator I_parts = (*I_subModels)->getPartDefinitions().begin(); I_parts != (*I_subModels)->getPartDefinitions().end(); ++I_parts) { if ((*I_parts)->getSubEntityDefinitions().size() > 0) { for (SubEntityDefinitionsStore::const_iterator I_subEntities = (*I_parts)->getSubEntityDefinitions().begin(); I_subEntities != (*I_parts)->getSubEntityDefinitions().end(); ++I_subEntities) { const std::string& materialName = (*I_subEntities)->getMaterialName(); if (materialName != "") { Ogre::MaterialPtr materialPtr = static_cast<Ogre::MaterialPtr> (Ogre::MaterialManager::getSingleton().getByName(materialName)); if (materialPtr.isNull() || !materialPtr->isPrepared()) { // S_LOG_VERBOSE("Preparing material " << materialName); Ogre::BackgroundProcessTicket ticket = Ogre::ResourceBackgroundQueue::getSingleton().prepare(Ogre::MaterialManager::getSingleton().getResourceType(), materialName, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, false, 0, 0, createListener()); if (ticket) { addTicket(ticket); } } } } } } } mState = LS_MATERIAL_PREPARING; return poll(timeFrame); } else if (mState == LS_MATERIAL_PREPARING) { if (areAllTicketsProcessed()) { mState = LS_MATERIAL_PREPARED; return poll(timeFrame); } } else if (mState == LS_MATERIAL_PREPARED) { for (SubModelDefinitionsStore::const_iterator I_subModels = mModel.getDefinition()->getSubModelDefinitions().begin(); I_subModels != mModel.getDefinition()->getSubModelDefinitions().end(); ++I_subModels) { Ogre::MeshPtr meshPtr = static_cast<Ogre::MeshPtr> (Ogre::MeshManager::getSingleton().getByName((*I_subModels)->getMeshName())); Ogre::Mesh::SubMeshIterator subMeshI = meshPtr->getSubMeshIterator(); while (subMeshI.hasMoreElements()) { Ogre::SubMesh* submesh(subMeshI.getNext()); Ogre::MaterialPtr materialPtr = static_cast<Ogre::MaterialPtr> (Ogre::MaterialManager::getSingleton().getByName(submesh->getMaterialName())); if (!materialPtr.isNull() && !materialPtr->isLoaded()) { #if OGRE_THREAD_SUPPORT == 1 Ogre::BackgroundProcessTicket ticket = Ogre::ResourceBackgroundQueue::getSingleton().load(Ogre::MaterialManager::getSingleton().getResourceType(), materialPtr->getName(), Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, false, 0, 0, createListener()); if (ticket) { // materialPtr->setBackgroundLoaded(true); addTicket(ticket); } #else Ogre::Material::TechniqueIterator techIter = materialPtr->getSupportedTechniqueIterator(); while (techIter.hasMoreElements()) { Ogre::Technique* tech = techIter.getNext(); Ogre::Technique::PassIterator passIter = tech->getPassIterator(); while (passIter.hasMoreElements()) { Ogre::Pass* pass = passIter.getNext(); Ogre::Pass::TextureUnitStateIterator tusIter = pass->getTextureUnitStateIterator(); while (tusIter.hasMoreElements()) { Ogre::TextureUnitState* tus = tusIter.getNext(); unsigned int frames = tus->getNumFrames(); for (unsigned int i = 0; i < frames; ++i) { if (!timeFrame.isTimeLeft()) { return false; } //This will automatically load the texture. // S_LOG_VERBOSE("Loading texture " << tus->getTextureName()); Ogre::TexturePtr texturePtr = tus->_getTexturePtr(i); } } } } if (!timeFrame.isTimeLeft()) { return false; } // S_LOG_VERBOSE("Loading material " << materialPtr->getName()); materialPtr->load(); #endif } } for (PartDefinitionsStore::const_iterator I_parts = (*I_subModels)->getPartDefinitions().begin(); I_parts != (*I_subModels)->getPartDefinitions().end(); ++I_parts) { if ((*I_parts)->getSubEntityDefinitions().size() > 0) { for (SubEntityDefinitionsStore::const_iterator I_subEntities = (*I_parts)->getSubEntityDefinitions().begin(); I_subEntities != (*I_parts)->getSubEntityDefinitions().end(); ++I_subEntities) { const std::string& materialName = (*I_subEntities)->getMaterialName(); if (materialName != "") { Ogre::MaterialPtr materialPtr = static_cast<Ogre::MaterialPtr> (Ogre::MaterialManager::getSingleton().getByName(materialName)); if (!materialPtr.isNull() && !materialPtr->isLoaded()) { #if OGRE_THREAD_SUPPORT == 1 Ogre::BackgroundProcessTicket ticket = Ogre::ResourceBackgroundQueue::getSingleton().load(Ogre::MaterialManager::getSingleton().getResourceType(), materialPtr->getName(), Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, false, 0, 0, createListener()); if (ticket) { addTicket(ticket); } #else Ogre::Material::TechniqueIterator techIter = materialPtr->getSupportedTechniqueIterator(); while (techIter.hasMoreElements()) { Ogre::Technique* tech = techIter.getNext(); Ogre::Technique::PassIterator passIter = tech->getPassIterator(); while (passIter.hasMoreElements()) { Ogre::Pass* pass = passIter.getNext(); Ogre::Pass::TextureUnitStateIterator tusIter = pass->getTextureUnitStateIterator(); while (tusIter.hasMoreElements()) { Ogre::TextureUnitState* tus = tusIter.getNext(); unsigned int frames = tus->getNumFrames(); for (unsigned int i = 0; i < frames; ++i) { if (!timeFrame.isTimeLeft()) { return false; } //This will automatically load the texture. // S_LOG_VERBOSE("Loading texture " << tus->getTextureName()); Ogre::TexturePtr texturePtr = tus->_getTexturePtr(i); } } } } if (!timeFrame.isTimeLeft()) { return false; } // S_LOG_VERBOSE("Loading material " << materialPtr->getName()); materialPtr->load(); #endif } } } } } } mState = LS_MATERIAL_LOADING; return poll(timeFrame); } else if (mState == LS_MATERIAL_LOADING) { if (areAllTicketsProcessed()) { mState = LS_DONE; return true; } } else { return true; } return false; #else //If there's no threading support, just return here. return true; #endif }
void MeshExtractor( const MeshData& mesh_data, const Ogre::String& material_name, File* file, int offset_to_data, VectorTexForGen& textures, const Ogre::MeshPtr& mesh, const Ogre::String& name, int bone_id ) { int offset_to_vertex = offset_to_data; int offset_to_triangle_t = offset_to_vertex + 0x04 + file->GetU32LE( offset_to_vertex ); int number_of_triangle_t = file->GetU16LE( offset_to_triangle_t ); u16 tpage = file->GetU16LE( offset_to_triangle_t + 0x02 ); int offset_to_quad_t = offset_to_triangle_t + 0x04 + number_of_triangle_t * 0x10; int number_of_quad_t = file->GetU16LE( offset_to_quad_t ); int offset_to_triangle = offset_to_quad_t + 0x4 + number_of_quad_t * 0x14; int number_of_triangle = file->GetU16LE( offset_to_triangle ); int offset_to_quad = offset_to_triangle + 0x4 + number_of_triangle * 0x14; int number_of_quad = file->GetU16LE( offset_to_quad ); Ogre::SubMesh* sub_mesh = mesh->createSubMesh( name ); sub_mesh->setMaterialName( material_name ); sub_mesh->useSharedVertices = false; sub_mesh->operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST; // Allocate and prepare vertex data sub_mesh->vertexData = new Ogre::VertexData(); sub_mesh->vertexData->vertexStart = 0; sub_mesh->vertexData->vertexCount = static_cast< size_t >( number_of_triangle_t * 3 + number_of_quad_t * 6 + number_of_triangle * 3 + number_of_quad * 6 ); sub_mesh->indexData = new Ogre::IndexData(); sub_mesh->indexData->indexStart = 0; sub_mesh->indexData->indexCount = sub_mesh->vertexData->vertexCount; sub_mesh->indexData->indexBuffer = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer( Ogre::HardwareIndexBuffer::IT_16BIT, sub_mesh->indexData->indexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY ); u16* idata = static_cast< u16* >( sub_mesh->indexData->indexBuffer->lock( Ogre::HardwareBuffer::HBL_DISCARD ) ); u32 cur_index = 0; Ogre::VertexDeclaration* decl = sub_mesh->vertexData->vertexDeclaration; Ogre::VertexBufferBinding* bind = sub_mesh->vertexData->vertexBufferBinding; // 1st buffer decl->addElement( POSITION_BINDING, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION ); Ogre::HardwareVertexBufferSharedPtr vbuf0 = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer( decl->getVertexSize( POSITION_BINDING ), sub_mesh->vertexData->vertexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY ); bind->setBinding( POSITION_BINDING, vbuf0 ); // 2nd buffer decl->addElement( COLOUR_BINDING, 0, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE ); Ogre::HardwareVertexBufferSharedPtr vbuf1 = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer( decl->getVertexSize( COLOUR_BINDING ), sub_mesh->vertexData->vertexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY ); // Set vertex buffer binding so buffer 1 is bound to our colour buffer bind->setBinding( COLOUR_BINDING, vbuf1 ); // 3rd buffer decl->addElement( TEXTURE_BINDING, 0, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, 0 ); Ogre::HardwareVertexBufferSharedPtr vbuf2 = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer( decl->getVertexSize( TEXTURE_BINDING ), sub_mesh->vertexData->vertexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY ); bind->setBinding( TEXTURE_BINDING, vbuf2 ); float* pPos = static_cast< float* >( vbuf0->lock( Ogre::HardwareBuffer::HBL_DISCARD ) ); float* tPos = static_cast< float* >( vbuf2->lock( Ogre::HardwareBuffer::HBL_DISCARD ) ); Ogre::RenderSystem* rs = Ogre::Root::getSingleton().getRenderSystem(); Ogre::RGBA colours[ sub_mesh->vertexData->vertexCount ]; // add textured triangle for (int j = 0; j < number_of_triangle_t; ++j) { int offset_a = file->GetU16LE(offset_to_triangle_t + 0x4 + j * 0x10 + 0x0); int offset_b = file->GetU16LE(offset_to_triangle_t + 0x4 + j * 0x10 + 0x2); int offset_c = file->GetU16LE(offset_to_triangle_t + 0x4 + j * 0x10 + 0x4); Ogre::Vector3 a((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 00), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 02), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 04)); Ogre::Vector3 b((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 00), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 02), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 04)); Ogre::Vector3 c((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 00), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 02), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 04)); a /= 512; b /= 512; c /= 512; u16 clut = file->GetU16LE(offset_to_triangle_t + 0x4 + j * 0x10 + 0xa); int clut_x = (clut & 0x003f) << 3; int clut_y = (clut & 0xffc0) >> 6; int bpp = (tpage >> 0x7) & 0x3; int vram_x = (tpage & 0xf) * 64; int vram_y = ((tpage & 0x10) >> 4) * 256; TexForGen texture; texture.palette_x = clut_x; texture.palette_y = clut_y; texture.texture_x = vram_x; texture.texture_y = vram_y; texture.bpp = ( BPP )bpp; AddTexture( texture, mesh_data, textures, LOGGER ); Ogre::Vector2 at(0, 0); Ogre::Vector2 bt(0, 0); Ogre::Vector2 ct(0, 0); int x = file->GetU8(offset_to_triangle_t + 0x4 + j * 0x10 + 0x8) + texture.start_x; at.x = x / (float)mesh_data.tex_width; int y = file->GetU8(offset_to_triangle_t + 0x4 + j * 0x10 + 0x9) + texture.start_y; at.y = y / (float)mesh_data.tex_height; x = file->GetU8(offset_to_triangle_t + 0x4 + j * 0x10 + 0xc) + texture.start_x; bt.x = x / (float)mesh_data.tex_width; y = file->GetU8(offset_to_triangle_t + 0x4 + j * 0x10 + 0xd) + texture.start_y; bt.y = y / (float)mesh_data.tex_height; x = file->GetU8(offset_to_triangle_t + 0x4 + j * 0x10 + 0xe) + texture.start_x; ct.x = x / (float)mesh_data.tex_width; y = file->GetU8(offset_to_triangle_t + 0x4 + j * 0x10 + 0xf) + texture.start_y; ct.y = y / (float)mesh_data.tex_height; *pPos++ = a.x; *pPos++ = a.y; *pPos++ = a.z; *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z; *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z; *tPos++ = at.x; *tPos++ = at.y; *tPos++ = ct.x; *tPos++ = ct.y; *tPos++ = bt.x; *tPos++ = bt.y; Ogre::ColourValue colour = Ogre::ColourValue(file->GetU8(offset_to_triangle_t + 0x4 + j * 0x10 + 0x6) / 256.0f, file->GetU8(offset_to_triangle_t + 0x4 + j * 0x10 + 0x6) / 256.0f, file->GetU8(offset_to_triangle_t + 0x4 + j * 0x10 + 0x6) / 256.0f, 1.0f); rs->convertColourValue(colour, colours + cur_index + 0); rs->convertColourValue(colour, colours + cur_index + 1); rs->convertColourValue(colour, colours + cur_index + 2); idata[cur_index + 0] = cur_index + 0; idata[cur_index + 1] = cur_index + 1; idata[cur_index + 2] = cur_index + 2; cur_index += 3; } // add textured quad for (int j = 0; j < number_of_quad_t; ++j) { int offset_a = file->GetU16LE(offset_to_quad_t + 0x4 + j * 0x14 + 0x0); int offset_b = file->GetU16LE(offset_to_quad_t + 0x4 + j * 0x14 + 0x2); int offset_c = file->GetU16LE(offset_to_quad_t + 0x4 + j * 0x14 + 0x4); int offset_d = file->GetU16LE(offset_to_quad_t + 0x4 + j * 0x14 + 0x6); Ogre::Vector3 a((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 00), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 02), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 04)); Ogre::Vector3 b((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 00), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 02), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 04)); Ogre::Vector3 c((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 00), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 02), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 04)); Ogre::Vector3 d((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_d + 00), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_d + 02), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_d + 04)); a /= 512; b /= 512; c /= 512; d /= 512; u16 clut = file->GetU16LE(offset_to_quad_t + 0x4 + j * 0x14 + 0xa); int clut_x = (clut & 0x003f) << 3; int clut_y = (clut & 0xffc0) >> 6; int bpp = (tpage >> 0x7) & 0x3; int vram_x = (tpage & 0xf) * 64; int vram_y = ((tpage & 0x10) >> 4) * 256; TexForGen texture; texture.palette_x = clut_x; texture.palette_y = clut_y; texture.texture_x = vram_x; texture.texture_y = vram_y; texture.bpp = ( BPP )bpp; AddTexture( texture, mesh_data, textures, LOGGER ); Ogre::Vector2 at(0, 0); Ogre::Vector2 bt(0, 0); Ogre::Vector2 ct(0, 0); Ogre::Vector2 dt(0, 0); int x = file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0x8) + texture.start_x; at.x = x / (float)mesh_data.tex_width; int y = file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0x9) + texture.start_y; at.y = y / (float)mesh_data.tex_height; x = file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0xc) + texture.start_x; bt.x = x / (float)mesh_data.tex_width; y = file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0xd) + texture.start_y; bt.y = y / (float)mesh_data.tex_height; x = file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0xe) + texture.start_x; ct.x = x / (float)mesh_data.tex_width; y = file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0xf) + texture.start_y; ct.y = y / (float)mesh_data.tex_height; x = file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0x10) + texture.start_x; dt.x = x / (float)mesh_data.tex_width; y = file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0x11) + texture.start_y; dt.y = y / (float)mesh_data.tex_height; *pPos++ = a.x; *pPos++ = a.y; *pPos++ = a.z; *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z; *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z; *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z; *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z; *pPos++ = d.x; *pPos++ = d.y; *pPos++ = d.z; *tPos++ = at.x; *tPos++ = at.y; *tPos++ = ct.x; *tPos++ = ct.y; *tPos++ = bt.x; *tPos++ = bt.y; *tPos++ = bt.x; *tPos++ = bt.y; *tPos++ = ct.x; *tPos++ = ct.y; *tPos++ = dt.x; *tPos++ = dt.y; Ogre::ColourValue colour = Ogre::ColourValue(file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0x12) / 256.0f, file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0x12) / 256.0f, file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0x12) / 256.0f, 1.0f); rs->convertColourValue(colour, colours + cur_index + 0); rs->convertColourValue(colour, colours + cur_index + 1); rs->convertColourValue(colour, colours + cur_index + 2); rs->convertColourValue(colour, colours + cur_index + 3); rs->convertColourValue(colour, colours + cur_index + 4); rs->convertColourValue(colour, colours + cur_index + 5); idata[cur_index + 0] = cur_index + 0; idata[cur_index + 1] = cur_index + 1; idata[cur_index + 2] = cur_index + 2; idata[cur_index + 3] = cur_index + 3; idata[cur_index + 4] = cur_index + 4; idata[cur_index + 5] = cur_index + 5; cur_index += 6; } // add color triangle for (int j = 0; j < number_of_triangle; ++j) { int offset_a = file->GetU16LE(offset_to_triangle + 0x4 + j * 0x14 + 0x0); int offset_b = file->GetU16LE(offset_to_triangle + 0x4 + j * 0x14 + 0x2); int offset_c = file->GetU16LE(offset_to_triangle + 0x4 + j * 0x14 + 0x4); Ogre::Vector3 a((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 00), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 02), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 04)); Ogre::Vector3 b((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 00), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 02), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 04)); Ogre::Vector3 c((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 00), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 02), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 04)); a /= 512; b /= 512; c /= 512; TexForGen texture; texture.palette_x = 0; texture.palette_y = 0; texture.texture_x = 0; texture.texture_y = 0; texture.bpp = BPP_BLACK; AddTexture( texture, mesh_data, textures, LOGGER ); Ogre::Vector2 at(0, 0); Ogre::Vector2 bt(0, 0); Ogre::Vector2 ct(0, 0); at.x = bt.x = ct.x = texture.start_x / (float)mesh_data.tex_width; at.y = bt.y = ct.y = texture.start_y / (float)mesh_data.tex_height; *pPos++ = a.x; *pPos++ = a.y; *pPos++ = a.z; *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z; *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z; *tPos++ = at.x; *tPos++ = at.y; *tPos++ = ct.x; *tPos++ = ct.y; *tPos++ = bt.x; *tPos++ = bt.y; Ogre::ColourValue a_colour = Ogre::ColourValue(file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x08) / 256.0f, file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x09) / 256.0f, file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x0a) / 256.0f, file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x0b) / 256.0f); Ogre::ColourValue b_colour = Ogre::ColourValue(file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x0c) / 256.0f, file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x0d) / 256.0f, file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x0e) / 256.0f, file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x0f) / 256.0f); Ogre::ColourValue c_colour = Ogre::ColourValue(file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x10) / 256.0f, file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x11) / 256.0f, file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x12) / 256.0f, file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x13) / 256.0f); rs->convertColourValue(a_colour, colours + cur_index + 0); rs->convertColourValue(c_colour, colours + cur_index + 1); rs->convertColourValue(b_colour, colours + cur_index + 2); idata[cur_index + 0] = cur_index + 0; idata[cur_index + 1] = cur_index + 1; idata[cur_index + 2] = cur_index + 2; cur_index += 3; } // add color quad for (int j = 0; j < number_of_quad; ++j) { int offset_a = file->GetU16LE(offset_to_quad + 0x4 + j * 0x18 + 0x0); int offset_b = file->GetU16LE(offset_to_quad + 0x4 + j * 0x18 + 0x2); int offset_c = file->GetU16LE(offset_to_quad + 0x4 + j * 0x18 + 0x4); int offset_d = file->GetU16LE(offset_to_quad + 0x4 + j * 0x18 + 0x6); Ogre::Vector3 a((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 00), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 02), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 04)); Ogre::Vector3 b((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 00), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 02), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 04)); Ogre::Vector3 c((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 00), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 02), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 04)); Ogre::Vector3 d((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_d + 00), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_d + 02), (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_d + 04)); a /= 512; b /= 512; c /= 512; d /= 512; TexForGen texture; texture.palette_x = 0; texture.palette_y = 0; texture.texture_x = 0; texture.texture_y = 0; texture.bpp = BPP_BLACK; AddTexture( texture, mesh_data, textures, LOGGER ); Ogre::Vector2 at(0, 0); Ogre::Vector2 bt(0, 0); Ogre::Vector2 ct(0, 0); Ogre::Vector2 dt(0, 0); at.x = bt.x = ct.x = dt.x = texture.start_x / (float)mesh_data.tex_width; at.y = bt.y = ct.y = dt.y = texture.start_y / (float)mesh_data.tex_height; *pPos++ = a.x; *pPos++ = a.y; *pPos++ = a.z; *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z; *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z; *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z; *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z; *pPos++ = d.x; *pPos++ = d.y; *pPos++ = d.z; *tPos++ = at.x; *tPos++ = at.y; *tPos++ = ct.x; *tPos++ = ct.y; *tPos++ = bt.x; *tPos++ = bt.y; *tPos++ = bt.x; *tPos++ = bt.y; *tPos++ = ct.x; *tPos++ = ct.y; *tPos++ = dt.x; *tPos++ = dt.y; Ogre::ColourValue a_colour = Ogre::ColourValue(file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x08) / 256.0f, file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x09) / 256.0f, file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x0a) / 256.0f, file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x0b) / 256.0f); Ogre::ColourValue b_colour = Ogre::ColourValue(file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x0c) / 256.0f, file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x0d) / 256.0f, file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x0e) / 256.0f, file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x0f) / 256.0f); Ogre::ColourValue c_colour = Ogre::ColourValue(file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x10) / 256.0f, file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x11) / 256.0f, file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x12) / 256.0f, file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x13) / 256.0f); Ogre::ColourValue d_colour = Ogre::ColourValue(file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x14) / 256.0f, file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x15) / 256.0f, file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x16) / 256.0f, file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x17) / 256.0f); rs->convertColourValue(a_colour, colours + cur_index + 0); rs->convertColourValue(c_colour, colours + cur_index + 1); rs->convertColourValue(b_colour, colours + cur_index + 2); rs->convertColourValue(b_colour, colours + cur_index + 3); rs->convertColourValue(c_colour, colours + cur_index + 4); rs->convertColourValue(d_colour, colours + cur_index + 5); idata[cur_index + 0] = cur_index + 0; idata[cur_index + 1] = cur_index + 1; idata[cur_index + 2] = cur_index + 2; idata[cur_index + 3] = cur_index + 3; idata[cur_index + 4] = cur_index + 4; idata[cur_index + 5] = cur_index + 5; cur_index += 6; } vbuf0->unlock(); vbuf1->writeData(0, vbuf1->getSizeInBytes(), colours, true); vbuf2->unlock(); sub_mesh->indexData->indexBuffer->unlock(); // Optimize index data sub_mesh->indexData->optimiseVertexCacheTriList(); if (bone_id != -1) { LOGGER->Log("Assign bones to vertexes\n"); int vertex_number = sub_mesh->vertexData->vertexCount; for( int i = 0; i < vertex_number; ++i ) { Ogre::VertexBoneAssignment vba; vba.vertexIndex = i; vba.boneIndex = bone_id; vba.weight = 1.0f; sub_mesh->addBoneAssignment( vba ); } } }
// =============================================================================== // We updated a mesh. Now we have to find all the scene nodes that use this mesh // and tell them something changed. void OLMeshTracker::UpdateSceneNodesForMesh(Ogre::String meshName) { Ogre::MeshPtr meshP = (Ogre::MeshPtr)Ogre::MeshManager::getSingleton().getByName(meshName); if (!meshP.isNull()) { UpdateSceneNodesForMesh(meshP); } }
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(); }
// Write submesh data to an Ogre compatible mesh bool Submesh::createOgreSubmesh(Ogre::MeshPtr pMesh,const ParamList& params) { size_t i,j; bool stat; // Create a new submesh Ogre::SubMesh* pSubmesh; if (m_name != "") pSubmesh = pMesh->createSubMesh(m_name.c_str()); else pSubmesh = pMesh->createSubMesh(); // Set material pSubmesh->setMaterialName(m_pMaterial->name().c_str()); // Set use shared geometry flag pSubmesh->useSharedVertices = params.useSharedGeom; // Create vertex data for current submesh pSubmesh->vertexData = new Ogre::VertexData(); // Set number of indexes pSubmesh->indexData->indexCount = 3*m_faces.size(); pSubmesh->vertexData->vertexCount = m_vertices.size(); // Check if we need to use 32 bit indexes bool use32BitIndexes = false; if (m_vertices.size() > 65536 || params.useSharedGeom) { use32BitIndexes = true; } // Create a new index buffer pSubmesh->indexData->indexBuffer = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer( use32BitIndexes ? Ogre::HardwareIndexBuffer::IT_32BIT : Ogre::HardwareIndexBuffer::IT_16BIT, pSubmesh->indexData->indexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY); // Fill the index buffer with faces data if (use32BitIndexes) { Ogre::uint32* pIdx = static_cast<Ogre::uint32*>( pSubmesh->indexData->indexBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD)); for (i=0; i<m_faces.size(); i++) { *pIdx++ = static_cast<Ogre::uint32>(m_faces[i].v[0]); *pIdx++ = static_cast<Ogre::uint32>(m_faces[i].v[1]); *pIdx++ = static_cast<Ogre::uint32>(m_faces[i].v[2]); } pSubmesh->indexData->indexBuffer->unlock(); } else { Ogre::uint16* pIdx = static_cast<Ogre::uint16*>( pSubmesh->indexData->indexBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD)); for (i=0; i<m_faces.size(); i++) { *pIdx++ = static_cast<Ogre::uint16>(m_faces[i].v[0]); *pIdx++ = static_cast<Ogre::uint16>(m_faces[i].v[1]); *pIdx++ = static_cast<Ogre::uint16>(m_faces[i].v[2]); } pSubmesh->indexData->indexBuffer->unlock(); } // Define vertex declaration (only if we're not using shared geometry) if(!params.useSharedGeom) { Ogre::VertexDeclaration* pDecl = pSubmesh->vertexData->vertexDeclaration; unsigned buf = 0; size_t offset = 0; // Add vertex position pDecl->addElement(buf, offset, Ogre::VET_FLOAT3, Ogre::VES_POSITION); offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3); // Add vertex normal if (params.exportVertNorm) { pDecl->addElement(buf, offset, Ogre::VET_FLOAT3, Ogre::VES_NORMAL); offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3); } // Add vertex colour if(params.exportVertCol) { pDecl->addElement(buf, offset, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE); offset += Ogre::VertexElement::getTypeSize(Ogre::VET_COLOUR); } // Add texture coordinates for (i=0; i<m_vertices[0].texcoords.size(); i++) { Ogre::VertexElementType uvType = Ogre::VertexElement::multiplyTypeCount(Ogre::VET_FLOAT1, 2); pDecl->addElement(buf, offset, uvType, Ogre::VES_TEXTURE_COORDINATES, static_cast<unsigned short>(i)); offset += Ogre::VertexElement::getTypeSize(uvType); } Ogre::VertexDeclaration* pOptimalDecl = pDecl->getAutoOrganisedDeclaration( params.exportVBA, params.exportBlendShapes || params.exportVertAnims, false); // Fill the vertex buffer using the newly created vertex declaration stat = createOgreVertexBuffer(pSubmesh,pDecl,m_vertices); // Write vertex bone assignements list if (params.exportVBA) { // Create a new vertex bone assignements list Ogre::SubMesh::VertexBoneAssignmentList vbas; // Scan list of shared geometry vertices for (i=0; i<m_vertices.size(); i++) { vertex v = m_vertices[i]; // Add all bone assignemnts for every vertex to the bone assignements list for (j=0; j<v.vbas.size(); j++) { Ogre::VertexBoneAssignment vba; vba.vertexIndex = static_cast<unsigned int>(i); vba.boneIndex = v.vbas[j].jointIdx; vba.weight = v.vbas[j].weight; vbas.insert(Ogre::SubMesh::VertexBoneAssignmentList::value_type(i, vba)); } } // Rationalise the bone assignements list pSubmesh->parent->_rationaliseBoneAssignments(pSubmesh->vertexData->vertexCount,vbas); // Add bone assignements to the submesh for (Ogre::SubMesh::VertexBoneAssignmentList::iterator bi = vbas.begin(); bi != vbas.end(); bi++) { pSubmesh->addBoneAssignment(bi->second); } pSubmesh->_compileBoneAssignments(); } pSubmesh->vertexData->reorganiseBuffers(pOptimalDecl); } return true; }