Integrating up through commit 90f050496

This commit is contained in:
alexpete
2021-04-07 14:03:29 -07:00
parent 8f2ed080a9
commit c2cbd430fe
2694 changed files with 285622 additions and 176874 deletions
+3 -3
View File
@@ -559,7 +559,7 @@ public:
virtual bool Init();
virtual void OnFrameStart();
virtual void Update();
virtual void RenderWorld(const int nRenderFlags, const SRenderingPassInfo& passInfo, const char* szDebugName);
virtual void RenderWorld(int nRenderFlags, const SRenderingPassInfo& passInfo, const char* szDebugName);
virtual void PreWorldStreamUpdate(const CCamera& cam);
virtual void WorldStreamUpdate();
virtual void ShutDown();
@@ -570,7 +570,7 @@ public:
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 DisplayInfo(float& fTextPosX, float& fTextPosY, float& fTextStepY, bool bEnhanced);
virtual void DisplayMemoryStatistics();
virtual void SetupDistanceFog();
virtual IStatObj* LoadStatObjUnsafeManualRef(const char* fileName, const char* geomName = nullptr, /*[Out]*/ IStatObj::SSubObject** subObject = nullptr,
@@ -893,7 +893,7 @@ public:
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 RenderSceneReflection(int nRenderFlags, const SRenderingPassInfo& passInfo);
virtual void DebugDraw_UpdateDebugNode();
void DebugDraw_Draw();
+103 -65
View File
@@ -38,7 +38,9 @@
#include <I3DEngine.h>
#include <LoadScreenBus.h>
#include <StatObjBus.h>
#include "AzCore/Component/TickBus.h"
#include <AzCore/Component/TickBus.h>
#include <AzFramework/API/ApplicationAPI.h>
//------------------------------------------------------------------------------
#define LEVEL_DATA_FILE "LevelData.xml"
@@ -154,6 +156,9 @@ bool C3DEngine::InitLevelForEditor([[maybe_unused]] const char* szFolderName, [[
ClearDebugFPSInfo();
bool usePrefabSystemEnabled = false;
AzFramework::ApplicationRequests::Bus::BroadcastResult(
usePrefabSystemEnabled, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
if (!szFolderName || !szFolderName[0])
{
@@ -161,7 +166,7 @@ bool C3DEngine::InitLevelForEditor([[maybe_unused]] const char* szFolderName, [[
return 0;
}
if (!szMissionName || !szMissionName[0])
if (!usePrefabSystemEnabled && (!szMissionName || !szMissionName[0]))
{
Warning("C3DEngine::LoadLevel: Mission name is not specified");
}
@@ -248,6 +253,17 @@ bool C3DEngine::LevelLoadingInProgress()
bool C3DEngine::LoadCompiledOctreeForEditor()
{
bool usePrefabSystemForLevels = false;
AzFramework::ApplicationRequests::Bus::BroadcastResult(
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
if (usePrefabSystemForLevels)
{
// Prefab levels don't use any of the legacy level data.
return true;
}
// Load LevelData.xml File.
XmlNodeRef xmlLevelData = GetSystem()->LoadXmlFromFile(GetLevelFilePath(LEVEL_DATA_FILE));
@@ -257,18 +273,8 @@ bool C3DEngine::LoadCompiledOctreeForEditor()
return false;
}
std::vector<struct IStatObj*>* pStatObjTable = NULL;
std::vector<_smart_ptr<IMaterial> >* pMatTable = NULL;
int nSID = 0;
XmlNodeRef nodeRef = xmlLevelData->findChild("SurfaceTypes");
LoadCollisionClasses(xmlLevelData->findChild("CollisionClasses"));
SAFE_DELETE(pStatObjTable);
SAFE_DELETE(pMatTable);
return true;
}
@@ -617,6 +623,11 @@ bool C3DEngine::LoadLevel(const char* szFolderName, const char* szMissionName)
GetISystem()->LoadConfiguration(GetLevelFilePath(LEVEL_CONFIG_FILE));
}
bool usePrefabSystemForLevels = false;
AzFramework::ApplicationRequests::Bus::BroadcastResult(
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
if (!usePrefabSystemForLevels)
{ // check is LevelData.xml file exist
char sMapFileName[_MAX_PATH];
cry_strcpy(sMapFileName, m_szLevelFolder);
@@ -659,12 +670,16 @@ bool C3DEngine::LoadLevel(const char* szFolderName, const char* szMissionName)
}
// Load LevelData.xml File.
XmlNodeRef xmlLevelData = GetSystem()->LoadXmlFromFile(GetLevelFilePath(LEVEL_DATA_FILE));
if (xmlLevelData == 0)
XmlNodeRef xmlLevelData;
if (!usePrefabSystemForLevels)
{
Error("C3DEngine::LoadLevel: xml file not found (files missing?)"); // files missing ?
return false;
xmlLevelData = GetSystem()->LoadXmlFromFile(GetLevelFilePath(LEVEL_DATA_FILE));
if (xmlLevelData == 0)
{
Error("C3DEngine::LoadLevel: xml file not found (files missing?)"); // files missing ?
return false;
}
}
// re-create decal manager
@@ -690,41 +705,48 @@ bool C3DEngine::LoadLevel(const char* szFolderName, const char* szMissionName)
m_pObjManager->PreloadLevelObjects();
}
std::vector<struct IStatObj*>* pStatObjTable = NULL;
std::vector<_smart_ptr<IMaterial> >* pMatTable = NULL;
int nSID = 0;
// load terrain
XmlNodeRef nodeRef = xmlLevelData->findChild("SurfaceTypes");
LoadCollisionClasses(xmlLevelData->findChild("CollisionClasses"));
if (!usePrefabSystemForLevels)
{
LoadCollisionClasses(xmlLevelData->findChild("CollisionClasses"));
}
gEnv->pSystem->SetSystemGlobalState(ESYSTEM_GLOBAL_STATE_LEVEL_LOAD_START_STATIC_WORLD);
#if defined(FEATURE_SVO_GI)
if (gEnv->pConsole->GetCVar("e_GI")->GetIVal())
if (usePrefabSystemForLevels)
{
// Load SVOGI settings
char szFileName[256];
azsprintf(szFileName, "mission_%s.xml", szMissionName);
XmlNodeRef xmlMission = GetSystem()->LoadXmlFromFile(Get3DEngine()->GetLevelFilePath(szFileName));
if (xmlMission)
{
LoadTISettings(xmlMission->findChild("Environment"));
}
// When using the prefab system, just initialize a default manager instead of loading values from the indoor.dat file.
m_pVisAreaManager = new CVisAreaManager();
}
else
{
#if defined(FEATURE_SVO_GI)
if (gEnv->pConsole->GetCVar("e_GI")->GetIVal())
{
// Load SVOGI settings
char szFileName[256];
azsprintf(szFileName, "mission_%s.xml", szMissionName);
XmlNodeRef xmlMission = GetSystem()->LoadXmlFromFile(Get3DEngine()->GetLevelFilePath(szFileName));
if (xmlMission)
{
LoadTISettings(xmlMission->findChild("Environment"));
}
}
#endif
// load indoors
if (!LoadVisAreas(&pStatObjTable, &pMatTable))
{
Error("VisAreas file (%s) not found or file version error, please try to re-export the level", COMPILED_VISAREA_MAP_FILE_NAME);
return false;
// load indoors
std::vector<struct IStatObj*>* pStatObjTable = NULL;
std::vector<_smart_ptr<IMaterial>>* pMatTable = NULL;
if (!LoadVisAreas(&pStatObjTable, &pMatTable))
{
Error("VisAreas file (%s) not found or file version error, please try to re-export the level", COMPILED_VISAREA_MAP_FILE_NAME);
return false;
}
SAFE_DELETE(pStatObjTable);
SAFE_DELETE(pMatTable);
}
SAFE_DELETE(pStatObjTable);
SAFE_DELETE(pMatTable);
//Update loading screen and important tick functions
SYNCHRONOUS_LOADING_TICK();
@@ -737,29 +759,37 @@ bool C3DEngine::LoadLevel(const char* szFolderName, const char* szMissionName)
// load leveldata.xml
m_pTerrainWaterMat = 0;
m_nWaterBottomTexId = 0;
// This call is needed whether or not the prefab system is used for levels. If prefabs are used, it will initialize the
// environment and time of day managers with default values. With legacy levels, they will intialize from the saved xml files.
LoadMissionDataFromXMLNode(szMissionName);
//Update loading screen and important tick functions
SYNCHRONOUS_LOADING_TICK();
// init water if not initialized already (if no mission was found)
if (!GetOcean())
if (!usePrefabSystemForLevels)
{
PrintMessage("===== Creating Ocean =====");
CreateOcean(m_pTerrainWaterMat, COcean::GetWaterLevelInfo());
}
// init water if not initialized already (if no mission was found)
if (!GetOcean())
{
PrintMessage("===== Creating Ocean =====");
CreateOcean(m_pTerrainWaterMat, COcean::GetWaterLevelInfo());
}
PrintMessage("===== Load level physics data =====");
LoadFlaresData();
PrintMessage("===== Load level physics data =====");
LoadFlaresData();
}
// restore game state
EnableOceanRendering(true);
m_pObjManager->SetLockCGFResources(false);
PrintMessage("===== loading occlusion mesh =====");
if (!usePrefabSystemForLevels)
{
PrintMessage("===== loading occlusion mesh =====");
GetObjManager()->LoadOcclusionMesh(szFolderName);
GetObjManager()->LoadOcclusionMesh(szFolderName);
}
PrintMessage("===== Finished loading static world =====");
@@ -817,7 +847,9 @@ void C3DEngine::LoadMissionDataFromXMLNode(const char* szMissionName)
}
else
{
Error("C3DEngine::LoadMissionDataFromXMLNode: Mission file not found: %s", szFileName);
// XML file couldn't be found, just use the defaults for everything.
LoadEnvironmentSettingsFromXML(nullptr, GetDefSID());
LoadTimeOfDaySettingsFromXML(nullptr);
}
}
else
@@ -832,10 +864,13 @@ char* C3DEngine::GetXMLAttribText(XmlNodeRef pInputNode, const char* szLevel1, c
cry_strcpy(szResText, szDefaultValue);
XmlNodeRef nodeLevel = pInputNode->findChild(szLevel1);
if (nodeLevel && nodeLevel->haveAttr(szLevel2))
if (pInputNode)
{
cry_strcpy(szResText, nodeLevel->getAttr(szLevel2));
XmlNodeRef nodeLevel = pInputNode->findChild(szLevel1);
if (nodeLevel && nodeLevel->haveAttr(szLevel2))
{
cry_strcpy(szResText, nodeLevel->getAttr(szLevel2));
}
}
return szResText;
@@ -847,13 +882,16 @@ char* C3DEngine::GetXMLAttribText(XmlNodeRef pInputNode, const char* szLevel1, c
cry_strcpy(szResText, szDefaultValue);
XmlNodeRef nodeLevel = pInputNode->findChild(szLevel1);
if (nodeLevel)
if (pInputNode)
{
nodeLevel = nodeLevel->findChild(szLevel2);
XmlNodeRef nodeLevel = pInputNode->findChild(szLevel1);
if (nodeLevel)
{
cry_strcpy(szResText, nodeLevel->getAttr(szLevel3));
nodeLevel = nodeLevel->findChild(szLevel2);
if (nodeLevel)
{
cry_strcpy(szResText, nodeLevel->getAttr(szLevel3));
}
}
}
@@ -904,7 +942,7 @@ void C3DEngine::LoadEnvironmentSettingsFromXML(XmlNodeRef pInputNode, [[maybe_un
{
char moonTexture[256];
cry_strcpy(moonTexture, GetXMLAttribText(pInputNode, "Moon", "Texture", ""));
cry_strcpy(moonTexture, GetXMLAttribText(pInputNode, "Moon", "Texture", "Textures/Skys/Night/half_moon.dds"));
ITexture* pTex(0);
if (moonTexture[0] != '\0')
@@ -923,14 +961,14 @@ void C3DEngine::LoadEnvironmentSettingsFromXML(XmlNodeRef pInputNode, [[maybe_un
m_volFogGlobalDensityMultiplierLDR = (float)max(atof(GetXMLAttribText(pInputNode, "Fog", "LDRGlobalDensMult", "1.0")), 0.0);
// SkyBox
const string skyMaterialName = GetXMLAttribText(pInputNode, "SkyBox", "Material", "Materials/Sky/Sky");
const string skyLowSpecMaterialName = GetXMLAttribText(pInputNode, "SkyBox", "MaterialLowSpec", "Materials/Sky/Sky");
const string skyMaterialName = GetXMLAttribText(pInputNode, "SkyBox", "Material", "EngineAssets/Materials/Sky/Sky");
const string skyLowSpecMaterialName = GetXMLAttribText(pInputNode, "SkyBox", "MaterialLowSpec", "EngineAssets/Materials/Sky/Sky");
SetSkyMaterialPath(skyMaterialName);
SetSkyLowSpecMaterialPath(skyLowSpecMaterialName);
LoadSkyMaterial();
m_fSkyBoxAngle = (float)atof(GetXMLAttribText(pInputNode, "SkyBox", "Angle", "0.0"));
m_fSkyBoxStretching = (float)atof(GetXMLAttribText(pInputNode, "SkyBox", "Stretching", "1.0"));
m_fSkyBoxStretching = (float)atof(GetXMLAttribText(pInputNode, "SkyBox", "Stretching", "0.5"));
// set terrain water (aka the infinite ocean), sun road and bottom shaders
if (OceanToggle::IsActive())
@@ -37,7 +37,7 @@ namespace LegacyCryPhysicsUtils
strided_pointer<Vec3mem> pts = strided_pointer<Vec3mem>((Vec3mem*)_pts.data, _pts.iStride);
ptitem* pt, * ptmax, * ptdeleted, * ptlist = npts > sizeof(ptbuf) / sizeof(ptbuf[0]) ? new ptitem[npts] : ptbuf;
qhtritem* tr, * trnext, * trend, * trnew, * trdata = trbuf, * trstart = 0, * trlast, * trbest;
qhtritem* tr, * trnext, * trend, * trnew, * trdata = trbuf, * trstart = 0, * trlast, * trbest = nullptr;
int i, j, k, ti, trdatasz = sizeof(trbuf) / sizeof(trbuf[0]), bidx[6], n, next_iter, delbuds;
qhtritem** tmparr_ptr = tmparr_ptr_buf;
int* tmparr_idx = tmparr_idx_buf, tmparr_sz = 512;
@@ -679,7 +679,7 @@ namespace LegacyCryPhysicsUtils
{
return 0;
}
vtxthunk* pThunks, * pPrevThunk, * pContStart, ** pSags, ** pBottoms, * pPinnacle, * pBounds[2], * pPrevBounds[2], * ptr, * ptr_next;
vtxthunk* pThunks, * pPrevThunk, * pContStart, ** pSags, ** pBottoms, * pPinnacle = nullptr, * pBounds[2], * pPrevBounds[2], * ptr, * ptr_next;
vtxthunk bufThunks[32], * bufSags[16], * bufBottoms[16];
int i, nThunks, nBottoms = 0, nSags = 0, iBottom = 0, nConts = 0, j, isag, nThunks0, nTris = 0, nPrevSags, nTrisCnt, iter, nDegenTris = 0;
float ymax, ymin, e, area0 = 0, area1 = 0, cntarea, minCntArea;
+31 -28
View File
@@ -281,46 +281,49 @@ void CObjManager::PreloadLevelObjects()
//////////////////////////////////////////////////////////////////////////
// Request objects loading from Streaming System.
if (const char* pCgfName = pResList->GetFirst())
if (pResList)
{
while (pCgfName)
if (const char* pCgfName = pResList->GetFirst())
{
if (strstr(pCgfName, ".cgf"))
while (pCgfName)
{
const char* sLodName = strstr(pCgfName, "_lod");
if (sLodName && (sLodName[4] >= '0' && sLodName[4] <= '9'))
if (strstr(pCgfName, ".cgf"))
{
// Ignore Lod files.
pCgfName = pResList->GetNext();
continue;
}
cgfFilename = pCgfName;
if (bVerboseLogging)
{
CryLog("%s", cgfFilename.c_str());
}
IStatObj* pStatObj = GetObjManager()->LoadStatObjUnsafeManualRef(cgfFilename.c_str(), NULL, 0, true, 0);
if (pStatObj)
{
if (pStatObj->IsMeshStrippedCGF())
const char* sLodName = strstr(pCgfName, "_lod");
if (sLodName && (sLodName[4] >= '0' && sLodName[4] <= '9'))
{
nInLevelCacheCount++;
// Ignore Lod files.
pCgfName = pResList->GetNext();
continue;
}
cgfFilename = pCgfName;
if (bVerboseLogging)
{
CryLog("%s", cgfFilename.c_str());
}
IStatObj* pStatObj = GetObjManager()->LoadStatObjUnsafeManualRef(cgfFilename.c_str(), NULL, 0, true, 0);
if (pStatObj)
{
if (pStatObj->IsMeshStrippedCGF())
{
nInLevelCacheCount++;
}
}
// cgfStreamer.StartStreaming(cgfFilename.c_str());
nCgfCounter++;
// This loop can take a few seconds, so we should refresh the loading screen and call the loading tick functions to
// ensure that no big gaps in coverage occur.
SYNCHRONOUS_LOADING_TICK();
}
//cgfStreamer.StartStreaming(cgfFilename.c_str());
nCgfCounter++;
//This loop can take a few seconds, so we should refresh the loading screen and call the loading tick functions to ensure that no big gaps in coverage occur.
SYNCHRONOUS_LOADING_TICK();
pCgfName = pResList->GetNext();
}
pCgfName = pResList->GetNext();
}
}
// PrintMessage("Finished requesting level CGF's: %d objects in %.1f sec", nCgfCounter, GetCurAsyncTimeSec()-fStartTime);
// Continue updating streaming system until all CGF's are loaded
+3 -56
View File
@@ -344,61 +344,18 @@ struct ICaptureKey
{
friend class AnimSerializer;
enum CaptureBufferType
{
Color = 0,
ColorWithAlpha,
NumCaptureBufferTypes // keep this last
};
enum CaptureFileFormat
{
Jpg = 0,
Tga,
Tif,
NumCaptureFileFormats // keep this last
};
AZStd::string folder;
AZStd::string prefix;
float duration;
float timeStep;
AZStd::string folder;
bool once;
AZStd::string prefix;
CaptureBufferType captureBufferIndex;
const char* GetFormat() const
{ return format.c_str(); }
void FormatJPG()
{ format = "jpg"; }
void FormatTIF()
{ format = "tif"; }
void FormatTGA()
{ format = "tga"; }
void FormatHDR()
{
// deprecated
if (gEnv->pLog)
{
gEnv->pLog->LogWarning("'hdr' capture format is deprecated.");
}
format = "hdr";
}
void FormatBMP()
{
// deprecated
if (gEnv->pLog)
{
gEnv->pLog->LogWarning("'bmp' capture format is deprecated.");
}
format = "bmp";
}
ICaptureKey()
: IKey()
, duration(0)
, duration(0.0f)
, timeStep(0.033f)
, once(false)
, captureBufferIndex(Color)
{
FormatTGA();
ICVar* pCaptureFolderCVar = gEnv->pConsole->GetCVar("capture_folder");
if (pCaptureFolderCVar != NULL && pCaptureFolderCVar->GetString())
{
@@ -409,11 +366,6 @@ struct ICaptureKey
{
prefix = pCaptureFilePrefixCVar->GetString();
}
ICVar* pCaptureFileFormatCVar = gEnv->pConsole->GetCVar("capture_file_format");
if (pCaptureFileFormatCVar != NULL)
{
format = pCaptureFileFormatCVar->GetString();
}
}
ICaptureKey(const ICaptureKey& other)
@@ -423,13 +375,8 @@ struct ICaptureKey
, duration(other.duration)
, timeStep(other.timeStep)
, once(other.once)
, format(other.format)
, captureBufferIndex(other.captureBufferIndex)
{
}
private:
AZStd::string format;
};
//! Boolean key.
+3 -3
View File
@@ -1309,9 +1309,9 @@ struct I3DEngine
// SetCamera
// Arguments:
// szDebugName - name that can be visualized for debugging purpose, must not be 0
virtual void RenderWorld(const int nRenderFlags, const SRenderingPassInfo& passInfo, const char* szDebugName) = 0;
virtual void RenderWorld(int nRenderFlags, const SRenderingPassInfo& passInfo, const char* szDebugName) = 0;
virtual void RenderSceneReflection(const int nRenderFlags, const SRenderingPassInfo& passInfo) = 0;
virtual void RenderSceneReflection(int nRenderFlags, const SRenderingPassInfo& passInfo) = 0;
// Summary:
// Prepares for the world stream update, should be called before rendering
@@ -1816,7 +1816,7 @@ struct I3DEngine
// fTextPosY - Y position for the text
// fTextStepY - Amount of pixels to distance each line
// bEnhanced - false=normal, true=more interesting information
virtual void DisplayInfo(float& fTextPosX, float& fTextPosY, float& fTextStepY, const bool bEnhanced) = 0;
virtual void DisplayInfo(float& fTextPosX, float& fTextPosY, float& fTextStepY, bool bEnhanced) = 0;
// Summary:
// Displays CPU and GPU memory usage statistics on screen
+23 -23
View File
@@ -844,21 +844,21 @@ namespace Audio
{
virtual ~IAudioProxy() = default;
virtual void Initialize(const char* const sObjectName, const bool bInitAsync = true) = 0;
virtual void Initialize(const char* sObjectName, bool bInitAsync = true) = 0;
virtual void Release() = 0;
virtual void Reset() = 0;
virtual void ExecuteSourceTrigger(TAudioControlID nTriggerID, const SAudioSourceInfo& rSourceInfo, const SAudioCallBackInfos& rCallbackInfos = SAudioCallBackInfos::GetEmptyObject()) = 0;
virtual void ExecuteTrigger(const TAudioControlID nTriggerID, const SAudioCallBackInfos& rCallbackInfos = SAudioCallBackInfos::GetEmptyObject()) = 0;
virtual void ExecuteTrigger(TAudioControlID nTriggerID, const SAudioCallBackInfos& rCallbackInfos = SAudioCallBackInfos::GetEmptyObject()) = 0;
virtual void StopAllTriggers() = 0;
virtual void StopTrigger(const TAudioControlID nTriggerID) = 0;
virtual void SetSwitchState(const TAudioControlID nSwitchID, const TAudioSwitchStateID nStateID) = 0;
virtual void SetRtpcValue(const TAudioControlID nRtpcID, const float fValue) = 0;
virtual void SetObstructionCalcType(const EAudioObjectObstructionCalcType eObstructionType) = 0;
virtual void StopTrigger(TAudioControlID nTriggerID) = 0;
virtual void SetSwitchState(TAudioControlID nSwitchID, TAudioSwitchStateID nStateID) = 0;
virtual void SetRtpcValue(TAudioControlID nRtpcID, float fValue) = 0;
virtual void SetObstructionCalcType(EAudioObjectObstructionCalcType eObstructionType) = 0;
virtual void SetPosition(const SATLWorldPosition& rPosition) = 0;
virtual void SetPosition(const AZ::Vector3& rPosition) = 0;
virtual void SetMultiplePositions(const MultiPositionParams& params) = 0;
virtual void SetEnvironmentAmount(const TAudioEnvironmentID nEnvironmentID, const float fAmount) = 0;
virtual void SetEnvironmentAmount(TAudioEnvironmentID nEnvironmentID, float fAmount) = 0;
virtual void SetCurrentEnvironments() = 0;
virtual void ResetRtpcValues() = 0;
virtual TAudioObjectID GetAudioObjectID() const = 0;
@@ -907,37 +907,37 @@ namespace Audio
virtual void AddRequestListener(
AudioRequestCallbackType callBack,
void* const objectToListenTo,
const EAudioRequestType requestType = eART_AUDIO_ALL_REQUESTS,
const TATLEnumFlagsType specificRequestMask = ALL_AUDIO_REQUEST_SPECIFIC_TYPE_FLAGS) = 0;
void* objectToListenTo,
EAudioRequestType requestType = eART_AUDIO_ALL_REQUESTS,
TATLEnumFlagsType specificRequestMask = ALL_AUDIO_REQUEST_SPECIFIC_TYPE_FLAGS) = 0;
virtual void RemoveRequestListener(
AudioRequestCallbackType callBack,
void* const requestOwner) = 0;
void* requestOwner) = 0;
virtual TAudioControlID GetAudioTriggerID(const char* const sAudioTriggerName) const = 0;
virtual TAudioControlID GetAudioRtpcID(const char* const sAudioRtpcName) const = 0;
virtual TAudioControlID GetAudioSwitchID(const char* const sAudioSwitchName) const = 0;
virtual TAudioSwitchStateID GetAudioSwitchStateID(const TAudioControlID nSwitchID, const char* const sAudioSwitchStateName) const = 0;
virtual TAudioPreloadRequestID GetAudioPreloadRequestID(const char* const sAudioPreloadRequestName) const = 0;
virtual TAudioEnvironmentID GetAudioEnvironmentID(const char* const sAudioEnvironmentName) const = 0;
virtual TAudioControlID GetAudioTriggerID(const char* sAudioTriggerName) const = 0;
virtual TAudioControlID GetAudioRtpcID(const char* sAudioRtpcName) const = 0;
virtual TAudioControlID GetAudioSwitchID(const char* sAudioSwitchName) const = 0;
virtual TAudioSwitchStateID GetAudioSwitchStateID(TAudioControlID nSwitchID, const char* sAudioSwitchStateName) const = 0;
virtual TAudioPreloadRequestID GetAudioPreloadRequestID(const char* sAudioPreloadRequestName) const = 0;
virtual TAudioEnvironmentID GetAudioEnvironmentID(const char* sAudioEnvironmentName) const = 0;
virtual bool ReserveAudioListenerID(TAudioObjectID& rAudioObjectID) = 0;
virtual bool ReleaseAudioListenerID(const TAudioObjectID nAudioObjectID) = 0;
virtual bool SetAudioListenerOverrideID(const TAudioObjectID nAudioObjectID) = 0;
virtual bool ReleaseAudioListenerID(TAudioObjectID nAudioObjectID) = 0;
virtual bool SetAudioListenerOverrideID(TAudioObjectID nAudioObjectID) = 0;
virtual void GetInfo(SAudioSystemInfo& rAudioSystemInfo) = 0;
virtual const char* GetControlsPath() const = 0;
virtual void UpdateControlsPath() = 0;
virtual void RefreshAudioSystem(const char* const levelName) = 0;
virtual void RefreshAudioSystem(const char* levelName) = 0;
virtual IAudioProxy* GetFreeAudioProxy() = 0;
virtual void FreeAudioProxy(IAudioProxy* const pIAudioProxy) = 0;
virtual void FreeAudioProxy(IAudioProxy* pIAudioProxy) = 0;
virtual TAudioSourceId CreateAudioSource(const SAudioInputConfig& sourceConfig) = 0;
virtual void DestroyAudioSource(TAudioSourceId sourceId) = 0;
virtual const char* GetAudioControlName(const EAudioControlType controlType, const TATLIDType atlID) const = 0;
virtual const char* GetAudioSwitchStateName(const TAudioControlID switchID, const TAudioSwitchStateID stateID) const = 0;
virtual const char* GetAudioControlName(EAudioControlType controlType, TATLIDType atlID) const = 0;
virtual const char* GetAudioSwitchStateName(TAudioControlID switchID, TAudioSwitchStateID stateID) const = 0;
};
using AudioSystemRequestBus = AZ::EBus<AudioSystemRequests>;
+7 -7
View File
@@ -282,7 +282,7 @@ struct IConsole
// show/hide the console
// @param specifies if the window must be (true=show,false=hide)
// @param specifies iRequestScrollMax <=0 if not used, otherwise it sets SetScrollMax temporary to the given value
virtual void ShowConsole(bool show, const int iRequestScrollMax = -1) = 0;
virtual void ShowConsole(bool show, int iRequestScrollMax = -1) = 0;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Dump all console-variables to a callback-interface
// @param Callback callback-interface which needs to be called for each element
@@ -318,7 +318,7 @@ struct IConsole
// @param indwBufferSize 1.. size of the buffer
// @return true=line was returned, false=there are no more lines
virtual bool GetLineNo(const int indwLineNo, char* outszBuffer, const int indwBufferSize) const = 0;
virtual bool GetLineNo(int indwLineNo, char* outszBuffer, int indwBufferSize) const = 0;
// @return current number of lines in the console
virtual int GetLineCount() const = 0;
@@ -408,7 +408,7 @@ struct IConsole
// bDeferExecution - true=the command is stored in special fifo that allows delayed execution
// by using wait_seconds and wait_frames commands
//
virtual void ExecuteString(const char* command, const bool bSilentMode = false, const bool bDeferExecution = false) = 0;
virtual void ExecuteString(const char* command, bool bSilentMode = false, bool bDeferExecution = false) = 0;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Print a message into the log and abort the execution of the application
@@ -489,7 +489,7 @@ struct IConsole
// \param bUpOrDown true=after pressed "up", false=after pressed "down"
// \return 0 if there is no history line or pointer to the null terminated history line
virtual const char* GetHistoryElement(const bool bUpOrDown) = 0;
virtual const char* GetHistoryElement(bool bUpOrDown) = 0;
//! \param szCommand must not be 0
virtual void AddCommandToHistory(const char* szCommand) = 0;
@@ -602,11 +602,11 @@ struct ICVar
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// set the float value of the variable
// @param s float representation the value
virtual void Set(const float f) = 0;
virtual void Set(float f) = 0;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// set the float value of the variable
// @param s integer representation the value
virtual void Set(const int i) = 0;
virtual void Set(int i) = 0;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// clear the specified bits in the flag field
virtual void ClearFlags (int flags) = 0;
@@ -659,7 +659,7 @@ struct ICVar
//////////////////////////////////////////////////////////////////////////
// Removes an on change functor
// returns true if removal was successful.
virtual bool RemoveOnChangeFunctor(const uint64 nFunctorId) = 0;
virtual bool RemoveOnChangeFunctor(uint64 nFunctorId) = 0;
//////////////////////////////////////////////////////////////////////////
// Get the current callback function.
+32 -169
View File
@@ -20,8 +20,8 @@
#include <CrySizer.h>
#include <IXml.h>
#include <AzCore/Asset/AssetCommon.h>
struct ILevelRotationFile;
struct IConsoleCmdArgs;
namespace AZ::IO
@@ -29,212 +29,75 @@ namespace AZ::IO
struct IArchive;
}
struct ILevelRotation
{
virtual ~ILevelRotation() {}
typedef uint32 TExtInfoId;
struct IExtendedInfo
{
};
typedef uint8 TRandomisationFlags;
enum EPlaylistRandomisationFlags
{
ePRF_None = 0,
ePRF_Shuffle = 1 << 0,
ePRF_MaintainPairs = 1 << 1,
};
virtual bool Load([[maybe_unused]] ILevelRotationFile* file) { return false; }
virtual bool LoadFromXmlRootNode(const XmlNodeRef rootNode, [[maybe_unused]] const char* altRootTag) { return false; }
virtual void Reset() {}
virtual int AddLevel([[maybe_unused]] const char* level) { return 0; }
virtual void AddGameMode([[maybe_unused]] int level, [[maybe_unused]] const char* gameMode) {}
virtual int AddLevel([[maybe_unused]] const char* level, [[maybe_unused]] const char* gameMode) { return 0; }
//call to set the playlist ready for a new session
virtual void Initialise([[maybe_unused]] int nSeed) {}
virtual bool First() { return false; }
virtual bool Advance() { return false; }
virtual bool AdvanceAndLoopIfNeeded() { return false; }
virtual const char* GetNextLevel() const { return nullptr; }
virtual const char* GetNextGameRules() const { return nullptr; }
virtual int GetLength() const { return 0; }
virtual int GetTotalGameModeEntries() const { return 0; }
virtual int GetNext() const { return 0; }
virtual const char* GetLevel([[maybe_unused]] uint32 idx, [[maybe_unused]] bool accessShuffled = true) const { return nullptr; }
virtual int GetNGameRulesForEntry([[maybe_unused]] uint32 idx, [[maybe_unused]] bool accessShuffled = true) const { return 0; }
virtual const char* GetGameRules([[maybe_unused]] uint32 idx, [[maybe_unused]] uint32 iMode, [[maybe_unused]] bool accessShuffled = true) const { return nullptr; }
virtual const char* GetNextGameRulesForEntry([[maybe_unused]] int idx) const { return nullptr; }
virtual const int NumAdvancesTaken() const { return 0; }
virtual void ResetAdvancement() {}
virtual bool IsRandom() const { return false; }
virtual ILevelRotation::TRandomisationFlags GetRandomisationFlags() const { return ePRF_None; }
virtual void SetRandomisationFlags([[maybe_unused]] TRandomisationFlags flags) {}
virtual void ChangeLevel([[maybe_unused]] IConsoleCmdArgs* pArgs = NULL) {}
virtual bool NextPairMatch() const { return false; }
};
// [LYN-2376] Remove once legacy slice support is removed
struct ILevelInfo
{
virtual ~ILevelInfo() {}
typedef std::vector<string> TStringVec;
struct TGameTypeInfo
{
string name;
string xmlFile;
int cgfCount;
void GetMemoryUsage(ICrySizer* pSizer) const
{
pSizer->AddObject(name);
pSizer->AddObject(xmlFile);
}
};
struct SMinimapInfo
{
SMinimapInfo()
: fStartX(0)
, fStartY(0)
, fEndX(1)
, fEndY(1)
, fDimX(1)
, fDimY(1)
, iWidth(1024)
, iHeight(1024) {}
string sMinimapName;
int iWidth;
int iHeight;
float fStartX;
float fStartY;
float fEndX;
float fEndY;
float fDimX;
float fDimY;
};
virtual ~ILevelInfo() = default;
virtual const char* GetName() const = 0;
virtual const bool IsOfType(const char* sType) const = 0;
virtual const char* GetPath() const = 0;
virtual const char* GetPaks() const = 0;
virtual const char* GetDisplayName() const = 0;
virtual const char* GetPreviewImagePath() const = 0;
virtual const char* GetBackgroundImagePath() const = 0;
virtual const char* GetMinimapImagePath() const = 0;
//virtual const ILevelInfo::TStringVec& GetMusicLibs() const = 0; // Gets reintroduced when level specific music data loading is implemented.
virtual const bool MetadataLoaded() const = 0;
virtual bool GetIsModLevel() const = 0;
virtual const uint32 GetScanTag() const = 0;
virtual const uint32 GetLevelTag() const = 0;
virtual int GetGameTypeCount() const = 0;
virtual const ILevelInfo::TGameTypeInfo* GetGameType(int gameType) const = 0;
virtual bool SupportsGameType(const char* gameTypeName) const = 0;
virtual const ILevelInfo::TGameTypeInfo* GetDefaultGameType() const = 0;
virtual ILevelInfo::TStringVec GetGameRules() const = 0;
virtual bool HasGameRules() const = 0;
virtual const ILevelInfo::SMinimapInfo& GetMinimapInfo() const = 0;
virtual const char* GetDefaultGameRules() const = 0;
virtual const char* GetAssetName() const = 0;
};
struct ILevel
{
virtual ~ILevel() {}
virtual void Release() = 0;
virtual ILevelInfo* GetLevelInfo() = 0;
};
/*!
* Extend this class and call ILevelSystem::AddListener() to receive level system related events.
*/
struct ILevelSystemListener
{
virtual ~ILevelSystemListener() {}
virtual ~ILevelSystemListener() = default;
//! Called when loading a level fails due to it not being found.
virtual void OnLevelNotFound([[maybe_unused]] const char* levelName) {}
//! Called after ILevelSystem::PrepareNextLevel() completes.
virtual void OnPrepareNextLevel([[maybe_unused]] ILevelInfo* pLevel) {}
virtual void OnPrepareNextLevel([[maybe_unused]] const char* levelName) {}
//! Called after ILevelSystem::OnLoadingStart() completes, before the level actually starts loading.
virtual void OnLoadingStart([[maybe_unused]] ILevelInfo* pLevel) {}
virtual void OnLoadingStart([[maybe_unused]] const char* levelName) {}
//! Called after the level finished
virtual void OnLoadingComplete([[maybe_unused]] ILevel* pLevel) {}
virtual void OnLoadingComplete([[maybe_unused]] const char* levelName) {}
//! Called when there's an error loading a level, with the level info and a description of the error.
virtual void OnLoadingError([[maybe_unused]] ILevelInfo* pLevel, [[maybe_unused]] const char* error) {}
virtual void OnLoadingError([[maybe_unused]] const char* levelName, [[maybe_unused]] const char* error) {}
//! Called whenever the loading status of a level changes. progressAmount goes from 0->100.
virtual void OnLoadingProgress([[maybe_unused]] ILevelInfo* pLevel, [[maybe_unused]] int progressAmount) {}
virtual void OnLoadingProgress([[maybe_unused]] const char* levelName, [[maybe_unused]] int progressAmount) {}
//! Called after a level is unloaded, before the data is freed.
virtual void OnUnloadComplete([[maybe_unused]] ILevel* pLevel) {}
virtual void OnUnloadComplete([[maybe_unused]] const char* levelName) {}
void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const { }
};
struct ILevelSystem
: public ILevelSystemListener
{
enum
{
TAG_MAIN = 'MAIN',
TAG_UNKNOWN = 'ZZZZ'
};
static constexpr char LevelsDirectoryName[] = "levels";
static constexpr char LevelPakName[] = "level.pak";
virtual ~ILevelSystem() = default;
virtual void Release() = 0;
virtual void Rescan(const char* levelsFolder, const uint32 tag) = 0;
virtual void ScanFolder(const char* subfolder, bool modFolder, const uint32 tag) = 0;
virtual void PopulateLevels(string searchPattern, string& folder, AZ::IO::IArchive* pPak, bool& modFolder, const uint32& tag, bool fromFileSystemOnly) = 0;
virtual void LoadRotation() {}
virtual int GetLevelCount() = 0;
virtual DynArray<string>* GetLevelTypeList() = 0;
virtual ILevelInfo* GetLevelInfo(int level) = 0;
virtual ILevelInfo* GetLevelInfo(const char* levelName) = 0;
virtual void AddListener(ILevelSystemListener* pListener) = 0;
virtual void RemoveListener(ILevelSystemListener* pListener) = 0;
virtual ILevel* GetCurrentLevel() const = 0;
virtual ILevel* LoadLevel(const char* levelName) = 0;
virtual void UnLoadLevel() = 0;
virtual ILevel* SetEditorLoadedLevel(const char* levelName, bool bReadLevelInfoMetaData = false) = 0;
virtual bool LoadLevel(const char* levelName) = 0;
virtual void UnloadLevel() = 0;
virtual bool IsLevelLoaded() = 0;
virtual void PrepareNextLevel(const char* levelName) = 0;
virtual ILevelRotation* GetLevelRotation() { return nullptr; }
virtual ILevelRotation* FindLevelRotationForExtInfoId([[maybe_unused]] const ILevelRotation::TExtInfoId findId) { return nullptr; }
virtual bool AddExtendedLevelRotationFromXmlRootNode(const XmlNodeRef rootNode, [[maybe_unused]] const char* altRootTag, [[maybe_unused]] const ILevelRotation::TExtInfoId extInfoId) { return false; }
virtual void ClearExtendedLevelRotations() {}
virtual ILevelRotation* CreateNewRotation([[maybe_unused]] const ILevelRotation::TExtInfoId id) { return nullptr; }
// Retrieve`s last level level loading time.
virtual float GetLastLevelLoadTime() = 0;
virtual const char* GetCurrentLevelName() const = 0;
// If the level load failed then we need to have a different shutdown procedure vs when a level is naturally unloaded
virtual void SetLevelLoadFailed(bool loadFailed) = 0;
virtual bool GetLevelLoadFailed() = 0;
virtual AZ::Data::AssetType GetLevelAssetType() const = 0;
static const char* GetLevelsDirectoryName()
{
return LevelsDirectoryName;
}
// [LYN-2376] Deprecated methods, to be removed once slices are removed:
virtual void Rescan(const char* levelsFolder) = 0;
virtual int GetLevelCount() = 0;
virtual ILevelInfo* GetLevelInfo(int level) = 0;
virtual ILevelInfo* GetLevelInfo(const char* levelName) = 0;
protected:
static constexpr const char* LevelsDirectoryName = "levels";
};
#endif // CRYINCLUDE_CRYACTION_ILEVELSYSTEM_H
+4 -4
View File
@@ -40,9 +40,9 @@ struct IMiniLog
// <interfuscator:shuffle>
// Notes:
// You only have to implement this function.
virtual void LogV (const ELogType nType, const char* szFormat, va_list args) PRINTF_PARAMS(3, 0) = 0;
virtual void LogV(ELogType nType, const char* szFormat, va_list args) PRINTF_PARAMS(3, 0) = 0;
virtual void LogV (const ELogType nType, int flags, const char* szFormat, va_list args) PRINTF_PARAMS(4, 0) = 0;
virtual void LogV(ELogType nType, int flags, const char* szFormat, va_list args) PRINTF_PARAMS(4, 0) = 0;
// Summary:
// Logs using type.
@@ -123,8 +123,8 @@ struct CNullMiniLog
// The default implementation just won't do anything
//##@{
void LogV([[maybe_unused]] const char* szFormat, [[maybe_unused]] va_list args) {}
void LogV([[maybe_unused]] const ELogType nType, [[maybe_unused]] const char* szFormat, [[maybe_unused]] va_list args) {}
void LogV ([[maybe_unused]] const ELogType nType, [[maybe_unused]] int flags, [[maybe_unused]] const char* szFormat, [[maybe_unused]] va_list args) {}
void LogV([[maybe_unused]] ELogType nType, [[maybe_unused]] const char* szFormat, [[maybe_unused]] va_list args) {}
void LogV ([[maybe_unused]] ELogType nType, [[maybe_unused]] int flags, [[maybe_unused]] const char* szFormat, [[maybe_unused]] va_list args) {}
//##@}
};
+1 -1
View File
@@ -29,7 +29,7 @@ struct IProcess
virtual ~IProcess(){}
virtual bool Init() = 0;
virtual void Update() = 0;
virtual void RenderWorld(const int nRenderFlags, const SRenderingPassInfo& passInfo, const char* szDebugName) = 0;
virtual void RenderWorld(int nRenderFlags, const SRenderingPassInfo& passInfo, const char* szDebugName) = 0;
virtual void ShutDown() = 0;
virtual void SetFlags(int flags) = 0;
virtual int GetFlags(void) = 0;
+18 -18
View File
@@ -1119,8 +1119,8 @@ struct IRenderer
//Sums DIP counts for the EFSLIST_* passes that match the submitted mask.
//Compose the mask with bitwise arithmetic, use (1 << EFSLIST_*) per list.
//e.g. to sum general and transparent, pass in ( (1 << EFSLIST_GENERAL) | (1 << EFSLIST_TRANSP) )
virtual int GetCurrentNumberOfDrawCalls(const uint32 EFSListMask) const = 0;
virtual float GetCurrentDrawCallRTTimes(const uint32 EFSListMask) const = 0;
virtual int GetCurrentNumberOfDrawCalls(uint32 EFSListMask) const = 0;
virtual float GetCurrentDrawCallRTTimes(uint32 EFSListMask) const = 0;
virtual void SetDebugRenderNode(IRenderNode* pRenderNode) = 0;
virtual bool IsDebugRenderNode(IRenderNode* pRenderNode) const = 0;
@@ -1211,7 +1211,7 @@ struct IRenderer
// Summary:
// Draws user primitives.
virtual void DrawDynVB(SVF_P3F_C4B_T2F* pBuf, uint16* pInds, int nVerts, int nInds, const PublicRenderPrimitiveType nPrimType) = 0;
virtual void DrawDynVB(SVF_P3F_C4B_T2F* pBuf, uint16* pInds, int nVerts, int nInds, PublicRenderPrimitiveType nPrimType) = 0;
struct DynUiPrimitive : public AZStd::intrusive_slist_node<DynUiPrimitive>
{
@@ -1242,7 +1242,7 @@ struct IRenderer
// Summary:
// Sets delta gamma.
virtual bool SetGammaDelta(const float fGamma) = 0;
virtual bool SetGammaDelta(float fGamma) = 0;
// Summary:
// Restores gamma
@@ -1442,7 +1442,7 @@ struct IRenderer
virtual void FontRestoreRenderingState(bool overrideViewProjMatrices, const TransformationMatrices& restoringMatrices) = 0;
virtual bool FlushRTCommands(bool bWait, bool bImmediatelly, bool bForce) = 0;
virtual void DrawStringU(IFFont_RenderProxy* pFont, float x, float y, float z, const char* pStr, const bool asciiMultiLine, const STextDrawContext& ctx) const = 0;
virtual void DrawStringU(IFFont_RenderProxy* pFont, float x, float y, float z, const char* pStr, bool asciiMultiLine, const STextDrawContext& ctx) const = 0;
virtual int RT_CurThreadList() = 0;
@@ -1522,8 +1522,8 @@ struct IRenderer
virtual ITexture* EF_GetTextureByName(const char* name, uint32 flags = 0) = 0;
// Summary:
// Loads the texture for name(nameTex).
virtual ITexture* EF_LoadTexture(const char* nameTex, const uint32 flags = 0) = 0;
virtual ITexture* EF_LoadCubemapTexture(const char* nameTex, const uint32 flags = 0) = 0;
virtual ITexture* EF_LoadTexture(const char* nameTex, uint32 flags = 0) = 0;
virtual ITexture* EF_LoadCubemapTexture(const char* nameTex, uint32 flags = 0) = 0;
// Summary:
// Loads default texture whose life cycle is managed by Texture Manager, do not try to release them by yourself!
virtual ITexture* EF_LoadDefaultTexture(const char* nameTex) = 0;
@@ -1556,9 +1556,9 @@ struct IRenderer
virtual void EF_AddEf (IRenderElement* pRE, SShaderItem& pSH, CRenderObject* pObj, const SRenderingPassInfo& passInfo, int nList, int nAW, const SRendItemSorter& rendItemSorter) = 0;
//! Draw all shaded REs in the list
virtual void EF_EndEf3D (const int nFlags, const int nPrecacheUpdateId, const int nNearPrecacheUpdateId, const SRenderingPassInfo& passInfo) = 0;
virtual void EF_EndEf3D (int nFlags, int nPrecacheUpdateId, int nNearPrecacheUpdateId, const SRenderingPassInfo& passInfo) = 0;
virtual void EF_InvokeShadowMapRenderJobs(const int nFlags) = 0;
virtual void EF_InvokeShadowMapRenderJobs(int nFlags) = 0;
// Dynamic lights
void EF_ClearLightsList() {}; // For FC Compatibility.
@@ -1570,9 +1570,9 @@ struct IRenderer
// Deferred lights/vis areas
virtual int EF_AddDeferredLight(const CDLight& pLight, float fMult, const SRenderingPassInfo& passInfo, const SRendItemSorter& rendItemSorter) = 0;
virtual uint32 EF_GetDeferredLightsNum(const eDeferredLightType eLightType = eDLT_DeferredLight) = 0;
virtual uint32 EF_GetDeferredLightsNum(eDeferredLightType eLightType = eDLT_DeferredLight) = 0;
virtual void EF_ClearDeferredLightsList() = 0;
virtual TArray<SRenderLight>* EF_GetDeferredLights(const SRenderingPassInfo& passInfo, const eDeferredLightType eLightType = eDLT_DeferredLight) = 0;
virtual TArray<SRenderLight>* EF_GetDeferredLights(const SRenderingPassInfo& passInfo, eDeferredLightType eLightType = eDLT_DeferredLight) = 0;
virtual uint8 EF_AddDeferredClipVolume(const IClipVolume* pClipVolume) = 0;
virtual bool EF_SetDeferredClipVolumeBlendData(const IClipVolume* pClipVolume, const SClipVolumeBlendInfo& blendInfo) = 0;
@@ -1605,13 +1605,13 @@ struct IRenderer
//////////////////////////////////////////////////////////////////////////
virtual void EF_AddWaterSimHit(const Vec3& vPos, const float scale, const float strength) = 0;
virtual void EF_AddWaterSimHit(const Vec3& vPos, float scale, float strength) = 0;
virtual void EF_DrawWaterSimHits() = 0;
/////////////////////////////////////////////////////////////////////////////////
// 2d interface for the shaders
/////////////////////////////////////////////////////////////////////////////////
virtual void EF_EndEf2D(const bool bSort) = 0;
virtual void EF_EndEf2D(bool bSort) = 0;
// Summary:
// Returns various Renderer Settings, see ERenderQueryTypes.
@@ -1771,7 +1771,7 @@ struct IRenderer
virtual void UpdateTextureInVideoMemory(uint32 tnum, const byte* newdata, int posx, int posy, int w, int h, ETEX_Format eTFSrc = eTF_B8G8R8, int posz = 0, int sizez = 1) = 0;
virtual bool DXTCompress(const byte* raw_data, int nWidth, int nHeight, ETEX_Format eTF, bool bUseHW, bool bGenMips, int nSrcBytesPerPix, MIPDXTcallback callback) = 0;
virtual bool DXTDecompress(const byte* srcData, const size_t srcFileSize, byte* dstData, int nWidth, int nHeight, int nMips, ETEX_Format eSrcTF, bool bUseHW, int nDstBytesPerPix) = 0;
virtual bool DXTDecompress(const byte* srcData, size_t srcFileSize, byte* dstData, int nWidth, int nHeight, int nMips, ETEX_Format eSrcTF, bool bUseHW, int nDstBytesPerPix) = 0;
virtual void RemoveTexture(unsigned int TextureId) = 0;
virtual void DeleteFont(IFFont* font) = 0;
@@ -2219,7 +2219,7 @@ struct IRenderer
virtual void EndScreenShot([[maybe_unused]] int e_ScreenShot) {};
// Sets a renderer tracked cvar
virtual void SetRendererCVar(ICVar* pCVar, const char* pArgText, const bool bSilentMode = false) = 0;
virtual void SetRendererCVar(ICVar* pCVar, const char* pArgText, bool bSilentMode = false) = 0;
// Get the render piepline
virtual SRenderPipeline* GetRenderPipeline() = 0;
@@ -2303,7 +2303,7 @@ struct IRenderer
virtual long FX_SetVertexDeclaration(int StreamMask, const AZ::Vertex::Format& vertexFormat) = 0;
// Draw indexed prim
virtual void FX_DrawIndexedPrimitive(const eRenderPrimitiveType eType, const int nVBOffset, const int nMinVertexIndex, const int nVerticesCount, const int nStartIndex, const int nNumIndices, bool bInstanced = false) = 0;
virtual void FX_DrawIndexedPrimitive(eRenderPrimitiveType eType, int nVBOffset, int nMinVertexIndex, int nVerticesCount, int nStartIndex, int nNumIndices, bool bInstanced = false) = 0;
// Set Index stream
virtual long FX_SetIStream(const void* pB, uint32 nOffs, RenderIndexType idxType) = 0;
@@ -2312,7 +2312,7 @@ struct IRenderer
virtual long FX_SetVStream(int nID, const void* pB, uint32 nOffs, uint32 nStride, uint32 nFreq = 1) = 0;
// Draw primitives
virtual void FX_DrawPrimitive(const eRenderPrimitiveType eType, const int nStartVertex, const int nVerticesCount, const int nInstanceVertices = 0) = 0;
virtual void FX_DrawPrimitive(eRenderPrimitiveType eType, int nStartVertex, int nVerticesCount, int nInstanceVertices = 0) = 0;
// Clear texture
virtual void FX_ClearTarget(ITexture* pTex) = 0;
@@ -2370,7 +2370,7 @@ struct IRenderer
virtual void ApplyDepthTextureState(int unit, int nFilter, bool clamp) = 0;
virtual ITexture* GetZTargetTexture() = 0;
virtual int GetTextureState(const STexState& TS) = 0;
virtual uint32 TextureDataSize(uint32 nWidth, uint32 nHeight, uint32 nDepth, uint32 nMips, uint32 nSlices, const ETEX_Format eTF, ETEX_TileMode eTM = eTM_None) = 0;
virtual uint32 TextureDataSize(uint32 nWidth, uint32 nHeight, uint32 nDepth, uint32 nMips, uint32 nSlices, ETEX_Format eTF, ETEX_TileMode eTM = eTM_None) = 0;
virtual void ApplyForID(int nID, int nTUnit, int nTState, int nTexMaterialSlot, int nSUnit, bool useWhiteDefault) = 0;
virtual ITexture* Create3DTexture(const char* szName, int nWidth, int nHeight, int nDepth, int nMips, int nFlags, const byte* pData, ETEX_Format eTFSrc, ETEX_Format eTFDst) = 0;
virtual bool IsTextureExist(const ITexture* pTex) = 0;
+4 -4
View File
@@ -1267,7 +1267,7 @@ struct ISystem
// Arguments:
// bValue - Set to true when running on a cheat protected server or a client that is connected to it (not used in singleplayer).
virtual void SetForceNonDevMode(const bool bValue) = 0;
virtual void SetForceNonDevMode(bool bValue) = 0;
// Return Value:
// True when running on a cheat protected server or a client that is connected to it (not used in singleplayer).
virtual bool GetForceNonDevMode() const = 0;
@@ -1386,12 +1386,12 @@ struct ISystem
// Summary:
// Changes current configuration platform.
virtual void SetConfigPlatform(const ESystemConfigPlatform platform) = 0;
virtual void SetConfigPlatform(ESystemConfigPlatform platform) = 0;
//////////////////////////////////////////////////////////////////////////
// Summary:
// Detects and set optimal spec.
virtual void AutoDetectSpec(const bool detectResolution) = 0;
virtual void AutoDetectSpec(bool detectResolution) = 0;
// Summary:
// Thread management for subsystems
@@ -1519,7 +1519,7 @@ struct ISystem
// it adds a line to "MemoryCoverage.bmp" (generated the first time, there is a max line count).
virtual void DumpMemoryCoverage() = 0;
virtual ESystemGlobalState GetSystemGlobalState(void) = 0;
virtual void SetSystemGlobalState(const ESystemGlobalState systemGlobalState) = 0;
virtual void SetSystemGlobalState(ESystemGlobalState systemGlobalState) = 0;
// Summary:
// Asynchronous memcpy
+1 -1
View File
@@ -323,7 +323,7 @@ public:
/*LATER*/
}
virtual void SetKeepSystemCopy(const bool bKeepSystemCopy) = 0;
virtual void SetKeepSystemCopy(bool bKeepSystemCopy) = 0;
virtual void UpdateTextureRegion(const uint8_t* data, int nX, int nY, int nZ, int USize, int VSize, int ZSize, ETEX_Format eTFSrc) = 0;
virtual CDeviceTexture* GetDevTexture() const = 0;
+1 -1
View File
@@ -87,7 +87,7 @@ namespace MaterialUtils
if (cachedGameName[0] == 0)
{
// at least substitute something so that unit tests can make this assumption:
azstrcpy(cachedGameName, AZ_MAX_PATH_LEN, "SamplesProject/");
azstrcpy(cachedGameName, AZ_MAX_PATH_LEN, "AutomatedTesting/");
}
removals[removalSize - 1] = cachedGameName;
@@ -69,9 +69,9 @@ public:
MOCK_METHOD0(Release,
void());
MOCK_METHOD3(RenderWorld,
void(const int nRenderFlags, const SRenderingPassInfo& passInfo, const char* szDebugName));
void(int nRenderFlags, const SRenderingPassInfo& passInfo, const char* szDebugName));
MOCK_METHOD2(RenderSceneReflection,
void(const int nRenderFlags, const SRenderingPassInfo& passInfo));
void(int nRenderFlags, const SRenderingPassInfo& passInfo));
MOCK_METHOD1(PreWorldStreamUpdate,
void(const CCamera& cam));
MOCK_METHOD0(WorldStreamUpdate,
@@ -262,7 +262,7 @@ public:
MOCK_METHOD1(GetLevelFilePath,
const char*(const char* szFileName));
MOCK_METHOD4(DisplayInfo,
void(float& fTextPosX, float& fTextPosY, float& fTextStepY, const bool bEnhanced));
void(float& fTextPosX, float& fTextPosY, float& fTextStepY, bool bEnhanced));
MOCK_METHOD0(DisplayMemoryStatistics,
void());
@@ -19,16 +19,16 @@ namespace Audio
struct AudioProxyMock
: public IAudioProxy
{
MOCK_METHOD2(Initialize, void(const char* const sObjectName, const bool bInitAsync /* = true */));
MOCK_METHOD2(Initialize, void(const char* const sObjectName, bool bInitAsync /* = true */));
MOCK_METHOD0(Release, void());
MOCK_METHOD0(Reset, void());
MOCK_METHOD1(StopTrigger, void(const TAudioControlID nTriggerID));
MOCK_METHOD2(SetSwitchState, void(const TAudioControlID nSwitchID, const TAudioSwitchStateID nStateID));
MOCK_METHOD2(SetRtpcValue, void(const TAudioControlID nRtpcID, const float fValue));
MOCK_METHOD1(SetObstructionCalcType, void(const EAudioObjectObstructionCalcType eObstructionType));
MOCK_METHOD1(StopTrigger, void(TAudioControlID nTriggerID));
MOCK_METHOD2(SetSwitchState, void(TAudioControlID nSwitchID, TAudioSwitchStateID nStateID));
MOCK_METHOD2(SetRtpcValue, void(TAudioControlID nRtpcID, float fValue));
MOCK_METHOD1(SetObstructionCalcType, void(EAudioObjectObstructionCalcType eObstructionType));
MOCK_METHOD1(SetPosition, void(const SATLWorldPosition& rPosition));
MOCK_METHOD1(SetPosition, void(const AZ::Vector3& rPosition));
MOCK_METHOD2(SetEnvironmentAmount, void(const TAudioEnvironmentID nEnvironmentID, const float fAmount));
MOCK_METHOD2(SetEnvironmentAmount, void(TAudioEnvironmentID nEnvironmentID, float fAmount));
MOCK_METHOD0(SetCurrentEnvironments, void());
MOCK_CONST_METHOD0(GetAudioObjectID, TAudioObjectID());
};
@@ -39,25 +39,25 @@ namespace Audio
MOCK_METHOD0(Initialize, bool());
MOCK_METHOD0(Release, void());
MOCK_METHOD1(PushRequest, void(const SAudioRequest& rAudioRequestData));
MOCK_METHOD4(AddRequestListener, void(AudioRequestCallbackType func, void* const pObjectToListenTo, const EAudioRequestType requestType /* = eART_AUDIO_ALL_REQUESTS */, const TATLEnumFlagsType specificRequestMask /* = ALL_AUDIO_REQUEST_SPECIFIC_TYPE_FLAGS */));
MOCK_METHOD2(RemoveRequestListener, void(AudioRequestCallbackType func, void* const pObjectToListenTo));
MOCK_METHOD4(AddRequestListener, void(AudioRequestCallbackType func, void* pObjectToListenTo, EAudioRequestType requestType /* = eART_AUDIO_ALL_REQUESTS */, TATLEnumFlagsType specificRequestMask /* = ALL_AUDIO_REQUEST_SPECIFIC_TYPE_FLAGS */));
MOCK_METHOD2(RemoveRequestListener, void(AudioRequestCallbackType func, void* pObjectToListenTo));
MOCK_METHOD0(ExternalUpdate, void());
MOCK_CONST_METHOD1(GetAudioTriggerID, TAudioControlID(const char* const sAudioTriggerName));
MOCK_CONST_METHOD1(GetAudioRtpcID, TAudioControlID(const char* const sAudioRtpcName));
MOCK_CONST_METHOD1(GetAudioSwitchID, TAudioControlID(const char* const sAudioSwitchName));
MOCK_CONST_METHOD2(GetAudioSwitchStateID, TAudioSwitchStateID(const TAudioControlID nSwitchID, const char* const sAudioStateName));
MOCK_CONST_METHOD1(GetAudioPreloadRequestID, TAudioPreloadRequestID(const char* const sAudioPreloadRequestName));
MOCK_CONST_METHOD1(GetAudioEnvironmentID, TAudioEnvironmentID(const char* const sAudioEnvironmentName));
MOCK_CONST_METHOD1(GetAudioTriggerID, TAudioControlID(const char* sAudioTriggerName));
MOCK_CONST_METHOD1(GetAudioRtpcID, TAudioControlID(const char* sAudioRtpcName));
MOCK_CONST_METHOD1(GetAudioSwitchID, TAudioControlID(const char* sAudioSwitchName));
MOCK_CONST_METHOD2(GetAudioSwitchStateID, TAudioSwitchStateID(const TAudioControlID nSwitchID, const char* sAudioStateName));
MOCK_CONST_METHOD1(GetAudioPreloadRequestID, TAudioPreloadRequestID(const char* sAudioPreloadRequestName));
MOCK_CONST_METHOD1(GetAudioEnvironmentID, TAudioEnvironmentID(const char* sAudioEnvironmentName));
MOCK_METHOD1(ReserveAudioListenerID, bool(TAudioObjectID& rAudioListenerID));
MOCK_METHOD1(ReleaseAudioListenerID, bool(const TAudioObjectID nAudioObjectID));
MOCK_METHOD1(ReleaseAudioListenerID, bool(TAudioObjectID nAudioObjectID));
MOCK_METHOD1(OnCVarChanged, void(ICVar* const pCVar));
MOCK_METHOD1(GetInfo, void(SAudioSystemInfo& rAudioSystemInfo));
MOCK_CONST_METHOD0(GetControlsPath, const char*());
MOCK_METHOD0(UpdateControlsPath, void());
MOCK_METHOD0(GetFreeAudioProxy, IAudioProxy*());
MOCK_METHOD1(FreeAudioProxy, void(IAudioProxy* const pIAudioProxy));
MOCK_CONST_METHOD2(GetAudioControlName, const char*(const EAudioControlType eAudioEntityType, const TATLIDType nAudioEntityID));
MOCK_CONST_METHOD2(GetAudioSwitchStateName, const char*(const TAudioControlID switchID, const TAudioSwitchStateID stateID));
MOCK_METHOD1(FreeAudioProxy, void(IAudioProxy* pIAudioProxy));
MOCK_CONST_METHOD2(GetAudioControlName, const char*(EAudioControlType eAudioEntityType, TATLIDType nAudioEntityID));
MOCK_CONST_METHOD2(GetAudioSwitchStateName, const char*(TAudioControlID switchID, TAudioSwitchStateID stateID));
};
} // namespace Audio
+2 -2
View File
@@ -29,8 +29,8 @@ public:
MOCK_CONST_METHOD0(GetDataProbeString, const char*());
MOCK_METHOD1(Set, void(const char*));
MOCK_METHOD1(ForceSet, void(const char*));
MOCK_METHOD1(Set, void(const float));
MOCK_METHOD1(Set, void(const int));
MOCK_METHOD1(Set, void(float));
MOCK_METHOD1(Set, void(int));
MOCK_METHOD1(ClearFlags, void(const int));
MOCK_CONST_METHOD0(GetFlags, int());
MOCK_METHOD1(SetFlags, int(const int));
@@ -36,14 +36,14 @@ public:
MOCK_METHOD1(SetScrollMax, void(int value));
MOCK_METHOD1(AddOutputPrintSink, void(IOutputPrintSink * inpSink));
MOCK_METHOD1(RemoveOutputPrintSink, void(IOutputPrintSink * inpSink));
MOCK_METHOD2(ShowConsole, void(bool show, const int iRequestScrollMax));
MOCK_METHOD2(ShowConsole, void(bool show, int iRequestScrollMax));
MOCK_METHOD2(DumpCVars, void(ICVarDumpSink * pCallback, unsigned int nFlagsFilter));
MOCK_METHOD2(CreateKeyBind, void(const char* sCmd, const char* sRes));
MOCK_METHOD2(SetImage, void (ITexture * pImage, bool bDeleteCurrent));
MOCK_METHOD0(GetImage, ITexture * ());
MOCK_METHOD1(StaticBackground, void (bool bStatic));
MOCK_METHOD1(SetLoadingImage, void(const char* szFilename));
MOCK_CONST_METHOD3(GetLineNo, bool(const int indwLineNo, char* outszBuffer, const int indwBufferSize));
MOCK_CONST_METHOD3(GetLineNo, bool(int indwLineNo, char* outszBuffer, int indwBufferSize));
MOCK_CONST_METHOD0(GetLineCount, int ());
MOCK_METHOD1(GetCVar, ICVar * (const char* name));
MOCK_METHOD3(GetVariable, char*(const char* szVarName, const char* szFileName, const char* def_val));
@@ -57,7 +57,7 @@ public:
MOCK_METHOD4(AddCommand, bool (const char* sCommand, ConsoleCommandFunc func, int nFlags, const char* sHelp));
MOCK_METHOD4(AddCommand, bool (const char* sName, const char* sScriptFunc, int nFlags, const char* sHelp));
MOCK_METHOD1(RemoveCommand, void (const char* sName));
MOCK_METHOD3(ExecuteString, void (const char* command, const bool bSilentMode, const bool bDeferExecution ));
MOCK_METHOD3(ExecuteString, void (const char* command, bool bSilentMode, bool bDeferExecution ));
MOCK_METHOD0(IsOpened, bool ());
MOCK_METHOD0(GetNumVars, int());
MOCK_METHOD0(GetNumVisibleVars, int());
@@ -83,7 +83,7 @@ public:
MOCK_METHOD1(GetCheatVarAt, char* (uint32 nOffset));
MOCK_METHOD1(AddConsoleVarSink, void (IConsoleVarSink * pSink));
MOCK_METHOD1(RemoveConsoleVarSink, void (IConsoleVarSink * pSink));
MOCK_METHOD1(GetHistoryElement, const char*(const bool bUpOrDown));
MOCK_METHOD1(GetHistoryElement, const char*(bool bUpOrDown));
MOCK_METHOD1(AddCommandToHistory, void (const char* szCommand));
MOCK_METHOD2(LoadConfigVar, void (const char* sVariable, const char* sValue));
MOCK_METHOD1(EnableActivationKey, void (bool bEnable));
+2 -2
View File
@@ -17,9 +17,9 @@ class LogMock
{
public:
MOCK_METHOD3(LogV,
void(const ELogType nType, const char* szFormat, va_list args));
void(ELogType nType, const char* szFormat, va_list args));
MOCK_METHOD4(LogV,
void(const ELogType nType, int flags, const char* szFormat, va_list args));
void(ELogType nType, int flags, const char* szFormat, va_list args));
MOCK_METHOD0(Release,
void());
MOCK_METHOD2(SetFileName,
+11 -11
View File
@@ -63,9 +63,9 @@ public:
MOCK_CONST_METHOD2(GetCurrentNumberOfDrawCalls,
void(int& nGeneral, int& nShadowGen));
MOCK_CONST_METHOD1(GetCurrentNumberOfDrawCalls,
int(const uint32 EFSListMask));
int(uint32 EFSListMask));
MOCK_CONST_METHOD1(GetCurrentDrawCallRTTimes,
float(const uint32 EFSListMask));
float(uint32 EFSListMask));
MOCK_METHOD1(SetDebugRenderNode,
void(IRenderNode * pRenderNode));
MOCK_CONST_METHOD1(IsDebugRenderNode,
@@ -135,7 +135,7 @@ public:
MOCK_METHOD1(ApplyViewParameters,
void(const CameraViewParameters& viewParameters));
MOCK_METHOD5(DrawDynVB,
void(SVF_P3F_C4B_T2F * pBuf, uint16 * pInds, int nVerts, int nInds, const PublicRenderPrimitiveType nPrimType));
void(SVF_P3F_C4B_T2F * pBuf, uint16 * pInds, int nVerts, int nInds, PublicRenderPrimitiveType nPrimType));
// Hand-edit: google mock has issues with DynUiPrimitiveList
void DrawDynUiPrimitiveList([[maybe_unused]] DynUiPrimitiveList& primitives, [[maybe_unused]] int totalNumVertices, [[maybe_unused]] int totalNumIndices) override { return; }
@@ -147,7 +147,7 @@ public:
MOCK_METHOD1(GetRenderViewForThread,
CRenderView * (int nThreadID));
MOCK_METHOD1(SetGammaDelta,
bool(const float fGamma));
bool(float fGamma));
MOCK_METHOD0(RestoreGamma,
void(void));
MOCK_METHOD3(ChangeDisplay,
@@ -255,7 +255,7 @@ public:
MOCK_METHOD3(FlushRTCommands,
bool(bool bWait, bool bImmediatelly, bool bForce));
MOCK_CONST_METHOD7(DrawStringU,
void(IFFont_RenderProxy * pFont, float x, float y, float z, const char* pStr, const bool asciiMultiLine, const STextDrawContext& ctx));
void(IFFont_RenderProxy * pFont, float x, float y, float z, const char* pStr, bool asciiMultiLine, const STextDrawContext& ctx));
MOCK_METHOD0(RT_CurThreadList,
int());
MOCK_METHOD6(EF_PrecacheResource,
@@ -343,9 +343,9 @@ public:
MOCK_METHOD7(EF_AddEf,
void(IRenderElement * pRE, SShaderItem & pSH, CRenderObject * pObj, const SRenderingPassInfo& passInfo, int nList, int nAW, const SRendItemSorter& rendItemSorter));
MOCK_METHOD4(EF_EndEf3D,
void(const int nFlags, const int nPrecacheUpdateId, const int nNearPrecacheUpdateId, const SRenderingPassInfo& passInfo));
void(int nFlags, int nPrecacheUpdateId, int nNearPrecacheUpdateId, const SRenderingPassInfo& passInfo));
MOCK_METHOD1(EF_InvokeShadowMapRenderJobs,
void(const int nFlags));
void(int nFlags));
MOCK_METHOD1(EF_IsFakeDLight,
bool(const CDLight * Source));
MOCK_METHOD2(EF_ADDDlight,
@@ -393,11 +393,11 @@ public:
MOCK_METHOD0(EF_DisableTemporalEffects,
void());
MOCK_METHOD3(EF_AddWaterSimHit,
void(const Vec3& vPos, const float scale, const float strength));
void(const Vec3& vPos, float scale, float strength));
MOCK_METHOD0(EF_DrawWaterSimHits,
void());
MOCK_METHOD1(EF_EndEf2D,
void(const bool bSort));
void(bool bSort));
MOCK_METHOD0(ForceGC,
void());
MOCK_CONST_METHOD0(GetPolyCount,
@@ -532,7 +532,7 @@ public:
MOCK_METHOD8(DXTCompress,
bool(const byte * raw_data, int nWidth, int nHeight, ETEX_Format eTF, bool bUseHW, bool bGenMips, int nSrcBytesPerPix, MIPDXTcallback callback));
MOCK_METHOD9(DXTDecompress,
bool(const byte * srcData, const size_t srcFileSize, byte * dstData, int nWidth, int nHeight, int nMips, ETEX_Format eSrcTF, bool bUseHW, int nDstBytesPerPix));
bool(const byte * srcData, size_t srcFileSize, byte * dstData, int nWidth, int nHeight, int nMips, ETEX_Format eSrcTF, bool bUseHW, int nDstBytesPerPix));
MOCK_METHOD1(RemoveTexture,
void(unsigned int TextureId));
MOCK_METHOD1(DeleteFont,
@@ -727,7 +727,7 @@ public:
MOCK_METHOD1(EndScreenShot,
void(int e_ScreenShot));
MOCK_METHOD3(SetRendererCVar,
void(ICVar*, const char*, const bool));
void(ICVar*, const char*, bool));
MOCK_METHOD0(GetRenderPipeline,
SRenderPipeline * ());
MOCK_METHOD0(GetShaderManager,
@@ -107,7 +107,7 @@ public:
MOCK_METHOD3(GetLowResSystemCopy,
const ColorB * (uint16 & nWidth, uint16 & nHeight, int** ppLowResSystemCopyAtlasId));
MOCK_METHOD1(SetKeepSystemCopy,
void(const bool bKeepSystemCopy));
void(bool bKeepSystemCopy));
MOCK_METHOD8(UpdateTextureRegion,
void(const uint8_t * data, int nX, int nY, int nZ, int USize, int VSize, int ZSize, ETEX_Format eTFSrc));
MOCK_CONST_METHOD0(GetDevTexture,
@@ -401,8 +401,8 @@ IResourceCompilerHelper::ERcCallResult CResourceCompilerHelper::CallResourceComp
[[maybe_unused]] const wchar_t* szRootPath)
{
#if defined(AZ_PLATFORM_WINDOWS)
HANDLE hChildStdOutRd, hChildStdOutWr;
HANDLE hChildStdInRd, hChildStdInWr;
HANDLE hChildStdOutRd = INVALID_HANDLE_VALUE, hChildStdOutWr = INVALID_HANDLE_VALUE;
HANDLE hChildStdInRd = INVALID_HANDLE_VALUE, hChildStdInWr = INVALID_HANDLE_VALUE;
PROCESS_INFORMATION pi;
#else
FILE* hChildStdOutRd;
+1 -1
View File
@@ -2112,7 +2112,7 @@ struct pe_status_area
{
type_id = ePE_status_area
};
pe_status_area() { type = type_id; bUniformOnly = false; ctr.zero(); size.zero(); vel.zero(); MARK_UNUSED gravity, pb; pLockUpdate = 0; pSurface = 0; }
pe_status_area() { type = type_id; bUniformOnly = false; ctr.zero(); size.zero(); vel.zero(); MARK_UNUSED gravity; pLockUpdate = 0; pSurface = 0; }
// inputs.
Vec3 ctr, size; // query bounds
+28 -10
View File
@@ -19,6 +19,7 @@
#include "System.h"
#include "IStreamEngine.h"
#include <AzFramework/Archive/Archive.h>
#include <AzFramework/API/ApplicationAPI.h>
#include "ResourceManager.h"
#define MEGA_BYTE 1024* 1024
@@ -360,20 +361,37 @@ void CAsyncPakManager::StreamAsyncOnComplete(
}
else
{
//
// ugly hack - depending on the pak file pak may need special root info / open flags
//
if (pLayerPak->layername.find("level.pak") != string::npos)
bool usePrefabSystemForLevels = false;
AzFramework::ApplicationRequests::Bus::BroadcastResult(
usePrefabSystemForLevels,
&AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
if (usePrefabSystemForLevels)
{
gEnv->pCryPak->OpenPack({ pLayerPak->filename.c_str(), pLayerPak->filename.size() }, AZ::IO::IArchive::FLAGS_FILENAMES_AS_CRC32, NULL);
}
else if (pLayerPak->layername.find("levelshadercache.pak") != string::npos)
{
gEnv->pCryPak->OpenPack("@assets@", { pLayerPak->filename.c_str(), pLayerPak->filename.size() }, AZ::IO::IArchive::FLAGS_PATH_REAL, NULL);
gEnv->pCryPak->OpenPack(
"@assets@", {pLayerPak->filename.c_str(), pLayerPak->filename.size()}, AZ::IO::IArchive::FLAGS_FILENAMES_AS_CRC32, NULL);
}
else
{
gEnv->pCryPak->OpenPack("@assets@", { pLayerPak->filename.c_str(), pLayerPak->filename.size() }, AZ::IO::IArchive::FLAGS_FILENAMES_AS_CRC32, NULL);
//
// ugly hack - depending on the pak file pak may need special root info / open flags
//
if (pLayerPak->layername.find("level.pak") != string::npos)
{
gEnv->pCryPak->OpenPack(
{pLayerPak->filename.c_str(), pLayerPak->filename.size()}, AZ::IO::IArchive::FLAGS_FILENAMES_AS_CRC32, NULL);
}
else if (pLayerPak->layername.find("levelshadercache.pak") != string::npos)
{
gEnv->pCryPak->OpenPack(
"@assets@", {pLayerPak->filename.c_str(), pLayerPak->filename.size()}, AZ::IO::IArchive::FLAGS_PATH_REAL, NULL);
}
else
{
gEnv->pCryPak->OpenPack(
"@assets@", {pLayerPak->filename.c_str(), pLayerPak->filename.size()}, AZ::IO::IArchive::FLAGS_FILENAMES_AS_CRC32,
NULL);
}
}
gEnv->pCryPak->LoadPakToMemory(pLayerPak->filename.c_str(), AZ::IO::IArchive::eInMemoryPakLocale_GPU, pLayerPak->pData);
}
File diff suppressed because it is too large Load Diff
@@ -16,6 +16,8 @@
#include "ILevelSystem.h"
#include <AzFramework/Archive/IArchive.h>
// [LYN-2376] Remove the entire file once legacy slice support is removed
namespace LegacyLevelSystem
{
@@ -24,75 +26,38 @@ class CLevelInfo
{
friend class CLevelSystem;
public:
CLevelInfo()
: m_heightmapSize(0)
, m_bMetaDataRead(false)
, m_isModLevel(false)
, m_scanTag(ILevelSystem::TAG_UNKNOWN)
, m_levelTag(ILevelSystem::TAG_UNKNOWN)
{
SwapEndian(m_scanTag, eBigEndian);
SwapEndian(m_levelTag, eBigEndian);
};
CLevelInfo() = default;
// ILevelInfo
virtual const char* GetName() const { return m_levelName.c_str(); };
virtual const bool IsOfType(const char* sType) const;
virtual const char* GetPath() const { return m_levelPath.c_str(); };
virtual const char* GetPaks() const { return m_levelPaks.c_str(); };
virtual bool GetIsModLevel() const { return m_isModLevel; }
virtual const uint32 GetScanTag() const { return m_scanTag; }
virtual const uint32 GetLevelTag() const { return m_levelTag; }
virtual const char* GetDisplayName() const;
virtual const char* GetPreviewImagePath() const { return m_previewImagePath.c_str(); }
virtual const char* GetBackgroundImagePath() const { return m_backgroundImagePath.c_str(); }
virtual const char* GetMinimapImagePath() const {return m_minimapImagePath.c_str(); }
//virtual const ILevelInfo::TStringVec& GetMusicLibs() const { return m_musicLibs; }; // Gets reintroduced when level specific music data loading is implemented.
virtual const bool MetadataLoaded() const { return m_bMetaDataRead; }
virtual int GetGameTypeCount() const { return m_gameTypes.size(); };
virtual const ILevelInfo::TGameTypeInfo* GetGameType(int gameType) const { return &m_gameTypes[gameType]; };
virtual bool SupportsGameType(const char* gameTypeName) const;
virtual const ILevelInfo::TGameTypeInfo* GetDefaultGameType() const;
virtual bool HasGameRules() const{ return !m_gamerules.empty(); }
virtual const ILevelInfo::SMinimapInfo& GetMinimapInfo() const { return m_minimapInfo; }
virtual const char* GetDefaultGameRules() const{ return m_gamerules.empty() ? NULL : m_gamerules[0].c_str(); }
virtual ILevelInfo::TStringVec GetGameRules() const{ return m_gamerules; }
virtual const char* GetName() const { return m_levelName.c_str(); }
virtual const char* GetPath() const { return m_levelPath.c_str(); }
virtual const char* GetAssetName() const { return m_levelAssetName.c_str(); }
// ~ILevelInfo
void GetMemoryUsage(ICrySizer*) const;
private:
void ReadMetaData();
bool ReadInfo();
bool OpenLevelPak();
void CloseLevelPak();
string m_levelName;
string m_levelPath;
string m_levelPaks;
string m_levelDisplayName;
string m_previewImagePath;
string m_backgroundImagePath;
string m_minimapImagePath;
AZStd::string m_defaultGameTypeName;
AZStd::string m_levelName;
AZStd::string m_levelPath;
AZStd::string m_levelAssetName;
string m_levelPakFullPath;
AZStd::string m_levelPakFullPath;
TStringVec m_gamerules;
int m_heightmapSize;
uint32 m_scanTag;
uint32 m_levelTag;
bool m_bMetaDataRead;
std::vector<ILevelInfo::TGameTypeInfo> m_gameTypes;
bool m_isModLevel;
SMinimapInfo m_minimapInfo;
bool m_isPak = false;
};
DynArray<string> m_levelTypeList;
bool m_isPak = false;
struct ILevel
{
virtual ~ILevel() = default;
virtual void Release() = 0;
virtual ILevelInfo* GetLevelInfo() = 0;
};
class CLevel
@@ -121,10 +86,7 @@ public:
void Release() { delete this; };
// ILevelSystem
virtual DynArray<string>* GetLevelTypeList();
virtual void Rescan(const char* levelsFolder, const uint32 tag);
void ScanFolder(const char* subfolder, bool modFolder, const uint32 tag) override;
void PopulateLevels(string searchPattern, string& folder, AZ::IO::IArchive* pPak, bool& modFolder, const uint32& tag, bool fromFileSystemOnly) override;
virtual void Rescan(const char* levelsFolder);
virtual int GetLevelCount();
virtual ILevelInfo* GetLevelInfo(int level);
virtual ILevelInfo* GetLevelInfo(const char* levelName);
@@ -132,74 +94,81 @@ public:
virtual void AddListener(ILevelSystemListener* pListener);
virtual void RemoveListener(ILevelSystemListener* pListener);
virtual ILevel* GetCurrentLevel() const { return m_pCurrentLevel; }
virtual ILevel* LoadLevel(const char* levelName);
virtual void UnLoadLevel();
virtual ILevel* SetEditorLoadedLevel(const char* levelName, bool bReadLevelInfoMetaData = false);
virtual void PrepareNextLevel(const char* levelName);
virtual float GetLastLevelLoadTime() { return m_fLastLevelLoadTime; };
virtual bool LoadLevel(const char* levelName);
virtual void UnloadLevel();
virtual bool IsLevelLoaded() { return m_bLevelLoaded; }
const char* GetCurrentLevelName() const override
{
if (m_pCurrentLevel && m_pCurrentLevel->GetLevelInfo())
{
return m_pCurrentLevel->GetLevelInfo()->GetName();
}
else
{
return "";
}
}
// If the level load failed then we need to have a different shutdown procedure vs when a level is naturally unloaded
virtual void SetLevelLoadFailed(bool loadFailed) { m_levelLoadFailed = loadFailed; }
virtual bool GetLevelLoadFailed() { return m_levelLoadFailed; }
// Unsupported by legacy level system.
virtual AZ::Data::AssetType GetLevelAssetType() const { return {}; }
// ~ILevelSystem
void GetMemoryUsage(ICrySizer* s) const;
void SaveOpenedFilesList();
private:
float GetLastLevelLoadTime() { return m_fLastLevelLoadTime; }
void ScanFolder(const char* subfolder, bool modFolder);
void PopulateLevels(
AZStd::string searchPattern, AZStd::string& folder, AZ::IO::IArchive* pPak, bool& modFolder, bool fromFileSystemOnly);
void PrepareNextLevel(const char* levelName);
ILevel* LoadLevelInternal(const char* _levelName);
// ILevelSystemListener events notification
// Methods to notify ILevelSystemListener
void OnLevelNotFound(const char* levelName);
void OnLoadingStart(ILevelInfo* pLevel);
void OnLoadingComplete(ILevel* pLevel);
void OnLoadingError(ILevelInfo* pLevel, const char* error);
void OnLoadingProgress(ILevelInfo* pLevel, int progressAmount);
void OnUnloadComplete(ILevel* pLevel);
void OnLoadingStart(const char* levelName);
void OnLoadingComplete(const char* levelName);
void OnLoadingError(const char* levelName, const char* error);
void OnLoadingProgress(const char* levelName, int progressAmount);
void OnUnloadComplete(const char* levelName);
// lowercase string and replace backslashes with forward slashes
// TODO: move this to a more general place in CryEngine
string& UnifyName(string& name);
void LogLoadingTime();
bool LoadLevelInfo(CLevelInfo& levelInfo);
// internal get functions for the level infos ... they preserve the type and don't
// directly cast to the interface
CLevelInfo* GetLevelInfoInternal(int level);
CLevelInfo* GetLevelInfoInternal(const char* levelName);
CLevelInfo* GetLevelInfoInternal(const AZStd::string& levelName);
ISystem* m_pSystem;
std::vector<CLevelInfo> m_levelInfos;
string m_levelsFolder;
AZStd::vector<CLevelInfo> m_levelInfos;
AZStd::string m_levelsFolder;
ILevel* m_pCurrentLevel;
ILevelInfo* m_pLoadingLevelInfo;
string m_lastLevelName;
AZStd::string m_lastLevelName;
float m_fLastLevelLoadTime;
float m_fFilteredProgress;
float m_fLastTime;
bool m_bLevelLoaded;
bool m_bRecordingFileOpens;
bool m_levelLoadFailed = false;
int m_nLoadedLevelsCount;
CTimeValue m_levelLoadStartTime;
static int s_loadCount;
std::vector<ILevelSystemListener*> m_listeners;
DynArray<string> m_levelTypeList;
AZStd::vector<ILevelSystemListener*> m_listeners;
AZ::IO::IArchive::LevelPackOpenEvent::Handler m_levelPackOpenHandler;
AZ::IO::IArchive::LevelPackCloseEvent::Handler m_levelPackCloseHandler;
static constexpr const char* LevelPakName = "level.pak";
};
} // namespace LegacyLevelSystem
@@ -0,0 +1,709 @@
/*
* 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.
*
*/
#include "CrySystem_precompiled.h"
#include "SpawnableLevelSystem.h"
#include <IAudioSystem.h>
#include "IMovieSystem.h"
#include <IResourceManager.h>
#include "IDeferredCollisionEvent.h"
#include <LoadScreenBus.h>
#include <AzCore/Debug/AssetTracking.h>
#include <AzFramework/API/ApplicationAPI.h>
#include <AzFramework/IO/FileOperations.h>
#include <AzFramework/Entity/GameEntityContextBus.h>
#include <AzFramework/Input/Buses/Requests/InputChannelRequestBus.h>
#include "MainThreadRenderRequestBus.h"
#include <LyShine/ILyShine.h>
#include <AzCore/Component/TickBus.h>
#include <AzCore/IO/Path/Path.h>
#include <AzCore/StringFunc/StringFunc.h>
#include <AzCore/Script/ScriptSystemBus.h>
namespace LegacyLevelSystem
{
//------------------------------------------------------------------------
static void LoadLevel(const AZ::ConsoleCommandContainer& arguments)
{
AZ_Error("SpawnableLevelSystem", arguments.empty(), "LoadLevel requires a level file name to be provided.");
AZ_Error("SpawnableLevelSystem", arguments.size() > 1, "LoadLevel requires a single level file name to be provided.");
if (!arguments.empty() && gEnv->pSystem && gEnv->pSystem->GetILevelSystem() && !gEnv->IsEditor())
{
gEnv->pSystem->GetILevelSystem()->LoadLevel(arguments[0].data());
}
}
//------------------------------------------------------------------------
static void UnloadLevel([[maybe_unused]] const AZ::ConsoleCommandContainer& arguments)
{
AZ_Warning("SpawnableLevelSystem", !arguments.empty(), "UnloadLevel doesn't use any arguments.");
if (gEnv->pSystem && gEnv->pSystem->GetILevelSystem() && !gEnv->IsEditor())
{
gEnv->pSystem->GetILevelSystem()->UnloadLevel();
if (gEnv->p3DEngine)
{
gEnv->p3DEngine->LoadEmptyLevel();
}
}
}
AZ_CONSOLEFREEFUNC(LoadLevel, AZ::ConsoleFunctorFlags::Null, "Unloads the current level and loads a new one with the given asset name");
AZ_CONSOLEFREEFUNC(UnloadLevel, AZ::ConsoleFunctorFlags::Null, "Unloads the current level");
//------------------------------------------------------------------------
SpawnableLevelSystem::SpawnableLevelSystem(ISystem* pSystem)
: m_pSystem(pSystem)
{
LOADING_TIME_PROFILE_SECTION;
CRY_ASSERT(pSystem);
m_fLastLevelLoadTime = 0;
m_fLastTime = 0;
m_bLevelLoaded = false;
m_levelLoadStartTime.SetValue(0);
m_nLoadedLevelsCount = 0;
AZ_Assert(gEnv && gEnv->pCryPak, "gEnv and CryPak must be initialized for loading levels.");
if (!gEnv || !gEnv->pCryPak)
{
return;
}
auto pPak = gEnv->pCryPak;
AzFramework::RootSpawnableNotificationBus::Handler::BusConnect();
}
//------------------------------------------------------------------------
SpawnableLevelSystem::~SpawnableLevelSystem()
{
AzFramework::RootSpawnableNotificationBus::Handler::BusDisconnect();
}
void SpawnableLevelSystem::Release()
{
delete this;
}
bool SpawnableLevelSystem::IsLevelLoaded()
{
return m_bLevelLoaded;
}
const char* SpawnableLevelSystem::GetCurrentLevelName() const
{
return m_bLevelLoaded ? m_lastLevelName.c_str() : "";
}
// If the level load failed then we need to have a different shutdown procedure vs when a level is naturally unloaded
void SpawnableLevelSystem::SetLevelLoadFailed(bool loadFailed)
{
m_levelLoadFailed = loadFailed;
}
bool SpawnableLevelSystem::GetLevelLoadFailed()
{
return m_levelLoadFailed;
}
AZ::Data::AssetType SpawnableLevelSystem::GetLevelAssetType() const
{
return azrtti_typeid<AzFramework::Spawnable>();
}
// The following methods are deprecated from ILevelSystem and will be removed once slice support is removed.
// [LYN-2376] Remove once legacy slice support is removed
void SpawnableLevelSystem::Rescan([[maybe_unused]] const char* levelsFolder)
{
AZ_Assert(false, "Rescan - No longer supported.");
}
// [LYN-2376] Remove once legacy slice support is removed
int SpawnableLevelSystem::GetLevelCount()
{
AZ_Assert(false, "GetLevelCount - No longer supported.");
return 0;
}
// [LYN-2376] Remove once legacy slice support is removed
ILevelInfo* SpawnableLevelSystem::GetLevelInfo([[maybe_unused]] int level)
{
AZ_Assert(false, "GetLevelInfo - No longer supported.");
return nullptr;
}
// [LYN-2376] Remove once legacy slice support is removed
ILevelInfo* SpawnableLevelSystem::GetLevelInfo([[maybe_unused]] const char* levelName)
{
AZ_Assert(false, "GetLevelInfo - No longer supported.");
return nullptr;
}
//------------------------------------------------------------------------
void SpawnableLevelSystem::AddListener(ILevelSystemListener* pListener)
{
AZStd::vector<ILevelSystemListener*>::iterator it = AZStd::find(m_listeners.begin(), m_listeners.end(), pListener);
if (it == m_listeners.end())
{
m_listeners.push_back(pListener);
}
}
//------------------------------------------------------------------------
void SpawnableLevelSystem::RemoveListener(ILevelSystemListener* pListener)
{
AZStd::vector<ILevelSystemListener*>::iterator it = AZStd::find(m_listeners.begin(), m_listeners.end(), pListener);
if (it != m_listeners.end())
{
m_listeners.erase(it);
}
}
//------------------------------------------------------------------------
bool SpawnableLevelSystem::LoadLevel(const char* levelName)
{
if (gEnv->IsEditor())
{
AZ_TracePrintf("CrySystem::CLevelSystem", "LoadLevel for %s was called in the editor - not actually loading.\n", levelName);
return false;
}
// If a level is currently loaded, unload it before loading the next one.
if (IsLevelLoaded())
{
UnloadLevel();
}
gEnv->pSystem->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_LEVEL_LOAD_PREPARE, 0, 0);
PrepareNextLevel(levelName);
bool result = LoadLevelInternal(levelName);
if (result)
{
OnLoadingComplete(levelName);
}
return result;
}
//------------------------------------------------------------------------
bool SpawnableLevelSystem::LoadLevelInternal(const char* levelName)
{
gEnv->pSystem->SetSystemGlobalState(ESYSTEM_GLOBAL_STATE_LEVEL_LOAD_START);
AZ_ASSET_NAMED_SCOPE("Level: %s", levelName);
INDENT_LOG_DURING_SCOPE();
AZ::Data::AssetId rootSpawnableAssetId;
AZ::Data::AssetCatalogRequestBus::BroadcastResult(
rootSpawnableAssetId, &AZ::Data::AssetCatalogRequestBus::Events::GetAssetIdByPath, levelName, nullptr, false);
if (!rootSpawnableAssetId.IsValid())
{
OnLoadingError(levelName, "AssetCatalog has no entry for the requested level.");
return false;
}
// This scope is specifically used for marking a loading time profile section
{
LOADING_TIME_PROFILE_SECTION;
m_bLevelLoaded = false;
m_lastLevelName = levelName;
gEnv->pConsole->SetScrollMax(600);
ICVar* con_showonload = gEnv->pConsole->GetCVar("con_showonload");
if (con_showonload && con_showonload->GetIVal() != 0)
{
gEnv->pConsole->ShowConsole(true);
ICVar* g_enableloadingscreen = gEnv->pConsole->GetCVar("g_enableloadingscreen");
if (g_enableloadingscreen)
{
g_enableloadingscreen->Set(0);
}
}
// Reset the camera to (1,1,1) (not (0,0,0) which is the invalid/uninitialised state,
// to avoid the hack in the renderer to not show anything if the camera is at the origin).
CCamera defaultCam;
defaultCam.SetPosition(Vec3(1.0f));
m_pSystem->SetViewCamera(defaultCam);
OnLoadingStart(levelName);
auto pPak = gEnv->pCryPak;
m_pSystem->SetThreadState(ESubsys_Physics, false);
ICVar* pSpamDelay = gEnv->pConsole->GetCVar("log_SpamDelay");
float spamDelay = 0.0f;
if (pSpamDelay)
{
spamDelay = pSpamDelay->GetFVal();
pSpamDelay->Set(0.0f);
}
if (gEnv->p3DEngine)
{
AZ::IO::PathView levelPath(levelName);
AZStd::string parentPath(levelPath.ParentPath().Native());
static constexpr const char* defaultGameTypeName = "Mission0";
bool is3DEngineLoaded = gEnv->IsEditor() ? gEnv->p3DEngine->InitLevelForEditor(parentPath.c_str(), defaultGameTypeName)
: gEnv->p3DEngine->LoadLevel(parentPath.c_str(), defaultGameTypeName);
if (!is3DEngineLoaded)
{
OnLoadingError(levelName, "3DEngine failed to handle loading the level");
return 0;
}
}
// Parse level specific config data.
AZStd::string const sLevelNameOnly(PathUtil::GetFileName(levelName));
if (!sLevelNameOnly.empty())
{
const char* controlsPath = nullptr;
Audio::AudioSystemRequestBus::BroadcastResult(controlsPath, &Audio::AudioSystemRequestBus::Events::GetControlsPath);
if (controlsPath)
{
AZStd::string sAudioLevelPath(controlsPath);
sAudioLevelPath.append("levels/");
sAudioLevelPath += sLevelNameOnly;
Audio::SAudioManagerRequestData<Audio::eAMRT_PARSE_CONTROLS_DATA> oAMData(
sAudioLevelPath.c_str(), Audio::eADS_LEVEL_SPECIFIC);
Audio::SAudioRequest oAudioRequestData;
oAudioRequestData.nFlags =
(Audio::eARF_PRIORITY_HIGH |
Audio::eARF_EXECUTE_BLOCKING); // Needs to be blocking so data is available for next preloading request!
oAudioRequestData.pData = &oAMData;
Audio::AudioSystemRequestBus::Broadcast(&Audio::AudioSystemRequestBus::Events::PushRequestBlocking, oAudioRequestData);
Audio::SAudioManagerRequestData<Audio::eAMRT_PARSE_PRELOADS_DATA> oAMData2(
sAudioLevelPath.c_str(), Audio::eADS_LEVEL_SPECIFIC);
oAudioRequestData.pData = &oAMData2;
Audio::AudioSystemRequestBus::Broadcast(&Audio::AudioSystemRequestBus::Events::PushRequestBlocking, oAudioRequestData);
Audio::TAudioPreloadRequestID nPreloadRequestID = INVALID_AUDIO_PRELOAD_REQUEST_ID;
Audio::AudioSystemRequestBus::BroadcastResult(
nPreloadRequestID, &Audio::AudioSystemRequestBus::Events::GetAudioPreloadRequestID, sLevelNameOnly.c_str());
if (nPreloadRequestID != INVALID_AUDIO_PRELOAD_REQUEST_ID)
{
Audio::SAudioManagerRequestData<Audio::eAMRT_PRELOAD_SINGLE_REQUEST> requestData(nPreloadRequestID, true);
oAudioRequestData.pData = &requestData;
Audio::AudioSystemRequestBus::Broadcast(&Audio::AudioSystemRequestBus::Events::PushRequestBlocking, oAudioRequestData);
}
}
}
AZ::Data::Asset<AzFramework::Spawnable> rootSpawnable(
rootSpawnableAssetId, azrtti_typeid<AzFramework::Spawnable>(), levelName);
m_rootSpawnableId = rootSpawnableAssetId;
m_rootSpawnableGeneration = AzFramework::RootSpawnableInterface::Get()->AssignRootSpawnable(rootSpawnable);
//////////////////////////////////////////////////////////////////////////
// Movie system must be reset after entities.
//////////////////////////////////////////////////////////////////////////
IMovieSystem* movieSys = gEnv->pMovieSystem;
if (movieSys != NULL)
{
// bSeekAllToStart needs to be false here as it's only of interest in the editor
movieSys->Reset(true, false);
}
gEnv->pSystem->SetSystemGlobalState(ESYSTEM_GLOBAL_STATE_LEVEL_LOAD_START_PRECACHE);
//////////////////////////////////////////////////////////////////////////
// Notify 3D engine that loading finished
//////////////////////////////////////////////////////////////////////////
if (gEnv->p3DEngine)
{
gEnv->p3DEngine->PostLoadLevel();
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
gEnv->pConsole->SetScrollMax(600 / 2);
pPak->GetResourceList(AZ::IO::IArchive::RFOM_NextLevel)->Clear();
if (pSpamDelay)
{
pSpamDelay->Set(spamDelay);
}
m_bLevelLoaded = true;
gEnv->pSystem->SetSystemGlobalState(ESYSTEM_GLOBAL_STATE_LEVEL_LOAD_END);
}
GetISystem()->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_LEVEL_LOAD_END, 0, 0);
if (auto cvar = gEnv->pConsole->GetCVar("sv_map"); cvar)
{
cvar->Set(levelName);
}
gEnv->pSystem->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_LEVEL_PRECACHE_START, 0, 0);
m_pSystem->SetThreadState(ESubsys_Physics, true);
return true;
}
//------------------------------------------------------------------------
void SpawnableLevelSystem::PrepareNextLevel(const char* levelName)
{
AZ::Data::AssetId rootSpawnableAssetId;
AZ::Data::AssetCatalogRequestBus::BroadcastResult(
rootSpawnableAssetId, &AZ::Data::AssetCatalogRequestBus::Events::GetAssetIdByPath, levelName, nullptr, false);
if (!rootSpawnableAssetId.IsValid())
{
// alert the listener
OnLevelNotFound(levelName);
return;
}
// This work not required in-editor.
if (!gEnv || !gEnv->IsEditor())
{
m_levelLoadStartTime = gEnv->pTimer->GetAsyncTime();
// switched to level heap, so now imm start the loading screen (renderer will be reinitialized in the levelheap)
gEnv->pSystem->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_LEVEL_LOAD_START_LOADINGSCREEN, 0, 0);
gEnv->pSystem->SetSystemGlobalState(ESYSTEM_GLOBAL_STATE_LEVEL_LOAD_START_PREPARE);
}
OnPrepareNextLevel(levelName);
}
void SpawnableLevelSystem::OnPrepareNextLevel(const char* levelName)
{
AZ_TracePrintf("LevelSystem", "Level system is preparing to load '%s'\n", levelName);
for (auto& listener : m_listeners)
{
listener->OnPrepareNextLevel(levelName);
}
}
//------------------------------------------------------------------------
void SpawnableLevelSystem::OnLevelNotFound(const char* levelName)
{
AZ_Error("LevelSystem", false, "Requested level not found: '%s'\n", levelName);
for (auto& listener : m_listeners)
{
listener->OnLevelNotFound(levelName);
}
}
//------------------------------------------------------------------------
void SpawnableLevelSystem::OnLoadingStart(const char* levelName)
{
AZ_TracePrintf("LevelSystem", "Level system is loading '%s'\n", levelName);
if (gEnv->pCryPak->GetRecordFileOpenList() == AZ::IO::IArchive::RFOM_EngineStartup)
{
gEnv->pCryPak->RecordFileOpen(AZ::IO::IArchive::RFOM_Level);
}
m_fLastTime = gEnv->pTimer->GetAsyncCurTime();
GetISystem()->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_LEVEL_LOAD_START, 0, 0);
LOADING_TIME_PROFILE_SECTION(gEnv->pSystem);
for (auto& listener : m_listeners)
{
listener->OnLoadingStart(levelName);
}
}
//------------------------------------------------------------------------
void SpawnableLevelSystem::OnLoadingError(const char* levelName, const char* error)
{
AZ_Error("LevelSystem", false, "Error loading level '%s': %s\n", levelName, error);
if (gEnv->pRenderer)
{
gEnv->pRenderer->SetTexturePrecaching(false);
}
for (auto& listener : m_listeners)
{
listener->OnLoadingError(levelName, error);
}
}
//------------------------------------------------------------------------
void SpawnableLevelSystem::OnLoadingComplete(const char* levelName)
{
CTimeValue t = gEnv->pTimer->GetAsyncTime();
m_fLastLevelLoadTime = (t - m_levelLoadStartTime).GetSeconds();
LogLoadingTime();
m_nLoadedLevelsCount++;
// Hide console after loading.
gEnv->pConsole->ShowConsole(false);
for (auto& listener : m_listeners)
{
listener->OnLoadingComplete(levelName);
}
#if AZ_LOADSCREENCOMPONENT_ENABLED
EBUS_EVENT(LoadScreenBus, Stop);
#endif // if AZ_LOADSCREENCOMPONENT_ENABLED
AZ_TracePrintf("LevelSystem", "Level load complete: '%s'\n", levelName);
}
//------------------------------------------------------------------------
void SpawnableLevelSystem::OnLoadingProgress(const char* levelName, int progressAmount)
{
for (auto& listener : m_listeners)
{
listener->OnLoadingProgress(levelName, progressAmount);
}
}
//------------------------------------------------------------------------
void SpawnableLevelSystem::OnUnloadComplete(const char* levelName)
{
for (auto& listener : m_listeners)
{
listener->OnUnloadComplete(levelName);
}
AZ_TracePrintf("LevelSystem", "Level unload complete: '%s'\n", levelName);
}
//////////////////////////////////////////////////////////////////////////
void SpawnableLevelSystem::LogLoadingTime()
{
if (gEnv->IsEditor())
{
return;
}
if (!GetISystem()->IsDevMode())
{
return;
}
char vers[128];
GetISystem()->GetFileVersion().ToString(vers, sizeof(vers));
const char* sChain = "";
if (m_nLoadedLevelsCount > 0)
{
sChain = " (Chained)";
}
AZStd::string text;
text.format(
"Game Level Load Time: [%s] Level %s loaded in %.2f seconds%s", vers, m_lastLevelName.c_str(), m_fLastLevelLoadTime, sChain);
gEnv->pLog->Log(text.c_str());
}
//////////////////////////////////////////////////////////////////////////
void SpawnableLevelSystem::UnloadLevel()
{
if (gEnv->IsEditor())
{
return;
}
if (m_lastLevelName.empty())
{
return;
}
AZ_TracePrintf("LevelSystem", "UnloadLevel Start\n");
INDENT_LOG_DURING_SCOPE();
// Flush core buses. We're about to unload Cry modules and need to ensure we don't have module-owned functions left behind.
AZ::Data::AssetBus::ExecuteQueuedEvents();
AZ::TickBus::ExecuteQueuedEvents();
AZ::MainThreadRenderRequestBus::ExecuteQueuedEvents();
if (gEnv && gEnv->pSystem)
{
// clear all error messages to prevent stalling due to runtime file access check during chainloading
gEnv->pSystem->ClearErrorMessages();
}
if (gEnv && gEnv->pCryPak)
{
gEnv->pCryPak->DisableRuntimeFileAccess(false);
}
CTimeValue tBegin = gEnv->pTimer->GetAsyncTime();
I3DEngine* p3DEngine = gEnv->p3DEngine;
if (p3DEngine)
{
IDeferredPhysicsEventManager* pPhysEventManager = p3DEngine->GetDeferredPhysicsEventManager();
if (pPhysEventManager)
{
// clear deferred physics queues before renderer, since we could have jobs running
// which access a rendermesh
pPhysEventManager->ClearDeferredEvents();
}
}
// AM: Flush render thread (Flush is not exposed - using EndFrame())
// We are about to delete resources that could be in use
if (gEnv->pRenderer)
{
gEnv->pRenderer->EndFrame();
bool isLoadScreenPlaying = false;
#if AZ_LOADSCREENCOMPONENT_ENABLED
LoadScreenBus::BroadcastResult(isLoadScreenPlaying, &LoadScreenBus::Events::IsPlaying);
#endif // if AZ_LOADSCREENCOMPONENT_ENABLED
// force a black screen as last render command.
// if load screen is playing do not call this draw as it may lead to a crash due to UI loading code getting
// pumped while loading the shaders for this draw.
if (!isLoadScreenPlaying)
{
gEnv->pRenderer->BeginFrame();
gEnv->pRenderer->SetState(GS_BLSRC_SRCALPHA | GS_BLDST_ONEMINUSSRCALPHA | GS_NODEPTHTEST);
gEnv->pRenderer->Draw2dImage(0, 0, 800, 600, -1, 0.0f, 0.0f, 1.0f, 1.0f, 0.f, 0.0f, 0.0f, 0.0f, 1.0, 0.f);
gEnv->pRenderer->EndFrame();
}
// flush any outstanding texture requests
gEnv->pRenderer->FlushPendingTextureTasks();
}
// Clear level entities and prefab instances.
EBUS_EVENT(AzFramework::GameEntityContextRequestBus, ResetGameContext);
if (gEnv->pMovieSystem)
{
gEnv->pMovieSystem->Reset(false, false);
gEnv->pMovieSystem->RemoveAllSequences();
}
// Unload level specific audio binary data.
Audio::SAudioManagerRequestData<Audio::eAMRT_UNLOAD_AFCM_DATA_BY_SCOPE> oAMData(Audio::eADS_LEVEL_SPECIFIC);
Audio::SAudioRequest oAudioRequestData;
oAudioRequestData.nFlags = (Audio::eARF_PRIORITY_HIGH | Audio::eARF_EXECUTE_BLOCKING);
oAudioRequestData.pData = &oAMData;
Audio::AudioSystemRequestBus::Broadcast(&Audio::AudioSystemRequestBus::Events::PushRequestBlocking, oAudioRequestData);
// Now unload level specific audio config data.
Audio::SAudioManagerRequestData<Audio::eAMRT_CLEAR_CONTROLS_DATA> oAMData2(Audio::eADS_LEVEL_SPECIFIC);
oAudioRequestData.pData = &oAMData2;
Audio::AudioSystemRequestBus::Broadcast(&Audio::AudioSystemRequestBus::Events::PushRequestBlocking, oAudioRequestData);
Audio::SAudioManagerRequestData<Audio::eAMRT_CLEAR_PRELOADS_DATA> oAMData3(Audio::eADS_LEVEL_SPECIFIC);
oAudioRequestData.pData = &oAMData3;
Audio::AudioSystemRequestBus::Broadcast(&Audio::AudioSystemRequestBus::Events::PushRequestBlocking, oAudioRequestData);
// Reset the camera to (0,0,0) which is the invalid/uninitialised state
CCamera defaultCam;
m_pSystem->SetViewCamera(defaultCam);
OnUnloadComplete(m_lastLevelName.c_str());
AzFramework::RootSpawnableInterface::Get()->ReleaseRootSpawnable();
m_lastLevelName.clear();
GetISystem()->GetIResourceManager()->UnloadLevel();
/*
Force Lua garbage collection before p3DEngine->UnloadLevel() and pRenderer->FreeResources(flags) are called.
p3DEngine->UnloadLevel() will destroy particle emitters even if they're still referenced by Lua objects that are yet to be
collected. (as per comment in 3dEngineLoad.cpp (line 501) - "Force to clean all particles that are left, even if still referenced.").
Then, during the next GC cycle, Lua finally cleans up, the particle emitter smart pointers will be pointing to invalid memory).
Normally the GC step is triggered at the end of this method (by the ESYSTEM_EVENT_LEVEL_POST_UNLOAD event), which is too late
(after the render resources have been purged).
This extra GC step takes a few ms more level unload time, which is a small price for fixing nasty crashes.
If, however, we wanted to claim it back, we could potentially get rid of the GC step that is triggered by
ESYSTEM_EVENT_LEVEL_POST_UNLOAD to break even.
*/
EBUS_EVENT(AZ::ScriptSystemRequestBus, GarbageCollect);
// Delete engine resources
if (p3DEngine)
{
p3DEngine->UnloadLevel();
}
// Force to clean render resources left after deleting all objects and materials.
IRenderer* pRenderer = gEnv->pRenderer;
if (pRenderer)
{
pRenderer->FlushRTCommands(true, true, true);
CryComment("Deleting Render meshes, render resources and flush texture streaming");
// This may also release some of the materials.
int flags = FRR_DELETED_MESHES | FRR_FLUSH_TEXTURESTREAMING | FRR_OBJECTS | FRR_RENDERELEMENTS | FRR_RP_BUFFERS | FRR_POST_EFFECTS;
// Always keep the system resources around in the editor.
// If a level load fails for any reason, then do not unload the system resources, otherwise we will not have any system resources to
// continue rendering the console and debug output text.
if (!gEnv->IsEditor() && !GetLevelLoadFailed())
{
flags |= FRR_SYSTEM_RESOURCES;
}
pRenderer->FreeResources(flags);
CryComment("done");
}
// Perform level unload procedures for the LyShine UI system
if (gEnv && gEnv->pLyShine)
{
gEnv->pLyShine->OnLevelUnload();
}
m_bLevelLoaded = false;
CTimeValue tUnloadTime = gEnv->pTimer->GetAsyncTime() - tBegin;
AZ_TracePrintf("LevelSystem", "UnloadLevel End: %.1f sec\n", tUnloadTime.GetSeconds());
// Must be sent last.
// Cleanup all containers
GetISystem()->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_LEVEL_POST_UNLOAD, 0, 0);
AzFramework::InputChannelRequestBus::Broadcast(&AzFramework::InputChannelRequests::ResetState);
}
void SpawnableLevelSystem::OnRootSpawnableAssigned(
[[maybe_unused]] AZ::Data::Asset<AzFramework::Spawnable> rootSpawnable, [[maybe_unused]] uint32_t generation)
{
}
void SpawnableLevelSystem::OnRootSpawnableReleased([[maybe_unused]] uint32_t generation)
{
}
} // namespace LegacyLevelSystem
@@ -0,0 +1,93 @@
/*
* 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.
*
*/
#pragma once
#include "ILevelSystem.h"
#include <AzCore/Console/IConsole.h>
#include <AzFramework/Archive/IArchive.h>
#include <AzFramework/Spawnable/RootSpawnableInterface.h>
namespace LegacyLevelSystem
{
class SpawnableLevelSystem
: public ILevelSystem
, public AzFramework::RootSpawnableNotificationBus::Handler
{
public:
explicit SpawnableLevelSystem(ISystem* pSystem);
~SpawnableLevelSystem() override;
// ILevelSystem
void Release() override;
void AddListener(ILevelSystemListener* pListener) override;
void RemoveListener(ILevelSystemListener* pListener) override;
bool LoadLevel(const char* levelName) override;
void UnloadLevel() override;
bool IsLevelLoaded() override;
const char* GetCurrentLevelName() const override;
// If the level load failed then we need to have a different shutdown procedure vs when a level is naturally unloaded
void SetLevelLoadFailed(bool loadFailed) override;
bool GetLevelLoadFailed() override;
AZ::Data::AssetType GetLevelAssetType() const override;
// The following methods are deprecated from ILevelSystem and will be removed once slice support is removed.
// [LYN-2376] Remove once legacy slice support is removed
void Rescan([[maybe_unused]] const char* levelsFolder) override;
int GetLevelCount() override;
ILevelInfo* GetLevelInfo([[maybe_unused]] int level) override;
ILevelInfo* GetLevelInfo([[maybe_unused]] const char* levelName) override;
private:
void OnRootSpawnableAssigned(AZ::Data::Asset<AzFramework::Spawnable> rootSpawnable, uint32_t generation) override;
void OnRootSpawnableReleased(uint32_t generation) override;
void PrepareNextLevel(const char* levelName);
bool LoadLevelInternal(const char* levelName);
// Methods to notify ILevelSystemListener
void OnPrepareNextLevel(const char* levelName);
void OnLevelNotFound(const char* levelName);
void OnLoadingStart(const char* levelName);
void OnLoadingComplete(const char* levelName);
void OnLoadingError(const char* levelName, const char* error);
void OnLoadingProgress(const char* levelName, int progressAmount);
void OnUnloadComplete(const char* levelName);
void LogLoadingTime();
ISystem* m_pSystem{nullptr};
AZStd::string m_lastLevelName;
float m_fLastLevelLoadTime{0.0f};
float m_fLastTime{0.0f};
bool m_bLevelLoaded{false};
bool m_levelLoadFailed{false};
int m_nLoadedLevelsCount{0};
CTimeValue m_levelLoadStartTime;
AZStd::vector<ILevelSystemListener*> m_listeners;
// Information about the currently-loaded root spawnable, used for tracking loads and unloads.
uint64_t m_rootSpawnableGeneration{0};
AZ::Data::AssetId m_rootSpawnableId{};
};
} // namespace LegacyLevelSystem
+2 -2
View File
@@ -92,8 +92,8 @@ public:
virtual void UnregisterConsoleVariables();
virtual void AddCallback(ILogCallback* pCallback);
virtual void RemoveCallback(ILogCallback* pCallback);
virtual void LogV(const ELogType ineType, int flags, const char* szFormat, va_list args);
virtual void LogV(const ELogType ineType, const char* szFormat, va_list args);
virtual void LogV(ELogType ineType, int flags, const char* szFormat, va_list args);
virtual void LogV(ELogType ineType, const char* szFormat, va_list args);
virtual void Update();
virtual const char* GetModuleFilter();
virtual void FlushAndClose();
+23 -7
View File
@@ -19,6 +19,7 @@
#include "System.h"
#include "MaterialUtils.h"
#include <CryPath.h>
#include <AzFramework/API/ApplicationAPI.h>
#include <AzFramework/IO/FileOperations.h>
#include <AzFramework/Archive/Archive.h>
#include <AzFramework/Archive/INestedArchive.h>
@@ -216,12 +217,20 @@ void CResourceManager::PrepareLevel(const char* sLevelFolder, const char* sLevel
if (g_cvars.archiveVars.nLoadCache)
{
CryPathString levelpak = PathUtil::Make(sLevelFolder, LEVEL_PAK_FILENAME);
size_t nPakFileSize = gEnv->pCryPak->FGetSize(levelpak.c_str());
if (nPakFileSize < LEVEL_PAK_INMEMORY_MAXSIZE) // 10 megs.
bool usePrefabSystemForLevels = false;
AzFramework::ApplicationRequests::Bus::BroadcastResult(
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
// The prefab system doesn't use level.pak
if (!usePrefabSystemForLevels)
{
// Force level.pak from this level in memory.
gEnv->pCryPak->LoadPakToMemory(LEVEL_PAK_FILENAME, AZ::IO::IArchive::eInMemoryPakLocale_GPU);
CryPathString levelpak = PathUtil::Make(sLevelFolder, LEVEL_PAK_FILENAME);
size_t nPakFileSize = gEnv->pCryPak->FGetSize(levelpak.c_str());
if (nPakFileSize < LEVEL_PAK_INMEMORY_MAXSIZE) // 10 megs.
{
// Force level.pak from this level in memory.
gEnv->pCryPak->LoadPakToMemory(LEVEL_PAK_FILENAME, AZ::IO::IArchive::eInMemoryPakLocale_GPU);
}
}
gEnv->pCryPak->LoadPakToMemory(ENGINE_PAK_FILENAME, AZ::IO::IArchive::eInMemoryPakLocale_GPU);
@@ -584,8 +593,15 @@ void CResourceManager::UnloadAllLevelCachePaks(bool bLevelLoadEnd)
{
gEnv->pCryPak->LoadPakToMemory(ENGINE_PAK_FILENAME, AZ::IO::IArchive::eInMemoryPakLocale_Unload);
// Force level.pak out of memory.
gEnv->pCryPak->LoadPakToMemory(LEVEL_PAK_FILENAME, AZ::IO::IArchive::eInMemoryPakLocale_Unload);
bool usePrefabSystemForLevels = false;
AzFramework::ApplicationRequests::Bus::BroadcastResult(
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
if (!usePrefabSystemForLevels)
{
// Force level.pak out of memory.
gEnv->pCryPak->LoadPakToMemory(LEVEL_PAK_FILENAME, AZ::IO::IArchive::eInMemoryPakLocale_Unload);
}
}
if (!bLevelLoadEnd)
{
+1 -18
View File
@@ -1501,7 +1501,7 @@ bool CSystem::UpdatePreTickBus(int updateFlags, int nPauseMode)
if (maxFPS == 0 && vSync == 0)
{
ILevelSystem* pLvlSys = GetILevelSystem();
const bool inLevel = pLvlSys && pLvlSys->GetCurrentLevel() != 0;
const bool inLevel = pLvlSys && pLvlSys->IsLevelLoaded();
maxFPS = !inLevel || IsPaused() ? 60 : 0;
}
@@ -1791,23 +1791,6 @@ bool CSystem::UpdatePostTickBus(int updateFlags, int nPauseMode)
GetIViewSystem()->Update(min(gEnv->pTimer->GetFrameTime(), 0.1f));
}
if (gEnv->pLyShine)
{
// Tell the UI system the size of the viewport we are rendering to - this drives the
// canvas size for full screen UI canvases. It needs to be set before either pLyShine->Update or
// pLyShine->Render are called. It must match the viewport size that the input system is using.
AZ::Vector2 viewportSize;
viewportSize.SetX(static_cast<float>(gEnv->pRenderer->GetOverlayWidth()));
viewportSize.SetY(static_cast<float>(gEnv->pRenderer->GetOverlayHeight()));
gEnv->pLyShine->SetViewportSize(viewportSize);
bool isUiPaused = gEnv->pTimer->IsTimerPaused(ITimer::ETIMER_UI);
if (!isUiPaused)
{
gEnv->pLyShine->Update(gEnv->pTimer->GetFrameTime(ITimer::ETIMER_UI));
}
}
// Begin occlusion job after setting the correct camera.
gEnv->p3DEngine->PrepareOcclusion(GetViewCamera());
+4 -4
View File
@@ -612,7 +612,7 @@ public:
virtual void SetConfigSpec(ESystemConfigSpec spec, ESystemConfigPlatform platform, bool bClient);
virtual ESystemConfigSpec GetMaxConfigSpec() const;
virtual ESystemConfigPlatform GetConfigPlatform() const;
virtual void SetConfigPlatform(const ESystemConfigPlatform platform);
virtual void SetConfigPlatform(ESystemConfigPlatform platform);
//////////////////////////////////////////////////////////////////////////
virtual int SetThreadState(ESubsystem subsys, bool bActive);
@@ -746,7 +746,7 @@ public:
// interface ISystem -------------------------------------------
virtual IDataProbe* GetIDataProbe() { return m_pDataProbe; };
virtual void SetForceNonDevMode(const bool bValue);
virtual void SetForceNonDevMode(bool bValue);
virtual bool GetForceNonDevMode() const;
virtual bool WasInDevMode() const { return m_bWasInDevMode; };
virtual bool IsDevMode() const { return m_bInDevMode && !GetForceNonDevMode(); }
@@ -759,7 +759,7 @@ public:
}
return (true);
}
virtual void AutoDetectSpec(const bool detectResolution);
virtual void AutoDetectSpec(bool detectResolution);
virtual void AsyncMemcpy(void* dst, const void* src, size_t size, int nFlags, volatile int* sync)
{
@@ -1084,7 +1084,7 @@ public:
}
virtual ESystemGlobalState GetSystemGlobalState(void);
virtual void SetSystemGlobalState(const ESystemGlobalState systemGlobalState);
virtual void SetSystemGlobalState(ESystemGlobalState systemGlobalState);
#if !defined(_RELEASE)
virtual bool IsSavingResourceList() const { return (g_cvars.archiveVars.nSaveLevelResourceList != 0); }
+16 -605
View File
@@ -54,6 +54,7 @@
#include <AzCore/IO/Streamer/Streamer.h>
#include <AzCore/IO/Streamer/StreamerComponent.h>
#include <AzCore/Component/ComponentApplicationBus.h>
#include <AzFramework/API/ApplicationAPI.h>
#include <AzFramework/StringFunc/StringFunc.h>
#include <AzFramework/Asset/AssetProcessorMessages.h>
#include <AzFramework/Asset/AssetSystemBus.h>
@@ -131,6 +132,7 @@
#include "ServiceNetwork.h"
#include "RemoteCommand.h"
#include "LevelSystem/LevelSystem.h"
#include "LevelSystem/SpawnableLevelSystem.h"
#include "ViewSystem/ViewSystem.h"
#include <CrySystemBus.h>
#include <AzCore/Jobs/JobFunction.h>
@@ -310,8 +312,6 @@ namespace
//static int g_sysSpecChanged = false;
const char* g_szLvlResExt = "_LvlRes.txt";
struct SCVarsClientConfigSink
: public ILoadConfigurationEntrySink
{
@@ -1517,27 +1517,16 @@ bool CSystem::InitFileSystem()
m_pUserCallback->OnInitProgress("Initializing File System...");
}
bool bLvlRes = false; // true: all assets since executable start are recorded, false otherwise
// get the DirectInstance FileIOBase which should be the AZ::LocalFileIO
m_env.pFileIO = AZ::IO::FileIOBase::GetDirectInstance();
m_env.pResourceCompilerHelper = nullptr;
#if !defined(_RELEASE)
const ICmdLineArg* pArg = m_pCmdLine->FindArg(eCLAT_Pre, "LvlRes"); // -LvlRes command line option
if (pArg)
{
bLvlRes = true;
}
#endif // !defined(_RELEASE)
m_env.pCryPak = AZ::Interface<AZ::IO::IArchive>::Get();
m_env.pFileIO = AZ::IO::FileIOBase::GetInstance();
AZ_Assert(m_env.pCryPak, "CryPak has not been initialized on AZ::Interface");
AZ_Assert(m_env.pFileIO, "FileIOBase has not been initialized");
if (m_bEditor || bLvlRes)
if (m_bEditor)
{
m_env.pCryPak->RecordFileOpen(AZ::IO::IArchive::RFOM_EngineStartup);
}
@@ -2212,43 +2201,6 @@ public:
using CommandRegisteredHandler = AZ::IConsole::ConsoleCommandRegisteredEvent::Handler;
static inline CommandRegisteredHandler s_commandRegisteredHandler = CommandRegisteredHandler([](AZ::ConsoleFunctorBase* functor) { Visit(functor); });
using CommandInvokedHandler = AZ::ConsoleCommandInvokedEvent::Handler;
static inline CommandInvokedHandler s_commandInvokedHandler = CommandInvokedHandler([]
(
AZStd::string_view command,
const AZ::ConsoleCommandContainer& args,
[[maybe_unused]] AZ::ConsoleFunctorFlags flags,
AZ::ConsoleInvokedFrom invokedFrom
)
{
if (invokedFrom == AZ::ConsoleInvokedFrom::CryBinding)
{
// If a command originated from the cry console, do not echo it back to the cry console
return;
}
AZ::CVarFixedString joinedCommand = AZ::CVarFixedString(command) + " ";
AZ::StringFunc::Join(joinedCommand, args.begin(), args.end(), " ");
gEnv->pConsole->ExecuteString(joinedCommand.c_str(), true);
});
using CommandNotFoundHandler = AZ::DispatchCommandNotFoundEvent::Handler;
static inline CommandNotFoundHandler s_commandNotFoundHandler = CommandNotFoundHandler([]
(
AZStd::string_view command,
const AZ::ConsoleCommandContainer& args,
AZ::ConsoleInvokedFrom invokedFrom
)
{
if (invokedFrom == AZ::ConsoleInvokedFrom::CryBinding)
{
// If a command originated from the cry console, do not echo it back to the cry console
return;
}
AZ::CVarFixedString joinedCommand = AZ::CVarFixedString(command) + " ";
AZ::StringFunc::Join(joinedCommand, args.begin(), args.end(), " ");
gEnv->pConsole->ExecuteString(joinedCommand.c_str(), true);
});
};
// System initialization
@@ -3193,7 +3145,19 @@ AZ_POP_DISABLE_WARNING
//////////////////////////////////////////////////////////////////////////
// LEVEL SYSTEM
m_pLevelSystem = new LegacyLevelSystem::CLevelSystem(this, "levels");
bool usePrefabSystemForLevels = false;
AzFramework::ApplicationRequests::Bus::BroadcastResult(
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
if (usePrefabSystemForLevels)
{
m_pLevelSystem = new LegacyLevelSystem::SpawnableLevelSystem(this);
}
else
{
// [LYN-2376] Remove once legacy slice support is removed
m_pLevelSystem = new LegacyLevelSystem::CLevelSystem(this, ILevelSystem::GetLevelsDirectoryName());
}
InlineInitializationProcessing("CSystem::Init Level System");
@@ -3276,8 +3240,6 @@ AZ_POP_DISABLE_WARNING
// Az to Cry console binding
AZ::Interface<AZ::IConsole>::Get()->VisitRegisteredFunctors([](AZ::ConsoleFunctorBase* functor) { AzConsoleToCryConsoleBinder::Visit(functor); });
AzConsoleToCryConsoleBinder::s_commandRegisteredHandler.Connect(AZ::Interface<AZ::IConsole>::Get()->GetConsoleCommandRegisteredEvent());
AzConsoleToCryConsoleBinder::s_commandInvokedHandler.Connect(AZ::Interface<AZ::IConsole>::Get()->GetConsoleCommandInvokedEvent());
AzConsoleToCryConsoleBinder::s_commandNotFoundHandler.Connect(AZ::Interface<AZ::IConsole>::Get()->GetDispatchCommandNotFoundEvent());
// final tryflush to be sure that all framework init request have been processed
if (!startupParams.bShaderCacheGen && m_env.pRenderer)
@@ -3384,548 +3346,6 @@ static string ConcatPath(const char* szPart1, const char* szPart2)
return ret;
}
class CLvlRes_base
{
public:
// destructor
virtual ~CLvlRes_base()
{
}
void RegisterAllLevelPaks(const string& sPath)
{
string sPathPattern = ConcatPath(sPath, "*");
AZ::IO::ArchiveFileIterator handle = gEnv->pCryPak->FindFirst(sPathPattern.c_str());
if (!handle)
{
gEnv->pLog->LogError("ERROR: CLvlRes_base failed '%s'", sPathPattern.c_str());
return;
}
do
{
if ((handle.m_fileDesc.nAttrib & AZ::IO::FileDesc::Attribute::Subdirectory) == AZ::IO::FileDesc::Attribute::Subdirectory)
{
if (handle.m_filename != "." && handle.m_filename != "..")
{
RegisterAllLevelPaks(ConcatPath(sPath, handle.m_filename.data()));
}
}
else if (HasRightExtension(handle.m_filename.data())) // open only the level paks if there is a LvlRes.txt, opening all would be too slow
{
OnPakEntry(sPath, handle.m_filename.data());
}
} while (handle = gEnv->pCryPak->FindNext(handle));
gEnv->pCryPak->FindClose(handle);
}
void Process(const string& sPath)
{
string sPathPattern = ConcatPath(sPath, "*");
AZ::IO::ArchiveFileIterator handle = gEnv->pCryPak->FindFirst(sPathPattern.c_str());
if (!handle)
{
gEnv->pLog->LogError("ERROR: LvlRes_finalstep failed '%s'", sPathPattern.c_str());
return;
}
do
{
if ((handle.m_fileDesc.nAttrib & AZ::IO::FileDesc::Attribute::Subdirectory) == AZ::IO::FileDesc::Attribute::Subdirectory)
{
if (handle.m_filename != "." && handle.m_filename != "..")
{
Process(ConcatPath(sPath, handle.m_filename.data()));
}
}
else if (HasRightExtension(handle.m_filename.data()))
{
string sFilePath = ConcatPath(sPath, handle.m_filename.data());
gEnv->pLog->Log("CLvlRes_base processing '%s' ...", sFilePath.c_str());
AZ::IO::HandleType fileHandle = gEnv->pCryPak->FOpen(sFilePath.c_str(), "rb");
if (fileHandle != AZ::IO::InvalidHandle)
{
std::vector<char> vBuffer;
size_t len = gEnv->pCryPak->FGetSize(fileHandle);
vBuffer.resize(len + 1);
if (len)
{
if (gEnv->pCryPak->FReadRaw(&vBuffer[0], len, 1, fileHandle) == 1)
{
vBuffer[len] = 0; // end terminator
char* p = &vBuffer[0];
while (*p)
{
while (*p != 0 && *p <= ' ') // jump over whitespace
{
++p;
}
char* pLineStart = p;
while (*p != 0 && *p != 10 && *p != 13) // goto end of line
{
++p;
}
char* pLineEnd = p;
while (*p != 0 && (*p == 10 || *p == 13)) // goto next line with data
{
++p;
}
if (*pLineStart != ';') // if it's not a commented line
{
*pLineEnd = 0;
OnFileEntry(pLineStart); // add line
}
}
}
else
{
gEnv->pLog->LogError("Error: LvlRes_finalstep file open '%s' failed", sFilePath.c_str());
}
}
gEnv->pCryPak->FClose(fileHandle);
}
else
{
gEnv->pLog->LogError("Error: LvlRes_finalstep file open '%s' failed", sFilePath.c_str());
}
}
} while (handle = gEnv->pCryPak->FindNext(handle));
gEnv->pCryPak->FindClose(handle);
}
bool IsFileKnown(const char* szFilePath)
{
string sFilePath = szFilePath;
return m_UniqueFileList.find(sFilePath) != m_UniqueFileList.end();
}
protected: // -------------------------------------------------------------------------
static bool HasRightExtension(const char* szFileName)
{
const char* szLvlResExt = szFileName;
size_t lenName = strlen(szLvlResExt);
static size_t lenLvlExt = strlen(g_szLvlResExt);
if (lenName >= lenLvlExt)
{
szLvlResExt += lenName - lenLvlExt; // "test_LvlRes.txt" -> "_LvlRes.txt"
}
return azstricmp(szLvlResExt, g_szLvlResExt) == 0;
}
// Arguments
// sFilePath - e.g. "game/object/vehices/car01.dds"
void OnFileEntry(const char* szFilePath)
{
string sFilePath = szFilePath;
if (m_UniqueFileList.find(sFilePath) == m_UniqueFileList.end()) // to to file processing only once per file
{
m_UniqueFileList.insert(sFilePath);
ProcessFile(sFilePath);
gEnv->pLog->UpdateLoadingScreen(0);
}
}
virtual void ProcessFile(const string& sFilePath) = 0;
virtual void OnPakEntry([[maybe_unused]] const string& sPath, [[maybe_unused]] const char* szPak) {}
// -----------------------------------------------------------------
std::set<string> m_UniqueFileList; // to removed duplicate files
};
class CLvlRes_finalstep
: public CLvlRes_base
{
public:
// constructor
CLvlRes_finalstep(const char* szPath)
: m_sPath(szPath)
{
assert(szPath);
}
// destructor
virtual ~CLvlRes_finalstep()
{
// free registered paks
std::set<string>::iterator it, end = m_RegisteredPakFiles.end();
for (it = m_RegisteredPakFiles.begin(); it != end; ++it)
{
string sName = *it;
gEnv->pCryPak->ClosePack(sName.c_str());
}
}
// register a pak file so all files within do not become file entries but the pak file becomes
void RegisterPak(const string& sPath, const char* szFile)
{
string sPak = ConcatPath(sPath, szFile);
AZStd::string_view pakView{ sPak.c_str(), sPak.size() };
gEnv->pCryPak->ClosePack(pakView); // so we don't get error for paks that were already opened
if (!gEnv->pCryPak->OpenPack(pakView))
{
CryLog("RegisterPak '%s' failed - file not present?", sPak.c_str());
return;
}
enum
{
nMaxPath = 0x800
};
char szAbsPathBuf[nMaxPath];
const char* szAbsPath = gEnv->pCryPak->AdjustFileName({ sPak.c_str(), sPak.size() }, szAbsPathBuf, AZ_ARRAY_SIZE(szAbsPathBuf), 0);
// string sAbsPath = PathUtil::RemoveSlash(PathUtil::GetPath(szAbsPath));
// debug
CryLog("RegisterPak '%s'", szAbsPath);
m_RegisteredPakFiles.insert(string(szAbsPath));
OnFileEntry(sPak); // include pak as file entry
}
// finds a specific file
static AZ::IO::ArchiveFileIterator FindFile(const char* szFilePath, const char* szFile)
{
AZ::IO::ArchiveFileIterator handle = gEnv->pCryPak->FindFirst(szFilePath);
if (!handle)
{
return {};
}
do
{
if (azstricmp(handle.m_filename.data(), szFile) == 0)
{
gEnv->pCryPak->FindClose(handle);
return handle;
}
} while (handle = gEnv->pCryPak->FindNext(handle));
gEnv->pCryPak->FindClose(handle);
return {};
}
// slow but safe (to correct path and file name upper/lower case to the existing files)
// some code might rely on the case (e.g. CVarGroup creation) so it's better to correct the case
static void CorrectCaseInPlace(char* szFilePath)
{
// required for FindFirst, TODO: investigate as this seems wrong behavior
{
// jump over "Game"
while (*szFilePath != '/' && *szFilePath != '\\' && *szFilePath != 0)
{
++szFilePath;
}
// jump over "/"
if (*szFilePath != 0)
{
++szFilePath;
}
}
char* szFile = szFilePath, * p = szFilePath;
for (;; )
{
if (*p == '/' || *p == '\\' || *p == 0)
{
char cOldChar = *p;
*p = 0; // create zero termination
auto fileIterator = FindFile(szFilePath, szFile);
if (fileIterator)
{
assert(strlen(szFile) == fileIterator.m_filename.size());
}
*p = cOldChar; // get back the old separator
if (!fileIterator)
{
return;
}
fileIterator.m_filename.copy(szFile, fileIterator.m_filename.size());
if (*p == 0)
{
break;
}
++p;
szFile = p;
}
else
{
++p;
}
}
}
virtual void ProcessFile(const string& _sFilePath)
{
string sFilePath = _sFilePath;
CorrectCaseInPlace((char*)&sFilePath[0]);
gEnv->pLog->LogWithType(ILog::eAlways, "LvlRes: %s", sFilePath.c_str());
CCryFile file;
std::vector<char> data;
if (!file.Open(sFilePath.c_str(), "rb"))
{
gEnv->pLog->LogError("ERROR: failed to open '%s'", sFilePath.c_str()); // pak not opened ?
return;
}
if (IsInRegisteredPak(file.GetHandle()))
{
return; // then don't process as we include the pak
}
// Save this file in target folder.
string trgFilename = PathUtil::Make(m_sPath, sFilePath);
int fsize = file.GetLength();
size_t len = file.GetLength();
if (fsize > (int)data.size())
{
data.resize(fsize + 16);
}
// Read data.
file.ReadRaw(&data[0], fsize);
// Save this data to target file.
string trgFileDir = PathUtil::ToDosPath(PathUtil::RemoveSlash(PathUtil::GetPath(trgFilename)));
gEnv->pFileIO->CreatePath(trgFileDir); // ensure path exists
// Create target file
FILE* trgFile = nullptr;
azfopen(&trgFile, trgFilename, "wb");
if (trgFile)
{
fwrite(&data[0], fsize, 1, trgFile);
fclose(trgFile);
}
else
{
gEnv->pLog->LogError("ERROR: failed to write '%s' (write protected/disk full/rights)", trgFilename.c_str());
assert(0);
}
}
bool IsInRegisteredPak(AZ::IO::HandleType fileHandle)
{
const char* szPak = gEnv->pCryPak->GetFileArchivePath(fileHandle);
if (!szPak)
{
return false; // outside pak
}
bool bInsideRegisteredPak = m_RegisteredPakFiles.find(szPak) != m_RegisteredPakFiles.end();
return bInsideRegisteredPak;
}
virtual void OnPakEntry(const string& sPath, [[maybe_unused]] const char* szPak)
{
RegisterPak(sPath, "level.pak");
RegisterPak(sPath, "levelmm.pak");
}
// -------------------------------------------------------------------------------
string m_sPath; // directory path to store the assets e.g. "c:\temp\Out"
std::set<string> m_RegisteredPakFiles; // abs path to pak files we registered e.g. "c:\MasterCD\game\GameData.pak", to avoid processing files inside these pak files - the ones we anyway want to include
};
class CLvlRes_findunused
: public CLvlRes_base
{
public:
virtual void ProcessFile([[maybe_unused]] const string& sFilePath)
{
}
};
static void LvlRes_finalstep(IConsoleCmdArgs* pParams)
{
assert(pParams);
uint32 dwCnt = pParams->GetArgCount();
if (dwCnt != 2)
{
gEnv->pLog->LogWithType(ILog::eError, "ERROR: sys_LvlRes_finalstep requires destination path as parameter");
return;
}
const char* szPath = pParams->GetArg(1);
assert(szPath);
gEnv->pLog->LogWithType(ILog::eInputResponse, "sys_LvlRes_finalstep %s ...", szPath);
// open console
gEnv->pConsole->ShowConsole(true);
CLvlRes_finalstep sink(szPath);
sink.RegisterPak("@assets@", "GameData.pak");
sink.RegisterPak("@assets@", "Shaders.pak");
sink.RegisterAllLevelPaks("levels");
sink.Process("levels");
}
static void _LvlRes_findunused_recursive(CLvlRes_findunused& sink, const string& sPath,
uint32& dwUnused, uint32& dwAll)
{
string sPathPattern = ConcatPath(sPath, "*");
// ignore some directories
if (azstricmp(sPath.c_str(), "Shaders") == 0
|| azstricmp(sPath.c_str(), "ScreenShots") == 0
|| azstricmp(sPath.c_str(), "Scripts") == 0
|| azstricmp(sPath.c_str(), "Config") == 0
|| azstricmp(sPath.c_str(), "LowSpec") == 0)
{
return;
}
// gEnv->pLog->Log("_LvlRes_findunused_recursive '%s'",sPath.c_str());
AZ::IO::ArchiveFileIterator handle = gEnv->pCryPak->FindFirst(sPathPattern.c_str());
if (!handle)
{
gEnv->pLog->LogError("ERROR: _LvlRes_findunused_recursive failed '%s'", sPathPattern.c_str());
return;
}
do
{
if ((handle.m_fileDesc.nAttrib & AZ::IO::FileDesc::Attribute::Subdirectory) == AZ::IO::FileDesc::Attribute::Subdirectory)
{
if (handle.m_filename != "." && handle.m_filename != "..")
{
_LvlRes_findunused_recursive(sink, ConcatPath(sPath, handle.m_filename.data()), dwUnused, dwAll);
}
}
else
{
string sFilePath = CryStringUtils::ToLower(ConcatPath(sPath, handle.m_filename.data()));
enum
{
nMaxPath = 0x800
};
char szAbsPathBuf[nMaxPath];
gEnv->pCryPak->AdjustFileName(sFilePath.c_str(), szAbsPathBuf, AZ_ARRAY_SIZE(szAbsPathBuf), 0);
if (!sink.IsFileKnown(szAbsPathBuf))
{
gEnv->pLog->LogWithType(IMiniLog::eAlways, "%d, %s", (uint32)handle.m_fileDesc.nSize, szAbsPathBuf);
++dwUnused;
}
++dwAll;
}
} while (handle = gEnv->pCryPak->FindNext(handle));
gEnv->pCryPak->FindClose(handle);
}
static void LvlRes_findunused([[maybe_unused]] IConsoleCmdArgs* pParams)
{
assert(pParams);
gEnv->pLog->LogWithType(ILog::eInputResponse, "sys_LvlRes_findunused ...");
// open console
gEnv->pConsole->ShowConsole(true);
CLvlRes_findunused sink;
sink.RegisterAllLevelPaks("levels");
sink.Process("levels");
gEnv->pLog->LogWithType(ILog::eInputResponse, " ");
gEnv->pLog->LogWithType(ILog::eInputResponse, "Assets not used by the existing LvlRes data:");
gEnv->pLog->LogWithType(ILog::eInputResponse, " ");
char rootpath[_MAX_PATH];
AZ::Utils::GetExecutableDirectory(rootpath, _MAX_PATH);
gEnv->pLog->LogWithType(ILog::eInputResponse, "Folder: %s", rootpath);
uint32 dwUnused = 0, dwAll = 0;
string unused;
_LvlRes_findunused_recursive(sink, unused, dwUnused, dwAll);
gEnv->pLog->LogWithType(ILog::eInputResponse, " ");
gEnv->pLog->LogWithType(ILog::eInputResponse, "Unused assets: %d/%d", dwUnused, dwAll);
gEnv->pLog->LogWithType(ILog::eInputResponse, " ");
}
static void ScreenshotCmd(IConsoleCmdArgs* pParams)
{
assert(pParams);
@@ -4628,15 +4048,9 @@ void CSystem::CreateSystemVars()
REGISTER_INT("capture_frames", 0, 0, "Enables capturing of frames. 0=off, 1=on");
REGISTER_STRING("capture_folder", "CaptureOutput", 0, "Specifies sub folder to write captured frames.");
REGISTER_STRING("capture_file_format", "jpg", 0, "Specifies file format of captured files (jpg, tga, tif).");
REGISTER_INT("capture_frame_once", 0, 0, "Makes capture single frame only");
REGISTER_STRING("capture_file_name", "", 0, "If set, specifies the path and name to use for the captured frame");
REGISTER_STRING("capture_file_prefix", "", 0, "If set, specifies the prefix to use for the captured frame instead of the default 'Frame'.");
REGISTER_INT("capture_buffer", 0, 0,
"Buffer to capture when capture_frames is enabled.\n"
"0=Color\n"
"1=Color with Alpha (requires capture_file_format=tga)");
m_gpu_particle_physics = REGISTER_INT("gpu_particle_physics", 0, VF_REQUIRE_APP_RESTART, "Enable GPU physics if available (0=off / 1=enabled).");
assert(m_gpu_particle_physics);
@@ -4645,7 +4059,6 @@ void CSystem::CreateSystemVars()
"Load .cfg file from disk (from the {Game}/Config directory)\n"
"e.g. LoadConfig lowspec.cfg\n"
"Usage: LoadConfig <filename>");
assert(m_env.pConsole);
m_env.pConsole->CreateKeyBind("alt_keyboard_key_function_F12", "Screenshot");
m_env.pConsole->CreateKeyBind("alt_keyboard_key_function_F11", "RecordClip");
@@ -4656,8 +4069,6 @@ void CSystem::CreateSystemVars()
"e.g. Screenshot beach scene with shark\n"
"Usage: Screenshot <annotation text>");
REGISTER_COMMAND("sys_LvlRes_finalstep", &LvlRes_finalstep, 0, "to combine all recorded level resources and create final stripped build (pass directory name as parameter)");
REGISTER_COMMAND("sys_LvlRes_findunused", &LvlRes_findunused, 0, "find unused level resources");
/*
// experimental feature? - needs to be created very early
m_sys_filecache = REGISTER_INT("sys_FileCache",0,0,
-15
View File
@@ -353,15 +353,6 @@ void CSystem::RenderEnd([[maybe_unused]] bool bRenderStats, bool bMainWindow)
if (!gEnv->pSystem->GetILevelSystem() || !gEnv->pSystem->GetILevelSystem()->IsLevelLoaded())
{
IConsole* console = GetIConsole();
ILyShine* lyShine = gEnv->pLyShine;
//Normally the UI is drawn as part of the scene so it can properly render once per eye in VR
//We only want to draw here if there is no level loaded. This way the user can see loading
// UI and other information before the level is loaded.
if (lyShine != nullptr)
{
lyShine->Render();
}
//Same goes for the console. When no level is loaded, it's okay to render it outside of the renderer
//so that users can load maps or change settings.
@@ -390,12 +381,6 @@ void CSystem::RenderEnd([[maybe_unused]] bool bRenderStats, bool bMainWindow)
void CSystem::OnScene3DEnd()
{
// Render UI Canvas
if (m_bDrawUI && gEnv->pLyShine)
{
gEnv->pLyShine->Render();
}
//Render Console
if (m_bDrawConsole && gEnv->pConsole)
{
@@ -20,7 +20,11 @@ namespace UnitTest
: public ::testing::Test
{};
#if AZ_TRAIT_DISABLE_FAILED_MATH_TESTS
TEST_F(CryMathTestFixture, DISABLED_InverserSqrt_HasAtLeast22BitsOfAccuracy)
#else
TEST_F(CryMathTestFixture, InverserSqrt_HasAtLeast22BitsOfAccuracy)
#endif
{
float testFloat(0.336950600);
const float result = isqrt_safe_tpl(testFloat * testFloat);
@@ -28,7 +32,11 @@ namespace UnitTest
EXPECT_NEAR(2.96779, result, epsilon);
}
#if AZ_TRAIT_DISABLE_FAILED_MATH_TESTS
TEST_F(CryMathTestFixture, DISABLED_SimdSqrt_HasAtLeast23BitsOfAccuracy)
#else
TEST_F(CryMathTestFixture, SimdSqrt_HasAtLeast23BitsOfAccuracy)
#endif
{
float testFloat(3434.34839439);
const float result = sqrt_tpl(testFloat);
@@ -55,55 +55,6 @@ namespace CryPakUnitTests
}
};
TEST_F(Integ_CryPakUnitTests, TestCryPakArchiveContainingLevels)
{
AZ::IO::FileIOBase* fileIo = AZ::IO::FileIOBase::GetInstance();
ASSERT_NE(nullptr, fileIo);
constexpr const char* testPakPath = "@usercache@/archivecontainerlevel.pak";
char resolvedArchivePath[AZ_MAX_PATH_LEN] = { 0 };
EXPECT_TRUE(fileIo->ResolvePath(testPakPath, resolvedArchivePath, AZ_MAX_PATH_LEN));
AZ::IO::IArchive* pak = gEnv->pCryPak;
ASSERT_NE(nullptr, pak);
// delete test files in case they already exist
pak->ClosePack(testPakPath);
fileIo->Remove(testPakPath);
ILevelSystem* levelSystem = gEnv->pSystem->GetILevelSystem();
EXPECT_NE(nullptr, levelSystem);
// ------------ Create an archive with a dummy level in it ------------
AZStd::intrusive_ptr<AZ::IO::INestedArchive> pArchive = pak->OpenArchive(testPakPath, nullptr, AZ::IO::INestedArchive::FLAGS_CREATE_NEW);
EXPECT_NE(nullptr, pArchive);
const char levelInfoFile[] = "levelInfo.xml";
AZStd::string relativeLevelPakPath = AZStd::string::format("levels/dummy/%s", ILevelSystem::LevelPakName);
AZStd::string relativeLevelInfoPath = AZStd::string::format("levels/dummy/%s", levelInfoFile);
EXPECT_EQ(0, pArchive->UpdateFile(relativeLevelPakPath.c_str(), const_cast<char*>("test"), 4, AZ::IO::INestedArchive::METHOD_COMPRESS, AZ::IO::INestedArchive::LEVEL_BEST));
EXPECT_EQ(0, pArchive->UpdateFile(relativeLevelInfoPath.c_str(), const_cast<char*>("test"), 4, AZ::IO::INestedArchive::METHOD_COMPRESS, AZ::IO::INestedArchive::LEVEL_BEST));
pArchive.reset();
EXPECT_TRUE(IsPackValid(testPakPath));
AZStd::fixed_string<AZ::IO::IArchive::MaxPath> fullLevelPakPath;
bool addLevel = true;
EXPECT_TRUE(pak->OpenPack("@assets@", resolvedArchivePath, AZ::IO::IArchive::FLAGS_LEVEL_PAK_INSIDE_PAK, nullptr, &fullLevelPakPath, addLevel));
ILevelInfo* levelInfo = nullptr;
// Since the archive was open, we should be able to find the level "dummy"
levelInfo = levelSystem->GetLevelInfo("dummy");
EXPECT_NE(nullptr, levelInfo);
EXPECT_TRUE(pak->ClosePack(resolvedArchivePath));
// After closing the archive we should not be able to find the level "dummy"
levelInfo = levelSystem->GetLevelInfo("dummy");
EXPECT_EQ(nullptr, levelInfo);
}
TEST_F(Integ_CryPakUnitTests, TestCryPakModTime)
{
AZ::IO::FileIOBase* fileIo = AZ::IO::FileIOBase::GetInstance();
@@ -595,7 +595,7 @@ void CViewSystem::UpdateSoundListeners()
}
//////////////////////////////////////////////////////////////////
void CViewSystem::OnLoadingStart([[maybe_unused]] ILevelInfo* pLevel)
void CViewSystem::OnLoadingStart([[maybe_unused]] const char* levelName)
{
//If the level is being restarted (IsSerializingFile() == 1)
//views should not be cleared, because the main view (player one) won't be recreated in this case
@@ -609,7 +609,7 @@ void CViewSystem::OnLoadingStart([[maybe_unused]] ILevelInfo* pLevel)
}
/////////////////////////////////////////////////////////////////////
void CViewSystem::OnUnloadComplete([[maybe_unused]] ILevel* pLevel)
void CViewSystem::OnUnloadComplete([[maybe_unused]] const char* levelName)
{
bool shouldClearViews = gEnv->pSystem ? (gEnv->pSystem->IsSerializingFile() != 1) : false;
@@ -85,11 +85,11 @@ public:
// ILevelSystemListener
virtual void OnLevelNotFound([[maybe_unused]] const char* levelName) {};
virtual void OnLoadingStart(ILevelInfo* pLevel);
virtual void OnLoadingComplete([[maybe_unused]] ILevel* pLevel) {};
virtual void OnLoadingError([[maybe_unused]] ILevelInfo* pLevel, [[maybe_unused]] const char* error) {};
virtual void OnLoadingProgress([[maybe_unused]] ILevelInfo* pLevel, [[maybe_unused]] int progressAmount) {};
virtual void OnUnloadComplete(ILevel* pLevel);
virtual void OnLoadingStart([[maybe_unused]] const char* levelName);
virtual void OnLoadingComplete([[maybe_unused]] const char* levelName){};
virtual void OnLoadingError([[maybe_unused]] const char* levelName, [[maybe_unused]] const char* error){};
virtual void OnLoadingProgress([[maybe_unused]] const char* levelName, [[maybe_unused]] int progressAmount){};
virtual void OnUnloadComplete([[maybe_unused]] const char* levelName);
//~ILevelSystemListener
CViewSystem(ISystem* pSystem);
+4 -4
View File
@@ -170,7 +170,7 @@ public:
virtual void SetScrollMax(int value);
virtual void AddOutputPrintSink(IOutputPrintSink* inpSink);
virtual void RemoveOutputPrintSink(IOutputPrintSink* inpSink);
virtual void ShowConsole(bool show, const int iRequestScrollMax = -1);
virtual void ShowConsole(bool show, int iRequestScrollMax = -1);
virtual void DumpCVars(ICVarDumpSink* pCallback, unsigned int nFlagsFilter = 0);
virtual void DumpKeyBinds(IKeyBindDumpSink* pCallback);
virtual void CreateKeyBind(const char* sCmd, const char* sRes);
@@ -178,7 +178,7 @@ public:
virtual void SetImage(ITexture* pImage, bool bDeleteCurrent);
virtual inline ITexture* GetImage() { return m_pImage; }
virtual void StaticBackground(bool bStatic) { m_bStaticBackground = bStatic; }
virtual bool GetLineNo(const int indwLineNo, char* outszBuffer, const int indwBufferSize) const;
virtual bool GetLineNo(int indwLineNo, char* outszBuffer, int indwBufferSize) const;
virtual int GetLineCount() const;
virtual ICVar* GetCVar(const char* name);
virtual char* GetVariable(const char* szVarName, const char* szFileName, const char* def_val);
@@ -192,7 +192,7 @@ public:
virtual bool AddCommand(const char* sCommand, ConsoleCommandFunc func, int nFlags = 0, const char* sHelp = NULL);
virtual bool AddCommand(const char* sName, const char* sScriptFunc, int nFlags = 0, const char* sHelp = NULL);
virtual void RemoveCommand(const char* sName);
virtual void ExecuteString(const char* command, const bool bSilentMode, const bool bDeferExecution = false);
virtual void ExecuteString(const char* command, bool bSilentMode, bool bDeferExecution = false);
virtual void ExecuteConsoleCommand(const char* command) override;
virtual void ResetCVarsToDefaults() override;
virtual void Exit(const char* command, ...) PRINTF_PARAMS(2, 3);
@@ -218,7 +218,7 @@ public:
virtual void SetLoadingImage(const char* szFilename);
virtual void AddConsoleVarSink(IConsoleVarSink* pSink);
virtual void RemoveConsoleVarSink(IConsoleVarSink* pSink);
virtual const char* GetHistoryElement(const bool bUpOrDown);
virtual const char* GetHistoryElement(bool bUpOrDown);
virtual void AddCommandToHistory(const char* szCommand);
virtual void SetInputLine(const char* szLine);
virtual void LoadConfigVar(const char* sVariable, const char* sValue);
+16 -16
View File
@@ -221,7 +221,7 @@ public:
}
}
virtual void Set(const float f)
virtual void Set(float f)
{
stack_string s;
s.Format("%g", f);
@@ -235,7 +235,7 @@ public:
Set(s.c_str());
}
virtual void Set(const int i)
virtual void Set(int i)
{
stack_string s;
s.Format("%d", i);
@@ -289,11 +289,11 @@ public:
Set(nValue);
}
virtual void Set(const float f)
virtual void Set(float f)
{
Set((int)f);
}
virtual void Set(const int i)
virtual void Set(int i)
{
if (i == m_iValue && (m_nFlags & VF_ALWAYSONCHANGE) == 0)
{
@@ -353,15 +353,15 @@ public:
Set(nValue);
}
virtual void Set(const float f)
virtual void Set(float f)
{
Set((int)f);
}
virtual void Set(const int i)
virtual void Set(int i)
{
Set((int64)i);
}
virtual void Set(const int64 i)
virtual void Set(int64 i)
{
if (i == m_iValue && (m_nFlags & VF_ALWAYSONCHANGE) == 0)
{
@@ -439,7 +439,7 @@ public:
m_pConsole->OnAfterVarChange(this);
}
}
virtual void Set(const float f)
virtual void Set(float f)
{
if (f == m_fValue && (m_nFlags & VF_ALWAYSONCHANGE) == 0)
{
@@ -459,7 +459,7 @@ public:
m_pConsole->OnAfterVarChange(this);
}
}
virtual void Set(const int i)
virtual void Set(int i)
{
if ((float)i == m_fValue && (m_nFlags & VF_ALWAYSONCHANGE) == 0)
{
@@ -542,7 +542,7 @@ public:
m_pConsole->OnAfterVarChange(this);
}
}
virtual void Set(const float f)
virtual void Set(float f)
{
if ((int)f == m_iValue && (m_nFlags & VF_ALWAYSONCHANGE) == 0)
{
@@ -560,7 +560,7 @@ public:
m_pConsole->OnAfterVarChange(this);
}
}
virtual void Set(const int i)
virtual void Set(int i)
{
if (i == m_iValue && (m_nFlags & VF_ALWAYSONCHANGE) == 0)
{
@@ -639,7 +639,7 @@ public:
m_pConsole->OnAfterVarChange(this);
}
}
virtual void Set(const float f)
virtual void Set(float f)
{
if (f == m_fValue && (m_nFlags & VF_ALWAYSONCHANGE) == 0)
{
@@ -657,7 +657,7 @@ public:
m_pConsole->OnAfterVarChange(this);
}
}
virtual void Set(const int i)
virtual void Set(int i)
{
if ((float)i == m_fValue && (m_nFlags & VF_ALWAYSONCHANGE) == 0)
{
@@ -742,13 +742,13 @@ public:
m_pConsole->OnAfterVarChange(this);
}
}
virtual void Set(const float f)
virtual void Set(float f)
{
stack_string s;
s.Format("%g", f);
Set(s.c_str());
}
virtual void Set(const int i)
virtual void Set(int i)
{
stack_string s;
s.Format("%d", i);
@@ -792,7 +792,7 @@ public:
virtual void DebugLog(const int iExpectedValue, const ICVar::EConsoleLogMode mode) const;
virtual void Set(const int i);
virtual void Set(int i);
// ConsoleVarFunc ------------------------------------------------------------------------------------
@@ -178,6 +178,8 @@ set(FILES
LZ4Decompressor.cpp
LevelSystem/LevelSystem.cpp
LevelSystem/LevelSystem.h
LevelSystem/SpawnableLevelSystem.cpp
LevelSystem/SpawnableLevelSystem.h
ViewSystem/DebugCamera.cpp
ViewSystem/DebugCamera.h
ViewSystem/View.cpp
+15 -15
View File
@@ -781,8 +781,8 @@ public:
#include AZ_RESTRICTED_FILE(Renderer_h)
#endif
virtual void DrawStringU(IFFont_RenderProxy* pFont, float x, float y, float z, const char* pStr, const bool asciiMultiLine, const STextDrawContext& ctx) const;
virtual void RT_DrawStringU(IFFont_RenderProxy* pFont, float x, float y, float z, const char* pStr, const bool asciiMultiLine, const STextDrawContext& ctx) const = 0;
virtual void DrawStringU(IFFont_RenderProxy* pFont, float x, float y, float z, const char* pStr, bool asciiMultiLine, const STextDrawContext& ctx) const;
virtual void RT_DrawStringU(IFFont_RenderProxy* pFont, float x, float y, float z, const char* pStr, bool asciiMultiLine, const STextDrawContext& ctx) const = 0;
virtual void RT_DrawLines(Vec3 v[], int nump, ColorF& col, int flags, float fGround) = 0;
@@ -847,7 +847,7 @@ public:
virtual void RequestFlushAllPendingTextureStreamingJobs(int nFrames) { m_nFlushAllPendingTextureStreamingJobs = nFrames; }
virtual void SetTexturesStreamingGlobalMipFactor(float fFactor) { m_fTexturesStreamingGlobalMipFactor = fFactor; }
virtual void SetRendererCVar(ICVar* pCVar, const char* pArgText, const bool bSilentMode = false) = 0;
virtual void SetRendererCVar(ICVar* pCVar, const char* pArgText, bool bSilentMode = false) = 0;
virtual void EF_ClearTargetsImmediately(uint32 nFlags) = 0;
virtual void EF_ClearTargetsImmediately(uint32 nFlags, const ColorF& Colors, float fDepth, uint8 nStencil) = 0;
@@ -935,7 +935,7 @@ public:
#endif
}
virtual int GetCurrentNumberOfDrawCalls([[maybe_unused]] const uint32 EFSListMask) const
virtual int GetCurrentNumberOfDrawCalls([[maybe_unused]] uint32 EFSListMask) const
{
int nDIPs = 0;
#if defined(ENABLE_PROFILING_CODE)
@@ -951,7 +951,7 @@ public:
return nDIPs;
}
virtual float GetCurrentDrawCallRTTimes(const uint32 EFSListMask) const
virtual float GetCurrentDrawCallRTTimes(uint32 EFSListMask) const
{
float fDIPTimes = 0.0f;
int nThr = m_pRT->GetThreadList();
@@ -1052,8 +1052,8 @@ public:
virtual unsigned int DownLoadToVideoMemoryCube(const byte* data, int w, int h, ETEX_Format eTFSrc, ETEX_Format eTFDst, int nummipmap, bool repeat = true, int filter = FILTER_BILINEAR, int Id = 0, const char* szCacheName = NULL, int flags = 0, EEndian eEndian = eLittleEndian, RectI* pRegion = NULL, bool bAsynDevTexCreation = false) = 0;
virtual bool DXTCompress(const byte* raw_data, int nWidth, int nHeight, ETEX_Format eTF, bool bUseHW, bool bGenMips, int nSrcBytesPerPix, MIPDXTcallback callback);
virtual bool DXTDecompress(const byte* srcData, const size_t srcFileSize, byte* dstData, int nWidth, int nHeight, int nMips, ETEX_Format eSrcTF, bool bUseHW, int nDstBytesPerPix);
virtual bool SetGammaDelta(const float fGamma) = 0;
virtual bool DXTDecompress(const byte* srcData, size_t srcFileSize, byte* dstData, int nWidth, int nHeight, int nMips, ETEX_Format eSrcTF, bool bUseHW, int nDstBytesPerPix);
virtual bool SetGammaDelta(float fGamma) = 0;
virtual void RemoveTexture(unsigned int TextureId) = 0;
@@ -1598,8 +1598,8 @@ public:
virtual bool EF_RenderEnvironmentCubeHDR (int size, Vec3& Pos, TArray<unsigned short>& vecData);
virtual ITexture* EF_GetTextureByID(int Id);
virtual ITexture* EF_GetTextureByName(const char* name, uint32 flags = 0);
virtual ITexture* EF_LoadTexture(const char* nameTex, const uint32 flags = 0);
virtual ITexture* EF_LoadCubemapTexture(const char* nameTex, const uint32 flags = 0);
virtual ITexture* EF_LoadTexture(const char* nameTex, uint32 flags = 0);
virtual ITexture* EF_LoadCubemapTexture(const char* nameTex, uint32 flags = 0);
virtual ITexture* EF_LoadDefaultTexture(const char* nameTex);
virtual const SShaderProfile& GetShaderProfile(EShaderType eST) const;
@@ -1627,19 +1627,19 @@ public:
void EF_AddEf_NotVirtual (IRenderElement* pRE, SShaderItem& pSH, CRenderObject* pObj, const SRenderingPassInfo& passInfo, int nList, int nAW, const SRendItemSorter& rendItemSorter);
// Draw all shaded REs in the list
virtual void EF_EndEf3D (const int nFlags, const int nPrecacheUpdateId, const int nNearPrecacheUpdateId, const SRenderingPassInfo& passInfo) = 0;
virtual void EF_EndEf3D (int nFlags, int nPrecacheUpdateId, int nNearPrecacheUpdateId, const SRenderingPassInfo& passInfo) = 0;
virtual void EF_InvokeShadowMapRenderJobs(const int nFlags) = 0;
virtual void EF_InvokeShadowMapRenderJobs(int nFlags) = 0;
// 2d interface for shaders
virtual void EF_EndEf2D(const bool bSort) = 0;
virtual void EF_EndEf2D(bool bSort) = 0;
// Dynamic lights
virtual bool EF_IsFakeDLight (const CDLight* Source);
virtual void EF_ADDDlight(CDLight* Source, const SRenderingPassInfo& passInfo);
virtual bool EF_AddDeferredDecal(const SDeferredDecal& rDecal);
virtual uint32 EF_GetDeferredLightsNum(const eDeferredLightType eLightType = eDLT_DeferredLight);
virtual uint32 EF_GetDeferredLightsNum(eDeferredLightType eLightType = eDLT_DeferredLight);
virtual int EF_AddDeferredLight(const CDLight& pLight, float fMult, const SRenderingPassInfo& passInfo, const SRendItemSorter& rendItemSorter);
virtual TArray<SRenderLight>* EF_GetDeferredLights(const SRenderingPassInfo& passInfo, const eDeferredLightType eLightType = eDLT_DeferredLight);
virtual TArray<SRenderLight>* EF_GetDeferredLights(const SRenderingPassInfo& passInfo, eDeferredLightType eLightType = eDLT_DeferredLight);
SRenderLight* EF_GetDeferredLightByID(const uint16 nLightID, const eDeferredLightType eLightType = eDLT_DeferredLight);
virtual void EF_ClearDeferredLightsList();
virtual void EF_ReleaseDeferredData();
@@ -1649,7 +1649,7 @@ public:
void EF_CheckLightMaterial(CDLight* pLight, uint16 nRenderLightID, const SRenderingPassInfo& passInfo, const SRendItemSorter& rendItemSorter);
// Water sim hits
virtual void EF_AddWaterSimHit(const Vec3& vPos, const float scale, const float strength);
virtual void EF_AddWaterSimHit(const Vec3& vPos, float scale, float strength);
virtual void EF_DrawWaterSimHits();
virtual void EF_QueryImpl(ERenderQueryTypes eQuery, void* pInOut0, uint32 nInOutSize0, void* pInOut1, uint32 nInOutSize1);
@@ -1792,7 +1792,7 @@ public:
void SetWasUnload(bool bSet) { m_bWasUnloaded = bSet; }
const bool IsPartiallyLoaded() const { return m_nMinMipVidUploaded != 0; }
const bool IsUnloaded(void) const { return m_bWasUnloaded; }
void SetKeepSystemCopy(const bool bKeepSystemCopy)
void SetKeepSystemCopy(bool bKeepSystemCopy)
{
if (bKeepSystemCopy)
{
@@ -259,7 +259,7 @@ namespace NCryMetal
}
else if(CTexture::IsDeviceFormatTypeless(pFormat->m_eDXGIFormat))
{
//Apple recommendation -> For sRGB variant views, you dont need the PFV flag when: - running on
//Apple recommendation -> For sRGB variant views, you don't need the PFV flag when: - running on
//iOS/tvOS 12.0 or newer - running on macOS 10.15 or newer
//However, on older OSs (and in macOS case, older GPUs) you are still required to set the flag.
#if defined(AZ_COMPILER_CLANG) && AZ_COMPILER_CLANG >= 9 //@available was added in Xcode 9
@@ -443,7 +443,6 @@ void CD3D9Renderer::InitRenderer()
CV_capture_frames = 0;
CV_capture_folder = 0;
CV_capture_file_format = 0;
CV_capture_buffer = 0;
m_NewViewport.fMinZ = 0;
@@ -1830,8 +1829,10 @@ bool CD3D9Renderer::PrepFrameCapture(FrameBufferDescription& frameBufDesc, CText
HRESULT hrZ = GetDevice().CreateTexture2D(&tmpZdesc, NULL, &frameBufDesc.tempZtex);
D3D11_MAPPED_SUBRESOURCE zMappedResource;
frameBufDesc.includeAlpha = ((CV_capture_buffer->GetIVal() == ICaptureKey::ColorWithAlpha) && frameBufDesc.tempZtex && (tmpZdesc.Width == frameBufDesc.backBufferDesc.Width) && (tmpZdesc.Height == frameBufDesc.backBufferDesc.Height));
// default to includeAlpha 'on'
frameBufDesc.includeAlpha = frameBufDesc.tempZtex && tmpZdesc.Width == frameBufDesc.backBufferDesc.Width &&
tmpZdesc.Height == frameBufDesc.backBufferDesc.Height;
if (frameBufDesc.includeAlpha)
{
@@ -2095,7 +2096,7 @@ bool CD3D9Renderer::InternalSaveToTIFF(ID3D11Texture2D* backBuffer, const char*
void CD3D9Renderer::CacheCaptureCVars()
{
// cache console vars
if (!CV_capture_frames || !CV_capture_folder || !CV_capture_file_format || !CV_capture_frame_once ||
if (!CV_capture_frames || !CV_capture_folder || !CV_capture_frame_once ||
!CV_capture_file_name || !CV_capture_file_prefix || !CV_capture_buffer)
{
ISystem* pSystem(GetISystem());
@@ -2112,7 +2113,6 @@ void CD3D9Renderer::CacheCaptureCVars()
CV_capture_frames = !CV_capture_frames ? pConsole->GetCVar("capture_frames") : CV_capture_frames;
CV_capture_folder = !CV_capture_folder ? pConsole->GetCVar("capture_folder") : CV_capture_folder;
CV_capture_file_format = !CV_capture_file_format ? pConsole->GetCVar("capture_file_format") : CV_capture_file_format;
CV_capture_frame_once = !CV_capture_frame_once ? pConsole->GetCVar("capture_frame_once") : CV_capture_frame_once;
CV_capture_file_name = !CV_capture_file_name ? pConsole->GetCVar("capture_file_name") : CV_capture_file_name;
CV_capture_file_prefix = !CV_capture_file_prefix ? pConsole->GetCVar("capture_file_prefix") : CV_capture_file_prefix;
@@ -2125,7 +2125,7 @@ void CD3D9Renderer::CaptureFrameBuffer()
CDebugAllowFileAccess ignoreInvalidFileAccess;
CacheCaptureCVars();
if (!CV_capture_frames || !CV_capture_folder || !CV_capture_file_format || !CV_capture_frame_once ||
if (!CV_capture_frames || !CV_capture_folder || !CV_capture_frame_once ||
!CV_capture_file_name || !CV_capture_file_prefix || !CV_capture_buffer)
{
return;
@@ -2156,7 +2156,7 @@ void CD3D9Renderer::CaptureFrameBuffer()
}
size_t pathLen = strlen(path);
snprintf(&path[pathLen], sizeof(path) - 1 - pathLen, "\\%s%06d.%s", prefix, frameNum - 1, CV_capture_file_format->GetString());
snprintf(&path[pathLen], sizeof(path) - 1 - pathLen, "\\%s%06d.%s", prefix, frameNum - 1, "jpg");
}
if (CV_capture_frame_once->GetIVal())
@@ -852,7 +852,7 @@ public:
bool EF_PrepareShadowGenForLight(SRenderLight* pLight, int nLightID);
bool PrepareShadowGenForFrustum(ShadowMapFrustum* pCurFrustum, SRenderLight* pLight, int nLightFrustumID = 0, int nLOD = 0);
void PrepareShadowGenForFrustumNonJobs(const int nFlags);
virtual void EF_InvokeShadowMapRenderJobs(const int nFlags);
virtual void EF_InvokeShadowMapRenderJobs(int nFlags);
void InvokeShadowMapRenderJobs(ShadowMapFrustum* pCurFrustum, const SRenderingPassInfo& passInfo);
void StartInvokeShadowMapRenderJobs(ShadowMapFrustum* pCurFrustum, const SRenderingPassInfo& passInfo);
@@ -989,7 +989,7 @@ public:
virtual void RT_ReleaseCB(void* pCB);
virtual void RT_DrawDynVB(SVF_P3F_C4B_T2F* pBuf, uint16* pInds, uint32 nVerts, uint32 nInds, const PublicRenderPrimitiveType nPrimType);
virtual void RT_DrawDynVBUI(SVF_P2F_C4B_T2F_F4B* pBuf, uint16* pInds, uint32 nVerts, uint32 nInds, const PublicRenderPrimitiveType nPrimType);
virtual void RT_DrawStringU(IFFont_RenderProxy* pFont, float x, float y, float z, const char* pStr, const bool asciiMultiLine, const STextDrawContext& ctx) const;
virtual void RT_DrawStringU(IFFont_RenderProxy* pFont, float x, float y, float z, const char* pStr, bool asciiMultiLine, const STextDrawContext& ctx) const;
virtual void RT_DrawLines(Vec3 v[], int nump, ColorF& col, int flags, float fGround);
virtual void RT_Draw2dImage(float xpos, float ypos, float w, float h, CTexture* pTexture, float s0, float t0, float s1, float t1, float angle, DWORD col, float z);
virtual void RT_Draw2dImageStretchMode(bool bStretch);
@@ -1112,7 +1112,7 @@ public:
void DrawLines(Vec3 v[], int nump, ColorF& col, int flags, float fGround);
virtual void Graph(byte* g, int x, int y, int wdt, int hgt, int nC, int type, const char* text, ColorF& color, float fScale);
virtual void DrawDynVB(SVF_P3F_C4B_T2F* pBuf, uint16* pInds, int nVerts, int nInds, const PublicRenderPrimitiveType nPrimType);
virtual void DrawDynVB(SVF_P3F_C4B_T2F* pBuf, uint16* pInds, int nVerts, int nInds, PublicRenderPrimitiveType nPrimType);
virtual void DrawDynUiPrimitiveList(DynUiPrimitiveList& primitives, int totalNumVertices, int totalNumIndices);
virtual void PrintResourcesLeaks();
@@ -1159,7 +1159,7 @@ public:
virtual void ReadFrameBuffer(unsigned char* pRGB, int nImageX, int nSizeX, int nSizeY, ERB_Type eRBType, bool bRGBA, int nScaledX = -1, int nScaledY = -1);
virtual void ReadFrameBufferFast(uint32* pDstARGBA8, int dstWidth, int dstHeight, bool BGRA = true);
virtual void SetRendererCVar(ICVar* pCVar, const char* pArgText, const bool bSilentMode = false);
virtual void SetRendererCVar(ICVar* pCVar, const char* pArgText, bool bSilentMode = false);
/////////////////////////////////////////////////////////////////////////////////////////////////////
// This routines uses 2 destination surfaces. It triggers a backbuffer copy to one of its surfaces,
@@ -1267,7 +1267,7 @@ public:
virtual int ScreenToTexture(int nTexID);
virtual bool SetGammaDelta(const float fGamma);
virtual bool SetGammaDelta(float fGamma);
//////////////////////////////////////////////////////////////////////
// Replacement functions for the Font engine
@@ -1871,7 +1871,7 @@ public:
}
// This is a cross-platform low-level function for DIP call
ILINE void FX_DrawPrimitive(const eRenderPrimitiveType eType, const int nStartVertex, const int nVerticesCount, const int nInstanceVertices = 0)
ILINE void FX_DrawPrimitive(eRenderPrimitiveType eType, int nStartVertex, int nVerticesCount, int nInstanceVertices = 0)
{
int nPrimitives;
if (nInstanceVertices)
@@ -2046,8 +2046,8 @@ public:
void EF_PrintProfileInfo();
virtual void EF_EndEf3D (const int nFlags, const int nPrecacheUpdateId, const int nNearPrecacheUpdateId, const SRenderingPassInfo& passInfo);
virtual void EF_EndEf2D(const bool bSort); // 2d only
virtual void EF_EndEf3D (int nFlags, int nPrecacheUpdateId, int nNearPrecacheUpdateId, const SRenderingPassInfo& passInfo);
virtual void EF_EndEf2D(bool bSort); // 2d only
virtual WIN_HWND GetHWND() { return m_hWnd; }
virtual bool SetWindowIcon(const char* path);
@@ -2268,7 +2268,6 @@ private:
ICVar* CV_capture_frames;
ICVar* CV_capture_folder;
ICVar* CV_capture_buffer;
ICVar* CV_capture_file_format;
ICVar* CV_capture_frame_once;
ICVar* CV_capture_file_name;
ICVar* CV_capture_file_prefix;
@@ -47,7 +47,7 @@ public:
virtual SDepthTexture* FX_GetDepthSurface([[maybe_unused]] int nWidth, [[maybe_unused]] int nHeight, [[maybe_unused]] bool bAA, [[maybe_unused]] bool shaderResourceView = false) override { return nullptr; }
virtual long FX_SetIStream([[maybe_unused]] const void* pB, [[maybe_unused]] uint32 nOffs, [[maybe_unused]] RenderIndexType idxType) override { return -1; }
virtual long FX_SetVStream([[maybe_unused]] int nID, [[maybe_unused]] const void* pB, [[maybe_unused]] uint32 nOffs, [[maybe_unused]] uint32 nStride, [[maybe_unused]] uint32 nFreq = 1) override { return -1; }
virtual void FX_DrawPrimitive([[maybe_unused]] const eRenderPrimitiveType eType, [[maybe_unused]] const int nStartVertex, [[maybe_unused]] const int nVerticesCount, [[maybe_unused]] const int nInstanceVertices = 0) {}
virtual void FX_DrawPrimitive([[maybe_unused]] eRenderPrimitiveType eType, [[maybe_unused]] int nStartVertex, [[maybe_unused]] int nVerticesCount, [[maybe_unused]] int nInstanceVertices = 0) {}
virtual void DrawQuad3D([[maybe_unused]] const Vec3& v0, [[maybe_unused]] const Vec3& v1, [[maybe_unused]] const Vec3& v2, [[maybe_unused]] const Vec3& v3, [[maybe_unused]] const ColorF& color, [[maybe_unused]] float ftx0, [[maybe_unused]] float fty0, [[maybe_unused]] float ftx1, [[maybe_unused]] float fty1) override {}
virtual void FX_ClearTarget(ITexture* pTex) override;
virtual void FX_ClearTarget(SDepthTexture* pTex) override;
@@ -97,7 +97,7 @@ public:
virtual void SetRenderTile([[maybe_unused]] f32 nTilesPosX, [[maybe_unused]] f32 nTilesPosY, [[maybe_unused]] f32 nTilesGridSizeX, [[maybe_unused]] f32 nTilesGridSizeY) {}
virtual void EF_InvokeShadowMapRenderJobs([[maybe_unused]] const int nFlags){}
virtual void EF_InvokeShadowMapRenderJobs([[maybe_unused]] int nFlags){}
//! Fills array of all supported video formats (except low resolution formats)
//! Returns number of formats, also when called with NULL
virtual int EnumDisplayFormats(SDispFormat* Formats);
@@ -128,7 +128,7 @@ public:
virtual void Reset (void) {};
virtual void RT_ReleaseCB(void*){}
virtual void DrawDynVB(SVF_P3F_C4B_T2F* pBuf, uint16* pInds, int nVerts, int nInds, const PublicRenderPrimitiveType nPrimType);
virtual void DrawDynVB(SVF_P3F_C4B_T2F* pBuf, uint16* pInds, int nVerts, int nInds, PublicRenderPrimitiveType nPrimType);
virtual void DrawDynUiPrimitiveList(DynUiPrimitiveList& primitives, int totalNumVertices, int totalNumIndices);
virtual void DrawBuffer(CVertexBuffer* pVBuf, CIndexBuffer* pIBuf, int nNumIndices, int nOffsIndex, const PublicRenderPrimitiveType nPrmode, int nVertStart = 0, int nVertStop = 0);
@@ -177,7 +177,7 @@ public:
virtual unsigned int DownLoadToVideoMemory3D([[maybe_unused]] const byte* data, [[maybe_unused]] int w, [[maybe_unused]] int h, [[maybe_unused]] int d, [[maybe_unused]] ETEX_Format eTFSrc, [[maybe_unused]] ETEX_Format eTFDst, [[maybe_unused]] int nummipmap, [[maybe_unused]] bool repeat = true, [[maybe_unused]] int filter = FILTER_BILINEAR, [[maybe_unused]] int Id = 0, [[maybe_unused]] const char* szCacheName = NULL, [[maybe_unused]] int flags = 0, [[maybe_unused]] EEndian eEndian = eLittleEndian, [[maybe_unused]] RectI* pRegion = NULL, [[maybe_unused]] bool bAsynDevTexCreation = false) { return 0; }
virtual void UpdateTextureInVideoMemory([[maybe_unused]] uint32 tnum, [[maybe_unused]] const byte* newdata, [[maybe_unused]] int posx, [[maybe_unused]] int posy, [[maybe_unused]] int w, [[maybe_unused]] int h, [[maybe_unused]] ETEX_Format eTFSrc = eTF_R8G8B8A8, [[maybe_unused]] int posz = 0, [[maybe_unused]] int sizez = 1){}
virtual bool SetGammaDelta(const float fGamma);
virtual bool SetGammaDelta(float fGamma);
virtual void RestoreGamma(void) {};
virtual void RemoveTexture([[maybe_unused]] unsigned int TextureId) {}
@@ -238,7 +238,7 @@ public:
virtual void GetProjectionMatrix(float* mat);
//for texture
virtual ITexture* EF_LoadTexture(const char* nameTex, const uint32 flags = 0);
virtual ITexture* EF_LoadTexture(const char* nameTex, uint32 flags = 0);
virtual ITexture* EF_LoadDefaultTexture(const char* nameTex);
virtual void DrawQuad(const Vec3& right, const Vec3& up, const Vec3& origin, int nFlipMode = 0);
@@ -298,10 +298,10 @@ public:
virtual bool EF_SetLightHole(Vec3 vPos, Vec3 vNormal, int idTex, float fScale = 1.0f, bool bAdditive = true);
// Draw all shaded REs in the list
virtual void EF_EndEf3D (const int nFlags, const int nPrecacheUpdateId, const int nNearPrecacheUpdateId, const SRenderingPassInfo& passInfo);
virtual void EF_EndEf3D (int nFlags, int nPrecacheUpdateId, int nNearPrecacheUpdateId, const SRenderingPassInfo& passInfo);
// 2d interface for shaders
virtual void EF_EndEf2D(const bool bSort);
virtual void EF_EndEf2D(bool bSort);
virtual bool EF_PrecacheResource(SShaderItem* pSI, float fMipFactor, float fTimeToReady, int Flags, int nUpdateId, int nCounter);
virtual bool EF_PrecacheResource(ITexture* pTP, float fDist, float fTimeToReady, int Flags, int nUpdateId, int nCounter);
virtual void PrecacheResources();
@@ -380,7 +380,7 @@ public:
virtual void RT_DrawDynVB([[maybe_unused]] int Pool, [[maybe_unused]] uint32 nVerts) {}
virtual void RT_DrawDynVB([[maybe_unused]] SVF_P3F_C4B_T2F* pBuf, [[maybe_unused]] uint16* pInds, [[maybe_unused]] uint32 nVerts, [[maybe_unused]] uint32 nInds, [[maybe_unused]] const PublicRenderPrimitiveType nPrimType) {}
virtual void RT_DrawDynVBUI([[maybe_unused]] SVF_P2F_C4B_T2F_F4B* pBuf, [[maybe_unused]] uint16* pInds, [[maybe_unused]] uint32 nVerts, [[maybe_unused]] uint32 nInds, [[maybe_unused]] const PublicRenderPrimitiveType nPrimType) {}
virtual void RT_DrawStringU([[maybe_unused]] IFFont_RenderProxy* pFont, [[maybe_unused]] float x, [[maybe_unused]] float y, [[maybe_unused]] float z, [[maybe_unused]] const char* pStr, [[maybe_unused]] const bool asciiMultiLine, [[maybe_unused]] const STextDrawContext& ctx) const {}
virtual void RT_DrawStringU([[maybe_unused]] IFFont_RenderProxy* pFont, [[maybe_unused]] float x, [[maybe_unused]] float y, [[maybe_unused]] float z, [[maybe_unused]] const char* pStr, [[maybe_unused]] bool asciiMultiLine, [[maybe_unused]] const STextDrawContext& ctx) const {}
virtual void RT_DrawLines([[maybe_unused]] Vec3 v[], [[maybe_unused]] int nump, [[maybe_unused]] ColorF& col, [[maybe_unused]] int flags, [[maybe_unused]] float fGround) {}
virtual void RT_Draw2dImage([[maybe_unused]] float xpos, [[maybe_unused]] float ypos, [[maybe_unused]] float w, [[maybe_unused]] float h, [[maybe_unused]] CTexture* pTexture, [[maybe_unused]] float s0, [[maybe_unused]] float t0, [[maybe_unused]] float s1, [[maybe_unused]] float t1, [[maybe_unused]] float angle, [[maybe_unused]] DWORD col, [[maybe_unused]] float z) {}
virtual void RT_Push2dImage([[maybe_unused]] float xpos, [[maybe_unused]] float ypos, [[maybe_unused]] float w, [[maybe_unused]] float h, [[maybe_unused]] CTexture* pTexture, [[maybe_unused]] float s0, [[maybe_unused]] float t0, [[maybe_unused]] float s1, [[maybe_unused]] float t1, [[maybe_unused]] float angle, [[maybe_unused]] DWORD col, [[maybe_unused]] float z, [[maybe_unused]] float stereoDepth) {}
@@ -402,7 +402,7 @@ public:
virtual void RT_SetViewport([[maybe_unused]] int x, [[maybe_unused]] int y, [[maybe_unused]] int width, [[maybe_unused]] int height, [[maybe_unused]] int id) {};
virtual void RT_SetRendererCVar([[maybe_unused]] ICVar* pCVar, [[maybe_unused]] const char* pArgText, [[maybe_unused]] const bool bSilentMode = false) {};
virtual void SetRendererCVar([[maybe_unused]] ICVar* pCVar, [[maybe_unused]] const char* pArgText, [[maybe_unused]] const bool bSilentMode = false) {};
virtual void SetRendererCVar([[maybe_unused]] ICVar* pCVar, [[maybe_unused]] const char* pArgText, [[maybe_unused]] bool bSilentMode = false) {};
virtual void SetMatrices([[maybe_unused]] float* pProjMat, [[maybe_unused]] float* pViewMat) {}
@@ -107,15 +107,9 @@ namespace AZ
result = ContinueLoading(&id, azrtti_typeid<AssetId>(), it->value, context);
if (!id.m_guid.IsNull())
{
if (instance->Create(id))
{
result.Combine(context.Report(result, "Successfully created Asset<T>."));
}
else
{
result.Combine(context.Report(JSR::Tasks::Convert, JSR::Outcomes::Unknown,
"The asset id was successfully read, but creating an Asset<T> instance from it failed."));
}
*instance = Asset<AssetData>(id, instance->GetType());
result.Combine(context.Report(result, "Successfully created Asset<T> with id."));
}
else if (result.GetProcessing() == JSR::Processing::Completed)
{
@@ -48,6 +48,7 @@
#include <AzCore/Module/ModuleManager.h>
#include <AzCore/IO/FileIO.h>
#include <AzCore/IO/Path/Path_fwd.h>
#include <AzCore/IO/SystemFile.h>
#include <AzCore/Driller/Driller.h>
@@ -434,6 +435,7 @@ namespace AZ
// Merge the bootstrap.cfg file into the Settings Registry as soon as the OSAllocator has been created.
SettingsRegistryMergeUtils::MergeSettingsToRegistry_Bootstrap(*m_settingsRegistry);
SettingsRegistryMergeUtils::MergeSettingsToRegistry_O3deUserRegistry(*m_settingsRegistry, AZ_TRAIT_OS_PLATFORM_CODENAME, {});
SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(*m_settingsRegistry, m_commandLine, executeRegDumpCommands);
SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(*m_settingsRegistry);
@@ -888,17 +890,19 @@ namespace AZ
SettingsRegistryMergeUtils::MergeSettingsToRegistry_TargetBuildDependencyRegistry(registry,
AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer);
#if defined(AZ_DEBUG_BUILD) || defined(AZ_PROFILE_BUILD)
// In development builds apply the developer registry and the command line to allow early overrides. This will
// In development builds apply the o3de registry and the command line to allow early overrides. This will
// allow developers to override things like default paths or Asset Processor connection settings. Any additional
// values will be replaced by later loads, so this step will happen again at the end of loading.
SettingsRegistryMergeUtils::MergeSettingsToRegistry_UserRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer);
SettingsRegistryMergeUtils::MergeSettingsToRegistry_O3deUserRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer);
SettingsRegistryMergeUtils::MergeSettingsToRegistry_ProjectUserRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer);
SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, m_commandLine, false);
#endif
SettingsRegistryMergeUtils::MergeSettingsToRegistry_EngineRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer);
SettingsRegistryMergeUtils::MergeSettingsToRegistry_GemRegistries(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer);
SettingsRegistryMergeUtils::MergeSettingsToRegistry_ProjectRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer);
#if defined(AZ_DEBUG_BUILD) || defined(AZ_PROFILE_BUILD)
SettingsRegistryMergeUtils::MergeSettingsToRegistry_UserRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer);
SettingsRegistryMergeUtils::MergeSettingsToRegistry_O3deUserRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer);
SettingsRegistryMergeUtils::MergeSettingsToRegistry_ProjectUserRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer);
SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, m_commandLine, true);
#endif
}
@@ -1455,6 +1459,8 @@ namespace AZ
PolygonPrismReflect(context);
// reflect name dictionary.
Name::Reflect(context);
// reflect path
IO::PathReflection::Reflect(context);
// reflect the SettingsRegistryInterface, SettignsRegistryImpl and the global Settings Registry
// instance (AZ::SettingsRegistry::Get()) into the Behavior Context
@@ -96,6 +96,11 @@ namespace AZ
}
Entity::~Entity()
{
Reset();
}
void Entity::Reset()
{
AZ_Assert(m_state != State::Activating && m_state != State::Deactivating && m_state != State::Initializing, "Unsafe to delete an entity during its state transition.");
if (m_state == State::Active)
@@ -116,6 +121,8 @@ namespace AZ
delete *it;
}
m_components.clear();
if (m_state == State::Init)
{
EBUS_EVENT(EntitySystemBus, OnEntityDestroyed, m_id);
@@ -751,6 +758,8 @@ namespace AZ
->Field("IsRuntimeActive", &Entity::m_isRuntimeActiveByDefault)
;
serializeContext->RegisterGenericType<AZStd::unordered_map<AZStd::string, AZ::Component*>>();
serializeContext->Class<EntityId>()
->Version(1, &EntityIdConverter)
->Field("id", &EntityId::m_id);
@@ -118,6 +118,9 @@ namespace AZ
//! If the entity is in a transition state, this function asserts.
virtual ~Entity();
//! Resets the state to default
void Reset();
//! Gets the ID of the entity.
//! @return The ID of the entity.
EntityId GetId() const { return m_id; }
@@ -10,6 +10,7 @@
*
*/
#include <AzCore/std/containers/map.h>
#include <AzCore/Component/Entity.h>
#include <AzCore/Component/EntityIdSerializer.h>
#include <AzCore/Component/EntitySerializer.h>
@@ -62,11 +63,17 @@ namespace AZ
}
{
AZStd::unordered_map<AZStd::string, AZ::Component*> componentMap;
JSR::ResultCode componentLoadResult =
ContinueLoadingFromJsonObjectField(&entityInstance->m_components,
azrtti_typeid<decltype(entityInstance->m_components)>(),
ContinueLoadingFromJsonObjectField(&componentMap,
azrtti_typeid<decltype(componentMap)>(),
inputValue, "Components", context);
for (auto& [componentKey, component] : componentMap)
{
entityInstance->m_components.emplace_back(component);
}
result.Combine(componentLoadResult);
}
@@ -145,9 +152,21 @@ namespace AZ
const AZ::Entity::ComponentArrayType* defaultComponents =
defaultEntityInstance ? &defaultEntityInstance->m_components : nullptr;
AZStd::unordered_map<AZStd::string, AZ::Component*> componentMap;
AZStd::unordered_map<AZStd::string, AZ::Component*> defaultComponentMap;
ConvertComponentVectorToMap(*components, componentMap);
if (defaultComponents)
{
ConvertComponentVectorToMap(*defaultComponents, defaultComponentMap);
}
JSR::ResultCode resultComponents =
ContinueStoringToJsonObjectField(outputValue, "Components",
components, defaultComponents, azrtti_typeid<decltype(entityInstance->m_components)>(), context);
&componentMap,
defaultComponents ? &defaultComponentMap : nullptr,
azrtti_typeid<decltype(componentMap)>(), context);
result.Combine(resultComponents);
}
@@ -183,4 +202,16 @@ namespace AZ
result.GetProcessing() == JSR::Processing::Halted ? "Successfully stored Entity information." :
"Failed to store Entity information.");
}
void JsonEntitySerializer::ConvertComponentVectorToMap(const AZ::Entity::ComponentArrayType& components,
AZStd::unordered_map<AZStd::string, AZ::Component*>& componentMapOut)
{
for (AZ::Component* component : components)
{
if (component)
{
componentMapOut.emplace(AZStd::string::format("Component_[%llu]", component->GetId()), component);
}
}
}
}
@@ -29,5 +29,9 @@ namespace AZ
JsonSerializationResult::Result Store(rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue, const Uuid& valueTypeId,
JsonSerializerContext& context) override;
private:
void ConvertComponentVectorToMap(const AZ::Entity::ComponentArrayType& components,
AZStd::unordered_map<AZStd::string, AZ::Component*>& componentMapOut);
};
}
@@ -196,7 +196,7 @@ namespace AZ
return nullptr;
}
AZStd::string Console::AutoCompleteCommand(const char* command)
AZStd::string Console::AutoCompleteCommand(const char* command, AZStd::vector<AZStd::string>* matches)
{
const size_t commandLength = strlen(command);
@@ -219,6 +219,10 @@ namespace AZ
{
AZLOG_INFO("- %s : %s\n", curr->m_name, curr->m_desc);
commandSubset.push_back(curr->m_name);
if (matches)
{
matches->push_back(curr->m_name);
}
}
}
@@ -283,6 +287,12 @@ namespace AZ
AZ_Assert(false, "Mismatched console functor types registered under the same name");
return;
}
// Discard duplicate functors if the 'DontDuplicate' flag has been set
if ((front->GetFlags() & ConsoleFunctorFlags::DontDuplicate) != ConsoleFunctorFlags::Null)
{
return;
}
}
}
m_commands[lowerName].emplace_back(functor);
@@ -62,7 +62,7 @@ namespace AZ
void ExecuteCommandLine(const AZ::CommandLine& commandLine) override;
bool HasCommand(const char* command) override;
ConsoleFunctorBase* FindCommand(const char* command) override;
AZStd::string AutoCompleteCommand(const char* command) override;
AZStd::string AutoCompleteCommand(const char* command, AZStd::vector<AZStd::string>* matches = nullptr) override;
void VisitRegisteredFunctors(const FunctorVisitor& visitor) override;
void RegisterFunctor(ConsoleFunctorBase* functor) override;
void UnregisterFunctor(ConsoleFunctorBase* functor) override;
@@ -17,6 +17,7 @@
#include <AzCore/Console/IConsoleTypes.h>
#include <AzCore/EBus/Event.h>
#include <AzCore/RTTI/RTTI.h>
#include <AzCore/std/containers/vector.h>
#include <AzCore/std/functional.h>
namespace AZ
@@ -103,10 +104,13 @@ namespace AZ
//! @return non-null pointer to the console command if found
virtual ConsoleFunctorBase* FindCommand(const char* command) = 0;
//! Prints all commands of which the input is a prefix.
//! @param command the prefix string to dump all matching commands for
//! @return boolean true on success, false otherwise
virtual AZStd::string AutoCompleteCommand(const char* command) = 0;
//! Finds all commands where the input command is a prefix and returns
//! the longest matching substring prefix the results have in common.
//! @param command The prefix string to find all matching commands for.
//! @param matches The list of all commands that match the input prefix.
//! @return The longest matching substring prefix the results have in common.
virtual AZStd::string AutoCompleteCommand(const char* command,
AZStd::vector<AZStd::string>* matches = nullptr) = 0;
//! Retrieves the value of the requested cvar.
//! @param command the name of the cvar to find and retrieve the current value of
@@ -233,7 +237,7 @@ static constexpr AZ::ThreadSafety ConsoleThreadSafety<_TYPE, std::enable_if_t<st
//! @param _FLAGS a set of AzFramework::ConsoleFunctorFlags used to mutate behaviour
//! @param _DESC a description of the cvar
#define AZ_CONSOLEFREEFUNC_3(_FUNCTION, _FLAGS, _DESC) \
inline AZ::ConsoleFunctor<void, false> Functor##_FUNCTION(#_FUNCTION, _DESC, _FLAGS, AZ::TypeId::CreateNull(), &_FUNCTION)
inline AZ::ConsoleFunctor<void, false> Functor##_FUNCTION(#_FUNCTION, _DESC, _FLAGS | AZ::ConsoleFunctorFlags::DontDuplicate, AZ::TypeId::CreateNull(), &_FUNCTION)
//! Implements a console functor for a non-member function.
//!
@@ -243,6 +247,6 @@ static constexpr AZ::ThreadSafety ConsoleThreadSafety<_TYPE, std::enable_if_t<st
//! @param _FLAGS a set of AzFramework::ConsoleFunctorFlags used to mutate behaviour
//! @param _DESC a description of the cvar
#define AZ_CONSOLEFREEFUNC_4(_NAME, _FUNCTION, _FLAGS, _DESC) \
inline AZ::ConsoleFunctor<void, false> Functor##_FUNCTION(#_FUNCTION, _DESC, _FLAGS, AZ::TypeId::CreateNull(), &_FUNCTION)
inline AZ::ConsoleFunctor<void, false> Functor##_FUNCTION(#_FUNCTION, _DESC, _FLAGS | AZ::ConsoleFunctorFlags::DontDuplicate, AZ::TypeId::CreateNull(), &_FUNCTION)
#define AZ_CONSOLEFREEFUNC(...) AZ_MACRO_SPECIALIZE(AZ_CONSOLEFREEFUNC_, AZ_VA_NUM_ARGS(__VA_ARGS__), (__VA_ARGS__))
@@ -55,6 +55,7 @@ namespace AZ
, IsDeprecated = (1 << 5) // Command is deprecated, show a warning when invoked
, NeedsReload = (1 << 6) // Level should be reloaded after executing this command
, AllowClientSet = (1 << 7) // Allow clients to modify this cvar even in release (this alters the cvar for all connected servers and clients, be VERY careful enabling this flag)
, DontDuplicate = (1 << 8) // Discard functors with the same name as another that has already been registered instead of duplicating them (which is the default behavior)
};
AZ_DEFINE_ENUM_BITWISE_OPERATORS(ConsoleFunctorFlags);
@@ -11,6 +11,7 @@
*/
#include <AzCore/IO/Path/Path.h>
#include <AzCore/Serialization/SerializeContext.h>
// Explicit instantations of our support Path classes
namespace AZ::IO
@@ -53,4 +54,13 @@ namespace AZ::IO
const PathIterator<Path>& rhs);
template bool operator!=<FixedMaxPath>(const PathIterator<FixedMaxPath>& lhs,
const PathIterator<FixedMaxPath>& rhs);
void PathReflection::Reflect(AZ::ReflectContext* context)
{
if (auto* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
{
serializeContext->Class<AZ::IO::Path>()
->Field("m_path", &AZ::IO::Path::m_path);
}
}
}
@@ -300,6 +300,7 @@ namespace AZ::IO
using const_iterator = const PathIterator<BasicPath>;
using iterator = const_iterator;
friend PathIterator<BasicPath>;
friend struct PathReflection;
// constructors and destructor
constexpr BasicPath() = default;
@@ -631,6 +632,11 @@ namespace AZ::IO
constexpr BasicPath<StringType> operator/(const BasicPath<StringType>& lhs, const typename BasicPath<StringType>::value_type* rhs);
}
namespace AZ
{
AZ_TYPE_INFO_SPECIALIZE(AZ::IO::Path, "{88E0A40F-3085-4CAB-8B11-EF5A2659C71A}");
}
namespace AZ::IO
{
//! Path iterator that allows traversal of the path elements
@@ -31,6 +31,11 @@ namespace AZStd
struct hash;
}
namespace AZ
{
class ReflectContext;
}
namespace AZ::IO
{
//! Path Constants
@@ -56,6 +61,11 @@ namespace AZ::IO
// It depends on the path type
template <typename PathType>
class PathIterator;
struct PathReflection
{
static void Reflect(AZ::ReflectContext* context);
};
}
namespace AZStd
@@ -68,9 +68,11 @@ namespace AZ
bool useAllHardware = true;
settingsRegistry->Get(useAllHardware, "/Amazon/AzCore/Streamer/UseAllHardware");
bool reportHardware = true;
settingsRegistry->Get(reportHardware, "/Amazon/AzCore/Streamer/ReportHardware");
AZ::IO::HardwareInformation hardwareInfo;
if (!AZ::IO::CollectIoHardwareInformation(hardwareInfo, useAllHardware))
if (!AZ::IO::CollectIoHardwareInformation(hardwareInfo, useAllHardware, reportHardware))
{
AZ_Assert(false, "Unable to collect information on available IO hardware.");
return CreateSimpleStreamerStack();
@@ -42,8 +42,8 @@ namespace AZ::IO
AZStd::string m_profile{"Default"};
size_t m_maxPhysicalSectorSize{ AZCORE_GLOBAL_NEW_ALIGNMENT };
size_t m_maxLogicalSectorSize{ AZCORE_GLOBAL_NEW_ALIGNMENT };
size_t m_maxPageSize{ 0 };
size_t m_maxTransfer{ 0 };
size_t m_maxPageSize{ AZCORE_GLOBAL_NEW_ALIGNMENT };
size_t m_maxTransfer{ AZCORE_GLOBAL_NEW_ALIGNMENT };
};
class IStreamerStackConfig
@@ -73,7 +73,8 @@ namespace AZ::IO
//! @param includeAllHardware Includes all available hardware that can be used by AZ::IO::Streamer. If set to false
//! only hardware is listed that is known to be used. This may be more performant, but can result is file
//! requests failing if they use an previously unknown path.
extern bool CollectIoHardwareInformation(HardwareInformation& info, bool includeAllHardware);
//! @param reportHardware If true, hardware information will be printed to the log if available.
extern bool CollectIoHardwareInformation(HardwareInformation& info, bool includeAllHardware, bool reportHardware);
extern void ReflectNative(ReflectContext* context);
//! Constant used to denote "file not found" in StreamStackEntry processing.
@@ -29,6 +29,7 @@
#include <AzCore/Math/ColorSerializer.h>
#include <AzCore/Math/Quaternion.h>
#include <AzCore/Math/Transform.h>
#include <AzCore/Math/TransformSerializer.h>
#include <AzCore/Math/Matrix3x3.h>
#include <AzCore/Math/Matrix3x4.h>
#include <AzCore/Math/Matrix4x4.h>
@@ -370,6 +371,7 @@ namespace AZ
context.Serializer<JsonVector3Serializer>()->HandlesType<Vector3>();
context.Serializer<JsonVector4Serializer>()->HandlesType<Vector4>();
context.Serializer<JsonQuaternionSerializer>()->HandlesType<Quaternion>();
context.Serializer<JsonTransformSerializer>()->HandlesType<Transform>();
}
void MathReflect(ReflectContext* context)
@@ -0,0 +1,143 @@
/*
* 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.
*
*/
#include <AzCore/Math/Transform.h>
#include <AzCore/Math/TransformSerializer.h>
namespace AZ
{
AZ_CLASS_ALLOCATOR_IMPL(JsonTransformSerializer, AZ::SystemAllocator, 0);
JsonSerializationResult::Result JsonTransformSerializer::Load(
void* outputValue, [[maybe_unused]] const Uuid& outputValueTypeId, const rapidjson::Value& inputValue,
JsonDeserializerContext& context)
{
namespace JSR = JsonSerializationResult;
if (azrtti_typeid<AZ::Transform>() != outputValueTypeId)
{
return context.Report(
JSR::Tasks::ReadField, JSR::Outcomes::Unsupported,
"Unable to deserialize Transform from json because the outputValueTypeId isn't a Transform type.");
}
AZ::Transform* transformInstance = reinterpret_cast<AZ::Transform*>(outputValue);
AZ_Assert(transformInstance, "Output value for JsonTransformSerializer can't be null.");
JSR::ResultCode result(JSR::Tasks::ReadField);
{
AZ::Vector3 translation = transformInstance->GetTranslation();
JSR::ResultCode loadResult = ContinueLoadingFromJsonObjectField(
&translation, azrtti_typeid<decltype(translation)>(), inputValue, TranslationTag, context);
result.Combine(loadResult);
transformInstance->SetTranslation(translation);
}
{
AZ::Quaternion rotation = transformInstance->GetRotation();
JSR::ResultCode loadResult =
ContinueLoadingFromJsonObjectField(&rotation, azrtti_typeid<decltype(rotation)>(), inputValue, RotationTag, context);
result.Combine(loadResult);
transformInstance->SetRotation(rotation);
}
{
// Scale is transitioning to a single uniform scale value, but since it's still internally represented as a Vector3,
// we need to pick one number to use for load/store operations.
float scale = transformInstance->GetScale().GetMaxElement();
JSR::ResultCode loadResult =
ContinueLoadingFromJsonObjectField(&scale, azrtti_typeid<decltype(scale)>(), inputValue, ScaleTag, context);
result.Combine(loadResult);
transformInstance->SetScale(AZ::Vector3(scale));
}
return context.Report(
result,
result.GetProcessing() != JSR::Processing::Halted ? "Succesfully loaded Transform information."
: "Failed to load Transform information.");
}
JsonSerializationResult::Result JsonTransformSerializer::Store(
rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue, [[maybe_unused]] const Uuid& valueTypeId,
JsonSerializerContext& context)
{
namespace JSR = AZ::JsonSerializationResult;
if (azrtti_typeid<AZ::Transform>() != valueTypeId)
{
return context.Report(
JSR::Tasks::WriteValue, JSR::Outcomes::Unsupported,
"Unable to Serialize Transform to json because the valueTypeId isn't a Transform type.");
}
const AZ::Transform* transformInstance = reinterpret_cast<const AZ::Transform*>(inputValue);
AZ_Assert(transformInstance, "Input value for JsonTransformSerializer can't be null.");
const AZ::Transform* defaultTransformInstance = reinterpret_cast<const AZ::Transform*>(defaultValue);
JSR::ResultCode result(JSR::Tasks::WriteValue);
{
AZ::ScopedContextPath subPathName(context, TranslationTag);
const AZ::Vector3 translation = transformInstance->GetTranslation();
const AZ::Vector3 defaultTranslation = defaultTransformInstance ? defaultTransformInstance->GetTranslation() : AZ::Vector3();
JSR::ResultCode storeResult = ContinueStoringToJsonObjectField(
outputValue, TranslationTag, &translation, defaultTransformInstance ? &defaultTranslation : nullptr,
azrtti_typeid<decltype(translation)>(), context);
result.Combine(storeResult);
}
{
AZ::ScopedContextPath subPathName(context, RotationTag);
const AZ::Quaternion rotation = transformInstance->GetRotation();
const AZ::Quaternion defaultRotation = defaultTransformInstance ? defaultTransformInstance->GetRotation() : AZ::Quaternion();
JSR::ResultCode storeResult = ContinueStoringToJsonObjectField(
outputValue, RotationTag, &rotation, defaultTransformInstance ? &defaultRotation : nullptr,
azrtti_typeid<decltype(rotation)>(), context);
result.Combine(storeResult);
}
{
AZ::ScopedContextPath subPathName(context, ScaleTag);
// Scale is transitioning to a single uniform scale value, but since it's still internally represented as a Vector3,
// we need to pick one number to use for load/store operations.
float scale = transformInstance->GetScale().GetMaxElement();
float defaultScale = defaultTransformInstance ? defaultTransformInstance->GetScale().GetMaxElement() : 0.0f;
JSR::ResultCode storeResult = ContinueStoringToJsonObjectField(
outputValue, ScaleTag, &scale, defaultTransformInstance ? &defaultScale : nullptr, azrtti_typeid<decltype(scale)>(),
context);
result.Combine(storeResult);
}
return context.Report(
result,
result.GetProcessing() != JSR::Processing::Halted ? "Successfully stored Transform information."
: "Failed to store Transform information.");
}
} // namespace AZ
@@ -0,0 +1,41 @@
/*
* 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.
*
*/
#pragma once
#include <AzCore/Serialization/Json/BaseJsonSerializer.h>
namespace AZ
{
class JsonTransformSerializer : public BaseJsonSerializer
{
public:
AZ_RTTI(JsonTransformSerializer, "{51C321B8-9214-4E85-AA5C-B720428A3B17}", BaseJsonSerializer);
AZ_CLASS_ALLOCATOR_DECL;
JsonSerializationResult::Result Load(
void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue,
JsonDeserializerContext& context) override;
JsonSerializationResult::Result Store(
rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue, const Uuid& valueTypeId,
JsonSerializerContext& context) override;
private:
// Note: These need to be defined as "const char[]" instead of "const char*" so that they can be implicitly converted
// to a rapidjson::GenericStringRef<>. (This also lets rapidjson get the string length at compile time)
static inline constexpr const char TranslationTag[] = "Translation";
static inline constexpr const char RotationTag[] = "Rotation";
static inline constexpr const char ScaleTag[] = "Scale";
};
} // namespace AZ
@@ -19,6 +19,7 @@
#include <AzCore/std/any.h>
#include <AzCore/std/utils.h>
#include <AzCore/std/string/string.h>
#include <AzCore/std/string/fixed_string.h>
namespace AZ
{
@@ -195,7 +196,9 @@ namespace AZ
context.GetSerializeContext()->FindClassData(classElement.m_typeId);
if (!elementClassData)
{
return context.Report(Tasks::RetrieveInfo, Outcomes::Unknown, "Failed to retrieve serialization information.");
return context.Report(Tasks::RetrieveInfo, Outcomes::Unknown,
AZStd::string::format("Failed to retrieve serialization information for type %s.",
classElement.m_typeId.ToString<AZStd::fixed_string<AZ::Uuid::MaxStringBuffer>>().c_str()));
}
if (!elementClassData->m_azRtti)
{
@@ -709,7 +709,7 @@ namespace AZ::SettingsRegistryMergeUtils
}
}
void MergeSettingsToRegistry_UserRegistry(SettingsRegistryInterface& registry, const AZStd::string_view platform,
void MergeSettingsToRegistry_ProjectUserRegistry(SettingsRegistryInterface& registry, const AZStd::string_view platform,
const SettingsRegistryInterface::Specializations& specializations, AZStd::vector<char>* scratchBuffer)
{
// Unlike other paths, the path can't be overwritten by the dev settings because that would create a circular dependency.
@@ -721,6 +721,16 @@ namespace AZ::SettingsRegistryMergeUtils
}
}
void MergeSettingsToRegistry_O3deUserRegistry(SettingsRegistryInterface& registry, const AZStd::string_view platform,
const SettingsRegistryInterface::Specializations& specializations, AZStd::vector<char>* scratchBuffer)
{
if (AZ::IO::FixedMaxPath o3deUserPath = AZ::Utils::GetO3deManifestDirectory(); !o3deUserPath.empty())
{
o3deUserPath /= SettingsRegistryInterface::RegistryFolder;
registry.MergeSettingsFolder(o3deUserPath.Native(), specializations, platform, "", scratchBuffer);
}
}
void MergeSettingsToRegistry_CommandLine(SettingsRegistryInterface& registry, const AZ::CommandLine& commandLine, bool executeCommands)
{
// Iterate over all the command line options in order to parse the --regset and --regremove
@@ -171,7 +171,14 @@ namespace AZ::SettingsRegistryMergeUtils
//! Adds the development settings added by individual users of the project to the Settings Registry.
//! Note that this function is only called in development builds and is compiled out in release builds.
void MergeSettingsToRegistry_UserRegistry(SettingsRegistryInterface& registry, const AZStd::string_view platform,
void MergeSettingsToRegistry_ProjectUserRegistry(SettingsRegistryInterface& registry, const AZStd::string_view platform,
const SettingsRegistryInterface::Specializations& specializations, AZStd::vector<char>* scratchBuffer = nullptr);
//! Adds the user settings from the users home directory of "~/.o3de/Registry"
//! '~' corresponds to %USERPROFILE% on Windows and $HOME on Unix-like platforms(Linux, Mac)
//! Note that this function is only called in development builds and is compiled out in release builds.
//! It is merged before the command line settings are merged so that the command line always takes precedence
void MergeSettingsToRegistry_O3deUserRegistry(SettingsRegistryInterface& registry, const AZStd::string_view platform,
const SettingsRegistryInterface::Specializations& specializations, AZStd::vector<char>* scratchBuffer = nullptr);
//! Adds the settings set through the command line to the Settings Registry. This will also execute any Settings
@@ -42,6 +42,30 @@ namespace AZ::Utils
return result.m_pathStored;
}
AZ::IO::FixedMaxPathString GetExecutableDirectory()
{
AZ::IO::FixedMaxPathString executableDirectory;
if(GetExecutableDirectory(executableDirectory.data(), executableDirectory.capacity())
== ExecutablePathResult::Success)
{
// Updated the size field within the fixed string by using char_traits to calculate the string length
executableDirectory.resize_no_construct(AZStd::char_traits<char>::length(executableDirectory.data()));
}
return executableDirectory;
}
AZ::IO::FixedMaxPathString GetEngineManifestPath()
{
AZ::IO::FixedMaxPath o3deManifestPath = GetO3deManifestDirectory();
if (!o3deManifestPath.empty())
{
o3deManifestPath /= "o3de_manifest.json";
}
return o3deManifestPath.Native();
}
AZ::IO::FixedMaxPathString GetEnginePath()
{
if (auto registry = AZ::SettingsRegistry::Get(); registry != nullptr)
@@ -76,6 +76,9 @@ namespace AZ
//! @returns a result object that indicates if the executable directory was able to be stored within the buffer
ExecutablePathResult GetExecutableDirectory(char* exeStorageBuffer, size_t exeStorageSize);
//! Retrieves the full path of the directroy containing the executable
AZ::IO::FixedMaxPathString GetExecutableDirectory();
//! Retrieves the full path to the engine from settings registry
AZ::IO::FixedMaxPathString GetEnginePath();
@@ -85,6 +88,9 @@ namespace AZ
//! Retrieves the project name from the settings registry
AZ::SettingsRegistryInterface::FixedValueString GetProjectName();
//! Retrieves the full directory to the O3DE manifest directory, i.e. "<userhome>/.o3de"
AZ::IO::FixedMaxPathString GetO3deManifestDirectory();
//! Retrieves the full path where the manifest file lives, i.e. "<userhome>/.o3de/o3de_manifest.json"
AZ::IO::FixedMaxPathString GetEngineManifestPath();
@@ -332,6 +332,8 @@ set(FILES
Math/Transform.cpp
Math/Transform.h
Math/Transform.inl
Math/TransformSerializer.cpp
Math/TransformSerializer.h
Math/Uuid.cpp
Math/Uuid.h
Math/UuidSerializer.h
@@ -38,7 +38,7 @@ namespace AZStd
* therefore an empty class in C++ has size of 1 byte.
* From the C++20 draft chapter 10, note 5
* "[Note: Complete objects of class type have nonzero size. Base class subobjects and "
* "members declared with the no_­unique_­address attribute ([dcl.attr.nouniqueaddr]) are not so constrained. end note]"
* "members declared with the no_unique_address attribute ([dcl.attr.nouniqueaddr]) are not so constrained. -end note]"
* The Index template parameter is used to disambiguate a compressed pair containing multiple elements of the same types
* This is used to allow multiple inheritance from 2 of the same types underlying elements
*/
+1 -1
View File
@@ -96,7 +96,7 @@ namespace AZStd
* \page Setup AZSTD Setup
*
* After you have the AZStd code, you need to make sure you project has add the include path to the folder where AZStd was installed. All AZStd include files are using based on
* AZStd parent folder. For instance all includes are like this \e AZStd/base.h,"AZCore/std/containers/vector,h",etc. We use use the AZStd to avoid name collisions with other
* AZStd parent folder. For instance all includes are like this \e AZStd/base.h,"AzCore/std/containers/vector,h",etc. We use use the AZStd to avoid name collisions with other
* stl implementations and make it obvious where the included file comes from.
* If you decide to use the default allocator (AZStd::allocator) you will need to implement AZStd::Default_Alloc and AZStd::Default_Free functions otherwise you should
* use your own allocator.
@@ -15,7 +15,8 @@
namespace AZ::IO
{
bool CollectIoHardwareInformation(HardwareInformation& info, [[maybe_unused]] bool includeAllHardware)
bool CollectIoHardwareInformation(
HardwareInformation& info, [[maybe_unused]] bool includeAllHardware, [[maybe_unused]] bool reportHardware)
{
// The numbers below are based on common defaults from a local hardware survey.
info.m_maxPageSize = 4096;
@@ -14,9 +14,8 @@
namespace AZ::Utils
{
AZ::IO::FixedMaxPathString GetEngineManifestPath()
AZ::IO::FixedMaxPathString GetO3deManifestDirectory()
{
return {};
}
} // namespace AZ::Utils
} // namespace AZ::Utils
@@ -25,7 +25,7 @@ namespace AZ
void NativeErrorMessageBox(const char*, const char*) {}
AZ::IO::FixedMaxPathString GetEngineManifestPath()
AZ::IO::FixedMaxPathString GetO3deManifestDirectory()
{
if (const char* homePath = std::getenv("HOME"); homePath != nullptr)
{
@@ -33,7 +33,6 @@ namespace AZ
if (!path.empty())
{
path /= ".o3de";
path /= "o3de_manifest.json";
}
return path.Native();
}
@@ -31,6 +31,7 @@ namespace AZ::IO
options.m_enableUnbufferedReads = m_enableUnbufferedReads;
options.m_enableSharing = m_enableFileSharing;
options.m_hasSeekPenalty = drive.m_hasSeekPenalty;
options.m_minimalReporting = m_minimalReporting;
AZStd::vector<AZStd::string_view> drivePaths(drive.m_paths.begin(), drive.m_paths.end());
AZ_Assert(!drive.m_paths.empty(), "Expected at least one drive path.");
@@ -59,7 +60,8 @@ namespace AZ::IO
->Field("MaxMetaDataCache", &WindowsStorageDriveConfig::m_maxMetaDataCache)
->Field("Overcommit", &WindowsStorageDriveConfig::m_overcommit)
->Field("EnableFileSharing", &WindowsStorageDriveConfig::m_enableFileSharing)
->Field("EnableUnbufferedReads", &WindowsStorageDriveConfig::m_enableUnbufferedReads);
->Field("EnableUnbufferedReads", &WindowsStorageDriveConfig::m_enableUnbufferedReads)
->Field("MinimalReporting", &WindowsStorageDriveConfig::m_minimalReporting);
}
}
} // namespace AZ::IO
@@ -34,5 +34,6 @@ namespace AZ::IO
AZ::u32 m_overcommit{ 8 };
bool m_enableFileSharing{ false };
bool m_enableUnbufferedReads{ true };
bool m_minimalReporting{ false };
};
} // namespace AZ::IO
@@ -41,6 +41,7 @@ namespace AZ::IO
: m_hasSeekPenalty(true)
, m_enableUnbufferedReads(true)
, m_enableSharing(false)
, m_minimalReporting(false)
{}
//
@@ -102,7 +103,10 @@ namespace AZ::IO
m_name += m_drivePaths[i].substr(0, m_drivePaths[i].length()-1);
}
m_name += ')';
AZ_Printf("Streamer", "%s created.\n", m_name.c_str());
if (!m_constructionOptions.m_minimalReporting)
{
AZ_Printf("Streamer", "%s created.\n", m_name.c_str());
}
if (m_physicalSectorSize == 0)
{
@@ -160,7 +164,10 @@ namespace AZ::IO
::CloseHandle(file);
}
}
AZ_Printf("Streamer", "%s destroyed.\n", m_name.c_str());
if (!m_constructionOptions.m_minimalReporting)
{
AZ_Printf("Streamer", "%s destroyed.\n", m_name.c_str());
}
}
void StorageDriveWin::PrepareRequest(FileRequest* request)
@@ -483,7 +490,7 @@ namespace AZ::IO
// Remove any alertable IO completion notifications that could be queued by the IO Manager.
if (!::SetFileCompletionNotificationModes(file, FILE_SKIP_SET_EVENT_ON_HANDLE | FILE_SKIP_COMPLETION_PORT_ON_SUCCESS))
{
AZ_Printf("StorageDriveWin", "Failed to remove alertable IO completion notifications. (Error: %u)\n", ::GetLastError());
AZ_Warning("StorageDriveWin", false, "Failed to remove alertable IO completion notifications. (Error: %u)\n", ::GetLastError());
}
if (m_fileCache_handles[cacheIndex] != INVALID_HANDLE_VALUE)
@@ -651,15 +658,6 @@ namespace AZ::IO
#endif // AZ_STREAMER_ADD_EXTRA_PROFILING_INFO
}
// Keep this, it helps to see the critical info about every read.
//AZ_Printf("StorageDriveWin", "FileRead: addr: 0x%p size: %zu offs: %zu alloc: %s direct: %.2f%% '%s'\n",
// data->m_output,
// data->m_size,
// data->m_offset,
// (isAligned) ? "Yes" : "No",
// m_directReadsPercentageStat.GetAverage() * 100.0,
// data->m_path.GetRelativePath());
FileReadStatus& readStatus = m_readSlots_statusInfo[readSlot];
LPOVERLAPPED overlapped = &readStatus.m_overlapped;
overlapped->Offset = aznumeric_caster(readOffs);
@@ -678,7 +676,7 @@ namespace AZ::IO
DWORD error = ::GetLastError();
if (error != ERROR_IO_PENDING)
{
AZ_Printf("StorageDriveWin", "::ReadFile failed with error: %u\n", error);
AZ_Warning("StorageDriveWin", false, "::ReadFile failed with error: %u\n", error);
m_context->GetStreamerThreadSynchronizer().DestroyEventHandle(overlapped->hEvent);
@@ -47,6 +47,9 @@ namespace AZ::IO
//! while in use by AZ::IO::Streamer. File sharing can negatively impact performance and is recommended for
//! development only.
u8 m_enableSharing : 1;
//! If true, only information that's explicitly requested or issues are reported. If false, status information
//! such as when drives are created and destroyed is reported as well.
u8 m_minimalReporting : 1;
};
//! Creates an instance of a storage device that's optimized for use on Windows.
@@ -34,7 +34,7 @@ namespace AZ::IO
return value;
}
static void CollectIoAdaptor(HANDLE deviceHandle, DriveInformation& info, const char* driveName)
static void CollectIoAdaptor(HANDLE deviceHandle, DriveInformation& info, const char* driveName, bool reportHardware)
{
STORAGE_ADAPTER_DESCRIPTOR adapterDescriptor{};
STORAGE_PROPERTY_QUERY query{};
@@ -71,17 +71,21 @@ namespace AZ::IO
DWORD pageSize = NextPowerOfTwo(adapterDescriptor.MaximumTransferLength / adapterDescriptor.MaximumPhysicalPages);
AZ_Printf("Streamer",
"Adapter for drive '%s':\n"
" Bus: %s %i.%i\n"
" Max transfer: %.3f kb\n"
" Page size: %i kb for %i pages\n"
" Supports queuing: %s\n",
driveName,
info.m_profile.c_str(), adapterDescriptor.BusMajorVersion, adapterDescriptor.BusMinorVersion,
(1.0f / 1024.0f) * adapterDescriptor.MaximumTransferLength,
pageSize, adapterDescriptor.MaximumPhysicalPages,
adapterDescriptor.CommandQueueing ? "Yes" : "No");
if (reportHardware)
{
AZ_Printf(
"Streamer",
"Adapter for drive '%s':\n"
" Bus: %s %i.%i\n"
" Max transfer: %.3f kb\n"
" Page size: %i kb for %i pages\n"
" Supports queuing: %s\n",
driveName,
info.m_profile.c_str(), adapterDescriptor.BusMajorVersion, adapterDescriptor.BusMinorVersion,
(1.0f / 1024.0f) * adapterDescriptor.MaximumTransferLength,
pageSize, adapterDescriptor.MaximumPhysicalPages,
adapterDescriptor.CommandQueueing ? "Yes" : "No");
}
info.m_maxTransfer = adapterDescriptor.MaximumTransferLength;
info.m_pageSize = pageSize;
@@ -89,7 +93,7 @@ namespace AZ::IO
}
}
static void AppendDriveTypeToProfile(HANDLE deviceHandle, DriveInformation& information)
static void AppendDriveTypeToProfile(HANDLE deviceHandle, DriveInformation& information, bool reportHardware)
{
// Check for support for the TRIM command. This command is exclusively used by SSD drives so can be used to
// tell the difference between SSD and HDD. Since these are the only 2 types supported right now, no further
@@ -105,18 +109,24 @@ namespace AZ::IO
&trimDescriptor, sizeof(trimDescriptor), &bytesReturned, nullptr))
{
information.m_profile += trimDescriptor.TrimEnabled ? "_SSD" : "_HDD";
AZ_Printf("Streamer",
" Drive type: %s\n",
trimDescriptor.TrimEnabled ? "SSD" : "HDD");
if (reportHardware)
{
AZ_Printf("Streamer",
" Drive type: %s\n",
trimDescriptor.TrimEnabled ? "SSD" : "HDD");
}
}
else
{
AZ_Printf("Streamer",
" Drive type couldn't be determined.");
if (reportHardware)
{
AZ_Printf("Streamer", " Drive type couldn't be determined.");
}
}
}
static void CollectAlignmentRequirements(HANDLE deviceHandle, DriveInformation& information)
static void CollectAlignmentRequirements(HANDLE deviceHandle, DriveInformation& information, bool reportHardware)
{
STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR alignmentDescriptor{};
STORAGE_PROPERTY_QUERY query{};
@@ -129,15 +139,19 @@ namespace AZ::IO
{
information.m_physicalSectorSize = aznumeric_caster(alignmentDescriptor.BytesPerPhysicalSector);
information.m_logicalSectorSize = aznumeric_caster(alignmentDescriptor.BytesPerLogicalSector);
AZ_Printf("Streamer",
" Physical sector size: %i bytes\n"
" Logical sector size: %i bytes\n",
alignmentDescriptor.BytesPerPhysicalSector,
alignmentDescriptor.BytesPerLogicalSector);
if (reportHardware)
{
AZ_Printf(
"Streamer",
" Physical sector size: %i bytes\n"
" Logical sector size: %i bytes\n",
alignmentDescriptor.BytesPerPhysicalSector,
alignmentDescriptor.BytesPerLogicalSector);
}
}
}
static void CollectDriveInfo(HANDLE deviceHandle, const char* driveName)
static void CollectDriveInfo(HANDLE deviceHandle, const char* driveName, bool reportHardware)
{
STORAGE_DEVICE_DESCRIPTOR sizeRequest{};
STORAGE_PROPERTY_QUERY query{};
@@ -154,21 +168,24 @@ namespace AZ::IO
if (::DeviceIoControl(deviceHandle, IOCTL_STORAGE_QUERY_PROPERTY, &query, sizeof(query),
buffer.get(), header->Size, &bytesReturned, nullptr))
{
auto deviceDescriptor = reinterpret_cast<STORAGE_DEVICE_DESCRIPTOR*>(buffer.get());
AZ_Printf("Streamer",
"Drive info for '%s':\n"
" Id: %s%s%s%s%s\n",
driveName,
deviceDescriptor->VendorIdOffset != 0 ? buffer.get() + deviceDescriptor->VendorIdOffset : "",
deviceDescriptor->VendorIdOffset != 0 ? " " : "",
deviceDescriptor->ProductIdOffset != 0 ? buffer.get() + deviceDescriptor->ProductIdOffset : "",
deviceDescriptor->ProductIdOffset != 0 ? " " : "",
deviceDescriptor->ProductRevisionOffset != 0 ? buffer.get() + deviceDescriptor->ProductRevisionOffset : "");
if (reportHardware)
{
auto deviceDescriptor = reinterpret_cast<STORAGE_DEVICE_DESCRIPTOR*>(buffer.get());
AZ_Printf("Streamer",
"Drive info for '%s':\n"
" Id: %s%s%s%s%s\n",
driveName,
deviceDescriptor->VendorIdOffset != 0 ? buffer.get() + deviceDescriptor->VendorIdOffset : "",
deviceDescriptor->VendorIdOffset != 0 ? " " : "",
deviceDescriptor->ProductIdOffset != 0 ? buffer.get() + deviceDescriptor->ProductIdOffset : "",
deviceDescriptor->ProductIdOffset != 0 ? " " : "",
deviceDescriptor->ProductRevisionOffset != 0 ? buffer.get() + deviceDescriptor->ProductRevisionOffset : "");
}
}
}
}
static void CollectDriveIoCapability(HANDLE deviceHandle, DriveInformation& information)
static void CollectDriveIoCapability(HANDLE deviceHandle, DriveInformation& information, bool reportHardware)
{
STORAGE_DEVICE_IO_CAPABILITY_DESCRIPTOR capabilityDescriptor{};
STORAGE_PROPERTY_QUERY query{};
@@ -180,15 +197,19 @@ namespace AZ::IO
&capabilityDescriptor, sizeof(capabilityDescriptor), &bytesReturned, nullptr))
{
information.m_ioChannelCount = aznumeric_caster(capabilityDescriptor.LunMaxIoCount);
AZ_Printf("Streamer",
" Max IO count (LUN): %i\n"
" Max IO count (Adapter): %i\n",
capabilityDescriptor.LunMaxIoCount,
capabilityDescriptor.AdapterMaxIoCount);
if (reportHardware)
{
AZ_Printf(
"Streamer",
" Max IO count (LUN): %i\n"
" Max IO count (Adapter): %i\n",
capabilityDescriptor.LunMaxIoCount,
capabilityDescriptor.AdapterMaxIoCount);
}
}
}
static void CollectDriveSeekPenalty(HANDLE deviceHandle, DriveInformation& information)
static void CollectDriveSeekPenalty(HANDLE deviceHandle, DriveInformation& information, bool reportHardware)
{
DWORD bytesReturned = 0;
@@ -201,9 +222,12 @@ namespace AZ::IO
&seekPenaltyDescriptor, sizeof(seekPenaltyDescriptor), &bytesReturned, nullptr))
{
information.m_hasSeekPenalty = seekPenaltyDescriptor.IncursSeekPenalty ? true : false;
AZ_Printf("Streamer",
" Has seek penalty: %s\n",
information.m_hasSeekPenalty ? "Yes" : "No");
if (reportHardware)
{
AZ_Printf("Streamer",
" Has seek penalty: %s\n",
information.m_hasSeekPenalty ? "Yes" : "No");
}
}
}
@@ -267,7 +291,7 @@ namespace AZ::IO
return visitor.m_found;
}
static bool CollectHardwareInfo(HardwareInformation& hardwareInfo, bool addAllDrives)
static bool CollectHardwareInfo(HardwareInformation& hardwareInfo, bool addAllDrives, bool reportHardware)
{
char drives[512];
if (::GetLogicalDriveStrings(sizeof(drives) - 1, drives))
@@ -286,7 +310,10 @@ namespace AZ::IO
{
if (!addAllDrives && !IsDriveUsed(driveIt))
{
AZ_Printf("Streamer", "Skipping drive '%s' because to no paths make use of it.\n", driveIt);
if (reportHardware)
{
AZ_Printf("Streamer", "Skipping drive '%s' because to no paths make use of it.\n", driveIt);
}
while (*driveIt++);
continue;
}
@@ -311,14 +338,14 @@ namespace AZ::IO
DriveInformation driveInformation;
driveInformation.m_paths.emplace_back(driveIt);
CollectIoAdaptor(deviceHandle, driveInformation, driveIt);
CollectIoAdaptor(deviceHandle, driveInformation, driveIt, reportHardware);
if (driveInformation.m_supportsQueuing)
{
CollectDriveInfo(deviceHandle, driveIt);
AppendDriveTypeToProfile(deviceHandle, driveInformation);
CollectDriveIoCapability(deviceHandle, driveInformation);
CollectDriveSeekPenalty(deviceHandle, driveInformation);
CollectAlignmentRequirements(deviceHandle, driveInformation);
CollectDriveInfo(deviceHandle, driveIt, reportHardware);
AppendDriveTypeToProfile(deviceHandle, driveInformation, reportHardware);
CollectDriveIoCapability(deviceHandle, driveInformation, reportHardware);
CollectDriveSeekPenalty(deviceHandle, driveInformation, reportHardware);
CollectAlignmentRequirements(deviceHandle, driveInformation, reportHardware);
hardwareInfo.m_maxPhysicalSectorSize =
AZStd::max(hardwareInfo.m_maxPhysicalSectorSize, driveInformation.m_physicalSectorSize);
@@ -329,24 +356,39 @@ namespace AZ::IO
driveMappings.insert({ storageDeviceNumber.DeviceNumber, AZStd::move(driveInformation) });
AZ_Printf("Streamer", "\n");
if (reportHardware)
{
AZ_Printf("Streamer", "\n");
}
}
else
{
AZ_Printf("Streamer", "Skipping drive '%s' because device does not support queuing requests.\n", driveIt);
if (reportHardware)
{
AZ_Printf(
"Streamer", "Skipping drive '%s' because device does not support queuing requests.\n", driveIt);
}
}
}
else
{
AZ_Printf("Streamer", "Drive '%s' is on the same storage drive as '%s'.\n",
driveIt, driveInformationEntry->second.m_paths[0].c_str());
if (reportHardware)
{
AZ_Printf(
"Streamer", "Drive '%s' is on the same storage drive as '%s'.\n",
driveIt, driveInformationEntry->second.m_paths[0].c_str());
}
driveInformationEntry->second.m_paths.emplace_back(driveIt);
}
}
else
{
AZ_Printf("Streamer",
"Skipping drive '%s' because device is not registered with OS as a storage device.\n", driveIt);
if (reportHardware)
{
AZ_Printf(
"Streamer", "Skipping drive '%s' because device is not registered with OS as a storage device.\n",
driveIt);
}
}
::CloseHandle(deviceHandle);
}
@@ -358,7 +400,10 @@ namespace AZ::IO
}
else
{
AZ_Printf("Streamer", "Skipping drive '%s', as it the type of drive is not supported.\n", driveIt);
if (reportHardware)
{
AZ_Printf("Streamer", "Skipping drive '%s', as it the type of drive is not supported.\n", driveIt);
}
}
// Move to next drive string. GetLogicalDriveStrings fills the target buffer with null-terminated strings, for instance
@@ -384,9 +429,9 @@ namespace AZ::IO
}
}
bool CollectIoHardwareInformation(HardwareInformation& info, bool includeAllHardware)
bool CollectIoHardwareInformation(HardwareInformation& info, bool includeAllHardware, bool reportHardware)
{
if (!CollectHardwareInfo(info, includeAllHardware))
if (!CollectHardwareInfo(info, includeAllHardware, reportHardware))
{
// The numbers below are based on common defaults from a local hardware survey.
info.m_maxPageSize = 4096;
@@ -22,20 +22,18 @@ namespace AZ::Utils
::MessageBox(0, message, title, MB_OK | MB_ICONERROR);
}
AZ::IO::FixedMaxPathString GetEngineManifestPath()
AZ::IO::FixedMaxPathString GetO3deManifestDirectory()
{
char userProfileBuffer[AZ::IO::MaxPathLength] = {0};
char userProfileBuffer[AZ::IO::MaxPathLength]{};
size_t variableSize = 0;
auto err = getenv_s(&variableSize, userProfileBuffer, AZ::IO::MaxPathLength, "USERPROFILE");
if (!err)
{
AZ::IO::FixedMaxPath path{userProfileBuffer};
AZ::IO::FixedMaxPath path{ userProfileBuffer };
path /= ".o3de";
path /= "o3de_manifest.json";
return path.Native();
}
return {};
}
} // namespace AZ::Utils
@@ -41,7 +41,7 @@ namespace AZ::Utils
const char* src = [appSupportDir UTF8String];
const size_t srcLen = strlen(src);
if (srcLen > MaxPathLength - 1)
if (srcLen > AZ::IO::MaxPathLength - 1)
{
return AZStd::nullopt;
}
@@ -0,0 +1,218 @@
/*
* 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.
*
*/
#include <AzCore/Math/Transform.h>
#include <AzCore/Math/TransformSerializer.h>
#include <Tests/Serialization/Json/BaseJsonSerializerFixture.h>
#include <Tests/Serialization/Json/JsonSerializerConformityTests.h>
namespace JsonSerializationTests
{
class JsonTransformSerializerTestDescription : public JsonSerializerConformityTestDescriptor<AZ::Transform>
{
public:
AZStd::shared_ptr<AZ::BaseJsonSerializer> CreateSerializer() override
{
return AZStd::make_shared<AZ::JsonTransformSerializer>();
}
AZStd::shared_ptr<AZ::Transform> CreateDefaultInstance() override
{
return AZStd::make_shared<AZ::Transform>(AZ::Transform::CreateIdentity());
}
AZStd::shared_ptr<AZ::Transform> CreatePartialDefaultInstance() override
{
return AZStd::make_shared<AZ::Transform>(AZ::Transform::CreateTranslation(AZ::Vector3(1.0f, 2.0f, 3.0f)));
}
AZStd::string_view GetJsonForPartialDefaultInstance() override
{
return "{ \"Translation\" : [ 1.0, 2.0, 3.0 ] }";
}
AZStd::shared_ptr<AZ::Transform> CreateFullySetInstance() override
{
return AZStd::make_shared<AZ::Transform>(
AZ::Vector3(1.0f, 2.0f, 3.0f), AZ::Quaternion(0.25f, 0.5f, 0.75f, 1.0f), AZ::Vector3(9.0f));
}
AZStd::string_view GetJsonForFullySetInstance() override
{
return "{ \"Translation\" : [ 1.0, 2.0, 3.0 ], \"Rotation\" : [ 0.25, 0.5, 0.75, 1.0 ], \"Scale\" : 9.0 }";
}
void ConfigureFeatures(JsonSerializerConformityTestDescriptorFeatures& features) override
{
features.EnableJsonType(rapidjson::kObjectType);
features.m_supportsPartialInitialization = true;
features.m_supportsInjection = false;
features.m_requiresTypeIdLookups = true;
}
bool AreEqual(const AZ::Transform& lhs, const AZ::Transform& rhs) override
{
return lhs == rhs;
}
};
using JsonTransformSerializerConformityTestTypes = ::testing::Types<JsonTransformSerializerTestDescription>;
INSTANTIATE_TYPED_TEST_CASE_P(JsonTransformSerializer, JsonSerializerConformityTests, JsonTransformSerializerConformityTestTypes);
class JsonTransformSerializerTests
: public BaseJsonSerializerFixture
{
public:
void SetUp() override
{
BaseJsonSerializerFixture::SetUp();
m_transformSerializer = AZStd::make_unique<AZ::JsonTransformSerializer>();
}
void TearDown() override
{
m_transformSerializer.reset();
BaseJsonSerializerFixture::TearDown();
}
protected:
AZStd::unique_ptr<AZ::JsonTransformSerializer> m_transformSerializer;
};
TEST_F(JsonTransformSerializerTests, Load_FullySetTransform_ReturnsSuccessWithAllValuesSetCorrectly)
{
AZ::Transform testTransform = AZ::Transform::CreateIdentity();
AZ::Transform expectedTransform(
AZ::Vector3(2.25f, 3.5f, 4.75f),
AZ::Quaternion(0.25f, 0.5f, 0.75f, 1.0f),
AZ::Vector3(5.5f));
rapidjson::Document json;
json.Parse(R"({ "Translation": [ 2.25, 3.5, 4.75 ], "Rotation": [ 0.25, 0.5, 0.75, 1.0 ], "Scale": 5.5 })");
ResultCode result =
m_transformSerializer->Load(&testTransform, azrtti_typeid<decltype(testTransform)>(), json, *m_jsonDeserializationContext);
EXPECT_EQ(result.GetOutcome(), AZ::JsonSerializationResult::Outcomes::Success);
EXPECT_EQ(testTransform, expectedTransform);
}
TEST_F(JsonTransformSerializerTests, Load_FullySetTransform_ReturnsSuccessWithDefaultTranslation)
{
AZ::Transform testTransform = AZ::Transform::CreateIdentity();
AZ::Transform expectedTransform =
AZ::Transform::CreateFromQuaternion(AZ::Quaternion(0.25f, 0.5f, 0.75f, 1.0f));
expectedTransform.SetScale(AZ::Vector3(5.5f));
rapidjson::Document json;
json.Parse(R"({ "Rotation": [ 0.25, 0.5, 0.75, 1.0 ], "Scale": 5.5 })");
ResultCode result =
m_transformSerializer->Load(&testTransform, azrtti_typeid<decltype(testTransform)>(), json, *m_jsonDeserializationContext);
EXPECT_EQ(result.GetOutcome(), AZ::JsonSerializationResult::Outcomes::PartialDefaults);
EXPECT_EQ(testTransform, expectedTransform);
}
TEST_F(JsonTransformSerializerTests, Load_FullySetTransform_ReturnsSuccessWithDefaultRotation)
{
AZ::Transform testTransform = AZ::Transform::CreateIdentity();
AZ::Transform expectedTransform = AZ::Transform::CreateTranslation(AZ::Vector3(2.25f, 3.5f, 4.75f));
expectedTransform.SetScale(AZ::Vector3(5.5f));
rapidjson::Document json;
json.Parse(R"({ "Translation": [ 2.25, 3.5, 4.75 ], "Scale": 5.5 })");
ResultCode result =
m_transformSerializer->Load(&testTransform, azrtti_typeid<decltype(testTransform)>(), json, *m_jsonDeserializationContext);
EXPECT_EQ(result.GetOutcome(), AZ::JsonSerializationResult::Outcomes::PartialDefaults);
EXPECT_EQ(testTransform, expectedTransform);
}
TEST_F(JsonTransformSerializerTests, Load_FullySetTransform_ReturnsSuccessWithDefaultScale)
{
AZ::Transform testTransform = AZ::Transform::CreateIdentity();
AZ::Transform expectedTransform =
AZ::Transform::CreateFromQuaternionAndTranslation(AZ::Quaternion(0.25f, 0.5f, 0.75f, 1.0f), AZ::Vector3(2.25f, 3.5f, 4.75f));
rapidjson::Document json;
json.Parse(R"({ "Translation": [ 2.25, 3.5, 4.75 ], "Rotation": [ 0.25, 0.5, 0.75, 1.0 ] })");
ResultCode result =
m_transformSerializer->Load(&testTransform, azrtti_typeid<decltype(testTransform)>(), json, *m_jsonDeserializationContext);
EXPECT_EQ(result.GetOutcome(), AZ::JsonSerializationResult::Outcomes::PartialDefaults);
EXPECT_EQ(testTransform, expectedTransform);
}
TEST_F(JsonTransformSerializerTests, Load_FullySetTransform_ReturnsSuccessWithOnlyTranslation)
{
AZ::Transform testTransform = AZ::Transform::CreateIdentity();
AZ::Transform expectedTransform = AZ::Transform::CreateTranslation(AZ::Vector3(2.25f, 3.5f, 4.75f));
rapidjson::Document json;
json.Parse(R"({ "Translation": [ 2.25, 3.5, 4.75 ] })");
ResultCode result =
m_transformSerializer->Load(&testTransform, azrtti_typeid<decltype(testTransform)>(), json, *m_jsonDeserializationContext);
EXPECT_EQ(result.GetOutcome(), AZ::JsonSerializationResult::Outcomes::PartialDefaults);
EXPECT_EQ(testTransform, expectedTransform);
}
TEST_F(JsonTransformSerializerTests, Load_FullySetTransform_ReturnsSuccessWithOnlyRotation)
{
AZ::Transform testTransform = AZ::Transform::CreateIdentity();
AZ::Transform expectedTransform = AZ::Transform::CreateFromQuaternion(AZ::Quaternion(0.25f, 0.5f, 0.75f, 1.0f));
rapidjson::Document json;
json.Parse(R"({ "Rotation": [ 0.25, 0.5, 0.75, 1.0 ] })");
ResultCode result =
m_transformSerializer->Load(&testTransform, azrtti_typeid<decltype(testTransform)>(), json, *m_jsonDeserializationContext);
EXPECT_EQ(result.GetOutcome(), AZ::JsonSerializationResult::Outcomes::PartialDefaults);
EXPECT_EQ(testTransform, expectedTransform);
}
TEST_F(JsonTransformSerializerTests, Load_FullySetTransform_ReturnsSuccessWithOnlyScale)
{
AZ::Transform testTransform = AZ::Transform::CreateIdentity();
AZ::Transform expectedTransform = AZ::Transform::CreateScale(AZ::Vector3(5.5f));
rapidjson::Document json;
json.Parse(R"({ "Scale" : 5.5 })");
ResultCode result =
m_transformSerializer->Load(&testTransform, azrtti_typeid<decltype(testTransform)>(), json, *m_jsonDeserializationContext);
EXPECT_EQ(result.GetOutcome(), AZ::JsonSerializationResult::Outcomes::PartialDefaults);
EXPECT_EQ(testTransform, expectedTransform);
}
TEST_F(JsonTransformSerializerTests, Load_FullySetTransform_ReturnsSuccessWithAllDefaults)
{
AZ::Transform testTransform = AZ::Transform::CreateIdentity();
AZ::Transform expectedTransform = AZ::Transform::CreateIdentity();
rapidjson::Document json;
json.Parse(R"({})");
ResultCode result =
m_transformSerializer->Load(&testTransform, azrtti_typeid<decltype(testTransform)>(), json, *m_jsonDeserializationContext);
EXPECT_EQ(result.GetOutcome(), AZ::JsonSerializationResult::Outcomes::DefaultsUsed);
EXPECT_EQ(testTransform, expectedTransform);
}
} // namespace JsonSerializationTests
@@ -123,6 +123,7 @@ set(FILES
Serialization/Json/TestCases_Pointers.h
Serialization/Json/TestCases_Pointers.cpp
Serialization/Json/TestCases_TypeId.cpp
Serialization/Json/TransformSerializerTests.cpp
Serialization/Json/TupleSerializerTests.cpp
Serialization/Json/UnorderedSetSerializerTests.cpp
Serialization/Json/UuidSerializerTests.cpp
@@ -93,8 +93,8 @@ namespace AzFramework
/// Execute a function in a new thread and pump the system event loop at the specified frequency until the thread returns.
virtual void PumpSystemEventLoopWhileDoingWorkInNewThread(const AZStd::chrono::milliseconds& /*eventPumpFrequency*/,
const AZStd::function<void()>& /*workForNewThread*/,
const char* /*newThreadName*/) {}
const AZStd::function<void()>& /*workForNewThread*/,
const char* /*newThreadName*/) {}
/// Run the main loop until ExitMainLoop is called.
virtual void RunMainLoop() {}
@@ -114,6 +114,21 @@ namespace AzFramework
/// Calculate the branch token from the current application's engine root
virtual void CalculateBranchTokenForEngineRoot(AZStd::string& token) const = 0;
/// Returns true if Prefab System is enabled, false if Legacy Slice System is enabled
virtual bool IsPrefabSystemEnabled() const { return true; }
/// Returns true if the additional work in progress Prefab features are enabled, false otherwise
virtual bool ArePrefabWipFeaturesEnabled() const { return false; }
/// Sets whether or not the Prefab System should be enabled. The application will need to be restarted when this changes
virtual void SetPrefabSystemEnabled([[maybe_unused]] bool enable) {}
/// Returns true if Prefab System is enabled for use with levels, false if legacy level system is enabled (level.pak)
virtual bool IsPrefabSystemForLevelsEnabled() const { return false; }
/// Returns true if code should assert when the Legacy Slice System is used
virtual bool ShouldAssertForLegacySlicesUsage() const { return false; }
/*!
* Returns a Type Uuid of the component for the given componentId and entityId.
* if no component matches the entity and component Id pair, a Null Uuid is returned
@@ -89,6 +89,10 @@ namespace AzFramework
{
namespace ApplicationInternal
{
static constexpr const char s_prefabSystemKey[] = "/Amazon/Preferences/EnablePrefabSystem";
static constexpr const char s_prefabWipSystemKey[] = "/Amazon/Preferences/EnablePrefabSystemWipFeatures";
static constexpr const char s_legacySlicesAssertKey[] = "/Amazon/Preferences/ShouldAssertForLegacySlicesUsage";
// A Helper function that can load an app descriptor from file.
AZ::Outcome<AZStd::unique_ptr<AZ::ComponentApplication::Descriptor>, AZStd::string> LoadDescriptorFromFilePath(const char* appDescriptorFilePath, AZ::SerializeContext& serializeContext)
{
@@ -411,9 +415,10 @@ namespace AzFramework
// UserSettingsFileLocatorBus
AZStd::string Application::ResolveFilePath([[maybe_unused]] AZ::u32 providerId)
{
AZStd::string result;
AzFramework::StringFunc::Path::Join(GetEngineRoot(), "UserSettings.xml", result, /*bCaseInsenitive*/false);
return result;
AZ::IO::Path userSettingsPath;
m_settingsRegistry->Get(userSettingsPath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_ProjectUserPath);
userSettingsPath /= "UserSettings.xml";
return userSettingsPath.Native();
}
AZ::Component* Application::EnsureComponentAdded(AZ::Entity* systemEntity, const AZ::Uuid& typeId)
@@ -779,4 +784,47 @@ namespace AzFramework
}
}
bool Application::IsPrefabSystemEnabled() const
{
bool value = true;
if (auto* registry = AZ::SettingsRegistry::Get())
{
registry->Get(value, ApplicationInternal::s_prefabSystemKey);
}
return value;
}
bool Application::ArePrefabWipFeaturesEnabled() const
{
bool value = false;
if (auto* registry = AZ::SettingsRegistry::Get())
{
registry->Get(value, ApplicationInternal::s_prefabWipSystemKey);
}
return value;
}
void Application::SetPrefabSystemEnabled(bool enable)
{
if (auto* registry = AZ::SettingsRegistry::Get())
{
registry->Set(ApplicationInternal::s_prefabSystemKey, enable);
}
}
bool Application::IsPrefabSystemForLevelsEnabled() const
{
return IsPrefabSystemEnabled();
}
bool Application::ShouldAssertForLegacySlicesUsage() const
{
bool value = false;
if (auto* registry = AZ::SettingsRegistry::Get())
{
registry->Get(value, ApplicationInternal::s_legacySlicesAssertKey);
}
return value;
}
} // namespace AzFramework
@@ -104,6 +104,11 @@ namespace AzFramework
const char* GetAppRoot() const override;
void ResolveEnginePath(AZStd::string& engineRelativePath) const override;
void CalculateBranchTokenForEngineRoot(AZStd::string& token) const override;
bool IsPrefabSystemEnabled() const override;
bool ArePrefabWipFeaturesEnabled() const override;
void SetPrefabSystemEnabled(bool enable) override;
bool IsPrefabSystemForLevelsEnabled() const override;
bool ShouldAssertForLegacySlicesUsage() const override;
#pragma push_macro("GetCommandLine")
#undef GetCommandLine
@@ -31,6 +31,7 @@
#include <AzCore/std/sort.h>
#include <AzCore/StringFunc/StringFunc.h>
#include <AzFramework/API/ApplicationAPI.h>
#include <AzFramework/Asset/AssetBundleManifest.h>
#include <AzFramework/Asset/AssetRegistry.h>
#include <AzFramework/IO/FileOperations.h>
@@ -1506,35 +1507,48 @@ namespace AZ::IO
auto bundleManifest = GetBundleManifest(desc.pZip);
AZStd::shared_ptr<AzFramework::AssetRegistry> bundleCatalog;
AZStd::vector<AZStd::string> levelDirs;
if (bundleManifest)
{
bundleCatalog = GetBundleCatalog(desc.pZip, bundleManifest->GetCatalogName());
}
if (addLevels)
{
// Note that manifest version two and above will contain level directory information inside them
// otherwise we will fallback to scanning the archive for levels.
if (bundleManifest && bundleManifest->GetBundleVersion() >= 2)
{
bool usePrefabSystemForLevels = false;
AzFramework::ApplicationRequests::Bus::BroadcastResult(
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
levelDirs = bundleManifest->GetLevelDirectories();
}
else
if (usePrefabSystemForLevels)
{
m_arrZips.insert(revItZip.base(), desc);
}
else
{
// [LYN-2376] Remove once legacy slice support is removed
AZStd::vector<AZStd::string> levelDirs;
if (addLevels)
{
levelDirs = ScanForLevels(desc.pZip);
// Note that manifest version two and above will contain level directory information inside them
// otherwise we will fallback to scanning the archive for levels.
if (bundleManifest && bundleManifest->GetBundleVersion() >= 2)
{
levelDirs = bundleManifest->GetLevelDirectories();
}
else
{
levelDirs = ScanForLevels(desc.pZip);
}
}
if (!levelDirs.empty())
{
desc.m_containsLevelPak = true;
}
m_arrZips.insert(revItZip.base(), desc);
m_levelOpenEvent.Signal(levelDirs);
}
if (!levelDirs.empty())
{
desc.m_containsLevelPak = true;
}
m_arrZips.insert(revItZip.base(), desc);
m_levelOpenEvent.Signal(levelDirs);
AZ::IO::ArchiveNotificationBus::Broadcast([](AZ::IO::ArchiveNotifications* archiveNotifications, const char* bundleName,
AZStd::shared_ptr<AzFramework::AssetBundleManifest> bundleManifest, const char* nextBundle, AZStd::shared_ptr<AzFramework::AssetRegistry> bundleCatalog)
{
@@ -1555,10 +1569,13 @@ namespace AZ::IO
return false;
}
bool usePrefabSystemForLevels = false;
AzFramework::ApplicationRequests::Bus::BroadcastResult(
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
AZStd::unique_lock lock(m_csZips);
for (auto it = m_arrZips.begin(); it != m_arrZips.end();)
{
bool needRescan = false;
if (azstricmp(szZipPath->c_str(), it->GetFullPath()) == 0)
{
// this is the pack with the given name - remove it, and if possible it will be deleted
@@ -1571,16 +1588,25 @@ namespace AZ::IO
archiveNotifications->BundleClosed(bundleName);
}, it->GetFullPath());
if (it->m_containsLevelPak)
if (usePrefabSystemForLevels)
{
needRescan = true;
it = m_arrZips.erase(it);
}
it = m_arrZips.erase(it);
if (needRescan)
else
{
m_levelCloseEvent.Signal(szZipPath->Native());
// [LYN-2376] Remove once legacy slice support is removed
bool needRescan = false;
if (it->m_containsLevelPak)
{
needRescan = true;
}
it = m_arrZips.erase(it);
if (needRescan)
{
m_levelCloseEvent.Signal(szZipPath->Native());
}
}
}
else
@@ -120,6 +120,8 @@ namespace AZ::IO
{
AZ::IO::Path m_pathBindRoot; // the zip binding root
AZStd::string strFileName; // the zip file name (with path) - very useful for debugging so please don't remove
// [LYN-2376] Remove once legacy slice support is removed
bool m_containsLevelPak = false; // indicates whether this archive has level.pak inside it or not
const char* GetFullPath() const { return pZip->GetFilePath(); }
@@ -199,6 +201,7 @@ namespace AZ::IO
bool IsInstalledToHDD(AZStd::string_view acFilePath = 0) const override;
// [LYN-2376] Remove 'addLevels' parameter once legacy slice support is removed
bool OpenPack(AZStd::string_view pName, uint32_t nFlags = 0, AZStd::intrusive_ptr<AZ::IO::MemoryBlock> pData = nullptr, AZ::IO::FixedMaxPathString* pFullPath = nullptr, bool addLevels = true) override;
bool OpenPack(AZStd::string_view szBindRoot, AZStd::string_view pName, uint32_t nFlags = 0, AZStd::intrusive_ptr<AZ::IO::MemoryBlock> pData = nullptr, AZ::IO::FixedMaxPathString* pFullPath = nullptr, bool addLevels = true) override;
// after this call, the file will be unlocked and closed, and its contents won't be used to search for files
@@ -300,7 +303,8 @@ namespace AZ::IO
EStreamSourceMediaType GetFileMediaType(AZStd::string_view szName) const override;
auto GetLevelPackOpenEvent()->LevelPackOpenEvent* override;
// [LYN-2376] Remove once legacy slice support is removed
auto GetLevelPackOpenEvent() -> LevelPackOpenEvent* override;
auto GetLevelPackCloseEvent()->LevelPackCloseEvent* override;
@@ -336,6 +340,8 @@ namespace AZ::IO
//! Return the Manifest from a bundle, if it exists
AZStd::shared_ptr<AzFramework::AssetBundleManifest> GetBundleManifest(ZipDir::CachePtr pZip);
AZStd::shared_ptr<AzFramework::AssetRegistry> GetBundleCatalog(ZipDir::CachePtr pZip, const AZStd::string& catalogName);
// [LYN-2376] Remove once legacy slice support is removed
AZStd::vector<AZStd::string> ScanForLevels(ZipDir::CachePtr pZip);
mutable AZStd::shared_mutex m_csOpenFiles;
@@ -362,6 +368,8 @@ namespace AZ::IO
RecordedFilesSet m_recordedFilesSet;
AZStd::intrusive_ptr<IResourceList> m_pEngineStartupResourceList;
// [LYN-2376] Remove once legacy slice support is removed
AZStd::intrusive_ptr<IResourceList> m_pLevelResourceList;
AZStd::intrusive_ptr<IResourceList> m_pNextLevelResourceList;
@@ -378,6 +386,8 @@ namespace AZ::IO
AZStd::fixed_string<128> m_sLocalizationRoot;
AZStd::set<uint32_t, AZStd::less<>, AZ::OSStdAllocator> m_filesCachedOnHDD;
// [LYN-2376] Remove once legacy slice support is removed
LevelPackOpenEvent m_levelOpenEvent;
LevelPackCloseEvent m_levelCloseEvent;
};
@@ -17,17 +17,28 @@
#include <AzFramework/Archive/ArchiveVars.h>
#include <AzFramework/Archive/ZipDirFind.h>
namespace AZ::IO
{
bool AZStdStringLessCaseInsensitive::operator()(AZStd::string_view left, AZStd::string_view right) const
{
// If one or both strings are 0-length, return true if the left side is smaller, false if they're equal or left is larger.
size_t compareLength = (AZStd::min)(left.size(), right.size());
if (compareLength == 0)
{
return left.size() < right.size();
}
// They're both non-zero, so compare the strings up until the length of the shorter string.
int compareResult = azstrnicmp(left.data(), right.data(), compareLength);
// If both strings are equal for the number of characters compared, return true if the left side is shorter, false if
// they're equal or left is longer.
if (compareResult == 0)
{
return left.size() < right.size();
}
// Return true if the left side should come first alphabetically, false if the right side should.
return compareResult < 0;
}
@@ -124,7 +135,8 @@ namespace AZ::IO
fileDesc.tAccess = fileDesc.tWrite;
fileDesc.tCreate = fileDesc.tWrite;
}
m_mapFiles.emplace(AZStd::move(fullFilePath), fileDesc);
[[maybe_unused]] auto result = m_mapFiles.emplace(AZStd::move(fullFilePath), fileDesc);
AZ_Assert(result.second, "Failed to insert FindData entry for %s", fullFilePath.c_str());
return true;
});
@@ -16,6 +16,7 @@
namespace Camera
{
//! Stores camera configuration values that describe the camera's view frustum.
struct Configuration
{
float m_fovRadians = 0.f;
@@ -25,114 +26,83 @@ namespace Camera
float m_frustumHeight = 0.f;
};
/**
* Use this bus to send messages to a camera component on an entity
* If you create your own camera you should implement this bus
* Call like this:
* Camera::CameraRequestBus::Event(cameraEntityId, &Camera::CameraRequestBus::Events::SetFov, newFov);
*/
//! Use this bus to send messages to a camera component on an entity
//! If you create your own camera you should implement this bus
//! Call like this:
//! Camera::CameraRequestBus::Event(cameraEntityId, &Camera::CameraRequestBus::Events::SetFov, newFov);
class CameraComponentRequests
: public AZ::ComponentBus
{
public:
virtual ~CameraComponentRequests() = default;
/**
* Gets the camera's field of view in degrees
* @return The camera's field of view in degrees
*/
//! Gets the camera's field of view in degrees
//! @return The camera's field of view in degrees
virtual float GetFov()
{
AZ_WarningOnce("CameraBus", false, "GetFov is deprecated. Please use GetFovDegrees or GetFovRadians.");
return GetFovDegrees();
}
/**
* Gets the camera's field of view in degrees
* @return The camera's field of view in degrees
*/
//! Gets the camera's field of view in degrees
//! @return The camera's field of view in degrees
virtual float GetFovDegrees() = 0;
/**
* Gets the camera's field of view in radians
* @return The camera's field of view in radians
*/
//! Gets the camera's field of view in radians
//! @return The camera's field of view in radians
virtual float GetFovRadians() = 0;
/**
* Gets the camera's distance from the near clip plane in meters
* @return The camera's distance from the near clip plane in meters
*/
//! Gets the camera's distance from the near clip plane in meters
//! @return The camera's distance from the near clip plane in meters
virtual float GetNearClipDistance() = 0;
/**
* Gets the camera's distance from the far clip plane in meters
* @return The camera's distance from the far clip plane in meters
*/
//! Gets the camera's distance from the far clip plane in meters
//! @return The camera's distance from the far clip plane in meters
virtual float GetFarClipDistance() = 0;
/**
* Gets the camera frustum's width
* @return The camera frustum's width
*/
//! Gets the camera frustum's width
//! @return The camera frustum's width
virtual float GetFrustumWidth() = 0;
/**
* Gets the camera frustum's height
* @return The camera frustum's height
*/
//! Gets the camera frustum's height
//! @return The camera frustum's height
virtual float GetFrustumHeight() = 0;
/**
* Sets the camera's field of view in degrees between 0 < fov < 180 degrees
* @param fov The camera frustum's new field of view in degrees
*/
//! Sets the camera's field of view in degrees between 0 < fov < 180 degrees
//! @param fov The camera frustum's new field of view in degrees
virtual void SetFov(float fov)
{
AZ_WarningOnce("CameraBus", false, "SetFov is deprecated. Please use SetFovDegrees or SetFovRadians.");
SetFovDegrees(fov);
}
/**
* Sets the camera's field of view in degrees between 0 < fov < 180 degrees
* @param fov The camera frustum's new field of view in degrees
*/
//! Sets the camera's field of view in degrees between 0 < fov < 180 degrees
//! @param fov The camera frustum's new field of view in degrees
virtual void SetFovDegrees(float fovInDegrees) = 0;
/**
* Sets the camera's field of view in radians between 0 < fov < pi radians
* @param fov The camera frustum's new field of view in radians
*/
//! Sets the camera's field of view in radians between 0 < fov < pi radians
//! @param fov The camera frustum's new field of view in radians
virtual void SetFovRadians(float fovInRadians) = 0;
/**
* Sets the near clip plane to a given distance from the camera in meters. Should be small, but greater than 0
* @param nearClipDistance The camera frustum's new near clip plane distance from camera
*/
//! Sets the near clip plane to a given distance from the camera in meters. Should be small, but greater than 0
//! @param nearClipDistance The camera frustum's new near clip plane distance from camera
virtual void SetNearClipDistance(float nearClipDistance) = 0;
/**
* Sets the far clip plane to a given distance from the camera in meters.
* @param farClipDistance The camera frustum's new far clip plane distance from camera
*/
//! Sets the far clip plane to a given distance from the camera in meters.
//! @param farClipDistance The camera frustum's new far clip plane distance from camera
virtual void SetFarClipDistance(float farClipDistance) = 0;
/**
* Sets the camera frustum's width
* @param width The camera frustum's new width
*/
//! Sets the camera frustum's width
//! @param width The camera frustum's new width
virtual void SetFrustumWidth(float width) = 0;
/**
* Sets the camera frustum's height
* @param height The camera frustum's new height
*/
//! Sets the camera frustum's height
//! @param height The camera frustum's new height
virtual void SetFrustumHeight(float height) = 0;
/**
* Makes the camera the active view
*/
//! Makes the camera the active view
virtual void MakeActiveView() = 0;
//! Get the camera frustum's aggregate configuration
virtual Configuration GetCameraConfiguration()
{
return Configuration
@@ -147,14 +117,11 @@ namespace Camera
};
using CameraRequestBus = AZ::EBus<CameraComponentRequests>;
/**
* Use this broadcast bus to gather a list of all active cameras
* If you create your own camera you should handle this bus
* Call like this:
*
* AZ::EBusAggregateResults<AZ::EntityId> results;
* Camera::CameraBus::BroadcastResult(results, &Camera::CameraRequests::GetCameras);
*/
//! Use this broadcast bus to gather a list of all active cameras
//! If you create your own camera you should handle this bus
//! Call like this:
//! AZ::EBusAggregateResults<AZ::EntityId> results;
//! Camera::CameraBus::BroadcastResult(results, &Camera::CameraRequests::GetCameras);
class CameraRequests
: public AZ::EBusTraits
{
@@ -166,18 +133,14 @@ namespace Camera
};
using CameraBus = AZ::EBus<CameraRequests>;
/**
* Use this system broadcast for things like getting the active camera
*/
//! Use this system broadcast for things like getting the active camera
class CameraSystemRequests
: public AZ::EBusTraits
{
public:
virtual ~CameraSystemRequests() = default;
/**
* returns the camera being used by the active view
*/
//! returns the camera being used by the active view
virtual AZ::EntityId GetActiveCamera() = 0;
};
using CameraSystemRequestBus = AZ::EBus<CameraSystemRequests>;
@@ -198,13 +161,11 @@ namespace Camera
};
using ActiveCameraRequestBus = AZ::EBus<ActiveCameraRequests>;
/**
* Handle this bus if you want to know when cameras are added or removed during edit or run time
* You will get an OnCameraAdded event for each camera that is already active
* If you create your own camera you should call this bus on activation/deactivation
* Connect to the bus like this
* Camera::CameraNotificationBus::Handler::Connect()
*/
//! Handle this bus if you want to know when cameras are added or removed during edit or run time
//! You will get an OnCameraAdded event for each camera that is already active
//! If you create your own camera you should call this bus on activation/deactivation
//! Connect to the bus like this
//! Camera::CameraNotificationBus::Handler::Connect()
class CameraNotifications
: public AZ::EBusTraits
{
@@ -223,28 +184,33 @@ namespace Camera
{
handler->OnCameraAdded(cameraId);
}
AZ::EntityId activeView;
CameraSystemRequestBus::BroadcastResult(activeView, &CameraSystemRequestBus::Events::GetActiveCamera);
if (activeView.IsValid())
{
handler->OnActiveViewChanged(activeView);
}
}
};
/**
* If the camera is active when a handler connects to the bus,
* then OnCameraAdded() is immediately dispatched.
*/
//! If the camera is active when a handler connects to the bus,
//! then OnCameraAdded() is immediately dispatched.
template<class Bus>
using ConnectionPolicy = CameraNotificationConnectionPolicy<Bus>;
virtual ~CameraNotifications() = default;
/**
* Called whenever a camera entity is added
* @param cameraId The id of the camera added
*/
virtual void OnCameraAdded(const AZ::EntityId& cameraId) = 0;
//! Called whenever a camera entity is added
//! @param cameraId The id of the camera added
virtual void OnCameraAdded(const AZ::EntityId& /*cameraId*/) {}
/**
* Called whenever a camera entity is removed
* @param cameraId The id of the camera removed
*/
virtual void OnCameraRemoved(const AZ::EntityId& cameraId) = 0;
//! Called whenever a camera entity is removed
//! @param cameraId The id of the camera removed
virtual void OnCameraRemoved(const AZ::EntityId& /*cameraId*/) {}
//! Called whenever the active camera entity changes
//! @param cameraId The id of the newly activated camera
virtual void OnActiveViewChanged(const AZ::EntityId&) {}
};
using CameraNotificationBus = AZ::EBus<CameraNotifications>;
@@ -44,10 +44,7 @@ namespace AzFramework
incompatible.push_back(AZ_CRC_CE("LookAtService"));
incompatible.push_back(AZ_CRC_CE("SequenceService"));
incompatible.push_back(AZ_CRC_CE("ClothMeshService"));
incompatible.push_back(AZ_CRC_CE("PhysXColliderService"));
incompatible.push_back(AZ_CRC_CE("PhysXTriggerService"));
incompatible.push_back(AZ_CRC_CE("PhysXJointService"));
incompatible.push_back(AZ_CRC_CE("PhysXShapeColliderService"));
incompatible.push_back(AZ_CRC_CE("PhysXCharacterControllerService"));
incompatible.push_back(AZ_CRC_CE("PhysXRagdollService"));
incompatible.push_back(AZ_CRC_CE("WhiteBoxService"));
@@ -1,47 +0,0 @@
/*
* 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.
*
*/
#include <AzFramework/Engine/Engine.h>
#include <AzCore/IO/SystemFile.h>
#include <AzCore/Utils/Utils.h>
namespace AzFramework
{
namespace Engine
{
AZ::IO::FixedMaxPath FindEngineRoot(AZStd::string_view searchPath)
{
// File to locate
const char engineRootMarker[] = "engine.json";
AZ::IO::FixedMaxPath currentSearchPath{searchPath};
if (currentSearchPath.empty())
{
char executablePath[AZ_MAX_PATH_LEN];
AZ::Utils::GetExecutablePathReturnType result = AZ::Utils::GetExecutablePath(executablePath, AZ_MAX_PATH_LEN);
currentSearchPath = executablePath;
}
do
{
currentSearchPath = currentSearchPath.ParentPath();
if (AZ::IO::SystemFile::Exists((currentSearchPath / engineRootMarker).c_str()))
{
return currentSearchPath;
}
} while (currentSearchPath.ParentPath() != currentSearchPath);
return {};
}
}
} // AzFramework
@@ -100,9 +100,9 @@ namespace AzFramework
//! @param idRemapTable if remapIds is true, the provided table is filled with a map of original ids to new ids
//! @param filterDesc any ObjectStream::LoadFlags
//! @return whether or not the root slice was successfully loaded from the provided stream
virtual bool LoadFromStream(AZ::IO::GenericStream& stream, bool remapIds,
bool LoadFromStream(AZ::IO::GenericStream& stream, bool remapIds,
EntityIdToEntityIdMap* idRemapTable = nullptr,
const AZ::ObjectStream::FilterDescriptor& filterDesc = AZ::ObjectStream::FilterDescriptor());
const AZ::ObjectStream::FilterDescriptor& filterDesc = AZ::ObjectStream::FilterDescriptor()) override;
//! Executes the post-add actions for the provided list of entities, like connecting to required ebuses.
//! @param entities The entities to perform the post-add actions for.
@@ -1,127 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates, or
* a third party where indicated.
*
* 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.
*
*/
#include <AzFramework/Physics/World.h>
#include <AzFramework/Physics/ShapeConfiguration.h>
#include <AzFramework/Physics/Casts.h>
#include <AzFramework/Physics/CollisionBus.h>
#include <AzFramework/Physics/Configuration/CollisionConfiguration.h>
#include <AzCore/RTTI/BehaviorContext.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/std/sort.h>
#include <AzCore/Interface/Interface.h>
namespace Physics
{
/// This structure is used only for reflecting type vector<RayCastHit> to
/// serialize and behavior context. It's not used in the API anywhere
struct RaycastHitArray
{
AZ_TYPE_INFO(RaycastHitArray, "{BAFCC4E7-A06B-4909-B2AE-C89D9E84FE4E}");
AZStd::vector<Physics::RayCastHit> m_hitArray;
};
AZStd::vector<AZStd::pair<AzPhysics::CollisionGroup, AZStd::string>> PopulateCollisionGroups()
{
AZStd::vector<AZStd::pair<AzPhysics::CollisionGroup, AZStd::string>> elems;
const AzPhysics::CollisionConfiguration& configuration = AZ::Interface<Physics::CollisionRequests>::Get()->GetCollisionConfiguration();
for (const AzPhysics::CollisionGroups::Preset& preset : configuration.m_collisionGroups.GetPresets())
{
elems.push_back({ AzPhysics::CollisionGroup(preset.m_name), preset.m_name });
}
return elems;
}
void RayCastHit::Reflect(AZ::ReflectContext* context)
{
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
{
serializeContext->Class<RayCastRequest>()
->Field("Distance", &RayCastRequest::m_distance)
->Field("Start", &RayCastRequest::m_start)
->Field("Direction", &RayCastRequest::m_direction)
->Field("Collision", &RayCastRequest::m_collisionGroup)
->Field("QueryType", &RayCastRequest::m_queryType)
->Field("MaxResults", &RayCastRequest::m_maxResults)
;
serializeContext->Class<RayCastHit>()
->Field("Distance", &RayCastHit::m_distance)
->Field("Position", &RayCastHit::m_position)
->Field("Normal", &RayCastHit::m_normal)
;
serializeContext->Class<RaycastHitArray>()
->Field("HitArray", &RaycastHitArray::m_hitArray)
;
if (auto editContext = azrtti_cast<AZ::EditContext*>(serializeContext->GetEditContext()))
{
editContext->Enum<QueryType>("Query Type", "Object types to include in the query")
->Value("Static", QueryType::Static)
->Value("Dynamic", QueryType::Dynamic)
->Value("Static and Dynamic", QueryType::StaticAndDynamic)
;
editContext->Class<RayCastRequest>("RayCast Request", "Parameters for raycast")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
->DataElement(AZ::Edit::UIHandlers::Default, &RayCastRequest::m_start, "Start", "Start position of the raycast")
->DataElement(AZ::Edit::UIHandlers::Default, &RayCastRequest::m_distance, "Distance", "Length of the raycast")
->DataElement(AZ::Edit::UIHandlers::Default, &RayCastRequest::m_direction, "Direction", "Direction of the raycast")
->DataElement(AZ::Edit::UIHandlers::ComboBox, &RayCastRequest::m_collisionGroup, "Collision Group", "The layers to include in the query")
->Attribute(AZ::Edit::Attributes::EnumValues, &PopulateCollisionGroups)
->DataElement(AZ::Edit::UIHandlers::ComboBox, &RayCastRequest::m_queryType, "Query Type", "Object types to include in the query")
->DataElement(AZ::Edit::UIHandlers::Default, &RayCastRequest::m_maxResults, "Max results", "The Maximum results for this request to return, this is limited by the value set in WorldConfiguration")
;
}
}
if (auto behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
{
behaviorContext->Class<RayCastRequest>("RayCastRequest")
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
->Attribute(AZ::Script::Attributes::Module, "physics")
->Attribute(AZ::Script::Attributes::Category, "PhysX")
->Property("Distance", BehaviorValueProperty(&RayCastRequest::m_distance))
->Property("Start", BehaviorValueProperty(&RayCastRequest::m_start))
->Property("Direction", BehaviorValueProperty(&RayCastRequest::m_direction))
->Property("Collision", BehaviorValueProperty(&RayCastRequest::m_collisionGroup))
// Until enum class support for behavior context is done, expose this as an int
->Property("QueryType", [](const RayCastRequest& self) { return static_cast<int>(self.m_queryType); },
[](RayCastRequest& self, int newQueryType) { self.m_queryType = QueryType(newQueryType); })
->Property("MaxResults", BehaviorValueProperty(&RayCastRequest::m_maxResults))
;
behaviorContext->Class<RayCastHit>("RayCastHit")
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
->Attribute(AZ::Script::Attributes::Module, "physics")
->Attribute(AZ::Script::Attributes::Category, "PhysX")
->Property("Distance", BehaviorValueProperty(&RayCastHit::m_distance))
->Property("Position", BehaviorValueProperty(&RayCastHit::m_position))
->Property("Normal", BehaviorValueProperty(&RayCastHit::m_normal))
->Property("EntityId", [](RayCastHit& result) { return result.m_body != nullptr ? result.m_body->GetEntityId() : AZ::EntityId(); }, nullptr)
;
behaviorContext->Class<RaycastHitArray>()
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
->Attribute(AZ::Script::Attributes::Module, "physics")
->Attribute(AZ::Script::Attributes::Category, "PhysX")
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
->Property("HitArray", BehaviorValueProperty(&RaycastHitArray::m_hitArray))
;
}
}
} // namespace Physics
@@ -1,175 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates, or
* a third party where indicated.
*
* 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.
*
*/
#pragma once
#include <functional>
#include <AzCore/std/containers/vector.h>
#include <AzCore/Math/Vector3.h>
#include <AzCore/Math/Aabb.h>
#include <AzCore/Math/Transform.h>
#include <AzCore/Component/EntityId.h>
#include <AzCore/RTTI/RTTI.h>
#include <AzFramework/Physics/WorldBody.h>
#include <AzFramework/Physics/Collision/CollisionGroups.h>
#include <AzFramework/Physics/Material.h>
namespace Physics
{
class WorldBody;
class Shape;
class ShapeConfiguration;
/// Enum to specify the hit type returned by the filter callback.
enum QueryHitType
{
None, ///< The hit should not be reported.
Touch, ///< The hit should be reported but it should not block the query
Block ///< The hit should be reported and it should block the query
};
/// Callback used for directed scene queries: RayCasts and ShapeCasts
using FilterCallback = AZStd::function<QueryHitType(const Physics::WorldBody* body, const Physics::Shape* shape)>;
/// Enum to specify which shapes are included in the query.
enum class QueryType : int
{
Static, ///< Only test against static shapes
Dynamic, ///< Only test against dynamic shapes
StaticAndDynamic ///< Test against both static and dynamic shapes
};
//! Scene query and geometry query behavior flags.
//!
//! HitFlags are used for 3 different purposes:
//!
//! 1) To request hit fields to be filled in by scene queries (such as hit position, normal, face index or UVs).
//! 2) Once query is completed, to indicate which fields are valid (note that a query may produce more valid fields than requested).
//! 3) To specify additional options for the narrow phase and mid-phase intersection routines.
enum class HitFlags : AZ::u16
{
Position = (1 << 0), //!< "position" member of the hit is valid
Normal = (1 << 1), //!< "normal" member of the hit is valid
UV = (1 << 3), //!< "u" and "v" barycentric coordinates of the hit are valid. Not applicable to ShapeCast queries.
//! Performance hint flag for ShapeCasts when it is known upfront there's no initial overlap.
//! NOTE: using this flag may cause undefined results if shapes are initially overlapping.
AssumeNoInitialOverlap = (1 << 4),
MeshMultiple = (1 << 5), //!< Report all hits for meshes rather than just the first. Not applicable to ShapeCast queries.
//! Report any first hit for meshes. If neither MeshMultiple nor MeshAny is specified,
//! a single closest hit will be reported for meshes.
MeshAny = (1 << 6),
//! Report hits with back faces of mesh triangles. Also report hits for raycast
//! originating on mesh surface and facing away from the surface normal. Not applicable to ShapeCast queries.
MeshBothSides = (1 << 7),
PreciseSweep = (1 << 8), //!< Use more accurate but slower narrow phase sweep tests.
MTD = (1 << 9), //!< Report the minimum translation depth, normal and contact point.
FaceIndex = (1 << 10), //!< "face index" member of the hit is valid. Required to get the per-face material data.
Default = Position | Normal | FaceIndex
};
/// Casts a ray from a starting pose along a direction returning objects that intersected with the ray.
struct RayCastRequest
{
AZ_CLASS_ALLOCATOR(RayCastRequest, AZ::SystemAllocator, 0);
AZ_TYPE_INFO(RayCastRequest, "{53EAD088-A391-48F1-8370-2A1DBA31512F}");
float m_distance = 500.0f; ///< The distance along m_dir direction.
AZ::Vector3 m_start = AZ::Vector3::CreateZero(); ///< World space point where ray starts from.
AZ::Vector3 m_direction = AZ::Vector3::CreateZero(); ///< World space direction (normalized).
AzPhysics::CollisionGroup m_collisionGroup = AzPhysics::CollisionGroup::All; ///< The layers to include in the query
FilterCallback m_filterCallback = nullptr; ///< Hit filtering function
QueryType m_queryType = QueryType::StaticAndDynamic; ///< Object types to include in the query
HitFlags m_hitFlags = HitFlags::Default; ///< Query behavior flags
AZ::u64 m_maxResults = 32; ///< The Maximum results for this request to return, this is limited by the value set in WorldConfiguration
};
/// Sweeps a shape from a starting pose along a direction returning objects that intersected with the shape.
struct ShapeCastRequest
{
AZ_CLASS_ALLOCATOR(ShapeCastRequest, AZ::SystemAllocator, 0);
AZ_TYPE_INFO(ShapeCastRequest, "{52F6C536-92F6-4C05-983D-0A74800AE56D}");
float m_distance = 500.0f; /// The distance to cast along m_dir direction.
AZ::Transform m_start = AZ::Transform::CreateIdentity(); ///< World space start position. Assumes only rotation + translation (no scaling).
AZ::Vector3 m_direction = AZ::Vector3::CreateZero(); ///< World space direction (Should be normalized)
ShapeConfiguration* m_shapeConfiguration = nullptr; ///< Shape information.
AzPhysics::CollisionGroup m_collisionGroup = AzPhysics::CollisionGroup::All; ///< Collision filter for the query.
FilterCallback m_filterCallback = nullptr; ///< Hit filtering function
QueryType m_queryType = QueryType::StaticAndDynamic; ///< Object types to include in the query
HitFlags m_hitFlags = HitFlags::Default; ///< Query behavior flags
AZ::u64 m_maxResults = 32; ///< The Maximum results for this request to return, this is limited by the value set in WorldConfiguration
};
/// Callback used for undirected scene queries: Overlaps
using OverlapFilterCallback = AZStd::function<bool(const Physics::WorldBody* body, const Physics::Shape* shape)>;
/// Searches a region enclosed by a specified shape for any overlapping objects in the scene.
struct OverlapRequest
{
AZ_CLASS_ALLOCATOR(OverlapRequest, AZ::SystemAllocator, 0);
AZ_TYPE_INFO(OverlapRequest, "{3DC986C2-316B-4C54-A0A6-8ABBB8ABCC4A}");
AZ::Transform m_pose = AZ::Transform::CreateIdentity(); ///< Initial shape pose
ShapeConfiguration* m_shapeConfiguration = nullptr; ///< Shape information.
AzPhysics::CollisionGroup m_collisionGroup = AzPhysics::CollisionGroup::All; ///< Collision filter for the query.
OverlapFilterCallback m_filterCallback = nullptr; ///< Hit filtering function
QueryType m_queryType = QueryType::StaticAndDynamic; ///< Object types to include in the query
AZ::u64 m_maxResults = 32; ///< The Maximum results for this request to return, this is limited by the value set in WorldConfiguration
};
/// Structure used to store the result from either a raycast or a shape cast.
struct RayCastHit
{
AZ_CLASS_ALLOCATOR(RayCastHit, AZ::SystemAllocator, 0);
AZ_TYPE_INFO(RayCastHit, "{A46CBEA6-6B92-4809-9363-9DDF0F74F296}");
static void Reflect(AZ::ReflectContext* context);
inline operator bool() const { return m_body != nullptr; }
float m_distance = 0.0f; ///< The distance along the cast at which the hit occurred as given by Dot(m_normal, startPoint) - Dot(m_normal, m_point).
AZ::Vector3 m_position = AZ::Vector3::CreateZero(); ///< The position of the hit in world space
AZ::Vector3 m_normal = AZ::Vector3::CreateZero(); ///< The normal of the surface hit
WorldBody* m_body = nullptr; ///< World body that was hit.
Shape* m_shape = nullptr; ///< The shape on the body that was hit
Material* m_material = nullptr; ///< The material on the shape (or face) that was hit
};
/// Overlap hit.
struct OverlapHit
{
AZ_CLASS_ALLOCATOR(OverlapHit, AZ::SystemAllocator, 0);
AZ_TYPE_INFO(OverlapHit, "{7A7201B9-67B5-438B-B4EB-F3EEBB78C617}");
inline operator bool() const { return m_body != nullptr; }
WorldBody* m_body = nullptr; ///< World body that was hit.
Shape* m_shape = nullptr; ///< The shape on the body that was hit
Material* m_material = nullptr; ///< The material on the shape (or face) that was hit
};
/// Bitwise operators for HitFlags
inline HitFlags operator|(HitFlags lhs, HitFlags rhs)
{
return static_cast<HitFlags>(static_cast<AZ::u16>(lhs) | static_cast<AZ::u16>(rhs));
}
inline HitFlags operator&(HitFlags lhs, HitFlags rhs)
{
return static_cast<HitFlags>(static_cast<AZ::u16>(lhs) & static_cast<AZ::u16>(rhs));
}
} // namespace Physics
namespace AZ
{
AZ_TYPE_INFO_SPECIALIZE(Physics::QueryType, "{0E0E56A8-73A8-40B4-B438-B19FC852E3C0}");
}
@@ -88,7 +88,7 @@ namespace Physics
AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context);
if (serializeContext)
{
serializeContext->Class<CharacterConfiguration>()
serializeContext->Class<CharacterConfiguration, AzPhysics::SimulatedBodyConfiguration>()
->Version(2)
->Field("CollisionLayer", &CharacterConfiguration::m_collisionLayer)
->Field("CollisionGroupId", &CharacterConfiguration::m_collisionGroupId)
@@ -15,11 +15,11 @@
#include <AzCore/Math/Vector3.h>
#include <AzFramework/Physics/Shape.h>
#include <AzFramework/Physics/WorldBody.h>
#include <AzFramework/Physics/Collision/CollisionGroups.h>
#include <AzFramework/Physics/Collision/CollisionLayers.h>
#include <AzFramework/Physics/Common/PhysicsSimulatedBody.h>
#include <AzFramework/Physics/Configuration/SimulatedBodyConfiguration.h>
namespace Physics
{
@@ -59,11 +59,11 @@ namespace Physics
/// Information required to create the basic physics representation of a character.
class CharacterConfiguration
: public WorldBodyConfiguration
: public AzPhysics::SimulatedBodyConfiguration
{
public:
AZ_CLASS_ALLOCATOR(CharacterConfiguration, AZ::SystemAllocator, 0);
AZ_RTTI(CharacterConfiguration, "{58D5A6CA-113B-4AC3-8D53-239DB0C4E240}");
AZ_RTTI(CharacterConfiguration, "{58D5A6CA-113B-4AC3-8D53-239DB0C4E240}", AzPhysics::SimulatedBodyConfiguration);
virtual ~CharacterConfiguration() = default;
@@ -84,11 +84,11 @@ namespace Physics
/// all-purpose character controller implementation. This class just abstracts some common functionality amongst
/// typical characters, and is take-it-or-leave it style; useful as a starting point or reference.
class Character
: public WorldBody
: public AzPhysics::SimulatedBody
{
public:
AZ_CLASS_ALLOCATOR(Character, AZ::SystemAllocator, 0);
AZ_RTTI(Character, "{962E37A1-3401-4672-B896-0A6157CFAC97}", WorldBody);
AZ_RTTI(Character, "{962E37A1-3401-4672-B896-0A6157CFAC97}", AzPhysics::SimulatedBody);
~Character() override = default;

Some files were not shown because too many files have changed in this diff Show More