1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010-2020 Winch Gate Property Limited
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2013 Laszlo KIS-ADAM (dfighter) <dfighter1985@gmail.com>
6 // Copyright (C) 2013-2020 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
8 // This program is free software: you can redistribute it and/or modify
9 // it under the terms of the GNU Affero General Public License as
10 // published by the Free Software Foundation, either version 3 of the
11 // License, or (at your option) any later version.
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU Affero General Public License for more details.
18 // You should have received a copy of the GNU Affero General Public License
19 // along with this program. If not, see <http://www.gnu.org/licenses/>.
30 #include "nel/misc/path.h"
31 #include "nel/misc/i18n.h"
32 #include "nel/misc/hierarchical_timer.h"
33 #include "nel/misc/displayer.h"
34 #include "nel/misc/value_smoother.h"
35 #include "nel/misc/geom_ext.h"
37 #include "nel/net/module_manager.h"
39 #include "nel/3d/bloom_effect.h"
40 #include "nel/3d/u_driver.h"
41 #include "nel/3d/u_scene.h"
42 #include "nel/3d/u_landscape.h"
43 #include "nel/3d/u_camera.h"
44 #include "nel/3d/u_text_context.h"
45 #include "nel/3d/u_instance.h"
46 #include "nel/3d/u_material.h"
47 #include "nel/3d/u_instance_material.h"
48 #include "nel/3d/u_cloud_scape.h"
49 #include "nel/3d/stereo_hmd.h"
50 #include "nel/3d/render_target_manager.h"
51 #include "nel/3d/driver_user.h"
52 #include "nel/3d/fxaa.h"
54 #include "game_share/brick_types.h"
55 #include "game_share/light_cycle.h"
56 #include "game_share/time_weather_season/time_and_season.h"
57 #include "game_share/bot_chat_types.h"
59 #include "nel/pacs/u_global_position.h"
61 #include "client_sheets/weather_function_params_sheet.h"
65 #include "game_share/constants.h"
66 #include "main_loop.h"
68 #include "client_cfg.h"
69 #include "actions_client.h"
70 #include "motion/user_controls.h"
71 #include "entity_animation_manager.h"
72 #include "pacs_client.h"
74 #include "time_client.h"
75 #include "cursor_functions.h"
76 #include "pacs_client.h"
77 #include "entity_fx.h"
78 #include "light_cycle_manager.h"
79 #include "weather_manager_client.h"
81 #include "game_share/time_weather_season/weather_predict.h"
83 #include "net_manager.h"
84 #include "world_database_manager.h"
85 #include "continent_manager.h"
86 #include "ig_callback.h"
88 //#include "fog_map.h"
89 #include "movie_shooter.h"
90 #include "sound_manager.h"
92 #include "interface_v3/interface_manager.h"
94 #include "color_slot_manager.h"
95 #include "interface_v3/input_handler_manager.h"
96 #include "ingame_database_manager.h"
97 #include "sky_render.h"
98 #include "prim_file.h"
100 #include "interface_v3/people_interraction.h"
101 #include "debug_client.h"
102 #include "nel/gui/action_handler.h"
103 #include "interface_v3/action_handler_misc.h"
104 #include "interface_v3/action_handler_item.h"
105 #include "fx_manager.h"
106 #include "ground_fx_manager.h"
107 #include "string_manager_client.h"
108 #include "interface_v3/group_in_scene_bubble.h"
109 #include "game_context_menu.h"
110 #include "init_main_loop.h"
111 #include "micro_life_manager.h"
112 #include "timed_fx_manager.h"
113 #include "interface_v3/sphrase_manager.h"
114 #include "outpost_manager.h"
115 #include "sky.h" // new-style sky
116 #include "sky_render.h" // new-style sky
117 #include "interface_v3/music_player.h"
118 #include "permanent_ban.h"
119 #include "camera_recorder.h"
120 #include "connection.h"
121 #include "landscape_poly_drawer.h"
122 #include "nel/gui/lua_ihm.h"
123 #include "interface_v3/lua_ihm_ryzom.h"
125 #include "session_browser_impl.h"
126 #include "bg_downloader_access.h"
127 #include "login_progress_post_thread.h"
128 #include "npc_icon.h"
129 #include "item_group_manager.h"
131 #include "r2/editor.h"
133 #include "nel/misc/check_fpu.h"
137 #ifdef USE_WATER_ENV_MAP
138 #include "water_env_map_rdr.h"
142 #include "precipitation.h"
143 #include "interface_v3/bot_chat_manager.h"
144 #include "string_manager_client.h"
146 #include "nel/gui/lua_manager.h"
147 #include "nel/gui/group_table.h"
149 // pulled from main_loop.cpp
151 #include "profiling.h"
153 #include "main_loop_debug.h"
154 #include "main_loop_temp.h"
155 #include "main_loop_utilities.h"
161 using namespace NLMISC
;
162 using namespace NL3D
;
163 using namespace NLPACS
;
164 using namespace NLNET
;
168 #define new DEBUG_NEW
177 extern UDriver
*Driver
;
178 extern UScene
*Scene
;
179 extern UScene
*SceneRoot
;
180 extern ULandscape
*Landscape
;
181 extern UCloudScape
*CloudScape
;
182 extern bool InitCloudScape
;
183 extern CLandscapeIGManager LandscapeIGManager
;
184 extern UTextContext
*TextContext
;
185 extern CEntityAnimationManager
*EAM
;
186 extern TTime UniversalTime
;
187 extern UMaterial GenericMat
;
188 extern UCamera MainCam
;
189 extern CEventsListener EventsListener
;
190 extern CMatrix MainSceneViewMatrix
;
191 extern CMatrix InvMainSceneViewMatrix
;
192 extern std::vector
<UTextureFile
*> LogoBitmaps
;
193 extern bool IsInRingSession
;
194 extern std::string UsedFSAddr
;
197 extern NLMISC::CValueSmoother smoothFPS
;
198 extern NLMISC::CValueSmoother moreSmoothFPS
;
200 void loadBackgroundBitmap (TBackground background
);
201 void destroyLoadingBitmap ();
202 void drawLoadingBitmap (float progress
);
203 void updateStatReport ();
205 CFogState MainFogState
;
206 CFogState RootFogState
;
209 #define RYZOM_FIRST_FRAME_TO_SKIP 30
212 const float CANOPY_DEPTH_RANGE_START
= 0.95f
;
213 const float SKY_DEPTH_RANGE_START
= 0.99f
;
217 float SimulatedServerDate
= 0.f
;
218 uint64 SimulatedServerTick
= 0;
226 bool game_exit
= false;
227 bool ryzom_exit
= false;
228 bool game_exit_request
= false;
229 bool ryzom_exit_request
= false;
230 bool paying_account_request
= false;
231 bool paying_account_already_request
= false;
232 bool game_exit_after_paying_account_request
= false;
235 float MouseX
; // Mouse pos X for the frame.
236 float MouseY
; // Mouse pos Y for the frame.
237 float OldMouseX
; // Mouse pos X of the last frame.
238 float OldMouseY
; // Mouse pos Y of the last frame.
240 uint32 Width
; // Width of the window.
241 uint32 Height
; // Height of the window.
242 uint32 OldWidth
; // Last Width of the window.
243 uint32 OldHeight
; // Last Height of the window.
245 bool ShowInterface
= true; // Do the Chat OSD have to be displayed.
246 bool DebugUIView
= false;
247 bool DebugUICtrl
= false;
248 bool DebugUIGroup
= false;
249 std::string DebugUIFilter
;
250 bool ShowHelp
= false; // Do the Help have to be displayed.
251 uint8 ShowInfos
= 0; // 0=no info 1=text info 2=graph info
253 bool bZeroCpu
= false; // For no Cpu use if application is minimize TODO: intercept minimize message, called by CTRL + Z at this
255 bool MovieShooterSaving
= false; // Are we in Shooting mode?
258 bool DisplayWeatherFunction
= false;
261 float DelayBeforeCloudUpdate
= 0.f
; // delay in s before cloud state must be recomputed
262 const float CloudUpdatePeriod
= 45.f
; // period used for clouds update
264 TScreenshotRequest ScreenshotRequest
= ScreenshotRequestNone
;
267 // First frames to skip
268 bool FirstFrame
= false;
271 // temp : for timed fxs test
272 bool ShowTimedFX
= false;
273 CTimedFXManager::TDebugDisplayMode ShowTimedFXMode
= CTimedFXManager::NoText
;
275 //CGraph FpsGraph ("frame rate (fps)", 10.0f, 110.0f, 100.0f, 100.0f, CRGBA(128,0,0,128), 1000, 60.0f);
276 //CGraph SpfGraph ("mspf", 10.0f, 10.0f, 100.0f, 100.0f, CRGBA(0,128,0,128), 0, 800.0f);
278 //CGraph CameraThirPersonGraph ("Camera Thir Person", 300.0f, 460.0f, 200.0f, 200.0f, CRGBA(0,64,128,128), 0, 5.0f, 1);
281 bool PACSBorders
= false;
282 bool ARKPACSBorders
= false;
283 bool DebugClusters
= false;
284 CVector LastDebugClusterCameraThirdPersonStart
= CVector::Null
;
285 CVector LastDebugClusterCameraThirdPersonEnd
= CVector::Null
;
286 CVector LastDebugClusterCameraThirdPersonTestStart
= CVector::Null
;
287 CVector LastDebugClusterCameraThirdPersonPelvisPos
= CVector::Null
;
288 CVector LastDebugClusterCameraThirdPersonResult
= CVector::Null
;
289 bool LastDebugClusterCameraThirdPersonForceFPV
= false;
290 bool SoundBox
= false;
292 sint CompassMode
= 0; // 0: compass with regard to the user front, 1: to the camera direction.
294 float BanMsgCountdown
= 0.f
;
295 const float BanMsgRepeatTime
= 5.f
;
297 CGameContextMenu GameContextMenu
;
303 static CRefPtr
<CCDBNodeLeaf
> s_FpsLeaf
;
304 static CRefPtr
<CCDBNodeLeaf
> s_UiDirectionLeaf
;
318 bool Filter3D
[RYZOM_MAX_FILTER_3D
] = {true, true, true, true, true, true, true, true, true, true};
319 bool Scene_Profile
= false;
323 // Hierarchical timer
324 H_AUTO_DECL ( RZ_Client_Check_Actions
)
325 H_AUTO_DECL ( RZ_Client_Main_Loop
)
326 H_AUTO_DECL ( RZ_Client_Main_Loop_Zero_Cpu
)
327 H_AUTO_DECL ( RZ_Client_Main_Loop_Cursor
)
328 H_AUTO_DECL ( RZ_Client_Main_Loop_Time_Update
)
329 H_AUTO_DECL ( RZ_Client_Main_Loop_Selection_FX
)
330 H_AUTO_DECL ( RZ_Client_Main_Loop_Sky_And_Weather
)
331 H_AUTO_DECL ( RZ_Client_Main_Loop_Render_Root
)
332 H_AUTO_DECL ( RZ_Client_Main_Loop_Render_Main
)
333 H_AUTO_DECL ( RZ_Client_Main_Loop_Anim_Cloud_Scape
)
334 H_AUTO_DECL ( RZ_Client_Main_Loop_Update_Cloud_Scape
)
335 H_AUTO_DECL ( RZ_Client_Main_Loop_Render_Cloud_Scape
)
336 H_AUTO_DECL ( RZ_Client_Main_Loop_Debug
)
337 H_AUTO_DECL ( RZ_Client_Main_Loop_Guild_Symbol
)
338 H_AUTO_DECL ( RZ_Client_Main_Loop_Render_Thunder
)
339 H_AUTO_DECL ( RZ_Client_Main_Loop_Interface
)
340 H_AUTO_DECL ( RZ_Client_Main_Loop_Sound
)
341 H_AUTO_DECL ( RZ_Client_Main_Loop_Net
)
347 //update the sound manager (listener pos, user walk/run sound...)
350 void displaySpecialTextProgress(const char *text
);
352 void endMovieShooting();
353 void updateMovieShooting();
355 void updateLightDesc();
358 void displayPACSBorders();
359 void displayPACSPrimitive();
360 void displaySoundBox();
361 void displayDebugClusters();
363 void displaySceneProfiles();
365 // validate current dialogs (end them if the player is too far from its interlocutor)
366 void validateDialogs(const CGameContextMenu
&gcm
);
369 // ***************************************************************************
371 enum TSkyMode
{ NoSky
, OldSky
, NewSky
};
372 static TSkyMode s_SkyMode
= NoSky
;
374 void preRenderNewSky ()
376 CSky
&sky
= ContinentMngr
.cur()->CurrentSky
;
377 // setup fog, lighting & sky object. We use the same light direction than with the main scene
378 CClientDate cd
= SmoothedClientDate
;
379 if (ClientCfg
.R2EDEnabled
&& R2::getEditor().getFixedLighting())
383 sky
.setup(cd
, SmoothedClientDate
, WeatherManager
.getWeatherValue(), MainFogState
.FogColor
, Scene
->getSunDirection(), false);
388 // Set the sky camera
389 if (s_SkyMode
== NewSky
)
391 CSky
&sky
= ContinentMngr
.cur()->CurrentSky
;
393 CFrustum frust
= MainCam
.getFrustum();
394 UCamera camSky
= sky
.getScene()->getCam();
395 sky
.getScene()->setViewport(Scene
->getViewport());
396 camSky
.setTransformMode(UTransform::DirectMatrix
);
397 // must have our own Far!!!
398 frust
.Far
= SkyCameraZFar
;
399 camSky
.setFrustum(frust
);
400 CMatrix skyCameraMatrix
;
401 skyCameraMatrix
.identity();
402 skyCameraMatrix
= MainCam
.getMatrix();
403 skyCameraMatrix
.setPos(CVector::Null
);
404 camSky
.setMatrix(skyCameraMatrix
);
407 // Set The Root Camera
408 UCamera camRoot
= SceneRoot
->getCam();
411 // Update Camera Position/Rotation.
412 //camRoot.setPos(View.currentViewPos());
413 //camRoot.setRotQuat(View.currentViewQuat());
414 camRoot
.setPos(MainCam
.getPos());
415 camRoot
.setRotQuat(MainCam
.getRotQuat());
419 // ***************************************************************************
421 void beginRenderCanopyPart()
423 SceneRoot
->beginPartRender();
425 void endRenderCanopyPart()
427 SceneRoot
->endPartRender(false);
430 void beginRenderMainScenePart()
432 Scene
->beginPartRender();
434 void endRenderMainScenePart(bool keepTraversals
)
436 Scene
->endPartRender(!keepTraversals
, true, keepTraversals
);
439 void beginRenderSkyPart()
441 if (s_SkyMode
== NewSky
)
443 CSky
&sky
= ContinentMngr
.cur()->CurrentSky
;
444 sky
.getScene()->beginPartRender();
447 void endRenderSkyPart()
449 if (s_SkyMode
== NewSky
)
451 CSky
&sky
= ContinentMngr
.cur()->CurrentSky
;
452 sky
.getScene()->endPartRender(false);
457 // ***************************************************************************************************************************
458 // Render a part of the canopy
459 static void renderCanopyPart(UScene::TRenderPart renderPart
)
461 H_AUTO_USE ( RZ_Client_Main_Loop_Render_Root
)
462 Driver
->setDepthRange(CANOPY_DEPTH_RANGE_START
, SKY_DEPTH_RANGE_START
);
464 ContinentMngr
.getFogState(CanopyFog
, LightCycleManager
.getLightLevel(), LightCycleManager
.getLightDesc().DuskRatio
, LightCycleManager
.getState(), View
.viewPos(), RootFogState
);
465 RootFogState
.setupInDriver(*Driver
);
467 // Render the root scene
468 SceneRoot
->renderPart(renderPart
);
471 // ***************************************************************************************************************************
472 // Render a part of the main scene
473 static void renderMainScenePart(UScene::TRenderPart renderPart
, bool wantTraversals
, bool keepTraversals
)
475 H_AUTO_USE ( RZ_Client_Main_Loop_Render_Main
)
476 Driver
->setDepthRange(0.f
, CANOPY_DEPTH_RANGE_START
);
477 if(ClientCfg
.Fog
== false )
479 Driver
->enableFog (false);
483 MainFogState
.setupInDriver (*Driver
);
485 Scene
->renderPart(renderPart
, true, wantTraversals
, keepTraversals
);
489 // ***************************************************************************************************************************
490 // Render a part of the sky
491 static void renderSkyPart(UScene::TRenderPart renderPart
)
493 nlassert(s_SkyMode
!= NoSky
);
494 Driver
->setDepthRange(SKY_DEPTH_RANGE_START
, 1.f
);
495 Driver
->enableFog(false);
496 if (s_SkyMode
== NewSky
)
498 CSky
&sky
= ContinentMngr
.cur()->CurrentSky
;
499 sky
.getScene()->renderPart(renderPart
);
504 renderSky(LightCycleManager
, MainFogState
.FogColor
);
507 if (CloudScape
!= NULL
&& Filter3D
[FilterCloud
])
509 H_AUTO_USE( RZ_Client_Main_Loop_Render_Cloud_Scape
)
510 CloudScape
->render ();
515 // ***************************************************************************************************************************
516 // Utility to force full detail
517 struct CForceFullDetail
522 maxFullDetailChar
= Scene
->getMaxSkeletonsInNotCLodForm();
523 oldBalancingMode
= Scene
->getPolygonBalancingMode();
524 oldSkyBalancingMode
= UScene::PolygonBalancingOff
;
525 UScene
*skyScene
= getSkyScene();
526 if (skyScene
) oldSkyBalancingMode
= skyScene
->getPolygonBalancingMode();
530 Scene
->setMaxSkeletonsInNotCLodForm(1000000);
531 Scene
->setPolygonBalancingMode(UScene::PolygonBalancingOff
);
532 UScene
*skyScene
= getSkyScene();
533 if (skyScene
) skyScene
->setPolygonBalancingMode(UScene::PolygonBalancingOff
);
537 Scene
->setMaxSkeletonsInNotCLodForm(maxFullDetailChar
);
538 Scene
->setPolygonBalancingMode(oldBalancingMode
);
539 UScene
*skyScene
= getSkyScene();
540 if (skyScene
) skyScene
->setPolygonBalancingMode(oldSkyBalancingMode
);
543 uint maxFullDetailChar
;
544 UScene::TPolygonBalancingMode oldBalancingMode
;
545 UScene::TPolygonBalancingMode oldSkyBalancingMode
;
547 static CForceFullDetail s_ForceFullDetail
;
553 if (Driver
->getPolygonMode() == UDriver::Filled
)
555 Driver
->clearZBuffer();
558 // Sky is used to clear the frame buffer now, but if in line or point polygon mode, we should draw it
559 if (Driver
->getPolygonMode() != UDriver::Filled
|| !Filter3D
[FilterSky
])
561 if (!Driver
->isLost())
563 Driver
->clearBuffers (ClientCfg
.BGColor
);
569 Driver
->clearBuffers(ClientCfg
.BGColor
);
573 void renderScene(bool forceFullDetail
, bool bloom
)
575 CTextureUser
*effectRenderTarget
= NULL
;
578 // set bloom parameters before applying bloom effect
579 CBloomEffect::getInstance().setSquareBloom(ClientCfg
.SquareBloom
);
580 CBloomEffect::getInstance().setDensityBloom((uint8
)ClientCfg
.DensityBloom
);
582 // init effect render target
583 Driver
->beginDefaultRenderTarget();
587 s_ForceFullDetail
.backup();
588 s_ForceFullDetail
.set();
591 doRenderScene(true, false);
594 s_ForceFullDetail
.restore();
598 // apply bloom effect
599 CBloomEffect::getInstance().applyBloom();
601 // draw final result to backbuffer
602 Driver
->endDefaultRenderTarget(Scene
);
606 // ***************************************************************************************************************************
608 void updateWaterEnvMap()
610 #ifdef USE_WATER_ENV_MAP
611 if (WaterEnvMapRefCount
> 0) // water env map needed
615 CSky
&sky
= ContinentMngr
.cur()->CurrentSky
;
618 nlassert(WaterEnvMapSkyCam
.empty());
619 WaterEnvMapSkyCam
= sky
.getScene()->createCamera(); // deleted in unselect
620 nlassert(WaterEnvMapCanopyCam
.empty());
621 WaterEnvMapCanopyCam
= SceneRoot
->createCamera(); // deleted in unselect
622 // Create water env map if not already created
623 WaterEnvMap
= Driver
->createWaterEnvMap();
626 WaterEnvMap
->init(128, 256, ClientCfg
.WaterEnvMapUpdateTime
);
627 WaterEnvMap
->setWaterEnvMapRenderCallback(&WaterEnvMapRdr
);
628 Scene
->setWaterEnvMap(WaterEnvMap
);
632 WaterEnvMapRdr
.CurrDate
= SmoothedClientDate
;
633 WaterEnvMapRdr
.AnimationDate
= SmoothedClientDate
;
634 if (ClientCfg
.R2EDEnabled
&& R2::getEditor().getFixedLighting())
636 WaterEnvMapRdr
.CurrDate
.Hour
= 12.f
;
638 WaterEnvMapRdr
.CurrFogColor
= MainFogState
.FogColor
;
639 WaterEnvMapRdr
.CurrTime
= TimeInSec
- FirstTimeInSec
;
640 WaterEnvMapRdr
.CurrWeather
= WeatherManager
.getWeatherValue();
641 CSky
&sky
= ContinentMngr
.cur()->CurrentSky
;
642 WaterEnvMap
->setAlpha(sky
.getWaterEnvMapAlpha());
643 Scene
->updateWaterEnvMaps(TimeInSec
- FirstTimeInSec
);
648 // ***************************************************************************************************************************
652 H_AUTO_USE ( RZ_Client_Main_Loop_Sky_And_Weather
)
654 //HeightGrid.update(Scene->getCam().getPos());
656 // update description of light cycle
659 // server driven weather mgt
660 updateDBDrivenWeatherValue();
662 // Update the weather manager
663 updateWeatherManager(MainCam
.getMatrix(), ContinentMngr
.cur());
665 // compute thunder color
666 ThunderColor
.modulateFromui(WeatherManager
.getCurrWeatherState().ThunderColor
, (uint
) (256.f
* WeatherManager
.getThunderLevel()));
668 // Update the lighting
669 LightCycleManager
.setHour(DayNightCycleHour
, WeatherManager
, ThunderColor
);
672 if (Filter3D
[FilterCloud
])
674 H_AUTO_USE ( RZ_Client_Main_Loop_Update_Cloud_Scape
);
679 ContinentMngr
.getFogState(MainFog
, LightCycleManager
.getLightLevel(), LightCycleManager
.getLightDesc().DuskRatio
, LightCycleManager
.getState(), View
.viewPos(), MainFogState
);
681 // TODO: ZBuffer clear was originally before this, but should not be necessary normally.
682 // The anim function renders new clouds. Ensure this does not break.
683 // These are old-style nel clouds.
686 if (CloudScape
!= NULL
&& Filter3D
[FilterCloud
])
688 H_AUTO_USE ( RZ_Client_Main_Loop_Anim_Cloud_Scape
);
690 Driver
->enableFog (false);
692 // Force polygon mode to filled
693 NL3D::UDriver::TPolygonMode oldMode
= Driver
->getPolygonMode();
694 Driver
->setPolygonMode(NL3D::UDriver::Filled
);
696 CloudScape
->anim (DT
); // WARNING this function work with screen
698 Driver
->enableFog (true);
700 // Reset backuped polygon mode
701 Driver
->setPolygonMode(oldMode
);
707 if (ContinentMngr
.cur() && !ContinentMngr
.cur()->Indoor
)
709 if(Driver
->getPolygonMode() == UDriver::Filled
)
711 if (Filter3D
[FilterSky
])
713 CSky
&sky
= ContinentMngr
.cur()->CurrentSky
;
717 sky
.getScene()->animate(TimeInSec
-FirstTimeInSec
);
718 // Setup the sky camera
730 void beginRenderScene()
732 // Update Filter Flags
733 Scene
->enableElementRender(UScene::FilterAllMeshNoVP
, Filter3D
[FilterMeshNoVP
]);
734 Scene
->enableElementRender(UScene::FilterAllMeshVP
, Filter3D
[FilterMeshVP
]);
735 Scene
->enableElementRender(UScene::FilterFX
, Filter3D
[FilterFXs
]);
736 Scene
->enableElementRender(UScene::FilterLandscape
, Filter3D
[FilterLandscape
]);
737 Scene
->enableElementRender(UScene::FilterSkeleton
, Filter3D
[FilterSkeleton
]);
738 Scene
->enableElementRender(UScene::FilterWater
, Filter3D
[FilterWater
]);
739 Scene
->enableElementRender(UScene::FilterCoarseMesh
, Filter3D
[FilterCoarseMesh
]);
741 // profile this frame?
743 Scene
->profileNextRender();
745 // initialisation of polygons renderer
746 CLandscapePolyDrawer::getInstance().beginRenderLandscapePolyPart();
748 // Start Part Rendering
749 beginRenderCanopyPart();
750 beginRenderMainScenePart();
751 beginRenderSkyPart();
754 void drawRenderScene(bool wantTraversals
, bool keepTraversals
)
757 // WARNING: always must begin rendering with at least UScene::RenderOpaque,
758 // else dynamic shadows won't work
759 renderCanopyPart(UScene::RenderOpaque
);
760 renderMainScenePart(UScene::RenderOpaque
, wantTraversals
, keepTraversals
);
762 // render of polygons on landscape
763 CLandscapePolyDrawer::getInstance().renderLandscapePolyPart();
765 if (s_SkyMode
!= NoSky
) renderSkyPart((UScene::TRenderPart
) (UScene::RenderOpaque
| UScene::RenderTransparent
));
766 renderCanopyPart((UScene::TRenderPart
) (UScene::RenderTransparent
| UScene::RenderFlare
));
767 renderMainScenePart((UScene::TRenderPart
) (UScene::RenderTransparent
| UScene::RenderFlare
), wantTraversals
, keepTraversals
);
768 if (s_SkyMode
== NewSky
) renderSkyPart(UScene::RenderFlare
);
771 void endRenderScene(bool keepTraversals
)
773 // End Part Rendering
775 endRenderMainScenePart(keepTraversals
);
776 endRenderCanopyPart();
779 Driver
->setDepthRange(0.f
, CANOPY_DEPTH_RANGE_START
);
782 // ***************************************************************************************************************************
784 void doRenderScene(bool wantTraversals
, bool keepTraversals
)
787 drawRenderScene(wantTraversals
, keepTraversals
);
788 endRenderScene(keepTraversals
);
792 // ***************************************************************************
801 CMusicFader(uint nframeToSkip
, float fadeTime
)
803 NFrameSkip
= nframeToSkip
;
805 fadeTime
= max(fadeTime
, 0.01f
);
812 void CMusicFader::fade()
815 if(NFrameSkip
==0 && Done
)
821 // stop music (slow fade out of 3 secondes)
823 SoundMngr
->stopMusic(uint(TotalTime
*1000));
830 // ***************************************************************************
831 void updateGameQuitting()
833 static sint64 firstTimeLostConnection
= 0;
835 // Yoyo: prefer now leave the user press "Quit Now" if don't want to wait server
837 // if want quiting, and if server stalled, quit now
838 if(game_exit_request)
840 // abort until 10 seconds if connection lost
841 if(!NetMngr.getConnectionQuality())
843 if(!firstTimeLostConnection)
844 firstTimeLostConnection= T1;
848 firstTimeLostConnection= 0;
851 // if connection lost until 10 seconds
852 if(firstTimeLostConnection && T1-firstTimeLostConnection > 10000)
855 ryzom_exit= ryzom_exit_request;
861 firstTimeLostConnection= 0;
865 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
867 CInterfaceGroup
*group
= dynamic_cast<CInterfaceGroup
*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:free_trial_game_quitting"));
871 if(paying_account_request
)
873 // if no current modal window, or if not the quit window
874 if(group
!= CWidgetManager::getInstance()->getModalWindow())
877 CWidgetManager::getInstance()->disableModalWindow();
878 CWidgetManager::getInstance()->enableModalWindow(NULL
, group
);
884 // if the current modal window is the quit window, disable
885 if(group
== CWidgetManager::getInstance()->getModalWindow())
888 CWidgetManager::getInstance()->disableModalWindow();
893 group
= dynamic_cast<CInterfaceGroup
*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:game_quitting"));
897 if(game_exit_request
&& !paying_account_request
)
899 // if no current modal window, or if not the quit window
900 if(group
!= CWidgetManager::getInstance()->getModalWindow())
903 CWidgetManager::getInstance()->disableModalWindow();
904 CWidgetManager::getInstance()->enableModalWindow(NULL
, group
);
906 bool farTPing
= FarTP
.isFarTPInProgress();
907 // Far TP: skipping not allowed (because we can't duplicate the avatar...), anyway the quit button would quit the game (no far tp)
908 CInterfaceElement
*quitNowButton
= group
->getElement(group
->getId() + ":indent_middle:ryzom");
910 quitNowButton
->setActive(!farTPing
);
911 // From ring session or from mainland's ring access point: cancelling not allowed (would lead to inconsistencies with the SU & DSS)
912 CInterfaceElement
*backToGame
= group
->getElement(group
->getId() + ":indent_middle:cancel");
914 backToGame
->setActive(!(farTPing
&& (IsInRingSession
|| FarTP
.isFastDisconnectGranted())));
915 CInterfaceElement
*quittingRules
= group
->getElement(group
->getId() + ":text_mean");
917 quittingRules
->setActive(!farTPing
);
918 CInterfaceElement
*quittingText
= group
->getElement(group
->getId() + ":text");
920 quittingText
->setActive(!farTPing
);
926 // if the current modal window is the quit window, disable
927 if(group
== CWidgetManager::getInstance()->getModalWindow())
930 CWidgetManager::getInstance()->disableModalWindow();
937 void setDefaultChatWindow(CChatWindow
*defaultChatWindow
)
939 if (defaultChatWindow
)
941 CInterfaceManager
*im
= CInterfaceManager::getInstance();
942 if (defaultChatWindow
->getContainer())
944 CInterfaceGroup
*ig
= defaultChatWindow
->getContainer()->getGroup("eb");
945 if (ig
) CWidgetManager::getInstance()->setDefaultCaptureKeyboard(ig
);
950 void updateDayNightCycleHour()
952 if (ClientCfg
.R2EDEnabled
&& R2::getEditor().getFixedLighting())
954 DayNightCycleHour
= 12.f
;
958 // if there's a forced time, apply it
959 if( ForcedDayNightCycleHour
< 0 )
960 DayNightCycleHour
= (float)RT
.getRyzomTime();
962 DayNightCycleHour
= ForcedDayNightCycleHour
;
967 // ***************************************************************************
968 //---------------------------------------------------
970 // Main loop of the application (displayer, input, ...).
971 // Return true to exit the game, false to return to character selection
972 //---------------------------------------------------
977 NLMISC::TTime initStart
= ryzomGetLocalTime();
978 NLMISC::TTime initLast
= initStart
;
979 NLMISC::TTime initCurrent
= initLast
;
982 game_exit_request
= false;
983 paying_account_request
= false;
984 paying_account_already_request
= false;
985 game_exit_after_paying_account_request
= false;
986 FarTP
.setMainLoopEntered();
988 nlinfo ("Starting main loop...", (uint32
)(initCurrent
-initLast
)/1000, (uint32
)(initCurrent
-initStart
)/1000);
990 // Get the Width and Height of the window and set the Old values..
991 Driver
->getWindowSize(Width
, Height
);
992 OldWidth
= Width
; OldHeight
= Height
;
994 CGraph::init( Driver
);
995 CGraph::Display
= false;
997 T1
= ryzomGetLocalTime (); //(sint64)CGDTime::getTime (); // \todo GUIGUI : VOIR COMMENT MANAGER LE TEMPS
998 TSend
= ((T1
+DTSend
)/DTSend
)*DTSend
;
1000 // initialize the structure for the ping.
1003 // Call a function for a demo to init.
1005 if (ClientCfg
.Local
)
1007 if (!ClientCfg
.Light
)
1011 // Get the Connection State.
1012 CNetworkConnection::TConnectionState lastConnectionState
= CNetworkConnection::Connected
;
1013 CNetworkConnection::TConnectionState connectionState
= NetMngr
.getConnectionState();
1017 SetMouseFreeLook ();
1020 ContextCur
.context("STAND BY");
1021 UserControls
.reset();
1023 // set the default box for keyboard
1024 setDefaultChatWindow(PeopleInterraction
.ChatGroup
.Window
);
1027 // Init GameContextMenu.
1028 GameContextMenu
.init("");
1031 Actions
.enable(true);
1032 EditActions
.enable(true);
1034 // For stoping the outgame music, start after 30 frames, and duration of 3 seconds
1035 CMusicFader
outgameFader(60, 3);
1038 // check for banned player
1039 if (testPermanentBanMarkers())
1041 setPermanentBanMarkers(true); // re-set any marker that could have been removed by the trouble maker
1042 applyPermanentBanPunishment();
1043 PermanentlyBanned
= true;
1047 CNiceInputAuto niceInputs
;
1048 // R2 editor and modules
1049 R2::getEditor().autoConfigInit(IsInRingSession
);
1051 if (ClientCfg
.BeepWhenLaunched
)
1055 Driver
->showWindow();
1060 CurrSeason
= computeCurrSeason();
1062 initLast
= initCurrent
;
1063 initCurrent
= ryzomGetLocalTime();
1064 nlinfo ("PROFILE: %d seconds (%d total) for Starting main loop", (uint32
)(initCurrent
-initLast
)/1000, (uint32
)(initCurrent
-initStart
)/1000);
1066 if (ClientCfg
.R2EDEnabled
&& !ClientCfg
.Local
)
1068 R2::getEditor().waitScenario();
1071 CSessionBrowserImpl::getInstance().init(CLuaManager::getInstance().getLuaState());
1074 CLuaManager::getInstance().executeLuaScript("game:onMainLoopBegin()");
1077 if (StartInitTime
!= 0)
1079 CLoginProgressPostThread::getInstance().step(CLoginStep(LoginStep_InGameEntry
, "login_step_game_entry&load_time=" + toString((NLMISC::CTime::getLocalTime() - StartInitTime
) / 1000)));
1083 ProgressBar
.finish();
1085 bool musicTriggerAutoPlay
= true;
1087 // Main loop. If the window is no more Active -> Exit.
1088 while( !UserEntity
->permanentDeath()
1091 // If an action handler execute. NB: MUST BE DONE BEFORE ANY THING ELSE PROFILE CRASH!!!!!!!!!!!!!!!!!
1092 testLaunchProfile();
1094 // Test and may run a VBLock profile (only once)
1095 testLaunchProfileVBLock();
1098 H_AUTO_USE ( RZ_Client_Main_Loop
)
1100 #ifdef RYZOM_BG_DOWNLOADER
1101 if (isBGDownloadEnabled())
1103 CBGDownloaderAccess
&bgDownloader
= CBGDownloaderAccess::getInstance();
1104 // if the ui is frozen, wait for a few frame to allow client to do first frame load,
1105 // without having to compete with the downloader frame
1106 if (!FirstFrame
&& bgDownloader
.isDownloaderUIFrozen() && SkipFrame
== 0)
1108 unpauseBGDownloader();
1115 EGSPD::CSeason::TSeason newLocalSeason
= computeCurrSeason();
1116 if (newLocalSeason
!= CurrSeason
)
1118 LoadingBackground
= TeleportKaravanBackground
;
1119 beginLoading (LoadingBackground
);
1120 extern void selectTipsOfTheDay (uint tips
);
1121 selectTipsOfTheDay (rand());
1122 UseEscapeDuringLoading
= false;
1124 #define BAR_STEP_TP 2
1125 ProgressBar
.reset (BAR_STEP_TP
);
1126 string
nmsg("Loading...");
1127 ProgressBar
.newMessage ( ClientCfg
.buildLoadingString(nmsg
) );
1128 ProgressBar
.progress(0);
1129 ContinentMngr
.select(UserEntity
->pos(), ProgressBar
);
1130 ProgressBar
.finish();
1131 CurrSeason
= newLocalSeason
;
1134 if (ClientCfg
.R2EDEnabled
)
1136 if (R2::ResetWanted
)
1138 R2::getEditor().reset();
1139 R2::ResetWanted
= false;
1142 if (R2::ResetScenarioWanted)
1144 R2::getEditor().resetScenario();
1145 R2::ResetScenarioWanted = false;
1147 if (R2::ReloadScenarioWanted)
1149 R2::getEditor().reloadScenario();
1150 R2::ReloadScenarioWanted = false;
1156 if (PermanentlyBanned
)
1160 UserEntity
->runVelocity(0);
1161 UserEntity
->walkVelocity(0);
1163 BanMsgCountdown
-= DT
;
1164 if (BanMsgCountdown
< 0.f
)
1166 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
1167 string msg
= CI18N::get("msgPermanentlyBanned");
1168 string cat
= getStringCategory(msg
, msg
);
1169 pIM
->displaySystemInfo(msg
, cat
);
1170 BanMsgCountdown
= BanMsgRepeatTime
;
1176 // Stop the Outgame music, with fade effect
1177 outgameFader
.fade();
1179 // update quit feature
1180 updateGameQuitting();
1182 // update module manager
1183 NLNET::IModuleManager::getInstance().updateModules();
1185 if (ClientCfg
.R2EDEnabled
)
1187 R2::getEditor().getDMC().flushActions();
1189 if (UserEntity
) { UserEntity
->updateNpcContolSpeed(); }
1193 // update outpost stuff
1194 OutpostManager
.update();
1198 IngameDbMngr
.flushObserverCalls();
1199 NLGUI::CDBManager::getInstance()->flushObserverCalls();
1203 EventsListener
.setUIHandledButtonMask(NLMISC::noButton
);
1208 H_AUTO_USE ( RZ_Client_Main_Loop_Zero_Cpu
)
1211 CInputHandlerManager::getInstance()->pumpEventsNoIM();
1216 IngameDbMngr
.flushObserverCalls();
1217 NLGUI::CDBManager::getInstance()->flushObserverCalls();
1221 // End of the frame.
1229 CSessionBrowserImpl::getInstance().update();
1231 //////////////////////////
1232 // INITIALIZE THE FRAME //
1233 //////////////////////////
1234 CInterfaceManager
*pIMinstance
;
1237 if (ClientCfg
.IsInvalidated
)
1238 updateFromClientCfg();
1241 // Update the event listener
1242 EventsListener
.update ();
1246 EventsListener
.updateMouseSmoothing(); // IMPORTANT: this should be called before updateClientTime && events handling in the frame
1254 CInputHandlerManager::getInstance()->pumpEvents();
1256 CLandscapePolyDrawer::getInstance().deletePolygons();
1257 CDecalRenderList::getInstance().clearRenderList();
1260 // Update the Interface Manager Events.
1261 pIMinstance
= CInterfaceManager::getInstance();
1264 // NB: must update frame events, even if ShowInterface==0, else may OutOfMemory (cause vector<> never cleared).
1265 pIMinstance
->updateFrameEvents ();
1268 if ((ContinentMngr
.cur()) && (UserEntity
!= NULL
))
1269 ContinentMngr
.cur()->FoW
.explore((float)UserEntity
->pos().x
, (float)UserEntity
->pos().y
);
1271 // Check if the window size has changed.
1272 OldWidth
= Width
; OldHeight
= Height
;
1273 Driver
->getWindowSize(Width
, Height
);
1276 // if yes, must update the camera perspective
1277 if(OldWidth
!=Width
|| OldHeight
!=Height
)
1278 updateCameraPerspective();
1280 // Get Mouse Position.
1281 OldMouseX
= MouseX
; OldMouseY
= MouseY
;
1283 #ifdef RYZOM_BG_DOWNLOADER
1284 updateBGDownloaderUI();
1288 // Get the pointer pos
1291 H_AUTO_USE ( RZ_Client_Main_Loop_Cursor
)
1293 // Change only if screen is not minimized
1294 if(!CViewRenderer::getInstance()->isMinimized())
1296 // Get the cursor instance
1297 CViewPointer
*cursor
= static_cast< CViewPointer
* >( CWidgetManager::getInstance()->getPointer() );
1300 // Get the pointer position (in pixel)
1302 cursor
->getPointerPos(x
, y
);
1305 CViewRenderer
&viewRender
= *CViewRenderer::getInstance();
1306 viewRender
.getScreenSize(w
, h
);
1309 MouseX
= (float)x
/(float)w
;
1313 MouseY
= (float)y
/(float)h
;
1320 ///////////////////////
1321 // PROCESS THE FRAME //
1322 ///////////////////////
1328 IngameDbMngr
.flushObserverCalls();
1329 NLGUI::CDBManager::getInstance()->flushObserverCalls();
1330 bool prevDatabaseInitStatus
= IngameDbMngr
.initInProgress();
1331 IngameDbMngr
.setChangesProcessed();
1332 bool newDatabaseInitStatus
= IngameDbMngr
.initInProgress();
1333 if ((!newDatabaseInitStatus
) && prevDatabaseInitStatus
)
1335 // When database received, activate allegiance buttons (for neutral state) in fame window
1336 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
1337 CInterfaceGroup
*group
= dynamic_cast<CInterfaceGroup
*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:fame:content:you"));
1339 group
->updateAllLinks();
1340 // send a msg to lua for specific ui update
1341 CLuaManager::getInstance().executeLuaScript("game:onInGameDbInitialized()");
1346 // For Debug (after netmngr update). Log entity stage change.
1347 EntitiesMngr
.logStageChange(T1
);
1349 // Update Ryzom Time.
1351 H_AUTO_USE ( RZ_Client_Main_Loop_Time_Update
)
1352 if (!ClientCfg
.Local
)
1354 if(NetMngr
.getCurrentServerTick() > LastGameCycle
)
1355 RT
.updateRyzomClock(NetMngr
.getCurrentServerTick());
1357 else if (ClientCfg
.SimulateServerTick
)
1359 SimulatedServerDate
+= DT
;
1360 uint numTicks
= (uint
) floor(SimulatedServerDate
* 10);
1361 SimulatedServerTick
+= numTicks
;
1362 SimulatedServerDate
= (float)((double)SimulatedServerDate
- (double) numTicks
* 0.1);
1363 RT
.updateRyzomClock((uint32
)SimulatedServerTick
);
1367 updateDayNightCycleHour();
1371 updateSmoothedTime();
1373 if (!ClientCfg
.Light
)
1375 // Call a function for a demo to update.
1378 updateDemo( (double)(T1
-T0
)*0.001 );
1382 // R2ED pre render update
1383 if (ClientCfg
.R2EDEnabled
)
1385 R2::getEditor().updatePreCamera();
1389 * Update position of all the primitives. Make a PACS move.
1391 EntitiesMngr
.updatePreCamera();
1393 // Snap the user entity on the ground
1394 UserEntity
->snapToGround();
1398 CBotChatManager::getInstance()->update();
1399 IngameDbMngr
.flushObserverCalls();
1400 NLGUI::CDBManager::getInstance()->flushObserverCalls();
1402 // updateItemEdition
1403 CInterfaceItemEdition::getInstance()->update();
1406 * Update user controls and compute the camera position
1408 UserControls
.update();
1410 // Update Landscape RefineCenter
1411 if (Landscape
) Landscape
->setRefineCenterUser(View
.refinePos());
1413 // Update camera recorder, possibly replacing current view
1414 updateCameraRecorder();
1416 // Update Camera Position/Orientation.
1417 CVector currViewPos
= View
.currentViewPos();
1418 MainCam
.setTransformMode(UTransformable::RotQuat
);
1420 CVector cameraMoves
= UserEntity
->getCameraMoves();
1422 currViewPos
.z
+= cameraMoves
.z
;
1423 MainCam
.setPos(currViewPos
);
1424 MainCam
.setRotQuat(View
.currentViewQuat());
1429 viewMatrix
= MainCam
.getMatrix();
1430 viewMatrix
.rotateZ(cameraMoves
.x
);
1431 MainCam
.setRotQuat(viewMatrix
.getRot());
1434 UserEntity
->setCameraMoves(CVector(0, 0, 0));
1439 camMatrix
.translate(MainCam
.getMatrix().getPos());
1440 CVector dir
= MainCam
.getMatrix().getJ();
1444 camMatrix
.rotateZ(float(NLMISC::Pi
+asin(dir
.x
)));
1446 camMatrix
.rotateZ(float(NLMISC::Pi
+NLMISC::Pi
-asin(dir
.x
)));
1448 StereoHMD
->setInterfaceMatrix(camMatrix
);
1450 NLMISC::CQuat hmdOrient
= StereoHMD
->getOrientation();
1451 // NLMISC::CMatrix camMatrix = MainCam.getMatrix();
1452 NLMISC::CMatrix hmdMatrix
;
1453 hmdMatrix
.setRot(hmdOrient
);
1454 NLMISC::CMatrix posMatrix
; // minimal head modeling, will be changed in the future
1455 posMatrix
.translate(StereoHMD
->getEyePosition());
1456 NLMISC::CMatrix mat
= ((camMatrix
* hmdMatrix
) * posMatrix
);
1457 MainCam
.setPos(mat
.getPos());
1458 MainCam
.setRotQuat(mat
.getRot());
1460 if (true) // TODO: ClientCfg.Headphone
1462 // NOTE: non-(StereoHMD+Headphone) impl in user_entity.cpp
1463 SoundMngr
->setListenerPos(mat
.getPos()); // TODO: Move ears back ... :)
1464 SoundMngr
->setListenerOrientation(mat
.getJ(), mat
.getK());
1469 StereoDisplay
->updateCamera(0, &MainCam
);
1472 UCamera cam
= SceneRoot
->getCam();
1473 StereoDisplay
->updateCamera(1, &cam
);
1477 // see if camera is below water (useful for sort order)
1478 if (ContinentMngr
.cur())
1482 if (ContinentMngr
.cur()->WaterMap
.getWaterHeight(CVector2f(currViewPos
.x
, currViewPos
.y
), waterHeight
, splashEnabled
))
1484 // camera is above / below a water surface
1485 Scene
->setLayersRenderingOrder(currViewPos
.z
> waterHeight
);
1486 UserEntity
->setOrderingLayer(currViewPos
.z
> waterHeight
? 0 : 2);
1490 UserEntity
->setOrderingLayer(2);
1491 Scene
->setLayersRenderingOrder(true);
1495 // Build the camera clipping planes
1496 vector
<CPlane
> planes
;
1497 buildCameraClippingPyramid (planes
);
1500 * Clip the entities.
1501 * Update display for visible entities.
1502 * Update display for clipped entities at a lower frequency.
1504 static uint clippedUpdateTime
= 0;
1505 EntitiesMngr
.updatePostCamera(clippedUpdateTime
, planes
, MainCam
.getPos());
1506 clippedUpdateTime
++;
1507 clippedUpdateTime
&=RZ_CLIPPED_UPDATE_TIME_MASK
;
1509 // Update the position for the vision.
1510 NetMngr
.setReferencePosition(UserEntity
->pos());
1512 // For Debug (after entities update). Log entity stage change.
1513 EntitiesMngr
.logStageChange(T1
);
1515 if (!ClientCfg
.Light
)
1517 // Animate all the playlists
1518 EAM
->setup (TimeInSec
);
1522 // update the sound of the player (walk, run....) if sound is allocated.
1527 if (!ClientCfg
.Light
)
1529 // Not in an indoor ?
1530 if (ContinentMngr
.cur() && !ContinentMngr
.cur()->Indoor
)
1532 // Load Zone in streaming according to the refine position (not necessarily the User Position);
1533 string zoneAdded
, zoneRemoved
;
1534 const R2::CScenarioEntryPoints::CCompleteIsland
*ci
= R2::CScenarioEntryPoints::getInstance().getCompleteIslandFromCoords(CVector2f((float) UserEntity
->pos().x
, (float) UserEntity
->pos().y
));
1535 Landscape
->refreshZonesAround(View
.refinePos(), ClientCfg
.Vision
+ ExtraZoneLoadingVision
, zoneAdded
, zoneRemoved
, ci
? &(ci
->ZoneIDs
) : NULL
);
1536 LandscapeIGManager
.loadZoneIG(zoneAdded
);
1537 LandscapeIGManager
.unloadZoneIG(zoneRemoved
);
1544 GR
->refreshLrAround (View
.refinePos(), LRRefeshRadius
);
1546 // load / unload streamable obj (villages ...)
1547 if (ClientCfg
.VillagesEnabled
)
1549 ContinentMngr
.updateStreamable(View
.refinePos());
1552 if (!ClientCfg
.Light
)
1554 // Load / unload streaming Instances textures.
1555 Driver
->updateAsyncTexture();
1560 // Animate all systems in scene.
1561 Scene
->animate(TimeInSec
-FirstTimeInSec
);
1566 if (!ClientCfg
.Light
)
1568 CClientDate
newDate(RT
.getRyzomDay(), DayNightCycleHour
);
1569 if (newDate
< CTimedFXManager::getInstance().getDate() ||
1570 abs((sint32
)RT
.getRyzomDay() - CTimedFXManager::getInstance().getDate().Day
) > 1)
1572 // The manager make the assumption that no more than one day can occurs between 2 ticks
1573 // This only happens when date is changed manually
1576 IGCallbacks
->changeSeason(); // the season doesn't change, but this force fxs to be recreated
1579 CTimedFXManager::getInstance().update(newDate
, CurrSeason
, Scene
->getCam().getPos());
1581 CProjectileManager::getInstance().update();
1583 // temp temp : for debug
1584 //TestGroundFX.update();
1588 // Set the right camera cluster.
1591 UInstanceGroup
*pPlayerClusterSystem
= NULL
;
1594 if(UserControls
.mode() != CUserControls::ThirdMode
)
1596 // get the Pacs global position of the camera
1597 UGlobalPosition gPos
;
1598 if((UserControls
.mode() != CUserControls::AIMode
)
1599 && UserEntity
->getPrimitive())
1600 UserEntity
->getPrimitive()->getGlobalPosition(gPos
, dynamicWI
);
1602 gPos
= GR
->retrievePosition(View
.viewPos());
1604 // get the cluster IG associated to this pacs position
1605 pPlayerClusterSystem
= getCluster(gPos
);
1606 MainCam
.setClusterSystem(pPlayerClusterSystem
);
1608 // important to update this each frame, for shadow map consideration against the "matis serre bug"
1609 CollisionManager
->setPlayerInside(pPlayerClusterSystem
!=NULL
);
1611 // Camera 3rd person complex mode
1614 UGlobalPosition gPos
;
1615 if(UserEntity
->getPrimitive())
1616 UserEntity
->getPrimitive()->getGlobalPosition(gPos
, dynamicWI
);
1617 // get the cluster IG associated to this pacs position
1618 pPlayerClusterSystem
= getCluster(gPos
);
1620 // set the one found in CView::updateCameraCollision()
1621 MainCam
.setClusterSystem(View
.getThirdPersonClusterSystem());
1623 // important to update this each frame, for shadow map consideration against the "matis serre bug"
1624 CollisionManager
->setPlayerInside(pPlayerClusterSystem
!=NULL
);
1627 View
.getCamera3rdPersonSetup(LastDebugClusterCameraThirdPersonStart
,
1628 LastDebugClusterCameraThirdPersonEnd
,
1629 LastDebugClusterCameraThirdPersonTestStart
);
1630 LastDebugClusterCameraThirdPersonResult
= View
.currentViewPos();
1631 LastDebugClusterCameraThirdPersonPelvisPos
= View
.viewPos() + CVector(0.f
,0.f
,1.f
);
1632 LastDebugClusterCameraThirdPersonForceFPV
= View
.forceFirstPersonView();
1634 //CameraThirPersonGraph.addOneValue ((startPos - endPos).norm());
1637 // If we are flushing open all doors
1640 // update only the cluster system where the player is!
1641 if (pPlayerClusterSystem
!= NULL
)
1643 static vector
<string
> PortalsName
;
1644 PortalsName
.clear();
1645 pPlayerClusterSystem
->getDynamicPortals(PortalsName
);
1646 for (uint32 i
= 0; i
< PortalsName
.size(); ++i
)
1647 pPlayerClusterSystem
->setDynamicPortal (PortalsName
[i
], true);
1653 // R2ED pre render update
1654 if (ClientCfg
.R2EDEnabled
)
1656 R2::getEditor().updateBeforeRender();
1659 if (!ClientCfg
.Light
)
1664 // Update water env map (happens when continent changed etc)
1665 updateWaterEnvMap();
1673 CTextureUser
*effectRenderTarget
= NULL
;
1674 bool haveEffects
= Render
&& Driver
->getPolygonMode() == UDriver::Filled
1675 && (ClientCfg
.Bloom
|| FXAA
);
1676 bool defaultRenderTarget
= false;
1681 Driver
->beginDefaultRenderTarget();
1682 defaultRenderTarget
= true;
1684 if (ClientCfg
.Bloom
)
1686 CBloomEffect::getInstance().setSquareBloom(ClientCfg
.SquareBloom
);
1687 CBloomEffect::getInstance().setDensityBloom((uint8
)ClientCfg
.DensityBloom
);
1690 bool fullDetail
= false;
1691 while ((!StereoDisplay
&& i
== 0) || (StereoDisplay
&& StereoDisplay
->nextPass()))
1700 // modify cameras for stereo display
1701 const CViewport
&vp
= StereoDisplay
->getCurrentViewport();
1702 Driver
->setViewport(vp
);
1704 Scene
->setViewport(vp
);
1707 SceneRoot
->setViewport(vp
);
1709 //MainCam.setTransformMode(UTransformable::DirectMatrix);
1710 StereoDisplay
->getCurrentMatrix(0, &MainCam
);
1711 StereoDisplay
->getCurrentFrustum(0, &MainCam
);
1714 // matrix updated during commitCamera from maincam
1715 UCamera cam
= SceneRoot
->getCam();
1716 StereoDisplay
->getCurrentFrustum(1, &cam
);
1720 // Commit camera changes
1723 //////////////////////////
1724 // RENDER THE FRAME 3D //
1725 //////////////////////////
1727 bool stereoRenderTarget
= (StereoDisplay
!= NULL
) && StereoDisplay
->beginRenderTarget();
1729 if (!StereoDisplay
|| StereoDisplay
->wantClear())
1735 if (!StereoDisplay
|| StereoDisplay
->wantScene())
1737 if (!ClientCfg
.Light
&& Render
)
1739 if (!StereoDisplay
|| StereoDisplay
->isSceneFirst())
1741 // nb : force full detail if a screenshot is asked
1742 // todo : move outside render code
1745 fullDetail
= ScreenshotRequest
!= ScreenshotRequestNone
&& ClientCfg
.ScreenShotFullDetail
;
1748 s_ForceFullDetail
.backup();
1749 s_ForceFullDetail
.set();
1755 bool wantTraversals
= !StereoDisplay
|| StereoDisplay
->isSceneFirst();
1756 bool keepTraversals
= StereoDisplay
&& !StereoDisplay
->isSceneLast();
1757 doRenderScene(wantTraversals
, keepTraversals
);
1759 if (!StereoDisplay
|| StereoDisplay
->isSceneLast())
1763 s_ForceFullDetail
.restore();
1770 if (!StereoDisplay
|| StereoDisplay
->wantSceneEffects())
1772 if (!ClientCfg
.Light
&& Render
&& haveEffects
)
1774 if (StereoDisplay
) Driver
->setViewport(NL3D::CViewport());
1775 UCamera pCam
= Scene
->getCam();
1776 Driver
->setMatrixMode2D11();
1777 if (FXAA
) FXAA
->applyEffect();
1778 if (ClientCfg
.Bloom
) CBloomEffect::instance().applyBloom();
1779 Driver
->setMatrixMode3D(pCam
);
1780 if (StereoDisplay
) Driver
->setViewport(StereoDisplay
->getCurrentViewport());
1784 if (!StereoDisplay
|| StereoDisplay
->wantInterface3D())
1786 if (!ClientCfg
.Light
)
1791 // for that frame and
1792 // tmp : display height grid
1793 //static volatile bool displayHeightGrid = true;
1794 /*if (displayHeightGrid)
1796 HeightGrid.display(*Driver);
1801 displaySceneProfiles();
1802 Scene_Profile
= false;
1804 // Render the primitives
1806 H_AUTO_USE ( RZ_Client_Main_Loop_Debug
)
1807 PrimFiles
.display (*Driver
);
1811 // Draw Extra 3D Objects
1812 Driver
->setMatrixMode3D(MainCam
);
1813 Driver
->setModelMatrix(CMatrix::Identity
);
1815 // Display PACS borders.
1818 H_AUTO_USE ( RZ_Client_Main_Loop_Debug
)
1819 displayPACSBorders();
1820 displayPACSPrimitive();
1823 // Display PACS borders only (for ARK).
1826 displayPACSPrimitive();
1829 // display Sound box
1832 H_AUTO_USE ( RZ_Client_Main_Loop_Debug
)
1836 // display Debug of Clusters
1839 H_AUTO_USE ( RZ_Client_Main_Loop_Debug
)
1840 displayDebugClusters();
1842 } /* if (!ClientCfg.Light) */
1845 // static UTextureFile *backgroundBitmap = NULL;
1846 // if (backgroundBitmap == NULL)
1847 // backgroundBitmap = Driver->createTextureFile("temp_background.tga");
1848 // Driver->setMatrixMode2D11();
1849 // Driver->drawBitmap (0.f, 0.f, 1024.f/1024.f, 1024.f/768.f, (UTexture&)*backgroundBitmap);
1850 // Driver->setMatrixMode3D(MainCam);
1852 Driver
->clearBuffers(CRGBA (0,0,0,0));
1853 displayPACSBorders();
1854 displayPACSPrimitive();
1857 if (!ClientCfg
.Light
&& !Landscape
)
1859 displayPACSBorders();
1862 // Display some things not in the scene like the name, the entity path, etc.
1863 EntitiesMngr
.updatePostRender();
1865 // Render the stat graphs if needed
1867 H_AUTO_USE ( RZ_Client_Main_Loop_Debug
)
1868 CGraph::render (ShowInfos
);
1871 } /* if (!StereoDisplay || StereoDisplay->wantInterface3D()) */
1873 if (!StereoDisplay
|| StereoDisplay
->wantInterface2D())
1875 // Render in 2D Mode to display 2D Interfaces and 2D texts.
1876 Driver
->setMatrixMode2D11();
1878 // draw a big quad to represent thunder strokes
1879 /*if (Render && WeatherManager.getThunderLevel() != 0.f)
1881 H_AUTO_USE ( RZ_Client_Main_Loop_Render_Thunder )
1882 Driver->drawQuad(0, 0, 1, 1, ThunderColor);
1884 // TODO : boris : add sound here !
1885 // Needs more explosions
1888 // Update the contextual menu
1890 H_AUTO_USE ( RZ_Client_Main_Loop_Interface
)
1892 // Update the game cursor.
1894 GameContextMenu
.update();
1897 validateDialogs(GameContextMenu
);
1899 // Display interface v3
1900 Driver
->enableFog (false);
1901 if (!Driver
->isLost())
1904 pIMinstance
->updateFrameViews (MainCam
);
1906 pIMinstance
->displayUIViewBBoxs(DebugUIFilter
);
1908 pIMinstance
->displayUICtrlBBoxs(DebugUIFilter
);
1910 pIMinstance
->displayUIGroupBBoxs(DebugUIFilter
);
1913 // special case in OpenGL : all scene has been display in render target,
1914 // now, final texture is display with a quad
1915 /*if (!ClientCfg.Light && ClientCfg.Bloom && Render && bloomStage == 2) // NO VR BLOOMZ
1917 // End bloom effect system after drawing the 3d interface (z buffer related).
1918 if (StereoDisplay) Driver->setViewport(NL3D::CViewport());
1919 CBloomEffect::instance().endInterfacesDisplayBloom();
1920 if (StereoDisplay) Driver->setViewport(StereoDisplay->getCurrentViewport());
1926 H_AUTO_USE ( RZ_Client_Main_Loop_Debug
)
1927 if (!Driver
->isLost())
1929 // If show information is Active.
1933 // If show information is Active.
1937 // If show information is Active.
1941 // If show information is Active.
1943 displayDebugUIUnderMouse();
1945 // If show information is Active.
1946 displayStreamingDebug();
1948 // If Show Help is active -> Display an help.
1952 // Yoyo: indicate profiling state
1954 displaySpecialTextProgress("Profiling");
1956 // Display frame rate
1958 // Create a shadow when displaying a text.
1959 TextContext
->setShaded(true);
1960 TextContext
->setShadeOutline(false);
1961 // Set the font size.
1962 TextContext
->setFontSize(10);
1963 // Set the text color
1964 TextContext
->setColor(CRGBA(255,255,255));
1966 // temporary values for conversions
1967 float x
, y
, width
, height
;
1969 for(uint i
= 0; i
< ClientCfg
.Logos
.size(); i
++)
1971 std::vector
<string
> res
;
1972 explode(ClientCfg
.Logos
[i
],std::string(":"), res
);
1973 if(res
.size()==9 && i
<LogoBitmaps
.size() && LogoBitmaps
[i
]!=NULL
)
1975 fromString(res
[5], x
);
1976 fromString(res
[6], y
);
1977 fromString(res
[7], width
);
1978 fromString(res
[8], height
);
1979 Driver
->drawBitmap(x
/(float)ClientCfg
.Width
, y
/(float)ClientCfg
.Height
, width
/(float)ClientCfg
.Width
, height
/(float)ClientCfg
.Height
, *LogoBitmaps
[i
]);
1987 static TTicks oldTick
= CTime::getPerformanceTime();
1988 TTicks newTick
= CTime::getPerformanceTime();
1989 double deltaTime
= CTime::ticksToSecond (newTick
-oldTick
);
1991 smoothFPS
.addValue((float)deltaTime
);
1992 moreSmoothFPS
.addValue((float)deltaTime
);
1993 deltaTime
= smoothFPS
.getSmoothValue ();
1994 if (deltaTime
> 0.0)
1996 CCDBNodeLeaf
*pNL
= s_FpsLeaf
? &*s_FpsLeaf
1997 : &*(s_FpsLeaf
= NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:FPS"));
1998 pNL
->setValue64((sint64
)(1.f
/deltaTime
));
2002 // R2ED post render update
2003 if (ClientCfg
.R2EDEnabled
)
2005 // IMPORTANT : this should be called after CEntitiesMngr::updatePostRender() because
2006 // entity may be added / removed there !
2007 R2::getEditor().updateAfterRender();
2010 // Update FXs (remove them).
2013 // Detect disconnection / server down: display information text
2014 // but keep the rendering so that the player can remember where he is
2015 // and what he was doing. He can't move because the connection quality returns false.
2017 if ((connectionState
== CNetworkConnection::Disconnect
) && (lastConnectionState
!= CNetworkConnection::Disconnect
) && (!FarTP
.isFarTPInProgress()))
2019 UserControls
.stopFreeLook(); // let the player click on Exit
2020 pIMinstance
->messageBoxWithHelp(CI18N::get("uiDisconnected"));
2022 // If we have started a Far TP sequence and are waiting for onServerQuitOK()
2023 // from the EGS, resume the sequence because the EGS is down and won't reply.
2024 FarTP
.onServerQuitOk();
2027 // Yoyo: MovieShooter.
2028 if(MovieShooterSaving
)
2030 H_AUTO_USE ( RZ_Client_Main_Loop_Debug
)
2032 // Add the buffer frame to the movie.
2033 if(!MovieShooter
.addFrame(TimeInSec
, Driver
))
2035 // Fail to add the frame => abort.
2040 // Ok, just add a display.
2041 displaySpecialTextProgress("MovieShooting");
2045 if (isRecordingCamera())
2047 displaySpecialTextProgress("CameraRecording");
2050 // Temp for weather test
2051 if (ClientCfg
.ManualWeatherSetup
)
2053 H_AUTO_USE ( RZ_Client_Main_Loop_Debug
)
2054 static float displayHourDelta
= 0.04f
; // static for edition during debug..
2056 // Display weather function
2057 if (DisplayWeatherFunction
)
2059 uint64 currDay
= RT
.getRyzomDay();
2060 float currHour
= DayNightCycleHour
;
2061 float singleHourDelta
= fmodf(currHour
, 1.f
);
2062 uint32 wndWidth
, wndHeight
;
2063 Driver
->getWindowSize(wndWidth
, wndHeight
);
2064 Driver
->setMatrixMode2D(CFrustum(0, 800, 600, 0, 0, 1, false));
2065 const float lineHeight
= 100.f
;
2067 // draw the weather function
2068 for(uint x
= 0; x
< wndWidth
; ++x
)
2071 if(ContinentMngr
.cur())
2072 weatherValue
= ::getBlendedWeather(currDay
, currHour
, *WeatherFunctionParams
, ContinentMngr
.cur()->WeatherFunction
);
2074 weatherValue
= ::getBlendedWeather(currDay
, currHour
, *WeatherFunctionParams
, 0);
2076 NLMISC::clamp(weatherValue
, 0.f
, 1.f
);
2077 CRGBA seasonToColor
[EGSPD::CSeason::Invalid
] =
2084 Driver
->drawLine((float) x
, 0.f
, (float) x
, lineHeight
* weatherValue
, seasonToColor
[CRyzomTime::getSeasonByDay((uint32
)currDay
)]);
2085 currHour
+= displayHourDelta
;
2086 if (currHour
>= 24.f
)
2091 singleHourDelta
+= displayHourDelta
;
2092 if (singleHourDelta
>= 1.f
)
2094 singleHourDelta
-= 1.f
;
2095 Driver
->drawLine((float) x
, 100.f
, (float) x
, 130, CRGBA::Red
);
2099 if(ContinentMngr
.cur())
2101 // draw lines for current weather setups
2102 uint numWeatherSetups
= ContinentMngr
.cur()->WeatherFunction
[CurrSeason
].getNumWeatherSetups();
2103 for (uint y
= 0; y
< numWeatherSetups
; ++y
)
2105 float py
= lineHeight
* (y
/ (float) numWeatherSetups
);
2106 Driver
->drawLine(0.f
, py
, 800.f
, py
, CRGBA::Magenta
);
2111 // Ctrl+ & Ctrl- change the weather value
2112 if (Actions
.valide ("inc_time"))
2114 ManualWeatherValue
+= DT
* 0.04f
;
2116 if (Actions
.valide ("dec_time"))
2118 ManualWeatherValue
-= DT
* 0.04f
;
2120 NLMISC::clamp(ManualWeatherValue
, 0.f
, 1.f
);
2122 if (ForcedDayNightCycleHour
< 0) // if time is forced then can't change it manually ...
2124 // Ctrl-K increase hour
2125 if (Actions
.valide ("inc_hour"))
2127 RT
.increaseTickOffset( (uint32
)(2000 * displayHourDelta
) );
2128 RT
.updateRyzomClock(NetMngr
.getCurrentServerTick());
2131 // Ctrl-L decrease hour
2132 if (Actions
.valide ("dec_hour"))
2134 RT
.decreaseTickOffset( (uint32
)(2000 * displayHourDelta
) );
2135 RT
.updateRyzomClock(NetMngr
.getCurrentServerTick());
2136 CTimedFXManager::getInstance().setDate(CClientDate(RT
.getRyzomDay(), (float) RT
.getRyzomTime()));
2139 IGCallbacks
->changeSeason(); // the season doesn't change, but this force fxs to be recreated
2144 // Ctrl-M generate statistics in a file
2146 if (Actions.valide ("weather_stats"))
2148 // Only usable if there is a continent loaded.
2149 if(ContinentMngr.cur())
2150 CPredictWeather::generateWeatherStats("weather_stats.csv", WeatherFunctionParams, ContinentMngr.cur()->WeatherFunction);
2153 // Ctrl-B decrease display factor
2154 if (Actions
.valide ("dec_display_factor"))
2156 displayHourDelta
*= 0.90f
;
2158 // Ctrl-J increase display factor
2159 if (Actions
.valide ("inc_display_factor"))
2161 displayHourDelta
*= 1.1f
;
2162 displayHourDelta
= std::min(1000.f
, displayHourDelta
);
2166 // Ctrl-AltGR-Z show timed FXs
2169 if (!Driver
->isLost())
2171 CTimedFXManager::getInstance().displayFXBoxes(ShowTimedFXMode
);
2176 CVector2f
camPos(Scene
->getCam().getPos().x
, Scene
->getCam().getPos().y
);
2177 if (!ClientCfg
.Light
)
2179 if (DisplayMicroLifeZones
)
2181 CMicroLifeManager::getInstance().renderMLZones(camPos
);
2184 if (DisplayWaterMap
)
2186 if (ContinentMngr
.cur())
2188 ContinentMngr
.cur()->WaterMap
.render(camPos
);
2194 if (!ClientCfg
.Light
)
2196 if (DisplayMicroLifeActiveTiles
)
2198 CMicroLifeManager::getInstance().renderActiveTiles();
2202 // tmp : debug of ground fxs
2203 //TestGroundFX.displayFXBoxes();
2205 // Temp for sound debug
2207 H_AUTO_USE ( RZ_Client_Main_Loop_Debug
)
2211 static bool drawSound
= false;
2212 static float camHeigh
= 150.0f
;
2215 if (ClientCfg
.ExtendedCommands
)
2217 if (Actions
.valide ("draw_sound"))
2218 drawSound
= !drawSound
;
2220 if (Actions
.valide ("inc_camera_height"))
2222 if (Actions
.valide ("dec_camera_height"))
2226 SoundMngr
->drawSounds(camHeigh
);
2229 } /* if (!StereoDisplay || StereoDisplay->wantInterface2D()) */
2233 StereoDisplay
->endRenderTarget();
2237 if (defaultRenderTarget
)
2239 // draw final result to backbuffer
2240 Driver
->endDefaultRenderTarget(Scene
);
2244 static CQuat MainCamOri
;
2247 // Frame to skip before swap buffer
2248 SkipFrame
= RYZOM_FIRST_FRAME_TO_SKIP
;
2250 MainCam
.getRotQuat(MainCamOri
);
2255 if (StartPlayTime
== 0)
2257 StartPlayTime
= NLMISC::CTime::getLocalTime();
2260 // Start background sound play now ! (nb: restarted if load just ended, or if sound re-enabled)
2263 H_AUTO_USE ( RZ_Client_Main_Loop_Sound
)
2265 // fade out loading music
2266 if (SoundMngr
->getEventMusicPlayed() == LoadingMusic
)
2268 SoundMngr
->stopEventMusic(LoadingMusic
, CSoundManager::LoadingMusicXFade
);
2271 SoundMngr
->playBackgroundSound();
2273 // Fade in Game Sound now (before endLoading)
2274 // fade in game sound
2275 SoundMngr
->fadeInGameSound(ClientCfg
.SoundTPFade
);
2278 // end loading (if previous load)
2281 // if a screenshot request was made then do it now
2282 switch(ScreenshotRequest
)
2284 case ScreenshotRequestTGA
:
2286 ScreenshotRequest
= ScreenshotRequestNone
;
2288 case ScreenshotRequestJPG
:
2290 ScreenshotRequest
= ScreenshotRequestNone
;
2292 case ScreenshotRequestPNG
:
2294 ScreenshotRequest
= ScreenshotRequestNone
;
2301 static volatile bool dumpValidPolys
= false;
2302 if (dumpValidPolys
) { tempDumpValidPolys(); dumpValidPolys
= false; }
2305 static volatile bool dumpColPolys
= false;
2306 if (dumpColPolys
) { tempDumpColPolys(); }
2308 if (ClientCfg
.R2EDEnabled
)
2310 R2::getEditor().updateBeforeSwapBuffer();
2313 Driver
->swapBuffers();
2318 if (ProfileNumFrame
== ClientCfg
.NumFrameForProfile
)
2320 WantProfiling
= true;
2324 // If the device is lost then no rendering will occur, so let some time to other applications
2325 if (Driver
->isLost())
2328 nldebug("lost device");
2335 // Turn the camera to make a 360 degree turn
2336 // UTransformable::TTransformMode m = MainCam.getTransformMode();
2339 MainCam
.setRotQuat(MainCamOri
);
2343 CMatrix mat
= CMatrix::Identity
;
2344 mat
.setRot(MainCamOri
);
2345 mat
.rotateZ(2*(float)Pi
*((float)(SkipFrame
)/(float)RYZOM_FIRST_FRAME_TO_SKIP
));
2348 MainCam
.setRotQuat(qTmp
);
2353 // Force the client to sleep a bit.
2354 if(ClientCfg
.Sleep
>= 0)
2356 H_AUTO_USE ( RZ_Client_Main_Loop_Debug
)
2357 nlSleep(ClientCfg
.Sleep
);
2360 //++MainLoopCounter;
2362 // Send new data Only when server tick changed.
2363 if(NetMngr
.getCurrentServerTick() > LastGameCycle
)
2365 H_AUTO_USE ( RZ_Client_Main_Loop_Net
)
2366 // Put here things you have to send to the server only once per tick like user position.
2368 NLMISC::CCDBNodeLeaf
*node
= s_UiDirectionLeaf
? (&*s_UiDirectionLeaf
)
2369 : &*(s_UiDirectionLeaf
= NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:DIRECTION"));
2370 CInterfaceProperty prop
;
2371 prop
.setNodePtr(node
);
2372 if(CompassMode
== 1)
2374 double camDir
= atan2(View
.view().y
, View
.view().x
);
2375 prop
.setDouble(camDir
);
2378 prop
.setDouble(atan2(UserEntity
->front().y
, UserEntity
->front().x
));
2379 // Update the server with our position and orientation.
2382 if(UserEntity
->sendToServer(out
))
2385 // Give information to the server about the combat position (ability to strike).
2388 if(UserEntity
->msgForCombatPos(out
))
2392 // Create the message for the server to move the user (except in combat mode).
2393 if(Ping
.rdyToPing())
2396 if(GenericMsgHeaderMngr
.pushNameToStream("DEBUG:PING", out
))
2398 const TTime mask
= 0xFFFFFFFF;
2399 uint32 localTime
= (uint32
)(mask
&ryzomGetLocalTime ());
2400 out
.serial(localTime
);
2403 Ping
.rdyToPing(false);
2406 nlwarning("mainloop: unknown message named 'DEBUG:PING'.");
2410 NetMngr
.send(NetMngr
.getCurrentServerTick());
2411 // Update the Last tick received from the server.
2412 LastGameCycle
= NetMngr
.getCurrentServerTick();
2415 if (ClientCfg
.AutoReloadFiles
)
2417 // Check for files update.
2418 CFile::checkFileChange();
2420 // Check for configuration files update.
2421 CConfigFile::checkConfigFiles();
2424 // Get the Connection State.
2425 lastConnectionState
= connectionState
;
2426 connectionState
= NetMngr
.getConnectionState();
2428 // Update movie shooter
2429 updateMovieShooting();
2431 // Update the bubble manager
2432 InSceneBubbleManager
.update();
2434 // Update the NPC icon system
2435 CNPCIconCache::getInstance().update();
2437 // Update Phrase Manager
2438 CSPhraseManager
*pPM
= CSPhraseManager::getInstance();
2439 pPM
->updateEquipInvalidation(NetMngr
.getCurrentServerTick());
2440 pPM
->updateAllActionRegen();
2442 // Update ingame duration and stat report sending
2443 updateStatReport ();
2445 // Auto play once on character login
2446 if (musicTriggerAutoPlay
)
2448 musicTriggerAutoPlay
= false;
2449 if (ClientCfg
.SoundOn
&& ClientCfg
.MediaPlayerAutoPlay
)
2452 CAHManager::getInstance()->runActionHandler("music_player", NULL
, "play_songs");
2456 // Update the music player
2457 MusicPlayer
.update ();
2460 if (ClientCfg
.CheckMemoryEveryNFrame
!= -1)
2462 static int frameToSkip
= ClientCfg
.CheckMemoryEveryNFrame
;
2463 if (frameToSkip
== 0)
2465 frameToSkip
= ClientCfg
.CheckMemoryEveryNFrame
;
2466 //NLMEMORY::CheckHeap (true);
2475 // Enter a network loop during the FarTP process, without doing the whole real main loop.
2476 // This code must remain at the very end of the main loop.
2477 if(LoginSM
.getCurrentState() == CLoginStateMachine::st_enter_far_tp_main_loop
)
2479 CLuaManager::getInstance().executeLuaScript("game:onFarTpStart()");
2480 // Will loop the network until the end of the relogging process
2481 FarTP
.farTPmainLoop();
2483 if( FarTP
.isReselectingChar() )
2485 if ( game_exit
) // check if the user has decided to quit
2488 // we have just completed init main loop, after reselecting character
2489 // repeat the steps before the main loop itself
2491 // new char, retrigger music autoplay
2492 musicTriggerAutoPlay
= true;
2494 // pre main loop in mainLoop
2498 game_exit_request
= false;
2499 FarTP
.setMainLoopEntered();
2501 // Get the Width and Height of the window and set the Old values..
2502 Driver
->getWindowSize(Width
, Height
);
2503 OldWidth
= Width
; OldHeight
= Height
;
2505 CGraph::init( Driver
);
2506 CGraph::Display
= false;
2508 T1
= ryzomGetLocalTime();
2509 TSend
= ((T1
+DTSend
)/DTSend
)*DTSend
;
2511 SetMouseFreeLook ();
2514 ContextCur
.context("STAND BY");
2515 UserControls
.reset();
2517 // set the default box for keyboard
2518 CChatWindow
*defaultChatWindow
;
2519 if (ClientCfg
.R2EDEnabled
)
2521 defaultChatWindow
= PeopleInterraction
.DebugInfo
;
2525 defaultChatWindow
= PeopleInterraction
.ChatGroup
.Window
;
2527 setDefaultChatWindow(defaultChatWindow
);
2529 // Init GameContextMenu.
2530 GameContextMenu
.init("");
2533 Actions
.enable(true);
2534 EditActions
.enable(true);
2536 // check for banned player
2537 if (testPermanentBanMarkers())
2539 setPermanentBanMarkers(true); // re-set any marker that could have been removed by the trouble maker
2540 applyPermanentBanPunishment();
2541 PermanentlyBanned
= true;
2545 // For stoping the outgame music, start after 30 frames, and duration of 3 seconds
2546 outgameFader
= CMusicFader(60, 3);
2548 // Short reinit of the main loop after farTP or character reselection
2553 R2::getEditor().autoConfigInit(IsInRingSession
);
2555 // TODO: temporary commented, CEditor must be initialized before to call next lines
2556 // if (!IsInRingSession)
2557 // R2::getEditor().registerLuaFunc();
2559 CurrSeason
= computeCurrSeason();
2561 // Get the Connection State (must be done after any Far TP to prevent the uiDisconnected box to be displayed)
2562 lastConnectionState
= CNetworkConnection::Connected
;
2563 connectionState
= NetMngr
.getConnectionState();
2565 CLuaManager::getInstance().executeLuaScript("game:onFarTpEnd()");
2571 } // end of main loop
2573 CInterfaceManager
*im
= CInterfaceManager::getInstance();
2574 if (CLuaManager::getInstance().getLuaState())
2576 CLuaManager::getInstance().executeLuaScript("game:onMainLoopEnd()");
2579 // Stop Running Profiles (kick result)
2582 WantProfiling
= false;
2584 CHTimer::endBench();
2589 WantProfilingVBLock
= false;
2590 ProfilingVBLock
= false;
2591 vector
<string
> strs
;
2592 Driver
->endProfileVBHardLock(strs
);
2595 if ( ! FarTP
.isReselectingChar() ) // skip some parts if the user wants to quit in the middle of a char reselect
2597 // Saving ingame resolution when in windowed mode
2598 saveIngameResolution();
2600 // Release the structure for the ping.
2604 Actions
.enable(false);
2605 EditActions
.enable(false);
2607 CWidgetManager::getInstance()->setDefaultCaptureKeyboard(NULL
);
2610 CInterfaceManager::getInstance()->uninitInGame0();
2611 CItemGroupManager::getInstance()->uninit();
2613 /////////////////////////////////
2614 // Display the end background. //
2615 /////////////////////////////////
2616 // Create the loading texture.
2617 loadBackgroundBitmap (EndBackground
);
2619 // TTime endTime = ryzomGetLocalTime () + (TTime)(ClientCfg.EndScreenTimeOut*1000.f);
2623 // CInputHandlerManager::getInstance()->pumpEventsNoIM();
2624 // Display the background
2625 drawLoadingBitmap (0);
2626 // Display to screen.
2627 Driver
->swapBuffers();
2628 // } while(ryzomGetLocalTime () < endTime);
2630 // Destroy the Loading Background.
2631 destroyLoadingBitmap ();
2633 IngameDbMngr
.resetInitState();
2638 return ryzom_exit
|| (Driver
== NULL
) || (!Driver
->isActive ());
2641 //---------------------------------------------------
2642 // Just Display some text with ... anim at some place.
2643 //---------------------------------------------------
2644 void displaySpecialTextProgress(const char *text
)
2646 // Create a shadow when displaying a text.
2647 TextContext
->setShaded(true);
2648 TextContext
->setShadeOutline(false);
2649 // Set the font size.
2650 TextContext
->setFontSize(12);
2651 // Set the text color
2652 TextContext
->setColor(CRGBA(255,255,255));
2654 TextContext
->setHotSpot(UTextContext::BottomLeft
);
2657 const uint MaxDot
= 8;
2658 static uint counter
=0;
2659 counter
= (counter
+1) % (MaxDot
+1);
2663 for(i
=0;i
<counter
;i
++)
2667 TextContext
->printfAt(0.05f
,0.80f
,"%s%s", text
, str
);
2671 //---------------------------------------------------
2672 // MovieShooter methods
2673 //---------------------------------------------------
2676 void endMovieShooting()
2678 MovieShooterSaving
= false;
2681 bool MovieShooterReplay
= false;
2682 bool MovieShooterSave
= false;
2684 void updateMovieShooting()
2686 #ifdef _MOVIE_SHOOTER_ON_
2687 if (MovieShooterReplay
)
2689 if(!MovieShooter
.enabled())
2691 Driver
->systemMessageBox("MovieShooter not enabled", "MovieShooter");
2695 if( !MovieShooterSaving
)
2699 MovieShooter
.replayMovie(Driver
, TextContext
);
2701 catch (const Exception
&e
)
2703 Driver
->systemMessageBox(e
.what(), "MovieShooter");
2707 MovieShooterReplay
= false;
2710 if (MovieShooterSave
)
2712 if(!MovieShooter
.enabled())
2714 Driver
->systemMessageBox("MovieShooter not enabled", "MovieShooter");
2718 if( !MovieShooterSaving
)
2729 sprintf(tmp
, "%03d", num
);
2730 theDir
= ClientCfg
.MovieShooterPath
+ "/" + "Movie" + tmp
;
2732 while( CFile::isDirectory(theDir
) );
2734 CFile::createDirectory(theDir
);
2737 MovieShooter
.saveMovie(Driver
, TextContext
, theDir
.c_str(), ClientCfg
.MovieShooterFramePeriod
, ClientCfg
.MovieShooterBlend
, ClientCfg
.MovieShooterPrefix
.c_str());
2739 catch (const Exception
&e
)
2741 Driver
->systemMessageBox(e
.what(), "MovieShooter");
2745 MovieShooterSave
= false;
2747 #endif // _MOVIE_SHOOTER_ON_
2751 //---------------------------------------------------
2753 // update the listener pos and user walk/run/idle sound (stereo)
2754 //---------------------------------------------------
2759 SoundMngr
->update ();
2766 //===================================================================================================
2767 void updateLightDesc()
2769 if (!ClientCfg
.Light
)
2771 // Update the lighting description (when season change, or for first setup)
2772 static bool init
= false;
2773 EGSPD::CSeason::TSeason season
= CurrSeason
;
2774 if (!init
|| season
!= CurrSeason
)
2776 CLightCycleDesc desc
;
2777 buildLightCycleDesc(desc
, CurrSeason
);
2778 LightCycleManager
.setLightDesc(desc
);
2781 if (CurrSeason
!= season
)
2783 CurrSeason
= season
;
2784 // also update seasonal fxs
2787 IGCallbacks
->changeSeason();
2793 //===================================================================================================
2794 static void updateCloudScape(const CCloudState
&desc
, const CWeatherContext
&wc
, float /* wind */, float dayNight
, float updateDelay
, bool mustInit
)
2796 if (!CloudScape
) return;
2797 SCloudScapeSetup css
;
2798 NLMISC::clamp(dayNight
, 0.f
, 1.f
);
2799 css
.CloudSpeed
= desc
.DiffusionSpeed
;
2800 float duskRatio
= LightCycleManager
.getLightDesc().DuskRatio
;
2801 switch(LightCycleManager
.getState())
2803 case CLightCycleManager::DayToNight
:
2804 if (dayNight
< duskRatio
) // day->dusk
2806 float blendFactor
= duskRatio
!= 0 ? dayNight
/ duskRatio
: 0.f
;
2807 css
.Ambient
.blendFromui(desc
.AmbientDay
, desc
.AmbientDusk
, (uint
) (256.f
* blendFactor
));
2808 css
.Diffuse
.blendFromui(desc
.DiffuseDay
, desc
.DiffuseDusk
, (uint
) (256.f
* blendFactor
));
2812 float blendFactor
= duskRatio
!= 1 ? (dayNight
- duskRatio
) / (1.f
- duskRatio
) : 0.f
;
2813 css
.Ambient
.blendFromui(desc
.AmbientDusk
, desc
.AmbientNight
, (uint
) (256.f
* blendFactor
));
2814 css
.Diffuse
.blendFromui(desc
.DiffuseDusk
, desc
.DiffuseNight
, (uint
) (256.f
* blendFactor
));
2817 default: // not a day->night transition, so no step for dusk
2818 css
.Ambient
.blendFromui(desc
.AmbientDay
, desc
.AmbientNight
, (uint
) (256.f
* dayNight
));
2819 css
.Diffuse
.blendFromui(desc
.DiffuseDay
, desc
.DiffuseNight
, (uint
) (256.f
* dayNight
));
2823 css
.NbCloud
= desc
.NumClouds
;
2824 css
.WindSpeed
= WeatherManager
.getCurrWeatherState().WindIntensity
* wc
.WFP
->CloudWindSpeedFactor
+ wc
.WFP
->CloudMinSpeed
;
2827 css
.TimeToChange
= 0;
2828 CloudScape
->init(&css
);
2829 CloudScape
->setNbCloudToUpdateIn80ms (ClientCfg
.CloudUpdate
);
2830 CloudScape
->setQuality (ClientCfg
.CloudQuality
);
2834 css
.TimeToChange
= updateDelay
;
2835 CloudScape
->set(css
);
2839 //===================================================================================================
2842 // build a weather context
2845 if(ContinentMngr
.cur())
2846 wc
.WF
= ContinentMngr
.cur()->WeatherFunction
;
2850 if (ClientCfg
.ManualWeatherSetup
&& !ForceTrueWeatherValue
)
2852 // Try to update the clouds quickly for manual test
2856 WeatherManager
.computeCloudState(ManualWeatherValue
, CurrSeason
, cs
, wc
.WF
);
2857 updateCloudScape(cs
, wc
, WeatherManager
.getCurrWeatherState().WindIntensity
, LightCycleManager
.getLightLevel(), 1.f
, InitCloudScape
);
2858 InitCloudScape
= false;
2863 // update the clouds
2866 InitCloudScape
= false;
2867 // 1 ) set current state
2869 WeatherManager
.computeCloudState(RT
.getRyzomDay(), DayNightCycleHour
, wc
, cs
);
2870 updateCloudScape(cs
, wc
, WeatherManager
.getCurrWeatherState().WindIntensity
, LightCycleManager
.getLightLevel(), 0.f
, true);
2871 // 2 )set next state
2872 // compute date of next update
2873 const CLightCycleDesc
&lcd
= LightCycleManager
.getLightDesc();
2874 float updateDelay
= 0.f
;
2875 if (lcd
.RealDayLength
!= 0.f
)
2877 updateDelay
= CloudUpdatePeriod
/ lcd
.RealDayLength
* lcd
.NumHours
;
2879 WeatherManager
.computeCloudState(RT
.getRyzomDay(), DayNightCycleHour
+ updateDelay
, wc
, cs
);
2880 updateCloudScape(cs
, wc
, WeatherManager
.getCurrWeatherState().WindIntensity
, LightCycleManager
.getLightLevel(), 0.f
, true);
2881 DelayBeforeCloudUpdate
= CloudUpdatePeriod
;
2885 DelayBeforeCloudUpdate
-= DT
;
2886 if (DelayBeforeCloudUpdate
<= 0.f
)
2888 DelayBeforeCloudUpdate
+= CloudUpdatePeriod
;
2889 if (DelayBeforeCloudUpdate
<= 0.f
)
2891 DelayBeforeCloudUpdate
= CloudUpdatePeriod
;
2894 // compute date of next update
2895 const CLightCycleDesc
&lcd
= LightCycleManager
.getLightDesc();
2896 float updateDelay
= 0.f
;
2897 if (lcd
.RealDayLength
!= 0.f
)
2899 updateDelay
= DelayBeforeCloudUpdate
/ lcd
.RealDayLength
* lcd
.NumHours
;
2902 WeatherManager
.computeCloudState(RT
.getRyzomDay(), DayNightCycleHour
+ updateDelay
, wc
, cs
);
2903 updateCloudScape(cs
, wc
, WeatherManager
.getCurrWeatherState().WindIntensity
, LightCycleManager
.getLightLevel(), updateDelay
, false);
2910 //-----------------------------------------------
2911 // displayPACSBorders :
2912 // Display Borders from PACS.
2913 //-----------------------------------------------
2914 void displayPACSBorders()
2916 static std::vector
<std::pair
<NLMISC::CLine
, uint8
> > edges
;
2917 if(UserEntity
->getPrimitive())
2919 UGlobalPosition gPos
;
2920 UserEntity
->getPrimitive()->getGlobalPosition(gPos
, dynamicWI
);
2921 if (GR
) GR
->getBorders(gPos
, edges
);
2925 for(uint i
=0; i
<edges
.size(); ++i
)
2927 line
= (edges
[i
].first
);
2928 // Choose the color according to the edge type.
2929 switch(edges
[i
].second
)
2933 line
.Color0
= CRGBA::Red
;
2934 line
.Color1
= CRGBA::Red
;
2938 line
.Color0
= CRGBA::Green
;
2939 line
.Color1
= CRGBA::Green
;
2943 line
.Color0
= CRGBA::Yellow
;
2944 line
.Color1
= CRGBA::Yellow
;
2948 line
.Color0
= CRGBA::Blue
;
2949 line
.Color1
= CRGBA::Blue
;
2952 line
.Color0
= CRGBA::Magenta
;
2953 line
.Color1
= CRGBA::Magenta
;
2955 case 5: // Exterior door
2956 line
.Color0
= CRGBA(127, 127, 127);
2957 line
.Color1
= CRGBA(127, 127, 127);
2961 line
.Color0
= CRGBA::White
;
2962 line
.Color1
= CRGBA::White
;
2966 Driver
->drawLine(line
, GenericMat
);
2971 }// displayPACSBorders //
2973 const uint PacsBoxPointCount
= 24;
2975 CVector PacsBox
[PacsBoxPointCount
] =
2977 CVector( -0.5f
, -0.5f
, 0), CVector( 0.5f
, -0.5f
, 0),
2978 CVector( 0.5f
, -0.5f
, 0), CVector( 0.5f
, 0.5f
, 0),
2979 CVector( 0.5f
, 0.5f
, 0), CVector( -0.5f
, 0.5f
, 0),
2980 CVector( -0.5f
, 0.5f
, 0), CVector( -0.5f
, -0.5f
, 0),
2982 CVector( -0.5f
, -0.5f
, 1), CVector( 0.5f
, -0.5f
, 1),
2983 CVector( 0.5f
, -0.5f
, 1), CVector( 0.5f
, 0.5f
, 1),
2984 CVector( 0.5f
, 0.5f
, 1), CVector( -0.5f
, 0.5f
, 1),
2985 CVector( -0.5f
, 0.5f
, 1), CVector( -0.5f
, -0.5f
, 1),
2987 CVector( -0.5f
, -0.5f
, 0), CVector( -0.5f
, -0.5f
, 1),
2988 CVector( 0.5f
, -0.5f
, 0), CVector( 0.5f
, -0.5f
, 1),
2989 CVector( 0.5f
, 0.5f
, 0), CVector( 0.5f
, 0.5f
, 1),
2990 CVector( -0.5f
, 0.5f
, 0), CVector( -0.5f
, 0.5f
, 1),
2993 const uint PacsCylPointCount
= 48;
2995 CVector PacsCyl
[PacsCylPointCount
] =
2997 CVector( 0, 1, 0),CVector( 0.7071067f
, 0.7071067f
, 0),
2998 CVector( 0.7071067f
, 0.7071067f
, 0),CVector( 1, 0, 0),
2999 CVector( 1, 0, 0),CVector( 0.7071067f
, -0.7071067f
,0),
3000 CVector( 0.7071067f
, -0.7071067f
,0),CVector( 0, -1, 0),
3001 CVector( 0, -1, 0),CVector( -0.7071067f
,-0.7071067f
,0),
3002 CVector( -0.7071067f
,-0.7071067f
,0),CVector( -1, 0, 0),
3003 CVector( -1, 0, 0),CVector( -0.7071067f
,0.7071067f
, 0),
3004 CVector( -0.7071067f
,0.7071067f
, 0),CVector( 0, 1, 0),
3006 CVector( 0, 1, 1),CVector( 0.7071067f
, 0.7071067f
, 1),
3007 CVector( 0.7071067f
, 0.7071067f
, 1),CVector( 1, 0, 1),
3008 CVector( 1, 0, 1),CVector( 0.7071067f
, -0.7071067f
,1),
3009 CVector( 0.7071067f
, -0.7071067f
,1),CVector( 0, -1, 1),
3010 CVector( 0, -1, 1),CVector( -0.7071067f
,-0.7071067f
,1),
3011 CVector( -0.7071067f
,-0.7071067f
,1),CVector( -1, 0, 1),
3012 CVector( -1, 0, 1),CVector( -0.7071067f
,0.7071067f
, 1),
3013 CVector( -0.7071067f
,0.7071067f
, 1),CVector( 0, 1, 1),
3015 CVector( 0, 1, 1),CVector( 0, 1, 0),
3016 CVector( 0.7071067f
, 0.7071067f
, 1),CVector( 0.7071067f
, 0.7071067f
, 0),
3017 CVector( 1, 0, 1),CVector( 1, 0, 0),
3018 CVector( 0.7071067f
, -0.7071067f
,1),CVector( 0.7071067f
, -0.7071067f
,0),
3019 CVector( 0, -1, 1),CVector( 0, -1, 0),
3020 CVector( -0.7071067f
,-0.7071067f
,1),CVector( -0.7071067f
,-0.7071067f
,0),
3021 CVector( -1, 0, 1),CVector( -1, 0, 0),
3022 CVector( -0.7071067f
,0.7071067f
, 1),CVector( -0.7071067f
,0.7071067f
, 0),
3025 void displayPACSPrimitive()
3027 std::vector
<const UMovePrimitive
*> movePrimitives
;
3029 // if no continent selected, skip
3033 PACS
->getPrimitives(movePrimitives
);
3036 for (i
=0; i
<movePrimitives
.size(); i
++)
3039 const UMovePrimitive
*prim
= movePrimitives
[i
];
3040 uint8 wI
= prim
->getFirstWorldImageV();
3043 CVector position
= prim
->getFinalPosition(wI
);
3044 if ((position
-UserEntity
->pos()).sqrnorm() < (200*200))
3048 if (prim
->isCollisionable())
3051 if (prim
->getReactionType() == UMovePrimitive::DoNothing
)
3053 line
.Color0
= CRGBA::Red
;
3057 line
.Color0
= CRGBA::Yellow
;
3063 line
.Color0
= CRGBA::White
;
3065 line
.Color1
= line
.Color0
;
3079 // Draw the primitive
3080 if (prim
->getPrimitiveType() == UMovePrimitive::_2DOrientedBox
)
3083 linecount
= PacsBoxPointCount
/2;
3086 prim
->getSize (width
, depth
);
3087 scale
.scale(CVector (width
, depth
, prim
->getHeight()));
3088 rot
.rotateZ((float)prim
->getOrientation(wI
));
3093 linecount
= PacsCylPointCount
/2;
3094 float radius
= prim
->getRadius ();
3095 scale
.scale(CVector (radius
, radius
, prim
->getHeight()));
3100 pos
.setPos (position
);
3101 pos
= pos
*rot
*scale
;
3103 // Draw the primitive
3105 for (j
=0; j
<linecount
; j
++)
3107 line
.V0
= pos
* lines
[j
*2];
3108 line
.V1
= pos
* lines
[j
*2+1];
3111 Driver
->drawLine(line
, GenericMat
);
3117 //-----------------------------------------------
3118 // displaySoundBox :
3119 //-----------------------------------------------
3120 void displaySoundBox()
3124 SoundMngr
->drawSounds(50.f
);
3129 //-----------------------------------------------
3130 // displaySceneProfiles();
3131 // nlinfo the Scene Profile results
3132 //-----------------------------------------------
3133 string
buildStrVBFormat(uint32 format
)
3135 // Yoyo: Uggly: hardcoded :)
3145 res
+= "|TexCoord1 ";
3149 res
+= "|TexCoord3 ";
3151 res
+= "|TexCoord4 ";
3153 res
+= "|TexCoord5 ";
3155 res
+= "|TexCoord6 ";
3159 res
+= "|PrimaryColor";
3161 res
+= "|SecondaryColor";
3165 res
+= "|PaletteSkin";
3171 void displaySceneProfiles()
3173 // **** Scene Profile
3174 UScene::CBenchResults res
;
3175 Scene
->getProfileResults(res
);
3178 nlinfo("****** Scene Profile Result: %d *******", id
);
3181 // Display Mesh PerVertexFormat Benchs
3182 nlinfo(" * Mesh Per VertexFormat:");
3183 std::map
<uint32
, uint32
>::iterator it
;
3184 for(it
=res
.MeshProfileTriVBFormat
.begin();it
!=res
.MeshProfileTriVBFormat
.end();it
++)
3187 string format
= buildStrVBFormat(it
->first
);
3188 nlinfo(" NumTris: %5d. Format: %s", it
->second
, format
.c_str() );
3191 // Display MeshMRM PerVertexFormat Benchs
3192 nlinfo(" * MeshMRM Per VertexFormat:");
3193 for(it
=res
.MeshMRMProfileTriVBFormat
.begin();it
!=res
.MeshMRMProfileTriVBFormat
.end();it
++)
3196 string format
= buildStrVBFormat(it
->first
);
3197 nlinfo(" NumTris: %5d. Format: %s", it
->second
, format
.c_str() );
3200 // Display BlockRendering Information
3201 nlinfo(" * Mesh BlockRender Info:");
3202 nlinfo(" NumMeshRdrNormal: %d", res
.NumMeshRdrNormal
);
3203 nlinfo(" NumMeshRdrBlock: %d", res
.NumMeshRdrBlock
);
3204 nlinfo(" NumMeshRdrBlockWithVBHeap: %d", res
.NumMeshRdrBlockWithVBHeap
);
3205 nlinfo(" NumMeshRdrNormal TriCount: %d", res
.NumMeshTriRdrNormal
);
3206 nlinfo(" NumMeshRdrBlock TriCount: %d", res
.NumMeshTriRdrBlock
);
3207 nlinfo(" NumMeshRdrBlockWithVBHeap TriCount: %d", res
.NumMeshTriRdrBlockWithVBHeap
);
3209 nlinfo(" * MeshMRM BlockRender Info:");
3210 nlinfo(" NumMeshMRMRdrNormal: %d", res
.NumMeshMRMRdrNormal
);
3211 nlinfo(" NumMeshMRMRdrBlock: %d", res
.NumMeshMRMRdrBlock
);
3212 nlinfo(" NumMeshMRMRdrBlockWithVBHeap: %d", res
.NumMeshMRMRdrBlockWithVBHeap
);
3213 nlinfo(" NumMeshMRMRdrNormal TriCount: %d", res
.NumMeshMRMTriRdrNormal
);
3214 nlinfo(" NumMeshMRMRdrBlock TriCount: %d", res
.NumMeshMRMTriRdrBlock
);
3215 nlinfo(" NumMeshMRMRdrBlockWithVBHeap TriCount: %d", res
.NumMeshMRMTriRdrBlockWithVBHeap
);
3217 // Display VBHard usage Information
3218 nlinfo(" * VBHard usage Info:");
3219 nlinfo(" NumMeshVBufferStd: %d", res
.NumMeshVBufferStd
);
3220 nlinfo(" NumMeshVBufferHard: %d", res
.NumMeshVBufferHard
);
3221 nlinfo(" NumMeshMRMVBufferStd: %d", res
.NumMeshMRMVBufferStd
);
3222 nlinfo(" NumMeshMRMVBufferHard: %d", res
.NumMeshMRMVBufferHard
);
3225 nlinfo("****** END Scene Profile Result *******");
3227 // **** Additionaly, display QuadGridClipManager profile
3228 Scene
->profileQuadGridClipManager();
3230 // **** Additionaly, display List of Landscape IG Loaded
3233 nlinfo("****** Land IG Profile *******");
3234 std::vector
<std::pair
<UInstanceGroup
*, std::string
> > igList
;
3235 LandscapeIGManager
.getAllIGWithNames(igList
);
3237 for(uint i
=0;i
<igList
.size();i
++)
3239 string igName
= CFile::getFilenameWithoutExtension(igList
[i
].second
);
3240 if( LandscapeIGManager
.isIGAddedToScene(igName
) )
3241 nlinfo("%s", igList
[i
].second
.c_str() );
3244 nlinfo("****** END Land IG Profile *******");
3249 //-----------------------------------------------
3250 // validateDialogs();
3251 // validate current dialogs by checking the distance between the two talking entities. End dialogs if they are too far
3252 //-----------------------------------------------
3253 void validateDialogs(const CGameContextMenu
&gcm
)
3256 if ( UserEntity
->trader() != CLFECOMMON::INVALID_SLOT
)
3258 CEntityCL
* trader
= EntitiesMngr
.entity(UserEntity
->trader());
3261 CVectorD vect1
= trader
->pos();
3262 CVectorD vect2
= UserEntity
->pos();
3264 double distanceSquare
= pow(vect1
.x
-vect2
.x
,2) + pow(vect1
.y
-vect2
.y
,2);
3266 if (gcm
.isBuilding())
3268 if (distanceSquare
> MaxTalkingOutpostBuildingDistSquare
)
3270 // Prevent also the Server of ending bot chat
3271 if (CBotChatManager::getInstance()->getCurrPage())
3272 CBotChatManager::getInstance()->endDialog();
3277 if(distanceSquare
> MaxTalkingDistSquare
)
3279 // Prevent also the Server of ending bot chat
3280 if(CBotChatManager::getInstance()->getCurrPage())
3281 CBotChatManager::getInstance()->endDialog();
3288 NLMISC_DYNVARIABLE(float, FPS
, "The second smoothed frame rate per second")
3290 if (get
) *pointer
= 1.0f
/smoothFPS
.getSmoothValue ();
3293 // show hide all the debuging of ui
3294 NLMISC_COMMAND(debugUI
, "Debug the ui : show/hide quads of bboxs and hotspots", "debugUI 1 or 0")
3296 if (args
.size() > 1) return false;
3298 DebugUIFilter
.clear();
3299 if (args
.size() == 1)
3301 if(!args
[0].empty() && !isdigit(args
[0][0]))
3304 DebugUIFilter
= args
[0];
3307 fromString(args
[0], on
);
3310 CGroupCell::setDebugUICell( on
);
3318 // show hide the debuging of ui
3319 NLMISC_COMMAND(debugUIView
, "Debug the ui : show/hide quads of bboxs and hotspots for views", "")
3321 DebugUIView
= !DebugUIView
;
3325 // show hide the debuging of ui
3326 NLMISC_COMMAND(debugUICtrl
, "Debug the ui : show/hide quads of bboxs and hotspots for ctrl", "")
3328 DebugUICtrl
= !DebugUICtrl
;
3332 // show hide the debuging of ui
3333 NLMISC_COMMAND(debugUIGroup
, "Debug the ui : show/hide quads of bboxs and hotspots for group", "")
3335 DebugUIGroup
= !DebugUIGroup
;
3339 // show hide the debuging of cells
3340 NLMISC_COMMAND(debugUICell
, "Debug the ui : show/hide quads of bboxs for cells", "")
3342 CGroupCell::setDebugUICell( !CGroupCell::getDebugUICell() );
3346 // Set weather value
3347 NLMISC_COMMAND(setWeatherValue
, "Set weather value", "")
3349 if (args
.size() != 1) return false;
3351 fromString(args
[0], value
);
3352 ManualWeatherValue
= value
/ (ContinentMngr
.cur()->WeatherFunction
[CurrSeason
].getNumWeatherSetups() - 1);
3356 class CHandlerDebugUIGroup
: public IActionHandler
3358 virtual void execute (CCtrlBase
* /* pCaller */, const std::string
&/* sParams */)
3360 DebugUIGroup
= !DebugUIGroup
;
3363 REGISTER_ACTION_HANDLER( CHandlerDebugUIGroup
, "debug_ui_group");
3365 class CHandlerDebugUICtrl
: public IActionHandler
3367 virtual void execute (CCtrlBase
* /* pCaller */, const std::string
&/* sParams */)
3369 DebugUICtrl
= !DebugUICtrl
;
3372 REGISTER_ACTION_HANDLER( CHandlerDebugUICtrl
, "debug_ui_ctrl");
3374 class CHandlerDebugUIView
: public IActionHandler
3376 virtual void execute (CCtrlBase
* /* pCaller */, const std::string
&/* sParams */)
3378 DebugUIView
= !DebugUIView
;
3381 REGISTER_ACTION_HANDLER( CHandlerDebugUIView
, "debug_ui_view");
3384 class CAHShowTimedFX
: public IActionHandler
3386 void execute(CCtrlBase
* /* pCaller */, const std::string
&/* params */)
3390 ShowTimedFXMode
= (CTimedFXManager::TDebugDisplayMode
) (ShowTimedFXMode
+ 1);
3391 if (ShowTimedFXMode
== CTimedFXManager::DebugModeCount
)
3393 ShowTimedFX
= false;
3399 ShowTimedFXMode
= CTimedFXManager::NoText
;
3403 // ***************************************************************************
3404 REGISTER_ACTION_HANDLER (CAHShowTimedFX
, "show_timed_fx");
3407 // ***************************************************************************
3408 void displayDebugClusters()
3410 // Get the Cluster system where the player (not the camera!) lies
3411 UGlobalPosition gPos
;
3412 if(UserEntity
->getPrimitive())
3413 UserEntity
->getPrimitive()->getGlobalPosition(gPos
, dynamicWI
);
3414 // get the cluster IG associated to this pacs position
3415 UInstanceGroup
*ig
= getCluster(gPos
);
3417 // Then display debug for it!
3419 ig
->displayDebugClusters(Driver
, TextContext
);
3421 // Draw the last camera 3rd person setuped
3424 // start to test start
3425 line
.V0
= LastDebugClusterCameraThirdPersonStart
;
3426 line
.V1
= LastDebugClusterCameraThirdPersonTestStart
;
3427 line
.Color0
= CRGBA::Blue
;
3428 line
.Color1
= CRGBA::Green
;
3429 Driver
->drawLine(line
, GenericMat
);
3431 // test start to result
3432 line
.V0
= LastDebugClusterCameraThirdPersonTestStart
;
3433 if(LastDebugClusterCameraThirdPersonForceFPV
)
3434 line
.V1
= LastDebugClusterCameraThirdPersonEnd
;
3436 line
.V1
= LastDebugClusterCameraThirdPersonResult
;
3437 line
.Color0
= CRGBA::Red
;
3438 line
.Color1
= CRGBA::Green
;
3439 Driver
->drawLine(line
, GenericMat
);
3442 if(!LastDebugClusterCameraThirdPersonForceFPV
)
3444 line
.V0
= LastDebugClusterCameraThirdPersonResult
;
3445 line
.V1
= LastDebugClusterCameraThirdPersonEnd
;
3446 line
.Color0
= CRGBA::Yellow
;
3447 line
.Color1
= CRGBA::Green
;
3448 Driver
->drawLine(line
, GenericMat
);
3451 // pelvis pos to test start
3452 line
.V0
= LastDebugClusterCameraThirdPersonPelvisPos
;
3453 line
.V1
= LastDebugClusterCameraThirdPersonTestStart
;
3454 line
.Color0
= CRGBA::Magenta
;
3455 line
.Color1
= CRGBA::Green
;
3456 Driver
->drawLine(line
, GenericMat
);
3460 NLMISC_COMMAND(dumpFontTexture
, "Write font texture to file", "")
3462 CInterfaceManager
*im
= CInterfaceManager::getInstance();
3465 std::string fname
= CFile::findNewFile("font-texture.tga");
3466 TextContext
->dumpCacheTexture(fname
.c_str());
3467 im
->displaySystemInfo(fname
+ " created", "SYS");
3471 im
->displaySystemInfo("Error: TextContext == NULL", "SYS");
3477 // ***************************************************************************
3478 void inGamePatchUncompleteWarning()
3480 CInterfaceManager
*im
= CInterfaceManager::getInstance();
3481 CLuaManager::getInstance().executeLuaScript("bgdownloader:inGamePatchUncompleteWarning()");
3483 CInterfaceManager *im = CInterfaceManager::getInstance();
3484 CGroupContainer *gc = dynamic_cast<CGroupContainer *>(CWidgetManager::getInstance()->getElementFromId("ui:interface:bg_downloader"));
3487 gc->setActive(true);
3488 CWidgetManager::getInstance()->setTopWindow(gc);
3491 im->messageBoxWithHelp(CI18N::get("uiBGD_InGamePatchIncomplete"));
3492 im->displaySystemInfo(CI18N::get("uiBGD_InGamePatchIncompleteBC"), "BC");