bool operator()() { Ogre::SceneManager* sm = GraphicsManager::get().sceneManager(); Ogre::Entity* entity = sm->createEntity( Ogre::StringConverter::toString(component->localId()), fileName); Ogre::StaticGeometry* sg = sm->createStaticGeometry( Ogre::StringConverter::toString(component->localId())); sg->addEntity( entity, positionComponent->sceneNode()->getPosition() + offset, positionComponent->sceneNode()->getOrientation() * offsetRotation); sg->build(); component->m_entity = entity; component->m_staticGeometry = sg; ThreadPool::get().schedule(boost::bind( &ComponentContainer::componentAttachedCallback, component->parent(), component)); return true; }
void CubeWorld::displaySimpleWorld (void) { Ogre::MaterialPtr mat = Ogre::MaterialManager::getSingleton().create("BoxColor", "General", true ); Ogre::Technique* tech = mat->getTechnique(0); Ogre::Pass* pass = tech->getPass(0); Ogre::TextureUnitState* tex = pass->createTextureUnitState(); tex->setColourOperationEx(Ogre::LBX_MODULATE, Ogre::LBS_MANUAL, Ogre::LBS_CURRENT, Ogre::ColourValue(0, 0.5, 0)); Ogre::ManualObject* testBox = createCubeMesh("TestBox1", "BoxColor"); Ogre::SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); Ogre::MeshPtr Mesh = testBox->convertToMesh("TestBox2"); Ogre::StaticGeometry* pGeom = new Ogre::StaticGeometry (mSceneMgr, "Boxes"); Ogre::Entity* pEnt = mSceneMgr->createEntity("TestBox2"); pGeom->setRegionDimensions(Ogre::Vector3(300, 300, 300)); for (int z = 0; z < WORLD_SIZE; ++z) { for (int y = 0; y < WORLD_SIZE; ++y) { for (int x = 0; x < WORLD_SIZE; ++x) { if (GetBlock(x,y,z)) pGeom->addEntity(pEnt, Ogre::Vector3(x,y,z)); } } } pGeom->build (); }
void OgreBuilding::render() { while (readNextSymbol()) { if (!boundingBox->encloses(cursor.getPosition())) { finishDrawing(); break; } } Ogre::String name = buildingObject->getName(); buildingObject->convertToMesh(name + "Mesh"); Ogre::SceneNode* sceneNode = parentSceneNode->createChildSceneNode(name+"Node"); Ogre::StaticGeometry* staticObject = sceneManager->createStaticGeometry(name+"Static"); Ogre::Entity* entity; entity = sceneManager->createEntity(name + "Entity", name + "Mesh"); entity->setCastShadows(true); staticObject->addEntity(entity, Ogre::Vector3(0,0,0)); staticObject->setCastShadows(true); staticObject->build(); //sceneNode->attachObject(entity); }
void GameState::generateEnvironment() { Ogre::StaticGeometry *sg = mSceneMgr->createStaticGeometry("Asteroids"); const int size = 7000; const int amount = 5; sg->setRegionDimensions(Ogre::Vector3(size, size, size)); //sg->setOrigin(Ogre::Vector3(-size/2, 0, -size/2)); sg->setOrigin(Vector3(-size/2, -size/2, -size/2) + Vector3(0, 0, 0)); // this will center the staticgeometry around the point in 3D space for (int x = -size/2; x < size/2; x += (size/amount)) { for (int y = -size/2; y < size/2; y += (size/amount)) { for (int z = -size/2; z < size/2; z += (size/amount)) { Ogre::Real r = size / (float)amount / 2; Ogre::Vector3 pos(x + Ogre::Math::RangeRandom(-r, r), y + Ogre::Math::RangeRandom(-r, r), z + Ogre::Math::RangeRandom(-r, r)); Ogre::Vector3 scale(Ogre::Math::RangeRandom(0.7, 20), Ogre::Math::RangeRandom(0.7, 20), Ogre::Math::RangeRandom(0.7, 20)); Ogre::Quaternion orientation; orientation.FromAngleAxis(Ogre::Degree(Ogre::Math::RangeRandom(0, 359)), Ogre::Vector3::UNIT_Y); MyEntity * ent = new MyEntity("asteroid1.mesh", mSceneMgr, mWorld, pos); ent->transform(orientation, Ogre::Vector3::ZERO); //ent->setScale(scale); sg->addEntity(ent->getEntity(), pos, orientation/*, scale*/); } } } sg->build(); }
Environment::Environment(Ogre::SceneManager* sceneManager, btDynamicsWorld& world, std::istream& level) : _sceneManager(sceneManager), _world(world), _DebugDrawers(), DebugAI(-1) { for(int i = 0; i < 5; ++i) { _DebugDrawers.push_back(std::unique_ptr<DebugDrawer>(new DebugDrawer(sceneManager, 0.5))); } boost::posix_time::ptime t1 = boost::posix_time::microsec_clock::universal_time(); while (!level.eof()) { std::string MeshName; std::string Orientation; float x, y, z; level >> MeshName >> x >> y >> z >> Orientation; if (MeshName.compare("") && (MeshName[0] != '#')) { std::cout << "mesh " << MeshName << " at (" << x << "," << y << "," << z << "), " << Orientation << std::endl; orientation_t o; if (!Orientation.compare("N")) o = North; else if (!Orientation.compare("S")) o = South; else if (!Orientation.compare("E")) o = East; else if (!Orientation.compare("W")) o = West; else { std::stringstream str; str << "Invalid orientation (" << Orientation << ")"; throw std::invalid_argument(str.str()); } Ogre::Entity * Entity = _sceneManager->createEntity(MeshName); Entity->setCastShadows(false); _blocks.push_back(Block(Entity, o, Ogre::Vector3(x,y,z))); } } boost::posix_time::ptime t2 = boost::posix_time::microsec_clock::universal_time(); Ogre::StaticGeometry *sg = _sceneManager->createStaticGeometry("environment"); boost::posix_time::ptime t3 = boost::posix_time::microsec_clock::universal_time(); _NavMesh.AgentHeight = 1.8; _NavMesh.AgentRadius = 0.8; _NavMesh.AgentMaxSlope = M_PI / 4; _NavMesh.AgentMaxClimb = 0.5; _NavMesh.CellHeight = 0.2; _NavMesh.CellSize = 0.2; _NavMesh.QueryExtent = Ogre::Vector3(10, 10, 10); //for(auto const & block : _blocks) BOOST_FOREACH(auto const & block, _blocks) { sg->addEntity(block._entity, block._position, getQuaternion(block._orientation)); OgreConverter converter(*block._entity); Ogre::Matrix4 transform = getMatrix4(block._orientation, block._position); converter.AddToTriMesh(transform, _TriMesh); converter.AddToHeightField(transform, _NavMesh); }
/// @brief Loads the graphics for the supplied arena. /// @param aid The ArenaID of the arena to load. void SceneSetup::loadArenaGraphics (ArenaID aid) { // Load the main arena mesh Ogre::Entity* arenaEntity; if (aid == COLOSSEUM_ARENA) arenaEntity = GameCore::mSceneMgr->createEntity("Arena", "arena1.mesh"); else if (aid == FOREST_ARENA) arenaEntity = GameCore::mSceneMgr->createEntity("Arena", "arena2.mesh"); else arenaEntity = GameCore::mSceneMgr->createEntity("Arena", "arena3.mesh"); #if SHADOW_METHOD == 2 arenaEntity->setCastShadows(false); #else arenaEntity->setCastShadows(true); #endif arenaNode->attachObject(arenaEntity); // Load the props if (aid == COLOSSEUM_ARENA) { Ogre::SceneNode* propsNode = GameCore::mSceneMgr->getRootSceneNode()->createChildSceneNode("PropsNode"); GameCore::mPhysicsCore->auto_scale_scenenode(propsNode); Ogre::Entity* propsEntity = GameCore::mSceneMgr->createEntity("PropsEntity", "arena1_props.mesh"); #if SHADOW_METHOD == 1 propsEntity->setCastShadows(false); #else propsEntity->setCastShadows(true); #endif propsNode->attachObject(propsEntity); } else if (aid == FOREST_ARENA) { unsigned int i; int treeType; Ogre::Real radius, theta; std::string entityName, nodeName, fileName; Ogre::Vector3 treePosition; Ogre::Vector3 treeScale(MESH_SCALING_CONSTANT, MESH_SCALING_CONSTANT, MESH_SCALING_CONSTANT); Ogre::Entity* lowPolyTrees[5]; Ogre::Entity* superLowPolyTrees[5]; // Load the trees arrays with entities. for (i = 1; i <= 5; i++) { entityName = "LPTreeEntity" + boost::lexical_cast<std::string>(i); fileName = "birch" + boost::lexical_cast<std::string>(i) + "_lp.mesh"; lowPolyTrees[i-1] = GameCore::mSceneMgr->createEntity(entityName, fileName); lowPolyTrees[i-1]->setCastShadows(false); entityName = "SLPTreeEntity" + boost::lexical_cast<std::string>(i); fileName = "birch" + boost::lexical_cast<std::string>(i) + "_slp.mesh"; superLowPolyTrees[i-1] = GameCore::mSceneMgr->createEntity(entityName, fileName); superLowPolyTrees[i-1]->setCastShadows(false); } // Load the static geometry - fun on the bun int size = 184.5 * 2; Ogre::StaticGeometry* sg = GameCore::mSceneMgr->createStaticGeometry("Trees"); sg->setRegionDimensions(Ogre::Vector3(size, 100, size)); sg->setOrigin(Ogre::Vector3(-size/2, 0, -size/2)); // Notes: 134.2m < r < 184.2m // rand() returns a value which is at least 32767. // First 15m are good trees, subsequent 35m are crap trees. // Place 50 higher detail trees close to the viewer. for (i = 0; i < FOREST_ARENA_HQ_TREE_COUNT + FOREST_ARENA_LQ_TREE_COUNT; i++) { if (i < FOREST_ARENA_HQ_TREE_COUNT) radius = (1345 + (rand() % (FOREST_ARENA_LQ_TREE_CUTOFF * 10))) / 10.0f; else radius = (1345 + (FOREST_ARENA_LQ_TREE_CUTOFF * 10) + (rand() % (1845 - 1345 - (FOREST_ARENA_LQ_TREE_CUTOFF*10)))) / 10.0f; theta = ((rand() % 32767) / 32767.0f) * 6.28318531f; treeType = rand() % 5; treePosition.x = radius * cos(theta); treePosition.z = radius * sin(theta); treePosition.y = 1.6f; if (i < FOREST_ARENA_HQ_TREE_COUNT) sg->addEntity(superLowPolyTrees[treeType], treePosition, Ogre::Quaternion::IDENTITY, treeScale); else sg->addEntity(lowPolyTrees[treeType], treePosition, Ogre::Quaternion::IDENTITY, treeScale); } sg->build(); // Unload the trees arrays. for (i = 1; i <= 5; i++) { entityName = "LPTreeEntity" + boost::lexical_cast<std::string>(i); GameCore::mSceneMgr->destroyEntity(entityName); entityName = "SLPTreeEntity" + boost::lexical_cast<std::string>(i); GameCore::mSceneMgr->destroyEntity(entityName); } } else { Ogre::SceneNode* propsNode = GameCore::mSceneMgr->getRootSceneNode()->createChildSceneNode("PropsNode"); GameCore::mPhysicsCore->auto_scale_scenenode(propsNode); Ogre::Entity* propsEntity = GameCore::mSceneMgr->createEntity("PropsEntity", "arena3_props.mesh"); #if SHADOW_METHOD == 1 propsEntity->setCastShadows(false); #else propsEntity->setCastShadows(true); #endif propsNode->attachObject(propsEntity); } #ifdef COLLISION_DOMAIN_CLIENT //GameCore::mClientGraphics->mGameCam->setTarget( arenaNode ); GameCore::mClientGraphics->mGameCam->setTransform( btVector3( 0, 10, 80 ) ); #endif }
void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh) { Ogre::SceneNode* insert = ptr.getRefData().getBaseNode(); assert(insert); Ogre::AxisAlignedBox bounds = Ogre::AxisAlignedBox::BOX_NULL; NifOgre::EntityList entities = NifOgre::NIFLoader::createEntities(insert, NULL, mesh); for(size_t i = 0;i < entities.mEntities.size();i++) { const Ogre::AxisAlignedBox &tmp = entities.mEntities[i]->getBoundingBox(); bounds.merge(Ogre::AxisAlignedBox(insert->_getDerivedPosition() + tmp.getMinimum(), insert->_getDerivedPosition() + tmp.getMaximum()) ); } Ogre::Vector3 extents = bounds.getSize(); extents *= insert->getScale(); float size = std::max(std::max(extents.x, extents.y), extents.z); bool small = (size < Settings::Manager::getInt("small object size", "Viewing distance")) && Settings::Manager::getBool("limit small object distance", "Viewing distance"); // do not fade out doors. that will cause holes and look stupid if (ptr.getTypeName().find("Door") != std::string::npos) small = false; if (mBounds.find(ptr.getCell()) == mBounds.end()) mBounds[ptr.getCell()] = Ogre::AxisAlignedBox::BOX_NULL; mBounds[ptr.getCell()].merge(bounds); bool transparent = false; for(size_t i = 0;i < entities.mEntities.size();i++) { Ogre::Entity *ent = entities.mEntities[i]; for (unsigned int i=0; i<ent->getNumSubEntities(); ++i) { Ogre::MaterialPtr mat = ent->getSubEntity(i)->getMaterial(); Ogre::Material::TechniqueIterator techIt = mat->getTechniqueIterator(); while (techIt.hasMoreElements()) { Ogre::Technique* tech = techIt.getNext(); Ogre::Technique::PassIterator passIt = tech->getPassIterator(); while (passIt.hasMoreElements()) { Ogre::Pass* pass = passIt.getNext(); if (pass->getDepthWriteEnabled() == false) transparent = true; } } } } if(!mIsStatic || !Settings::Manager::getBool("use static geometry", "Objects") || transparent) { for(size_t i = 0;i < entities.mEntities.size();i++) { Ogre::Entity *ent = entities.mEntities[i]; ent->setRenderingDistance(small ? Settings::Manager::getInt("small object distance", "Viewing distance") : 0); ent->setVisibilityFlags(mIsStatic ? (small ? RV_StaticsSmall : RV_Statics) : RV_Misc); ent->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main); } } else { Ogre::StaticGeometry* sg = 0; if (small) { if( mStaticGeometrySmall.find(ptr.getCell()) == mStaticGeometrySmall.end()) { uniqueID = uniqueID +1; sg = mRenderer.getScene()->createStaticGeometry( "sg" + Ogre::StringConverter::toString(uniqueID)); mStaticGeometrySmall[ptr.getCell()] = sg; sg->setRenderingDistance(Settings::Manager::getInt("small object distance", "Viewing distance")); } else sg = mStaticGeometrySmall[ptr.getCell()]; } else { if( mStaticGeometry.find(ptr.getCell()) == mStaticGeometry.end()) { uniqueID = uniqueID +1; sg = mRenderer.getScene()->createStaticGeometry( "sg" + Ogre::StringConverter::toString(uniqueID)); mStaticGeometry[ptr.getCell()] = sg; } else sg = mStaticGeometry[ptr.getCell()]; } // This specifies the size of a single batch region. // If it is set too high: // - there will be problems choosing the correct lights // - the culling will be more inefficient // If it is set too low: // - there will be too many batches. sg->setRegionDimensions(Ogre::Vector3(2500,2500,2500)); sg->setVisibilityFlags(small ? RV_StaticsSmall : RV_Statics); sg->setCastShadows(true); sg->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main); for(size_t i = 0;i < entities.mEntities.size();i++) { Ogre::Entity *ent = entities.mEntities[i]; insert->detachObject(ent); sg->addEntity(ent,insert->_getDerivedPosition(),insert->_getDerivedOrientation(),insert->_getDerivedScale()); mRenderer.getScene()->destroyEntity(ent); } } }
void Vizi3DWorld::drawNext() { // @init load() if ( drawItr.empty() ) { return; } // Наносим на холст сразу всю битовую карту текущего элемента // Чудесный метод предоставляет нам всю необходимую информацию const auto info = *get( drawItr ); // Пробел - всегда отсутствие элемента if (info.signElement != ' ') { // Оформлять будем как стат. геометрию const std::string signInString = std::string( &info.signElement, 1 ); Ogre::StaticGeometry* staticScene = sm->createStaticGeometry( signInString + "::Vizi3DWorld" ); //staticScene->setRegionDimensions( ... ); // Создаём элемент const std::string meshName = info.noteElement.form + ".mesh"; auto e = sm->createEntity( meshName ); // Фикс для прозрачных материалов // @see http://ogre3d.org/forums/viewtopic.php?f=2&t=32172&start=0 e->setRenderQueueGroup( Ogre::RENDER_QUEUE_9 ); const std::string materialName = info.noteElement.material; if ( !materialName.empty() ) { // Заменяем материал по умолчанию const auto material = Ogre::MaterialManager::getSingleton().getByName( materialName ); #ifdef TEST_TRANSPARENT_CELL // @test Добавляем прозрачность всем материалам const auto mt = static_cast< Ogre::Material* >( material.get() ); mt->setSceneBlending( Ogre::SBT_TRANSPARENT_COLOUR ); //mt->setParameter( "set_alpha_rejection", "greater 128" ); mt->setDepthWriteEnabled( false ); mt->setDepthCheckEnabled( true ); #endif e->setMaterial( material ); e->setCastShadows( true ); } // if ( !materialName.empty() ) // Размер области const size_t N = info.bitContent.size().get<0>(); const size_t M = info.bitContent.size().get<1>(); const size_t L = info.bitContent.size().get<2>(); // Позиционируем область в мировом пространстве const float halfN = (float)N / 2.0f; const float halfM = (float)M / 2.0f; const float halfL = (float)L / 2.0f; staticScene->setOrigin( Ogre::Vector3( info.coord.get<0>() * info.scaleWorld - halfN * info.scale, info.coord.get<1>() * info.scaleWorld - halfM * info.scale, info.coord.get<2>() * info.scaleWorld - halfL * info.scale ) ); /* - Заменено на предварительную подготовку образа в load(). См. ниже. // Добавляем элемент в *область*, определяя его расположение благодаря // битовой карте области for (size_t l = 0; l < L; ++l) { for (size_t m = 0; m < M; ++m) { for (size_t n = 0; n < N; ++n) { // 3D-указатель для определения положения элемента const auto c = d::coordInt3d_t( n, m, l ); // Каждый установленный бит - признак наличия элемента в области // @todo optimize Быстрый доступ по 1D-указателю if ( info.bitContent.test( c ) ) { staticScene->addEntity( e, // положение элемента, центрируем блок позже Ogre::Vector3( (float)c.get<0>(), (float)c.get<1>(), (float)c.get<2>() ) * info.scale, Ogre::Quaternion::ZERO, Ogre::Vector3( info.scale ) ); } } // for (size_t n = 0; n < N; ++n) } // for (size_t m = 0; m < M; ++m } // for (size_t l = 0; l < L; ++l) */ // Не все элементы требуют отрисовки // @see prepareVisualBitImage() const auto content = *drawItr.mapElement()->second; const auto& alphaBI = *drawItr.tinyMap()->second.visualContent.alphaTypeBitImage; const auto& solidBI = *drawItr.tinyMap()->second.visualContent.solidTypeBitImage; assert( (alphaBI.raw().size() == solidBI.raw().size()) && "Размеры битовых образов должны совпадать." ); for (size_t l = 0; l < L; ++l) { for (size_t m = 0; m < M; ++m) { for (size_t n = 0; n < N; ++n) { // 3D-указатель для определения положения элемента const auto c = d::coordInt3d_t( n, m, l ); // Каждый установленный бит - признак наличия элемента в области // @todo optimize Быстрый доступ по 1D-указателю if ( content.test( c ) && ( solidBI.test( c ) || alphaBI.test( c ) ) ) { staticScene->addEntity( e, // положение элемента в статическом блоке (блок // центрировали раньше) Ogre::Vector3( ((float)c.get<0>() - (float)halfN), -((float)c.get<1>() - (float)halfM), -((float)c.get<2>() - (float)halfL) ) * info.scale, Ogre::Quaternion::ZERO, #ifdef TEST_VISUAL_CELL Ogre::Vector3( info.scale / 1.80f ) #else Ogre::Vector3( info.scale ) #endif ); } } // for (size_t n = 0; n < N; ++n) } // for (size_t m = 0; m < M; ++m } // for (size_t l = 0; l < L; ++l) // Строим! staticScene->build(); } // if (info.signElement != ' ') // Переводим итератор на след. элемент ++drawItr; }
void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh, bool light) { Ogre::SceneNode* insert = ptr.getRefData().getBaseNode(); assert(insert); Ogre::AxisAlignedBox bounds = Ogre::AxisAlignedBox::BOX_NULL; NifOgre::ObjectList objects = NifOgre::Loader::createObjects(insert, mesh); for(size_t i = 0;i < objects.mEntities.size();i++) bounds.merge(objects.mEntities[i]->getWorldBoundingBox(true)); Ogre::Vector3 extents = bounds.getSize(); extents *= insert->getScale(); float size = std::max(std::max(extents.x, extents.y), extents.z); bool small = (size < Settings::Manager::getInt("small object size", "Viewing distance")) && Settings::Manager::getBool("limit small object distance", "Viewing distance"); // do not fade out doors. that will cause holes and look stupid if (ptr.getTypeName().find("Door") != std::string::npos) small = false; if (mBounds.find(ptr.getCell()) == mBounds.end()) mBounds[ptr.getCell()] = Ogre::AxisAlignedBox::BOX_NULL; mBounds[ptr.getCell()].merge(bounds); bool anyTransparency = false; for(size_t i = 0;!anyTransparency && i < objects.mEntities.size();i++) { Ogre::Entity *ent = objects.mEntities[i]; for(unsigned int i=0;!anyTransparency && i < ent->getNumSubEntities(); ++i) { anyTransparency = ent->getSubEntity(i)->getMaterial()->isTransparent(); } } if(!mIsStatic || !Settings::Manager::getBool("use static geometry", "Objects") || anyTransparency || objects.mParticles.size() > 0) { for(size_t i = 0;i < objects.mEntities.size();i++) { Ogre::Entity *ent = objects.mEntities[i]; for(unsigned int i=0; i < ent->getNumSubEntities(); ++i) { Ogre::SubEntity* subEnt = ent->getSubEntity(i); subEnt->setRenderQueueGroup(subEnt->getMaterial()->isTransparent() ? RQG_Alpha : RQG_Main); } ent->setRenderingDistance(small ? Settings::Manager::getInt("small object distance", "Viewing distance") : 0); ent->setVisibilityFlags(mIsStatic ? (small ? RV_StaticsSmall : RV_Statics) : RV_Misc); } for(size_t i = 0;i < objects.mParticles.size();i++) { Ogre::ParticleSystem *part = objects.mParticles[i]; // TODO: Check the particle system's material for actual transparency part->setRenderQueueGroup(RQG_Alpha); part->setRenderingDistance(small ? Settings::Manager::getInt("small object distance", "Viewing distance") : 0); part->setVisibilityFlags(mIsStatic ? (small ? RV_StaticsSmall : RV_Statics) : RV_Misc); } } else { Ogre::StaticGeometry* sg = 0; if (small) { if( mStaticGeometrySmall.find(ptr.getCell()) == mStaticGeometrySmall.end()) { uniqueID = uniqueID +1; sg = mRenderer.getScene()->createStaticGeometry( "sg" + Ogre::StringConverter::toString(uniqueID)); mStaticGeometrySmall[ptr.getCell()] = sg; sg->setRenderingDistance(Settings::Manager::getInt("small object distance", "Viewing distance")); } else sg = mStaticGeometrySmall[ptr.getCell()]; } else { if( mStaticGeometry.find(ptr.getCell()) == mStaticGeometry.end()) { uniqueID = uniqueID +1; sg = mRenderer.getScene()->createStaticGeometry( "sg" + Ogre::StringConverter::toString(uniqueID)); mStaticGeometry[ptr.getCell()] = sg; } else sg = mStaticGeometry[ptr.getCell()]; } // This specifies the size of a single batch region. // If it is set too high: // - there will be problems choosing the correct lights // - the culling will be more inefficient // If it is set too low: // - there will be too many batches. sg->setRegionDimensions(Ogre::Vector3(2500,2500,2500)); sg->setVisibilityFlags(small ? RV_StaticsSmall : RV_Statics); sg->setCastShadows(true); sg->setRenderQueueGroup(RQG_Main); std::vector<Ogre::Entity*>::reverse_iterator iter = objects.mEntities.rbegin(); while(iter != objects.mEntities.rend()) { Ogre::Node *node = (*iter)->getParentNode(); sg->addEntity(*iter, node->_getDerivedPosition(), node->_getDerivedOrientation(), node->_getDerivedScale()); (*iter)->detachFromParent(); mRenderer.getScene()->destroyEntity(*iter); iter++; } } if (light) { insertLight(ptr, objects.mSkelBase, bounds.getCenter() - insert->_getDerivedPosition()); } }