/* * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or * its licensors. * * For complete copyright and license terms please see the LICENSE at the root of this * distribution (the "License"). All use of this software is governed by the License, * or, if provided, by the license below or the license accompanying this file. Do not * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ // Original file Copyright Crytek GMBH or its affiliates, used under license. #ifndef CRYINCLUDE_CRY3DENGINE_3DENGINE_H #define CRYINCLUDE_CRY3DENGINE_3DENGINE_H #pragma once #include #include #include #include #include #include #ifdef DrawText #undef DrawText #endif //DrawText struct ITerrain; struct STerrainInfo; struct IOctreeNode; class COctreeNode; class CCullBuffer; class IDeformableNode; class CRoadRenderNode; struct STerrainChunkHeader; struct StatInstGroup; struct StatInstGroupChunk; namespace LegacyProceduralVegetation { class VegetationPoolManager; } struct SEntInFoliage { int id; float timeIdle; void GetMemoryUsage(ICrySizer* pSizer) const { /*nothing*/ } }; class CREParticleGPU; struct IFaceGen; class CMemoryBlock : public IMemoryBlock { public: virtual void* GetData() { return m_pData; } virtual int GetSize() { return m_nSize; } virtual ~CMemoryBlock() { delete[] m_pData; } CMemoryBlock() { m_pData = 0; m_nSize = 0; } CMemoryBlock(const void* pData, int nSize) { m_pData = 0; m_nSize = 0; SetData(pData, nSize); } void SetData(const void* pData, int nSize) { delete[] m_pData; m_pData = new uint8[nSize]; memcpy(m_pData, pData, nSize); m_nSize = nSize; } void Free() { delete[] m_pData; m_pData = NULL; m_nSize = 0; } void Allocate(int nSize) { delete[] m_pData; m_pData = new uint8[nSize]; memset(m_pData, 0, nSize); m_nSize = nSize; } static CMemoryBlock* CompressToMemBlock(void* pData, int nSize, ISystem* pSystem) { CMemoryBlock* pMemBlock = NULL; uint8* pTmp = new uint8[nSize + 4]; size_t nComprSize = nSize; *(uint32*)pTmp = nSize; if (pSystem->CompressDataBlock(pData, nSize, pTmp + 4, nComprSize)) { pMemBlock = new CMemoryBlock(pTmp, nComprSize + 4); } delete[] pTmp; return pMemBlock; } static CMemoryBlock* DecompressFromMemBlock(CMemoryBlock* pMemBlock, ISystem* pSystem) { size_t nUncompSize = *(uint32*)pMemBlock->GetData(); SwapEndian(nUncompSize); CMemoryBlock* pResult = new CMemoryBlock; pResult->Allocate(nUncompSize); if (!pSystem->DecompressDataBlock((byte*)pMemBlock->GetData() + 4, pMemBlock->GetSize() - 4, pResult->GetData(), nUncompSize)) { assert(!"CMemoryBlock::DecompressFromMemBlock failed"); delete pResult; pResult = NULL; } return pResult; } uint8* m_pData; int m_nSize; }; // Values to combine for phys area type selection enum EAreaPhysics { Area_Water = BIT(0), Area_Air = BIT(1), // Other physics media can be masked in as well Area_Gravity = BIT(14), Area_Other = BIT(15), }; struct SAreaChangeRecord { AABB boxAffected; // Area of change uint16 uPhysicsMask; // Types of mediums for this area }; struct SPhysAreaNodeProxy { void Reset() { pRenderNode = (IRenderNode*)(intptr_t)-1; bIsValid = false; bbox.Reset(); } IRenderNode* pRenderNode; // RenderNode uint16 uPhysicsMask; // Bit mask of physics interested in bool bIsValid; // Does the proxy carry valid data AABB bbox; // Bounding box of render node }; struct SFrameInfo { void Reset() { ppRNTmpData = (CRNTmpData**)(intptr_t)-1; bIsValid = false; nCreatedFrameId = nLastUsedFrameId = ~0; } uint32 nLastUsedFrameId; uint32 nCreatedFrameId; bool bIsValid; CRNTmpData** ppRNTmpData; }; struct SNodeInfo; class CStitchedImage; struct DLightAmount { CDLight* pLight; float fAmount; }; template struct CPoolAllocator { CPoolAllocator() { m_nCounter = 0; } ~CPoolAllocator() { Reset(); } void Reset() { for (int i = 0; i < m_Pools.Count(); i++) { delete[](byte*)m_Pools[i]; m_Pools[i] = NULL; } m_nCounter = 0; } void ReleaseElement(T* pElem) { if (pElem) { m_FreeElements.Add(pElem); } } T* GetNewElement() { if (m_FreeElements.Count()) { T* pPtr = m_FreeElements.Last(); m_FreeElements.DeleteLast(); return pPtr; } int nPoolId = m_nCounter / nMaxElemsInChunk; int nElemId = m_nCounter - nPoolId * nMaxElemsInChunk; m_Pools.PreAllocate(nPoolId + 1, nPoolId + 1); if (!m_Pools[nPoolId]) { m_Pools[nPoolId] = (T*)new byte[nMaxElemsInChunk * sizeof(T)]; } m_nCounter++; return &m_Pools[nPoolId][nElemId]; } int GetCount() { return m_nCounter - m_FreeElements.Count(); } int GetCapacity() { return m_Pools.Count() * nMaxElemsInChunk; } int GetCapacityBytes() { return GetCapacity() * sizeof(T); } private: int m_nCounter; PodArray m_Pools; PodArray m_FreeElements; }; struct SImageSubInfo { SImageSubInfo() { memset(this, 0, sizeof(*this)); fTiling = fTilingIn = 1.f; } static const int nMipsNum = 4; union { byte* pImgMips[nMipsNum]; int pImgMipsSizeKeeper[8]; }; float fAmount; int nReady; int nDummy[4]; _smart_ptr pMat; int nDim; float fTilingIn; float fTiling; float fSpecularAmount; int nSortOrder; int nAlignFix; AUTO_STRUCT_INFO }; struct SImageInfo : public Cry3DEngineBase { SImageInfo() { szDetMatName[0] = szBaseTexName[0] = '\0'; nPhysSurfaceType = 0; nLayerId = 0; fUseRemeshing = 0; fBr = 1.f; layerFilterColor = Col_White; nDetailSurfTypeId = 0; ZeroStruct(arrTextureId); } void GetMemoryUsage(ICrySizer* pSizer) const { /*nothing*/ } SImageSubInfo baseInfo; SImageSubInfo detailInfo; char szDetMatName[128 - 20]; int arrTextureId[4]; int nPhysSurfaceType; char szBaseTexName[128]; float fUseRemeshing; ColorF layerFilterColor; int nLayerId; float fBr; int nDetailSurfTypeId; int GetMemoryUsage(); AUTO_STRUCT_INFO }; struct SSceneFrustum { uint32* pRgbImage; uint32 nRgbWidth, nRgbHeight; float* pDepthImage; uint32 nDepthWidth, nDepthHeight; CCamera camera; IRenderMesh* pRM; _smart_ptr pMaterial; float fDistance; int nId; static int Compare(const void* v1, const void* v2) { SSceneFrustum* p[2] = { (SSceneFrustum*)v1, (SSceneFrustum*)v2 }; if (p[0]->fDistance > p[1]->fDistance) { return 1; } if (p[0]->fDistance < p[1]->fDistance) { return -1; } if (p[0]->nId > p[1]->nId) { return 1; } if (p[0]->nId < p[1]->nId) { return -1; } return 0; } }; struct SPerObjectShadow { IShadowCaster* pCaster; float fConstBias; float fSlopeBias; float fJitter; Vec3 vBBoxScale; uint nTexSize; }; ////////////////////////////////////////////////////////////////////// #define LV_MAX_COUNT 256 #define LV_LIGHTS_MAX_COUNT 64 #define LV_WORLD_BUCKET_SIZE 512 #define LV_LIGHTS_WORLD_BUCKET_SIZE 512 #define LV_WORLD_SIZEX 128 #define LV_WORLD_SIZEY 128 #define LV_WORLD_SIZEZ 64 #define LV_CELL_SIZEX 4 #define LV_CELL_SIZEY 4 #define LV_CELL_SIZEZ 8 #define LV_CELL_RSIZEX (1.0f / (float)LV_CELL_SIZEX) #define LV_CELL_RSIZEY (1.0f / (float)LV_CELL_SIZEY) #define LV_CELL_RSIZEZ (1.0f / (float)LV_CELL_SIZEZ) #define LV_LIGHT_CELL_SIZE 32 #define LV_LIGHT_CELL_R_SIZE (1.0f / (float)LV_LIGHT_CELL_SIZE) #define LV_DLF_LIGHTVOLUMES_MASK (DLF_DISABLED | DLF_FAKE | DLF_AMBIENT | DLF_DEFERRED_CUBEMAPS) class CLightVolumesMgr : public Cry3DEngineBase { public: CLightVolumesMgr() { Init(); } void Init(); void Reset(); uint16 RegisterVolume(const Vec3& vPos, f32 fRadius, uint8 nClipVolumeRef, const SRenderingPassInfo& passInfo); void RegisterLight(const CDLight& pDL, uint32 nLightID, const SRenderingPassInfo& passInfo); void Update(const SRenderingPassInfo& passInfo); void Clear(const SRenderingPassInfo& passInfo); void GetLightVolumes(threadID nThreadID, SLightVolume*& pLightVols, uint32& nNumVols); #ifndef _RELEASE void DrawDebug(const SRenderingPassInfo& passInfo); #endif private: struct SLightVolInfo { SLightVolInfo() : vVolume(ZERO, 0.0f) , nNextVolume(0) , nClipVolumeID(0) { }; SLightVolInfo(const Vec3& pPos, float fRad, uint8 clipVolumeID) : vVolume(pPos, fRad) , nNextVolume(0) , nClipVolumeID(clipVolumeID) { }; Vec4 vVolume; // xyz: position, w: radius uint16 nNextVolume; // index of next light volume for this hash bucket (0 if none) uint8 nClipVolumeID; // clip volume stencil ref }; struct SLightCell { SLightCell() : nLightCount(0) { }; uint16 nLightID[LV_LIGHTS_MAX_COUNT]; uint8 nLightCount; }; inline int32 GetIntHash(const int32 k, const int32 nBucketSize = LV_WORLD_BUCKET_SIZE) const { static const uint32 nHashBits = 9; static const uint32 nGoldenRatio32bits = 2654435761u; // (2^32) / (golden ratio) return (k * nGoldenRatio32bits) >> (32 - nHashBits); // ref: knuths integer multiplicative hash function } inline uint16 GetWorldHashBucketKey(const int32 x, const int32 y, const int32 z, const int32 nBucketSize = LV_WORLD_BUCKET_SIZE) const { const uint32 nPrimeNum = 101;//0xd8163841; return aznumeric_caster((((GetIntHash(x) + nPrimeNum) * nPrimeNum + GetIntHash(y)) * nPrimeNum + GetIntHash(z)) & (nBucketSize - 1)); } void AddLight(const SRenderLight& pLight, const SLightVolInfo* __restrict pVolInfo, SLightVolume& pVolume); typedef DynArray LightVolumeVector; private: LightVolumeVector m_pLightVolumes[RT_COMMAND_BUF_COUNT]; // Final light volume list. move light list creation to renderer to avoid double-buffering this DynArray m_pLightVolsInfo[RT_COMMAND_BUF_COUNT]; // World cells data SLightCell m_pWorldLightCells[LV_LIGHTS_WORLD_BUCKET_SIZE]; // 2D World cell buckets for light sources ids uint16 m_nWorldCells[LV_WORLD_BUCKET_SIZE]; // World cell buckets for light volumes bool m_bUpdateLightVolumes : 1; }; // onscreen infodebug for e_debugDraw >= 100 #ifndef _RELEASE class CDebugDrawListMgr { typedef CryFixedStringT<64> TMyStandardString; typedef CryFixedStringT<128> TFilenameString; public: CDebugDrawListMgr(); void Update(); void AddObject(I3DEngine::SObjectInfoToAddToDebugDrawList& objInfo); void DumpLog(); bool IsEnabled() const { return Cry3DEngineBase::GetCVars()->e_DebugDraw >= LM_BASENUMBER; } static void ConsoleCommand(IConsoleCmdArgs* args); private: enum { UNDEFINED_ASSET_ID = 0xffffffff }; struct TAssetInfo { TMyStandardString name; TFilenameString fileName; uint32 numTris; uint32 numVerts; uint32 texMemory; uint32 meshMemory; uint32 drawCalls; uint32 numInstances; I3DEngine::EDebugDrawListAssetTypes type; uint32 ID; // to identify which drawBoxes belong to this asset TAssetInfo(const I3DEngine::SObjectInfoToAddToDebugDrawList& objInfo); bool operator<(const TAssetInfo& other) const; }; struct TObjectDrawBoxInfo { Matrix34 mat; AABB bbox; uint32 assetID; TObjectDrawBoxInfo(const I3DEngine::SObjectInfoToAddToDebugDrawList& objInfo); }; void FindNewLeastValueAsset(); void ClearFrameData(); void ClearConsoleCommandRequestVars(); static bool SortComparison(const TAssetInfo& A, const TAssetInfo& B) { return B < A; } const char* GetStrCurrMode(); void GetStrCurrFilter(TMyStandardString& strOut); bool ShouldFilterOutObject(const I3DEngine::SObjectInfoToAddToDebugDrawList& newObject); void MemToString(uint32 memVal, TMyStandardString& outStr); static void PrintText(float x, float y, const ColorF& fColor, const char* label_text, ...); const char* GetAssetTypeName(I3DEngine::EDebugDrawListAssetTypes type); TAssetInfo* FindDuplicate(const TAssetInfo& object); void CheckFilterCVar(); // to avoid any heap allocation static void MyStandardString_Concatenate(TMyStandardString& outStr, const char* str); static void MyFileNameString_Assign(TFilenameString& outStr, const char* pStr); template static void MyString_Assign(T& outStr, const char* pStr) { if (pStr) { outStr._Assign(pStr, min(strlen(pStr), outStr.capacity())); } else { outStr = ""; } } enum EListModes { LM_BASENUMBER = 100, LM_TRI_COUNT = LM_BASENUMBER, LM_VERT_COUNT, LM_DRAWCALLS, LM_TEXTMEM, LM_MESHMEM }; bool m_isFrozen; uint32 m_counter; uint32 m_assetCounter; uint32 m_indexLeastValueAsset; std::vector m_assets; std::vector m_drawBoxes; CryCriticalSection m_lock; static bool m_dumpLogRequested; static bool m_freezeRequested; static bool m_unfreezeRequested; static uint32 m_filter; }; #endif //_RELEASE #pragma pack(push,4) //! structure to vegetation group properties loading/saving struct StatInstGroupChunk { StatInstGroupChunk() { ZeroStruct(*this); } char szFileName[256]; float fBending; float fSpriteDistRatio; float fShadowDistRatio; float fMaxViewDistRatio; float fBrightness; int32 nRotationRangeToTerrainNormal; // applied to a vegetation object that has been realigned in the terrain's Y/X direction float fAlignToTerrainCoefficient; uint32 nMaterialLayers; float fDensity; float fElevationMax; float fElevationMin; float fSize; float fSizeVar; float fSlopeMax; float fSlopeMin; float fStatObjRadius_NotUsed; int nIDPlusOne; // For backward compatibility, we need to save ID + 1 float fLodDistRatio; uint32 nReserved; int nFlags; int nMaterialId; //! flags similar to entity render flags int m_dwRndFlags; float fStiffness; float fDamping; float fVariance; float fAirResistance; AUTO_STRUCT_INFO_LOCAL }; struct SNameChunk { SNameChunk() { memset(this, 0, sizeof(SNameChunk)); } char szFileName[256]; AUTO_STRUCT_INFO_LOCAL }; #pragma pack(pop) ////////////////////////////////////////////////////////////////////// class C3DEngine : public I3DEngine , public Cry3DEngineBase , private StatObjEventBus::MultiHandler { public: // I3DEngine interface implementation virtual bool Init(); virtual void OnFrameStart(); virtual void Update(); virtual void RenderWorld(const int nRenderFlags, const SRenderingPassInfo& passInfo, const char* szDebugName); virtual void PreWorldStreamUpdate(const CCamera& cam); virtual void WorldStreamUpdate(); virtual void ShutDown(); virtual void Release() { CryAlignedDelete(this); }; virtual void SetLevelPath(const char* szFolderName); virtual bool LoadLevel(const char* szFolderName, const char* szMissionName); virtual void UnloadLevel(); virtual void PostLoadLevel(); virtual bool InitLevelForEditor(const char* szFolderName, const char* szMissionName); virtual bool LevelLoadingInProgress(); virtual void DisplayInfo(float& fTextPosX, float& fTextPosY, float& fTextStepY, const bool bEnhanced); virtual void DisplayMemoryStatistics(); virtual void SetupDistanceFog(); virtual IStatObj* LoadStatObjUnsafeManualRef(const char* fileName, const char* geomName = nullptr, /*[Out]*/ IStatObj::SSubObject** subObject = nullptr, bool useStreaming = true, unsigned long loadingFlags = 0, const void* data = nullptr, int dataSize = 0) override; virtual _smart_ptr LoadStatObjAutoRef(const char* fileName, const char* geomName = nullptr, /*[Out]*/ IStatObj::SSubObject** subObject = nullptr, bool useStreaming = true, unsigned long loadingFlags = 0, const void* data = nullptr, int dataSize = 0) override; virtual IDeformableNode* CreateDeformableNode(); virtual void DestroyDeformableNode(IDeformableNode* node); virtual const IObjManager* GetObjectManager() const; virtual IObjManager* GetObjectManager(); virtual IStatObj* FindStatObjectByFilename(const char* filename); virtual void RegisterEntity(IRenderNode* pEnt, int nSID = -1, int nSIDConsideredSafe = -1); virtual bool IsSunShadows(){ return m_bSunShadows; }; virtual void SelectEntity(IRenderNode* pEnt); virtual void LoadEmptyLevel() override; virtual void LoadStatObjAsync(LoadStaticObjectAsyncResult resultCallback, const char* szFileName, const char* szGeomName = nullptr, bool bUseStreaming = true, unsigned long nLoadingFlags = 0); virtual void ProcessAsyncStaticObjectLoadRequests() override; LegacyProceduralVegetation::IVegetationPoolManager& GetIVegetationPoolManager() override; #ifndef _RELEASE virtual void AddObjToDebugDrawList(SObjectInfoToAddToDebugDrawList& objInfo); virtual bool IsDebugDrawListEnabled() const { return m_DebugDrawListMgr.IsEnabled(); } #endif virtual void UnRegisterEntityDirect(IRenderNode* pEnt); virtual void UnRegisterEntityAsJob(IRenderNode* pEnt); virtual bool IsUnderWater(const Vec3& vPos) const; virtual void SetOceanRenderFlags(uint8 nFlags); virtual uint8 GetOceanRenderFlags() const { return m_nOceanRenderFlags; } virtual uint32 GetOceanVisiblePixelsCount() const; virtual float GetBottomLevel(const Vec3& referencePos, float maxRelevantDepth, int objtypes); virtual float GetBottomLevel(const Vec3& referencePos, float maxRelevantDepth /* = 10.0f*/); virtual float GetBottomLevel(const Vec3& referencePos, int objflags); #if defined(USE_GEOM_CACHES) virtual IGeomCache* LoadGeomCache(const char* szFileName); virtual IGeomCache* FindGeomCacheByFilename(const char* szFileName); #endif virtual IStatObj* LoadDesignerObject(int nVersion, const char* szBinaryStream, int size); void AsyncOctreeUpdate(IRenderNode* pEnt, int nSID, int nSIDConsideredSafe, uint32 nFrameID, bool bUnRegisterOnly); bool UnRegisterEntityImpl(IRenderNode* pEnt); // Fast option - use if just ocean height required virtual float GetWaterLevel(); // This will return ocean height or water volume height, optional for accurate water height query virtual float GetWaterLevel(const Vec3* pvPos, IPhysicalEntity* pent = NULL, bool bAccurate = false); // Only use for Accurate query - this will return exact ocean height virtual float GetAccurateOceanHeight(const Vec3& pCurrPos) const; virtual CausticsParams GetCausticsParams() const; virtual OceanAnimationData GetOceanAnimationParams() const override; virtual void GetHDRSetupParams(Vec4 pParams[5]) const; virtual void CreateDecal(const CryEngineDecalInfo& Decal); int GetLegacyTerrainLevelData(AZ::IO::HandleType& fileHandle, STerrainInfo& terrainInfo , bool& bSectorPalettes, EEndian& eEndian , XmlNodeRef& surfaceTypesXmlNode) override; int GetLegacyTerrainLevelData(uint8*& octreeData, STerrainInfo& terrainInfo , bool& bSectorPalettes, EEndian& eEndian) override; virtual void SetSunDir(const Vec3& newSunOffset); virtual Vec3 GetSunDir() const; virtual Vec3 GetSunDirNormalized() const; virtual Vec3 GetRealtimeSunDirNormalized() const; virtual void SetSunColor(Vec3 vColor); Vec3 GetSunAnimColor() override; void SetSunAnimColor(const Vec3& sunAnimColor) override; float GetSunAnimSpeed() override; void SetSunAnimSpeed(float sunAnimSpeed) override; AZ::u8 GetSunAnimPhase() override; void SetSunAnimPhase(AZ::u8 sunAnimPhase) override; AZ::u8 GetSunAnimIndex() override; void SetSunAnimIndex(AZ::u8 sunAnimIndex) override; virtual void SetSSAOAmount(float fMul); virtual void SetSSAOContrast(float fMul); virtual void SetRainParams(const SRainParams& rainParams); virtual bool GetRainParams(SRainParams& rainParams); virtual void SetSnowSurfaceParams(const Vec3& vCenter, float fRadius, float fSnowAmount, float fFrostAmount, float fSurfaceFreezing); virtual bool GetSnowSurfaceParams(Vec3& vCenter, float& fRadius, float& fSnowAmount, float& fFrostAmount, float& fSurfaceFreezing); virtual void SetSnowFallParams(int nSnowFlakeCount, float fSnowFlakeSize, float fSnowFallBrightness, float fSnowFallGravityScale, float fSnowFallWindScale, float fSnowFallTurbulence, float fSnowFallTurbulenceFreq); virtual bool GetSnowFallParams(int& nSnowFlakeCount, float& fSnowFlakeSize, float& fSnowFallBrightness, float& fSnowFallGravityScale, float& fSnowFallWindScale, float& fSnowFallTurbulence, float& fSnowFallTurbulenceFreq); virtual void OnExplosion(Vec3 vPos, float fRadius, bool bDeformTerrain = true); //! For editor virtual void RemoveAllStaticObjects(int nSID); virtual void SetPhysMaterialEnumerator(IPhysMaterialEnumerator* pPhysMaterialEnumerator); virtual IPhysMaterialEnumerator* GetPhysMaterialEnumerator(); virtual void LoadMissionDataFromXMLNode(const char* szMissionName); void AddDynamicLightSource(const class CDLight& LSource, ILightSource* pEnt, int nEntityLightId, float fFadeout, const SRenderingPassInfo& passInfo); inline void AddLightToRenderer(const CDLight& pLight, float fMult, const SRenderingPassInfo& passInfo, const SRendItemSorter& rendItemSorter) { const uint32 nLightID = GetRenderer()->EF_GetDeferredLightsNum(); GetRenderer()->EF_AddDeferredLight(pLight, fMult, passInfo, rendItemSorter); Get3DEngine()->m_LightVolumesMgr.RegisterLight(pLight, nLightID, passInfo); m_nDeferredLightsNum++; } virtual void SetMaxViewDistanceScale(float fScale) { m_fMaxViewDistScale = fScale; } virtual float GetMaxViewDistance(bool bScaled = true); virtual const SFrameLodInfo& GetFrameLodInfo() const { return m_frameLodInfo; } virtual void SetFrameLodInfo(const SFrameLodInfo& frameLodInfo); virtual void SetFogColor(const Vec3& vFogColor); virtual Vec3 GetFogColor(); virtual float GetDistanceToSectorWithWater(); virtual void GetSkyLightParameters(Vec3& sunDir, Vec3& sunIntensity, float& Km, float& Kr, float& g, Vec3& rgbWaveLengths); virtual void SetSkyLightParameters(const Vec3& sunDir, const Vec3& sunIntensity, float Km, float Kr, float g, const Vec3& rgbWaveLengths, bool forceImmediateUpdate = false); void SetLightsHDRDynamicPowerFactor(const float value); virtual float GetLightsHDRDynamicPowerFactor() const; // Return true if tessellation is allowed (by cvars) into currently set shadow map LOD bool IsTessellationAllowedForShadowMap(const SRenderingPassInfo& passInfo) const; // Return true if tessellation is allowed for given render object virtual bool IsTessellationAllowed(const CRenderObject* pObj, const SRenderingPassInfo& passInfo, bool bIgnoreShadowPass = false) const; virtual void SetRenderNodeMaterialAtPosition(EERType eNodeType, const Vec3& vPos, _smart_ptr pMat); virtual void OverrideCameraPrecachePoint(const Vec3& vPos); virtual int AddPrecachePoint(const Vec3& vPos, const Vec3& vDir, float fTimeOut = 3.f, float fImportanceFactor = 1.0f); virtual void ClearPrecachePoint(int id); virtual void ClearAllPrecachePoints(); virtual void GetPrecacheRoundIds(int pRoundIds[MAX_STREAM_PREDICTION_ZONES]); virtual void TraceFogVolumes(const Vec3& vPos, const AABB& objBBox, SFogVolumeData& fogVolData, const SRenderingPassInfo& passInfo, bool fogVolumeShadingQuality); virtual Vec3 GetSunColor() const; virtual float GetSSAOAmount() const; virtual float GetSSAOContrast() const; virtual void FreeRenderNodeState(IRenderNode* pEnt); virtual const char* GetLevelFilePath(const char* szFileName); bool LoadCompiledOctreeForEditor() override; virtual bool SetStatInstGroup(int nGroupId, const IStatInstGroup& siGroup, int nSID); virtual bool GetStatInstGroup(int nGroupId, IStatInstGroup& siGroup, int nSID); virtual void ActivatePortal(const Vec3& vPos, bool bActivate, const char* szEntityName); virtual void GetMemoryUsage(ICrySizer* pSizer) const; virtual void GetResourceMemoryUsage(ICrySizer* pSizer, const AABB& cstAABB); virtual IVisArea* CreateVisArea(uint64 visGUID); virtual void DeleteVisArea(IVisArea* pVisArea); virtual void UpdateVisArea(IVisArea* pArea, const Vec3* pPoints, int nCount, const char* szName, const SVisAreaInfo& info, bool bReregisterObjects); virtual IClipVolume* CreateClipVolume(); virtual void DeleteClipVolume(IClipVolume* pClipVolume); virtual void UpdateClipVolume(IClipVolume* pClipVolume, _smart_ptr pRenderMesh, IBSPTree3D* pBspTree, const Matrix34& worldTM, bool bActive, uint32 flags, const char* szName); virtual void ResetParticlesAndDecals(); virtual IRenderNode* CreateRenderNode(EERType type); virtual void DeleteRenderNode(IRenderNode* pRenderNode); #if ENABLE_CRY_PHYSICS virtual void SetWind(const Vec3& vWind); #endif // ENABLE_CRY_PHYSICS virtual Vec3 GetWind(const AABB& box, bool bIndoors) const; virtual Vec3 GetGlobalWind(bool bIndoors) const; virtual bool SampleWind(Vec3* pSamples, int nSamples, const AABB& volume, bool bIndoors) const; void SetupBending(CRenderObject*& pObj, const IRenderNode* pNode, const float fRadiusVert, const SRenderingPassInfo& passInfo, bool alreadyDuplicated = false); virtual IVisArea* GetVisAreaFromPos(const Vec3& vPos); virtual bool IntersectsVisAreas(const AABB& box, void** pNodeCache = 0); virtual bool ClipToVisAreas(IVisArea* pInside, Sphere& sphere, Vec3 const& vNormal, void* pNodeCache = 0); virtual bool IsVisAreasConnected(IVisArea* pArea1, IVisArea* pArea2, int nMaxReqursion, bool bSkipDisabledPortals); void EnableOceanRendering(bool bOcean); // todo: remove virtual void AddTextureLoadHandler(ITextureLoadHandler* pHandler); virtual void RemoveTextureLoadHandler(ITextureLoadHandler* pHandler); virtual ITextureLoadHandler* GetTextureLoadHandlerForImage(const char* ext); virtual struct ILightSource* CreateLightSource(); virtual void DeleteLightSource(ILightSource* pLightSource); virtual bool RestoreTerrainFromDisk(int nSID); virtual void CheckMemoryHeap(); virtual int GetLoadedObjectCount(); virtual void GetLoadedStatObjArray(IStatObj** pObjectsArray, int& nCount); virtual void GetObjectsStreamingStatus(SObjectsStreamingStatus& outStatus); virtual void GetStreamingSubsystemData(int subsystem, SStremaingBandwidthData& outData); virtual void DeleteEntityDecals(IRenderNode* pEntity); virtual void DeleteDecalsInRange(AABB* pAreaBox, IRenderNode* pEntity); virtual void LockCGFResources(); virtual void UnlockCGFResources(); virtual void FreeUnusedCGFResources(); virtual void SerializeState(TSerialize ser); virtual void PostSerialize(bool bReading); virtual void SetStreamableListener(IStreamedObjectListener* pListener); ////////////////////////////////////////////////////////////////////////// // Materials access. virtual IMaterialHelpers& GetMaterialHelpers(); virtual IMaterialManager* GetMaterialManager(); ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// // ObjManager access. virtual IObjManager* GetObjManager() override; ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// // CGF Loader. ////////////////////////////////////////////////////////////////////////// virtual CContentCGF* CreateChunkfileContent(const char* filename); virtual void ReleaseChunkfileContent(CContentCGF*); virtual bool LoadChunkFileContent(CContentCGF* pCGF, const char* filename, bool bNoWarningMode = false, bool bCopyChunkFile = true); virtual bool LoadChunkFileContentFromMem(CContentCGF* pCGF, const void* pData, size_t nDataLen, uint32 nLoadingFlags, bool bNoWarningMode = false, bool bCopyChunkFile = true); ////////////////////////////////////////////////////////////////////////// virtual IChunkFile* CreateChunkFile(bool bReadOnly = false); ////////////////////////////////////////////////////////////////////////// // Chunk file writer. ////////////////////////////////////////////////////////////////////////// virtual ChunkFile::IChunkFileWriter* CreateChunkFileWriter(EChunkFileFormat eFormat, ICryPak* pPak, const char* filename) const; virtual void ReleaseChunkFileWriter(ChunkFile::IChunkFileWriter* p) const; ////////////////////////////////////////////////////////////////////////// // Post processing effects interfaces class IPostEffectGroupManager* GetPostEffectGroups() const override { return m_postEffectGroups.get(); } class IPostEffectGroup* GetPostEffectBaseGroup() const override { return m_postEffectBaseGroup; } // Most code should use either GetPostEffectGroups() or GetPostEffectBaseGroup() instead of these virtual void SetPostEffectParam(const char* pParam, float fValue, bool bForceValue = false) const; virtual void SetPostEffectParamVec4(const char* pParam, const Vec4& pValue, bool bForceValue = false) const; virtual void SetPostEffectParamString(const char* pParam, const char* pszArg) const; virtual void GetPostEffectParam(const char* pParam, float& fValue) const; virtual void GetPostEffectParamVec4(const char* pParam, Vec4& pValue) const; virtual void GetPostEffectParamString(const char* pParam, const char*& pszArg) const; virtual int32 GetPostEffectID(const char* pPostEffectName); virtual void ResetPostEffects(bool bOnSpecChange = false); virtual void DisablePostEffects(); virtual void SetShadowsGSMCache(bool bCache); virtual void SetCachedShadowBounds(const AABB& shadowBounds, float fAdditionalCascadesScale); virtual void SetRecomputeCachedShadows(uint nUpdateStrategy = 0); void SetShadowsCascadesBias(const float* pCascadeConstBias, const float* pCascadeSlopeBias); const float* GetShadowsCascadesConstBias() const { return m_pShadowCascadeConstBias; } const float* GetShadowsCascadesSlopeBias() const { return m_pShadowCascadeSlopeBias; } int GetShadowsCascadeCount(const CDLight* pLight) const; virtual uint32 GetObjectsByType(EERType objType, IRenderNode** pObjects); uint32 GetObjectsByTypeInBox(EERType objType, const AABB& bbox, IRenderNode** pObjects, ObjectTreeQueryFilterCallback filterCallback = nullptr) override; virtual uint32 GetObjectsInBox(const AABB& bbox, IRenderNode** pObjects = 0); void GetObjectsByTypeInBox(EERType objType, const AABB& bbox, PodArray* pLstObjects, ObjectTreeQueryFilterCallback filterCallback = nullptr) override; virtual uint32 GetObjectsByFlags(uint dwFlags, IRenderNode** pObjects = 0); virtual void OnObjectModified(IRenderNode* pRenderNode, uint dwFlags); virtual void ActivateObjectsLayer(uint16 nLayerId, bool bActivate, bool bPhys, bool bObjects, bool bStaticLights, const char* pLayerName, IGeneralMemoryHeap* pHeap = NULL, bool bCheckLayerActivation = true); virtual void GetLayerMemoryUsage(uint16 nLayerId, ICrySizer* pSizer, int* pNumBrushes, int* pNumDecals) const; virtual void SkipLayerLoading(uint16 nLayerId, bool bClearList); bool IsLayerSkipped(uint16 nLayerId); void ObjectsTreeMarkAsUncompiled(const IRenderNode* pRenderNode); ////////////////////////////////////////////////////////////////////////// const char* GetLevelFolder() { return m_szLevelFolder; } bool SaveCGF(std::vector& pObjs); virtual bool IsAreaActivationInUse() { return m_bAreaActivationInUse && GetCVars()->e_ObjectLayersActivation; } int GetCurrentLightSpec() { return CONFIG_VERYHIGH_SPEC; // very high spec. } bool CheckMinSpec(uint32 nMinSpec) override; void UpdateRenderingCamera(const char* szCallerName, const SRenderingPassInfo& passInfo); virtual void PrepareOcclusion(const CCamera& rCamera); virtual void EndOcclusion(); #ifndef _RELEASE void ProcessStreamingLatencyTest(const CCamera& camIn, CCamera& camOut, const SRenderingPassInfo& passInfo); #endif void ScreenShotHighRes(CStitchedImage* pStitchedImage, const int nRenderFlags, const SRenderingPassInfo& passInfo, uint32 SliceCount, f32 fTransitionSize); // cylindrical mapping made by multiple slices rendered and distorted // Returns: // true=mode is active, stop normal rendering, false=mode is not active bool ScreenShotPanorama(CStitchedImage* pStitchedImage, const int nRenderFlags, const SRenderingPassInfo& passInfo, uint32 SliceCount, f32 fTransitionSize); // Render simple top-down screenshot for map overviews bool ScreenShotMap(CStitchedImage* pStitchedImage, const int nRenderFlags, const SRenderingPassInfo& passInfo, uint32 SliceCount, f32 fTransitionSize); void ScreenshotDispatcher(const int nRenderFlags, const SRenderingPassInfo& passInfo); virtual void FillDebugFPSInfo(SDebugFPSInfo& info); void ClearDebugFPSInfo(bool bUnload = false) { m_fAverageFPS = 0.0f; m_fMinFPS = m_fMinFPSDecay = 999.f; m_fMaxFPS = m_fMaxFPSDecay = 0.0f; ClearPrecacheInfo(); if (bUnload) { stl::free_container(arrFPSforSaveLevelStats); } else { arrFPSforSaveLevelStats.clear(); } } void ClearPrecacheInfo() { m_nFramesSinceLevelStart = 0; m_nStreamingFramesSinceLevelStart = 0; m_bPreCacheEndEventSent = false; m_fTimeStateStarted = 0.0f; } virtual const CCamera& GetRenderingCamera() const { return m_RenderingCamera; } virtual float GetZoomFactor() const { return m_fZoomFactor; } virtual void Tick(); virtual void UpdateShaderItems(); void GetCollisionClass(SCollisionClass& collclass, int tableIndex); C3DEngine(ISystem* pSystem); ~C3DEngine(); const float GetGSMRange() override { return m_fGsmRange; } const float GetGSMRangeStep() override { return m_fGsmRangeStep; } float GetTerrainDetailMaterialsViewDistRatio() const override { return m_fTerrainDetailMaterialsViewDistRatio; } void UpdatePreRender(const SRenderingPassInfo& passInfo); void UpdatePostRender(const SRenderingPassInfo& passInfo); virtual void RenderScene(const int nRenderFlags, const SRenderingPassInfo& passInfo); virtual void RenderSceneReflection(const int nRenderFlags, const SRenderingPassInfo& passInfo); virtual void DebugDraw_UpdateDebugNode(); void DebugDraw_Draw(); bool IsOutdoorVisible(); void RenderSkyBox(_smart_ptr pMat, const SRenderingPassInfo& passInfo); int GetStreamingFramesSinceLevelStart() { return m_nStreamingFramesSinceLevelStart; } int GetRenderFramesSinceLevelStart() { return m_nFramesSinceLevelStart; } bool CreateDecalInstance(const CryEngineDecalInfo&DecalInfo, class CDecal* pCallerManagedDecal); //void CreateDecalOnCharacterComponents(ICharacterInstance * pChar, const struct CryEngineDecalInfo & decal); Vec3 GetTerrainSurfaceNormal(Vec3 vPos); void LoadEnvironmentSettingsFromXML(XmlNodeRef pInputNode, int nSID); #if defined(FEATURE_SVO_GI) void LoadTISettings(XmlNodeRef pInputNode); #endif void LoadDefaultAssets(); // access to components static CVars* GetCVars() { return m_pCVars; } ILINE CVisAreaManager* GetVisAreaManager() { return m_pVisAreaManager; } ILINE CClipVolumeManager* GetClipVolumeManager() { return m_pClipVolumeManager; } ILINE PodArray* GetLightEntities() { return &m_lstStaticLights; } ILINE IGeneralMemoryHeap* GetBreakableBrushHeap() { return m_pBreakableBrushHeap; } virtual void OnCameraTeleport(); bool m_bAreaActivationInUse; // Level info float m_fSkyBoxAngle, m_fSkyBoxStretching; float m_fMaxViewDistScale; float m_fMaxViewDistHighSpec; float m_fMaxViewDistLowSpec; float m_fTerrainDetailMaterialsViewDistRatio; float m_volFogGlobalDensity; float m_volFogGlobalDensityMultiplierLDR; float m_volFogFinalDensityClamp; float m_fCloudShadingSunLightMultiplier; float m_fCloudShadingSkyLightMultiplier; Vec3 m_vCloudShadingCustomSunColor; Vec3 m_vCloudShadingCustomSkyColor; Vec3 m_vFogColor; Vec3 m_vDefFogColor; Vec3 m_vSunDir; Vec3 m_vSunDirNormalized; float m_fSunDirUpdateTime; Vec3 m_vSunDirRealtime; Vec3 m_volFogRamp; Vec3 m_volFogShadowRange; Vec3 m_volFogShadowDarkening; Vec3 m_volFogShadowEnable; Vec3 m_volFog2CtrlParams; Vec3 m_volFog2ScatteringParams; Vec3 m_volFog2Ramp; Vec3 m_volFog2Color; Vec3 m_volFog2GlobalDensity; Vec3 m_volFog2HeightDensity; Vec3 m_volFog2HeightDensity2; Vec3 m_volFog2Color1; Vec3 m_volFog2Color2; Vec3 m_nightSkyHorizonCol; Vec3 m_nightSkyZenithCol; float m_nightSkyZenithColShift; float m_nightSkyStarIntensity; Vec3 m_nightMoonCol; float m_nightMoonSize; Vec3 m_nightMoonInnerCoronaCol; float m_nightMoonInnerCoronaScale; Vec3 m_nightMoonOuterCoronaCol; float m_nightMoonOuterCoronaScale; float m_moonRotationLatitude; float m_moonRotationLongitude; Vec3 m_moonDirection; int m_nWaterBottomTexId; int m_nNightMoonTexId; float m_fSunClipPlaneRange; float m_fSunClipPlaneRangeShift; bool m_bSunShadows; int m_nCloudShadowTexId; float m_fGsmRange; float m_fGsmRangeStep; float m_fShadowsConstBias; float m_fShadowsSlopeBias; int m_nSunAdditionalCascades; int m_nGsmCache; Vec3 m_oceanFogColor; Vec3 m_oceanFogColorShallow; float m_oceanFogDensity; float m_skyboxMultiplier; float m_dayNightIndicator; bool m_bHeightMapAoEnabled; Vec3 m_fogColor2; Vec3 m_fogColorRadial; Vec3 m_volFogHeightDensity; Vec3 m_volFogHeightDensity2; Vec3 m_volFogGradientCtrl; private: float m_oceanWindDirection; float m_oceanWindSpeed; float m_oceanWavesSpeed; float m_oceanWavesAmount; float m_oceanWavesSize; public: float m_dawnStart; float m_dawnEnd; float m_duskStart; float m_duskEnd; float m_fParticlesAmbientMultiplier; float m_fParticlesLightMultiplier; // film characteristic curve tweakables Vec4 m_vHDRFilmCurveParams; Vec3 m_vHDREyeAdaptation; Vec3 m_vHDREyeAdaptationLegacy; float m_fHDRBloomAmount; // hdr color grading Vec3 m_vColorBalance; float m_fHDRSaturation; // default post effect group path const char* m_defaultPostEffectGroup = "Libs/PostEffectGroups/Default.xml"; #ifndef _RELEASE CDebugDrawListMgr m_DebugDrawListMgr; #endif #define MAX_SHADOW_CASCADES_NUM 20 float m_pShadowCascadeConstBias[MAX_SHADOW_CASCADES_NUM]; float m_pShadowCascadeSlopeBias[MAX_SHADOW_CASCADES_NUM]; AABB m_CachedShadowsBounds; uint m_nCachedShadowsUpdateStrategy; float m_fCachedShadowsCascadeScale; // special case for combat mode adjustments float m_fSaturation; Vec4 m_pPhotoFilterColor; float m_fPhotoFilterColorDensity; float m_fGrainAmount; float m_fSunSpecMult; // Level shaders _smart_ptr m_pTerrainWaterMat; _smart_ptr m_pSkyMat; _smart_ptr m_pSkyLowSpecMat; _smart_ptr m_pSunMat; // Fog Materials _smart_ptr< IMaterial > m_pMatFogVolEllipsoid; _smart_ptr< IMaterial > m_pMatFogVolBox; void CleanLevelShaders() { m_pTerrainWaterMat = 0; m_pSkyMat = 0; m_pSkyLowSpecMat = 0; m_pSunMat = 0; m_pMatFogVolEllipsoid = 0; m_pMatFogVolBox = 0; } // Render elements CRESky* m_pRESky; CREHDRSky* m_pREHDRSky; int m_nDeferredLightsNum; mutable Vec3* m_pWindSamplePositions; mutable size_t m_nWindSamplePositions; // functions SRenderingPass virtual CCamera* GetRenderingPassCamera(const CCamera& rCamera); virtual void GetSvoStaticTextures(I3DEngine::SSvoStaticTexInfo& svoInfo, PodArray* pLightsTI_S, PodArray* pLightsTI_D); virtual void GetSvoBricksForUpdate(PodArray& arrNodeInfo, bool getDynamic); bool IsTerrainSyncLoad() override { return m_bContentPrecacheRequested && GetCVars()->e_AutoPrecacheTerrainAndProcVeget; } bool IsShadersSyncLoad() { return m_bContentPrecacheRequested && GetCVars()->e_AutoPrecacheTexturesAndShaders; } bool IsStatObjSyncLoad() { return m_bContentPrecacheRequested && GetCVars()->e_AutoPrecacheCgf; } float GetAverageCameraSpeed() { return m_fAverageCameraSpeed; } Vec3 GetAverageCameraMoveDir() { return m_vAverageCameraMoveDir; } typedef std::map ShadowFrustumListsCacheUsers; ShadowFrustumListsCacheUsers m_FrustumsCacheUsers[2]; class CStatObjFoliage* m_pFirstFoliage, * m_pLastFoliage; PodArray m_arrEntsInFoliage; void RemoveEntInFoliage(int i, IPhysicalEntity* pent = 0); struct ILightSource* GetSunEntity(); void OnCasterDeleted(IShadowCaster* pCaster) override; CCullBuffer* GetCoverageBuffer() { return m_pCoverageBuffer; } void InitShadowFrustums(const SRenderingPassInfo& passInfo); /////////////////////////////////////////////////////////////////////////////// virtual void GetLightVolumes(threadID nThreadID, SLightVolume*& pLightVols, uint32& nNumVols); virtual uint16 RegisterVolumeForLighting(const Vec3& vPos, f32 fRadius, uint8 nClipVolumeRef, const SRenderingPassInfo& passInfo); CLightVolumesMgr m_LightVolumesMgr; /////////////////////////////////////////////////////////////////////////////// void RemoveEntityLightSources(IRenderNode* pEntity); int GetRealLightsNum() { return m_nRealLightsNum; } void SetupClearColor(); void CheckAddLight(CDLight* pLight, const SRenderingPassInfo& passInfo); void DrawTextRightAligned(const float x, const float y, const char* format, ...) PRINTF_PARAMS(4, 5); void DrawTextRightAligned(const float x, const float y, const float scale, const ColorF& color, const char* format, ...) PRINTF_PARAMS(6, 7); void DrawTextLeftAligned(const float x, const float y, const float scale, const ColorF& color, const char* format, ...) PRINTF_PARAMS(6, 7); void DrawTextAligned(int flags, const float x, const float y, const float scale, const ColorF& color, const char* format, ...) PRINTF_PARAMS(7, 8); void DrawBBoxHelper(const Vec3& vMin, const Vec3& vMax, ColorB col = Col_White) override { DrawBBox(vMin, vMax, col); } void DrawBBoxHelper(const AABB& box, ColorB col = Col_White) override { DrawBBox(box, col); } float GetLightAmount(CDLight* pLight, const AABB& objBox); IStatObj* CreateStatObj(); virtual IStatObj* CreateStatObjOptionalIndexedMesh(bool createIndexedMesh); IStatObj* UpdateDeformableStatObj(IGeometry* pPhysGeom, bop_meshupdate* pLastUpdate = 0, IFoliage* pSrcFoliage = 0); // Creates a new indexed mesh. IIndexedMesh* CreateIndexedMesh(); void InitMaterialDefautMappingAxis(_smart_ptr pMat) override; _smart_ptr MakeSystemMaterialFromShaderHelper(const char* sShaderName, SInputShaderResources* Res = NULL) override { return MakeSystemMaterialFromShader(sShaderName, Res); } bool CheckMinSpecHelper(uint32 nMinSpec) override { return CheckMinSpec(nMinSpec); } virtual ITerrain* GetITerrain() { AZ_Warning("LegacyTerrain", false, "C3DEngine::GetITerrain is deprecated. Use AzFramework::Terrain::TerrainDataRequestBus or LegacyTerrain::LegacyTerrainDataRequestBus instead."); return nullptr; } virtual IVisAreaManager* GetIVisAreaManager() { return (IVisAreaManager*)m_pVisAreaManager; } virtual IMergedMeshesManager* GetIMergedMeshesManager() { return (IMergedMeshesManager*)m_pMergedMeshesManager; } bool CreateOcean(_smart_ptr pTerrainWaterMat, float waterLevel) override; void DeleteOcean() override; void ChangeOceanMaterial(_smart_ptr pMat) override; void ChangeOceanWaterLevel(float fWaterLevel) override; bool LoadOctree(XmlNodeRef pDoc, std::vector** ppStatObjTable, std::vector<_smart_ptr >** ppMatTable, int nSID); bool LoadVisAreas(std::vector** ppStatObjTable, std::vector<_smart_ptr >** ppMatTable); bool LoadUsedShadersList(); bool PrecreateDecals(); #if ENABLE_CRY_PHYSICS void LoadPhysicsData(); void UnloadPhysicsData(); #endif void LoadFlaresData(); void FreeFoliages(); void LoadCollisionClasses(XmlNodeRef node); virtual void PrecacheLevel(bool bPrecacheAllVisAreas, Vec3* pPrecachePoints, int nPrecachePointsNum); virtual void ProposeContentPrecache() { m_bContentPrecacheRequested = true; } bool IsContentPrecacheRequested() { return m_bContentPrecacheRequested; } virtual ITimeOfDay* GetTimeOfDay(); virtual void SetSkyMaterialPath(const string& skyMaterialPath); virtual void SetSkyLowSpecMaterialPath(const string& skyMaterialPath); virtual void LoadSkyMaterial(); virtual _smart_ptr GetSkyMaterial(); void SetSkyMaterial(_smart_ptr pSkyMat) override; bool IsHDRSkyMaterial(_smart_ptr pMat) const; using I3DEngine::SetGlobalParameter; virtual void SetGlobalParameter(E3DEngineParameter param, const Vec3& v); using I3DEngine::GetGlobalParameter; virtual void GetGlobalParameter(E3DEngineParameter param, Vec3& v); virtual void SetShadowMode(EShadowMode shadowMode) { m_eShadowMode = shadowMode; } virtual EShadowMode GetShadowMode() const { return m_eShadowMode; } virtual void AddPerObjectShadow(IShadowCaster* pCaster, float fConstBias, float fSlopeBias, float fJitter, const Vec3& vBBoxScale, uint nTexSize); virtual void RemovePerObjectShadow(IShadowCaster* pCaster); virtual struct SPerObjectShadow* GetPerObjectShadow(IShadowCaster* pCaster); virtual void GetCustomShadowMapFrustums(ShadowMapFrustum*& arrFrustums, int& nFrustumCount); virtual int SaveStatObj(IStatObj* pStatObj, TSerialize ser); virtual IStatObj* LoadStatObj(TSerialize ser); virtual bool CheckIntersectClouds(const Vec3& p1, const Vec3& p2); virtual void OnRenderMeshDeleted(IRenderMesh* pRenderMesh); virtual bool RayObjectsIntersection2D(Vec3 vStart, Vec3 vEnd, Vec3& vHitPoint, EERType eERType); virtual bool RenderMeshRayIntersection(IRenderMesh* pRenderMesh, SRayHitInfo& hitInfo, _smart_ptr pCustomMtl = 0); virtual IParticleManager* GetParticleManager() { return m_pPartManager; } virtual IOpticsManager* GetOpticsManager() { return m_pOpticsManager; } virtual void RegisterForStreaming(IStreamable* pObj); virtual void UnregisterForStreaming(IStreamable* pObj); virtual void PrecacheCharacter(IRenderNode* pObj, const float fImportance, ICharacterInstance* pCharacter, _smart_ptr pSlotMat, const Matrix34& matParent, const float fEntDistance, const float fScale, int nMaxDepth, bool bForceStreamingSystemUpdate, const SRenderingPassInfo& passInfo); virtual void PrecacheRenderNode(IRenderNode* pObj, float fEntDistanceReal); void MarkRNTmpDataPoolForReset() { m_bResetRNTmpDataPool = true; } SBending* GetBendingEntry(SBending*, const SRenderingPassInfo& passInfo); static void GetObjectsByTypeGlobal(PodArray& lstObjects, EERType objType, const AABB* pBBox, ObjectTreeQueryFilterCallback filterCallback = nullptr); static void MoveObjectsIntoListGlobal(PodArray* plstResultEntities, const AABB* pAreaBox, bool bRemoveObjects = false, bool bSkipDecals = false, bool bSkip_ERF_NO_DECALNODE_DECALS = false, bool bSkipDynamicObjects = false, EERType eRNType = eERType_TypesNum); bool IsObjectTreeReady() override { return m_pObjectsTree != nullptr; } IOctreeNode* GetIObjectTree() override { return (IOctreeNode*)m_pObjectsTree; } inline COctreeNode* GetObjectTree() { return m_pObjectsTree; } inline void SetObjectTree(COctreeNode* tree) { m_pObjectsTree = tree; } int m_idMatLeaves; // for shooting foliages bool m_bResetRNTmpDataPool; float m_fRefreshSceneDataCVarsSumm; int m_nRenderTypeEnableCVarSum; PodArray m_lstAlwaysVisible; PodArray m_lstKilledVegetations; PodArray m_lstPerObjectShadows; PodArray m_lstCustomShadowFrustums; int m_nCustomShadowFrustumCount; CryCriticalSection m_checkCreateRNTmpData; CThreadSafeRendererContainer m_elementFrameInfo; CRNTmpData m_LTPRootFree, m_LTPRootUsed; void CreateRNTmpData(CRNTmpData** ppInfo, IRenderNode* pRNode, const SRenderingPassInfo& passInfo); void CheckCreateRNTmpData(CRNTmpData** ppInfo, IRenderNode* pRNode, const SRenderingPassInfo& passInfo) override { // Lock to avoid a situation where two threads simultaneously find that *ppinfo is null, // which would result in two CRNTmpData objects for the same owner which eventually leads to a crash AUTO_LOCK(m_checkCreateRNTmpData); if (CRNTmpData* tmpData = (*ppInfo)) { m_elementFrameInfo[tmpData->nFrameInfoId].nLastUsedFrameId = passInfo.GetMainFrameID(); } else { CreateRNTmpData(ppInfo, pRNode, passInfo); } } uint32 GetFrameInfoId(CRNTmpData** ppRNTmpData, uint32 createdFrameID) { size_t index = 0; SFrameInfo* pFrameInfo = m_elementFrameInfo.push_back_new(index); pFrameInfo->nCreatedFrameId = createdFrameID; pFrameInfo->nLastUsedFrameId = createdFrameID; pFrameInfo->ppRNTmpData = ppRNTmpData; pFrameInfo->bIsValid = true; return index; } void FreeRNTmpData(CRNTmpData** ppInfo); void FreeRNTmpDataPool(); void UpdateRNTmpDataPool(bool bFreeAll); // CPoolAllocator m_RNTmpDataPools; void UpdateStatInstGroups(); void UpdateRenderTypeEnableLookup(); void ProcessOcean(const SRenderingPassInfo& passInfo); void ReRegisterKilledVegetationInstances(); Vec3 GetEntityRegisterPoint(IRenderNode* pEnt); virtual void RenderRenderNode_ShadowPass(IShadowCaster* pRNode, const SRenderingPassInfo& passInfo, AZ::LegacyJobExecutor* pJobExecutor); void ProcessCVarsChange(); ILINE int GetGeomDetailScreenRes() { return GetCVars()->e_ForceDetailLevelForScreenRes ? GetCVars()->e_ForceDetailLevelForScreenRes : GetRenderer()->GetWidth(); } int GetBlackTexID() { return m_nBlackTexID; } int GetBlackCMTexID() { return m_nBlackCMTexID; } virtual void SyncProcessStreamingUpdate(); virtual void SetScreenshotCallback(IScreenshotCallback* pCallback); virtual IDeferredPhysicsEventManager* GetDeferredPhysicsEventManager() { return m_pDeferredPhysicsEventManager; } void PrintDebugInfo(const SRenderingPassInfo& passInfo); SImageSubInfo* RegisterImageInfo(byte** pMips, int nDim, const char* pName); SImageSubInfo* GetImageInfo(const char* pName); std::map m_imageInfos; byte** AllocateMips(byte* pImage, int nDim, byte** pImageMips); IScreenshotCallback* m_pScreenshotCallback; OcclusionTestClient m_OceanOcclTestVar; bool m_bInShutDown; bool m_bInUnload; bool m_bInLoad; IDeferredPhysicsEventManager* m_pDeferredPhysicsEventManager; std::set m_skipedLayers; IGeneralMemoryHeap* m_pBreakableBrushHeap; AZStd::mutex m_statObjQueueLock; std::queue m_statObjLoadRequests; typedef std::list TTextureLoadHandlers; TTextureLoadHandlers m_textureLoadHandlers; class PhysicsAreaUpdates { public: void SetAreaDirty(const SAreaChangeRecord& rec); uint32 CreateProxy(const IRenderNode* pRenderNode, uint16 uPhysicsMask); void UpdateProxy(const IRenderNode* pRenderNode, uint32 nProxyId); void ResetProxy(uint32 proxyId); void Update(); void Reset(); void GarbageCollect(); CryCriticalSection m_Mutex; private: CThreadSafeRendererContainer m_Proxies; PodArray m_DirtyAreas; }; PhysicsAreaUpdates& GetPhysicsAreaUpdates() { return m_PhysicsAreaUpdates; } // RoadRenderNode Recompile Queue void RoadRenderNodeRebuildQueue_Add(CRoadRenderNode* roadRenderNodePtr); void RoadRenderNodeRebuildQueue_Remove(CRoadRenderNode* roadRenderNodePtr); //I3DEngine Overrides START int GetOctreeCompiledDataSize(SHotUpdateInfo* pExportInfo) override; bool SetOctreeCompiledData(byte* pData, int nDataSize, std::vector** ppStatObjTable, std::vector<_smart_ptr >** ppMatTable, bool bHotUpdate, SHotUpdateInfo* pExportInfo, bool loadTerrainMacroTexture) override; bool GetOctreeCompiledData(byte* pData, int nDataSize, std::vector** ppStatObjTable, std::vector<_smart_ptr >** ppMatTable, std::vector** ppStatInstGroupTable, EEndian eEndian, SHotUpdateInfo* pExportInfo) override; void GetStatObjAndMatTables(DynArray* pStatObjTable, DynArray<_smart_ptr >* pMatTable, DynArray* pStatInstGroupTable, uint32 nObjTypeMask) override; IRenderNode* AddVegetationInstance(int nStaticGroupID, const Vec3& vPos, const float fScale, uint8 ucBright, uint8 angle, uint8 angleX, uint8 angleY) override; void WaitForCullingJobsCompletion() override; void ClipTriangleHelper(const PodArray& lstInds, const Plane pPlanes[4], PodArray& lstVerts, PodArray& lstClippedInds) const override; //I3DEngine Overrides END private: // RoadRenderNode Management PodArray m_lstRoadRenderNodesForUpdate; // Update any pending RoadRenderNodes // Standalone Client: updates one RoadRenderNode at a time // Editor: updates all RoadRenderNodes // Returns true if the RoadRenderNode update queue is not empty bool RoadRenderNodeRebuildQueue_Update(); // IProcess Implementation void SetFlags(int flags) { m_nFlags = flags; } int GetFlags(void) { return m_nFlags; } int m_nFlags; COctreeNode* m_pObjectsTree; std::vector arrFPSforSaveLevelStats; PodArray m_arrProcessStreamingLatencyTestResults; PodArray m_arrProcessStreamingLatencyTexNum; // fields which are used by SRenderingPass to store over frame information CThreadSafeRendererContainer m_RenderingPassCameras[2]; // camera storage for SRenderingPass, the cameras cannot be stored on stack to allow job execution float m_fZoomFactor; // zoom factor of m_RenderingCamera // cameras used by 3DEngine CCamera m_RenderingCamera; // Camera used for Rendering on 3DEngine Side, normally equal to the view camera, except if frozen with e_camerafreeze PodArray m_deferredRenderComponentStreamingPriorityUpdates; // deferred streaming priority updates for newly seen CComponentRenders float m_fLightsHDRDynamicPowerFactor; // lights hdr exponent/exposure int m_nBlackTexID; int m_nBlackCMTexID; char m_sGetLevelFilePathTmpBuff[AZ_MAX_PATH_LEN]; char m_szLevelFolder[_MAX_PATH]; bool m_bOcean; // todo: remove // Ocean Caustics - Should be removed once the Ocean Gem is done and the feature toggle for it is removed. float m_oceanCausticsDistanceAtten; float m_oceanCausticsTiling; float m_oceanCausticDepth; float m_oceanCausticIntensity; Vec3 m_vSkyHightlightPos; Vec3 m_vSkyHightlightCol; float m_fSkyHighlightSize; Vec3 m_vAmbGroundCol; float m_fAmbMaxHeight; float m_fAmbMinHeight; #if ENABLE_CRY_PHYSICS IPhysicalEntity* m_pGlobalWind; Vec3 m_vWindSpeed; #endif uint8 m_nOceanRenderFlags; Vec3 m_vPrevMainFrameCamPos; float m_fAverageCameraSpeed; Vec3 m_vAverageCameraMoveDir; EShadowMode m_eShadowMode; bool m_bLayersActivated; bool m_bContentPrecacheRequested; bool m_bTerrainTextureStreamingInProgress; bool m_bSegmentOperationInProgress; // interfaces IPhysMaterialEnumerator* m_pPhysMaterialEnumerator; // data containers int m_nRealLightsNum; PodArray m_lstStaticLights; PodArray m_collisionClasses; #define MAX_LIGHTS_NUM 32 PodArray m_arrLightProjFrustums; class CTimeOfDay* m_pTimeOfDay; std::unique_ptr m_postEffectGroups; class IPostEffectGroup* m_postEffectBaseGroup; ICVar* m_pLightQuality; AZStd::unique_ptr m_vegetationPoolManager; // FPS for savelevelstats float m_fAverageFPS; float m_fMinFPS, m_fMinFPSDecay; float m_fMaxFPS, m_fMaxFPSDecay; int m_nFramesSinceLevelStart; int m_nStreamingFramesSinceLevelStart; bool m_bPreCacheEndEventSent; float m_fTimeStateStarted; uint32 m_nRenderWorldUSecs; SFrameLodInfo m_frameLodInfo; ITexture* m_ptexIconLowMemoryUsage; ITexture* m_ptexIconAverageMemoryUsage; ITexture* m_ptexIconHighMemoryUsage; ITexture* m_ptexIconEditorConnectedToConsole; std::vector m_decalRenderNodes; // list of registered decal render nodes, used to clean up longer not drawn decals class PhysicsAreaUpdatesHandler; AZStd::unique_ptr m_physicsAreaUpdatesHandler; PhysicsAreaUpdates m_PhysicsAreaUpdates; string m_skyMatName; string m_skyLowSpecMatName; // Variable to keep track if the cvar e_SkyType has changed, which may cause the engine to load a different sky material int m_previousSkyType = -1; //Bending Pools contain the per frame Vegetation, Decals, etc. structures. Each Engine-frame the next buffer is // cleared and set as the current in a ring and page-allocated to fit the needs of the current frame. static const int NUM_BENDING_POOLS = 4; CThreadSafeRendererContainer m_bendingPool[NUM_BENDING_POOLS]; int m_bendingPoolIdx; bool m_levelLoaded; // not sorted void LoadTimeOfDaySettingsFromXML(XmlNodeRef node); char* GetXMLAttribText(XmlNodeRef pInputNode, const char* szLevel1, const char* szLevel2, const char* szDefaultValue); char* GetXMLAttribText(XmlNodeRef pInputNode, const char* szLevel1, const char* szLevel2, const char* szLevel3, const char* szDefaultValue); // without calling high level functions like panorama screenshot void RenderInternal(const int nRenderFlags, const SRenderingPassInfo& passInfo, const char* szDebugName); bool IsCameraAnd3DEngineInvalid(const SRenderingPassInfo& passInfo, const char* szCaller); ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// // StatObjBus MultiHandler: void OnStatObjReloaded() override; ////////////////////////////////////////////////////////////////////////// void ResetCasterCombinationsCache(); void DeleteAllStaticLightSources(); void LoadParticleEffects(const char* szFolderName); void UpdateSun(const SRenderingPassInfo& passInfo); void SubmitSun(const SRenderingPassInfo& passInfo); CCullBuffer* m_pCoverageBuffer; struct CLightEntity* m_pSun; void UpdateMoonDirection(); // Copy objects from tree void CopyObjectsByType(EERType objType, const AABB* pBox, PodArray* plistObjects, ObjectTreeQueryFilterCallback filterCallback = nullptr); void CopyObjects(const AABB* pBox, PodArray* plistObjects); void CleanUpOldDecals(); template using LoadStatObjFunc = TReturn(CObjManager::*)(const char* filename, const char* _szGeomName, IStatObj::SSubObject** ppSubObject, bool bUseStreaming, unsigned long nLoadingFlags, const void* pData, int nDataSize, const char* szBlockName); template TReturn LoadStatObjInternal(const char* fileName, const char* geomName, IStatObj::SSubObject** subObject, bool useStreaming, unsigned long loadingFlags, LoadStatObjFunc loadStatObjFunc, const void* data = nullptr, int dataSize = 0); bool RemoveObjectsInArea(Vec3 vExploPos, float fExploRadius); /////////////////////////////////////////////////////////////////////////// // Octree Loading/Saving related START /////////////////////////////////////////////////////////////////////////// //! Reads STerrainInfo from the compiled octree data file, and seeks within the compiled octree file //! until positioned at the first byte of the terrain heightmap data. //! //! @fileHandle [Out] Returns the open file handle pointing to the first byte of terrain data. It is the caller responsibility //! to close the file handle. //! @terrainInfo [Out] Returns the parsed STerrainInfo from the octree file. //! @bSectorPalettes [Out] //! @eEndian [Out] The endianess of the octree data. //! //! Returns: //! The number of bytes left in @fileHandle. int GetLegacyTerrainDataFromCompiledOctreeFile(AZ::IO::HandleType& fileHandle, STerrainInfo& terrainInfo, bool& bSectorPalettes, EEndian& eEndian); //! Reads STerrainInfo from a buffer that represents octree data, and seeks within the buffer //! until positioned at the first byte of the terrain heightmap data. //! //! @octreeData [In & Out] Initially it is the starting address of the octree data. //! Upon return points to the first byte of the terrain heightmap data. //! @terrainInfo [Out] Returns the parsed STerrainInfo from the @octreeData buffer. //! @bSectorPalettes [Out] //! @eEndian [Out] The endianess of the octree data. //! //! Returns: //! The number of bytes left to read in @octreeData. int GetLegacyTerrainDataFromOctreeBuffer(uint8*& octreeData, STerrainInfo& terrainInfo, bool& bSectorPalettes, EEndian& eEndian); //! Skips all the data from a fileHandle or buffer until finding the first byte of terrain heightmap data. template int SeekTerrainDataInOctree(T& handle, STerrainChunkHeader* pOctreeChunkHeader, int nDataSize, EEndian eEndian); //! initialWorldSize: in Meters. bool CreateOctree(float initialWorldSize); void DestroyOctree(); //!Returns the number of nodes in the Quadtree as if the terrain was actually loaded. template int SkipTerrainData_T(T& f, int& nDataSize, const STerrainInfo& terrainInfo, bool bHotUpdate, bool bHMap, bool bSectorPalettes, EEndian eEndian, SHotUpdateInfo* pExportInfo); void GetEmptyTerrainCompiledData(byte*& pData, int &nDataSize, EEndian eEndian); template bool LoadOctreeInternal_T(XmlNodeRef pDoc, T& f, int& nDataSize, STerrainChunkHeader* pOctreeChunkHeader, std::vector** ppStatObjTable, std::vector<_smart_ptr >** ppMatTable, bool bHotUpdate, SHotUpdateInfo* pExportInfo, bool loadTerrainMacroTexture = true); bool LoadOctreeInternal(XmlNodeRef pDoc, AZ::IO::HandleType fileHandle, int nDataSize, STerrainChunkHeader* pOctreeChunkHeader, std::vector** ppStatObjTable, std::vector<_smart_ptr >** ppMatTable); void GetVegetationMaterials(std::vector<_smart_ptr >*& pMatTable); void LoadVegetationData(PodArray& rTable, PodArray& lstFileChunks, int i); int GetTablesSize(SHotUpdateInfo* pExportInfo); void SaveTables(byte*& pData, int& nDataSize, std::vector*& pStatObjTable, std::vector<_smart_ptr >*& pMatTable, std::vector*& pStatInstGroupTable, EEndian eEndian, SHotUpdateInfo* pExportInfo); /////////////////////////////////////////////////////////////////////////// // Octree Loading/Saving related END /////////////////////////////////////////////////////////////////////////// }; #endif // CRYINCLUDE_CRY3DENGINE_3DENGINE_H