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/exclude.filetag b/Assets/Engine/exclude.filetag
index 52534a87d8..3528454ec4 100644
--- a/Assets/Engine/exclude.filetag
+++ b/Assets/Engine/exclude.filetag
@@ -125,17 +125,6 @@
-
-
-
-
-
-
-
-
-
-
-
@@ -207,27 +196,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/Editor/Scripts/scene_mesh_to_prefab.py b/AutomatedTesting/Editor/Scripts/scene_mesh_to_prefab.py
new file mode 100644
index 0000000000..4aeff06f18
--- /dev/null
+++ b/AutomatedTesting/Editor/Scripts/scene_mesh_to_prefab.py
@@ -0,0 +1,184 @@
+#
+# 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
+#
+#
+import os, traceback, binascii, sys, json, pathlib
+import azlmbr.math
+import azlmbr.bus
+
+#
+# SceneAPI Processor
+#
+
+
+def log_exception_traceback():
+ exc_type, exc_value, exc_tb = sys.exc_info()
+ data = traceback.format_exception(exc_type, exc_value, exc_tb)
+ print(str(data))
+
+def get_mesh_node_names(sceneGraph):
+ import azlmbr.scene as sceneApi
+ import azlmbr.scene.graph
+ from scene_api import scene_data as sceneData
+
+ meshDataList = []
+ node = sceneGraph.get_root()
+ children = []
+ paths = []
+
+ while node.IsValid():
+ # store children to process after siblings
+ if sceneGraph.has_node_child(node):
+ children.append(sceneGraph.get_node_child(node))
+
+ nodeName = sceneData.SceneGraphName(sceneGraph.get_node_name(node))
+ paths.append(nodeName.get_path())
+
+ # store any node that has mesh data content
+ nodeContent = sceneGraph.get_node_content(node)
+ if nodeContent.CastWithTypeName('MeshData'):
+ if sceneGraph.is_node_end_point(node) is False:
+ if (len(nodeName.get_path())):
+ meshDataList.append(sceneData.SceneGraphName(sceneGraph.get_node_name(node)))
+
+ # advance to next node
+ if sceneGraph.has_node_sibling(node):
+ node = sceneGraph.get_node_sibling(node)
+ elif children:
+ node = children.pop()
+ else:
+ node = azlmbr.scene.graph.NodeIndex()
+
+ return meshDataList, paths
+
+def update_manifest(scene):
+ import json
+ import uuid, os
+ import azlmbr.scene as sceneApi
+ import azlmbr.scene.graph
+ from scene_api import scene_data as sceneData
+
+ graph = sceneData.SceneGraph(scene.graph)
+ # Get a list of all the mesh nodes, as well as all the nodes
+ mesh_name_list, all_node_paths = get_mesh_node_names(graph)
+ scene_manifest = sceneData.SceneManifest()
+
+ clean_filename = scene.sourceFilename.replace('.', '_')
+
+ # Compute the filename of the scene file
+ source_basepath = scene.watchFolder
+ source_relative_path = os.path.dirname(os.path.relpath(clean_filename, source_basepath))
+ source_filename_only = os.path.basename(clean_filename)
+
+ created_entities = []
+ previous_entity_id = azlmbr.entity.InvalidEntityId
+
+ # Loop every mesh node in the scene
+ for activeMeshIndex in range(len(mesh_name_list)):
+ mesh_name = mesh_name_list[activeMeshIndex]
+ mesh_path = mesh_name.get_path()
+ # Create a unique mesh group name using the filename + node name
+ mesh_group_name = '{}_{}'.format(source_filename_only, mesh_name.get_name())
+ # Remove forbidden filename characters from the name since this will become a file on disk later
+ mesh_group_name = "".join(char for char in mesh_group_name if char not in "|<>:\"/?*\\")
+ # Add the MeshGroup to the manifest and give it a unique ID
+ mesh_group = scene_manifest.add_mesh_group(mesh_group_name)
+ mesh_group['id'] = '{' + str(uuid.uuid5(uuid.NAMESPACE_DNS, source_filename_only + mesh_path)) + '}'
+ # Set our current node as the only node that is included in this MeshGroup
+ scene_manifest.mesh_group_select_node(mesh_group, mesh_path)
+
+ # Explicitly remove all other nodes to prevent implicit inclusions
+ for node in all_node_paths:
+ if node != mesh_path:
+ scene_manifest.mesh_group_unselect_node(mesh_group, node)
+
+ # Create an editor entity
+ entity_id = azlmbr.entity.EntityUtilityBus(azlmbr.bus.Broadcast, "CreateEditorReadyEntity", mesh_group_name)
+ # Add an EditorMeshComponent to the entity
+ editor_mesh_component = azlmbr.entity.EntityUtilityBus(azlmbr.bus.Broadcast, "GetOrAddComponentByTypeName", entity_id, "AZ::Render::EditorMeshComponent")
+ # Set the ModelAsset assetHint to the relative path of the input asset + the name of the MeshGroup we just created + the azmodel extension
+ # The MeshGroup we created will be output as a product in the asset's path named mesh_group_name.azmodel
+ # The assetHint will be converted to an AssetId later during prefab loading
+ json_update = json.dumps({
+ "Controller": { "Configuration": { "ModelAsset": {
+ "assetHint": os.path.join(source_relative_path, mesh_group_name) + ".azmodel" }}}
+ });
+ # Apply the JSON above to the component we created
+ result = azlmbr.entity.EntityUtilityBus(azlmbr.bus.Broadcast, "UpdateComponentForEntity", entity_id, editor_mesh_component, json_update)
+
+ if not result:
+ raise RuntimeError("UpdateComponentForEntity failed for Mesh component")
+
+ # Get the transform component
+ transform_component = azlmbr.entity.EntityUtilityBus(azlmbr.bus.Broadcast, "GetOrAddComponentByTypeName", entity_id, "27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0")
+
+ # Set this entity to be a child of the last entity we created
+ # This is just an example of how to do parenting and isn't necessarily useful to parent everything like this
+ if previous_entity_id is not None:
+ transform_json = json.dumps({
+ "Parent Entity" : previous_entity_id.to_json()
+ });
+
+ # Apply the JSON update
+ result = azlmbr.entity.EntityUtilityBus(azlmbr.bus.Broadcast, "UpdateComponentForEntity", entity_id, transform_component, transform_json)
+
+ if not result:
+ raise RuntimeError("UpdateComponentForEntity failed for Transform component")
+
+ # Update the last entity id for next time
+ previous_entity_id = entity_id
+
+ # Keep track of the entity we set up, we'll add them all to the prefab we're creating later
+ created_entities.append(entity_id)
+
+ # Create a prefab with all our entities
+ prefab_filename = source_filename_only + ".prefab"
+ created_template_id = azlmbr.prefab.PrefabSystemScriptingBus(azlmbr.bus.Broadcast, "CreatePrefab", created_entities, prefab_filename)
+
+ if created_template_id == azlmbr.prefab.InvalidTemplateId:
+ raise RuntimeError("CreatePrefab {} failed".format(prefab_filename))
+
+ # Convert the prefab to a JSON string
+ output = azlmbr.prefab.PrefabLoaderScriptingBus(azlmbr.bus.Broadcast, "SaveTemplateToString", created_template_id)
+
+ if output.IsSuccess():
+ jsonString = output.GetValue()
+ uuid = azlmbr.math.Uuid_CreateRandom().ToString()
+ jsonResult = json.loads(jsonString)
+ # Add a PrefabGroup to the manifest and store the JSON on it
+ scene_manifest.add_prefab_group(source_filename_only, uuid, jsonResult)
+ else:
+ raise RuntimeError("SaveTemplateToString failed for template id {}, prefab {}".format(created_template_id, prefab_filename))
+
+ # Convert the manifest to a JSON string and return it
+ new_manifest = scene_manifest.export()
+
+ return new_manifest
+
+sceneJobHandler = None
+
+def on_update_manifest(args):
+ try:
+ scene = args[0]
+ return update_manifest(scene)
+ except RuntimeError as err:
+ print (f'ERROR - {err}')
+ log_exception_traceback()
+ except:
+ log_exception_traceback()
+
+ global sceneJobHandler
+ sceneJobHandler = None
+
+# try to create SceneAPI handler for processing
+try:
+ import azlmbr.scene as sceneApi
+ if (sceneJobHandler == None):
+ sceneJobHandler = sceneApi.ScriptBuildingNotificationBusHandler()
+ sceneJobHandler.connect()
+ sceneJobHandler.add_callback('OnUpdateManifest', on_update_manifest)
+except:
+ sceneJobHandler = None
diff --git a/AutomatedTesting/Gem/Code/enabled_gems.cmake b/AutomatedTesting/Gem/Code/enabled_gems.cmake
index 0d281661b9..30740a489d 100644
--- a/AutomatedTesting/Gem/Code/enabled_gems.cmake
+++ b/AutomatedTesting/Gem/Code/enabled_gems.cmake
@@ -21,7 +21,6 @@ set(ENABLED_GEMS
QtForPython
PythonAssetBuilder
Metastream
-
Camera
EMotionFX
AtomTressFX
@@ -53,6 +52,6 @@ set(ENABLED_GEMS
AWSCore
AWSClientAuth
AWSMetrics
-
+ PrefabBuilder
AudioSystem
)
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/Atom/CMakeLists.txt
index 02aaa42597..ff3cd5c465 100644
--- a/AutomatedTesting/Gem/PythonTests/Atom/CMakeLists.txt
+++ b/AutomatedTesting/Gem/PythonTests/Atom/CMakeLists.txt
@@ -6,12 +6,7 @@
#
#
-################################################################################
-# Atom Renderer: Automated Tests
-# Runs EditorPythonBindings (hydra) scripts inside the Editor to verify test results for the Atom renderer.
-################################################################################
-
-if(PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_BUILD_TESTS_SUPPORTED AND AutomatedTesting IN_LIST LY_PROJECTS)
+if(PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_BUILD_TESTS_SUPPORTED)
ly_add_pytest(
NAME AutomatedTesting::Atom_TestSuite_Main
TEST_SUITE main
@@ -65,4 +60,18 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_BUILD_TESTS_SUPPORTED AND AutomatedT
COMPONENT
Atom
)
+ ly_add_pytest(
+ NAME AutomatedTesting::Atom_TestSuite_Main_GPU_Optimized
+ TEST_SUITE main
+ TEST_REQUIRES gpu
+ TEST_SERIAL
+ TIMEOUT 1200
+ PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Main_GPU_Optimized.py
+ RUNTIME_DEPENDENCIES
+ AssetProcessor
+ AutomatedTesting.Assets
+ Editor
+ COMPONENT
+ Atom
+ )
endif()
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main.py b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main.py
index 4c5716d365..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,20 +23,20 @@ TEST_DIRECTORY = os.path.join(os.path.dirname(__file__), "tests")
class TestAtomEditorComponentsMain(object):
"""Holds tests for Atom components."""
+ @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]
@@ -71,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",
@@ -161,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 = [
@@ -197,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):
"""
@@ -283,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
new file mode 100644
index 0000000000..568768e12e
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_GPU_Optimized.py
@@ -0,0 +1,44 @@
+"""
+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
+"""
+import os
+
+import pytest
+
+import ly_test_tools.environment.file_system as file_system
+from ly_test_tools.o3de.editor_test import EditorSharedTest, EditorTestSuite
+from ly_test_tools.image.screenshot_compare_qssim import qssim as compare_screenshots
+from .atom_utils.atom_component_helper import create_screenshots_archive, golden_images_directory
+
+DEFAULT_SUBFOLDER_PATH = 'user/PythonTests/Automated/Screenshots'
+
+
+@pytest.mark.xfail(reason="Optimized tests are experimental, we will enable xfail and monitor them temporarily.")
+@pytest.mark.parametrize("project", ["AutomatedTesting"])
+@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
+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"
+ test_screenshots = [] # Gets set by setup()
+ screenshot_directory = "" # Gets set by setup()
+
+ # Clear existing test screenshots before starting test.
+ def setup(self, workspace):
+ screenshot_directory = os.path.join(workspace.paths.project(), DEFAULT_SUBFOLDER_PATH)
+ test_screenshots = [os.path.join(screenshot_directory, self.screenshot_name)]
+ file_system.delete(test_screenshots, True, True)
+
+ from Atom.tests import hydra_AtomGPU_BasicLevelSetup as test_module
+
+ golden_images = [os.path.join(golden_images_directory(), screenshot_name)]
+ for test_screenshot, golden_screenshot in zip(test_screenshots, golden_images):
+ compare_screenshots(test_screenshot, golden_screenshot)
+ create_screenshots_archive(screenshot_directory)
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_Optimized.py b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_Optimized.py
index 47b2204d56..c29a391be4 100644
--- a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_Optimized.py
+++ b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_Optimized.py
@@ -14,33 +14,66 @@ from ly_test_tools.o3de.editor_test import EditorSharedTest, EditorTestSuite
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
class TestAutomation(EditorTestSuite):
+ @pytest.mark.test_case_id("C32078118")
class AtomEditorComponents_DecalAdded(EditorSharedTest):
from Atom.tests import hydra_AtomEditorComponents_DecalAdded as test_module
+ @pytest.mark.test_case_id("C32078119")
class AtomEditorComponents_DepthOfFieldAdded(EditorSharedTest):
from Atom.tests import hydra_AtomEditorComponents_DepthOfFieldAdded as test_module
+ @pytest.mark.test_case_id("C32078120")
class AtomEditorComponents_DirectionalLightAdded(EditorSharedTest):
from Atom.tests import hydra_AtomEditorComponents_DirectionalLightAdded as test_module
+ @pytest.mark.test_case_id("C32078121")
class AtomEditorComponents_ExposureControlAdded(EditorSharedTest):
from Atom.tests import hydra_AtomEditorComponents_ExposureControlAdded as test_module
+ @pytest.mark.test_case_id("C32078115")
class AtomEditorComponents_GlobalSkylightIBLAdded(EditorSharedTest):
from Atom.tests import hydra_AtomEditorComponents_GlobalSkylightIBLAdded as test_module
+ @pytest.mark.test_case_id("C32078125")
class AtomEditorComponents_PhysicalSkyAdded(EditorSharedTest):
from Atom.tests import hydra_AtomEditorComponents_PhysicalSkyAdded as test_module
+ @pytest.mark.test_case_id("C32078131")
class AtomEditorComponents_PostFXRadiusWeightModifierAdded(EditorSharedTest):
from Atom.tests import (
hydra_AtomEditorComponents_PostFXRadiusWeightModifierAdded as test_module)
+ @pytest.mark.test_case_id("C32078117")
class AtomEditorComponents_LightAdded(EditorSharedTest):
from Atom.tests import hydra_AtomEditorComponents_LightAdded as test_module
+ @pytest.mark.test_case_id("C36525660")
class AtomEditorComponents_DisplayMapperAdded(EditorSharedTest):
from Atom.tests import hydra_AtomEditorComponents_DisplayMapperAdded as test_module
+ @pytest.mark.test_case_id("C32078128")
+ class AtomEditorComponents_ReflectionProbeAdded(EditorSharedTest):
+ from Atom.tests import hydra_AtomEditorComponents_ReflectionProbeAdded as test_module
+
+ @pytest.mark.test_case_id("C32078124")
+ 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
+
+ @pytest.mark.test_case_id("C36525664")
+ class AtomEditorComponents_PostFXGradientWeightModifierAdded(EditorSharedTest):
+ from Atom.tests import hydra_AtomEditorComponents_PostFXGradientWeightModifierAdded 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 58b72ef01a..11832f8846 100644
--- a/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_component_helper.py
+++ b/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_component_helper.py
@@ -3,13 +3,54 @@ Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright
SPDX-License-Identifier: Apache-2.0 OR MIT
-File to assist with common hydra component functions used across various Atom tests.
"""
+import datetime
import os
+import zipfile
-from editor_python_test_tools.editor_test_helper import EditorTestHelper
-helper = EditorTestHelper(log_prefix="Atom_EditorTestHelper")
+def create_screenshots_archive(screenshot_path):
+ """
+ Creates a new zip file archive at archive_path containing all files listed within archive_path.
+ :param screenshot_path: location containing the files to archive, the zip archive file will also be saved here.
+ :return: None, but creates a new zip file archive inside path containing all of the files inside archive_path.
+ """
+ files_to_archive = []
+
+ # Search for .png and .ppm files to add to the zip archive file.
+ for (folder_name, sub_folders, file_names) in os.walk(screenshot_path):
+ for file_name in file_names:
+ if file_name.endswith(".png") or file_name.endswith(".ppm"):
+ file_path = os.path.join(folder_name, file_name)
+ files_to_archive.append(file_path)
+
+ # Setup variables for naming the zip archive file.
+ timestamp = datetime.datetime.now().timestamp()
+ formatted_timestamp = datetime.datetime.utcfromtimestamp(timestamp).strftime("%Y-%m-%d_%H-%M-%S")
+ screenshots_file = os.path.join(screenshot_path, f'screenshots_{formatted_timestamp}.zip')
+
+ # Write all of the valid .png and .ppm files to the archive file.
+ with zipfile.ZipFile(screenshots_file, 'w', compression=zipfile.ZIP_DEFLATED, allowZip64=True) as zip_archive:
+ for file_path in files_to_archive:
+ file_name = os.path.basename(file_path)
+ zip_archive.write(file_path, file_name)
+
+
+def golden_images_directory():
+ """
+ Uses this file location to return the valid location for golden image files.
+ :return: The path to the golden_images directory, but raises an IOError if the golden_images directory is missing.
+ """
+ current_file_directory = os.path.join(os.path.dirname(__file__))
+ golden_images_dir = os.path.join(current_file_directory, '..', 'golden_images')
+
+ if not os.path.exists(golden_images_dir):
+ raise IOError(
+ f'golden_images" directory was not found at path "{golden_images_dir}"'
+ f'Please add a "golden_images" directory inside: "{current_file_directory}"'
+ )
+
+ return golden_images_dir
def create_basic_atom_level(level_name):
@@ -31,6 +72,9 @@ def create_basic_atom_level(level_name):
import azlmbr.object
import editor_python_test_tools.hydra_editor_utils as hydra
+ from editor_python_test_tools.editor_test_helper import EditorTestHelper
+
+ helper = EditorTestHelper(log_prefix="Atom_EditorTestHelper")
# Create a new level.
new_level_name = level_name
@@ -69,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/atom_utils/material_editor_utils.py b/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/material_editor_utils.py
index ef0a592df0..b21c74de19 100644
--- a/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/material_editor_utils.py
+++ b/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/material_editor_utils.py
@@ -211,7 +211,7 @@ class Timeout:
return time.time() > self.die_after
-screenshotsFolder = os.path.join(azlmbr.paths.devroot, "AtomTest", "Cache" "pc", "Screenshots")
+screenshotsFolder = os.path.join(azlmbr.paths.products, "Screenshots")
class ScreenshotHelper:
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_AddedToEntity.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_AddedToEntity.py
index 602e7564b3..bbc8463152 100644
--- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_AddedToEntity.py
+++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_AddedToEntity.py
@@ -17,7 +17,7 @@ import azlmbr.legacy.general as general
import azlmbr.editor as editor
import azlmbr.render as render
-sys.path.append(os.path.join(azlmbr.paths.devroot, "AutomatedTesting", "Gem", "PythonTests"))
+sys.path.append(os.path.join(azlmbr.paths.projectroot, "Gem", "PythonTests"))
import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.utils import TestHelper
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_LightComponent.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_LightComponent.py
index 751f425916..7ecdc6859b 100644
--- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_LightComponent.py
+++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_LightComponent.py
@@ -14,7 +14,7 @@ import azlmbr.math as math
import azlmbr.paths
import azlmbr.legacy.general as general
-sys.path.append(os.path.join(azlmbr.paths.devassets, "Gem", "PythonTests"))
+sys.path.append(os.path.join(azlmbr.paths.projectroot, "Gem", "PythonTests"))
import editor_python_test_tools.hydra_editor_utils as hydra
from Atom.atom_utils.atom_constants import LIGHT_TYPES
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_MeshAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_MeshAdded.py
new file mode 100644
index 0000000000..fbf5c987d1
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_MeshAdded.py
@@ -0,0 +1,171 @@
+"""
+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")
+ mesh_entity_creation = (
+ "Mesh Entity successfully created",
+ "Mesh Entity failed to be created")
+ mesh_component_added = (
+ "Entity has a Mesh component",
+ "Entity failed to find Mesh component")
+ mesh_asset_specified = (
+ "Mesh asset set",
+ "Mesh asset not set")
+ 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_Mesh_AddedToEntity():
+ """
+ Summary:
+ Tests the Mesh 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 Mesh entity with no components.
+ 2) Add a Mesh component to Mesh entity.
+ 3) UNDO the entity creation and component addition.
+ 4) REDO the entity creation and component addition.
+ 5) Specify the Mesh component asset
+ 6) Enter/Exit game mode.
+ 7) Test IsHidden.
+ 8) Test IsVisible.
+ 9) Delete Mesh entity.
+ 10) UNDO deletion.
+ 11) REDO deletion.
+ 12) Look for errors.
+
+ :return: None
+ """
+
+ import os
+
+ import azlmbr.legacy.general as general
+
+ from editor_python_test_tools.asset_utils import Asset
+ from editor_python_test_tools.editor_entity_utils import EditorEntity
+ from editor_python_test_tools.utils import Report, Tracer, TestHelper as helper
+
+ with Tracer() as error_tracer:
+ # Test setup begins.
+ # Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
+ helper.init_idle()
+ helper.open_level("", "Base")
+
+ # Test steps begin.
+ # 1. Create a Mesh entity with no components.
+ mesh_name = "Mesh"
+ mesh_entity = EditorEntity.create_editor_entity(mesh_name)
+ Report.critical_result(Tests.mesh_entity_creation, mesh_entity.exists())
+
+ # 2. Add a Mesh component to Mesh entity.
+ mesh_component = mesh_entity.add_component(mesh_name)
+ Report.critical_result(
+ Tests.mesh_component_added,
+ mesh_entity.has_component(mesh_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 mesh_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, mesh_entity.exists())
+
+ # 5. Set Mesh component asset property
+ mesh_property_asset = 'Controller|Configuration|Mesh Asset'
+ model_path = os.path.join('Objects', 'shaderball', 'shaderball_default_1m.azmodel')
+ model = Asset.find_asset_by_path(model_path)
+ mesh_component.set_component_property_value(mesh_property_asset, model.id)
+ Report.result(Tests.mesh_asset_specified,
+ mesh_component.get_component_property_value(mesh_property_asset) == model.id)
+
+ # 6. Enter/Exit game mode.
+ helper.enter_game_mode(Tests.enter_game_mode)
+ general.idle_wait_frames(1)
+ helper.exit_game_mode(Tests.exit_game_mode)
+
+ # 7. Test IsHidden.
+ mesh_entity.set_visibility_state(False)
+ Report.result(Tests.is_hidden, mesh_entity.is_hidden() is True)
+
+ # 8. Test IsVisible.
+ mesh_entity.set_visibility_state(True)
+ general.idle_wait_frames(1)
+ Report.result(Tests.is_visible, mesh_entity.is_visible() is True)
+
+ # 9. Delete Mesh entity.
+ mesh_entity.delete()
+ Report.result(Tests.entity_deleted, not mesh_entity.exists())
+
+ # 10. UNDO deletion.
+ general.undo()
+ Report.result(Tests.deletion_undo, mesh_entity.exists())
+
+ # 11. REDO deletion.
+ general.redo()
+ Report.result(Tests.deletion_redo, not mesh_entity.exists())
+
+ # 12. Look for errors or asserts.
+ helper.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_Mesh_AddedToEntity)
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_PostFXGradientWeightModifierAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_PostFXGradientWeightModifierAdded.py
new file mode 100644
index 0000000000..d38e96739d
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_PostFXGradientWeightModifierAdded.py
@@ -0,0 +1,179 @@
+"""
+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_gradient_weight_creation = (
+ "PostFX Gradient Weight Modifier Entity successfully created",
+ "PostFX Gradient Weight Modifier Entity failed to be created")
+ postfx_gradient_weight_component = (
+ "Entity has a PostFX Gradient Weight Modifier component",
+ "Entity failed to find PostFX Gradient Weight Modifier component")
+ postfx_gradient_weight_disabled = (
+ "PostFX Gradient Weight Modifier component disabled",
+ "PostFX Gradient Weight Modifier component was not disabled.")
+ postfx_layer_component = (
+ "Entity has a PostFX Layer component",
+ "Entity did not have an PostFX Layer component")
+ postfx_gradient_weight_enabled = (
+ "PostFX Gradient Weight Modifier component enabled",
+ "PostFX Gradient 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_PostFXGradientWeightModifier_AddedToEntity():
+ """
+ Summary:
+ Tests the PostFX Gradient 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 Gradient Weight Modifier entity with no components.
+ 2) Add a PostFX Gradient Weight Modifier component to PostFX Gradient Weight Modifier entity.
+ 3) UNDO the entity creation and component addition.
+ 4) REDO the entity creation and component addition.
+ 5) Verify PostFX Gradient Weight Modifier component not enabled.
+ 6) Add PostFX Layer component since it is required by the PostFX Gradient Weight Modifier component.
+ 7) Verify PostFX Gradient Weight Modifier component is enabled.
+ 8) Enter/Exit game mode.
+ 9) Test IsHidden.
+ 10) Test IsVisible.
+ 11) Delete PostFX Gradient Weight Modifier entity.
+ 12) UNDO deletion.
+ 13) REDO deletion.
+ 14) 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 Gradient Weight Modifier entity with no components.
+ postfx_gradient_weight_name = "PostFX Gradient Weight Modifier"
+ postfx_gradient_weight_entity = EditorEntity.create_editor_entity(postfx_gradient_weight_name)
+ Report.critical_result(Tests.postfx_gradient_weight_creation, postfx_gradient_weight_entity.exists())
+
+ # 2. Add a PostFX Gradient Weight Modifier component to PostFX Gradient Weight Modifier entity.
+ postfx_gradient_weight_component = postfx_gradient_weight_entity.add_component(postfx_gradient_weight_name)
+ Report.critical_result(
+ Tests.postfx_gradient_weight_component,
+ postfx_gradient_weight_entity.has_component(postfx_gradient_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_gradient_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_gradient_weight_entity.exists())
+
+ # 5. Verify PostFX Gradient Weight Modifier component not enabled.
+ Report.result(Tests.postfx_gradient_weight_disabled, not postfx_gradient_weight_component.is_enabled())
+
+ # 6. Add PostFX Layer component since it is required by the PostFX Gradient Weight Modifier component.
+ postfx_layer_name = "PostFX Layer"
+ postfx_gradient_weight_entity.add_component(postfx_layer_name)
+ Report.result(Tests.postfx_layer_component, postfx_gradient_weight_entity.has_component(postfx_layer_name))
+
+ # 7. Verify PostFX Gradient Weight Modifier component is enabled.
+ Report.result(Tests.postfx_gradient_weight_enabled, postfx_gradient_weight_component.is_enabled())
+
+ # 8. 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)
+
+ # 9. Test IsHidden.
+ postfx_gradient_weight_entity.set_visibility_state(False)
+ Report.result(Tests.is_hidden, postfx_gradient_weight_entity.is_hidden() is True)
+
+ # 10. Test IsVisible.
+ postfx_gradient_weight_entity.set_visibility_state(True)
+ general.idle_wait_frames(1)
+ Report.result(Tests.is_visible, postfx_gradient_weight_entity.is_visible() is True)
+
+ # 11. Delete PostFX Gradient Weight Modifier entity.
+ postfx_gradient_weight_entity.delete()
+ Report.result(Tests.entity_deleted, not postfx_gradient_weight_entity.exists())
+
+ # 12. UNDO deletion.
+ general.undo()
+ Report.result(Tests.deletion_undo, postfx_gradient_weight_entity.exists())
+
+ # 13. REDO deletion.
+ general.redo()
+ Report.result(Tests.deletion_redo, not postfx_gradient_weight_entity.exists())
+
+ # 14. 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_PostFXGradientWeightModifier_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_AtomEditorComponents_ReflectionProbeAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_ReflectionProbeAdded.py
new file mode 100644
index 0000000000..9b13eb2c7e
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_ReflectionProbeAdded.py
@@ -0,0 +1,194 @@
+"""
+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")
+ reflection_probe_creation = (
+ "Reflection Probe Entity successfully created",
+ "Reflection Probe Entity failed to be created")
+ reflection_probe_component = (
+ "Entity has a Reflection Probe component",
+ "Entity failed to find Reflection Probe component")
+ reflection_probe_disabled = (
+ "Reflection Probe component disabled",
+ "Reflection Probe component was not disabled.")
+ reflection_map_generated = (
+ "Reflection Probe cubemap generated",
+ "Reflection Probe cubemap not generated")
+ box_shape_component = (
+ "Entity has a Box Shape component",
+ "Entity did not have a Box Shape component")
+ reflection_probe_enabled = (
+ "Reflection Probe component enabled",
+ "Reflection Probe 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_ReflectionProbe_AddedToEntity():
+ """
+ Summary:
+ Tests the Reflection Probe 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 Reflection Probe entity with no components.
+ 2) Add a Reflection Probe component to Reflection Probe entity.
+ 3) UNDO the entity creation and component addition.
+ 4) REDO the entity creation and component addition.
+ 5) Verify Reflection Probe component not enabled.
+ 6) Add Shape component since it is required by the Reflection Probe component.
+ 7) Verify Reflection Probe component is enabled.
+ 8) Enter/Exit game mode.
+ 9) Test IsHidden.
+ 10) Test IsVisible.
+ 11) Verify cubemap generation
+ 12) Delete Reflection Probe entity.
+ 13) UNDO deletion.
+ 14) REDO deletion.
+ 15) Look for errors.
+
+ :return: None
+ """
+
+ import azlmbr.legacy.general as general
+ import azlmbr.math as math
+ import azlmbr.render as render
+
+ from editor_python_test_tools.editor_entity_utils import EditorEntity
+ from editor_python_test_tools.utils import Report, Tracer, TestHelper as helper
+
+ with Tracer() as error_tracer:
+ # Test setup begins.
+ # Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
+ helper.init_idle()
+ helper.open_level("", "Base")
+
+ # Test steps begin.
+ # 1. Create a Reflection Probe entity with no components.
+ reflection_probe_name = "Reflection Probe"
+ reflection_probe_entity = EditorEntity.create_editor_entity_at(
+ math.Vector3(512.0, 512.0, 34.0), reflection_probe_name)
+ Report.critical_result(Tests.reflection_probe_creation, reflection_probe_entity.exists())
+
+ # 2. Add a Reflection Probe component to Reflection Probe entity.
+ reflection_probe_component = reflection_probe_entity.add_component(reflection_probe_name)
+ Report.critical_result(
+ Tests.reflection_probe_component,
+ reflection_probe_entity.has_component(reflection_probe_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 reflection_probe_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, reflection_probe_entity.exists())
+
+ # 5. Verify Reflection Probe component not enabled.
+ Report.result(Tests.reflection_probe_disabled, not reflection_probe_component.is_enabled())
+
+ # 6. Add Box Shape component since it is required by the Reflection Probe component.
+ box_shape = "Box Shape"
+ reflection_probe_entity.add_component(box_shape)
+ Report.result(Tests.box_shape_component, reflection_probe_entity.has_component(box_shape))
+
+ # 7. Verify Reflection Probe component is enabled.
+ Report.result(Tests.reflection_probe_enabled, reflection_probe_component.is_enabled())
+
+ # 8. Enter/Exit game mode.
+ helper.enter_game_mode(Tests.enter_game_mode)
+ general.idle_wait_frames(1)
+ helper.exit_game_mode(Tests.exit_game_mode)
+
+ # 9. Test IsHidden.
+ reflection_probe_entity.set_visibility_state(False)
+ Report.result(Tests.is_hidden, reflection_probe_entity.is_hidden() is True)
+
+ # 10. Test IsVisible.
+ reflection_probe_entity.set_visibility_state(True)
+ general.idle_wait_frames(1)
+ Report.result(Tests.is_visible, reflection_probe_entity.is_visible() is True)
+
+ # 11. Verify cubemap generation
+ render.EditorReflectionProbeBus(azlmbr.bus.Event, "BakeReflectionProbe", reflection_probe_entity.id)
+ Report.result(
+ Tests.reflection_map_generated,
+ helper.wait_for_condition(
+ lambda: reflection_probe_component.get_component_property_value("Cubemap|Baked Cubemap Path") != "",
+ 20.0))
+
+ # 12. Delete Reflection Probe entity.
+ reflection_probe_entity.delete()
+ Report.result(Tests.entity_deleted, not reflection_probe_entity.exists())
+
+ # 13. UNDO deletion.
+ general.undo()
+ Report.result(Tests.deletion_undo, reflection_probe_entity.exists())
+
+ # 14. REDO deletion.
+ general.redo()
+ Report.result(Tests.deletion_redo, not reflection_probe_entity.exists())
+
+ # 15. Look for errors or asserts.
+ helper.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_ReflectionProbe_AddedToEntity)
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_BasicLevelSetup.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_BasicLevelSetup.py
new file mode 100644
index 0000000000..92c555127a
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_BasicLevelSetup.py
@@ -0,0 +1,292 @@
+"""
+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
+"""
+
+
+# fmt: off
+class Tests :
+ camera_component_added = ("Camera component was added", "Camera component wasn't added")
+ camera_fov_set = ("Camera component FOV property set", "Camera component FOV property wasn't set")
+ directional_light_component_added = ("Directional Light component added", "Directional Light component wasn't added")
+ enter_game_mode = ("Entered game mode", "Failed to enter game mode")
+ exit_game_mode = ("Exited game mode", "Couldn't exit game mode")
+ global_skylight_component_added = ("Global Skylight (IBL) component added", "Global Skylight (IBL) component wasn't added")
+ global_skylight_diffuse_image_set = ("Global Skylight Diffuse Image property set", "Global Skylight Diffuse Image property wasn't set")
+ global_skylight_specular_image_set = ("Global Skylight Specular Image property set", "Global Skylight Specular Image property wasn't set")
+ ground_plane_material_asset_set = ("Ground Plane Material Asset was set", "Ground Plane Material Asset wasn't set")
+ ground_plane_material_component_added = ("Ground Plane Material component added", "Ground Plane Material component wasn't added")
+ ground_plane_mesh_asset_set = ("Ground Plane Mesh Asset property was set", "Ground Plane Mesh Asset property wasn't set")
+ hdri_skybox_component_added = ("HDRi Skybox component added", "HDRi Skybox component wasn't added")
+ hdri_skybox_cubemap_texture_set = ("HDRi Skybox Cubemap Texture property set", "HDRi Skybox Cubemap Texture property wasn't set")
+ mesh_component_added = ("Mesh component added", "Mesh component wasn't added")
+ no_assert_occurred = ("No asserts detected", "Asserts were detected")
+ no_error_occurred = ("No errors detected", "Errors were detected")
+ secondary_grid_spacing = ("Secondary Grid Spacing set", "Secondary Grid Spacing not set")
+ sphere_material_component_added = ("Sphere Material component added", "Sphere Material component wasn't added")
+ sphere_material_set = ("Sphere Material Asset was set", "Sphere Material Asset wasn't set")
+ sphere_mesh_asset_set = ("Sphere Mesh Asset was set", "Sphere Mesh Asset wasn't set")
+ viewport_set = ("Viewport set to correct size", "Viewport not set to correct size")
+# fmt: on
+
+
+def AtomGPU_BasicLevelSetup_SetsUpLevel():
+ """
+ Summary:
+ Sets up a level to match the AtomBasicLevelSetup.ppm golden image then takes a screenshot to verify the setup.
+
+ Test setup:
+ - Wait for Editor idle loop.
+ - Open the "Base" level.
+
+ Expected Behavior:
+ The scene can be setup for a basic level.
+ The test screenshot matches the appearance of the AtomBasicLevelSetup.ppm golden image.
+
+ Test Steps:
+ 1. Close error windows and display helpers then update the viewport size.
+ 2. Create Default Level Entity.
+ 3. Create Grid Entity as a child entity of the Default Level Entity.
+ 4. Add Grid component to Grid Entity and set Secondary Grid Spacing.
+ 5. Create Global Skylight (IBL) Entity as a child entity of the Default Level Entity.
+ 6. Add HDRi Skybox component to the Global Skylight (IBL) Entity.
+ 7. Add Global Skylight (IBL) component to the Global Skylight (IBL) Entity.
+ 8. Set the Cubemap Texture property of the HDRi Skybox component.
+ 9. Set the Diffuse Image property of the Global Skylight (IBL) component.
+ 10. Set the Specular Image property of the Global Skylight (IBL) component.
+ 11. Create a Ground Plane Entity with a Material component that is a child entity of the Default Level Entity.
+ 12. Set the Material Asset property of the Material component for the Ground Plane Entity.
+ 13. Add the Mesh component to the Ground Plane Entity and set the Mesh component Mesh Asset property.
+ 14. Create a Directional Light Entity as a child entity of the Default Level Entity.
+ 15. Add Directional Light component to Directional Light Entity and set entity rotation.
+ 16. Create a Sphere Entity as a child entity of the Default Level Entity then add a Material component.
+ 17. Set the Material Asset property of the Material component for the Sphere Entity.
+ 18. Add Mesh component to Sphere Entity and set the Mesh Asset property for the Mesh component.
+ 19. Create a Camera Entity as a child entity of the Default Level Entity then add a Camera component.
+ 20. Set the Camera Entity rotation value and set the Camera component Field of View value.
+ 21. Enter game mode.
+ 22. Take screenshot.
+ 23. Exit game mode.
+ 24. Look for errors.
+
+ :return: None
+ """
+
+ import os
+ from math import isclose
+
+ import azlmbr.asset as asset
+ import azlmbr.bus as bus
+ import azlmbr.legacy.general as general
+ import azlmbr.math as math
+ import azlmbr.paths
+
+ from editor_python_test_tools.editor_entity_utils import EditorEntity
+ from editor_python_test_tools.utils import Report, Tracer, TestHelper as helper
+
+ from Atom.atom_utils.screenshot_utils import ScreenshotHelper
+
+ MATERIAL_COMPONENT_NAME = "Material"
+ MESH_COMPONENT_NAME = "Mesh"
+ SCREENSHOT_NAME = "AtomBasicLevelSetup"
+ SCREEN_WIDTH = 1280
+ SCREEN_HEIGHT = 720
+ DEGREE_RADIAN_FACTOR = 0.0174533
+
+ def initial_viewport_setup(screen_width, screen_height):
+ general.set_viewport_size(screen_width, screen_height)
+ general.update_viewport()
+ result = isclose(
+ a=general.get_viewport_size().x, b=SCREEN_WIDTH, rel_tol=0.1) and isclose(
+ a=general.get_viewport_size().y, b=SCREEN_HEIGHT, rel_tol=0.1)
+
+ return result
+
+ with Tracer() as error_tracer:
+ # Test setup begins.
+ # Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
+ helper.init_idle()
+ helper.open_level("", "Base")
+
+ # Test steps begin.
+ # 1. Close error windows and display helpers then update the viewport size.
+ helper.close_error_windows()
+ helper.close_display_helpers()
+ general.update_viewport()
+ Report.critical_result(Tests.viewport_set, initial_viewport_setup(SCREEN_WIDTH, SCREEN_HEIGHT))
+
+ # 2. Create Default Level Entity.
+ default_level_entity_name = "Default Level"
+ default_level_entity = EditorEntity.create_editor_entity_at(
+ math.Vector3(0.0, 0.0, 0.0), default_level_entity_name)
+
+ # 3. Create Grid Entity as a child entity of the Default Level Entity.
+ grid_name = "Grid"
+ grid_entity = EditorEntity.create_editor_entity(grid_name, default_level_entity.id)
+
+ # 4. Add Grid component to Grid Entity and set Secondary Grid Spacing.
+ grid_component = grid_entity.add_component(grid_name)
+ secondary_grid_spacing_property = "Controller|Configuration|Secondary Grid Spacing"
+ secondary_grid_spacing_value = 1.0
+ grid_component.set_component_property_value(secondary_grid_spacing_property, secondary_grid_spacing_value)
+ secondary_grid_spacing_set = grid_component.get_component_property_value(
+ secondary_grid_spacing_property) == secondary_grid_spacing_value
+ Report.result(Tests.secondary_grid_spacing, secondary_grid_spacing_set)
+
+ # 5. Create Global Skylight (IBL) Entity as a child entity of the Default Level Entity.
+ global_skylight_name = "Global Skylight (IBL)"
+ global_skylight_entity = EditorEntity.create_editor_entity(global_skylight_name, default_level_entity.id)
+
+ # 6. Add HDRi Skybox component to the Global Skylight (IBL) Entity.
+ hdri_skybox_name = "HDRi Skybox"
+ hdri_skybox_component = global_skylight_entity.add_component(hdri_skybox_name)
+ Report.result(Tests.hdri_skybox_component_added, global_skylight_entity.has_component(hdri_skybox_name))
+
+ # 7. Add Global Skylight (IBL) component to the Global Skylight (IBL) Entity.
+ global_skylight_component = global_skylight_entity.add_component(global_skylight_name)
+ Report.result(Tests.global_skylight_component_added, global_skylight_entity.has_component(global_skylight_name))
+
+ # 8. Set the Cubemap Texture property of the HDRi Skybox component.
+ global_skylight_image_asset_path = os.path.join(
+ "LightingPresets", "greenwich_park_02_4k_iblskyboxcm_iblspecular.exr.streamingimage")
+ global_skylight_image_asset = asset.AssetCatalogRequestBus(
+ bus.Broadcast, "GetAssetIdByPath", global_skylight_image_asset_path, math.Uuid(), False)
+ hdri_skybox_cubemap_texture_property = "Controller|Configuration|Cubemap Texture"
+ hdri_skybox_component.set_component_property_value(
+ hdri_skybox_cubemap_texture_property, global_skylight_image_asset)
+ Report.result(
+ Tests.hdri_skybox_cubemap_texture_set,
+ hdri_skybox_component.get_component_property_value(
+ hdri_skybox_cubemap_texture_property) == global_skylight_image_asset)
+
+ # 9. Set the Diffuse Image property of the Global Skylight (IBL) component.
+ # Re-use the same image that was used in the previous test step.
+ global_skylight_diffuse_image_property = "Controller|Configuration|Diffuse Image"
+ global_skylight_component.set_component_property_value(
+ global_skylight_diffuse_image_property, global_skylight_image_asset)
+ Report.result(
+ Tests.global_skylight_diffuse_image_set,
+ global_skylight_component.get_component_property_value(
+ global_skylight_diffuse_image_property) == global_skylight_image_asset)
+
+ # 10. Set the Specular Image property of the Global Skylight (IBL) component.
+ # Re-use the same image that was used in the previous test step.
+ global_skylight_specular_image_property = "Controller|Configuration|Specular Image"
+ global_skylight_component.set_component_property_value(
+ global_skylight_specular_image_property, global_skylight_image_asset)
+ global_skylight_specular_image_set = global_skylight_component.get_component_property_value(
+ global_skylight_specular_image_property)
+ Report.result(
+ Tests.global_skylight_specular_image_set, global_skylight_specular_image_set == global_skylight_image_asset)
+
+ # 11. Create a Ground Plane Entity with a Material component that is a child entity of the Default Level Entity.
+ ground_plane_name = "Ground Plane"
+ ground_plane_entity = EditorEntity.create_editor_entity(ground_plane_name, default_level_entity.id)
+ ground_plane_material_component = ground_plane_entity.add_component(MATERIAL_COMPONENT_NAME)
+ Report.result(
+ Tests.ground_plane_material_component_added, ground_plane_entity.has_component(MATERIAL_COMPONENT_NAME))
+
+ # 12. Set the Material Asset property of the Material component for the Ground Plane Entity.
+ ground_plane_entity.set_local_uniform_scale(32.0)
+ ground_plane_material_asset_path = os.path.join("Materials", "Presets", "PBR", "metal_chrome.azmaterial")
+ ground_plane_material_asset = asset.AssetCatalogRequestBus(
+ bus.Broadcast, "GetAssetIdByPath", ground_plane_material_asset_path, math.Uuid(), False)
+ ground_plane_material_asset_property = "Default Material|Material Asset"
+ ground_plane_material_component.set_component_property_value(
+ ground_plane_material_asset_property, ground_plane_material_asset)
+ Report.result(
+ Tests.ground_plane_material_asset_set,
+ ground_plane_material_component.get_component_property_value(
+ ground_plane_material_asset_property) == ground_plane_material_asset)
+
+ # 13. Add the Mesh component to the Ground Plane Entity and set the Mesh component Mesh Asset property.
+ ground_plane_mesh_component = ground_plane_entity.add_component(MESH_COMPONENT_NAME)
+ Report.result(Tests.mesh_component_added, ground_plane_entity.has_component(MESH_COMPONENT_NAME))
+ ground_plane_mesh_asset_path = os.path.join("Objects", "plane.azmodel")
+ ground_plane_mesh_asset = asset.AssetCatalogRequestBus(
+ bus.Broadcast, "GetAssetIdByPath", ground_plane_mesh_asset_path, math.Uuid(), False)
+ ground_plane_mesh_asset_property = "Controller|Configuration|Mesh Asset"
+ ground_plane_mesh_component.set_component_property_value(
+ ground_plane_mesh_asset_property, ground_plane_mesh_asset)
+ Report.result(
+ Tests.ground_plane_mesh_asset_set,
+ ground_plane_mesh_component.get_component_property_value(
+ ground_plane_mesh_asset_property) == ground_plane_mesh_asset)
+
+ # 14. Create a Directional Light Entity as a child entity of the Default Level Entity.
+ directional_light_name = "Directional Light"
+ directional_light_entity = EditorEntity.create_editor_entity_at(
+ math.Vector3(0.0, 0.0, 10.0), directional_light_name, default_level_entity.id)
+
+ # 15. Add Directional Light component to Directional Light Entity and set entity rotation.
+ directional_light_entity.add_component(directional_light_name)
+ directional_light_entity_rotation = math.Vector3(DEGREE_RADIAN_FACTOR * -90.0, 0.0, 0.0)
+ directional_light_entity.set_local_rotation(directional_light_entity_rotation)
+ Report.result(
+ Tests.directional_light_component_added, directional_light_entity.has_component(directional_light_name))
+
+ # 16. Create a Sphere Entity as a child entity of the Default Level Entity then add a Material component.
+ sphere_entity = EditorEntity.create_editor_entity_at(
+ math.Vector3(0.0, 0.0, 1.0), "Sphere", default_level_entity.id)
+ sphere_material_component = sphere_entity.add_component(MATERIAL_COMPONENT_NAME)
+ Report.result(Tests.sphere_material_component_added, sphere_entity.has_component(MATERIAL_COMPONENT_NAME))
+
+ # 17. Set the Material Asset property of the Material component for the Sphere Entity.
+ sphere_material_asset_path = os.path.join("Materials", "Presets", "PBR", "metal_brass_polished.azmaterial")
+ sphere_material_asset = asset.AssetCatalogRequestBus(
+ bus.Broadcast, "GetAssetIdByPath", sphere_material_asset_path, math.Uuid(), False)
+ sphere_material_asset_property = "Default Material|Material Asset"
+ sphere_material_component.set_component_property_value(sphere_material_asset_property, sphere_material_asset)
+ Report.result(Tests.sphere_material_set, sphere_material_component.get_component_property_value(
+ sphere_material_asset_property) == sphere_material_asset)
+
+ # 18. Add Mesh component to Sphere Entity and set the Mesh Asset property for the Mesh component.
+ sphere_mesh_component = sphere_entity.add_component(MESH_COMPONENT_NAME)
+ sphere_mesh_asset_path = os.path.join("Models", "sphere.azmodel")
+ sphere_mesh_asset = asset.AssetCatalogRequestBus(
+ bus.Broadcast, "GetAssetIdByPath", sphere_mesh_asset_path, math.Uuid(), False)
+ sphere_mesh_asset_property = "Controller|Configuration|Mesh Asset"
+ sphere_mesh_component.set_component_property_value(sphere_mesh_asset_property, sphere_mesh_asset)
+ Report.result(Tests.sphere_mesh_asset_set, sphere_mesh_component.get_component_property_value(
+ sphere_mesh_asset_property) == sphere_mesh_asset)
+
+ # 19. Create a Camera Entity as a child entity of the Default Level Entity then add a Camera component.
+ camera_name = "Camera"
+ camera_entity = EditorEntity.create_editor_entity_at(
+ math.Vector3(5.5, -12.0, 9.0), camera_name, default_level_entity.id)
+ camera_component = camera_entity.add_component(camera_name)
+ Report.result(Tests.camera_component_added, camera_entity.has_component(camera_name))
+
+ # 20. Set the Camera Entity rotation value and set the Camera component Field of View value.
+ camera_entity_rotation = math.Vector3(
+ DEGREE_RADIAN_FACTOR * -27.0, DEGREE_RADIAN_FACTOR * -12.0, DEGREE_RADIAN_FACTOR * 25.0)
+ camera_entity.set_local_rotation(camera_entity_rotation)
+ camera_fov_property = "Controller|Configuration|Field of view"
+ camera_fov_value = 60.0
+ camera_component.set_component_property_value(camera_fov_property, camera_fov_value)
+ azlmbr.camera.EditorCameraViewRequestBus(azlmbr.bus.Event, "ToggleCameraAsActiveView", camera_entity.id)
+ Report.result(Tests.camera_fov_set, camera_component.get_component_property_value(
+ camera_fov_property) == camera_fov_value)
+
+ # 21. Enter game mode.
+ helper.enter_game_mode(Tests.enter_game_mode)
+ helper.wait_for_condition(function=lambda: general.is_in_game_mode(), timeout_in_seconds=4.0)
+
+ # 22. Take screenshot.
+ ScreenshotHelper(general.idle_wait_frames).capture_screenshot_blocking(f"{SCREENSHOT_NAME}.ppm")
+
+ # 23. Exit game mode.
+ helper.exit_game_mode(Tests.exit_game_mode)
+ helper.wait_for_condition(function=lambda: not general.is_in_game_mode(), timeout_in_seconds=4.0)
+
+ # 24. Look for errors.
+ helper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0)
+ Report.result(Tests.no_assert_occurred, not error_tracer.has_asserts)
+ Report.result(Tests.no_error_occurred, not error_tracer.has_errors)
+
+
+if __name__ == "__main__":
+ from editor_python_test_tools.utils import Report
+ Report.start_test(AtomGPU_BasicLevelSetup_SetsUpLevel)
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomMaterialEditor_BasicTests.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomMaterialEditor_BasicTests.py
index 88a1ef4c7b..9f8f6c44b2 100644
--- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomMaterialEditor_BasicTests.py
+++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomMaterialEditor_BasicTests.py
@@ -16,7 +16,7 @@ import time
import azlmbr.math as math
import azlmbr.paths
-sys.path.append(os.path.join(azlmbr.paths.devassets, "Gem", "PythonTests"))
+sys.path.append(os.path.join(azlmbr.paths.projectroot, "Gem", "PythonTests"))
import Atom.atom_utils.material_editor_utils as material_editor
@@ -27,10 +27,10 @@ TEST_MATERIAL_1 = "001_DefaultWhite.material"
TEST_MATERIAL_2 = "002_BaseColorLerp.material"
TEST_MATERIAL_3 = "003_MetalMatte.material"
TEST_DATA_PATH = os.path.join(
- azlmbr.paths.devroot, "Gems", "Atom", "TestData", "TestData", "Materials", "StandardPbrTestCases"
+ azlmbr.paths.engroot, "Gems", "Atom", "TestData", "TestData", "Materials", "StandardPbrTestCases"
)
MATERIAL_TYPE_PATH = os.path.join(
- azlmbr.paths.devroot, "Gems", "Atom", "Feature", "Common", "Assets",
+ azlmbr.paths.engroot, "Gems", "Atom", "Feature", "Common", "Assets",
"Materials", "Types", "StandardPBR.materialtype",
)
CACHE_FILE_EXTENSION = ".azmaterial"
@@ -61,7 +61,7 @@ def run():
print(f"Material opened: {material_editor.is_open(document_id)}")
# Verify if the test material exists initially
- target_path = os.path.join(azlmbr.paths.devroot, "AutomatedTesting", "Materials", NEW_MATERIAL)
+ target_path = os.path.join(azlmbr.paths.projectroot, "Materials", NEW_MATERIAL)
print(f"Test asset doesn't exist initially: {not os.path.exists(target_path)}")
# 2) Test Case: Creating a New Material Using Existing One
@@ -109,10 +109,10 @@ def run():
# Assign new color to the material file and save the document as copy
expected_color_1 = math.Color(0.5, 0.5, 0.5, 1.0)
material_editor.set_property(document_id, property_name, expected_color_1)
- target_path_1 = os.path.join(azlmbr.paths.devroot, "AutomatedTesting", "Materials", NEW_MATERIAL_1)
+ target_path_1 = os.path.join(azlmbr.paths.projectroot, "Materials", NEW_MATERIAL_1)
cache_file_name_1 = os.path.splitext(NEW_MATERIAL_1) # Example output: ('test_material_1', '.material')
cache_file_1 = f"{cache_file_name_1[0]}{CACHE_FILE_EXTENSION}"
- target_path_1_cache = os.path.join(azlmbr.paths.devassets, "Cache", "pc", "materials", cache_file_1)
+ target_path_1_cache = os.path.join(azlmbr.paths.products, "materials", cache_file_1)
material_editor.save_document_as_copy(document_id, target_path_1)
material_editor.wait_for_condition(lambda: os.path.exists(target_path_1_cache), 4.0)
@@ -120,10 +120,10 @@ def run():
# Assign new color to the material file save the document as child
expected_color_2 = math.Color(0.75, 0.75, 0.75, 1.0)
material_editor.set_property(document_id, property_name, expected_color_2)
- target_path_2 = os.path.join(azlmbr.paths.devroot, "AutomatedTesting", "Materials", NEW_MATERIAL_2)
+ target_path_2 = os.path.join(azlmbr.paths.projectroot, "Materials", NEW_MATERIAL_2)
cache_file_name_2 = os.path.splitext(NEW_MATERIAL_1) # Example output: ('test_material_2', '.material')
cache_file_2 = f"{cache_file_name_2[0]}{CACHE_FILE_EXTENSION}"
- target_path_2_cache = os.path.join(azlmbr.paths.devassets, "Cache", "pc", "materials", cache_file_2)
+ target_path_2_cache = os.path.join(azlmbr.paths.products, "materials", cache_file_2)
material_editor.save_document_as_child(document_id, target_path_2)
material_editor.wait_for_condition(lambda: os.path.exists(target_path_2_cache), 4.0)
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_GPUTest_AtomFeatureIntegrationBenchmark.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_GPUTest_AtomFeatureIntegrationBenchmark.py
index 4f7edeba75..fbd9f3459a 100644
--- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_GPUTest_AtomFeatureIntegrationBenchmark.py
+++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_GPUTest_AtomFeatureIntegrationBenchmark.py
@@ -10,7 +10,7 @@ import sys
import azlmbr.legacy.general as general
-sys.path.append(os.path.join(azlmbr.paths.devroot, "AutomatedTesting", "Gem", "PythonTests"))
+sys.path.append(os.path.join(azlmbr.paths.projectroot, "Gem", "PythonTests"))
import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.editor_test_helper import EditorTestHelper
@@ -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 62a122a723..93e78a7c0a 100644
--- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_GPUTest_BasicLevelSetup.py
+++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_GPUTest_BasicLevelSetup.py
@@ -17,7 +17,7 @@ import azlmbr.math as math
import azlmbr.paths
import azlmbr.editor as editor
-sys.path.append(os.path.join(azlmbr.paths.devroot, "AutomatedTesting", "Gem", "PythonTests"))
+sys.path.append(os.path.join(azlmbr.paths.projectroot, "Gem", "PythonTests"))
import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.editor_test_helper import EditorTestHelper
@@ -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/Atom/tests/hydra_GPUTest_LightComponent.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_GPUTest_LightComponent.py
index 4a3ae8c85d..1c3e6226c1 100644
--- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_GPUTest_LightComponent.py
+++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_GPUTest_LightComponent.py
@@ -14,7 +14,7 @@ import azlmbr.math as math
import azlmbr.paths
import azlmbr.legacy.general as general
-sys.path.append(os.path.join(azlmbr.paths.devroot, "AutomatedTesting", "Gem", "PythonTests"))
+sys.path.append(os.path.join(azlmbr.paths.projectroot, "Gem", "PythonTests"))
import editor_python_test_tools.hydra_editor_utils as hydra
from Atom.atom_utils import atom_component_helper, atom_constants, screenshot_utils
diff --git a/AutomatedTesting/Gem/PythonTests/EditorPythonBindings/EditorCommandLine_test.py b/AutomatedTesting/Gem/PythonTests/EditorPythonBindings/EditorCommandLine_test.py
index 1d3ca11618..fcce6eab37 100755
--- a/AutomatedTesting/Gem/PythonTests/EditorPythonBindings/EditorCommandLine_test.py
+++ b/AutomatedTesting/Gem/PythonTests/EditorPythonBindings/EditorCommandLine_test.py
@@ -42,7 +42,6 @@ class TestEditorAutomation(object):
"editor command line arg bar",
"editor command line arg baz",
"editor engroot set",
- "editor devroot set",
"path resolved worked"
]
diff --git a/AutomatedTesting/Gem/PythonTests/EditorPythonBindings/EditorCommandLine_test_case.py b/AutomatedTesting/Gem/PythonTests/EditorPythonBindings/EditorCommandLine_test_case.py
index bd8791fad6..c6ae65612f 100755
--- a/AutomatedTesting/Gem/PythonTests/EditorPythonBindings/EditorCommandLine_test_case.py
+++ b/AutomatedTesting/Gem/PythonTests/EditorPythonBindings/EditorCommandLine_test_case.py
@@ -20,12 +20,6 @@ if (engroot is not None and len(engroot) is not 0):
print ('engroot is {}'.format(engroot))
print ('editor engroot set')
-# make sure the @devroot@ exists as a azlmbr.paths property
-devroot = azlmbr.paths.devroot
-if (devroot is not None and len(devroot) != 0):
- print ('devroot is {}'.format(devroot))
- print ('editor devroot set')
-
# resolving a basic path
path = azlmbr.paths.resolve_path('@engroot@/engineassets/texturemsg/defaultsolids.mtl')
if (len(path) != 0 and path.find('@engroot@') == -1):
diff --git a/AutomatedTesting/Gem/PythonTests/EditorPythonBindings/EditorScripts/ComponentUpdateListProperty_test_case.py b/AutomatedTesting/Gem/PythonTests/EditorPythonBindings/EditorScripts/ComponentUpdateListProperty_test_case.py
index 5b7f2f42c1..c5ca4de603 100644
--- a/AutomatedTesting/Gem/PythonTests/EditorPythonBindings/EditorScripts/ComponentUpdateListProperty_test_case.py
+++ b/AutomatedTesting/Gem/PythonTests/EditorPythonBindings/EditorScripts/ComponentUpdateListProperty_test_case.py
@@ -16,7 +16,7 @@ import azlmbr.entity as entity
import azlmbr.math as math
import azlmbr.paths
-sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
+sys.path.append(os.path.join(azlmbr.paths.projectroot, 'Gem', 'PythonTests'))
from automatedtesting_shared.editor_test_helper import EditorTestHelper
diff --git a/AutomatedTesting/Gem/PythonTests/EditorPythonBindings/LevelComponentCommands.cfg b/AutomatedTesting/Gem/PythonTests/EditorPythonBindings/LevelComponentCommands.cfg
index 3adc32d20a..ccc605cec9 100644
--- a/AutomatedTesting/Gem/PythonTests/EditorPythonBindings/LevelComponentCommands.cfg
+++ b/AutomatedTesting/Gem/PythonTests/EditorPythonBindings/LevelComponentCommands.cfg
@@ -1,2 +1,2 @@
# this file is copied to $/dev/editor_autoexec.cfg so the the Editor automation runs for this Hydra test
-pyRunFile @devroot@/Tests/hydra/LevelComponentCommands_test_case.py exit_when_done
\ No newline at end of file
+pyRunFile @engroot@/Tests/hydra/LevelComponentCommands_test_case.py exit_when_done
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/PythonTests/EditorPythonBindings/ViewportTitleDlgCommands.cfg b/AutomatedTesting/Gem/PythonTests/EditorPythonBindings/ViewportTitleDlgCommands.cfg
index 6230dfe0fa..3cbd84c1b5 100644
--- a/AutomatedTesting/Gem/PythonTests/EditorPythonBindings/ViewportTitleDlgCommands.cfg
+++ b/AutomatedTesting/Gem/PythonTests/EditorPythonBindings/ViewportTitleDlgCommands.cfg
@@ -1,2 +1,2 @@
# this file is copied to $/dev/editor_autoexec.cfg so the the Editor automation runs for this Hydra test
-pyRunFile @devroot@/Tests/hydra/ViewportTitleDlgCommands_test_case.py
\ No newline at end of file
+pyRunFile @engroot@/Tests/hydra/ViewportTitleDlgCommands_test_case.py
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py
index 154b5730d7..783f71e06c 100644
--- a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py
+++ b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py
@@ -361,3 +361,19 @@ class EditorEntity:
:return: True if "isVisible" is enabled, False otherwise.
"""
return editor.EditorEntityInfoRequestBus(bus.Event, "IsVisible", self.id)
+
+ def set_local_uniform_scale(self, scale_float) -> None:
+ """
+ Sets the "SetLocalUniformScale" value on the entity.
+ :param scale_float: value for "SetLocalUniformScale" to set to.
+ :return: None
+ """
+ azlmbr.components.TransformBus(azlmbr.bus.Event, "SetLocalUniformScale", self.id, scale_float)
+
+ def set_local_rotation(self, vector3_rotation) -> None:
+ """
+ Sets the "SetLocalRotation" value on the entity.
+ :param vector3_rotation: The math.Vector3 value to use for rotation on the entity (uses radians).
+ :return: None
+ """
+ azlmbr.components.TransformBus(azlmbr.bus.Event, "SetLocalRotation", self.id, vector3_rotation)
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 cc217f81da..1b094b1cfa 100644
--- a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/utils.py
+++ b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/utils.py
@@ -4,18 +4,18 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
+
+import json
+import math
import os
import time
-import math
+import traceback
+from typing import Callable, Tuple
import azlmbr
import azlmbr.legacy.general as general
import azlmbr.debug
-import json
-import traceback
-
-from typing import Callable, Tuple
class FailFast(Exception):
"""
@@ -127,6 +127,30 @@ class TestHelper:
if ret:
return True
+ @staticmethod
+ def close_error_windows():
+ """
+ Closes Error Report and Error Log windows that block focus if they are visible.
+ :return: None
+ """
+ if general.is_pane_visible("Error Report"):
+ general.close_pane("Error Report")
+ if general.is_pane_visible("Error Log"):
+ general.close_pane("Error Log")
+
+ @staticmethod
+ def close_display_helpers():
+ """
+ Closes helper gizmos, anti-aliasing, and FPS meters.
+ :return: None
+ """
+ if general.is_helpers_shown():
+ general.toggle_helpers()
+ general.idle_wait(1.0)
+ general.idle_wait(1.0)
+ general.run_console("r_displayInfo=0")
+ general.idle_wait(1.0)
+
class Timeout:
# type: (float) -> None
@@ -149,6 +173,7 @@ class Timeout:
def timed_out(self):
return time.time() > self.die_after
+
class Report:
_results = []
_exception = None
@@ -290,8 +315,8 @@ class Report:
Report.info(" x: {:.2f}, y: {:.2f}, z: {:.2f}".format(vector3.x, vector3.y, vector3.z))
if magnitude is not None:
Report.info(" magnitude: {:.2f}".format(magnitude))
-
-
+
+
'''
Utility for scope tracing errors and warnings.
Usage:
@@ -303,7 +328,7 @@ Usage:
Report.result(Tests.warnings_not_found_in_section, not section_tracer.has_warnings)
-'''
+'''
class Tracer:
def __init__(self):
self.warnings = []
@@ -349,10 +374,10 @@ class Tracer:
self.line = args[1]
self.function = args[2]
self.message = args[3]
-
+
def __str__(self):
return f"Assert: [{self.filename}:{self.function}:{self.line}]: {self.message}"
-
+
def __repr__(self):
return f"[Assert: {self.message}]"
@@ -360,21 +385,21 @@ class Tracer:
def __init__(self, args):
self.window = args[0]
self.message = args[1]
-
+
def _on_warning(self, args):
warningInfo = Tracer.WarningInfo(args)
self.warnings.append(warningInfo)
Report.info("Tracer caught Warning: %s" % warningInfo.message)
self.has_warnings = True
return False
-
+
def _on_error(self, args):
errorInfo = Tracer.ErrorInfo(args)
self.errors.append(errorInfo)
Report.info("Tracer caught Error: %s" % errorInfo.message)
self.has_errors = True
return False
-
+
def _on_assert(self, args):
assertInfo = Tracer.AssertInfo(args)
self.asserts.append(assertInfo)
@@ -436,6 +461,7 @@ class AngleHelper:
def vector3_str(vector3):
return "(x: {:.2f}, y: {:.2f}, z: {:.2f})".format(vector3.x, vector3.y, vector3.z)
-
+
+
def aabb_str(aabb):
return "[Min: %s, Max: %s]" % (vector3_str(aabb.min), vector3_str(aabb.max))
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
-
- # 5) Check to see if lead and follower behaved as expected
- Report.critical_result(Tests.check_collision_happened, lead.collided and follower.collided)
+ # 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))
- # 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/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_Embedded_E2E.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_Embedded_E2E.py
index e51be58ec6..84c661873c 100755
--- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_Embedded_E2E.py
+++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_Embedded_E2E.py
@@ -109,7 +109,7 @@ def DynamicSliceInstanceSpawner_Embedded_E2E():
# 6) Save and export to engine
general.save_level()
general.export_to_engine()
- pak_path = os.path.join(paths.devroot, "AutomatedTesting", "cache", "pc", "levels", lvl_name, "level.pak")
+ pak_path = os.path.join(paths.products, "levels", lvl_name, "level.pak")
Report.result(Tests.saved_and_exported, os.path.exists(pak_path))
diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_External_E2E.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_External_E2E.py
index 7a0abdd969..de2554034f 100755
--- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_External_E2E.py
+++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_External_E2E.py
@@ -131,7 +131,7 @@ def DynamicSliceInstanceSpawner_External_E2E():
# 6) Save and export to engine
general.save_level()
general.export_to_engine()
- pak_path = os.path.join(paths.devroot, "AutomatedTesting", "cache", "pc", "levels", lvl_name, "level.pak")
+ pak_path = os.path.join(paths.products, "levels", lvl_name, "level.pak")
Report.result(Tests.saved_and_exported, os.path.exists(pak_path))
diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerBlender_E2E_Editor.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerBlender_E2E_Editor.py
index f56c0b836e..bf6501f469 100755
--- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerBlender_E2E_Editor.py
+++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerBlender_E2E_Editor.py
@@ -155,7 +155,7 @@ def LayerBlender_E2E_Editor():
# 6) Save and export to engine
general.save_level()
general.export_to_engine()
- pak_path = os.path.join(paths.devroot, "AutomatedTesting", "cache", "pc", "levels", lvl_name, "level.pak")
+ pak_path = os.path.join(paths.products, "levels", lvl_name, "level.pak")
Report.result(Tests.saved_and_exported, os.path.exists(pak_path))
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/Gem/PythonTests/largeworlds/large_worlds_utils/editor_dynveg_test_helper.py b/AutomatedTesting/Gem/PythonTests/largeworlds/large_worlds_utils/editor_dynveg_test_helper.py
index 65ebf8e59e..957536fffb 100755
--- a/AutomatedTesting/Gem/PythonTests/largeworlds/large_worlds_utils/editor_dynveg_test_helper.py
+++ b/AutomatedTesting/Gem/PythonTests/largeworlds/large_worlds_utils/editor_dynveg_test_helper.py
@@ -17,7 +17,7 @@ import azlmbr.vegetation as vegetation
import azlmbr.areasystem as areasystem
import azlmbr.paths
-sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
+sys.path.append(os.path.join(azlmbr.paths.projectroot, 'Gem', 'PythonTests'))
import editor_python_test_tools.hydra_editor_utils as hydra
@@ -25,7 +25,7 @@ def create_surface_entity(name, center_point, box_size_x, box_size_y, box_size_z
# Create a "flat surface" entity to use as a plantable vegetation surface
surface_entity = hydra.Entity(name)
surface_entity.create_entity(
- center_point,
+ center_point,
["Box Shape", "Shape Surface Tag Emitter"]
)
if surface_entity.id.IsValid():
@@ -56,7 +56,7 @@ def create_vegetation_area(name, center_point, box_size_x, box_size_y, box_size_
# Create a vegetation area entity to use as our test vegetation spawner
spawner_entity = hydra.Entity(name)
spawner_entity.create_entity(
- center_point,
+ center_point,
["Vegetation Layer Spawner", "Box Shape", "Vegetation Asset List"]
)
if spawner_entity.id.IsValid():
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/Material_DefaultLibraryConsistentOnAllFeatures/cowboy.emfxworkspace b/AutomatedTesting/Levels/Physics/Material_DefaultLibraryConsistentOnAllFeatures/cowboy.emfxworkspace
index 188fee9f05..05140f340b 100644
--- a/AutomatedTesting/Levels/Physics/Material_DefaultLibraryConsistentOnAllFeatures/cowboy.emfxworkspace
+++ b/AutomatedTesting/Levels/Physics/Material_DefaultLibraryConsistentOnAllFeatures/cowboy.emfxworkspace
@@ -1,3 +1,3 @@
[General]
version=1
-startScript="ImportActor -filename \"@assets@/characters/cowboy/actor/cowboy_01.actor\"\nCreateActorInstance -actorID %LASTRESULT% -xPos 0.000000 -yPos 0.000000 -zPos 0.000000 -xScale 1.000000 -yScale 1.000000 -zScale 1.000000 -rot 0.00000000,0.00000000,0.00000000,1.00000000\n"
+startScript="ImportActor -filename \"@products@/characters/cowboy/actor/cowboy_01.actor\"\nCreateActorInstance -actorID %LASTRESULT% -xPos 0.000000 -yPos 0.000000 -zPos 0.000000 -xScale 1.000000 -yScale 1.000000 -zScale 1.000000 -rot 0.00000000,0.00000000,0.00000000,1.00000000\n"
diff --git a/AutomatedTesting/Levels/Physics/Material_DefaultMaterialLibraryChangesWork/ws.emfxworkspace b/AutomatedTesting/Levels/Physics/Material_DefaultMaterialLibraryChangesWork/ws.emfxworkspace
index e429d74a57..870b9a8579 100644
--- a/AutomatedTesting/Levels/Physics/Material_DefaultMaterialLibraryChangesWork/ws.emfxworkspace
+++ b/AutomatedTesting/Levels/Physics/Material_DefaultMaterialLibraryChangesWork/ws.emfxworkspace
@@ -1,3 +1,3 @@
[General]
version=1
-startScript="ImportActor -filename \"@assets@/levels/physics/c15096734_physxmaterials_defaultmateriallibrary/rin_skeleton_newgeo.actor\"\nCreateActorInstance -actorID %LASTRESULT% -xPos 0.000000 -yPos 0.000000 -zPos 0.000000 -xScale 1.000000 -yScale 1.000000 -zScale 1.000000 -rot 0.00000000,0.00000000,0.00000000,1.00000000\nLoadMotionSet -filename \"@assets@/Levels/Physics/C15096734_PhysxMaterials_DefaultMaterialLibrary/custom_motionset.motionset\"\nLoadAnimGraph -filename \"@assets@/Levels/Physics/C15096734_PhysxMaterials_DefaultMaterialLibrary/rin_physics.animgraph\"\n"
+startScript="ImportActor -filename \"@products@/levels/physics/c15096734_physxmaterials_defaultmateriallibrary/rin_skeleton_newgeo.actor\"\nCreateActorInstance -actorID %LASTRESULT% -xPos 0.000000 -yPos 0.000000 -zPos 0.000000 -xScale 1.000000 -yScale 1.000000 -zScale 1.000000 -rot 0.00000000,0.00000000,0.00000000,1.00000000\nLoadMotionSet -filename \"@products@/levels/physics/c15096734_physxmaterials_defaultmateriallibrary/custom_motionset.motionset\"\nLoadAnimGraph -filename \"@products@/levels/physics/c15096734_physxmaterials_defaultmateriallibrary/rin_physics.animgraph\"\n"
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/Registry/physx_overrides/Collider_AddingNewGroupWorks.setreg_override b/AutomatedTesting/Registry/physx_overrides/Collider_AddingNewGroupWorks.setreg_override
index 7065f0dfeb..209e9a9feb 100644
--- a/AutomatedTesting/Registry/physx_overrides/Collider_AddingNewGroupWorks.setreg_override
+++ b/AutomatedTesting/Registry/physx_overrides/Collider_AddingNewGroupWorks.setreg_override
@@ -109,7 +109,7 @@
},
"MaterialLibrary": {
"assetId": {
- "guid": "{62446378-67F8-5E49-AC31-761DD5942695}"
+ "guid": "{7CDF49C3-91A2-5C4E-B642-6D1AEC80E70E}"
},
"loadBehavior": "QueueLoad",
"assetHint": "assets/physics/surfacetypemateriallibrary.physmaterial"
diff --git a/AutomatedTesting/Registry/physx_overrides/Collider_CollisionGroupsWorkflow.setreg_override b/AutomatedTesting/Registry/physx_overrides/Collider_CollisionGroupsWorkflow.setreg_override
index b82acaf0ae..65f15f8554 100644
--- a/AutomatedTesting/Registry/physx_overrides/Collider_CollisionGroupsWorkflow.setreg_override
+++ b/AutomatedTesting/Registry/physx_overrides/Collider_CollisionGroupsWorkflow.setreg_override
@@ -121,7 +121,7 @@
},
"MaterialLibrary": {
"assetId": {
- "guid": "{62446378-67F8-5E49-AC31-761DD5942695}"
+ "guid": "{7CDF49C3-91A2-5C4E-B642-6D1AEC80E70E}"
},
"loadBehavior": "QueueLoad",
"assetHint": "assets/physics/surfacetypemateriallibrary.physmaterial"
diff --git a/AutomatedTesting/Registry/physx_overrides/Collider_DiffCollisionGroupDiffCollidingLayersNotCollide.setreg_override b/AutomatedTesting/Registry/physx_overrides/Collider_DiffCollisionGroupDiffCollidingLayersNotCollide.setreg_override
index b82acaf0ae..65f15f8554 100644
--- a/AutomatedTesting/Registry/physx_overrides/Collider_DiffCollisionGroupDiffCollidingLayersNotCollide.setreg_override
+++ b/AutomatedTesting/Registry/physx_overrides/Collider_DiffCollisionGroupDiffCollidingLayersNotCollide.setreg_override
@@ -121,7 +121,7 @@
},
"MaterialLibrary": {
"assetId": {
- "guid": "{62446378-67F8-5E49-AC31-761DD5942695}"
+ "guid": "{7CDF49C3-91A2-5C4E-B642-6D1AEC80E70E}"
},
"loadBehavior": "QueueLoad",
"assetHint": "assets/physics/surfacetypemateriallibrary.physmaterial"
diff --git a/AutomatedTesting/Registry/physx_overrides/Collider_NoneCollisionGroupSameLayerNotCollide.setreg_override b/AutomatedTesting/Registry/physx_overrides/Collider_NoneCollisionGroupSameLayerNotCollide.setreg_override
index b82acaf0ae..65f15f8554 100644
--- a/AutomatedTesting/Registry/physx_overrides/Collider_NoneCollisionGroupSameLayerNotCollide.setreg_override
+++ b/AutomatedTesting/Registry/physx_overrides/Collider_NoneCollisionGroupSameLayerNotCollide.setreg_override
@@ -121,7 +121,7 @@
},
"MaterialLibrary": {
"assetId": {
- "guid": "{62446378-67F8-5E49-AC31-761DD5942695}"
+ "guid": "{7CDF49C3-91A2-5C4E-B642-6D1AEC80E70E}"
},
"loadBehavior": "QueueLoad",
"assetHint": "assets/physics/surfacetypemateriallibrary.physmaterial"
diff --git a/AutomatedTesting/Registry/physx_overrides/Collider_SameCollisionGroupSameCustomLayerCollide.setreg_override b/AutomatedTesting/Registry/physx_overrides/Collider_SameCollisionGroupSameCustomLayerCollide.setreg_override
index b82acaf0ae..65f15f8554 100644
--- a/AutomatedTesting/Registry/physx_overrides/Collider_SameCollisionGroupSameCustomLayerCollide.setreg_override
+++ b/AutomatedTesting/Registry/physx_overrides/Collider_SameCollisionGroupSameCustomLayerCollide.setreg_override
@@ -121,7 +121,7 @@
},
"MaterialLibrary": {
"assetId": {
- "guid": "{62446378-67F8-5E49-AC31-761DD5942695}"
+ "guid": "{7CDF49C3-91A2-5C4E-B642-6D1AEC80E70E}"
},
"loadBehavior": "QueueLoad",
"assetHint": "assets/physics/surfacetypemateriallibrary.physmaterial"
diff --git a/AutomatedTesting/Registry/physxsystemconfiguration.setreg b/AutomatedTesting/Registry/physxsystemconfiguration.setreg
index 83aad307a6..2ade83d769 100644
--- a/AutomatedTesting/Registry/physxsystemconfiguration.setreg
+++ b/AutomatedTesting/Registry/physxsystemconfiguration.setreg
@@ -103,7 +103,7 @@
},
"MaterialLibrary": {
"assetId": {
- "guid": "{62446378-67F8-5E49-AC31-761DD5942695}"
+ "guid": "{7CDF49C3-91A2-5C4E-B642-6D1AEC80E70E}"
},
"loadBehavior": "QueueLoad",
"assetHint": "assets/physics/surfacetypemateriallibrary.physmaterial"
diff --git a/AutomatedTesting/multiple_mesh_one_material/FBXTestTexture.png b/AutomatedTesting/multiple_mesh_one_material/FBXTestTexture.png
new file mode 100644
index 0000000000..4f52364cb3
--- /dev/null
+++ b/AutomatedTesting/multiple_mesh_one_material/FBXTestTexture.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:827a63985273229050bf4f63030bcc666f045091fe81cf8157a9ca23b40074b6
+size 3214
diff --git a/AutomatedTesting/multiple_mesh_one_material/multiple_mesh_one_material.fbx b/AutomatedTesting/multiple_mesh_one_material/multiple_mesh_one_material.fbx
new file mode 100644
index 0000000000..d9deb899f0
--- /dev/null
+++ b/AutomatedTesting/multiple_mesh_one_material/multiple_mesh_one_material.fbx
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d8d24963e6e8765205bc79cbe2304fc39f1245ee75249e2834a71c96c3cab824
+size 22700
diff --git a/AutomatedTesting/multiple_mesh_one_material/multiple_mesh_one_material.fbx.assetinfo b/AutomatedTesting/multiple_mesh_one_material/multiple_mesh_one_material.fbx.assetinfo
new file mode 100644
index 0000000000..fe18a16cb5
--- /dev/null
+++ b/AutomatedTesting/multiple_mesh_one_material/multiple_mesh_one_material.fbx.assetinfo
@@ -0,0 +1,8 @@
+{
+ "values": [
+ {
+ "$type": "ScriptProcessorRule",
+ "scriptFilename": "Editor/Scripts/scene_mesh_to_prefab.py"
+ }
+ ]
+}
\ No newline at end of file
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 5884795413..bdfac373eb 100644
--- a/Code/Editor/CMakeLists.txt
+++ b/Code/Editor/CMakeLists.txt
@@ -33,7 +33,6 @@ ly_add_target(
BUILD_DEPENDENCIES
PRIVATE
Legacy::CryCommon
- 3rdParty::zlib
PUBLIC
3rdParty::Qt::Core
3rdParty::Qt::Gui
@@ -103,9 +102,8 @@ ly_add_target(
3rdParty::Qt::Gui
3rdParty::Qt::Widgets
3rdParty::Qt::Concurrent
- 3rdParty::tiff
+ 3rdParty::TIFF
3rdParty::squish-ccr
- 3rdParty::zlib
3rdParty::AWSNativeSDK::STS
Legacy::CryCommon
Legacy::EditorCommon
diff --git a/Code/Editor/Controls/FolderTreeCtrl.cpp b/Code/Editor/Controls/FolderTreeCtrl.cpp
index b1cbb9414e..1464580ffc 100644
--- a/Code/Editor/Controls/FolderTreeCtrl.cpp
+++ b/Code/Editor/Controls/FolderTreeCtrl.cpp
@@ -278,17 +278,16 @@ void CFolderTreeCtrl::LoadTreeRec(const QString& currentFolder)
void CFolderTreeCtrl::AddItem(const QString& path)
{
- QString folder;
- QString fileNameWithoutExtension;
- QString ext;
-
- Path::Split(path, folder, fileNameWithoutExtension, ext);
+ AZ::IO::FixedMaxPath folder{ AZ::IO::PathView(path.toUtf8().constData()) };
+ AZ::IO::FixedMaxPath fileNameWithoutExtension = folder.Stem();
+ folder = folder.ParentPath();
auto regex = QRegExp(m_fileNameSpec, Qt::CaseInsensitive, QRegExp::Wildcard);
if (regex.exactMatch(path))
{
- CTreeItem* folderTreeItem = CreateFolderItems(folder);
- folderTreeItem->AddChild(fileNameWithoutExtension, path, eTreeImage_File);
+ CTreeItem* folderTreeItem = CreateFolderItems(QString::fromUtf8(folder.c_str(), static_cast(folder.Native().size())));
+ folderTreeItem->AddChild(QString::fromUtf8(fileNameWithoutExtension.c_str(),
+ static_cast(fileNameWithoutExtension.Native().size())), path, eTreeImage_File);
}
}
diff --git a/Code/Editor/Core/LevelEditorMenuHandler.cpp b/Code/Editor/Core/LevelEditorMenuHandler.cpp
index e568f05167..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()
@@ -487,8 +487,6 @@ void LevelEditorMenuHandler::PopulateEditMenu(ActionManager::MenuWrapper& editMe
editMenu.AddAction(AzToolsFramework::EditPivot);
editMenu.AddAction(AzToolsFramework::EditReset);
editMenu.AddAction(AzToolsFramework::EditResetManipulator);
- editMenu.AddAction(AzToolsFramework::EditResetLocal);
- editMenu.AddAction(AzToolsFramework::EditResetWorld);
// Hide Selection
editMenu.AddAction(AzToolsFramework::HideSelection);
@@ -1186,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);
}
@@ -1239,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/Core/QtEditorApplication_linux.cpp b/Code/Editor/Core/QtEditorApplication_linux.cpp
index 2fd4ef629e..5491134170 100644
--- a/Code/Editor/Core/QtEditorApplication_linux.cpp
+++ b/Code/Editor/Core/QtEditorApplication_linux.cpp
@@ -19,10 +19,16 @@ namespace Editor
if (GetIEditor()->IsInGameMode())
{
#ifdef PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB
- AzFramework::XcbEventHandlerBus::Broadcast(&AzFramework::XcbEventHandler::HandleXcbEvent, static_cast(message));
+ // We need to handle RAW Input events in a separate loop. This is a workaround to enable XInput2 RAW Inputs using Editor mode.
+ // TODO To have this call here might be not be perfect.
+ AzFramework::XcbEventHandlerBus::Broadcast(&AzFramework::XcbEventHandler::PollSpecialEvents);
+
+ // Now handle the rest of the events.
+ AzFramework::XcbEventHandlerBus::Broadcast(
+ &AzFramework::XcbEventHandler::HandleXcbEvent, static_cast(message));
#endif
return true;
}
return false;
}
-}
+} // namespace Editor
diff --git a/Code/Editor/Core/Tests/test_Main.cpp b/Code/Editor/Core/Tests/test_Main.cpp
index 3d3e286f18..16b0aa92cf 100644
--- a/Code/Editor/Core/Tests/test_Main.cpp
+++ b/Code/Editor/Core/Tests/test_Main.cpp
@@ -33,6 +33,7 @@ public:
protected:
void SetupEnvironment() override
{
+ AttachEditorCoreAZEnvironment(AZ::Environment::GetInstance());
m_allocatorScope.ActivateAllocators();
m_cryPak = new NiceMock();
@@ -49,6 +50,7 @@ protected:
{
delete m_cryPak;
m_allocatorScope.DeactivateAllocators();
+ DetachEditorCoreAZEnvironment();
}
private:
diff --git a/Code/Editor/Core/Tests/test_PathUtil.cpp b/Code/Editor/Core/Tests/test_PathUtil.cpp
index 83e50a5947..cade19eb81 100644
--- a/Code/Editor/Core/Tests/test_PathUtil.cpp
+++ b/Code/Editor/Core/Tests/test_PathUtil.cpp
@@ -5,22 +5,29 @@
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
-#include "EditorDefs.h"
-#include
-#include "Util/PathUtil.h"
-#include
-
-TEST(PathUtil, GamePathToFullPath_DoesNotBufferOverflow)
+#include
+#include
+namespace UnitTest
{
- // There are no test assertions in this test because the purpose is just to verify that the test runs without crashing
- QString pngExtension(".png");
+ class PathUtil
+ : public ScopedAllocatorSetupFixture
+ {
+ };
+
+ TEST_F(PathUtil, GamePathToFullPath_DoesNotBufferOverflow)
+ {
+ // There are no test assertions in this test because the purpose is just to verify that the test runs without crashing
+ QString pngExtension(".png");
- // Create a string of lenth AZ_MAX_PATH_LEN that ends in .png
- QString longStringMaxPath(AZ_MAX_PATH_LEN, 'x');
- longStringMaxPath.replace(longStringMaxPath.length() - pngExtension.length(), longStringMaxPath.length(), pngExtension);
- Path::GamePathToFullPath(longStringMaxPath);
+ // Create a string of length AZ_MAX_PATH_LEN that ends in .png
+ QString longStringMaxPath(AZ_MAX_PATH_LEN, 'x');
+ longStringMaxPath.replace(longStringMaxPath.length() - pngExtension.length(), longStringMaxPath.length(), pngExtension);
+ AZ_TEST_START_TRACE_SUPPRESSION;
+ Path::GamePathToFullPath(longStringMaxPath);
+ AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT;
- QString longStringMaxPathPlusOne(AZ_MAX_PATH_LEN + 1, 'x');
- longStringMaxPathPlusOne.replace(longStringMaxPathPlusOne.length() - pngExtension.length(), longStringMaxPathPlusOne.length(), pngExtension);
- Path::GamePathToFullPath(longStringMaxPathPlusOne);
+ QString longStringMaxPathPlusOne(AZ_MAX_PATH_LEN + 1, 'x');
+ longStringMaxPathPlusOne.replace(longStringMaxPathPlusOne.length() - pngExtension.length(), longStringMaxPathPlusOne.length(), pngExtension);
+ Path::GamePathToFullPath(longStringMaxPathPlusOne);
+ }
}
diff --git a/Code/Editor/CryEdit.cpp b/Code/Editor/CryEdit.cpp
index b5eb4229df..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
@@ -2124,6 +2125,8 @@ bool CCryEditApp::FixDanglingSharedMemory(const QString& sharedMemName) const
int CCryEditApp::ExitInstance(int exitCode)
{
+ AZ_TracePrintf("Exit", "Called ExitInstance() with exit code: 0x%x", exitCode);
+
if (m_pEditor)
{
m_pEditor->OnBeginShutdownSequence();
@@ -2642,7 +2645,7 @@ void CCryEditApp::OnFileResaveSlices()
sliceAssetInfos.reserve(5000);
AZ::Data::AssetCatalogRequests::AssetEnumerationCB sliceCountCb = [&sliceAssetInfos]([[maybe_unused]] const AZ::Data::AssetId id, const AZ::Data::AssetInfo& info)
{
- // Only add slices and nothing that has been temporarily added to the catalog with a macro in it (ie @devroot@)
+ // Only add slices and nothing that has been temporarily added to the catalog with a macro in it (ie @engroot@)
if (info.m_assetType == azrtti_typeid() && info.m_relativePath[0] != '@')
{
sliceAssetInfos.push_back(info);
@@ -3019,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 07d946c609..4944c3bff5 100644
--- a/Code/Editor/CryEditDoc.cpp
+++ b/Code/Editor/CryEditDoc.cpp
@@ -1108,7 +1108,7 @@ bool CCryEditDoc::SaveLevel(const QString& filename)
if (QFileInfo(filename).isRelative())
{
// Resolving the path through resolvepath would normalize and lowcase it, and in this case, we don't want that.
- fullPathName = Path::ToUnixPath(QDir(QString::fromUtf8(gEnv->pFileIO->GetAlias("@devassets@"))).absoluteFilePath(fullPathName));
+ fullPathName = Path::ToUnixPath(QDir(QString::fromUtf8(gEnv->pFileIO->GetAlias("@projectroot@"))).absoluteFilePath(fullPathName));
}
if (!CFileUtil::OverwriteFile(fullPathName))
@@ -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"))
@@ -2159,7 +2159,7 @@ bool CCryEditDoc::LoadXmlArchiveArray(TDocMultiArchive& arrXmlAr, const QString&
xmlAr.bLoading = true;
// bound to the level folder, as if it were the assets folder.
- // this mounts (whateverlevelname.ly) as @assets@/Levels/whateverlevelname/ and thus it works...
+ // this mounts (whateverlevelname.ly) as @products@/Levels/whateverlevelname/ and thus it works...
bool openLevelPakFileSuccess = pIPak->OpenPack(levelPath.toUtf8().data(), absoluteLevelPath.toUtf8().data());
if (!openLevelPakFileSuccess)
{
diff --git a/Code/Editor/Dialogs/PythonScriptsDialog.cpp b/Code/Editor/Dialogs/PythonScriptsDialog.cpp
index e95fb90c0a..35047947ac 100644
--- a/Code/Editor/Dialogs/PythonScriptsDialog.cpp
+++ b/Code/Editor/Dialogs/PythonScriptsDialog.cpp
@@ -91,7 +91,7 @@ CPythonScriptsDialog::CPythonScriptsDialog(QWidget* parent)
{
AZ::IO::Path newSourcePath = jsonSourcePathPointer;
// Resolve any file aliases first - Do not use ResolvePath() as that assumes
- // any relative path is underneath the @assets@ alias
+ // any relative path is underneath the @products@ alias
if (auto fileIoBase = AZ::IO::FileIOBase::GetInstance(); fileIoBase != nullptr)
{
AZ::IO::FixedMaxPath replacedAliasPath;
diff --git a/Code/Editor/EditorFileMonitor.cpp b/Code/Editor/EditorFileMonitor.cpp
index 7feb9d32a8..311c42befa 100644
--- a/Code/Editor/EditorFileMonitor.cpp
+++ b/Code/Editor/EditorFileMonitor.cpp
@@ -14,6 +14,8 @@
// Editor
#include "CryEdit.h"
+#include
+
//////////////////////////////////////////////////////////////////////////
CEditorFileMonitor::CEditorFileMonitor()
{
@@ -177,26 +179,14 @@ void CEditorFileMonitor::OnFileMonitorChange(const SFileChangeInfo& rChange)
// Make file relative to PrimaryCD folder.
QString filename = rChange.filename;
- // Remove game directory if present in path.
- const QString rootPath =
- QDir::fromNativeSeparators(QString::fromLatin1(Path::GetEditingRootFolder().c_str()));
- if (filename.startsWith(rootPath, Qt::CaseInsensitive))
- {
- filename = filename.right(filename.length() - rootPath.length());
- }
-
- // Make sure there is no leading slash
- if (!filename.isEmpty() && (filename[0] == '\\' || filename[0] == '/'))
- {
- filename = filename.mid(1);
- }
+ // Make path relative to the the project directory
+ AZ::IO::Path projectPath{ AZ::Utils::GetProjectPath() };
+ AZ::IO::FixedMaxPath projectRelativeFilePath = AZ::IO::PathView(filename.toUtf8().constData()).LexicallyProximate(
+ projectPath);
- if (!filename.isEmpty())
+ if (!projectRelativeFilePath.empty())
{
- //remove game name. Make it relative to the game folder
- const QString filenameRelGame = RemoveGameName(filename);
- const int extIndex = filename.lastIndexOf('.');
- const QString ext = filename.right(filename.length() - 1 - extIndex);
+ AZ::IO::PathView ext = projectRelativeFilePath.Extension();
// Check for File Monitor callback
std::vector::iterator iter;
@@ -207,15 +197,11 @@ void CEditorFileMonitor::OnFileMonitorChange(const SFileChangeInfo& rChange)
// We compare against length of callback string, so we get directory matches as well as full filenames
if (sCallback.pListener)
{
- if (sCallback.extension == "*" || ext.compare(sCallback.extension, Qt::CaseInsensitive) == 0)
+ if (sCallback.extension == "*" || AZ::IO::PathView(sCallback.extension.toUtf8().constData()) == ext)
{
- if (filenameRelGame.compare(sCallback.item, Qt::CaseInsensitive) == 0)
- {
- sCallback.pListener->OnFileChange(qPrintable(filenameRelGame), IFileChangeListener::EChangeType(rChange.changeType));
- }
- else if (filename.compare(sCallback.item, Qt::CaseInsensitive) == 0)
+ if (AZ::IO::PathView(sCallback.item.toUtf8().constData()) == projectRelativeFilePath)
{
- sCallback.pListener->OnFileChange(qPrintable(filename), IFileChangeListener::EChangeType(rChange.changeType));
+ sCallback.pListener->OnFileChange(qPrintable(projectRelativeFilePath.c_str()), IFileChangeListener::EChangeType(rChange.changeType));
}
}
}
diff --git a/Code/Editor/EditorModularViewportCameraComposer.cpp b/Code/Editor/EditorModularViewportCameraComposer.cpp
index 29cf348ab5..ce4a0a2e33 100644
--- a/Code/Editor/EditorModularViewportCameraComposer.cpp
+++ b/Code/Editor/EditorModularViewportCameraComposer.cpp
@@ -95,7 +95,8 @@ namespace SandboxEditor
cameras.AddCamera(m_firstPersonPanCamera);
cameras.AddCamera(m_firstPersonTranslateCamera);
cameras.AddCamera(m_firstPersonScrollCamera);
- cameras.AddCamera(m_pivotCamera);
+ cameras.AddCamera(m_firstPersonFocusCamera);
+ cameras.AddCamera(m_orbitCamera);
});
return controller;
@@ -111,6 +112,7 @@ namespace SandboxEditor
viewportId, &AzToolsFramework::ViewportInteraction::ViewportMouseCursorRequestBus::Events::BeginCursorCapture);
}
};
+
const auto showCursor = [viewportId = m_viewportId]
{
if (SandboxEditor::CameraCaptureCursorForLook())
@@ -133,7 +135,7 @@ namespace SandboxEditor
m_firstPersonRotateCamera->SetActivationEndedFn(showCursor);
m_firstPersonPanCamera = AZStd::make_shared(
- SandboxEditor::CameraFreePanChannelId(), AzFramework::LookPan, AzFramework::TranslatePivot);
+ SandboxEditor::CameraFreePanChannelId(), AzFramework::LookPan, AzFramework::TranslatePivotLook);
m_firstPersonPanCamera->m_panSpeedFn = []
{
@@ -153,7 +155,7 @@ namespace SandboxEditor
const auto translateCameraInputChannelIds = BuildTranslateCameraInputChannelIds();
m_firstPersonTranslateCamera = AZStd::make_shared(
- translateCameraInputChannelIds, AzFramework::LookTranslation, AzFramework::TranslatePivot);
+ translateCameraInputChannelIds, AzFramework::LookTranslation, AzFramework::TranslatePivotLook);
m_firstPersonTranslateCamera->m_translateSpeedFn = []
{
@@ -165,90 +167,111 @@ namespace SandboxEditor
return SandboxEditor::CameraBoostMultiplier();
};
- m_firstPersonScrollCamera = AZStd::make_shared();
+ m_firstPersonScrollCamera = AZStd::make_shared();
m_firstPersonScrollCamera->m_scrollSpeedFn = []
{
return SandboxEditor::CameraScrollSpeed();
};
- m_pivotCamera = AZStd::make_shared(SandboxEditor::CameraPivotChannelId());
+ const auto pivotFn = []
+ {
+ // use the manipulator transform as the pivot point
+ AZStd::optional entityPivot;
+ AzToolsFramework::EditorTransformComponentSelectionRequestBus::EventResult(
+ entityPivot, AzToolsFramework::GetEntityContextId(),
+ &AzToolsFramework::EditorTransformComponentSelectionRequestBus::Events::GetManipulatorTransform);
- m_pivotCamera->SetPivotFn(
- []([[maybe_unused]] const AZ::Vector3& position, [[maybe_unused]] const AZ::Vector3& direction)
+ if (entityPivot.has_value())
{
- // use the manipulator transform as the pivot point
- AZStd::optional entityPivot;
- AzToolsFramework::EditorTransformComponentSelectionRequestBus::EventResult(
- entityPivot, AzToolsFramework::GetEntityContextId(),
- &AzToolsFramework::EditorTransformComponentSelectionRequestBus::Events::GetManipulatorTransform);
-
- // otherwise just use the identity
- return entityPivot.value_or(AZ::Transform::CreateIdentity()).GetTranslation();
+ return entityPivot->GetTranslation();
+ }
+
+ // otherwise just use the identity
+ return AZ::Vector3::CreateZero();
+ };
+
+ m_firstPersonFocusCamera =
+ AZStd::make_shared(SandboxEditor::CameraFocusChannelId(), AzFramework::FocusLook);
+
+ m_firstPersonFocusCamera->SetPivotFn(pivotFn);
+
+ m_orbitCamera = AZStd::make_shared(SandboxEditor::CameraOrbitChannelId());
+
+ m_orbitCamera->SetPivotFn(
+ [pivotFn]([[maybe_unused]] const AZ::Vector3& position, [[maybe_unused]] const AZ::Vector3& direction)
+ {
+ return pivotFn();
});
- m_pivotRotateCamera = AZStd::make_shared(SandboxEditor::CameraPivotLookChannelId());
+ m_orbitRotateCamera = AZStd::make_shared(SandboxEditor::CameraOrbitLookChannelId());
- m_pivotRotateCamera->m_rotateSpeedFn = []
+ m_orbitRotateCamera->m_rotateSpeedFn = []
{
return SandboxEditor::CameraRotateSpeed();
};
- m_pivotRotateCamera->m_invertYawFn = []
+ m_orbitRotateCamera->m_invertYawFn = []
{
- return SandboxEditor::CameraPivotYawRotationInverted();
+ return SandboxEditor::CameraOrbitYawRotationInverted();
};
- m_pivotTranslateCamera = AZStd::make_shared(
- translateCameraInputChannelIds, AzFramework::LookTranslation, AzFramework::TranslateOffset);
+ m_orbitTranslateCamera = AZStd::make_shared(
+ translateCameraInputChannelIds, AzFramework::LookTranslation, AzFramework::TranslateOffsetOrbit);
- m_pivotTranslateCamera->m_translateSpeedFn = []
+ m_orbitTranslateCamera->m_translateSpeedFn = []
{
return SandboxEditor::CameraTranslateSpeed();
};
- m_pivotTranslateCamera->m_boostMultiplierFn = []
+ m_orbitTranslateCamera->m_boostMultiplierFn = []
{
return SandboxEditor::CameraBoostMultiplier();
};
- m_pivotDollyScrollCamera = AZStd::make_shared();
+ m_orbitDollyScrollCamera = AZStd::make_shared();
- m_pivotDollyScrollCamera->m_scrollSpeedFn = []
+ m_orbitDollyScrollCamera->m_scrollSpeedFn = []
{
return SandboxEditor::CameraScrollSpeed();
};
- m_pivotDollyMoveCamera = AZStd::make_shared(SandboxEditor::CameraPivotDollyChannelId());
+ m_orbitDollyMoveCamera = AZStd::make_shared(SandboxEditor::CameraOrbitDollyChannelId());
- m_pivotDollyMoveCamera->m_motionSpeedFn = []
+ m_orbitDollyMoveCamera->m_motionSpeedFn = []
{
return SandboxEditor::CameraDollyMotionSpeed();
};
- m_pivotPanCamera = AZStd::make_shared(
- SandboxEditor::CameraPivotPanChannelId(), AzFramework::LookPan, AzFramework::TranslateOffset);
+ m_orbitPanCamera = AZStd::make_shared(
+ SandboxEditor::CameraOrbitPanChannelId(), AzFramework::LookPan, AzFramework::TranslateOffsetOrbit);
- m_pivotPanCamera->m_panSpeedFn = []
+ m_orbitPanCamera->m_panSpeedFn = []
{
return SandboxEditor::CameraPanSpeed();
};
- m_pivotPanCamera->m_invertPanXFn = []
+ m_orbitPanCamera->m_invertPanXFn = []
{
return SandboxEditor::CameraPanInvertedX();
};
- m_pivotPanCamera->m_invertPanYFn = []
+ m_orbitPanCamera->m_invertPanYFn = []
{
return SandboxEditor::CameraPanInvertedY();
};
- m_pivotCamera->m_pivotCameras.AddCamera(m_pivotRotateCamera);
- m_pivotCamera->m_pivotCameras.AddCamera(m_pivotTranslateCamera);
- m_pivotCamera->m_pivotCameras.AddCamera(m_pivotDollyScrollCamera);
- m_pivotCamera->m_pivotCameras.AddCamera(m_pivotDollyMoveCamera);
- m_pivotCamera->m_pivotCameras.AddCamera(m_pivotPanCamera);
+ m_orbitFocusCamera =
+ AZStd::make_shared(SandboxEditor::CameraFocusChannelId(), AzFramework::FocusOrbit);
+
+ m_orbitFocusCamera->SetPivotFn(pivotFn);
+
+ m_orbitCamera->m_orbitCameras.AddCamera(m_orbitRotateCamera);
+ m_orbitCamera->m_orbitCameras.AddCamera(m_orbitTranslateCamera);
+ m_orbitCamera->m_orbitCameras.AddCamera(m_orbitDollyScrollCamera);
+ m_orbitCamera->m_orbitCameras.AddCamera(m_orbitDollyMoveCamera);
+ m_orbitCamera->m_orbitCameras.AddCamera(m_orbitPanCamera);
+ m_orbitCamera->m_orbitCameras.AddCamera(m_orbitFocusCamera);
}
void EditorModularViewportCameraComposer::OnEditorModularViewportCameraComposerSettingsChanged()
@@ -257,12 +280,14 @@ namespace SandboxEditor
m_firstPersonTranslateCamera->SetTranslateCameraInputChannelIds(translateCameraInputChannelIds);
m_firstPersonPanCamera->SetPanInputChannelId(SandboxEditor::CameraFreePanChannelId());
m_firstPersonRotateCamera->SetRotateInputChannelId(SandboxEditor::CameraFreeLookChannelId());
-
- m_pivotCamera->SetPivotInputChannelId(SandboxEditor::CameraPivotChannelId());
- m_pivotTranslateCamera->SetTranslateCameraInputChannelIds(translateCameraInputChannelIds);
- m_pivotPanCamera->SetPanInputChannelId(SandboxEditor::CameraPivotPanChannelId());
- m_pivotRotateCamera->SetRotateInputChannelId(SandboxEditor::CameraPivotLookChannelId());
- m_pivotDollyMoveCamera->SetDollyInputChannelId(SandboxEditor::CameraPivotDollyChannelId());
+ m_firstPersonFocusCamera->SetFocusInputChannelId(SandboxEditor::CameraFocusChannelId());
+
+ m_orbitCamera->SetOrbitInputChannelId(SandboxEditor::CameraOrbitChannelId());
+ m_orbitTranslateCamera->SetTranslateCameraInputChannelIds(translateCameraInputChannelIds);
+ m_orbitPanCamera->SetPanInputChannelId(SandboxEditor::CameraOrbitPanChannelId());
+ m_orbitRotateCamera->SetRotateInputChannelId(SandboxEditor::CameraOrbitLookChannelId());
+ m_orbitDollyMoveCamera->SetDollyInputChannelId(SandboxEditor::CameraOrbitDollyChannelId());
+ m_orbitFocusCamera->SetFocusInputChannelId(SandboxEditor::CameraFocusChannelId());
}
void EditorModularViewportCameraComposer::OnViewportViewEntityChanged(const AZ::EntityId& viewEntityId)
diff --git a/Code/Editor/EditorModularViewportCameraComposer.h b/Code/Editor/EditorModularViewportCameraComposer.h
index e691ca1c89..9cfd6f3554 100644
--- a/Code/Editor/EditorModularViewportCameraComposer.h
+++ b/Code/Editor/EditorModularViewportCameraComposer.h
@@ -41,13 +41,15 @@ namespace SandboxEditor
AZStd::shared_ptr m_firstPersonRotateCamera;
AZStd::shared_ptr m_firstPersonPanCamera;
AZStd::shared_ptr m_firstPersonTranslateCamera;
- AZStd::shared_ptr m_firstPersonScrollCamera;
- AZStd::shared_ptr m_pivotCamera;
- AZStd::shared_ptr m_pivotRotateCamera;
- AZStd::shared_ptr m_pivotTranslateCamera;
- AZStd::shared_ptr m_pivotDollyScrollCamera;
- AZStd::shared_ptr m_pivotDollyMoveCamera;
- AZStd::shared_ptr m_pivotPanCamera;
+ AZStd::shared_ptr m_firstPersonScrollCamera;
+ AZStd::shared_ptr m_firstPersonFocusCamera;
+ AZStd::shared_ptr m_orbitCamera;
+ AZStd::shared_ptr m_orbitRotateCamera;
+ AZStd::shared_ptr m_orbitTranslateCamera;
+ AZStd::shared_ptr m_orbitDollyScrollCamera;
+ AZStd::shared_ptr m_orbitDollyMoveCamera;
+ AZStd::shared_ptr m_orbitPanCamera;
+ AZStd::shared_ptr m_orbitFocusCamera;
AzFramework::ViewportId m_viewportId;
};
diff --git a/Code/Editor/EditorPreferencesDialog.cpp b/Code/Editor/EditorPreferencesDialog.cpp
index c56df15908..a1859b0f14 100644
--- a/Code/Editor/EditorPreferencesDialog.cpp
+++ b/Code/Editor/EditorPreferencesDialog.cpp
@@ -264,6 +264,9 @@ void EditorPreferencesDialog::SetFilter(const QString& filter)
else if (m_currentPageItem)
{
m_currentPageItem->UpdateEditorFilter(ui->propertyEditor, m_filter);
+
+ // Refresh the Stylesheet - when using search functionality.
+ AzQtComponents::StyleManager::repolishStyleSheet(this);
}
}
diff --git a/Code/Editor/EditorPreferencesPageFiles.cpp b/Code/Editor/EditorPreferencesPageFiles.cpp
index 4be3269d42..c3423c4e5b 100644
--- a/Code/Editor/EditorPreferencesPageFiles.cpp
+++ b/Code/Editor/EditorPreferencesPageFiles.cpp
@@ -14,6 +14,7 @@
// Editor
#include "Settings.h"
+#include "EditorViewportSettings.h"
@@ -43,17 +44,16 @@ void CEditorPreferencesPage_Files::Reflect(AZ::SerializeContext& serialize)
->Field("MaxCount", &AutoBackup::m_maxCount)
->Field("RemindTime", &AutoBackup::m_remindTime);
- serialize.Class()
+ serialize.Class()
->Version(1)
- ->Field("Max number of items displayed", &AssetBrowserSearch::m_maxNumberOfItemsShownInSearch);
+ ->Field("MaxEntriesShownCount", &AssetBrowserSettings::m_maxNumberOfItemsShownInSearch);
serialize.Class()
->Version(1)
->Field("Files", &CEditorPreferencesPage_Files::m_files)
->Field("Editors", &CEditorPreferencesPage_Files::m_editors)
->Field("AutoBackup", &CEditorPreferencesPage_Files::m_autoBackup)
- ->Field("AssetBrowserSearch", &CEditorPreferencesPage_Files::m_assetBrowserSearch);
-
+ ->Field("AssetBrowserSettings", &CEditorPreferencesPage_Files::m_assetBrowserSettings);
AZ::EditContext* editContext = serialize.GetEditContext();
if (editContext)
@@ -85,9 +85,10 @@ void CEditorPreferencesPage_Files::Reflect(AZ::SerializeContext& serialize)
->Attribute(AZ::Edit::Attributes::Max, 100)
->DataElement(AZ::Edit::UIHandlers::SpinBox, &AutoBackup::m_remindTime, "Remind Time", "Auto Remind Every (Minutes)");
- editContext->Class("Asset Browser Search View", "Asset Browser Search View")
- ->DataElement(AZ::Edit::UIHandlers::SpinBox, &AssetBrowserSearch::m_maxNumberOfItemsShownInSearch, "Maximum number of displayed items",
- "Maximum number of displayed items displayed in the Search View")
+ editContext->Class("Asset Browser Settings", "Asset Browser Settings")
+ ->DataElement(
+ AZ::Edit::UIHandlers::SpinBox, &AssetBrowserSettings::m_maxNumberOfItemsShownInSearch, "Maximum number of displayed items",
+ "Maximum number of items to display in the Search View.")
->Attribute(AZ::Edit::Attributes::Min, 50)
->Attribute(AZ::Edit::Attributes::Max, 5000);
@@ -97,7 +98,7 @@ void CEditorPreferencesPage_Files::Reflect(AZ::SerializeContext& serialize)
->DataElement(AZ::Edit::UIHandlers::Default, &CEditorPreferencesPage_Files::m_files, "Files", "File Preferences")
->DataElement(AZ::Edit::UIHandlers::Default, &CEditorPreferencesPage_Files::m_editors, "External Editors", "External Editors")
->DataElement(AZ::Edit::UIHandlers::Default, &CEditorPreferencesPage_Files::m_autoBackup, "Auto Backup", "Auto Backup")
- ->DataElement(AZ::Edit::UIHandlers::Default, &CEditorPreferencesPage_Files::m_assetBrowserSearch, "Asset Browser Search", "Asset Browser Search");
+ ->DataElement(AZ::Edit::UIHandlers::Default, &CEditorPreferencesPage_Files::m_assetBrowserSettings, "Asset Browser Settings","Asset Browser Settings");
}
}
@@ -117,6 +118,7 @@ QIcon& CEditorPreferencesPage_Files::GetIcon()
void CEditorPreferencesPage_Files::OnApply()
{
using namespace AzToolsFramework::SliceUtilities;
+
auto sliceSettings = AZ::UserSettings::CreateFind(AZ_CRC("SliceUserSettings", 0x055b32eb), AZ::UserSettings::CT_LOCAL);
sliceSettings->m_autoNumber = m_files.m_autoNumberSlices;
sliceSettings->m_saveLocation = m_files.m_saveLocation;
@@ -137,7 +139,7 @@ void CEditorPreferencesPage_Files::OnApply()
gSettings.autoBackupMaxCount = m_autoBackup.m_maxCount;
gSettings.autoRemindTime = m_autoBackup.m_remindTime;
- gSettings.maxNumberOfItemsShownInSearch = m_assetBrowserSearch.m_maxNumberOfItemsShownInSearch;
+ SandboxEditor::SetMaxItemsShownInAssetBrowserSearch(m_assetBrowserSettings.m_maxNumberOfItemsShownInSearch);
}
void CEditorPreferencesPage_Files::InitializeSettings()
@@ -163,5 +165,5 @@ void CEditorPreferencesPage_Files::InitializeSettings()
m_autoBackup.m_maxCount = gSettings.autoBackupMaxCount;
m_autoBackup.m_remindTime = gSettings.autoRemindTime;
- m_assetBrowserSearch.m_maxNumberOfItemsShownInSearch = gSettings.maxNumberOfItemsShownInSearch;
+ m_assetBrowserSettings.m_maxNumberOfItemsShownInSearch = SandboxEditor::MaxItemsShownInAssetBrowserSearch();
}
diff --git a/Code/Editor/EditorPreferencesPageFiles.h b/Code/Editor/EditorPreferencesPageFiles.h
index 368cd91fc3..9022032edc 100644
--- a/Code/Editor/EditorPreferencesPageFiles.h
+++ b/Code/Editor/EditorPreferencesPageFiles.h
@@ -69,18 +69,15 @@ private:
int m_remindTime;
};
- struct AssetBrowserSearch
+ struct AssetBrowserSettings
{
- AZ_TYPE_INFO(AssetBrowserSearch, "{9FBFCD24-9452-49DF-99F4-2711443CEAAE}")
-
- int m_maxNumberOfItemsShownInSearch;
+ AZ_TYPE_INFO(AssetBrowserSettings, "{5F407EC4-BBD1-4A87-92DB-D938D7127BB0}")
+ AZ::u64 m_maxNumberOfItemsShownInSearch;
};
Files m_files;
ExternalEditors m_editors;
AutoBackup m_autoBackup;
- AssetBrowserSearch m_assetBrowserSearch;
+ AssetBrowserSettings m_assetBrowserSettings;
QIcon m_icon;
};
-
-
diff --git a/Code/Editor/EditorPreferencesPageViewportCamera.cpp b/Code/Editor/EditorPreferencesPageViewportCamera.cpp
index 55b631e1f6..16176bc241 100644
--- a/Code/Editor/EditorPreferencesPageViewportCamera.cpp
+++ b/Code/Editor/EditorPreferencesPageViewportCamera.cpp
@@ -73,7 +73,7 @@ void CEditorPreferencesPage_ViewportCamera::Reflect(AZ::SerializeContext& serial
->Field("TranslateSmoothing", &CameraMovementSettings::m_translateSmoothing)
->Field("TranslateSmoothness", &CameraMovementSettings::m_translateSmoothness)
->Field("CaptureCursorLook", &CameraMovementSettings::m_captureCursorLook)
- ->Field("PivotYawRotationInverted", &CameraMovementSettings::m_pivotYawRotationInverted)
+ ->Field("OrbitYawRotationInverted", &CameraMovementSettings::m_orbitYawRotationInverted)
->Field("PanInvertedX", &CameraMovementSettings::m_panInvertedX)
->Field("PanInvertedY", &CameraMovementSettings::m_panInvertedY);
@@ -86,12 +86,13 @@ void CEditorPreferencesPage_ViewportCamera::Reflect(AZ::SerializeContext& serial
->Field("TranslateUp", &CameraInputSettings::m_translateUpChannelId)
->Field("TranslateDown", &CameraInputSettings::m_translateDownChannelId)
->Field("Boost", &CameraInputSettings::m_boostChannelId)
- ->Field("Pivot", &CameraInputSettings::m_pivotChannelId)
+ ->Field("Orbit", &CameraInputSettings::m_orbitChannelId)
->Field("FreeLook", &CameraInputSettings::m_freeLookChannelId)
->Field("FreePan", &CameraInputSettings::m_freePanChannelId)
- ->Field("PivotLook", &CameraInputSettings::m_pivotLookChannelId)
- ->Field("PivotDolly", &CameraInputSettings::m_pivotDollyChannelId)
- ->Field("PivotPan", &CameraInputSettings::m_pivotPanChannelId);
+ ->Field("OrbitLook", &CameraInputSettings::m_orbitLookChannelId)
+ ->Field("OrbitDolly", &CameraInputSettings::m_orbitDollyChannelId)
+ ->Field("OrbitPan", &CameraInputSettings::m_orbitPanChannelId)
+ ->Field("Focus", &CameraInputSettings::m_focusChannelId);
serialize.Class()
->Version(1)
@@ -143,8 +144,8 @@ void CEditorPreferencesPage_ViewportCamera::Reflect(AZ::SerializeContext& serial
->Attribute(AZ::Edit::Attributes::Min, minValue)
->Attribute(AZ::Edit::Attributes::Visibility, &CameraMovementSettings::TranslateSmoothingVisibility)
->DataElement(
- AZ::Edit::UIHandlers::CheckBox, &CameraMovementSettings::m_pivotYawRotationInverted, "Camera Pivot Yaw Inverted",
- "Inverted yaw rotation while pivoting")
+ AZ::Edit::UIHandlers::CheckBox, &CameraMovementSettings::m_orbitYawRotationInverted, "Camera Orbit Yaw Inverted",
+ "Inverted yaw rotation while orbiting")
->DataElement(
AZ::Edit::UIHandlers::CheckBox, &CameraMovementSettings::m_panInvertedX, "Invert Pan X",
"Invert direction of pan in local X axis")
@@ -185,8 +186,8 @@ void CEditorPreferencesPage_ViewportCamera::Reflect(AZ::SerializeContext& serial
"Key/button to move the camera more quickly")
->Attribute(AZ::Edit::Attributes::StringList, &GetEditorInputNames)
->DataElement(
- AZ::Edit::UIHandlers::ComboBox, &CameraInputSettings::m_pivotChannelId, "Pivot",
- "Key/button to begin the camera pivot behavior")
+ AZ::Edit::UIHandlers::ComboBox, &CameraInputSettings::m_orbitChannelId, "Orbit",
+ "Key/button to begin the camera orbit behavior")
->Attribute(AZ::Edit::Attributes::StringList, &GetEditorInputNames)
->DataElement(
AZ::Edit::UIHandlers::ComboBox, &CameraInputSettings::m_freeLookChannelId, "Free Look",
@@ -196,24 +197,27 @@ void CEditorPreferencesPage_ViewportCamera::Reflect(AZ::SerializeContext& serial
AZ::Edit::UIHandlers::ComboBox, &CameraInputSettings::m_freePanChannelId, "Free Pan", "Key/button to begin camera free pan")
->Attribute(AZ::Edit::Attributes::StringList, &GetEditorInputNames)
->DataElement(
- AZ::Edit::UIHandlers::ComboBox, &CameraInputSettings::m_pivotLookChannelId, "Pivot Look",
- "Key/button to begin camera pivot look")
+ AZ::Edit::UIHandlers::ComboBox, &CameraInputSettings::m_orbitLookChannelId, "Orbit Look",
+ "Key/button to begin camera orbit look")
->Attribute(AZ::Edit::Attributes::StringList, &GetEditorInputNames)
->DataElement(
- AZ::Edit::UIHandlers::ComboBox, &CameraInputSettings::m_pivotDollyChannelId, "Pivot Dolly",
- "Key/button to begin camera pivot dolly")
+ AZ::Edit::UIHandlers::ComboBox, &CameraInputSettings::m_orbitDollyChannelId, "Orbit Dolly",
+ "Key/button to begin camera orbit dolly")
->Attribute(AZ::Edit::Attributes::StringList, &GetEditorInputNames)
->DataElement(
- AZ::Edit::UIHandlers::ComboBox, &CameraInputSettings::m_pivotPanChannelId, "Pivot Pan",
- "Key/button to begin camera pivot pan")
+ AZ::Edit::UIHandlers::ComboBox, &CameraInputSettings::m_orbitPanChannelId, "Orbit Pan",
+ "Key/button to begin camera orbit pan")
+ ->Attribute(AZ::Edit::Attributes::StringList, &GetEditorInputNames)
+ ->DataElement(
+ AZ::Edit::UIHandlers::ComboBox, &CameraInputSettings::m_focusChannelId, "Focus", "Key/button to focus camera orbit")
->Attribute(AZ::Edit::Attributes::StringList, &GetEditorInputNames);
editContext->Class("Viewport Preferences", "Viewport Preferences")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::Visibility, AZ_CRC("PropertyVisibility_ShowChildrenOnly", 0xef428f20))
->DataElement(
- AZ::Edit::UIHandlers::Default, &CEditorPreferencesPage_ViewportCamera::m_cameraMovementSettings,
- "Camera Movement Settings", "Camera Movement Settings")
+ AZ::Edit::UIHandlers::Default, &CEditorPreferencesPage_ViewportCamera::m_cameraMovementSettings, "Camera Movement Settings",
+ "Camera Movement Settings")
->DataElement(
AZ::Edit::UIHandlers::Default, &CEditorPreferencesPage_ViewportCamera::m_cameraInputSettings, "Camera Input Settings",
"Camera Input Settings");
@@ -264,7 +268,7 @@ void CEditorPreferencesPage_ViewportCamera::OnApply()
SandboxEditor::SetCameraTranslateSmoothness(m_cameraMovementSettings.m_translateSmoothness);
SandboxEditor::SetCameraTranslateSmoothingEnabled(m_cameraMovementSettings.m_translateSmoothing);
SandboxEditor::SetCameraCaptureCursorForLook(m_cameraMovementSettings.m_captureCursorLook);
- SandboxEditor::SetCameraPivotYawRotationInverted(m_cameraMovementSettings.m_pivotYawRotationInverted);
+ SandboxEditor::SetCameraOrbitYawRotationInverted(m_cameraMovementSettings.m_orbitYawRotationInverted);
SandboxEditor::SetCameraPanInvertedX(m_cameraMovementSettings.m_panInvertedX);
SandboxEditor::SetCameraPanInvertedY(m_cameraMovementSettings.m_panInvertedY);
@@ -275,12 +279,13 @@ void CEditorPreferencesPage_ViewportCamera::OnApply()
SandboxEditor::SetCameraTranslateUpChannelId(m_cameraInputSettings.m_translateUpChannelId);
SandboxEditor::SetCameraTranslateDownChannelId(m_cameraInputSettings.m_translateDownChannelId);
SandboxEditor::SetCameraTranslateBoostChannelId(m_cameraInputSettings.m_boostChannelId);
- SandboxEditor::SetCameraPivotChannelId(m_cameraInputSettings.m_pivotChannelId);
+ SandboxEditor::SetCameraOrbitChannelId(m_cameraInputSettings.m_orbitChannelId);
SandboxEditor::SetCameraFreeLookChannelId(m_cameraInputSettings.m_freeLookChannelId);
SandboxEditor::SetCameraFreePanChannelId(m_cameraInputSettings.m_freePanChannelId);
- SandboxEditor::SetCameraPivotLookChannelId(m_cameraInputSettings.m_pivotLookChannelId);
- SandboxEditor::SetCameraPivotDollyChannelId(m_cameraInputSettings.m_pivotDollyChannelId);
- SandboxEditor::SetCameraPivotPanChannelId(m_cameraInputSettings.m_pivotPanChannelId);
+ SandboxEditor::SetCameraOrbitLookChannelId(m_cameraInputSettings.m_orbitLookChannelId);
+ SandboxEditor::SetCameraOrbitDollyChannelId(m_cameraInputSettings.m_orbitDollyChannelId);
+ SandboxEditor::SetCameraOrbitPanChannelId(m_cameraInputSettings.m_orbitPanChannelId);
+ SandboxEditor::SetCameraFocusChannelId(m_cameraInputSettings.m_focusChannelId);
SandboxEditor::EditorModularViewportCameraComposerNotificationBus::Broadcast(
&SandboxEditor::EditorModularViewportCameraComposerNotificationBus::Events::OnEditorModularViewportCameraComposerSettingsChanged);
@@ -299,7 +304,7 @@ void CEditorPreferencesPage_ViewportCamera::InitializeSettings()
m_cameraMovementSettings.m_translateSmoothness = SandboxEditor::CameraTranslateSmoothness();
m_cameraMovementSettings.m_translateSmoothing = SandboxEditor::CameraTranslateSmoothingEnabled();
m_cameraMovementSettings.m_captureCursorLook = SandboxEditor::CameraCaptureCursorForLook();
- m_cameraMovementSettings.m_pivotYawRotationInverted = SandboxEditor::CameraPivotYawRotationInverted();
+ m_cameraMovementSettings.m_orbitYawRotationInverted = SandboxEditor::CameraOrbitYawRotationInverted();
m_cameraMovementSettings.m_panInvertedX = SandboxEditor::CameraPanInvertedX();
m_cameraMovementSettings.m_panInvertedY = SandboxEditor::CameraPanInvertedY();
@@ -310,10 +315,11 @@ void CEditorPreferencesPage_ViewportCamera::InitializeSettings()
m_cameraInputSettings.m_translateUpChannelId = SandboxEditor::CameraTranslateUpChannelId().GetName();
m_cameraInputSettings.m_translateDownChannelId = SandboxEditor::CameraTranslateDownChannelId().GetName();
m_cameraInputSettings.m_boostChannelId = SandboxEditor::CameraTranslateBoostChannelId().GetName();
- m_cameraInputSettings.m_pivotChannelId = SandboxEditor::CameraPivotChannelId().GetName();
+ m_cameraInputSettings.m_orbitChannelId = SandboxEditor::CameraOrbitChannelId().GetName();
m_cameraInputSettings.m_freeLookChannelId = SandboxEditor::CameraFreeLookChannelId().GetName();
m_cameraInputSettings.m_freePanChannelId = SandboxEditor::CameraFreePanChannelId().GetName();
- m_cameraInputSettings.m_pivotLookChannelId = SandboxEditor::CameraPivotLookChannelId().GetName();
- m_cameraInputSettings.m_pivotDollyChannelId = SandboxEditor::CameraPivotDollyChannelId().GetName();
- m_cameraInputSettings.m_pivotPanChannelId = SandboxEditor::CameraPivotPanChannelId().GetName();
+ m_cameraInputSettings.m_orbitLookChannelId = SandboxEditor::CameraOrbitLookChannelId().GetName();
+ m_cameraInputSettings.m_orbitDollyChannelId = SandboxEditor::CameraOrbitDollyChannelId().GetName();
+ m_cameraInputSettings.m_orbitPanChannelId = SandboxEditor::CameraOrbitPanChannelId().GetName();
+ m_cameraInputSettings.m_focusChannelId = SandboxEditor::CameraFocusChannelId().GetName();
}
diff --git a/Code/Editor/EditorPreferencesPageViewportCamera.h b/Code/Editor/EditorPreferencesPageViewportCamera.h
index 01dc4664f6..fdc86b0f89 100644
--- a/Code/Editor/EditorPreferencesPageViewportCamera.h
+++ b/Code/Editor/EditorPreferencesPageViewportCamera.h
@@ -54,7 +54,7 @@ private:
float m_translateSmoothness;
bool m_translateSmoothing;
bool m_captureCursorLook;
- bool m_pivotYawRotationInverted;
+ bool m_orbitYawRotationInverted;
bool m_panInvertedX;
bool m_panInvertedY;
@@ -80,12 +80,13 @@ private:
AZStd::string m_translateUpChannelId;
AZStd::string m_translateDownChannelId;
AZStd::string m_boostChannelId;
- AZStd::string m_pivotChannelId;
+ AZStd::string m_orbitChannelId;
AZStd::string m_freeLookChannelId;
AZStd::string m_freePanChannelId;
- AZStd::string m_pivotLookChannelId;
- AZStd::string m_pivotDollyChannelId;
- AZStd::string m_pivotPanChannelId;
+ AZStd::string m_orbitLookChannelId;
+ AZStd::string m_orbitDollyChannelId;
+ AZStd::string m_orbitPanChannelId;
+ AZStd::string m_focusChannelId;
};
CameraMovementSettings m_cameraMovementSettings;
diff --git a/Code/Editor/EditorViewportSettings.cpp b/Code/Editor/EditorViewportSettings.cpp
index fe8efecd17..2b54622d1c 100644
--- a/Code/Editor/EditorViewportSettings.cpp
+++ b/Code/Editor/EditorViewportSettings.cpp
@@ -15,6 +15,7 @@
namespace SandboxEditor
{
+ constexpr AZStd::string_view AssetBrowserMaxItemsShownInSearchSetting = "/Amazon/Preferences/Editor/AssetBrowser/MaxItemsShowInSearch";
constexpr AZStd::string_view GridSnappingSetting = "/Amazon/Preferences/Editor/GridSnapping";
constexpr AZStd::string_view GridSizeSetting = "/Amazon/Preferences/Editor/GridSize";
constexpr AZStd::string_view AngleSnappingSetting = "/Amazon/Preferences/Editor/AngleSnapping";
@@ -28,7 +29,7 @@ namespace SandboxEditor
constexpr AZStd::string_view CameraRotateSpeedSetting = "/Amazon/Preferences/Editor/Camera/RotateSpeed";
constexpr AZStd::string_view CameraScrollSpeedSetting = "/Amazon/Preferences/Editor/Camera/DollyScrollSpeed";
constexpr AZStd::string_view CameraDollyMotionSpeedSetting = "/Amazon/Preferences/Editor/Camera/DollyMotionSpeed";
- constexpr AZStd::string_view CameraPivotYawRotationInvertedSetting = "/Amazon/Preferences/Editor/Camera/YawRotationInverted";
+ constexpr AZStd::string_view CameraOrbitYawRotationInvertedSetting = "/Amazon/Preferences/Editor/Camera/YawRotationInverted";
constexpr AZStd::string_view CameraPanInvertedXSetting = "/Amazon/Preferences/Editor/Camera/PanInvertedX";
constexpr AZStd::string_view CameraPanInvertedYSetting = "/Amazon/Preferences/Editor/Camera/PanInvertedY";
constexpr AZStd::string_view CameraPanSpeedSetting = "/Amazon/Preferences/Editor/Camera/PanSpeed";
@@ -44,12 +45,13 @@ namespace SandboxEditor
constexpr AZStd::string_view CameraTranslateUpIdSetting = "/Amazon/Preferences/Editor/Camera/CameraTranslateUpId";
constexpr AZStd::string_view CameraTranslateDownIdSetting = "/Amazon/Preferences/Editor/Camera/CameraTranslateUpDownId";
constexpr AZStd::string_view CameraTranslateBoostIdSetting = "/Amazon/Preferences/Editor/Camera/TranslateBoostId";
- constexpr AZStd::string_view CameraPivotIdSetting = "/Amazon/Preferences/Editor/Camera/PivotId";
+ constexpr AZStd::string_view CameraOrbitIdSetting = "/Amazon/Preferences/Editor/Camera/OrbitId";
constexpr AZStd::string_view CameraFreeLookIdSetting = "/Amazon/Preferences/Editor/Camera/FreeLookId";
constexpr AZStd::string_view CameraFreePanIdSetting = "/Amazon/Preferences/Editor/Camera/FreePanId";
- constexpr AZStd::string_view CameraPivotLookIdSetting = "/Amazon/Preferences/Editor/Camera/PivotLookId";
- constexpr AZStd::string_view CameraPivotDollyIdSetting = "/Amazon/Preferences/Editor/Camera/PivotDollyId";
- constexpr AZStd::string_view CameraPivotPanIdSetting = "/Amazon/Preferences/Editor/Camera/PivotPanId";
+ constexpr AZStd::string_view CameraOrbitLookIdSetting = "/Amazon/Preferences/Editor/Camera/OrbitLookId";
+ constexpr AZStd::string_view CameraOrbitDollyIdSetting = "/Amazon/Preferences/Editor/Camera/OrbitDollyId";
+ constexpr AZStd::string_view CameraOrbitPanIdSetting = "/Amazon/Preferences/Editor/Camera/OrbitPanId";
+ constexpr AZStd::string_view CameraFocusIdSetting = "/Amazon/Preferences/Editor/Camera/FocusId";
template
void SetRegistry(const AZStd::string_view setting, T&& value)
@@ -109,6 +111,16 @@ namespace SandboxEditor
return AZStd::make_unique();
}
+ AZ::u64 MaxItemsShownInAssetBrowserSearch()
+ {
+ return GetRegistry(AssetBrowserMaxItemsShownInSearchSetting, aznumeric_cast(50));
+ }
+
+ void SetMaxItemsShownInAssetBrowserSearch(const AZ::u64 numberOfItemsShown)
+ {
+ SetRegistry(AssetBrowserMaxItemsShownInSearchSetting, numberOfItemsShown);
+ }
+
bool GridSnappingEnabled()
{
return GetRegistry(GridSnappingSetting, false);
@@ -239,14 +251,14 @@ namespace SandboxEditor
SetRegistry(CameraDollyMotionSpeedSetting, speed);
}
- bool CameraPivotYawRotationInverted()
+ bool CameraOrbitYawRotationInverted()
{
- return GetRegistry(CameraPivotYawRotationInvertedSetting, false);
+ return GetRegistry(CameraOrbitYawRotationInvertedSetting, false);
}
- void SetCameraPivotYawRotationInverted(const bool inverted)
+ void SetCameraOrbitYawRotationInverted(const bool inverted)
{
- SetRegistry(CameraPivotYawRotationInvertedSetting, inverted);
+ SetRegistry(CameraOrbitYawRotationInvertedSetting, inverted);
}
bool CameraPanInvertedX()
@@ -403,14 +415,14 @@ namespace SandboxEditor
SetRegistry(CameraTranslateBoostIdSetting, cameraTranslateBoostId);
}
- AzFramework::InputChannelId CameraPivotChannelId()
+ AzFramework::InputChannelId CameraOrbitChannelId()
{
- return AzFramework::InputChannelId(GetRegistry(CameraPivotIdSetting, AZStd::string("keyboard_key_modifier_alt_l")).c_str());
+ return AzFramework::InputChannelId(GetRegistry(CameraOrbitIdSetting, AZStd::string("keyboard_key_modifier_alt_l")).c_str());
}
- void SetCameraPivotChannelId(AZStd::string_view cameraPivotId)
+ void SetCameraOrbitChannelId(AZStd::string_view cameraOrbitId)
{
- SetRegistry(CameraPivotIdSetting, cameraPivotId);
+ SetRegistry(CameraOrbitIdSetting, cameraOrbitId);
}
AzFramework::InputChannelId CameraFreeLookChannelId()
@@ -433,33 +445,43 @@ namespace SandboxEditor
SetRegistry(CameraFreePanIdSetting, cameraFreePanId);
}
- AzFramework::InputChannelId CameraPivotLookChannelId()
+ AzFramework::InputChannelId CameraOrbitLookChannelId()
+ {
+ return AzFramework::InputChannelId(GetRegistry(CameraOrbitLookIdSetting, AZStd::string("mouse_button_left")).c_str());
+ }
+
+ void SetCameraOrbitLookChannelId(AZStd::string_view cameraOrbitLookId)
+ {
+ SetRegistry(CameraOrbitLookIdSetting, cameraOrbitLookId);
+ }
+
+ AzFramework::InputChannelId CameraOrbitDollyChannelId()
{
- return AzFramework::InputChannelId(GetRegistry(CameraPivotLookIdSetting, AZStd::string("mouse_button_left")).c_str());
+ return AzFramework::InputChannelId(GetRegistry(CameraOrbitDollyIdSetting, AZStd::string("mouse_button_right")).c_str());
}
- void SetCameraPivotLookChannelId(AZStd::string_view cameraPivotLookId)
+ void SetCameraOrbitDollyChannelId(AZStd::string_view cameraOrbitDollyId)
{
- SetRegistry(CameraPivotLookIdSetting, cameraPivotLookId);
+ SetRegistry(CameraOrbitDollyIdSetting, cameraOrbitDollyId);
}
- AzFramework::InputChannelId CameraPivotDollyChannelId()
+ AzFramework::InputChannelId CameraOrbitPanChannelId()
{
- return AzFramework::InputChannelId(GetRegistry(CameraPivotDollyIdSetting, AZStd::string("mouse_button_right")).c_str());
+ return AzFramework::InputChannelId(GetRegistry(CameraOrbitPanIdSetting, AZStd::string("mouse_button_middle")).c_str());
}
- void SetCameraPivotDollyChannelId(AZStd::string_view cameraPivotDollyId)
+ void SetCameraOrbitPanChannelId(AZStd::string_view cameraOrbitPanId)
{
- SetRegistry(CameraPivotDollyIdSetting, cameraPivotDollyId);
+ SetRegistry(CameraOrbitPanIdSetting, cameraOrbitPanId);
}
- AzFramework::InputChannelId CameraPivotPanChannelId()
+ AzFramework::InputChannelId CameraFocusChannelId()
{
- return AzFramework::InputChannelId(GetRegistry(CameraPivotPanIdSetting, AZStd::string("mouse_button_middle")).c_str());
+ return AzFramework::InputChannelId(GetRegistry(CameraFocusIdSetting, AZStd::string("keyboard_key_alphanumeric_X")).c_str());
}
- void SetCameraPivotPanChannelId(AZStd::string_view cameraPivotPanId)
+ void SetCameraFocusChannelId(AZStd::string_view cameraFocusId)
{
- SetRegistry(CameraPivotPanIdSetting, cameraPivotPanId);
+ SetRegistry(CameraFocusIdSetting, cameraFocusId);
}
} // namespace SandboxEditor
diff --git a/Code/Editor/EditorViewportSettings.h b/Code/Editor/EditorViewportSettings.h
index d1271017c6..c6f51cf461 100644
--- a/Code/Editor/EditorViewportSettings.h
+++ b/Code/Editor/EditorViewportSettings.h
@@ -32,6 +32,9 @@ namespace SandboxEditor
//! event will fire when a value in the settings registry (editorpreferences.setreg) is modified.
SANDBOX_API AZStd::unique_ptr CreateEditorViewportSettingsCallbacks();
+ SANDBOX_API AZ::u64 MaxItemsShownInAssetBrowserSearch();
+ SANDBOX_API void SetMaxItemsShownInAssetBrowserSearch(AZ::u64 numberOfItemsShown);
+
SANDBOX_API bool GridSnappingEnabled();
SANDBOX_API void SetGridSnapping(bool enabled);
@@ -71,8 +74,8 @@ namespace SandboxEditor
SANDBOX_API float CameraDollyMotionSpeed();
SANDBOX_API void SetCameraDollyMotionSpeed(float speed);
- SANDBOX_API bool CameraPivotYawRotationInverted();
- SANDBOX_API void SetCameraPivotYawRotationInverted(bool inverted);
+ SANDBOX_API bool CameraOrbitYawRotationInverted();
+ SANDBOX_API void SetCameraOrbitYawRotationInverted(bool inverted);
SANDBOX_API bool CameraPanInvertedX();
SANDBOX_API void SetCameraPanInvertedX(bool inverted);
@@ -119,8 +122,8 @@ namespace SandboxEditor
SANDBOX_API AzFramework::InputChannelId CameraTranslateBoostChannelId();
SANDBOX_API void SetCameraTranslateBoostChannelId(AZStd::string_view cameraTranslateBoostId);
- SANDBOX_API AzFramework::InputChannelId CameraPivotChannelId();
- SANDBOX_API void SetCameraPivotChannelId(AZStd::string_view cameraPivotId);
+ SANDBOX_API AzFramework::InputChannelId CameraOrbitChannelId();
+ SANDBOX_API void SetCameraOrbitChannelId(AZStd::string_view cameraOrbitId);
SANDBOX_API AzFramework::InputChannelId CameraFreeLookChannelId();
SANDBOX_API void SetCameraFreeLookChannelId(AZStd::string_view cameraFreeLookId);
@@ -128,12 +131,15 @@ namespace SandboxEditor
SANDBOX_API AzFramework::InputChannelId CameraFreePanChannelId();
SANDBOX_API void SetCameraFreePanChannelId(AZStd::string_view cameraFreePanId);
- SANDBOX_API AzFramework::InputChannelId CameraPivotLookChannelId();
- SANDBOX_API void SetCameraPivotLookChannelId(AZStd::string_view cameraPivotLookId);
+ SANDBOX_API AzFramework::InputChannelId CameraOrbitLookChannelId();
+ SANDBOX_API void SetCameraOrbitLookChannelId(AZStd::string_view cameraOrbitLookId);
+
+ SANDBOX_API AzFramework::InputChannelId CameraOrbitDollyChannelId();
+ SANDBOX_API void SetCameraOrbitDollyChannelId(AZStd::string_view cameraOrbitDollyId);
- SANDBOX_API AzFramework::InputChannelId CameraPivotDollyChannelId();
- SANDBOX_API void SetCameraPivotDollyChannelId(AZStd::string_view cameraPivotDollyId);
+ SANDBOX_API AzFramework::InputChannelId CameraOrbitPanChannelId();
+ SANDBOX_API void SetCameraOrbitPanChannelId(AZStd::string_view cameraOrbitPanId);
- SANDBOX_API AzFramework::InputChannelId CameraPivotPanChannelId();
- SANDBOX_API void SetCameraPivotPanChannelId(AZStd::string_view cameraPivotPanId);
+ SANDBOX_API AzFramework::InputChannelId CameraFocusChannelId();
+ SANDBOX_API void SetCameraFocusChannelId(AZStd::string_view cameraFocusId);
} // namespace SandboxEditor
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..ee7e9a8e96 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);
@@ -106,16 +108,11 @@ CObjectManager::CObjectManager()
m_objectsByName.reserve(1024);
LoadRegistry();
-
- AzToolsFramework::ComponentModeFramework::EditorComponentModeNotificationBus::Handler::BusConnect(
- AzToolsFramework::GetEntityContextId());
}
//////////////////////////////////////////////////////////////////////////
CObjectManager::~CObjectManager()
{
- AzToolsFramework::ComponentModeFramework::EditorComponentModeNotificationBus::Handler::BusDisconnect();
-
m_bExiting = true;
SaveRegistry();
DeleteAllObjects();
@@ -2306,29 +2303,6 @@ void CObjectManager::SelectObjectInRect(CBaseObject* pObj, CViewport* view, HitC
}
}
-void CObjectManager::EnteredComponentMode(const AZStd::vector& /*componentModeTypes*/)
-{
- // 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*/)
-{
- // show translate/rotate/scale gizmo again
- if (IGizmoManager* gizmoManager = GetGizmoManager())
- {
- if (CBaseObject* selectedObject = GetIEditor()->GetSelectedObject())
- {
- gizmoManager->AddGizmo(new CAxisGizmo(selectedObject));
- }
- }
-}
-
//////////////////////////////////////////////////////////////////////////
namespace
{
diff --git a/Code/Editor/Objects/ObjectManager.h b/Code/Editor/Objects/ObjectManager.h
index 0ad5d8323e..7389dfa6a1 100644
--- a/Code/Editor/Objects/ObjectManager.h
+++ b/Code/Editor/Objects/ObjectManager.h
@@ -20,8 +20,8 @@
#include "ObjectManagerEventBus.h"
#include
-#include
#include
+#include
#include
// forward declarations.
@@ -58,7 +58,6 @@ public:
*/
class CObjectManager
: public IObjectManager
- , private AzToolsFramework::ComponentModeFramework::EditorComponentModeNotificationBus::Handler
{
public:
//! Selection functor callback.
@@ -329,10 +328,6 @@ private:
void FindDisplayableObjects(DisplayContext& dc, bool bDisplay);
- // EditorComponentModeNotificationBus
- void EnteredComponentMode(const AZStd::vector& componentModeTypes) override;
- void LeftComponentMode(const AZStd::vector& componentModeTypes) override;
-
private:
typedef std::map Objects;
Objects m_objects;
diff --git a/Code/Editor/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.cpp b/Code/Editor/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.cpp
index b9e4878879..41e950a058 100644
--- a/Code/Editor/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.cpp
+++ b/Code/Editor/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.cpp
@@ -1895,7 +1895,7 @@ void SandboxIntegrationManager::MakeSliceFromEntities(const AzToolsFramework::En
AzToolsFramework::ToolsApplicationRequestBus::BroadcastResult(entitiesAndDescendants,
&AzToolsFramework::ToolsApplicationRequestBus::Events::GatherEntitiesAndAllDescendents, entities);
- const AZStd::string slicesAssetsPath = "@devassets@/Slices";
+ const AZStd::string slicesAssetsPath = "@projectroot@/Slices";
if (!gEnv->pFileIO->Exists(slicesAssetsPath.c_str()))
{
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/Plugins/EditorAssetImporter/AssetImporterWindow.cpp b/Code/Editor/Plugins/EditorAssetImporter/AssetImporterWindow.cpp
index 98bf228391..0ff9467f33 100644
--- a/Code/Editor/Plugins/EditorAssetImporter/AssetImporterWindow.cpp
+++ b/Code/Editor/Plugins/EditorAssetImporter/AssetImporterWindow.cpp
@@ -30,6 +30,7 @@ class CXTPDockingPaneLayout; // Needed for settings.h
#include
#include
#include
+#include
#include
#include
#include
@@ -47,41 +48,6 @@ class CXTPDockingPaneLayout; // Needed for settings.h
const char* AssetImporterWindow::s_documentationWebAddress = "http://docs.aws.amazon.com/lumberyard/latest/userguide/char-fbx-importer.html";
const AZ::Uuid AssetImporterWindow::s_browseTag = AZ::Uuid::CreateString("{C240D2E1-BFD2-4FFA-BB5B-CC0FA389A5D3}");
-void MakeUserFriendlySourceAssetPath(QString& out, const QString& sourcePath)
-{
- char devAssetsRoot[AZ_MAX_PATH_LEN] = { 0 };
- if (!gEnv->pFileIO->ResolvePath("@devroot@", devAssetsRoot, AZ_MAX_PATH_LEN))
- {
- out = sourcePath;
- return;
- }
-
- AZStd::replace(devAssetsRoot, devAssetsRoot + AZ_MAX_PATH_LEN- 1, AZ_WRONG_FILESYSTEM_SEPARATOR, AZ_CORRECT_FILESYSTEM_SEPARATOR);
-
- // Find if the sourcePathArray is a sub directory of the devAssets folder
- // Keep reference to sourcePathArray long enough to use in PathView
- QByteArray sourcePathArray = sourcePath.toUtf8();
- AZ::IO::PathView sourcePathRootView(sourcePathArray.data());
- AZ::IO::PathView devAssetsRootView(devAssetsRoot);
- auto [sourcePathIter, devAssetsIter] = AZStd::mismatch(sourcePathRootView.begin(), sourcePathRootView.end(),
- devAssetsRootView.begin(), devAssetsRootView.end());
- // If the devAssets path iterator is not equal to the end, then there was a mismistch while comparing it
- // against the source path indicating that the source path is not a sub-directory
- if (devAssetsIter != devAssetsRootView.end())
- {
- out = sourcePath;
- return;
- }
-
- int offset = aznumeric_cast(strlen(devAssetsRoot));
- if (sourcePath.at(offset) == AZ_CORRECT_FILESYSTEM_SEPARATOR)
- {
- ++offset;
- }
- out = sourcePath.right(sourcePath.length() - offset);
-
-}
-
AssetImporterWindow::AssetImporterWindow()
: AssetImporterWindow(nullptr)
{
@@ -102,7 +68,7 @@ AssetImporterWindow::AssetImporterWindow(QWidget* parent)
AssetImporterWindow::~AssetImporterWindow()
{
- AZ_Assert(m_processingOverlayIndex == AZ::SceneAPI::UI::OverlayWidget::s_invalidOverlayIndex,
+ AZ_Assert(m_processingOverlayIndex == AZ::SceneAPI::UI::OverlayWidget::s_invalidOverlayIndex,
"Processing overlay (and potentially background thread) still active at destruction.");
AZ_Assert(!m_processingOverlay, "Processing overlay (and potentially background thread) still active at destruction.");
}
@@ -133,7 +99,7 @@ void AssetImporterWindow::OpenFile(const AZStd::string& filePath)
QMessageBox::warning(this, "In progress", "Unable to close one or more windows at this time.");
return;
}
-
+
OpenFileInternal(filePath);
}
@@ -146,7 +112,7 @@ void AssetImporterWindow::closeEvent(QCloseEvent* ev)
if (m_processingOverlay)
{
- AZ_Assert(m_processingOverlayIndex != AZ::SceneAPI::UI::OverlayWidget::s_invalidOverlayIndex,
+ AZ_Assert(m_processingOverlayIndex != AZ::SceneAPI::UI::OverlayWidget::s_invalidOverlayIndex,
"Processing overlay present, but not the index in the overlay for it.");
if (m_processingOverlay->HasProcessingCompleted())
{
@@ -157,7 +123,7 @@ void AssetImporterWindow::closeEvent(QCloseEvent* ev)
}
else
{
- QMessageBox::critical(this, "Processing In Progress", "Unable to close the result window at this time.",
+ QMessageBox::critical(this, "Processing In Progress", "Unable to close the result window at this time.",
QMessageBox::Ok, QMessageBox::Ok);
ev->ignore();
return;
@@ -165,7 +131,7 @@ void AssetImporterWindow::closeEvent(QCloseEvent* ev)
}
else
{
- QMessageBox::critical(this, "Processing In Progress", "Please wait until processing has completed to try again.",
+ QMessageBox::critical(this, "Processing In Progress", "Please wait until processing has completed to try again.",
QMessageBox::Ok, QMessageBox::Ok);
ev->ignore();
return;
@@ -199,7 +165,9 @@ void AssetImporterWindow::Init()
// Load the style sheets
AzQtComponents::StylesheetPreprocessor styleSheetProcessor(nullptr);
- AZStd::string mainWindowQSSPath = Path::GetEditingRootFolder() + "\\Editor\\Styles\\AssetImporterWindow.qss";
+ auto mainWindowQSSPath = AZ::IO::Path(AZ::Utils::GetEnginePath()) / "Assets";
+ mainWindowQSSPath /= "Editor/Styles/AssetImporterWindow.qss";
+ mainWindowQSSPath.MakePreferred();
QFile mainWindowStyleSheetFile(mainWindowQSSPath.c_str());
if (mainWindowStyleSheetFile.open(QFile::ReadOnly))
{
@@ -212,7 +180,7 @@ void AssetImporterWindow::Init()
{
ui->m_actionInspect->setVisible(false);
}
-
+
ResetMenuAccess(WindowState::InitialNothingLoaded);
// Setup the overlay system, and set the root to be the root display. The root display has the browse,
@@ -220,7 +188,7 @@ void AssetImporterWindow::Init()
m_overlay.reset(aznew AZ::SceneAPI::UI::OverlayWidget(this));
m_rootDisplay.reset(aznew ImporterRootDisplay(m_serializeContext));
connect(m_rootDisplay.data(), &ImporterRootDisplay::UpdateClicked, this, &AssetImporterWindow::UpdateClicked);
-
+
connect(m_overlay.data(), &AZ::SceneAPI::UI::OverlayWidget::LayerAdded, this, &AssetImporterWindow::OverlayLayerAdded);
connect(m_overlay.data(), &AZ::SceneAPI::UI::OverlayWidget::LayerRemoved, this, &AssetImporterWindow::OverlayLayerRemoved);
@@ -242,7 +210,7 @@ void AssetImporterWindow::Init()
AZStd::string joinedExtensions;
AzFramework::StringFunc::Join(joinedExtensions, extensions.begin(), extensions.end(), " or ");
- AZStd::string firstLineText =
+ AZStd::string firstLineText =
AZStd::string::format(
"%s files are available for use after placing them in any folder within your game project. "
"These files will automatically be processed and may be accessed via the Asset Browser. Learn more...",
@@ -250,13 +218,13 @@ void AssetImporterWindow::Init()
ui->m_initialPromptFirstLine->setText(firstLineText.c_str());
- AZStd::string secondLineText =
+ AZStd::string secondLineText =
AZStd::string::format("To adjust the %s settings, right-click the file in the Asset Browser and select \"Edit Settings\" from the context menu.", joinedExtensions.c_str());
ui->m_initialPromptSecondLine->setText(secondLineText.c_str());
}
else
{
- AZStd::string firstLineText =
+ AZStd::string firstLineText =
AZStd::string::format(
"Files are available for use after placing them in any folder within your game project. "
"These files will automatically be processed and may be accessed via the Asset Browser. Learn more...", s_documentationWebAddress);
@@ -282,12 +250,12 @@ void AssetImporterWindow::OpenFileInternal(const AZStd::string& filePath)
auto asyncLoadHandler = AZStd::make_shared(
s_browseTag,
[this, filePath]()
- {
- m_assetImporterDocument->LoadScene(filePath);
+ {
+ m_assetImporterDocument->LoadScene(filePath);
},
[this]()
{
- HandleAssetLoadingCompleted();
+ HandleAssetLoadingCompleted();
}, this);
m_processingOverlay.reset(new ProcessingOverlayWidget(m_overlay.data(), ProcessingOverlayWidget::Layout::Loading, s_browseTag));
@@ -304,7 +272,7 @@ bool AssetImporterWindow::IsAllowedToChangeSourceFile()
return true;
}
- QMessageBox messageBox(QMessageBox::Icon::NoIcon, "Unsaved changes",
+ QMessageBox messageBox(QMessageBox::Icon::NoIcon, "Unsaved changes",
"You have unsaved changes. Do you want to discard those changes?",
QMessageBox::StandardButton::Discard | QMessageBox::StandardButton::Cancel, this);
messageBox.exec();
@@ -406,7 +374,7 @@ void AssetImporterWindow::OnSceneResetRequested()
else
{
m_assetImporterDocument->ClearScene();
- AZ_TracePrintf(ErrorWindow, "Manifest reset returned in '%s'",
+ AZ_TracePrintf(ErrorWindow, "Manifest reset returned in '%s'",
result.GetResult() == ProcessingResult::Failure ? "Failure" : "Ignored");
}
},
@@ -456,7 +424,7 @@ void AssetImporterWindow::OnInspect()
// make sure the inspector doesn't outlive the AssetImporterWindow, since we own the data it will be inspecting.
auto* theInspectWidget = aznew AZ::SceneAPI::UI::SceneGraphInspectWidget(*m_assetImporterDocument->GetScene());
QObject::connect(this, &QObject::destroyed, theInspectWidget, [theInspectWidget]() { theInspectWidget->window()->close(); } );
-
+
m_overlay->PushLayer(label, theInspectWidget, "Scene Inspector", buttons);
}
@@ -483,7 +451,7 @@ void AssetImporterWindow::OverlayLayerRemoved()
else
{
ResetMenuAccess(WindowState::InitialNothingLoaded);
-
+
ui->m_initialBrowseContainer->show();
m_rootDisplay->hide();
}
@@ -533,8 +501,9 @@ void AssetImporterWindow::HandleAssetLoadingCompleted()
m_fullSourcePath = m_assetImporterDocument->GetScene()->GetSourceFilename();
SetTitle(m_fullSourcePath.c_str());
- QString userFriendlyFileName;
- MakeUserFriendlySourceAssetPath(userFriendlyFileName, m_fullSourcePath.c_str());
+ AZ::IO::FixedMaxPath projectPath = AZ::Utils::GetProjectPath();
+ AZ::IO::FixedMaxPath relativeSourcePath = AZ::IO::PathView(m_fullSourcePath).LexicallyProximate(projectPath);
+ auto userFriendlyFileName = QString::fromUtf8(relativeSourcePath.c_str(), static_cast(relativeSourcePath.Native().size()));
m_rootDisplay->SetSceneDisplay(userFriendlyFileName, m_assetImporterDocument->GetScene());
// Once we've browsed to something successfully, we need to hide the initial browse button layer and
diff --git a/Code/Editor/Plugins/EditorAssetImporter/SceneSerializationHandler.cpp b/Code/Editor/Plugins/EditorAssetImporter/SceneSerializationHandler.cpp
index b1d07af41c..5ee54667b9 100644
--- a/Code/Editor/Plugins/EditorAssetImporter/SceneSerializationHandler.cpp
+++ b/Code/Editor/Plugins/EditorAssetImporter/SceneSerializationHandler.cpp
@@ -7,9 +7,11 @@
*/
#include
+#include
#include
#include
#include
+#include
#include
#include
#include
@@ -50,22 +52,15 @@ namespace AZ
return nullptr;
}
- AZStd::string cleanPath = filePath;
- if (AzFramework::StringFunc::Path::IsRelative(filePath.c_str()))
+ AZ::IO::Path enginePath;
+ if (auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry != nullptr)
{
- const char* absolutePath = nullptr;
- AzToolsFramework::AssetSystemRequestBus::BroadcastResult(absolutePath,
- &AzToolsFramework::AssetSystemRequestBus::Events::GetAbsoluteDevRootFolderPath);
- AZ_Assert(absolutePath, "Unable to retrieve the dev folder path");
- AzFramework::StringFunc::Path::Join(absolutePath, cleanPath.c_str(), cleanPath);
- }
- else
- {
- // Normalizing is not needed if the path is relative as Join(...) will also normalize.
- AzFramework::StringFunc::Path::Normalize(cleanPath);
+ settingsRegistry->Get(enginePath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_EngineRootFolder);
}
- auto sceneIt = m_scenes.find(cleanPath);
+ AZ::IO::Path cleanPath = (enginePath / filePath).LexicallyNormal();
+
+ auto sceneIt = m_scenes.find(cleanPath.Native());
if (sceneIt != m_scenes.end())
{
AZStd::shared_ptr scene = sceneIt->second.lock();
@@ -98,14 +93,14 @@ namespace AZ
}
AZStd::shared_ptr scene =
- AssetImportRequest::LoadSceneFromVerifiedPath(cleanPath, sceneSourceGuid, AssetImportRequest::RequestingApplication::Editor, SceneAPI::SceneCore::LoadingComponent::TYPEINFO_Uuid());
+ AssetImportRequest::LoadSceneFromVerifiedPath(cleanPath.Native(), sceneSourceGuid, AssetImportRequest::RequestingApplication::Editor, SceneAPI::SceneCore::LoadingComponent::TYPEINFO_Uuid());
if (!scene)
{
AZ_TracePrintf(Utilities::ErrorWindow, "Failed to load the requested scene.");
return nullptr;
}
- m_scenes.emplace(AZStd::move(cleanPath), scene);
+ m_scenes.emplace(AZStd::move(cleanPath.Native()), scene);
return scene;
}
diff --git a/Code/Editor/Plugins/EditorCommon/CMakeLists.txt b/Code/Editor/Plugins/EditorCommon/CMakeLists.txt
index cd9f2e79c7..609482b581 100644
--- a/Code/Editor/Plugins/EditorCommon/CMakeLists.txt
+++ b/Code/Editor/Plugins/EditorCommon/CMakeLists.txt
@@ -39,7 +39,6 @@ ly_add_target(
EDITOR_COMMON_IMPORTS
BUILD_DEPENDENCIES
PRIVATE
- 3rdParty::zlib
3rdParty::Qt::Core
3rdParty::Qt::Widgets
Legacy::CryCommon
diff --git a/Code/Editor/Plugins/ProjectSettingsTool/ProjectSettingsToolWindow.cpp b/Code/Editor/Plugins/ProjectSettingsTool/ProjectSettingsToolWindow.cpp
index 6b454474be..a53ce966c4 100644
--- a/Code/Editor/Plugins/ProjectSettingsTool/ProjectSettingsToolWindow.cpp
+++ b/Code/Editor/Plugins/ProjectSettingsTool/ProjectSettingsToolWindow.cpp
@@ -46,7 +46,6 @@ namespace ProjectSettingsTool
, LastPathBus::Handler()
, m_ui(new Ui::ProjectSettingsToolWidget())
, m_reconfigureProcess()
- , m_devRoot(GetDevRoot())
, m_projectRoot(GetProjectRoot())
, m_projectName(GetProjectName())
, m_plistsInitVector(
diff --git a/Code/Editor/Plugins/ProjectSettingsTool/ProjectSettingsToolWindow.h b/Code/Editor/Plugins/ProjectSettingsTool/ProjectSettingsToolWindow.h
index 1c9aa4b1bf..daa5bea27c 100644
--- a/Code/Editor/Plugins/ProjectSettingsTool/ProjectSettingsToolWindow.h
+++ b/Code/Editor/Plugins/ProjectSettingsTool/ProjectSettingsToolWindow.h
@@ -147,7 +147,6 @@ namespace ProjectSettingsTool
// The process used to reconfigure settings
QProcess m_reconfigureProcess;
- AZStd::string m_devRoot;
AZStd::string m_projectRoot;
AZStd::string m_projectName;
diff --git a/Code/Editor/Plugins/ProjectSettingsTool/Utils.cpp b/Code/Editor/Plugins/ProjectSettingsTool/Utils.cpp
index 0e171adf04..d5b94469cc 100644
--- a/Code/Editor/Plugins/ProjectSettingsTool/Utils.cpp
+++ b/Code/Editor/Plugins/ProjectSettingsTool/Utils.cpp
@@ -27,37 +27,31 @@ namespace
}
template
- StringType GetAbsoluteDevRoot()
+ StringType GetAbsoluteEngineRoot()
{
- const char* devRoot = nullptr;
- AzToolsFramework::AssetSystemRequestBus::BroadcastResult(
- devRoot,
- &AzToolsFramework::AssetSystemRequestBus::Handler::GetAbsoluteDevRootFolderPath);
+ AZ::IO::FixedMaxPath engineRoot = AZ::Utils::GetEnginePath();
- if (!devRoot)
+ if (engineRoot.empty())
{
return "";
}
- StringType devRootString(devRoot);
- ToUnixPath(devRootString);
- return devRootString;
+ StringType engineRootString(engineRoot.c_str());
+ ToUnixPath(engineRootString);
+ return engineRootString;
}
template
StringType GetAbsoluteProjectRoot()
{
- const char* projectRoot = nullptr;
- AzToolsFramework::AssetSystemRequestBus::BroadcastResult(
- projectRoot,
- &AzToolsFramework::AssetSystemRequestBus::Handler::GetAbsoluteDevGameFolderPath);
+ AZ::IO::FixedMaxPath projectRoot = AZ::Utils::GetProjectPath();
- if (!projectRoot)
+ if (projectRoot.empty())
{
return "";
}
- StringType projectRootString(projectRoot);
+ StringType projectRootString(projectRoot.c_str());
ToUnixPath(projectRootString);
return projectRootString;
}
@@ -87,9 +81,9 @@ namespace ProjectSettingsTool
return reinterpret_cast(func);
}
- AZStd::string GetDevRoot()
+ AZStd::string GetEngineRoot()
{
- return GetAbsoluteDevRoot();
+ return GetAbsoluteEngineRoot();
}
AZStd::string GetProjectRoot()
{
@@ -104,7 +98,7 @@ namespace ProjectSettingsTool
QString SelectXmlFromFileDialog(const QString& currentFile)
{
// The selected file must be relative to this path
- QString defaultPath = GetAbsoluteDevRoot();
+ QString defaultPath = GetAbsoluteEngineRoot();
QString startPath;
// Choose the starting path for file dialog
@@ -139,7 +133,7 @@ namespace ProjectSettingsTool
QString SelectImageFromFileDialog(const QString& currentFile)
{
- QString defaultPath = QStringLiteral("%1Code%2/Resources/").arg(GetAbsoluteDevRoot(), ::GetProjectName());
+ QString defaultPath = QStringLiteral("%1Code%2/Resources/").arg(GetAbsoluteEngineRoot(), ::GetProjectName());
QString startPath;
@@ -188,7 +182,7 @@ namespace ProjectSettingsTool
// Android
if (group <= ImageGroup::AndroidPortrait)
{
- root = GetDevRoot() + "/Code/Tools/Android/ProjectBuilder/app_";
+ root = GetEngineRoot() + "/Code/Tools/Android/ProjectBuilder/app_";
}
//Ios
else
diff --git a/Code/Editor/Plugins/ProjectSettingsTool/Utils.h b/Code/Editor/Plugins/ProjectSettingsTool/Utils.h
index 4226d534a6..050fb3b85b 100644
--- a/Code/Editor/Plugins/ProjectSettingsTool/Utils.h
+++ b/Code/Editor/Plugins/ProjectSettingsTool/Utils.h
@@ -17,7 +17,7 @@
namespace ProjectSettingsTool
{
void* ConvertFunctorToVoid(AZStd::pair(*func)(const QString&));
- AZStd::string GetDevRoot();
+ AZStd::string GetEngineRoot();
AZStd::string GetProjectRoot();
AZStd::string GetProjectName();
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/Settings.cpp b/Code/Editor/Settings.cpp
index 05a6960695..d548cffb52 100644
--- a/Code/Editor/Settings.cpp
+++ b/Code/Editor/Settings.cpp
@@ -10,6 +10,7 @@
#include "EditorDefs.h"
#include "Settings.h"
+#include "EditorViewportSettings.h"
// Qt
#include
@@ -487,7 +488,6 @@ void SEditorSettings::Save()
SaveValue("Settings", "AutoBackupTime", autoBackupTime);
SaveValue("Settings", "AutoBackupMaxCount", autoBackupMaxCount);
SaveValue("Settings", "AutoRemindTime", autoRemindTime);
- SaveValue("Settings", "MaxDisplayedItemsNumInSearch", maxNumberOfItemsShownInSearch);
SaveValue("Settings", "CameraMoveSpeed", cameraMoveSpeed);
SaveValue("Settings", "CameraRotateSpeed", cameraRotateSpeed);
SaveValue("Settings", "StylusMode", stylusMode);
@@ -682,7 +682,6 @@ void SEditorSettings::Load()
LoadValue("Settings", "AutoBackupTime", autoBackupTime);
LoadValue("Settings", "AutoBackupMaxCount", autoBackupMaxCount);
LoadValue("Settings", "AutoRemindTime", autoRemindTime);
- LoadValue("Settings", "MaxDisplayedItemsNumInSearch", maxNumberOfItemsShownInSearch);
LoadValue("Settings", "CameraMoveSpeed", cameraMoveSpeed);
LoadValue("Settings", "CameraRotateSpeed", cameraRotateSpeed);
LoadValue("Settings", "StylusMode", stylusMode);
@@ -935,8 +934,9 @@ void SEditorSettings::LoadDefaultGamePaths()
searchPaths[EDITOR_PATH_MATERIALS].push_back((Path::GetEditingGameDataFolder() + "/Materials").c_str());
}
- AZStd::string iconsPath;
- AZ::StringFunc::Path::Join(Path::GetEditingRootFolder().c_str(), "Editor/UI/Icons", iconsPath);
+ auto iconsPath = AZ::IO::Path(AZ::Utils::GetEnginePath()) / "Assets";
+ iconsPath /= "Editor/UI/Icons";
+ iconsPath.MakePreferred();
searchPaths[EDITOR_PATH_UI_ICONS].push_back(iconsPath.c_str());
}
@@ -1173,7 +1173,7 @@ AzToolsFramework::ConsoleColorTheme SEditorSettings::GetConsoleColorTheme() cons
return consoleBackgroundColorTheme;
}
-int SEditorSettings::GetMaxNumberOfItemsShownInSearchView() const
+AZ::u64 SEditorSettings::GetMaxNumberOfItemsShownInSearchView() const
{
- return SEditorSettings::maxNumberOfItemsShownInSearch;
+ return SandboxEditor::MaxItemsShownInAssetBrowserSearch();
}
diff --git a/Code/Editor/Settings.h b/Code/Editor/Settings.h
index 8bf22b43e5..426d2300d3 100644
--- a/Code/Editor/Settings.h
+++ b/Code/Editor/Settings.h
@@ -279,7 +279,7 @@ AZ_POP_DISABLE_DLL_EXPORT_BASECLASS_WARNING
SettingOutcome GetValue(const AZStd::string_view path) override;
SettingOutcome SetValue(const AZStd::string_view path, const AZStd::any& value) override;
AzToolsFramework::ConsoleColorTheme GetConsoleColorTheme() const override;
- int GetMaxNumberOfItemsShownInSearchView() const override;
+ AZ::u64 GetMaxNumberOfItemsShownInSearchView() const override;
void ConvertPath(const AZStd::string_view sourcePath, AZStd::string& category, AZStd::string& attribute);
@@ -353,14 +353,6 @@ AZ_POP_DISABLE_DLL_EXPORT_BASECLASS_WARNING
int autoRemindTime;
//////////////////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////////////////
- // Asset Browser Search View.
- //////////////////////////////////////////////////////////////////////////
- //! Current maximum number of items that can be displayed in the AssetBrowser Search View.
- int maxNumberOfItemsShownInSearch;
- //////////////////////////////////////////////////////////////////////////
-
-
//! If true preview windows is displayed when browsing geometries.
bool bPreviewGeometryWindow;
diff --git a/Code/Editor/TrackView/SequenceBatchRenderDialog.cpp b/Code/Editor/TrackView/SequenceBatchRenderDialog.cpp
index b510315995..d7901e338a 100644
--- a/Code/Editor/TrackView/SequenceBatchRenderDialog.cpp
+++ b/Code/Editor/TrackView/SequenceBatchRenderDialog.cpp
@@ -269,7 +269,7 @@ void CSequenceBatchRenderDialog::OnRenderItemSelChange()
// Enable/disable the 'remove'/'update' button properly.
bool bNoSelection = !m_ui->m_renderList->selectionModel()->hasSelection();
m_ui->BATCH_RENDER_REMOVE_SEQ->setEnabled(bNoSelection ? false : true);
-
+
CheckForEnableUpdateButton();
if (bNoSelection)
@@ -360,7 +360,7 @@ void CSequenceBatchRenderDialog::OnRenderItemSelChange()
cvarsText += item.cvars[static_cast(i)];
cvarsText += "\r\n";
}
- m_ui->m_cvarsEdit->setPlainText(cvarsText);
+ m_ui->m_cvarsEdit->setPlainText(cvarsText);
}
void CSequenceBatchRenderDialog::CheckForEnableUpdateButton()
@@ -494,7 +494,7 @@ void CSequenceBatchRenderDialog::OnSavePreset()
}
void CSequenceBatchRenderDialog::stashActiveViewportResolution()
-{
+{
// stash active resolution in global vars
activeViewportWidth = resolutions[0][0];
activeViewportHeight = resolutions[0][1];
@@ -502,7 +502,7 @@ void CSequenceBatchRenderDialog::stashActiveViewportResolution()
if (activeViewport)
{
activeViewport->GetDimensions(&activeViewportWidth, &activeViewportHeight);
- }
+ }
}
void CSequenceBatchRenderDialog::OnGo()
@@ -640,7 +640,7 @@ void CSequenceBatchRenderDialog::OnResolutionSelected()
int defaultH;
const QString currentCustomResText = m_ui->m_resolutionCombo->currentText();
GetResolutionFromCustomResText(currentCustomResText.toStdString().c_str(), defaultW, defaultH);
-
+
CCustomResolutionDlg resDlg(defaultW, defaultH, this);
if (resDlg.exec() == QDialog::Accepted)
{
@@ -752,7 +752,7 @@ bool CSequenceBatchRenderDialog::LoadOutputOptions(const QString& pathname)
{
const QString customResText = resolutionNode->getContent();
m_ui->m_resolutionCombo->setItemText(curSel, customResText);
-
+
GetResolutionFromCustomResText(customResText.toStdString().c_str(), m_customResW, m_customResH);
}
m_ui->m_resolutionCombo->setCurrentIndex(curSel);
@@ -907,12 +907,12 @@ void CSequenceBatchRenderDialog::CaptureItemStart()
folder += "/";
folder += itemText;
- // If this is a relative path, prepend the @assets@ folder to match where the Renderer is going
+ // If this is a relative path, prepend the @products@ folder to match where the Renderer is going
// to dump the frame buffer image captures.
if (AzFramework::StringFunc::Path::IsRelative(folder.toUtf8().data()))
{
AZStd::string absolutePath;
- AZStd::string assetsRoot = AZ::IO::FileIOBase::GetInstance()->GetAlias("@assets@");
+ AZStd::string assetsRoot = AZ::IO::FileIOBase::GetInstance()->GetAlias("@products@");
AzFramework::StringFunc::Path::Join(assetsRoot.c_str(), folder.toUtf8().data(), absolutePath);
folder = absolutePath.c_str();
}
@@ -962,7 +962,7 @@ void CSequenceBatchRenderDialog::CaptureItemStart()
m_renderContext.cvarDisplayInfoBU = cvarDebugInfo->GetIVal();
if (renderItem.disableDebugInfo && cvarDebugInfo->GetIVal())
{
- const int DISPLAY_INFO_OFF = 0;
+ const int DISPLAY_INFO_OFF = 0;
cvarDebugInfo->Set(DISPLAY_INFO_OFF);
}
}
@@ -1100,13 +1100,13 @@ void CSequenceBatchRenderDialog::OnUpdateEnd(IAnimSequence* sequence)
sequence->SetActiveDirector(m_renderContext.pActiveDirectorBU);
const auto imageFormat = m_ui->m_imageFormatCombo->currentText();
-
+
SRenderItem renderItem = m_renderItems[m_renderContext.currentItemIndex];
if (m_bFFMPEGCommandAvailable && renderItem.bCreateVideo)
{
// Create a video using the ffmpeg plug-in from captured images.
m_renderContext.processingFFMPEG = true;
-
+
AZStd::string outputFolder = m_renderContext.captureOptions.folder;
auto future = QtConcurrent::run(
[renderItem, outputFolder, imageFormat]
@@ -1238,7 +1238,7 @@ void CSequenceBatchRenderDialog::OnKickIdleTimout()
}
void CSequenceBatchRenderDialog::OnKickIdle()
-{
+{
if (m_renderContext.captureState == CaptureState::WarmingUpAfterResChange)
{
OnUpdateWarmingUpAfterResChange();
@@ -1254,7 +1254,7 @@ void CSequenceBatchRenderDialog::OnKickIdle()
else if (m_renderContext.captureState == CaptureState::Capturing)
{
OnUpdateCapturing();
- }
+ }
else if (m_renderContext.captureState == CaptureState::End)
{
OnUpdateEnd(m_renderContext.endingSequence);
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/PathUtil.cpp b/Code/Editor/Util/PathUtil.cpp
index c9e6823824..ca3481ddae 100644
--- a/Code/Editor/Util/PathUtil.cpp
+++ b/Code/Editor/Util/PathUtil.cpp
@@ -11,9 +11,9 @@
#include "PathUtil.h"
-#include // for AZ_MAX_PATH_LEN
+#include
+#include
#include // for ebus events
-#include
#include
#include
#include
@@ -179,7 +179,7 @@ namespace Path
EBUS_EVENT_RESULT(engineRoot, AzFramework::ApplicationRequests::Bus, GetEngineRoot);
return QString(engineRoot);
}
-
+
//////////////////////////////////////////////////////////////////////////
QString& ReplaceFilename(const QString& strFilepath, const QString& strFilename, QString& strOutputFilename, bool bCallCaselessPath)
{
@@ -216,30 +216,21 @@ namespace Path
//////////////////////////////////////////////////////////////////////////
QString GetResolvedUserSandboxFolder()
{
- char resolvedPath[AZ_MAX_PATH_LEN] = { 0 };
- gEnv->pFileIO->ResolvePath(GetUserSandboxFolder().toUtf8().data(), resolvedPath, AZ_MAX_PATH_LEN);
- return QString::fromLatin1(resolvedPath);
+ AZ::IO::FixedMaxPath userSandboxFolderPath;
+ gEnv->pFileIO->ResolvePath(userSandboxFolderPath, GetUserSandboxFolder().toUtf8().constData());
+ return QString::fromUtf8(userSandboxFolderPath.c_str(), static_cast(userSandboxFolderPath.Native().size()));
}
// internal function, you should use GetEditingGameDataFolder instead.
AZStd::string GetGameAssetsFolder()
{
- const char* resultValue = nullptr;
- EBUS_EVENT_RESULT(resultValue, AzToolsFramework::AssetSystemRequestBus, GetAbsoluteDevGameFolderPath);
- if (!resultValue)
- {
- if ((gEnv) && (gEnv->pFileIO))
- {
- resultValue = gEnv->pFileIO->GetAlias("@devassets@");
- }
- }
-
- if (!resultValue)
+ AZ::IO::Path projectPath;
+ if (auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry != nullptr)
{
- resultValue = ".";
+ settingsRegistry->Get(projectPath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_ProjectPath);
}
- return resultValue;
+ return projectPath.Native();
}
/// Get the data folder
@@ -258,26 +249,6 @@ namespace Path
return str;
}
- //! Get the root folder (in source control or other writable assets) where you should save root data.
- AZStd::string GetEditingRootFolder()
- {
- const char* resultValue = nullptr;
- EBUS_EVENT_RESULT(resultValue, AzToolsFramework::AssetSystemRequestBus, GetAbsoluteDevRootFolderPath);
-
- if (!resultValue)
- {
- if ((gEnv) && (gEnv->pFileIO))
- {
- resultValue = gEnv->pFileIO->GetAlias("@devassets@");
- }
- }
- if (!resultValue)
- {
- resultValue = ".";
- }
- return resultValue;
- }
-
AZStd::string MakeModPathFromGamePath(const char* relGamePath)
{
@@ -335,165 +306,60 @@ namespace Path
return "";
}
- bool relPathfound = false;
+ bool relPathFound = false;
AZStd::string relativePath;
AZStd::string fullAssetPath(fullPath.toUtf8().data());
- EBUS_EVENT_RESULT(relPathfound, AzToolsFramework::AssetSystemRequestBus, GetRelativeProductPathFromFullSourceOrProductPath, fullAssetPath, relativePath);
+ EBUS_EVENT_RESULT(relPathFound, AzToolsFramework::AssetSystemRequestBus, GetRelativeProductPathFromFullSourceOrProductPath, fullAssetPath, relativePath);
- if (relPathfound)
+ if (relPathFound)
{
// do not normalize this path, it will already be an appropriate asset ID.
return CaselessPaths(relativePath.c_str());
}
- char rootpath[_MAX_PATH] = { 0 };
- azstrcpy(rootpath, _MAX_PATH, Path::GetEditingRootFolder().c_str());
-
- if (bRelativeToGameFolder)
- {
- azstrcpy(rootpath, _MAX_PATH, Path::GetEditingGameDataFolder().c_str());
- }
-
- QString rootPathNormalized(rootpath);
- QString srcPathNormalized(fullPath);
-
-#if defined(AZ_PLATFORM_WINDOWS)
- // avoid confusing PathRelativePathTo
- rootPathNormalized.replace('/', '\\');
- srcPathNormalized.replace('/', '\\');
-#endif
+ AZ::IO::FixedMaxPath rootPath = bRelativeToGameFolder ? AZ::Utils::GetProjectPath() : AZ::Utils::GetEnginePath();
+ AZ::IO::FixedMaxPath resolvedFullPath;
+ AZ::IO::FileIOBase::GetDirectInstance()->ResolvePath(resolvedFullPath, fullPath.toUtf8().constData());
// Create relative path
- char resolvedSrcPath[AZ_MAX_PATH_LEN] = { 0 };
- AZ::IO::FileIOBase::GetDirectInstance()->ResolvePath(srcPathNormalized.toUtf8().data(), resolvedSrcPath, AZ_MAX_PATH_LEN);
- QByteArray path = QDir(rootPathNormalized).relativeFilePath(resolvedSrcPath).toUtf8();
- if (path.isEmpty())
- {
- return fullPath;
- }
- // The following code is required because the windows PathRelativePathTo function will always return "./SomePath" instead of just "SomePath"
- // Only remove single dot (.) and slash parts of a path, never the double dot (..)
- const char* pBuffer = path.data();
- bool bHasDot = false;
- while (*pBuffer && pBuffer != path.end())
- {
- switch (*pBuffer)
- {
- case '.':
- if (bHasDot)
- {
- // Found a double dot, rewind and stop removing
- pBuffer--;
- break;
- }
- // Fall through intended
- case '/':
- case '\\':
- bHasDot = (*pBuffer == '.');
- pBuffer++;
- continue;
- }
- break;
- }
-
- QString relPath = pBuffer;
- return CaselessPaths(relPath);
+ return CaselessPaths(resolvedFullPath.LexicallyProximate(rootPath).MakePreferred().c_str());
}
QString GamePathToFullPath(const QString& path)
{
using namespace AzToolsFramework;
- AZ_Warning("GamePathToFullPath", path.size() <= AZ_MAX_PATH_LEN, "Path exceeds maximum path length of %d", AZ_MAX_PATH_LEN);
- if ((gEnv) && (gEnv->pFileIO) && gEnv->pCryPak && path.size() <= AZ_MAX_PATH_LEN)
+ AZ_Warning("GamePathToFullPath", path.size() <= AZ::IO::MaxPathLength, "Path exceeds maximum path length of %zu", AZ::IO::MaxPathLength);
+ if (path.size() <= AZ::IO::MaxPathLength)
{
// first, adjust the file name for mods:
- bool fullPathfound = false;
- AZStd::string assetFullPath;
- AZStd::string adjustedFilePath = path.toUtf8().data();
- AssetSystemRequestBus::BroadcastResult(fullPathfound, &AssetSystemRequestBus::Events::GetFullSourcePathFromRelativeProductPath, adjustedFilePath, assetFullPath);
- if (fullPathfound)
+ bool fullPathFound = false;
+ AZ::IO::Path assetFullPath;
+ AZ::IO::Path adjustedFilePath = path.toUtf8().constData();
+ AssetSystemRequestBus::BroadcastResult(fullPathFound, &AssetSystemRequestBus::Events::GetFullSourcePathFromRelativeProductPath,
+ adjustedFilePath.Native(), assetFullPath.Native());
+ if (fullPathFound)
{
- //if the bus message succeeds than normalize and lowercase the path
- AzFramework::StringFunc::Path::Normalize(assetFullPath);
- return assetFullPath.c_str();
+ //if the bus message succeeds than normalize
+ return assetFullPath.LexicallyNormal().c_str();
}
- // if the bus message didn't succeed, 'guess' the source assets:
+ // if the bus message didn't succeed, check if he path exist as a resolved path
else
{
// Not all systems have been converted to use local paths. Some editor files save XML files directly, and a full or correctly aliased path is already passed in.
// If the path passed in exists already, then return the resolved filepath
if (AZ::IO::FileIOBase::GetDirectInstance()->Exists(adjustedFilePath.c_str()))
{
- char resolvedPath[AZ_MAX_PATH_LEN + PathUtil::maxAliasLength] = { 0 };
- AZ::IO::FileIOBase::GetDirectInstance()->ResolvePath(adjustedFilePath.c_str(), resolvedPath, AZ_MAX_PATH_LEN + PathUtil::maxAliasLength);
- return QString::fromUtf8(resolvedPath);
+ AZ::IO::FixedMaxPath resolvedPath;
+ AZ::IO::FileIOBase::GetDirectInstance()->ResolvePath(resolvedPath, adjustedFilePath);
+ return QString::fromUtf8(resolvedPath.c_str(), static_cast(resolvedPath.Native().size()));
}
- // if we get here it means that the Asset Processor does not know about this file. most of the time we should never get here
- // the rest of this code just does a bunch of heuristic guesses in case of missing files or if the user has hand-edited
- // the asset cache by moving files in via some other means or external process.
- if (adjustedFilePath[0] != '@')
- {
- const char* prefix = (adjustedFilePath[0] == '/' || adjustedFilePath[0] == '\\') ? "@devassets@" : "@devassets@/";
- adjustedFilePath = prefix + adjustedFilePath;
- }
-
- char szAdjustedFile[AZ_MAX_PATH_LEN + PathUtil::maxAliasLength] = { 0 };
- gEnv->pFileIO->ResolvePath(adjustedFilePath.c_str(), szAdjustedFile, AZ_ARRAY_SIZE(szAdjustedFile));
-
- if ((azstrnicmp(szAdjustedFile, "@devassets@", 11) == 0) && ((szAdjustedFile[11] == '/') || (szAdjustedFile[11] == '\\')))
- {
- if (!gEnv->pCryPak->IsFileExist(szAdjustedFile))
- {
- AZStd::string newName(szAdjustedFile);
- AzFramework::StringFunc::Replace(newName, "@devassets@", "@devroot@/engine", false);
-
- if (gEnv->pCryPak->IsFileExist(newName.c_str()))
- {
- azstrcpy(szAdjustedFile, AZ_ARRAY_SIZE(szAdjustedFile), newName.c_str());
- }
- else
- {
- // getting tricky here, try @devroot@ alone, in case its 'editor'
- AzFramework::StringFunc::Replace(newName, "@devassets@", "@devroot@", false);
- if (gEnv->pCryPak->IsFileExist(szAdjustedFile))
- {
- azstrcpy(szAdjustedFile, AZ_ARRAY_SIZE(szAdjustedFile), newName.c_str());
- }
- // give up, best guess is just @devassets@
- }
- }
- }
-
- // we should very rarely actually get to this point in the code.
-
- // szAdjustedFile may contain an alias at this point. (@assets@/blah.whatever)
- // there is a case in which the loose asset exists only within a pak file for some reason
- // this is not recommended but it is possible.in that case, we want to return the original szAdjustedFile
- // without touching it or resolving it so that crypak can open it successfully.
- char adjustedPath[AZ_MAX_PATH_LEN + PathUtil::maxAliasLength] = { 0 };
- if (gEnv->pFileIO->ResolvePath(szAdjustedFile, adjustedPath, AZ_MAX_PATH_LEN + PathUtil::maxAliasLength)) // resolve to full path
- {
- if ((gEnv->pCryPak->IsFileExist(adjustedPath)) || (!gEnv->pCryPak->IsFileExist(szAdjustedFile)))
- {
- // note that if we get here, then EITHER
- // the file exists as a loose asset in the actual adjusted path
- // OR the file does not exist in the original passed-in aliased name (like '@assets@/whatever')
- // in which case we may as well just resolve the path to a full path and return it.
- assetFullPath = adjustedPath;
- AzFramework::StringFunc::Path::Normalize(assetFullPath);
- azstrcpy(szAdjustedFile, AZ_MAX_PATH_LEN + PathUtil::maxAliasLength, assetFullPath.c_str());
- }
- // if the above case succeeded then it means that the file does NOT exist loose
- // but DOES exist in a pak, in which case we leave szAdjustedFile with the alias on the front of it, meaning
- // fopens via crypak will actually succeed.
- }
- return szAdjustedFile;
+ return path;
}
}
else
{
- return "";
+ return QString{};
}
}
diff --git a/Code/Editor/Util/PathUtil.h b/Code/Editor/Util/PathUtil.h
index 2c49031155..163d74e358 100644
--- a/Code/Editor/Util/PathUtil.h
+++ b/Code/Editor/Util/PathUtil.h
@@ -44,9 +44,6 @@ namespace Path
//! always returns a full path
EDITOR_CORE_API AZStd::string GetEditingGameDataFolder();
- //! Get the root folder (in source control or other writable assets) where you should save root data.
- EDITOR_CORE_API AZStd::string GetEditingRootFolder();
-
//! Set the current mod NAME for editing purposes. After doing this the above functions will take this into account
//! name only, please!
EDITOR_CORE_API void SetModName(const char* input);
@@ -69,93 +66,6 @@ namespace Path
return strPath;
}
- //! Split full file name to path and filename
- //! @param filepath [IN] Full file name inclusing path.
- //! @param path [OUT] Extracted file path.
- //! @param file [OUT] Extracted file (with extension).
- inline void Split(const QString& filepath, QString& path, QString& file)
- {
- char path_buffer[_MAX_PATH];
- char drive[_MAX_DRIVE];
- char dir[_MAX_DIR];
- char fname[_MAX_FNAME];
- char ext[_MAX_EXT];
-#ifdef AZ_COMPILER_MSVC
- _splitpath_s(filepath.toUtf8().data(), drive, AZ_ARRAY_SIZE(drive), dir, AZ_ARRAY_SIZE(dir), fname, AZ_ARRAY_SIZE(fname), ext, AZ_ARRAY_SIZE(ext));
- _makepath_s(path_buffer, AZ_ARRAY_SIZE(path_buffer), drive, dir, 0, 0);
- path = path_buffer;
- _makepath_s(path_buffer, AZ_ARRAY_SIZE(path_buffer), 0, 0, fname, ext);
-#else
- _splitpath(filepath.toUtf8().data(), drive, dir, fname, ext);
- _makepath(path_buffer, drive, dir, 0, 0);
- path = path_buffer;
- _makepath(path_buffer, 0, 0, fname, ext);
-#endif
- file = path_buffer;
- }
- inline void Split(const AZStd::string& filepath, AZStd::string& path, AZStd::string& file)
- {
- char path_buffer[_MAX_PATH];
- char drive[_MAX_DRIVE];
- char dir[_MAX_DIR];
- char fname[_MAX_FNAME];
- char ext[_MAX_EXT];
-#ifdef AZ_COMPILER_MSVC
- _splitpath_s(filepath.c_str(), drive, AZ_ARRAY_SIZE(drive), dir, AZ_ARRAY_SIZE(dir), 0, 0, 0, 0);
- _makepath_s(path_buffer, AZ_ARRAY_SIZE(path_buffer), drive, dir, 0, 0);
- path = path_buffer;
- _makepath_s(path_buffer, AZ_ARRAY_SIZE(path_buffer), 0, 0, fname, ext);
-#else
- _splitpath(filepath.c_str(), drive, dir, fname, ext);
- _makepath(path_buffer, drive, dir, 0, 0);
- path = path_buffer;
- _makepath(path_buffer, 0, 0, fname, ext);
-#endif
- file = path_buffer;
- }
-
- //! Split full file name to path and filename
- //! @param filepath [IN] Full file name inclusing path.
- //! @param path [OUT] Extracted file path.
- //! @param filename [OUT] Extracted file (without extension).
- //! @param ext [OUT] Extracted files extension.
- inline void Split(const QString& filepath, QString& path, QString& filename, QString& fext)
- {
- char path_buffer[_MAX_PATH];
- char drive[_MAX_DRIVE];
- char dir[_MAX_DIR];
- char fname[_MAX_FNAME];
- char ext[_MAX_EXT];
-#ifdef AZ_COMPILER_MSVC
- _splitpath_s(filepath.toUtf8().data(), drive, AZ_ARRAY_SIZE(drive), dir, AZ_ARRAY_SIZE(dir), fname, AZ_ARRAY_SIZE(fname), ext, AZ_ARRAY_SIZE(ext));
- _makepath_s(path_buffer, AZ_ARRAY_SIZE(path_buffer), drive, dir, 0, 0);
-#else
- _splitpath(filepath.toUtf8().data(), drive, dir, fname, ext);
- _makepath(path_buffer, drive, dir, 0, 0);
-#endif
- path = path_buffer;
- filename = fname;
- fext = ext;
- }
- inline void Split(const AZStd::string& filepath, AZStd::string& path, AZStd::string& filename, AZStd::string& fext)
- {
- char path_buffer[_MAX_PATH];
- char drive[_MAX_DRIVE];
- char dir[_MAX_DIR];
- char fname[_MAX_FNAME];
- char ext[_MAX_EXT];
-#ifdef AZ_COMPILER_MSVC
- _splitpath_s(filepath.c_str(), drive, AZ_ARRAY_SIZE(drive), dir, AZ_ARRAY_SIZE(dir), fname, AZ_ARRAY_SIZE(fname), ext, AZ_ARRAY_SIZE(ext));
- _makepath_s(path_buffer, AZ_ARRAY_SIZE(path_buffer), drive, dir, 0, 0);
-#else
- _splitpath(filepath.c_str(), drive, dir, fname, ext);
- _makepath(path_buffer, drive, dir, 0, 0);
-#endif
- path = path_buffer;
- filename = fname;
- fext = ext;
- }
-
//! Split path into segments
//! @param filepath [IN] path
inline QStringList SplitIntoSegments(const QString& path)
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/Asset/AssetJsonSerializer.cpp b/Code/Framework/AzCore/AzCore/Asset/AssetJsonSerializer.cpp
index 3a83aa5d1c..3fa3b39ca5 100644
--- a/Code/Framework/AzCore/AzCore/Asset/AssetJsonSerializer.cpp
+++ b/Code/Framework/AzCore/AzCore/Asset/AssetJsonSerializer.cpp
@@ -173,6 +173,7 @@ namespace AZ
if (assetTracker)
{
+ assetTracker->FixUpAsset(*instance);
assetTracker->AddAsset(*instance);
}
@@ -185,7 +186,20 @@ namespace AZ
return context.Report(result, message);
}
- void SerializedAssetTracker::AddAsset(Asset& asset)
+ void SerializedAssetTracker::SetAssetFixUp(AssetFixUp assetFixUpCallback)
+ {
+ m_assetFixUpCallback = AZStd::move(assetFixUpCallback);
+ }
+
+ void SerializedAssetTracker::FixUpAsset(Asset& asset)
+ {
+ if (m_assetFixUpCallback)
+ {
+ m_assetFixUpCallback(asset);
+ }
+ }
+
+ void SerializedAssetTracker::AddAsset(Asset asset)
{
m_serializedAssets.emplace_back(asset);
}
@@ -199,5 +213,6 @@ namespace AZ
{
return m_serializedAssets;
}
+
} // namespace Data
} // namespace AZ
diff --git a/Code/Framework/AzCore/AzCore/Asset/AssetJsonSerializer.h b/Code/Framework/AzCore/AzCore/Asset/AssetJsonSerializer.h
index 879952c82d..e1b8cda00d 100644
--- a/Code/Framework/AzCore/AzCore/Asset/AssetJsonSerializer.h
+++ b/Code/Framework/AzCore/AzCore/Asset/AssetJsonSerializer.h
@@ -39,13 +39,18 @@ namespace AZ
{
public:
AZ_RTTI(SerializedAssetTracker, "{1E067091-8C0A-44B1-A455-6E97663F6963}");
+ using AssetFixUp = AZStd::function& asset)>;
- void AddAsset(Asset& asset);
+ void SetAssetFixUp(AssetFixUp assetFixUpCallback);
+ void FixUpAsset(Asset& asset);
+
+ void AddAsset(Asset asset);
AZStd::vector>& GetTrackedAssets();
const AZStd::vector>& GetTrackedAssets() const;
private:
AZStd::vector> m_serializedAssets;
+ AssetFixUp m_assetFixUpCallback;
};
} // namespace Data
} // namespace AZ
diff --git a/Code/Framework/AzCore/AzCore/Console/Console.cpp b/Code/Framework/AzCore/AzCore/Console/Console.cpp
index a1b8a1759d..79e1f79697 100644
--- a/Code/Framework/AzCore/AzCore/Console/Console.cpp
+++ b/Code/Framework/AzCore/AzCore/Console/Console.cpp
@@ -225,8 +225,16 @@ namespace AZ
ConsoleCommandContainer commandSubset;
- for (ConsoleFunctorBase* curr = m_head; curr != nullptr; curr = curr->m_next)
+ for (const auto& functor : m_commands)
{
+ if (functor.second.empty())
+ {
+ continue;
+ }
+
+ // Filter functors registered with the same name
+ const ConsoleFunctorBase* curr = functor.second.front();
+
if ((curr->GetFlags() & ConsoleFunctorFlags::IsInvisible) == ConsoleFunctorFlags::IsInvisible)
{
// Filter functors marked as invisible
@@ -236,7 +244,12 @@ namespace AZ
if (StringFunc::StartsWith(curr->m_name, command, false))
{
AZLOG_INFO("- %s : %s\n", curr->m_name, curr->m_desc);
- commandSubset.push_back(curr->m_name);
+
+ if (commandSubset.size() < MaxConsoleCommandPlusArgsLength)
+ {
+ commandSubset.push_back(curr->m_name);
+ }
+
if (matches)
{
matches->push_back(curr->m_name);
@@ -271,7 +284,10 @@ namespace AZ
{
for (auto& curr : m_commands)
{
- visitor(curr.second.front());
+ if (!curr.second.empty())
+ {
+ visitor(curr.second.front());
+ }
}
}
@@ -336,6 +352,11 @@ namespace AZ
{
iter->second.erase(iter2);
}
+
+ if (iter->second.empty())
+ {
+ m_commands.erase(iter);
+ }
}
functor->Unlink(m_head);
functor->m_console = nullptr;
@@ -476,15 +497,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 +532,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 +637,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/StackTracer.h b/Code/Framework/AzCore/AzCore/Debug/StackTracer.h
index 430fd69168..2d09c16e99 100644
--- a/Code/Framework/AzCore/AzCore/Debug/StackTracer.h
+++ b/Code/Framework/AzCore/AzCore/Debug/StackTracer.h
@@ -40,6 +40,12 @@ namespace AZ
static unsigned int Record(StackFrame* frames, unsigned int maxNumOfFrames, unsigned int suppressCount = 0, void* nativeThread = 0);
};
+ class StackConverter
+ {
+ public:
+ static unsigned int FromNative(StackFrame* frames, unsigned int maxNumOfFrames, void* nativeContext);
+ };
+
class SymbolStorage
{
public:
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/Debug/Trace.cpp b/Code/Framework/AzCore/AzCore/Debug/Trace.cpp
index 14504cc282..cde8c36a4e 100644
--- a/Code/Framework/AzCore/AzCore/Debug/Trace.cpp
+++ b/Code/Framework/AzCore/AzCore/Debug/Trace.cpp
@@ -31,6 +31,8 @@ namespace AZ
{
namespace Debug
{
+ struct StackFrame;
+
namespace Platform
{
#if defined(AZ_ENABLE_DEBUG_TOOLS)
@@ -224,6 +226,8 @@ namespace AZ
void Debug::Trace::Terminate(int exitCode)
{
+ AZ_TracePrintf("Exit", "Called Terminate() with exit code: 0x%x", exitCode);
+ AZ::Debug::Trace::PrintCallstack("Exit");
Platform::Terminate(exitCode);
}
@@ -549,17 +553,19 @@ namespace AZ
{
StackFrame frames[25];
- // Without StackFrame explicit alignment frames array is aligned to 4 bytes
- // which causes the stack tracing to fail.
- //size_t bla = AZStd::alignment_of::value;
- //printf("Alignment value %d address 0x%08x : 0x%08x\n",bla,frames);
SymbolStorage::StackLine lines[AZ_ARRAY_SIZE(frames)];
+ unsigned int numFrames = 0;
if (!nativeContext)
{
- suppressCount += 1; /// If we don't provide a context we will capture in the RecordFunction, so skip us (Trace::PrinCallstack).
+ suppressCount += 1; /// If we don't provide a context we will capture in the RecordFunction, so skip us (Trace::PrintCallstack).
+ numFrames = StackRecorder::Record(frames, AZ_ARRAY_SIZE(frames), suppressCount);
}
- unsigned int numFrames = StackRecorder::Record(frames, AZ_ARRAY_SIZE(frames), suppressCount, nativeContext);
+ else
+ {
+ numFrames = StackConverter::FromNative(frames, AZ_ARRAY_SIZE(frames), nativeContext);
+ }
+
if (numFrames)
{
SymbolStorage::DecodeFrames(frames, numFrames, lines);
diff --git a/Code/Framework/AzCore/AzCore/EBus/BusImpl.h b/Code/Framework/AzCore/AzCore/EBus/BusImpl.h
index 8e655c0525..e2b1c2e92b 100644
--- a/Code/Framework/AzCore/AzCore/EBus/BusImpl.h
+++ b/Code/Framework/AzCore/AzCore/EBus/BusImpl.h
@@ -160,8 +160,8 @@ namespace AZ
/**
* Locking primitive that is used when executing events in the event queue.
*/
- using EventQueueMutexType = typename AZStd::Utils::if_c::value, // if EventQueueMutexType==NullMutex use MutexType otherwise EventQueueMutexType
- MutexType, typename Traits::EventQueueMutexType>::type;
+ using EventQueueMutexType = AZStd::conditional_t::value, // if EventQueueMutexType==NullMutex use MutexType otherwise EventQueueMutexType
+ MutexType, typename Traits::EventQueueMutexType>;
/**
* Pointer to an address on the bus.
@@ -180,14 +180,22 @@ namespace AZ
* `::ExecuteQueuedEvents()`.
* By default, the event queue is disabled.
*/
- static const bool EnableEventQueue = Traits::EnableEventQueue;
- static const bool EventQueueingActiveByDefault = Traits::EventQueueingActiveByDefault;
- static const bool EnableQueuedReferences = Traits::EnableQueuedReferences;
+ static constexpr bool EnableEventQueue = Traits::EnableEventQueue;
+ static constexpr bool EventQueueingActiveByDefault = Traits::EventQueueingActiveByDefault;
+ static constexpr bool EnableQueuedReferences = Traits::EnableQueuedReferences;
/**
* True if the EBus supports more than one address. Otherwise, false.
*/
- static const bool HasId = Traits::AddressPolicy != EBusAddressPolicy::Single;
+ static constexpr bool HasId = Traits::AddressPolicy != EBusAddressPolicy::Single;
+
+ /**
+ * Template Lock Guard class that wraps around the Mutex
+ * The EBus uses for Dispatching Events.
+ * This is not the EBus Context Mutex if LocklessDispatch is true
+ */
+ template
+ using DispatchLockGuard = typename Traits::template DispatchLockGuard;
};
/**
@@ -460,7 +468,7 @@ namespace AZ
using BusPtr = typename Traits::BusPtr;
/**
- * Helper to queue an event by BusIdType only when function queueing is enabled
+ * Helper to queue an event by BusIdType only when function queueing is enabled
* @param id Address ID. Handlers that are connected to this ID will receive the event.
* @param func Function pointer of the event to dispatch.
* @param args Function arguments that are passed to each handler.
@@ -581,7 +589,7 @@ namespace AZ
, public EBusBroadcaster
, public EBusEventer
, public EBusEventEnumerator
- , public AZStd::Utils::if_c, EBusNullQueue>::type
+ , public AZStd::conditional_t, EBusNullQueue>
{
};
@@ -599,7 +607,7 @@ namespace AZ
: public EventDispatcher
, public EBusBroadcaster
, public EBusBroadcastEnumerator
- , public AZStd::Utils::if_c, EBusNullQueue>::type
+ , public AZStd::conditional_t, EBusNullQueue>
{
};
diff --git a/Code/Framework/AzCore/AzCore/EBus/EBus.h b/Code/Framework/AzCore/AzCore/EBus/EBus.h
index da8c880963..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
@@ -236,6 +238,17 @@ namespace AZ
* code before or after an event.
*/
using EventProcessingPolicy = EBusEventProcessingPolicy;
+
+ /**
+ * Template Lock Guard class that wraps around the Mutex
+ * The EBus Context uses the LockGuard when dispatching
+ * (either AZStd::scoped_lock or NullLockGuard)
+ * The IsLocklessDispatch bool is there to defer evaluation of the LocklessDispatch constant
+ * Otherwise the value above in EBusTraits.h is always used and not the value
+ * that the derived trait class sets.
+ */
+ template
+ using DispatchLockGuard = AZStd::conditional_t, AZStd::scoped_lock>;
};
namespace Internal
@@ -496,6 +509,14 @@ namespace AZ
*/
static const bool HasId = Traits::AddressPolicy != EBusAddressPolicy::Single;
+ /**
+ * Template Lock Guard class that wraps around the Mutex
+ * The EBus uses for Dispatching Events.
+ * This is not EBus Context Mutex when LocklessDispatch is set
+ */
+ template
+ using DispatchLockGuard = typename ImplTraits::template DispatchLockGuard;
+
//////////////////////////////////////////////////////////////////////////
// Check to help identify common mistakes
/// @cond EXCLUDE_DOCS
@@ -620,11 +641,11 @@ namespace AZ
using ContextMutexType = AZStd::conditional_t, AZStd::shared_mutex, MutexType>;
/**
- * The scoped lock guard to use (either AZStd::scoped_lock or NullLockGuard
+ * The scoped lock guard to use
* during broadcast/event dispatch.
* @see EBusTraits::LocklessDispatch
*/
- using DispatchLockGuard = AZStd::conditional_t, AZStd::scoped_lock>;
+ using DispatchLockGuard = DispatchLockGuard;
/**
* The scoped lock guard to use during connection. Some specialized policies execute handler methods which
@@ -704,6 +725,11 @@ namespace AZ
static Context& GetOrCreateContext(bool trackCallstack=true);
static bool IsInDispatch(Context* context = GetContext(false));
+
+ /**
+ * Returns whether the EBus context is in the middle of a dispatch on the current thread
+ */
+ static bool IsInDispatchThisThread(Context* context = GetContext(false));
/// @cond EXCLUDE_DOCS
struct RouterCallstackEntry
: public CallstackEntry
@@ -1208,6 +1234,13 @@ AZ_POP_DISABLE_WARNING
return context != nullptr && context->m_dispatches > 0;
}
+ template
+ bool EBus::IsInDispatchThisThread(Context* context)
+ {
+ return context != nullptr && context->s_callstack != nullptr
+ && context->s_callstack->m_prev != nullptr;
+ }
+
//=========================================================================
template
EBus::RouterCallstackEntry::RouterCallstackEntry(Iterator it, const BusIdType* busId, bool isQueued, bool isReverse)
diff --git a/Code/Framework/AzCore/AzCore/IO/FileIO.h b/Code/Framework/AzCore/AzCore/IO/FileIO.h
index 6406025417..25dd422a47 100644
--- a/Code/Framework/AzCore/AzCore/IO/FileIO.h
+++ b/Code/Framework/AzCore/AzCore/IO/FileIO.h
@@ -148,7 +148,7 @@ namespace AZ
virtual AZ::u64 ModificationTime(HandleType fileHandle) = 0;
virtual AZ::u64 ModificationTime(const char* filePath) = 0;
- /// Get the size of the file. Returns Success if we report size.
+ /// Get the size of the file. Returns Success if we report size.
virtual Result Size(const char* filePath, AZ::u64& size) = 0;
virtual Result Size(HandleType fileHandle, AZ::u64& size) = 0;
@@ -198,7 +198,7 @@ namespace AZ
/// note: the callback will contain the full concatenated path (filePath + slash + fileName)
/// not just the individual file name found.
/// note: if the file path of the found file corresponds to a registered ALIAS, the longest matching alias will be returned
- /// so expect return values like @assets@/textures/mytexture.dds instead of a full path. This is so that fileIO works over remote connections.
+ /// so expect return values like @products@/textures/mytexture.dds instead of a full path. This is so that fileIO works over remote connections.
/// note: if rootPath is specified the implementation has the option of substituting it for the current directory
/// as would be the case on a file server.
typedef AZStd::function FindFilesCallbackType;
@@ -206,13 +206,18 @@ namespace AZ
// Alias system
- /// SetAlias - Adds an alias to the path resolution system, e.g. @user@, @root@, etc.
+ /// SetAlias - Adds an alias to the path resolution system, e.g. @user@, @products@, etc.
virtual void SetAlias(const char* alias, const char* path) = 0;
/// ClearAlias - Removes an alias from the path resolution system
virtual void ClearAlias(const char* alias) = 0;
/// GetAlias - Returns the destination path for a given alias, or nullptr if the alias does not exist
virtual const char* GetAlias(const char* alias) const = 0;
+ /// SetDeprecateAlias - Adds a deprecated alias with path resolution which points to a new alias
+ /// When the DeprecatedAlias is used an Error is logged and the alias is resolved to the path
+ /// specified by the new alais
+ virtual void SetDeprecatedAlias(AZStd::string_view oldAlias, AZStd::string_view newAlias) = 0;
+
/// Shorten the given path if it contains an alias. it will always pick the longest alias match.
/// note that it re-uses the buffer, since the data can only get smaller and we don't want to internally allocate memory if we
/// can avoid it.
@@ -230,8 +235,8 @@ namespace AZ
//! ResolvePath - Replaces any aliases in path with their values and stores the result in resolvedPath,
//! also ensures that the path is absolute
- //! NOTE: If the path does not start with an alias then the resolved value of the @assets@ is used
- //! which has the effect of making the path relative to the @assets@/ folder
+ //! NOTE: If the path does not start with an alias then the resolved value of the @products@ is used
+ //! which has the effect of making the path relative to the @products@/ folder
//! returns true if path was resolved, false otherwise
//! note that all of the above file-finding and opening functions automatically resolve the path before operating
//! so you should not need to call this except in very exceptional circumstances where you absolutely need to
diff --git a/Code/Framework/AzCore/AzCore/IO/IStreamer.h b/Code/Framework/AzCore/AzCore/IO/IStreamer.h
index d959fa716c..438384e687 100644
--- a/Code/Framework/AzCore/AzCore/IO/IStreamer.h
+++ b/Code/Framework/AzCore/AzCore/IO/IStreamer.h
@@ -42,8 +42,8 @@ namespace AZ::IO
// These functions can't be called after a request has been queued.
//
- //! Creates a request to read a file.
- //! @param relativePath Relative path to the file to load. This can include aliases such as @assets@.
+ //! Creates a request to read a file.
+ //! @param relativePath Relative path to the file to load. This can include aliases such as @products@.
//! @param outputBuffer The buffer that will hold the loaded data. This must be able to at least hold "size" number of bytes.
//! @param outputBufferSize The size of the buffer that will hold the loaded data. This must be equal or larger than "size" number of bytes.
//! @param readSize The number of bytes to read from the file at the relative path.
@@ -62,9 +62,9 @@ namespace AZ::IO
IStreamerTypes::Priority priority = IStreamerTypes::s_priorityMedium,
size_t offset = 0) = 0;
- //! Sets a request to the read command.
+ //! Sets a request to the read command.
//! @param request The request that will store the read command.
- //! @param relativePath Relative path to the file to load. This can include aliases such as @assets@.
+ //! @param relativePath Relative path to the file to load. This can include aliases such as @products@.
//! @param outputBuffer The buffer that will hold the loaded data. This must be able to at least hold "size" number of bytes.
//! @param outputBufferSize The size of the buffer that will hold the loaded data. This must be equal or larger than "size" number of bytes.
//! @param readSize The number of bytes to read from the file at the relative path.
@@ -84,8 +84,8 @@ namespace AZ::IO
IStreamerTypes::Priority priority = IStreamerTypes::s_priorityMedium,
size_t offset = 0) = 0;
- //! Creates a request to the read command.
- //! @param relativePath Relative path to the file to load. This can include aliases such as @assets@.
+ //! Creates a request to the read command.
+ //! @param relativePath Relative path to the file to load. This can include aliases such as @products@.
//! @param allocator The allocator used to reserve and release memory for the read request. Memory allocated this way will
//! be automatically freed when there are no more references to the FileRequestPtr. To avoid this, use GetReadRequestResult
//! to claim the pointer and use the provided allocator to release the memory at a later point.
@@ -106,9 +106,9 @@ namespace AZ::IO
IStreamerTypes::Priority priority = IStreamerTypes::s_priorityMedium,
size_t offset = 0) = 0;
- //! Sets a request to the read command.
+ //! Sets a request to the read command.
//! @param request The request that will store the read command.
- //! @param relativePath Relative path to the file to load. This can include aliases such as @assets@.
+ //! @param relativePath Relative path to the file to load. This can include aliases such as @products@.
//! @param allocator The allocator used to reserve and release memory for the read request. Memory allocated this way will
//! be automatically freed when there are no more references to the FileRequestPtr. To avoid this, use GetReadRequestResult
//! to claim the pointer and use the provided allocator to release the memory at a later point.
@@ -138,7 +138,7 @@ namespace AZ::IO
//! @result A smart pointer to the newly created request with the cancel command.
virtual FileRequestPtr Cancel(FileRequestPtr target) = 0;
- //! Sets a request to the cancel command.
+ //! Sets a request to the cancel command.
//! When this request completes it's not guaranteed to have canceled the target request. Not all requests can be canceled and requests
//! that already processing may complete. It's recommended to let the target request handle the completion of the request as normal
//! and handle cancellation by checking the status on the target request is set to IStreamerTypes::RequestStatus::Canceled.
@@ -177,7 +177,7 @@ namespace AZ::IO
//! DestroyDedicatedCache is called. Typical use of a dedicated cache is for files that have their own compression
//! and are periodically visited to read a section, e.g. streaming video play or streaming audio banks. This
//! request will fail if there are no nodes in Streamer's stack that deal with dedicated caches.
- //! @param relativePath Relative path to the file to receive a dedicated cache. This can include aliases such as @assets@.
+ //! @param relativePath Relative path to the file to receive a dedicated cache. This can include aliases such as @products@.
//! @return A smart pointer to the newly created request with the command to create a dedicated cache.
virtual FileRequestPtr CreateDedicatedCache(AZStd::string_view relativePath) = 0;
@@ -186,25 +186,25 @@ namespace AZ::IO
//! and are periodically visited to read a section, e.g. streaming video play or streaming audio banks. This
//! request will fail if there are no nodes in Streamer's stack that deal with dedicated caches.
//! @param request The request that will store the command to create a dedicated cache.
- //! @param relativePath Relative path to the file to receive a dedicated cache. This can include aliases such as @assets@.
+ //! @param relativePath Relative path to the file to receive a dedicated cache. This can include aliases such as @products@.
//! @return A reference to the provided request.
virtual FileRequestPtr& CreateDedicatedCache(FileRequestPtr& request, AZStd::string_view relativePath) = 0;
//! Destroy a dedicated cache created by CreateDedicatedCache. See CreateDedicatedCache for more details.
- //! @param relativePath Relative path to the file that got a dedicated cache. This can include aliases such as @assets@.
+ //! @param relativePath Relative path to the file that got a dedicated cache. This can include aliases such as @products@.
//! @return A smart pointer to the newly created request with the command to destroy a dedicated cache.
virtual FileRequestPtr DestroyDedicatedCache(AZStd::string_view relativePath) = 0;
//! Destroy a dedicated cache created by CreateDedicatedCache. See CreateDedicatedCache for more details.
//! @param request The request that will store the command to destroy a dedicated cache.
- //! @param relativePath Relative path to the file that got a dedicated cache. This can include aliases such as @assets@.
+ //! @param relativePath Relative path to the file that got a dedicated cache. This can include aliases such as @products@.
//! @return A reference to the provided request.
virtual FileRequestPtr& DestroyDedicatedCache(FileRequestPtr& request, AZStd::string_view relativePath) = 0;
//! Clears a file from all caches in use by Streamer.
//! Flushing the cache will cause the streaming stack to pause processing until it's idle before issuing the flush and resuming
//! processing. This can result in a noticeable interruption.
- //! @param relativePath Relative path to the file that will be cleared from all caches. This can include aliases such as @assets@.
+ //! @param relativePath Relative path to the file that will be cleared from all caches. This can include aliases such as @products@.
//! @return A smart pointer to the newly created request with the command to flush a file from all caches.
virtual FileRequestPtr FlushCache(AZStd::string_view relativePath) = 0;
@@ -212,7 +212,7 @@ namespace AZ::IO
//! Flushing the cache will cause the streaming stack to pause processing until it's idle before issuing the flush and resuming
//! processing. This can result in a noticeable interruption.
//! @param request The request that will store the command to flush a file from all caches.
- //! @param relativePath Relative path to the file that will be cleared from all caches. This can include aliases such as @assets@.
+ //! @param relativePath Relative path to the file that will be cleared from all caches. This can include aliases such as @products@.
//! @return A reference to the provided request.
virtual FileRequestPtr& FlushCache(FileRequestPtr& request, AZStd::string_view relativePath) = 0;
@@ -334,7 +334,7 @@ namespace AZ::IO
//
//! Collect statistics from all the components that make up Streamer.
- //! This is thread safe in the sense that it won't crash.
+ //! This is thread safe in the sense that it won't crash.
//! Data is collected lockless from involved threads and might be slightly
//! out of date in some cases.
//! @param statistics The container where statistics will be added to.
diff --git a/Code/Framework/AzCore/AzCore/IO/Path/Path.h b/Code/Framework/AzCore/AzCore/IO/Path/Path.h
index 24f26daa51..3b5c224957 100644
--- a/Code/Framework/AzCore/AzCore/IO/Path/Path.h
+++ b/Code/Framework/AzCore/AzCore/IO/Path/Path.h
@@ -98,6 +98,11 @@ namespace AZ::IO
//! made from the internal string
constexpr AZStd::fixed_string FixedMaxPathString() const noexcept;
+ // as_posix
+ //! Replicates the behavior of the Python pathlib as_posix method
+ //! by replacing the Windows Path Separator with the Posix Path Seperator
+ constexpr AZStd::fixed_string FixedMaxPathStringAsPosix() const noexcept;
+
// decomposition
//! Given a windows path of "C:\O3DE\foo\bar\name.txt" and a posix path of
//! "/O3DE/foo/bar/name.txt"
@@ -178,7 +183,7 @@ namespace AZ::IO
//! Normalizes a path in a purely lexical manner.
//! # Path separators are converted to their preferred path separator
//! # Path parts of "." are collapsed to nothing empty
- //! # Paths parts of ".." are removed if there is a preceding directory
+ //! # Paths parts of ".." are removed if there is a preceding directory
//! The preceding directory is also removed
//! # Runs of Two or more path separators are collapsed into one path separator
//! unless the path begins with two path separators
@@ -238,7 +243,7 @@ namespace AZ::IO
// iterators
//! Returns an iterator to the beginning of the path that can be used to traverse the path
- //! according to the following
+ //! according to the following
//! 1. Root name - (0 or 1)
//! 2. Root directory - (0 or 1)
//! 3. Filename - (0 or more)
@@ -253,24 +258,23 @@ namespace AZ::IO
template
friend class BasicPath;
friend struct AZStd::hash;
+ struct PathIterable;
- template