//----------------------------------------------------------------------- void EntityRenderer::_prepare(ParticleTechnique* technique) { /** - This renderer is a ´hacky´ solution to display geometry-based particles. It pre-creates a number of SceneNodes (childs of the parent Node to which the ParticleSystem is attached) and Entities and uses these pools to display the particles. There are better solutions, but this one is simple and fast enough, although it has some drawbacks. - Future solutions should rather make use of hardware instancing to display a large number of geometry-based particles at once. */ // Use the given technique, although it should be the same as mParentTechnique (must be set already) if (!technique || mRendererInitialised) return; std::stringstream ss; ss << this; mEntityName = mMeshName + ss.str(); mQuota = technique->getVisualParticleQuota(); Ogre::SceneNode* parentNode = technique->getParentSystem()->getParentSceneNode(); Ogre::MeshPtr mesh = Ogre::MeshManager::getSingleton().load(mMeshName, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); Ogre::Mesh* meshPointer = mesh.getPointer(); Vector3 size = meshPointer->getBounds().getSize(); mBoxWidth = size.x == 0.0f ? 1.0f : size.x; mBoxHeight = size.y == 0.0f ? 1.0f : size.y; mBoxDepth = size.z == 0.0f ? 1.0f : size.z; if (parentNode) { // Create number of VisualData objects including SceneNodes String sceneNodeName; for (size_t i = 0; i < mQuota; i++) { sceneNodeName = "ParticleUniverse" + ss.str() + StringConverter::toString(i); EntityRendererVisualData* visualData = PU_NEW_T(EntityRendererVisualData, MEMCATEGORY_SCENE_OBJECTS)(parentNode->createChildSceneNode(sceneNodeName)); mAllVisualData.push_back(visualData); // Managed by this renderer mVisualData.push_back(visualData); // Used to assign to a particle } // Create number of Entities Ogre::Entity* entity = technique->getParentSystem()->getSceneManager()->createEntity(mEntityName, mMeshName); // Base entity vector<EntityRendererVisualData*>::const_iterator it; vector<EntityRendererVisualData*>::const_iterator itEnd = mAllVisualData.end(); size_t j; for (it = mAllVisualData.begin(), j = 0; it != itEnd; ++it, ++j) { Ogre::Entity* clonedEntity = entity->clone(mEntityName + StringConverter::toString(j)); clonedEntity->setMaterialName(technique->getMaterialName()); clonedEntity->setRenderQueueGroup(mQueueId); mEntities.push_back(clonedEntity); (*it)->node->attachObject(clonedEntity); } technique->getParentSystem()->getSceneManager()->destroyEntity(mEntityName); } _makeNodesVisible(false); mRendererInitialised = true; }
void GraphicsResourceMesh::setMaterialNames(GraphicsResourceMesh* resourcePtr) { Ogre::ResourcePtr meshResource = Ogre::MeshManager::getSingleton().getByName(resourcePtr->getID()); Ogre::Mesh* meshPtr = static_cast<Ogre::Mesh *>(&*meshResource); Ogre::Mesh::SubMeshIterator currSubMeshIter = meshPtr->getSubMeshIterator(); while (currSubMeshIter.hasMoreElements()) { Ogre::SubMesh *curSubMesh = currSubMeshIter.getNext(); if (!OPTION_ENABLE_TEXTURES->as<bool>()) { curSubMesh->setMaterialName("BaseWhiteTexture"); } else { const Ogre::String& curMatName = curSubMesh->getMaterialName(); int pos = curMatName.find_last_of(':'); if (pos != -1) { String start = curMatName.substr(0, pos); String ending = curMatName.substr(pos); std::map<String, String>::iterator itr = resourcePtr->mMaterialNames.find(start); if (itr != resourcePtr->mMaterialNames.end()) curSubMesh->setMaterialName(itr->second + ending); } } } }
void NIFMeshLoader::loadResource(Ogre::Resource *resource) { Ogre::Mesh *mesh = dynamic_cast<Ogre::Mesh*>(resource); OgreAssert(mesh, "Attempting to load a mesh into a non-mesh resource!"); Nif::NIFFile::ptr nif = Nif::NIFFile::create(mName); if(mShapeIndex >= nif->numRecords()) { Ogre::SkeletonManager *skelMgr = Ogre::SkeletonManager::getSingletonPtr(); if(!skelMgr->getByName(mName).isNull()) mesh->setSkeletonName(mName); return; } const Nif::Record *record = nif->getRecord(mShapeIndex); createSubMesh(mesh, dynamic_cast<const Nif::NiTriShape*>(record)); }
bool EC_Mesh::SetAttachmentMesh(uint index, const std::string& mesh_name, const std::string& attach_point, bool share_skeleton) { if (!ViewEnabled()) return false; OgreWorldPtr world = world_.lock(); if (!entity_) { LogError("EC_Mesh::SetAttachmentMesh: No mesh entity created yet, can not create attachments!"); return false; } Ogre::SceneManager* sceneMgr = world->OgreSceneManager(); size_t oldsize = attachment_entities_.size(); size_t newsize = index + 1; if (oldsize < newsize) { attachment_entities_.resize(newsize); attachment_nodes_.resize(newsize); for(uint i = oldsize; i < newsize; ++i) { attachment_entities_[i] = 0; attachment_nodes_[i] = 0; } } RemoveAttachmentMesh(index); Ogre::Mesh* mesh = PrepareMesh(mesh_name, false); if (!mesh) return false; if (share_skeleton) { // If sharing a skeleton, force the attachment mesh to use the same skeleton // This is theoretically quite a scary operation, for there is possibility for things to go wrong Ogre::SkeletonPtr entity_skel = entity_->getMesh()->getSkeleton(); if (entity_skel.isNull()) { LogError("EC_Mesh::SetAttachmentMesh: Cannot share skeleton for attachment, not found"); return false; } try { mesh->_notifySkeleton(entity_skel); } catch(const Ogre::Exception &/*e*/) { LogError("EC_Mesh::SetAttachmentMesh: Could not set shared skeleton for attachment"); return false; } } try { QString entityName = QString("EC_Mesh_attach") + QString::number(index); attachment_entities_[index] = sceneMgr->createEntity(world->GetUniqueObjectName(entityName.toStdString()), mesh->getName()); if (!attachment_entities_[index]) { LogError("EC_Mesh::SetAttachmentMesh: Could not set attachment mesh " + mesh_name); return false; } attachment_entities_[index]->setRenderingDistance(drawDistance.Get()); attachment_entities_[index]->setCastShadows(castShadows.Get()); attachment_entities_[index]->setUserAny(entity_->getUserAny()); // Set UserAny also on subentities for(uint i = 0; i < attachment_entities_[index]->getNumSubEntities(); ++i) attachment_entities_[index]->getSubEntity(i)->setUserAny(entity_->getUserAny()); Ogre::Bone* attach_bone = 0; if (!attach_point.empty()) { Ogre::Skeleton* skel = entity_->getSkeleton(); if (skel && skel->hasBone(attach_point)) attach_bone = skel->getBone(attach_point); } if (attach_bone) { Ogre::TagPoint* tag = entity_->attachObjectToBone(attach_point, attachment_entities_[index]); attachment_nodes_[index] = tag; } else { QString nodeName = QString("EC_Mesh_attachment_") + QString::number(index); Ogre::SceneNode* node = sceneMgr->createSceneNode(world->GetUniqueObjectName(nodeName.toStdString())); node->attachObject(attachment_entities_[index]); adjustment_node_->addChild(node); attachment_nodes_[index] = node; } if (share_skeleton && entity_->hasSkeleton() && attachment_entities_[index]->hasSkeleton()) { attachment_entities_[index]->shareSkeletonInstanceWith(entity_); } } catch(Ogre::Exception& e) { LogError("EC_Mesh::SetAttachmentMesh: Could not set attachment mesh " + mesh_name + ": " + std::string(e.what())); return false; } return true; }
bool EC_Mesh::SetMeshWithSkeleton(const std::string& mesh_name, const std::string& skeleton_name, bool clone) { if (!ViewEnabled()) return false; OgreWorldPtr world = world_.lock(); Ogre::SkeletonPtr skel = Ogre::SkeletonManager::getSingleton().getByName(AssetAPI::SanitateAssetRef(skeleton_name)); if (skel.isNull()) { LogError("EC_Mesh::SetMeshWithSkeleton: Could not set skeleton " + skeleton_name + " to mesh " + mesh_name + ": not found"); return false; } RemoveMesh(); Ogre::SceneManager* sceneMgr = world->OgreSceneManager(); Ogre::Mesh* mesh = PrepareMesh(mesh_name, clone); if (!mesh) return false; try { mesh->_notifySkeleton(skel); // LogDebug("Set skeleton " + skeleton_name + " to mesh " + mesh_name); } catch(Ogre::Exception& e) { LogError("EC_Mesh::SetMeshWithSkeleton: Could not set skeleton " + skeleton_name + " to mesh " + mesh_name + ": " + std::string(e.what())); return false; } try { entity_ = sceneMgr->createEntity(world->GetUniqueObjectName("EC_Mesh_entwithskel"), mesh->getName()); if (!entity_) { LogError("EC_Mesh::SetMeshWithSkeleton: Could not set mesh " + mesh_name); return false; } entity_->setRenderingDistance(drawDistance.Get()); entity_->setCastShadows(castShadows.Get()); entity_->setUserAny(Ogre::Any(static_cast<IComponent *>(this))); // Set UserAny also on subentities for(uint i = 0; i < entity_->getNumSubEntities(); ++i) entity_->getSubEntity(i)->setUserAny(entity_->getUserAny()); if (entity_->hasSkeleton()) { Ogre::SkeletonInstance* skel = entity_->getSkeleton(); // Enable cumulative mode on skeletal animations if (skel) skel->setBlendMode(Ogre::ANIMBLEND_CUMULATIVE); } } catch(Ogre::Exception& e) { LogError("EC_Mesh::SetMeshWithSkeleton: Could not set mesh " + mesh_name + ": " + std::string(e.what())); return false; } AttachEntity(); emit MeshChanged(); return true; }
bool EC_Mesh::SetMesh(QString meshResourceName, bool clone) { if (!ViewEnabled()) return false; OgreWorldPtr world = world_.lock(); std::string mesh_name = meshResourceName.trimmed().toStdString(); RemoveMesh(); // If placeable is not set yet, set it manually by searching it from the parent entity if (!placeable_) { Entity* entity = ParentEntity(); if (entity) { ComponentPtr placeable = entity->GetComponent(EC_Placeable::TypeNameStatic()); if (placeable) placeable_ = placeable; } } Ogre::SceneManager* sceneMgr = world->OgreSceneManager(); Ogre::Mesh* mesh = PrepareMesh(mesh_name, clone); if (!mesh) return false; try { entity_ = sceneMgr->createEntity(world->GetUniqueObjectName("EC_Mesh_entity"), mesh->getName()); if (!entity_) { LogError("EC_Mesh::SetMesh: Could not set mesh " + mesh_name); return false; } entity_->setRenderingDistance(drawDistance.Get()); entity_->setCastShadows(castShadows.Get()); entity_->setUserAny(Ogre::Any(static_cast<IComponent *>(this))); // Set UserAny also on subentities for(uint i = 0; i < entity_->getNumSubEntities(); ++i) entity_->getSubEntity(i)->setUserAny(entity_->getUserAny()); if (entity_->hasSkeleton()) { Ogre::SkeletonInstance* skel = entity_->getSkeleton(); // Enable cumulative mode on skeletal animations if (skel) skel->setBlendMode(Ogre::ANIMBLEND_CUMULATIVE); } // Make sure adjustment node is uptodate Transform newTransform = nodeTransformation.Get(); adjustment_node_->setPosition(newTransform.pos); adjustment_node_->setOrientation(newTransform.Orientation()); // Prevent Ogre exception from zero scale adjustment_node_->setScale(Max(newTransform.scale, float3::FromScalar(0.0000001f))); // Force a re-apply of all materials to this new mesh. ApplyMaterial(); } catch(Ogre::Exception& e) { LogError("EC_Mesh::SetMesh: Could not set mesh " + mesh_name + ": " + std::string(e.what())); return false; } AttachEntity(); emit MeshChanged(); return true; }
Mesh* OgreSubsystem::createMesh(const MeshData& data,String name) { String nombre = name; if(name=="AUTO_NAME_ME") { nombre = "OryxSceneNodeAutoNamed"+StringUtils::toString(mAutoNameIndex); ++mAutoNameIndex; } using namespace Ogre; bool hasVertexColor = data.getDiffuse(); bool hasNormals = data.getNormals(); int numFaces = data.indices.size()/3; int numVertices = data.vertices.size()/3; HardwareVertexBufferSharedPtr posVertexBuffer; HardwareVertexBufferSharedPtr normVertexBuffer; std::vector<HardwareVertexBufferSharedPtr> texcoordsVertexBuffer; HardwareVertexBufferSharedPtr diffuseVertexBuffer; HardwareIndexBufferSharedPtr indexBuffer; Ogre::Mesh* m = Ogre::MeshManager::getSingletonPtr()->createManual( nombre,ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME).get(); Ogre::SubMesh* sm = m->createSubMesh(); sm->useSharedVertices = false; sm->vertexData = new VertexData(); sm->vertexData->vertexStart = 0; sm->vertexData->vertexCount = numVertices; Ogre::VertexDeclaration* vdecl = sm->vertexData->vertexDeclaration; Ogre::VertexBufferBinding* vbind = sm->vertexData->vertexBufferBinding; size_t bufferCount = 0; vdecl->addElement(bufferCount, 0, VET_FLOAT3, VES_POSITION); if(hasNormals) vdecl->addElement(++bufferCount, 0, VET_FLOAT3, VES_NORMAL); if(hasVertexColor) vdecl->addElement(++bufferCount, 0, VET_FLOAT4, VES_DIFFUSE); for(int i=0;i<data.texcoords.size();++i) vdecl->addElement(++bufferCount, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES,i); bufferCount = 0; // Positions posVertexBuffer = HardwareBufferManager::getSingleton().createVertexBuffer( 3*sizeof(float),numVertices,Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE); vbind->setBinding(bufferCount, posVertexBuffer); float* vertices = data.getVertices(); float* normals = data.getNormals(); float* diffuse = data.getDiffuse(); unsigned short* indices = data.getIndices(); posVertexBuffer->writeData(0,posVertexBuffer->getSizeInBytes(),vertices, true); // Normals if(hasNormals) { normVertexBuffer = HardwareBufferManager::getSingleton().createVertexBuffer( 3*sizeof(float),numVertices,HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE); vbind->setBinding(++bufferCount, normVertexBuffer); normVertexBuffer->writeData(0,normVertexBuffer->getSizeInBytes(),normals, true); } if(hasVertexColor) { diffuseVertexBuffer = HardwareBufferManager::getSingleton().createVertexBuffer( 4*sizeof(float),numVertices,HardwareBuffer::HBU_STATIC_WRITE_ONLY); vbind->setBinding(++bufferCount, diffuseVertexBuffer); diffuseVertexBuffer->writeData(0,diffuseVertexBuffer->getSizeInBytes(), diffuse, true); } // Texcoords for(int i=0;i<data.texcoords.size();++i) { texcoordsVertexBuffer.push_back(HardwareBufferManager::getSingleton().createVertexBuffer( 2*sizeof(float),numVertices,HardwareBuffer::HBU_STATIC_WRITE_ONLY)); vbind->setBinding(++bufferCount, texcoordsVertexBuffer[i]); texcoordsVertexBuffer[i]->writeData(0,sizeof(float)*data.texcoords[i].size(),&data.texcoords[i][0], false); } if(!data.indices.empty()) { // Prepare buffer for indices indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer( HardwareIndexBuffer::IT_16BIT,3*numFaces,HardwareBuffer::HBU_STATIC_WRITE_ONLY, true); //unsigned short *faceVertexIndices = (unsigned short*) //indexBuffer->lock(0, numFaces*3*2, HardwareBuffer::HBL_DISCARD); // Set index buffer for this submesh sm->indexData->indexBuffer = indexBuffer; sm->indexData->indexStart = 0; sm->indexData->indexCount = 3*numFaces; indexBuffer->writeData(0,indexBuffer->getSizeInBytes(),indices,true); } //vdecl->sort(); m->load(); m->touch(); m->_setBounds(AxisAlignedBox(data.bbox[0],data.bbox[1],data.bbox[2], data.bbox[3],data.bbox[4],data.bbox[5]), false); sm->setMaterialName("Terrain"); Ogre::Entity* ent = mSceneManager->createEntity(nombre,m->getName()); Ogre::SceneNode* node = mSceneManager->createSceneNode(nombre); node->attachObject(ent); ent->setCastShadows(false); Mesh* mm = new Mesh(nombre,node,ent); mSceneNodes.push_back(mm); return mm; }
bool MaterialVertexBuffer::setSubMeshColors( EntityMaterial* entity, unsigned short mesh_index, size_t ui32VertexColorCount, const float* pVertexColorArray) const { if(entity->getOgreEntity() == NULL) { m_rKernelContext.getLogManager() << LogLevel_Error << "Can't set colors : no Entity found!\n"; return false; } Ogre::Mesh* mesh = entity->getOgreEntity()->getMesh().get(); if(mesh == NULL || mesh_index >= mesh->getNumSubMeshes()) { m_rKernelContext.getLogManager() << LogLevel_Error << "Can't set colors : no Mesh found!\n"; return false; } Ogre::SubMesh* submesh = mesh->getSubMesh( mesh_index ); if(submesh->useSharedVertices) { m_rKernelContext.getLogManager() << LogLevel_Error << "Can't set colors : vertices are shared and thus not accessible from SubMesh!\n"; return false; } else { if(ui32VertexColorCount != submesh->vertexData->vertexCount) { m_rKernelContext.getLogManager() << LogLevel_Error << "Can't set colors : vertex count mismatch!\n"; return false; } //get pointer to submesh vertex data Ogre::VertexData* vertex_data = submesh->vertexData; //get pointer to DIFFUSE element const Ogre::VertexElement* difElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_DIFFUSE); if(difElem == NULL) { m_rKernelContext.getLogManager() << LogLevel_Error << "Can't set colors : no colours_diffuse element found in vertex buffer!\n"; return false; } //convert color to current RenderSystem's format Ogre::VertexElementType type = difElem->getType(); //retrieve VB for DIFFUSE element Ogre::HardwareVertexBufferSharedPtr vbuf = vertex_data->vertexBufferBinding->getBuffer(difElem->getSource()); //lock VB for reading unsigned char* color = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_NORMAL)); // 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; Ogre::RGBA* pRGBA; Ogre::ColourValue colour; for( size_t j = 0; j < vertex_data->vertexCount; ++j, color += vbuf->getVertexSize()) { //get pointer to RGBA DIFFUSE data difElem->baseVertexPointerToElement(color, &pRGBA); colour.r = pVertexColorArray[4*j]; colour.g = pVertexColorArray[4*j+1]; colour.b = pVertexColorArray[4*j+2]; colour.a = pVertexColorArray[4*j+3]; //convert color from RGBA floats to a single ARGB uint32 if(type == Ogre::VET_COLOUR_ARGB) //D3D format { *pRGBA = colour.getAsARGB(); } else /*if type == OGRE::VET_COLOUR_ABGR)*/ //GL format { *pRGBA = colour.getAsABGR(); } } //unlock VB vbuf->unlock(); } return true; }
bool EC_Mesh::SetMesh(QString meshResourceName, bool clone) { if (!ViewEnabled()) return false; if (renderer_.expired()) return false; RendererPtr renderer = renderer_.lock(); std::string mesh_name = meshResourceName.trimmed().toStdString(); RemoveMesh(); // If placeable is not set yet, set it manually by searching it from the parent entity if (!placeable_) { Scene::Entity* entity = GetParentEntity(); if (entity) { ComponentPtr placeable = entity->GetComponent(EC_Placeable::TypeNameStatic()); if (placeable) placeable_ = placeable; } } Ogre::SceneManager* scene_mgr = renderer->GetSceneManager(); Ogre::Mesh* mesh = PrepareMesh(mesh_name, clone); if (!mesh) return false; try { entity_ = scene_mgr->createEntity(renderer->GetUniqueObjectName("EC_Mesh_entity"), mesh->getName()); if (!entity_) { LogError("Could not set mesh " + mesh_name); return false; } entity_->setRenderingDistance(drawDistance.Get()); entity_->setCastShadows(castShadows.Get()); entity_->setUserAny(Ogre::Any(GetParentEntity())); // Set UserAny also on subentities for (uint i = 0; i < entity_->getNumSubEntities(); ++i) entity_->getSubEntity(i)->setUserAny(entity_->getUserAny()); if (entity_->hasSkeleton()) { Ogre::SkeletonInstance* skel = entity_->getSkeleton(); // Enable cumulative mode on skeletal animations if (skel) skel->setBlendMode(Ogre::ANIMBLEND_CUMULATIVE); } // Make sure adjustment node is uptodate if (adjustment_node_) { Transform newTransform = nodeTransformation.Get(); adjustment_node_->setPosition(newTransform.position.x, newTransform.position.y, newTransform.position.z); Quaternion adjust(DEGTORAD * newTransform.rotation.x, DEGTORAD * newTransform.rotation.y, DEGTORAD * newTransform.rotation.z); adjustment_node_->setOrientation(Ogre::Quaternion(adjust.w, adjust.x, adjust.y, adjust.z)); // Prevent Ogre exception from zero scale if (newTransform.scale.x < 0.0000001f) newTransform.scale.x = 0.0000001f; if (newTransform.scale.y < 0.0000001f) newTransform.scale.y = 0.0000001f; if (newTransform.scale.z < 0.0000001f) newTransform.scale.z = 0.0000001f; adjustment_node_->setScale(newTransform.scale.x, newTransform.scale.y, newTransform.scale.z); } // Force a re-apply of all materials to this new mesh. ApplyMaterial(); } catch (Ogre::Exception& e) { LogError("Could not set mesh " + mesh_name + ": " + std::string(e.what())); return false; } AttachEntity(); emit MeshChanged(); return true; }