BVB Source Codes

CRYENGINE Show 3dEngine.cpp Source code

Return Download CRYENGINE: download 3dEngine.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:   3dengine.cpp
  5. //  Version:     v1.00
  6. //  Created:     28/5/2001 by Vladimir Kajalin
  7. //  Compilers:   Visual Studio.NET
  8. //  Description: Implementation of I3DEngine interface methods
  9. // -------------------------------------------------------------------------
  10. //  History:
  11. //
  12. ////////////////////////////////////////////////////////////////////////////
  13.  
  14. #include "StdAfx.h"
  15. #include <CryAnimation/ICryAnimation.h>
  16. #include <CryGame/IGameFramework.h>
  17. #include <CryAudio/IAudioSystem.h>
  18. #include <CryParticleSystem/IParticlesPfx2.h>
  19.  
  20. #include "3dEngine.h"
  21. #include "terrain.h"
  22. #include "VisAreas.h"
  23. #include "ObjMan.h"
  24. #include "terrain_water.h"
  25.  
  26. #include "DecalManager.h"
  27. #include "Vegetation.h"
  28. #include "IndexedMesh.h"
  29.  
  30. #include "MatMan.h"
  31.  
  32. #include "Brush.h"
  33. #include "PolygonClipContext.h"
  34. #include "CGF/CGFLoader.h"
  35. #include "CGF/ChunkFileWriters.h"
  36. #include "CGF/ReadOnlyChunkFile.h"
  37.  
  38. #include "CloudRenderNode.h"
  39. #include "CloudsManager.h"
  40. #include "SkyLightManager.h"
  41. #include "FogVolumeRenderNode.h"
  42. #include "RoadRenderNode.h"
  43. #include "DecalRenderNode.h"
  44. #include "TimeOfDay.h"
  45. #include "LightEntity.h"
  46. #include "FogVolumeRenderNode.h"
  47. #include "ObjectsTree.h"
  48. #include "WaterVolumeRenderNode.h"
  49. #include "WaterWaveRenderNode.h"
  50. #include "DistanceCloudRenderNode.h"
  51. #include "VolumeObjectRenderNode.h"
  52. #include "WaterWaveRenderNode.h"
  53. #include "RopeRenderNode.h"
  54. #include "RenderMeshMerger.h"
  55. #include "PhysCallbacks.h"
  56. #include "DeferredCollisionEvent.h"
  57. #include "MergedMeshRenderNode.h"
  58. #include "BreakableGlassRenderNode.h"
  59. #include "BreezeGenerator.h"
  60. #include "OpticsManager.h"
  61. #include "GeomCacheRenderNode.h"
  62. #include "GeomCacheManager.h"
  63. #include "ClipVolumeManager.h"
  64. #include "RenderNodes/CharacterRenderNode.h"
  65. #include <CryNetwork/IRemoteCommand.h>
  66. #include "CloudBlockerRenderNode.h"
  67. #include "WaterRippleManager.h"
  68.  
  69. #if defined(FEATURE_SVO_GI)
  70.         #include "SVO/SceneTreeManager.h"
  71. #endif
  72.  
  73. #include <CryThreading/IJobManager_JobDelegator.h>
  74.  
  75. threadID Cry3DEngineBase::m_nMainThreadId = 0;
  76. bool Cry3DEngineBase::m_bRenderTypeEnabled[eERType_TypesNum];
  77. ISystem* Cry3DEngineBase::m_pSystem = 0;
  78. #if !defined(DEDICATED_SERVER)
  79. IRenderer* Cry3DEngineBase::m_pRenderer = 0;
  80. #else
  81. IRenderer* const Cry3DEngineBase::m_pRenderer = 0;
  82. #endif
  83. ITimer* Cry3DEngineBase::m_pTimer = 0;
  84. ILog* Cry3DEngineBase::m_pLog = 0;
  85. IPhysicalWorld* Cry3DEngineBase::m_pPhysicalWorld = 0;
  86. CTerrain* Cry3DEngineBase::m_pTerrain = 0;
  87. CObjManager* Cry3DEngineBase::m_pObjManager = 0;
  88. IConsole* Cry3DEngineBase::m_pConsole = 0;
  89. C3DEngine* Cry3DEngineBase::m_p3DEngine = 0;
  90. CVars* Cry3DEngineBase::m_pCVars = 0;
  91. ICryPak* Cry3DEngineBase::m_pCryPak = 0;
  92. IParticleManager* Cry3DEngineBase::m_pPartManager = 0;
  93. std::shared_ptr<pfx2::IParticleSystem> Cry3DEngineBase::m_pParticleSystem;
  94. IOpticsManager* Cry3DEngineBase::m_pOpticsManager = 0;
  95. CDecalManager* Cry3DEngineBase::m_pDecalManager = 0;
  96. CSkyLightManager* Cry3DEngineBase::m_pSkyLightManager = 0;
  97. CCloudsManager* Cry3DEngineBase::m_pCloudsManager = 0;
  98. CVisAreaManager* Cry3DEngineBase::m_pVisAreaManager = 0;
  99. CClipVolumeManager* Cry3DEngineBase::m_pClipVolumeManager = 0;
  100. CWaterWaveManager* Cry3DEngineBase::m_pWaterWaveManager = 0;
  101. CRenderMeshMerger* Cry3DEngineBase::m_pRenderMeshMerger = 0;
  102. CMatMan* Cry3DEngineBase::m_pMatMan = 0;
  103. CMergedMeshesManager* Cry3DEngineBase::m_pMergedMeshesManager = 0;
  104. CBreezeGenerator* Cry3DEngineBase::m_pBreezeGenerator = 0;
  105. IStreamedObjectListener* Cry3DEngineBase::m_pStreamListener = 0;
  106. #if defined(USE_GEOM_CACHES)
  107. CGeomCacheManager* Cry3DEngineBase::m_pGeomCacheManager = 0;
  108. #endif
  109.  
  110. bool Cry3DEngineBase::m_bProfilerEnabled = false;
  111. bool Cry3DEngineBase::m_bLevelLoadingInProgress = false;
  112. bool Cry3DEngineBase::m_bIsInRenderScene = false;
  113. int Cry3DEngineBase::m_mergedMeshesPoolSize = 0;
  114.  
  115. #if CRY_PLATFORM_DESKTOP
  116. bool Cry3DEngineBase::m_bEditor = false;
  117. #endif
  118. ESystemConfigSpec Cry3DEngineBase::m_LightConfigSpec = CONFIG_VERYHIGH_SPEC;
  119. int Cry3DEngineBase::m_arrInstancesCounter[eERType_TypesNum];
  120. IGetLayerIdAtCallback* C3DEngine::m_pGetLayerIdAtCallback = 0;
  121.  
  122. #define LAST_POTENTIALLY_VISIBLE_TIME 2
  123.  
  124. // The only direct particle function needed by 3DEngine, implemented in the same DLL.
  125. extern IParticleManager* CreateParticleManager(bool bEnable);
  126. extern void              DestroyParticleManager(IParticleManager* pParticleManager);
  127.  
  128. namespace
  129. {
  130. class CLoadLogListener : public ILoaderCGFListener
  131. {
  132. public:
  133.         virtual ~CLoadLogListener(){}
  134.         virtual void Warning(const char* format) { Cry3DEngineBase::Warning("%s", format); }
  135.         virtual void Error(const char* format)   { Cry3DEngineBase::Error("%s", format); }
  136.         virtual bool IsValidationEnabled()       { return Cry3DEngineBase::GetCVars()->e_StatObjValidate != 0; }
  137. };
  138. }
  139.  
  140. ///////////////////////////////////////////////////////////////////////////////
  141. CryCriticalSectionNonRecursive g_renderNodeTempDataLock;
  142.  
  143. //////////////////////////////////////////////////////////////////////
  144. C3DEngine::C3DEngine(ISystem* pSystem)
  145. {
  146.         //#if defined(_DEBUG) && CRY_PLATFORM_WINDOWS
  147.         //      _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
  148.         //#endif
  149.  
  150.         // Level info
  151.         m_fSunSpecMult = 1.f;
  152.         m_bAreaActivationInUse = false;
  153.  
  154.         CVegetation::InitVegDecomprTable();
  155.  
  156.         Cry3DEngineBase::m_nMainThreadId = CryGetCurrentThreadId();
  157.         Cry3DEngineBase::m_pSystem = pSystem;
  158. #if !defined(DEDICATED_SERVER)
  159.         Cry3DEngineBase::m_pRenderer = gEnv->pRenderer;
  160. #endif
  161.         Cry3DEngineBase::m_pTimer = gEnv->pTimer;
  162.         Cry3DEngineBase::m_pLog = gEnv->pLog;
  163.         Cry3DEngineBase::m_pPhysicalWorld = gEnv->pPhysicalWorld;
  164.         Cry3DEngineBase::m_pConsole = gEnv->pConsole;
  165.         Cry3DEngineBase::m_p3DEngine = this;
  166.         Cry3DEngineBase::m_pCryPak = gEnv->pCryPak;
  167.         Cry3DEngineBase::m_pCVars = 0;
  168.         Cry3DEngineBase::m_pRenderMeshMerger = new CRenderMeshMerger;
  169.         Cry3DEngineBase::m_pMergedMeshesManager = new CMergedMeshesManager;
  170.         Cry3DEngineBase::m_pMatMan = new CMatMan;
  171.         Cry3DEngineBase::m_pBreezeGenerator = new CBreezeGenerator;
  172.         Cry3DEngineBase::m_pStreamListener = NULL;
  173.  
  174.         memset(Cry3DEngineBase::m_arrInstancesCounter, 0, sizeof(Cry3DEngineBase::m_arrInstancesCounter));
  175.  
  176. #if CRY_PLATFORM_DESKTOP
  177.         m_bEditor = gEnv->IsEditor();
  178. #endif
  179.  
  180.         m_pCVars = new CVars();
  181.  
  182.         m_pTimeOfDay = NULL;
  183.  
  184.         m_szLevelFolder[0] = 0;
  185.  
  186.         m_pSun = 0;
  187.         m_nFlags = 0;
  188.         m_pSkyMat = 0;
  189.         m_pSkyLowSpecMat = 0;
  190.         m_pTerrainWaterMat = 0;
  191.         m_nWaterBottomTexId = 0;
  192.         m_vSunDir = Vec3(5.f, 5.f, DISTANCE_TO_THE_SUN);
  193.         m_vSunDirRealtime = Vec3(5.f, 5.f, DISTANCE_TO_THE_SUN).GetNormalized();
  194.  
  195.         m_pTerrain = 0;
  196.  
  197.         m_nBlackTexID = 0;
  198.  
  199.         m_nCurWind = 0;
  200.         m_bWindJobRun = false;
  201.         m_pWindField = NULL;
  202.  
  203.         // create components
  204.         m_pObjManager = CryAlignedNew<CObjManager>();
  205.  
  206.         m_pDecalManager = 0;    //new CDecalManager   (m_pSystem, this);
  207.         m_pCloudsManager = new CCloudsManager;
  208.         m_pPartManager = 0;
  209.         m_pOpticsManager = 0;
  210.         m_pVisAreaManager = 0;
  211.         m_pClipVolumeManager = new CClipVolumeManager();
  212.         m_pSkyLightManager = CryAlignedNew<CSkyLightManager>();
  213.         m_pWaterWaveManager = 0;
  214.         m_pWaterRippleManager.reset(new CWaterRippleManager());
  215.  
  216.         // create REs
  217.         m_pRESky = 0;
  218.         m_pREHDRSky = 0;
  219.  
  220.         m_pFarTreeSprites = 0;
  221.  
  222.         m_pPhysMaterialEnumerator = 0;
  223.  
  224.         m_fMaxViewDistHighSpec = 8000;
  225.         m_fMaxViewDistLowSpec = 1000;
  226.         m_fTerrainDetailMaterialsViewDistRatio = 1.f;
  227.  
  228.         m_fSkyBoxAngle = 0;
  229.         m_fSkyBoxStretching = 0;
  230.  
  231.         m_pGlobalWind = 0;
  232.         m_vWindSpeed(1, 0, 0);
  233.  
  234.         m_bOcean = true;
  235.         m_nOceanRenderFlags = 0;
  236.  
  237.         m_bSunShadows = m_bShowTerrainSurface = true;
  238.         m_bSunShadowsFromTerrain = false;
  239.         m_nSunAdditionalCascades = 0;
  240.         m_CachedShadowsBounds.Reset();
  241.         m_nCachedShadowsUpdateStrategy = ShadowMapFrustum::ShadowCacheData::eFullUpdate;
  242.  
  243.         m_fSunClipPlaneRange = 256.0f;
  244.         m_fSunClipPlaneRangeShift = 0.0f;
  245.  
  246.         m_nRealLightsNum = m_nDeferredLightsNum = 0;
  247.  
  248.         union
  249.         {
  250.                 CStatObjFoliage* CStatObjFoliage::* next;
  251.                 INT_PTR                             inext;
  252.         } tmp;
  253.         tmp.inext = 0;
  254.         tmp.next = &CStatObjFoliage::m_next;
  255.         m_pFirstFoliage = m_pLastFoliage = (CStatObjFoliage*)((INT_PTR)&m_pFirstFoliage - tmp.inext);
  256.  
  257.         m_fLightsHDRDynamicPowerFactor = 0.0f;
  258.  
  259.         m_vHDRFilmCurveParams = Vec4(1.0f, 1.0f, 1.0f, 1.0f);
  260.         m_vHDREyeAdaptation = Vec3(0.05f, 0.8f, 0.9f);
  261.         m_fHDRBloomAmount = 0.0f;
  262.         m_vColorBalance = Vec3(1.0f, 1.0f, 1.0f);
  263.         m_fHDRSaturation = 1.0f;
  264.  
  265.         m_vSkyHightlightPos.Set(0, 0, 0);
  266.         m_vSkyHightlightCol.Set(0, 0, 0);
  267.         m_fSkyHighlightSize = 0;
  268.  
  269.         m_volFogGlobalDensity = 0.02f;
  270.         m_volFogGlobalDensityMultiplierLDR = 1.0f;
  271.         m_volFogFinalDensityClamp = 1.0f;
  272.  
  273.         m_idMatLeaves = -1;
  274.  
  275.         /* // structures should not grow too much - commented out as in 64bit they do
  276.            assert(sizeof(CVegetation)-sizeof(IRenderNode)<=52);
  277.            assert(sizeof(CBrush)-sizeof(IRenderNode)<=120);
  278.            assert(sizeof(IRenderNode)<=96);
  279.          */
  280.         m_oceanFogColor = 0.2f * Vec3(29.0f, 102.0f, 141.0f) / 255.0f;
  281.         m_oceanFogColorShallow = Vec3(0, 0, 0); //0.5f * Vec3( 206.0f, 249.0f, 253.0f ) / 255.0f;
  282.         m_oceanFogDensity = 0;                  //0.2f;
  283.  
  284.         m_oceanCausticsDistanceAtten = 100.0f;
  285.         m_oceanCausticsMultiplier = 1.0f;
  286.         m_oceanCausticsDarkeningMultiplier = 1.0f;
  287.  
  288.         m_oceanCausticHeight = 2.5f;
  289.         m_oceanCausticDepth = 8.0f;
  290.         m_oceanCausticIntensity = 1.0f;
  291.  
  292.         m_oceanWindDirection = 1;
  293.         m_oceanWindSpeed = 4.0f;
  294.         m_oceanWavesSpeed = 5.0f;
  295.         m_oceanWavesAmount = 1.5f;
  296.         m_oceanWavesSize = 0.75f;
  297.  
  298.         m_fRefreshSceneDataCVarsSumm = -1;
  299.         m_nRenderTypeEnableCVarSum = -1;
  300.  
  301.         /*
  302.            CTerrainNode::SetProcObjChunkPool(new SProcObjChunkPool);
  303.            CTerrainNode::SetProcObjPoolMan(new CProcVegetPoolMan);
  304.          */
  305.         m_bResetRNTmpDataPool = false;
  306.  
  307.         m_fSunDirUpdateTime = 0;
  308.         m_vSunDirNormalized.zero();
  309.  
  310.         m_volFogRamp = Vec3(0, 100.0f, 0);
  311.         m_volFogShadowRange = Vec3(0.1f, 0, 0);
  312.         m_volFogShadowDarkening = Vec3(0.25f, 1, 1);
  313.         m_volFogShadowEnable = Vec3(0, 0, 0);
  314.         m_volFog2CtrlParams = Vec3(64.0f, 0.0f, 1.0f);
  315.         m_volFog2ScatteringParams = Vec3(1.0f, 0.3f, 0.6f);
  316.         m_volFog2Ramp = Vec3(0.0f, 0.0f, 0.0f);
  317.         m_volFog2Color = Vec3(1.0f, 1.0f, 1.0f);
  318.         m_volFog2GlobalDensity = Vec3(0.1f, 1.0f, 0.4f);
  319.         m_volFog2HeightDensity = Vec3(0.0f, 1.0f, 0.1f);
  320.         m_volFog2HeightDensity2 = Vec3(4000.0f, 0.0001f, 0.95f);
  321.         m_volFog2Color1 = Vec3(1.0f, 1.0f, 1.0f);
  322.         m_volFog2Color2 = Vec3(1.0f, 1.0f, 1.0f);
  323.         m_nightSkyHorizonCol = Vec3(0, 0, 0);
  324.         m_nightSkyZenithCol = Vec3(0, 0, 0);
  325.         m_nightSkyZenithColShift = 0;
  326.         m_nightSkyStarIntensity = 0;
  327.         m_moonDirection = Vec3(0, 0, 0);
  328.         m_nightMoonCol = Vec3(0, 0, 0);
  329.         m_nightMoonSize = 0;
  330.         m_nightMoonInnerCoronaCol = Vec3(0, 0, 0);
  331.         m_nightMoonInnerCoronaScale = 1.0f;
  332.         m_nightMoonOuterCoronaCol = Vec3(0, 0, 0);
  333.         m_nightMoonOuterCoronaScale = 1.0f;
  334.         m_moonRotationLatitude = 0;
  335.         m_moonRotationLongitude = 0;
  336.         m_skyboxMultiplier = 1.0f;
  337.         m_dayNightIndicator = 1.0f;
  338.         m_fogColor2 = Vec3(0, 0, 0);
  339.         m_fogColorRadial = Vec3(0, 0, 0);
  340.         m_volFogHeightDensity = Vec3(0, 1, 0);
  341.         m_volFogHeightDensity2 = Vec3(4000.0f, 0, 0);
  342.         m_volFogGradientCtrl = Vec3(1, 1, 1);
  343.  
  344.         m_fogColorSkylightRayleighInScatter = Vec3(0, 0, 0);
  345.  
  346.         m_vFogColor = Vec3(1.0f, 1.0f, 1.0f);
  347.         m_vAmbGroundCol = Vec3(0.0f, 0.0f, 0.0f);
  348.  
  349.         m_dawnStart = 350.0f / 60.0f;
  350.         m_dawnEnd = 360.0f / 60.0f;
  351.         m_duskStart = 12.0f + 360.0f / 60.0f;
  352.         m_duskEnd = 12.0f + 370.0f / 60.0f;
  353.  
  354.         m_fCloudShadingSunLightMultiplier = 0;
  355.         m_fCloudShadingSkyLightMultiplier = 0;
  356.         m_vCloudShadingCustomSunColor = Vec3(0, 0, 0);
  357.         m_vCloudShadingCustomSkyColor = Vec3(0, 0, 0);
  358.  
  359.         m_vVolCloudAtmosphericScattering = Vec3(0, 0, 0);
  360.         m_vVolCloudGenParams = Vec3(0, 0, 0);
  361.         m_vVolCloudScatteringLow = Vec3(0, 0, 0);
  362.         m_vVolCloudScatteringHigh = Vec3(0, 0, 0);
  363.         m_vVolCloudGroundColor = Vec3(0, 0, 0);
  364.         m_vVolCloudScatteringMulti = Vec3(0, 0, 0);
  365.         m_vVolCloudWindAtmospheric = Vec3(0, 0, 0);
  366.         m_vVolCloudTurbulence = Vec3(0, 0, 0);
  367.         m_vVolCloudEnvParams = Vec3(0, 0, 0);
  368.         m_vVolCloudGlobalNoiseScale = Vec3(0, 0, 0);
  369.         m_vVolCloudRenderParams = Vec3(0, 0, 0);
  370.         m_vVolCloudTurbulenceNoiseScale = Vec3(0, 0, 0);
  371.         m_vVolCloudTurbulenceNoiseParams = Vec3(0, 0, 0);
  372.         m_vVolCloudDensityParams = Vec3(0, 0, 0);
  373.         m_vVolCloudMiscParams = Vec3(0, 0, 0);
  374.         m_vVolCloudTilingSize = Vec3(0, 0, 0);
  375.         m_vVolCloudTilingOffset = Vec3(0, 0, 0);
  376.  
  377.         m_vPrevMainFrameCamPos.Set(-1000000.f, -1000000.f, -1000000.f);
  378.         m_fAverageCameraSpeed = 0;
  379.         m_vAverageCameraMoveDir = Vec3(0);
  380.         m_bContentPrecacheRequested = false;
  381.         m_bTerrainTextureStreamingInProgress = false;
  382.         m_bLayersActivated = false;
  383.         m_eShadowMode = ESM_NORMAL;
  384.         m_pSegmentsManager = 0;
  385.         m_bSegmentOperationInProgress = false;
  386.  
  387.         ClearDebugFPSInfo();
  388.  
  389.         m_fMaxViewDistScale = 1.f;
  390.  
  391.         m_ptexIconLowMemoryUsage = NULL;
  392.         m_ptexIconAverageMemoryUsage = NULL;
  393.         m_ptexIconHighMemoryUsage = NULL;
  394.         m_ptexIconEditorConnectedToConsole = NULL;
  395.         m_pScreenshotCallback = 0;
  396.         m_bInShutDown = false;
  397.         m_bInUnload = false;
  398.         m_bInLoad = false;
  399.  
  400.         m_nCloudShadowTexId = 0;
  401.  
  402.         m_nNightMoonTexId = 0;
  403.  
  404.         m_pDeferredPhysicsEventManager = new CDeferredPhysicsEventManager();
  405.  
  406. #if defined(USE_GEOM_CACHES)
  407.         m_pGeomCacheManager = new CGeomCacheManager();
  408. #endif
  409.  
  410.         m_LightVolumesMgr.Init();
  411.  
  412.         m_pBreakableBrushHeap = NULL;
  413.  
  414.         m_fZoomFactor = 0.0f;
  415.         m_fPrevZoomFactor = 0.0f;
  416.         m_bZoomInProgress = false;
  417.         m_nZoomMode = 0;
  418.  
  419.         m_fAmbMaxHeight = 0.0f;
  420.         m_fAmbMinHeight = 0.0f;
  421.  
  422.         m_pLightQuality = NULL;
  423.         m_fSaturation = 0.0f;
  424.  
  425.         m_fGsmRange = 0.0f;
  426.         m_fGsmRangeStep = 0.0f;
  427.         m_fShadowsConstBias = 0.0f;
  428.         m_fShadowsSlopeBias = 0.0f;
  429.         m_nCustomShadowFrustumCount = 0;
  430.         m_bHeightMapAoEnabled = false;
  431.  
  432.         m_nCurrentWindAreaList = 0;
  433.         m_pLevelStatObjTable = NULL;
  434.         m_pLevelMaterialsTable = NULL;
  435.         m_bLevelFilesEndian = false;
  436. }
  437.  
  438. //////////////////////////////////////////////////////////////////////
  439. C3DEngine::~C3DEngine()
  440. {
  441.         m_bInShutDown = true;
  442.         m_bInUnload = true;
  443.         m_bInLoad = false;
  444.  
  445.         delete CTerrainNode::GetProcObjPoolMan();
  446.         CTerrainNode::SetProcObjChunkPool(NULL);
  447.  
  448.         delete CTerrainNode::GetProcObjChunkPool();
  449.         CTerrainNode::SetProcObjPoolMan(NULL);
  450.  
  451.         assert(IsHeapValid());
  452.  
  453.         ShutDown();
  454.  
  455.         delete m_pTimeOfDay;
  456.         delete m_pDecalManager;
  457.         delete m_pVisAreaManager;
  458.         SAFE_DELETE(m_pClipVolumeManager);
  459.  
  460.         CryAlignedDelete(m_pSkyLightManager);
  461.         m_pSkyLightManager = 0;
  462.         for (int nSID = 0; nSID < Get3DEngine()->m_pObjectsTree.Count(); nSID++)
  463.                 SAFE_DELETE(m_pObjectsTree[nSID]);
  464.         //  delete m_pSceneTree;
  465.         delete m_pRenderMeshMerger;
  466.         delete m_pMatMan;
  467.         m_pMatMan = 0;
  468.         delete m_pCloudsManager;
  469.  
  470.         delete m_pCVars;
  471.  
  472.         delete m_pDeferredPhysicsEventManager;
  473. }
  474.  
  475. //////////////////////////////////////////////////////////////////////
  476.  
  477. void C3DEngine::RemoveEntInFoliage(int i, IPhysicalEntity* pent)
  478. {
  479.         IPhysicalEntity* pent1 = m_pPhysicalWorld->GetPhysicalEntityById(m_arrEntsInFoliage[i].id);
  480.         pe_params_foreign_data pfd;
  481.         if (!pent)
  482.                 pent = pent1;
  483.         else if (pent != pent1)
  484.         {
  485.                 // probably someone overwrote foreign flags
  486.                 for (i = m_arrEntsInFoliage.size() - 1; i >= 0 && pent != m_pPhysicalWorld->GetPhysicalEntityById(m_arrEntsInFoliage[i].id); i--)
  487.                         ;
  488.                 if (i < 0)
  489.                         return;
  490.         }
  491.         if (pent && pent->GetParams(&pfd) && (pfd.iForeignFlags >> 8 & 255) == i + 1)
  492.         {
  493.                 MARK_UNUSED pfd.pForeignData, pfd.iForeignData, pfd.iForeignFlags;
  494.                 pfd.iForeignFlagsAND = 255;
  495.                 pent->SetParams(&pfd, 1);
  496.         }
  497.         int j = m_arrEntsInFoliage.size() - 1;
  498.         if (i < j)
  499.         {
  500.                 m_arrEntsInFoliage[i] = m_arrEntsInFoliage[j];
  501.                 if ((pent = m_pPhysicalWorld->GetPhysicalEntityById(m_arrEntsInFoliage[i].id)) && pent->GetParams(&pfd) &&
  502.                     (pfd.iForeignFlags >> 8 & 255) == j + 1)
  503.                 {
  504.                         MARK_UNUSED pfd.pForeignData, pfd.iForeignData;
  505.                         pfd.iForeignFlags = pfd.iForeignFlags & 255 | (i + 1) << 8;
  506.                         pent->SetParams(&pfd, 1);
  507.                 }
  508.         }
  509.         m_arrEntsInFoliage.DeleteLast();
  510. }
  511.  
  512. bool C3DEngine::Init()
  513. {
  514.         m_pPartManager = CreateParticleManager(!gEnv->IsDedicated());
  515.         m_pParticleSystem = pfx2::GetIParticleSystem();
  516.         m_pSystem->SetIParticleManager(m_pPartManager);
  517.  
  518.         m_pOpticsManager = new COpticsManager;
  519.         m_pSystem->SetIOpticsManager(m_pOpticsManager);
  520.  
  521.         CRY_ASSERT(m_pWaterRippleManager);
  522.         m_pWaterRippleManager->Initialize();
  523.  
  524.         for (int i = 0; i < eERType_TypesNum; i++)
  525.         {
  526.                 m_bRenderTypeEnabled[i] = true;
  527.         }
  528.  
  529.         UpdateRenderTypeEnableLookup();
  530.  
  531.         // Allocate the temporary pool used for allocations during streaming and loading
  532.         const size_t tempPoolSize = static_cast<size_t>(GetCVars()->e_3dEngineTempPoolSize) << 10;
  533.         CRY_ASSERT_MESSAGE(tempPoolSize != 0, "C3DEngine::Init() temp pool size is set to 0");
  534.  
  535.         {
  536.                 MEMSTAT_CONTEXT(EMemStatContextTypes::MSC_Other, 0, "3Engine Temp Pool");
  537.  
  538.                 if (!CTemporaryPool::Initialize(tempPoolSize))
  539.                 {
  540.                         CryFatalError("C3DEngine::Init() could not initialize temporary pool");
  541.                         return false;
  542.                 }
  543.         }
  544.  
  545.         SFrameLodInfo frameLodInfo;
  546.         frameLodInfo.fLodRatio = GetCVars()->e_LodRatio;
  547.  
  548.         frameLodInfo.fTargetSize = GetCVars()->e_LodFaceAreaTargetSize;
  549.         CRY_ASSERT(frameLodInfo.fTargetSize > 0.f);
  550.         if (frameLodInfo.fTargetSize <= 0.f)
  551.         {
  552.                 frameLodInfo.fTargetSize = 1.f;
  553.         }
  554.  
  555.         frameLodInfo.nMinLod = GetCVars()->e_LodMin;
  556.         frameLodInfo.nMaxLod = GetCVars()->e_LodMax;
  557.         if (GetCVars()->e_Lods == 0)
  558.         {
  559.                 frameLodInfo.nMinLod = 0;
  560.                 frameLodInfo.nMaxLod = 0;
  561.         }
  562.         SetFrameLodInfo(frameLodInfo);
  563.  
  564.         return  (true);
  565. }
  566.  
  567. bool C3DEngine::IsCameraAnd3DEngineInvalid(const SRenderingPassInfo& passInfo, const char* szCaller)
  568. {
  569.         if (!m_pObjManager)
  570.         {
  571.                 return (true);
  572.         }
  573.  
  574.         const CCamera& rCamera = passInfo.GetCamera();
  575.         const float MAX_M23_REPORTED = 3000000.f; // MAT => upped from 100,000 which spammed this message on spear and cityhall. Really should stop editor generating
  576.         // water levels that trigger this message.
  577.  
  578.         if (!_finite(rCamera.GetMatrix().m03) || !_finite(rCamera.GetMatrix().m13) || !_finite(rCamera.GetMatrix().m23) || GetMaxViewDistance() <= 0 ||
  579.             rCamera.GetMatrix().m23 < -MAX_M23_REPORTED || rCamera.GetMatrix().m23 > MAX_M23_REPORTED || rCamera.GetFov() < 0.0001f || rCamera.GetFov() > gf_PI)
  580.         {
  581.                 Error("Bad camera passed to 3DEngine from %s: Pos=(%.1f, %.1f, %.1f), Fov=%.1f, MaxViewDist=%.1f. Maybe the water level is too extreme.",
  582.                       szCaller,
  583.                       rCamera.GetMatrix().m03, rCamera.GetMatrix().m13, rCamera.GetMatrix().m23,
  584.                       rCamera.GetFov(), _finite(rCamera.GetMatrix().m03) ? GetMaxViewDistance() : 0);
  585.                 return true;
  586.         }
  587.  
  588.         return false;
  589.  
  590. }
  591.  
  592. void C3DEngine::OnFrameStart()
  593. {
  594.         FUNCTION_PROFILER_3DENGINE;
  595.  
  596.         if (m_pPartManager)
  597.                 m_pPartManager->OnFrameStart();
  598.         if (m_pParticleSystem)
  599.                 m_pParticleSystem->OnFrameStart();
  600.  
  601.         m_nRenderWorldUSecs = 0;
  602.         m_pDeferredPhysicsEventManager->Update();
  603.  
  604. #if defined(USE_GEOM_CACHES)
  605.         if (m_pGeomCacheManager && !m_bLevelLoadingInProgress)
  606.         {
  607.                 m_pGeomCacheManager->StreamingUpdate();
  608.         }
  609. #endif
  610.  
  611.         UpdateWindAreas();
  612.  
  613.         if (m_pWaterRippleManager)
  614.         {
  615.                 m_pWaterRippleManager->OnFrameStart();
  616.         }
  617. }
  618.  
  619. float g_oceanLevel, g_oceanStep;
  620. float GetOceanLevelCallback(int ix, int iy)
  621. {
  622.         return gEnv->p3DEngine->GetAccurateOceanHeight(Vec3(ix * g_oceanStep, iy * g_oceanStep, g_oceanLevel));
  623.         /*pe_status_waterman psw;
  624.            gEnv->pPhysicalWorld->GetWatermanStatus(&psw);
  625.            Vec2 pos = Vec2((float)ix,(float)iy)*GetFloatCVar(e_PhysOceanCell)-Vec2(psw.origin);
  626.            Vec2i itile(FtoI(pos.x*0.25f-0.5f), FtoI(pos.y*0.25f-0.5f));
  627.            if ((itile.x|itile.y)<0 || max(itile.x,itile.y)>6)
  628.            return g_oceanLevel;
  629.            SWaterTileBase *pTile = psw.pTiles[itile.x+itile.y*7];
  630.            if (!pTile || !pTile->bActive)
  631.            return g_oceanLevel;
  632.            Vec2i ipos(FtoI((pos.x-itile.x*4)*10.0f-0.5f), FtoI((pos.y-itile.y*4)*10.0f-0.5f));
  633.            return psw.origin.z+pTile->ph[itile.x+itile.y*40];*/
  634. }
  635. unsigned char GetOceanSurfTypeCallback(int ix, int iy)
  636. {
  637.         return 0;
  638. }
  639.  
  640. void C3DEngine::Update()
  641. {
  642.         m_bProfilerEnabled = gEnv->pFrameProfileSystem->IsProfiling();
  643.  
  644.         FUNCTION_PROFILER_3DENGINE;
  645.  
  646.         m_LightConfigSpec = (ESystemConfigSpec)GetCurrentLightSpec();
  647.  
  648.         ///     if(m_pVisAreaManager)
  649.         //      m_pVisAreaManager->Preceche(m_pObjManager);
  650.  
  651.         if (GetObjManager())
  652.                 GetObjManager()->ClearStatObjGarbage();
  653.  
  654.         if (m_pTerrain)
  655.         {
  656.                 m_pTerrain->Recompile_Modified_Incrementaly_RoadRenderNodes();
  657.         }
  658.  
  659.         if (m_bEditor)
  660.                 CRoadRenderNode::FreeStaticMemoryUsage();
  661.  
  662.         if (m_pDecalManager)
  663.                 m_pDecalManager->Update(GetTimer()->GetFrameTime());
  664.  
  665.         if (GetCVars()->e_PrecacheLevel == 3)
  666.                 PrecacheLevel(true, 0, 0);
  667.  
  668.         DebugDraw_Draw();
  669.  
  670.         ProcessCVarsChange();
  671.  
  672.         pe_params_area pa;
  673.         IPhysicalEntity* pArea;
  674.         if ((pArea = gEnv->pPhysicalWorld->AddGlobalArea())->GetParams(&pa))
  675.         {
  676.                 g_oceanLevel = GetWaterLevel();
  677.                 bool bOceanEnabled = GetFloatCVar(e_PhysOceanCell) > 0 && g_oceanLevel > 0;
  678.  
  679.                 if (bOceanEnabled && (!pa.pGeom || g_oceanStep != GetFloatCVar(e_PhysOceanCell)))
  680.                 {
  681.                         new(&pa)pe_params_area;
  682.                         primitives::heightfield hf;
  683.                         hf.origin.zero().z = g_oceanLevel;
  684.                         g_oceanStep = GetFloatCVar(e_PhysOceanCell);
  685.                         hf.size.set((int)(8192 / g_oceanStep), (int)(8192 / g_oceanStep));
  686.                         hf.step.set(g_oceanStep, g_oceanStep);
  687.                         hf.fpGetHeightCallback = GetOceanLevelCallback;
  688.                         hf.fpGetSurfTypeCallback = GetOceanSurfTypeCallback;
  689.                         hf.Basis.SetIdentity();
  690.                         hf.bOriented = 0;
  691.                         hf.typemask = 255;
  692.                         hf.typehole = 255;
  693.                         hf.heightscale = 1.0f;
  694.                         pa.pGeom = gEnv->pPhysicalWorld->GetGeomManager()->CreatePrimitive(primitives::heightfield::type, &hf);
  695.                         pArea->SetParams(&pa);
  696.  
  697.                         Vec4 par0, par1;
  698.                         GetOceanAnimationParams(par0, par1);
  699.                         pe_params_buoyancy pb;
  700.                         pb.waterFlow = Vec3(par1.z, par1.y, 0) * (par0.z * 0.25f); // tone down the speed
  701.                         //pArea->SetParams(&pb);
  702.                 }
  703.                 else if (!bOceanEnabled && pa.pGeom)
  704.                 {
  705.                         new(&pa)pe_params_area;
  706.                         pa.pGeom = 0;
  707.                         pArea->SetParams(&pa);
  708.                         pe_params_buoyancy pb;
  709.                         pb.waterFlow.zero();
  710.                         pArea->SetParams(&pb);
  711.                 }
  712.         }
  713.  
  714.         CRenderMeshUtils::ClearHitCache();
  715.  
  716.         CleanUpOldDecals();
  717.  
  718.         CDecalRenderNode::ResetDecalUpdatesCounter();
  719.  
  720.         if (m_pBreezeGenerator)
  721.                 m_pBreezeGenerator->Update();
  722.  
  723.         if (m_pBreakableBrushHeap)
  724.                 m_pBreakableBrushHeap->Cleanup();
  725.  
  726.         m_bTerrainTextureStreamingInProgress = false;
  727.         if (CTerrain* const pTerrain = GetTerrain())
  728.         {
  729.                 if (pTerrain->GetNotReadyTextureNodesCount() > 0)
  730.                 {
  731.                         m_bTerrainTextureStreamingInProgress = true;
  732.                 }
  733.         }
  734. }
  735.  
  736. void C3DEngine::Tick()
  737. {
  738.         threadID nThreadID = 0;
  739.  
  740.         if (GetRenderer())
  741.         {
  742.                 GetRenderer()->EF_Query(EFQ_RenderThreadList, nThreadID);
  743.         }
  744.  
  745.         GetMatMan()->DelayedMaterialDeletion();
  746.  
  747.         // clear stored cameras from last frame
  748.         m_RenderingPassCameras[nThreadID].resize(0);
  749. }
  750.  
  751. void C3DEngine::ProcessCVarsChange()
  752. {
  753.         static int nObjectLayersActivation = -1;
  754.  
  755.         if (nObjectLayersActivation != GetCVars()->e_ObjectLayersActivation)
  756.         {
  757.                 if (GetCVars()->e_ObjectLayersActivation == 2)
  758.                         ActivateObjectsLayer(~0, true, true, true, true, "ALL_OBJECTS");
  759.                 if (GetCVars()->e_ObjectLayersActivation == 3)
  760.                         ActivateObjectsLayer(~0, false, true, true, true, "ALL_OBJECTS");
  761.  
  762.                 nObjectLayersActivation = GetCVars()->e_ObjectLayersActivation;
  763.         }
  764.  
  765.         float fNewCVarsSumm =
  766.           GetCVars()->e_ShadowsCastViewDistRatio +
  767.           GetCVars()->e_LodTransitionSpriteDistRatio +
  768.           GetCVars()->e_LodTransitionSpriteMinDist +
  769.           GetCVars()->e_VegetationUseTerrainColor +
  770.           GetCVars()->e_TerrainDetailMaterials +
  771.           GetCVars()->e_ViewDistRatio +
  772.           GetCVars()->e_ViewDistMin +
  773.           GetCVars()->e_ViewDistRatioDetail +
  774.           GetCVars()->e_ViewDistRatioVegetation +
  775.           GetCVars()->e_DefaultMaterial +
  776.           GetCVars()->e_VegetationSpritesDistanceRatio +
  777.           GetCVars()->e_VegetationSpritesDistanceCustomRatioMin +
  778.           GetCVars()->e_VegetationSpritesMinDistance +
  779.           GetGeomDetailScreenRes() +
  780.           GetCVars()->e_Portals +
  781.           GetCVars()->e_DebugDraw +
  782.           GetFloatCVar(e_ViewDistCompMaxSize) +
  783.           GetCVars()->e_DecalsDeferredStatic +
  784.           (GetRenderer() ? GetRenderer()->GetWidth() : 0);
  785.  
  786.         if (m_fRefreshSceneDataCVarsSumm != -1 && m_fRefreshSceneDataCVarsSumm != fNewCVarsSumm)
  787.         {
  788.                 UpdateStatInstGroups();
  789.  
  790.                 // re-register every instance in level
  791.                 const float terrainSize = (float)GetTerrainSize();
  792.                 GetObjManager()->ReregisterEntitiesInArea(
  793.                   Vec3(-terrainSize, -terrainSize, -terrainSize),
  794.                   Vec3(terrainSize * 2.f, terrainSize * 2.f, terrainSize * 2.f));
  795.  
  796.                 // force recreation of terrain meshes
  797.                 if (CTerrain* const pTerrain = GetTerrain())
  798.                 {
  799.                         pTerrain->ResetTerrainVertBuffers(NULL, -1);
  800.                 }
  801.  
  802.                 // refresh vegetation properties
  803.                 UpdateStatInstGroups();
  804.  
  805.                 // force refresh of temporary data associated with visible objects
  806.                 MarkRNTmpDataPoolForReset();
  807.         }
  808.  
  809.         m_fRefreshSceneDataCVarsSumm = fNewCVarsSumm;
  810.  
  811.         int nRenderTypeEnableCVarSum = (GetCVars()->e_Vegetation << 0)
  812.                                        + (GetCVars()->e_Brushes << 1)
  813.                                        + (GetCVars()->e_Entities << 2);
  814.  
  815.         if (m_nRenderTypeEnableCVarSum != nRenderTypeEnableCVarSum)
  816.         {
  817.                 m_nRenderTypeEnableCVarSum = nRenderTypeEnableCVarSum;
  818.  
  819.                 UpdateRenderTypeEnableLookup();
  820.         }
  821.  
  822.         {
  823.                 float fNewCVarsSumm2 = GetCVars()->e_LodRatio +
  824.                                        GetCVars()->e_PermanentRenderObjects;
  825.  
  826.                 if (m_bEditor)
  827.                 {
  828.                         fNewCVarsSumm2 += float(int(GetSkyColor().GetLength() * 10) / 10);
  829.                 }
  830.  
  831.                 static float fCVarsSumm2 = fNewCVarsSumm2;
  832.  
  833.                 if (fCVarsSumm2 != fNewCVarsSumm2)
  834.                 {
  835.                         MarkRNTmpDataPoolForReset();
  836.  
  837.                         fCVarsSumm2 = fNewCVarsSumm2;
  838.                 }
  839.         }
  840.  
  841.         SFrameLodInfo frameLodInfo;
  842.         frameLodInfo.fLodRatio = GetCVars()->e_LodRatio;
  843.  
  844.         frameLodInfo.fTargetSize = GetCVars()->e_LodFaceAreaTargetSize;
  845.         CRY_ASSERT(frameLodInfo.fTargetSize > 0.f);
  846.         if (frameLodInfo.fTargetSize <= 0.f)
  847.         {
  848.                 frameLodInfo.fTargetSize = 1.f;
  849.         }
  850.  
  851.         frameLodInfo.nMinLod = GetCVars()->e_LodMin;
  852.         frameLodInfo.nMaxLod = GetCVars()->e_LodMax;
  853.         if (GetCVars()->e_Lods == 0)
  854.         {
  855.                 frameLodInfo.nMinLod = 0;
  856.                 frameLodInfo.nMaxLod = 0;
  857.         }
  858.         SetFrameLodInfo(frameLodInfo);
  859. }
  860.  
  861. //////////////////////////////////////////////////////////////////////
  862. void C3DEngine::UpdateScene(const SRenderingPassInfo& passInfo)
  863. {
  864.         if (GetCVars()->e_Sun)
  865.                 UpdateSunLightSource(passInfo);
  866.  
  867.         FindPotentialLightSources(passInfo);
  868.  
  869.         // Set traceable fog volume areas
  870.         CFogVolumeRenderNode::SetTraceableArea(AABB(passInfo.GetCamera().GetPosition(), 1024.0f), passInfo);
  871. }
  872.  
  873. //////////////////////////////////////////////////////////////////////
  874. void C3DEngine::ShutDown()
  875. {
  876.         if (GetRenderer() != GetSystem()->GetIRenderer())
  877.                 CryFatalError("Renderer was deallocated before I3DEngine::ShutDown() call");
  878.  
  879.         UnlockCGFResources();
  880.  
  881.         UnloadLevel();
  882.  
  883. #if defined(USE_GEOM_CACHES)
  884.         delete m_pGeomCacheManager;
  885.         m_pGeomCacheManager = 0;
  886. #endif
  887.  
  888.         DestroyParticleManager(m_pPartManager);
  889.         m_pPartManager = nullptr;
  890.         m_pParticleSystem.reset();
  891.         m_pSystem->SetIParticleManager(0);
  892.  
  893.         if (m_pOpticsManager)
  894.         {
  895.                 delete m_pOpticsManager;
  896.                 m_pOpticsManager = 0;
  897.                 m_pSystem->SetIOpticsManager(m_pOpticsManager);
  898.         }
  899.  
  900.         CRY_ASSERT(m_pWaterRippleManager);
  901.         m_pWaterRippleManager->Finalize();
  902.         m_pWaterRippleManager.reset();
  903.  
  904.         CryAlignedDelete(m_pObjManager);
  905.         m_pObjManager = 0;
  906.  
  907.         if (GetPhysicalWorld())
  908.         {
  909.                 CPhysCallbacks::Done();
  910.         }
  911.  
  912.         // Free the temporary pool's underlying storage
  913.         // and reset the pool
  914.         if (!CTemporaryPool::Shutdown())
  915.         {
  916.                 CryFatalError("C3DEngine::Shutdown() could not shutdown temporary pool");
  917.         }
  918.  
  919.         COctreeNode::DeallocateRenderContentQueue();
  920. }
  921.  
  922. #if CRY_PLATFORM_WINDOWS && CRY_PLATFORM_64BIT
  923.         #pragma warning( push )               //AMD Port
  924.         #pragma warning( disable : 4311 )
  925. #endif
  926.  
  927. #ifndef _RELEASE
  928. void C3DEngine::ProcessStreamingLatencyTest(const CCamera& camIn, CCamera& camOut, const SRenderingPassInfo& passInfo)
  929. {
  930.         static float fSQTestOffset = 0;
  931.         static PodArray<ITexture*> arrTestTextures;
  932.         static ITexture* pTestTexture = 0;
  933.         static ITexture* pLastNotReadyTexture = 0;
  934.         static float fStartTime = 0;
  935.         static float fDelayStartTime = 0;
  936.         static size_t nMaxTexUsage = 0;
  937.  
  938.         static int nOpenRequestCount = 0;
  939.         SStreamEngineOpenStats stats;
  940.         gEnv->pSystem->GetStreamEngine()->GetStreamingOpenStatistics(stats);
  941.         if (stats.nOpenRequestCount > nOpenRequestCount)
  942.                 nOpenRequestCount = stats.nOpenRequestCount;
  943.         else
  944.                 nOpenRequestCount = max(0, nOpenRequestCount + stats.nOpenRequestCount) / 2;
  945.  
  946.         ICVar* pTSFlush = GetConsole()->GetCVar("r_TexturesStreamingDebug");
  947.  
  948.         if (GetCVars()->e_SQTestBegin == 1)
  949.         {
  950.                 // Init waiting few seconds until streaming is stabilized and all required textures are loaded
  951.                 PrintMessage("======== Starting streaming latency test ========");
  952.                 fDelayStartTime = GetCurTimeSec();
  953.                 nMaxTexUsage = 0;
  954.                 GetCVars()->e_SQTestBegin = 2;
  955.                 PrintMessage("Waiting %.1f seconds and zero requests and no camera movement", GetCVars()->e_SQTestDelay);
  956.  
  957.                 if (ICVar* pPart = GetConsole()->GetCVar("e_Particles"))
  958.                         pPart->Set(0);
  959.                 if (ICVar* pAI = GetConsole()->GetCVar("sys_AI"))
  960.                         pAI->Set(0);
  961.         }
  962.         else if (GetCVars()->e_SQTestBegin == 2)
  963.         {
  964.                 // Perform waiting
  965.                 if (GetCurTimeSec() - fDelayStartTime > GetCVars()->e_SQTestDelay && !nOpenRequestCount && m_fAverageCameraSpeed < .01f)
  966.                 {
  967.                         pTSFlush->Set(0);
  968.                         GetCVars()->e_SQTestBegin = 3;
  969.                 }
  970.                 else
  971.                         pTSFlush->Set(3);
  972.         }
  973.         else if (GetCVars()->e_SQTestBegin == 3)
  974.         {
  975.                 // Build a list of all important loaded textures
  976.                 PrintMessage("Collect information about loaded textures");
  977.  
  978.                 fSQTestOffset = (float)GetCVars()->e_SQTestDistance;
  979.  
  980.                 arrTestTextures.Clear();
  981.                 SRendererQueryGetAllTexturesParam param;
  982.  
  983.                 GetRenderer()->EF_Query(EFQ_GetAllTextures, param);
  984.                 if (param.pTextures)
  985.                 {
  986.                         for (uint32 i = 0; i < param.numTextures; i++)
  987.                         {
  988.                                 ITexture* pTexture = param.pTextures[i];
  989.                                 if (pTexture->GetAccessFrameId() > (int)(passInfo.GetMainFrameID() - 4))
  990.                                         if (pTexture->GetMinLoadedMip() <= GetCVars()->e_SQTestMip)
  991.                                                 if (pTexture->IsStreamable())
  992.                                                         if (pTexture->GetWidth() * pTexture->GetHeight() >= 256 * 256)
  993.                                                         {
  994.                                                                 arrTestTextures.Add(pTexture);
  995.  
  996.                                                                 if (strstr(pTexture->GetName(), GetCVars()->e_SQTestTextureName->GetString()))
  997.                                                                 {
  998.                                                                         pTestTexture = pTexture;
  999.                                                                         PrintMessage("Test texture name: %s", pTexture->GetName());
  1000.                                                                 }
  1001.                                                         }
  1002.                         }
  1003.  
  1004.                 }
  1005.  
  1006.                 GetRenderer()->EF_Query(EFQ_GetAllTexturesRelease, param);
  1007.  
  1008.                 PrintMessage("%d test textures found", arrTestTextures.Count());
  1009.  
  1010.                 PrintMessage("Teleporting camera to offset position");
  1011.  
  1012.                 GetCVars()->e_SQTestBegin = 4;
  1013.         }
  1014.         else if (GetCVars()->e_SQTestBegin == 4)
  1015.         {
  1016.                 // Init waiting few seconds until streaming is stabilized and all required textures are loaded
  1017.                 fDelayStartTime = GetCurTimeSec();
  1018.                 GetCVars()->e_SQTestBegin = 5;
  1019.                 PrintMessage("Waiting %.1f seconds and zero requests and no camera movement", GetCVars()->e_SQTestDelay);
  1020.         }
  1021.         else if (GetCVars()->e_SQTestBegin == 5)
  1022.         {
  1023.                 // Move camera to offset position and perform waiting
  1024.                 Matrix34 mat = camIn.GetMatrix();
  1025.                 Vec3 vPos = camIn.GetPosition() - camIn.GetViewdir() * fSQTestOffset;
  1026.                 mat.SetTranslation(vPos);
  1027.                 camOut.SetMatrix(mat);
  1028.  
  1029.                 if (GetCurTimeSec() - fDelayStartTime > GetCVars()->e_SQTestDelay && !nOpenRequestCount && m_fAverageCameraSpeed < .01f)
  1030.                 {
  1031.                         PrintMessage("Begin camera movement");
  1032.                         GetCVars()->e_SQTestBegin = 6;
  1033.                         pTSFlush->Set(0);
  1034.                 }
  1035.                 else
  1036.                         pTSFlush->Set(3);
  1037.         }
  1038.         else if (GetCVars()->e_SQTestBegin == 6)
  1039.         {
  1040.                 // Process camera movement from offset position to test point
  1041.                 Matrix34 mat = camIn.GetMatrix();
  1042.                 Vec3 vPos = camIn.GetPosition() - camIn.GetViewdir() * fSQTestOffset;
  1043.                 mat.SetTranslation(vPos);
  1044.                 camOut.SetMatrix(mat);
  1045.  
  1046.                 fSQTestOffset -= GetTimer()->GetFrameTime() * (float)GetCVars()->e_SQTestMoveSpeed;
  1047.  
  1048.                 STextureStreamingStats statsTex(true);
  1049.                 m_pRenderer->EF_Query(EFQ_GetTexStreamingInfo, statsTex);
  1050.                 nMaxTexUsage = max(nMaxTexUsage, statsTex.nRequiredStreamedTexturesSize);
  1051.  
  1052.                 if (fSQTestOffset <= 0)
  1053.                 {
  1054.                         PrintMessage("Finished camera movement");
  1055.                         fStartTime = GetCurTimeSec();
  1056.                         PrintMessage("Waiting for %d textures to stream in ...", arrTestTextures.Count());
  1057.  
  1058.                         GetCVars()->e_SQTestBegin = 7;
  1059.                         pLastNotReadyTexture = 0;
  1060.                 }
  1061.         }
  1062.         else if (GetCVars()->e_SQTestBegin == 7)
  1063.         {
  1064.                 // Wait until test all needed textures are loaded again
  1065.  
  1066.                 STextureStreamingStats statsTex(true);
  1067.                 m_pRenderer->EF_Query(EFQ_GetTexStreamingInfo, statsTex);
  1068.                 nMaxTexUsage = max(nMaxTexUsage, statsTex.nRequiredStreamedTexturesSize);
  1069.  
  1070.                 if (pTestTexture)
  1071.                 {
  1072.                         if (pTestTexture->GetMinLoadedMip() <= GetCVars()->e_SQTestMip)
  1073.                         {
  1074.                                 PrintMessage("BINGO: Selected test texture loaded in %.1f sec", GetCurTimeSec() - fStartTime);
  1075.                                 pTestTexture = NULL;
  1076.                                 if (!arrTestTextures.Count())
  1077.                                 {
  1078.                                         GetCVars()->e_SQTestBegin = 0;
  1079.                                         GetConsole()->GetCVar("e_SQTestBegin")->Set(0);
  1080.                                 }
  1081.                         }
  1082.                 }
  1083.  
  1084.                 if (arrTestTextures.Count())
  1085.                 {
  1086.                         int nFinishedNum = 0;
  1087.                         for (int i = 0; i < arrTestTextures.Count(); i++)
  1088.                         {
  1089.                                 if (arrTestTextures[i]->GetMinLoadedMip() <= GetCVars()->e_SQTestMip)
  1090.                                         nFinishedNum++;
  1091.                                 else
  1092.                                         pLastNotReadyTexture = arrTestTextures[i];
  1093.                         }
  1094.  
  1095.                         if (nFinishedNum == arrTestTextures.Count())
  1096.                         {
  1097.                                 PrintMessage("BINGO: %d of %d test texture loaded in %.1f sec", nFinishedNum, arrTestTextures.Count(), GetCurTimeSec() - fStartTime);
  1098.                                 if (pLastNotReadyTexture)
  1099.                                         PrintMessage("LastNotReadyTexture: %s [%d x %d]", pLastNotReadyTexture->GetName(), pLastNotReadyTexture->GetWidth(), pLastNotReadyTexture->GetHeight());
  1100.                                 PrintMessage("MaxTexUsage: %" PRISIZE_T " MB", nMaxTexUsage / 1024 / 1024);
  1101.                                 arrTestTextures.Clear();
  1102.  
  1103.                                 GetCVars()->e_SQTestBegin = 0;
  1104.                                 GetConsole()->GetCVar("e_SQTestBegin")->Set(0);
  1105.  
  1106.                                 m_arrProcessStreamingLatencyTestResults.Add(GetCurTimeSec() - fStartTime);
  1107.                                 m_arrProcessStreamingLatencyTexNum.Add(nFinishedNum);
  1108.  
  1109.                                 if (GetCVars()->e_SQTestCount == 0)
  1110.                                 {
  1111.                                         const char* szTestResults = "%USER%/TestResults";
  1112.                                         char path[ICryPak::g_nMaxPath] = "";
  1113.                                         gEnv->pCryPak->AdjustFileName(string(string(szTestResults) + "\\" + "Streaming_Latency_Test.xml").c_str(), path, ICryPak::FLAGS_PATH_REAL | ICryPak::FLAGS_FOR_WRITING);
  1114.                                         gEnv->pCryPak->MakeDir(szTestResults);
  1115.  
  1116.                                         if (FILE* f = ::fopen(path, "wb"))
  1117.                                         {
  1118.                                                 float fAverTime = 0;
  1119.                                                 for (int i = 0; i < m_arrProcessStreamingLatencyTestResults.Count(); i++)
  1120.                                                         fAverTime += m_arrProcessStreamingLatencyTestResults[i];
  1121.                                                 fAverTime /= m_arrProcessStreamingLatencyTestResults.Count();
  1122.  
  1123.                                                 int nAverTexNum = 0;
  1124.                                                 for (int i = 0; i < m_arrProcessStreamingLatencyTexNum.Count(); i++)
  1125.                                                         nAverTexNum += m_arrProcessStreamingLatencyTexNum[i];
  1126.                                                 nAverTexNum /= m_arrProcessStreamingLatencyTexNum.Count();
  1127.  
  1128.                                                 fprintf(f,
  1129.                                                         "<phase name=\"Streaming_Latency_Test\">\n"
  1130.                                                         "<metrics name=\"Streaming\">\n"
  1131.                                                         "<metric name=\"AvrLatency\" value=\"%.1f\"/>\n"
  1132.                                                         "<metric name=\"AvrTexNum\" value=\"%d\"/>\n"
  1133.                                                         "</metrics>\n"
  1134.                                                         "</phase>\n",
  1135.                                                         fAverTime,
  1136.                                                         nAverTexNum);
  1137.  
  1138.                                                 ::fclose(f);
  1139.                                         }
  1140.  
  1141.                                         if (GetCVars()->e_SQTestExitOnFinish)
  1142.                                                 GetSystem()->Quit();
  1143.                                 }
  1144.                         }
  1145.                         else if ((passInfo.GetMainFrameID() & 31) == 0)
  1146.                         {
  1147.                                 PrintMessage("Waiting: %d of %d test texture loaded in %.1f sec", nFinishedNum, arrTestTextures.Count(), GetCurTimeSec() - fStartTime);
  1148.                         }
  1149.                 }
  1150.         }
  1151. }
  1152. #endif
  1153.  
  1154. //////////////////////////////////////////////////////////////////////
  1155. void C3DEngine::UpdateRenderingCamera(const char* szCallerName, const SRenderingPassInfo& passInfo)
  1156. {
  1157.         CCamera newCam = passInfo.GetCamera();
  1158.  
  1159. #if defined(FEATURE_SVO_GI)
  1160.         if (passInfo.IsGeneralPass())
  1161.                 CSvoManager::Update(passInfo, newCam);
  1162. #endif
  1163.  
  1164.         if (GetFloatCVar(e_CameraRotationSpeed))
  1165.         {
  1166.                 Matrix34 mat = passInfo.GetCamera().GetMatrix();
  1167.                 Matrix33 matRot;
  1168.                 matRot.SetRotationZ(-GetCurTimeSec() * GetFloatCVar(e_CameraRotationSpeed));
  1169.                 newCam.SetMatrix(mat * matRot);
  1170.         }
  1171.  
  1172. #if !defined(_RELEASE)
  1173.  
  1174.         {
  1175.                 //this feature move the camera along with the player to a certain position and sets the angle accordingly
  1176.                 //      (does not work via goto)
  1177.                 //u can switch it off again via e_CameraGoto 0
  1178.                 const char* const pCamGoto = GetCVars()->e_CameraGoto->GetString();
  1179.                 assert(pCamGoto);
  1180.                 if (strlen(pCamGoto) > 1)
  1181.                 {
  1182.                         Ang3 aAngDeg;
  1183.                         Vec3 vPos;
  1184.                         int args = sscanf(pCamGoto, "%f %f %f %f %f %f", &vPos.x, &vPos.y, &vPos.z, &aAngDeg.x, &aAngDeg.y, &aAngDeg.z);
  1185.                         if (args >= 3)
  1186.                         {
  1187.                                 Vec3 curPos = newCam.GetPosition();
  1188.                                 if (fabs(vPos.x - curPos.x) > 10.f || fabs(vPos.y - curPos.y) > 10.f || fabs(vPos.z - curPos.z) > 10.f)
  1189.                                 {
  1190.                                         char buf[128];
  1191.                                         cry_sprintf(buf, "goto %f %f %f", vPos.x, vPos.y, vPos.z);
  1192.                                         gEnv->pConsole->ExecuteString(buf);
  1193.                                 }
  1194.                                 if (args >= 6)
  1195.                                 {
  1196.                                         Matrix34 mat = passInfo.GetCamera().GetMatrix();
  1197.                                         mat.SetTranslation(vPos);
  1198.                                         mat.SetRotation33(Matrix33::CreateRotationXYZ(DEG2RAD(aAngDeg)));
  1199.                                         newCam.SetMatrix(mat);
  1200.                                 }
  1201.                         }
  1202.                 }
  1203.         }
  1204.  
  1205.         // Streaming latency test
  1206.         if (GetCVars()->e_SQTestCount && !GetCVars()->e_SQTestBegin)
  1207.         {
  1208.                 GetConsole()->GetCVar("e_SQTestBegin")->Set(1);
  1209.                 GetConsole()->GetCVar("e_SQTestCount")->Set(GetCVars()->e_SQTestCount - 1);
  1210.         }
  1211.         if (GetCVars()->e_SQTestBegin)
  1212.                 ProcessStreamingLatencyTest(passInfo.GetCamera(), newCam, passInfo);
  1213.  
  1214. #endif
  1215.  
  1216.         // set the camera if e_cameraFreeze is not set
  1217.         if (GetCVars()->e_CameraFreeze || GetCVars()->e_CoverageBufferDebugFreeze)
  1218.         {
  1219.                 DrawSphere(GetRenderingCamera().GetPosition(), .05f);
  1220.  
  1221.                 // alwasy set camera to request postion for the renderer, allows debugging with e_camerafreeze
  1222.                 if (GetRenderer())
  1223.                 {
  1224.                         const CCamera& currentCamera = gEnv->pSystem->GetViewCamera();
  1225.                         static CCamera previousCamera = gEnv->pSystem->GetViewCamera();
  1226.  
  1227.                         GetRenderer()->SetCamera(currentCamera);
  1228.  
  1229.                         if (auto pRenderView = passInfo.GetIRenderView())
  1230.                         {
  1231.                                 pRenderView->SetCameras(&currentCamera, 1);
  1232.                                 pRenderView->SetPreviousFrameCameras(&previousCamera, 1);
  1233.                         }
  1234.  
  1235.                         previousCamera = currentCamera;
  1236.                 }
  1237.         }
  1238.         else
  1239.         {
  1240.                 CCamera previousCam = m_RenderingCamera;
  1241.                 m_RenderingCamera = newCam;
  1242.  
  1243.                 // alwasy set camera to request postion for the renderer, allows debugging with e_camerafreeze
  1244.                 if (GetRenderer())
  1245.                 {
  1246.                         GetRenderer()->SetCamera(newCam);
  1247.  
  1248.                         if (auto pRenderView = passInfo.GetIRenderView())
  1249.                         {
  1250.                                 pRenderView->SetCameras(&newCam, 1);
  1251.                                 pRenderView->SetPreviousFrameCameras(&previousCam, 1);
  1252.                         }
  1253.  
  1254.                 }
  1255.         }
  1256.  
  1257.         // update zoom state to be queried by client code
  1258.         m_fZoomFactor = passInfo.GetZoomFactor();
  1259.         m_bZoomInProgress = passInfo.IsZoomInProgress();
  1260.  
  1261.         // now we have a valid camera, we can start generation of the occlusion buffer
  1262.         // only needed for editor here, ingame we spawn the job more early
  1263.         if (passInfo.IsGeneralPass() && GetCVars()->e_StatObjBufferRenderTasks && JobManager::InvokeAsJob("CheckOcclusion"))
  1264.         {
  1265.                 if (gEnv->IsEditor())
  1266.                         GetObjManager()->PrepareCullbufferAsync(passInfo.GetCamera());
  1267.                 else
  1268.                         assert(IsEquivalent(passInfo.GetCamera().GetViewdir(), GetObjManager()->m_CullThread.GetViewDir())); // early set camera differs from current main camera - will cause occlusion errors
  1269.         }
  1270.  
  1271.         /////////////////////////////////////////////////////////////////////////////
  1272.         // Update Foliage
  1273.         float dt = GetTimer()->GetFrameTime();
  1274.         CStatObjFoliage* pFoliage, * pFoliageNext;
  1275.         for (pFoliage = m_pFirstFoliage; &pFoliage->m_next != &m_pFirstFoliage; pFoliage = pFoliageNext)
  1276.         {
  1277.                 pFoliageNext = pFoliage->m_next;
  1278.                 pFoliage->Update(dt, GetRenderingCamera());
  1279.         }
  1280.         for (int i = m_arrEntsInFoliage.size() - 1; i >= 0; i--)
  1281.                 if ((m_arrEntsInFoliage[i].timeIdle += dt) > 0.3f)
  1282.                         RemoveEntInFoliage(i);
  1283.  
  1284.         /////////////////////////////////////////////////////////////////////////////
  1285.         // update streaming priority of newly seen CRenderProxies (fix for streaming system issue)
  1286.         for (int i = 0, nSize = m_deferredRenderProxyStreamingPriorityUpdates.size(); i < nSize; ++i)
  1287.         {
  1288.                 IRenderNode* pRenderNode = m_deferredRenderProxyStreamingPriorityUpdates[i];
  1289.                 AABB aabb = pRenderNode->GetBBox();
  1290.                 const Vec3& vCamPos = GetRenderingCamera().GetPosition();
  1291.                 float fEntDistance = sqrt_tpl(Distance::Point_AABBSq(vCamPos, aabb)) * passInfo.GetZoomFactor();
  1292.  
  1293.                 GetObjManager()->UpdateRenderNodeStreamingPriority(pRenderNode, fEntDistance, 1.0f, false, passInfo);
  1294.                 if (GetCVars()->e_StreamCgfDebug == 2)
  1295.                         PrintMessage("C3DEngine::RegisterEntity__GetObjManager()->UpdateRenderNodeStreamingPriority %s", pRenderNode->GetName());
  1296.         }
  1297.         m_deferredRenderProxyStreamingPriorityUpdates.resize(0);
  1298. }
  1299.  
  1300. void C3DEngine::PrepareOcclusion(const CCamera& rCamera)
  1301. {
  1302.         const bool bInEditor = gEnv->IsEditor();
  1303.         const bool bStatObjBufferRenderTasks = GetCVars()->e_StatObjBufferRenderTasks != 0;
  1304.         const bool bIsFMVPlaying = gEnv->IsFMVPlaying();
  1305.         const bool bCameraAtZero = IsEquivalent(rCamera.GetPosition(), Vec3(0, 0, 0), VEC_EPSILON);
  1306.         const bool bPost3dEnabled = GetRenderer() && GetRenderer()->IsPost3DRendererEnabled();
  1307.         if (!bInEditor && bStatObjBufferRenderTasks && !bIsFMVPlaying && (!bCameraAtZero || bPost3dEnabled))
  1308.                 GetObjManager()->PrepareCullbufferAsync(rCamera);
  1309. }
  1310.  
  1311. void C3DEngine::EndOcclusion()
  1312. {
  1313.         GetObjManager()->EndOcclusionCulling();
  1314. }
  1315.  
  1316. #if CRY_PLATFORM_WINDOWS && CRY_PLATFORM_64BIT
  1317.         #pragma warning( pop )                //AMD Port
  1318. #endif
  1319.  
  1320. IStatObj* C3DEngine::LoadStatObj(const char* szFileName, const char* szGeomName, IStatObj::SSubObject** ppSubObject, bool bUseStreaming, unsigned long nLoadingFlags)
  1321. {
  1322.         if (!szFileName || !szFileName[0])
  1323.         {
  1324.                 m_pSystem->Warning(VALIDATOR_MODULE_3DENGINE, VALIDATOR_ERROR, 0, 0, "I3DEngine::LoadStatObj: filename is not specified");
  1325.                 return 0;
  1326.         }
  1327.  
  1328.         if (!m_pObjManager)
  1329.                 m_pObjManager = CryAlignedNew<CObjManager>();
  1330.  
  1331.         return m_pObjManager->LoadStatObj(szFileName, szGeomName, ppSubObject, bUseStreaming, nLoadingFlags);
  1332. }
  1333.  
  1334. IStatObj* C3DEngine::FindStatObjectByFilename(const char* filename)
  1335. {
  1336.         if (filename == NULL)
  1337.                 return NULL;
  1338.  
  1339.         if (filename[0] == 0)
  1340.                 return NULL;
  1341.  
  1342.         return m_pObjManager->FindStaticObjectByFilename(filename);
  1343. }
  1344.  
  1345. void C3DEngine::RegisterEntity(IRenderNode* pEnt, int nSID, int nSIDConsideredSafe)
  1346. {
  1347.         FUNCTION_PROFILER_3DENGINE;
  1348.         uint32 nFrameID = gEnv->nMainFrameID;
  1349.         AsyncOctreeUpdate(pEnt, nSID, nSIDConsideredSafe, nFrameID, false);
  1350. }
  1351.  
  1352. void C3DEngine::UnRegisterEntityDirect(IRenderNode* pEnt)
  1353. {
  1354.         UnRegisterEntityImpl(pEnt);
  1355. }
  1356.  
  1357. void C3DEngine::UnRegisterEntityAsJob(IRenderNode* pEnt)
  1358. {
  1359.         AsyncOctreeUpdate(pEnt, (int)0, (int)0, (int)0, true);
  1360. }
  1361.  
  1362. bool C3DEngine::CreateDecalInstance(const CryEngineDecalInfo& decal, CDecal* pCallerManagedDecal)
  1363. {
  1364.         if (!GetCVars()->e_Decals && !pCallerManagedDecal)
  1365.                 return false;
  1366.  
  1367.         return m_pDecalManager->Spawn(decal, pCallerManagedDecal);
  1368. }
  1369.  
  1370. void C3DEngine::SelectEntity(IRenderNode* pEntity)
  1371. {
  1372.         static IRenderNode* pSelectedNode;
  1373.         static float fLastTime;
  1374.         if (pEntity && GetCVars()->e_Decals == 3)
  1375.         {
  1376.                 float fCurTime = gEnv->pTimer->GetAsyncCurTime();
  1377.                 if (fCurTime - fLastTime < 1.0f)
  1378.                         return;
  1379.                 fLastTime = fCurTime;
  1380.                 if (pSelectedNode)
  1381.                         pSelectedNode->SetRndFlags(ERF_SELECTED, false);
  1382.                 pEntity->SetRndFlags(ERF_SELECTED, true);
  1383.                 pSelectedNode = pEntity;
  1384.         }
  1385. }
  1386.  
  1387. void C3DEngine::CreateDecal(const struct CryEngineDecalInfo& decal)
  1388. {
  1389.         IF (!GetCVars()->e_DecalsAllowGameDecals, 0)
  1390.                 return;
  1391.  
  1392.         if (GetCVars()->e_Decals == 2)
  1393.         {
  1394.                 IRenderNode* pRN = decal.ownerInfo.pRenderNode;
  1395.                 PrintMessage("Debug: C3DEngine::CreateDecal: Pos=(%.1f,%.1f,%.1f) Size=%.2f DecalMaterial=%s HitObjectName=%s(%s)",
  1396.                              decal.vPos.x, decal.vPos.y, decal.vPos.z, decal.fSize, decal.szMaterialName,
  1397.                              pRN ? pRN->GetName() : "NULL", pRN ? pRN->GetEntityClassName() : "NULL");
  1398.         }
  1399.  
  1400.         assert(!decal.pExplicitRightUpFront); // only game-play decals come here
  1401.  
  1402.         static uint32 nGroupId = 0;
  1403.         nGroupId++;
  1404.  
  1405.         if ((GetCVars()->e_DecalsDeferredStatic == 1 && decal.pExplicitRightUpFront) ||
  1406.             (GetCVars()->e_DecalsDeferredDynamic == 1 && !decal.pExplicitRightUpFront &&
  1407.              (!decal.ownerInfo.pRenderNode || decal.ownerInfo.pRenderNode->GetRenderNodeType() == eERType_Brush || decal.fGrowTimeAlpha || decal.fSize > GetFloatCVar(e_DecalsDeferredDynamicMinSize)))
  1408.             && !decal.bForceSingleOwner)
  1409.         {
  1410.                 CryEngineDecalInfo decal_adjusted = decal;
  1411.                 decal_adjusted.nGroupId = nGroupId;
  1412.                 decal_adjusted.bDeferred = true;
  1413.                 m_pDecalManager->SpawnHierarchical(decal_adjusted, NULL);
  1414.                 return;
  1415.         }
  1416.  
  1417.         if (decal.ownerInfo.pRenderNode && decal.fSize > 0.5f && !decal.bForceSingleOwner)
  1418.         {
  1419.                 PodArray<SRNInfo> lstEntities;
  1420.                 Vec3 vRadius(decal.fSize, decal.fSize, decal.fSize);
  1421.                 const AABB cExplosionBox(decal.vPos - vRadius, decal.vPos + vRadius);
  1422.  
  1423.                 if (CVisArea* pArea = (CVisArea*)decal.ownerInfo.pRenderNode->GetEntityVisArea())
  1424.                 {
  1425.                         if (pArea->m_pObjectsTree)
  1426.                                 pArea->m_pObjectsTree->MoveObjectsIntoList(&lstEntities, &cExplosionBox, false, true, true, true);
  1427.                 }
  1428.                 else
  1429.                         Get3DEngine()->MoveObjectsIntoListGlobal(&lstEntities, &cExplosionBox, false, true, true, true);
  1430.  
  1431.                 for (int i = 0; i < lstEntities.Count(); i++)
  1432.                 {
  1433.                         // decals on statobj's of render node
  1434.                         CryEngineDecalInfo decalOnRenderNode = decal;
  1435.                         decalOnRenderNode.ownerInfo.pRenderNode = lstEntities[i].pNode;
  1436.                         decalOnRenderNode.nGroupId = nGroupId;
  1437.  
  1438.                         //      if(decalOnRenderNode.ownerInfo.pRenderNode->GetRenderNodeType() != decal.ownerInfo.pRenderNode->GetRenderNodeType())
  1439.                         //      continue;
  1440.  
  1441.                         if (decalOnRenderNode.ownerInfo.pRenderNode->GetRndFlags() & ERF_HIDDEN)
  1442.                                 continue;
  1443.  
  1444.                         m_pDecalManager->SpawnHierarchical(decalOnRenderNode, NULL);
  1445.                 }
  1446.         }
  1447.         else
  1448.         {
  1449.                 CryEngineDecalInfo decalStatic = decal;
  1450.                 decalStatic.nGroupId = nGroupId;
  1451.                 m_pDecalManager->SpawnHierarchical(decalStatic, NULL);
  1452.         }
  1453. }
  1454.  
  1455. /*
  1456.    float C3DEngine::GetDayTime(float fPrevDayTime)
  1457.    {
  1458.    if(fPrevDayTime)
  1459.    {
  1460.     float fDayTimeDiff = (GetCVars()->e_day_time - fPrevDayTime);
  1461.     while(fDayTimeDiff>12)
  1462.       fDayTimeDiff-=12;
  1463.     while(fDayTimeDiff<-12)
  1464.       fDayTimeDiff+=12;
  1465.     fDayTimeDiff = (float)fabs(fDayTimeDiff);
  1466.     return fDayTimeDiff;
  1467.    }
  1468.  
  1469.    return GetCVars()->e_day_time;
  1470.    } */
  1471.  
  1472. namespace
  1473. {
  1474. inline const float GetSunSkyRel(const Vec3& crSkyColor, const Vec3& crSunColor)
  1475. {
  1476.         const float cSunMax = max(0.1f, max(crSunColor.x, max(crSunColor.y, crSunColor.z)));
  1477.         const float cSkyMax = max(0.1f, max(crSkyColor.x, max(crSkyColor.y, crSkyColor.z)));
  1478.         return cSunMax / (cSkyMax + cSunMax);
  1479. }
  1480. }
  1481.  
  1482. //////////////////////////////////////////////////////////////////////////
  1483. void C3DEngine::SetSkyColor(Vec3 vColor)
  1484. {
  1485.         if (m_pObjManager)
  1486.         {
  1487.                 m_pObjManager->m_vSkyColor = vColor;
  1488.                 m_pObjManager->m_fSunSkyRel = GetSunSkyRel(m_pObjManager->m_vSkyColor, m_pObjManager->m_vSunColor);
  1489.         }
  1490. }
  1491.  
  1492. //////////////////////////////////////////////////////////////////////////
  1493. void C3DEngine::SetSunColor(Vec3 vColor)
  1494. {
  1495.         if (m_pObjManager)
  1496.         {
  1497.                 m_pObjManager->m_vSunColor = vColor;
  1498.                 m_pObjManager->m_fSunSkyRel = GetSunSkyRel(m_pObjManager->m_vSkyColor, m_pObjManager->m_vSunColor);
  1499.         }
  1500. }
  1501.  
  1502. void C3DEngine::SetSkyBrightness(float fMul)
  1503. {
  1504.         if (m_pObjManager)
  1505.                 m_pObjManager->m_fSkyBrightMul = fMul;
  1506. }
  1507.  
  1508. void C3DEngine::SetSSAOAmount(float fMul)
  1509. {
  1510.         if (m_pObjManager)
  1511.                 m_pObjManager->m_fSSAOAmount = fMul;
  1512. }
  1513.  
  1514. void C3DEngine::SetSSAOContrast(float fMul)
  1515. {
  1516.         if (m_pObjManager)
  1517.                 m_pObjManager->m_fSSAOContrast = fMul;
  1518. }
  1519.  
  1520. void C3DEngine::SetGIAmount(float fMul)
  1521. {
  1522.         if (m_pObjManager)
  1523.                 m_pObjManager->m_fGIAmount = fMul;
  1524. }
  1525.  
  1526. float C3DEngine::GetTerrainElevation(float x, float y, int nSID)
  1527. {
  1528.         float fZ = 0;
  1529.  
  1530.         if (m_pTerrain)
  1531.                 fZ = m_pTerrain->GetZApr(x, y, nSID);
  1532.  
  1533.         return fZ;
  1534. }
  1535.  
  1536. float C3DEngine::GetTerrainElevation3D(Vec3 vPos)
  1537. {
  1538.         float fZ = 0;
  1539.  
  1540.         if (m_pTerrain)
  1541.                 fZ = m_pTerrain->GetZApr(vPos.x, vPos.y, GetDefSID());
  1542.  
  1543.         return fZ;
  1544. }
  1545.  
  1546. float C3DEngine::GetTerrainZ(int x, int y)
  1547. {
  1548.         if (x < 0 || y < 0 || x >= CTerrain::GetTerrainSize() || y >= CTerrain::GetTerrainSize())
  1549.                 return TERRAIN_BOTTOM_LEVEL;
  1550.         return m_pTerrain ? m_pTerrain->GetZ(x, y, GetDefSID()) : 0;
  1551. }
  1552.  
  1553. bool C3DEngine::GetTerrainHole(int x, int y)
  1554. {
  1555.         return m_pTerrain ? m_pTerrain->GetHole(x, y, GetDefSID()) : false;
  1556. }
  1557.  
  1558. int C3DEngine::GetHeightMapUnitSize()
  1559. {
  1560.         return CTerrain::GetHeightMapUnitSize();
  1561. }
  1562.  
  1563. void C3DEngine::RemoveAllStaticObjects(int nSID)
  1564. {
  1565.         if (m_pTerrain)
  1566.                 m_pTerrain->RemoveAllStaticObjects(nSID);
  1567. }
  1568.  
  1569. void C3DEngine::SetTerrainSurfaceType(int x, int y, int nType)
  1570. {
  1571.         assert(0);
  1572. }
  1573.  
  1574. void C3DEngine::SetTerrainSectorTexture(const int nTexSectorX, const int nTexSectorY, unsigned int textureId)
  1575. {
  1576.         if (m_pTerrain)
  1577.         {
  1578.                 bool bMergeNotAllowed = m_pSegmentsManager ? false : true;
  1579.                 m_pTerrain->SetTerrainSectorTexture(nTexSectorX, nTexSectorY, textureId, bMergeNotAllowed, GetDefSID());
  1580.         }
  1581. }
  1582.  
  1583. void C3DEngine::OnExplosion(Vec3 vPos, float fRadius, bool bDeformTerrain)
  1584. {
  1585.         if (GetCVars()->e_Decals == 2)
  1586.                 PrintMessage("Debug: C3DEngine::OnExplosion: Pos=(%.1f,%.1f,%.1f) fRadius=%.2f", vPos.x, vPos.y, vPos.z, fRadius);
  1587.  
  1588.         if (vPos.x < 0 || vPos.x >= CTerrain::GetTerrainSize() || vPos.y < 0 || vPos.y >= CTerrain::GetTerrainSize() || fRadius <= 0)
  1589.                 return; // out of terrain
  1590.  
  1591.         // do not create decals near the terrain holes
  1592.         {
  1593.                 for (int x = int(vPos.x - fRadius); x <= int(vPos.x + fRadius) + 1; x += CTerrain::GetHeightMapUnitSize())
  1594.                         for (int y = int(vPos.y - fRadius); y <= int(vPos.y + fRadius) + 1; y += CTerrain::GetHeightMapUnitSize())
  1595.                                 if (m_pTerrain->GetHole(x, y, GetDefSID()))
  1596.                                         return;
  1597.         }
  1598.  
  1599.         // try to remove objects around
  1600.         bool bGroundDeformationAllowed = m_pTerrain->RemoveObjectsInArea(vPos, fRadius) && bDeformTerrain && GetCVars()->e_TerrainDeformations;
  1601.  
  1602.         // reduce ground decals size depending on distance to the ground
  1603.         float fExploHeight = vPos.z - m_pTerrain->GetZApr(vPos.x, vPos.y, GetDefSID());
  1604.  
  1605.         if (bGroundDeformationAllowed && (fExploHeight > -0.1f) && fExploHeight < fRadius && fRadius > 0.125f)
  1606.         {
  1607.                 m_pTerrain->MakeCrater(vPos, fRadius);
  1608.  
  1609.                 // update roads
  1610.                 {
  1611.                         PodArray<IRenderNode*> lstRoads;
  1612.                         AABB bbox(vPos - Vec3(fRadius, fRadius, fRadius), vPos + Vec3(fRadius, fRadius, fRadius));
  1613.                         Get3DEngine()->GetObjectsByTypeGlobal(lstRoads, eERType_Road, &bbox);
  1614.                         for (int i = 0; i < lstRoads.Count(); i++)
  1615.                         {
  1616.                                 CRoadRenderNode* pRoad = (CRoadRenderNode*)lstRoads[i];
  1617.                                 pRoad->OnTerrainChanged();
  1618.                         }
  1619.                 }
  1620.         }
  1621.  
  1622.         // delete decals what can not be correctly updated
  1623.         Vec3 vRadius(fRadius, fRadius, fRadius);
  1624.         AABB areaBox(vPos - vRadius, vPos + vRadius);
  1625.         Get3DEngine()->DeleteDecalsInRange(&areaBox, NULL);
  1626. }
  1627.  
  1628. float C3DEngine::GetMaxViewDistance(bool bScaled)
  1629. {
  1630.         // spec lerp factor
  1631.         float lerpSpec = clamp_tpl(GetCVars()->e_MaxViewDistSpecLerp, 0.0f, 1.0f);
  1632.  
  1633.         // camera height lerp factor
  1634.         float lerpHeight = clamp_tpl(max(0.f, GetSystem()->GetViewCamera().GetPosition().z - GetWaterLevel()) / GetFloatCVar(e_MaxViewDistFullDistCamHeight), 0.0f, 1.0f);
  1635.  
  1636.         // lerp between specs
  1637.         float fMaxViewDist = m_fMaxViewDistLowSpec * (1.f - lerpSpec) + m_fMaxViewDistHighSpec * lerpSpec;
  1638.  
  1639.         // lerp between prev result and high spec
  1640.         fMaxViewDist = fMaxViewDist * (1.f - lerpHeight) + m_fMaxViewDistHighSpec * lerpHeight;
  1641.  
  1642.         if (bScaled)
  1643.                 fMaxViewDist *= m_fMaxViewDistScale;
  1644.  
  1645.         // for debugging
  1646.         const float fMaxViewDistCVar = GetFloatCVar(e_MaxViewDistance);
  1647.         fMaxViewDist = (float)__fsel(fMaxViewDistCVar, fMaxViewDistCVar, fMaxViewDist);
  1648.  
  1649.         fMaxViewDist = (float)__fsel(fabsf(fMaxViewDist) - 0.100001f, fMaxViewDist, 0.100001f);
  1650.  
  1651.         return fMaxViewDist;
  1652. }
  1653.  
  1654. void C3DEngine::SetFrameLodInfo(const SFrameLodInfo& frameLodInfo)
  1655. {
  1656.         if (frameLodInfo.fLodRatio != m_frameLodInfo.fLodRatio || frameLodInfo.fTargetSize != m_frameLodInfo.fTargetSize)
  1657.         {
  1658.                 ++m_frameLodInfo.nID;
  1659.                 m_frameLodInfo.fLodRatio = frameLodInfo.fLodRatio;
  1660.                 m_frameLodInfo.fTargetSize = frameLodInfo.fTargetSize;
  1661.         }
  1662.         m_frameLodInfo.nMinLod = frameLodInfo.nMinLod;
  1663.         m_frameLodInfo.nMaxLod = frameLodInfo.nMaxLod;
  1664. }
  1665.  
  1666. void C3DEngine::SetFogColor(const Vec3& vFogColor)
  1667. {
  1668.         m_vFogColor = vFogColor;
  1669.         if (GetRenderer())
  1670.         {
  1671.                 GetRenderer()->SetClearColor(m_vFogColor);
  1672.         }
  1673. }
  1674.  
  1675. Vec3 C3DEngine::GetFogColor()
  1676. {
  1677.         return m_vFogColor;
  1678. }
  1679.  
  1680. void C3DEngine::GetSkyLightParameters(Vec3& sunDir, Vec3& sunIntensity, float& Km, float& Kr, float& g, Vec3& rgbWaveLengths)
  1681. {
  1682.         CSkyLightManager::SSkyDomeCondition skyCond;
  1683.         m_pSkyLightManager->GetCurSkyDomeCondition(skyCond);
  1684.  
  1685.         g = skyCond.m_g;
  1686.         Km = skyCond.m_Km;
  1687.         Kr = skyCond.m_Kr;
  1688.         sunIntensity = skyCond.m_sunIntensity;
  1689.         rgbWaveLengths = skyCond.m_rgbWaveLengths;
  1690.         sunDir = skyCond.m_sunDirection;
  1691. }
  1692.  
  1693. void C3DEngine::SetSkyLightParameters(const Vec3& sunDir, const Vec3& sunIntensity, float Km, float Kr, float g, const Vec3& rgbWaveLengths, bool forceImmediateUpdate)
  1694. {
  1695.         CSkyLightManager::SSkyDomeCondition skyCond;
  1696.  
  1697.         skyCond.m_g = g;
  1698.         skyCond.m_Km = Km;
  1699.         skyCond.m_Kr = Kr;
  1700.         skyCond.m_sunIntensity = sunIntensity;
  1701.         skyCond.m_rgbWaveLengths = rgbWaveLengths;
  1702.         skyCond.m_sunDirection = sunDir;
  1703.  
  1704.         m_pSkyLightManager->SetSkyDomeCondition(skyCond);
  1705.         if (forceImmediateUpdate && IsHDRSkyMaterial(GetSkyMaterial()))
  1706.                 m_pSkyLightManager->FullUpdate();
  1707. }
  1708.  
  1709. void C3DEngine::SetLightsHDRDynamicPowerFactor(const float value)
  1710. {
  1711.         m_fLightsHDRDynamicPowerFactor = value;
  1712. }
  1713.  
  1714. float C3DEngine::GetLightsHDRDynamicPowerFactor() const
  1715. {
  1716.         return m_fLightsHDRDynamicPowerFactor;
  1717. }
  1718.  
  1719. bool C3DEngine::IsTessellationAllowedForShadowMap(const SRenderingPassInfo& passInfo) const
  1720. {
  1721. #ifdef MESH_TESSELLATION_ENGINE
  1722.         SRenderingPassInfo::EShadowMapType shadowType = passInfo.GetShadowMapType();
  1723.         switch (shadowType)
  1724.         {
  1725.         case SRenderingPassInfo::SHADOW_MAP_GSM:
  1726.                 return passInfo.ShadowFrustumLod() < GetCVars()->e_ShadowsTessellateCascades;
  1727.         case SRenderingPassInfo::SHADOW_MAP_LOCAL:
  1728.                 return GetCVars()->e_ShadowsTessellateDLights != 0;
  1729.         case SRenderingPassInfo::SHADOW_MAP_NONE:
  1730.         default:
  1731.                 return false;
  1732.         }
  1733. #endif //#ifdef MESH_TESSELLATION_ENGINE
  1734.  
  1735.         return false;
  1736. }
  1737.  
  1738. void C3DEngine::SetPhysMaterialEnumerator(IPhysMaterialEnumerator* pPhysMaterialEnumerator)
  1739. {
  1740.         m_pPhysMaterialEnumerator = pPhysMaterialEnumerator;
  1741. }
  1742.  
  1743. IPhysMaterialEnumerator* C3DEngine::GetPhysMaterialEnumerator()
  1744. {
  1745.         return m_pPhysMaterialEnumerator;
  1746. }
  1747.  
  1748. void C3DEngine::ApplyForceToEnvironment(Vec3 vPos, float fRadius, float fAmountOfForce)
  1749. {
  1750.         if (m_pTerrain)
  1751.                 m_pTerrain->ApplyForceToEnvironment(vPos, fRadius, fAmountOfForce);
  1752. }
  1753.  
  1754. float C3DEngine::GetDistanceToSectorWithWater()
  1755. {
  1756.         if (!m_pTerrain || !m_pTerrain->GetParentNode(0))
  1757.                 return 100000.f;
  1758.  
  1759.         Vec3 camPostion = GetRenderingCamera().GetPosition();
  1760.         bool bCameraInTerrainBounds = Overlap::Point_AABB2D(camPostion, m_pTerrain->GetParentNode(0)->GetBBoxVirtual());
  1761.  
  1762.         return (bCameraInTerrainBounds && (m_pTerrain && m_pTerrain->GetDistanceToSectorWithWater() > 0.1f))
  1763.                ? m_pTerrain->GetDistanceToSectorWithWater() : max(camPostion.z - GetWaterLevel(), 0.1f);
  1764. }
  1765.  
  1766. Vec3 C3DEngine::GetSunColor() const
  1767. {
  1768.         return m_pObjManager ? m_pObjManager->m_vSunColor : Vec3(0, 0, 0);
  1769. }
  1770.  
  1771. float C3DEngine::GetSkyBrightness() const
  1772. {
  1773.         return m_pObjManager ? m_pObjManager->m_fSkyBrightMul : 1.0f;
  1774. }
  1775.  
  1776. float C3DEngine::GetSSAOAmount() const
  1777. {
  1778.         return m_pObjManager ? m_pObjManager->m_fSSAOAmount : 1.0f;
  1779. }
  1780.  
  1781. float C3DEngine::GetSSAOContrast() const
  1782. {
  1783.         return m_pObjManager ? m_pObjManager->m_fSSAOContrast : 1.0f;
  1784. }
  1785.  
  1786. float C3DEngine::GetGIAmount() const
  1787. {
  1788.         return m_pObjManager ? m_pObjManager->m_fGIAmount : 1.0f;
  1789. }
  1790.  
  1791. float C3DEngine::GetSunRel() const
  1792. {
  1793.         return m_pObjManager->m_fSunSkyRel;
  1794. }
  1795.  
  1796. void C3DEngine::SetRainParams(const SRainParams& rainParams)
  1797. {
  1798.         if (m_pObjManager)
  1799.         {
  1800.                 m_pObjManager->m_rainParams.bIgnoreVisareas = rainParams.bIgnoreVisareas;
  1801.                 m_pObjManager->m_rainParams.bDisableOcclusion = rainParams.bDisableOcclusion;
  1802.                 m_pObjManager->m_rainParams.qRainRotation = rainParams.qRainRotation;
  1803.                 m_pObjManager->m_rainParams.vWorldPos = rainParams.vWorldPos;
  1804.                 m_pObjManager->m_rainParams.vColor = rainParams.vColor;
  1805.                 m_pObjManager->m_rainParams.fAmount = rainParams.fAmount;
  1806.                 m_pObjManager->m_rainParams.fCurrentAmount = rainParams.fCurrentAmount;
  1807.                 m_pObjManager->m_rainParams.fRadius = rainParams.fRadius;
  1808.                 m_pObjManager->m_rainParams.fFakeGlossiness = rainParams.fFakeGlossiness;
  1809.                 m_pObjManager->m_rainParams.fFakeReflectionAmount = rainParams.fFakeReflectionAmount;
  1810.                 m_pObjManager->m_rainParams.fDiffuseDarkening = rainParams.fDiffuseDarkening;
  1811.                 m_pObjManager->m_rainParams.fRainDropsAmount = rainParams.fRainDropsAmount;
  1812.                 m_pObjManager->m_rainParams.fRainDropsSpeed = rainParams.fRainDropsSpeed;
  1813.                 m_pObjManager->m_rainParams.fRainDropsLighting = rainParams.fRainDropsLighting;
  1814.                 m_pObjManager->m_rainParams.fMistAmount = rainParams.fMistAmount;
  1815.                 m_pObjManager->m_rainParams.fMistHeight = rainParams.fMistHeight;
  1816.                 m_pObjManager->m_rainParams.fPuddlesAmount = rainParams.fPuddlesAmount;
  1817.                 m_pObjManager->m_rainParams.fPuddlesMaskAmount = rainParams.fPuddlesMaskAmount;
  1818.                 m_pObjManager->m_rainParams.fPuddlesRippleAmount = rainParams.fPuddlesRippleAmount;
  1819.                 m_pObjManager->m_rainParams.fSplashesAmount = rainParams.fSplashesAmount;
  1820.  
  1821.                 m_pObjManager->m_rainParams.nUpdateFrameID = gEnv->nMainFrameID;
  1822.         }
  1823. }
  1824.  
  1825. bool C3DEngine::GetRainParams(SRainParams& rainParams)
  1826. {
  1827.         bool bRet = false;
  1828.         const int nFrmID = gEnv->nMainFrameID;
  1829.         if (m_pObjManager)
  1830.         {
  1831.                 // Copy shared rain data only
  1832.                 rainParams.bIgnoreVisareas = m_pObjManager->m_rainParams.bIgnoreVisareas;
  1833.                 rainParams.bDisableOcclusion = m_pObjManager->m_rainParams.bDisableOcclusion;
  1834.                 rainParams.qRainRotation = m_pObjManager->m_rainParams.qRainRotation;
  1835.                 rainParams.vWorldPos = m_pObjManager->m_rainParams.vWorldPos;
  1836.                 rainParams.vColor = m_pObjManager->m_rainParams.vColor;
  1837.                 rainParams.fAmount = m_pObjManager->m_rainParams.fAmount;
  1838.                 rainParams.fCurrentAmount = m_pObjManager->m_rainParams.fCurrentAmount;
  1839.                 rainParams.fRadius = m_pObjManager->m_rainParams.fRadius;
  1840.                 rainParams.fFakeGlossiness = m_pObjManager->m_rainParams.fFakeGlossiness;
  1841.                 rainParams.fFakeReflectionAmount = m_pObjManager->m_rainParams.fFakeReflectionAmount;
  1842.                 rainParams.fDiffuseDarkening = m_pObjManager->m_rainParams.fDiffuseDarkening;
  1843.                 rainParams.fRainDropsAmount = m_pObjManager->m_rainParams.fRainDropsAmount;
  1844.                 rainParams.fRainDropsSpeed = m_pObjManager->m_rainParams.fRainDropsSpeed;
  1845.                 rainParams.fRainDropsLighting = m_pObjManager->m_rainParams.fRainDropsLighting;
  1846.                 rainParams.fMistAmount = m_pObjManager->m_rainParams.fMistAmount;
  1847.                 rainParams.fMistHeight = m_pObjManager->m_rainParams.fMistHeight;
  1848.                 rainParams.fPuddlesAmount = m_pObjManager->m_rainParams.fPuddlesAmount;
  1849.                 rainParams.fPuddlesMaskAmount = m_pObjManager->m_rainParams.fPuddlesMaskAmount;
  1850.                 rainParams.fPuddlesRippleAmount = m_pObjManager->m_rainParams.fPuddlesRippleAmount;
  1851.                 rainParams.fSplashesAmount = m_pObjManager->m_rainParams.fSplashesAmount;
  1852.  
  1853.                 if (!IsOutdoorVisible() && !rainParams.bIgnoreVisareas)
  1854.                 {
  1855.                         rainParams.fAmount = 0.f;
  1856.                 }
  1857.  
  1858.                 bRet = m_pObjManager->m_rainParams.nUpdateFrameID == nFrmID;
  1859.         }
  1860.         return bRet;
  1861. }
  1862.  
  1863. void C3DEngine::SetSnowSurfaceParams(const Vec3& vCenter, float fRadius, float fSnowAmount, float fFrostAmount, float fSurfaceFreezing)
  1864. {
  1865.         if (m_pObjManager)
  1866.         {
  1867.                 m_pObjManager->m_snowParams.m_vWorldPos = vCenter;
  1868.                 m_pObjManager->m_snowParams.m_fRadius = fRadius;
  1869.                 m_pObjManager->m_snowParams.m_fSnowAmount = fSnowAmount;
  1870.                 m_pObjManager->m_snowParams.m_fFrostAmount = fFrostAmount;
  1871.                 m_pObjManager->m_snowParams.m_fSurfaceFreezing = fSurfaceFreezing;
  1872.         }
  1873. }
  1874.  
  1875. bool C3DEngine::GetSnowSurfaceParams(Vec3& vCenter, float& fRadius, float& fSnowAmount, float& fFrostAmount, float& fSurfaceFreezing)
  1876. {
  1877.         bool bRet = false;
  1878.         if (m_pObjManager)
  1879.         {
  1880.                 vCenter = m_pObjManager->m_snowParams.m_vWorldPos;
  1881.                 fRadius = m_pObjManager->m_snowParams.m_fRadius;
  1882.                 fSnowAmount = 0.f;
  1883.                 fFrostAmount = 0.f;
  1884.                 fSurfaceFreezing = 0.f;
  1885.                 if (IsOutdoorVisible())
  1886.                 {
  1887.                         fSnowAmount = m_pObjManager->m_snowParams.m_fSnowAmount;
  1888.                         fFrostAmount = m_pObjManager->m_snowParams.m_fFrostAmount;
  1889.                         fSurfaceFreezing = m_pObjManager->m_snowParams.m_fSurfaceFreezing;
  1890.                 }
  1891.                 bRet = true;
  1892.         }
  1893.         return bRet;
  1894. }
  1895.  
  1896. void C3DEngine::SetSnowFallParams(int nSnowFlakeCount, float fSnowFlakeSize, float fSnowFallBrightness, float fSnowFallGravityScale, float fSnowFallWindScale, float fSnowFallTurbulence, float fSnowFallTurbulenceFreq)
  1897. {
  1898.         if (m_pObjManager)
  1899.         {
  1900.                 m_pObjManager->m_snowParams.m_nSnowFlakeCount = nSnowFlakeCount;
  1901.                 m_pObjManager->m_snowParams.m_fSnowFlakeSize = fSnowFlakeSize;
  1902.                 m_pObjManager->m_snowParams.m_fSnowFallBrightness = fSnowFallBrightness;
  1903.                 m_pObjManager->m_snowParams.m_fSnowFallGravityScale = fSnowFallGravityScale;
  1904.                 m_pObjManager->m_snowParams.m_fSnowFallWindScale = fSnowFallWindScale;
  1905.                 m_pObjManager->m_snowParams.m_fSnowFallTurbulence = fSnowFallTurbulence;
  1906.                 m_pObjManager->m_snowParams.m_fSnowFallTurbulenceFreq = fSnowFallTurbulenceFreq;
  1907.         }
  1908. }
  1909.  
  1910. bool C3DEngine::GetSnowFallParams(int& nSnowFlakeCount, float& fSnowFlakeSize, float& fSnowFallBrightness, float& fSnowFallGravityScale, float& fSnowFallWindScale, float& fSnowFallTurbulence, float& fSnowFallTurbulenceFreq)
  1911. {
  1912.         bool bRet = false;
  1913.         if (m_pObjManager)
  1914.         {
  1915.                 nSnowFlakeCount = 0;
  1916.                 fSnowFlakeSize = 0.f;
  1917.                 fSnowFallBrightness = 0.f;
  1918.                 fSnowFallGravityScale = 0.f;
  1919.                 fSnowFallWindScale = 0.f;
  1920.                 fSnowFallTurbulence = 0.f;
  1921.                 fSnowFallTurbulenceFreq = 0.f;
  1922.                 if (IsOutdoorVisible())
  1923.                 {
  1924.                         nSnowFlakeCount = m_pObjManager->m_snowParams.m_nSnowFlakeCount;
  1925.                         fSnowFlakeSize = m_pObjManager->m_snowParams.m_fSnowFlakeSize;
  1926.                         fSnowFallBrightness = m_pObjManager->m_snowParams.m_fSnowFallBrightness;
  1927.                         fSnowFallGravityScale = m_pObjManager->m_snowParams.m_fSnowFallGravityScale;
  1928.                         fSnowFallWindScale = m_pObjManager->m_snowParams.m_fSnowFallWindScale;
  1929.                         fSnowFallTurbulence = m_pObjManager->m_snowParams.m_fSnowFallTurbulence;
  1930.                         fSnowFallTurbulenceFreq = m_pObjManager->m_snowParams.m_fSnowFallTurbulenceFreq;
  1931.                 }
  1932.                 bRet = true;
  1933.         }
  1934.         return bRet;
  1935. }
  1936.  
  1937. float C3DEngine::GetTerrainTextureMultiplier(int nSID) const
  1938. {
  1939.         if (!m_pTerrain || m_bInUnload)
  1940.                 return 0;
  1941.  
  1942.         return m_pTerrain->GetTerrainTextureMultiplier(nSID);
  1943. }
  1944.  
  1945. void C3DEngine::SetSunDir(const Vec3& newSunDir)
  1946. {
  1947.         Vec3 vSunDirNormalized = newSunDir.normalized();
  1948.         m_vSunDirRealtime = vSunDirNormalized;
  1949.         if (vSunDirNormalized.Dot(m_vSunDirNormalized) < GetFloatCVar(e_SunAngleSnapDot) ||
  1950.             GetCurTimeSec() - m_fSunDirUpdateTime > GetFloatCVar(e_SunAngleSnapSec))
  1951.         {
  1952.                 m_vSunDirNormalized = vSunDirNormalized;
  1953.                 m_vSunDir = m_vSunDirNormalized * DISTANCE_TO_THE_SUN;
  1954.  
  1955.                 m_fSunDirUpdateTime = GetCurTimeSec();
  1956.         }
  1957. }
  1958.  
  1959. Vec3 C3DEngine::GetSunDir()  const
  1960. {
  1961.         return m_vSunDir;
  1962. }
  1963.  
  1964. Vec3 C3DEngine::GetRealtimeSunDirNormalized() const
  1965. {
  1966.         return m_vSunDirRealtime;
  1967. }
  1968.  
  1969. Vec3 C3DEngine::GetAmbientColorFromPosition(const Vec3& vPos, float fRadius)
  1970. {
  1971.         Vec3 ret(0, 0, 0);
  1972.  
  1973.         if (m_pObjManager)
  1974.         {
  1975.                 if (CVisArea* pVisArea = (CVisArea*)m_pVisAreaManager->GetVisAreaFromPos(vPos))
  1976.                         ret = pVisArea->GetFinalAmbientColor();
  1977.                 else
  1978.                         ret = Get3DEngine()->GetSkyColor();
  1979.  
  1980.                 assert(ret.x >= 0 && ret.y >= 0 && ret.z >= 0);
  1981.         }
  1982.  
  1983.         return ret;
  1984. }
  1985.  
  1986. void C3DEngine::FreeRenderNodeState(IRenderNode* pEnt)
  1987. {
  1988.         FUNCTION_PROFILER_3DENGINE;
  1989.  
  1990.         // make sure we don't try to update the streaming priority if an object
  1991.         // was added and removed in the same frame
  1992.         int nElementID = m_deferredRenderProxyStreamingPriorityUpdates.Find(pEnt);
  1993.         if (nElementID != -1)
  1994.                 m_deferredRenderProxyStreamingPriorityUpdates.DeleteFastUnsorted(nElementID);
  1995.  
  1996.         m_pObjManager->RemoveFromRenderAllObjectDebugInfo(pEnt);
  1997.  
  1998. #if !defined(_RELEASE)
  1999.         if (gEnv->pRenderer)
  2000.         {
  2001.                 //As render nodes can be deleted in many places, it's possible that the map of render nodes used by stats gathering (r_stats 6, perfHUD, debug gun, Statoscope) could get aliased.
  2002.                 //Ensure that this node is removed from the map to prevent a dereference after deletion.
  2003.                 gEnv->pRenderer->ForceRemoveNodeFromDrawCallsMap(pEnt);
  2004.         }
  2005. #endif
  2006.  
  2007.         m_lstAlwaysVisible.Delete(pEnt);
  2008.  
  2009.         if (m_pDecalManager && (pEnt->m_nInternalFlags & IRenderNode::DECAL_OWNER))
  2010.                 m_pDecalManager->OnEntityDeleted(pEnt);
  2011.  
  2012.         if (pEnt->GetRenderNodeType() == eERType_Light && GetRenderer())
  2013.                 GetRenderer()->OnEntityDeleted(pEnt);
  2014.  
  2015.         if (pEnt->GetRndFlags() & (ERF_CASTSHADOWMAPS | ERF_HAS_CASTSHADOWMAPS))
  2016.         {
  2017.                 // make sure pointer to object will not be used somewhere in the renderer
  2018. #if !defined(_RELEASE)
  2019.                 if (!(pEnt->GetRndFlags() & ERF_HAS_CASTSHADOWMAPS))
  2020.                         Warning("IRenderNode has ERF_CASTSHADOWMAPS set but not ERF_HAS_CASTSHADOWMAPS, name: '%s', class: '%s'.", pEnt->GetName(), pEnt->GetEntityClassName());
  2021. #endif
  2022.                 Get3DEngine()->OnCasterDeleted(pEnt);
  2023.         }
  2024.  
  2025.         UnRegisterEntityImpl(pEnt);
  2026.  
  2027.         if (pEnt->m_pTempData)
  2028.         {
  2029.                 pEnt->m_pTempData->MarkForDelete();
  2030.                 pEnt->m_pTempData = nullptr;
  2031.         }
  2032. }
  2033.  
  2034. const char* C3DEngine::GetLevelFilePath(const char* szFileName)
  2035. {
  2036.         cry_strcpy(m_sGetLevelFilePathTmpBuff, m_szLevelFolder);
  2037.         if (*szFileName && (*szFileName == '/' || *szFileName == '\\'))
  2038.                 cry_strcat(m_sGetLevelFilePathTmpBuff, szFileName + 1);
  2039.         else
  2040.                 cry_strcat(m_sGetLevelFilePathTmpBuff, szFileName);
  2041.         return m_sGetLevelFilePathTmpBuff;
  2042. }
  2043.  
  2044. void C3DEngine::SetTerrainBurnedOut(int x, int y, bool bBurnedOut)
  2045. {
  2046.         assert(!"not supported");
  2047. }
  2048.  
  2049. bool C3DEngine::IsTerrainBurnedOut(int x, int y)
  2050. {
  2051.         assert(!"not supported");
  2052.         return 0;//m_pTerrain ? m_pTerrain->IsBurnedOut(x, y) : 0;
  2053. }
  2054.  
  2055. int C3DEngine::GetTerrainSectorSize()
  2056. {
  2057.         return m_pTerrain ? m_pTerrain->GetSectorSize() : 0;
  2058. }
  2059.  
  2060. void C3DEngine::ActivatePortal(const Vec3& vPos, bool bActivate, const char* szEntityName)
  2061. {
  2062.         if (m_pVisAreaManager)
  2063.                 m_pVisAreaManager->ActivatePortal(vPos, bActivate, szEntityName);
  2064. }
  2065.  
  2066. bool C3DEngine::SetStatInstGroup(int nGroupId, const IStatInstGroup& siGroup, int nSID)
  2067. {
  2068.         assert(nSID >= 0 && nSID < m_pObjManager->m_lstStaticTypes.Count());
  2069.  
  2070.         m_fRefreshSceneDataCVarsSumm = -100;
  2071.  
  2072.         m_pObjManager->m_lstStaticTypes[nSID].resize(max(nGroupId + 1, m_pObjManager->m_lstStaticTypes[nSID].Count()));
  2073.  
  2074.         if (nGroupId < 0 || nGroupId >= m_pObjManager->m_lstStaticTypes[nSID].Count())
  2075.                 return false;
  2076.  
  2077.         StatInstGroup& rGroup = m_pObjManager->m_lstStaticTypes[nSID][nGroupId];
  2078.  
  2079.         rGroup.pStatObj = siGroup.pStatObj;
  2080.  
  2081.         if (rGroup.pStatObj)
  2082.                 cry_strcpy(rGroup.szFileName, siGroup.pStatObj->GetFilePath());
  2083.         else
  2084.                 rGroup.szFileName[0] = 0;
  2085.  
  2086.         rGroup.bHideability = siGroup.bHideability;
  2087.         rGroup.bHideabilitySecondary = siGroup.bHideabilitySecondary;
  2088.         rGroup.nPlayerHideable = siGroup.nPlayerHideable;
  2089.         rGroup.bPickable = siGroup.bPickable;
  2090.         rGroup.fBending = siGroup.fBending;
  2091.         rGroup.nCastShadowMinSpec = siGroup.nCastShadowMinSpec;
  2092.         rGroup.bDynamicDistanceShadows = siGroup.bDynamicDistanceShadows;
  2093.         rGroup.bGIMode = siGroup.bGIMode;
  2094.         rGroup.fSpriteDistRatio = siGroup.fSpriteDistRatio;
  2095.         rGroup.fLodDistRatio = siGroup.fLodDistRatio;
  2096.         rGroup.fShadowDistRatio = siGroup.fShadowDistRatio;
  2097.         rGroup.fMaxViewDistRatio = siGroup.fMaxViewDistRatio;
  2098.  
  2099.         rGroup.fBrightness = siGroup.fBrightness;
  2100.  
  2101.         _smart_ptr<IMaterial> pMaterial = rGroup.pMaterial;
  2102.         rGroup.pMaterial = siGroup.pMaterial;
  2103.  
  2104.         rGroup.bUseSprites = siGroup.bUseSprites;
  2105.  
  2106.         rGroup.fDensity = siGroup.fDensity;
  2107.         rGroup.fElevationMax = siGroup.fElevationMax;
  2108.         rGroup.fElevationMin = siGroup.fElevationMin;
  2109.         rGroup.fSize = siGroup.fSize;
  2110.         rGroup.fSizeVar = siGroup.fSizeVar;
  2111.         rGroup.fSlopeMax = siGroup.fSlopeMax;
  2112.         rGroup.fSlopeMin = siGroup.fSlopeMin;
  2113.         rGroup.fStiffness = siGroup.fStiffness;
  2114.         rGroup.fDamping = siGroup.fDamping;
  2115.         rGroup.fVariance = siGroup.fVariance;
  2116.         rGroup.fAirResistance = siGroup.fAirResistance;
  2117.  
  2118.         rGroup.bRandomRotation = siGroup.bRandomRotation;
  2119.         rGroup.nRotationRangeToTerrainNormal = siGroup.nRotationRangeToTerrainNormal;
  2120.         rGroup.nMaterialLayers = siGroup.nMaterialLayers;
  2121.  
  2122.         rGroup.bUseTerrainColor = siGroup.bUseTerrainColor && Get3DEngine()->m_bShowTerrainSurface;
  2123.         rGroup.bAllowIndoor = siGroup.bAllowIndoor;
  2124.         rGroup.fAlignToTerrainCoefficient = Get3DEngine()->m_bShowTerrainSurface ? siGroup.fAlignToTerrainCoefficient : 0.f;
  2125.         rGroup.bAutoMerged = siGroup.bAutoMerged;
  2126.         rGroup.minConfigSpec = siGroup.minConfigSpec;
  2127.  
  2128.         rGroup.nID = siGroup.nID;
  2129.  
  2130.         rGroup.Update(GetCVars(), Get3DEngine()->GetGeomDetailScreenRes());
  2131.  
  2132.         if (CTerrain* const pTerrain = GetTerrain())
  2133.         {
  2134.                 pTerrain->MarkAllSectorsAsUncompiled(nSID);
  2135.         }
  2136.  
  2137.         if (gEnv->IsEditor() && pMaterial != rGroup.pMaterial)
  2138.                 m_pMergedMeshesManager->ResetActiveNodes();
  2139.  
  2140.         MarkRNTmpDataPoolForReset();
  2141.  
  2142.         return true;
  2143. }
  2144.  
  2145. bool C3DEngine::GetStatInstGroup(int nGroupId, IStatInstGroup& siGroup, int nSID)
  2146. {
  2147.         assert(nSID >= 0 && nSID < m_pObjManager->m_lstStaticTypes.Count());
  2148.  
  2149.         if (nGroupId < 0 || nGroupId >= m_pObjManager->m_lstStaticTypes[nSID].Count())
  2150.                 return false;
  2151.  
  2152.         StatInstGroup& rGroup = m_pObjManager->m_lstStaticTypes[nSID][nGroupId];
  2153.  
  2154.         siGroup.pStatObj = rGroup.pStatObj;
  2155.         if (siGroup.pStatObj)
  2156.                 cry_strcpy(siGroup.szFileName, rGroup.pStatObj->GetFilePath());
  2157.  
  2158.         siGroup.bHideability = rGroup.bHideability;
  2159.         siGroup.bHideabilitySecondary = rGroup.bHideabilitySecondary;
  2160.         siGroup.nPlayerHideable = rGroup.nPlayerHideable;
  2161.         siGroup.bPickable = rGroup.bPickable;
  2162.         siGroup.fBending = rGroup.fBending;
  2163.         siGroup.nCastShadowMinSpec = rGroup.nCastShadowMinSpec;
  2164.         siGroup.bDynamicDistanceShadows = rGroup.bDynamicDistanceShadows;
  2165.         siGroup.bGIMode = rGroup.bGIMode;
  2166.         siGroup.fSpriteDistRatio = rGroup.fSpriteDistRatio;
  2167.         siGroup.fLodDistRatio = rGroup.fLodDistRatio;
  2168.         siGroup.fShadowDistRatio = rGroup.fShadowDistRatio;
  2169.         siGroup.fMaxViewDistRatio = rGroup.fMaxViewDistRatio;
  2170.  
  2171.         siGroup.fBrightness = rGroup.fBrightness;
  2172.         siGroup.pMaterial = rGroup.pMaterial;
  2173.         siGroup.bUseSprites = rGroup.bUseSprites;
  2174.  
  2175.         siGroup.fDensity = rGroup.fDensity;
  2176.         siGroup.fElevationMax = rGroup.fElevationMax;
  2177.         siGroup.fElevationMin = rGroup.fElevationMin;
  2178.         siGroup.fSize = rGroup.fSize;
  2179.         siGroup.fSizeVar = rGroup.fSizeVar;
  2180.         siGroup.fSlopeMax = rGroup.fSlopeMax;
  2181.         siGroup.fSlopeMin = rGroup.fSlopeMin;
  2182.         siGroup.bAutoMerged = rGroup.bAutoMerged;
  2183.  
  2184.         siGroup.fStiffness = rGroup.fStiffness;
  2185.         siGroup.fDamping = rGroup.fDamping;
  2186.         siGroup.fVariance = rGroup.fVariance;
  2187.         siGroup.fAirResistance = rGroup.fAirResistance;
  2188.  
  2189.         siGroup.nID = rGroup.nID;
  2190.  
  2191.         return true;
  2192. }
  2193.  
  2194. void C3DEngine::UpdateStatInstGroups()
  2195. {
  2196.         if (!m_pObjManager)
  2197.                 return;
  2198.  
  2199.         for (uint32 nSID = 0; nSID < m_pObjManager->m_lstStaticTypes.size(); nSID++)
  2200.         {
  2201.                 PodArray<StatInstGroup>& rGroupTable = m_pObjManager->m_lstStaticTypes[nSID];
  2202.                 for (uint32 nGroupId = 0; nGroupId < rGroupTable.size(); nGroupId++)
  2203.                 {
  2204.                         StatInstGroup& rGroup = rGroupTable[nGroupId];
  2205.                         rGroup.Update(GetCVars(), Get3DEngine()->GetGeomDetailScreenRes());
  2206.                 }
  2207.         }
  2208. }
  2209.  
  2210. void C3DEngine::GetMemoryUsage(class ICrySizer* pSizer) const
  2211. {
  2212.  
  2213. #if !defined(_LIB) // Only when compiling as dynamic library
  2214.         //      {
  2215.         //SIZER_COMPONENT_NAME(pSizer,"Strings");
  2216.         //pSizer->AddObject( (this+1),string::_usedMemory(0) );
  2217.         //      }
  2218.         {
  2219.                 SIZER_COMPONENT_NAME(pSizer, "STL Allocator Waste");
  2220.                 CryModuleMemoryInfo meminfo;
  2221.                 ZeroStruct(meminfo);
  2222.                 CryGetMemoryInfoForModule(&meminfo);
  2223.                 pSizer->AddObject((this + 2), (size_t)meminfo.STL_wasted);
  2224.         }
  2225. #endif
  2226.  
  2227.         pSizer->AddObject(this, sizeof(*this) + (GetCVars()->e_StreamCgfDebug ? 100 * 1024 * 1024 : 0));
  2228.         pSizer->AddObject(m_pCVars);
  2229.  
  2230.         pSizer->AddObject(m_lstDynLights);
  2231.         pSizer->AddObject(m_lstDynLightsNoLight);
  2232.         pSizer->AddObject(m_lstStaticLights);
  2233.         pSizer->AddObject(m_lstAffectingLightsCombinations);
  2234.         pSizer->AddObject(m_arrLightProjFrustums);
  2235.         pSizer->AddObject(m_arrEntsInFoliage);
  2236.  
  2237.         pSizer->AddObject(m_lstRoadRenderNodesForUpdate);
  2238.  
  2239.         pSizer->AddObject(m_lstKilledVegetations);
  2240.         pSizer->AddObject(arrFPSforSaveLevelStats);
  2241.         pSizer->AddObject(m_lstAlwaysVisible);
  2242.  
  2243.         if (CTemporaryPool* pPool = CTemporaryPool::Get())
  2244.         {
  2245.                 SIZER_COMPONENT_NAME(pSizer, "Temporary Pool");
  2246.                 pPool->GetMemoryUsage(pSizer);
  2247.         }
  2248.  
  2249.         {
  2250.                 SIZER_COMPONENT_NAME(pSizer, "RenderMeshMerger");
  2251.                 m_pRenderMeshMerger->GetMemoryUsage(pSizer);
  2252.         }
  2253.  
  2254.         CRoadRenderNode::GetMemoryUsageStatic(pSizer);
  2255.  
  2256.         {
  2257.                 SIZER_COMPONENT_NAME(pSizer, "Particles");
  2258.                 pSizer->AddObject(m_pPartManager);
  2259.         }
  2260.  
  2261.         {
  2262.                 SIZER_COMPONENT_NAME(pSizer, "ParticleSystem");
  2263.                 pSizer->AddObject(m_pParticleSystem);
  2264.         }
  2265.  
  2266.         {
  2267.                 SIZER_COMPONENT_NAME(pSizer, "Optics");
  2268.                 pSizer->AddObject(m_pOpticsManager);
  2269.         }
  2270.  
  2271.         {
  2272.                 SIZER_COMPONENT_NAME(pSizer, "SkyLightManager");
  2273.                 pSizer->AddObject(m_pSkyLightManager);
  2274.         }
  2275.  
  2276.         {
  2277.                 SIZER_COMPONENT_NAME(pSizer, "DecalManager");
  2278.                 pSizer->AddObject(m_pDecalManager);
  2279.         }
  2280.  
  2281.         {
  2282.                 SIZER_COMPONENT_NAME(pSizer, "OutdoorObjectsTree");
  2283.                 pSizer->AddObject(m_pObjectsTree);
  2284.         }
  2285.  
  2286.         {
  2287.                 SIZER_COMPONENT_NAME(pSizer, "ObjManager");
  2288.                 pSizer->AddObject(m_pObjManager);
  2289.         }
  2290.  
  2291.         {
  2292.                 SIZER_COMPONENT_NAME(pSizer, "Terrain");
  2293.                 pSizer->AddObject(m_pTerrain);
  2294.         }
  2295.  
  2296.         {
  2297.                 SIZER_COMPONENT_NAME(pSizer, "VisAreas");
  2298.                 pSizer->AddObject(m_pVisAreaManager);
  2299.         }
  2300.  
  2301.         {
  2302.                 SIZER_COMPONENT_NAME(pSizer, "ClipVolumes");
  2303.                 pSizer->AddObject(m_pClipVolumeManager);
  2304.         }
  2305.  
  2306.         {
  2307.                 SIZER_COMPONENT_NAME(pSizer, "ProcVegetPool");
  2308.                 pSizer->AddObject(CTerrainNode::GetProcObjPoolMan());
  2309.                 pSizer->AddObject(CTerrainNode::GetProcObjChunkPool());
  2310.         }
  2311.  
  2312.         {
  2313.                 SIZER_COMPONENT_NAME(pSizer, "LayersBaseTextureData");
  2314.                 pSizer->AddObject(m_arrBaseTextureData);
  2315.         }
  2316.  
  2317.         {
  2318.                 SIZER_COMPONENT_NAME(pSizer, "WaterRipples");
  2319.                 pSizer->AddObject(m_pWaterRippleManager.get());
  2320.         }
  2321. }
  2322.  
  2323. void C3DEngine::GetResourceMemoryUsage(ICrySizer* pSizer, const AABB& cstAABB)
  2324. {
  2325.         //////////////////////////////////////////////////////////////////////////
  2326.         std::vector<IRenderNode*> cFoundRenderNodes;
  2327.         unsigned int nFoundObjects(0);
  2328.  
  2329.         nFoundObjects = GetObjectsInBox(cstAABB);
  2330.         cFoundRenderNodes.resize(nFoundObjects, NULL);
  2331.         GetObjectsInBox(cstAABB, &cFoundRenderNodes.front());
  2332.  
  2333.         size_t nCurrentRenderNode(0);
  2334.         size_t nTotalNumberOfRenderNodes(0);
  2335.  
  2336.         nTotalNumberOfRenderNodes = cFoundRenderNodes.size();
  2337.         for (nCurrentRenderNode = 0; nCurrentRenderNode < nTotalNumberOfRenderNodes; ++nCurrentRenderNode)
  2338.         {
  2339.                 IRenderNode*& piRenderNode = cFoundRenderNodes[nCurrentRenderNode];
  2340.  
  2341.                 IMaterial* piMaterial(piRenderNode->GetMaterialOverride());
  2342.                 if (!piMaterial)
  2343.                 {
  2344.                         piMaterial = piRenderNode->GetMaterial();
  2345.                 }
  2346.  
  2347.                 if (piMaterial)
  2348.                 {
  2349.                         piMaterial->GetResourceMemoryUsage(pSizer);
  2350.                 }
  2351.  
  2352.                 {
  2353.                         IRenderMesh* piMesh(NULL);
  2354.                         size_t nCount(0);
  2355.  
  2356.                         piMesh = piRenderNode->GetRenderMesh(nCount);
  2357.                         for (; piMesh; ++nCount, piMesh = piRenderNode->GetRenderMesh(nCount))
  2358.                         {
  2359.                                 // Timur, RenderMesh may not be loaded due to streaming!
  2360.                                 piMesh->GetMemoryUsage(pSizer, IRenderMesh::MEM_USAGE_COMBINED);
  2361.                         }
  2362.                 }
  2363.         }
  2364.         //////////////////////////////////////////////////////////////////////////
  2365.  
  2366.         if (m_pTerrain)
  2367.         {
  2368.                 CTerrainNode* poTerrainNode = m_pTerrain->FindMinNodeContainingBox(cstAABB, GetDefSID());
  2369.                 if (poTerrainNode)
  2370.                 {
  2371.                         poTerrainNode->GetResourceMemoryUsage(pSizer, cstAABB);
  2372.                 }
  2373.         }
  2374. }
  2375.  
  2376. void C3DEngine::AddWaterRipple(const Vec3& vPos, float scale, float strength)
  2377. {
  2378.         if (m_pWaterRippleManager)
  2379.         {
  2380.                 m_pWaterRippleManager->AddWaterRipple(vPos, scale, strength);
  2381.         }
  2382. }
  2383.  
  2384. bool C3DEngine::IsUnderWater(const Vec3& vPos) const
  2385. {
  2386.         bool bUnderWater = false;
  2387.         for (IPhysicalEntity* pArea = 0; pArea = GetPhysicalWorld()->GetNextArea(pArea); )
  2388.         {
  2389.                 if (bUnderWater)
  2390.                         // Must finish iteration to unlock areas.
  2391.                         continue;
  2392.  
  2393.                 pe_params_buoyancy buoy;
  2394.                 if (pArea->GetParams(&buoy) && buoy.iMedium == 0)
  2395.                 {
  2396.                         if (!is_unused(buoy.waterPlane.n))
  2397.                         {
  2398.                                 if (buoy.waterPlane.n * vPos < buoy.waterPlane.n * buoy.waterPlane.origin)
  2399.                                 {
  2400.                                         pe_status_contains_point st;
  2401.                                         st.pt = vPos;
  2402.                                         if (pArea->GetStatus(&st))
  2403.                                                 bUnderWater = true;
  2404.                                 }
  2405.                         }
  2406.                 }
  2407.         }
  2408.         return bUnderWater;
  2409. }
  2410.  
  2411. void C3DEngine::SetOceanRenderFlags(uint8 nFlags)
  2412. {
  2413.         m_nOceanRenderFlags = nFlags;
  2414. }
  2415.  
  2416. uint32 C3DEngine::GetOceanVisiblePixelsCount() const
  2417. {
  2418.         return COcean::GetVisiblePixelsCount();
  2419. }
  2420.  
  2421. float C3DEngine::GetBottomLevel(const Vec3& referencePos, float maxRelevantDepth, int objflags)
  2422. {
  2423.         FUNCTION_PROFILER_3DENGINE;
  2424.  
  2425.         const float terrainWorldZ = GetTerrainElevation(referencePos.x, referencePos.y);
  2426.  
  2427.         const float padding = 0.2f;
  2428.         float rayLength;
  2429.  
  2430.         // NOTE: Terrain is above referencePos, so referencePos is probably inside a voxel or something.
  2431.         if (terrainWorldZ <= referencePos.z)
  2432.                 rayLength = min(maxRelevantDepth, (referencePos.z - terrainWorldZ));
  2433.         else
  2434.                 rayLength = maxRelevantDepth;
  2435.  
  2436.         rayLength += padding * 2.0f;
  2437.  
  2438.         ray_hit hit;
  2439.         int rayFlags = geom_colltype_player << rwi_colltype_bit | rwi_stop_at_pierceable;
  2440.         if (m_pPhysicalWorld->RayWorldIntersection(referencePos + Vec3(0, 0, padding), Vec3(0, 0, -rayLength),
  2441.                                                    ent_terrain | ent_static | ent_sleeping_rigid | ent_rigid, rayFlags, &hit, 1))
  2442.         {
  2443.                 return hit.pt.z;
  2444.         }
  2445.  
  2446.         // Terrain was above or too far below referencePos, and no solid object was close enough.
  2447.         return BOTTOM_LEVEL_UNKNOWN;
  2448. }
  2449.  
  2450. float C3DEngine::GetBottomLevel(const Vec3& referencePos, float maxRelevantDepth /* = 10.0f */)
  2451. {
  2452.         return GetBottomLevel(referencePos, maxRelevantDepth, ent_terrain | ent_static | ent_sleeping_rigid | ent_rigid);
  2453. }
  2454.  
  2455. float C3DEngine::GetBottomLevel(const Vec3& referencePos, int objflags)
  2456. {
  2457.         return GetBottomLevel(referencePos, 10.0f, objflags);
  2458. }
  2459.  
  2460. #if defined(USE_GEOM_CACHES)
  2461. IGeomCache* C3DEngine::LoadGeomCache(const char* szFileName)
  2462. {
  2463.         if (!szFileName || !szFileName[0])
  2464.         {
  2465.                 m_pSystem->Warning(VALIDATOR_MODULE_3DENGINE, VALIDATOR_ERROR, 0, 0, "I3DEngine::LoadGeomCache: filename is not specified");
  2466.                 return 0;
  2467.         }
  2468.  
  2469.         return m_pGeomCacheManager->LoadGeomCache(szFileName);
  2470. }
  2471.  
  2472. IGeomCache* C3DEngine::FindGeomCacheByFilename(const char* szFileName)
  2473. {
  2474.         if (!szFileName || szFileName[0] == 0)
  2475.         {
  2476.                 return NULL;
  2477.         }
  2478.  
  2479.         return m_pGeomCacheManager->FindGeomCacheByFilename(szFileName);
  2480. }
  2481. #endif
  2482.  
  2483. namespace
  2484. {
  2485. // The return value is the next position of the source buffer.
  2486. int ReadFromBuffer(const char* pSource, int nSourceSize, int nSourcePos, void* pDest, int nDestSize)
  2487. {
  2488.         if (pDest == 0 || nDestSize == 0)
  2489.                 return 0;
  2490.  
  2491.         if (nSourcePos < 0 || nSourcePos >= nSourceSize)
  2492.                 return 0;
  2493.  
  2494.         memcpy(pDest, &pSource[nSourcePos], nDestSize);
  2495.  
  2496.         return nSourcePos + nDestSize;
  2497. }
  2498. }
  2499.  
  2500. //! Load an IStatObj for the engine based on the saved version. Save function is in
  2501. //! Code\Sandbox\Plugins\CryDesigner\Core\ModelCompiler.cpp, function ModelCompiler::SaveMesh
  2502. IStatObj* C3DEngine::LoadDesignerObject(int nVersion, const char* szBinaryStream, int size)
  2503. {
  2504.         if (nVersion < 0 || nVersion > 2)
  2505.                 return NULL;
  2506.  
  2507.         int nBufferPos = 0;
  2508.         int32 nSubObjectCount = 0;
  2509.         nBufferPos = ReadFromBuffer(szBinaryStream, size, nBufferPos, &nSubObjectCount, sizeof(int32));
  2510.  
  2511.         IStatObj* pStatObj = gEnv->p3DEngine->CreateStatObj();
  2512.         if (!pStatObj)
  2513.                 return NULL;
  2514.  
  2515.         std::vector<IStatObj*> statObjList;
  2516.         if (nSubObjectCount > 0)
  2517.         {
  2518.                 for (int i = 0; i < nSubObjectCount; ++i)
  2519.                 {
  2520.                         pStatObj->AddSubObject(gEnv->p3DEngine->CreateStatObj());
  2521.                         statObjList.push_back(pStatObj->GetSubObject(i)->pStatObj);
  2522.                 }
  2523.                 pStatObj->GetIndexedMesh()->FreeStreams();
  2524.         }
  2525.         else
  2526.         {
  2527.                 statObjList.push_back(pStatObj);
  2528.         }
  2529.  
  2530.         if (nVersion == 2)
  2531.         {
  2532.                 int32 nStaticObjFlags = 0;
  2533.                 nBufferPos = ReadFromBuffer(szBinaryStream, size, nBufferPos, &nStaticObjFlags, sizeof(int32));
  2534.                 pStatObj->SetFlags(nStaticObjFlags);
  2535.         }
  2536.  
  2537.         AABB statObj_bbox(AABB::RESET);
  2538.  
  2539.         for (int k = 0, iCount(statObjList.size()); k < iCount; ++k)
  2540.         {
  2541.                 int32 nPositionCount = 0;
  2542.                 int32 nTexCoordCount = 0;
  2543.                 int32 nFaceCount = 0;
  2544.                 int32 nIndexCount = 0;
  2545.                 int32 nTangentCount = 0;
  2546.                 int32 nSubsetCount = 0;
  2547.  
  2548.                 nBufferPos = ReadFromBuffer(szBinaryStream, size, nBufferPos, &nPositionCount, sizeof(int32));
  2549.                 nBufferPos = ReadFromBuffer(szBinaryStream, size, nBufferPos, &nTexCoordCount, sizeof(int32));
  2550.                 if (nPositionCount <= 0 || nTexCoordCount <= 0)
  2551.                         return NULL;
  2552.  
  2553.                 if (nVersion == 0)
  2554.                 {
  2555.                         nBufferPos = ReadFromBuffer(szBinaryStream, size, nBufferPos, &nFaceCount, sizeof(int32));
  2556.                         if (nFaceCount <= 0)
  2557.                                 return NULL;
  2558.                 }
  2559.                 else if (nVersion >= 1)
  2560.                 {
  2561.                         nBufferPos = ReadFromBuffer(szBinaryStream, size, nBufferPos, &nIndexCount, sizeof(int32));
  2562.                         if (nIndexCount <= 0)
  2563.                                 return NULL;
  2564.                         nBufferPos = ReadFromBuffer(szBinaryStream, size, nBufferPos, &nTangentCount, sizeof(int32));
  2565.                 }
  2566.                 nBufferPos = ReadFromBuffer(szBinaryStream, size, nBufferPos, &nSubsetCount, sizeof(int32));
  2567.                 IIndexedMesh* pMesh = statObjList[k]->GetIndexedMesh();
  2568.                 if (!pMesh)
  2569.                         return NULL;
  2570.  
  2571.                 pMesh->FreeStreams();
  2572.                 pMesh->SetVertexCount((int)nPositionCount);
  2573.                 pMesh->SetFaceCount((int)nFaceCount);
  2574.                 pMesh->SetIndexCount((int)nIndexCount);
  2575.                 pMesh->SetTexCoordCount((int)nTexCoordCount);
  2576.  
  2577.                 Vec3* const positions = pMesh->GetMesh()->GetStreamPtr<Vec3>(CMesh::POSITIONS);
  2578.                 Vec3* const normals = pMesh->GetMesh()->GetStreamPtr<Vec3>(CMesh::NORMALS);
  2579.                 SMeshTexCoord* const texcoords = pMesh->GetMesh()->GetStreamPtr<SMeshTexCoord>(CMesh::TEXCOORDS);
  2580.  
  2581.                 nBufferPos = ReadFromBuffer(szBinaryStream, size, nBufferPos, positions, sizeof(Vec3) * nPositionCount);
  2582.                 nBufferPos = ReadFromBuffer(szBinaryStream, size, nBufferPos, normals, sizeof(Vec3) * nPositionCount);
  2583.                 nBufferPos = ReadFromBuffer(szBinaryStream, size, nBufferPos, texcoords, sizeof(SMeshTexCoord) * nTexCoordCount);
  2584.                 if (nVersion == 0)
  2585.                 {
  2586.                         SMeshFace* const faces = pMesh->GetMesh()->GetStreamPtr<SMeshFace>(CMesh::FACES);
  2587.                         nBufferPos = ReadFromBuffer(szBinaryStream, size, nBufferPos, faces, sizeof(SMeshFace) * nFaceCount);
  2588.                 }
  2589.                 else if (nVersion >= 1)
  2590.                 {
  2591.                         vtx_idx* const indices = pMesh->GetMesh()->GetStreamPtr<vtx_idx>(CMesh::INDICES);
  2592.                         if (sizeof(vtx_idx) == sizeof(uint16))
  2593.                         {
  2594.                                 nBufferPos = ReadFromBuffer(szBinaryStream, size, nBufferPos, indices, sizeof(uint16) * nIndexCount);
  2595.                         }
  2596.                         else
  2597.                         {
  2598.                                 uint16* indices16 = new uint16[nIndexCount];
  2599.                                 nBufferPos = ReadFromBuffer(szBinaryStream, size, nBufferPos, indices16, sizeof(uint16) * nIndexCount);
  2600.                                 for (int32 i = 0; i < nIndexCount; ++i)
  2601.                                         indices[i] = (vtx_idx)indices16[i];
  2602.                                 delete[] indices16;
  2603.                         }
  2604.                         pMesh->SetTangentCount((int)nTangentCount);
  2605.                         if (nTangentCount > 0)
  2606.                         {
  2607.                                 SMeshTangents* const tangents = pMesh->GetMesh()->GetStreamPtr<SMeshTangents>(CMesh::TANGENTS);
  2608.                                 nBufferPos = ReadFromBuffer(szBinaryStream, size, nBufferPos, tangents, sizeof(SMeshTangents) * nTangentCount);
  2609.                         }
  2610.                 }
  2611.  
  2612.                 // AABB calculation
  2613. #if 0
  2614.                 if (nVersion < 3)
  2615. #endif
  2616.                 {
  2617.                         // No BB saved for this version, so we need to recalculate manually
  2618.                         pMesh->CalcBBox();
  2619.  
  2620.                         statObjList[k]->SetBBoxMin(pMesh->GetBBox().min);
  2621.                         statObjList[k]->SetBBoxMax(pMesh->GetBBox().max);
  2622.                 }
  2623.                 // optimization for AABB loading - keep ifdef temporarily to keep volatile changes for after GDC16
  2624. #if 0
  2625.                 else
  2626.                 {
  2627.                         // for version 3 we saved the result in the file, so we can load it directly instead of iterating through the mesh
  2628.                         Vec3 minBB, maxBB;
  2629.                         nBufferPos = ReadFromBuffer(szBinaryStream, size, nBufferPos, &minBB, sizeof(Vec3));
  2630.                         nBufferPos = ReadFromBuffer(szBinaryStream, size, nBufferPos, &maxBB, sizeof(Vec3));
  2631.  
  2632.                         statObjList[k]->SetBBoxMin(minBB);
  2633.                         statObjList[k]->SetBBoxMax(maxBB);
  2634.                 }
  2635. #endif
  2636.  
  2637.                 statObj_bbox.Add(statObjList[k]->GetAABB());
  2638.  
  2639.                 // subset loading
  2640.                 pMesh->SetSubSetCount(nSubsetCount);
  2641.  
  2642.                 for (int i = 0; i < nSubsetCount; ++i)
  2643.                 {
  2644.                         SMeshSubset subset;
  2645.                         nBufferPos = ReadFromBuffer(szBinaryStream, size, nBufferPos, &subset.vCenter, sizeof(Vec3));
  2646.                         nBufferPos = ReadFromBuffer(szBinaryStream, size, nBufferPos, &subset.fRadius, sizeof(float));
  2647.                         nBufferPos = ReadFromBuffer(szBinaryStream, size, nBufferPos, &subset.fTexelDensity, sizeof(float));
  2648.  
  2649.                         int32 nFirstIndexId = 0;
  2650.                         int32 nNumIndices = 0;
  2651.                         int32 nFirstVertId = 0;
  2652.                         int32 nNumVerts = 0;
  2653.                         int32 nMatID = 0;
  2654.                         int32 nMatFlags = 0;
  2655.                         int32 nPhysicalizeType = 0;
  2656.  
  2657.                         nBufferPos = ReadFromBuffer(szBinaryStream, size, nBufferPos, &nFirstIndexId, sizeof(int32));
  2658.                         nBufferPos = ReadFromBuffer(szBinaryStream, size, nBufferPos, &nNumIndices, sizeof(int32));
  2659.                         nBufferPos = ReadFromBuffer(szBinaryStream, size, nBufferPos, &nFirstVertId, sizeof(int32));
  2660.                         nBufferPos = ReadFromBuffer(szBinaryStream, size, nBufferPos, &nNumVerts, sizeof(int32));
  2661.                         nBufferPos = ReadFromBuffer(szBinaryStream, size, nBufferPos, &nMatID, sizeof(int32));
  2662.                         nBufferPos = ReadFromBuffer(szBinaryStream, size, nBufferPos, &nMatFlags, sizeof(int32));
  2663.                         nBufferPos = ReadFromBuffer(szBinaryStream, size, nBufferPos, &nPhysicalizeType, sizeof(int32));
  2664.  
  2665.                         pMesh->SetSubsetBounds(i, subset.vCenter, subset.fRadius);
  2666.                         pMesh->SetSubsetIndexVertexRanges(i, (int)nFirstIndexId, (int)nNumIndices, (int)nFirstVertId, (int)nNumVerts);
  2667.                         pMesh->SetSubsetMaterialId(i, nMatID == -1 ? 0 : (int)nMatID);
  2668.                         pMesh->SetSubsetMaterialProperties(i, (int)nMatFlags, (int)nPhysicalizeType);
  2669.                 }
  2670.  
  2671.                 if (nVersion == 0)
  2672.                 {
  2673. #if CRY_PLATFORM_WINDOWS
  2674.                         pMesh->Optimize();
  2675. #endif
  2676.                 }
  2677.  
  2678.                 statObjList[k]->Invalidate(true);
  2679.         }
  2680.         pStatObj->SetBBoxMin(statObj_bbox.min);
  2681.         pStatObj->SetBBoxMax(statObj_bbox.max);
  2682.  
  2683.         return pStatObj;
  2684. }
  2685.  
  2686. float C3DEngine::GetWaterLevel(const Vec3* pvPos, IPhysicalEntity* pent, bool bAccurate)
  2687. {
  2688.         FUNCTION_PROFILER_3DENGINE;
  2689.  
  2690.         bool bInVisarea = m_pVisAreaManager && m_pVisAreaManager->GetVisAreaFromPos(*pvPos) != 0;
  2691.  
  2692.         Vec3 gravity;
  2693.         pe_params_buoyancy pb[4];
  2694.         int i, nBuoys = m_pPhysicalWorld->CheckAreas(*pvPos, gravity, pb, 4, -1, ZERO, pent);
  2695.  
  2696.         float max_level = (!bInVisarea) ? (bAccurate ? GetAccurateOceanHeight(*pvPos) : GetWaterLevel()) : WATER_LEVEL_UNKNOWN;
  2697.  
  2698.         for (i = 0; i < nBuoys; i++)
  2699.         {
  2700.                 if (pb[i].iMedium == 0 && (!bInVisarea || fabs_tpl(pb[i].waterPlane.origin.x) + fabs_tpl(pb[i].waterPlane.origin.y) > 0))
  2701.                 {
  2702.                         float fVolumeLevel = pvPos->z - pb[i].waterPlane.n.z * (pb[i].waterPlane.n * (*pvPos - pb[i].waterPlane.origin));
  2703.  
  2704.                         // it's not ocean
  2705.                         if (pb[i].waterPlane.origin.y + pb[i].waterPlane.origin.x != 0.0f)
  2706.                                 max_level = max(max_level, fVolumeLevel);
  2707.                 }
  2708.         }
  2709.  
  2710.         return max(WATER_LEVEL_UNKNOWN, max_level);
  2711. }
  2712.  
  2713. void C3DEngine::SetShadowsGSMCache(bool bCache)
  2714. {
  2715.         if (bCache)
  2716.                 m_nGsmCache = m_pConsole->GetCVar("r_ShadowsCache")->GetIVal();
  2717.         else
  2718.                 m_nGsmCache = 0;
  2719. }
  2720.  
  2721. float C3DEngine::GetAccurateOceanHeight(const Vec3& pCurrPos) const
  2722. {
  2723.         FUNCTION_PROFILER_3DENGINE;
  2724.  
  2725.         static int nFrameID = -1;
  2726.         const int nEngineFrameID = gEnv->nMainFrameID;
  2727.         static float fWaterLevel = 0;
  2728.         if (nFrameID != nEngineFrameID && m_pTerrain)
  2729.         {
  2730.                 fWaterLevel = m_pTerrain->GetWaterLevel();
  2731.                 nFrameID = nEngineFrameID;
  2732.         }
  2733.  
  2734.         const float waterLevel = fWaterLevel + COcean::GetWave(pCurrPos, gEnv->nMainFrameID);
  2735.         return waterLevel;
  2736. }
  2737.  
  2738. Vec4 C3DEngine::GetCausticsParams() const
  2739. {
  2740.         return Vec4(m_oceanCausticsTilling, m_oceanCausticsDistanceAtten, m