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(); }
/// @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 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; }
bool LevelGeometryLoader::processStaticGeometries(TiXmlElement *XMLRoot) { ASSERT(XMLRoot); TiXmlElement *pElement, *auxPElem; // Process nodes (?) pElement = XMLRoot->FirstChildElement("staticGeometries"); if(!pElement){ debug("Error: Invalid .scene processStaticGeometries\n" ); return false; } mStaticGeometry.clear(); Ogre::StaticGeometry *sgeo = 0; Ogre::Vector3 origin; Ogre::Vector3 dimension; bool visible; Ogre::String name; bool castShadow; // parse the staticGeometries pElement = pElement->FirstChildElement("staticGeometry"); while(pElement) { // Parse a StaticGeometry visible = Ogre::DotSceneLoader::getAttribBool(pElement, "visible"); name = Ogre::DotSceneLoader::getAttrib(pElement, "name"); castShadow = Ogre::DotSceneLoader::getAttribBool(pElement, "castShadows"); try { sgeo = Common::GlobalObjects::sceneManager->createStaticGeometry(name); debug("StaticGeometry %s created\n", name.c_str()); } catch(...) { debug("Error: Invalid name to StaticGeometry\n" ); return false; } mStaticGeometry.push_back(sgeo); sgeo->setCastShadows(castShadow); sgeo->setVisible(visible); // get the origin auxPElem = pElement->FirstChildElement("origin"); if(auxPElem) { sgeo->setOrigin(Ogre::DotSceneLoader::parseVector3(auxPElem)); } // get the dimensions auxPElem = pElement->FirstChildElement("dimensions"); if(auxPElem) { sgeo->setRegionDimensions(Ogre::DotSceneLoader::parseVector3(auxPElem)); } // iterate over the entity list auxPElem = pElement; auxPElem = auxPElem->FirstChildElement("entities"); if(!auxPElem){ debug("Error: StaticGeometry without Entity! %s\n", sgeo->getName().c_str()); ASSERT(false); mStaticGeometry.erase(mStaticGeometry.end()-1); Common::GlobalObjects::sceneManager->destroyStaticGeometry(sgeo); pElement = pElement->NextSiblingElement("staticGeometry"); continue; } auxPElem = auxPElem->FirstChildElement("entity"); while(auxPElem){ // get the entities associated if(!processEntityStaticGeoemtry(auxPElem, sgeo)){ debug("Error: Invalid entity of StaticGeometry\n" ); return false; } auxPElem = auxPElem->NextSiblingElement("entity"); } // build the staticGeometry sgeo->build(); pElement = pElement->NextSiblingElement("staticGeometry"); } return true; }