// unload all about this mesh. The mesh itself and the textures. // BETWEEN FRAME OPERATION void VisCalcFrustDist::unloadTheMesh(Ogre::MeshPtr meshP) { if (m_shouldCullTextures) { Ogre::Mesh::SubMeshIterator smi = meshP->getSubMeshIterator(); while (smi.hasMoreElements()) { Ogre::SubMesh* oneSubMesh = smi.getNext(); Ogre::String subMeshMaterialName = oneSubMesh->getMaterialName(); Ogre::MaterialPtr subMeshMaterial = (Ogre::MaterialPtr)Ogre::MaterialManager::getSingleton().getByName(subMeshMaterialName); if (!subMeshMaterial.isNull()) { Ogre::Material::TechniqueIterator techIter = subMeshMaterial->getTechniqueIterator(); while (techIter.hasMoreElements()) { Ogre::Technique* oneTech = techIter.getNext(); Ogre::Technique::PassIterator passIter = oneTech->getPassIterator(); while (passIter.hasMoreElements()) { Ogre::Pass* onePass = passIter.getNext(); Ogre::Pass::TextureUnitStateIterator tusIter = onePass->getTextureUnitStateIterator(); while (tusIter.hasMoreElements()) { Ogre::TextureUnitState* oneTus = tusIter.getNext(); Ogre::String texName = oneTus->getTextureName(); Ogre::TexturePtr texP = (Ogre::TexturePtr)Ogre::TextureManager::getSingleton().getByName(texName); if (!texP.isNull()) { // if (texP.useCount() <= 1) { texP->unload(); LG::IncStat(LG::StatCullTexturesUnloaded); // LG::Log("unloadTheMesh: unloading texture %s", texName.c_str()); // } } } } } } } } if (m_shouldCullMeshes) { LG::OLMeshTracker::Instance()->MakeUnLoaded(meshP->getName(), Ogre::String(), NULL); LG::IncStat(LG::StatCullMeshesUnloaded); // LG::Log("unloadTheMesh: unloading mesh %s", mshName.c_str()); } }
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 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; } }
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 }