/** * This idle function allows progressive scanning of visibility etc */ bool GlueMapWindow::Idle() { bool still_dirty=false; bool topology_dirty = true; /* scan topology in every Idle() call */ bool terrain_dirty = true; bool weather_dirty = true; // StartTimer(); do { idle_robin = (idle_robin + 1) % 3; switch (idle_robin) { case 0: UpdateTopology(); topology_dirty = false; break; case 1: UpdateTerrain(); terrain_dirty = false; break; case 2: UpdateWeather(); weather_dirty = false; break; } } while (RenderTimeAvailable() && !draw_thread->is_triggered() && (still_dirty = terrain_dirty || topology_dirty || weather_dirty)); return still_dirty; }
/** * This idle function allows progressive scanning of visibility etc */ bool GlueMapWindow::Idle() { bool still_dirty; bool topography_dirty = true; /* scan topography in every Idle() call */ bool terrain_dirty = true; bool weather_dirty = true; // StartTimer(); do { idle_robin = (idle_robin + 1) % 3; switch (idle_robin) { case 0: topography_dirty = UpdateTopography(1) > 0; break; case 1: terrain_dirty = UpdateTerrain(); break; case 2: weather_dirty = UpdateWeather(); break; } still_dirty = terrain_dirty || topography_dirty || weather_dirty; } while (RenderTimeAvailable() && #ifndef ENABLE_OPENGL !draw_thread->IsTriggered() && #endif still_dirty); return still_dirty; }
/** * This idle function allows progressive scanning of visibility etc */ bool GlueMapWindow::Idle() { if (!render_projection.IsValid()) return false; if (idle_robin == unsigned(-1)) { /* draw the first frame as quickly as possible, so the user can start interacting with XCSoar immediately */ idle_robin = 2; return true; } if (!IsUserIdle(2500)) /* don't hold back the UI thread while the user is interacting */ return true; PeriodClock clock; clock.Update(); bool still_dirty; bool topography_dirty = true; /* scan topography in every Idle() call */ bool terrain_dirty = true; bool weather_dirty = true; do { idle_robin = (idle_robin + 1) % 3; switch (idle_robin) { case 0: topography_dirty = UpdateTopography(1) > 0; break; case 1: terrain_dirty = UpdateTerrain(); break; case 2: weather_dirty = UpdateWeather(); break; } still_dirty = terrain_dirty || topography_dirty || weather_dirty; } while (!clock.Check(700) && /* stop after 700ms */ #ifndef ENABLE_OPENGL !draw_thread->IsTriggered() && #endif IsUserIdle(2500) && still_dirty); return still_dirty; }
void CrossSectionRenderer::Paint(Canvas &canvas, const PixelRect rc) const { DrawVerticalGradient(canvas, rc, look.sky_color, look.background_color, look.background_color); canvas.SetTextColor(look.text_color); canvas.Select(*look.grid_font); ChartRenderer chart(chart_look, canvas, rc); if (!vec.IsValid() || !start.IsValid()) { chart.DrawNoData(); return; } const fixed nav_altitude = gps_info.NavAltitudeAvailable() ? gps_info.nav_altitude : fixed(0); fixed hmin = std::max(fixed(0), nav_altitude - fixed(3300)); fixed hmax = std::max(fixed(3300), nav_altitude + fixed(1000)); chart.ResetScale(); chart.ScaleXFromValue(fixed(0)); chart.ScaleXFromValue(vec.distance); chart.ScaleYFromValue(hmin); chart.ScaleYFromValue(hmax); short elevations[NUM_SLICES]; UpdateTerrain(elevations); if (airspace_database != nullptr) { const AircraftState aircraft = ToAircraftState(Basic(), Calculated()); airspace_renderer.Draw(canvas, chart, *airspace_database, start, vec, aircraft); } terrain_renderer.Draw(canvas, chart, elevations); PaintGlide(chart); PaintAircraft(canvas, chart, rc); PaintGrid(canvas, chart); }
/** * This idle function allows progressive scanning of visibility etc */ bool GlueMapWindow::Idle() { if (!render_projection.IsValid()) return false; if (skip_idle) { /* draw the first frame as quickly as possible, so the user can start interacting with XCSoar immediately */ skip_idle = false; return true; } /* hack: update RASP weather maps as quickly as possible; they only ever need to be updated after the user has selected a new map, so this is not a UI latency problem (quite contrary, don't let the user wait until he sees the new map) */ UpdateWeather(); if (!IsUserIdle(2500)) /* don't hold back the UI thread while the user is interacting */ return true; PeriodClock clock; clock.Update(); bool still_dirty; do { still_dirty = UpdateWeather() || UpdateTerrain(); } while (!clock.Check(700) && /* stop after 700ms */ #ifndef ENABLE_OPENGL !draw_thread->IsTriggered() && #endif IsUserIdle(2500) && still_dirty); return still_dirty; }
void AppGUI::Tick(RenderEngine& engine) { UpdateShader(engine); switch (m_cache->PageSelected.Get()) { case PAGE_SCENE: UpdateScene(engine); break; case PAGE_AREA: UpdateTerrain(engine); UpdateTexture(engine); break; case PAGE_MESH: UpdateMesh(); UpdateWater(); UpdateEmitter(); break; case PAGE_POST: UpdateLight(); UpdatePost(engine); break; } }
void World::SetTerrainGlobalMin( Event *ev ) { terrain_global = true; terrain_global_min = ev->GetFloat( 1 ); UpdateTerrain(); }
void World::SetTerrainGlobal( Event *ev ) { terrain_global = ev->GetBoolean( 1 ); terrain_global_min = MIN_WORLD_COORD; UpdateTerrain(); }
World::World() { const char *text; str mapname; int i; assert( this->entnum == ENTITYNUM_WORLD ); world = this; world_dying = false; setMoveType( MOVETYPE_NONE ); setSolidType( SOLID_BSP ); // world model is always index 1 edict->s.modelindex = 1; model = "*1"; turnThinkOn(); UpdateConfigStrings(); groupcoordinator = NULL; // Anything that modifies configstrings, or spawns things is ignored when loading savegames if ( LoadingSavegame ) { return; } // clear out the soundtrack from the last level ChangeSoundtrack( "" ); // set the default farplane parameters farplane_distance = 0; farplane_color = Vector(0, 0, 0); farplane_cull = true; farplane_fog = true; UpdateFog(); terrain_global = false; terrain_global_min = MIN_WORLD_COORD; UpdateTerrain(); entity_fade_dist = DEFAULT_ENTITY_FADE_DIST; UpdateEntityFadeDist(); UpdateDynamicLights(); UpdateWeather(); time_scale = 1.0f; sky_alpha = 1.0f; sky_portal = true; UpdateSky(); // // see if this is a cinematic level // level.cinematic = ( spawnflags & CINEMATIC ) ? true : false; if ( level.cinematic ) gi.cvar_set( "sv_cinematic", "1" ); else gi.cvar_set( "sv_cinematic", "0" ); level.nextmap = ""; level.level_name = level.mapname; // Set up the mapname as the default script mapname = "maps/"; mapname += level.mapname; for( i = mapname.length() - 1; i >= 0; i-- ) { if ( mapname[ i ] == '.' ) { mapname[ i ] = 0; break; } } mapname += ".scr"; text = &mapname[ 5 ]; // If there isn't a script with the same name as the map, then don't try to load script if ( gi.FS_ReadFile( mapname.c_str(), NULL, true ) != -1 ) { gi.DPrintf( "Adding script: '%s'\n", text ); // just set the script, we will start it in G_Spawn level.SetGameScript( mapname.c_str() ); } else { level.SetGameScript( "" ); } level.consoleThread = Director.CreateThread(); SoundMan.Init(); SoundMan.Load(); // Set the color for the blends. level.water_color = Vector( 0.0f, 0.0f, 0.5f ); level.water_alpha = 0.4f; level.slime_color = Vector( 0.2f, 0.4f, 0.2f ); level.slime_alpha = 0.6f; level.lava_color = Vector( 0.5f, 0.15f, 0.0f ); level.lava_alpha = 0.6f; // // set the targetname of the world // SetTargetName( "world" ); groupcoordinator = new GroupCoordinator; // Initialize movement info for ( i = 0 ; i < WORLD_PHYSICS_TOTAL_NUMBER ; i++ ) { _physicsInfo[ i ] = -1.0f; } _canShakeCamera = false; }
void World::Archive( Archiver &arc ) { int i; int num; TargetList *tempTargetList; Entity::Archive( arc ); if ( arc.Loading() ) { FreeTargetList(); } if ( arc.Saving() ) num = targetList.NumObjects(); arc.ArchiveInteger( &num ); for ( i = 1; i <= num; i++ ) { if ( arc.Saving() ) { tempTargetList = targetList.ObjectAt( i ); } else { tempTargetList = new TargetList; targetList.AddObject( tempTargetList ); } arc.ArchiveObject( ( Class * )tempTargetList ); } _brokenThings.Archive( arc ); _availableViewModes.Archive( arc ); arc.ArchiveBoolean( &world_dying ); arc.ArchiveString( &skipthread ); arc.ArchiveFloat( &farplane_distance ); arc.ArchiveVector( &farplane_color ); arc.ArchiveBoolean( &farplane_cull ); arc.ArchiveBoolean( &farplane_fog ); arc.ArchiveBoolean( &terrain_global ); arc.ArchiveFloat( &terrain_global_min ); arc.ArchiveFloat( &entity_fade_dist ); for( i = 0 ; i < MAX_LIGHTING_GROUPS ; i++ ) dynamic_lights[ i ].Archive( arc ); wind.Archive( arc ); weather.Archive( arc ); arc.ArchiveFloat( &time_scale ); arc.ArchiveFloat( &sky_alpha ); arc.ArchiveBoolean( &sky_portal ); for ( i = 0 ; i < WORLD_PHYSICS_TOTAL_NUMBER ; i++ ) { arc.ArchiveFloat( &_physicsInfo[ i ] ); } arc.ArchiveBool( &_canShakeCamera ); if ( arc.Loading() ) { UpdateConfigStrings(); UpdateFog(); UpdateTerrain(); UpdateSky(); UpdateDynamicLights(); UpdateWindDirection(); UpdateWindIntensity(); UpdateWeather(); UpdateTimeScale(); } // Archive groupcoordinator (not part of world but this is a good place) if ( arc.Loading() ) { if ( groupcoordinator ) delete groupcoordinator; groupcoordinator = new GroupCoordinator; } groupcoordinator->Archive( arc ); }
SceneWorld::SceneWorld(PseuGUI *g) : Scene(g) { DEBUG(logdebug("SceneWorld: Initializing...")); debugmode = false; _freeCameraMove = true; // store some pointers right now to prevent repeated ptr dereferencing later (speeds up code) gui = g; wsession = gui->GetInstance()->GetWSession(); world = wsession->GetWorld(); mapmgr = world->GetMapMgr(); movemgr = world->GetMoveMgr(); mychar = wsession->GetMyChar(); ASSERT(mychar); _CalcXYMoveVect(mychar->GetO()); old_char_o = mychar->GetO(); if(soundengine) { soundengine->stopAllSounds(); } ILightSceneNode* light = smgr->addLightSceneNode(0, core::vector3df(0,0,0), SColorf(255, 255, 255, 255), 1000.0f); SLight ldata = light->getLightData(); ldata.AmbientColor = video::SColorf(0.2f,0.2f,0.2f); ldata.DiffuseColor = video::SColorf(1.0f,1.0f,1.0f); ldata.Type = video::ELT_DIRECTIONAL; ldata.Position = core::vector3df(-0.22f,-1,0); light->setLightData(ldata); eventrecv = new MyEventReceiver(); device->setEventReceiver(eventrecv); eventrecv->mouse.wheel = MAX_CAM_DISTANCE; camera = new MCameraFPS(smgr); camera->setNearValue(0.1f); f32 farclip = instance->GetConf()->farclip; if(farclip < 50) farclip = TILESIZE; f32 fov = instance->GetConf()->fov; if(!iszero(fov)) { logdetail("Camera: Field of view (FOV) = %.3f",fov); camera->setFOV(fov); } camera->setFarValue(farclip); debugText = guienv->addStaticText(L"< debug text >",rect<s32>(0,0,driver->getScreenSize().Width,30),true,true,0,-1,true); envBasicColor = video::SColor(0,100,101,190); smgr->setShadowColor(); // set shadow to default color sky = NULL; selectedNode = oldSelectedNode = NULL; //sky = smgr->addSkyDomeSceneNode(driver->getTexture("data/misc/sky.jpg"),64,64,1.0f,2.0f); /* // TODO: for now let irrlicht draw the skybox sky->grab(); // if the camera clip is set too short, the sky will not be rendered properly. sky->remove(); // thus we grab the sky node while removing it from rendering. */ f32 fogfar = instance->GetConf()->fogfar; if(fogfar < 30) fogfar = farclip * 0.7f; f32 fognear = instance->GetConf()->fognear; if(fognear < 10) fognear = fogfar * 0.75f; logdetail("GUI: Using farclip=%.2f fogfar=%.2f fognear=%.2f", farclip, fogfar, fognear); driver->setFog(envBasicColor, true, fognear, fogfar, 0.02f); // setup cursor cursor->setOSCursorVisible(false); cursor->addMouseCursorTexture("data/misc/cursor.png", true); cursor->setVisible(true); InitTerrain(); UpdateTerrain(); RelocateCameraBehindChar(); DEBUG(logdebug("SceneWorld: Init done!")); }
void SceneWorld::OnUpdate(s32 timediff) { static position2d<s32> mouse_pos; UpdateTerrain(); mouse_pressed_left = eventrecv->mouse.left_pressed(); mouse_pressed_right = eventrecv->mouse.right_pressed(); float timediff_f = timediff / 1000.0f; if( (mouse_pressed_right || mouse_pressed_left) && cursor->isVisible()) { // TODO: if mouse is hovering over a gui element, do not hide cursor->setVisible(false); } else if( !(mouse_pressed_right || mouse_pressed_left) && !cursor->isVisible()) { cursor->setVisible(true); } // object focused - only check if mouse moved, saves CPU // TODO: check if camera moved, also (maybe from external source) /*if(mouse_pos != cursor->getMousePos()) { focusedNode = smgr->getSceneCollisionManager()->getSceneNodeFromScreenCoordinatesBB(cursor->getMousePos()); if(focusedNode && mouse_pressed_left) selectedNode = focusedNode; }*/ // i'll continue working on this - [FG] // maybe it is better to replace the sin() and cos() with some irr::core::matrix4 calcualtions... not sure what is more efficient if(eventrecv->key.pressed(KEY_KEY_W) || (mouse_pressed_left && mouse_pressed_right)) { if(_freeCameraMove) camera->moveForward(50 * timediff_f); else { f32 speedfactor = timediff_f * mychar->GetSpeed(MOVE_RUN); movemgr->SetMoveMode(MOVEMODE_MANUAL); movemgr->MoveStartForward(); WorldPosition wp = mychar->GetPosition(); _CalcXYMoveVect(wp.o); wp.x += (xyCharMovement.X * speedfactor); wp.y += (xyCharMovement.Y * speedfactor); wp.z = terrain->getHeight(WPToIrr(wp)); mychar->SetPosition(wp); } } if(eventrecv->key.pressed(KEY_KEY_S)) { if(_freeCameraMove) camera->moveBack(50 * timediff_f); else { f32 speedfactor = timediff_f * mychar->GetSpeed(MOVE_WALKBACK); movemgr->SetMoveMode(MOVEMODE_MANUAL); movemgr->MoveStartBackward(); WorldPosition wp = mychar->GetPosition(); _CalcXYMoveVect(wp.o); wp.x -= (xyCharMovement.X * speedfactor); wp.y -= (xyCharMovement.Y * speedfactor); wp.z = terrain->getHeight(WPToIrr(wp)); mychar->SetPosition(wp); } } // if right mouse button pressed, move in axis, if not, turn camera if(eventrecv->key.pressed(KEY_KEY_D)) { if(mouse_pressed_right) { if(_freeCameraMove) camera->moveRight(50 * timediff_f); else { // TODO: strafe case } } else { if(_freeCameraMove) camera->turnRight(timediff_f * M_PI * 25); else { movemgr->SetMoveMode(MOVEMODE_MANUAL); movemgr->MoveStartTurnRight(); WorldPosition wp = mychar->GetPosition(); wp.z = terrain->getHeight(WPToIrr(wp)); wp.o -= (timediff_f * mychar->GetSpeed(MOVE_TURN)); wp.o = RAD_FIX(wp.o); mychar->SetPosition(wp); _CalcXYMoveVect(wp.o); } } } if(eventrecv->key.pressed(KEY_KEY_A)) { if(mouse_pressed_right) { if(_freeCameraMove) camera->moveLeft(50 * timediff_f); else { // TODO: strafe case } } else { if(_freeCameraMove) camera->turnLeft(timediff_f * M_PI * 25); else { movemgr->SetMoveMode(MOVEMODE_MANUAL); movemgr->MoveStartTurnLeft(); WorldPosition wp = mychar->GetPosition(); wp.z = terrain->getHeight(WPToIrr(wp)); wp.o += (timediff_f * mychar->GetSpeed(MOVE_TURN)); wp.o = RAD_FIX(wp.o); mychar->SetPosition(wp); _CalcXYMoveVect(wp.o); } } } if(eventrecv->key.pressed(KEY_KEY_E)) { if(_freeCameraMove) camera->moveRight(50 * timediff_f); else {/* f32 speedfactor = timediff_f * mychar->GetSpeed(MOVE_RUN); movemgr->SetMoveMode(MOVEMODE_MANUAL); movemgr->MoveStartStrafeRight(); WorldPosition wp = mychar->GetPosition(); _CalcXYMoveVect(wp.o); wp.x -= (xyCharMovement.X * speedfactor); wp.y -= (xyCharMovement.Y * speedfactor); wp.z = terrain->getHeight(WPToIrr(wp)); mychar->SetPosition(wp); */} } if(eventrecv->key.pressed(KEY_KEY_Q)) { if(_freeCameraMove) camera->moveLeft(50 * timediff_f); else {/* f32 speedfactor = timediff_f * mychar->GetSpeed(MOVE_RUN); movemgr->SetMoveMode(MOVEMODE_MANUAL); movemgr->MoveStartStrafeLeft(); WorldPosition wp = mychar->GetPosition(); _CalcXYMoveVect(wp.o); wp.x -= (xyCharMovement.X * speedfactor); wp.y -= (xyCharMovement.Y * speedfactor); wp.z = terrain->getHeight(WPToIrr(wp)); mychar->SetPosition(wp); */} } /*if(eventrecv->key.pressed(KEY_SPACE)) { movemgr->SetMoveMode(MOVEMODE_MANUAL); movemgr->MoveJump(); }*/ // listen to *not* pressed keys only if manually moving if(movemgr->GetMoveMode() == MOVEMODE_MANUAL) { if (!eventrecv->key.pressed(KEY_KEY_D) && !eventrecv->key.pressed(KEY_KEY_A)) { movemgr->MoveStopTurn(); } if (!eventrecv->key.pressed(KEY_KEY_W) && !eventrecv->key.pressed(KEY_KEY_S) && !(mouse_pressed_left && mouse_pressed_right)) { movemgr->MoveStop(); } // TODO: add strafe case } // if we moved, relocate MyCharacter /*if(movemgr->IsMoved()) { MyCharacter *my = wsession->GetMyChar(); if(my) { WorldPosition newpos = GetWorldPosition(); my->SetPosition(newpos); } else { logerror("SceneWorld: Can't move MyCharacter, not found!"); } }*/ if(eventrecv->key.pressed_once(KEY_HOME)) { _freeCameraMove = !_freeCameraMove; // TODO: uncomment this as soon as the camera isn't adjusted anymore every single frame //if(!_freeCameraMove) // RelocateCameraBehindChar(); //TODO: this will not be needed anymore with the above code uncommented // make player always visble when switching to freefly mode scene::ISceneNode *charnode = GetMyCharacterSceneNode(); // NOTE: this call is absolutely not optimized! if(charnode) charnode->setVisible(true); } if(eventrecv->key.pressed_once(KEY_BACK)) { debugmode = !debugmode; // -- rendering with all debug flags uses WAY too much CPU to leave it turned on E_DEBUG_SCENE_TYPE dflags = E_DEBUG_SCENE_TYPE(debugmode ? (EDS_BBOX | EDS_BBOX_BUFFERS | EDS_SKELETON) : EDS_OFF); const core::list<scene::ISceneNode*>& nodelist = smgr->getRootSceneNode()->getChildren(); for(core::list<scene::ISceneNode*>::ConstIterator it = nodelist.begin(); it != nodelist.end(); it++) { (*it)->setDebugDataVisible(dflags); } // only terrain is especially useful with all debug flags enabled terrain->setDebugDataVisible(debugmode ? EDS_FULL : EDS_OFF); } if(eventrecv->key.pressed_once(KEY_INSERT)) { IImage *scrnshot = driver->createScreenShot(); if(scrnshot) { CreateDir("screenshots"); std::string date = getDateString(); for(uint32 i = 0; i < date.length(); i++) { if(date[i] == ':') date[i] = '_'; } if(date[date.length()-1] == ' ') { date = date.substr(0,date.length()-2); } driver->writeImageToFile(scrnshot, ("screenshots/PseuWoW " + date + ".jpg").c_str(), device->getTimer()->getRealTime()); scrnshot->drop(); } } // this fixes the camera getting screwed up by noob user; resets it back to a usable position if someone managed to flip it over if(camera->getPitch() < 270 && camera->getPitch() > 90) camera->turnUp(90); // camera distance control if (eventrecv->mouse.wheel < 0) eventrecv->mouse.wheel = 0; if(eventrecv->mouse.wheel > MAX_CAM_DISTANCE) eventrecv->mouse.wheel = MAX_CAM_DISTANCE; if(mouse_pressed_left || mouse_pressed_right) { if(mouse_pos != cursor->getMousePos()) { camera->turnRight(MOUSE_SENSIVITY * (device->getCursorControl()->getPosition().X - mouse_pos.X)); // check if new camera pitch would cause camera to flip over; if thats the case keep current pitch f32 upval = MOUSE_SENSIVITY * (device->getCursorControl()->getPosition().Y - mouse_pos.Y); f32 newval = camera->getPitch() + upval; if( newval > 270.1f || newval < 89.9f) { camera->turnUp(upval); } device->getCursorControl()->setPosition(mouse_pos); // rotate character if right mouse button pressed. if(mouse_pressed_right && !_freeCameraMove) { mychar->GetPositionPtr()->o = PI*3/2 - DEG_TO_RAD(camera->getHeading()); // send update to server only if we turned by some amount and not always when we turn if(!equals(old_char_o, mychar->GetO(), MOVE_TURN_UPDATE_DIFF)) { old_char_o = mychar->GetO(); movemgr->MoveSetFacing(); } } } } else { mouse_pos = device->getCursorControl()->getPosition(); } // TODO: check if the cam really has to be relocated; might save some CPU but not sure... if(_freeCameraMove) { camera->setHeight( terrain->getHeight(camera->getPosition()) + 4 ); } else { RelocateCameraBehindChar(); } core::stringw str = L""; DEBUG( WorldPosition wp = GetWorldPosition(); str += L" Camera: pitch:"; str += camera->getPitch(); str += L" c pos:"; str += camera->getPosition().X; str += L","; str += camera->getPosition().Y; str += L","; str += camera->getPosition().Z; str += L"\n"; str += " ## HEAD: "; str += IRR_TO_O(camera->getHeading()); str += L" Pos: "; str += wp.x; str += L" | "; str += wp.y; str += L" | "; str += wp.z; str += L" | OR:"; str += wp.o; // str += ((((((str + wp.x) + L" | ") + wp.y) + L" | ") + wp.z) + L" | OR:") + wp.o;// WTF? str += L" -- Terrain: Sectors: "; str += (int)terrain->getSectorsRendered(); str += L" / "; str += (int)terrain->getSectorCount(); str += L" ("; str += (u32)(((f32)terrain->getSectorsRendered()/(f32)terrain->getSectorCount())*100.0f); str += L"%)"; str += L" mwheel="; str += eventrecv->mouse.wheel; str += L"\n"; const core::list<scene::ISceneNode*>& nodelist = smgr->getRootSceneNode()->getChildren(); str += L"Scene nodes: total: "; str += nodelist.getSize(); str += L" visible: "; u32 vis = 0; for(core::list<scene::ISceneNode*>::ConstIterator it = nodelist.begin(); it != nodelist.end(); it++) if((*it)->isVisible()) vis++; str += vis; str += L"\n"; ); // END DEBUG;
bool WorldRenderer::Update() { // Update Terrain Routine UpdateTerrain(); // Cam Pos Vector3 camPos = zGraphics->GetCamera()->GetPosition(); // Don't update grass if we don't have a world if ( zWorld ) { // Check if we should render grass zGraphics->SetGrassFilePath("Media/Grass.png"); if ( zGraphics->GetRenderGrassFlag() ) { if ( (zLastGrassUpdatePos - camPos.GetXZ()).GetLength() >= zGrassUpdateDistance ) { std::map<Vector2UINT, int> grassSectors; // Remove Current Grass Sectors for( auto i = zGrass.cbegin(); i != zGrass.cend(); ++i ) { grassSectors[i->first]--; } // Insert New Sectors std::set<Vector2UINT> newSectorsSet; zWorld->GetSectorsInCicle(camPos.GetXZ(), zGrassFarDistance, newSectorsSet); for( auto i = newSectorsSet.cbegin(); i != newSectorsSet.cend(); ++i ) { grassSectors[*i]++; } // Update Sector Grasses for( auto i = grassSectors.cbegin(); i != grassSectors.cend(); ++i ) { if ( i->second < 0 ) { auto grassIt = zGrass.find(i->first); if ( grassIt != zGrass.cend() ) { if ( grassIt->second ) { zGraphics->DeleteBillboardCollection(grassIt->second); } zGrass.erase(grassIt); } } else if ( i->second > 0 ) { GenerateGrass(i->first); } } zLastGrassUpdatePos = camPos.GetXZ(); } } } // Check Distance if ( (zLastEntUpdatePos - camPos).GetLength() > 10.0f ) { // Update Existing LOD for( auto i = zEntities.cbegin(); i != zEntities.cend(); ++i ) { zEntsToUpdate.insert(i->first); } // Scan New Entities if ( zWorld ) { zWorld->GetEntitiesInCircle(camPos.GetXZ(), zGraphics->GetEngineParameters().FarClip, zEntsToUpdate); } // Update Position zLastEntUpdatePos = camPos; } // Update a between 10% and a minimum of 25 unsigned int x = zEntsToUpdate.size() / 10; if ( x < 25 ) x = 25; if ( x > 100 ) x = 100; auto i = zEntsToUpdate.begin(); while( i != zEntsToUpdate.end() ) { SetEntityGraphics(*i); i = zEntsToUpdate.erase(i); if ( !x || !--x ) break; } // Check if there is more to be updated return ( zEntsToUpdate.size() > 0 || zUpdatesRequired.size() > 0 ); }
void UpdateAll() { UpdateTopography(); UpdateTerrain(); UpdateWeather(); }