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;
        }
예제 #2
0
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 ();
}
예제 #3
0
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);
}
예제 #4
0
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();

	

}
예제 #5
0
파일: environment.cpp 프로젝트: Meumeu/PMD
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);
	}
예제 #6
0
/// @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
}
예제 #7
0
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);
        }
    }
}
예제 #8
0
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;

}
예제 #9
0
파일: objects.cpp 프로젝트: darkf/openmw
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());
    }
}