diff --git a/.github/ISSUE_TEMPLATE/bug_template.md b/.github/ISSUE_TEMPLATE/bug_template.md
index d197ca1312..5a6275b394 100644
--- a/.github/ISSUE_TEMPLATE/bug_template.md
+++ b/.github/ISSUE_TEMPLATE/bug_template.md
@@ -7,20 +7,30 @@ labels: 'needs-triage,needs-sig,kind/bug'
---
**Describe the bug**
-A clear and concise description of what the bug is.
+A clear and concise description of what the bug is. Try to isolate the issue to help the community to reproduce it easily and increase chances for a fast fix.
-**To Reproduce**
+**Steps to reproduce**
Steps to reproduce the behavior:
1. Go to '...'
-2. Click on '....'
-3. Scroll down to '....'
-4. See error
+2. Click on '...'
+3. Select attached asset '...'
+4. Scroll down to '...'
+5. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
-**Screenshots**
-If applicable, add screenshots to help explain your problem.
+**Actual behavior**
+A clear and concise description of what actually happened.
+
+**Assets required**
+Provide sample assets needed to reproduce the issue.
+
+**Screenshots/Video**
+If applicable, add screenshots and/or a video to help explain your problem.
+
+**Found in Branch**
+Name of or link to the branch where the issue occurs.
**Desktop/Device (please complete the following information):**
- Device: [e.g. PC, Mac, iPhone, Samsung]
diff --git a/Assets/Editor/MapScreenshotSettings.xml b/Assets/Editor/MapScreenshotSettings.xml
index 01f90db4b3..88a8a49aef 100644
--- a/Assets/Editor/MapScreenshotSettings.xml
+++ b/Assets/Editor/MapScreenshotSettings.xml
@@ -1,18 +1,5 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Assets/Editor/Materials/Stripes.tif.exportsettings b/Assets/Editor/Materials/Stripes.tif.exportsettings
deleted file mode 100644
index 0653bb85eb..0000000000
--- a/Assets/Editor/Materials/Stripes.tif.exportsettings
+++ /dev/null
@@ -1 +0,0 @@
-/autooptimizefile=0 /preset=Diffuse_lowQ
\ No newline at end of file
diff --git a/Assets/Editor/Materials/voxel_editor.png.exportsettings b/Assets/Editor/Materials/voxel_editor.png.exportsettings
deleted file mode 100644
index d19ae00148..0000000000
--- a/Assets/Editor/Materials/voxel_editor.png.exportsettings
+++ /dev/null
@@ -1 +0,0 @@
-/autooptimizefile=0 /mipmaps=0 /preset=AlbedoWithGenericAlpha /reduce=-1
\ No newline at end of file
diff --git a/Assets/Editor/UserTools.xml b/Assets/Editor/UserTools.xml
index 8f971cbd5c..4cc197afbe 100644
--- a/Assets/Editor/UserTools.xml
+++ b/Assets/Editor/UserTools.xml
@@ -7,8 +7,6 @@
-
-
diff --git a/Assets/Engine/Config/AutoTestChain.cfg b/Assets/Engine/Config/AutoTestChain.cfg
index 8c6fae9020..4164acb271 100644
--- a/Assets/Engine/Config/AutoTestChain.cfg
+++ b/Assets/Engine/Config/AutoTestChain.cfg
@@ -1,16 +1,5 @@
ConsoleHide
-g_godMode=1
sys_warnings=0
con_showonload=1
-i_forcefeedback=0
-g_infiniteammo=1
-e_ObjectLayersActivation=0
-e_ObjectLayersActivationPhysics=0
-g_flashrenderingduringloading=0
sys_maxfps=0
r_vsync=0
-p_max_substeps=1
-demo_file=autotest
-demo_num_runs=0
-demo_quit=1
-demo_ai=1
diff --git a/Assets/Engine/Config/AutoTestTimeDemo.cfg b/Assets/Engine/Config/AutoTestTimeDemo.cfg
index 687158eda9..664ea94939 100644
--- a/Assets/Engine/Config/AutoTestTimeDemo.cfg
+++ b/Assets/Engine/Config/AutoTestTimeDemo.cfg
@@ -1,15 +1,5 @@
ConsoleHide
-g_godMode=1
-g_infiniteammo=1
r_displayinfo=1
s_profiling=1
sys_maxfps=0
-e_ObjectLayersActivation=0
-e_ObjectLayersActivationPhysics=0
-
-demo_file=autotest
-demo_num_runs=2
-demo_quit=1
-demo_savestats=1
-demo_profile=-1
demo
diff --git a/Assets/Engine/Config/AutotestPlaythrough.cfg b/Assets/Engine/Config/AutotestPlaythrough.cfg
index f453097972..664ea94939 100644
--- a/Assets/Engine/Config/AutotestPlaythrough.cfg
+++ b/Assets/Engine/Config/AutotestPlaythrough.cfg
@@ -1,12 +1,5 @@
ConsoleHide
-g_godMode=1
-g_infiniteammo=1
r_displayinfo=1
s_profiling=1
sys_maxfps=0
-demo_file=playthru
-demo_num_runs=2
-demo_quit=1
-demo_savestats=1
-demo_profile=-1
-demo
\ No newline at end of file
+demo
diff --git a/Assets/Engine/Config/CVarGroups/sys_spec_Full.cfg b/Assets/Engine/Config/CVarGroups/sys_spec_Full.cfg
index 626dce3ee4..04fb56f3ca 100644
--- a/Assets/Engine/Config/CVarGroups/sys_spec_Full.cfg
+++ b/Assets/Engine/Config/CVarGroups/sys_spec_Full.cfg
@@ -11,113 +11,16 @@
; default of this CVarGroup
= 7
-sys_spec_ObjectDetail=7
-sys_spec_Shading=7
-sys_spec_VolumetricEffects=7
-sys_spec_Shadows=7
-sys_spec_Texture=7
-sys_spec_Physics=7
-sys_spec_PostProcessing=7
-sys_spec_Particles=7
-sys_spec_Sound=7
-sys_spec_Water=7
-sys_spec_GameEffects=7
-sys_spec_light=7
-
[1]
-sys_spec_ObjectDetail=1
-sys_spec_Shading=1
-sys_spec_VolumetricEffects=1
-sys_spec_Shadows=1
-sys_spec_Texture=1
-sys_spec_Physics=1
-sys_spec_PostProcessing=1
-sys_spec_Particles=1
-sys_spec_Sound=1
-sys_spec_Water=1
-sys_spec_GameEffects=1
-sys_spec_light=1
[2]
-sys_spec_ObjectDetail=2
-sys_spec_Shading=2
-sys_spec_VolumetricEffects=2
-sys_spec_Shadows=2
-sys_spec_Texture=2
-sys_spec_Physics=2
-sys_spec_PostProcessing=2
-sys_spec_Particles=2
-sys_spec_Sound=2
-sys_spec_Water=2
-sys_spec_GameEffects=2
-sys_spec_light=2
[3]
-sys_spec_ObjectDetail=3
-sys_spec_Shading=3
-sys_spec_VolumetricEffects=3
-sys_spec_Shadows=3
-sys_spec_Texture=3
-sys_spec_Physics=3
-sys_spec_PostProcessing=3
-sys_spec_Particles=3
-sys_spec_Sound=3
-sys_spec_Water=3
-sys_spec_GameEffects=3
-sys_spec_light=3
[4]
-sys_spec_ObjectDetail=4
-sys_spec_Shading=4
-sys_spec_VolumetricEffects=4
-sys_spec_Shadows=4
-sys_spec_Texture=4
-sys_spec_Physics=4
-sys_spec_PostProcessing=4
-sys_spec_Particles=4
-sys_spec_Sound=4
-sys_spec_Water=4
-sys_spec_GameEffects=4
-sys_spec_light=4
[5]
-sys_spec_ObjectDetail=5
-sys_spec_Shading=5
-sys_spec_VolumetricEffects=5
-sys_spec_Shadows=5
-sys_spec_Texture=5
-sys_spec_Physics=5
-sys_spec_PostProcessing=5
-sys_spec_Particles=5
-sys_spec_Sound=5
-sys_spec_Water=5
-sys_spec_GameEffects=5
-sys_spec_light=5
[6]
-sys_spec_ObjectDetail=6
-sys_spec_Shading=6
-sys_spec_VolumetricEffects=6
-sys_spec_Shadows=6
-sys_spec_Texture=6
-sys_spec_Physics=6
-sys_spec_PostProcessing=6
-sys_spec_Particles=6
-sys_spec_Sound=6
-sys_spec_Water=6
-sys_spec_GameEffects=6
-sys_spec_light=6
[8]
-sys_spec_ObjectDetail=8
-sys_spec_Shading=8
-sys_spec_VolumetricEffects=8
-sys_spec_Shadows=8
-sys_spec_Texture=8
-sys_spec_Physics=8
-sys_spec_PostProcessing=8
-sys_spec_Particles=8
-sys_spec_Sound=8
-sys_spec_Water=8
-sys_spec_GameEffects=8
-sys_spec_light=8
diff --git a/Assets/Engine/Config/CVarGroups/sys_spec_GameEffects.cfg b/Assets/Engine/Config/CVarGroups/sys_spec_GameEffects.cfg
deleted file mode 100644
index 34e058d47d..0000000000
--- a/Assets/Engine/Config/CVarGroups/sys_spec_GameEffects.cfg
+++ /dev/null
@@ -1,8 +0,0 @@
-[default]
-; default of this CVarGroup
-= 7
-
-mfx_Timeout = 0.01
-
-
-
diff --git a/Assets/Engine/Config/CVarGroups/sys_spec_ObjectDetail.cfg b/Assets/Engine/Config/CVarGroups/sys_spec_ObjectDetail.cfg
deleted file mode 100644
index a2996f7ded..0000000000
--- a/Assets/Engine/Config/CVarGroups/sys_spec_ObjectDetail.cfg
+++ /dev/null
@@ -1,160 +0,0 @@
-[default]
-; default of this CVarGroup
-= 7
-
-ca_AttachmentCullingRation=360
-es_DebrisLifetimeScale=1
-e_CoverageBufferReproj=6
-e_DecalsAllowGameDecals=1
-e_DecalsLifeTimeScale=2
-e_DecalsOverlapping=1
-e_Dissolve=2
-e_LightQuality=3
-e_LodMin=0
-e_LodRatio=20
-e_MaxViewDistSpecLerp=1
-e_MergedMeshesInstanceDist=1.0
-e_MergedMeshesPool=8192
-e_ObjQuality=3
-e_OcclusionCullingViewDistRatio=1
-e_ProcVegetation=1
-e_StatObjBufferRenderTasks=1
-e_StreamCgf=0
-e_TerrainLodRatio=1
-e_TerrainOcclusionCullingMaxDist=200
-e_Tessellation=0
-e_VegetationMinSize=0
-e_ViewDistMin=10
-e_ViewDistRatio=100
-e_ViewDistRatioCustom=100
-e_ViewDistRatioDetail=100
-e_ViewDistRatioLights=50
-e_ViewDistRatioVegetation=100
-r_DrawNearZRange=0.12
-r_FlaresTessellationRatio=1
-r_SilhouettePOM=0
-r_usezpass=2
-
-[1]
-ca_AttachmentCullingRation=145
-es_DebrisLifetimeScale=0.6
-e_DecalsLifeTimeScale=1
-e_Dissolve=0
-e_LightQuality=1
-e_LodRatio=10
-e_MaxViewDistSpecLerp=0.5
-e_ObjQuality=1
-e_TerrainOcclusionCullingMaxDist=130
-e_VegetationMinSize=0.5
-e_ViewDistRatioCustom=60
-e_ViewDistRatioDetail=25
-e_ViewDistRatioLights=25
-e_ViewDistRatioVegetation=21
-r_FlaresTessellationRatio=0.25
-r_usezpass=1
-e_ProcVegetation=0
-e_ViewDistRatio=50
-
-[2]
-ca_AttachmentCullingRation=145
-es_DebrisLifetimeScale=0.6
-e_DecalsLifeTimeScale=1
-e_Dissolve=0
-e_LightQuality=2
-e_LodRatio=10
-e_MaxViewDistSpecLerp=0.5
-e_ObjQuality=2
-e_TerrainOcclusionCullingMaxDist=130
-e_VegetationMinSize=0.5
-e_ViewDistRatioCustom=60
-e_ViewDistRatioDetail=25
-e_ViewDistRatioLights=25
-e_ViewDistRatioVegetation=50
-r_FlaresTessellationRatio=0.25
-r_usezpass=1
-e_ProcVegetation=1
-e_ViewDistRatio=50
-
-[3]
-ca_AttachmentCullingRation=145
-es_DebrisLifetimeScale=0.6
-e_DecalsLifeTimeScale=1
-e_Dissolve=0
-e_LightQuality=3
-e_LodRatio=10
-e_MaxViewDistSpecLerp=0.5
-e_ObjQuality=3
-e_TerrainOcclusionCullingMaxDist=130
-e_VegetationMinSize=0.5
-e_ViewDistRatioCustom=60
-e_ViewDistRatioDetail=25
-e_ViewDistRatioLights=25
-e_ViewDistRatioVegetation=50
-r_FlaresTessellationRatio=0.25
-r_usezpass=1
-e_ProcVegetation=1
-e_ViewDistRatio=75
-
-[4]
-ca_AttachmentCullingRation=145
-es_DebrisLifetimeScale=0.6
-e_DecalsLifeTimeScale=1
-e_Dissolve=0
-e_LightQuality=4
-e_LodRatio=10
-e_MaxViewDistSpecLerp=0.5
-e_ObjQuality=4
-e_TerrainOcclusionCullingMaxDist=130
-e_VegetationMinSize=0.5
-e_ViewDistRatioCustom=60
-e_ViewDistRatioDetail=25
-e_ViewDistRatioLights=25
-e_ViewDistRatioVegetation=50
-r_FlaresTessellationRatio=0.25
-r_usezpass=1
-e_ProcVegetation=1
-e_ViewDistRatio=75
-
-[5]
-ca_AttachmentCullingRation=145
-es_DebrisLifetimeScale=0.6
-e_DecalsLifeTimeScale=1
-e_LightQuality=1
-e_LodRatio=10
-e_MaxViewDistSpecLerp=0.5
-e_ObjQuality=1
-e_TerrainOcclusionCullingMaxDist=130
-e_VegetationMinSize=0.5
-e_ViewDistRatio=50
-e_ViewDistRatioCustom=60
-e_ViewDistRatioDetail=25
-e_ViewDistRatioLights=25
-e_ViewDistRatioVegetation=50
-r_FlaresTessellationRatio=0.25
-
-[6]
-ca_AttachmentCullingRation=300
-es_DebrisLifetimeScale=0.8
-e_LightQuality=2
-e_LodRatio=15
-e_ObjQuality=2
-e_ViewDistRatio=75
-e_ViewDistRatioDetail=35
-e_ViewDistRatioVegetation=75
-
-[8]
-ca_AttachmentCullingRation=400
-e_LightQuality=4
-e_LodRatio=40
-e_MergedMeshesInstanceDist=2.0
-e_MergedMeshesPool=16384
-e_ObjQuality=4
-e_TerrainLodRatio=0.5
-e_Tessellation=1
-e_ViewDistRatio=125
-e_ViewDistRatioCustom=125
-e_ViewDistRatioDetail=125
-e_ViewDistRatioLights=75
-e_ViewDistRatioVegetation=125
-r_DrawNearZRange = 0.08
-r_SilhouettePOM=1
\ No newline at end of file
diff --git a/Assets/Engine/Config/CVarGroups/sys_spec_Particles.cfg b/Assets/Engine/Config/CVarGroups/sys_spec_Particles.cfg
deleted file mode 100644
index 0a02170b97..0000000000
--- a/Assets/Engine/Config/CVarGroups/sys_spec_Particles.cfg
+++ /dev/null
@@ -1,94 +0,0 @@
-[default]
-; default of this CVarGroup
-= 7
-
-e_ParticlesGI=1
-e_ParticlesPreload=0
-e_ParticlesMaxScreenFill=128
-e_ParticlesMinDrawPixels=1
-e_ParticlesMotionBlur=0
-e_ParticlesObjectCollisions=2
-e_ParticlesQuality=3
-e_ParticlesSortQuality=0
-e_ParticlesPoolSize=16384
-r_ParticlesHalfRes=0
-r_ParticlesTessellation=1
-r_ParticlesInstanceVertices=1
-r_ParticlesGpuMaxEmitCount=10000
-
-[1]
-e_ParticlesGI=0
-e_ParticlesPreload=1
-e_ParticlesMaxScreenFill=16
-e_ParticlesMinDrawPixels=2
-e_ParticlesObjectCollisions=1
-e_ParticlesQuality=2
-e_ParticlesPoolSize=4096
-r_ParticlesHalfRes=1
-r_ParticlesTessellation=0
-r_ParticlesInstanceVertices=0
-r_ParticlesGpuMaxEmitCount=10
-
-
-[2]
-e_ParticlesGI=0
-e_ParticlesPreload=1
-e_ParticlesMaxScreenFill=16
-e_ParticlesMinDrawPixels=2
-e_ParticlesObjectCollisions=1
-e_ParticlesQuality=2
-e_ParticlesPoolSize=4096
-r_ParticlesHalfRes=1
-r_ParticlesTessellation=0
-r_ParticlesInstanceVertices=0
-r_ParticlesGpuMaxEmitCount=100
-
-
-[3]
-e_ParticlesGI=0
-e_ParticlesPreload=1
-e_ParticlesMaxScreenFill=16
-e_ParticlesMinDrawPixels=2
-e_ParticlesObjectCollisions=1
-e_ParticlesQuality=2
-e_ParticlesPoolSize=4096
-r_ParticlesHalfRes=1
-r_ParticlesTessellation=0
-r_ParticlesInstanceVertices=0
-r_ParticlesGpuMaxEmitCount=500
-
-
-[4]
-e_ParticlesGI=0
-e_ParticlesPreload=1
-e_ParticlesMaxScreenFill=16
-e_ParticlesMinDrawPixels=2
-e_ParticlesObjectCollisions=1
-e_ParticlesQuality=2
-e_ParticlesPoolSize=4096
-r_ParticlesHalfRes=1
-r_ParticlesTessellation=0
-r_ParticlesInstanceVertices=0
-r_ParticlesGpuMaxEmitCount=1000
-
-
-[5]
-e_ParticlesMaxScreenFill=32
-e_ParticlesMinDrawPixels=1.5
-e_ParticlesObjectCollisions=1
-e_ParticlesQuality=1
-r_ParticlesHalfRes=1
-r_ParticlesTessellation=0
-r_ParticlesGpuMaxEmitCount=3000
-
-[6]
-e_ParticlesMaxScreenFill=64
-e_ParticlesObjectCollisions=1
-e_ParticlesQuality=2
-r_ParticlesGpuMaxEmitCount=5000
-
-[8]
-e_ParticlesMaxScreenFill=160
-e_ParticlesMotionBlur=1
-e_ParticlesQuality=4
-r_ParticlesGpuMaxEmitCount=1048576
\ No newline at end of file
diff --git a/Assets/Engine/Config/CVarGroups/sys_spec_Physics.cfg b/Assets/Engine/Config/CVarGroups/sys_spec_Physics.cfg
deleted file mode 100644
index 15d9fc61e3..0000000000
--- a/Assets/Engine/Config/CVarGroups/sys_spec_Physics.cfg
+++ /dev/null
@@ -1,100 +0,0 @@
-[default]
-; default of this CVarGroup
-= 7
-
-es_MaxPhysDist=100
-es_MaxPhysDistInvisible=25
-e_CullVegActivation=50
-e_FoliageWindActivationDist=25
-e_PhysMinCellSize=4
-e_PhysOceanCell=0.5
-e_PhysProxyTriLimit=10000
-g_breakage_mem_limit=0
-g_breakage_particles_limit=160
-g_no_secondary_breaking=0
-g_tree_cut_reuse_dist=0
-p_gravity_z=-13
-p_max_entity_cells=300000
-p_max_MC_iters=6000
-p_max_object_splashes=3
-p_max_substeps=5
-p_max_substeps_large_group=5
-p_num_bodies_large_group=100
-p_splash_dist0=7
-p_splash_dist1=30
-p_splash_force0=10
-p_splash_force1=100
-p_splash_vel0=4.5
-p_splash_vel1=10
-v_vehicle_quality=4
-
-[1]
-es_MaxPhysDistInvisible=15
-e_CullVegActivation=30
-e_FoliageWindActivationDist=10
-e_PhysMinCellSize=16
-e_PhysOceanCell=1
-g_breakage_mem_limit=2000
-g_breakage_particles_limit=40
-g_no_secondary_breaking=1
-g_tree_cut_reuse_dist=1
-p_max_entity_cells=75000
-p_max_MC_iters=2000
-p_max_substeps=2
-
-[2]
-es_MaxPhysDistInvisible=15
-e_CullVegActivation=30
-e_FoliageWindActivationDist=10
-e_PhysMinCellSize=16
-e_PhysOceanCell=1
-g_breakage_mem_limit=2000
-g_breakage_particles_limit=40
-g_no_secondary_breaking=1
-g_tree_cut_reuse_dist=1
-p_max_entity_cells=75000
-p_max_MC_iters=2000
-p_max_substeps=2
-
-[3]
-es_MaxPhysDistInvisible=15
-e_CullVegActivation=30
-e_FoliageWindActivationDist=10
-e_PhysMinCellSize=16
-e_PhysOceanCell=1
-g_breakage_mem_limit=2000
-g_breakage_particles_limit=40
-g_no_secondary_breaking=1
-g_tree_cut_reuse_dist=1
-p_max_entity_cells=75000
-p_max_MC_iters=2000
-p_max_substeps=2
-
-[4]
-es_MaxPhysDistInvisible=15
-e_CullVegActivation=30
-e_FoliageWindActivationDist=10
-e_PhysMinCellSize=16
-e_PhysOceanCell=1
-g_breakage_mem_limit=2000
-g_breakage_particles_limit=40
-g_no_secondary_breaking=1
-g_tree_cut_reuse_dist=1
-p_max_entity_cells=75000
-p_max_MC_iters=2000
-p_max_substeps=2
-
-[5]
-es_MaxPhysDist=50
-es_MaxPhysDistInvisible=15
-e_CullVegActivation=30
-e_FoliageWindActivationDist=10
-e_PhysOceanCell=1
-g_breakage_particles_limit=80
-g_tree_cut_reuse_dist=0.35
-p_max_MC_iters=4000
-p_max_substeps=2
-
-[6]
-
-[8]
diff --git a/Assets/Engine/Config/CVarGroups/sys_spec_PostProcessing.cfg b/Assets/Engine/Config/CVarGroups/sys_spec_PostProcessing.cfg
deleted file mode 100644
index 9d2cd3754d..0000000000
--- a/Assets/Engine/Config/CVarGroups/sys_spec_PostProcessing.cfg
+++ /dev/null
@@ -1,114 +0,0 @@
-[default]
-; default of this CVarGroup
-= 7
-
-r_PostProcessEffects=1
-q_ShaderHDR=2
-q_ShaderPostProcess=2
-r_ChromaticAberration=0
-r_ColorGradingChartsCache=0
-r_DepthOfField=2
-r_Flares=1
-r_HDRBloomQuality=2
-r_MotionBlur=2
-r_MotionBlurMaxViewDist=100000
-r_MotionBlurQuality=1
-r_MotionBlurShutterSpeed=125
-r_Rain=2
-r_RainMaxViewDist_Deferred=150
-r_Sharpening=0
-r_Snow=2
-r_SunShafts=2
-r_TranspDepthFixup=1
-r_ToneMapTechnique=0
-r_ToneMapExposureType=0
-r_HDRBloom=1
-r_ColorGrading=1
-r_ColorSpace=0
-
-[1]
-q_ShaderHDR=1
-q_ShaderPostProcess=1
-r_ColorGrading=0
-r_DepthOfField=0
-r_Flares=0
-r_HDRBloom=0
-r_HDRBloomQuality=0
-r_MotionBlur=0
-r_MotionBlurMaxViewDist=16
-r_MotionBlurQuality=0
-r_Rain=1
-r_RainMaxViewDist_Deferred=40
-r_Snow=1
-r_SunShafts=0
-r_TranspDepthFixup=0
-r_ToneMapTechnique=3
-r_ToneMapExposureType=1
-r_ColorSpace=2
-
-
-[2]
-q_ShaderHDR=1
-q_ShaderPostProcess=1
-r_ColorGradingChartsCache=4
-r_DepthOfField=1
-r_Flares=0
-r_HDRBloomQuality=0
-r_MotionBlur=0
-r_MotionBlurMaxViewDist=16
-r_MotionBlurQuality=0
-r_Rain=1
-r_RainMaxViewDist_Deferred=40
-r_Snow=1
-r_SunShafts=1
-r_TranspDepthFixup=0
-
-
-[3]
-q_ShaderHDR=1
-q_ShaderPostProcess=2
-r_ColorGradingChartsCache=4
-r_DepthOfField=1
-r_HDRBloomQuality=1
-r_MotionBlur=0
-r_MotionBlurMaxViewDist=16
-r_MotionBlurQuality=0
-r_Rain=1
-r_RainMaxViewDist_Deferred=40
-r_Snow=1
-r_SunShafts=1
-r_TranspDepthFixup=0
-
-[4]
-q_ShaderHDR=1
-q_ShaderPostProcess=2
-r_ColorGradingChartsCache=4
-r_DepthOfField=1
-r_HDRBloomQuality=1
-r_MotionBlur=0
-r_MotionBlurMaxViewDist=16
-r_MotionBlurQuality=0
-r_Rain=1
-r_RainMaxViewDist_Deferred=40
-r_Snow=1
-r_SunShafts=1
-r_TranspDepthFixup=0
-
-[5]
-q_ShaderHDR=1
-q_ShaderPostProcess=1
-r_ColorGradingChartsCache=4
-r_MotionBlurMaxViewDist=16
-r_MotionBlurQuality=0
-r_RainMaxViewDist_Deferred=40
-r_TranspDepthFixup=0
-
-[6]
-q_ShaderHDR=1
-q_ShaderPostProcess=1
-r_RainMaxViewDist_Deferred=100
-
-[8]
-q_ShaderHDR=3
-q_ShaderPostProcess=3
-r_MotionBlurQuality=2
diff --git a/Assets/Engine/Config/CVarGroups/sys_spec_Quality.cfg b/Assets/Engine/Config/CVarGroups/sys_spec_Quality.cfg
deleted file mode 100644
index cf1bdf5184..0000000000
--- a/Assets/Engine/Config/CVarGroups/sys_spec_Quality.cfg
+++ /dev/null
@@ -1,98 +0,0 @@
-[default]
-; default of this CVarGroup
-= 7
-
-q_ShaderGeneral=2
-q_ShaderMetal=2
-q_ShaderGlass=2
-q_ShaderVegetation=2
-q_ShaderIce=2
-q_ShaderTerrain=2
-q_ShaderShadow=2
-q_ShaderFX=2
-q_ShaderSky=2
-q_Renderer=2
-
-[1]
-q_ShaderGeneral=1
-q_ShaderMetal=1
-q_ShaderGlass=1
-q_ShaderVegetation=1
-q_ShaderIce=1
-q_ShaderTerrain=1
-q_ShaderShadow=1
-q_ShaderFX=1
-q_ShaderSky=1
-q_Renderer=1
-
-[2]
-q_ShaderGeneral=1
-q_ShaderMetal=1
-q_ShaderGlass=1
-q_ShaderVegetation=1
-q_ShaderIce=1
-q_ShaderTerrain=1
-q_ShaderShadow=1
-q_ShaderFX=1
-q_ShaderSky=1
-q_Renderer=1
-
-[3]
-q_ShaderGeneral=1
-q_ShaderMetal=1
-q_ShaderGlass=1
-q_ShaderVegetation=1
-q_ShaderIce=1
-q_ShaderTerrain=1
-q_ShaderShadow=1
-q_ShaderFX=1
-q_ShaderSky=1
-q_Renderer=2
-
-[4]
-q_ShaderGeneral=1
-q_ShaderMetal=1
-q_ShaderGlass=1
-q_ShaderVegetation=1
-q_ShaderIce=1
-q_ShaderTerrain=1
-q_ShaderShadow=1
-q_ShaderFX=1
-q_ShaderSky=1
-q_Renderer=2
-
-[5]
-q_ShaderGeneral=1
-q_ShaderMetal=1
-q_ShaderGlass=1
-q_ShaderVegetation=1
-q_ShaderIce=1
-q_ShaderTerrain=1
-q_ShaderShadow=1
-q_ShaderFX=1
-q_ShaderSky=1
-q_Renderer=1
-
-[6]
-q_ShaderGeneral=1
-q_ShaderMetal=1
-q_ShaderGlass=1
-q_ShaderVegetation=1
-q_ShaderIce=1
-q_ShaderTerrain=1
-q_ShaderShadow=1
-q_ShaderFX=1
-q_ShaderSky=1
-q_Renderer=1
-
-[8]
-q_ShaderGeneral=3
-q_ShaderMetal=3
-q_ShaderGlass=3
-q_ShaderVegetation=3
-q_ShaderIce=3
-q_ShaderTerrain=3
-q_ShaderShadow=3
-q_ShaderFX=3
-q_ShaderSky=3
-q_Renderer=3
diff --git a/Assets/Engine/Config/CVarGroups/sys_spec_Shading.cfg b/Assets/Engine/Config/CVarGroups/sys_spec_Shading.cfg
deleted file mode 100644
index eb379a8583..0000000000
--- a/Assets/Engine/Config/CVarGroups/sys_spec_Shading.cfg
+++ /dev/null
@@ -1,120 +0,0 @@
-[default]
-; default of this CVarGroup
-= 7
-
-e_CacheNearestCubePicking=1
-e_DynamicLightsMaxEntityLights=16
-e_GI=1
-e_LightVolumes=1
-e_SkyUpdateRate=1
-e_TerrainAo=0
-e_VegetationUseTerrainColor=1
-r_DeferredShadingDepthBoundsTest=1
-r_DeferredShadingTiled=2
-r_DeferredShadingTiledHairQuality=1
-r_deferredShadingFilterGBuffer=0
-r_DeferredShadingSSS=1
-r_AntialiasingMode=3
-r_DetailDistance=8
-r_EnvTexUpdateInterval=0.05
-r_Refraction=1
-r_RefractionPartialResolves=2
-r_ssdo=1
-r_ssdoHalfRes=2
-r_ssdoColorBleeding=1
-r_SSReflections=1
-r_SSReflHalfRes=1
-r_VisAreaClipLightsPerPixel=1
-sys_spec_Quality=7
-
-[1]
-e_DynamicLightsMaxEntityLights=2
-e_GI=0
-e_SkyUpdateRate=0.5
-e_VegetationUseTerrainColor=0
-r_DeferredShadingTiled=0
-r_DeferredShadingTiledHairQuality=0
-r_DeferredShadingSSS=0
-r_AntialiasingMode=0
-r_DetailDistance=4
-r_EnvTexUpdateInterval=0.075
-r_Refraction=0
-r_RefractionPartialResolves=0
-r_ssdo=0
-r_ssdoHalfRes=1
-r_ssdoColorBleeding=0
-r_SSReflections=0
-sys_spec_Quality=1
-
-[2]
-e_DynamicLightsMaxEntityLights=2
-e_GI=0
-e_SkyUpdateRate=0.5
-e_VegetationUseTerrainColor=0
-r_DeferredShadingTiled=0
-r_DeferredShadingTiledHairQuality=0
-r_DeferredShadingSSS=0
-r_AntialiasingMode=0
-r_DetailDistance=4
-r_EnvTexUpdateInterval=0.075
-r_RefractionPartialResolves=0
-r_ssdo=0
-r_ssdoHalfRes=1
-r_ssdoColorBleeding=0
-r_SSReflections=0
-sys_spec_Quality=2
-
-[3]
-e_DynamicLightsMaxEntityLights=2
-e_GI=0
-e_SkyUpdateRate=0.5
-e_VegetationUseTerrainColor=0
-r_DeferredShadingTiled=0
-r_DeferredShadingTiledHairQuality=0
-r_DeferredShadingSSS=0
-r_AntialiasingMode=0
-r_DetailDistance=4
-r_EnvTexUpdateInterval=0.075
-r_RefractionPartialResolves=0
-r_ssdo=0
-r_ssdoColorBleeding=0
-r_SSReflections=0
-sys_spec_Quality=3
-
-[4]
-e_DynamicLightsMaxEntityLights=2
-e_GI=0
-e_SkyUpdateRate=0.5
-e_VegetationUseTerrainColor=0
-r_DeferredShadingTiled=0
-r_DeferredShadingTiledHairQuality=0
-r_DeferredShadingSSS=0
-r_AntialiasingMode=0
-r_DetailDistance=4
-r_EnvTexUpdateInterval=0.075
-r_RefractionPartialResolves=0
-r_ssdo=1
-r_ssdoHalfRes=1
-r_ssdoColorBleeding=0
-r_SSReflections=0
-sys_spec_Quality=4
-
-[5]
-e_DynamicLightsMaxEntityLights=7
-e_GI=0
-e_SkyUpdateRate=0.5
-r_DetailDistance=4
-r_EnvTexUpdateInterval=0.075
-r_SSReflections=0
-r_DeferredShadingTiledHairQuality=0
-r_DeferredShadingSSS=0
-sys_spec_Quality=5
-
-[6]
-e_DynamicLightsMaxEntityLights=11
-sys_spec_Quality=6
-
-[8]
-r_DeferredShadingTiledHairQuality=2
-r_SSReflHalfRes=0
-sys_spec_Quality=8
diff --git a/Assets/Engine/Config/CVarGroups/sys_spec_Shadows.cfg b/Assets/Engine/Config/CVarGroups/sys_spec_Shadows.cfg
deleted file mode 100644
index d43c28c09d..0000000000
--- a/Assets/Engine/Config/CVarGroups/sys_spec_Shadows.cfg
+++ /dev/null
@@ -1,116 +0,0 @@
-[default]
-; default of this CVarGroup
-= 7
-
-e_GsmLodsNum=5
-e_GsmRange=3
-e_ParticlesShadows=1
-e_Shadows=1
-e_ShadowsBlendCascades=1
-e_ShadowsClouds=1
-e_ShadowsCastViewDistRatio=1
-e_ShadowsLodBiasFixed=0
-e_ShadowsMaxTexRes=1024
-e_ShadowsOnAlphaBlend=0
-e_ShadowsPoolSize=4096
-e_ShadowsResScale=4
-e_ShadowsTessellateCascades=1
-e_ShadowsTessellateDLights=0
-e_ShadowsUpdateViewDistRatio=256
-r_DrawNearShadows=1
-r_FogShadows=2
-r_FogShadowsWater=0
-r_ShadowJittering=2.5
-r_ShadowPoolMaxFrames=30
-r_ShadowPoolMaxTimeslicedUpdatesPerFrame=100
-r_ShadowsPCFiltering=1
-r_ShadowsCache=4
-r_ShadowsCacheFormat=1
-r_ShadowsCacheResolutions=6324,4214
-r_ShadowsUseClipVolume=1
-e_ObjShadowCastSpec=3
-
-[1]
-e_GsmLodsNum=3
-e_ParticlesShadows=0
-e_ShadowsBlendCascades=0
-e_ShadowsCastViewDistRatio=0.8
-e_ShadowsLodBiasFixed=1
-e_ShadowsMaxTexRes=512
-r_DrawNearShadows=0
-r_FogShadows=0
-r_ShadowJittering=0
-r_ShadowsCacheFormat=0
-r_ShadowsCacheResolutions=3162,2107
-e_ObjShadowCastSpec=1
-e_ShadowsPoolSize=1024
-
-[2]
-e_GsmLodsNum=4
-e_ParticlesShadows=0
-e_ShadowsBlendCascades=0
-e_ShadowsCastViewDistRatio=0.8
-e_ShadowsLodBiasFixed=1
-e_ShadowsMaxTexRes=512
-r_DrawNearShadows=0
-r_FogShadows=0
-r_ShadowJittering=0
-r_ShadowsCacheFormat=0
-r_ShadowsCacheResolutions=3162,2107
-e_ObjShadowCastSpec=1
-e_ShadowsPoolSize=1024
-
-[3]
-e_GsmLodsNum=4
-e_ParticlesShadows=0
-e_ShadowsBlendCascades=0
-e_ShadowsCastViewDistRatio=0.8
-e_ShadowsLodBiasFixed=1
-e_ShadowsMaxTexRes=512
-r_DrawNearShadows=0
-r_FogShadows=0
-r_ShadowJittering=0
-r_ShadowsCacheFormat=0
-r_ShadowsCacheResolutions=3162,2107
-e_ObjShadowCastSpec=1
-e_ShadowsPoolSize=1024
-
-[4]
-e_GsmLodsNum=4
-e_ParticlesShadows=0
-e_ShadowsBlendCascades=0
-e_ShadowsCastViewDistRatio=0.8
-e_ShadowsLodBiasFixed=1
-e_ShadowsMaxTexRes=512
-r_DrawNearShadows=0
-r_FogShadows=0
-r_ShadowJittering=0
-r_ShadowsCacheFormat=0
-r_ShadowsCacheResolutions=3162,2107
-e_ObjShadowCastSpec=1
-e_ShadowsPoolSize=1024
-
-[5]
-e_GsmLodsNum=4
-e_ParticlesShadows=0
-e_ShadowsBlendCascades=0
-e_ShadowsCastViewDistRatio=0.8
-e_ShadowsLodBiasFixed=1
-e_ShadowsMaxTexRes=512
-r_FogShadows=0
-r_ShadowJittering=1
-e_ObjShadowCastSpec=1
-r_ShadowsCacheResolutions=3162,2107
-
-[6]
-r_ShadowJittering=1
-e_ObjShadowCastSpec=2
-
-[8]
-r_FogShadows=1
-r_FogShadowsWater=1
-r_ShadowPoolMaxFrames=0
-r_ShadowPoolMaxTimeslicedUpdatesPerFrame=100
-e_ObjShadowCastSpec=4
-r_ShadowsCache=5
-r_ShadowsCacheResolutions=4214
diff --git a/Assets/Engine/Config/CVarGroups/sys_spec_Sound.cfg b/Assets/Engine/Config/CVarGroups/sys_spec_Sound.cfg
deleted file mode 100644
index 42bd4c7f02..0000000000
--- a/Assets/Engine/Config/CVarGroups/sys_spec_Sound.cfg
+++ /dev/null
@@ -1,17 +0,0 @@
-[default]
-; default of this CVarGroup
-= 7
-
-[1]
-
-[2]
-
-[3]
-
-[4]
-
-[5]
-
-[6]
-
-[8]
diff --git a/Assets/Engine/Config/CVarGroups/sys_spec_Texture.cfg b/Assets/Engine/Config/CVarGroups/sys_spec_Texture.cfg
deleted file mode 100644
index 0e02c41ab2..0000000000
--- a/Assets/Engine/Config/CVarGroups/sys_spec_Texture.cfg
+++ /dev/null
@@ -1,94 +0,0 @@
-[default]
-; default of this CVarGroup
-= 7
-
-e_TerrainTextureStreamingPoolItemsNum=64
-r_DynTexAtlasCloudsMaxSize=32
-r_DynTexAtlasSpritesMaxSize=32
-r_DynTexMaxSize=80
-r_EnvCMResolution=2
-r_EnvTexResolution=3
-r_ImposterRatio=1
-r_TexAtlasSize=2048
-r_TexMaxAnisotropy=4
-r_TexMinAnisotropy=4
-r_TexNoAnisoAlphaTest=0
-
-[1]
-e_TerrainTextureStreamingPoolItemsNum=16
-r_DynTexAtlasCloudsMaxSize=8
-r_DynTexAtlasSpritesMaxSize=8
-r_DynTexMaxSize=20
-r_EnvCMResolution=0
-r_EnvTexResolution=1
-r_ImposterRatio=2
-r_TexAtlasSize=512
-r_TexMaxAnisotropy=2
-r_TexMinAnisotropy=2
-r_TexNoAnisoAlphaTest=1
-
-[2]
-e_TerrainTextureStreamingPoolItemsNum=16
-r_DynTexAtlasCloudsMaxSize=8
-r_DynTexAtlasSpritesMaxSize=8
-r_DynTexMaxSize=20
-r_EnvCMResolution=0
-r_EnvTexResolution=1
-r_ImposterRatio=2
-r_TexAtlasSize=512
-r_TexMaxAnisotropy=2
-r_TexMinAnisotropy=2
-r_TexNoAnisoAlphaTest=1
-
-[3]
-e_TerrainTextureStreamingPoolItemsNum=16
-r_DynTexAtlasCloudsMaxSize=8
-r_DynTexAtlasSpritesMaxSize=8
-r_DynTexMaxSize=20
-r_EnvCMResolution=0
-r_EnvTexResolution=1
-r_ImposterRatio=2
-r_TexAtlasSize=512
-r_TexMaxAnisotropy=2
-r_TexMinAnisotropy=2
-r_TexNoAnisoAlphaTest=1
-
-[4]
-e_TerrainTextureStreamingPoolItemsNum=16
-r_DynTexAtlasCloudsMaxSize=8
-r_DynTexAtlasSpritesMaxSize=8
-r_DynTexMaxSize=20
-r_EnvCMResolution=0
-r_EnvTexResolution=1
-r_ImposterRatio=2
-r_TexAtlasSize=512
-r_TexMaxAnisotropy=2
-r_TexMinAnisotropy=2
-r_TexNoAnisoAlphaTest=1
-
-[5]
-r_DynTexAtlasCloudsMaxSize=24
-r_DynTexAtlasSpritesMaxSize=16
-r_DynTexMaxSize=50
-r_EnvCMResolution=0
-r_EnvTexResolution=1
-r_ImposterRatio=2
-r_TexAtlasSize=512
-r_TexMaxAnisotropy=2
-r_TexMinAnisotropy=2
-r_TexNoAnisoAlphaTest=1
-
-[6]
-r_DynTexAtlasCloudsMaxSize=24
-r_DynTexAtlasSpritesMaxSize=16
-r_DynTexMaxSize=60
-r_EnvCMResolution=1
-r_EnvTexResolution=2
-r_ImposterRatio=1.5
-r_TexMaxAnisotropy=8
-r_TexMinAnisotropy=8
-r_TexNoAnisoAlphaTest=1
-
-[8]
-r_TexMaxAnisotropy=16
-r_TexMinAnisotropy=16
diff --git a/Assets/Engine/Config/CVarGroups/sys_spec_TextureResolution.cfg b/Assets/Engine/Config/CVarGroups/sys_spec_TextureResolution.cfg
deleted file mode 100644
index 6b6c11ddf6..0000000000
--- a/Assets/Engine/Config/CVarGroups/sys_spec_TextureResolution.cfg
+++ /dev/null
@@ -1,52 +0,0 @@
-[default]
-; dummy default for this CVarGroup (will be auto initialized during streaming system init or overridden by user via system.cfg)
-= 0
-
-; VRAM 1.0 GB
-r_TexturesStreaming=1
-r_TexturesStreamingMipBias=0
-r_TexturesstreamingMinUsableMips=8
-r_TexturesStreamingSkipMips=2
-r_TexturesStreamPoolSize=256
-
-[1]
-; VRAM 1.0 GB
-r_TexturesStreaming=0
-r_TexturesStreamingSkipMips=0
-r_TexturesStreamPoolSize=384
-
-[2]
-; VRAM 1.0 GB
-r_TexturesStreaming=0
-r_TexturesStreamingSkipMips=0
-r_TexturesStreamPoolSize=384
-
-[3]
-; VRAM 1.0 GB
-r_TexturesStreaming=0
-r_TexturesStreamingSkipMips=0
-r_TexturesStreamPoolSize=384
-
-[4]
-; VRAM 1.0 GB
-r_TexturesStreaming=0
-r_TexturesStreamingSkipMips=0
-r_TexturesStreamPoolSize=384
-
-[5]
-; VRAM 1.0 GB
-
-[6]
-; VRAM 1.5 GB
-r_TexturesStreamingSkipMips=1
-r_TexturesStreamPoolSize=512
-
-[7]
-; VRAM 2.0 GB
-r_TexturesStreamingSkipMips=0
-r_TexturesStreamPoolSize=640
-
-[8]
-; VRAM 3.0 GB
-r_TexturesStreamingSkipMips=0
-r_TexturesStreamPoolSize=1536
\ No newline at end of file
diff --git a/Assets/Engine/Config/CVarGroups/sys_spec_VolumetricEffects.cfg b/Assets/Engine/Config/CVarGroups/sys_spec_VolumetricEffects.cfg
deleted file mode 100644
index b6fdfec33c..0000000000
--- a/Assets/Engine/Config/CVarGroups/sys_spec_VolumetricEffects.cfg
+++ /dev/null
@@ -1,26 +0,0 @@
-[default]
-; default of this CVarGroup
-= 7
-
-e_Clouds=1
-r_Beams=1
-
-[1]
-r_Beams=0
-
-[2]
-r_Beams=0
-
-[3]
-r_Beams=0
-
-[4]
-r_Beams=0
-
-[5]
-r_Beams=0
-
-[6]
-r_Beams=0
-
-[8]
diff --git a/Assets/Engine/Config/CVarGroups/sys_spec_Water.cfg b/Assets/Engine/Config/CVarGroups/sys_spec_Water.cfg
deleted file mode 100644
index 720339dc98..0000000000
--- a/Assets/Engine/Config/CVarGroups/sys_spec_Water.cfg
+++ /dev/null
@@ -1,81 +0,0 @@
-[default]
-; default of this CVarGroup
-= 7
-
-e_WaterOceanFFT=1
-e_WaterTessellationAmount=10
-e_WaterTessellationSwathWidth=10
-q_ShaderWater=2
-r_WaterCaustics=1
-r_WaterReflections=1
-r_WaterReflectionsQuality=4
-r_WaterReflectionsMinVisiblePixelsUpdate=0.05
-r_WaterTessellationHW=0
-r_WaterUpdateDistance=0.2
-r_WaterUpdateFactor=0.0
-r_WaterVolumeCaustics=0
-r_WaterVolumeCausticsDensity=256
-r_WaterVolumeCausticsMaxDist=35
-r_WaterVolumeCausticsRes=1024
-r_WaterVolumeCausticsSnapFactor=1
-
-[1]
-e_WaterTessellationAmount=20
-q_ShaderWater=1
-r_WaterReflectionsQuality=0
-r_WaterUpdateDistance=1
-r_WaterUpdateFactor=0.1
-r_WaterVolumeCausticsDensity=64
-r_WaterVolumeCausticsMaxDist=20
-r_WaterVolumeCausticsRes=384
-
-[2]
-e_WaterTessellationAmount=20
-q_ShaderWater=1
-r_WaterReflectionsQuality=0
-r_WaterUpdateDistance=1
-r_WaterUpdateFactor=0.1
-r_WaterVolumeCausticsDensity=64
-r_WaterVolumeCausticsMaxDist=20
-r_WaterVolumeCausticsRes=384
-
-[3]
-e_WaterTessellationAmount=20
-q_ShaderWater=1
-r_WaterReflectionsQuality=0
-r_WaterUpdateDistance=1
-r_WaterUpdateFactor=0.05
-r_WaterVolumeCausticsDensity=64
-r_WaterVolumeCausticsMaxDist=20
-r_WaterVolumeCausticsRes=384
-
-[4]
-e_WaterTessellationAmount=20
-q_ShaderWater=1
-r_WaterReflectionsQuality=4
-r_WaterUpdateDistance=1
-r_WaterUpdateFactor=0.01
-r_WaterVolumeCausticsDensity=64
-r_WaterVolumeCausticsMaxDist=20
-r_WaterVolumeCausticsRes=384
-
-[5]
-e_WaterTessellationAmount=20
-q_ShaderWater=1
-r_WaterUpdateDistance=1
-r_WaterUpdateFactor=0.1
-r_WaterVolumeCausticsDensity=64
-r_WaterVolumeCausticsMaxDist=20
-r_WaterVolumeCausticsRes=384
-
-[6]
-r_WaterUpdateDistance=1
-r_WaterUpdateFactor=0.05
-r_WaterVolumeCausticsDensity=128
-r_WaterVolumeCausticsMaxDist=25
-r_WaterVolumeCausticsRes=512
-
-[8]
-e_WaterTessellationAmount=85
-r_WaterTessellationHW=1
-r_WaterVolumeCaustics=1
diff --git a/Assets/Engine/Config/aidebug.cfg b/Assets/Engine/Config/aidebug.cfg
index f8134c7461..b0eafaaa45 100644
--- a/Assets/Engine/Config/aidebug.cfg
+++ b/Assets/Engine/Config/aidebug.cfg
@@ -1,4 +1 @@
ai_DebugDraw = 1
-ai_DebugDrawNavigation = 1
-ai_DrawPath all
-ai_debugMNMAgentType MediumSizedCharacters
\ No newline at end of file
diff --git a/Assets/Engine/Config/artprof.cfg b/Assets/Engine/Config/artprof.cfg
index 2e1cf55a54..92b91623bf 100644
--- a/Assets/Engine/Config/artprof.cfg
+++ b/Assets/Engine/Config/artprof.cfg
@@ -1,7 +1,6 @@
; Setup useful cvars for artists profiling GPU cost
; Once in level (e.g. map c3mp_rooftop_gardens from the frontend/cmdline), in the console:
; exec artprof.cfg
-; Be sure also to set r_shadersAsyncActivation=0 in your user.cfg (or copy artprof_user.cfg -> user.cfg)
; used to allow loading of loose shaders
sys_pakPriority=0
@@ -9,19 +8,8 @@ sys_pakPriority=0
; because it's annoying and not relevant for artists
sys_pakLogInvalidFileAccess=0
-; disable fog volumes and particles as they can be misleading with r_measureOverdraw 4
-e_fogVolumes=0
-e_particles=0
-
; for convenience
-g_infiniteSuitEnergy=1
-g_infiniteAmmo=1
-g_timelimit=0
+
bind o "r_measureOverdraw 0"
bind p "r_measureOverdraw 4"
-bind k "r_artProfile 0"
-bind l "r_artProfile 1"
-
-; loading into an MP level with the map command stops you looking up and down unless you have a weapon
-i_giveitem scar
diff --git a/Assets/Engine/Config/artprof_user.cfg b/Assets/Engine/Config/artprof_user.cfg
index 673436f6f3..265021e120 100644
--- a/Assets/Engine/Config/artprof_user.cfg
+++ b/Assets/Engine/Config/artprof_user.cfg
@@ -1,6 +1,3 @@
-; disable async shader activation as it crashes when r_shadersAllowCompilation=1
-r_shadersAsyncActivation=0
-
; enable shader compiliation for r_measureOverdraw 4
r_shadersAllowCompilation=1
diff --git a/Assets/Engine/Config/benchmark_cpu.cfg b/Assets/Engine/Config/benchmark_cpu.cfg
index c75619107f..bbb3c9db95 100644
--- a/Assets/Engine/Config/benchmark_cpu.cfg
+++ b/Assets/Engine/Config/benchmark_cpu.cfg
@@ -1,13 +1,3 @@
-demo_restart_level = 2
-g_godMode=1
-g_infiniteammo=1
r_displayinfo=1
-demo_file = autotest
-demo_ai = 1
-demo_num_runs = 4
-demo_quit = 1
-hud_startPaused=0
sys_maxfps=0
-e_ObjectLayersActivation=0
-sys_flash = 0
r_vsync = 0
diff --git a/Assets/Engine/Config/benchmark_gpu.cfg b/Assets/Engine/Config/benchmark_gpu.cfg
index 7653b32d86..f0242d64d1 100644
--- a/Assets/Engine/Config/benchmark_gpu.cfg
+++ b/Assets/Engine/Config/benchmark_gpu.cfg
@@ -1,13 +1,3 @@
-demo_restart_level = 1
-g_godMode = 1
-g_infiniteammo = 1
r_displayinfo = 2
-demo_file = timedemo_short
-demo_ai = 0
-demo_num_runs = 2
-demo_quit = 1
--- hud_startPaused = 0
sys_maxfps = -1
--- e_ObjectLayersActivation = 0
--- sys_flash = 0
-r_vsync = 0
\ No newline at end of file
+r_vsync = 0
diff --git a/Assets/Engine/Config/mgpu.cfg b/Assets/Engine/Config/mgpu.cfg
index 93da7fdfd0..e69de29bb2 100644
--- a/Assets/Engine/Config/mgpu.cfg
+++ b/Assets/Engine/Config/mgpu.cfg
@@ -1,6 +0,0 @@
-r_ColorGradingChartsCache = 0
-r_waterupdateFactor = 0
-r_PostProcessHUD3DCache = 0
-e_gsmcache = 0
-r_ConditionalRendering = 0
-e_gicache = 0
\ No newline at end of file
diff --git a/Assets/Engine/Config/multiplayer.cfg b/Assets/Engine/Config/multiplayer.cfg
index eafa434f8e..e69de29bb2 100644
--- a/Assets/Engine/Config/multiplayer.cfg
+++ b/Assets/Engine/Config/multiplayer.cfg
@@ -1,77 +0,0 @@
-ag_turnSpeedParamScale=0.0
-aim_assistFalloffDistance=200
-aim_assistInputForFullFollow_Ironsight=0.20
-aim_assistMaxDistance=255
-aim_assistMaxDistance_ironsight=255
-aim_assistMinTurnScale=0.5
-aim_assistMinTurnScale_ironsight=0.5
-aim_assistSlowDisableDistance=255
-aim_assistSlowFalloffStartDistance=200
-aim_assistSlowThresholdOuter=2.5
-aim_assiststrength=0.7
-aim_assiststrength_ironsight=0.75
-br_breakmaxworldsize=511
-cl_sensitivityControllerMP=0.6
-cl_shallowWaterSpeedMulPlayer=1.0
-controller_multiplier_x=3
-controller_multiplier_z=4
-g_actorViewDistRatio=255
-
--- This forces broken trees to have spherical inertia, which makes them harder to rotate around their vertical axis.
-g_breakageMinAxisInertia=1.0
-g_glassAutoShatterMinArea=0.5
-
-g_distanceForceNoIk=35
-g_fpDbaManagementEnable=0
-g_godMode=0
-g_highlightingMaxDistanceToHighlightSquared=625
-g_hitDeathReactions_streaming=2
-g_mp_as_DefendersMaxHealth=150
-g_multiplayerDefault=1
-
--- Overriden in GameSDK\Difficulty\*.cfg
-g_playerLowHealthThreshold=20
-g_playerMidHealthThreshold=60
-
-g_spawn_vistable_numLineTestsPerFrame=3
-g_telemetryConfig="MP"
-g_telemetrySampleRateBandwidth=3
-g_telemetrySampleRateMemory=2
-g_telemetrySampleRatePerformance=1
-g_VTOLInsideBoundsScaleX=0.6
-g_VTOLInsideBoundsScaleY=1
-net_breakage_sync_entities=0
-net_enable_tfrc=0
-net_log=1
-
--- Make consoles match the PC gravity
-p_gravity_z="-13"
-
--- Sanity check for physics RepositionEntity
-p_max_entity_cells=10000
-
-pl_impulseEnabled=1
-pl_jump_maxTimerValue=0.0
-pl_jump_quickPressThresh=0.12
-pl_melee.angle_limit_from_behind=70
-pl_melee.impulses_enable=1
-pl_melee.melee_snap_angle_limit=45
-pl_melee.melee_snap_end_position_range=1.5
-pl_melee.melee_snap_move_speed_multiplier=10
-pl_melee.melee_snap_target_select_range=3.5
-pl_melee.mp_knockback_strength_hor=2
-pl_melee.mp_melee_system=1
-pl_melee.mp_victim_screenfx_blendout_duration=0.25
-pl_melee.mp_victim_screenfx_duration=0.1
-pl_nanovision_timetodrain=8
-pl_nanovision_timetorecharge=16
-pl_pickAndThrow.chargedThrowAutoAimConeSize=10
-pl_pickAndThrow.complexMelee_snap_angle_limit=25
-pl_sliding_control_mp.deceleration_speed=4
-pl_sliding_control_mp.max_downhill_acceleration=15
-pl_sliding_control_mp.min_speed=4
-pl_sliding_control_mp.min_speed_threshold=5
-pl_stealthKill_aimVsSpineLerp=0.65
-pl_stealthKill_useExtendedRange=1
-p_splash_vel0=0.5
-sv_bandwidth=2147483647
\ No newline at end of file
diff --git a/Assets/Engine/Config/multiplayer_console.cfg b/Assets/Engine/Config/multiplayer_console.cfg
index 0bed002497..e69de29bb2 100644
--- a/Assets/Engine/Config/multiplayer_console.cfg
+++ b/Assets/Engine/Config/multiplayer_console.cfg
@@ -1,29 +0,0 @@
-e_GI=0
-r_DeferredShadingIndexedAmbient=0
-e_ParticlesObjectCollisions=0
-g_distanceForceNoLegRaycasts=0.00001
-g_telemetryDisplaySessionId=1
-g_breakageNoDebrisCollisions=1
-
-; Breakage throttling
-; These are explained in ActionGame.cpp
-;
-g_glassAutoShatterOnExplosions=1
-g_glassNoDecals=1
-g_glassMaxPanesToBreakPerFrame=2
-g_breakageTreeMax=100
-g_breakageTreeInc=101
-g_breakageTreeDec=25
-g_breakageTreeIncGlass=51
-
-sys_PakInMemoryPakSizeLimit=25
-
-r_TexturesStreamPoolSecondarySize=35
-r_MotionBlur=1
-
-e_CoverageBufferReproj=2
-
-osm_enabled = 1
-
-g_waterHitOnly = 1
-p_max_object_splashes=1
diff --git a/Assets/Engine/Config/recording.cfg b/Assets/Engine/Config/recording.cfg
index 42a0dfd9bd..931dbf0858 100644
--- a/Assets/Engine/Config/recording.cfg
+++ b/Assets/Engine/Config/recording.cfg
@@ -1,63 +1,3 @@
--- added this lines for proper 360 deg panorama renderings
-
-e_ScreenShotFileFormat = jpg
-demo_fixed_timestep = 60
-s_SoundEnable = 0
r_DisplayInfo = 0
-e_PanoramaScreenShotHeight = 720
-e_PanoramaScreenShotWidth = 10053
c_shakeMult = 0
-demo_ai = 1
-r_MotionBlur = 0
-
--- enables full water reflection
--- e_DebugMask = 2 -- e_DebugMask not allowed here
-
--- set weapong lighting effect to 0 to prevent flickering bug because of too much dynamic lights in the scene
-
-
sys_spec = 2
-r_WaterRefractions = 1
-r_WaterReflections = 1
-r_WaterUpdateFactor = 0.01
-r_WaterReflections_ForceParticles = 0
-
-r_EnvCMResolution = 2
-r_EnvTexResolution = 3
-r_EnvTexUpdateInterval = 0.05
-e_Decals = 1
-e_DecalsLifeTimeScale = 2
-ca_EnableDecals = 1
-e_LodRatio = 10
-e_ViewDistRatio = 55
-e_Lods = 1
-e_VegetationMinSize = 0
-r_CloudsUpdateAlways = 0
-
-e_DynamicLightsMaxEntityLights = 3
-r_DepthOfField = 1
---r_MotionBlur = 1
-r_Flares = 1
-r_checkSunVis = 1
-r_Coronas = 1
-r_CoronaFade = 0.1625
-r_UseEdgeAA = 1
-e_Clouds = 1
-
-r_TexResolution = 0
-r_TexBumpResolution = 0
-r_DetailTextures = 1
-r_DetailNumLayers = 1
-r_DetailDistance = 8
-
-e_ParticlesLod = 0.9
-
-r_ShadowBlur = 3
-e_ShadowsMaxTexRes = 1024
-r_ShadowJittering = 1
-e_Shadows = 1
-e_VegetationBending = 1
-ai_UpdateAllAlways = 1
-r_refraction = 1
-r_sunshafts = 1
-r_ImposterRatio = 1
diff --git a/Assets/Engine/Config/singleplayer.cfg b/Assets/Engine/Config/singleplayer.cfg
index fc7a4f4c05..e69de29bb2 100644
--- a/Assets/Engine/Config/singleplayer.cfg
+++ b/Assets/Engine/Config/singleplayer.cfg
@@ -1,15 +0,0 @@
-ai_CompatibilityMode=crysis2
-ai_BurstWhileMovingDestinationRange=9999.0
-
-g_telemetryConfig=SP
-
-net_inactivitytimeout=3600
-net_inactivitytimeoutDevmode=3600
-
-pl_movement.nonCombat_heavy_weapon_speed_scale=1.0
-
--- BLM - Don't override game rules. The template project only has DummyRules.
--- Furthermore, multiplayer.cfg doesn't set sv_gamerules, so the inconsistency
--- is likely to create bugs.
---sv_gamerules=SinglePlayer
-ca_StreamCHR=1
\ No newline at end of file
diff --git a/Assets/Engine/Config/sketch_off.cfg b/Assets/Engine/Config/sketch_off.cfg
deleted file mode 100644
index 6b0562daab..0000000000
--- a/Assets/Engine/Config/sketch_off.cfg
+++ /dev/null
@@ -1,24 +0,0 @@
-r_UseZPass = 1
-r_GeomInstancing = 1
-
-e_Fog = 1
-e_Clouds = 1
-e_Decals = 1
-e_TerrainDetailMaterials = 1
-e_Dissolve = 1
-e_TerrainAo = 1
-
-r_WaterReflections = 1
-
-e_Shadows = 1
-e_VegetationBending = 1
-
-r_PostProcessEffects = 1
-r_Flares = 1
-r_Beams = 1
-r_Glow = 1
-
-r_DetailTextures = 1
-
-r_refraction = 1
-r_sunshafts = 1
\ No newline at end of file
diff --git a/Assets/Engine/Config/sketch_on.cfg b/Assets/Engine/Config/sketch_on.cfg
deleted file mode 100644
index 6759b5d4c8..0000000000
--- a/Assets/Engine/Config/sketch_on.cfg
+++ /dev/null
@@ -1,24 +0,0 @@
-r_UseZPass = 0
-r_GeomInstancing = 0
-
-e_Fog = 0
-e_Clouds = 0
-e_Decals = 0
-e_TerrainDetailMaterials = 0
-e_Dissolve = 0
-e_TerrainAo = 0
-
-r_WaterReflections = 0
-
-e_Shadows = 0
-e_VegetationBending = 0
-
-r_PostProcessEffects = 0
-r_Flares = 0
-r_Beams = 0
-r_Glow = 0
-
-r_DetailTextures = 0
-
-r_refraction = 0
-r_sunshafts = 0
\ No newline at end of file
diff --git a/Assets/Engine/Config/spec/android_MaliT760.cfg b/Assets/Engine/Config/spec/android_MaliT760.cfg
index f951e61eef..fd7c0a349d 100644
--- a/Assets/Engine/Config/spec/android_MaliT760.cfg
+++ b/Assets/Engine/Config/spec/android_MaliT760.cfg
@@ -1,76 +1,8 @@
-sys_spec_Full=2
-
-- Cap frame rate at 30fps
sys_maxfps=30
r_vsync=0
--- Disable gmem for this device because it causes a crash
-r_EnableGMEMPath=0
-
--- Default of 3 allocates all shaders (potentially >150 MB)
--- 1 is most memory efficient but definitely causes hitches when converting HLSL
--- shaders. Recommend 1 during dev, and 3 with optimized caches for release.
-r_ShadersPreactivate=1
-
-sys_job_system_max_worker=2
sys_streaming_in_blocks=1
sys_streaming_memory_budget=512
--- This allows the generation of reflections for the ocean water. Without it, the water looks really dark.
-e_recursion=1
-e_CheckOcclusion=1
-
-r_Fur=0
-az_Asset_EnableAsyncMeshLoading=0
-
-------------------------
--- Misc. memory buffers
-------------------------
-e_GeomCacheBufferSize=0
-e_CheckOcclusionQueueSize=512
-e_CheckOcclusionOutputQueueSize=1024
-
-------------------------
--- Animation
-------------------------
-ca_MemoryDefragPoolSize=33554432
-ca_StreamCHR=1
-
-------------------------
--- sys_spec_objectdetail
-------------------------
-e_Dissolve=2
-e_LodRatio=5
-e_ViewDistRatioDetail=19
-e_ViewDistRatioVegetation=21
-
-
-------------------------
--- sys_spec_postprocessing
-------------------------
-r_HDRBloom=0
-r_SunShafts=0
-r_ToneMapTechnique=3
-r_ToneMapExposureType=1
-r_ColorSpace=2
-
-------------------------
--- sys_spec_shading
-------------------------
-r_VisAreaClipLightsPerPixel=0
-
-------------------------
--- sys_spec_textureresolution
-------------------------
-r_TexturesstreamingMinUsableMips=7
-
-
-
--- Due to performance issues with incremental cached shadow map updates, enable this to prevent us from culling every object in the world vs each cached shadow map each frame.
--- If no objects are present in the level this will eliminate the need to clear the massive cached textures each frame.
--- Set to 2 to allow distance-based updates along with script-based updates for the cached shadow maps
-e_ShadowsCacheRequireManualUpdate = 2
-
---Use an optimized pixel format for the lighting rendertargets during the lighting pass.
-r_DeferredShadingLBuffersFmt = 2
\ No newline at end of file
diff --git a/Assets/Engine/Config/spec/android_high.cfg b/Assets/Engine/Config/spec/android_high.cfg
index fc46adc491..0ab8ebc37b 100644
--- a/Assets/Engine/Config/spec/android_high.cfg
+++ b/Assets/Engine/Config/spec/android_high.cfg
@@ -1,65 +1,7 @@
-sys_spec_Full=3
-
-- Cap frame rate at 30fps
sys_maxfps=30
r_vsync=0
--- Enable framebufferfetch(256bpp) or pls if applicable
-r_EnableGMEMPath=2
-
--- Skip the native upscale as a second upscale already occurs
-r_SkipNativeUpscale=1
-
--- Default of 3 allocates all shaders (potentially >150 MB)
--- 1 is most memory efficient but definitely causes hitches when converting HLSL
--- shaders. Recommend 1 during dev, and 3 with optimized caches for release.
-r_ShadersPreactivate=1
-
-sys_job_system_max_worker=2
sys_streaming_in_blocks=1
sys_streaming_memory_budget=512
-
-e_CheckOcclusion=1
-
-r_Fur=0
-az_Asset_EnableAsyncMeshLoading=0
-
-------------------------
--- Misc. memory buffers
-------------------------
-e_GeomCacheBufferSize=0
-e_CheckOcclusionQueueSize=512
-e_CheckOcclusionOutputQueueSize=1024
-
-------------------------
--- Animation
-------------------------
-ca_MemoryDefragPoolSize=33554432
-ca_StreamCHR=1
-
-------------------------
--- sys_spec_objectdetail
-------------------------
-e_Dissolve=2
-e_LodRatio=5
-e_ViewDistRatioDetail=19
-
-
-------------------------
--- sys_spec_shading
-------------------------
-r_VisAreaClipLightsPerPixel=0
-
--- Due to performance issues with incremental cached shadow map updates, enable this to prevent us from culling every object in the world vs each cached shadow map each frame.
--- If no objects are present in the level this will eliminate the need to clear the massive cached textures each frame.
--- Set to 2 to allow distance-based updates along with script-based updates for the cached shadow maps
-e_ShadowsCacheRequireManualUpdate = 2
-
-r_ClearGMEMGBuffer=1
-
--- Sort ligths since we have limited space in the shadowmap pool texture
-r_DeferredShadingSortLights = 3
-
---Use an optimized pixel format for the lighting rendertargets during the lighting pass.
-r_DeferredShadingLBuffersFmt = 2
\ No newline at end of file
diff --git a/Assets/Engine/Config/spec/android_high_nogmem.cfg b/Assets/Engine/Config/spec/android_high_nogmem.cfg
index ac718a57ee..fd7c0a349d 100644
--- a/Assets/Engine/Config/spec/android_high_nogmem.cfg
+++ b/Assets/Engine/Config/spec/android_high_nogmem.cfg
@@ -1,61 +1,8 @@
-sys_spec_Full=3
-
-- Cap frame rate at 30fps
sys_maxfps=30
r_vsync=0
--- Disabling gmem for this configuration
-r_EnableGMEMPath=0
-
--- Skip the native upscale as a second upscale already occurs
-r_SkipNativeUpscale=1
-
--- Default of 3 allocates all shaders (potentially >150 MB)
--- 1 is most memory efficient but definitely causes hitches when converting HLSL
--- shaders. Recommend 1 during dev, and 3 with optimized caches for release.
-r_ShadersPreactivate=1
-
-sys_job_system_max_worker=2
sys_streaming_in_blocks=1
sys_streaming_memory_budget=512
-e_CheckOcclusion=1
-
-r_Fur=0
-az_Asset_EnableAsyncMeshLoading=0
-
-------------------------
--- Misc. memory buffers
-------------------------
-e_GeomCacheBufferSize=0
-e_CheckOcclusionQueueSize=512
-e_CheckOcclusionOutputQueueSize=1024
-
-------------------------
--- Animation
-------------------------
-ca_MemoryDefragPoolSize=33554432
-ca_StreamCHR=1
-
-------------------------
--- sys_spec_objectdetail
-------------------------
-e_Dissolve=2
-e_LodRatio=5
-e_ViewDistRatioDetail=19
-
-
-------------------------
--- sys_spec_shading
-------------------------
-r_VisAreaClipLightsPerPixel=0
-
--- Due to performance issues with incremental cached shadow map updates, enable this to prevent us from culling every object in the world vs each cached shadow map each frame.
--- If no objects are present in the level this will eliminate the need to clear the massive cached textures each frame.
--- Set to 2 to allow distance-based updates along with script-based updates for the cached shadow maps
-e_ShadowsCacheRequireManualUpdate = 2
-
---Use an optimized pixel format for the lighting rendertargets during the lighting pass.
-r_DeferredShadingLBuffersFmt = 2
-
diff --git a/Assets/Engine/Config/spec/android_low.cfg b/Assets/Engine/Config/spec/android_low.cfg
index 6f2a876877..0ab8ebc37b 100644
--- a/Assets/Engine/Config/spec/android_low.cfg
+++ b/Assets/Engine/Config/spec/android_low.cfg
@@ -1,76 +1,7 @@
-sys_spec_Full=1
-
-- Cap frame rate at 30fps
sys_maxfps=30
r_vsync=0
--- Enable framebufferfetch(256bpp) or pls if applicable
-r_EnableGMEMPath=1
-
--- Skip the native upscale as a second upscale already occurs
-r_SkipNativeUpscale=1
-
--- Default of 3 allocates all shaders (potentially >150 MB)
--- 1 is most memory efficient but definitely causes hitches when converting HLSL
--- shaders. Recommend 1 during dev, and 3 with optimized caches for release.
-r_ShadersPreactivate=1
-
-sys_job_system_max_worker=2
sys_streaming_in_blocks=1
sys_streaming_memory_budget=512
-
--- This allows the generation of reflections for the ocean water. Without it, the water looks really dark.
-e_recursion=0
-e_CheckOcclusion=1
-
-r_Fur=0
-
--- Water occlusion queries crash in some OpenGL ES 3.0 devices
-e_HwOcclusionCullingWater = 0
-az_Asset_EnableAsyncMeshLoading=0
-
-------------------------
--- Misc. memory buffers
-------------------------
-e_GeomCacheBufferSize=0
-e_CheckOcclusionQueueSize=512
-e_CheckOcclusionOutputQueueSize=1024
-
-------------------------
--- Animation
-------------------------
-ca_MemoryDefragPoolSize=33554432
-ca_StreamCHR=1
-
-------------------------
--- sys_spec_objectdetail
-------------------------
-e_Dissolve=2
-e_LodRatio=5
-e_ViewDistRatioDetail=19
-
-
-------------------------
--- sys_spec_shading
-------------------------
-r_VisAreaClipLightsPerPixel=0
-
-
-------------------------
--- sys_spec_textureresolution
-------------------------
-r_TexturesstreamingMinUsableMips=6
-
-
--- Due to performance issues with incremental cached shadow map updates, enable this to prevent us from culling every object in the world vs each cached shadow map each frame.
--- If no objects are present in the level this will eliminate the need to clear the massive cached textures each frame.
--- Set to 2 to allow distance-based updates along with script-based updates for the cached shadow maps
-e_ShadowsCacheRequireManualUpdate = 2
-
--- Sort ligths since we have limited space in the shadowmap pool texture
-r_DeferredShadingSortLights = 3
-r_ClearGMEMGBuffer=1
-
---Use an optimized pixel format for the lighting rendertargets during the lighting pass.
-r_DeferredShadingLBuffersFmt = 2
\ No newline at end of file
diff --git a/Assets/Engine/Config/spec/android_medium.cfg b/Assets/Engine/Config/spec/android_medium.cfg
index f9d776efa7..0ab8ebc37b 100644
--- a/Assets/Engine/Config/spec/android_medium.cfg
+++ b/Assets/Engine/Config/spec/android_medium.cfg
@@ -1,81 +1,7 @@
-sys_spec_Full=2
-
-- Cap frame rate at 30fps
sys_maxfps=30
r_vsync=0
--- Enable framebufferfetch(256bpp) or pls if applicable
-r_EnableGMEMPath=1
-
--- Skip the native upscale as a second upscale already occurs
-r_SkipNativeUpscale=1
-
--- Default of 3 allocates all shaders (potentially >150 MB)
--- 1 is most memory efficient but definitely causes hitches when converting HLSL
--- shaders. Recommend 1 during dev, and 3 with optimized caches for release.
-r_ShadersPreactivate=1
-
-sys_job_system_max_worker=2
sys_streaming_in_blocks=1
sys_streaming_memory_budget=512
-
--- This allows the generation of reflections for the ocean water. Without it, the water looks really dark.
-e_recursion=1
-e_CheckOcclusion=1
-
-r_Fur=0
-az_Asset_EnableAsyncMeshLoading=0
-
-------------------------
--- Misc. memory buffers
-------------------------
-e_GeomCacheBufferSize=0
-e_CheckOcclusionQueueSize=512
-e_CheckOcclusionOutputQueueSize=1024
-
-------------------------
--- Animation
-------------------------
-ca_MemoryDefragPoolSize=33554432
-ca_StreamCHR=1
-
-------------------------
--- sys_spec_objectdetail
-------------------------
-e_Dissolve=2
-e_LodRatio=5
-e_ViewDistRatioDetail=19
-e_ViewDistRatioVegetation=21
-
-
-------------------------
--- sys_spec_postprocessing
-------------------------
-r_HDRBloom=0
-r_SunShafts=0
-r_ToneMapExposureType=1
-r_ColorSpace=2
-
-------------------------
--- sys_spec_shading
-------------------------
-r_VisAreaClipLightsPerPixel=0
-
-------------------------
--- sys_spec_textureresolution
-------------------------
-r_TexturesstreamingMinUsableMips=7
-
--- Due to performance issues with incremental cached shadow map updates, enable this to prevent us from culling every object in the world vs each cached shadow map each frame.
--- If no objects are present in the level this will eliminate the need to clear the massive cached textures each frame.
--- Set to 2 to allow distance-based updates along with script-based updates for the cached shadow maps
-e_ShadowsCacheRequireManualUpdate = 2
-
-r_ClearGMEMGBuffer=1
-
--- Sort ligths since we have limited space in the shadowmap pool texture
-r_DeferredShadingSortLights = 3
-
---Use an optimized pixel format for the lighting rendertargets during the lighting pass.
-r_DeferredShadingLBuffersFmt = 2
\ No newline at end of file
diff --git a/Assets/Engine/Config/spec/android_veryhigh.cfg b/Assets/Engine/Config/spec/android_veryhigh.cfg
index d4f8e9cd47..d58e319706 100644
--- a/Assets/Engine/Config/spec/android_veryhigh.cfg
+++ b/Assets/Engine/Config/spec/android_veryhigh.cfg
@@ -1,60 +1,5 @@
-sys_spec_Full=4
-
-- Cap frame rate at 30fps
sys_maxfps=30
r_vsync=0
-
--- Enable framebufferfetch(256bpp) or pls if applicable
-r_EnableGMEMPath=1
-
--- Skip the native upscale as a second upscale already occurs
-r_SkipNativeUpscale=1
-
--- Default of 3 allocates all shaders (potentially >150 MB)
--- 1 is most memory efficient but definitely causes hitches when converting HLSL
--- shaders. Recommend 1 during dev, and 3 with optimized caches for release.
-r_ShadersPreactivate=1
-
-sys_job_system_max_worker=2
sys_streaming_in_blocks=1
-
sys_streaming_memory_budget=512
-
-e_CheckOcclusion=1
-
-r_Fur=0
-az_Asset_EnableAsyncMeshLoading=0
-
-------------------------
--- Misc. memory buffers
-------------------------
-e_GeomCacheBufferSize=0
-e_CheckOcclusionQueueSize=512
-e_CheckOcclusionOutputQueueSize=1024
-
-------------------------
--- Animation
-------------------------
-ca_MemoryDefragPoolSize=33554432
-ca_StreamCHR=1
-
-------------------------
--- sys_spec_objectdetail
-------------------------
-e_Dissolve=2
-e_LodRatio=5
-e_ViewDistRatioDetail=19
-
-
-------------------------
--- sys_spec_shading
-------------------------
-r_VisAreaClipLightsPerPixel=0
-
-r_ClearGMEMGBuffer=1
-
--- Sort ligths since we have limited space in the shadowmap pool texture
-r_DeferredShadingSortLights = 3
-
---Use an optimized pixel format for the lighting rendertargets during the lighting pass.
-r_DeferredShadingLBuffersFmt = 2
\ No newline at end of file
diff --git a/Assets/Engine/Config/spec/ios_high.cfg b/Assets/Engine/Config/spec/ios_high.cfg
index 67fa99ca04..d0cf5b3bc5 100644
--- a/Assets/Engine/Config/spec/ios_high.cfg
+++ b/Assets/Engine/Config/spec/ios_high.cfg
@@ -1,100 +1,10 @@
-sys_spec_Full=3
-
-- Cap frame rate at 30fps
sys_maxfps=30
r_vsync=1
--- Enable framebufferfetch or pls if applicable
-r_EnableGMEMPath=1
-
--- Skip the native upscale as a second upscale occurs on Metal Present
-r_SkipNativeUpscale=1
-
--- Default of 3 allocates all shaders (potentially >150 MB)
--- 1 is most memory efficient but definitely causes hitches when converting HLSL
--- shaders. Recommend 1 during dev, and 3 with optimized caches for release.
-r_ShadersPreactivate=1
-
-
-------------------------
--- Job System
-------------------------
-sys_job_system_enable=0
-sys_job_system_max_worker=1
-
------------------------
-- Streaming
------------------------
sys_streaming_in_blocks=1
sys_streaming_memory_budget=512
-------------------------
--- General Rendering
-------------------------
-r_Flush=0
--- Enabling this will clear the GMEM buffer before the z-pass
-r_ClearGMEMGBuffer=2
-r_Fur=0
-
-------------------------
--- VisArea / Portals
-------------------------
-e_PortalsBlend=0
-r_GMEMVisAreasBlendWeight=0.5
-
-------------------------
--- Misc. memory buffers
-------------------------
-e_AutoPrecacheCgf=2
-e_AutoPrecacheTerrainAndProcVeget=1
-e_GeomCacheBufferSize=0
-e_CheckOcclusionQueueSize=512
-e_CheckOcclusionOutputQueueSize=2048
-
-------------------------
--- Animation
-------------------------
-ca_MemoryDefragPoolSize=32
-ca_StreamCHR=1
-
-------------------------
--- sys_spec_water
-------------------------
-e_WaterOcean=2
-e_WaterVolumes=2
-e_WaterOceanBottom=0
-
-------------------------
--- batching
-------------------------
-r_Batching = 1
-r_BatchType = 0
-
-------------------------
--- geom instancing
-------------------------
-r_GeomInstancing=1
-r_GeomInstancingThreshold=5
-
-------------------------
--- Upscaling
-------------------------
---0 point, 1 bilinear, 2 bicubic, 3 lanczos
-r_UpscalingQuality=1
-
-------------------------
--- Geometry Cache
-------------------------
-e_GeomCaches=0
-
-
--- Due to performance issues with incremental cached shadow map updates, enable this to prevent us from culling every object in the world vs each cached shadow map each frame.
--- If no objects are present in the level this will eliminate the need to clear the massive cached textures each frame.
--- Set to 2 to allow distance-based updates along with script-based updates for the cached shadow maps
-e_ShadowsCacheRequireManualUpdate = 2
-
--- Sort ligths since we have limited space in the shadowmap pool texture
-r_DeferredShadingSortLights = 3
-
---Use an optimized pixel format for the lighting rendertargets during the lighting pass.
-r_DeferredShadingLBuffersFmt = 2
\ No newline at end of file
diff --git a/Assets/Engine/Config/spec/ios_low.cfg b/Assets/Engine/Config/spec/ios_low.cfg
index 7870d65bd5..d0cf5b3bc5 100644
--- a/Assets/Engine/Config/spec/ios_low.cfg
+++ b/Assets/Engine/Config/spec/ios_low.cfg
@@ -1,103 +1,10 @@
-sys_spec_Full=1
-
-- Cap frame rate at 30fps
sys_maxfps=30
r_vsync=1
--- Enable framebufferfetch or pls if applicable
-r_EnableGMEMPath=1
-
--- Skip the native upscale as a second upscale occurs on Metal Present
-r_SkipNativeUpscale=1
-
--- Default of 3 allocates all shaders (potentially >150 MB)
--- 1 is most memory efficient but definitely causes hitches when converting HLSL
--- shaders. Recommend 1 during dev, and 3 with optimized caches for release.
-r_ShadersPreactivate=1
-
-
-------------------------
--- Job System
-------------------------
-sys_job_system_enable=0
-sys_job_system_max_worker=1
-
------------------------
-- Streaming
------------------------
sys_streaming_in_blocks=1
sys_streaming_memory_budget=512
-------------------------
--- General Rendering
-------------------------
-r_Flush=0
--- Enabling this will clear the GMEM buffer before the z-pass
-r_ClearGMEMGBuffer=2
-r_Fur=0
-
-------------------------
--- VisArea / Portals
-------------------------
-e_PortalsBlend=0
-r_GMEMVisAreasBlendWeight=0.5
-
-------------------------
--- Misc. memory buffers
-------------------------
-e_AutoPrecacheCgf=2
-e_AutoPrecacheTerrainAndProcVeget=1
-e_GeomCacheBufferSize=0
-e_CheckOcclusionQueueSize=512
-e_CheckOcclusionOutputQueueSize=1024
-
-------------------------
--- Animation
-------------------------
-ca_MemoryDefragPoolSize=32
-ca_StreamCHR=1
-
-------------------------
--- sys_spec_water
-------------------------
-e_WaterOcean=2
-e_WaterVolumes=2
-e_WaterOceanBottom=0
-
-
-------------------------
--- batching
-------------------------
-r_Batching = 1
-r_BatchType = 0
-
-------------------------
--- geom instancing
-------------------------
-r_GeomInstancing=1
-r_GeomInstancingThreshold=5
-
-------------------------
--- Upscaling
-------------------------
---0 point, 1 bilinear, 2 bicubic, 3 lanczos
-r_UpscalingQuality=1
-
-------------------------
--- Geometry Cache
-------------------------
-e_GeomCaches=0
-
-
-
-
--- Due to performance issues with incremental cached shadow map updates, enable this to prevent us from culling every object in the world vs each cached shadow map each frame.
--- If no objects are present in the level this will eliminate the need to clear the massive cached textures each frame.
--- Set to 2 to allow distance-based updates along with script-based updates for the cached shadow maps
-e_ShadowsCacheRequireManualUpdate = 2
-
--- Sort ligths since we have limited space in the shadowmap pool texture
-r_DeferredShadingSortLights = 3
-
---Use an optimized pixel format for the lighting rendertargets during the lighting pass.
-r_DeferredShadingLBuffersFmt = 2
\ No newline at end of file
diff --git a/Assets/Engine/Config/spec/ios_medium.cfg b/Assets/Engine/Config/spec/ios_medium.cfg
index 2eaecdef16..d0cf5b3bc5 100644
--- a/Assets/Engine/Config/spec/ios_medium.cfg
+++ b/Assets/Engine/Config/spec/ios_medium.cfg
@@ -1,101 +1,10 @@
-sys_spec_Full=2
-
-- Cap frame rate at 30fps
sys_maxfps=30
r_vsync=1
--- Enable framebufferfetch or pls if applicable
-r_EnableGMEMPath=1
-
--- Skip the native upscale as a second upscale occurs on Metal Present
-r_SkipNativeUpscale=1
-
--- Default of 3 allocates all shaders (potentially >150 MB)
--- 1 is most memory efficient but definitely causes hitches when converting HLSL
--- shaders. Recommend 1 during dev, and 3 with optimized caches for release.
-r_ShadersPreactivate=1
-
-
-------------------------
--- Job System
-------------------------
-sys_job_system_enable=0
-sys_job_system_max_worker=1
-
------------------------
-- Streaming
------------------------
sys_streaming_in_blocks=1
sys_streaming_memory_budget=512
-------------------------
--- General Rendering
-------------------------
-r_Flush=0
--- Enabling this will clear the GMEM buffer before the z-pass
-r_ClearGMEMGBuffer=2
-r_Fur=0
-
-------------------------
--- VisArea / Portals
-------------------------
-e_PortalsBlend=0
-r_GMEMVisAreasBlendWeight=0.5
-
-------------------------
--- Misc. memory buffers
-------------------------
-e_AutoPrecacheCgf=2
-e_AutoPrecacheTerrainAndProcVeget=1
-e_GeomCacheBufferSize=0
-e_CheckOcclusionQueueSize=512
-e_CheckOcclusionOutputQueueSize=1024
-
-------------------------
--- Animation
-------------------------
-ca_MemoryDefragPoolSize=32
-ca_StreamCHR=1
-
-------------------------
--- sys_spec_water
-------------------------
-e_WaterOcean=2
-e_WaterVolumes=2
-e_WaterOceanBottom=0
-
-
-------------------------
--- batching
-------------------------
-r_Batching = 1
-r_BatchType = 0
-
-------------------------
--- geom instancing
-------------------------
-r_GeomInstancing=1
-r_GeomInstancingThreshold=5
-
-------------------------
--- Upscaling
-------------------------
---0 point, 1 bilinear, 2 bicubic, 3 lanczos
-r_UpscalingQuality=1
-
-------------------------
--- Geometry Cache
-------------------------
-e_GeomCaches=0
-
-
--- Due to performance issues with incremental cached shadow map updates, enable this to prevent us from culling every object in the world vs each cached shadow map each frame.
--- If no objects are present in the level this will eliminate the need to clear the massive cached textures each frame.
--- Set to 2 to allow distance-based updates along with script-based updates for the cached shadow maps
-e_ShadowsCacheRequireManualUpdate = 2
-
--- Sort ligths since we have limited space in the shadowmap pool texture
-r_DeferredShadingSortLights = 3
-
---Use an optimized pixel format for the lighting rendertargets during the lighting pass.
-r_DeferredShadingLBuffersFmt = 2
\ No newline at end of file
diff --git a/Assets/Engine/Config/spec/ios_veryhigh.cfg b/Assets/Engine/Config/spec/ios_veryhigh.cfg
index 53937a77bf..d0cf5b3bc5 100644
--- a/Assets/Engine/Config/spec/ios_veryhigh.cfg
+++ b/Assets/Engine/Config/spec/ios_veryhigh.cfg
@@ -1,102 +1,10 @@
-sys_spec_Full=4
-
-- Cap frame rate at 30fps
sys_maxfps=30
r_vsync=1
--- Enable framebufferfetch or pls if applicable
-r_EnableGMEMPath=1
-
--- Skip the native upscale as a second upscale occurs on Metal Present
-r_SkipNativeUpscale=1
-
--- Default of 3 allocates all shaders (potentially >150 MB)
--- 1 is most memory efficient but definitely causes hitches when converting HLSL
--- shaders. Recommend 1 during dev, and 3 with optimized caches for release.
-r_ShadersPreactivate=1
-
-
-------------------------
--- Job System
-------------------------
-sys_job_system_enable=0
-sys_job_system_max_worker=1
-
------------------------
-- Streaming
------------------------
sys_streaming_in_blocks=1
sys_streaming_memory_budget=512
-------------------------
--- General Rendering
-------------------------
-r_Flush=0
--- Enabling this will clear the GMEM buffer before the z-pass
-r_ClearGMEMGBuffer=2
-r_Fur=0
-
-------------------------
--- VisArea / Portals
-------------------------
-e_PortalsBlend=0
-r_GMEMVisAreasBlendWeight=0.5
-
-------------------------
--- Misc. memory buffers
-------------------------
-e_AutoPrecacheCgf=2
-e_AutoPrecacheTerrainAndProcVeget=1
-e_GeomCacheBufferSize=0
-e_CheckOcclusionQueueSize=512
-e_CheckOcclusionOutputQueueSize=2048
-
-------------------------
--- Animation
-------------------------
-ca_MemoryDefragPoolSize=32
-ca_StreamCHR=1
-
-------------------------
--- sys_spec_water
-------------------------
-e_WaterOcean=2
-e_WaterVolumes=2
-e_WaterOceanBottom=0
-
-
-------------------------
--- batching
-------------------------
-r_Batching = 1
-r_BatchType = 0
-
-------------------------
--- geom instancing
-------------------------
-r_GeomInstancing=1
-r_GeomInstancingThreshold=5
-
-------------------------
--- Upscaling
-------------------------
---0 point, 1 bilinear, 2 bicubic, 3 lanczos
-r_UpscalingQuality=1
-
-------------------------
--- Geometry Cache
-------------------------
-e_GeomCaches=0
-
-
-
--- Due to performance issues with incremental cached shadow map updates, enable this to prevent us from culling every object in the world vs each cached shadow map each frame.
--- If no objects are present in the level this will eliminate the need to clear the massive cached textures each frame.
--- Set to 2 to allow distance-based updates along with script-based updates for the cached shadow maps
-e_ShadowsCacheRequireManualUpdate = 2
-
--- Sort ligths since we have limited space in the shadowmap pool texture
-r_DeferredShadingSortLights = 3
-
---Use an optimized pixel format for the lighting rendertargets during the lighting pass.
-r_DeferredShadingLBuffersFmt = 2
\ No newline at end of file
diff --git a/Assets/Engine/Config/spec/osx_metal_high.cfg b/Assets/Engine/Config/spec/osx_metal_high.cfg
deleted file mode 100644
index 8689e23c51..0000000000
--- a/Assets/Engine/Config/spec/osx_metal_high.cfg
+++ /dev/null
@@ -1,38 +0,0 @@
-
-sys_spec_Full=7
-r_ShadersMETAL=1
-
--- Default of 3 allocates all shaders (potentially >150 MB)
--- 1 is most memory efficient but definitely causes hitches when converting HLSL
--- shaders. Recommend 1 during dev, and 3 with optimized caches for release.
-r_ShadersPreactivate=1
-
--- Skip the native upscale as a second upscale occurs on Metal Present
-r_SkipNativeUpscale=1
-
-------------------------
--- sys_spec_postprocessing
-------------------------
-r_SunShafts=1
-
-------------------------
--- sys_spec_shading
-------------------------
-r_DeferredShadingTiled=0
-r_RefractionPartialResolves=0
-e_GI = 0
-
-
-r_Fur=2
-
-
-------------------------
--- Upscaling
-------------------------
---0 point, 1 bilinear, 2 bicubic, 3 lanczos
-r_UpscalingQuality=1
-
--- Due to performance issues with incremental cached shadow map updates, enable this to prevent us from culling every object in the world vs each cached shadow map each frame.
--- If no objects are present in the level this will eliminate the need to clear the massive cached textures each frame.
--- Set to 2 to allow distance-based updates along with script-based updates for the cached shadow maps
-e_ShadowsCacheRequireManualUpdate = 2
diff --git a/Assets/Engine/Config/spec/osx_metal_low.cfg b/Assets/Engine/Config/spec/osx_metal_low.cfg
deleted file mode 100644
index a3084d48c5..0000000000
--- a/Assets/Engine/Config/spec/osx_metal_low.cfg
+++ /dev/null
@@ -1,37 +0,0 @@
-
-sys_spec_Full=5
-r_ShadersMETAL=1
-
--- Default of 3 allocates all shaders (potentially >150 MB)
--- 1 is most memory efficient but definitely causes hitches when converting HLSL
--- shaders. Recommend 1 during dev, and 3 with optimized caches for release.
-r_ShadersPreactivate=1
-
--- Skip the native upscale as a second upscale occurs on Metal Present
-r_SkipNativeUpscale=1
-
-------------------------
--- sys_spec_postprocessing
-------------------------
-r_SunShafts=1
-
-------------------------
--- sys_spec_shading
-------------------------
-r_DeferredShadingTiled=0
-r_RefractionPartialResolves=0
-e_GI=0
-
-r_Fur=2
-
-
-------------------------
--- Upscaling
-------------------------
---0 point, 1 bilinear, 2 bicubic, 3 lanczos
-r_UpscalingQuality=1
-
--- Due to performance issues with incremental cached shadow map updates, enable this to prevent us from culling every object in the world vs each cached shadow map each frame.
--- If no objects are present in the level this will eliminate the need to clear the massive cached textures each frame.
--- Set to 2 to allow distance-based updates along with script-based updates for the cached shadow maps
-e_ShadowsCacheRequireManualUpdate = 2
diff --git a/Assets/Engine/Config/spec/osx_metal_medium.cfg b/Assets/Engine/Config/spec/osx_metal_medium.cfg
deleted file mode 100644
index 6477bbb217..0000000000
--- a/Assets/Engine/Config/spec/osx_metal_medium.cfg
+++ /dev/null
@@ -1,37 +0,0 @@
-
-sys_spec_Full=6
-r_ShadersMETAL=1
-
--- Default of 3 allocates all shaders (potentially >150 MB)
--- 1 is most memory efficient but definitely causes hitches when converting HLSL
--- shaders. Recommend 1 during dev, and 3 with optimized caches for release.
-r_ShadersPreactivate=1
-
--- Skip the native upscale as a second upscale occurs on Metal Present
-r_SkipNativeUpscale=1
-
-------------------------
--- sys_spec_postprocessing
-------------------------
-r_SunShafts=1
-
-------------------------
--- sys_spec_shading
-------------------------
-r_DeferredShadingTiled=0
-r_RefractionPartialResolves=0
-e_GI = 0
-
-r_Fur=2
-
-
-------------------------
--- Upscaling
-------------------------
---0 point, 1 bilinear, 2 bicubic, 3 lanczos
-r_UpscalingQuality=1
-
--- Due to performance issues with incremental cached shadow map updates, enable this to prevent us from culling every object in the world vs each cached shadow map each frame.
--- If no objects are present in the level this will eliminate the need to clear the massive cached textures each frame.
--- Set to 2 to allow distance-based updates along with script-based updates for the cached shadow maps
-e_ShadowsCacheRequireManualUpdate = 2
diff --git a/Assets/Engine/Config/spec/osx_metal_veryhigh.cfg b/Assets/Engine/Config/spec/osx_metal_veryhigh.cfg
deleted file mode 100644
index 899c198f31..0000000000
--- a/Assets/Engine/Config/spec/osx_metal_veryhigh.cfg
+++ /dev/null
@@ -1,37 +0,0 @@
-
-sys_spec_Full=8
-r_ShadersMETAL=1
-
--- Default of 3 allocates all shaders (potentially >150 MB)
--- 1 is most memory efficient but definitely causes hitches when converting HLSL
--- shaders. Recommend 1 during dev, and 3 with optimized caches for release.
-r_ShadersPreactivate=1
-
--- Skip the native upscale as a second upscale occurs on Metal Present
-r_SkipNativeUpscale=1
-
-------------------------
--- sys_spec_postprocessing
-------------------------
-r_SunShafts=1
-
-------------------------
--- sys_spec_shading
-------------------------
-r_DeferredShadingTiled=0
-r_RefractionPartialResolves=0
-e_GI = 0
-
-r_Fur=2
-
-
-------------------------
--- Upscaling
-------------------------
---0 point, 1 bilinear, 2 bicubic, 3 lanczos
-r_UpscalingQuality=1
-
--- Due to performance issues with incremental cached shadow map updates, enable this to prevent us from culling every object in the world vs each cached shadow map each frame.
--- If no objects are present in the level this will eliminate the need to clear the massive cached textures each frame.
--- Set to 2 to allow distance-based updates along with script-based updates for the cached shadow maps
-e_ShadowsCacheRequireManualUpdate = 2
diff --git a/Assets/Engine/Config/spec/pc_high.cfg b/Assets/Engine/Config/spec/pc_high.cfg
index a62ed25a6a..e69de29bb2 100644
--- a/Assets/Engine/Config/spec/pc_high.cfg
+++ b/Assets/Engine/Config/spec/pc_high.cfg
@@ -1 +0,0 @@
-sys_spec_Full = 7
\ No newline at end of file
diff --git a/Assets/Engine/Config/spec/pc_low.cfg b/Assets/Engine/Config/spec/pc_low.cfg
index 068446e151..e69de29bb2 100644
--- a/Assets/Engine/Config/spec/pc_low.cfg
+++ b/Assets/Engine/Config/spec/pc_low.cfg
@@ -1 +0,0 @@
-sys_spec_Full = 5
diff --git a/Assets/Engine/Config/spec/pc_medium.cfg b/Assets/Engine/Config/spec/pc_medium.cfg
index 0d08b956b4..e69de29bb2 100644
--- a/Assets/Engine/Config/spec/pc_medium.cfg
+++ b/Assets/Engine/Config/spec/pc_medium.cfg
@@ -1 +0,0 @@
-sys_spec_Full = 6
\ No newline at end of file
diff --git a/Assets/Engine/Config/spec/pc_veryhigh.cfg b/Assets/Engine/Config/spec/pc_veryhigh.cfg
index 33959937e8..e69de29bb2 100644
--- a/Assets/Engine/Config/spec/pc_veryhigh.cfg
+++ b/Assets/Engine/Config/spec/pc_veryhigh.cfg
@@ -1 +0,0 @@
-sys_spec_Full = 8
diff --git a/Assets/Engine/Config/statoscope.cfg b/Assets/Engine/Config/statoscope.cfg
index d1d18c813c..ed2089bd67 100644
--- a/Assets/Engine/Config/statoscope.cfg
+++ b/Assets/Engine/Config/statoscope.cfg
@@ -1,12 +1,3 @@
profile=-1
-profile_allthreads=1
-i_forcefeedback=0
-g_godmode=1
log_verbosity=-1
sys_pakLogInvalidFileAccess=1
-e_StatoscopeDataGroups=fgmrtudlipny
-e_StatoscopeFilenameUseBuildInfo=0
-e_StatoscopeFilenameUseMap=1
-e_StatoscopeMinFuncLengthMs=0.1
-e_StatoscopeMaxNumFuncsPerFrame=60
-e_StatoscopeScreenshotCapturePeriod=5
diff --git a/Assets/Engine/Config/vr.cfg b/Assets/Engine/Config/vr.cfg
index 989f55f345..80d4b7ce81 100644
--- a/Assets/Engine/Config/vr.cfg
+++ b/Assets/Engine/Config/vr.cfg
@@ -3,39 +3,13 @@
-----------------------------------------------
r_width = 960
r_height = 1080
-r_backbufferWidth = 1920
-r_backbufferHeight = 1080
-
-------------------------------------------
-- Set the system Spec (Medium)
-------------------------------------------
sys_spec = 2
-
--------------------------------------------
--- HMD related
--------------------------------------------
-r_overrideDXGIoutput = 0
-r_stereodevice = 100
-r_stereomode = 1
-r_stereooutput = 7
-r_minimizeLatency = 1
-hmd_low_persistence = 1
-r_stereoScaleCoefficient = 1
-
-
-------------------------------------------
-- Set some video optimisations
-------------------------------------------
r_vsync = 0
-r_MotionBlur = 0
-r_ssdoHalfRes = 3
-r_Refraction = 0
-r_DeferredShadingTiled = 0
-r_CBufferUseNativeDepth = 0
-
--------------------------------------------
--- Hide the hud
--------------------------------------------
---hud_hide = 1
diff --git a/Assets/Engine/EngineAssets/Icons/AverageMemoryUsage.TIF.exportsettings b/Assets/Engine/EngineAssets/Icons/AverageMemoryUsage.TIF.exportsettings
deleted file mode 100644
index c48fb8632a..0000000000
--- a/Assets/Engine/EngineAssets/Icons/AverageMemoryUsage.TIF.exportsettings
+++ /dev/null
@@ -1 +0,0 @@
-/autooptimizefile=0 /preset=Uncompressed
\ No newline at end of file
diff --git a/Assets/Engine/EngineAssets/Icons/HighMemoryUsage.TIF.exportsettings b/Assets/Engine/EngineAssets/Icons/HighMemoryUsage.TIF.exportsettings
deleted file mode 100644
index c48fb8632a..0000000000
--- a/Assets/Engine/EngineAssets/Icons/HighMemoryUsage.TIF.exportsettings
+++ /dev/null
@@ -1 +0,0 @@
-/autooptimizefile=0 /preset=Uncompressed
\ No newline at end of file
diff --git a/Assets/Engine/EngineAssets/Icons/LevelShaderCacheMiss.tif.exportsettings b/Assets/Engine/EngineAssets/Icons/LevelShaderCacheMiss.tif.exportsettings
deleted file mode 100644
index c48fb8632a..0000000000
--- a/Assets/Engine/EngineAssets/Icons/LevelShaderCacheMiss.tif.exportsettings
+++ /dev/null
@@ -1 +0,0 @@
-/autooptimizefile=0 /preset=Uncompressed
\ No newline at end of file
diff --git a/Assets/Engine/EngineAssets/Icons/LivePreview.TIF.exportsettings b/Assets/Engine/EngineAssets/Icons/LivePreview.TIF.exportsettings
deleted file mode 100644
index 8da27c31a4..0000000000
--- a/Assets/Engine/EngineAssets/Icons/LivePreview.TIF.exportsettings
+++ /dev/null
@@ -1 +0,0 @@
-/autooptimizefile=0 /dns=1 /preset=Uncompressed
\ No newline at end of file
diff --git a/Assets/Engine/EngineAssets/Icons/LowMemoryUsage.TIF.exportsettings b/Assets/Engine/EngineAssets/Icons/LowMemoryUsage.TIF.exportsettings
deleted file mode 100644
index c48fb8632a..0000000000
--- a/Assets/Engine/EngineAssets/Icons/LowMemoryUsage.TIF.exportsettings
+++ /dev/null
@@ -1 +0,0 @@
-/autooptimizefile=0 /preset=Uncompressed
\ No newline at end of file
diff --git a/Assets/Engine/EngineAssets/Icons/NavigationProcessing.tif.exportsettings b/Assets/Engine/EngineAssets/Icons/NavigationProcessing.tif.exportsettings
deleted file mode 100644
index 8da27c31a4..0000000000
--- a/Assets/Engine/EngineAssets/Icons/NavigationProcessing.tif.exportsettings
+++ /dev/null
@@ -1 +0,0 @@
-/autooptimizefile=0 /dns=1 /preset=Uncompressed
\ No newline at end of file
diff --git a/Assets/Engine/EngineAssets/Icons/NullSoundSystem.tif.exportsettings b/Assets/Engine/EngineAssets/Icons/NullSoundSystem.tif.exportsettings
deleted file mode 100644
index 8da27c31a4..0000000000
--- a/Assets/Engine/EngineAssets/Icons/NullSoundSystem.tif.exportsettings
+++ /dev/null
@@ -1 +0,0 @@
-/autooptimizefile=0 /dns=1 /preset=Uncompressed
\ No newline at end of file
diff --git a/Assets/Engine/EngineAssets/Icons/ShaderCompiling.tif.exportsettings b/Assets/Engine/EngineAssets/Icons/ShaderCompiling.tif.exportsettings
deleted file mode 100644
index 8da27c31a4..0000000000
--- a/Assets/Engine/EngineAssets/Icons/ShaderCompiling.tif.exportsettings
+++ /dev/null
@@ -1 +0,0 @@
-/autooptimizefile=0 /dns=1 /preset=Uncompressed
\ No newline at end of file
diff --git a/Assets/Engine/EngineAssets/Icons/Streaming.tif.exportsettings b/Assets/Engine/EngineAssets/Icons/Streaming.tif.exportsettings
deleted file mode 100644
index 8da27c31a4..0000000000
--- a/Assets/Engine/EngineAssets/Icons/Streaming.tif.exportsettings
+++ /dev/null
@@ -1 +0,0 @@
-/autooptimizefile=0 /dns=1 /preset=Uncompressed
\ No newline at end of file
diff --git a/Assets/Engine/EngineAssets/Icons/StreamingTerrain.tif.exportsettings b/Assets/Engine/EngineAssets/Icons/StreamingTerrain.tif.exportsettings
deleted file mode 100644
index 8da27c31a4..0000000000
--- a/Assets/Engine/EngineAssets/Icons/StreamingTerrain.tif.exportsettings
+++ /dev/null
@@ -1 +0,0 @@
-/autooptimizefile=0 /dns=1 /preset=Uncompressed
\ No newline at end of file
diff --git a/Assets/Engine/SeedAssetList.seed b/Assets/Engine/SeedAssetList.seed
index 579fd3c444..aafbffbe8f 100644
--- a/Assets/Engine/SeedAssetList.seed
+++ b/Assets/Engine/SeedAssetList.seed
@@ -48,22 +48,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -432,110 +416,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -616,38 +496,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Assets/Engine/textures/default_icon.png.exportsettings b/Assets/Engine/textures/default_icon.png.exportsettings
deleted file mode 100644
index 89ea1ac93f..0000000000
--- a/Assets/Engine/textures/default_icon.png.exportsettings
+++ /dev/null
@@ -1 +0,0 @@
-/autooptimizefile=0 /mipmaps=0 /preset=Albedo /reduce=-1 /ser=1
\ No newline at end of file
diff --git a/AutomatedTesting/Assets/Objects/Foliage/Textures/grass_atlas_diff.tif.exportsettings b/AutomatedTesting/Assets/Objects/Foliage/Textures/grass_atlas_diff.tif.exportsettings
deleted file mode 100644
index b65133fbb0..0000000000
--- a/AutomatedTesting/Assets/Objects/Foliage/Textures/grass_atlas_diff.tif.exportsettings
+++ /dev/null
@@ -1 +0,0 @@
-/autooptimizefile=0 /preset=AlbedoWithGenericAlpha /reduce="android:2,ios:2,mac:0,pc:0,provo:0"
\ No newline at end of file
diff --git a/AutomatedTesting/Assets/Objects/Foliage/Textures/grass_atlas_sss.tif.exportsettings b/AutomatedTesting/Assets/Objects/Foliage/Textures/grass_atlas_sss.tif.exportsettings
deleted file mode 100644
index e8da408b36..0000000000
--- a/AutomatedTesting/Assets/Objects/Foliage/Textures/grass_atlas_sss.tif.exportsettings
+++ /dev/null
@@ -1 +0,0 @@
-/autooptimizefile=0 /preset=Albedo /reduce="android:3,ios:3,mac:0,pc:0,provo:0"
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main.py b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main.py
index b148ffdcdb..3403c938a8 100644
--- a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main.py
+++ b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main.py
@@ -3,8 +3,6 @@ Copyright (c) Contributors to the Open 3D Engine Project.
For complete copyright and license terms please see the LICENSE at the root of this distribution.
SPDX-License-Identifier: Apache-2.0 OR MIT
-
-Main suite tests for the Atom renderer.
"""
import logging
import os
@@ -25,21 +23,20 @@ TEST_DIRECTORY = os.path.join(os.path.dirname(__file__), "tests")
class TestAtomEditorComponentsMain(object):
"""Holds tests for Atom components."""
- @pytest.mark.xfail(reason="This test is being marked xfail as it failed during an unrelated development run. See LYN-7530 for more details.")
+ @pytest.mark.test_case_id("C32078118") # Decal
+ @pytest.mark.test_case_id("C32078119") # DepthOfField
+ @pytest.mark.test_case_id("C32078120") # Directional Light
+ @pytest.mark.test_case_id("C32078121") # Exposure Control
+ @pytest.mark.test_case_id("C32078115") # Global Skylight (IBL)
+ @pytest.mark.test_case_id("C32078125") # Physical Sky
+ @pytest.mark.test_case_id("C32078127") # PostFX Layer
+ @pytest.mark.test_case_id("C32078131") # PostFX Radius Weight Modifier
+ @pytest.mark.test_case_id("C32078117") # Light
+ @pytest.mark.test_case_id("C36525660") # Display Mapper
def test_AtomEditorComponents_AddedToEntity(self, request, editor, level, workspace, project, launcher_platform):
"""
Please review the hydra script run by this test for more specific test info.
- Tests the following Atom components and verifies all "expected_lines" appear in Editor.log:
- 1. Display Mapper
- 2. Light
- 3. PostFX Radius Weight Modifier
- 4. PostFX Layer
- 5. Physical Sky
- 6. Global Skylight (IBL)
- 7. Exposure Control
- 8. Directional Light
- 9. DepthOfField
- 10. Decal
+ Tests the Atom components & verifies all "expected_lines" appear in Editor.log
"""
cfg_args = [level]
@@ -72,6 +69,18 @@ class TestAtomEditorComponentsMain(object):
"DepthOfField_test: Entity deleted: True",
"DepthOfField_test: UNDO entity deletion works: True",
"DepthOfField_test: REDO entity deletion works: True",
+ # Directional Light Component
+ "Directional Light Entity successfully created",
+ "Directional Light_test: Component added to the entity: True",
+ "Directional Light_test: Component removed after UNDO: True",
+ "Directional Light_test: Component added after REDO: True",
+ "Directional Light_test: Entered game mode: True",
+ "Directional Light_test: Exit game mode: True",
+ "Directional Light_test: Entity is hidden: True",
+ "Directional Light_test: Entity is shown: True",
+ "Directional Light_test: Entity deleted: True",
+ "Directional Light_test: UNDO entity deletion works: True",
+ "Directional Light_test: REDO entity deletion works: True",
# Exposure Control Component
"Exposure Control Entity successfully created",
"Exposure Control_test: Component added to the entity: True",
@@ -162,21 +171,6 @@ class TestAtomEditorComponentsMain(object):
"Display Mapper_test: Entity deleted: True",
"Display Mapper_test: UNDO entity deletion works: True",
"Display Mapper_test: REDO entity deletion works: True",
- # Reflection Probe Component
- "Reflection Probe Entity successfully created",
- "Reflection Probe_test: Component added to the entity: True",
- "Reflection Probe_test: Component removed after UNDO: True",
- "Reflection Probe_test: Component added after REDO: True",
- "Reflection Probe_test: Entered game mode: True",
- "Reflection Probe_test: Exit game mode: True",
- "Reflection Probe_test: Entity disabled initially: True",
- "Reflection Probe_test: Entity enabled after adding required components: True",
- "Reflection Probe_test: Cubemap is generated: True",
- "Reflection Probe_test: Entity is hidden: True",
- "Reflection Probe_test: Entity is shown: True",
- "Reflection Probe_test: Entity deleted: True",
- "Reflection Probe_test: UNDO entity deletion works: True",
- "Reflection Probe_test: REDO entity deletion works: True",
]
unexpected_lines = [
@@ -198,6 +192,7 @@ class TestAtomEditorComponentsMain(object):
cfg_args=cfg_args,
)
+ @pytest.mark.test_case_id("C34525095")
def test_AtomEditorComponents_LightComponent(
self, request, editor, workspace, project, launcher_platform, level):
"""
@@ -284,6 +279,15 @@ class TestMaterialEditorBasicTests(object):
request.addfinalizer(teardown)
@pytest.mark.parametrize("exe_file_name", ["MaterialEditor"])
+ @pytest.mark.test_case_id("C34448113") # Creating a New Asset.
+ @pytest.mark.test_case_id("C34448114") # Opening an Existing Asset.
+ @pytest.mark.test_case_id("C34448115") # Closing Selected Material.
+ @pytest.mark.test_case_id("C34448116") # Closing All Materials.
+ @pytest.mark.test_case_id("C34448117") # Closing all but Selected Material.
+ @pytest.mark.test_case_id("C34448118") # Saving Material.
+ @pytest.mark.test_case_id("C34448119") # Saving as a New Material.
+ @pytest.mark.test_case_id("C34448120") # Saving as a Child Material.
+ @pytest.mark.test_case_id("C34448121") # Saving all Open Materials.
def test_MaterialEditorBasicTests(
self, request, workspace, project, launcher_platform, generic_launcher, exe_file_name):
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_GPU.py b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_GPU.py
index 3403d8e9b1..381f266fab 100644
--- a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_GPU.py
+++ b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_GPU.py
@@ -73,6 +73,7 @@ def create_screenshots_archive(screenshot_path):
class TestAllComponentsIndepthTests(object):
@pytest.mark.parametrize("screenshot_name", ["AtomBasicLevelSetup.ppm"])
+ @pytest.mark.test_case_id("C34603773")
def test_BasicLevelSetup_SetsUpLevel(
self, request, editor, workspace, project, launcher_platform, level, screenshot_name):
"""
@@ -115,6 +116,7 @@ class TestAllComponentsIndepthTests(object):
create_screenshots_archive(screenshot_directory)
+ @pytest.mark.test_case_id("C34525095")
def test_LightComponent_ScreenshotMatchesGoldenImage(
self, request, editor, workspace, project, launcher_platform, level):
"""
@@ -146,7 +148,7 @@ class TestAllComponentsIndepthTests(object):
golden_image_path = os.path.join(golden_images_directory(), golden_image)
golden_images.append(golden_image_path)
- expected_lines = ["Light component tests completed."]
+ expected_lines = ["spot_light Controller|Configuration|Shadows|Shadowmap size: SUCCESS"]
unexpected_lines = [
"Trace::Assert",
"Trace::Error",
@@ -220,20 +222,20 @@ class TestPerformanceBenchmarkSuite(object):
@pytest.mark.system
class TestMaterialEditor(object):
- @pytest.mark.parametrize("cfg_args", ["-rhi=dx12", "-rhi=Vulkan"])
+ @pytest.mark.parametrize("cfg_args,expected_lines", [
+ pytest.param("-rhi=dx12", ["Registering dx12 RHI"]),
+ pytest.param("-rhi=Vulkan", ["Registering vulkan RHI"])
+ ])
@pytest.mark.parametrize("exe_file_name", ["MaterialEditor"])
+ @pytest.mark.test_case_id("C30973986") # Material Editor Launching in Dx12
+ @pytest.mark.test_case_id("C30973987") # Material Editor Launching in Vulkan
def test_MaterialEditorLaunch_AllRHIOptionsSucceed(
- self, request, workspace, project, launcher_platform, generic_launcher, exe_file_name, cfg_args):
+ self, request, workspace, project, launcher_platform, generic_launcher, exe_file_name, cfg_args,
+ expected_lines):
"""
Tests each valid RHI option (Null RHI excluded) can be launched with the MaterialEditor.
- Checks for the "Finished loading viewport configurations." success message post launch.
+ Checks for the specific expected_lines messaging for each RHI type.
"""
- expected_lines = ["Finished loading viewport configurations."]
- unexpected_lines = [
- # "Trace::Assert",
- # "Trace::Error",
- "Traceback (most recent call last):",
- ]
hydra.launch_and_validate_results(
request,
@@ -243,7 +245,7 @@ class TestMaterialEditor(object):
run_python="--runpython",
timeout=60,
expected_lines=expected_lines,
- unexpected_lines=unexpected_lines,
+ unexpected_lines=[],
halt_on_unexpected=False,
null_renderer=False,
cfg_args=[cfg_args],
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_GPU_Optimized.py b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_GPU_Optimized.py
index ef572d6e5c..568768e12e 100644
--- a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_GPU_Optimized.py
+++ b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_GPU_Optimized.py
@@ -23,6 +23,7 @@ class TestAutomation(EditorTestSuite):
# Remove -autotest_mode from global_extra_cmdline_args since we need rendering for these tests.
global_extra_cmdline_args = ["-BatchMode"] # Default is ["-BatchMode", "-autotest_mode"]
+ @pytest.mark.test_case_id("C34603773")
class AtomGPU_BasicLevelSetup_SetsUpLevel(EditorSharedTest):
use_null_renderer = False # Default is True
screenshot_name = "AtomBasicLevelSetup.ppm"
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_Optimized.py b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_Optimized.py
index 90436fbe27..447a4ebac9 100644
--- a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_Optimized.py
+++ b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_Optimized.py
@@ -59,5 +59,17 @@ class TestAutomation(EditorTestSuite):
class AtomEditorComponents_MeshAdded(EditorSharedTest):
from Atom.tests import hydra_AtomEditorComponents_MeshAdded as test_module
+ @pytest.mark.test_case_id("C32078123")
+ class AtomEditorComponents_MaterialAdded(EditorSharedTest):
+ from Atom.tests import hydra_AtomEditorComponents_MaterialAdded as test_module
+
+ @pytest.mark.test_case_id("C32078127")
+ class AtomEditorComponents_PostFXLayerAdded(EditorSharedTest):
+ from Atom.tests import hydra_AtomEditorComponents_PostFXLayerAdded as test_module
+
+ @pytest.mark.test_case_id("C36525665")
+ class AtomEditorComponents_PostFXShapeWeightModifierAdded(EditorSharedTest):
+ from Atom.tests import hydra_AtomEditorComponents_PostFxShapeWeightModifierAdded as test_module
+
class ShaderAssetBuilder_RecompilesShaderAsChainOfDependenciesChanges(EditorSharedTest):
from Atom.tests import hydra_ShaderAssetBuilder_RecompilesShaderAsChainOfDependenciesChanges as test_module
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Sandbox.py b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Sandbox.py
index 05401c0059..58e5d00ff2 100644
--- a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Sandbox.py
+++ b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Sandbox.py
@@ -3,12 +3,17 @@ Copyright (c) Contributors to the Open 3D Engine Project.
For complete copyright and license terms please see the LICENSE at the root of this distribution.
SPDX-License-Identifier: Apache-2.0 OR MIT
-
-Sandbox suite tests for the Atom renderer.
"""
+import logging
+import os
import pytest
+import editor_python_test_tools.hydra_test_utils as hydra
+
+logger = logging.getLogger(__name__)
+TEST_DIRECTORY = os.path.join(os.path.dirname(__file__), "tests")
+
@pytest.mark.parametrize("project", ["AutomatedTesting"])
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
@@ -18,3 +23,50 @@ class TestAtomEditorComponentsSandbox(object):
# It requires at least one test
def test_Dummy(self, request, editor, level, workspace, project, launcher_platform):
pass
+
+ @pytest.mark.parametrize("project", ["AutomatedTesting"])
+ @pytest.mark.parametrize("launcher_platform", ['windows_editor'])
+ @pytest.mark.parametrize("level", ["auto_test"])
+ class TestAtomEditorComponentsMain(object):
+ """Holds tests for Atom components."""
+
+ @pytest.mark.test_case_id("C32078128")
+ def test_AtomEditorComponents_ReflectionProbeAddedToEntity(
+ self, request, editor, level, workspace, project, launcher_platform):
+ """
+ Please review the hydra script run by this test for more specific test info.
+ Tests the following Atom components and verifies all "expected_lines" appear in Editor.log:
+ 1. Reflection Probe
+ """
+ cfg_args = [level]
+
+ expected_lines = [
+ # Reflection Probe Component
+ "Reflection Probe Entity successfully created",
+ "Reflection Probe_test: Component added to the entity: True",
+ "Reflection Probe_test: Component removed after UNDO: True",
+ "Reflection Probe_test: Component added after REDO: True",
+ "Reflection Probe_test: Entered game mode: True",
+ "Reflection Probe_test: Exit game mode: True",
+ "Reflection Probe_test: Entity disabled initially: True",
+ "Reflection Probe_test: Entity enabled after adding required components: True",
+ "Reflection Probe_test: Cubemap is generated: True",
+ "Reflection Probe_test: Entity is hidden: True",
+ "Reflection Probe_test: Entity is shown: True",
+ "Reflection Probe_test: Entity deleted: True",
+ "Reflection Probe_test: UNDO entity deletion works: True",
+ "Reflection Probe_test: REDO entity deletion works: True",
+ ]
+
+ hydra.launch_and_validate_results(
+ request,
+ TEST_DIRECTORY,
+ editor,
+ "hydra_AtomEditorComponents_AddedToEntity.py",
+ timeout=120,
+ expected_lines=expected_lines,
+ unexpected_lines=[],
+ halt_on_unexpected=True,
+ null_renderer=True,
+ cfg_args=cfg_args,
+ )
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_component_helper.py b/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_component_helper.py
index 821e0acfdb..11832f8846 100644
--- a/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_component_helper.py
+++ b/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_component_helper.py
@@ -113,7 +113,6 @@ def create_basic_atom_level(level_name):
general.close_pane("Error Log")
general.idle_wait(1.0)
general.run_console("r_displayInfo=0")
- general.run_console("r_antialiasingmode=0")
general.idle_wait(1.0)
# Delete all existing entities & create default_level entity
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_MaterialAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_MaterialAdded.py
new file mode 100644
index 0000000000..32cd5471f2
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_MaterialAdded.py
@@ -0,0 +1,205 @@
+"""
+Copyright (c) Contributors to the Open 3D Engine Project.
+For complete copyright and license terms please see the LICENSE at the root of this distribution.
+
+SPDX-License-Identifier: Apache-2.0 OR MIT
+"""
+
+class Tests:
+ creation_undo = (
+ "UNDO Entity creation success",
+ "UNDO Entity creation failed")
+ creation_redo = (
+ "REDO Entity creation success",
+ "REDO Entity creation failed")
+ material_creation = (
+ "Material Entity successfully created",
+ "Material Entity failed to be created")
+ material_component = (
+ "Entity has a Material component",
+ "Entity failed to find Material component")
+ material_disabled = (
+ "Material component disabled",
+ "Material component was not disabled.")
+ actor_component = (
+ "Entity has an Actor component",
+ "Entity did not have an Actor component")
+ actor_undo = (
+ "Entity Actor component gone",
+ "Entity Actor component add failed to undo")
+ mesh_component = (
+ "Entity has a Mesh component",
+ "Entity did not have a Mesh component")
+ material_enabled = (
+ "Material component enabled",
+ "Material component was not enabled.")
+ enter_game_mode = (
+ "Entered game mode",
+ "Failed to enter game mode")
+ exit_game_mode = (
+ "Exited game mode",
+ "Couldn't exit game mode")
+ is_visible = (
+ "Entity is visible",
+ "Entity was not visible")
+ is_hidden = (
+ "Entity is hidden",
+ "Entity was not hidden")
+ entity_deleted = (
+ "Entity deleted",
+ "Entity was not deleted")
+ deletion_undo = (
+ "UNDO deletion success",
+ "UNDO deletion failed")
+ deletion_redo = (
+ "REDO deletion success",
+ "REDO deletion failed")
+
+
+def AtomEditorComponents_Material_AddedToEntity():
+ """
+ Summary:
+ Tests the Material component can be added to an entity and has the expected functionality.
+
+ Test setup:
+ - Wait for Editor idle loop.
+ - Open the "Base" level.
+
+ Expected Behavior:
+ The component can be added, used in game mode, hidden/shown, deleted, and has accurate required components.
+ Creation and deletion undo/redo should also work.
+
+ Test Steps:
+ 1) Create a Material entity with no components.
+ 2) Add a Material component to Material entity.
+ 3) UNDO the entity creation and component addition.
+ 4) REDO the entity creation and component addition.
+ 5) Verify Material component not enabled.
+ 6) Add Actor component since it is required by the Material component.
+ 7) Verify Material component is enabled.
+ 8) UNDO add Actor component
+ 9) Verify Material component not enabled.
+ 10) Add Mesh component since it is required by the Material component.
+ 11) Verify Material component is enabled.
+ 12) Enter/Exit game mode.
+ 13) Test IsHidden.
+ 14) Test IsVisible.
+ 15) Delete Material entity.
+ 16) UNDO deletion.
+ 17) REDO deletion.
+ 18) Look for errors.
+
+ :return: None
+ """
+
+ import azlmbr.legacy.general as general
+
+ from editor_python_test_tools.editor_entity_utils import EditorEntity
+ from editor_python_test_tools.utils import Report, Tracer, TestHelper
+
+ with Tracer() as error_tracer:
+ # Test setup begins.
+ # Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
+ TestHelper.init_idle()
+ TestHelper.open_level("", "Base")
+
+ # Test steps begin.
+ # 1. Create a Material entity with no components.
+ material_name = "Material"
+ material_entity = EditorEntity.create_editor_entity(material_name)
+ Report.critical_result(Tests.material_creation, material_entity.exists())
+
+ # 2. Add a Material component to Material entity.
+ material_component = material_entity.add_component(material_name)
+ Report.critical_result(
+ Tests.material_component,
+ material_entity.has_component(material_name))
+
+ # 3. UNDO the entity creation and component addition.
+ # -> UNDO component addition.
+ general.undo()
+ # -> UNDO naming entity.
+ general.undo()
+ # -> UNDO selecting entity.
+ general.undo()
+ # -> UNDO entity creation.
+ general.undo()
+ general.idle_wait_frames(1)
+ Report.result(Tests.creation_undo, not material_entity.exists())
+
+ # 4. REDO the entity creation and component addition.
+ # -> REDO entity creation.
+ general.redo()
+ # -> REDO selecting entity.
+ general.redo()
+ # -> REDO naming entity.
+ general.redo()
+ # -> REDO component addition.
+ general.redo()
+ general.idle_wait_frames(1)
+ Report.result(Tests.creation_redo, material_entity.exists())
+
+ # 5. Verify Material component not enabled.
+ Report.result(Tests.material_disabled, not material_component.is_enabled())
+
+ # 6. Add Actor component since it is required by the Material component.
+ actor_name = "Actor"
+ material_entity.add_component(actor_name)
+ Report.result(Tests.actor_component, material_entity.has_component(actor_name))
+
+ # 7. Verify Material component is enabled.
+ Report.result(Tests.material_enabled, material_component.is_enabled())
+
+ # 8. UNDO component addition.
+ general.undo()
+ general.idle_wait_frames(1)
+ Report.result(Tests.actor_undo, not material_entity.has_component(actor_name))
+
+ # 9. Verify Material component not enabled.
+ Report.result(Tests.material_disabled, not material_component.is_enabled())
+
+ # 10. Add Mesh component since it is required by the Material component.
+ mesh_name = "Mesh"
+ material_entity.add_component(mesh_name)
+ Report.result(Tests.mesh_component, material_entity.has_component(mesh_name))
+
+ # 11. Verify Material component is enabled.
+ Report.result(Tests.material_enabled, material_component.is_enabled())
+
+ # 12. Enter/Exit game mode.
+ TestHelper.enter_game_mode(Tests.enter_game_mode)
+ general.idle_wait_frames(1)
+ TestHelper.exit_game_mode(Tests.exit_game_mode)
+
+ # 13. Test IsHidden.
+ material_entity.set_visibility_state(False)
+ Report.result(Tests.is_hidden, material_entity.is_hidden() is True)
+
+ # 14. Test IsVisible.
+ material_entity.set_visibility_state(True)
+ general.idle_wait_frames(1)
+ Report.result(Tests.is_visible, material_entity.is_visible() is True)
+
+ # 15. Delete Material entity.
+ material_entity.delete()
+ Report.result(Tests.entity_deleted, not material_entity.exists())
+
+ # 16. UNDO deletion.
+ general.undo()
+ Report.result(Tests.deletion_undo, material_entity.exists())
+
+ # 17. REDO deletion.
+ general.redo()
+ Report.result(Tests.deletion_redo, not material_entity.exists())
+
+ # 18. Look for errors or asserts.
+ TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0)
+ for error_info in error_tracer.errors:
+ Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}")
+ for assert_info in error_tracer.asserts:
+ Report.info(f"Assert: {assert_info.filename} {assert_info.function} | {assert_info.message}")
+
+
+if __name__ == "__main__":
+ from editor_python_test_tools.utils import Report
+ Report.start_test(AtomEditorComponents_Material_AddedToEntity)
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_PostFXLayerAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_PostFXLayerAdded.py
new file mode 100644
index 0000000000..8c2dee416b
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_PostFXLayerAdded.py
@@ -0,0 +1,156 @@
+"""
+Copyright (c) Contributors to the Open 3D Engine Project.
+For complete copyright and license terms please see the LICENSE at the root of this distribution.
+
+SPDX-License-Identifier: Apache-2.0 OR MIT
+"""
+
+class Tests:
+ creation_undo = (
+ "UNDO Entity creation success",
+ "UNDO Entity creation failed")
+ creation_redo = (
+ "REDO Entity creation success",
+ "REDO Entity creation failed")
+ postfx_layer_entity_creation = (
+ "PostFX Layer Entity successfully created",
+ "PostFX Layer Entity failed to be created")
+ postfx_layer_component_added = (
+ "Entity has a PostFX Layer component",
+ "Entity failed to find PostFX Layer component")
+ enter_game_mode = (
+ "Entered game mode",
+ "Failed to enter game mode")
+ exit_game_mode = (
+ "Exited game mode",
+ "Couldn't exit game mode")
+ is_visible = (
+ "Entity is visible",
+ "Entity was not visible")
+ is_hidden = (
+ "Entity is hidden",
+ "Entity was not hidden")
+ entity_deleted = (
+ "Entity deleted",
+ "Entity was not deleted")
+ deletion_undo = (
+ "UNDO deletion success",
+ "UNDO deletion failed")
+ deletion_redo = (
+ "REDO deletion success",
+ "REDO deletion failed")
+
+
+def AtomEditorComponents_postfx_layer_AddedToEntity():
+ """
+ Summary:
+ Tests the PostFX Layer component can be added to an entity and has the expected functionality.
+
+ Test setup:
+ - Wait for Editor idle loop.
+ - Open the "Base" level.
+
+ Expected Behavior:
+ The component can be added, used in game mode, hidden/shown, deleted, and has accurate required components.
+ Creation and deletion undo/redo should also work.
+
+ Test Steps:
+ 1) Create a PostFX Layer entity with no components.
+ 2) Add a PostFX Layer component to PostFX Layer entity.
+ 3) UNDO the entity creation and component addition.
+ 4) REDO the entity creation and component addition.
+ 5) Enter/Exit game mode.
+ 6) Test IsHidden.
+ 7) Test IsVisible.
+ 8) Delete PostFX Layer entity.
+ 9) UNDO deletion.
+ 10) REDO deletion.
+ 11) Look for errors.
+
+ :return: None
+ """
+
+ import os
+
+ import azlmbr.legacy.general as general
+
+ from editor_python_test_tools.editor_entity_utils import EditorEntity
+ from editor_python_test_tools.utils import Report, Tracer, TestHelper
+
+ with Tracer() as error_tracer:
+ # Test setup begins.
+ # Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
+ TestHelper.init_idle()
+ TestHelper.open_level("", "Base")
+
+ # Test steps begin.
+ # 1. Create a PostFX Layer entity with no components.
+ postfx_layer_name = "PostFX Layer"
+ postfx_layer_entity = EditorEntity.create_editor_entity(postfx_layer_name)
+ Report.critical_result(Tests.postfx_layer_entity_creation, postfx_layer_entity.exists())
+
+ # 2. Add a PostFX Layer component to PostFX Layer entity.
+ postfx_layer_component = postfx_layer_entity.add_component(postfx_layer_name)
+ Report.critical_result(Tests.postfx_layer_component_added, postfx_layer_entity.has_component(postfx_layer_name))
+
+ # 3. UNDO the entity creation and component addition.
+ # -> UNDO component addition.
+ general.undo()
+ # -> UNDO naming entity.
+ general.undo()
+ # -> UNDO selecting entity.
+ general.undo()
+ # -> UNDO entity creation.
+ general.undo()
+ general.idle_wait_frames(1)
+ Report.result(Tests.creation_undo, not postfx_layer_entity.exists())
+
+ # 4. REDO the entity creation and component addition.
+ # -> REDO entity creation.
+ general.redo()
+ # -> REDO selecting entity.
+ general.redo()
+ # -> REDO naming entity.
+ general.redo()
+ # -> REDO component addition.
+ general.redo()
+ general.idle_wait_frames(1)
+ Report.result(Tests.creation_redo, postfx_layer_entity.exists())
+
+ # 5. Enter/Exit game mode.
+ TestHelper.enter_game_mode(Tests.enter_game_mode)
+ general.idle_wait_frames(1)
+ TestHelper.exit_game_mode(Tests.exit_game_mode)
+
+ # 6. Test IsHidden.
+ postfx_layer_entity.set_visibility_state(False)
+ Report.result(Tests.is_hidden, postfx_layer_entity.is_hidden() is True)
+
+ # 7. Test IsVisible.
+ postfx_layer_entity.set_visibility_state(True)
+ general.idle_wait_frames(1)
+ Report.result(Tests.is_visible, postfx_layer_entity.is_visible() is True)
+
+ # 8. Delete PostFX Layer entity.
+ postfx_layer_entity.delete()
+ Report.result(Tests.entity_deleted, not postfx_layer_entity.exists())
+
+ # 9. UNDO deletion.
+ general.undo()
+ Report.result(Tests.deletion_undo, postfx_layer_entity.exists())
+
+ # 10. REDO deletion.
+ general.redo()
+ Report.result(Tests.deletion_redo, not postfx_layer_entity.exists())
+
+ # 11. Look for errors or asserts.
+ TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0)
+ for error_info in error_tracer.errors:
+ Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}")
+ for assert_info in error_tracer.asserts:
+ Report.info(f"Assert: {assert_info.filename} {assert_info.function} | {assert_info.message}")
+
+
+if __name__ == "__main__":
+ from editor_python_test_tools.utils import Report
+ Report.start_test(AtomEditorComponents_postfx_layer_AddedToEntity)
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_PostFxShapeWeightModifierAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_PostFxShapeWeightModifierAdded.py
new file mode 100644
index 0000000000..4c98bcd130
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_PostFxShapeWeightModifierAdded.py
@@ -0,0 +1,207 @@
+"""
+Copyright (c) Contributors to the Open 3D Engine Project.
+For complete copyright and license terms please see the LICENSE at the root of this distribution.
+
+SPDX-License-Identifier: Apache-2.0 OR MIT
+"""
+
+class Tests:
+ creation_undo = (
+ "UNDO Entity creation success",
+ "UNDO Entity creation failed")
+ creation_redo = (
+ "REDO Entity creation success",
+ "REDO Entity creation failed")
+ postfx_shape_weight_creation = (
+ "PostFx Shape Weight Modifier Entity successfully created",
+ "PostFx Shape Weight Modifier Entity failed to be created")
+ postfx_shape_weight_component = (
+ "Entity has a PostFx Shape Weight Modifier component",
+ "Entity failed to find PostFx Shape Weight Modifier component")
+ postfx_shape_weight_disabled = (
+ "PostFx Shape Weight Modifier component disabled",
+ "PostFx Shape Weight Modifier component was not disabled.")
+ postfx_layer_component = (
+ "Entity has a PostFX Layer component",
+ "Entity did not have an PostFX Layer component")
+ tube_shape_component = (
+ "Entity has a Tube Shape component",
+ "Entity did not have a Tube Shape component")
+ postfx_shape_weight_enabled = (
+ "PostFx Shape Weight Modifier component enabled",
+ "PostFx Shape Weight Modifier component was not enabled.")
+ enter_game_mode = (
+ "Entered game mode",
+ "Failed to enter game mode")
+ exit_game_mode = (
+ "Exited game mode",
+ "Couldn't exit game mode")
+ is_visible = (
+ "Entity is visible",
+ "Entity was not visible")
+ is_hidden = (
+ "Entity is hidden",
+ "Entity was not hidden")
+ entity_deleted = (
+ "Entity deleted",
+ "Entity was not deleted")
+ deletion_undo = (
+ "UNDO deletion success",
+ "UNDO deletion failed")
+ deletion_redo = (
+ "REDO deletion success",
+ "REDO deletion failed")
+
+
+def AtomEditorComponents_postfx_shape_weight_AddedToEntity():
+ """
+ Summary:
+ Tests the PostFx Shape Weight Modifier component can be added to an entity and has the expected functionality.
+
+ Test setup:
+ - Wait for Editor idle loop.
+ - Open the "Base" level.
+
+ Expected Behavior:
+ The component can be added, used in game mode, hidden/shown, deleted, and has accurate required components.
+ Creation and deletion undo/redo should also work.
+
+ Test Steps:
+ 1) Create a PostFx Shape Weight Modifier entity with no components.
+ 2) Add a PostFx Shape Weight Modifier component to PostFx Shape Weight Modifier entity.
+ 3) UNDO the entity creation and component addition.
+ 4) REDO the entity creation and component addition.
+ 5) Verify PostFx Shape Weight Modifier component not enabled.
+ 6) Add PostFX Layer component since it is required by the PostFx Shape Weight Modifier component.
+ 7) Verify PostFx Shape Weight Modifier component is NOT enabled since it also requires a shape.
+ 8) Add a required shape looping over a list and checking if it enables PostFX Shape Weight Modifier.
+ 9) Undo to remove each added shape and verify PostFX Shape Weight Modifier is not enabled.
+ 10) Verify PostFx Shape Weight Modifier component is enabled by adding Spline and Tube Shape component.
+ 11) Enter/Exit game mode.
+ 12) Test IsHidden.
+ 13) Test IsVisible.
+ 14) Delete PostFx Shape Weight Modifier entity.
+ 15) UNDO deletion.
+ 16) REDO deletion.
+ 17) Look for errors.
+
+ :return: None
+ """
+
+ import azlmbr.legacy.general as general
+
+ from editor_python_test_tools.editor_entity_utils import EditorEntity
+ from editor_python_test_tools.utils import Report, Tracer, TestHelper
+
+ with Tracer() as error_tracer:
+ # Test setup begins.
+ # Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
+ TestHelper.init_idle()
+ TestHelper.open_level("", "Base")
+
+ # Test steps begin.
+ # 1. Create a PostFx Shape Weight Modifier entity with no components.
+ postfx_shape_weight_name = "PostFX Shape Weight Modifier"
+ postfx_shape_weight_entity = EditorEntity.create_editor_entity(postfx_shape_weight_name)
+ Report.critical_result(Tests.postfx_shape_weight_creation, postfx_shape_weight_entity.exists())
+
+ # 2. Add a PostFx Shape Weight Modifier component to PostFx Shape Weight Modifier entity.
+ postfx_shape_weight_component = postfx_shape_weight_entity.add_component(postfx_shape_weight_name)
+ Report.critical_result(
+ Tests.postfx_shape_weight_component,
+ postfx_shape_weight_entity.has_component(postfx_shape_weight_name))
+
+ # 3. UNDO the entity creation and component addition.
+ # -> UNDO component addition.
+ general.undo()
+ # -> UNDO naming entity.
+ general.undo()
+ # -> UNDO selecting entity.
+ general.undo()
+ # -> UNDO entity creation.
+ general.undo()
+ general.idle_wait_frames(1)
+ Report.result(Tests.creation_undo, not postfx_shape_weight_entity.exists())
+
+ # 4. REDO the entity creation and component addition.
+ # -> REDO entity creation.
+ general.redo()
+ # -> REDO selecting entity.
+ general.redo()
+ # -> REDO naming entity.
+ general.redo()
+ # -> REDO component addition.
+ general.redo()
+ general.idle_wait_frames(1)
+ Report.result(Tests.creation_redo, postfx_shape_weight_entity.exists())
+
+ # 5. Verify PostFx Shape Weight Modifier component not enabled.
+ Report.result(Tests.postfx_shape_weight_disabled, not postfx_shape_weight_component.is_enabled())
+
+ # 6. Add PostFX Layer component since it is required by the PostFx Shape Weight Modifier component.
+ postfx_layer_name = "PostFX Layer"
+ postfx_shape_weight_entity.add_component(postfx_layer_name)
+ Report.result(Tests.postfx_layer_component, postfx_shape_weight_entity.has_component(postfx_layer_name))
+
+ # 7. Verify PostFx Shape Weight Modifier component is NOT enabled since it also requires a shape.
+ Report.result(Tests.postfx_shape_weight_disabled, not postfx_shape_weight_component.is_enabled())
+
+ # 8. Add a required shape looping over a list and checking if it enables PostFX Shape Weight Modifier.
+ for shape in ['Axis Aligned Box Shape', 'Box Shape', 'Capsule Shape', 'Compound Shape', 'Cylinder Shape',
+ 'Disk Shape', 'Polygon Prism Shape', 'Quad Shape', 'Sphere Shape', 'Vegetation Reference Shape']:
+ postfx_shape_weight_entity.add_component(shape)
+ test_shape = (
+ f"Entity has a {shape} component",
+ f"Entity did not have a {shape} component")
+ Report.result(test_shape, postfx_shape_weight_entity.has_component(shape))
+
+ # Check if required shape allows PostFX Shape Weight Modifier to be enabled
+ Report.result(Tests.postfx_shape_weight_enabled, postfx_shape_weight_component.is_enabled())
+
+ # 9. Undo to remove each added shape and verify PostFX Shape Weight Modifier is not enabled.
+ general.undo()
+ TestHelper.wait_for_condition(lambda: not postfx_shape_weight_entity.has_component(shape), 1.0)
+ Report.result(Tests.postfx_shape_weight_disabled, not postfx_shape_weight_component.is_enabled())
+
+ # 10. Verify PostFx Shape Weight Modifier component is enabled by adding Spline and Tube Shape component.
+ postfx_shape_weight_entity.add_components(['Spline', 'Tube Shape'])
+ Report.result(Tests.tube_shape_component, postfx_shape_weight_entity.has_component('Tube Shape'))
+ Report.result(Tests.postfx_shape_weight_enabled, postfx_shape_weight_component.is_enabled())
+
+ # 11. Enter/Exit game mode.
+ TestHelper.enter_game_mode(Tests.enter_game_mode)
+ general.idle_wait_frames(1)
+ TestHelper.exit_game_mode(Tests.exit_game_mode)
+
+ # 12. Test IsHidden.
+ postfx_shape_weight_entity.set_visibility_state(False)
+ Report.result(Tests.is_hidden, postfx_shape_weight_entity.is_hidden() is True)
+
+ # 13. Test IsVisible.
+ postfx_shape_weight_entity.set_visibility_state(True)
+ general.idle_wait_frames(1)
+ Report.result(Tests.is_visible, postfx_shape_weight_entity.is_visible() is True)
+
+ # 14. Delete PostFx Shape Weight Modifier entity.
+ postfx_shape_weight_entity.delete()
+ Report.result(Tests.entity_deleted, not postfx_shape_weight_entity.exists())
+
+ # 15. UNDO deletion.
+ general.undo()
+ Report.result(Tests.deletion_undo, postfx_shape_weight_entity.exists())
+
+ # 16. REDO deletion.
+ general.redo()
+ Report.result(Tests.deletion_redo, not postfx_shape_weight_entity.exists())
+
+ # 17. Look for errors or asserts.
+ TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0)
+ for error_info in error_tracer.errors:
+ Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}")
+ for assert_info in error_tracer.asserts:
+ Report.info(f"Assert: {assert_info.filename} {assert_info.function} | {assert_info.message}")
+
+
+if __name__ == "__main__":
+ from editor_python_test_tools.utils import Report
+ Report.start_test(AtomEditorComponents_postfx_shape_weight_AddedToEntity)
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_GPUTest_AtomFeatureIntegrationBenchmark.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_GPUTest_AtomFeatureIntegrationBenchmark.py
index 92199bf196..fbd9f3459a 100644
--- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_GPUTest_AtomFeatureIntegrationBenchmark.py
+++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_GPUTest_AtomFeatureIntegrationBenchmark.py
@@ -66,7 +66,6 @@ def run():
general.close_pane("Error Log")
general.idle_wait(1.0)
general.run_console("r_displayInfo=0")
- general.run_console("r_antialiasingmode=0")
general.idle_wait(1.0)
return True
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_GPUTest_BasicLevelSetup.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_GPUTest_BasicLevelSetup.py
index ac28e67fa1..93e78a7c0a 100644
--- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_GPUTest_BasicLevelSetup.py
+++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_GPUTest_BasicLevelSetup.py
@@ -82,7 +82,6 @@ def run():
general.close_pane("Error Log")
general.idle_wait(1.0)
general.run_console("r_displayInfo=0")
- general.run_console("r_antialiasingmode=0")
general.idle_wait(1.0)
return True
diff --git a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/utils.py b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/utils.py
index ef3048d8d4..1b094b1cfa 100644
--- a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/utils.py
+++ b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/utils.py
@@ -149,7 +149,6 @@ class TestHelper:
general.idle_wait(1.0)
general.idle_wait(1.0)
general.run_console("r_displayInfo=0")
- general.run_console("r_antialiasingmode=0")
general.idle_wait(1.0)
diff --git a/AutomatedTesting/Gem/PythonTests/Physics/TestSuite_Periodic.py b/AutomatedTesting/Gem/PythonTests/Physics/TestSuite_Periodic.py
index da89316993..e5dd9adbb9 100755
--- a/AutomatedTesting/Gem/PythonTests/Physics/TestSuite_Periodic.py
+++ b/AutomatedTesting/Gem/PythonTests/Physics/TestSuite_Periodic.py
@@ -525,10 +525,6 @@ class TestAutomation(TestAutomationBase):
from .tests.joints import Joints_BallNoLimitsConstrained as test_module
self._run_test(request, workspace, editor, test_module)
- def test_Joints_FixedLeadFollowerCollide(self, request, workspace, editor, launcher_platform):
- from .tests.joints import Joints_FixedLeadFollowerCollide as test_module
- self._run_test(request, workspace, editor, test_module)
-
def test_Joints_GlobalFrameConstrained(self, request, workspace, editor, launcher_platform):
from .tests.joints import Joints_GlobalFrameConstrained as test_module
self._run_test(request, workspace, editor, test_module)
diff --git a/AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_SplineRegionWithModifiedTransform.py b/AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_SplineRegionWithModifiedTransform.py
index abc58779a2..e949d2d8f9 100644
--- a/AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_SplineRegionWithModifiedTransform.py
+++ b/AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_SplineRegionWithModifiedTransform.py
@@ -82,7 +82,7 @@ def ForceRegion_SplineRegionWithModifiedTransform():
import azlmbr.bus as bus
# region Constants
- TIMEOUT = 5.0
+ TIMEOUT = 10.0
MIN_TRIGGER_DISTANCE = 2.0
# endregion
diff --git a/AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_ZeroPointForceDoesNothing.py b/AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_ZeroPointForceDoesNothing.py
index 91190f83e5..6582628ff9 100644
--- a/AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_ZeroPointForceDoesNothing.py
+++ b/AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_ZeroPointForceDoesNothing.py
@@ -77,7 +77,7 @@ def ForceRegion_ZeroPointForceDoesNothing():
helper.init_idle()
- TIMEOUT_SECONDS = 3.0
+ TIMEOUT_SECONDS = 5.0
X_Y_Z_TOLERANCE = 1.5
REGION_HEIGHT = 3.0
TERRAIN_HEIGHT = 32.0
diff --git a/AutomatedTesting/Gem/PythonTests/Physics/tests/joints/JointsHelper.py b/AutomatedTesting/Gem/PythonTests/Physics/tests/joints/JointsHelper.py
index 6226f42534..a85e460659 100644
--- a/AutomatedTesting/Gem/PythonTests/Physics/tests/joints/JointsHelper.py
+++ b/AutomatedTesting/Gem/PythonTests/Physics/tests/joints/JointsHelper.py
@@ -45,8 +45,13 @@ class JointEntity:
# Entity class that sets a flag when an instance receives collision events.
class JointEntityCollisionAware(JointEntity):
def on_collision_begin(self, args):
- if not self.collided:
- self.collided = True
+ self.collided = True
+
+ def on_collision_persist(self, args):
+ self.collided = True
+
+ def on_collision_end(self, args):
+ self.collided = True
def __init__(self, name):
self.id = general.find_game_entity(name)
@@ -58,3 +63,5 @@ class JointEntityCollisionAware(JointEntity):
self.handler = azlmbr.physics.CollisionNotificationBusHandler()
self.handler.connect(self.id)
self.handler.add_callback("OnCollisionBegin", self.on_collision_begin)
+ self.handler.add_callback("OnCollisionPresist", self.on_collision_persist)
+ self.handler.add_callback("OnCollisionEnd", self.on_collision_end)
diff --git a/AutomatedTesting/Gem/PythonTests/Physics/tests/joints/Joints_BallLeadFollowerCollide.py b/AutomatedTesting/Gem/PythonTests/Physics/tests/joints/Joints_BallLeadFollowerCollide.py
index 0e8d7ea255..1209cb6caf 100644
--- a/AutomatedTesting/Gem/PythonTests/Physics/tests/joints/Joints_BallLeadFollowerCollide.py
+++ b/AutomatedTesting/Gem/PythonTests/Physics/tests/joints/Joints_BallLeadFollowerCollide.py
@@ -52,9 +52,6 @@ def Joints_BallLeadFollowerCollide():
from editor_python_test_tools.utils import Report
from editor_python_test_tools.utils import TestHelper as helper
- import azlmbr.legacy.general as general
- import azlmbr.bus
-
from JointsHelper import JointEntityCollisionAware
# Helper Entity class - self.collided flag is set when instance receives collision event.
@@ -75,17 +72,12 @@ def Joints_BallLeadFollowerCollide():
lead = Entity("lead")
follower = Entity("follower")
- # 4) Wait for several seconds
- general.idle_wait(2.0) # wait for lead and follower to move
+ # 4) Wait for collision between lead and follower or timeout
+ Report.critical_result(Tests.check_collision_happened, helper.wait_for_condition(lambda: lead.collided and follower.collided, 10.0))
- # 5) Check to see if lead and follower behaved as expected
- Report.critical_result(Tests.check_collision_happened, lead.collided and follower.collided)
-
- # 6) Exit Game Mode
+ # 5) Exit Game Mode
helper.exit_game_mode(Tests.exit_game_mode)
-
-
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(Joints_BallLeadFollowerCollide)
diff --git a/AutomatedTesting/Gem/PythonTests/Physics/tests/joints/Joints_FixedLeadFollowerCollide.py b/AutomatedTesting/Gem/PythonTests/Physics/tests/joints/Joints_FixedLeadFollowerCollide.py
deleted file mode 100644
index e142941c5a..0000000000
--- a/AutomatedTesting/Gem/PythonTests/Physics/tests/joints/Joints_FixedLeadFollowerCollide.py
+++ /dev/null
@@ -1,92 +0,0 @@
-"""
-Copyright (c) Contributors to the Open 3D Engine Project.
-For complete copyright and license terms please see the LICENSE at the root of this distribution.
-
-SPDX-License-Identifier: Apache-2.0 OR MIT
-"""
-
-# Test case ID : C18243582
-# Test Case Title : Check that fixed joint allows lead-follower collision
-
-
-# fmt: off
-class Tests:
- enter_game_mode = ("Entered game mode", "Failed to enter game mode")
- exit_game_mode = ("Exited game mode", "Couldn't exit game mode")
- lead_found = ("Found lead", "Did not find lead")
- follower_found = ("Found follower", "Did not find follower")
- check_collision_happened = ("Lead and follower collided", "Lead and follower did not collide")
-# fmt: on
-
-
-def Joints_FixedLeadFollowerCollide():
- """
- Summary: Check that fixed joint allows lead-follower collision
-
- Level Description:
- lead - Starts above follower entity
- follower - Starts below lead entity. Constrained to lead entity with fixed joint. Starts with initial velocity of (5, 0, 0) in positive X direction.
-
- Expected Behavior:
- The follower entity moves in the positive X direction and the lead entity is dragged along towards the positive X direction.
- The x position of the lead entity is incremented from its original.
- The lead and follower entities are kept apart at a distance of approximately 1.0 due to collision.
-
- Test Steps:
- 1) Open Level
- 2) Enter Game Mode
- 3) Create and Validate Entities
- 4) Wait for several seconds
- 5) Check to see if lead and follower behaved as expected.
- 6) Exit Game Mode
- 7) Close Editor
-
- Note:
- - This test file must be called from the Open 3D Engine Editor command terminal
- - Any passed and failed tests are written to the Editor.log file.
- Parsing the file or running a log_monitor are required to observe the test results.
-
- :return: None
- """
- import os
- import sys
- from editor_python_test_tools.utils import Report
- from editor_python_test_tools.utils import TestHelper as helper
-
- import azlmbr.legacy.general as general
- import azlmbr.bus
-
- from JointsHelper import JointEntityCollisionAware
-
- # Helper Entity class - self.collided flag is set when instance receives collision event.
- class Entity(JointEntityCollisionAware):
- def criticalEntityFound(self): # Override function to use local Test dictionary
- Report.critical_result(Tests.__dict__[self.name + "_found"], self.id.isValid())
-
- # Main Script
- helper.init_idle()
-
- # 1) Open Level
- helper.open_level("Physics", "Joints_FixedLeadFollowerCollide")
-
- # 2) Enter Game Mode
- helper.enter_game_mode(Tests.enter_game_mode)
-
- # 3) Create and Validate Entities
- lead = Entity("lead")
- follower = Entity("follower")
-
- # 4) Wait for several seconds
- general.idle_wait(2.0) # wait for lead and follower to move
-
- # 5) Check to see if lead entity and follower collided
- Report.critical_result(Tests.check_collision_happened, lead.collided and follower.collided)
-
- # 6) Exit Game Mode
- helper.exit_game_mode(Tests.exit_game_mode)
-
-
-
-if __name__ == "__main__":
- from editor_python_test_tools.utils import Report
- Report.start_test(Joints_FixedLeadFollowerCollide)
diff --git a/AutomatedTesting/Gem/PythonTests/Physics/tests/joints/Joints_HingeNoLimitsConstrained.py b/AutomatedTesting/Gem/PythonTests/Physics/tests/joints/Joints_HingeNoLimitsConstrained.py
index 0870a807fc..0b3f88b4f6 100644
--- a/AutomatedTesting/Gem/PythonTests/Physics/tests/joints/Joints_HingeNoLimitsConstrained.py
+++ b/AutomatedTesting/Gem/PythonTests/Physics/tests/joints/Joints_HingeNoLimitsConstrained.py
@@ -52,11 +52,13 @@ def Joints_HingeNoLimitsConstrained():
"""
import os
import sys
+ import math
from editor_python_test_tools.utils import Report
from editor_python_test_tools.utils import TestHelper as helper
import azlmbr.legacy.general as general
import azlmbr.bus
+ import azlmbr.math as azmath
import JointsHelper
from JointsHelper import JointEntity
@@ -84,28 +86,65 @@ def Joints_HingeNoLimitsConstrained():
Report.info_vector3(lead.position, "lead initial position:")
Report.info_vector3(follower.position, "follower initial position:")
leadInitialPosition = lead.position
- followerInitialPosition = follower.position
- # 4) Wait for several seconds
- general.idle_wait(4.0) # wait for lead and follower to move
+ # 4) Wait for the follower to move above and over the lead or Timeout
+ normalizedStartPos = JointsHelper.getRelativeVector(lead.position, follower.position)
+ normalizedStartPos = normalizedStartPos.GetNormalizedSafe()
+
+ class WaitCondition:
+ ANGLE_CHECKPOINT_1 = math.radians(90)
+ ANGLE_CHECKPOINT_2 = math.radians(200)
+
+ angleAchieved = 0.0
+ followerMovedAbove90Deg = False #this is expected to be true to pass the test
+ followerMovedAbove200Deg = False #this is expected to be true to pass the test
+
+ jointNormal = azmath.Vector3(0.0, -1.0, 0.0) # the joint rotates around the y axis
+ def checkConditionMet(self):
+ #calculate the current follower-lead vector
+ normalVec = JointsHelper.getRelativeVector(lead.position, follower.position)
+ normalVec = normalVec.GetNormalizedSafe()
+
+ #triple product and get the angle
+ tripleProduct = normalizedStartPos.dot(normalVec.cross(self.jointNormal))
+ currentAngle = math.acos(normalizedStartPos.Dot(normalVec))
+ if tripleProduct < 0:
+ currentAngle = (2*math.pi) - currentAngle
+
+ #if the angle is now less then last time, it is no longer rising, so end the test.
+ if currentAngle < self.angleAchieved:
+ return True
+
+ #once we're passed the final check point, end the test
+ if currentAngle > self.ANGLE_CHECKPOINT_2:
+ self.followerMovedAbove200Deg = True
+ return True
+
+ self.angleAchieved = currentAngle
+ self.followerMovedAbove90Deg = currentAngle > self.ANGLE_CHECKPOINT_1
+ return False
+
+ def isFollowerPositionCorrect(self):
+ return self.followerMovedAbove90Deg and self.followerMovedAbove200Deg
+
+ waitCondition = WaitCondition()
+
+ MAX_WAIT_TIME = 10.0 #seconds
+ conditionMet = helper.wait_for_condition(lambda: waitCondition.checkConditionMet(), MAX_WAIT_TIME)
# 5) Check to see if lead and follower behaved as expected
- Report.info_vector3(lead.position, "lead position after 1 second:")
- Report.info_vector3(follower.position, "follower position after 1 second:")
+ Report.info_vector3(lead.position, "lead position after test run:")
+ Report.info_vector3(follower.position, "follower position after test run:")
leadPositionDelta = lead.position.Subtract(leadInitialPosition)
leadRemainedStill = JointsHelper.vector3SmallerThanScalar(leadPositionDelta, FLOAT_EPSILON)
Report.critical_result(Tests.check_lead_position, leadRemainedStill)
- followerSwingedOverLead = (follower.position.x < leadInitialPosition.x and
- follower.position.z > leadInitialPosition.z)
- Report.critical_result(Tests.check_follower_position, followerSwingedOverLead)
+ Report.critical_result(Tests.check_follower_position, conditionMet and waitCondition.isFollowerPositionCorrect())
# 6) Exit Game Mode
helper.exit_game_mode(Tests.exit_game_mode)
-
-
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(Joints_HingeNoLimitsConstrained)
diff --git a/AutomatedTesting/Gem/PythonTests/Physics/tests/rigid_body/RigidBody_KinematicModeWorks.py b/AutomatedTesting/Gem/PythonTests/Physics/tests/rigid_body/RigidBody_KinematicModeWorks.py
index 1c53854bab..05671389c2 100644
--- a/AutomatedTesting/Gem/PythonTests/Physics/tests/rigid_body/RigidBody_KinematicModeWorks.py
+++ b/AutomatedTesting/Gem/PythonTests/Physics/tests/rigid_body/RigidBody_KinematicModeWorks.py
@@ -80,6 +80,20 @@ def RigidBody_KinematicModeWorks():
ramp_id = general.find_game_entity("Ramp")
Report.result(Tests.find_ramp, ramp_id.IsValid())
+ # 2.1) setup collision handler
+ class RampTouched:
+ value = False
+
+ def on_collision_begin(args):
+ other_id = args[0]
+ if other_id.Equal(ramp_id):
+ Report.info("Box touched ramp")
+ RampTouched.value = True
+
+ handler = azlmbr.physics.CollisionNotificationBusHandler()
+ handler.connect(box_id)
+ handler.add_callback("OnCollisionBegin", on_collision_begin)
+
# 3) Check for kinematic ramp and not kinematic box
box_kinematic = azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "IsKinematic", box_id)
Report.result(Tests.box_is_not_kinematic, not box_kinematic)
@@ -98,21 +112,7 @@ def RigidBody_KinematicModeWorks():
ramp_pos_start = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", ramp_id)
Report.info("Ramp's initial position: {}".format(ramp_pos_start))
- # 6) Check to see that the box hits the ramp
- class RampTouched:
- value = False
-
- def on_collision_begin(args):
- other_id = args[0]
- if other_id.Equal(ramp_id):
- Report.info("Box touched ramp")
- RampTouched.value = True
-
- handler = azlmbr.physics.CollisionNotificationBusHandler()
- handler.connect(box_id)
- handler.add_callback("OnCollisionBegin", on_collision_begin)
-
- # 6.5) Wait for the box to touch the ramp or timeout
+ # 6) Wait for the box to touch the ramp or timeout
helper.wait_for_condition(lambda: RampTouched.value, TIME_OUT)
Report.result(Tests.box_touched_ramp, RampTouched.value)
diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/assets/C30936451/test_texture_sequence000.png.exportsettings b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/assets/C30936451/test_texture_sequence000.png.exportsettings
deleted file mode 100644
index a8fbf72992..0000000000
--- a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/assets/C30936451/test_texture_sequence000.png.exportsettings
+++ /dev/null
@@ -1 +0,0 @@
-/autooptimizefile=0 /preset=Terrain_Albedo_HighPassed /reduce=0
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/PythonTests/automatedtesting_shared/screenshot_utils.py b/AutomatedTesting/Gem/PythonTests/automatedtesting_shared/screenshot_utils.py
index 49cf17855f..22fa3aca0d 100755
--- a/AutomatedTesting/Gem/PythonTests/automatedtesting_shared/screenshot_utils.py
+++ b/AutomatedTesting/Gem/PythonTests/automatedtesting_shared/screenshot_utils.py
@@ -187,7 +187,3 @@ def prepare_for_screenshot_compare(remote_console_instance):
"""
wait_for(lambda: _retry_command(remote_console_instance, 'r_displayinfo 0',
'$3r_DisplayInfo = $60 $5[DUMPTODISK, RESTRICTEDMODE]$4'))
- wait_for(lambda: _retry_command(remote_console_instance, 'r_antialiasingmode 0',
- '$3r_AntialiasingMode = $60 $5[]$4'))
- wait_for(lambda: _retry_command(remote_console_instance, 'e_WaterOcean 0',
- '$3e_WaterOcean = $60 $5[]$4'))
diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/BasicEditorWorkflows_ExistingLevel_EntityComponentCRUD.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/BasicEditorWorkflows_ExistingLevel_EntityComponentCRUD.py
new file mode 100644
index 0000000000..39cacf9af5
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/BasicEditorWorkflows_ExistingLevel_EntityComponentCRUD.py
@@ -0,0 +1,101 @@
+"""
+Copyright (c) Contributors to the Open 3D Engine Project.
+For complete copyright and license terms please see the LICENSE at the root of this distribution.
+
+SPDX-License-Identifier: Apache-2.0 OR MIT
+"""
+
+
+class Tests:
+ load_level = (
+ "Level loaded successfully",
+ "Failed to load the level"
+ )
+ create_entity = (
+ "Parent entity created successfully",
+ "Failed to create a parent entity"
+ )
+ set_entity_name = (
+ "Entity name set successfully",
+ "Failed to set entity name"
+ )
+ delete_entity = (
+ "Parent Entity deleted successfully",
+ "Failed to delete parent entity"
+ )
+ create_child_entity = (
+ "Child entity created successfully",
+ "Failed to create a child entity"
+ )
+ delete_child_entity = (
+ "Child entity deleted successfully",
+ "Failed to delete child entity"
+ )
+ add_mesh_component = (
+ "Mesh component added successfully",
+ "Failed to add mesh component"
+ )
+ found_component_typeId = (
+ "Found component typeId",
+ "Unable to find component TypeId"
+ )
+ remove_mesh_component = (
+ "Mesh component removed successfully",
+ "Failed to remove mesh component"
+ )
+
+
+def BasicEditorWorkflows_ExistingLevel_EntityComponentCRUD():
+ """
+ Performing basic test in editor
+ 01. Load exiting level
+ 02. create parent entity and set name
+ 03. create child entity and set a name
+ 04. delete child entity
+ 05. add mesh component to parent entity
+ 06. delete parent entity
+ """
+
+ from editor_python_test_tools.utils import Report
+ from editor_python_test_tools.editor_entity_utils import EditorEntity
+
+ import azlmbr.bus as bus
+ import azlmbr.editor as editor
+ import azlmbr.entity as entity
+ import azlmbr.legacy.general as general
+ import azlmbr.object
+
+ # 01. load an existing level
+ test_level = 'Simple'
+ general.open_level_no_prompt(test_level)
+ Report.result(Tests.load_level, general.get_current_level_name() == test_level)
+
+ # 02. create parent entity and set name
+ # Delete any exiting entity and Create a new Entity at the root level
+ search_filter = azlmbr.entity.SearchFilter()
+ all_entities = entity.SearchBus(azlmbr.bus.Broadcast, "SearchEntities", search_filter)
+ editor.ToolsApplicationRequestBus(bus.Broadcast, "DeleteEntities", all_entities)
+ parent_entity = EditorEntity.create_editor_entity("Parent_1")
+ Report.result(Tests.create_entity, parent_entity.exists())
+
+ # 03. Create child Entity to above created parent entity and set a name
+ child_1_entity = EditorEntity.create_editor_entity("Child_1", parent_entity.id )
+ Report.result(Tests.create_child_entity, child_1_entity.exists())
+
+ # 04. delete_Child_entity
+ child_1_entity.delete()
+ Report.result(Tests.delete_child_entity, not child_1_entity.exists())
+
+ # 05. add mesh component to parent entity
+ parent_entity.add_component("Mesh")
+ Report.result(Tests.add_mesh_component, parent_entity.has_component("Mesh"))
+
+ # 06. delete parent entity
+ parent_entity.delete()
+ Report.result(Tests.delete_entity, not parent_entity.exists())
+
+
+if __name__ == "__main__":
+ from editor_python_test_tools.utils import Report
+
+ Report.start_test(BasicEditorWorkflows_ExistingLevel_EntityComponentCRUD)
diff --git a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main_Optimized.py b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main_Optimized.py
index 9c0b99daff..afc52f962d 100644
--- a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main_Optimized.py
+++ b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main_Optimized.py
@@ -73,3 +73,7 @@ class TestAutomationAutoTestMode(EditorTestSuite):
@pytest.mark.skip(reason="Times out due to dialogs failing to dismiss: LYN-4208")
class test_Menus_FileMenuOptions_Work(EditorSharedTest):
from .EditorScripts import Menus_FileMenuOptions as test_module
+
+
+ class test_BasicEditorWorkflows_ExistingLevel_EntityComponentCRUD(EditorSharedTest):
+ from .EditorScripts import BasicEditorWorkflows_ExistingLevel_EntityComponentCRUD as test_module
diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/largeworlds/CMakeLists.txt
index d5c7fd5109..c2123d683c 100644
--- a/AutomatedTesting/Gem/PythonTests/largeworlds/CMakeLists.txt
+++ b/AutomatedTesting/Gem/PythonTests/largeworlds/CMakeLists.txt
@@ -55,32 +55,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
## LandscapeCanvas ##
- ly_add_pytest(
- NAME AutomatedTesting::LandscapeCanvasTests_Main
- TEST_SERIAL
- TEST_SUITE main
- PATH ${CMAKE_CURRENT_LIST_DIR}/landscape_canvas/TestSuite_Main.py
- RUNTIME_DEPENDENCIES
- AZ::AssetProcessor
- Legacy::Editor
- AutomatedTesting.Assets
- COMPONENT
- LargeWorlds
- )
-
- ly_add_pytest(
- NAME AutomatedTesting::LandscapeCanvasTests_Periodic
- TEST_SERIAL
- TEST_SUITE periodic
- PATH ${CMAKE_CURRENT_LIST_DIR}/landscape_canvas/TestSuite_Periodic.py
- RUNTIME_DEPENDENCIES
- AZ::AssetProcessor
- Legacy::Editor
- AutomatedTesting.Assets
- COMPONENT
- LargeWorlds
- )
-
ly_add_pytest(
NAME AutomatedTesting::LandscapeCanvasTests_Main_Optimized
TEST_SERIAL
diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/TestSuite_Main_Optimized.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/TestSuite_Main_Optimized.py
index 9cc572ad69..0461ff2647 100644
--- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/TestSuite_Main_Optimized.py
+++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/TestSuite_Main_Optimized.py
@@ -12,7 +12,6 @@ import ly_test_tools.environment.file_system as file_system
from ly_test_tools.o3de.editor_test import EditorSingleTest, EditorSharedTest, EditorParallelTest, EditorTestSuite
-@pytest.mark.xfail(reason="Optimized tests are experimental, we will enable xfail and monitor them temporarily.")
@pytest.mark.SUITE_periodic
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
@pytest.mark.parametrize("project", ["AutomatedTesting"])
diff --git a/AutomatedTesting/Levels/Physics/Joints_FixedLeadFollowerCollide/Joints_FixedLeadFollowerCollide.ly b/AutomatedTesting/Levels/Physics/Joints_FixedLeadFollowerCollide/Joints_FixedLeadFollowerCollide.ly
deleted file mode 100644
index 0c3ac9e668..0000000000
--- a/AutomatedTesting/Levels/Physics/Joints_FixedLeadFollowerCollide/Joints_FixedLeadFollowerCollide.ly
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:3093fee5317ba6fb353a435c09f43f13c5e722421aae62a297f699c202d6129e
-size 6699
diff --git a/AutomatedTesting/Levels/Physics/Joints_FixedLeadFollowerCollide/filelist.xml b/AutomatedTesting/Levels/Physics/Joints_FixedLeadFollowerCollide/filelist.xml
deleted file mode 100644
index d0960f8154..0000000000
--- a/AutomatedTesting/Levels/Physics/Joints_FixedLeadFollowerCollide/filelist.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
diff --git a/AutomatedTesting/Levels/Physics/Joints_FixedLeadFollowerCollide/level.pak b/AutomatedTesting/Levels/Physics/Joints_FixedLeadFollowerCollide/level.pak
deleted file mode 100644
index 532be2c1bd..0000000000
--- a/AutomatedTesting/Levels/Physics/Joints_FixedLeadFollowerCollide/level.pak
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:b1daa050e732ff0594601bbfca8ac9ed05972c2f9fa3e43dbc8645e802ed2730
-size 7959
diff --git a/AutomatedTesting/Levels/Physics/Joints_FixedLeadFollowerCollide/leveldata/Environment.xml b/AutomatedTesting/Levels/Physics/Joints_FixedLeadFollowerCollide/leveldata/Environment.xml
deleted file mode 100644
index 4ba36f66ae..0000000000
--- a/AutomatedTesting/Levels/Physics/Joints_FixedLeadFollowerCollide/leveldata/Environment.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/AutomatedTesting/Levels/Physics/Joints_FixedLeadFollowerCollide/leveldata/TerrainTexture.xml b/AutomatedTesting/Levels/Physics/Joints_FixedLeadFollowerCollide/leveldata/TerrainTexture.xml
deleted file mode 100644
index f43df05b22..0000000000
--- a/AutomatedTesting/Levels/Physics/Joints_FixedLeadFollowerCollide/leveldata/TerrainTexture.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
diff --git a/AutomatedTesting/Levels/Physics/Joints_FixedLeadFollowerCollide/leveldata/TimeOfDay.xml b/AutomatedTesting/Levels/Physics/Joints_FixedLeadFollowerCollide/leveldata/TimeOfDay.xml
deleted file mode 100644
index 456d609b8a..0000000000
--- a/AutomatedTesting/Levels/Physics/Joints_FixedLeadFollowerCollide/leveldata/TimeOfDay.xml
+++ /dev/null
@@ -1,356 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/AutomatedTesting/Levels/Physics/Joints_FixedLeadFollowerCollide/leveldata/VegetationMap.dat b/AutomatedTesting/Levels/Physics/Joints_FixedLeadFollowerCollide/leveldata/VegetationMap.dat
deleted file mode 100644
index dce5631cd0..0000000000
--- a/AutomatedTesting/Levels/Physics/Joints_FixedLeadFollowerCollide/leveldata/VegetationMap.dat
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:0e6a5435c928079b27796f6b202bbc2623e7e454244ddc099a3cadf33b7cb9e9
-size 63
diff --git a/AutomatedTesting/Levels/Physics/Joints_FixedLeadFollowerCollide/tags.txt b/AutomatedTesting/Levels/Physics/Joints_FixedLeadFollowerCollide/tags.txt
deleted file mode 100644
index 0d6c1880e7..0000000000
--- a/AutomatedTesting/Levels/Physics/Joints_FixedLeadFollowerCollide/tags.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-0,0,0,0,0,0
-0,0,0,0,0,0
-0,0,0,0,0,0
-0,0,0,0,0,0
-0,0,0,0,0,0
-0,0,0,0,0,0
-0,0,0,0,0,0
-0,0,0,0,0,0
-0,0,0,0,0,0
-0,0,0,0,0,0
-0,0,0,0,0,0
-0,0,0,0,0,0
diff --git a/AutomatedTesting/Levels/Physics/Joints_FixedLeadFollowerCollide/terraintexture.pak b/AutomatedTesting/Levels/Physics/Joints_FixedLeadFollowerCollide/terraintexture.pak
deleted file mode 100644
index fe3604a050..0000000000
--- a/AutomatedTesting/Levels/Physics/Joints_FixedLeadFollowerCollide/terraintexture.pak
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:8739c76e681f900923b900c9df0ef75cf421d39cabb54650c4b9ad19b6a76d85
-size 22
diff --git a/AutomatedTesting/Levels/Physics/Joints_HingeNoLimitsConstrained/Joints_HingeNoLimitsConstrained.ly b/AutomatedTesting/Levels/Physics/Joints_HingeNoLimitsConstrained/Joints_HingeNoLimitsConstrained.ly
index 3d17ae7ccc..9babf84ba4 100644
--- a/AutomatedTesting/Levels/Physics/Joints_HingeNoLimitsConstrained/Joints_HingeNoLimitsConstrained.ly
+++ b/AutomatedTesting/Levels/Physics/Joints_HingeNoLimitsConstrained/Joints_HingeNoLimitsConstrained.ly
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:012caffa9354f6253d2e626ba183b44eb02a74eba286fde0430227ef024411e2
-size 8961
+oid sha256:60276c07b45a734e4f71d695278167ea61e884f8b513906168c9642078ad5954
+size 6045
diff --git a/AutomatedTesting/Levels/Physics/RigidBody_KinematicModeWorks/RigidBody_KinematicModeWorks.ly b/AutomatedTesting/Levels/Physics/RigidBody_KinematicModeWorks/RigidBody_KinematicModeWorks.ly
index 92e6788bf0..d6052ffa7c 100644
--- a/AutomatedTesting/Levels/Physics/RigidBody_KinematicModeWorks/RigidBody_KinematicModeWorks.ly
+++ b/AutomatedTesting/Levels/Physics/RigidBody_KinematicModeWorks/RigidBody_KinematicModeWorks.ly
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:619bcf0c2a2b08f4ffe05e60858c479828fe39d5530f4e488b9c0ec8a585ccb7
-size 7735
+oid sha256:cb97ada674d123c67d7a32eb65e81fa66472cf51f748054c4a4297649f2a0f40
+size 5568
diff --git a/AutomatedTesting/Objects/LumberTank/ProxyGray_ddna.tif.exportsettings b/AutomatedTesting/Objects/LumberTank/ProxyGray_ddna.tif.exportsettings
deleted file mode 100644
index a4e1a9a3c5..0000000000
--- a/AutomatedTesting/Objects/LumberTank/ProxyGray_ddna.tif.exportsettings
+++ /dev/null
@@ -1 +0,0 @@
-/autooptimizefile=0 /M=50,50,0,50,50,50 /preset=NormalsWithSmoothness /reduce="android:1,ios:1,mac:0,pc:0,provo:0"
\ No newline at end of file
diff --git a/AutomatedTesting/Objects/MorphTargets/DisplayWrinkleMaskBlendValues.material b/AutomatedTesting/Objects/MorphTargets/DisplayWrinkleMaskBlendValues.material
new file mode 100644
index 0000000000..878b3ac39f
--- /dev/null
+++ b/AutomatedTesting/Objects/MorphTargets/DisplayWrinkleMaskBlendValues.material
@@ -0,0 +1,13 @@
+{
+ "description": "",
+ "materialType": "Materials/Types/Skin.materialtype",
+ "parentMaterial": "",
+ "propertyLayoutVersion": 3,
+ "properties": {
+ "wrinkleLayers": {
+ "count": 3,
+ "enable": true,
+ "showBlendValues": true
+ }
+ }
+}
diff --git a/AutomatedTesting/Objects/MorphTargets/morphActor.fbx b/AutomatedTesting/Objects/MorphTargets/morphActor.fbx
new file mode 100644
index 0000000000..ffb75e680e
--- /dev/null
+++ b/AutomatedTesting/Objects/MorphTargets/morphActor.fbx
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:53e17ec8155911c8b42e85436130f600bd6dddd8931a8ccb1b2f8a9f8674cc85
+size 45104
diff --git a/AutomatedTesting/Objects/MorphTargets/morphActor_wrinklemasks/Morph1_wrinklemask.tif b/AutomatedTesting/Objects/MorphTargets/morphActor_wrinklemasks/Morph1_wrinklemask.tif
new file mode 100644
index 0000000000..3bc18cf450
--- /dev/null
+++ b/AutomatedTesting/Objects/MorphTargets/morphActor_wrinklemasks/Morph1_wrinklemask.tif
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:0da56a05daa0ec1c476cfe25ca6d3b65267c98886cf33408f6e852fb325a8e2c
+size 198084
diff --git a/AutomatedTesting/Objects/MorphTargets/morphActor_wrinklemasks/Morph2_wriklemask.tif b/AutomatedTesting/Objects/MorphTargets/morphActor_wrinklemasks/Morph2_wriklemask.tif
new file mode 100644
index 0000000000..39e70f5acf
--- /dev/null
+++ b/AutomatedTesting/Objects/MorphTargets/morphActor_wrinklemasks/Morph2_wriklemask.tif
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:e3537fbe9205731a242251c525a67bbb5f3b8f5307537f1dc0c318b5b885ce52
+size 198112
diff --git a/AutomatedTesting/Objects/MorphTargets/morphActor_wrinklemasks/Morph3_wrinklemask.tif b/AutomatedTesting/Objects/MorphTargets/morphActor_wrinklemasks/Morph3_wrinklemask.tif
new file mode 100644
index 0000000000..43e19f0d5f
--- /dev/null
+++ b/AutomatedTesting/Objects/MorphTargets/morphActor_wrinklemasks/Morph3_wrinklemask.tif
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:bd794d5dd4b749c3275bfab79b9b5ae3f8e007d3e6741c0566c9c2d3931123bf
+size 198112
diff --git a/AutomatedTesting/Objects/MorphTargets/morphAnimation.fbx b/AutomatedTesting/Objects/MorphTargets/morphAnimation.fbx
new file mode 100644
index 0000000000..c0dcc007dc
--- /dev/null
+++ b/AutomatedTesting/Objects/MorphTargets/morphAnimation.fbx
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:45ded862987a64061deffd8e4c9aa1dff4eec3bcff5f7b505679f1959e8ae137
+size 51440
diff --git a/AutomatedTesting/Registry/assets_scan_folders.setreg b/AutomatedTesting/Registry/assets_scan_folders.setreg
index c74ba6703e..3043533b59 100644
--- a/AutomatedTesting/Registry/assets_scan_folders.setreg
+++ b/AutomatedTesting/Registry/assets_scan_folders.setreg
@@ -10,13 +10,6 @@
"Gems/DevTextures"
]
},
- "PBSreferenceMaterials":
- {
- "SourcePaths":
- [
- "Gems/PBSreferenceMaterials"
- ]
- },
"PhysicsEntities":
{
"SourcePaths":
diff --git a/AutomatedTesting/textures/lights/flare01.tif.exportsettings b/AutomatedTesting/textures/lights/flare01.tif.exportsettings
deleted file mode 100644
index 4fee4cfc4b..0000000000
--- a/AutomatedTesting/textures/lights/flare01.tif.exportsettings
+++ /dev/null
@@ -1 +0,0 @@
-/autooptimizefile=0 /preset=LensOptics /reduce=-1
\ No newline at end of file
diff --git a/AutomatedTesting/textures/milestone2/AMA_Grey_01.tif.exportsettings b/AutomatedTesting/textures/milestone2/AMA_Grey_01.tif.exportsettings
deleted file mode 100644
index 2d1dccbf99..0000000000
--- a/AutomatedTesting/textures/milestone2/AMA_Grey_01.tif.exportsettings
+++ /dev/null
@@ -1 +0,0 @@
-/autooptimizefile=0 /preset=Albedo /reduce=0
\ No newline at end of file
diff --git a/AutomatedTesting/textures/milestone2/AMA_Grey_02.tif.exportsettings b/AutomatedTesting/textures/milestone2/AMA_Grey_02.tif.exportsettings
deleted file mode 100644
index a8fbf72992..0000000000
--- a/AutomatedTesting/textures/milestone2/AMA_Grey_02.tif.exportsettings
+++ /dev/null
@@ -1 +0,0 @@
-/autooptimizefile=0 /preset=Terrain_Albedo_HighPassed /reduce=0
\ No newline at end of file
diff --git a/AutomatedTesting/textures/milestone2/AMA_Grey_03.tif.exportsettings b/AutomatedTesting/textures/milestone2/AMA_Grey_03.tif.exportsettings
deleted file mode 100644
index a8fbf72992..0000000000
--- a/AutomatedTesting/textures/milestone2/AMA_Grey_03.tif.exportsettings
+++ /dev/null
@@ -1 +0,0 @@
-/autooptimizefile=0 /preset=Terrain_Albedo_HighPassed /reduce=0
\ No newline at end of file
diff --git a/AutomatedTesting/textures/milestone2/particles/FX_LauncherMuzzleFront_01.tif.exportsettings b/AutomatedTesting/textures/milestone2/particles/FX_LauncherMuzzleFront_01.tif.exportsettings
deleted file mode 100644
index be29bd9bc0..0000000000
--- a/AutomatedTesting/textures/milestone2/particles/FX_LauncherMuzzleFront_01.tif.exportsettings
+++ /dev/null
@@ -1 +0,0 @@
-/autooptimizefile=0 /preset=AlbedoWithOpacity /reduce=0
\ No newline at end of file
diff --git a/AutomatedTesting/textures/milestone2/particles/FX_LauncherMuzzleRing_01.tif.exportsettings b/AutomatedTesting/textures/milestone2/particles/FX_LauncherMuzzleRing_01.tif.exportsettings
deleted file mode 100644
index be29bd9bc0..0000000000
--- a/AutomatedTesting/textures/milestone2/particles/FX_LauncherMuzzleRing_01.tif.exportsettings
+++ /dev/null
@@ -1 +0,0 @@
-/autooptimizefile=0 /preset=AlbedoWithOpacity /reduce=0
\ No newline at end of file
diff --git a/Code/Editor/CMakeLists.txt b/Code/Editor/CMakeLists.txt
index 2ea0aa1a74..bdfac373eb 100644
--- a/Code/Editor/CMakeLists.txt
+++ b/Code/Editor/CMakeLists.txt
@@ -102,7 +102,7 @@ ly_add_target(
3rdParty::Qt::Gui
3rdParty::Qt::Widgets
3rdParty::Qt::Concurrent
- 3rdParty::tiff
+ 3rdParty::TIFF
3rdParty::squish-ccr
3rdParty::AWSNativeSDK::STS
Legacy::CryCommon
diff --git a/Code/Editor/Controls/FolderTreeCtrl.cpp b/Code/Editor/Controls/FolderTreeCtrl.cpp
index 4088ab976f..1464580ffc 100644
--- a/Code/Editor/Controls/FolderTreeCtrl.cpp
+++ b/Code/Editor/Controls/FolderTreeCtrl.cpp
@@ -279,7 +279,7 @@ void CFolderTreeCtrl::LoadTreeRec(const QString& currentFolder)
void CFolderTreeCtrl::AddItem(const QString& path)
{
AZ::IO::FixedMaxPath folder{ AZ::IO::PathView(path.toUtf8().constData()) };
- AZ::IO::FixedMaxPath fileNameWithoutExtension = folder.Extension();
+ AZ::IO::FixedMaxPath fileNameWithoutExtension = folder.Stem();
folder = folder.ParentPath();
auto regex = QRegExp(m_fileNameSpec, Qt::CaseInsensitive, QRegExp::Wildcard);
diff --git a/Code/Editor/Core/LevelEditorMenuHandler.cpp b/Code/Editor/Core/LevelEditorMenuHandler.cpp
index b53076361e..fdde1ac305 100644
--- a/Code/Editor/Core/LevelEditorMenuHandler.cpp
+++ b/Code/Editor/Core/LevelEditorMenuHandler.cpp
@@ -32,6 +32,7 @@
#include
// AzToolsFramework
+#include
#include
// AzQtComponents
@@ -166,15 +167,14 @@ LevelEditorMenuHandler::LevelEditorMenuHandler(MainWindow* mainWindow, QtViewPan
m_mainWindow->menuBar()->setNativeMenuBar(true);
#endif
- ComponentModeFramework::EditorComponentModeNotificationBus::Handler::BusConnect(
- AzToolsFramework::GetEntityContextId());
+ ViewportEditorModeNotificationsBus::Handler::BusConnect(GetEntityContextId());
EditorMenuRequestBus::Handler::BusConnect();
}
LevelEditorMenuHandler::~LevelEditorMenuHandler()
{
EditorMenuRequestBus::Handler::BusDisconnect();
- ComponentModeFramework::EditorComponentModeNotificationBus::Handler::BusDisconnect();
+ ViewportEditorModeNotificationsBus::Handler::BusDisconnect();
}
void LevelEditorMenuHandler::Initialize()
@@ -1184,36 +1184,44 @@ void LevelEditorMenuHandler::AddDisableActionInSimModeListener(QAction* action)
}));
}
-void LevelEditorMenuHandler::EnteredComponentMode(const AZStd::vector& /*componentModeTypes*/)
+void LevelEditorMenuHandler::OnEditorModeActivated(
+ [[maybe_unused]] const AzToolsFramework::ViewportEditorModesInterface& editorModeState, AzToolsFramework::ViewportEditorMode mode)
{
- auto menuWrapper = m_actionManager->FindMenu(s_editMenuId);
- if (!menuWrapper.isNull())
+ if (mode == ViewportEditorMode::Component)
{
- // copy of menu actions
- auto actions = menuWrapper.Get()->actions();
- // remove all non-reserved edit menu options
- actions.erase(
- std::remove_if(actions.begin(), actions.end(), [](QAction* action)
- {
- return !action->property("Reserved").toBool();
- }),
- actions.end());
+ if (auto menuWrapper = m_actionManager->FindMenu(s_editMenuId);
+ !menuWrapper.isNull())
+ {
+ // copy of menu actions
+ auto actions = menuWrapper.Get()->actions();
+ // remove all non-reserved edit menu options
+ actions.erase(
+ std::remove_if(actions.begin(), actions.end(), [](QAction* action)
+ {
+ return !action->property("Reserved").toBool();
+ }),
+ actions.end());
- // clear and update the menu with new actions
- menuWrapper.Get()->clear();
- menuWrapper.Get()->addActions(actions);
+ // clear and update the menu with new actions
+ menuWrapper.Get()->clear();
+ menuWrapper.Get()->addActions(actions);
+ }
}
}
-void LevelEditorMenuHandler::LeftComponentMode(const AZStd::vector& /*componentModeTypes*/)
+void LevelEditorMenuHandler::OnEditorModeDeactivated(
+ [[maybe_unused]] const AzToolsFramework::ViewportEditorModesInterface& editorModeState, AzToolsFramework::ViewportEditorMode mode)
{
- RestoreEditMenuToDefault();
+ if (mode == ViewportEditorMode::Component)
+ {
+ RestoreEditMenuToDefault();
+ }
}
void LevelEditorMenuHandler::AddEditMenuAction(QAction* action)
{
- auto menuWrapper = m_actionManager->FindMenu(s_editMenuId);
- if (!menuWrapper.isNull())
+ if (auto menuWrapper = m_actionManager->FindMenu(s_editMenuId);
+ !menuWrapper.isNull())
{
menuWrapper.Get()->addAction(action);
}
@@ -1237,8 +1245,8 @@ void LevelEditorMenuHandler::AddMenuAction(AZStd::string_view categoryId, QActio
void LevelEditorMenuHandler::RestoreEditMenuToDefault()
{
- auto menuWrapper = m_actionManager->FindMenu(s_editMenuId);
- if (!menuWrapper.isNull())
+ if (auto menuWrapper = m_actionManager->FindMenu(s_editMenuId);
+ !menuWrapper.isNull())
{
menuWrapper.Get()->clear();
PopulateEditMenu(menuWrapper);
diff --git a/Code/Editor/Core/LevelEditorMenuHandler.h b/Code/Editor/Core/LevelEditorMenuHandler.h
index 5ac8e63786..ff03c7748c 100644
--- a/Code/Editor/Core/LevelEditorMenuHandler.h
+++ b/Code/Editor/Core/LevelEditorMenuHandler.h
@@ -18,7 +18,7 @@
#include
#include "ActionManager.h"
#include "QtViewPaneManager.h"
-#include
+#include
#endif
class MainWindow;
@@ -28,7 +28,7 @@ struct QtViewPane;
class LevelEditorMenuHandler
: public QObject
- , private AzToolsFramework::ComponentModeFramework::EditorComponentModeNotificationBus::Handler
+ , private AzToolsFramework::ViewportEditorModeNotificationsBus::Handler
, private AzToolsFramework::EditorMenuRequestBus::Handler
{
Q_OBJECT
@@ -88,9 +88,11 @@ private:
void AddDisableActionInSimModeListener(QAction* action);
- // EditorComponentModeNotificationBus
- void EnteredComponentMode(const AZStd::vector& componentModeTypes) override;
- void LeftComponentMode(const AZStd::vector& componentModeTypes) override;
+ // ViewportEditorModeNotificationsBus overrides ...
+ void OnEditorModeActivated(
+ const AzToolsFramework::ViewportEditorModesInterface& editorModeState, AzToolsFramework::ViewportEditorMode mode) override;
+ void OnEditorModeDeactivated(
+ const AzToolsFramework::ViewportEditorModesInterface& editorModeState, AzToolsFramework::ViewportEditorMode mode) override;
// EditorMenuRequestBus
void AddEditMenuAction(QAction* action) override;
diff --git a/Code/Editor/CryEdit.cpp b/Code/Editor/CryEdit.cpp
index abba2bb9c6..4f2e995ac4 100644
--- a/Code/Editor/CryEdit.cpp
+++ b/Code/Editor/CryEdit.cpp
@@ -57,6 +57,7 @@ AZ_POP_DISABLE_WARNING
#include
#include
#include
+#include
// AzToolsFramework
#include
@@ -3021,6 +3022,15 @@ CCryEditApp::ECreateLevelResult CCryEditApp::CreateLevel(const QString& levelNam
bool bIsDocModified = GetIEditor()->GetDocument()->IsModified();
OnSwitchPhysics();
GetIEditor()->GetDocument()->SetModifiedFlag(bIsDocModified);
+
+ if (usePrefabSystemForLevels)
+ {
+ auto* rootSpawnableInterface = AzFramework::RootSpawnableInterface::Get();
+ if (rootSpawnableInterface)
+ {
+ rootSpawnableInterface->ProcessSpawnableQueue();
+ }
+ }
}
const QScopedValueRollback rollback(m_creatingNewLevel);
diff --git a/Code/Editor/CryEditDoc.cpp b/Code/Editor/CryEditDoc.cpp
index 75bd0ad270..4944c3bff5 100644
--- a/Code/Editor/CryEditDoc.cpp
+++ b/Code/Editor/CryEditDoc.cpp
@@ -1273,7 +1273,7 @@ bool CCryEditDoc::SaveLevel(const QString& filename)
if (savedEntities)
{
AZ_PROFILE_SCOPE(AzToolsFramework, "CCryEditDoc::SaveLevel Updated PakFile levelEntities.editor_xml");
- pakFile.UpdateFile("LevelEntities.editor_xml", entitySaveBuffer.begin(), static_cast(entitySaveBuffer.size()));
+ pakFile.UpdateFile("levelentities.editor_xml", entitySaveBuffer.begin(), static_cast(entitySaveBuffer.size()));
// Save XML archive to pak file.
bool bSaved = xmlAr.SaveToPak(Path::GetPath(tempSaveFile), pakFile);
@@ -1501,7 +1501,7 @@ bool CCryEditDoc::LoadEntitiesFromLevel(const QString& levelPakFile)
bool pakOpened = pakSystem->OpenPack(levelPakFile.toUtf8().data());
if (pakOpened)
{
- const QString entityFilename = Path::GetPath(levelPakFile) + "LevelEntities.editor_xml";
+ const QString entityFilename = Path::GetPath(levelPakFile) + "levelentities.editor_xml";
CCryFile entitiesFile;
if (entitiesFile.Open(entityFilename.toUtf8().data(), "rt"))
diff --git a/Code/Editor/GameExporter.cpp b/Code/Editor/GameExporter.cpp
index 9315505e08..0324629877 100644
--- a/Code/Editor/GameExporter.cpp
+++ b/Code/Editor/GameExporter.cpp
@@ -28,6 +28,7 @@
#include "Objects/EntityObject.h"
#include
+#include
//////////////////////////////////////////////////////////////////////////
#define MUSIC_LEVEL_LIBRARY_FILE "Music.xml"
diff --git a/Code/Editor/Lib/Tests/test_ModularViewportCameraController.cpp b/Code/Editor/Lib/Tests/test_ModularViewportCameraController.cpp
index 157291cfc2..ea3653f663 100644
--- a/Code/Editor/Lib/Tests/test_ModularViewportCameraController.cpp
+++ b/Code/Editor/Lib/Tests/test_ModularViewportCameraController.cpp
@@ -69,6 +69,7 @@ namespace UnitTest
m_rootWidget = AZStd::make_unique();
m_rootWidget->setFixedSize(WidgetSize);
+ m_rootWidget->move(0, 0); // explicitly set the widget to be in the upper left corner
m_controllerList = AZStd::make_shared();
m_controllerList->RegisterViewportContext(TestViewportId);
@@ -344,4 +345,51 @@ namespace UnitTest
// Clean-up
HaltCollaborators();
}
+
+ // test to verify deltas and cursor positions are handled correctly when the widget is moved
+ TEST_F(ModularViewportCameraControllerFixture, CameraDoesNotStutterAfterWidgetIsMoved)
+ {
+ // Given
+ PrepareCollaborators();
+ SandboxEditor::SetCameraCaptureCursorForLook(true);
+
+ const float deltaTime = 1.0f / 60.0f;
+
+ // When
+ // move cursor to the center of the screen
+ auto start = QPoint(WidgetSize.width() / 2, WidgetSize.height() / 2);
+ MouseMove(m_rootWidget.get(), start, QPoint(0, 0));
+ m_controllerList->UpdateViewport({ TestViewportId, AzFramework::FloatSeconds(deltaTime), AZ::ScriptTimePoint() });
+
+ // move camera right
+ const auto mouseDelta = QPoint(200, 0);
+ MousePressAndMove(m_rootWidget.get(), start, mouseDelta, Qt::MouseButton::RightButton);
+ m_controllerList->UpdateViewport({ TestViewportId, AzFramework::FloatSeconds(deltaTime), AZ::ScriptTimePoint() });
+
+ QTest::mouseRelease(m_rootWidget.get(), Qt::MouseButton::RightButton, Qt::NoModifier, start + mouseDelta);
+
+ // update the position of the widget
+ const auto offset = QPoint(500, 500);
+ m_rootWidget->move(offset);
+
+ // move cursor back to widget center
+ MouseMove(m_rootWidget.get(), start, QPoint(0, 0));
+ m_controllerList->UpdateViewport({ TestViewportId, AzFramework::FloatSeconds(deltaTime), AZ::ScriptTimePoint() });
+
+ // move camera left
+ MousePressAndMove(m_rootWidget.get(), start, -mouseDelta, Qt::MouseButton::RightButton);
+ m_controllerList->UpdateViewport({ TestViewportId, AzFramework::FloatSeconds(deltaTime), AZ::ScriptTimePoint() });
+
+ // Then
+ // ensure the camera rotation has returned to the identity
+ const AZ::Quaternion cameraRotation = m_cameraViewportContextView->GetCameraTransform().GetRotation();
+ const auto eulerAngles = AzFramework::EulerAngles(AZ::Matrix3x3::CreateFromQuaternion(cameraRotation));
+
+ using ::testing::FloatNear;
+ EXPECT_THAT(eulerAngles.GetX(), FloatNear(0.0f, 0.001f));
+ EXPECT_THAT(eulerAngles.GetZ(), FloatNear(0.0f, 0.001f));
+
+ // Clean-up
+ HaltCollaborators();
+ }
} // namespace UnitTest
diff --git a/Code/Editor/MainWindow.cpp b/Code/Editor/MainWindow.cpp
index 05477bb0c7..ed72cd9170 100644
--- a/Code/Editor/MainWindow.cpp
+++ b/Code/Editor/MainWindow.cpp
@@ -98,6 +98,7 @@ AZ_POP_DISABLE_WARNING
#include "ActionManager.h"
#include
+#include
#include
using namespace AZ;
diff --git a/Code/Editor/Objects/ObjectManager.cpp b/Code/Editor/Objects/ObjectManager.cpp
index f67cf24553..7057cc5b7b 100644
--- a/Code/Editor/Objects/ObjectManager.cpp
+++ b/Code/Editor/Objects/ObjectManager.cpp
@@ -30,6 +30,8 @@
#include "Plugins/ComponentEntityEditorPlugin/Objects/ComponentEntityObject.h"
#include
+#include
+#include
AZ_CVAR_EXTERNED(bool, ed_visibility_logTiming);
@@ -107,14 +109,13 @@ CObjectManager::CObjectManager()
m_objectsByName.reserve(1024);
LoadRegistry();
- AzToolsFramework::ComponentModeFramework::EditorComponentModeNotificationBus::Handler::BusConnect(
- AzToolsFramework::GetEntityContextId());
+ AzToolsFramework::ViewportEditorModeNotificationsBus::Handler::BusConnect(AzToolsFramework::GetEntityContextId());
}
//////////////////////////////////////////////////////////////////////////
CObjectManager::~CObjectManager()
{
- AzToolsFramework::ComponentModeFramework::EditorComponentModeNotificationBus::Handler::BusDisconnect();
+ AzToolsFramework::ViewportEditorModeNotificationsBus::Handler::BusDisconnect();
m_bExiting = true;
SaveRegistry();
@@ -2306,25 +2307,33 @@ void CObjectManager::SelectObjectInRect(CBaseObject* pObj, CViewport* view, HitC
}
}
-void CObjectManager::EnteredComponentMode(const AZStd::vector& /*componentModeTypes*/)
+void CObjectManager::OnEditorModeActivated(
+ [[maybe_unused]] const AzToolsFramework::ViewportEditorModesInterface& editorModeState, AzToolsFramework::ViewportEditorMode mode)
{
- // hide current gizmo for entity (translate/rotate/scale)
- IGizmoManager* gizmoManager = GetGizmoManager();
- const size_t gizmoCount = static_cast(gizmoManager->GetGizmoCount());
- for (size_t i = 0; i < gizmoCount; ++i)
+ if (mode == AzToolsFramework::ViewportEditorMode::Component)
{
- gizmoManager->RemoveGizmo(gizmoManager->GetGizmoByIndex(static_cast(i)));
+ // hide current gizmo for entity (translate/rotate/scale)
+ IGizmoManager* gizmoManager = GetGizmoManager();
+ const size_t gizmoCount = static_cast(gizmoManager->GetGizmoCount());
+ for (size_t i = 0; i < gizmoCount; ++i)
+ {
+ gizmoManager->RemoveGizmo(gizmoManager->GetGizmoByIndex(static_cast(i)));
+ }
}
}
-void CObjectManager::LeftComponentMode(const AZStd::vector& /*componentModeTypes*/)
+void CObjectManager::OnEditorModeDeactivated(
+ [[maybe_unused]] const AzToolsFramework::ViewportEditorModesInterface& editorModeState, AzToolsFramework::ViewportEditorMode mode)
{
- // show translate/rotate/scale gizmo again
- if (IGizmoManager* gizmoManager = GetGizmoManager())
+ if (mode == AzToolsFramework::ViewportEditorMode::Component)
{
- if (CBaseObject* selectedObject = GetIEditor()->GetSelectedObject())
+ // show translate/rotate/scale gizmo again
+ if (IGizmoManager* gizmoManager = GetGizmoManager())
{
- gizmoManager->AddGizmo(new CAxisGizmo(selectedObject));
+ if (CBaseObject* selectedObject = GetIEditor()->GetSelectedObject())
+ {
+ gizmoManager->AddGizmo(new CAxisGizmo(selectedObject));
+ }
}
}
}
diff --git a/Code/Editor/Objects/ObjectManager.h b/Code/Editor/Objects/ObjectManager.h
index 0ad5d8323e..7fb2342e40 100644
--- a/Code/Editor/Objects/ObjectManager.h
+++ b/Code/Editor/Objects/ObjectManager.h
@@ -20,8 +20,9 @@
#include "ObjectManagerEventBus.h"
#include
-#include
+#include
#include
+#include
#include
// forward declarations.
@@ -58,7 +59,7 @@ public:
*/
class CObjectManager
: public IObjectManager
- , private AzToolsFramework::ComponentModeFramework::EditorComponentModeNotificationBus::Handler
+ , private AzToolsFramework::ViewportEditorModeNotificationsBus::Handler
{
public:
//! Selection functor callback.
@@ -329,9 +330,11 @@ private:
void FindDisplayableObjects(DisplayContext& dc, bool bDisplay);
- // EditorComponentModeNotificationBus
- void EnteredComponentMode(const AZStd::vector& componentModeTypes) override;
- void LeftComponentMode(const AZStd::vector& componentModeTypes) override;
+ // ViewportEditorModeNotificationsBus overrides ...
+ void OnEditorModeActivated(
+ const AzToolsFramework::ViewportEditorModesInterface& editorModeState, AzToolsFramework::ViewportEditorMode mode) override;
+ void OnEditorModeDeactivated(
+ const AzToolsFramework::ViewportEditorModesInterface& editorModeState, AzToolsFramework::ViewportEditorMode mode) override;
private:
typedef std::map Objects;
diff --git a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerWidget.cpp b/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerWidget.cpp
index 9ed7c4a144..803deb3509 100644
--- a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerWidget.cpp
+++ b/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerWidget.cpp
@@ -36,6 +36,7 @@
#include
#include
#include
+#include
#include
#include
@@ -267,8 +268,7 @@ OutlinerWidget::OutlinerWidget(QWidget* pParent, Qt::WindowFlags flags)
ToolsApplicationEvents::Bus::Handler::BusConnect();
AzToolsFramework::EditorEntityContextNotificationBus::Handler::BusConnect();
AzToolsFramework::SliceEditorEntityOwnershipServiceNotificationBus::Handler::BusConnect();
- AzToolsFramework::ComponentModeFramework::EditorComponentModeNotificationBus::Handler::BusConnect(
- AzToolsFramework::GetEntityContextId());
+ AzToolsFramework::ViewportEditorModeNotificationsBus::Handler::BusConnect(AzToolsFramework::GetEntityContextId());
AzToolsFramework::EditorEntityInfoNotificationBus::Handler::BusConnect();
AzToolsFramework::EditorWindowUIRequestBus::Handler::BusConnect();
}
@@ -276,7 +276,7 @@ OutlinerWidget::OutlinerWidget(QWidget* pParent, Qt::WindowFlags flags)
OutlinerWidget::~OutlinerWidget()
{
AzToolsFramework::EditorWindowUIRequestBus::Handler::BusDisconnect();
- AzToolsFramework::ComponentModeFramework::EditorComponentModeNotificationBus::Handler::BusDisconnect();
+ AzToolsFramework::ViewportEditorModeNotificationsBus::Handler::BusDisconnect();
AzToolsFramework::EditorEntityInfoNotificationBus::Handler::BusDisconnect();
AzToolsFramework::EditorPickModeNotificationBus::Handler::BusDisconnect();
EntityHighlightMessages::Bus::Handler::BusDisconnect();
@@ -1335,14 +1335,22 @@ void OutlinerWidget::SetEditorUiEnabled(bool enable)
EnableUi(enable);
}
-void OutlinerWidget::EnteredComponentMode([[maybe_unused]] const AZStd::vector& componentModeTypes)
+void OutlinerWidget::OnEditorModeActivated(
+ [[maybe_unused]] const AzToolsFramework::ViewportEditorModesInterface& editorModeState, AzToolsFramework::ViewportEditorMode mode)
{
- EnableUi(false);
+ if (mode == AzToolsFramework::ViewportEditorMode::Component)
+ {
+ EnableUi(false);
+ }
}
-void OutlinerWidget::LeftComponentMode([[maybe_unused]] const AZStd::vector& componentModeTypes)
+void OutlinerWidget::OnEditorModeDeactivated(
+ [[maybe_unused]] const AzToolsFramework::ViewportEditorModesInterface& editorModeState, AzToolsFramework::ViewportEditorMode mode)
{
- EnableUi(true);
+ if (mode == AzToolsFramework::ViewportEditorMode::Component)
+ {
+ EnableUi(true);
+ }
}
void OutlinerWidget::OnSliceInstantiated(const AZ::Data::AssetId& /*sliceAssetId*/, AZ::SliceComponent::SliceInstanceAddress& sliceAddress, const AzFramework::SliceInstantiationTicket& /*ticket*/)
diff --git a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerWidget.hxx b/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerWidget.hxx
index b29032a760..364ab05eb7 100644
--- a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerWidget.hxx
+++ b/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerWidget.hxx
@@ -16,7 +16,7 @@
#include
#include
#include
-#include
+#include
#include
#include
#include
@@ -58,7 +58,7 @@ class OutlinerWidget
, private AzToolsFramework::EditorEntityContextNotificationBus::Handler
, private AzToolsFramework::SliceEditorEntityOwnershipServiceNotificationBus::Handler
, private AzToolsFramework::EditorEntityInfoNotificationBus::Handler
- , private AzToolsFramework::ComponentModeFramework::EditorComponentModeNotificationBus::Handler
+ , private AzToolsFramework::ViewportEditorModeNotificationsBus::Handler
, private AzToolsFramework::EditorWindowUIRequestBus::Handler
{
Q_OBJECT;
@@ -105,9 +105,11 @@ private:
void OnEntityInfoUpdatedAddChildEnd(AZ::EntityId /*parentId*/, AZ::EntityId /*childId*/) override;
void OnEntityInfoUpdatedName(AZ::EntityId entityId, const AZStd::string& /*name*/) override;
- // EditorComponentModeNotificationBus
- void EnteredComponentMode(const AZStd::vector& componentModeTypes) override;
- void LeftComponentMode(const AZStd::vector& componentModeTypes) override;
+ // ViewportEditorModeNotificationsBus overrides ...
+ void OnEditorModeActivated(
+ const AzToolsFramework::ViewportEditorModesInterface& editorModeState, AzToolsFramework::ViewportEditorMode mode) override;
+ void OnEditorModeDeactivated(
+ const AzToolsFramework::ViewportEditorModesInterface& editorModeState, AzToolsFramework::ViewportEditorMode mode) override;
// EditorWindowUIRequestBus overrides
void SetEditorUiEnabled(bool enable) override;
diff --git a/Code/Editor/QtViewPaneManager.cpp b/Code/Editor/QtViewPaneManager.cpp
index eff3a7331e..1ac4b9cfe3 100644
--- a/Code/Editor/QtViewPaneManager.cpp
+++ b/Code/Editor/QtViewPaneManager.cpp
@@ -37,6 +37,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -44,11 +45,54 @@
#include
#include
#include
-
#include
#include "ShortcutDispatcher.h"
+// Helper for EditorComponentModeNotifications to be used
+// as a member instead of inheriting from EBus directly.
+class ViewportEditorModeNotificationsBusImpl
+ : public AzToolsFramework::ViewportEditorModeNotificationsBus::Handler
+{
+ public:
+ // Set the function to be called when entering ComponentMode.
+ void SetEnteredComponentModeFunc(
+ const AZStd::function& enteredComponentModeFunc)
+ {
+ m_enteredComponentModeFunc = enteredComponentModeFunc;
+ }
+
+ // Set the function to be called when leaving ComponentMode.
+ void SetLeftComponentModeFunc(
+ const AZStd::function& leftComponentModeFunc)
+ {
+ m_leftComponentModeFunc = leftComponentModeFunc;
+ }
+
+ private:
+ // ViewportEditorModeNotificationsBus overrides ...
+ void OnEditorModeActivated(
+ const AzToolsFramework::ViewportEditorModesInterface& editorModeState, AzToolsFramework::ViewportEditorMode mode) override
+ {
+ if (mode == AzToolsFramework::ViewportEditorMode::Component)
+ {
+ m_enteredComponentModeFunc(editorModeState);
+ }
+ }
+
+ void OnEditorModeDeactivated(
+ const AzToolsFramework::ViewportEditorModesInterface& editorModeState, AzToolsFramework::ViewportEditorMode mode) override
+ {
+ if (mode == AzToolsFramework::ViewportEditorMode::Component)
+ {
+ m_leftComponentModeFunc(editorModeState);
+ }
+ }
+
+ AZStd::function m_enteredComponentModeFunc; ///< Function to call when entering ComponentMode.
+ AZStd::function m_leftComponentModeFunc; ///< Function to call when leaving ComponentMode.
+};
+
struct ViewLayoutState
{
QVector viewPanes;
@@ -519,16 +563,17 @@ QtViewPaneManager::QtViewPaneManager(QObject* parent)
, m_settings(nullptr)
, m_restoreInProgress(false)
, m_advancedDockManager(nullptr)
+ , m_componentModeNotifications(AZStd::make_unique())
{
qRegisterMetaTypeStreamOperators("ViewLayoutState");
qRegisterMetaTypeStreamOperators >("QVector");
// view pane manager is interested when we enter/exit ComponentMode
- m_componentModeNotifications.BusConnect(AzToolsFramework::GetEntityContextId());
+ m_componentModeNotifications->BusConnect(AzToolsFramework::GetEntityContextId());
m_windowRequest.BusConnect();
- m_componentModeNotifications.SetEnteredComponentModeFunc(
- [this](const AZStd::vector& /*componentModeTypes*/)
+ m_componentModeNotifications->SetEnteredComponentModeFunc(
+ [this](const AzToolsFramework::ViewportEditorModesInterface&)
{
// gray out panels when entering ComponentMode
SetDefaultActionsEnabled(false, m_registeredPanes, [](QWidget* widget, bool on)
@@ -537,8 +582,8 @@ QtViewPaneManager::QtViewPaneManager(QObject* parent)
});
});
- m_componentModeNotifications.SetLeftComponentModeFunc(
- [this](const AZStd::vector& /*componentModeTypes*/)
+ m_componentModeNotifications->SetLeftComponentModeFunc(
+ [this](const AzToolsFramework::ViewportEditorModesInterface&)
{
// enable panels again when leaving ComponentMode
SetDefaultActionsEnabled(true, m_registeredPanes, [](QWidget* widget, bool on)
@@ -563,7 +608,7 @@ QtViewPaneManager::QtViewPaneManager(QObject* parent)
QtViewPaneManager::~QtViewPaneManager()
{
m_windowRequest.BusDisconnect();
- m_componentModeNotifications.BusDisconnect();
+ m_componentModeNotifications->BusDisconnect();
}
static bool lessThan(const QtViewPane& v1, const QtViewPane& v2)
diff --git a/Code/Editor/QtViewPaneManager.h b/Code/Editor/QtViewPaneManager.h
index 3ad1cc9cf7..0515ae726e 100644
--- a/Code/Editor/QtViewPaneManager.h
+++ b/Code/Editor/QtViewPaneManager.h
@@ -17,7 +17,6 @@
#include
#include
#include
-#include
#include
#include
@@ -34,6 +33,7 @@
#endif
class QMainWindow;
+class ViewportEditorModeNotificationsBusImpl;
struct ViewLayoutState;
namespace AzQtComponents
@@ -245,9 +245,9 @@ private:
QPointer m_advancedDockManager;
- using EditorComponentModeNotificationBusImpl = AzToolsFramework::ComponentModeFramework::EditorComponentModeNotificationBusImpl;
- EditorComponentModeNotificationBusImpl m_componentModeNotifications; //!< Helper for EditorComponentModeNotificationBus so
- //!< QtViewPaneManager does not need to inherit directly from it. */
+ AZStd::unique_ptr
+ m_componentModeNotifications; //!< Helper for EditorComponentModeNotificationBus so
+ //!< QtViewPaneManager does not need to inherit directly from it. */
using EditorWindowRequestBusImpl = AzToolsFramework::EditorWindowRequestBusImpl;
EditorWindowRequestBusImpl m_windowRequest; //!< Helper for EditorWindowRequestBus so
diff --git a/Code/Editor/Util/FileUtil.cpp b/Code/Editor/Util/FileUtil.cpp
index eeb6912acf..baca69d628 100644
--- a/Code/Editor/Util/FileUtil.cpp
+++ b/Code/Editor/Util/FileUtil.cpp
@@ -1195,7 +1195,7 @@ bool CFileUtil::IsFileExclusivelyAccessable(const QString& strFilePath)
//////////////////////////////////////////////////////////////////////////
bool CFileUtil::CreatePath(const QString& strPath)
{
-#if defined(AZ_PLATFORM_MAC)
+#if !AZ_TRAIT_OS_USE_WINDOWS_FILE_PATHS
bool pathCreated = true;
QString cleanPath = QDir::cleanPath(strPath);
@@ -1252,7 +1252,7 @@ bool CFileUtil::CreatePath(const QString& strPath)
}
return true;
-#endif
+#endif // !AZ_TRAIT_OS_USE_WINDOWS_FILE_PATHS
}
//////////////////////////////////////////////////////////////////////////
diff --git a/Code/Editor/Util/XmlArchive.cpp b/Code/Editor/Util/XmlArchive.cpp
index 18c3fc8e63..3a965fb239 100644
--- a/Code/Editor/Util/XmlArchive.cpp
+++ b/Code/Editor/Util/XmlArchive.cpp
@@ -119,7 +119,7 @@ bool CXmlArchive::SaveToPak([[maybe_unused]] const QString& levelPath, CPakFile&
_smart_ptr pXmlStrData = root->getXMLData(5000000);
// Save xml file.
- QString xmlFilename = "Level.editor_xml";
+ QString xmlFilename = "level.editor_xml";
pakFile.UpdateFile(xmlFilename.toUtf8().data(), (void*)pXmlStrData->GetString(), static_cast(pXmlStrData->GetStringLength()));
if (pakFile.GetArchive())
@@ -134,7 +134,7 @@ bool CXmlArchive::SaveToPak([[maybe_unused]] const QString& levelPath, CPakFile&
//////////////////////////////////////////////////////////////////////////
bool CXmlArchive::LoadFromPak(const QString& levelPath, CPakFile& pakFile)
{
- QString xmlFilename = QDir(levelPath).absoluteFilePath("Level.editor_xml");
+ QString xmlFilename = QDir(levelPath).absoluteFilePath("level.editor_xml");
root = XmlHelpers::LoadXmlFromFile(xmlFilename.toUtf8().data());
if (!root)
{
diff --git a/Code/Editor/Viewport.cpp b/Code/Editor/Viewport.cpp
index 5b4f4a4df3..c8f2e268d9 100644
--- a/Code/Editor/Viewport.cpp
+++ b/Code/Editor/Viewport.cpp
@@ -19,6 +19,7 @@
#include
#include
+#include
// Editor
#include "ViewManager.h"
diff --git a/Code/Framework/AzCore/AzCore/Console/Console.cpp b/Code/Framework/AzCore/AzCore/Console/Console.cpp
index a1b8a1759d..9f207d9afd 100644
--- a/Code/Framework/AzCore/AzCore/Console/Console.cpp
+++ b/Code/Framework/AzCore/AzCore/Console/Console.cpp
@@ -476,15 +476,16 @@ namespace AZ
// Responsible for using the Json Serialization Issue Callback system
// to determine when a JSON Patch or JSON Merge Patch modifies a value
- // at a path underneath the IConsole::ConsoleRootCommandKey JSON pointer
+ // at a path underneath the IConsole::ConsoleRuntimeCommandKey JSON pointer
JsonSerializationResult::ResultCode operator()(AZStd::string_view message,
JsonSerializationResult::ResultCode result, AZStd::string_view path)
{
- AZ::IO::PathView consoleRootCommandKey{ IConsole::ConsoleRootCommandKey, AZ::IO::PosixPathSeparator };
+ constexpr AZ::IO::PathView consoleRootCommandKey{ IConsole::ConsoleRuntimeCommandKey, AZ::IO::PosixPathSeparator };
+ constexpr AZ::IO::PathView consoleAutoexecCommandKey{ IConsole::ConsoleAutoexecCommandKey, AZ::IO::PosixPathSeparator };
AZ::IO::PathView inputKey{ path, AZ::IO::PosixPathSeparator };
if (result.GetTask() == JsonSerializationResult::Tasks::Merge
&& result.GetProcessing() == JsonSerializationResult::Processing::Completed
- && inputKey.IsRelativeTo(consoleRootCommandKey))
+ && (inputKey.IsRelativeTo(consoleRootCommandKey) || inputKey.IsRelativeTo(consoleAutoexecCommandKey)))
{
if (auto type = m_settingsRegistry.GetType(path); type != SettingsRegistryInterface::Type::NoType)
{
@@ -510,12 +511,24 @@ namespace AZ
{
using FixedValueString = AZ::SettingsRegistryInterface::FixedValueString;
- AZ::IO::PathView consoleRootCommandKey{ IConsole::ConsoleRootCommandKey, AZ::IO::PosixPathSeparator };
+ constexpr AZ::IO::PathView consoleRuntimeCommandKey{ IConsole::ConsoleRuntimeCommandKey, AZ::IO::PosixPathSeparator };
+ constexpr AZ::IO::PathView consoleAutoexecCommandKey{ IConsole::ConsoleAutoexecCommandKey, AZ::IO::PosixPathSeparator };
AZ::IO::PathView inputKey{ path, AZ::IO::PosixPathSeparator };
- // The ConsoleRootComamndKey is not a command itself so strictly children keys are being examined
- if (inputKey.IsRelativeTo(consoleRootCommandKey) && inputKey != consoleRootCommandKey)
+
+ // Abuses the IsRelativeToFuncton function of the path class to extract the console
+ // command from the settings registry objects
+ FixedValueString command;
+ if (inputKey != consoleRuntimeCommandKey && inputKey.IsRelativeTo(consoleRuntimeCommandKey))
+ {
+ command = inputKey.LexicallyRelative(consoleRuntimeCommandKey).Native();
+ }
+ else if (inputKey != consoleAutoexecCommandKey && inputKey.IsRelativeTo(consoleAutoexecCommandKey))
+ {
+ command = inputKey.LexicallyRelative(consoleAutoexecCommandKey).Native();
+ }
+
+ if (!command.empty())
{
- FixedValueString command = inputKey.LexicallyRelative(consoleRootCommandKey).Native();
ConsoleCommandContainer commandArgs;
// Argument string which stores the value from the Settings Registry long enough
// to pass into the PerformCommand. The ConsoleCommandContainer stores string_views
@@ -603,9 +616,10 @@ namespace AZ
void Console::RegisterCommandInvokerWithSettingsRegistry(AZ::SettingsRegistryInterface& settingsRegistry)
{
- // Make sure the there is a JSON object at the path of AZ::IConsole::ConsoleRootCommandKey
+ // Make sure the there is a JSON object at the ConsoleRuntimeCommandKey or ConsoleAutoexecKey
// So that JSON Patch is able to add values underneath that object (JSON Patch doesn't create intermediate objects)
- settingsRegistry.MergeSettings(R"({ "Amazon": { "AzCore": { "Runtime": { "ConsoleCommands": {} } }}})",
+ settingsRegistry.MergeSettings(R"({ "Amazon": { "AzCore": { "Runtime": { "ConsoleCommands": {} } } })"
+ R"(,"O3DE": { "Autoexec": { "ConsoleCommands": {} } } })",
SettingsRegistryInterface::Format::JsonMergePatch);
m_consoleCommandKeyHandler = settingsRegistry.RegisterNotifier(ConsoleCommandKeyNotificationHandler{ settingsRegistry, *this });
diff --git a/Code/Framework/AzCore/AzCore/Console/IConsole.h b/Code/Framework/AzCore/AzCore/Console/IConsole.h
index dafc284ce3..73d17ac65a 100644
--- a/Code/Framework/AzCore/AzCore/Console/IConsole.h
+++ b/Code/Framework/AzCore/AzCore/Console/IConsole.h
@@ -31,7 +31,8 @@ namespace AZ
using FunctorVisitor = AZStd::function;
- inline static constexpr AZStd::string_view ConsoleRootCommandKey = "/Amazon/AzCore/Runtime/ConsoleCommands";
+ inline static constexpr AZStd::string_view ConsoleRuntimeCommandKey = "/Amazon/AzCore/Runtime/ConsoleCommands";
+ inline static constexpr AZStd::string_view ConsoleAutoexecCommandKey = "/O3DE/Autoexec/ConsoleCommands";
IConsole() = default;
virtual ~IConsole() = default;
diff --git a/Code/Framework/AzCore/AzCore/Debug/Timer.h b/Code/Framework/AzCore/AzCore/Debug/Timer.h
index 47bd3e1b95..6585fe7468 100644
--- a/Code/Framework/AzCore/AzCore/Debug/Timer.h
+++ b/Code/Framework/AzCore/AzCore/Debug/Timer.h
@@ -46,5 +46,23 @@ namespace AZ
private:
AZStd::sys_time_t m_timeStamp;
};
+
+ //! Utility type that updates the given variable with the lifetime of the object in cycles.
+ //! Useful for quick scope based timing.
+ struct ScopedTimer
+ {
+ explicit ScopedTimer(AZStd::sys_time_t& variable)
+ : m_variable(variable)
+ {
+ m_timer.Stamp();
+ }
+ ~ScopedTimer()
+ {
+ m_variable = m_timer.GetDeltaTimeInTicks();
+ }
+
+ AZStd::sys_time_t& m_variable;
+ Timer m_timer;
+ };
}
}
diff --git a/Code/Framework/AzCore/AzCore/EBus/EBus.h b/Code/Framework/AzCore/AzCore/EBus/EBus.h
index a3dc10b103..67cffb4e41 100644
--- a/Code/Framework/AzCore/AzCore/EBus/EBus.h
+++ b/Code/Framework/AzCore/AzCore/EBus/EBus.h
@@ -77,9 +77,11 @@ namespace AZ
public:
/**
* Allocator used by the EBus.
- * The default setting is AZStd::allocator, which uses AZ::SystemAllocator.
+ * The default setting is Internal EBusEnvironmentAllocator
+ * EBus code stores their Context instances in static memory
+ * Therfore the configured allocator must last as long as the EBus in a module
*/
- using AllocatorType = AZStd::allocator;
+ using AllocatorType = AZ::Internal::EBusEnvironmentAllocator;
/**
* Defines how many handlers can connect to an address on the EBus
diff --git a/Code/Framework/AzCore/AzCore/Math/IntersectSegment.cpp b/Code/Framework/AzCore/AzCore/Math/IntersectSegment.cpp
index a7a0d5197e..5d13acc34c 100644
--- a/Code/Framework/AzCore/AzCore/Math/IntersectSegment.cpp
+++ b/Code/Framework/AzCore/AzCore/Math/IntersectSegment.cpp
@@ -15,7 +15,7 @@ using namespace Intersect;
// IntersectSegmentTriangleCCW
// [10/21/2009]
//=========================================================================
-int Intersect::IntersectSegmentTriangleCCW(
+bool Intersect::IntersectSegmentTriangleCCW(
const Vector3& p, const Vector3& q, const Vector3& a, const Vector3& b, const Vector3& c,
/*float &u, float &v, float &w,*/ Vector3& normal, float& t)
{
@@ -34,7 +34,7 @@ int Intersect::IntersectSegmentTriangleCCW(
float d = qp.Dot(normal);
if (d <= 0.0f)
{
- return 0;
+ return false;
}
// Compute intersection t value of pq with plane of triangle. A ray
@@ -46,7 +46,7 @@ int Intersect::IntersectSegmentTriangleCCW(
// range segment check t[0,1] (it this case [0,d])
if (t < 0.0f || t > d)
{
- return 0;
+ return false;
}
// Compute barycentric coordinate components and test if within bounds
@@ -54,12 +54,12 @@ int Intersect::IntersectSegmentTriangleCCW(
v = ac.Dot(e);
if (v < 0.0f || v > d)
{
- return 0;
+ return false;
}
w = -ab.Dot(e);
if (w < 0.0f || v + w > d)
{
- return 0;
+ return false;
}
// Segment/ray intersects triangle. Perform delayed division and
@@ -72,14 +72,14 @@ int Intersect::IntersectSegmentTriangleCCW(
normal.Normalize();
- return 1;
+ return true;
}
//=========================================================================
// IntersectSegmentTriangle
// [10/21/2009]
//=========================================================================
-int
+bool
Intersect::IntersectSegmentTriangle(
const Vector3& p, const Vector3& q, const Vector3& a, const Vector3& b, const Vector3& c,
/*float &u, float &v, float &w,*/ Vector3& normal, float& t)
@@ -111,7 +111,7 @@ Intersect::IntersectSegmentTriangle(
// so either have a parallel ray or our normal is flipped
if (d >= -Constants::FloatEpsilon)
{
- return 0; // parallel
+ return false; // parallel
}
d = -d;
e = ap.Cross(qp);
@@ -125,19 +125,19 @@ Intersect::IntersectSegmentTriangle(
// range segment check t[0,1] (it this case [0,d])
if (t < 0.0f || t > d)
{
- return 0;
+ return false;
}
// Compute barycentric coordinate components and test if within bounds
v = ac.Dot(e);
if (v < 0.0f || v > d)
{
- return 0;
+ return false;
}
w = -ab.Dot(e);
if (w < 0.0f || v + w > d)
{
- return 0;
+ return false;
}
// Segment/ray intersects the triangle. Perform delayed division and
@@ -150,14 +150,14 @@ Intersect::IntersectSegmentTriangle(
normal.Normalize();
- return 1;
+ return true;
}
//=========================================================================
// TestSegmentAABBOrigin
// [10/21/2009]
//=========================================================================
-int
+bool
AZ::Intersect::TestSegmentAABBOrigin(const Vector3& midPoint, const Vector3& halfVector, const Vector3& aabbExtends)
{
const Vector3 EPSILON(0.001f); // \todo this is slow load move to a const
@@ -168,7 +168,7 @@ AZ::Intersect::TestSegmentAABBOrigin(const Vector3& midPoint, const Vector3& hal
// Try world coordinate axes as separating axes
if (!absMidpoint.IsLessEqualThan(absHalfMidpoint))
{
- return 0;
+ return false;
}
// Add in an epsilon term to counteract arithmetic errors when segment is
@@ -188,11 +188,11 @@ AZ::Intersect::TestSegmentAABBOrigin(const Vector3& midPoint, const Vector3& hal
Vector3 ead(ey * adz + ez * ady, ex * adz + ez * adx, ex * ady + ey * adx);
if (!absMDCross.IsLessEqualThan(ead))
{
- return 0;
+ return false;
}
// No separating axis found; segment must be overlapping AABB
- return 1;
+ return true;
}
@@ -200,7 +200,7 @@ AZ::Intersect::TestSegmentAABBOrigin(const Vector3& midPoint, const Vector3& hal
// IntersectRayAABB
// [10/21/2009]
//=========================================================================
-int
+RayAABBIsectTypes
AZ::Intersect::IntersectRayAABB(
const Vector3& rayStart, const Vector3& dir, const Vector3& dirRCP, const Aabb& aabb,
float& tStart, float& tEnd, Vector3& startNormal /*, Vector3& inter*/)
@@ -356,7 +356,7 @@ AZ::Intersect::IntersectRayAABB(
// IntersectRayAABB2
// [2/18/2011]
//=========================================================================
-int
+RayAABBIsectTypes
AZ::Intersect::IntersectRayAABB2(const Vector3& rayStart, const Vector3& dirRCP, const Aabb& aabb, float& start, float& end)
{
float tmin, tmax, tymin, tymax, tzmin, tzmax;
@@ -408,7 +408,7 @@ AZ::Intersect::IntersectRayAABB2(const Vector3& rayStart, const Vector3& dirRCP,
return ISECT_RAY_AABB_ISECT;
}
-int AZ::Intersect::IntersectRayDisk(
+bool AZ::Intersect::IntersectRayDisk(
const Vector3& rayOrigin, const Vector3& rayDir, const Vector3& diskCenter, const float diskRadius, const Vector3& diskNormal, float& t)
{
// First intersect with the plane of the disk
@@ -421,10 +421,10 @@ int AZ::Intersect::IntersectRayDisk(
if (pointOnPlane.GetDistance(diskCenter) < diskRadius)
{
t = planeIntersectionDistance;
- return 1;
+ return true;
}
}
- return 0;
+ return false;
}
// Reference: Real-Time Collision Detection - 5.3.7 Intersecting Ray or Segment Against Cylinder, and the book's errata.
@@ -1012,7 +1012,7 @@ int AZ::Intersect::IntersectRayQuad(
}
// reference: Real-Time Collision Detection, 5.3.3 Intersecting Ray or Segment Against Box
-int AZ::Intersect::IntersectRayBox(
+bool AZ::Intersect::IntersectRayBox(
const Vector3& rayOrigin, const Vector3& rayDir, const Vector3& boxCenter, const Vector3& boxAxis1,
const Vector3& boxAxis2, const Vector3& boxAxis3, float boxHalfExtent1, float boxHalfExtent2, float boxHalfExtent3, float& t)
{
@@ -1044,7 +1044,7 @@ int AZ::Intersect::IntersectRayBox(
// If the ray is parallel to the slab and the ray origin is outside, return no intersection.
if (tp < 0.0f || tn < 0.0f)
{
- return 0;
+ return false;
}
}
else
@@ -1065,7 +1065,7 @@ int AZ::Intersect::IntersectRayBox(
tmax = AZ::GetMin(tmax, t2);
if (tmin > tmax)
{
- return 0;
+ return false;
}
}
@@ -1085,7 +1085,7 @@ int AZ::Intersect::IntersectRayBox(
// If the ray is parallel to the slab and the ray origin is outside, return no intersection.
if (tp < 0.0f || tn < 0.0f)
{
- return 0;
+ return false;
}
}
else
@@ -1106,7 +1106,7 @@ int AZ::Intersect::IntersectRayBox(
tmax = AZ::GetMin(tmax, t2);
if (tmin > tmax)
{
- return 0;
+ return false;
}
}
@@ -1126,7 +1126,7 @@ int AZ::Intersect::IntersectRayBox(
// If the ray is parallel to the slab and the ray origin is outside, return no intersection.
if (tp < 0.0f || tn < 0.0f)
{
- return 0;
+ return false;
}
}
else
@@ -1147,15 +1147,15 @@ int AZ::Intersect::IntersectRayBox(
tmax = AZ::GetMin(tmax, t2);
if (tmin > tmax)
{
- return 0;
+ return false;
}
}
t = (isRayOriginInsideBox ? tmax : tmin);
- return 1;
+ return true;
}
-int AZ::Intersect::IntersectRayObb(const Vector3& rayOrigin, const Vector3& rayDir, const Obb& obb, float& t)
+bool AZ::Intersect::IntersectRayObb(const Vector3& rayOrigin, const Vector3& rayDir, const Obb& obb, float& t)
{
return AZ::Intersect::IntersectRayBox(rayOrigin, rayDir, obb.GetPosition(),
obb.GetAxisX(), obb.GetAxisY(), obb.GetAxisZ(),
@@ -1166,7 +1166,7 @@ int AZ::Intersect::IntersectRayObb(const Vector3& rayOrigin, const Vector3& rayD
// IntersectSegmentCylinder
// [10/21/2009]
//=========================================================================
-int
+CylinderIsectTypes
AZ::Intersect::IntersectSegmentCylinder(
const Vector3& sa, const Vector3& dir, const Vector3& p, const Vector3& q, const float r, float& t)
{
@@ -1225,7 +1225,7 @@ AZ::Intersect::IntersectSegmentCylinder(
return RR_ISECT_RAY_CYL_NONE; // No real roots; no intersection
}
t = (-b - Sqrt(discr)) / a;
- int result = RR_ISECT_RAY_CYL_PQ; // default along the PQ segment
+ CylinderIsectTypes result = RR_ISECT_RAY_CYL_PQ; // default along the PQ segment
if (md + t * nd < 0.0f)
{
@@ -1294,7 +1294,7 @@ AZ::Intersect::IntersectSegmentCylinder(
// IntersectSegmentCapsule
// [10/21/2009]
//=========================================================================
-int
+CapsuleIsectTypes
AZ::Intersect::IntersectSegmentCapsule(const Vector3& sa, const Vector3& dir, const Vector3& p, const Vector3& q, const float r, float& t)
{
int result = IntersectSegmentCylinder(sa, dir, p, q, r, t);
@@ -1361,13 +1361,13 @@ AZ::Intersect::IntersectSegmentCapsule(const Vector3& sa, const Vector3& dir, co
// IntersectSegmentPolyhedron
// [10/21/2009]
//=========================================================================
-int
+bool
AZ::Intersect::IntersectSegmentPolyhedron(
- const Vector3& sa, const Vector3& sBA, const Plane p[], int numPlanes,
+ const Vector3& sa, const Vector3& dir, const Plane p[], int numPlanes,
float& tfirst, float& tlast, int& iFirstPlane, int& iLastPlane)
{
// Compute direction vector for the segment
- Vector3 d = /*b - a*/ sBA;
+ Vector3 d = /*b - a*/ dir;
// Set initial interval to being the whole segment. For a ray, tlast should be
// set to +RR_FLT_MAX. For a line, additionally tfirst should be set to -RR_FLT_MAX
tfirst = 0.0f;
@@ -1388,7 +1388,7 @@ AZ::Intersect::IntersectSegmentPolyhedron(
// If so, return "no intersection" if segment lies outside plane
if (dist < 0.0f)
{
- return 0;
+ return false;
}
}
else
@@ -1417,7 +1417,7 @@ AZ::Intersect::IntersectSegmentPolyhedron(
// Exit with "no intersection" if intersection becomes empty
if (tfirst > tlast)
{
- return 0;
+ return false;
}
}
}
@@ -1425,11 +1425,11 @@ AZ::Intersect::IntersectSegmentPolyhedron(
//DBG_Assert(iFirstPlane!=-1&&iLastPlane!=-1,("We have some bad border case to have only one plane, fix this function!"));
if (iFirstPlane == -1 && iLastPlane == -1)
{
- return 0;
+ return false;
}
// A nonzero logical intersection, so the segment intersects the polyhedron
- return 1;
+ return true;
}
//=========================================================================
@@ -1442,7 +1442,7 @@ AZ::Intersect::ClosestSegmentSegment(
const Vector3& segment2Start, const Vector3& segment2End,
float& segment1Proportion, float& segment2Proportion,
Vector3& closestPointSegment1, Vector3& closestPointSegment2,
- float epsilon /*= 1e-4f*/ )
+ float epsilon)
{
const Vector3 segment1 = segment1End - segment1Start;
const Vector3 segment2 = segment2End - segment2Start;
diff --git a/Code/Framework/AzCore/AzCore/Math/IntersectSegment.h b/Code/Framework/AzCore/AzCore/Math/IntersectSegment.h
index df3d5e10fb..523069987f 100644
--- a/Code/Framework/AzCore/AzCore/Math/IntersectSegment.h
+++ b/Code/Framework/AzCore/AzCore/Math/IntersectSegment.h
@@ -5,363 +5,398 @@
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
-#ifndef AZCORE_MATH_SEGMENT_INTERSECTION_H
-#define AZCORE_MATH_SEGMENT_INTERSECTION_H
+#pragma once
-#include
#include
#include
#include
-
-/// \file isect_segment.h
+#include
namespace AZ
{
namespace Intersect
{
//! LineToPointDistanceTime computes the time of the shortest distance from point 'p' to segment (s1,s2).
- //! To calculate the point of intersection:
- //! P = s1 + u (s2 - s1)
- //! @param s1 segment start point
- //! @param s2 segment end point
- //! @param p point to find the closest time to.
- //! @return time (on the segment) for the shortest distance from 'p' to (s1,s2) [0.0f (s1),1.0f (s2)]
- inline float LineToPointDistanceTime(const Vector3& s1, const Vector3& s21, const Vector3& p)
- {
- // so u = (p.x - s1.x)*(s2.x - s1.x) + (p.y - s1.y)*(s2.y - s1.y) + (p.z-s1.z)*(s2.z-s1.z) / |s2-s1|^2
- return s21.Dot(p - s1) / s21.Dot(s21);
- }
+ //! To calculate the point of intersection: P = s1 + u (s2 - s1)
+ //! @param s1 Segment start point.
+ //! @param s2 Segment end point.
+ //! @param p Point to find the closest time to.
+ //! @return Time (on the segment) for the shortest distance from 'p' to (s1,s2) [0.0f (s1),1.0f (s2)]
+ float LineToPointDistanceTime(const Vector3& s1, const Vector3& s21, const Vector3& p);
//! LineToPointDistance computes the closest point to 'p' from a segment (s1,s2).
- //! @param s1 segment start point
- //! @param s2 segment end point
- //! @param p point to find the closest time to.
- //! @param u time (on the segment) for the shortest distance from 'p' to (s1,s2) [0.0f (s1),1.0f (s2)]
- //! @return the closest point
- inline Vector3 LineToPointDistance(const Vector3& s1, const Vector3& s2, const Vector3& p, float& u)
- {
- const Vector3 s21 = s2 - s1;
- // we assume seg1 and seg2 are NOT coincident
- AZ_MATH_ASSERT(!s21.IsClose(Vector3(0.0f), 1e-4f), "OK we agreed that we will pass valid segments! (s1 != s2)");
-
- u = LineToPointDistanceTime(s1, s21, p);
-
- return s1 + u * s21;
- }
+ //! @param s1 Segment start point
+ //! @param s2 Segment end point
+ //! @param p Point to find the closest time to.
+ //! @param u Time (on the segment) for the shortest distance from 'p' to (s1,s2) [0.0f (s1),1.0f (s2)]
+ //! @return The closest point
+ Vector3 LineToPointDistance(const Vector3& s1, const Vector3& s2, const Vector3& p, float& u);
//! Given segment pq and triangle abc (CCW), returns whether segment intersects
//! triangle and if so, also returns the barycentric coordinates (u,v,w)
//! of the intersection point.
- //! @param p segment start point
- //! @param q segment end point
- //! @param a triangle point 1
- //! @param b triangle point 2
- //! @param c triangle point 3
- //! @param normal at the intersection point.
- //! @param t time of intersection along the segment [0.0 (p), 1.0 (q)]
- //! @return 1 if the segment intersects the triangle otherwise 0
- int IntersectSegmentTriangleCCW(
- const Vector3& p, const Vector3& q, const Vector3& a, const Vector3& b, const Vector3& c,
- /*float &u, float &v, float &w,*/ Vector3& normal, float& t);
+ //! @param p Segment start point.
+ //! @param q Segment end point.
+ //! @param a Triangle point 1.
+ //! @param b Triangle point 2.
+ //! @param c Triangle point 3.
+ //! @param normal At the intersection point.
+ //! @param t Time of intersection along the segment [0.0 (p), 1.0 (q)].
+ //! @return true if the segments intersects the triangle otherwise false.
+ bool IntersectSegmentTriangleCCW(
+ const Vector3& p, const Vector3& q, const Vector3& a, const Vector3& b, const Vector3& c, Vector3& normal, float& t);
//! Same as \ref IntersectSegmentTriangleCCW without respecting the triangle (a,b,c) vertex order (double sided).
- int IntersectSegmentTriangle(
- const Vector3& p, const Vector3& q, const Vector3& a, const Vector3& b, const Vector3& c,
- /*float &u, float &v, float &w,*/ Vector3& normal, float& t);
+ //! @param p Segment start point.
+ //! @param q Segment end point.
+ //! @param a Triangle point 1.
+ //! @param b Triangle point 2.
+ //! @param c Triangle point 3.
+ //! @param normal At the intersection point.
+ //! @param t Time of intersection along the segment [0.0 (p), 1.0 (q)].
+ //! @return True if the segments intersects the triangle otherwise false.
+ bool IntersectSegmentTriangle(
+ const Vector3& p, const Vector3& q, const Vector3& a, const Vector3& b, const Vector3& c, Vector3& normal, float& t);
//! Ray aabb intersection result types.
- enum RayAABBIsectTypes
+ enum RayAABBIsectTypes : AZ::s32
{
- ISECT_RAY_AABB_NONE = 0, ///< no intersection
- ISECT_RAY_AABB_SA_INSIDE, ///< the ray starts inside the aabb
- ISECT_RAY_AABB_ISECT, ///< intersects along the PQ segment
+ ISECT_RAY_AABB_NONE = 0, ///< no intersection
+ ISECT_RAY_AABB_SA_INSIDE, ///< the ray starts inside the aabb
+ ISECT_RAY_AABB_ISECT, ///< intersects along the PQ segment
};
//! Intersect ray R(t) = rayStart + t*d against AABB a. When intersecting,
//! return intersection distance tmin and point q of intersection.
- //! @param rayStart ray starting point
- //! @param dir ray direction and length (dir = rayEnd - rayStart)
- //! @param dirRCP 1/dir (reciprocal direction - we cache this result very often so we don't need to compute it multiple times, otherwise just use dir.GetReciprocal())
+ //! @param rayStart Ray starting point
+ //! @param dir Ray direction and length (dir = rayEnd - rayStart)
+ //! @param dirRCP 1/dir (reciprocal direction - we cache this result very often so we don't need to compute it multiple times,
+ //! otherwise just use dir.GetReciprocal())
//! @param aabb Axis aligned bounding box to intersect against
- //! @param tStart time on ray of the first intersection [0,1] or 0 if the ray starts inside the aabb - check the return value
- //! @param tEnd time of the of the second intersection [0,1] (it can be > 1 if intersects after the rayEnd)
- //! @param startNormal normal at the start point.
+ //! @param tStart Time on ray of the first intersection [0,1] or 0 if the ray starts inside the aabb - check the return value
+ //! @param tEnd Time of the of the second intersection [0,1] (it can be > 1 if intersects after the rayEnd)
+ //! @param startNormal Normal at the start point.
//! @return \ref RayAABBIsectTypes
- int IntersectRayAABB(
- const Vector3& rayStart, const Vector3& dir, const Vector3& dirRCP, const Aabb& aabb,
- float& tStart, float& tEnd, Vector3& startNormal /*, Vector3& inter*/);
+ RayAABBIsectTypes IntersectRayAABB(
+ const Vector3& rayStart,
+ const Vector3& dir,
+ const Vector3& dirRCP,
+ const Aabb& aabb,
+ float& tStart,
+ float& tEnd,
+ Vector3& startNormal);
//! Intersect ray against AABB.
- //! @param rayStart ray starting point.
- //! @param dir ray reciprocal direction.
+ //! @param rayStart Ray starting point.
+ //! @param dir Ray reciprocal direction.
//! @param aabb Axis aligned bounding box to intersect against.
- //! @param start length on ray of the first intersection.
- //! @param end length of the of the second intersection.
- //! @return \ref RayAABBIsectTypes In this faster version than IntersectRayAABB we return only ISECT_RAY_AABB_NONE and ISECT_RAY_AABB_ISECT.
- //! You can check yourself for that case.
- int IntersectRayAABB2(
- const Vector3& rayStart, const Vector3& dirRCP, const Aabb& aabb,
- float& start, float& end);
+ //! @param start Length on ray of the first intersection.
+ //! @param end Length of the of the second intersection.
+ //! @return \ref RayAABBIsectTypes In this faster version than IntersectRayAABB we return only ISECT_RAY_AABB_NONE and
+ //! ISECT_RAY_AABB_ISECT. You can check yourself for that case.
+ RayAABBIsectTypes IntersectRayAABB2(const Vector3& rayStart, const Vector3& dirRCP, const Aabb& aabb, float& start, float& end);
//! Clip a ray to an aabb. return true if ray was clipped. The ray
//! can be inside so don't use the result if the ray intersect the box.
- inline int ClipRayWithAabb(
- const Aabb& aabb, Vector3& rayStart, Vector3& rayEnd, float& tClipStart, float& tClipEnd)
- {
- Vector3 startNormal;
- float tStart, tEnd;
- Vector3 dirLen = rayEnd - rayStart;
- if (IntersectRayAABB(rayStart, dirLen, dirLen.GetReciprocal(), aabb, tStart, tEnd, startNormal) != ISECT_RAY_AABB_NONE)
- {
- // clip the ray with the box
- if (tStart > 0.0f)
- {
- rayStart = rayStart + tStart * dirLen;
- tClipStart = tStart;
- }
- if (tEnd < 1.0f)
- {
- rayEnd = rayStart + tEnd * dirLen;
- tClipEnd = tEnd;
- }
-
- return 1;
- }
-
- return 0;
- }
+ //! @param aabb Bounds to test against.
+ //! @param rayStart The start of the ray.
+ //! @param rayEnd The end of the ray.
+ //! @param[out] tClipStart The proportion where the ray enters the \ref Aabb.
+ //! @param[out] tClipEnd The proportion where the ray exits the \ref Aabb.
+ //! @return True if the ray was clipped, otherwise false.
+ bool ClipRayWithAabb(const Aabb& aabb, Vector3& rayStart, Vector3& rayEnd, float& tClipStart, float& tClipEnd);
//! Test segment and aabb where the segment is defined by midpoint
//! midPoint = (p1-p0) * 0.5f and half vector halfVector = p1 - midPoint.
//! the aabb is at the origin and defined by half extents only.
- //! @return 1 if the intersect, otherwise 0.
- int TestSegmentAABBOrigin(const Vector3& midPoint, const Vector3& halfVector, const Vector3& aabbExtends);
+ //! @param midPoint Midpoint of a line segment.
+ //! @param halfVector Half vector of an aabb.
+ //! @param aabbExtends The extends of a bounded box.
+ //! @return True if the segment and AABB intersect, otherwise false
+ bool TestSegmentAABBOrigin(const Vector3& midPoint, const Vector3& halfVector, const Vector3& aabbExtends);
- //! Test if segment specified by points p0 and p1 intersects AABB. \ref TestSegmentAABBOrigin
- //! @return 1 if the segment and AABB intersect, otherwise 0.
- inline int TestSegmentAABB(const Vector3& p0, const Vector3& p1, const Aabb& aabb)
- {
- Vector3 e = aabb.GetExtents();
- Vector3 d = p1 - p0;
- Vector3 m = p0 + p1 - aabb.GetMin() - aabb.GetMax();
-
- return TestSegmentAABBOrigin(m, d, e);
- }
+ //! Test if segment specified by points p0 and p1 intersects AABB. \ref TestSegmentAABBOrigin.
+ //! @param p0 Segment start point.
+ //! @param p1 Segment end point.
+ //! @param aabb Bounded box to test against.
+ //! @return True if the segment and AABB intersect, otherwise false.
+ bool TestSegmentAABB(const Vector3& p0, const Vector3& p1, const Aabb& aabb);
//! Ray sphere intersection result types.
- enum SphereIsectTypes
+ enum SphereIsectTypes : AZ::s32
{
- ISECT_RAY_SPHERE_SA_INSIDE = -1, // the ray starts inside the cylinder
- ISECT_RAY_SPHERE_NONE, // no intersection
- ISECT_RAY_SPHERE_ISECT, // along the PQ segment
+ ISECT_RAY_SPHERE_SA_INSIDE = -1, //!< The ray starts inside the cylinder
+ ISECT_RAY_SPHERE_NONE, //!< No intersection
+ ISECT_RAY_SPHERE_ISECT, //!< Along the PQ segment
};
//! IntersectRaySphereOrigin
//! return time t>=0 but not limited, so if you check a segment make sure
- //! t <= segmentLen
- //! @param rayStart ray start point
+ //! t <= segmentLen.
+ //! @param rayStart ray start point.
//! @param rayDirNormalized ray direction normalized.
- //! @param shereRadius sphere radius
+ //! @param shereRadius Radius of sphere at origin.
//! @param time of closest intersection [0,+INF] in relation to the normalized direction.
- //! @return \ref SphereIsectTypes
- AZ_INLINE int IntersectRaySphereOrigin(
- const Vector3& rayStart, const Vector3& rayDirNormalized,
- const float sphereRadius, float& t)
- {
- Vector3 m = rayStart;
- float b = m.Dot(rayDirNormalized);
- float c = m.Dot(m) - sphereRadius * sphereRadius;
-
- // Exit if r's origin outside s (c > 0)and r pointing away from s (b > 0)
- if (c > 0.0f && b > 0.0f)
- {
- return ISECT_RAY_SPHERE_NONE;
- }
- float discr = b * b - c;
- // A negative discriminant corresponds to ray missing sphere
- if (discr < 0.0f)
- {
- return ISECT_RAY_SPHERE_NONE;
- }
-
- // Ray now found to intersect sphere, compute smallest t value of intersection
- t = -b - Sqrt(discr);
-
- // If t is negative, ray started inside sphere so clamp t to zero
- if (t < 0.0f)
- {
- // t = 0.0f;
- return ISECT_RAY_SPHERE_SA_INSIDE; // no hit if inside
- }
- //q = p + t * d;
- return ISECT_RAY_SPHERE_ISECT;
- }
+ //! @return \ref SphereIsectTypes.
+ SphereIsectTypes IntersectRaySphereOrigin(
+ const Vector3& rayStart, const Vector3& rayDirNormalized, const float sphereRadius, float& t);
//! Intersect ray (rayStart,rayDirNormalized) and sphere (sphereCenter,sphereRadius) \ref IntersectRaySphereOrigin
- inline int IntersectRaySphere(
- const Vector3& rayStart, const Vector3& rayDirNormalized, const Vector3& sphereCenter, const float sphereRadius, float& t)
- {
- return IntersectRaySphereOrigin(rayStart - sphereCenter, rayDirNormalized, sphereRadius, t);
- }
+ //! @param rayStart The start of the ray.
+ //! @param rayDirNormalized The direction of the ray normalized.
+ //! @param sphereCenter The center of the sphere.
+ //! @param sphereRadius Radius of the sphere.
+ //! @param[out] t Coefficient in the ray's explicit equation from which an
+ //! intersecting point is calculated as "rayOrigin + t1 * rayDir".
+ //! @return SphereIsectTypes
+ SphereIsectTypes IntersectRaySphere(
+ const Vector3& rayStart, const Vector3& rayDirNormalized, const Vector3& sphereCenter, const float sphereRadius, float& t);
- //! @param rayOrigin The origin of the ray to test.
- //! @param rayDir The direction of the ray to test. It has to be unit length.
- //! @param diskCenter Center point of the disk
- //! @param diskRadius Radius of the disk
- //! @param diskNormal A normal perpendicular to the disk
- //! @param[out] t If returning 1 (indicating a hit), this contains distance from rayOrigin along the normalized rayDir that the hit occured at.
- //! @return The number of intersecting points.
- int IntersectRayDisk(
- const Vector3& rayOrigin, const Vector3& rayDir, const Vector3& diskCenter, const float diskRadius, const AZ::Vector3& diskNormal, float& t);
+ //! Intersect ray (rayStarty, rayDirNormalized) and disk (center, radius, normal)
+ //! @param rayOrigin The origin of the ray to test.
+ //! @param rayDir The direction of the ray to test. It has to be unit length.
+ //! @param diskCenter Center point of the disk.
+ //! @param diskRadius Radius of the disk.
+ //! @param diskNormal A normal perpendicular to the disk.
+ //! @param[out] t If returning 1 (indicating a hit), this contains distance from rayOrigin along the normalized rayDir
+ //! that the hit occured at.
+ //! @return False if not interesecting and true if intersecting
+ bool IntersectRayDisk(
+ const Vector3& rayOrigin,
+ const Vector3& rayDir,
+ const Vector3& diskCenter,
+ const float diskRadius,
+ const AZ::Vector3& diskNormal,
+ float& t);
//! If there is only one intersecting point, the coefficient is stored in \ref t1.
- //! @param rayOrigin The origin of the ray to test.
- //! @param rayDir The direction of the ray to test. It has to be unit length.
- //! @param cylinderEnd1 The center of the circle on one end of the cylinder.
- //! @param cylinderDir The direction pointing from \ref cylinderEnd1 to the other end of the cylinder. It has to be unit length.
- //! @param cylinderHeight The distance between two centers of the circles on two ends of the cylinder respectively.
- //! @param[out] t1 A possible coefficient in the ray's explicit equation from which an intersecting point is calculated as "rayOrigin + t1 * rayDir".
- //! @param[out] t2 A possible coefficient in the ray's explicit equation from which an intersecting point is calculated as "rayOrigin + t2 * rayDir".
- //! @return The number of intersecting points.
+ //! @param rayOrigin The origin of the ray to test.
+ //! @param rayDir The direction of the ray to test. It has to be unit length.
+ //! @param cylinderEnd1 The center of the circle on one end of the cylinder.
+ //! @param cylinderDir The direction pointing from \ref cylinderEnd1 to the other end of the cylinder. It has to be unit length.
+ //! @param cylinderHeight The distance between two centers of the circles on two ends of the cylinder respectively.
+ //! @param[out] t1 A possible coefficient in the ray's explicit equation from which an intersecting point is calculated as "rayOrigin + t1 * rayDir".
+ //! @param[out] t2 A possible coefficient in the ray's explicit equation from which an intersecting point is calculated as "rayOrigin + t2 * rayDir".
+ //! @return The number of intersecting points.
int IntersectRayCappedCylinder(
- const Vector3& rayOrigin, const Vector3& rayDir,
- const Vector3& cylinderEnd1, const Vector3& cylinderDir, float cylinderHeight, float cylinderRadius,
- float& t1, float& t2);
+ const Vector3& rayOrigin,
+ const Vector3& rayDir,
+ const Vector3& cylinderEnd1,
+ const Vector3& cylinderDir,
+ float cylinderHeight,
+ float cylinderRadius,
+ float& t1,
+ float& t2);
//! If there is only one intersecting point, the coefficient is stored in \ref t1.
- //! @param rayOrigin The origin of the ray to test.
- //! @param rayDir The direction of the ray to test. It has to be unit length.
- //! @param coneApex The apex of the cone.
- //! @param coneDir The unit-length direction from the apex to the base.
- //! @param coneHeight The height of the cone, from the apex to the base.
- //! @param coneBaseRadius The radius of the cone base circle.
- //! @param[out] t1 A possible coefficient in the ray's explicit equation from which an intersecting point is calculated as "rayOrigin + t1 * rayDir".
- //! @param[out] t2 A possible coefficient in the ray's explicit equation from which an intersecting point is calculated as "rayOrigin + t2 * rayDir".
- //! @return The number of intersecting points.
+ //! @param rayOrigin The origin of the ray to test.
+ //! @param rayDir The direction of the ray to test. It has to be unit length.
+ //! @param coneApex The apex of the cone.
+ //! @param coneDir The unit-length direction from the apex to the base.
+ //! @param coneHeight The height of the cone, from the apex to the base.
+ //! @param coneBaseRadius The radius of the cone base circle.
+ //! @param[out] t1 A possible coefficient in the ray's explicit equation from which an intersecting point is calculated as "rayOrigin + t1 * rayDir".
+ //! @param[out] t2 A possible coefficient in the ray's explicit equation from which an intersecting point is calculated as "rayOrigin + t2 * rayDir".
+ //! @return The number of intersecting points.
int IntersectRayCone(
- const Vector3& rayOrigin, const Vector3& rayDir,
- const Vector3& coneApex, const Vector3& coneDir, float coneHeight, float coneBaseRadius,
- float& t1, float& t2);
+ const Vector3& rayOrigin,
+ const Vector3& rayDir,
+ const Vector3& coneApex,
+ const Vector3& coneDir,
+ float coneHeight,
+ float coneBaseRadius,
+ float& t1,
+ float& t2);
//! Test intersection between a ray and a plane in 3D.
- //! @param rayOrigin The origin of the ray to test intersection with.
- //! @param rayDir The direction of the ray to test intersection with.
- //! @param planePos A point on the plane to test intersection with.
- //! @param planeNormal The normal of the plane to test intersection with.
- //! @param t[out] The coefficient in the ray's explicit equation from which the intersecting point is calculated as "rayOrigin + t * rayDirection".
- //! @return The number of intersection point.
+ //! @param rayOrigin The origin of the ray to test intersection with.
+ //! @param rayDir The direction of the ray to test intersection with.
+ //! @param planePos A point on the plane to test intersection with.
+ //! @param planeNormal The normal of the plane to test intersection with.
+ //! @param[out] t The coefficient in the ray's explicit equation from which the intersecting point is calculated as "rayOrigin + t * rayDirection".
+ //! @return The number of intersection point.
int IntersectRayPlane(
- const Vector3& rayOrigin, const Vector3& rayDir, const Vector3& planePos,
- const Vector3& planeNormal, float& t);
+ const Vector3& rayOrigin, const Vector3& rayDir, const Vector3& planePos, const Vector3& planeNormal, float& t);
//! Test intersection between a ray and a two-sided quadrilateral defined by four points in 3D.
- //! The four points that define the quadrilateral could be passed in with either counter clock-wise
+ //! The four points that define the quadrilateral could be passed in with either counter clock-wise
//! winding or clock-wise winding.
- //! @param rayOrigin The origin of the ray to test intersection with.
- //! @param rayDir The direction of the ray to test intersection with.
- //! @param vertexA One of the four points that define the quadrilateral.
- //! @param vertexB One of the four points that define the quadrilateral.
- //! @param vertexC One of the four points that define the quadrilateral.
- //! @param vertexD One of the four points that define the quadrilateral.
- //! @param t[out] The coefficient in the ray's explicit equation from which the intersecting point is calculated as "rayOrigin + t * rayDirection".
- //! @return The number of intersection point.
+ //! @param rayOrigin The origin of the ray to test intersection with.
+ //! @param rayDir The direction of the ray to test intersection with.
+ //! @param vertexA One of the four points that define the quadrilateral.
+ //! @param vertexB One of the four points that define the quadrilateral.
+ //! @param vertexC One of the four points that define the quadrilateral.
+ //! @param vertexD One of the four points that define the quadrilateral.
+ //! @param[out] t The coefficient in the ray's explicit equation from which the
+ //! intersecting point is calculated as "rayOrigin + t * rayDirection".
+ //! @return The number of intersection point.
int IntersectRayQuad(
- const Vector3& rayOrigin, const Vector3& rayDir, const Vector3& vertexA,
- const Vector3& vertexB, const Vector3& vertexC, const Vector3& vertexD, float& t);
+ const Vector3& rayOrigin,
+ const Vector3& rayDir,
+ const Vector3& vertexA,
+ const Vector3& vertexB,
+ const Vector3& vertexC,
+ const Vector3& vertexD,
+ float& t);
- //! Test intersection between a ray and an oriented box in 3D.
- //! @param rayOrigin The origin of the ray to test intersection with.
- //! @param rayDir The direction of the ray to test intersection with.
- //! @param boxCenter The position of the center of the box.
- //! @param boxAxis1 An axis along one dimension of the oriented box.
- //! @param boxAxis2 An axis along one dimension of the oriented box.
- //! @param boxAxis3 An axis along one dimension of the oriented box.
- //! @param boxHalfExtent1 The half extent of the box on the dimension of \ref boxAxis1.
- //! @param boxHalfExtent2 The half extent of the box on the dimension of \ref boxAxis2.
- //! @param boxHalfExtent3 The half extent of the box on the dimension of \ref boxAxis3.
- //! @param t[out] The coefficient in the ray's explicit equation from which the intersecting point is calculated as "rayOrigin + t * rayDirection".
- //! @return 1 if there is an intersection, 0 otherwise.
- int IntersectRayBox(
- const Vector3& rayOrigin, const Vector3& rayDir, const Vector3& boxCenter, const Vector3& boxAxis1,
- const Vector3& boxAxis2, const Vector3& boxAxis3, float boxHalfExtent1, float boxHalfExtent2, float boxHalfExtent3,
+ //! Test intersection between a ray and an oriented box in 3D.
+ //! @param rayOrigin The origin of the ray to test intersection with.
+ //! @param rayDir The direction of the ray to test intersection with.
+ //! @param boxCenter The position of the center of the box.
+ //! @param boxAxis1 An axis along one dimension of the oriented box.
+ //! @param boxAxis2 An axis along one dimension of the oriented box.
+ //! @param boxAxis3 An axis along one dimension of the oriented box.
+ //! @param boxHalfExtent1 The half extent of the box on the dimension of \ref boxAxis1.
+ //! @param boxHalfExtent2 The half extent of the box on the dimension of \ref boxAxis2.
+ //! @param boxHalfExtent3 The half extent of the box on the dimension of \ref boxAxis3.
+ //! @param[out] t The coefficient in the ray's explicit equation from which the intersecting point is calculated as "rayOrigin + t * rayDirection".
+ //! @return true if there is an intersection, false otherwise.
+ bool IntersectRayBox(
+ const Vector3& rayOrigin,
+ const Vector3& rayDir,
+ const Vector3& boxCenter,
+ const Vector3& boxAxis1,
+ const Vector3& boxAxis2,
+ const Vector3& boxAxis3,
+ float boxHalfExtent1,
+ float boxHalfExtent2,
+ float boxHalfExtent3,
float& t);
//! Test intersection between a ray and an OBB.
//! @param rayOrigin The origin of the ray to test intersection with.
//! @param rayDir The direction of the ray to test intersection with.
//! @param obb The OBB to test for intersection with the ray.
- //! @param t[out] The coefficient in the ray's explicit equation from which the intersecting point is calculated as "rayOrigin + t * rayDirection".
- //! @return 1 if there is an intersection, 0 otherwise.
- int IntersectRayObb(const Vector3& rayOrigin, const Vector3& rayDir, const Obb& obb, float& t);
+ //! @param[out] t The coefficient in the ray's explicit equation from which the intersecting point is calculated as "rayOrigin + t * rayDirection".
+ //! @return True if there is an intersection, false otherwise.
+ bool IntersectRayObb(const Vector3& rayOrigin, const Vector3& rayDir, const Obb& obb, float& t);
//! Ray cylinder intersection types.
- enum CylinderIsectTypes
+ enum CylinderIsectTypes : AZ::s32
{
- RR_ISECT_RAY_CYL_SA_INSIDE = -1, // the ray starts inside the cylinder
- RR_ISECT_RAY_CYL_NONE, // no intersection
- RR_ISECT_RAY_CYL_PQ, // along the PQ segment
- RR_ISECT_RAY_CYL_P_SIDE, // on the P side
- RR_ISECT_RAY_CYL_Q_SIDE, // on the Q side
+ RR_ISECT_RAY_CYL_SA_INSIDE = -1, //!< the ray starts inside the cylinder
+ RR_ISECT_RAY_CYL_NONE, //!< no intersection
+ RR_ISECT_RAY_CYL_PQ, //!< along the PQ segment
+ RR_ISECT_RAY_CYL_P_SIDE, //!< on the P side
+ RR_ISECT_RAY_CYL_Q_SIDE, //!< on the Q side
};
+ //! Reference: Real-Time Collision Detection - 5.3.7 Intersecting Ray or Segment Against Cylinder
//! Intersect segment S(t)=sa+t(dir), 0<=t<=1 against cylinder specified by p, q and r.
- int IntersectSegmentCylinder(
- const Vector3& sa, const Vector3& dir, const Vector3& p, const Vector3& q,
- const float r, float& t);
+ //! @param sa The initial point.
+ //! @param dir Magnitude and direction for sa.
+ //! @param p Center point of side 1 cylinder.
+ //! @param q Center point of side 2 cylinder.
+ //! @param r Radius of cylinder.
+ //! @param[out] t Proporition along line segment.
+ //! @return CylinderIsectTypes
+ CylinderIsectTypes IntersectSegmentCylinder(
+ const Vector3& sa, const Vector3& dir, const Vector3& p, const Vector3& q, const float r, float& t);
//! Capsule ray intersect types.
enum CapsuleIsectTypes
{
- ISECT_RAY_CAPSULE_SA_INSIDE = -1, // the ray starts inside the cylinder
- ISECT_RAY_CAPSULE_NONE, // no intersection
- ISECT_RAY_CAPSULE_PQ, // along the PQ segment
- ISECT_RAY_CAPSULE_P_SIDE, // on the P side
- ISECT_RAY_CAPSULE_Q_SIDE, // on the Q side
+ ISECT_RAY_CAPSULE_SA_INSIDE = -1, //!< The ray starts inside the cylinder
+ ISECT_RAY_CAPSULE_NONE, //!< No intersection
+ ISECT_RAY_CAPSULE_PQ, //!< Along the PQ segment
+ ISECT_RAY_CAPSULE_P_SIDE, //!< On the P side
+ ISECT_RAY_CAPSULE_Q_SIDE, //!< On the Q side
};
//! This is a quick implementation of segment capsule based on segment cylinder \ref IntersectSegmentCylinder
//! segment sphere intersection. We can optimize it a lot once we fix the ray
//! cylinder intersection.
- int IntersectSegmentCapsule(
- const Vector3& sa, const Vector3& dir, const Vector3& p,
- const Vector3& q, const float r, float& t);
+ //! @param sa The beginning of the line segment.
+ //! @param dir The direction and length of the segment.
+ //! @param p Center point of side 1 capsule.
+ //! @param q Center point of side 1 capsule.
+ //! @param r The radius of the capsule.
+ //! @param[out] t Proporition along line segment.
+ //! @return CapsuleIsectTypes
+ CapsuleIsectTypes IntersectSegmentCapsule(
+ const Vector3& sa, const Vector3& dir, const Vector3& p, const Vector3& q, const float r, float& t);
//! Intersect segment S(t)=A+t(B-A), 0<=t<=1 against convex polyhedron specified
//! by the n halfspaces defined by the planes p[]. On exit tfirst and tlast
//! define the intersection, if any.
- int IntersectSegmentPolyhedron(
- const Vector3& sa, const Vector3& sBA, const Plane p[], int numPlanes,
- float& tfirst, float& tlast, int& iFirstPlane, int& iLastPlane);
+ //! @param sa The beggining of the line segment.
+ //! @param dir The direction and length of the segment.
+ //! @param p Planes that compose a convex ponvex polyhedron.
+ //! @param numPlanes number of planes.
+ //! @param[out] tfirst Proportion along the line segment where the line enters.
+ //! @param[out] tlast Proportion along the line segment where the line exits.
+ //! @param[out] iFirstPlane The plane where the line enters.
+ //! @param[out] iLastPlane The plane where the line exits.
+ //! @return True if intersects else false.
+ bool IntersectSegmentPolyhedron(
+ const Vector3& sa,
+ const Vector3& dir,
+ const Plane p[],
+ int numPlanes,
+ float& tfirst,
+ float& tlast,
+ int& iFirstPlane,
+ int& iLastPlane);
//! Calculate the line segment closestPointSegment1<->closestPointSegment2 that is the shortest route between
- //! two segments segment1Start<->segment1End and segment2Start<->segment2End. Also calculate the values of segment1Proportion and segment2Proportion where
- //! closestPointSegment1 = segment1Start + (segment1Proportion * (segment1End - segment1Start))
+ //! two segments segment1Start<->segment1End and segment2Start<->segment2End. Also calculate the values of segment1Proportion and
+ //! segment2Proportion where closestPointSegment1 = segment1Start + (segment1Proportion * (segment1End - segment1Start))
//! closestPointSegment2 = segment2Start + (segment2Proportion * (segment2End - segment2Start))
//! If segments are parallel returns a solution.
+ //! @param segment1Start Start of segment 1.
+ //! @param segment1End End of segment 1.
+ //! @param segment2Start Start of segment 2.
+ //! @param segment2End End of segment 2.
+ //! @param[out] segment1Proportion The proporition along segment 1 [0..1]
+ //! @param[out] segment2Proportion The proporition along segment 2 [0..1]
+ //! @param[out] closestPointSegment1 Closest point on segment 1.
+ //! @param[out] closestPointSegment2 Closest point on segment 2.
+ //! @param epsilon The minimum square distance where a line segment can be treated as a single point.
void ClosestSegmentSegment(
- const Vector3& segment1Start, const Vector3& segment1End,
- const Vector3& segment2Start, const Vector3& segment2End,
- float& segment1Proportion, float& segment2Proportion,
- Vector3& closestPointSegment1, Vector3& closestPointSegment2,
+ const Vector3& segment1Start,
+ const Vector3& segment1End,
+ const Vector3& segment2Start,
+ const Vector3& segment2End,
+ float& segment1Proportion,
+ float& segment2Proportion,
+ Vector3& closestPointSegment1,
+ Vector3& closestPointSegment2,
float epsilon = 1e-4f);
//! Calculate the line segment closestPointSegment1<->closestPointSegment2 that is the shortest route between
//! two segments segment1Start<->segment1End and segment2Start<->segment2End.
//! If segments are parallel returns a solution.
+ //! @param segment1Start Start of segment 1.
+ //! @param segment1End End of segment 1.
+ //! @param segment2Start Start of segment 2.
+ //! @param segment2End End of segment 2.
+ //! @param[out] closestPointSegment1 Closest point on segment 1.
+ //! @param[out] closestPointSegment2 Closest point on segment 2.
+ //! @param epsilon The minimum square distance where a line segment can be treated as a single point.
void ClosestSegmentSegment(
- const Vector3& segment1Start, const Vector3& segment1End,
- const Vector3& segment2Start, const Vector3& segment2End,
- Vector3& closestPointSegment1, Vector3& closestPointSegment2,
+ const Vector3& segment1Start,
+ const Vector3& segment1End,
+ const Vector3& segment2Start,
+ const Vector3& segment2End,
+ Vector3& closestPointSegment1,
+ Vector3& closestPointSegment2,
float epsilon = 1e-4f);
//! Calculate the point (closestPointOnSegment) that is the closest point on
//! segment segmentStart/segmentEnd to point. Also calculate the value of proportion where
//! closestPointOnSegment = segmentStart + (proportion * (segmentEnd - segmentStart))
+ //! @param point The point to test
+ //! @param segmentStart The start of the segment
+ //! @param segmentEnd The end of the segment
+ //! @param[out] proportion The proportion of the segment L(t) = (end - start) * t
+ //! @param[out] closestPointOnSegment The point along the line segment
void ClosestPointSegment(
- const Vector3& point, const Vector3& segmentStart, const Vector3& segmentEnd,
- float& proportion, Vector3& closestPointOnSegment);
- }
-}
+ const Vector3& point,
+ const Vector3& segmentStart,
+ const Vector3& segmentEnd,
+ float& proportion,
+ Vector3& closestPointOnSegment);
+ } // namespace Intersect
+} // namespace AZ
-#endif // AZCORE_MATH_SEGMENT_INTERSECTION_H
-#pragma once
+#include
diff --git a/Code/Framework/AzCore/AzCore/Math/IntersectSegment.inl b/Code/Framework/AzCore/AzCore/Math/IntersectSegment.inl
new file mode 100644
index 0000000000..b570b6a182
--- /dev/null
+++ b/Code/Framework/AzCore/AzCore/Math/IntersectSegment.inl
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+namespace AZ
+{
+ namespace Intersect
+ {
+ AZ_MATH_INLINE bool ClipRayWithAabb(const Aabb& aabb, Vector3& rayStart, Vector3& rayEnd, float& tClipStart, float& tClipEnd)
+ {
+ Vector3 startNormal;
+ float tStart, tEnd;
+ Vector3 dirLen = rayEnd - rayStart;
+ if (IntersectRayAABB(rayStart, dirLen, dirLen.GetReciprocal(), aabb, tStart, tEnd, startNormal) != ISECT_RAY_AABB_NONE)
+ {
+ // clip the ray with the box
+ if (tStart > 0.0f)
+ {
+ rayStart = rayStart + tStart * dirLen;
+ tClipStart = tStart;
+ }
+ if (tEnd < 1.0f)
+ {
+ rayEnd = rayStart + tEnd * dirLen;
+ tClipEnd = tEnd;
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ AZ_MATH_INLINE SphereIsectTypes
+ IntersectRaySphereOrigin(const Vector3& rayStart, const Vector3& rayDirNormalized, const float sphereRadius, float& t)
+ {
+ Vector3 m = rayStart;
+ float b = m.Dot(rayDirNormalized);
+ float c = m.Dot(m) - sphereRadius * sphereRadius;
+
+ // Exit if r's origin outside s (c > 0)and r pointing away from s (b > 0)
+ if (c > 0.0f && b > 0.0f)
+ {
+ return ISECT_RAY_SPHERE_NONE;
+ }
+ float discr = b * b - c;
+ // A negative discriminant corresponds to ray missing sphere
+ if (discr < 0.0f)
+ {
+ return ISECT_RAY_SPHERE_NONE;
+ }
+
+ // Ray now found to intersect sphere, compute smallest t value of intersection
+ t = -b - Sqrt(discr);
+
+ // If t is negative, ray started inside sphere so clamp t to zero
+ if (t < 0.0f)
+ {
+ // t = 0.0f;
+ return ISECT_RAY_SPHERE_SA_INSIDE; // no hit if inside
+ }
+ // q = p + t * d;
+ return ISECT_RAY_SPHERE_ISECT;
+ }
+
+ AZ_MATH_INLINE SphereIsectTypes IntersectRaySphere(const Vector3& rayStart, const Vector3& rayDirNormalized, const Vector3& sphereCenter, const float sphereRadius, float& t)
+ {
+ return IntersectRaySphereOrigin(rayStart - sphereCenter, rayDirNormalized, sphereRadius, t);
+ }
+
+ AZ_MATH_INLINE Vector3 LineToPointDistance(const Vector3& s1, const Vector3& s2, const Vector3& p, float& u)
+ {
+ const Vector3 s21 = s2 - s1;
+ // we assume seg1 and seg2 are NOT coincident
+ AZ_MATH_ASSERT(!s21.IsClose(Vector3(0.0f), 1e-4f), "OK we agreed that we will pass valid segments! (s1 != s2)");
+
+ u = LineToPointDistanceTime(s1, s21, p);
+
+ return s1 + u * s21;
+ }
+
+ AZ_MATH_INLINE float LineToPointDistanceTime(const Vector3& s1, const Vector3& s21, const Vector3& p)
+ {
+ // so u = (p.x - s1.x)*(s2.x - s1.x) + (p.y - s1.y)*(s2.y - s1.y) + (p.z-s1.z)*(s2.z-s1.z) / |s2-s1|^2
+ return s21.Dot(p - s1) / s21.Dot(s21);
+ }
+
+ AZ_MATH_INLINE bool TestSegmentAABB(const Vector3& p0, const Vector3& p1, const Aabb& aabb)
+ {
+ Vector3 e = aabb.GetExtents();
+ Vector3 d = p1 - p0;
+ Vector3 m = p0 + p1 - aabb.GetMin() - aabb.GetMax();
+
+ return TestSegmentAABBOrigin(m, d, e);
+ }
+ } // namespace Intersect
+} // namespace AZ
diff --git a/Code/Framework/AzCore/AzCore/Memory/AllocatorManager.h b/Code/Framework/AzCore/AzCore/Memory/AllocatorManager.h
index be0ab4a0a0..14dec68ad1 100644
--- a/Code/Framework/AzCore/AzCore/Memory/AllocatorManager.h
+++ b/Code/Framework/AzCore/AzCore/Memory/AllocatorManager.h
@@ -34,7 +34,9 @@ namespace AZ
friend IAllocator;
friend class AllocatorBase;
friend class Debug::AllocationRecords;
- friend class AZ::Internal::EnvironmentVariableHolder;
+ template friend constexpr auto AZStd::construct_at(T*, Args&&... args)
+ ->AZStd::enable_if_t()) T(AZStd::forward(args)...))>>, T*>;
+ template constexpr friend void AZStd::destroy_at(T*);
public:
typedef AZStd::function OutOfMemoryCBType;
diff --git a/Code/Framework/AzCore/AzCore/Module/Environment.h b/Code/Framework/AzCore/AzCore/Module/Environment.h
index e87ff81446..a2dcfbd8fa 100644
--- a/Code/Framework/AzCore/AzCore/Module/Environment.h
+++ b/Code/Framework/AzCore/AzCore/Module/Environment.h
@@ -251,16 +251,15 @@ namespace AZ
class EnvironmentVariableHolder
: public EnvironmentVariableHolderBase
{
- void ConstructImpl(const AZStd::true_type& /* AZStd::has_trivial_constructor */)
- {
- memset(&m_value, 0, sizeof(T));
- }
-
template
- void ConstructImpl(const AZStd::false_type& /* AZStd::has_trivial_constructor */, Args&&... args)
+ void ConstructImpl(Args&&... args)
{
- // Construction of non-trivial types is left up to the type's constructor.
- new(&m_value) T(AZStd::forward(args)...);
+ // Use std::launder to ensure that the compiler treats the T* reinterpret_cast as a new object
+ #if __cpp_lib_launder
+ AZStd::construct_at(std::launder(reinterpret_cast(&m_value)), AZStd::forward(args)...);
+ #else
+ AZStd::construct_at(reinterpret_cast(&m_value), AZStd::forward(args)...);
+ #endif
}
static void DestructDispatchNoLock(EnvironmentVariableHolderBase *base, DestroyTarget selfDestruct)
{
@@ -274,10 +273,12 @@ namespace AZ
AZ_Assert(self->m_isConstructed, "Variable is not constructed. Please check your logic and guard if needed!");
self->m_isConstructed = false;
self->m_moduleOwner = nullptr;
- if constexpr(!AZStd::is_trivially_destructible_v)
- {
- reinterpret_cast(&self->m_value)->~T();
- }
+ // Use std::launder to ensure that the compiler treats the T* reinterpret_cast as a new object
+ #if __cpp_lib_launder
+ AZStd::destroy_at(std::launder(reinterpret_cast(&self->m_value)));
+ #else
+ AZStd::destroy_at(reinterpret_cast(&self->m_value));
+ #endif
}
public:
EnvironmentVariableHolder(u32 guid, bool isOwnershipTransfer, Environment::AllocatorInterface* allocator)
@@ -303,24 +304,13 @@ namespace AZ
UnregisterAndDestroy(DestructDispatchNoLock, moduleRelease);
}
- void Construct()
- {
- AZStd::lock_guard lock(m_mutex);
- if (!m_isConstructed)
- {
- ConstructImpl(AZStd::is_trivially_constructible{});
- m_isConstructed = true;
- m_moduleOwner = Environment::GetModuleId();
- }
- }
-
template
void Construct(Args&&... args)
{
AZStd::lock_guard lock(m_mutex);
if (!m_isConstructed)
{
- ConstructImpl(typename AZStd::false_type(), AZStd::forward(args)...);
+ ConstructImpl(AZStd::forward(args)...);
m_isConstructed = true;
m_moduleOwner = Environment::GetModuleId();
}
@@ -333,7 +323,7 @@ namespace AZ
}
// variable storage
- typename AZStd::aligned_storage::value>::type m_value;
+ AZStd::aligned_storage_for_t m_value;
static int s_moduleUseCount;
};
@@ -468,6 +458,11 @@ namespace AZ
Get() = value;
}
+ void Set(T&& value)
+ {
+ Get() = AZStd::move(value);
+ }
+
explicit operator bool() const
{
return IsValid();
diff --git a/Code/Framework/AzCore/AzCore/Name/Internal/NameData.cpp b/Code/Framework/AzCore/AzCore/Name/Internal/NameData.cpp
index 0086e68c6d..574b0bcc7e 100644
--- a/Code/Framework/AzCore/AzCore/Name/Internal/NameData.cpp
+++ b/Code/Framework/AzCore/AzCore/Name/Internal/NameData.cpp
@@ -42,7 +42,10 @@ namespace AZ
AZ_Assert(m_useCount > 0, "m_useCount is already 0!");
if (m_useCount.fetch_sub(1) == 1)
{
- AZ::NameDictionary::Instance().TryReleaseName(hash);
+ if (AZ::NameDictionary::IsReady())
+ {
+ AZ::NameDictionary::Instance().TryReleaseName(hash);
+ }
}
}
}
diff --git a/Code/Framework/AzCore/AzCore/Name/NameDictionary.cpp b/Code/Framework/AzCore/AzCore/Name/NameDictionary.cpp
index 8e8011add9..3047a2894e 100644
--- a/Code/Framework/AzCore/AzCore/Name/NameDictionary.cpp
+++ b/Code/Framework/AzCore/AzCore/Name/NameDictionary.cpp
@@ -21,23 +21,18 @@ namespace AZ
namespace NameDictionaryInternal
{
- static AZ::EnvironmentVariable s_instance = nullptr;
+ static AZ::EnvironmentVariable s_instance = nullptr;
}
void NameDictionary::Create()
{
using namespace NameDictionaryInternal;
- AZ_Assert(!s_instance || !s_instance.Get(), "NameDictionary already created!");
+ AZ_Assert(!s_instance, "NameDictionary already created!");
if (!s_instance)
{
- s_instance = AZ::Environment::CreateVariable(NameDictionaryInstanceName);
- }
-
- if (!s_instance.Get())
- {
- s_instance.Set(aznew NameDictionary());
+ s_instance = AZ::Environment::CreateVariable(NameDictionaryInstanceName);
}
}
@@ -46,8 +41,7 @@ namespace AZ
using namespace NameDictionaryInternal;
AZ_Assert(s_instance, "NameDictionary not created!");
- delete (*s_instance);
- *s_instance = nullptr;
+ s_instance.Reset();
}
bool NameDictionary::IsReady()
@@ -56,10 +50,10 @@ namespace AZ
if (!s_instance)
{
- s_instance = Environment::FindVariable(NameDictionaryInstanceName);
+ s_instance = Environment::FindVariable(NameDictionaryInstanceName);
}
- return s_instance && *s_instance;
+ return s_instance.IsConstructed();
}
NameDictionary& NameDictionary::Instance()
@@ -68,12 +62,12 @@ namespace AZ
if (!s_instance)
{
- s_instance = Environment::FindVariable(NameDictionaryInstanceName);
+ s_instance = Environment::FindVariable(NameDictionaryInstanceName);
}
- AZ_Assert(s_instance && *s_instance, "NameDictionary has not been initialized yet.");
+ AZ_Assert(s_instance.IsConstructed(), "NameDictionary has not been initialized yet.");
- return *(*s_instance);
+ return *s_instance;
}
NameDictionary::NameDictionary()
diff --git a/Code/Framework/AzCore/AzCore/Name/NameDictionary.h b/Code/Framework/AzCore/AzCore/Name/NameDictionary.h
index fa13dbd682..8f9af4be3a 100644
--- a/Code/Framework/AzCore/AzCore/Name/NameDictionary.h
+++ b/Code/Framework/AzCore/AzCore/Name/NameDictionary.h
@@ -16,7 +16,7 @@
#include
#include
-namespace MaterialEditor
+namespace MaterialEditor
{
class MaterialEditorCoreComponent;
}
@@ -34,14 +34,14 @@ namespace AZ
{
class NameData;
};
-
+
//! Maintains a list of unique strings for Name objects.
//! The main benefit of the Name system is very fast string equality comparison, because every
- //! unique name has a unique ID. The NameDictionary's purpose is to guarantee name IDs do not
+ //! unique name has a unique ID. The NameDictionary's purpose is to guarantee name IDs do not
//! collide. It also saves memory by removing duplicate strings.
//!
- //! Benchmarks have shown that creating a new Name object can be quite slow when the name doesn't
- //! already exist in the NameDictionary, but is comparable to creating an AZStd::string for names
+ //! Benchmarks have shown that creating a new Name object can be quite slow when the name doesn't
+ //! already exist in the NameDictionary, but is comparable to creating an AZStd::string for names
//! that already exist.
class NameDictionary final
{
@@ -51,7 +51,10 @@ namespace AZ
friend Name;
friend Internal::NameData;
friend UnitTest::NameDictionaryTester;
-
+ template friend constexpr auto AZStd::construct_at(T*, Args&&... args)
+ -> AZStd::enable_if_t()) T(AZStd::forward(args)...))>>, T*>;
+ template constexpr friend void AZStd::destroy_at(T*);
+
public:
static void Create();
@@ -62,7 +65,7 @@ namespace AZ
//! Makes a Name from the provided raw string. If an entry already exists in the dictionary, it is shared.
//! Otherwise, it is added to the internal dictionary.
- //!
+ //!
//! @param name The name to resolve against the dictionary.
//! @return A Name instance holding a dictionary entry associated with the provided raw string.
Name MakeName(AZStd::string_view name);
@@ -84,13 +87,13 @@ namespace AZ
// Attempts to release the name from the dictionary, but checks to make sure
// a reference wasn't taken by another thread.
void TryReleaseName(Name::Hash hash);
-
+
//////////////////////////////////////////////////////////////////////////
// Calculates a hash for the provided name string.
// Does not attempt to resolve hash collisions; that is handled elsewhere.
Name::Hash CalcHash(AZStd::string_view name);
-
+
AZStd::unordered_map m_dictionary;
mutable AZStd::shared_mutex m_sharedMutex;
};
diff --git a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistry.h b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistry.h
index 3dc1be87c5..40022bdc04 100644
--- a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistry.h
+++ b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistry.h
@@ -204,14 +204,14 @@ namespace AZ
[[nodiscard]] virtual PreMergeEventHandler RegisterPreMergeEvent(const PreMergeEventCallback& callback) = 0;
//! Register a function that will be called before a file is merged.
//! @callback The function to call before a file is merged.
- [[nodiscard]] virtual PreMergeEventHandler RegisterPreMergeEvent (PreMergeEventCallback&& callback) = 0;
+ [[nodiscard]] virtual PreMergeEventHandler RegisterPreMergeEvent(PreMergeEventCallback&& callback) = 0;
//! Register a function that will be called after a file is merged.
//! @callback The function to call after a file is merged.
[[nodiscard]] virtual PostMergeEventHandler RegisterPostMergeEvent(const PostMergeEventCallback& callback) = 0;
//! Register a function that will be called after a file is merged.
//! @callback The function to call after a file is merged.
- [[nodiscard]] virtual PostMergeEventHandler RegisterPostMergeEvent (PostMergeEventCallback&& callback) = 0;
+ [[nodiscard]] virtual PostMergeEventHandler RegisterPostMergeEvent(PostMergeEventCallback&& callback) = 0;
//! Gets the boolean value at the provided path.
//! @param result The target to write the result to.
diff --git a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryVisitorUtils.cpp b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryVisitorUtils.cpp
new file mode 100644
index 0000000000..9456616024
--- /dev/null
+++ b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryVisitorUtils.cpp
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#include
+
+
+namespace AZ::SettingsRegistryVisitorUtils
+{
+ // Field Visitor implementation
+ FieldVisitor::FieldVisitor() = default;
+ FieldVisitor::FieldVisitor(VisitFieldType visitFieldType)
+ : m_visitFieldType{ visitFieldType }
+ {
+ }
+
+ auto FieldVisitor::Traverse(AZStd::string_view path, AZStd::string_view valueName,
+ VisitAction action, Type type) -> VisitResponse
+ {
+ // A default response skip prevents visiting grand children(depth 2 or lower)
+ VisitResponse visitResponse = VisitResponse::Skip;
+ if (action == VisitAction::Begin)
+ {
+ // Invoke FieldVisitor override if the root path has been set
+ if (m_rootPath.has_value())
+ {
+ Visit(path, valueName, type);
+ }
+ // To make sure only the direct children are visited(depth 1)
+ // set the root path once and set the VisitReponsoe
+ // to Continue to recurse into is fields
+ if (!m_rootPath.has_value())
+ {
+ bool visitableFieldType{};
+ switch (m_visitFieldType)
+ {
+ case VisitFieldType::Array:
+ visitableFieldType = type == Type::Array;
+ break;
+ case VisitFieldType::Object:
+ visitableFieldType = type == Type::Object;
+ break;
+ case VisitFieldType::ArrayOrObject:
+ visitableFieldType = type == Type::Array || type ==Type::Object;
+ break;
+ default:
+ AZ_Error("FieldVisitor", false, "The field visitation type value is invalid");
+ break;
+ }
+
+ if (visitableFieldType)
+ {
+ m_rootPath = path;
+ visitResponse = VisitResponse::Continue;
+ }
+ }
+ }
+ else if (action == VisitAction::Value)
+ {
+ // Invoke FieldVisitor override if the root path has been set
+ if (m_rootPath.has_value())
+ {
+ Visit(path, valueName, type);
+ }
+ }
+ else if (action == VisitAction::End)
+ {
+ // Reset m_rootPath back to null when the root path has finished being visited
+ if (m_rootPath.has_value() && *m_rootPath == path)
+ {
+ m_rootPath = AZStd::nullopt;
+ }
+ }
+
+
+ return visitResponse;
+ }
+
+ // Array Visitor implementation
+ ArrayVisitor::ArrayVisitor()
+ : FieldVisitor(VisitFieldType::Array)
+ {
+ }
+
+ // Object Visitor implementation
+ ObjectVisitor::ObjectVisitor()
+ : FieldVisitor(VisitFieldType::Object)
+ {
+ }
+
+ // Generic VisitField Callback implemention
+ template
+ bool VisitFieldCallback(AZ::SettingsRegistryInterface& settingsRegistry, const VisitorCallback& visitCallback, AZStd::string_view path)
+ {
+ struct VisitFieldVisitor
+ : BaseVisitor
+ {
+ using BaseVisitor::Visit;
+ VisitFieldVisitor(const VisitorCallback& visitCallback)
+ : m_visitCallback{ visitCallback }
+ {}
+
+ void Visit(AZStd::string_view path, AZStd::string_view fieldIndex, typename BaseVisitor::Type type) override
+ {
+ m_visitCallback(path, fieldIndex, type);
+ }
+
+ const VisitorCallback& m_visitCallback;
+ };
+
+ VisitFieldVisitor visitor{ visitCallback };
+ return settingsRegistry.Visit(visitor, path);
+ }
+
+ // VisitField implementation
+ bool VisitField(AZ::SettingsRegistryInterface& settingsRegistry, const VisitorCallback& visitCallback, AZStd::string_view path)
+ {
+ return VisitFieldCallback(settingsRegistry, visitCallback, path);
+ }
+
+ // VisitArray implementation
+ bool VisitArray(AZ::SettingsRegistryInterface& settingsRegistry, const VisitorCallback& visitCallback, AZStd::string_view path)
+ {
+ return VisitFieldCallback(settingsRegistry, visitCallback, path);
+ }
+
+ // VisitObject implementation
+ bool VisitObject(AZ::SettingsRegistryInterface& settingsRegistry, const VisitorCallback& visitCallback, AZStd::string_view path)
+ {
+ return VisitFieldCallback(settingsRegistry, visitCallback, path);
+ }
+}
diff --git a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryVisitorUtils.h b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryVisitorUtils.h
new file mode 100644
index 0000000000..a45712521f
--- /dev/null
+++ b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryVisitorUtils.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#pragma once
+
+#include
+
+
+namespace AZ::SettingsRegistryVisitorUtils
+{
+ //! Interface for visiting the fields of an array or object
+ //! To access the values, use the SettingsRegistryInterface Get/GetObject methods
+ struct FieldVisitor
+ : public AZ::SettingsRegistryInterface::Visitor
+ {
+ using VisitResponse = AZ::SettingsRegistryInterface::VisitResponse;
+ using VisitAction = AZ::SettingsRegistryInterface::VisitAction;
+ using Type = AZ::SettingsRegistryInterface::Type;
+
+ FieldVisitor();
+
+ // Bring the base class visitor functions into scope
+ using AZ::SettingsRegistryInterface::Visitor::Visit;
+ virtual void Visit(AZStd::string_view path, AZStd::string_view arrayIndex, Type type) = 0;
+
+ protected:
+ // VisitFieldType is used for filtering the type of referenced by the root path
+ enum class VisitFieldType
+ {
+ Array,
+ Object,
+ ArrayOrObject
+ };
+ FieldVisitor(const VisitFieldType visitFieldType);
+ private:
+ VisitResponse Traverse(AZStd::string_view path, AZStd::string_view valueName,
+ VisitAction action, Type type) override;
+
+ VisitFieldType m_visitFieldType{ VisitFieldType::ArrayOrObject };
+ AZStd::optional m_rootPath;
+ };
+
+ //! Interface for visiting the fields of an array
+ //! To access the values, use the SettingsRegistryInterface Get/GetObject methods
+ struct ArrayVisitor
+ : public FieldVisitor
+ {
+ ArrayVisitor();
+ };
+
+ //! Interface for visiting the fields of an object
+ //! To access the values, use the SettingsRegistryInterface Get/GetObject methods
+ struct ObjectVisitor
+ : public FieldVisitor
+ {
+ ObjectVisitor();
+ };
+
+ //! Signature of callback funcition invoked when visiting an element of an array or object
+ using VisitorCallback = AZStd::function;
+
+ //! Invokes the visitor callback for each element of either the array or object at @path
+ //! If @path is not an array or object, then no elements are visited
+ //! This function will not recurse into children of elements
+ //! @visitCallback functor that is invoked for each array or object element found
+ bool VisitField(AZ::SettingsRegistryInterface& settingsRegistry, const VisitorCallback& visitCallback, AZStd::string_view path);
+ //! Invokes the visitor callback for each element of the array at @path
+ //! If @path is not an array, then no elements are visited
+ //! This function will not recurse into children of elements
+ //! @visitCallback functor that is invoked for each array element found
+ bool VisitArray(AZ::SettingsRegistryInterface& settingsRegistry, const VisitorCallback& visitCallback, AZStd::string_view path);
+ //! Invokes the visitor callback for each element of the object at @path
+ //! If @path is not an object, then no elements are visited
+ //! This function will not recurse into children of elements
+ //! @visitCallback functor that is invoked for each object element found
+ bool VisitObject(AZ::SettingsRegistryInterface& settingsRegistry, const VisitorCallback& visitCallback, AZStd::string_view path);
+}
diff --git a/Code/Framework/AzCore/AzCore/azcore_files.cmake b/Code/Framework/AzCore/AzCore/azcore_files.cmake
index 010c748402..4d95ddf098 100644
--- a/Code/Framework/AzCore/AzCore/azcore_files.cmake
+++ b/Code/Framework/AzCore/AzCore/azcore_files.cmake
@@ -282,6 +282,7 @@ set(FILES
Math/Internal/VertexContainer.inl
Math/InterpolationSample.h
Math/IntersectPoint.h
+ Math/IntersectSegment.inl
Math/IntersectSegment.cpp
Math/IntersectSegment.h
Math/MathIntrinsics.h
@@ -566,6 +567,8 @@ set(FILES
Settings/SettingsRegistryMergeUtils.h
Settings/SettingsRegistryScriptUtils.cpp
Settings/SettingsRegistryScriptUtils.h
+ Settings/SettingsRegistryVisitorUtils.cpp
+ Settings/SettingsRegistryVisitorUtils.h
State/HSM.cpp
State/HSM.h
Statistics/NamedRunningStatistic.h
diff --git a/Code/Framework/AzCore/AzCore/std/allocator_stateless.cpp b/Code/Framework/AzCore/AzCore/std/allocator_stateless.cpp
new file mode 100644
index 0000000000..5806cc485c
--- /dev/null
+++ b/Code/Framework/AzCore/AzCore/std/allocator_stateless.cpp
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#include
+#include
+
+namespace AZStd
+{
+ stateless_allocator::stateless_allocator(const char* name)
+ : m_name(name) {}
+
+ const char* stateless_allocator::get_name() const
+ {
+ return m_name;
+ }
+
+ void stateless_allocator::set_name(const char* name)
+ {
+ m_name = name;
+ }
+
+ auto stateless_allocator::allocate(size_type byteSize) -> pointer_type
+ {
+ return allocate(byteSize, AZ_DEFAULT_ALIGNMENT, 0);
+ }
+
+ auto stateless_allocator::allocate(size_type byteSize, size_type alignment, int) -> pointer_type
+ {
+ pointer_type address = AZ_OS_MALLOC(byteSize, alignment);
+
+ if (address == nullptr)
+ {
+ AZ_Error("Memory", false, "stateless_allocator ran out of system memory!\n");
+ }
+
+ return address;
+ }
+
+ void stateless_allocator::deallocate(pointer_type ptr, size_type)
+ {
+ AZ_OS_FREE(ptr);
+ }
+
+ void stateless_allocator::deallocate(pointer_type ptr, size_type, size_type)
+ {
+ AZ_OS_FREE(ptr);
+ }
+
+ auto stateless_allocator::max_size() const -> size_type
+ {
+ return AZ_CORE_MAX_ALLOCATOR_SIZE;
+ }
+
+ stateless_allocator stateless_allocator::select_on_container_copy_construction() const
+ {
+ return *this;
+ }
+
+ auto stateless_allocator::resize(pointer_type, size_type) -> size_type
+ {
+ return 0;
+ }
+
+ bool stateless_allocator::is_lock_free()
+ {
+ return false;
+ }
+
+ bool stateless_allocator::is_stale_read_allowed()
+ {
+ return false;
+ }
+
+ bool stateless_allocator::is_delayed_recycling()
+ {
+ return false;
+ }
+
+ // comparison operators
+ bool operator==(const stateless_allocator&, const stateless_allocator&)
+ {
+ return true;
+ }
+
+ bool operator!=(const stateless_allocator&, const stateless_allocator&)
+ {
+ return false;
+ }
+}
diff --git a/Code/Framework/AzCore/AzCore/std/allocator_stateless.h b/Code/Framework/AzCore/AzCore/std/allocator_stateless.h
new file mode 100644
index 0000000000..b73c680c32
--- /dev/null
+++ b/Code/Framework/AzCore/AzCore/std/allocator_stateless.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#pragma once
+
+#include
+#include
+#include
+
+namespace AZStd
+{
+ class stateless_allocator
+ {
+ public:
+
+ AZ_TYPE_INFO(stateless_allocator, "{E4976C53-0B20-4F39-8D41-0A76F59A7D68}");
+
+ using value_type = uint8_t;
+ using pointer_type = void*;
+ using size_type = size_t;
+ using difference_type = ptrdiff_t;
+ using allow_memory_leaks = AZStd::true_type;
+
+ stateless_allocator(const char* name = "AZStd::stateless_allocator");
+ stateless_allocator(const stateless_allocator& rhs) = default;
+
+ stateless_allocator& operator=(const stateless_allocator& rhs) = default;
+
+ const char* get_name() const;
+ void set_name(const char* name);
+
+ pointer_type allocate(size_type byteSize);
+ pointer_type allocate(size_type byteSize, size_type alignment, int flags = 0);
+ void deallocate(pointer_type ptr, size_type alignment);
+ void deallocate(pointer_type ptr, size_type byteSize, size_type alignment);
+
+ // max_size actually returns the true maximum size of a single allocation
+ size_type max_size() const;
+
+ // Returns a copy of the allocator
+ stateless_allocator select_on_container_copy_construction() const;
+
+ //! extensions
+ size_type resize(pointer_type ptr, size_type newSize);
+
+ bool is_lock_free();
+ bool is_stale_read_allowed();
+ bool is_delayed_recycling();
+
+ private:
+ const char* m_name;
+ };
+
+ bool operator==(const stateless_allocator& left, const stateless_allocator& right);
+ bool operator!=(const stateless_allocator& left, const stateless_allocator& right);
+}
diff --git a/Code/Framework/AzCore/AzCore/std/azstd_files.cmake b/Code/Framework/AzCore/AzCore/std/azstd_files.cmake
index 08e72c5649..2746489f8c 100644
--- a/Code/Framework/AzCore/AzCore/std/azstd_files.cmake
+++ b/Code/Framework/AzCore/AzCore/std/azstd_files.cmake
@@ -12,6 +12,8 @@ set(FILES
allocator.h
allocator_ref.h
allocator_stack.h
+ allocator_stateless.cpp
+ allocator_stateless.h
allocator_static.h
allocator_traits.h
any.h
diff --git a/Code/Framework/AzCore/AzCore/std/createdestroy.h b/Code/Framework/AzCore/AzCore/std/createdestroy.h
index 0fa6e4ed40..355374a13a 100644
--- a/Code/Framework/AzCore/AzCore/std/createdestroy.h
+++ b/Code/Framework/AzCore/AzCore/std/createdestroy.h
@@ -20,7 +20,7 @@
namespace AZStd
{
- // alias std::pointer_traits into the AZStd::namespace
+ // alias std::pointer_traits into the AZStd::namespace
using std::pointer_traits;
//! Bring the names of uninitialized_default_construct and
@@ -229,7 +229,7 @@ namespace AZStd
//! `new (declval()) T(declval()...)` is well-formed
template
constexpr auto construct_at(T* ptr, Args&&... args)
- -> enable_if_t()) T(AZStd::forward(args)...))>>, T*>
+ -> enable_if_t()) T(AZStd::forward(args)...))>>, T*>
{
return ::new (ptr) T(AZStd::forward(args)...);
}
@@ -487,7 +487,7 @@ namespace AZStd
{
//! Implements the C++17 uninitialized_move function
//! The functions accepts two input iterators and an output iterator
- //! It performs an AZStd::move on each in in the range of the input iterator
+ //! It performs an AZStd::move on each in in the range of the input iterator
//! and stores the result in location pointed by the output iterator
template
ForwardIt uninitialized_move(InputIt first, InputIt last, ForwardIt result)
diff --git a/Code/Framework/AzCore/AzCore/std/math.h b/Code/Framework/AzCore/AzCore/std/math.h
index 03f12e6e08..042dcca657 100644
--- a/Code/Framework/AzCore/AzCore/std/math.h
+++ b/Code/Framework/AzCore/AzCore/std/math.h
@@ -30,4 +30,49 @@ namespace AZStd
using std::sqrt;
using std::tan;
using std::trunc;
+
+} // namespace AZStd
+
+// from c++20 standard
+namespace AZStd::Internal
+{
+ template
+ constexpr T lerp(T a, T b, T t) noexcept
+ {
+ if ((a <= 0 && b >= 0) || (a >= 0 && b <= 0))
+ {
+ return t * b + (1 - t) * a;
+ }
+ if (t == 1)
+ {
+ return b;
+ }
+ const T x = a + t * (b - a);
+ if ((t > 1) == (b > a))
+ {
+ return b < x ? x : b;
+ }
+ else
+ {
+ return x < b ? x : b;
+ }
+ }
+} // namespace AZStd::Internal
+
+namespace AZStd
+{
+ constexpr float lerp(float a, float b, float t) noexcept
+ {
+ return Internal::lerp(a, b, t);
+ }
+
+ constexpr double lerp(double a, double b, double t) noexcept
+ {
+ return Internal::lerp(a, b, t);
+ }
+
+ constexpr long double lerp(long double a, long double b, long double t) noexcept
+ {
+ return Internal::lerp(a, b, t);
+ }
} // namespace AZStd
diff --git a/Code/Framework/AzCore/Tests/AZStd/Math.cpp b/Code/Framework/AzCore/Tests/AZStd/Math.cpp
new file mode 100644
index 0000000000..5379c9946b
--- /dev/null
+++ b/Code/Framework/AzCore/Tests/AZStd/Math.cpp
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#include
+#include
+
+namespace UnitTest
+{
+ template
+ class StdMathTest : public ::testing::Test
+ {
+ };
+
+ using MathTestConfigs = ::testing::Types;
+ TYPED_TEST_CASE(StdMathTest, MathTestConfigs);
+
+ TYPED_TEST(StdMathTest, LerpOperations)
+ {
+ using AZStd::lerp;
+ using ::testing::Eq;
+ using T = TypeParam;
+
+ constexpr T maxNumber = AZStd::numeric_limits::max();
+ constexpr T eps = AZStd::numeric_limits::epsilon();
+ constexpr T a{ 42 };
+
+ // exactness: lerp(a,b,0)==a && lerp(a,b,1)==b
+ EXPECT_THAT(lerp(eps, maxNumber, T(0)), Eq(eps));
+ EXPECT_THAT(lerp(eps, maxNumber, T(1)), Eq(maxNumber));
+
+ // consistency: lerp(a,a,t)==a
+ EXPECT_THAT(lerp(a, a, T(0.5)), Eq(a));
+ EXPECT_THAT(lerp(eps, eps, T(0.5)), Eq(eps));
+
+ // a few generic tests taken from MathUtilTests.cpp
+ EXPECT_EQ(T(2.5), lerp(T(2), T(4), T(0.25)));
+ EXPECT_EQ(T(6.0), lerp(T(2), T(4), T(2.0)));
+ EXPECT_EQ(T(3.5), lerp(T(2), T(4), T(0.75)));
+ EXPECT_EQ(T(0.0), lerp(T(2), T(4), T(-1.0)));
+ }
+} // namespace UnitTest
diff --git a/Code/Framework/AzCore/Tests/AssetJsonSerializerTests.cpp b/Code/Framework/AzCore/Tests/AssetJsonSerializerTests.cpp
index e04c5190f9..e3a2c5c23b 100644
--- a/Code/Framework/AzCore/Tests/AssetJsonSerializerTests.cpp
+++ b/Code/Framework/AzCore/Tests/AssetJsonSerializerTests.cpp
@@ -64,6 +64,91 @@ namespace JsonSerializationTests
};
+ class TestSerializedAssetTracker
+ : public BaseJsonSerializerFixture
+ {
+ public:
+ void SetUp() override
+ {
+ BaseJsonSerializerFixture::SetUp();
+
+ AZ::AllocatorInstance::Create();
+ AZ::AllocatorInstance::Create();
+
+ // Set up the Job Manager with 1 thread so that the Asset Manager is able to load assets.
+ AZ::JobManagerDesc jobDesc;
+ AZ::JobManagerThreadDesc threadDesc;
+ jobDesc.m_workerThreads.push_back(threadDesc);
+ m_jobManager = aznew AZ::JobManager(jobDesc);
+ m_jobContext = aznew AZ::JobContext(*m_jobManager);
+ AZ::JobContext::SetGlobalContext(m_jobContext);
+
+ AZ::Data::AssetManager::Descriptor descriptor;
+ AZ::Data::AssetManager::Create(descriptor);
+ AZ::Data::AssetManager::Instance().RegisterHandler(&m_assetHandler, azrtti_typeid());
+
+ m_serializeContext->RegisterGenericType>();
+ m_jsonRegistrationContext->Serializer()->HandlesType();
+ }
+
+ void TearDown() override
+ {
+ m_jsonRegistrationContext->EnableRemoveReflection();
+ m_jsonRegistrationContext->Serializer()->HandlesType();
+ m_jsonRegistrationContext->DisableRemoveReflection();
+
+ AZ::Data::AssetManager::Instance().UnregisterHandler(&m_assetHandler);
+ AZ::Data::AssetManager::Destroy();
+
+ AZ::JobContext::SetGlobalContext(nullptr);
+ delete m_jobContext;
+ delete m_jobManager;
+
+ AZ::AllocatorInstance::Destroy();
+ AZ::AllocatorInstance::Destroy();
+
+ BaseJsonSerializerFixture::TearDown();
+ }
+
+ private:
+ TestAssetHandler m_assetHandler;
+ AZ::JobManager* m_jobManager{ nullptr };
+ AZ::JobContext* m_jobContext{ nullptr };
+ };
+
+ TEST_F(TestSerializedAssetTracker, AssetTracker_Callback_Works)
+ {
+ auto assetCallback = [](AZ::Data::Asset& asset)
+ {
+ if (!asset.GetId().IsValid() && !asset.GetHint().empty())
+ {
+ if (asset.GetHint() == "test/path/foo.asset")
+ {
+ asset.SetHint("passed");
+ }
+ }
+ };
+ auto tracker = AZ::Data::SerializedAssetTracker{};
+ tracker.SetAssetFixUp(assetCallback);
+
+ AZ::JsonDeserializerSettings settings;
+ settings.m_metadata.Add(tracker);
+ settings.m_registrationContext = this->m_jsonRegistrationContext.get();
+ settings.m_serializeContext = this->m_serializeContext.get();
+
+ AZStd::string_view assetHintOnlyTestAsset = R"(
+ {
+ "assetHint" : "test/path/foo.asset"
+ })";
+ rapidjson::Document jsonDom;
+ jsonDom.Parse(assetHintOnlyTestAsset.data());
+
+ AZ::Data::Asset instance;
+ auto result = AZ::JsonSerialization::Load(instance, jsonDom, settings);
+ EXPECT_NE(result.GetProcessing(), AZ::JsonSerializationResult::Processing::Halted);
+ EXPECT_STREQ(instance.GetHint().c_str(), "passed");
+ }
+
class AssetSerializerTestDescription final
: public JsonSerializerConformityTestDescriptor>
{
diff --git a/Code/Framework/AzCore/Tests/SettingsRegistryMergeUtilsTests.cpp b/Code/Framework/AzCore/Tests/Settings/SettingsRegistryMergeUtilsTests.cpp
similarity index 100%
rename from Code/Framework/AzCore/Tests/SettingsRegistryMergeUtilsTests.cpp
rename to Code/Framework/AzCore/Tests/Settings/SettingsRegistryMergeUtilsTests.cpp
diff --git a/Code/Framework/AzCore/Tests/SettingsRegistryTests.cpp b/Code/Framework/AzCore/Tests/Settings/SettingsRegistryTests.cpp
similarity index 100%
rename from Code/Framework/AzCore/Tests/SettingsRegistryTests.cpp
rename to Code/Framework/AzCore/Tests/Settings/SettingsRegistryTests.cpp
diff --git a/Code/Framework/AzCore/Tests/Settings/SettingsRegistryVisitorUtilsTests.cpp b/Code/Framework/AzCore/Tests/Settings/SettingsRegistryVisitorUtilsTests.cpp
new file mode 100644
index 0000000000..15f346ee93
--- /dev/null
+++ b/Code/Framework/AzCore/Tests/Settings/SettingsRegistryVisitorUtilsTests.cpp
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace SettingsRegistryVisitorUtilsTests
+{
+ struct VisitCallbackParams
+ {
+ AZStd::string_view m_inputJsonDocument;
+ using VisitFieldFunction = bool(*)(AZ::SettingsRegistryInterface&,
+ const AZ::SettingsRegistryVisitorUtils::VisitorCallback&,
+ AZStd::string_view);
+
+ static inline constexpr size_t MaxFieldCount = 10;
+ using ObjectFields = AZStd::fixed_vector, MaxFieldCount>;
+ using ArrayFields = AZStd::fixed_vector;
+ ObjectFields m_objectFields;
+ ArrayFields m_arrayFields;
+ };
+
+ template
+ class SettingsRegistryVisitorUtilsParamFixture
+ : public UnitTest::ScopedAllocatorSetupFixture
+ , public ::testing::WithParamInterface
+ {
+ public:
+
+ void SetUp() override
+ {
+ m_registry = AZStd::make_unique();
+ }
+
+ void TearDown() override
+ {
+ m_registry.reset();
+ }
+
+ AZStd::unique_ptr m_registry;
+ };
+
+ using SettingsRegistryVisitCallbackFixture = SettingsRegistryVisitorUtilsParamFixture;
+
+ TEST_P(SettingsRegistryVisitCallbackFixture, VisitFunction_VisitFieldsOfArrayType_ReturnsFields)
+ {
+ const VisitCallbackParams& visitParams = GetParam();
+
+ ASSERT_TRUE(m_registry->MergeSettings(visitParams.m_inputJsonDocument, AZ::SettingsRegistryInterface::Format::JsonMergePatch));
+
+ AZStd::fixed_vector testArrayFields;
+ auto visitorCallback = [this, &testArrayFields](AZStd::string_view path, AZStd::string_view, AZ::SettingsRegistryInterface::Type)
+ {
+ AZStd::string fieldValue;
+ EXPECT_TRUE(m_registry->Get(fieldValue, path));
+ testArrayFields.emplace_back(AZStd::move(fieldValue));
+ };
+
+ AZ::SettingsRegistryVisitorUtils::VisitField(*m_registry, visitorCallback, "/Test/Array");
+
+ const AZStd::fixed_vector expectedFields{
+ visitParams.m_arrayFields.begin(), visitParams.m_arrayFields.end() };
+ EXPECT_THAT(testArrayFields, ::testing::ContainerEq(expectedFields));
+ }
+
+ TEST_P(SettingsRegistryVisitCallbackFixture, VisitFunction_VisitFieldsOfObjectType_ReturnsFields)
+ {
+ const VisitCallbackParams& visitParams = GetParam();
+
+ ASSERT_TRUE(m_registry->MergeSettings(visitParams.m_inputJsonDocument, AZ::SettingsRegistryInterface::Format::JsonMergePatch));
+
+ AZStd::fixed_vector, VisitCallbackParams::MaxFieldCount> testObjectFields;
+ auto visitorCallback = [this, &testObjectFields](AZStd::string_view path, AZStd::string_view fieldName, AZ::SettingsRegistryInterface::Type)
+ {
+ AZStd::string fieldValue;
+ EXPECT_TRUE(m_registry->Get(fieldValue, path));
+ testObjectFields.emplace_back(fieldName, AZStd::move(fieldValue));
+ };
+
+ AZ::SettingsRegistryVisitorUtils::VisitField(*m_registry, visitorCallback, "/Test/Object");
+
+ const AZStd::fixed_vector, VisitCallbackParams::MaxFieldCount> expectedFields{
+ visitParams.m_objectFields.begin(), visitParams.m_objectFields.end() };
+ EXPECT_THAT(testObjectFields, ::testing::ContainerEq(expectedFields));
+ }
+
+ TEST_P(SettingsRegistryVisitCallbackFixture, VisitFunction_VisitArrayOfArrayType_ReturnsFields)
+ {
+ const VisitCallbackParams& visitParams = GetParam();
+
+ ASSERT_TRUE(m_registry->MergeSettings(visitParams.m_inputJsonDocument, AZ::SettingsRegistryInterface::Format::JsonMergePatch));
+
+ AZStd::fixed_vector testArrayFields;
+ auto visitorCallback = [this, &testArrayFields](AZStd::string_view path, AZStd::string_view, AZ::SettingsRegistryInterface::Type)
+ {
+ AZStd::string fieldValue;
+ EXPECT_TRUE(m_registry->Get(fieldValue, path));
+ testArrayFields.emplace_back(AZStd::move(fieldValue));
+ };
+
+ AZ::SettingsRegistryVisitorUtils::VisitArray(*m_registry, visitorCallback, "/Test/Array");
+
+ const AZStd::fixed_vector expectedArrayFields{
+ visitParams.m_arrayFields.begin(), visitParams.m_arrayFields.end() };
+ EXPECT_THAT(testArrayFields, ::testing::ContainerEq(expectedArrayFields));
+ }
+
+ TEST_P(SettingsRegistryVisitCallbackFixture, VisitFunction_VisitArrayOfObjectType_ReturnsEmpty)
+ {
+ const VisitCallbackParams& visitParams = GetParam();
+
+ ASSERT_TRUE(m_registry->MergeSettings(visitParams.m_inputJsonDocument, AZ::SettingsRegistryInterface::Format::JsonMergePatch));
+
+ AZStd::fixed_vector testArrayFields;
+ auto visitorCallback = [this, &testArrayFields](AZStd::string_view path, AZStd::string_view, AZ::SettingsRegistryInterface::Type)
+ {
+ AZStd::string fieldValue;
+ EXPECT_TRUE(m_registry->Get(fieldValue, path));
+ testArrayFields.emplace_back(AZStd::move(fieldValue));
+ };
+
+ AZ::SettingsRegistryVisitorUtils::VisitArray(*m_registry, visitorCallback, "/Test/Object");
+
+ EXPECT_TRUE(testArrayFields.empty());
+ }
+
+ TEST_P(SettingsRegistryVisitCallbackFixture, VisitFunction_VisitObjectOfArrayType_ReturnsEmpty)
+ {
+ const VisitCallbackParams& visitParams = GetParam();
+
+ ASSERT_TRUE(m_registry->MergeSettings(visitParams.m_inputJsonDocument, AZ::SettingsRegistryInterface::Format::JsonMergePatch));
+
+ AZStd::fixed_vector, VisitCallbackParams::MaxFieldCount> testObjectFields;
+ auto visitorCallback = [this, &testObjectFields](AZStd::string_view path, AZStd::string_view fieldName, AZ::SettingsRegistryInterface::Type)
+ {
+ AZStd::string fieldValue;
+ EXPECT_TRUE(m_registry->Get(fieldValue, path));
+ testObjectFields.emplace_back(fieldName, AZStd::move(fieldValue));
+ };
+
+ AZ::SettingsRegistryVisitorUtils::VisitObject(*m_registry, visitorCallback, "/Test/Array");
+
+ EXPECT_TRUE(testObjectFields.empty());
+ }
+
+ TEST_P(SettingsRegistryVisitCallbackFixture, VisitFunction_VisitObjectOfObjectType_ReturnsFields)
+ {
+ const VisitCallbackParams& visitParams = GetParam();
+
+ ASSERT_TRUE(m_registry->MergeSettings(visitParams.m_inputJsonDocument, AZ::SettingsRegistryInterface::Format::JsonMergePatch));
+
+ AZStd::fixed_vector, VisitCallbackParams::MaxFieldCount> testObjectFields;
+ auto visitorCallback = [this, &testObjectFields](AZStd::string_view path, AZStd::string_view fieldName, AZ::SettingsRegistryInterface::Type)
+ {
+ AZStd::string fieldValue;
+ EXPECT_TRUE(m_registry->Get(fieldValue, path));
+ testObjectFields.emplace_back(fieldName, AZStd::move(fieldValue));
+ };
+
+ AZ::SettingsRegistryVisitorUtils::VisitObject(*m_registry, visitorCallback, "/Test/Object");
+
+ const AZStd::fixed_vector, VisitCallbackParams::MaxFieldCount> expectedObjectFields{
+ visitParams.m_objectFields.begin(), visitParams.m_objectFields.end() };
+ EXPECT_THAT(testObjectFields, ::testing::ContainerEq(expectedObjectFields));
+ }
+
+
+ INSTANTIATE_TEST_CASE_P(
+ VisitField,
+ SettingsRegistryVisitCallbackFixture,
+ ::testing::Values(
+ VisitCallbackParams
+ {
+ R"({)" "\n"
+ R"( "Test":)" "\n"
+ R"( {)" "\n"
+ R"( "Array": [ "Hello", "World" ],)" "\n"
+ R"( "Object": { "Foo": "Hello", "Bar": "World"})" "\n"
+ R"( })" "\n"
+ R"(})" "\n",
+ VisitCallbackParams::ObjectFields{{"Foo", "Hello"}, {"Bar", "World"}},
+ VisitCallbackParams::ArrayFields{"Hello", "World"}
+ }
+ )
+ );
+}
diff --git a/Code/Framework/AzCore/Tests/azcoretests_files.cmake b/Code/Framework/AzCore/Tests/azcoretests_files.cmake
index e155594aa0..6ba9944f7d 100644
--- a/Code/Framework/AzCore/Tests/azcoretests_files.cmake
+++ b/Code/Framework/AzCore/Tests/azcoretests_files.cmake
@@ -75,11 +75,12 @@ set(FILES
Name/NameJsonSerializerTests.cpp
Name/NameTests.cpp
RTTI/TypeSafeIntegralTests.cpp
- SettingsRegistryTests.cpp
- SettingsRegistryMergeUtilsTests.cpp
Settings/CommandLineTests.cpp
+ Settings/SettingsRegistryTests.cpp
Settings/SettingsRegistryConsoleUtilsTests.cpp
+ Settings/SettingsRegistryMergeUtilsTests.cpp
Settings/SettingsRegistryScriptUtilsTests.cpp
+ Settings/SettingsRegistryVisitorUtilsTests.cpp
Streamer/BlockCacheTests.cpp
Streamer/DedicatedCacheTests.cpp
Streamer/FullDecompressorTests.cpp
@@ -194,6 +195,7 @@ set(FILES
AZStd/LockFreeQueues.cpp
AZStd/LockFreeStacks.cpp
AZStd/LockTests.cpp
+ AZStd/Math.cpp
AZStd/Numeric.cpp
AZStd/Ordered.cpp
AZStd/Optional.cpp
diff --git a/Code/Framework/AzFramework/AzFramework/Gem/GemInfo.h b/Code/Framework/AzFramework/AzFramework/Gem/GemInfo.h
index 1f300af770..3435d810fd 100644
--- a/Code/Framework/AzFramework/AzFramework/Gem/GemInfo.h
+++ b/Code/Framework/AzFramework/AzFramework/Gem/GemInfo.h
@@ -29,6 +29,10 @@ namespace AzFramework
AZStd::vector m_absoluteSourcePaths; //!< Where the gem's source path folder are located(as an absolute path)
static constexpr const char* GetGemAssetFolder() { return "Assets"; }
+ static constexpr const char* GetGemRegistryFolder()
+ {
+ return "Registry";
+ }
};
//! Returns a list of GemInfo of all the gems that are active for the for the specified game project.
diff --git a/Code/Framework/AzFramework/AzFramework/Input/System/InputSystemComponent.cpp b/Code/Framework/AzFramework/AzFramework/Input/System/InputSystemComponent.cpp
index 33690f2246..14fb7ea5eb 100644
--- a/Code/Framework/AzFramework/AzFramework/Input/System/InputSystemComponent.cpp
+++ b/Code/Framework/AzFramework/AzFramework/Input/System/InputSystemComponent.cpp
@@ -20,6 +20,7 @@
#include
#include
#include
+#include
////////////////////////////////////////////////////////////////////////////////////////////////////
namespace AzFramework
@@ -190,6 +191,25 @@ namespace AzFramework
////////////////////////////////////////////////////////////////////////////////////////////////
void InputSystemComponent::Activate()
{
+ const auto* settingsRegistry = AZ::SettingsRegistry::Get();
+ if (settingsRegistry)
+ {
+ AZ::u64 value = 0;
+ if (settingsRegistry->Get(value, "/O3DE/InputSystem/MouseMovementSampleRateHertz"))
+ {
+ m_mouseMovementSampleRateHertz = aznumeric_caster(value);
+ }
+ if (settingsRegistry->Get(value, "/O3DE/InputSystem/GamepadsEnabled"))
+ {
+ m_gamepadsEnabled = aznumeric_caster(value);
+ }
+ settingsRegistry->Get(m_keyboardEnabled, "/O3DE/InputSystem/KeyboardEnabled");
+ settingsRegistry->Get(m_motionEnabled, "/O3DE/InputSystem/MotionEnabled");
+ settingsRegistry->Get(m_mouseEnabled, "/O3DE/InputSystem/MouseEnabled");
+ settingsRegistry->Get(m_touchEnabled, "/O3DE/InputSystem/TouchEnabled");
+ settingsRegistry->Get(m_virtualKeyboardEnabled, "/O3DE/InputSystem/VirtualKeyboardEnabled");
+ }
+
// Create all enabled input devices
CreateEnabledInputDevices();
diff --git a/Code/Framework/AzFramework/AzFramework/Matchmaking/MatchmakingRequests.h b/Code/Framework/AzFramework/AzFramework/Matchmaking/MatchmakingRequests.h
index 58e335696f..9169a83588 100644
--- a/Code/Framework/AzFramework/AzFramework/Matchmaking/MatchmakingRequests.h
+++ b/Code/Framework/AzFramework/AzFramework/Matchmaking/MatchmakingRequests.h
@@ -9,6 +9,7 @@
#pragma once
#include
+#include
#include
namespace AZ
diff --git a/Code/Framework/AzFramework/AzFramework/Session/SessionConfig.cpp b/Code/Framework/AzFramework/AzFramework/Session/SessionConfig.cpp
index 0c879a930f..0856ddeed6 100644
--- a/Code/Framework/AzFramework/AzFramework/Session/SessionConfig.cpp
+++ b/Code/Framework/AzFramework/AzFramework/Session/SessionConfig.cpp
@@ -22,6 +22,7 @@ namespace AzFramework
->Field("terminationTime", &SessionConfig::m_terminationTime)
->Field("creatorId", &SessionConfig::m_creatorId)
->Field("sessionProperties", &SessionConfig::m_sessionProperties)
+ ->Field("matchmakingData", &SessionConfig::m_matchmakingData)
->Field("sessionId", &SessionConfig::m_sessionId)
->Field("sessionName", &SessionConfig::m_sessionName)
->Field("dnsName", &SessionConfig::m_dnsName)
@@ -46,6 +47,8 @@ namespace AzFramework
"CreatorId", "A unique identifier for a player or entity creating the session.")
->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_sessionProperties,
"SessionProperties", "A collection of custom properties for a session.")
+ ->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_matchmakingData,
+ "MatchmakingData", "The matchmaking process information that was used to create the session.")
->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_sessionId,
"SessionId", "A unique identifier for the session.")
->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_sessionName,
diff --git a/Code/Framework/AzFramework/AzFramework/Session/SessionConfig.h b/Code/Framework/AzFramework/AzFramework/Session/SessionConfig.h
index cfd6aa7c8b..45e40c2f29 100644
--- a/Code/Framework/AzFramework/AzFramework/Session/SessionConfig.h
+++ b/Code/Framework/AzFramework/AzFramework/Session/SessionConfig.h
@@ -35,6 +35,9 @@ namespace AzFramework
// A collection of custom properties for a session.
AZStd::unordered_map m_sessionProperties;
+
+ // The matchmaking process information that was used to create the session.
+ AZStd::string m_matchmakingData;
// A unique identifier for the session.
AZStd::string m_sessionId;
diff --git a/Code/Framework/AzFramework/AzFramework/Session/SessionNotifications.h b/Code/Framework/AzFramework/AzFramework/Session/SessionNotifications.h
index 7788c2d030..902500fe9a 100644
--- a/Code/Framework/AzFramework/AzFramework/Session/SessionNotifications.h
+++ b/Code/Framework/AzFramework/AzFramework/Session/SessionNotifications.h
@@ -41,6 +41,11 @@ namespace AzFramework
// OnDestroySessionBegin is fired at the beginning of session termination
// @return The result of all OnDestroySessionBegin notifications
virtual bool OnDestroySessionBegin() = 0;
+
+ // OnUpdateSessionBegin is fired at the beginning of session update
+ // @param sessionConfig The properties to describe a session
+ // @param updateReason The reason for session update
+ virtual void OnUpdateSessionBegin(const SessionConfig& sessionConfig, const AZStd::string& updateReason) = 0;
};
using SessionNotificationBus = AZ::EBus;
} // namespace AzFramework
diff --git a/Code/Framework/AzFramework/AzFramework/Spawnable/RootSpawnableInterface.h b/Code/Framework/AzFramework/AzFramework/Spawnable/RootSpawnableInterface.h
index bb1f137ba2..72a3031e3e 100644
--- a/Code/Framework/AzFramework/AzFramework/Spawnable/RootSpawnableInterface.h
+++ b/Code/Framework/AzFramework/AzFramework/Spawnable/RootSpawnableInterface.h
@@ -61,6 +61,10 @@ namespace AzFramework
//! be deleted and the spawnable asset to be released. This call is automatically done when
//! AssignRootSpawnable is called while a root spawnable is assigned.
virtual void ReleaseRootSpawnable() = 0;
+ //! Force processing all SpawnableEntitiesManager requests immediately
+ //! This is useful when loading a different level while SpawnableEntitiesManager still has
+ //! pending requests
+ virtual void ProcessSpawnableQueue() = 0;
};
using RootSpawnableInterface = AZ::Interface;
diff --git a/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableSystemComponent.cpp b/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableSystemComponent.cpp
index f6130c9e31..957786c6df 100644
--- a/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableSystemComponent.cpp
+++ b/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableSystemComponent.cpp
@@ -45,8 +45,7 @@ namespace AzFramework
void SpawnableSystemComponent::OnTick(float /*deltaTime*/, AZ::ScriptTimePoint /*time*/)
{
- m_entitiesManager.ProcessQueue(
- SpawnableEntitiesManager::CommandQueuePriority::High | SpawnableEntitiesManager::CommandQueuePriority::Regular);
+ ProcessSpawnableQueue();
RootSpawnableNotificationBus::ExecuteQueuedEvents();
}
@@ -121,6 +120,12 @@ namespace AzFramework
m_rootSpawnableId = AZ::Data::AssetId();
}
+ void SpawnableSystemComponent::ProcessSpawnableQueue()
+ {
+ m_entitiesManager.ProcessQueue(
+ SpawnableEntitiesManager::CommandQueuePriority::High | SpawnableEntitiesManager::CommandQueuePriority::Regular);
+ }
+
void SpawnableSystemComponent::OnRootSpawnableAssigned([[maybe_unused]] AZ::Data::Asset rootSpawnable,
[[maybe_unused]] uint32_t generation)
{
@@ -161,6 +166,8 @@ namespace AzFramework
void SpawnableSystemComponent::Deactivate()
{
+ ProcessSpawnableQueue();
+
m_registryChangeHandler.Disconnect();
AZ::TickBus::Handler::BusDisconnect();
diff --git a/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableSystemComponent.h b/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableSystemComponent.h
index 5b5fb1b7ee..74e255d624 100644
--- a/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableSystemComponent.h
+++ b/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableSystemComponent.h
@@ -75,6 +75,7 @@ namespace AzFramework
uint64_t AssignRootSpawnable(AZ::Data::Asset rootSpawnable) override;
void ReleaseRootSpawnable() override;
+ void ProcessSpawnableQueue() override;
//
// RootSpawnbleNotificationBus
diff --git a/Code/Framework/AzFramework/Platform/Common/Xcb/AzFramework/XcbNativeWindow.cpp b/Code/Framework/AzFramework/Platform/Common/Xcb/AzFramework/XcbNativeWindow.cpp
index 6ab97fd616..43f7e7140f 100644
--- a/Code/Framework/AzFramework/Platform/Common/Xcb/AzFramework/XcbNativeWindow.cpp
+++ b/Code/Framework/AzFramework/Platform/Common/Xcb/AzFramework/XcbNativeWindow.cpp
@@ -10,6 +10,7 @@
#include
#include
#include
+#include
#include
diff --git a/Code/Framework/AzFramework/Platform/iOS/AzFramework/Application/Application_iOS.mm b/Code/Framework/AzFramework/Platform/iOS/AzFramework/Application/Application_iOS.mm
index 41bba124c7..36d920085b 100644
--- a/Code/Framework/AzFramework/Platform/iOS/AzFramework/Application/Application_iOS.mm
+++ b/Code/Framework/AzFramework/Platform/iOS/AzFramework/Application/Application_iOS.mm
@@ -112,9 +112,10 @@ namespace AzFramework
void ApplicationIos::PumpSystemEventLoopUntilEmpty()
{
SInt32 result;
+ const CFTimeInterval MaxSecondsInRunLoop = 0.001; // One millisecond
do
{
- result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, DBL_EPSILON, TRUE);
+ result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, MaxSecondsInRunLoop, TRUE);
}
while (result == kCFRunLoopRunHandledSource);
}
diff --git a/Code/Framework/AzFramework/Tests/Platform/Common/Xcb/XcbInputDeviceKeyboardTests.cpp b/Code/Framework/AzFramework/Tests/Platform/Common/Xcb/XcbInputDeviceKeyboardTests.cpp
index 3abbcdc564..76d00eda50 100644
--- a/Code/Framework/AzFramework/Tests/Platform/Common/Xcb/XcbInputDeviceKeyboardTests.cpp
+++ b/Code/Framework/AzFramework/Tests/Platform/Common/Xcb/XcbInputDeviceKeyboardTests.cpp
@@ -19,6 +19,7 @@
#include "Matchers.h"
#include "Actions.h"
#include "XcbBaseTestFixture.h"
+#include "XcbTestApplication.h"
template
xcb_generic_event_t MakeEvent(T event)
@@ -32,6 +33,7 @@ namespace AzFramework
class XcbInputDeviceKeyboardTests
: public XcbBaseTestFixture
{
+ public:
void SetUp() override
{
using testing::Return;
@@ -122,6 +124,15 @@ namespace AzFramework
static constexpr xcb_keycode_t s_keycodeForAKey{38};
static constexpr xcb_keycode_t s_keycodeForShiftLKey{50};
+
+ XcbTestApplication m_application{
+ /*enabledGamepadsCount=*/0,
+ /*keyboardEnabled=*/true,
+ /*motionEnabled=*/false,
+ /*mouseEnabled=*/false,
+ /*touchEnabled=*/false,
+ /*virtualKeyboardEnabled=*/false
+ };
};
class InputTextNotificationListener
@@ -194,26 +205,23 @@ namespace AzFramework
EXPECT_CALL(m_interface, xkb_state_key_get_one_sym(&m_xkbState, s_keycodeForAKey))
.Times(2);
- Application application;
- application.Start({}, {});
+ m_application.Start();
const InputChannel* inputChannel = InputChannelRequests::FindInputChannel(InputDeviceKeyboard::Key::AlphanumericA);
ASSERT_TRUE(inputChannel);
EXPECT_THAT(inputChannel->GetState(), Eq(InputChannel::State::Idle));
- application.PumpSystemEventLoopUntilEmpty();
- application.TickSystem();
- application.Tick();
+ m_application.PumpSystemEventLoopUntilEmpty();
+ m_application.TickSystem();
+ m_application.Tick();
EXPECT_THAT(inputChannel->GetState(), Eq(InputChannel::State::Began));
- application.PumpSystemEventLoopUntilEmpty();
- application.TickSystem();
- application.Tick();
+ m_application.PumpSystemEventLoopUntilEmpty();
+ m_application.TickSystem();
+ m_application.Tick();
EXPECT_THAT(inputChannel->GetState(), Eq(InputChannel::State::Ended));
-
- application.Stop();
}
TEST_F(XcbInputDeviceKeyboardTests, TextEnteredFromXcbKeyPressEvents)
@@ -418,16 +426,13 @@ namespace AzFramework
EXPECT_CALL(textListener, OnInputTextEvent(StrEq("a"), _)).Times(1);
EXPECT_CALL(textListener, OnInputTextEvent(StrEq("A"), _)).Times(1);
- Application application;
- application.Start({}, {});
+ m_application.Start();
for (int i = 0; i < 4; ++i)
{
- application.PumpSystemEventLoopUntilEmpty();
- application.TickSystem();
- application.Tick();
+ m_application.PumpSystemEventLoopUntilEmpty();
+ m_application.TickSystem();
+ m_application.Tick();
}
-
- application.Stop();
}
} // namespace AzFramework
diff --git a/Code/Framework/AzFramework/Tests/Platform/Common/Xcb/XcbTestApplication.h b/Code/Framework/AzFramework/Tests/Platform/Common/Xcb/XcbTestApplication.h
new file mode 100644
index 0000000000..3035a9de74
--- /dev/null
+++ b/Code/Framework/AzFramework/Tests/Platform/Common/Xcb/XcbTestApplication.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#pragma once
+
+#include
+#include
+#include
+
+namespace AzFramework
+{
+ class XcbTestApplication
+ : public Application
+ {
+ public:
+ XcbTestApplication(AZ::u64 enabledGamepadsCount, bool keyboardEnabled, bool motionEnabled, bool mouseEnabled, bool touchEnabled, bool virtualKeyboardEnabled)
+ {
+ auto* settingsRegistry = AZ::SettingsRegistry::Get();
+ settingsRegistry->Set("/O3DE/InputSystem/GamepadsEnabled", enabledGamepadsCount);
+ settingsRegistry->Set("/O3DE/InputSystem/KeyboardEnabled", keyboardEnabled);
+ settingsRegistry->Set("/O3DE/InputSystem/MotionEnabled", motionEnabled);
+ settingsRegistry->Set("/O3DE/InputSystem/MouseEnabled", mouseEnabled);
+ settingsRegistry->Set("/O3DE/InputSystem/TouchEnabled", touchEnabled);
+ settingsRegistry->Set("/O3DE/InputSystem/VirtualKeyboardEnabled", virtualKeyboardEnabled);
+ }
+
+ void Start(const Descriptor& descriptor = {}, const StartupParameters& startupParameters = {}) override
+ {
+ Application::Start(descriptor, startupParameters);
+ AZ::UserSettingsComponentRequestBus::Broadcast(&AZ::UserSettingsComponentRequests::DisableSaveOnFinalize);
+ }
+ };
+} // namespace AzFramework
diff --git a/Code/Framework/AzFramework/Tests/Platform/Common/Xcb/azframework_xcb_tests_files.cmake b/Code/Framework/AzFramework/Tests/Platform/Common/Xcb/azframework_xcb_tests_files.cmake
index 762d5d74fe..147fd2bfe1 100644
--- a/Code/Framework/AzFramework/Tests/Platform/Common/Xcb/azframework_xcb_tests_files.cmake
+++ b/Code/Framework/AzFramework/Tests/Platform/Common/Xcb/azframework_xcb_tests_files.cmake
@@ -17,4 +17,5 @@ set(FILES
XcbBaseTestFixture.cpp
XcbBaseTestFixture.h
XcbInputDeviceKeyboardTests.cpp
+ XcbTestApplication.h
)
diff --git a/Code/Framework/AzGameFramework/AzGameFramework/Application/GameApplication.cpp b/Code/Framework/AzGameFramework/AzGameFramework/Application/GameApplication.cpp
index 462de43262..0cce93d751 100644
--- a/Code/Framework/AzGameFramework/AzGameFramework/Application/GameApplication.cpp
+++ b/Code/Framework/AzGameFramework/AzGameFramework/Application/GameApplication.cpp
@@ -96,6 +96,8 @@ namespace AzGameFramework
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, m_commandLine, false);
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_ProjectUserRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer);
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, m_commandLine, true);
+#else
+ AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, m_commandLine, false);
#endif
// Update the Runtime file paths in case the "{BootstrapSettingsRootKey}/assets" key was overriden by a setting registry
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(registry);
diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/CardNotification.cpp b/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/CardNotification.cpp
index d9451949ea..d2144457c8 100644
--- a/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/CardNotification.cpp
+++ b/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/CardNotification.cpp
@@ -33,6 +33,9 @@ namespace AzQtComponents
titleLabel->setObjectName("Title");
titleLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
titleLabel->setWordWrap(true);
+ titleLabel->setTextFormat(Qt::RichText);
+ titleLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
+ titleLabel->setOpenExternalLinks(true);
QHBoxLayout* headerLayout = new QHBoxLayout(headerFrame);
headerLayout->setSizeConstraint(QLayout::SetMinimumSize);
diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Platform/Linux/platform_linux_files.cmake b/Code/Framework/AzQtComponents/AzQtComponents/Platform/Linux/platform_linux_files.cmake
index ec71d7b508..f292c29c3c 100644
--- a/Code/Framework/AzQtComponents/AzQtComponents/Platform/Linux/platform_linux_files.cmake
+++ b/Code/Framework/AzQtComponents/AzQtComponents/Platform/Linux/platform_linux_files.cmake
@@ -12,6 +12,7 @@ set(FILES
../../Utilities/QtWindowUtilities_linux.cpp
../../Utilities/ScreenGrabber_linux.cpp
../../../Platform/Linux/AzQtComponents/Components/StyledDockWidget_Linux.cpp
+ ../../../Platform/Linux/AzQtComponents/Utilities/DesktopUtilities_Linux.cpp
../../../Platform/Linux/AzQtComponents/AzQtComponents_Traits_Linux.h
../../../Platform/Linux/AzQtComponents/AzQtComponents_Traits_Platform.h
)
diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Platform/Mac/platform_mac_files.cmake b/Code/Framework/AzQtComponents/AzQtComponents/Platform/Mac/platform_mac_files.cmake
index 18f9479289..4addf53599 100644
--- a/Code/Framework/AzQtComponents/AzQtComponents/Platform/Mac/platform_mac_files.cmake
+++ b/Code/Framework/AzQtComponents/AzQtComponents/Platform/Mac/platform_mac_files.cmake
@@ -12,6 +12,7 @@ set(FILES
../../Utilities/QtWindowUtilities_mac.mm
../../Utilities/ScreenGrabber_mac.mm
../../../Platform/Mac/AzQtComponents/Components/StyledDockWidget_Mac.cpp
+ ../../../Platform/Mac/AzQtComponents/Utilities/DesktopUtilities_Mac.cpp
../../../Platform/Mac/AzQtComponents/AzQtComponents_Traits_Mac.h
../../../Platform/Mac/AzQtComponents/AzQtComponents_Traits_Platform.h
)
diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Platform/Windows/platform_windows_files.cmake b/Code/Framework/AzQtComponents/AzQtComponents/Platform/Windows/platform_windows_files.cmake
index ca4145ef35..bf0d0bb785 100644
--- a/Code/Framework/AzQtComponents/AzQtComponents/Platform/Windows/platform_windows_files.cmake
+++ b/Code/Framework/AzQtComponents/AzQtComponents/Platform/Windows/platform_windows_files.cmake
@@ -9,6 +9,7 @@
set(FILES
../../natvis/qt.natvis
../../../Platform/Windows/AzQtComponents/Utilities/HandleDpiAwareness_Windows.cpp
+ ../../../Platform/Windows/AzQtComponents/Utilities/DesktopUtilities_Windows.cpp
../../Utilities/MouseHider_win.cpp
../../Utilities/QtWindowUtilities_win.cpp
../../Utilities/ScreenGrabber_win.cpp
diff --git a/Code/Framework/AzQtComponents/AzQtComponents/azqtcomponents_files.cmake b/Code/Framework/AzQtComponents/AzQtComponents/azqtcomponents_files.cmake
index 8219ab04b2..4c343b852c 100644
--- a/Code/Framework/AzQtComponents/AzQtComponents/azqtcomponents_files.cmake
+++ b/Code/Framework/AzQtComponents/AzQtComponents/azqtcomponents_files.cmake
@@ -271,7 +271,6 @@ set(FILES
Utilities/ColorUtilities.h
Utilities/Conversions.h
Utilities/Conversions.cpp
- Utilities/DesktopUtilities.cpp
Utilities/DesktopUtilities.h
Utilities/HandleDpiAwareness.cpp
Utilities/HandleDpiAwareness.h
diff --git a/Code/Framework/AzQtComponents/Platform/Linux/AzQtComponents/Utilities/DesktopUtilities_Linux.cpp b/Code/Framework/AzQtComponents/Platform/Linux/AzQtComponents/Utilities/DesktopUtilities_Linux.cpp
new file mode 100644
index 0000000000..e4ddaceec7
--- /dev/null
+++ b/Code/Framework/AzQtComponents/Platform/Linux/AzQtComponents/Utilities/DesktopUtilities_Linux.cpp
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#include
+
+#include
+#include
+
+namespace AzQtComponents
+{
+ void ShowFileOnDesktop(const QString& path)
+ {
+ const char* defaultNautilusPath = "/usr/bin/nautilus";
+ const char* defaultXdgOpenPath = "/usr/bin/xdg-open";
+
+ // Determine if Nautilus (for Gnome Desktops) is available because it supports opening the file manager
+ // and selecting a specific file
+ bool nautilusAvailable = QFileInfo(defaultNautilusPath).exists();
+
+ QFileInfo pathInfo(path);
+ if (pathInfo.isDir())
+ {
+ QProcess::startDetached(defaultXdgOpenPath, { path });
+ }
+ else
+ {
+ if (nautilusAvailable)
+ {
+ QProcess::startDetached(defaultNautilusPath, { "--select", path });
+ }
+ else
+ {
+ QDir parentDir { pathInfo.dir() };
+ QProcess::startDetached(defaultXdgOpenPath, { parentDir.path() });
+ }
+ }
+ }
+
+ QString fileBrowserActionName()
+ {
+ const char* exploreActionName = "Open in file browser";
+ return QObject::tr(exploreActionName);
+ }
+}
diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Utilities/DesktopUtilities.cpp b/Code/Framework/AzQtComponents/Platform/Mac/AzQtComponents/Utilities/DesktopUtilities_Mac.cpp
similarity index 67%
rename from Code/Framework/AzQtComponents/AzQtComponents/Utilities/DesktopUtilities.cpp
rename to Code/Framework/AzQtComponents/Platform/Mac/AzQtComponents/Utilities/DesktopUtilities_Mac.cpp
index c210f17136..5920dc76c6 100644
--- a/Code/Framework/AzQtComponents/AzQtComponents/Utilities/DesktopUtilities.cpp
+++ b/Code/Framework/AzQtComponents/Platform/Mac/AzQtComponents/Utilities/DesktopUtilities_Mac.cpp
@@ -15,21 +15,6 @@ namespace AzQtComponents
{
void ShowFileOnDesktop(const QString& path)
{
-#if defined(AZ_PLATFORM_WINDOWS)
-
- // Launch explorer at the path provided
- QStringList args;
- if (!QFileInfo(path).isDir())
- {
- // Folders are just opened, files are selected
- args << "/select,";
- }
- args << QDir::toNativeSeparators(path);
-
- QProcess::startDetached("explorer", args);
-
-#else
-
if (QFileInfo(path).isDir())
{
QProcess::startDetached("/usr/bin/osascript", { "-e",
@@ -43,19 +28,11 @@ namespace AzQtComponents
QProcess::startDetached("/usr/bin/osascript", { "-e",
QStringLiteral("tell application \"Finder\" to activate") });
-
-#endif
}
QString fileBrowserActionName()
{
-#ifdef AZ_PLATFORM_WINDOWS
- const char* exploreActionName = "Open in Explorer";
-#elif defined(AZ_PLATFORM_MAC)
const char* exploreActionName = "Open in Finder";
-#else
- const char* exploreActionName = "Open in file browser";
-#endif
return QObject::tr(exploreActionName);
}
}
diff --git a/Code/Framework/AzQtComponents/Platform/Windows/AzQtComponents/Utilities/DesktopUtilities_Windows.cpp b/Code/Framework/AzQtComponents/Platform/Windows/AzQtComponents/Utilities/DesktopUtilities_Windows.cpp
new file mode 100644
index 0000000000..796e2c0ccf
--- /dev/null
+++ b/Code/Framework/AzQtComponents/Platform/Windows/AzQtComponents/Utilities/DesktopUtilities_Windows.cpp
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#include
+
+#include
+#include
+
+namespace AzQtComponents
+{
+ void ShowFileOnDesktop(const QString& path)
+ {
+ // Launch explorer at the path provided
+ QStringList args;
+ if (!QFileInfo(path).isDir())
+ {
+ // Folders are just opened, files are selected
+ args << "/select,";
+ }
+ args << QDir::toNativeSeparators(path);
+
+ QProcess::startDetached("explorer", args);
+ }
+
+ QString fileBrowserActionName()
+ {
+ const char* exploreActionName = "Open in Explorer";
+ return QObject::tr(exploreActionName);
+ }
+}
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/API/ComponentModeCollectionInterface.h b/Code/Framework/AzToolsFramework/AzToolsFramework/API/ComponentModeCollectionInterface.h
new file mode 100644
index 0000000000..4f9d72cb4d
--- /dev/null
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/API/ComponentModeCollectionInterface.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#pragma once
+
+#include
+#include
+#include
+
+namespace AzToolsFramework
+{
+ //! The AZ::Interface for component mode collection queries.
+ class ComponentModeCollectionInterface
+ {
+ public:
+ AZ_RTTI(ComponentModeCollectionInterface, "{DFAA4450-BBCD-47C0-9B91-FEA2DBD9B152}");
+
+ virtual ~ComponentModeCollectionInterface() = default;
+
+ //! Retrieves the list of all Component types (usually one).
+ //! @note If called outside of component mode, an empty vector will be returned.
+ virtual AZStd::vector GetComponentTypes() const = 0;
+ };
+} // namespace AzToolsFramework
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/API/ViewportEditorModeTrackerNotificationBus.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/API/ViewportEditorModeTrackerNotificationBus.cpp
new file mode 100644
index 0000000000..a61ea088d0
--- /dev/null
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/API/ViewportEditorModeTrackerNotificationBus.cpp
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#include
+#include
+
+namespace AzToolsFramework
+{
+ void ViewportEditorModeNotifications::Reflect(AZ::ReflectContext* context)
+ {
+ if (auto* behaviorContext = azrtti_cast(context))
+ {
+ behaviorContext->EBus("ViewportEditorModeNotificationsBus")
+ ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation)
+ ->Attribute(AZ::Script::Attributes::Category, "Editor")
+ ->Attribute(AZ::Script::Attributes::Module, "editor")
+ ->Event("OnEditorModeActivated", &ViewportEditorModeNotifications::OnEditorModeActivated)
+ ->Event("OnEditorModeDeactivated", &ViewportEditorModeNotifications::OnEditorModeDeactivated)
+ ;
+ }
+ }
+} // namespace AzToolsFramework
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/API/ViewportEditorModeTrackerNotificationBus.h b/Code/Framework/AzToolsFramework/AzToolsFramework/API/ViewportEditorModeTrackerNotificationBus.h
index 4fcb891e61..4fb4191d45 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/API/ViewportEditorModeTrackerNotificationBus.h
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/API/ViewportEditorModeTrackerNotificationBus.h
@@ -34,6 +34,8 @@ namespace AzToolsFramework
class ViewportEditorModesInterface
{
public:
+ AZ_RTTI(ViewportEditorModesInterface, "{2421496C-4A46-41C9-8AEF-AE2B6E43E6CF}");
+
virtual ~ViewportEditorModesInterface() = default;
//! Returns true if the specified editor mode is active, otherwise false.
@@ -52,6 +54,9 @@ namespace AzToolsFramework
using BusIdType = ViewportEditorModeTrackerInfo::IdType;
//////////////////////////////////////////////////////////////////////////
+ AZ_RTTI(ViewportEditorModeNotifications, "{9469DE39-6C21-423C-94FA-EF3A9616B14F}", AZ::EBusTraits);
+ static void Reflect(AZ::ReflectContext* context);
+
//! Notifies subscribers of the a given viewport to the activation of the specified editor mode.
virtual void OnEditorModeActivated([[maybe_unused]] const ViewportEditorModesInterface& editorModeState, [[maybe_unused]] ViewportEditorMode mode)
{
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ComponentMode/ComponentModeCollection.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ComponentMode/ComponentModeCollection.cpp
index df93e924b8..1768cb5920 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/ComponentMode/ComponentModeCollection.cpp
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ComponentMode/ComponentModeCollection.cpp
@@ -203,6 +203,12 @@ namespace AzToolsFramework
}
}
+ AZStd::vector ComponentModeCollection::GetComponentTypes() const
+ {
+ // If in component mode, return the active component types, otherwise return an empty vector
+ return InComponentMode() ? m_activeComponentTypes : AZStd::vector{};
+ }
+
void ComponentModeCollection::BeginComponentMode()
{
m_selectedComponentModeIndex = 0;
@@ -211,13 +217,6 @@ namespace AzToolsFramework
// notify listeners the editor has entered ComponentMode - listeners may
// wish to modify state to indicate this (e.g. appearance, functionality etc.)
- EditorComponentModeNotificationBus::Event(
- GetEntityContextId(), &EditorComponentModeNotifications::EnteredComponentMode,
- m_activeComponentTypes);
-
- // this call to activate the component mode editor state should eventually replace the bus call in
- // ComponentModeCollection::BeginComponentMode() to EditorComponentModeNotifications::EnteredComponentMode
- // such that all of the notifications for activating/deactivating the different editor modes are in a central location
m_viewportEditorModeTracker->ActivateMode({ GetEntityContextId() }, ViewportEditorMode::Component);
// enable actions for the first/primary ComponentMode
@@ -288,14 +287,6 @@ namespace AzToolsFramework
// notify listeners the editor has left ComponentMode - listeners may
// wish to modify state to indicate this (e.g. appearance, functionality etc.)
- EditorComponentModeNotificationBus::Event(
- GetEntityContextId(),
- &EditorComponentModeNotifications::LeftComponentMode,
- m_activeComponentTypes);
-
- // this call to deactivate the component mode editor state should eventually replace the bus call in
- // ComponentModeCollection::EndComponentMode() to EditorComponentModeNotifications::LeftComponentMode
- // such that all of the notifications for activating/deactivating the different editor modes are in a central location
m_viewportEditorModeTracker->DeactivateMode({ GetEntityContextId() }, ViewportEditorMode::Component);
// clear stored modes and builders for this ComponentMode
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ComponentMode/ComponentModeCollection.h b/Code/Framework/AzToolsFramework/AzToolsFramework/ComponentMode/ComponentModeCollection.h
index 9e299d2323..3b7690b969 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/ComponentMode/ComponentModeCollection.h
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ComponentMode/ComponentModeCollection.h
@@ -9,6 +9,7 @@
#pragma once
#include
+#include
#include
#include