BVB Source Codes

CRYENGINE Show 3dEngineLoad.cpp Source code

Return Download CRYENGINE: download 3dEngineLoad.cpp Source code - Download CRYENGINE Source code - Type:.cpp
  1. // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
  2.  
  3. // -------------------------------------------------------------------------
  4. //  File name:   3dengineload.cpp
  5. //  Version:     v1.00
  6. //  Created:     28/5/2001 by Vladimir Kajalin
  7. //  Compilers:   Visual Studio.NET
  8. //  Description: Level loading
  9. // -------------------------------------------------------------------------
  10. //  History:
  11. //
  12. ////////////////////////////////////////////////////////////////////////////
  13.  
  14. #include "StdAfx.h"
  15.  
  16. #include "3dEngine.h"
  17. #include "terrain.h"
  18. #include "ObjMan.h"
  19. #include "VisAreas.h"
  20. #include <CryParticleSystem/IParticles.h>
  21. #include "ParticleSystem/ParticleSystem.h"
  22. #include "DecalManager.h"
  23. #include "Vegetation.h"
  24. #include "Brush.h"
  25. #include "MatMan.h"
  26. #include "IndexedMesh.h"
  27. #include "SkyLightManager.h"
  28. #include "ObjectsTree.h"
  29. #include "LightEntity.h"
  30. #include "WaterWaveRenderNode.h"
  31. #include "RoadRenderNode.h"
  32. #include "PhysCallbacks.h"
  33. #include "TimeOfDay.h"
  34. #include "LightEntity.h"
  35. #include "RenderMeshMerger.h"
  36. #include "FogVolumeRenderNode.h"
  37. #include "RopeRenderNode.h"
  38. #include "MergedMeshRenderNode.h"
  39. #include "BreezeGenerator.h"
  40. #include <CryAnimation/ICryAnimation.h>
  41. #include <CryAction/IMaterialEffects.h>
  42. #include "ClipVolumeManager.h"
  43.  
  44. #if defined(FEATURE_SVO_GI)
  45.         #include "SVO/SceneTreeManager.h"
  46. #endif
  47.  
  48. #define LEVEL_DATA_FILE          "LevelData.xml"
  49. #define CUSTOM_MATERIALS_FILE    "Materials.xml"
  50. #define PARTICLES_FILE           "LevelParticles.xml"
  51. #define SHADER_LIST_FILE         "ShadersList.txt"
  52. #define LEVEL_CONFIG_FILE        "Level.cfg"
  53. #define LEVEL_EDITOR_CONFIG_FILE "Editor.cfg"
  54.  
  55. inline Vec3 StringToVector(const char* str)
  56. {
  57.         Vec3 vTemp(0, 0, 0);
  58.         float x, y, z;
  59.         if (sscanf(str, "%f,%f,%f", &x, &y, &z) == 3)
  60.         {
  61.                 vTemp(x, y, z);
  62.         }
  63.         else
  64.         {
  65.                 vTemp(0, 0, 0);
  66.         }
  67.         return vTemp;
  68. }
  69.  
  70. //////////////////////////////////////////////////////////////////////////
  71. void C3DEngine::SetLevelPath(const char* szFolderName)
  72. {
  73.         // make folder path
  74.         assert(strlen(szFolderName) < 1024);
  75.         cry_strcpy(m_szLevelFolder, szFolderName);
  76.         if (strlen(m_szLevelFolder) > 0)
  77.         {
  78.                 if (m_szLevelFolder[strlen(m_szLevelFolder) - 1] != '/')
  79.                         cry_strcat(m_szLevelFolder, "/");
  80.         }
  81. }
  82.  
  83. //////////////////////////////////////////////////////////////////////////
  84. void C3DEngine::LoadDefaultAssets()
  85. {
  86.         if (GetRenderer())
  87.         {
  88.                 GetRenderer()->InitSystemResources(FRR_SYSTEM_RESOURCES);
  89.                 m_nBlackTexID = GetRenderer()->EF_LoadTexture("EngineAssets/Textures/black.dds", FT_DONT_STREAM)->GetTextureID();
  90.                 m_nBlackCMTexID = GetRenderer()->EF_LoadTexture("EngineAssets/Textures/BlackCM.dds", FT_DONT_RELEASE | FT_DONT_STREAM)->GetTextureID();
  91.                 m_nWhiteTexID = GetRenderer()->EF_LoadTexture("EngineAssets/Textures/white.dds", FT_DONT_STREAM)->GetTextureID();
  92.         }
  93.  
  94.         //Add a call to refresh the loading screen and call the loading tick functions to ensure that no big gaps in coverage occur.
  95.         SYNCHRONOUS_LOADING_TICK();
  96.  
  97. #if !defined(SYS_ENV_AS_STRUCT)
  98.         PREFAST_ASSUME(gEnv);
  99. #endif
  100.  
  101.         GetMatMan()->InitDefaults();
  102.  
  103.         m_pMatFogVolEllipsoid = GetMatMan()->LoadMaterial("EngineAssets/Materials/Fog/FogVolumeEllipsoid", false);
  104.         m_pMatFogVolBox = GetMatMan()->LoadMaterial("EngineAssets/Materials/Fog/FogVolumeBox", false);
  105.  
  106.         if (GetRenderer())
  107.         {
  108.                 if (!m_pRESky)
  109.                 {
  110.                         m_pRESky = (CRESky*)GetRenderer()->EF_CreateRE(eDATA_Sky); //m_pRESky->m_fAlpha = 1.f;
  111.                 }
  112.                 if (!m_pREHDRSky)
  113.                 {
  114.                         m_pREHDRSky = (CREHDRSky*)GetRenderer()->EF_CreateRE(eDATA_HDRSky);
  115.                 }
  116.  
  117.                 if (!m_pFarTreeSprites)
  118.                 {
  119.                         m_pFarTreeSprites = GetRenderer()->EF_LoadShader("FarTreeSprites", 0);
  120.                 }
  121.  
  122.                 if (!m_ptexIconLowMemoryUsage)
  123.                 {
  124.                         m_ptexIconLowMemoryUsage = GetRenderer()->EF_LoadTexture("EngineAssets/Icons/LowMemoryUsage.tif", FT_DONT_STREAM);
  125.                 }
  126.  
  127.                 if (!m_ptexIconAverageMemoryUsage)
  128.                 {
  129.                         m_ptexIconAverageMemoryUsage = GetRenderer()->EF_LoadTexture("EngineAssets/Icons/AverageMemoryUsage.tif", FT_DONT_STREAM);
  130.                 }
  131.  
  132.                 if (!m_ptexIconHighMemoryUsage)
  133.                 {
  134.                         m_ptexIconHighMemoryUsage = GetRenderer()->EF_LoadTexture("EngineAssets/Icons/HighMemoryUsage.tif", FT_DONT_STREAM);
  135.                 }
  136.  
  137.                 if (!m_ptexIconEditorConnectedToConsole)
  138.                 {
  139.                         m_ptexIconEditorConnectedToConsole = GetRenderer()->EF_LoadTexture("EngineAssets/Icons/LivePreview.TIF", FT_DONT_STREAM);
  140.                 }
  141.         }
  142. }
  143.  
  144. //////////////////////////////////////////////////////////////////////////
  145. bool C3DEngine::InitLevelForEditor(const char* szFolderName, const char* szMissionName)
  146. {
  147. #if !CRY_PLATFORM_DESKTOP
  148.         CRY_ASSERT_MESSAGE(0, "InitLevelForEditor not supported on consoles yet");
  149.         return false;
  150. #else
  151.         LOADING_TIME_PROFILE_SECTION;
  152.  
  153.         m_bInUnload = false;
  154.         m_bEditor = true;
  155.         m_bAreaActivationInUse = false;
  156.         m_bLayersActivated = true;
  157.  
  158.         ClearDebugFPSInfo();
  159.  
  160.         gEnv->pPhysicalWorld->DeactivateOnDemandGrid();
  161.  
  162.         gEnv->pEntitySystem->RegisterPhysicCallbacks();
  163.  
  164.         if (!szFolderName || !szFolderName[0])
  165.         { Warning("%s: Level name is not specified", __FUNCTION__); return 0; }
  166.  
  167.         if (!szMissionName || !szMissionName[0])
  168.         { Warning("%s: Mission name is not specified", __FUNCTION__); }
  169.  
  170.         SetLevelPath(szFolderName);
  171.  
  172.         // Load console vars specific to this level.
  173.         if (GetPak()->IsFileExist(GetLevelFilePath(LEVEL_CONFIG_FILE)))
  174.                 GetISystem()->LoadConfiguration(GetLevelFilePath(LEVEL_CONFIG_FILE), 0, eLoadConfigLevel);
  175.  
  176.         if (GetPak()->IsFileExist(GetLevelFilePath(LEVEL_EDITOR_CONFIG_FILE)))
  177.                 GetISystem()->LoadConfiguration(GetLevelFilePath(LEVEL_EDITOR_CONFIG_FILE), 0, eLoadConfigLevel);
  178.  
  179.         if (!m_pObjManager)
  180.                 m_pObjManager = CryAlignedNew<CObjManager>();
  181.  
  182.         if (!m_pVisAreaManager)
  183.                 m_pVisAreaManager = new CVisAreaManager();
  184.  
  185.         CRY_ASSERT(m_pClipVolumeManager->GetClipVolumeCount() == 0);
  186.         assert(gEnv->pCharacterManager);
  187.  
  188.         //////////////////////////////////////////////////////////////////////////
  189.         CryComment("initializing merged mesh manager");
  190.         m_pMergedMeshesManager->Init();
  191.  
  192.         m_pBreezeGenerator->Initialize();
  193.  
  194.         if (m_pSkyLightManager)
  195.                 m_pSkyLightManager->InitSkyDomeMesh();
  196.  
  197.         // recreate particles and decals
  198.         if (m_pPartManager)
  199.                 m_pPartManager->Reset();
  200.  
  201.         // recreate decals
  202.         SAFE_DELETE(m_pDecalManager);
  203.         m_pDecalManager = new CDecalManager();
  204.  
  205.         // restore game state
  206.         EnableOceanRendering(true);
  207.         m_pObjManager->m_bLockCGFResources = 0;
  208.  
  209.         LoadDefaultAssets();
  210.  
  211.         LoadParticleEffects(szFolderName);
  212.  
  213.         if (!m_pWaterWaveManager)
  214.         {
  215.                 m_pWaterWaveManager = new CWaterWaveManager();
  216.         }
  217.  
  218.         {
  219.                 string SettingsFileName = GetLevelFilePath("ScreenshotMap.Settings");
  220.  
  221.                 FILE* metaFile = gEnv->pCryPak->FOpen(SettingsFileName, "r");
  222.                 if (metaFile)
  223.                 {
  224.                         char Data[1024 * 8];
  225.                         gEnv->pCryPak->FRead(Data, sizeof(Data), metaFile);
  226.                         sscanf(Data, "<Map CenterX=\"%f\" CenterY=\"%f\" SizeX=\"%f\" SizeY=\"%f\" Height=\"%f\"  Quality=\"%d\" Orientation=\"%d\" />",
  227.                                &GetCVars()->e_ScreenShotMapCenterX,
  228.                                &GetCVars()->e_ScreenShotMapCenterY,
  229.                                &GetCVars()->e_ScreenShotMapSizeX,
  230.                                &GetCVars()->e_ScreenShotMapSizeY,
  231.                                &GetCVars()->e_ScreenShotMapCamHeight,
  232.                                &GetCVars()->e_ScreenShotQuality,
  233.                                &GetCVars()->e_ScreenShotMapOrientation);
  234.                         gEnv->pCryPak->FClose(metaFile);
  235.                 }
  236.         }
  237.  
  238.         LoadPhysicsData();
  239.  
  240.         GetObjManager()->LoadOcclusionMesh(szFolderName);
  241.  
  242.         //      delete m_pObjectsTree[nSID];
  243.         //      m_pObjectsTree[nSID] = NULL;
  244.         return (true);
  245. #endif
  246. }
  247.  
  248. bool C3DEngine::LoadTerrain(XmlNodeRef pDoc, std::vector<struct IStatObj*>** ppStatObjTable, std::vector<IMaterial*>** ppMatTable, int nSID, Vec3 vSegmentOrigin)
  249. {
  250.         LOADING_TIME_PROFILE_SECTION;
  251.  
  252.         PrintMessage("===== Loading %s =====", COMPILED_HEIGHT_MAP_FILE_NAME);
  253.  
  254.         // open file
  255.         FILE* f = GetPak()->FOpen(GetLevelFilePath(COMPILED_HEIGHT_MAP_FILE_NAME), "rbx");
  256.         if (!f)
  257.                 return 0;
  258.  
  259.         // read header
  260.         STerrainChunkHeader header;
  261.         if (!GetPak()->FRead(&header, 1, f, false))
  262.         {
  263.                 GetPak()->FClose(f);
  264.                 return 0;
  265.         }
  266.  
  267.         SwapEndian(header, (header.nFlags & SERIALIZATION_FLAG_BIG_ENDIAN) ? eBigEndian : eLittleEndian);
  268.         m_bLevelFilesEndian = (header.nFlags & SERIALIZATION_FLAG_BIG_ENDIAN) ? eBigEndian : eLittleEndian;
  269.  
  270.         if (header.nChunkSize)
  271.         {
  272.                 MEMSTAT_CONTEXT(EMemStatContextTypes::MSC_Terrain, 0, "Terrain");
  273.  
  274.                 if (!m_pTerrain)
  275.                         m_pTerrain = (CTerrain*)CreateTerrain(header.TerrainInfo);
  276.  
  277.                 m_pTerrain->LoadSurfaceTypesFromXML(pDoc, nSID);
  278.  
  279.                 if (!m_pTerrain->Load(f, header.nChunkSize - sizeof(STerrainChunkHeader), &header, ppStatObjTable, ppMatTable, nSID, vSegmentOrigin))
  280.                 {
  281.                         delete m_pTerrain;
  282.                         m_pTerrain = NULL;
  283.                 }
  284.         }
  285.  
  286.         assert(GetPak()->FEof(f));
  287.  
  288.         GetPak()->FClose(f);
  289.  
  290.         return m_pTerrain != NULL;
  291. }
  292.  
  293. bool C3DEngine::LoadVisAreas(std::vector<struct IStatObj*>** ppStatObjTable, std::vector<IMaterial*>** ppMatTable)
  294. {
  295.         LOADING_TIME_PROFILE_SECTION;
  296.  
  297.         PrintMessage("===== Loading %s =====", COMPILED_VISAREA_MAP_FILE_NAME);
  298.  
  299.         // open file
  300.         FILE* f = GetPak()->FOpen(GetLevelFilePath(COMPILED_VISAREA_MAP_FILE_NAME), "rbx");
  301.         if (!f)
  302.                 return false;
  303.  
  304.         // read header
  305.         SVisAreaManChunkHeader header;
  306.         if (!GetPak()->FRead(&header, 1, f, false))
  307.         {
  308.                 GetPak()->FClose(f);
  309.                 return 0;
  310.         }
  311.  
  312.         SwapEndian(header, (header.nFlags & SERIALIZATION_FLAG_BIG_ENDIAN) ? eBigEndian : eLittleEndian);
  313.  
  314.         if (header.nChunkSize)
  315.         {
  316.                 assert(!m_pVisAreaManager);
  317.                 m_pVisAreaManager = new CVisAreaManager();
  318.                 if (!m_pVisAreaManager->Load(f, header.nChunkSize, &header, *ppStatObjTable, *ppMatTable))
  319.                 {
  320.                         delete m_pVisAreaManager;
  321.                         m_pVisAreaManager = NULL;
  322.                 }
  323.         }
  324.  
  325.         assert(GetPak()->FEof(f));
  326.  
  327.         GetPak()->FClose(f);
  328.  
  329.         return m_pVisAreaManager != NULL;
  330. }
  331.  
  332. //////////////////////////////////////////////////////////////////////////
  333. void C3DEngine::UnloadLevel()
  334. {
  335.         if (GetRenderer())
  336.         {
  337.                 GetRenderer()->EnableLevelUnloading(true);
  338.         }
  339.         GetISystem()->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_LEVEL_UNLOAD, 0, 0);
  340.  
  341.         if (GetRenderer())
  342.         {
  343.                 GetRenderer()->EnableLevelUnloading(false);
  344.         }
  345.  
  346.         m_bInUnload = true;
  347.         m_szLevelFolder[0] = 0;
  348.  
  349.         if (GetRenderer())
  350.         {
  351.                 GetRenderer()->FlushRTCommands(true, true, true);
  352.         }
  353.        
  354.         // release CGF and materials table
  355.         for (uint32 i = 0; m_pLevelStatObjTable && i < m_pLevelStatObjTable->size(); i++)
  356.         {
  357.                 SAFE_RELEASE((*m_pLevelStatObjTable)[i]);
  358.         }
  359.         SAFE_DELETE(m_pLevelStatObjTable);
  360.  
  361.         for (uint32 i = 0; m_pLevelMaterialsTable && i < m_pLevelMaterialsTable->size(); i++)
  362.         {
  363.                 SAFE_RELEASE((*m_pLevelMaterialsTable)[i]);
  364.         }
  365.         SAFE_DELETE(m_pLevelMaterialsTable);
  366.  
  367.         m_arrObjectLayersActivity.Reset();
  368.         COctreeNode::m_nNodesCounterStreamable = 0;
  369.  
  370. #if defined(FEATURE_SVO_GI)
  371.         CSvoManager::Release();
  372. #endif
  373.  
  374.         m_visibleNodesManager.ClearAll();
  375.  
  376.         FreeFoliages();
  377.  
  378.         if (m_pSkyLightManager)
  379.                 m_pSkyLightManager->ReleaseSkyDomeMesh();
  380.  
  381.         // free vegetation and brush CGF's
  382.         m_lstKilledVegetations.Reset();
  383.  
  384.         ResetPostEffects();
  385.  
  386.         if (m_pPartManager)
  387.         {
  388.                 // Force clear of all deferred release operations
  389.                 m_pPartManager->ClearDeferredReleaseResources();
  390.         }
  391.  
  392.         if (gEnv->pCharacterManager)
  393.         {
  394.                 CryComment("Deleting Characters");
  395.                 gEnv->pCharacterManager->ClearResources(false);
  396.                 CryComment("done");
  397.         }
  398.  
  399.         //SAFE_DELETE(m_pObjManager);
  400.         // delete terrain
  401.  
  402.         // delete decal manager
  403.         if (m_pDecalManager)
  404.         {
  405.                 CryComment("Deleting Decals");
  406.                 SAFE_DELETE(m_pDecalManager);
  407.                 CryComment("done");
  408.         }
  409.  
  410.         if (m_pTerrain)
  411.         {
  412.                 CryComment("Deleting Terain");
  413.                 SAFE_DELETE(m_pTerrain);
  414.                 CryComment("done");
  415.         }
  416.  
  417.         // delete outdoor objects
  418.         CryComment("Deleting Octree");
  419.         for (int nSID = 0; nSID < m_pObjectsTree.Count(); nSID++)
  420.         {
  421.                 SAFE_DELETE(m_pObjectsTree[nSID]);
  422.         }
  423.         m_pObjectsTree.Reset();
  424.  
  425.         // set as unsafe
  426.         for (int nSID = 0; nSID < m_safeToUseSegments.Count(); nSID++)
  427.                 m_safeToUseSegments[nSID] = 0;
  428.  
  429.         // delete indoors
  430.         if (m_pVisAreaManager)
  431.         {
  432.                 CryComment("Deleting VisAreas");
  433.                 SAFE_DELETE(m_pVisAreaManager);
  434.                 CryComment("done");
  435.         }
  436.  
  437.         CRY_ASSERT(m_pClipVolumeManager->GetClipVolumeCount() == 0);
  438.         CRY_ASSERT(!COctreeNode::m_nNodesCounterAll);
  439.  
  440.         if (m_pWaterWaveManager)
  441.         {
  442.                 CryComment("Deleting WaterWaves");
  443.                 SAFE_DELETE(m_pWaterWaveManager);
  444.                 CryComment("done");
  445.         }
  446.  
  447.         m_LightVolumesMgr.Reset();
  448.  
  449.         m_pTerrainWaterMat = 0;
  450.         m_nWaterBottomTexId = 0;
  451.  
  452.         //////////////////////////////////////////////////////////////////////////
  453.         CryComment("Removing Lights ...");
  454.         for (int i = 0; i < m_lstDynLights.Count(); i++)
  455.         {
  456.                 CDLight* pLight = m_lstDynLights[i];
  457.                 FreeLightSourceComponents(pLight);
  458.         }
  459.         m_lstDynLights.Reset();
  460.         DeleteAllStaticLightSources();
  461.         SAFE_DELETE(m_pSun);
  462.         CryComment("done");
  463.         //////////////////////////////////////////////////////////////////////////
  464.  
  465.         CleanLevelShaders();
  466.  
  467.         if (m_pRESky)
  468.                 m_pRESky->Release(true);
  469.         if (m_pREHDRSky)
  470.                 m_pREHDRSky->Release(true);
  471.         m_pRESky = 0;
  472.         m_pREHDRSky = 0;
  473.         stl::free_container(m_skyMatName);
  474.         stl::free_container(m_skyLowSpecMatName);
  475.  
  476.         if (m_nCloudShadowTexId)
  477.         {
  478.                 ITexture* tex = GetRenderer()->EF_GetTextureByID(m_nCloudShadowTexId);
  479.                 if (tex)
  480.                         tex->Release();
  481.  
  482.                 m_nCloudShadowTexId = 0;
  483.                 GetRenderer()->SetCloudShadowsParams(0, Vec3(0, 0, 0), 1, false, 1);
  484.                 SetGlobalParameter(E3DPARAM_VOLFOG_SHADOW_ENABLE, Vec3(0, 0, 0));
  485.         }
  486.  
  487.         // reset volumetric cloud parameters
  488.         {
  489.                 // reset wind influence, tiling size, and tiling offset
  490.                 SetGlobalParameter(E3DPARAM_VOLCLOUD_WIND_ATMOSPHERIC, Vec3(0.0f, 0.0f, 0.0f));
  491.                 SetGlobalParameter(E3DPARAM_VOLCLOUD_TILING_SIZE, Vec3(64000.0f, 64000.0f, 4000.0f));
  492.                 SetGlobalParameter(E3DPARAM_VOLCLOUD_TILING_OFFSET, Vec3(0.0f, 0.0f, 0.0f));
  493.  
  494.                 SetGlobalParameter(E3DPARAM_VOLCLOUD_ENV_PARAMS, Vec3(6360000.0f, 0.0f, -1000.0f));
  495.                 SetGlobalParameter(E3DPARAM_VOLCLOUD_GLOBAL_NOISE_SCALE, Vec3(3, 3, 5));
  496.                 SetGlobalParameter(E3DPARAM_VOLCLOUD_RENDER_PARAMS, Vec3(100000.0f, 35000.0f, 64.0f));
  497.                 SetGlobalParameter(E3DPARAM_VOLCLOUD_TURBULENCE_NOISE_SCALE, Vec3(1.0f, 1.0f, 1.0f));
  498.                 SetGlobalParameter(E3DPARAM_VOLCLOUD_TURBULENCE_NOISE_PARAMS, Vec3(1.0f, 1.0f, 0.0f));
  499.                 SetGlobalParameter(E3DPARAM_VOLCLOUD_DENSITY_PARAMS, Vec3(0.04f, 0.0f, 1.0f));
  500.                 SetGlobalParameter(E3DPARAM_VOLCLOUD_MISC_PARAM, Vec3(0.2f, 0.1f, 16000.0f));
  501.  
  502.                 // reset texture
  503.                 if (GetRenderer())
  504.                 {
  505.                         GetRenderer()->SetVolumetricCloudParams(0);
  506.                 }
  507.         }
  508.  
  509.         if (m_nNightMoonTexId)
  510.         {
  511.                 ITexture* tex = GetRenderer()->EF_GetTextureByID(m_nNightMoonTexId);
  512.                 if (tex)
  513.                         tex->Release();
  514.  
  515.                 m_nNightMoonTexId = 0;
  516.         }
  517.  
  518.         //////////////////////////////////////////////////////////////////////////
  519.         if (m_pPartManager || m_pParticleSystem)
  520.         {
  521.                 CryComment("Purge particles");
  522.                 // Force to clean all particles that are left, even if still referenced.
  523.                 if (m_pPartManager)
  524.                         m_pPartManager->ClearRenderResources(true);
  525.                 if (m_pParticleSystem)
  526.                         static_cast<pfx2::CParticleSystem*>(m_pParticleSystem.get())->ClearRenderResources();
  527.                 CryComment("done");
  528.         }
  529.  
  530.         //////////////////////////////////////////////////////////////////////////
  531.         if (gEnv->pCharacterManager)
  532.         {
  533.                 // Moved here as the particles need to be torn down before the char instances
  534.                 CryComment("Purge Characters");
  535.                 // Delete all character instances and models.
  536.                 gEnv->pCharacterManager->ClearResources(true);
  537.                 CryComment("done");
  538.         }
  539.  
  540.         //////////////////////////////////////////////////////////////////////////
  541.         if (m_pObjManager)
  542.         {
  543.                 bool bDeleteAll = !m_bEditor || m_bInShutDown;
  544.                 CryComment("Deleting Static Objects");
  545.                 m_pObjManager->UnloadObjects(bDeleteAll);
  546.                 m_pObjManager->m_CullThread.UnloadLevel();
  547.                 CryComment("done");
  548.         }
  549.  
  550.         for (int nSID = 0; nSID < Get3DEngine()->m_pObjectsTree.Count(); nSID++)
  551.         {
  552.                 assert(m_pObjectsTree[nSID] == NULL);
  553.         }
  554.  
  555.         //[AlexMcC|28.04.10]: If we don't clear this array when chainloading, the first call to
  556.         // C3DEngine::RegisterEntity will create a COctTree and store it in m_pObjectsTree,
  557.         // which we'll leak when we hit CTerrain::CreateSegment
  558.         m_pObjectsTree.clear();
  559.         COctreeNode::StaticReset();
  560.  
  561.         //////////////////////////////////////////////////////////////////////////
  562.         // Force delete all materials.
  563.         //////////////////////////////////////////////////////////////////////////
  564.         if (GetMatMan() && !m_bEditor)
  565.         {
  566.                 // Should be after deleting all meshes.
  567.                 // We force delete all materials.
  568.                 CryComment("Deleting Materials");
  569.                 GetMatMan()->ShutDown();
  570.                 CryComment("done");
  571.         }
  572.  
  573.         if (!gEnv->IsDedicated())
  574.         {
  575.                 SAFE_RELEASE_FORCE(m_ptexIconLowMemoryUsage);
  576.                 SAFE_RELEASE_FORCE(m_ptexIconAverageMemoryUsage);
  577.                 SAFE_RELEASE_FORCE(m_ptexIconHighMemoryUsage);
  578.                 SAFE_RELEASE_FORCE(m_ptexIconEditorConnectedToConsole);
  579.  
  580.                 //////////////////////////////////////////////////////////////////////////
  581.                 // Relases loaded default loaded textures.
  582.                 //////////////////////////////////////////////////////////////////////////
  583.                 {
  584.                         SAFE_RELEASE(m_ptexIconAverageMemoryUsage);
  585.                         SAFE_RELEASE(m_ptexIconLowMemoryUsage);
  586.                         SAFE_RELEASE(m_ptexIconHighMemoryUsage);
  587.                         SAFE_RELEASE(m_ptexIconEditorConnectedToConsole);
  588.                 }
  589.         }
  590.         else
  591.         {
  592.                 // loading a texture will return default on the dedicated server,
  593.                 // therefore we just NULL the pointers here as it would be bad to delete them,
  594.                 // bad things happen if we do
  595.                 m_ptexIconAverageMemoryUsage = NULL;
  596.                 m_ptexIconLowMemoryUsage = NULL;
  597.                 m_ptexIconHighMemoryUsage = NULL;
  598.                 m_ptexIconEditorConnectedToConsole = NULL;
  599.         }
  600.  
  601.         if (m_pOpticsManager && !gEnv->IsEditor())
  602.         {
  603.                 m_pOpticsManager->Reset();
  604.         }
  605.  
  606.         //////////////////////////////////////////////////////////////////////////
  607.         m_pBreezeGenerator->Shutdown();
  608.  
  609.         //////////////////////////////////////////////////////////////////////////
  610.         // Delete physics related things.
  611.         //////////////////////////////////////////////////////////////////////////
  612.         if (gEnv->pEntitySystem)
  613.                 gEnv->pEntitySystem->UnregisterPhysicCallbacks();
  614.         UnloadPhysicsData();
  615.  
  616.         stl::free_container(m_lstRoadRenderNodesForUpdate);
  617.         stl::free_container(m_lstAlwaysVisible);
  618.         if (m_decalRenderNodes.empty())
  619.                 stl::free_container(m_decalRenderNodes);
  620.         stl::free_container(m_tmpLstLights);
  621.         stl::free_container(m_tmpLstAffectingLights);
  622.         stl::free_container(m_lstPerObjectShadows);
  623.         m_nCustomShadowFrustumCount = 0;
  624.  
  625.         Cry3DEngineBase::m_pRenderMeshMerger->Reset();
  626.  
  627.         SAFE_DELETE(m_pTimeOfDay);
  628.         CLightEntity::StaticReset();
  629.         CVisArea::StaticReset();
  630.         CRoadRenderNode::FreeStaticMemoryUsage();
  631.         CFogVolumeRenderNode::StaticReset();
  632.         CRopeRenderNode::StaticReset();
  633.  
  634.         if (GetRenderer())
  635.         {
  636.                 GetRenderer()->FlushRTCommands(true, true, true);
  637.         }
  638.  
  639.         IDeferredPhysicsEventManager* pPhysEventManager = GetDeferredPhysicsEventManager();
  640.         if (pPhysEventManager)
  641.         {
  642.                 pPhysEventManager->ClearDeferredEvents();
  643.         }
  644.  
  645.         //////////////////////////////////////////////////////////////////////////
  646.         CryComment("Shutting down merged mesh manager");
  647.         m_pMergedMeshesManager->Shutdown();
  648.  
  649.         //////////////////////////////////////////////////////////////////////////
  650.         // clear data used for SRenderingPass
  651.         stl::free_container(m_RenderingPassCameras[0]);
  652.         stl::free_container(m_RenderingPassCameras[1]);
  653.         stl::free_container(m_deferredRenderProxyStreamingPriorityUpdates);
  654.  
  655.         for (auto& pFr : m_lstCustomShadowFrustums)
  656.         {
  657.                 CRY_ASSERT(pFr->Unique());
  658.                 SAFE_RELEASE(pFr);
  659.         }
  660.         stl::free_container(m_lstCustomShadowFrustums);
  661.  
  662.         stl::free_container(m_collisionClasses);
  663. }
  664.  
  665. //////////////////////////////////////////////////////////////////////////
  666. void C3DEngine::LoadFlaresData()
  667. {
  668.         MEMSTAT_CONTEXT(EMemStatContextTypes::MSC_Other, 0, "Flare data");
  669.  
  670.         string flareExportListPath = gEnv->p3DEngine->GetLevelFilePath(FLARE_EXPORT_FILE);
  671.         XmlNodeRef pFlareRootNode = gEnv->pSystem->LoadXmlFromFile(flareExportListPath);
  672.  
  673.         if (pFlareRootNode == NULL)
  674.                 return;
  675.  
  676.         int nFlareExportFileVer = 0;
  677.         pFlareRootNode->getAttr("Version", nFlareExportFileVer);
  678.  
  679.         for (int i = 0, iCount(pFlareRootNode->getChildCount()); i < iCount; ++i)
  680.         {
  681.                 XmlNodeRef pFlareNode = pFlareRootNode->getChild(i);
  682.                 if (pFlareNode == NULL)
  683.                         continue;
  684.                 const char* flareName = NULL;
  685.                 if (!pFlareNode->getAttr("name", &flareName))
  686.                         continue;
  687.                 int nOutIndex(-1);
  688.  
  689.                 if (nFlareExportFileVer == 0)
  690.                 {
  691.                         gEnv->pOpticsManager->Load(flareName, nOutIndex);
  692.                 }
  693.                 else if (nFlareExportFileVer == 1)
  694.                 {
  695.                         if (pFlareNode->getChildCount() == 0)
  696.                         {
  697.                                 gEnv->pOpticsManager->Load(flareName, nOutIndex);
  698.                         }
  699.                         else if (pFlareNode->getChildCount() > 0)
  700.                         {
  701.                                 gEnv->pOpticsManager->Load(pFlareNode, nOutIndex);
  702.                         }
  703.                 }
  704.         }
  705. }
  706.  
  707. //////////////////////////////////////////////////////////////////////////
  708. bool C3DEngine::LoadLevel(const char* szFolderName, const char* szMissionName)
  709. {
  710.         LOADING_TIME_PROFILE_SECTION;
  711.  
  712. #if !defined(SYS_ENV_AS_STRUCT)
  713.         PREFAST_ASSUME(gEnv);
  714. #endif
  715.  
  716.         stl::scoped_set<bool> setInLoad(m_bInLoad, true);
  717.  
  718.         m_bInUnload = false;
  719.         m_bAreaActivationInUse = false;
  720.         m_bLayersActivated = false;
  721.         m_eShadowMode = ESM_NORMAL;
  722.  
  723.         m_vPrevMainFrameCamPos.Set(-1000000.f, -1000000.f, -1000000.f);
  724.         m_vAverageCameraMoveDir = Vec3(0);
  725.         m_fAverageCameraSpeed = 0;
  726.  
  727.         ClearDebugFPSInfo();
  728.  
  729. #if CRY_PLATFORM_DESKTOP
  730.         m_bEditor = false;
  731. #endif
  732.  
  733.         gEnv->pEntitySystem->RegisterPhysicCallbacks();
  734.  
  735.         assert(!m_bEditor);
  736.  
  737.         //////////////////////////////////////////////////////////////////////////
  738.         CryComment("initializing merged mesh manager");
  739.         m_pMergedMeshesManager->Init();
  740.  
  741.         //////////////////////////////////////////////////////////////////////////
  742.         m_pBreezeGenerator->Initialize();
  743.  
  744.         if (!szFolderName || !szFolderName[0])
  745.         {
  746.                 Warning("%s: Level name is not specified", __FUNCTION__);
  747.                 return 0;
  748.         }
  749.  
  750.         if (!szMissionName || !szMissionName[0])
  751.         { Warning("%s: Mission name is not specified", __FUNCTION__); }
  752.  
  753.         char szMissionNameBody[256] = "NoMission";
  754.         if (!szMissionName)
  755.                 szMissionName = szMissionNameBody;
  756.  
  757.         SetLevelPath(szFolderName);
  758.  
  759.         if (GetPak()->IsFileExist(GetLevelFilePath(LEVEL_CONFIG_FILE)))
  760.                 GetISystem()->LoadConfiguration(GetLevelFilePath(LEVEL_CONFIG_FILE), 0, eLoadConfigLevel);
  761.  
  762.         {
  763.                 // check is LevelData.xml file exist
  764.                 char sMapFileName[_MAX_PATH];
  765.                 cry_strcpy(sMapFileName, m_szLevelFolder);
  766.                 cry_strcat(sMapFileName, LEVEL_DATA_FILE);
  767.                 if (!IsValidFile(sMapFileName))
  768.                 {
  769.                         PrintMessage("Error: Level not found: %s", sMapFileName);
  770.                         return 0;
  771.                 }
  772.         }
  773.  
  774.         if (!m_pObjManager)
  775.         {
  776.                 m_pObjManager = CryAlignedNew<CObjManager>();
  777.         }
  778.  
  779.         CRY_ASSERT(m_pClipVolumeManager->GetClipVolumeCount() == 0);
  780.         assert(gEnv->pCharacterManager);
  781.  
  782.         // Load and activate all shaders used by the level before activating any shaders
  783.         if (!m_bEditor && GetRenderer())
  784.         {
  785.                 LoadUsedShadersList();
  786.  
  787.                 GetRenderer()->EF_Query(EFQ_SetDynTexSourceLayerInfo);
  788.         }
  789.  
  790.         LoadDefaultAssets();
  791.  
  792.         if (m_pSkyLightManager)
  793.                 m_pSkyLightManager->InitSkyDomeMesh();
  794.  
  795.         // Load LevelData.xml File.
  796.         XmlNodeRef xmlLevelData = GetSystem()->LoadXmlFromFile(GetLevelFilePath(LEVEL_DATA_FILE));
  797.  
  798.         if (xmlLevelData == 0)
  799.         {
  800.                 Error("%s: xml file not found (files missing?)", __FUNCTION__);  // files missing ?
  801.                 return false;
  802.         }
  803.  
  804.         // re-create decal manager
  805.         SAFE_DELETE(m_pDecalManager);
  806.         m_pDecalManager = new CDecalManager();
  807.  
  808.         SAFE_DELETE(m_pWaterWaveManager);
  809.         m_pWaterWaveManager = new CWaterWaveManager();
  810.  
  811.         gEnv->pSystem->SetSystemGlobalState(ESYSTEM_GLOBAL_STATE_LEVEL_LOAD_START_MATERIALS);
  812.         if (GetCVars()->e_PreloadMaterials)
  813.         {
  814.                 // Preload materials.
  815.                 GetMatMan()->PreloadLevelMaterials();
  816.         }
  817.         if (GetCVars()->e_PreloadDecals)
  818.         {
  819.                 // Preload materials.
  820.                 GetMatMan()->PreloadDecalMaterials();
  821.         }
  822.  
  823.         // Preload any geometry used by merged meshes
  824.         m_pMergedMeshesManager->PreloadMeshes();
  825.  
  826.         gEnv->pSystem->SetSystemGlobalState(ESYSTEM_GLOBAL_STATE_LEVEL_LOAD_START_OBJECTS);
  827.         // preload level cgfs
  828.         if (GetCVars()->e_StatObjPreload && !gEnv->IsEditor())
  829.         {
  830.                 if (GetCVars()->e_StatObjPreload == 2)
  831.                         GetSystem()->OutputLoadingTimeStats();
  832.  
  833.                 m_pObjManager->PreloadLevelObjects();
  834.  
  835.                 if (GetCVars()->e_StatObjPreload == 2)
  836.                 {
  837.                         GetSystem()->OutputLoadingTimeStats();
  838.                 }
  839.  
  840.                 gEnv->pSystem->SetSystemGlobalState(ESYSTEM_GLOBAL_STATE_LEVEL_LOAD_START_CHARACTERS);
  841.                 if (gEnv->pCharacterManager)
  842.                 {
  843.                         PrintMessage("Starting loading level characters ...");
  844.                         INDENT_LOG_DURING_SCOPE();
  845.                         float fStartTime = GetCurAsyncTimeSec();
  846.  
  847.                         gEnv->pCharacterManager->PreloadLevelModels();
  848.  
  849.                         float dt = GetCurAsyncTimeSec() - fStartTime;
  850.                         PrintMessage("Finished loading level characters (%.1f sec)", dt);
  851.                 }
  852.         }
  853.  
  854.         assert(!m_pLevelStatObjTable);
  855.         assert(!m_pLevelMaterialsTable);
  856.         assert(!m_arrObjectLayersActivity.Count());
  857.  
  858.         int nSID = 0;
  859.  
  860.         // load terrain
  861.         XmlNodeRef nodeRef = xmlLevelData->findChild("SurfaceTypes");
  862.  
  863.         LoadCollisionClasses(xmlLevelData->findChild("CollisionClasses"));
  864.  
  865.         gEnv->pSystem->SetSystemGlobalState(ESYSTEM_GLOBAL_STATE_LEVEL_LOAD_START_STATIC_WORLD);
  866.  
  867. #if defined(FEATURE_SVO_GI)
  868.         if (GetCVars()->e_svoTI_Active >= 0)
  869.         {
  870.                 // Load SVOGI settings (must be called before loading of brushes, vegetation and textures)
  871.                 char szFileName[256];
  872.                 cry_sprintf(szFileName, "mission_%s.xml", szMissionName);
  873.                 XmlNodeRef xmlMission = GetSystem()->LoadXmlFromFile(Get3DEngine()->GetLevelFilePath(szFileName));
  874.                 if (xmlMission)
  875.                         LoadTISettings(xmlMission->findChild("Environment"));
  876.         }
  877. #endif
  878.  
  879.         if (!m_pSegmentsManager)
  880.         {
  881.                 if (!LoadTerrain(nodeRef, &m_pLevelStatObjTable, &m_pLevelMaterialsTable, nSID, Vec3(0, 0, 0)))
  882.                 {
  883.                         Error("Terrain file (%s) not found or file version error, please try to re-export the level", COMPILED_HEIGHT_MAP_FILE_NAME);
  884.                         return false;
  885.                 }
  886.  
  887.                 // load indoors
  888.                 if (!LoadVisAreas(&m_pLevelStatObjTable, &m_pLevelMaterialsTable))
  889.                 {
  890.                         Error("VisAreas file (%s) not found or file version error, please try to re-export the level", COMPILED_VISAREA_MAP_FILE_NAME);
  891.                         return false;
  892.                 }
  893.         }
  894.         else
  895.         {
  896.                 PrintMessage("===== Load terrain called with segments manager active =====");
  897.  
  898.                 PrintMessage("Loading level info");
  899.                 XmlNodeRef levelInfo = GetISystem()->LoadXmlFromFile(GetLevelFilePath(LEVEL_INFO_FILE_NAME));
  900.                 XmlNodeRef terrainInfoNode = levelInfo->findChild("TerrainInfo");
  901.                 STerrainInfo terrainInfo;
  902.                 terrainInfoNode->getAttr("UnitSize", terrainInfo.nUnitSize_InMeters);
  903.  
  904.                 //terrainInfoNode->getAttr("HeightmapSize", terrainInfo.nHeightMapSize_InUnits);
  905.                 int xm, ym;
  906.                 m_pSegmentsManager->GetTerrainSizeInMeters(xm, ym);
  907.                 terrainInfo.nHeightMapSize_InUnits = max(xm, ym) / terrainInfo.nUnitSize_InMeters;
  908.  
  909.                 terrainInfoNode->getAttr("SectorSize", terrainInfo.nSectorSize_InMeters);
  910.                 terrainInfoNode->getAttr("SectorsTableSize", terrainInfo.nSectorsTableSize_InSectors);
  911.                 terrainInfoNode->getAttr("HeightmapZRatio", terrainInfo.fHeightmapZRatio);
  912.                 terrainInfoNode->getAttr("OceanWaterLevel", terrainInfo.fOceanWaterLevel);
  913.  
  914.                 if (!m_pTerrain)
  915.                 {
  916.                         m_pTerrain = (CTerrain*)CreateTerrain(terrainInfo);
  917.                         m_pTerrain->DeleteSegment(0, true);
  918.  
  919.                         int nCellSize = CTerrain::GetTerrainSize() > 2048 ? CTerrain::GetTerrainSize() >> 10 : 2;
  920.                         nCellSize = max(nCellSize, GetCVars()->e_PhysMinCellSize);
  921.                         int log2PODGridSize = 0;
  922.                         if (nCellSize == 2)
  923.                                 log2PODGridSize = 2;
  924.                         else if (nCellSize == 4)
  925.                                 log2PODGridSize = 1;
  926.                         GetPhysicalWorld()->SetupEntityGrid(2, Vec3(0, 0, 0), // this call will destroy all physicalized stuff
  927.                                                             CTerrain::GetTerrainSize() / nCellSize, CTerrain::GetTerrainSize() / nCellSize, (float)nCellSize, (float)nCellSize, log2PODGridSize);
  928.                 }
  929.                 if (!m_pVisAreaManager)
  930.                 {
  931.                         m_pVisAreaManager = new CVisAreaManager();
  932.                 }
  933.         }
  934.  
  935.         COctreeNode::FreeLoadingCache();
  936.  
  937.         // Preload any geometry used by merged meshes
  938.         if (m_pMergedMeshesManager->SyncPreparationStep() == false)
  939.         {
  940.                 Error("some merged meshes failed to prepare properly (missing cgfs, re-export?!)");
  941.         }
  942.  
  943.         // re-create particles and decals
  944.         if (m_pPartManager)
  945.                 m_pPartManager->Reset();
  946.  
  947.         //Update loading screen and important tick functions
  948.         SYNCHRONOUS_LOADING_TICK();
  949.  
  950.         LoadParticleEffects(szFolderName);
  951.  
  952.         PrintMessage("===== Loading mission settings from XML =====");
  953.  
  954.         //Update loading screen and important tick functions
  955.         SYNCHRONOUS_LOADING_TICK();
  956.  
  957.         // load leveldata.xml
  958.         m_pTerrainWaterMat = 0;
  959.         m_nWaterBottomTexId = 0;
  960.         LoadMissionDataFromXMLNode(szMissionName);
  961.  
  962.         //Update loading screen and important tick functions
  963.         SYNCHRONOUS_LOADING_TICK();
  964.  
  965.         if (!m_bShowTerrainSurface)
  966.         {
  967.                 gEnv->pPhysicalWorld->SetHeightfieldData(NULL);
  968.         }
  969.  
  970.         // init water if not initialized already (if no mission was found)
  971.         if (m_pTerrain && !m_pTerrain->GetOcean())
  972.         {
  973.                 PrintMessage("===== Creating Ocean =====");
  974.                 m_pTerrain->InitTerrainWater(m_pTerrainWaterMat, m_nWaterBottomTexId);
  975.         }
  976.  
  977.         PrintMessage("===== Load level physics data =====");
  978.         LoadPhysicsData();
  979.         LoadFlaresData();
  980.  
  981.         // restore game state
  982.         EnableOceanRendering(true);
  983.         m_pObjManager->m_bLockCGFResources = 0;
  984.  
  985.         PrintMessage("===== loading occlusion mesh =====");
  986.  
  987.         GetObjManager()->LoadOcclusionMesh(szFolderName);
  988.  
  989.         PrintMessage("===== Finished loading static world =====");
  990.  
  991.         m_skipedLayers.clear();
  992.  
  993.         if (gEnv->pMaterialEffects)
  994.         {
  995.                 gEnv->pMaterialEffects->CompleteInit();
  996.         }
  997.  
  998.         return (true);
  999. }
  1000.  
  1001. //////////////////////////////////////////////////////////////////////////
  1002. void C3DEngine::LoadPhysicsData()
  1003. {
  1004.         CPhysCallbacks::Init();
  1005. }
  1006.  
  1007. static void OnReleaseGeom(IGeometry* pGeom)
  1008. {
  1009.         if (IStatObj* pStatObj = (IStatObj*)pGeom->GetForeignData())
  1010.                 pStatObj->Release();
  1011. }
  1012.  
  1013. void C3DEngine::UnloadPhysicsData()
  1014. {
  1015.         if (m_pGlobalWind != 0)
  1016.         {
  1017.                 gEnv->pPhysicalWorld->DestroyPhysicalEntity(m_pGlobalWind);
  1018.                 m_pGlobalWind = 0;
  1019.         }
  1020.         if (gEnv->pPhysicalWorld)
  1021.         {
  1022.                 // Pause and wait for the physics
  1023.                 gEnv->pSystem->SetThreadState(ESubsys_Physics, false);
  1024.  
  1025.                 gEnv->pPhysicalWorld->RemoveAllExplosionShapes(OnReleaseGeom);
  1026.                 gEnv->pPhysicalWorld->GetGeomManager()->UnregisterAllCracks(OnReleaseGeom);
  1027.  
  1028.                 CryComment("Physics PurgeDeletedEntities...");
  1029.                 gEnv->pPhysicalWorld->DeactivateOnDemandGrid();
  1030.                 gEnv->pPhysicalWorld->PurgeDeletedEntities();
  1031.                 CryComment("done");
  1032.  
  1033.                 CPhysCallbacks::Done();
  1034.  
  1035.                 if (!gEnv->IsEditor())
  1036.                 {
  1037.                         CryComment("Physics Cleanup...");
  1038.                         gEnv->pPhysicalWorld->Cleanup();
  1039.                         CryComment("Physics Cleanup done");
  1040.                 }
  1041.         }
  1042.         //////////////////////////////////////////////////////////////////////////
  1043. }
  1044.  
  1045. //////////////////////////////////////////////////////////////////////////
  1046. void C3DEngine::LoadCollisionClasses(XmlNodeRef node)
  1047. {
  1048.         m_collisionClasses.clear();
  1049.         if (node)
  1050.         {
  1051.                 int count = node->getChildCount();
  1052.                 m_collisionClasses.reserve(count);
  1053.                 for (int i = 0; i < count; i++)
  1054.                 {
  1055.                         SCollisionClass cc(0, 0);
  1056.                         XmlNodeRef xmlCC = node->getChild(i);
  1057.                         xmlCC->getAttr("type", cc.type);
  1058.                         xmlCC->getAttr("ignore", cc.ignore);
  1059.                         m_collisionClasses.push_back(cc);
  1060.                 }
  1061.         }
  1062. }
  1063.  
  1064. void C3DEngine::FreeFoliages()
  1065. {
  1066.         if (m_pFirstFoliage)
  1067.         {
  1068.                 CryComment("Removing physicalized foliages ...");
  1069.                 CStatObjFoliage* pFoliage, * pFoliageNext;
  1070.                 for (pFoliage = m_pFirstFoliage; &pFoliage->m_next != &m_pFirstFoliage; pFoliage = pFoliageNext)
  1071.                 {
  1072.                         pFoliageNext = pFoliage->m_next;
  1073.                         delete pFoliage;
  1074.                 }
  1075.                 CryComment("done");
  1076.         }
  1077.         m_arrEntsInFoliage.Reset();
  1078. }
  1079.  
  1080. void C3DEngine::LoadTerrainSurfacesFromXML(XmlNodeRef pDoc, bool bUpdateTerrain, int nSID)
  1081. {
  1082.         if (!m_pTerrain)
  1083.                 return;
  1084.  
  1085. #ifdef SEG_WORLD
  1086.         if (nSID < 0)
  1087.         {
  1088.                 int cnt = m_pTerrain->GetMaxSegmentsCount();
  1089.                 for (nSID = 0; nSID < cnt; ++nSID)
  1090.                 {
  1091.                         if (!IsSegmentSafeToUse(nSID))
  1092.                                 continue;
  1093.  
  1094.                         LoadTerrainSurfacesFromXML(pDoc, bUpdateTerrain, nSID);
  1095.                 }
  1096.                 return;
  1097.         }
  1098. #endif
  1099.  
  1100.         m_pTerrain->LoadSurfaceTypesFromXML(pDoc, nSID);
  1101.  
  1102.         if (!IsSegmentOperationInProgress())
  1103.         {
  1104.                 m_pTerrain->UpdateSurfaceTypes(nSID);
  1105.  
  1106.                 m_pTerrain->InitHeightfieldPhysics(nSID);
  1107.         }
  1108. }
  1109.  
  1110. void C3DEngine::LoadMissionDataFromXMLNode(const char* szMissionName)
  1111. {
  1112.         LOADING_TIME_PROFILE_SECTION;
  1113.  
  1114.         if (!m_pTerrain)
  1115.         {
  1116.                 Warning("Calling %s while level is not loaded", __FUNCTION__);
  1117.                 return;
  1118.         }
  1119.  
  1120.         if (GetRenderer())
  1121.         {
  1122.                 GetRenderer()->MakeMainContextActive();
  1123.         }
  1124.  
  1125.         // set default values
  1126.         m_vFogColor(1, 1, 1);
  1127.         m_fMaxViewDistHighSpec = 8000;
  1128.         m_fMaxViewDistLowSpec = 1000;
  1129.         m_fTerrainDetailMaterialsViewDistRatio = 1;
  1130.         m_vDefFogColor = m_vFogColor;
  1131.  
  1132.         // mission environment
  1133.         if (szMissionName && szMissionName[0])
  1134.         {
  1135.                 char szFileName[256];
  1136.                 cry_sprintf(szFileName, "mission_%s.xml", szMissionName);
  1137.                 XmlNodeRef xmlMission = GetSystem()->LoadXmlFromFile(Get3DEngine()->GetLevelFilePath(szFileName));
  1138.                 if (xmlMission)
  1139.                 {
  1140.                         LoadEnvironmentSettingsFromXML(xmlMission->findChild("Environment"), GetDefSID());
  1141.                         LoadTimeOfDaySettingsFromXML(xmlMission->findChild("TimeOfDay"));
  1142.                 }
  1143.                 else
  1144.                         Error("%s: Mission file not found: %s", __FUNCTION__, szFileName);
  1145.         }
  1146.         else
  1147.                 Error("%s: Mission name is not defined", __FUNCTION__);
  1148. }
  1149.  
  1150. char* C3DEngine::GetXMLAttribText(XmlNodeRef pInputNode, const char* szLevel1, const char* szLevel2, const char* szDefaultValue)
  1151. {
  1152.         static char szResText[128];
  1153.  
  1154.         cry_strcpy(szResText, szDefaultValue);
  1155.  
  1156.         XmlNodeRef nodeLevel = pInputNode->findChild(szLevel1);
  1157.         if (nodeLevel && nodeLevel->haveAttr(szLevel2))
  1158.         {
  1159.                 cry_strcpy(szResText, nodeLevel->getAttr(szLevel2));
  1160.         }
  1161.  
  1162.         return szResText;
  1163. }
  1164.  
  1165. char* C3DEngine::GetXMLAttribText(XmlNodeRef pInputNode, const char* szLevel1, const char* szLevel2, const char* szLevel3, const char* szDefaultValue)
  1166. {
  1167.         static char szResText[128];
  1168.  
  1169.         cry_strcpy(szResText, szDefaultValue);
  1170.  
  1171.         XmlNodeRef nodeLevel = pInputNode->findChild(szLevel1);
  1172.         if (nodeLevel)
  1173.         {
  1174.                 nodeLevel = nodeLevel->findChild(szLevel2);
  1175.                 if (nodeLevel)
  1176.                 {
  1177.                         cry_strcpy(szResText, nodeLevel->getAttr(szLevel3));
  1178.                 }
  1179.         }
  1180.  
  1181.         return szResText;
  1182. }
  1183.  
  1184. void C3DEngine::UpdateMoonDirection()
  1185. {
  1186.         float moonLati(-gf_PI + gf_PI * m_moonRotationLatitude / 180.0f);
  1187.         float moonLong(0.5f * gf_PI - gf_PI * m_moonRotationLongitude / 180.0f);
  1188.  
  1189.         float sinLon(sinf(moonLong));
  1190.         float cosLon(cosf(moonLong));
  1191.         float sinLat(sinf(moonLati));
  1192.         float cosLat(cosf(moonLati));
  1193.  
  1194.         m_moonDirection = Vec3(sinLon * cosLat, sinLon * sinLat, cosLon);
  1195. }
  1196.  
  1197. void C3DEngine::LoadEnvironmentSettingsFromXML(XmlNodeRef pInputNode, int nSID)
  1198. {
  1199.         PrintComment("Loading environment settings from XML ...");
  1200.  
  1201.         // set start and end time for dawn/dusk (to fade moon/sun light in and out)
  1202.         float dawnTime = (float) atof(GetXMLAttribText(pInputNode, "Lighting", "DawnTime", "355"));
  1203.         float dawnDuration = (float) atof(GetXMLAttribText(pInputNode, "Lighting", "DawnDuration", "10"));
  1204.         float duskTime = (float) atof(GetXMLAttribText(pInputNode, "Lighting", "DuskTime", "365"));
  1205.         float duskDuration = (float) atof(GetXMLAttribText(pInputNode, "Lighting", "DuskDuration", "10"));
  1206.  
  1207.         m_dawnStart = (dawnTime - dawnDuration * 0.5f) / 60.0f;
  1208.         m_dawnEnd = (dawnTime + dawnDuration * 0.5f) / 60.0f;
  1209.         m_duskStart = 12.0f + (duskTime - duskDuration * 0.5f) / 60.0f;
  1210.         m_duskEnd = 12.0f + (duskTime + duskDuration * 0.5f) / 60.0f;
  1211.  
  1212.         if (m_dawnEnd > m_duskStart)
  1213.         {
  1214.                 m_duskEnd += m_dawnEnd - m_duskStart;
  1215.                 m_duskStart = m_dawnEnd;
  1216.         }
  1217.  
  1218.         // get moon info
  1219.         m_moonRotationLatitude = (float) atof(GetXMLAttribText(pInputNode, "Moon", "Latitude", "240"));
  1220.         m_moonRotationLongitude = (float) atof(GetXMLAttribText(pInputNode, "Moon", "Longitude", "45"));
  1221.         UpdateMoonDirection();
  1222.  
  1223.         m_nightMoonSize = (float) atof(GetXMLAttribText(pInputNode, "Moon", "Size", "0.5"));
  1224.  
  1225.         {
  1226.                 char moonTexture[256];
  1227.                 cry_strcpy(moonTexture, GetXMLAttribText(pInputNode, "Moon", "Texture", ""));
  1228.  
  1229.                 ITexture* pTex(0);
  1230.                 if (moonTexture[0] != '\0' && GetRenderer())
  1231.                 {
  1232.                         pTex = GetRenderer()->EF_LoadTexture(moonTexture, FT_DONT_STREAM);
  1233.                 }
  1234.                 m_nNightMoonTexId = pTex ? pTex->GetTextureID() : 0;
  1235.         }
  1236.  
  1237.         // max view distance
  1238.         m_fMaxViewDistHighSpec = (float)atol(GetXMLAttribText(pInputNode, "Fog", "ViewDistance", "8000"));
  1239.         m_fMaxViewDistLowSpec = (float)atol(GetXMLAttribText(pInputNode, "Fog", "ViewDistanceLowSpec", "1000"));
  1240.         m_fMaxViewDistScale = 1.f;
  1241.  
  1242.         m_volFogGlobalDensityMultiplierLDR = (float) max(atof(GetXMLAttribText(pInputNode, "Fog", "LDRGlobalDensMult", "1.0")), 0.0);
  1243.  
  1244.         float fTerrainDetailMaterialsViewDistRatio = (float)atof(GetXMLAttribText(pInputNode, "Terrain", "DetailLayersViewDistRatio", "1.0"));
  1245.         if (m_fTerrainDetailMaterialsViewDistRatio != fTerrainDetailMaterialsViewDistRatio && GetTerrain())
  1246.                 GetTerrain()->ResetTerrainVertBuffers(NULL, nSID);
  1247.         m_fTerrainDetailMaterialsViewDistRatio = fTerrainDetailMaterialsViewDistRatio;
  1248.  
  1249.         // SkyBox
  1250.         m_skyMatName = GetXMLAttribText(pInputNode, "SkyBox", "Material", "Materials/Sky/Sky");
  1251.         m_skyLowSpecMatName = GetXMLAttribText(pInputNode, "SkyBox", "MaterialLowSpec", "Materials/Sky/Sky");
  1252.  
  1253.         // Forces the engine to reload the material of the skybox in the next time it renders it.
  1254.         m_pSkyMat = NULL;
  1255.         m_pSkyLowSpecMat = NULL;
  1256.  
  1257.         m_fSkyBoxAngle = (float)atof(GetXMLAttribText(pInputNode, "SkyBox", "Angle", "0.0"));
  1258.         m_fSkyBoxStretching = (float)atof(GetXMLAttribText(pInputNode, "SkyBox", "Stretching", "1.0"));
  1259.  
  1260.         // set terrain water, sun road and bottom shaders
  1261.         char szTerrainWaterMatName[256];
  1262.         cry_strcpy(szTerrainWaterMatName, GetXMLAttribText(pInputNode, "Ocean", "Material", "EngineAssets/Materials/Water/Ocean_default"));
  1263.         m_pTerrainWaterMat = szTerrainWaterMatName[0] ? GetMatMan()->LoadMaterial(szTerrainWaterMatName, false) : NULL;
  1264.  
  1265.         if (m_pTerrain)
  1266.                 m_pTerrain->InitTerrainWater(m_pTerrainWaterMat, 0);
  1267.  
  1268.         m_oceanCausticsMultiplier = (float) atof(GetXMLAttribText(pInputNode, "Ocean", "CausticsMultiplier", "0.85"));
  1269.         m_oceanCausticsDistanceAtten = (float) atof(GetXMLAttribText(pInputNode, "Ocean", "CausticsDistanceAtten", "100.0"));
  1270.         m_oceanCausticsTilling = (float) atof(GetXMLAttribText(pInputNode, "Ocean", "CausticsTilling", "1.0"));
  1271.  
  1272.         m_oceanWindDirection = (float) atof(GetXMLAttribText(pInputNode, "OceanAnimation", "WindDirection", "1.0"));
  1273.         m_oceanWindSpeed = (float) atof(GetXMLAttribText(pInputNode, "OceanAnimation", "WindSpeed", "4.0"));
  1274.         m_oceanWavesSpeed = (float) atof(GetXMLAttribText(pInputNode, "OceanAnimation", "WavesSpeed", "1.0"));
  1275.         m_oceanWavesSpeed = clamp_tpl<float>(m_oceanWavesSpeed, 0.0f, 1.0f);
  1276.         m_oceanWavesAmount = (float) atof(GetXMLAttribText(pInputNode, "OceanAnimation", "WavesAmount", "1.5"));
  1277.         m_oceanWavesAmount = clamp_tpl<float>(m_oceanWavesAmount, 0.4f, 3.0f);
  1278.         m_oceanWavesSize = (float) atof(GetXMLAttribText(pInputNode, "OceanAnimation", "WavesSize", "0.75"));
  1279.         m_oceanWavesSize = clamp_tpl<float>(m_oceanWavesSize, 0.0f, 3.0f);
  1280.  
  1281.         // disabled temporarily - we'll use fixed height instead with tweaked attenuation function
  1282.         m_oceanCausticHeight = 0.0f;
  1283.         //m_oceanCausticHeight = (float) atof( GetXMLAttribText(pInputNode, "Ocean", "CausticHeight", "2.5"));
  1284.         m_oceanCausticDepth = (float) atof(GetXMLAttribText(pInputNode, "Ocean", "CausticDepth", "8.0"));
  1285.         m_oceanCausticIntensity = (float) atof(GetXMLAttribText(pInputNode, "Ocean", "CausticIntensity", "1.0"));
  1286.  
  1287.         // re-scale speed based on size - the smaller the faster waves move
  1288.         m_oceanWavesSpeed /= clamp_tpl<float>(m_oceanWavesSize, 0.45f, 1.0f);
  1289.  
  1290.         // get wind
  1291.         Vec3 vWindSpeed = StringToVector(GetXMLAttribText(pInputNode, "EnvState", "WindVector", "1,0,0"));
  1292.         SetWind(vWindSpeed);
  1293.  
  1294.         // Define breeze generation
  1295.         if (m_pBreezeGenerator)
  1296.         {
  1297.                 m_pBreezeGenerator->Shutdown();
  1298.  
  1299.                 const char* pText = GetXMLAttribText(pInputNode, "EnvState", "BreezeGeneration", "false");
  1300.                 m_pBreezeGenerator->m_enabled = !strcmp(pText, "true") || !strcmp(pText, "1");
  1301.                 m_pBreezeGenerator->m_strength = (float)atof(GetXMLAttribText(pInputNode, "EnvState", "BreezeStrength", "1.f"));
  1302.                 m_pBreezeGenerator->m_variance = (float)atof(GetXMLAttribText(pInputNode, "EnvState", "BreezeVariation", "1.f"));
  1303.                 m_pBreezeGenerator->m_lifetime = (float)atof(GetXMLAttribText(pInputNode, "EnvState", "BreezeLifeTime", "15.f"));
  1304.                 m_pBreezeGenerator->m_count = (uint32)max(0, atoi(GetXMLAttribText(pInputNode, "EnvState", "BreezeCount", "4")));
  1305.                 m_pBreezeGenerator->m_radius = (float)atof(GetXMLAttribText(pInputNode, "EnvState", "BreezeRadius", "5.f"));
  1306.                 m_pBreezeGenerator->m_spawn_radius = (float)atof(GetXMLAttribText(pInputNode, "EnvState", "BreezeSpawnRadius", "25.f"));
  1307.                 m_pBreezeGenerator->m_spread = (float)atof(GetXMLAttribText(pInputNode, "EnvState", "BreezeSpread", "0.f"));
  1308.                 m_pBreezeGenerator->m_movement_speed = (float)atof(GetXMLAttribText(pInputNode, "EnvState", "BreezeMovementSpeed", "8.f"));
  1309.                 m_pBreezeGenerator->m_awake_thresh = (float)atof(GetXMLAttribText(pInputNode, "EnvState", "BreezeAwakeThreshold", "0"));
  1310.                 m_pBreezeGenerator->m_wind_speed = vWindSpeed;
  1311.                 m_pBreezeGenerator->m_fixed_height = (float)atof(GetXMLAttribText(pInputNode, "EnvState", "BreezeFixedHeight", "-1.f"));
  1312.  
  1313.                 m_pBreezeGenerator->Initialize();
  1314.         }
  1315.  
  1316.         // Per-level mergedmeshes pool size (on consoles)
  1317.         Cry3DEngineBase::m_mergedMeshesPoolSize = atoi(GetXMLAttribText(pInputNode, "EnvState", "ConsoleMergedMeshesPool", MMRM_DEFAULT_POOLSIZE_STR));
  1318.  
  1319.         // update relevant time of day settings
  1320.         ITimeOfDay* pTimeOfDay(GetTimeOfDay());
  1321.         if (pTimeOfDay)
  1322.         {
  1323.                 CTimeOfDay::SEnvironmentInfo envTODInfo;
  1324.                 {
  1325.                         const char* pText = GetXMLAttribText(pInputNode, "EnvState", "SunLinkedToTOD", "true");
  1326.                         envTODInfo.bSunLinkedToTOD = !strcmp(pText, "true") || !strcmp(pText, "1");
  1327.                 }
  1328.                 // get rotation of sun around z axis (needed to define an arbitrary path over zenit for day/night cycle position calculations)
  1329.                 envTODInfo.sunRotationLatitude = (float) atof(GetXMLAttribText(pInputNode, "Lighting", "SunRotation", "240"));
  1330.                 envTODInfo.sunRotationLongitude = (float) atof(GetXMLAttribText(pInputNode, "Lighting", "Longitude", "90"));
  1331.  
  1332.                 pTimeOfDay->SetEnvironmentSettings(envTODInfo);
  1333.         }
  1334.  
  1335.         {
  1336.                 const char* pText = GetXMLAttribText(pInputNode, "EnvState", "ShowTerrainSurface", "true");
  1337.                 m_bShowTerrainSurface = !strcmp(pText, "true") || !strcmp(pText, "1");
  1338.         }
  1339.  
  1340.         {
  1341.                 const char* pText = GetXMLAttribText(pInputNode, "EnvState", "SunShadowsMinSpec", "1");
  1342.                 int nMinSpec = atoi(pText);
  1343.                 if (nMinSpec > 0 && CheckMinSpec(nMinSpec))
  1344.                         m_bSunShadows = true;
  1345.                 else
  1346.                         m_bSunShadows = false;
  1347.         }
  1348.  
  1349.         {
  1350.                 const char* pText = GetXMLAttribText(pInputNode, "EnvState", "SunShadowsAdditionalCascadeMinSpec", "0");
  1351.                 int nMinSpec = atoi(pText);
  1352.                 if (nMinSpec > 0 && CheckMinSpec(nMinSpec))
  1353.                         m_nSunAdditionalCascades = 1;
  1354.                 else
  1355.                         m_nSunAdditionalCascades = 0;
  1356.         }
  1357.  
  1358.         {
  1359.                 if (auto cvar = m_pConsole->GetCVar("r_ShadowsCache"))
  1360.                 {
  1361.                         m_nGsmCache = cvar->GetIVal();
  1362.                 }
  1363.         }
  1364.  
  1365.         {
  1366.                 const char* pText = GetXMLAttribText(pInputNode, "Terrain", "HeightMapAO", "false");
  1367.                 m_bHeightMapAoEnabled = !strcmp(pText, "true") || !strcmp(pText, "1");
  1368.         }
  1369.  
  1370.         {
  1371.                 int nMinSpec = 3;//atoi(pText);
  1372.                 m_fSunClipPlaneRange = 256.0;
  1373.                 m_fSunClipPlaneRangeShift = 0.0f;
  1374.  
  1375.                 if (nMinSpec > 0 && CheckMinSpec(nMinSpec))
  1376.                 {
  1377.                         m_fSunClipPlaneRange = (float)atof(GetXMLAttribText(pInputNode, "EnvState", "SunShadowsClipPlaneRange", "256.0"));
  1378.  
  1379.                         float fSunClipPlaneRangeShift = (float)atof(GetXMLAttribText(pInputNode, "EnvState", "SunShadowsClipPlaneRangeShift", "0.0"));
  1380.                         m_fSunClipPlaneRangeShift = clamp_tpl(fSunClipPlaneRangeShift / 100.0f, 0.0f, 1.0f);
  1381.                 }
  1382.         }
  1383.  
  1384.         {
  1385.                 const char* pText = GetXMLAttribText(pInputNode, "EnvState", "SunShadowsFromTerrain", "false");
  1386.                 m_bSunShadowsFromTerrain = (!strcmp(pText, "true") || !strcmp(pText, "1")) && GetCVars()->e_GsmCastFromTerrain;
  1387.         }
  1388.  
  1389.         {
  1390.                 const char* pText = GetXMLAttribText(pInputNode, "EnvState", "UseLayersActivation", "false");
  1391.                 Get3DEngine()->m_bAreaActivationInUse = !strcmp(pText, "true") || !strcmp(pText, "1");
  1392.         }
  1393.  
  1394.         // load cloud shadow parameters
  1395.         {
  1396.                 char cloudShadowTexture[256];
  1397.                 cry_strcpy(cloudShadowTexture, GetXMLAttribText(pInputNode, "CloudShadows", "CloudShadowTexture", ""));
  1398.  
  1399.                 ITexture* pTex = 0;
  1400.                 if (cloudShadowTexture[0] != '\0' && GetRenderer())
  1401.                         pTex = GetRenderer()->EF_LoadTexture(cloudShadowTexture);
  1402.  
  1403.                 m_nCloudShadowTexId = pTex ? pTex->GetTextureID() : 0;
  1404.  
  1405.                 // Get animation parameters
  1406.                 const Vec3 cloudShadowSpeed = StringToVector(GetXMLAttribText(pInputNode, "CloudShadows", "CloudShadowSpeed", "0,0,0"));
  1407.  
  1408.                 const float cloudShadowTiling = (float)atof(GetXMLAttribText(pInputNode, "CloudShadows", "CloudShadowTiling", "1.0"));
  1409.                 const float cloudShadowBrightness = (float)atof(GetXMLAttribText(pInputNode, "CloudShadows", "CloudShadowBrightness", "1.0"));
  1410.  
  1411.                 const char* pText = GetXMLAttribText(pInputNode, "CloudShadows", "CloudShadowInvert", "false");
  1412.                 const bool cloudShadowInvert = !strcmp(pText, "true") || !strcmp(pText, "1");
  1413.  
  1414.                 if (GetRenderer())
  1415.                 {
  1416.                         GetRenderer()->SetCloudShadowsParams(m_nCloudShadowTexId, cloudShadowSpeed, cloudShadowTiling, cloudShadowInvert, cloudShadowBrightness);
  1417.                 }
  1418.         }
  1419.  
  1420.         // load volumetric cloud parameters
  1421.         {
  1422. #if 0 //disable spherical cloud layer until it works correctly.
  1423.                 const char* pText = GetXMLAttribText(pInputNode, "VolumetricCloud", "SphericalCloud", "false");
  1424.                 const bool sphericalCloud = !strcmp(pText, "true") || !strcmp(pText, "1");
  1425.                 const float volCloudEarthRadius = max(0.0f, (float)atof(GetXMLAttribText(pInputNode, "VolumetricCloud", "EarthRadius", "6360000.0")));
  1426. #else
  1427.                 const bool sphericalCloud = false;
  1428.                 const float volCloudEarthRadius = 6360000.0f;
  1429. #endif
  1430.                 const float horizonHeight = (float)atof(GetXMLAttribText(pInputNode, "VolumetricCloud", "HorizonHeight", "-1000.0"));
  1431.                 SetGlobalParameter(E3DPARAM_VOLCLOUD_ENV_PARAMS, Vec3(volCloudEarthRadius, sphericalCloud ? 1.0f : 0.0f, horizonHeight));
  1432.  
  1433.                 const Vec3 cloudNoiseScale = StringToVector(GetXMLAttribText(pInputNode, "VolumetricCloud", "GlobalCloudNoiseScale", "3,3,5"));
  1434.                 SetGlobalParameter(E3DPARAM_VOLCLOUD_GLOBAL_NOISE_SCALE, cloudNoiseScale);
  1435.  
  1436.                 const float maxViewableDistance = min(1000000.0f, max(0.0f, (float)atof(GetXMLAttribText(pInputNode, "VolumetricCloud", "MaxViewableDistance", "100000.0"))));
  1437.                 const float maxRayMarchDistance = min(200000.0f, max(0.0f, (float)atof(GetXMLAttribText(pInputNode, "VolumetricCloud", "MaxRayMarchDistance", "20000.0"))));
  1438.                 const float maxRayMarchStep = (float)min(512, max(16, atoi(GetXMLAttribText(pInputNode, "VolumetricCloud", "MaxRayMarchStep", "64"))));
  1439.                 SetGlobalParameter(E3DPARAM_VOLCLOUD_RENDER_PARAMS, Vec3(maxViewableDistance, maxRayMarchDistance, maxRayMarchStep));
  1440.  
  1441.                 const Vec3 cloudTilingSize = StringToVector(GetXMLAttribText(pInputNode, "VolumetricCloud", "TilingSize", "64000,64000,4000"));
  1442.                 SetGlobalParameter(E3DPARAM_VOLCLOUD_TILING_SIZE, cloudTilingSize);
  1443.  
  1444.                 const Vec3 cloudTilingOffset = StringToVector(GetXMLAttribText(pInputNode, "VolumetricCloud", "TilingOffset", "0,0,0"));
  1445.                 SetGlobalParameter(E3DPARAM_VOLCLOUD_TILING_OFFSET, -cloudTilingOffset);
  1446.  
  1447.                 const Vec3 edgeTurbulenceNoiseScale = StringToVector(GetXMLAttribText(pInputNode, "VolumetricCloud", "EdgeTurbulenceNoiseScale", "1,1,1"));
  1448.                 SetGlobalParameter(E3DPARAM_VOLCLOUD_TURBULENCE_NOISE_SCALE, edgeTurbulenceNoiseScale);
  1449.  
  1450.                 const char* pTextEdgeErode = GetXMLAttribText(pInputNode, "VolumetricCloud", "EdgeTurbulenceNoiseErode", "true");
  1451.                 const float edgeTurbulenceNoiseErode = (!strcmp(pTextEdgeErode, "true") || !strcmp(pTextEdgeErode, "1")) ? 1.0f : 0.0f;
  1452.                 const char* pTextEdgeAbs = GetXMLAttribText(pInputNode, "VolumetricCloud", "EdgeTurbulenceNoiseAbsolute", "true");
  1453.                 const float edgeTurbulenceNoiseAbsolute = (!strcmp(pTextEdgeAbs, "true") || !strcmp(pTextEdgeAbs, "1")) ? 1.0f : 0.0f;
  1454.                 SetGlobalParameter(E3DPARAM_VOLCLOUD_TURBULENCE_NOISE_PARAMS, Vec3(edgeTurbulenceNoiseErode, edgeTurbulenceNoiseAbsolute, 0.0f));
  1455.  
  1456.                 const float maxGlobalCloudDensity = min(1.0f, max(0.0f, (float)atof(GetXMLAttribText(pInputNode, "VolumetricCloud", "MaxGlobalCloudDensity", "0.04"))));
  1457.                 const float minRescaleCloudTexDensity = (float)atof(GetXMLAttribText(pInputNode, "VolumetricCloud", "RemapCloudDensityMin", "0.0"));
  1458.                 const float maxRescaleCloudTexDensity = (float)atof(GetXMLAttribText(pInputNode, "VolumetricCloud", "RemapCloudDensityMax", "1.0"));
  1459.                 SetGlobalParameter(E3DPARAM_VOLCLOUD_DENSITY_PARAMS, Vec3(maxGlobalCloudDensity, minRescaleCloudTexDensity, maxRescaleCloudTexDensity));
  1460.  
  1461.                 const float additionalNoiseIntensity = (float)atof(GetXMLAttribText(pInputNode, "VolumetricCloud", "AdditionalNoiseIntensity", "0.2"));
  1462.                 const float shadingLOD = min(1.0f, max(0.0f, (float)atof(GetXMLAttribText(pInputNode, "VolumetricCloud", "ShadingLOD", "0.7"))));
  1463.                 const float cloudShadowTilingSize = max(1.0f, (float)atof(GetXMLAttribText(pInputNode, "VolumetricCloud", "ShadowTilingSize", "16000")));
  1464.                 SetGlobalParameter(E3DPARAM_VOLCLOUD_MISC_PARAM, Vec3(additionalNoiseIntensity, shadingLOD, cloudShadowTilingSize));
  1465.  
  1466.                 if (GetRenderer())
  1467.                 {
  1468.                         char cloudVolumeTexture[256];
  1469.                         cry_strcpy(cloudVolumeTexture, GetXMLAttribText(pInputNode, "VolumetricCloud", "CloudVolumeTexture", ""));
  1470.                         ITexture* pTex = 0;
  1471.                         if (cloudVolumeTexture[0] != '\0')
  1472.                                 pTex = GetRenderer()->EF_LoadTexture(cloudVolumeTexture);
  1473.                         int volCloudTexId = pTex ? pTex->GetTextureID() : 0;
  1474.                         GetRenderer()->SetVolumetricCloudParams(volCloudTexId);
  1475.                 }
  1476.         }
  1477.  
  1478.         {
  1479.                 const char* pText = GetXMLAttribText(pInputNode, "VolFogShadows", "Enable", "false");
  1480.                 const bool enable = !strcmp(pText, "true") || !strcmp(pText, "1");
  1481.  
  1482.                 pText = GetXMLAttribText(pInputNode, "VolFogShadows", "EnableForClouds", "false");
  1483.                 const bool enableForClouds = !strcmp(pText, "true") || !strcmp(pText, "1");
  1484.  
  1485.                 SetGlobalParameter(E3DPARAM_VOLFOG_SHADOW_ENABLE, Vec3(enable ? 1.0f : 0.0f, enableForClouds ? 1.0f : 0.0f, 0.0f));
  1486.         }
  1487.  
  1488.         if (GetRenderer())
  1489.         {
  1490.                 int dim[2];
  1491.  
  1492.                 const char* pWidth = GetXMLAttribText(pInputNode, "DynTexSource", "Width", "256");
  1493.                 dim[0] = atoi(pWidth);
  1494.  
  1495.                 const char* pHeight = GetXMLAttribText(pInputNode, "DynTexSource", "Height", "256");
  1496.                 dim[1] = atoi(pHeight);
  1497.  
  1498.                 GetRenderer()->EF_Query(EFQ_SetDynTexSourceSharedRTDim, dim[0], dim[1]);
  1499.         }
  1500.  
  1501. #if defined(FEATURE_SVO_GI)
  1502.         LoadTISettings(pInputNode);
  1503. #endif
  1504.  
  1505.         if (pTimeOfDay)
  1506.                 pTimeOfDay->Update();
  1507.  
  1508.         if (GetSystem()->GetISystemEventDispatcher())
  1509.                 GetSystem()->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_ENVIRONMENT_SETTINGS_CHANGED, 0, 0);
  1510. }
  1511.  
  1512. //////////////////////////////////////////////////////////////////////////
  1513. void C3DEngine::LoadTimeOfDaySettingsFromXML(XmlNodeRef node)
  1514. {
  1515.         if (node)
  1516.         {
  1517.                 GetTimeOfDay()->Serialize(node, true);
  1518.                 ITimeOfDay::SAdvancedInfo info;
  1519.                 GetTimeOfDay()->GetAdvancedInfo(info);
  1520.                 GetTimeOfDay()->SetTime(info.fStartTime, true);
  1521.         }
  1522. }
  1523.  
  1524. //////////////////////////////////////////////////////////////////////////
  1525. void C3DEngine::LoadParticleEffects(const char* szFolderName)
  1526. {
  1527.         LOADING_TIME_PROFILE_SECTION;
  1528.  
  1529.         if (m_pPartManager)
  1530.         {
  1531.                 PrintMessage("===== Loading Particle Effects =====");
  1532.  
  1533.                 m_pPartManager->LoadLibrary("Level", GetLevelFilePath(PARTICLES_FILE), true);
  1534.  
  1535.                 if (GetCVars()->e_ParticlesPreload)
  1536.                 {
  1537.                         // Force loading all effects and assets, to ensure no runtime stalls.
  1538.                         CTimeValue t0 = GetTimer()->GetAsyncTime();
  1539.                         PrintMessage("Preloading Particle Effects...");
  1540.                         m_pPartManager->LoadLibrary("*", NULL, true);
  1541.                         CTimeValue t1 = GetTimer()->GetAsyncTime();
  1542.                         float dt = (t1 - t0).GetSeconds();
  1543.                         PrintMessage("Particle Effects Loaded in %.2f seconds", dt);
  1544.                 }
  1545.                 else
  1546.                 {
  1547.                         // Load just specified libraries.
  1548.                         m_pPartManager->LoadLibrary("@PreloadLibs", szFolderName, true);
  1549.                 }
  1550.         }
  1551. }
  1552.  
  1553. //! create static object containing empty IndexedMesh
  1554. IStatObj* C3DEngine::CreateStatObj()
  1555. {
  1556.         CStatObj* pStatObj = new CStatObj();
  1557.         pStatObj->m_pIndexedMesh = new CIndexedMesh();
  1558.         return pStatObj;
  1559. }
  1560.  
  1561. IStatObj* C3DEngine::CreateStatObjOptionalIndexedMesh(bool createIndexedMesh)
  1562. {
  1563.         CStatObj* pStatObj = new CStatObj();
  1564.         if (createIndexedMesh)
  1565.                 pStatObj->m_pIndexedMesh = new CIndexedMesh();
  1566.         return pStatObj;
  1567. }
  1568.  
  1569. bool C3DEngine::RestoreTerrainFromDisk(int nSID)
  1570. {
  1571.         if (m_pTerrain && m_pObjManager && !m_bEditor && GetCVars()->e_TerrainDeformations)
  1572.         {
  1573.                 m_pTerrain->ResetTerrainVertBuffers(NULL, nSID);
  1574.  
  1575.                 if (FILE* f = GetPak()->FOpen(GetLevelFilePath(COMPILED_HEIGHT_MAP_FILE_NAME), "rbx"))
  1576.                 {
  1577.                         GetTerrain()->ReloadModifiedHMData(f, nSID);
  1578.                         GetPak()->FClose(f);
  1579.                 }
  1580.         }
  1581.  
  1582.         ResetParticlesAndDecals();
  1583.  
  1584.         // update roads
  1585.         for (int id = 0; id < Get3DEngine()->m_pObjectsTree.Count(); id++)
  1586.         {
  1587.                 if (m_pObjectsTree[id] && GetCVars()->e_TerrainDeformations)
  1588.                 {
  1589.                         PodArray<IRenderNode*> lstRoads;
  1590.                         m_pObjectsTree[id]->GetObjectsByType(lstRoads, eERType_Road, NULL);
  1591.                         for (int i = 0; i < lstRoads.Count(); i++)
  1592.                         {
  1593.                                 CRoadRenderNode* pRoad = (CRoadRenderNode*)lstRoads[i];
  1594.                                 pRoad->OnTerrainChanged();
  1595.                         }
  1596.                 }
  1597.         }
  1598.  
  1599.         ReRegisterKilledVegetationInstances();
  1600.  
  1601.         return true;
  1602. }
  1603.  
  1604. void C3DEngine::ReRegisterKilledVegetationInstances()
  1605. {
  1606.         for (int i = 0; i < m_lstKilledVegetations.Count(); i++)
  1607.         {
  1608.                 IRenderNode* pObj = m_lstKilledVegetations[i];
  1609.                 pObj->Physicalize();
  1610.                 Get3DEngine()->RegisterEntity(pObj);
  1611.         }
  1612.  
  1613.         m_lstKilledVegetations.Clear();
  1614. }
  1615.  
  1616. //////////////////////////////////////////////////////////////////////////
  1617. bool C3DEngine::LoadUsedShadersList()
  1618. {
  1619.         LOADING_TIME_PROFILE_SECTION;
  1620.  
  1621.         MEMSTAT_CONTEXT(EMemStatContextTypes::MSC_Other, 0, "LoadUsedShadersList");
  1622.  
  1623.         GetRenderer()->EF_Query(EFQ_SetShaderCombinations);
  1624.  
  1625.         return true;
  1626. }
  1627.  
  1628. //////////////////////////////////////////////////////////////////////////
  1629. bool C3DEngine::PrecreateDecals()
  1630. {
  1631.         LOADING_TIME_PROFILE_SECTION;
  1632.         MEMSTAT_CONTEXT(EMemStatContextTypes::MSC_Other, 0, "PrecreateDecals");
  1633.  
  1634.         CObjManager::DecalsToPrecreate& decals(GetObjManager()->m_decalsToPrecreate);
  1635.         // pre-create ...
  1636.         if (GetCVars()->e_DecalsPreCreate)
  1637.         {
  1638.                 CryLog("Pre-creating %d decals...", (int)decals.size());
  1639.  
  1640.                 CObjManager::DecalsToPrecreate::iterator it(decals.begin());
  1641.                 CObjManager::DecalsToPrecreate::iterator itEnd(decals.end());
  1642.                 for (; it != itEnd; ++it)
  1643.                 {
  1644.                         IDecalRenderNode* pDecalRenderNode(*it);
  1645.                         pDecalRenderNode->Precache();
  1646.                 }
  1647.  
  1648.                 CryLog(" done.\n");
  1649.         }
  1650.         else
  1651.                 CryLog("Skipped pre-creation of decals.\n");
  1652.  
  1653.         // ... and discard list (even if pre-creation was skipped!)
  1654.         decals.resize(0);
  1655.  
  1656.         return true;
  1657. }
  1658.  
  1659. //////////////////////////////////////////////////////////////////////////
  1660. // Called by game when everything needed for level is loaded.
  1661. //////////////////////////////////////////////////////////////////////////
  1662. void C3DEngine::PostLoadLevel()
  1663. {
  1664.         MEMSTAT_CONTEXT(EMemStatContextTypes::MSC_Other, 0, "PostLoadLevel");
  1665.         LOADING_TIME_PROFILE_SECTION;
  1666.  
  1667.         //////////////////////////////////////////////////////////////////////////
  1668.         // Submit water material to physics
  1669.         //////////////////////////////////////////////////////////////////////////
  1670.         {
  1671.                 IMaterialManager* pMatMan = GetMaterialManager();
  1672.                 IPhysicalWorld* pPhysicalWorld = gEnv->pPhysicalWorld;
  1673.                 IPhysicalEntity* pGlobalArea = pPhysicalWorld->AddGlobalArea();
  1674.  
  1675.                 pe_params_buoyancy pb;
  1676.                 pb.waterPlane.n.Set(0, 0, 1);
  1677.                 pb.waterPlane.origin.Set(0, 0, GetWaterLevel());
  1678.                 pGlobalArea->SetParams(&pb);
  1679.  
  1680.                 ISurfaceType* pSrfType = pMatMan->GetSurfaceTypeByName("mat_water");
  1681.                 if (pSrfType)
  1682.                         pPhysicalWorld->SetWaterMat(pSrfType->GetId());
  1683.  
  1684.                 pe_params_waterman pwm;
  1685.                 pwm.nExtraTiles = 3;
  1686.                 pwm.nCells = 40;
  1687.                 pwm.tileSize = 4;
  1688.                 pwm.waveSpeed = 11.0f;
  1689.                 pwm.dampingCenter = 0.6f;
  1690.                 pwm.dampingRim = 2.3f;
  1691.                 //pPhysicalWorld->SetWaterManagerParams(&pwm);
  1692.         }
  1693.  
  1694.         if (GetCVars()->e_PrecacheLevel)
  1695.         {
  1696.                 // pre-create decals
  1697.                 PrecreateDecals();
  1698.         }
  1699.  
  1700.         CompleteObjectsGeometry();
  1701.  
  1702.         gEnv->pSystem->SetSystemGlobalState(ESYSTEM_GLOBAL_STATE_LEVEL_LOAD_START_TEXTURES);
  1703.  
  1704.         if (GetRenderer())
  1705.         {
  1706.                 GetRenderer()->PostLevelLoading();
  1707.         }
  1708.  
  1709.         // refresh material constants pulled in from resources (such as textures)
  1710.         GetMatMan()->RefreshShaderResourceConstants();
  1711.  
  1712.         if (m_nGsmCache > 0)
  1713.         {
  1714.                 m_CachedShadowsBounds.Reset();
  1715.                 SetRecomputeCachedShadows(m_nCachedShadowsUpdateStrategy = ShadowMapFrustum::ShadowCacheData::eFullUpdate);
  1716.         }
  1717. }
  1718.  
  1719. int C3DEngine::SaveStatObj(IStatObj* pStatObj, TSerialize ser)
  1720. {
  1721.         if (!(pStatObj->GetFlags() & STATIC_OBJECT_GENERATED))
  1722.         {
  1723.                 bool bVal = false;
  1724.                 ser.Value("altered", bVal);
  1725.                 ser.Value("file", pStatObj->GetFilePath());
  1726.                 ser.Value("geom", pStatObj->GetGeoName());
  1727.         }
  1728.         else
  1729.         {
  1730.                 bool bVal = true;
  1731.                 ser.Value("altered", bVal);
  1732.                 ser.Value("CloneSource", pStatObj->GetCloneSourceObject() ? pStatObj->GetCloneSourceObject()->GetFilePath() : "0");
  1733.                 pStatObj->Serialize(ser);
  1734.         }
  1735.  
  1736.         return 1;
  1737. }
  1738.  
  1739. IStatObj* C3DEngine::LoadStatObj(TSerialize ser)
  1740. {
  1741.         bool bVal;
  1742.         IStatObj* pStatObj;
  1743.         ser.Value("altered", bVal);
  1744.         if (!bVal)
  1745.         {
  1746.                 string fileName, geomName;
  1747.                 ser.Value("file", fileName);
  1748.                 ser.Value("geom", geomName);
  1749.                 pStatObj = LoadStatObj(fileName, geomName);
  1750.         }
  1751.         else
  1752.         {
  1753.                 string srcObjName;
  1754.                 ser.Value("CloneSource", srcObjName);
  1755.                 if (*(const unsigned short*)(const char*)srcObjName != '0')
  1756.                         pStatObj = LoadStatObj(srcObjName)->Clone(false, false, true);
  1757.                 else
  1758.                         pStatObj = CreateStatObj();
  1759.                 pStatObj->Serialize(ser);
  1760.         }
  1761.         return pStatObj;
  1762. }
  1763.  
download3dEngineLoad.cpp Source code - Download CRYENGINE Source code
Related Source Codes/Software:
postal - 2017-06-11
reactide - Reactide is the first dedicated IDE for React web ... 2017-06-11
rkt - rkt is a pod-native container engine for Linux. It... 2017-06-11
uWebSockets - Tiny WebSockets https://for... 2017-06-11
realworld - TodoMVC for the RealWorld - Exemplary fullstack Me... 2017-06-11
CRYENGINE - CRYENGINE is a powerful real-time game development... 2017-06-11
goreplay - GoReplay is an open-source tool for capturing and ... 2017-06-10
pyenv - Simple Python version management 2017-06-10
redux-saga - An alternative side effect model for Redux apps ... 2017-06-10
angular-starter - 2017-06-10

 Back to top