Compare commits

..

1 Commits

Author SHA1 Message Date
Gavin Monroe 7dea7a72f5
Create config.yml
Disables the "Open a blank issue" option when choosing a template for a new issue.

This should only be merged upon acceptance by the Technical Steering Committee. See o3de/tsc#16

Signed-off-by: Gavin Monroe <71404632+monroegm@users.noreply.github.com>
4 years ago

@ -0,0 +1 @@
blank_issues_enabled: false

@ -9,17 +9,27 @@ SPDX-License-Identifier: Apache-2.0 OR MIT
# This suite consists of all test cases that are passing and have been verified.
import pytest
from ly_test_tools.o3de.editor_test import EditorTestSuite, EditorSharedTest
import sys
import os
from ly_test_tools import LAUNCHERS
sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../automatedtesting_shared')
from base import TestAutomationBase
@pytest.mark.SUITE_main
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
@pytest.mark.parametrize("project", ["AutomatedTesting"])
class TestAutomation(EditorTestSuite):
class test_WhiteBox_AddComponentToEntity(EditorSharedTest):
class TestAutomation(TestAutomationBase):
def test_WhiteBox_AddComponentToEntity(self, request, workspace, editor, launcher_platform):
from .tests import WhiteBox_AddComponentToEntity as test_module
self._run_test(request, workspace, editor, test_module)
class test_WhiteBox_SetDefaultShape(EditorSharedTest):
def test_WhiteBox_SetDefaultShape(self, request, workspace, editor, launcher_platform):
from .tests import WhiteBox_SetDefaultShape as test_module
self._run_test(request, workspace, editor, test_module)
class test_WhiteBox_SetInvisible(EditorSharedTest):
def test_WhiteBox_SetInvisible(self, request, workspace, editor, launcher_platform):
from .tests import WhiteBox_SetInvisible as test_module
self._run_test(request, workspace, editor, test_module)

@ -18,17 +18,21 @@ class Tests():
def C28798177_WhiteBox_AddComponentToEntity():
import os
import sys
from Gems.WhiteBox.Editor.Scripts import WhiteBoxInit as init
import editor_python_test_tools.hydra_editor_utils as hydra
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.legacy.general as general
import WhiteBoxInit as init
from editor_python_test_tools.utils import Report
from editor_python_test_tools.utils import TestHelper as helper
# open level
hydra.open_base_level()
helper.init_idle()
helper.open_level("WhiteBox", "EmptyLevel", no_prompt=False)
# create white box entity and attach component
white_box_entity = init.create_white_box_entity()
@ -42,6 +46,10 @@ def C28798177_WhiteBox_AddComponentToEntity():
component_enabled = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', white_box_mesh_component)
Report.result(Tests.white_box_component_enabled, component_enabled)
# close editor
helper.close_editor()
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(C28798177_WhiteBox_AddComponentToEntity)

@ -22,13 +22,17 @@ class Tests():
critical_shape_check = ("Default shape has more than 0 sides", "default shape has 0 sides")
def C29279329_WhiteBox_SetDefaultShape():
import os
import sys
from Gems.WhiteBox.Editor.Scripts import WhiteBoxInit as init
import azlmbr.whitebox.api as api
import azlmbr.bus as bus
import editor_python_test_tools.hydra_editor_utils as hydra
import WhiteBoxInit as init
import azlmbr.legacy.general as general
from editor_python_test_tools.utils import Report
from editor_python_test_tools.utils import TestHelper as helper
def check_shape_result(success_fail_tuple, condition):
result = Report.result(success_fail_tuple, condition)
@ -49,7 +53,8 @@ def C29279329_WhiteBox_SetDefaultShape():
}
# open level
hydra.open_base_level()
helper.init_idle()
helper.open_level("WhiteBox", "EmptyLevel", no_prompt=False)
# create white box entity and attach component
white_box_entity = init.create_white_box_entity()
@ -90,6 +95,10 @@ def C29279329_WhiteBox_SetDefaultShape():
Tests.default_shape_sphere,
white_box_handle.MeshFaceCount() == expected_results.get(shape_types.SPHERE))
# close editor
helper.close_editor()
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(C29279329_WhiteBox_SetDefaultShape)

@ -21,16 +21,25 @@ def C28798205_WhiteBox_SetInvisible():
# note: This automated test does not fully replicate the test case in Test Rail as it's
# not currently possible using the Hydra API to get an EntityComponentIdPair at runtime,
# in future game_mode will be activated and a runtime White Box Component queried
import os
import sys
from Gems.WhiteBox.Editor.Scripts import WhiteBoxInit as init
import editor_python_test_tools.hydra_editor_utils as hydra
import azlmbr.whitebox.api as api
import azlmbr.whitebox
import azlmbr.bus as bus
import azlmbr.editor as editor
import editor_python_test_tools.hydra_editor_utils as hydra
import WhiteBoxInit as init
import azlmbr.entity as entity
import azlmbr.legacy.general as general
from editor_python_test_tools.utils import Report
from editor_python_test_tools.utils import TestHelper as helper
# open level
hydra.open_base_level()
helper.init_idle()
helper.open_level("WhiteBox", "EmptyLevel", no_prompt=False)
white_box_entity_name = 'WhiteBox-Visibility'
white_box_visibility_path = 'White Box Material|Visible'
@ -48,6 +57,9 @@ def C28798205_WhiteBox_SetInvisible():
visible_property = hydra.get_component_property_value(white_box_mesh_component, white_box_visibility_path)
Report.result(Tests.white_box_set_to_invisible, not visible_property)
helper.close_editor()
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(C28798205_WhiteBox_SetInvisible)

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:2dfc16cf4e47fc73c40d8a30ce08c34fe7805d369bf6ca69bd0d00ede4509902
size 4542

@ -0,0 +1,118 @@
{
"ContainerEntity": {
"Id": "ContainerEntity",
"Name": "EmptyLevel",
"Components": {
"Component_[10182366347512475253]": {
"$type": "EditorPrefabComponent",
"Id": 10182366347512475253
},
"Component_[12917798267488243668]": {
"$type": "EditorPendingCompositionComponent",
"Id": 12917798267488243668
},
"Component_[3261249813163778338]": {
"$type": "EditorOnlyEntityComponent",
"Id": 3261249813163778338
},
"Component_[3837204912784440039]": {
"$type": "EditorDisabledCompositionComponent",
"Id": 3837204912784440039
},
"Component_[4272963378099646759]": {
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
"Id": 4272963378099646759,
"Parent Entity": ""
},
"Component_[4848458548047175816]": {
"$type": "EditorVisibilityComponent",
"Id": 4848458548047175816
},
"Component_[5787060997243919943]": {
"$type": "EditorInspectorComponent",
"Id": 5787060997243919943
},
"Component_[7804170251266531779]": {
"$type": "EditorLockComponent",
"Id": 7804170251266531779
},
"Component_[7874177159288365422]": {
"$type": "EditorEntitySortComponent",
"Id": 7874177159288365422
},
"Component_[8018146290632383969]": {
"$type": "EditorEntityIconComponent",
"Id": 8018146290632383969
},
"Component_[8452360690590857075]": {
"$type": "SelectionComponent",
"Id": 8452360690590857075
}
}
},
"Entities": {
"Entity_[273050554979]": {
"Id": "Entity_[273050554979]",
"Name": "DefaultLevelSetup",
"Components": {
"Component_[10017568850356726118]": {
"$type": "EditorEntitySortComponent",
"Id": 10017568850356726118
},
"Component_[13730791873699866292]": {
"$type": "EditorVisibilityComponent",
"Id": 13730791873699866292
},
"Component_[14036484285432839222]": {
"$type": "EditorInspectorComponent",
"Id": 14036484285432839222,
"ComponentOrderEntryArray": [
{
"ComponentId": 9432950532896492451
},
{
"ComponentId": 16094906495473882735,
"SortIndex": 1
}
]
},
"Component_[16744953497953161231]": {
"$type": "EditorOnlyEntityComponent",
"Id": 16744953497953161231
},
"Component_[17819059404707659501]": {
"$type": "EditorDisabledCompositionComponent",
"Id": 17819059404707659501
},
"Component_[2317367007807622931]": {
"$type": "EditorLockComponent",
"Id": 2317367007807622931
},
"Component_[2676812743453687109]": {
"$type": "EditorPendingCompositionComponent",
"Id": 2676812743453687109
},
"Component_[3047355939801335922]": {
"$type": "EditorEntityIconComponent",
"Id": 3047355939801335922
},
"Component_[3687396159953003426]": {
"$type": "SelectionComponent",
"Id": 3687396159953003426
},
"Component_[9432950532896492451]": {
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
"Id": 9432950532896492451,
"Parent Entity": "ContainerEntity",
"Transform Data": {
"Translate": [
512.0,
512.0,
100.0
]
}
}
}
}
}
}

@ -0,0 +1,14 @@
<Environment>
<Fog ViewDistance="8000" ViewDistanceLowSpec="1000"/>
<Terrain DetailLayersViewDistRatio="1.0" HeightMapAO="0"/>
<EnvState WindVector="1,0,0" BreezeGeneration="0" BreezeStrength="1.f" BreezeMovementSpeed="8.f" BreezeVariation="1.f" BreezeLifeTime="15.f" BreezeCount="4" BreezeSpawnRadius="25.f" BreezeSpread="0.f" BreezeRadius="5.f" ConsoleMergedMeshesPool="2750" ShowTerrainSurface="false" SunShadowsMinSpec="1" SunShadowsAdditionalCascadeMinSpec="0" SunShadowsClipPlaneRange="256.0f" SunShadowsClipPlaneRangeShift="0.0f" UseLayersActivation="0" SunLinkedToTOD="1"/>
<VolFogShadows Enable="0" EnableForClouds="0"/>
<CloudShadows CloudShadowTexture="" CloudShadowSpeed="0,0,0" CloudShadowTiling="1.0" CloudShadowBrightness="1.0" CloudShadowInvert="0"/>
<ParticleLighting AmbientMul="1.0" LightsMul="1.0"/>
<SkyBox Material="EngineAssets/Materials/Sky/Sky" MaterialLowSpec="EngineAssets/Materials/Sky/Sky" Angle="0" Stretching="0.5"/>
<Ocean Material="EngineAssets/Materials/Water/Ocean_default" CausticsDistanceAtten="100.0" CausticDepth="8.0" CausticIntensity="1.0" CausticsTilling="1.0"/>
<OceanAnimation WindDirection="1.0" WindSpeed="4.0" WavesAmount="1.5" WavesSize="0.4" WavesSpeed="1.0"/>
<Moon Latitude="240.0" Longitude="45.0" Size="0.5" Texture="Textures/Skys/Night/half_moon.dds"/>
<DynTexSource Width="256" Height="256"/>
<Total_Illumination_v2 Active="0" IntegrationMode="0" NumberOfBounces="1" DiffuseConeWidth="24" ConeMaxLength="12.0" UseLightProbes="0" InjectionMultiplier="1.0" AmbientOffsetRed="1.0" AmbientOffsetGreen="1.0" AmbientOffsetBlue="1.0" AmbientOffsetBias="0.1" Saturation="0.8" SSAOAmount="0.7"/>
</Environment>

@ -0,0 +1,7 @@
<TerrainTexture TileCountX="1" TileCountY="1" TileResolution="512">
<RGBLayer>
<Tiles>
<tile X="0" Y="0" Size="512"/>
</Tiles>
</RGBLayer>
</TerrainTexture>

@ -0,0 +1,356 @@
<TimeOfDay Time="13.5" TimeStart="13.5" TimeEnd="13.5" TimeAnimSpeed="0">
<Variable Name="Sun color" Color="0.99989021,0.99946922,0.9991194">
<Spline Keys="-0.000628322:(0.783538:0.89627:0.930341):36,0:(0.783538:0.887923:0.921582):36,0.229167:(0.783538:0.879623:0.921582):36,0.25:(0.947307:0.745404:0.577581):36,0.458333:(1:1:1):36,0.5625:(1:1:1):36,0.75:(0.947307:0.745404:0.577581):36,0.770833:(0.783538:0.879623:0.921582):36,1:(0.783538:0.89627:0.930556):36,"/>
</Variable>
<Variable Name="Sun intensity" Value="92366.68">
<Spline Keys="0:1000:36,0.229167:1000:36,0.5:120000:36,0.770833:1000:65572,0.999306:1000:36,"/>
</Variable>
<Variable Name="Sun specular multiplier" Value="1">
<Spline Keys="0:1:36,0.25:1:36,0.5:1:36,0.75:1:36,1:1:36,"/>
</Variable>
<Variable Name="Fog color" Color="0.27049801,0.47353199,0.83076996">
<Spline Keys="0:(0.00651209:0.00972122:0.0137021):36,0.229167:(0.00604883:0.00972122:0.0137021):36,0.25:(0.270498:0.473532:0.83077):36,0.5:(0.270498:0.473532:0.83077):458788,0.75:(0.270498:0.473532:0.83077):36,0.770833:(0.00604883:0.00972122:0.0137021):36,1:(0.00651209:0.00972122:0.0137021):36,"/>
</Variable>
<Variable Name="Fog color multiplier" Value="1">
<Spline Keys="0:0.5:36,0.229167:0.5:36,0.25:1:36,0.5:1:36,0.75:1:36,0.770833:0.5:36,1:0.5:65572,"/>
</Variable>
<Variable Name="Fog height (bottom)" Value="0">
<Spline Keys="0:0:36,0.25:0:36,0.5:0:36,0.75:0:36,1:0:36,"/>
</Variable>
<Variable Name="Fog layer density (bottom)" Value="1">
<Spline Keys="0:1:36,0.25:1:36,0.5:1:36,0.75:1:36,1:1:36,"/>
</Variable>
<Variable Name="Fog color (top)" Color="0.597202,0.72305501,0.91309899">
<Spline Keys="0:(0.00699541:0.00972122:0.0122865):36,0.229167:(0.00699541:0.00972122:0.0122865):36,0.25:(0.597202:0.723055:0.913099):36,0.5:(0.597202:0.723055:0.913099):458788,0.75:(0.597202:0.723055:0.913099):36,0.770833:(0.00699541:0.00972122:0.0122865):36,1:(0.00699541:0.00972122:0.0122865):36,"/>
</Variable>
<Variable Name="Fog color (top) multiplier" Value="0.88389361">
<Spline Keys="-4.40702e-06:0.5:36,0.0297507:0.499195:36,0.229167:0.5:36,0.5:1:36,0.770833:0.5:36,1:0.5:36,"/>
</Variable>
<Variable Name="Fog height (top)" Value="100.00001">
<Spline Keys="0:100:36,0.25:100:36,0.5:100:36,0.75:100:65572,1:100:36,"/>
</Variable>
<Variable Name="Fog layer density (top)" Value="9.9999997e-05">
<Spline Keys="0:0.0001:36,0.25:0.0001:36,0.5:0.0001:65572,0.75:0.0001:36,1:0.0001:36,"/>
</Variable>
<Variable Name="Fog color height offset" Value="0">
<Spline Keys="0:0:36,0.25:0:36,0.5:0:36,0.75:0:36,1:0:65572,"/>
</Variable>
<Variable Name="Fog color (radial)" Color="0.78592348,0.52744436,0.17234583">
<Spline Keys="0:(0:0:0):36,0.229167:(0.00439144:0.00367651:0.00334654):36,0.25:(0.838799:0.564712:0.184475):36,0.5:(0.768151:0.514918:0.168269):458788,0.75:(0.838799:0.564712:0.184475):36,0.770833:(0.00402472:0.00334654:0.00303527):36,1:(0:0:0):36,"/>
</Variable>
<Variable Name="Fog color (radial) multiplier" Value="6">
<Spline Keys="0:0:36,0.25:6:36,0.5:6:36,0.75:6:36,1:0:36,"/>
</Variable>
<Variable Name="Fog radial size" Value="0.85000002">
<Spline Keys="0:0:36,0.25:0.85:65572,0.5:0.85:36,0.75:0.85:36,1:0:36,"/>
</Variable>
<Variable Name="Fog radial lobe" Value="0.75">
<Spline Keys="0:0:36,0.25:0.75:36,0.5:0.75:36,0.75:0.75:65572,1:0:36,"/>
</Variable>
<Variable Name="Volumetric fog: Final density clamp" Value="1">
<Spline Keys="0:1:36,0.25:1:36,0.5:1:65572,0.75:1:36,1:1:36,"/>
</Variable>
<Variable Name="Volumetric fog: Global density" Value="1.5">
<Spline Keys="0:1.5:36,0.25:1.5:36,0.5:1.5:65572,0.75:1.5:36,1:1.5:36,"/>
</Variable>
<Variable Name="Volumetric fog: Ramp start" Value="25.000002">
<Spline Keys="0:25:36,0.25:25:36,0.5:25:65572,0.75:25:36,1:25:36,"/>
</Variable>
<Variable Name="Volumetric fog: Ramp end" Value="1000.0001">
<Spline Keys="0:1000:36,0.25:1000:36,0.5:1000:65572,0.75:1000:36,1:1000:36,"/>
</Variable>
<Variable Name="Volumetric fog: Ramp influence" Value="0.69999993">
<Spline Keys="0:0.7:36,0.25:0.7:36,0.5:0.7:65572,0.75:0.7:36,1:0.7:36,"/>
</Variable>
<Variable Name="Volumetric fog: Shadow darkening" Value="0.20000002">
<Spline Keys="0:0.2:36,0.25:0.2:36,0.5:0.2:65572,0.75:0.2:36,1:0.2:36,"/>
</Variable>
<Variable Name="Volumetric fog: Shadow darkening sun" Value="0.5">
<Spline Keys="0:0.5:36,0.25:0.5:36,0.5:0.5:65572,0.75:0.5:36,1:0.5:36,"/>
</Variable>
<Variable Name="Volumetric fog: Shadow darkening ambient" Value="1">
<Spline Keys="0:1:36,0.25:1:36,0.5:1:65572,0.75:1:36,1:1:36,"/>
</Variable>
<Variable Name="Volumetric fog: Shadow range" Value="0.10000001">
<Spline Keys="0:0.1:36,0.25:0.1:36,0.5:0.1:65572,0.75:0.1:36,1:0.1:36,"/>
</Variable>
<Variable Name="Volumetric fog 2: Fog height (bottom)" Value="0">
<Spline Keys="0:0:0,1:0:0,"/>
</Variable>
<Variable Name="Volumetric fog 2: Fog layer density (bottom)" Value="1">
<Spline Keys="0:1:0,1:1:0,"/>
</Variable>
<Variable Name="Volumetric fog 2: Fog height (top)" Value="4000">
<Spline Keys="0:4000:0,1:4000:0,"/>
</Variable>
<Variable Name="Volumetric fog 2: Fog layer density (top)" Value="9.9999997e-05">
<Spline Keys="0:0.0001:0,1:0.0001:0,"/>
</Variable>
<Variable Name="Volumetric fog 2: Global fog density" Value="0.1">
<Spline Keys="0:0.1:0,1:0.1:0,"/>
</Variable>
<Variable Name="Volumetric fog 2: Ramp start" Value="0">
<Spline Keys="0:0:0,1:0:0,"/>
</Variable>
<Variable Name="Volumetric fog 2: Ramp end" Value="0">
<Spline Keys="0:0:0,1:0:0,"/>
</Variable>
<Variable Name="Volumetric fog 2: Fog albedo color (atmosphere)" Color="1,1,1">
<Spline Keys="0:(1:1:1):0,1:(1:1:1):0,"/>
</Variable>
<Variable Name="Volumetric fog 2: Anisotropy factor (atmosphere)" Value="0.60000002">
<Spline Keys="0:0.6:0,1:0.6:0,"/>
</Variable>
<Variable Name="Volumetric fog 2: Fog albedo color (sun radial)" Color="1,1,1">
<Spline Keys="0:(1:1:1):0,1:(1:1:1):0,"/>
</Variable>
<Variable Name="Volumetric fog 2: Anisotropy factor (sun radial)" Value="0.94999999">
<Spline Keys="0:0.95:0,1:0.95:0,"/>
</Variable>
<Variable Name="Volumetric fog 2: Blend factor for sun scattering" Value="1">
<Spline Keys="0:1:0,1:1:0,"/>
</Variable>
<Variable Name="Volumetric fog 2: Blend mode for sun scattering" Value="0">
<Spline Keys="0:0:0,1:0:0,"/>
</Variable>
<Variable Name="Volumetric fog 2: Fog albedo color (entities)" Color="1,1,1">
<Spline Keys="0:(1:1:1):0,1:(1:1:1):0,"/>
</Variable>
<Variable Name="Volumetric fog 2: Anisotropy factor (entities)" Value="0.60000002">
<Spline Keys="0:0.6:0,1:0.6:0,"/>
</Variable>
<Variable Name="Volumetric fog 2: Maximum range of ray-marching" Value="64">
<Spline Keys="0:64:0,1:64:0,"/>
</Variable>
<Variable Name="Volumetric fog 2: In-scattering factor" Value="1">
<Spline Keys="0:1:0,1:1:0,"/>
</Variable>
<Variable Name="Volumetric fog 2: Extinction factor" Value="0.30000001">
<Spline Keys="0:0.3:0,1:0.3:0,"/>
</Variable>
<Variable Name="Volumetric fog 2: Analytical volumetric fog visibility" Value="0.5">
<Spline Keys="0:0.5:0,1:0.5:0,"/>
</Variable>
<Variable Name="Volumetric fog 2: Final density clamp" Value="1">
<Spline Keys="0:1:0,0.5:1:36,1:1:0,"/>
</Variable>
<Variable Name="Sky light: Sun intensity" Color="1,1,1">
<Spline Keys="0:(1:1:1):36,0.25:(1:1:1):36,0.494381:(1:1:1):65572,0.5:(1:1:1):36,0.75:(1:1:1):36,1:(1:1:1):36,"/>
</Variable>
<Variable Name="Sky light: Sun intensity multiplier" Value="200.00002">
<Spline Keys="0:200:36,0.25:200:36,0.5:200:36,0.75:200:36,1:200:36,"/>
</Variable>
<Variable Name="Sky light: Mie scattering" Value="6.779707">
<Spline Keys="0:40:36,0.5:2:36,1:40:36,"/>
</Variable>
<Variable Name="Sky light: Rayleigh scattering" Value="0.20000002">
<Spline Keys="0:0.2:36,0.229167:0.2:36,0.25:1:36,0.291667:0.2:36,0.5:0.2:36,0.729167:0.2:36,0.75:1:36,0.770833:0.2:36,1:0.2:36,"/>
</Variable>
<Variable Name="Sky light: Sun anisotropy factor" Value="-0.99989998">
<Spline Keys="0:-0.9999:36,0.25:-0.9999:36,0.5:-0.9999:65572,0.75:-0.9999:36,1:-0.9999:36,"/>
</Variable>
<Variable Name="Sky light: Wavelength (R)" Value="694">
<Spline Keys="0:694:36,0.25:694:36,0.5:694:65572,0.75:694:36,1:694:36,"/>
</Variable>
<Variable Name="Sky light: Wavelength (G)" Value="596.99994">
<Spline Keys="0:597:36,0.25:597:36,0.5:597:36,0.75:597:36,1:597:36,"/>
</Variable>
<Variable Name="Sky light: Wavelength (B)" Value="488">
<Spline Keys="0:488:36,0.25:488:36,0.5:488:65572,0.75:488:36,1:488:36,"/>
</Variable>
<Variable Name="Night sky: Horizon color" Color="0.27049801,0.39157301,0.52711499">
<Spline Keys="0:(0.270498:0.391573:0.520996):36,0.25:(0.270498:0.391573:0.527115):36,0.5:(0.270498:0.391573:0.527115):262180,0.75:(0.270498:0.391573:0.527115):36,1:(0.270498:0.391573:0.520996):36,"/>
</Variable>
<Variable Name="Night sky: Horizon color multiplier" Value="0">
<Spline Keys="0:0.1:36,0.25:0:36,0.5:0:65572,0.75:0:36,1:0.1:36,"/>
</Variable>
<Variable Name="Night sky: Zenith color" Color="0.36130697,0.434154,0.46778399">
<Spline Keys="0:(0.361307:0.434154:0.467784):36,0.25:(0.361307:0.434154:0.467784):36,0.5:(0.361307:0.434154:0.467784):262180,0.75:(0.361307:0.434154:0.467784):36,1:(0.361307:0.434154:0.467784):36,"/>
</Variable>
<Variable Name="Night sky: Zenith color multiplier" Value="0">
<Spline Keys="0:0.02:36,0.25:0:36,0.5:0:65572,0.75:0:36,1:0.02:36,"/>
</Variable>
<Variable Name="Night sky: Zenith shift" Value="0.5">
<Spline Keys="0:0.5:36,0.25:0.5:36,0.5:0.5:65572,0.75:0.5:36,1:0.5:36,"/>
</Variable>
<Variable Name="Night sky: Star intensity" Value="0">
<Spline Keys="0:3:36,0.25:0:36,0.5:0:65572,0.75:0:36,0.836647:1.03977:36,1:3:36,"/>
</Variable>
<Variable Name="Night sky: Moon color" Color="1,1,1">
<Spline Keys="0:(1:1:1):36,0.25:(1:1:1):36,0.5:(1:1:1):458788,0.75:(1:1:1):36,1:(1:1:1):36,"/>
</Variable>
<Variable Name="Night sky: Moon color multiplier" Value="0">
<Spline Keys="0:0.4:36,0.25:0:36,0.5:0:36,0.75:0:65572,1:0.4:36,"/>
</Variable>
<Variable Name="Night sky: Moon inner corona color" Color="0.904661,1,1">
<Spline Keys="0:(0.89627:1:1):36,0.25:(0.904661:1:1):36,0.5:(0.904661:1:1):393252,0.75:(0.904661:1:1):36,0.836647:(0.89627:1:1):36,1:(0.89627:1:1):36,"/>
</Variable>
<Variable Name="Night sky: Moon inner corona color multiplier" Value="0">
<Spline Keys="0:0.1:36,0.25:0:36,0.5:0:65572,0.75:0:36,1:0.1:36,"/>
</Variable>
<Variable Name="Night sky: Moon inner corona scale" Value="0">
<Spline Keys="0:2:36,0.25:0:36,0.5:0:65572,0.75:0:36,0.836647:0.693178:36,1:2:36,"/>
</Variable>
<Variable Name="Night sky: Moon outer corona color" Color="0.201556,0.22696599,0.25415203">
<Spline Keys="0:(0.198069:0.226966:0.250158):36,0.25:(0.201556:0.226966:0.254152):36,0.5:(0.201556:0.226966:0.254152):36,0.75:(0.201556:0.226966:0.254152):36,1:(0.198069:0.226966:0.250158):36,"/>
</Variable>
<Variable Name="Night sky: Moon outer corona color multiplier" Value="0">
<Spline Keys="0:0.1:36,0.25:0:36,0.5:0:65572,0.75:0:36,1:0.1:36,"/>
</Variable>
<Variable Name="Night sky: Moon outer corona scale" Value="0">
<Spline Keys="0:0.01:36,0.25:0:36,0.5:0:65572,0.75:0:36,1:0.01:36,"/>
</Variable>
<Variable Name="Cloud shading: Sun light multiplier" Value="1">
<Spline Keys="0:1:36,0.25:1:36,0.5:1:65572,0.75:1:36,1:1:36,"/>
</Variable>
<Variable Name="Cloud shading: Sun custom color" Color="0.83076996,0.76815104,0.65837508">
<Spline Keys="0:(0.737911:0.737911:0.737911):36,0.25:(0.83077:0.768151:0.658375):36,0.5:(0.83077:0.768151:0.658375):458788,0.75:(0.83077:0.768151:0.658375):36,1:(0.737911:0.737911:0.737911):36,"/>
</Variable>
<Variable Name="Cloud shading: Sun custom color multiplier" Value="1">
<Spline Keys="0:0.1:36,0.25:1:36,0.5:1:65572,0.75:1:36,1:0.1:36,"/>
</Variable>
<Variable Name="Cloud shading: Sun custom color influence" Value="0">
<Spline Keys="0:0.5:36,0.25:0:36,0.5:0:65572,0.75:0:36,1:0.5:36,"/>
</Variable>
<Variable Name="Sun shafts visibility" Value="0">
<Spline Keys="0:0:36,0.25:0:36,0.5:0:65572,0.75:0:36,1:0:36,"/>
</Variable>
<Variable Name="Sun rays visibility" Value="1.5">
<Spline Keys="0:1:36,0.25:1.5:36,0.5:1.5:65572,0.75:1.5:36,1:1:36,"/>
</Variable>
<Variable Name="Sun rays attenuation" Value="1.5">
<Spline Keys="0:0.1:36,0.25:1.5:36,0.5:1.5:65572,0.75:1.5:36,1:0.1:36,"/>
</Variable>
<Variable Name="Sun rays suncolor influence" Value="0.5">
<Spline Keys="0:0.5:36,0.25:0.5:36,0.5:0.5:65572,0.75:0.5:36,1:0.5:36,"/>
</Variable>
<Variable Name="Sun rays custom color" Color="0.66538697,0.83879906,0.94730699">
<Spline Keys="0:(0.665387:0.838799:0.947307):36,0.25:(0.665387:0.838799:0.947307):36,0.5:(0.665387:0.838799:0.947307):458788,0.75:(0.665387:0.838799:0.947307):36,1:(0.665387:0.838799:0.947307):36,"/>
</Variable>
<Variable Name="Ocean fog color" Color="0.0012141101,0.0091340598,0.017642001">
<Spline Keys="0:(0.00121411:0.00913406:0.017642):36,0.25:(0.00121411:0.00913406:0.017642):36,0.5:(0.00121411:0.00913406:0.017642):458788,0.75:(0.00121411:0.00913406:0.017642):36,1:(0.00121411:0.00913406:0.017642):36,"/>
</Variable>
<Variable Name="Ocean fog color multiplier" Value="0.5">
<Spline Keys="0:0.5:36,0.25:0.5:36,0.5:0.5:65572,0.75:0.5:36,1:0.5:36,"/>
</Variable>
<Variable Name="Ocean fog density" Value="0.5">
<Spline Keys="0:0.5:36,0.25:0.5:36,0.5:0.5:65572,0.75:0.5:36,1:0.5:36,"/>
</Variable>
<Variable Name="Static skybox multiplier" Value="1">
<Spline Keys="0:1:0,1:1:0,"/>
</Variable>
<Variable Name="Film curve shoulder scale" Value="2.232213">
<Spline Keys="0:3:36,0.229167:3:36,0.5:2:36,0.770833:3:36,1:3:36,"/>
</Variable>
<Variable Name="Film curve midtones scale" Value="0.88389361">
<Spline Keys="0:0.5:36,0.229167:0.5:36,0.5:1:36,0.770833:0.5:36,1:0.5:36,"/>
</Variable>
<Variable Name="Film curve toe scale" Value="1">
<Spline Keys="0:1:36,0.25:1:36,0.5:1:65572,0.75:1:36,1:1:36,"/>
</Variable>
<Variable Name="Film curve whitepoint" Value="4">
<Spline Keys="0:4:36,0.25:4:36,0.5:4:65572,0.75:4:36,1:4:36,"/>
</Variable>
<Variable Name="Saturation" Value="1">
<Spline Keys="0:0.8:36,0.229167:0.8:36,0.5:1:36,0.751391:1:65572,0.770833:0.8:36,1:0.8:36,"/>
</Variable>
<Variable Name="Color balance" Color="1,1,1">
<Spline Keys="0:(1:1:1):36,0.25:(1:1:1):36,0.5:(1:1:1):36,0.75:(1:1:1):36,1:(1:1:1):36,"/>
</Variable>
<Variable Name="Scene key" Value="0.18000002">
<Spline Keys="0:0.18:36,0.25:0.18:36,0.5:0.18:65572,0.75:0.18:36,1:0.18:36,"/>
</Variable>
<Variable Name="Min exposure" Value="1">
<Spline Keys="0:1:36,0.25:1:36,0.5:1:65572,0.75:1:36,1:1:36,"/>
</Variable>
<Variable Name="Max exposure" Value="2.6142297">
<Spline Keys="0:2:36,0.229167:2:36,0.5:2.8:36,0.770833:2:36,1:2:36,"/>
</Variable>
<Variable Name="EV Min" Value="4.5">
<Spline Keys="0:4.5:0,1:4.5:0,"/>
</Variable>
<Variable Name="EV Max" Value="17">
<Spline Keys="0:17:0,1:17:0,"/>
</Variable>
<Variable Name="EV Auto compensation" Value="1.5">
<Spline Keys="0:1.5:0,1:1.5:0,"/>
</Variable>
<Variable Name="Bloom amount" Value="0.30899152">
<Spline Keys="0:1:36,0.229167:1:36,0.5:0.1:36,0.770833:1:36,1:1:36,"/>
</Variable>
<Variable Name="Filters: grain" Value="0">
<Spline Keys="0:0.3:65572,0.229167:0.3:36,0.25:0:36,0.5:0:36,0.75:0:36,1:0.3:36,"/>
</Variable>
<Variable Name="Filters: photofilter color" Color="0,0,0">
<Spline Keys="0:(0:0:0):36,0.25:(0:0:0):36,0.5:(0:0:0):458788,0.75:(0:0:0):36,1:(0:0:0):36,"/>
</Variable>
<Variable Name="Filters: photofilter density" Value="0">
<Spline Keys="0:0:36,0.25:0:36,0.5:0:36,0.75:0:36,1:0:36,"/>
</Variable>
<Variable Name="Dof: focus range" Value="500.00003">
<Spline Keys="0:500:36,0.25:500:36,0.5:500:65572,0.75:500:36,1:500:36,"/>
</Variable>
<Variable Name="Dof: blur amount" Value="0.10000001">
<Spline Keys="0:0.1:36,0.25:0.1:36,0.5:0.1:65572,0.75:0.1:36,1:0.1:36,"/>
</Variable>
<Variable Name="Cascade 0: Bias" Value="0.10000001">
<Spline Keys="0:0.1:36,0.25:0.1:36,0.5:0.1:65572,0.75:0.1:36,1:0.1:36,"/>
</Variable>
<Variable Name="Cascade 0: Slope Bias" Value="64">
<Spline Keys="0:64:36,0.25:64:36,0.5:64:65572,0.75:64:36,1:64:36,"/>
</Variable>
<Variable Name="Cascade 1: Bias" Value="0.10000001">
<Spline Keys="0:0.1:36,0.25:0.1:36,0.5:0.1:65572,0.75:0.1:36,1:0.1:36,"/>
</Variable>
<Variable Name="Cascade 1: Slope Bias" Value="23">
<Spline Keys="0:23:36,0.25:23:36,0.5:23:65572,0.75:23:36,1:23:36,"/>
</Variable>
<Variable Name="Cascade 2: Bias" Value="0.10000001">
<Spline Keys="0:0.1:36,0.25:0.1:36,0.5:0.1:65572,0.75:0.1:36,1:0.1:36,"/>
</Variable>
<Variable Name="Cascade 2: Slope Bias" Value="4">
<Spline Keys="0:4:36,0.25:4:36,0.5:4:65572,0.75:4:36,1:4:36,"/>
</Variable>
<Variable Name="Cascade 3: Bias" Value="0.10000001">
<Spline Keys="0:0.1:36,0.25:0.1:36,0.5:0.1:36,0.75:0.1:36,1:0.1:36,"/>
</Variable>
<Variable Name="Cascade 3: Slope Bias" Value="1">
<Spline Keys="0:1:36,0.25:1:36,0.5:1:65572,0.75:1:36,1:1:36,"/>
</Variable>
<Variable Name="Cascade 4: Bias" Value="0.10000001">
<Spline Keys="0:0.1:0,0.25:0.1:36,0.5:0.1:65572,0.75:0.1:36,1:0.1:36,"/>
</Variable>
<Variable Name="Cascade 4: Slope Bias" Value="1">
<Spline Keys="0:1:0,0.25:1:36,0.5:1:65572,0.75:1:36,1:1:36,"/>
</Variable>
<Variable Name="Cascade 5: Bias" Value="0.0099999998">
<Spline Keys="0:0.01:0,0.25:0.01:36,0.5:0.01:65572,0.75:0.01:36,1:0.01:36,"/>
</Variable>
<Variable Name="Cascade 5: Slope Bias" Value="1">
<Spline Keys="0:1:0,0.25:1:36,0.5:1:65572,0.75:1:36,1:1:36,"/>
</Variable>
<Variable Name="Cascade 6: Bias" Value="0.10000001">
<Spline Keys="0:0.1:0,0.25:0.1:36,0.5:0.1:36,0.75:0.1:36,1:0.1:36,"/>
</Variable>
<Variable Name="Cascade 6: Slope Bias" Value="1">
<Spline Keys="0:1:0,0.25:1:36,0.5:1:65572,0.75:1:36,1:1:36,"/>
</Variable>
<Variable Name="Cascade 7: Bias" Value="0.10000001">
<Spline Keys="0:0.1:0,0.25:0.1:36,0.5:0.1:36,0.75:0.1:36,1:0.1:36,"/>
</Variable>
<Variable Name="Cascade 7: Slope Bias" Value="1">
<Spline Keys="0:1:0,0.25:1:36,0.5:1:65572,0.75:1:36,1:1:36,"/>
</Variable>
<Variable Name="Shadow jittering" Value="2.4999998">
<Spline Keys="0:5:36,0.25:2.5:36,0.5:2.5:65572,0.75:2.5:36,1:5:0,"/>
</Variable>
<Variable Name="HDR dynamic power factor" Value="0">
<Spline Keys="0:0:36,0.25:0:36,0.5:0:65572,0.75:0:36,1:0:36,"/>
</Variable>
<Variable Name="Sky brightening (terrain occlusion)" Value="0">
<Spline Keys="0:0:36,0.25:0:36,0.5:0:36,0.75:0:36,1:0:36,"/>
</Variable>
<Variable Name="Sun color multiplier" Value="9.999999">
<Spline Keys="0:0.1:36,0.25:10:36,0.5:10:36,0.75:10:36,1:0.1:36,"/>
</Variable>
</TimeOfDay>

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:0e6a5435c928079b27796f6b202bbc2623e7e454244ddc099a3cadf33b7cb9e9
size 63

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:8739c76e681f900923b900c9df0ef75cf421d39cabb54650c4b9ad19b6a76d85
size 22

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:9799510badafd54e2a47574ea7e0112b8cb7eb23facf4dff8adc6f51fa624953
size 7955

@ -43,14 +43,13 @@ AZ_POP_DISABLE_WARNING
#include <AzCore/RTTI/BehaviorContext.h>
#include <AzCore/std/smart_ptr/make_shared.h>
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
#include <AzCore/StringFunc/StringFunc.h>
#include <AzCore/Utils/Utils.h>
#include <AzCore/Console/IConsole.h>
// AzFramework
#include <AzFramework/Components/CameraBus.h>
#include <AzFramework/StringFunc/StringFunc.h>
#include <AzFramework/Terrain/TerrainDataRequestBus.h>
#include <AzFramework/Process/ProcessWatcher.h>
#include <AzFramework/ProjectManager/ProjectManager.h>
#include <AzFramework/Spawnable/RootSpawnableInterface.h>
@ -105,6 +104,7 @@ AZ_POP_DISABLE_WARNING
#include "WaitProgress.h"
#include "ToolBox.h"
#include "LevelInfo.h"
#include "EditorPreferencesDialog.h"
#include "AnimationContext.h"
@ -422,6 +422,7 @@ void CCryEditApp::RegisterActionHandlers()
ON_COMMAND(ID_DISPLAY_GOTOPOSITION, OnDisplayGotoPosition)
ON_COMMAND(ID_FILE_SAVELEVELRESOURCES, OnFileSavelevelresources)
ON_COMMAND(ID_CLEAR_REGISTRY, OnClearRegistryData)
ON_COMMAND(ID_VALIDATELEVEL, OnValidatelevel)
ON_COMMAND(ID_TOOLS_PREFERENCES, OnToolsPreferences)
ON_COMMAND(ID_SWITCHCAMERA_DEFAULTCAMERA, OnSwitchToDefaultCamera)
ON_COMMAND(ID_SWITCHCAMERA_SEQUENCECAMERA, OnSwitchToSequenceCamera)
@ -769,6 +770,28 @@ QString CCryEditApp::ShowWelcomeDialog()
return levelName;
}
//////////////////////////////////////////////////////////////////////////
void CCryEditApp::InitDirectory()
{
//////////////////////////////////////////////////////////////////////////
// Initializes Root folder of the game.
//////////////////////////////////////////////////////////////////////////
QString szExeFileName = qApp->applicationDirPath();
const static char* s_engineMarkerFile = "engine.json";
while (!QFile::exists(QString("%1/%2").arg(szExeFileName, s_engineMarkerFile)))
{
QDir currentdir(szExeFileName);
if (!currentdir.cdUp())
{
break;
}
szExeFileName = currentdir.absolutePath();
}
QDir::setCurrent(szExeFileName);
}
//////////////////////////////////////////////////////////////////////////
// Needed to work with custom memory manager.
//////////////////////////////////////////////////////////////////////////
@ -1481,7 +1504,7 @@ void CCryEditApp::RunInitPythonScript(CEditCommandLineInfo& cmdInfo)
// We support specifying multiple files in the cmdline by separating them with ';'
AZStd::vector<AZStd::string_view> fileList;
AZ::StringFunc::TokenizeVisitor(
AzFramework::StringFunc::TokenizeVisitor(
fileStr.constData(),
[&fileList](AZStd::string_view elem)
{
@ -1493,7 +1516,7 @@ void CCryEditApp::RunInitPythonScript(CEditCommandLineInfo& cmdInfo)
{
QByteArray pythonArgsStr = cmdInfo.m_pythonArgs.toUtf8();
AZStd::vector<AZStd::string_view> pythonArgs;
AZ::StringFunc::TokenizeVisitor(pythonArgsStr.constData(),
AzFramework::StringFunc::TokenizeVisitor(pythonArgsStr.constData(),
[&pythonArgs](AZStd::string_view elem)
{
pythonArgs.push_back(elem);
@ -1508,7 +1531,7 @@ void CCryEditApp::RunInitPythonScript(CEditCommandLineInfo& cmdInfo)
testcaseList.resize(fileList.size());
{
int i = 0;
AZ::StringFunc::TokenizeVisitor(
AzFramework::StringFunc::TokenizeVisitor(
pythonTestCase.constData(),
[&i, &testcaseList](AZStd::string_view elem)
{
@ -1572,6 +1595,7 @@ bool CCryEditApp::InitInstance()
{
QElapsedTimer startupTimer;
startupTimer.start();
InitDirectory();
// create / attach to the environment:
AttachEditorCoreAZEnvironment(AZ::Environment::GetInstance());
@ -1582,6 +1606,8 @@ bool CCryEditApp::InitInstance()
InitFromCommandLine(cmdInfo);
InitDirectory();
qobject_cast<Editor::EditorQtApplication*>(qApp)->Initialize(); // Must be done after CEditorImpl() is created
m_pEditor->Initialize();
@ -3618,6 +3644,14 @@ void CCryEditApp::OnClearRegistryData()
}
}
//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnValidatelevel()
{
// TODO: Add your command handler code here
CLevelInfo levelInfo;
levelInfo.Validate();
}
//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnToolsPreferences()
{
@ -3793,68 +3827,131 @@ CMainFrame * CCryEditApp::GetMainFrame() const
return MainWindow::instance()->GetOldMainFrame();
}
void CCryEditApp::OpenLUAEditor(const char* files)
void CCryEditApp::StartProcessDetached(const char* process, const char* args)
{
AZ::IO::FixedMaxPathString enginePath = AZ::Utils::GetEnginePath();
// Build the arguments as a QStringList
AZStd::vector<AZStd::string> tokens;
AZ::IO::FixedMaxPathString projectPath = AZ::Utils::GetProjectPath();
AZStd::string filename = "LuaIDE";
AZ::IO::FixedMaxPath executablePath = AZ::Utils::GetExecutableDirectory();
executablePath /= filename + AZ_TRAIT_OS_EXECUTABLE_EXTENSION;
// separate the string based on spaces for paths like "-launch", "lua", "-files";
// also separate the string and keep spaces inside the folder path;
// Ex: C:\dev\Foundation\dev\Cache\AutomatedTesting\pc\automatedtesting\scripts\components\a a\empty.lua;
// Ex: C:\dev\Foundation\dev\Cache\AutomatedTesting\pc\automatedtesting\scripts\components\a a\'empty'.lua;
AZStd::string currentStr(args);
AZStd::size_t firstQuotePos = AZStd::string::npos;
AZStd::size_t secondQuotePos = 0;
AZStd::size_t pos = 0;
if (!AZ::IO::SystemFile::Exists(executablePath.c_str()))
while (!currentStr.empty())
{
AZ_Error("LuaIDE", false, "%s not found", executablePath.c_str());
return;
firstQuotePos = currentStr.find_first_of('\"');
pos = currentStr.find_first_of(" ");
if ((firstQuotePos != AZStd::string::npos) && (firstQuotePos < pos || pos == AZStd::string::npos))
{
secondQuotePos = currentStr.find_first_of('\"', firstQuotePos + 1);
if (secondQuotePos == AZStd::string::npos)
{
AZ_Warning("StartProcessDetached", false, "String tokenize failed, no matching \" found.");
return;
}
AZStd::string newElement(AZStd::string(currentStr.data() + (firstQuotePos + 1), (secondQuotePos - 1)));
tokens.push_back(newElement);
currentStr = currentStr.substr(secondQuotePos + 1);
firstQuotePos = AZStd::string::npos;
secondQuotePos = 0;
continue;
}
else
{
if (pos != AZStd::string::npos)
{
AZStd::string newElement(AZStd::string(currentStr.data() + 0, pos));
tokens.push_back(newElement);
currentStr = currentStr.substr(pos + 1);
}
else
{
tokens.push_back(AZStd::string(currentStr));
break;
}
}
}
AzFramework::ProcessLauncher::ProcessLaunchInfo processLaunchInfo;
QStringList argsList;
for (const auto& arg : tokens)
{
argsList.push_back(QString(arg.c_str()));
}
AZStd::vector<AZStd::string> launchCmd = { executablePath.String() };
launchCmd.emplace_back("--engine-path");
launchCmd.emplace_back(AZStd::string_view{ enginePath });
launchCmd.emplace_back("--project-path");
launchCmd.emplace_back(AZStd::string_view{ projectPath });
launchCmd.emplace_back("--launch");
launchCmd.emplace_back("lua");
// Launch the process
[[maybe_unused]] bool startDetachedReturn = QProcess::startDetached(
process,
argsList,
QCoreApplication::applicationDirPath()
);
AZ_Warning("StartProcessDetached", startDetachedReturn, "Failed to start process:%s args:%s", process, args);
}
auto ParseFilesList = [&launchCmd](AZStd::string_view filePath)
void CCryEditApp::OpenLUAEditor(const char* files)
{
AZStd::string args = "-launch lua";
if (files && strlen(files) > 0)
{
bool fullPathFound = false;
auto GetFullSourcePath = [&launchCmd, &filePath, &fullPathFound]
(AzToolsFramework::AssetSystem::AssetSystemRequest* assetSystemRequests)
AZStd::vector<AZStd::string> resolvedPaths;
AZStd::vector<AZStd::string> tokens;
AzFramework::StringFunc::Tokenize(files, tokens, '|');
for (const auto& file : tokens)
{
AZ::IO::Path assetFullPath;
if(assetSystemRequests->GetFullSourcePathFromRelativeProductPath(filePath, assetFullPath.Native()))
char resolved[AZ_MAX_PATH_LEN];
AZStd::string fullPath = Path::GamePathToFullPath(file.c_str()).toUtf8().data();
azstrncpy(resolved, AZ_MAX_PATH_LEN, fullPath.c_str(), fullPath.size());
if (AZ::IO::FileIOBase::GetInstance()->Exists(resolved))
{
fullPathFound = true;
launchCmd.emplace_back("--files");
launchCmd.emplace_back(AZStd::move(assetFullPath.Native()));
AZStd::string current = '\"' + AZStd::string(resolved) + '\"';
AZStd::replace(current.begin(), current.end(), '\\', '/');
resolvedPaths.push_back(current);
}
};
AzToolsFramework::AssetSystemRequestBus::Broadcast(AZStd::move(GetFullSourcePath));
// If the full source path could be found through the Asset System, then
// attempt to resolve the path using the FileIO instance
if (!fullPathFound)
{
AZ::IO::FixedMaxPath resolvedFilePath;
if (auto fileIo = AZ::IO::FileIOBase::GetInstance();
fileIo != nullptr && fileIo->ResolvePath(resolvedFilePath, filePath)
&& fileIo->Exists(resolvedFilePath.c_str()))
}
if (!resolvedPaths.empty())
{
for (const auto& resolvedPath : resolvedPaths)
{
launchCmd.emplace_back("--files");
launchCmd.emplace_back(resolvedFilePath.String());
args.append(AZStd::string::format(" -files %s", resolvedPath.c_str()));
}
}
};
AZ::StringFunc::TokenizeVisitor(files, ParseFilesList, "|");
}
processLaunchInfo.m_commandlineParameters = AZStd::move(launchCmd);
AZ::IO::FixedMaxPathString engineRoot = AZ::Utils::GetEnginePath();
AZ_Assert(!engineRoot.empty(), "Unable to query Engine Path");
AZ_VerifyError("LuaIDE", AzFramework::ProcessLauncher::LaunchUnwatchedProcess(processLaunchInfo),
"Lua IDE has failed to launch at path %s", executablePath.c_str());
AZStd::string_view exePath;
AZ::ComponentApplicationBus::BroadcastResult(exePath, &AZ::ComponentApplicationRequests::GetExecutableFolder);
#if defined(AZ_PLATFORM_LINUX)
// On Linux platforms, launching a process is not done through a shell and its arguments are passed in
// separately. There is no need to wrap the process path in case of spaces in the path
constexpr const char* argumentQuoteString = "";
#else
constexpr const char* argumentQuoteString = "\"";
#endif
AZStd::string process = AZStd::string::format("%s%.*s" AZ_CORRECT_FILESYSTEM_SEPARATOR_STRING "LuaIDE"
#if defined(AZ_PLATFORM_WINDOWS)
".exe"
#endif
"%s", argumentQuoteString, aznumeric_cast<int>(exePath.size()), exePath.data(), argumentQuoteString);
AZStd::string processArgs = AZStd::string::format("%s -engine-path \"%s\"", args.c_str(), engineRoot.c_str());
StartProcessDetached(process.c_str(), processArgs.c_str());
}
void CCryEditApp::PrintAlways(const AZStd::string& output)
@ -3968,6 +4065,11 @@ extern "C" int AZ_DLL_EXPORT CryEditMain(int argc, char* argv[])
gSettings.Connect();
auto theApp = AZStd::make_unique<CCryEditApp>();
// this does some magic to set the current directory...
{
QCoreApplication app(argc, argv);
CCryEditApp::InitDirectory();
}
// Must be set before QApplication is initialized, so that we support HighDpi monitors, like the Retina displays
// on Windows 10

@ -138,6 +138,7 @@ public:
RecentFileList* GetRecentFileList();
virtual void AddToRecentFileList(const QString& lpszPathName);
ECreateLevelResult CreateLevel(const QString& levelName, QString& fullyQualifiedLevelName);
static void InitDirectory();
bool FirstInstance(bool bForceNewInstance = false);
void InitFromCommandLine(CEditCommandLineInfo& cmdInfo);
bool CheckIfAlreadyRunning();
@ -158,6 +159,11 @@ public:
// Print to stdout even if there out has been redirected
void PrintAlways(const AZStd::string& output);
//! Launches a detached process
//! \param process The path to the process to start
//! \param args Space separated list of arguments to pass to the process on start.
void StartProcessDetached(const char* process, const char* args);
//! Launches the Lua Editor/Debugger
//! \param files A space separated list of aliased paths
void OpenLUAEditor(const char* files);
@ -393,6 +399,7 @@ private:
void OnDisplayGotoPosition();
void OnFileSavelevelresources();
void OnClearRegistryData();
void OnValidatelevel();
void OnToolsPreferences();
void OnSwitchToDefaultCamera();
void OnUpdateSwitchToDefaultCamera(QAction* action);

@ -260,6 +260,11 @@ namespace
namespace
{
void PyStartProcessDetached(const char* process, const char* args)
{
CCryEditApp::instance()->StartProcessDetached(process, args);
}
void PyLaunchLUAEditor(const char* files)
{
CCryEditApp::instance()->OpenLUAEditor(files);
@ -424,6 +429,7 @@ namespace AzToolsFramework
addLegacyGeneral(behaviorContext->Method("idle_wait", PyIdleWait, nullptr, "Waits idling for a given seconds. Primarily used for auto-testing."));
addLegacyGeneral(behaviorContext->Method("idle_wait_frames", PyIdleWaitFrames, nullptr, "Waits idling for a frames. Primarily used for auto-testing."));
addLegacyGeneral(behaviorContext->Method("start_process_detached", PyStartProcessDetached, nullptr, "Launches a detached process with an optional space separated list of arguments."));
addLegacyGeneral(behaviorContext->Method("launch_lua_editor", PyLaunchLUAEditor, nullptr, "Launches the Lua editor, may receive a list of space separate file paths, or an empty string to only open the editor."));
addLegacyGeneral(behaviorContext->Method("attach_debugger", PyAttachDebugger, nullptr, "Prompts for attaching the debugger"));

@ -287,16 +287,16 @@ namespace SandboxEditor
return SandboxEditor::CameraBoostMultiplier();
};
m_orbitScrollDollyCamera = AZStd::make_shared<AzFramework::OrbitScrollDollyCameraInput>();
m_orbitDollyScrollCamera = AZStd::make_shared<AzFramework::OrbitDollyScrollCameraInput>();
m_orbitScrollDollyCamera->m_scrollSpeedFn = []
m_orbitDollyScrollCamera->m_scrollSpeedFn = []
{
return SandboxEditor::CameraScrollSpeed();
};
m_orbitMotionDollyCamera = AZStd::make_shared<AzFramework::OrbitMotionDollyCameraInput>(SandboxEditor::CameraOrbitDollyChannelId());
m_orbitDollyMoveCamera = AZStd::make_shared<AzFramework::OrbitDollyMotionCameraInput>(SandboxEditor::CameraOrbitDollyChannelId());
m_orbitMotionDollyCamera->m_motionSpeedFn = []
m_orbitDollyMoveCamera->m_motionSpeedFn = []
{
return SandboxEditor::CameraDollyMotionSpeed();
};
@ -326,8 +326,8 @@ namespace SandboxEditor
m_orbitCamera->m_orbitCameras.AddCamera(m_orbitRotateCamera);
m_orbitCamera->m_orbitCameras.AddCamera(m_orbitTranslateCamera);
m_orbitCamera->m_orbitCameras.AddCamera(m_orbitScrollDollyCamera);
m_orbitCamera->m_orbitCameras.AddCamera(m_orbitMotionDollyCamera);
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);
}
@ -344,7 +344,7 @@ namespace SandboxEditor
m_orbitTranslateCamera->SetTranslateCameraInputChannelIds(translateCameraInputChannelIds);
m_orbitPanCamera->SetPanInputChannelId(SandboxEditor::CameraOrbitPanChannelId());
m_orbitRotateCamera->SetRotateInputChannelId(SandboxEditor::CameraOrbitLookChannelId());
m_orbitMotionDollyCamera->SetDollyInputChannelId(SandboxEditor::CameraOrbitDollyChannelId());
m_orbitDollyMoveCamera->SetDollyInputChannelId(SandboxEditor::CameraOrbitDollyChannelId());
m_orbitFocusCamera->SetFocusInputChannelId(SandboxEditor::CameraFocusChannelId());
}

@ -56,8 +56,8 @@ namespace SandboxEditor
AZStd::shared_ptr<AzFramework::OrbitCameraInput> m_orbitCamera;
AZStd::shared_ptr<AzFramework::RotateCameraInput> m_orbitRotateCamera;
AZStd::shared_ptr<AzFramework::TranslateCameraInput> m_orbitTranslateCamera;
AZStd::shared_ptr<AzFramework::OrbitScrollDollyCameraInput> m_orbitScrollDollyCamera;
AZStd::shared_ptr<AzFramework::OrbitMotionDollyCameraInput> m_orbitMotionDollyCamera;
AZStd::shared_ptr<AzFramework::OrbitDollyScrollCameraInput> m_orbitDollyScrollCamera;
AZStd::shared_ptr<AzFramework::OrbitDollyMotionCameraInput> m_orbitDollyMoveCamera;
AZStd::shared_ptr<AzFramework::PanCameraInput> m_orbitPanCamera;
AZStd::shared_ptr<AzFramework::FocusCameraInput> m_orbitFocusCamera;

@ -0,0 +1,178 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include "EditorDefs.h"
#include "LevelInfo.h"
// Qt
#include <QMessageBox>
// Editor
#include "Util/fastlib.h"
#include <AzFramework/Terrain/TerrainDataRequestBus.h>
#include "QtUI/WaitCursor.h" // for WaitCursor
#include "Include/IErrorReport.h"
#include "Include/IObjectManager.h"
#include "Objects/BaseObject.h"
#include "UsedResources.h"
#include "ErrorReport.h"
//////////////////////////////////////////////////////////////////////////
CLevelInfo::CLevelInfo()
{
m_pReport = GetIEditor()->GetErrorReport();
}
//////////////////////////////////////////////////////////////////////////
void CLevelInfo::SaveLevelResources([[maybe_unused]] const QString& toPath)
{
}
//////////////////////////////////////////////////////////////////////////
void CLevelInfo::Validate()
{
m_pReport->Clear();
m_pReport->SetImmediateMode(false);
m_pReport->SetShowErrors(true);
int nTotalErrors(0);
int nCurrentError(0);
// Here we are appending the current level load errors to the general errors.
// Actually we are inserting them before all others, but this is not important :-).
IErrorReport* poLastLoadedLevelErrorReport = GetIEditor()->GetLastLoadedLevelErrorReport();
if (poLastLoadedLevelErrorReport)
{
nTotalErrors = poLastLoadedLevelErrorReport->GetErrorCount();
for (nCurrentError = 0; nCurrentError < nTotalErrors; ++nCurrentError)
{
m_pReport->ReportError(poLastLoadedLevelErrorReport->GetError(nCurrentError));
}
}
// Validate level.
ValidateObjects();
if (m_pReport->GetErrorCount() == 0)
{
QMessageBox::information(QApplication::activeWindow(), QString(), QObject::tr("No Errors Found"));
}
else
{
m_pReport->Display();
}
}
//////////////////////////////////////////////////////////////////////////
void CLevelInfo::ValidateObjects()
{
WaitCursor cursor;
// Validate all objects
CBaseObjectsArray objects;
GetIEditor()->GetObjectManager()->GetObjects(objects);
int i;
CLogFile::WriteLine("Validating Objects...");
for (i = 0; i < objects.size(); i++)
{
CBaseObject* pObject = objects[i];
m_pReport->SetCurrentValidatorObject(pObject);
pObject->Validate(m_pReport);
m_pReport->SetCurrentValidatorObject(nullptr);
}
CLogFile::WriteLine("Validating Duplicate Objects...");
//////////////////////////////////////////////////////////////////////////
// Find duplicate objects, Same objects with same transform.
// Use simple grid to speed up the check.
//////////////////////////////////////////////////////////////////////////
int gridSize = 256;
AZ::Aabb terrainAabb = AZ::Aabb::CreateFromPoint(AZ::Vector3::CreateZero());
AzFramework::Terrain::TerrainDataRequestBus::BroadcastResult(terrainAabb, &AzFramework::Terrain::TerrainDataRequests::GetTerrainAabb);
float worldSize = terrainAabb.GetXExtent();
float fGridToWorld = worldSize / gridSize;
// Put all objects into parition grid.
std::vector<std::list<CBaseObject*> > grid;
grid.resize(gridSize * gridSize);
// Put objects to grid.
for (i = 0; i < objects.size(); i++)
{
CBaseObject* pObject = objects[i];
Vec3 pos = pObject->GetWorldPos();
int px = ftoi(pos.x / fGridToWorld);
int py = ftoi(pos.y / fGridToWorld);
if (px < 0)
{
px = 0;
}
if (py < 0)
{
py = 0;
}
if (px >= gridSize)
{
px = gridSize - 1;
}
if (py >= gridSize)
{
py = gridSize - 1;
}
grid[py * gridSize + px].push_back(pObject);
}
std::list<CBaseObject*>::iterator it1, it2;
// Check objects in grid.
for (i = 0; i < gridSize * gridSize; i++)
{
std::list<CBaseObject*>::iterator first = grid[i].begin();
std::list<CBaseObject*>::iterator last = grid[i].end();
for (it1 = first; it1 != last; ++it1)
{
for (it2 = first; it2 != it1; ++it2)
{
// Check if same object.
CBaseObject* p1 = *it1;
CBaseObject* p2 = *it2;
if (p1 != p2 && p1->GetClassDesc() == p2->GetClassDesc())
{
// Same class.
Quat q1 = p1->GetRotation();
Quat q2 = p2->GetRotation();
if (p1->GetWorldPos() == p2->GetWorldPos() && q1.w == q2.w && IsEquivalent(q1.v, q2.v, 0) && p1->GetScale() == p2->GetScale())
{
// Same transformation
// Check if objects are really same.
if (p1->IsSimilarObject(p2))
{
// Report duplicate objects.
CErrorRecord err;
err.error = QObject::tr("Found multiple objects in the same location (class %1): %2 and %3")
.arg(p1->GetClassDesc()->ClassName(), p1->GetName(), p2->GetName());
err.pObject = p1;
err.severity = CErrorRecord::ESEVERITY_ERROR;
m_pReport->ReportError(err);
}
}
}
}
}
}
}

@ -0,0 +1,30 @@
/*
* 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
*
*/
#ifndef CRYINCLUDE_EDITOR_LEVELINFO_H
#define CRYINCLUDE_EDITOR_LEVELINFO_H
#pragma once
/*! CLevelInfo provides methods for getting information about current level.
*/
class CLevelInfo
{
public:
CLevelInfo();
void Validate();
void SaveLevelResources(const QString& toPath);
private:
void ValidateObjects();
IErrorReport* m_pReport;
};
#endif // CRYINCLUDE_EDITOR_LEVELINFO_H

@ -36,7 +36,7 @@ namespace CryEditPythonBindingsUnitTests
m_app.Start(appDesc);
// Without this, the user settings component would attempt to save on finalize/shutdown. Since the file is
// shared across the whole engine, if multiple tests are run in parallel, the saving could cause a crash
// shared across the whole engine, if multiple tests are run in parallel, the saving could cause a crash
// in the unit tests.
AZ::UserSettingsComponentRequestBus::Broadcast(&AZ::UserSettingsComponentRequests::DisableSaveOnFinalize);
m_app.RegisterComponentDescriptor(AzToolsFramework::CryEditPythonHandler::CreateDescriptor());
@ -74,6 +74,7 @@ namespace CryEditPythonBindingsUnitTests
EXPECT_TRUE(behaviorContext->m_methods.find("idle_is_enabled") != behaviorContext->m_methods.end());
EXPECT_TRUE(behaviorContext->m_methods.find("idle_wait") != behaviorContext->m_methods.end());
EXPECT_TRUE(behaviorContext->m_methods.find("idle_wait_frames") != behaviorContext->m_methods.end());
EXPECT_TRUE(behaviorContext->m_methods.find("start_process_detached") != behaviorContext->m_methods.end());
EXPECT_TRUE(behaviorContext->m_methods.find("launch_lua_editor") != behaviorContext->m_methods.end());
}

@ -1011,6 +1011,9 @@ void MainWindow::InitActions()
am->AddAction(ID_TOOLS_ENABLEFILECHANGEMONITORING, tr("Enable File Change Monitoring"));
am->AddAction(ID_CLEAR_REGISTRY, tr("Clear Registry Data"))
.SetStatusTip(tr("Clear Registry Data"));
am->AddAction(ID_VALIDATELEVEL, tr("&Check Level for Errors"))
.SetStatusTip(tr("Validate Level"));
am->AddAction(ID_TOOLS_VALIDATEOBJECTPOSITIONS, tr("Check Object Positions"));
QAction* saveLevelStatsAction =
am->AddAction(ID_TOOLS_LOGMEMORYUSAGE, tr("Save Level Statistics"))
.SetStatusTip(tr("Logs Editor memory usage."));

@ -1,55 +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
*
*/
#include <ContextMenuHandlers.h>
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
#include <QAction>
#include <QMenu>
void ContextMenuBottomHandler::Setup()
{
AzToolsFramework::EditorContextMenuBus::Handler::BusConnect();
}
void ContextMenuBottomHandler::Teardown()
{
AzToolsFramework::EditorContextMenuBus::Handler::BusDisconnect();
}
int ContextMenuBottomHandler::GetMenuPosition() const
{
return aznumeric_cast<int>(AzToolsFramework::EditorContextMenuOrdering::BOTTOM);
}
void ContextMenuBottomHandler::PopulateEditorGlobalContextMenu(
QMenu* menu, [[maybe_unused]] const AZ::Vector2& point, [[maybe_unused]] int flags)
{
AzToolsFramework::EntityIdList selected;
AzToolsFramework::ToolsApplicationRequestBus::BroadcastResult(
selected, &AzToolsFramework::ToolsApplicationRequests::GetSelectedEntities);
QAction* action = nullptr;
if (selected.size() > 0)
{
action = menu->addAction(QObject::tr("Open pinned Inspector"));
QObject::connect(
action, &QAction::triggered, action,
[selected]
{
AzToolsFramework::EntityIdSet pinnedEntities(selected.begin(), selected.end());
AzToolsFramework::EditorRequestBus::Broadcast(&AzToolsFramework::EditorRequests::OpenPinnedInspector, pinnedEntities);
}
);
menu->addSeparator();
}
}

@ -1,23 +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
*
*/
#pragma once
#include <AzToolsFramework/Editor/EditorContextMenuBus.h>
class ContextMenuBottomHandler : private AzToolsFramework::EditorContextMenuBus::Handler
{
public:
void Setup();
void Teardown();
private:
// EditorContextMenu overrides ...
void PopulateEditorGlobalContextMenu(QMenu* menu, const AZ::Vector2& point, int flags) override;
int GetMenuPosition() const override;
};

@ -45,17 +45,17 @@
#include <AzToolsFramework/Entity/SliceEditorEntityOwnershipServiceBus.h>
#include <AzToolsFramework/Slice/SliceRequestBus.h>
#include <AzToolsFramework/Slice/SliceUtilities.h>
#include <AzToolsFramework/ToolsComponents/GenericComponentWrapper.h>
#include <AzToolsFramework/ToolsComponents/EditorLayerComponent.h>
#include <AzToolsFramework/ToolsComponents/EditorVisibilityComponent.h>
#include <AzToolsFramework/ToolsComponents/GenericComponentWrapper.h>
#include <AzToolsFramework/Undo/UndoSystem.h>
#include <AzToolsFramework/UI/EditorEntityUi/EditorEntityUiInterface.h>
#include <AzToolsFramework/UI/Layer/AddToLayerMenu.h>
#include <AzToolsFramework/UI/Layer/NameConflictWarning.hxx>
#include <AzToolsFramework/UI/Prefab/PrefabIntegrationInterface.h>
#include <AzToolsFramework/UI/PropertyEditor/InstanceDataHierarchy.h>
#include <AzToolsFramework/UI/PropertyEditor/PropertyEditorAPI.h>
#include <AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.hxx>
#include <AzToolsFramework/UI/Layer/NameConflictWarning.hxx>
#include <AzToolsFramework/ViewportSelection/EditorHelpers.h>
#include <AzToolsFramework/ViewportSelection/EditorSelectionUtil.h>
#include <MathConversion.h>
@ -212,8 +212,6 @@ void SandboxIntegrationManager::Setup()
AZ_Assert(m_readOnlyEntityPublicInterface, "SandboxIntegrationManager requires an ReadOnlyEntityPublicInterface instance to be present on Setup().");
AzToolsFramework::Layers::EditorLayerComponentNotificationBus::Handler::BusConnect();
m_contextMenuBottomHandler.Setup();
}
void SandboxIntegrationManager::SaveSlice(const bool& QuickPushToFirstLevel)
@ -397,8 +395,6 @@ void SandboxIntegrationManager::GetEntitiesInSlices(
void SandboxIntegrationManager::Teardown()
{
m_contextMenuBottomHandler.Teardown();
AzToolsFramework::Layers::EditorLayerComponentNotificationBus::Handler::BusDisconnect();
AzFramework::DisplayContextRequestBus::Handler::BusDisconnect();
AzToolsFramework::SliceEditorEntityOwnershipServiceNotificationBus::Handler::BusDisconnect();
@ -655,14 +651,12 @@ void SandboxIntegrationManager::PopulateEditorGlobalContextMenu(QMenu* menu, con
if (selected.size() == 0)
{
action = menu->addAction(QObject::tr("Create entity"));
action->setShortcut(QKeySequence(Qt::CTRL + Qt::ALT + Qt::Key_N));
QObject::connect(
action, &QAction::triggered, action,
[this]
{
ContextMenu_NewEntity();
}
);
});
}
// when a single entity is selected, entity is created as its child
else if (selected.size() == 1)
@ -673,7 +667,6 @@ void SandboxIntegrationManager::PopulateEditorGlobalContextMenu(QMenu* menu, con
if (!prefabSystemEnabled || (containerEntityInterface && containerEntityInterface->IsContainerOpen(selectedEntityId) && !selectedEntityIsReadOnly))
{
action = menu->addAction(QObject::tr("Create entity"));
action->setShortcut(QKeySequence(Qt::CTRL + Qt::ALT + Qt::Key_N));
QObject::connect(
action, &QAction::triggered, action,
[selectedEntityId]
@ -701,30 +694,33 @@ void SandboxIntegrationManager::PopulateEditorGlobalContextMenu(QMenu* menu, con
AzToolsFramework::SetupAddToLayerMenu(menu, flattenedSelection, [this] { return ContextMenu_NewLayer(); });
SetupSliceContextMenu(menu);
}
if (!selected.empty())
if (!selected.empty())
{
// Don't allow duplication if any of the selected entities are direct desendants of a read-only entity
bool selectionContainsDescendantOfReadOnlyEntity = false;
for (const auto& entityId : selected)
{
// Don't allow duplication if any of the selected entities are direct descendants of a read-only entity
bool selectionContainsDescendantOfReadOnlyEntity = false;
for (const auto& entityId : selected)
{
AZ::EntityId parentEntityId;
AZ::TransformBus::EventResult(parentEntityId, entityId, &AZ::TransformBus::Events::GetParentId);
if (parentEntityId.IsValid() && m_readOnlyEntityPublicInterface->IsReadOnly(parentEntityId))
{
selectionContainsDescendantOfReadOnlyEntity = true;
break;
}
}
AZ::EntityId parentEntityId;
AZ::TransformBus::EventResult(parentEntityId, entityId, &AZ::TransformBus::Events::GetParentId);
if (!selectionContainsDescendantOfReadOnlyEntity)
if (parentEntityId.IsValid() && m_readOnlyEntityPublicInterface->IsReadOnly(parentEntityId))
{
action = menu->addAction(QObject::tr("Duplicate"));
QObject::connect(action, &QAction::triggered, action, [this] { ContextMenu_Duplicate(); });
selectionContainsDescendantOfReadOnlyEntity = true;
break;
}
}
if (!selectionContainsDescendantOfReadOnlyEntity)
{
action = menu->addAction(QObject::tr("Duplicate"));
QObject::connect(action, &QAction::triggered, action, [this] { ContextMenu_Duplicate(); });
}
}
if (!prefabSystemEnabled)
{
action = menu->addAction(QObject::tr("Delete"));
QObject::connect(action, &QAction::triggered, action, [this] { ContextMenu_DeleteSelected(); });
if (selected.size() == 0)
@ -737,14 +733,20 @@ void SandboxIntegrationManager::PopulateEditorGlobalContextMenu(QMenu* menu, con
if (selected.size() > 0)
{
action = menu->addAction(QObject::tr("Find in Entity Outliner"));
QObject::connect(
action, &QAction::triggered,
[selected]
action = menu->addAction(QObject::tr("Open pinned Inspector"));
QObject::connect(action, &QAction::triggered, action, [this, selected]
{
AzToolsFramework::EntityIdSet pinnedEntities(selected.begin(), selected.end());
OpenPinnedInspector(pinnedEntities);
});
if (selected.size() > 0)
{
action = menu->addAction(QObject::tr("Find in Entity Outliner"));
QObject::connect(action, &QAction::triggered, [selected]
{
AzToolsFramework::EditorEntityContextNotificationBus::Broadcast(
&EditorEntityContextNotification::OnFocusInEntityOutliner, selected);
AzToolsFramework::EditorEntityContextNotificationBus::Broadcast(&EditorEntityContextNotification::OnFocusInEntityOutliner, selected);
});
}
menu->addSeparator();
}
}

@ -9,8 +9,6 @@
#ifndef CRYINCLUDE_COMPONENTENTITYEDITORPLUGIN_SANDBOXINTEGRATION_H
#define CRYINCLUDE_COMPONENTENTITYEDITORPLUGIN_SANDBOXINTEGRATION_H
#include "ContextMenuHandlers.h"
#include <AzCore/Component/ComponentApplicationBus.h>
#include <AzCore/Slice/SliceBus.h>
#include <AzCore/Slice/SliceComponent.h>
@ -275,8 +273,6 @@ private:
};
private:
ContextMenuBottomHandler m_contextMenuBottomHandler;
AZ::Vector2 m_contextMenuViewPoint;
short m_startedUndoRecordingNestingLevel; // used in OnBegin/EndUndo to ensure we only accept undo's we started recording

@ -10,8 +10,6 @@ set(FILES
dllmain.cpp
ComponentEntityEditorPlugin.h
ComponentEntityEditorPlugin.cpp
ContextMenuHandlers.h
ContextMenuHandlers.cpp
SandboxIntegration.h
SandboxIntegration.cpp
UI/QComponentEntityEditorMainWindow.h

@ -86,6 +86,7 @@
#define ID_PHYSICS_RESETPHYSICSSTATE 32938
#define ID_GAME_SYNCPLAYER 32941
#define ID_FILE_SAVELEVELRESOURCES 32942
#define ID_VALIDATELEVEL 32943
#define ID_TERRAIN_RESIZE 32944
#define ID_TERRAIN_COLLISION 32960
#define ID_TOOL_FIRST 32972
@ -235,6 +236,7 @@
#define ID_SNAP_TO_GRID_RANGE_END 34106
#define ID_TOOLS_EXPORT_SHORTCUTS 34138
#define ID_TOOLS_IMPORT_SHORTCUTS 34139
#define ID_TOOLS_VALIDATEOBJECTPOSITIONS 34143
#define ID_TOOLS_BATCH_RENDER 34151
#define ID_TOOLS_SCRIPTHELP 34152
#define ID_TV_MODE_OPENCURVEEDITOR 34153

@ -532,6 +532,8 @@ set(FILES
ErrorReport.h
IconManager.cpp
IconManager.h
LevelInfo.cpp
LevelInfo.h
ProcessInfo.cpp
ProcessInfo.h
TrackView/AtomOutputFrameCapture.cpp

@ -9,7 +9,6 @@
#pragma once
#include <AzCore/base.h>
#include <AzCore/std/limits.h>
#include <AzCore/std/math.h>
#include <AzCore/std/typetraits/conditional.h>
#include <AzCore/std/typetraits/is_integral.h>
@ -21,7 +20,6 @@
#include <limits>
#include <math.h>
#include <utility>
#include <inttypes.h>
// We have a separate inline define for math functions.
// The performance of these functions is very sensitive to inlining, and some compilers don't deal well with this.
@ -258,13 +256,13 @@ namespace AZ
struct ClampedIntegralLimits
{
//! If SourceType and ClampType are different, returns the greater value of
//! AZStd::numeric_limits<SourceType>::lowest() and AZStd::numeric_limits<ClampType>::lowest(),
//! otherwise returns AZStd::numeric_limits<SourceType>::lowest().
//! std::numeric_limits<SourceType>::lowest() and std::numeric_limits<ClampType>::lowest(),
//! otherwise returns std::numeric_limits<SourceType>::lowest().
static constexpr SourceType Min();
//! If SourceType and ClampType are different, returns the lesser value of
//! AZStd::numeric_limits<SourceType>::max() and AZStd::numeric_limits<ClampType>::max(),
//! otherwise returns AZStd::numeric_limits<SourceType>::max().
//! std::numeric_limits<SourceType>::max() and std::numeric_limits<ClampType>::max(),
//! otherwise returns std::numeric_limits<SourceType>::max().
static constexpr SourceType Max();
//! Safely clamps a value of type ValueType to the [Min(), Max()] range as determined by the
@ -377,12 +375,12 @@ namespace AZ
//! Returns a value t where Lerp(a, b, t) == value (or 0 if a == b).
inline float LerpInverse(float a, float b, float value)
{
return IsClose(a, b, AZStd::numeric_limits<float>::epsilon()) ? 0.0f : (value - a) / (b - a);
return IsClose(a, b, std::numeric_limits<float>::epsilon()) ? 0.0f : (value - a) / (b - a);
}
inline double LerpInverse(double a, double b, double value)
{
return IsClose(a, b, AZStd::numeric_limits<double>::epsilon()) ? 0.0 : (value - a) / (b - a);
return IsClose(a, b, std::numeric_limits<double>::epsilon()) ? 0.0 : (value - a) / (b - a);
}
//! Returns true if the number provided is even.
@ -433,19 +431,19 @@ namespace AZ
AZ_MATH_INLINE float GetFloatQNaN()
{
return AZStd::numeric_limits<float>::quiet_NaN();
return std::numeric_limits<float>::quiet_NaN();
}
//! IsCloseMag(x, y, epsilon) returns true if y and x are sufficiently close, taking magnitude of x and y into account in the epsilon
template<typename T>
AZ_MATH_INLINE bool IsCloseMag(T x, T y, T epsilonValue = AZStd::numeric_limits<T>::epsilon())
AZ_MATH_INLINE bool IsCloseMag(T x, T y, T epsilonValue = std::numeric_limits<T>::epsilon())
{
return (AZStd::abs(x - y) <= epsilonValue * GetMax<T>(GetMax<T>(T(1.0), AZStd::abs(x)), AZStd::abs(y)));
}
//! ClampIfCloseMag(x, y, epsilon) returns y when x and y are within epsilon of each other (taking magnitude into account). Otherwise returns x.
template<typename T>
AZ_MATH_INLINE T ClampIfCloseMag(T x, T y, T epsilonValue = AZStd::numeric_limits<T>::epsilon())
AZ_MATH_INLINE T ClampIfCloseMag(T x, T y, T epsilonValue = std::numeric_limits<T>::epsilon())
{
return IsCloseMag<T>(x, y, epsilonValue) ? y : x;
}
@ -463,44 +461,6 @@ namespace AZ
return (azisfinite(x) != 0);
}
//! Returns the value divided by alignment, where the result is rounded up if the remainder is non-zero.
//! Example: alignment: 4
//! Value: 0 1 2 3 4 5 6 7 8
//! Result: 0 1 1 1 1 2 2 2 2
constexpr uint32_t DivideAndRoundUp(uint32_t value, uint32_t alignment)
{
AZ_Assert(alignment != 0, "0 is an invalid multiple to round to.");
AZ_Assert(
AZStd::numeric_limits<uint32_t>::max() - value >= alignment,
"value '%" PRIu32 "' and alignment '%" PRIu32 "' will overflow when added together during DivideAndRoundUp.", value, alignment);
return (value + alignment - 1) / alignment;
}
constexpr uint64_t DivideAndRoundUp(uint64_t value, uint64_t alignment)
{
AZ_Assert(alignment != 0, "0 is an invalid multiple to round to.");
AZ_Assert(
AZStd::numeric_limits<uint64_t>::max() - value >= alignment,
"value '%" PRIu64 "' and alignment '%" PRIu64 "' will overflow when added together during DivideAndRoundUp.", value, alignment);
return (value + alignment - 1) / alignment;
}
//! Returns the value rounded up to a multiple of alignment.
//! This function will work for non power of two alignments.
//! If your alignment is guaranteed to be a power of two, SizeAlignUp in base.h is a more efficient implementation.
//! Example: roundTo: 4
//! Value: 0 1 2 3 4 5 6 7 8
//! Result: 0 4 4 4 4 8 8 8 8
constexpr uint32_t RoundUpToMultiple(uint32_t value, uint32_t alignment)
{
return DivideAndRoundUp(value, alignment) * alignment;
}
constexpr uint64_t RoundUpToMultiple(uint64_t value, uint64_t alignment)
{
return DivideAndRoundUp(value, alignment) * alignment;
}
//! Returns the maximum value for SourceType as constrained by the numerical range of ClampType.
template <typename SourceType, typename ClampType>
constexpr SourceType ClampedIntegralLimits<SourceType, ClampType>::Min()
@ -514,8 +474,8 @@ namespace AZ
{
// Both SourceType and ClampType are signed, take the greater of the lower limits of each type
return sizeof(SourceType) < sizeof(ClampType) ?
(AZStd::numeric_limits<SourceType>::lowest)() :
static_cast<SourceType>((AZStd::numeric_limits<ClampType>::lowest)());
(std::numeric_limits<SourceType>::lowest)() :
static_cast<SourceType>((std::numeric_limits<ClampType>::lowest)());
}
}
@ -526,12 +486,12 @@ namespace AZ
if constexpr (sizeof(SourceType) < sizeof(ClampType))
{
// If SourceType is narrower than ClampType, the upper limit will be SourceType's
return (AZStd::numeric_limits<SourceType>::max)();
return (std::numeric_limits<SourceType>::max)();
}
else if constexpr (sizeof(SourceType) > sizeof(ClampType))
{
// If SourceType is wider than ClampType, the upper limit will be ClampType's
return static_cast<SourceType>((AZStd::numeric_limits<ClampType>::max)());
return static_cast<SourceType>((std::numeric_limits<ClampType>::max)());
}
else
{
@ -539,13 +499,13 @@ namespace AZ
{
// SourceType and ClampType are the same width, ClampType is signed
// so our upper limit will be ClampType
return static_cast<SourceType>((AZStd::numeric_limits<ClampType>::max)());
return static_cast<SourceType>((std::numeric_limits<ClampType>::max)());
}
else
{
// SourceType and ClampType are the same width, ClampType is unsigned
// then our upper limit will be SourceType
return (AZStd::numeric_limits<SourceType>::max)();
return (std::numeric_limits<SourceType>::max)();
}
}
}
@ -628,7 +588,7 @@ namespace AZ
// LeftTypeSize <= RightTypeSize
// LeftType is signed
// RightType is unsigned
RightType max = static_cast<RightType>((AZStd::numeric_limits<LeftType>::max)());
RightType max = static_cast<RightType>((std::numeric_limits<LeftType>::max)());
if (rhs > max)
{
@ -644,7 +604,7 @@ namespace AZ
// LeftType < RightType
// LeftType is unsigned
// RightType is signed
RightType max = static_cast<RightType>((AZStd::numeric_limits<LeftType>::max)());
RightType max = static_cast<RightType>((std::numeric_limits<LeftType>::max)());
if (rhs < 0)
{

@ -85,16 +85,6 @@ namespace AZ::Internal
[[maybe_unused]] AZ::SettingsRegistryInterface::Type type, AZStd::string_view value) override
{
m_enginePaths.emplace_back(EngineInfo{ AZ::IO::FixedMaxPath{value}.LexicallyNormal(), FixedValueString{valueName} });
// Make sure any engine paths read from the manifest are absolute
AZ::IO::FixedMaxPath& recentEnginePath = m_enginePaths.back().m_path;
if (recentEnginePath.IsRelative())
{
if (auto engineRootAbsPath = AZ::Utils::ConvertToAbsolutePath(recentEnginePath.Native());
engineRootAbsPath.has_value())
{
recentEnginePath = AZStd::move(*engineRootAbsPath);
}
}
}
AZStd::vector<EngineInfo> m_enginePaths{};
@ -219,15 +209,8 @@ namespace AZ::Internal
return {};
}
enum class InjectLocation : bool
{
Front,
Back
};
void InjectSettingToCommandLine(AZ::SettingsRegistryInterface& settingsRegistry,
AZStd::string_view path, AZStd::string_view value,
InjectLocation injectLocation = InjectLocation::Front)
void InjectSettingToCommandLineBack(AZ::SettingsRegistryInterface& settingsRegistry,
AZStd::string_view path, AZStd::string_view value)
{
AZ::CommandLine commandLine;
AZ::SettingsRegistryMergeUtils::GetCommandLineFromRegistry(settingsRegistry, commandLine);
@ -236,8 +219,7 @@ namespace AZ::Internal
auto projectPathOverride = AZStd::string::format(R"(--regset="%.*s=%.*s")",
aznumeric_cast<int>(path.size()), path.data(), aznumeric_cast<int>(value.size()), value.data());
auto emplaceIter = injectLocation == InjectLocation::Front ? paramContainer.begin() : paramContainer.end();
paramContainer.emplace(emplaceIter, AZStd::move(projectPathOverride));
paramContainer.emplace(paramContainer.end(), AZStd::move(projectPathOverride));
commandLine.Parse(paramContainer);
AZ::SettingsRegistryMergeUtils::StoreCommandLineToRegistry(settingsRegistry, commandLine);
}
@ -262,26 +244,13 @@ namespace AZ::SettingsRegistryMergeUtils
{
// We can scan up from exe directory to find engine.json, use that for engine root if it exists.
engineRoot = Internal::ScanUpRootLocator("engine.json");
// The Internal ScanUp Engine Root Key will be set as an absolute path
if (!engineRoot.empty())
{
if (engineRoot.IsRelative())
{
if (auto engineRootAbsPath = AZ::Utils::ConvertToAbsolutePath(engineRoot.Native());
engineRootAbsPath.has_value())
{
engineRoot = AZStd::move(*engineRootAbsPath);
}
}
}
// Set the {InternalScanUpEngineRootKey} to make sure this code path isn't called again for this settings registry
settingsRegistry.Set(InternalScanUpEngineRootKey, engineRoot.Native());
if (!engineRoot.empty())
{
settingsRegistry.Set(engineRootKey, engineRoot.Native());
// Inject the engine root to the front of the command line settings
Internal::InjectSettingToCommandLine(settingsRegistry, engineRootKey, engineRoot.Native());
// Inject the engine root at the end of the command line settings
Internal::InjectSettingToCommandLineBack(settingsRegistry, engineRootKey, engineRoot.Native());
return engineRoot;
}
}
@ -289,14 +258,6 @@ namespace AZ::SettingsRegistryMergeUtils
// Step 2 check if the engine_path key has been supplied
if (settingsRegistry.Get(engineRoot.Native(), engineRootKey); !engineRoot.empty())
{
if (engineRoot.IsRelative())
{
if (auto engineRootAbsPath = AZ::Utils::ConvertToAbsolutePath(engineRoot.Native());
engineRootAbsPath.has_value())
{
engineRoot = AZStd::move(*engineRootAbsPath);
}
}
return engineRoot;
}
@ -337,28 +298,13 @@ namespace AZ::SettingsRegistryMergeUtils
if (settingsRegistry.GetType(InternalScanUpProjectRootKey) == Type::NoType)
{
projectRoot = Internal::ScanUpRootLocator("project.json");
// Convert the path to an absolute path before adding it as a setting to the
// InternalScanUpProjectRootKey
if (!projectRoot.empty())
{
if (projectRoot.IsRelative())
{
if (auto projectAbsPath = AZ::Utils::ConvertToAbsolutePath(projectRoot.Native());
projectAbsPath.has_value())
{
projectRoot = AZStd::move(*projectAbsPath);
}
}
}
// Set the {InternalScanUpProjectRootKey} to make sure this code path isn't called again for this settings registry
settingsRegistry.Set(InternalScanUpProjectRootKey, projectRoot.Native());
if (!projectRoot.empty())
{
settingsRegistry.Set(projectRootKey, projectRoot.c_str());
// Inject the project root at to the front of the command line settings
Internal::InjectSettingToCommandLine(settingsRegistry, projectRootKey, projectRoot.Native());
// Inject the project root at the end of the command line settings
Internal::InjectSettingToCommandLineBack(settingsRegistry, projectRootKey, projectRoot.Native());
return projectRoot;
}
}
@ -366,18 +312,6 @@ namespace AZ::SettingsRegistryMergeUtils
// Step 2 Check the project-path key
// This is the project path root key, as passed from command-line or *.setreg files.
settingsRegistry.Get(projectRoot.Native(), projectRootKey);
if (!projectRoot.empty())
{
if (projectRoot.IsRelative())
{
if (auto projectAbsPath = AZ::Utils::ConvertToAbsolutePath(projectRoot.Native());
projectAbsPath.has_value())
{
projectRoot = AZStd::move(*projectAbsPath);
}
}
}
return projectRoot;
}
@ -391,22 +325,13 @@ namespace AZ::SettingsRegistryMergeUtils
constexpr auto projectCachePathKey = FixedValueString(BootstrapSettingsRootKey) + "/project_cache_path";
// Step 1 Check the project-cache-path key
AZ::IO::FixedMaxPath projectCachePath;
if (!settingsRegistry.Get(projectCachePath.Native(), projectCachePathKey))
if (AZ::IO::FixedMaxPath projectCachePath; settingsRegistry.Get(projectCachePath.Native(), projectCachePathKey))
{
// Step 2 Append the "Cache" directory to the project-path
projectCachePath = projectPath / Internal::ProductCacheDirectoryName;
return projectCachePath;
}
if (projectCachePath.IsRelative())
{
if (auto projectCacheAbsPath = AZ::Utils::ConvertToAbsolutePath(projectCachePath.Native());
projectCacheAbsPath.has_value())
{
projectCachePath = AZStd::move(*projectCacheAbsPath);
}
}
return projectCachePath;
// Step 2 Append the "Cache" directory to the project-path
return projectPath / Internal::ProductCacheDirectoryName;
}
//! Set the user directory with the provided path or using <project-path>/user as default
@ -419,22 +344,13 @@ namespace AZ::SettingsRegistryMergeUtils
constexpr auto projectUserPathKey = FixedValueString(BootstrapSettingsRootKey) + "/project_user_path";
// Step 1 Check the project-user-path key
AZ::IO::FixedMaxPath projectUserPath;
if (!settingsRegistry.Get(projectUserPath.Native(), projectUserPathKey))
if (AZ::IO::FixedMaxPath projectUserPath; settingsRegistry.Get(projectUserPath.Native(), projectUserPathKey))
{
// Step 2 Append the "User" directory to the project-path
projectUserPath = projectPath / "user";
return projectUserPath;
}
if (projectUserPath.IsRelative())
{
if (auto projectUserAbsPath = AZ::Utils::ConvertToAbsolutePath(projectUserPath.Native());
projectUserAbsPath.has_value())
{
projectUserPath = AZStd::move(*projectUserAbsPath);
}
}
return projectUserPath;
// Step 2 Append the "User" directory to the project-path
return projectPath / "user";
}
//! Set the log directory using the settings registry path or using <project-user-path>/log as default
@ -447,37 +363,20 @@ namespace AZ::SettingsRegistryMergeUtils
constexpr auto projectLogPathKey = FixedValueString(BootstrapSettingsRootKey) + "/project_log_path";
// Step 1 Check the project-user-path key
AZ::IO::FixedMaxPath projectLogPath;
if (!settingsRegistry.Get(projectLogPath.Native(), projectLogPathKey))
{
// Step 2 Append the "Log" directory to the project-user-path
projectLogPath = projectUserPath / "log";
}
if (projectLogPath.IsRelative())
if (AZ::IO::FixedMaxPath projectLogPath; settingsRegistry.Get(projectLogPath.Native(), projectLogPathKey))
{
if (auto projectLogAbsPath = AZ::Utils::ConvertToAbsolutePath(projectLogPath.Native()))
{
projectLogPath = AZStd::move(*projectLogAbsPath);
}
return projectLogPath;
}
return projectLogPath;
// Step 2 Append the "Log" directory to the project-user-path
return projectUserPath / "log";
}
// check for a default write storage path, fall back to the <project-user-path> if not
static AZ::IO::FixedMaxPath FindDevWriteStoragePath(const AZ::IO::FixedMaxPath& projectUserPath)
{
AZStd::optional<AZ::IO::FixedMaxPathString> devWriteStorage = Utils::GetDevWriteStoragePath();
AZ::IO::FixedMaxPath devWriteStoragePath = devWriteStorage.has_value() ? *devWriteStorage : projectUserPath;
if (devWriteStoragePath.IsRelative())
{
if (auto devWriteStorageAbsPath = AZ::Utils::ConvertToAbsolutePath(devWriteStoragePath.Native()))
{
devWriteStoragePath = AZStd::move(*devWriteStorageAbsPath);
}
}
return devWriteStoragePath;
return devWriteStorage.has_value() ? *devWriteStorage : projectUserPath;
}
// check for the project build path, which is a relative path from the project root
@ -770,6 +669,15 @@ namespace AZ::SettingsRegistryMergeUtils
if ([[maybe_unused]] constexpr auto projectPathKey = FixedValueString(BootstrapSettingsRootKey) + "/project_path";
!projectPath.empty())
{
if (projectPath.IsRelative())
{
if (auto projectAbsPath = AZ::Utils::ConvertToAbsolutePath(projectPath.Native());
projectAbsPath.has_value())
{
projectPath = AZStd::move(*projectAbsPath);
}
}
projectPath = projectPath.LexicallyNormal();
AZ_Warning("SettingsRegistryMergeUtils", AZ::IO::SystemFile::Exists(projectPath.c_str()),
R"(Project path "%s" does not exist. Is the "%.*s" registry setting set to a valid absolute path?)"
@ -791,6 +699,15 @@ namespace AZ::SettingsRegistryMergeUtils
AZ::IO::FixedMaxPath engineRoot = FindEngineRoot(registry);
if (!engineRoot.empty())
{
if (engineRoot.IsRelative())
{
if (auto engineRootAbsPath = AZ::Utils::ConvertToAbsolutePath(engineRoot.Native());
engineRootAbsPath.has_value())
{
engineRoot = AZStd::move(*engineRootAbsPath);
}
}
engineRoot = engineRoot.LexicallyNormal();
registry.Set(FilePathKey_EngineRootFolder, engineRoot.Native());
}
@ -799,6 +716,15 @@ namespace AZ::SettingsRegistryMergeUtils
AZ::IO::FixedMaxPath projectCachePath = FindProjectCachePath(registry, projectPath).LexicallyNormal();
if (!projectCachePath.empty())
{
if (projectCachePath.IsRelative())
{
if (auto projectCacheAbsPath = AZ::Utils::ConvertToAbsolutePath(projectCachePath.Native());
projectCacheAbsPath.has_value())
{
projectCachePath = AZStd::move(*projectCacheAbsPath);
}
}
projectCachePath = projectCachePath.LexicallyNormal();
registry.Set(FilePathKey_CacheProjectRootFolder, projectCachePath.Native());
@ -829,6 +755,15 @@ namespace AZ::SettingsRegistryMergeUtils
AZ::IO::FixedMaxPath projectUserPath = FindProjectUserPath(registry, projectPath);
if (!projectUserPath.empty())
{
if (projectUserPath.IsRelative())
{
if (auto projectUserAbsPath = AZ::Utils::ConvertToAbsolutePath(projectUserPath.Native());
projectUserAbsPath.has_value())
{
projectUserPath = AZStd::move(*projectUserAbsPath);
}
}
projectUserPath = projectUserPath.LexicallyNormal();
registry.Set(FilePathKey_ProjectUserPath, projectUserPath.Native());
}
@ -836,6 +771,14 @@ namespace AZ::SettingsRegistryMergeUtils
// Log folder
if (AZ::IO::FixedMaxPath projectLogPath = FindProjectLogPath(registry, projectUserPath); !projectLogPath.empty())
{
if (projectLogPath.IsRelative())
{
if (auto projectLogAbsPath = AZ::Utils::ConvertToAbsolutePath(projectLogPath.Native()))
{
projectLogPath = AZStd::move(*projectLogAbsPath);
}
}
projectLogPath = projectLogPath.LexicallyNormal();
registry.Set(FilePathKey_ProjectLogPath, projectLogPath.Native());
}
@ -843,6 +786,14 @@ namespace AZ::SettingsRegistryMergeUtils
// Developer Write Storage folder
if (AZ::IO::FixedMaxPath devWriteStoragePath = FindDevWriteStoragePath(projectUserPath); !devWriteStoragePath.empty())
{
if (devWriteStoragePath.IsRelative())
{
if (auto devWriteStorageAbsPath = AZ::Utils::ConvertToAbsolutePath(devWriteStoragePath.Native()))
{
devWriteStoragePath = AZStd::move(*devWriteStorageAbsPath);
}
}
devWriteStoragePath = devWriteStoragePath.LexicallyNormal();
registry.Set(FilePathKey_DevWriteStorage, devWriteStoragePath.Native());
}

@ -89,14 +89,15 @@ namespace AZ::SettingsRegistryMergeUtils
//! The algorithm that is used to find the project root is as follows
//! 1. The first time this function runs it performs an upward scan for a "project.json" file from
//! the executable directory and stores that path into an internal key.
//! In the same step it injects the path into the front of the command line parameters
//! In the same step it injects the path into the back of the command line parameters
//! using the --regset="{BootstrapSettingsRootKey}/project_path=<path>" value
//! 2. Next the "{BootstrapSettingsRootKey}/project_path" is checked to see if it has a project path set
//!
//! The order in which the project path settings are overridden proceeds in the following order
//! 1. project_path set in a *.setreg/*.setregpatch file
//! 2. project_path found by scanning upwards from the executable directory to the project.json path
//! 3. project_path set on the Command line via either --regset="{BootstrapSettingsRootKey}/project_path=<path>"
//! 1. project_path set in the <engine-root>/bootstrap.cfg file
//! 2. project_path set in a *.setreg/*.setregpatch file
//! 3. project_path found by scanning upwards from the executable directory to the project.json path
//! 4. project_path set on the Command line via either --regset="{BootstrapSettingsRootKey}/project_path=<path>"
//! or --project_path=<path>
AZ::IO::FixedMaxPath FindProjectRoot(SettingsRegistryInterface& settingsRegistry);
@ -212,15 +213,9 @@ namespace AZ::SettingsRegistryMergeUtils
const SettingsRegistryInterface::Specializations& specializations, AZStd::vector<char>* scratchBuffer = nullptr);
//! Adds the settings set through the command line to the Settings Registry. This will also execute any Settings
//! Registry related arguments. Note that --regset, --regset-file and -regremove will run in the order in which they are parsed
//! Registry related arguments. Note that --regset and -regremove will run in the order in which they are parsed
//! --regset <arg> Sets a value in the registry. See MergeCommandLineArgument for options for <arg>
//! example: --regset "/My/String/Value=String value set"
//! --regset-file <path>[::anchor] Merges the specified file into the Settings registry
//! If the extension is .setregpatch, then JSON Patch will be used to merge the file otherwise JSON Merge Patch will be used
//! `anchor` is a JSON path used to optionally select where to merge the settings underneath, otherwise settings are merged
//! under the root.
//! example: --regset-file="C:/Users/testuser/custom.setreg"
//! example: --regset-file="relative/path/other.setregpatch::/O3DE/settings"
//! --regremove <arg> Removes a value in the registry
//! example: --regremove "/My/String/Value"
//! only when executeCommands is true are the following options supported:

@ -416,27 +416,27 @@ namespace AZ
Join(fixedOutput, example.begin(), example.end(), ",");
// fixedOutput == "test,string,joining"
*/
template<typename StringType, typename ConvertableToStringViewIterator, typename SeparatorString>
template<typename TStringType, typename TConvertableToStringViewIterator, typename TSeparatorString>
inline void Join(
StringType& joinTarget,
const ConvertableToStringViewIterator& iteratorBegin,
const ConvertableToStringViewIterator& iteratorEnd,
const SeparatorString& separator)
TStringType& joinTarget,
const TConvertableToStringViewIterator& iteratorBegin,
const TConvertableToStringViewIterator& iteratorEnd,
const TSeparatorString& separator)
{
if (iteratorBegin == iteratorEnd)
{
return;
}
using CharType = typename StringType::value_type;
using CharTraitsType = typename StringType::traits_type;
using CharType = typename TStringType::value_type;
using CharTraitsType = typename TStringType::traits_type;
size_t size = joinTarget.size() + AZStd::basic_string_view<CharType, CharTraitsType>(*iteratorBegin).size();
for (auto currentIterator = AZStd::next(iteratorBegin); currentIterator != iteratorEnd; ++currentIterator)
{
size += AZStd::basic_string_view<CharType, CharTraitsType>(*currentIterator).size();
// Special case for when the separator is just the character type
if constexpr (AZStd::is_same_v<AZStd::remove_cvref_t<SeparatorString>, CharType>)
if constexpr (AZStd::is_same_v<AZStd::remove_cvref_t<TSeparatorString>, CharType>)
{
size += 1;
}
@ -455,19 +455,6 @@ namespace AZ
}
}
template<typename StringType, typename Range, typename SeparatorString,
class = AZStd::enable_if_t<AZStd::ranges::input_range<Range> &&
AZStd::convertible_to<AZStd::ranges::range_value_t<Range>,
AZStd::basic_string_view<typename StringType::value_type, typename StringType::traits_type>>
>>
void Join(StringType& joinTarget, Range&& stringViewConvertibleRange, const SeparatorString& separator)
{
Join(joinTarget,
AZStd::ranges::begin(stringViewConvertibleRange),
AZStd::ranges::end(stringViewConvertibleRange),
separator);
}
//////////////////////////////////////////////////////////////////////////
//! StringFunc::NumberFormatting Namespace
/*! For string functions supporting string representations of numbers

@ -302,13 +302,7 @@ namespace AZStd
inline AZStd::string to_string(long long val) { AZStd::string str; to_string(str, val); return str; }
inline AZStd::string to_string(unsigned long long val) { AZStd::string str; to_string(str, val); return str; }
inline AZStd::string to_string(long double val) { AZStd::string str; to_string(str, val); return str; }
template<class BoolType>
auto to_string(BoolType value) -> enable_if_t<same_as<remove_cvref_t<BoolType>, bool>, AZStd::string>
{
AZStd::string str;
to_string(str, value);
return str;
}
inline AZStd::string to_string(bool val) { AZStd::string str; to_string(str, val); return str; }
// In our engine we assume AZStd::string is Utf8 encoded!
template<class Allocator>

@ -656,6 +656,18 @@ namespace UnitTest
fval = AZStd::stof(wfloatStr);
AZ_TEST_ASSERT_FLOAT_CLOSE(fval, 2.32f);
AZStd::to_string(intStr, 20);
AZ_TEST_ASSERT(intStr == "20");
EXPECT_EQ("20", AZStd::to_string(static_cast<int16_t>(20)));
EXPECT_EQ("20", AZStd::to_string(static_cast<uint16_t>(20)));
EXPECT_EQ("20", AZStd::to_string(static_cast<int32_t>(20)));
EXPECT_EQ("20", AZStd::to_string(static_cast<uint32_t>(20)));
EXPECT_EQ("20", AZStd::to_string(static_cast<int64_t>(20)));
EXPECT_EQ("20", AZStd::to_string(static_cast<uint64_t>(20)));
EXPECT_EQ("false", AZStd::to_string(false));
EXPECT_EQ("true", AZStd::to_string(true));
// wstring to string
AZStd::string str1;
AZStd::to_string(str1, wstr);
@ -966,47 +978,6 @@ namespace UnitTest
AZ_TEST_ASSERT(*vecIt++ == "Xiph Xlater 10000");
}
// Concept to model if AZStd::to_string(<type>) is a valid expression
template<class T, class = void>
constexpr bool IsToStringInvocable = false;
template<class T>
constexpr bool IsToStringInvocable<T, AZStd::void_t<decltype(AZStd::to_string(AZStd::declval<T>()))>> = true;
TEST_F(String, String_to_stringOverload_DoesNotImplicitlyConvertToBool)
{
AZStd::string intStr;
AZStd::to_string(intStr, 20);
EXPECT_EQ("20", intStr);
EXPECT_EQ("20", AZStd::to_string(static_cast<int16_t>(20)));
EXPECT_EQ("20", AZStd::to_string(static_cast<uint16_t>(20)));
EXPECT_EQ("20", AZStd::to_string(static_cast<int32_t>(20)));
EXPECT_EQ("20", AZStd::to_string(static_cast<uint32_t>(20)));
EXPECT_EQ("20", AZStd::to_string(static_cast<int64_t>(20)));
EXPECT_EQ("20", AZStd::to_string(static_cast<uint64_t>(20)));
EXPECT_EQ("false", AZStd::to_string(false));
EXPECT_EQ("true", AZStd::to_string(true));
// AZStd::to_string should not be invocable with a char or wchar_t literal
static_assert(!IsToStringInvocable<decltype("NarrowStrLiteral")>);
static_assert(!IsToStringInvocable<decltype(L"WideStrLiteral")>);
// AZStd::to_string should
static_assert(IsToStringInvocable<bool>);
static_assert(IsToStringInvocable<AZ::s8>);
static_assert(IsToStringInvocable<AZ::u8>);
static_assert(IsToStringInvocable<AZ::s16>);
static_assert(IsToStringInvocable<AZ::u16>);
static_assert(IsToStringInvocable<AZ::s32>);
static_assert(IsToStringInvocable<AZ::u32>);
static_assert(IsToStringInvocable<AZ::s64>);
static_assert(IsToStringInvocable<AZ::u64>);
static_assert(IsToStringInvocable<float>);
static_assert(IsToStringInvocable<double>);
static_assert(IsToStringInvocable<long double>);
}
class Regex
: public AllocatorsFixture
{

@ -37,8 +37,8 @@ namespace UnitTest
// min/max need to be substantially different to return a useful t value
// Float
const float epsilonF = AZStd::numeric_limits<float>::epsilon();
const float doesntMatterF = AZStd::numeric_limits<float>::signaling_NaN();
const float epsilonF = std::numeric_limits<float>::epsilon();
const float doesntMatterF = std::numeric_limits<float>::signaling_NaN();
float lowerF = 2.3f, upperF = 2.3f;
EXPECT_EQ(0.0f, AZ::LerpInverse(lowerF, upperF, doesntMatterF));
EXPECT_EQ(0.0f, AZ::LerpInverse(0.0f, 0.5f * epsilonF, doesntMatterF));
@ -48,8 +48,8 @@ namespace UnitTest
EXPECT_NEAR(1.0f, AZ::LerpInverse(1.0f, 1.0f + 5.0f * epsilonF, 1.0f + 5.0f * epsilonF), epsilonF);
// Double
const double epsilonD = AZStd::numeric_limits<double>::epsilon();
const double doesntMatterD = AZStd::numeric_limits<double>::signaling_NaN();
const double epsilonD = std::numeric_limits<double>::epsilon();
const double doesntMatterD = std::numeric_limits<double>::signaling_NaN();
double lowerD = 2.3, upperD = 2.3;
EXPECT_EQ(0.0, AZ::LerpInverse(lowerD, upperD, doesntMatterD));
EXPECT_EQ(0.0, AZ::LerpInverse(0.0, 0.5 * epsilonD, doesntMatterD));
@ -58,128 +58,4 @@ namespace UnitTest
EXPECT_NEAR(0.6, AZ::LerpInverse(1.0, 1.0 + 5.0 * epsilonD, 1.0 + 3.0 * epsilonD), epsilonD);
EXPECT_NEAR(1.0, AZ::LerpInverse(1.0, 1.0 + 5.0 * epsilonD, 1.0 + 5.0 * epsilonD), epsilonD);
}
template <typename T>
void TestRoundUpToMultipleIsCorrect()
{
// Example: alignment: 4
// inputValue: 0 1 2 3 4 5 6 7 8 ...
// expectedOutput: 0 4 4 4 4 8 8 8 8 ...
EXPECT_EQ(RoundUpToMultiple(static_cast<T>(0) , static_cast<T>(1)) , 0);
EXPECT_EQ(RoundUpToMultiple(static_cast<T>(1) , static_cast<T>(1)) , 1);
EXPECT_EQ(RoundUpToMultiple(static_cast<T>(2) , static_cast<T>(1)) , 2);
EXPECT_EQ(RoundUpToMultiple(static_cast<T>(0) , static_cast<T>(2)) , 0);
EXPECT_EQ(RoundUpToMultiple(static_cast<T>(1) , static_cast<T>(2)) , 2);
EXPECT_EQ(RoundUpToMultiple(static_cast<T>(2) , static_cast<T>(2)) , 2);
EXPECT_EQ(RoundUpToMultiple(static_cast<T>(3) , static_cast<T>(2)) , 4);
EXPECT_EQ(RoundUpToMultiple(static_cast<T>(4) , static_cast<T>(2)) , 4);
EXPECT_EQ(RoundUpToMultiple(static_cast<T>(5) , static_cast<T>(2)) , 6);
EXPECT_EQ(RoundUpToMultiple(static_cast<T>(0) , static_cast<T>(8)) , 0);
EXPECT_EQ(RoundUpToMultiple(static_cast<T>(1) , static_cast<T>(8)) , 8);
EXPECT_EQ(RoundUpToMultiple(static_cast<T>(7) , static_cast<T>(8)) , 8);
EXPECT_EQ(RoundUpToMultiple(static_cast<T>(8) , static_cast<T>(8)) , 8);
EXPECT_EQ(RoundUpToMultiple(static_cast<T>(9) , static_cast<T>(8)) , 16);
EXPECT_EQ(RoundUpToMultiple(static_cast<T>(15), static_cast<T>(8)) , 16);
EXPECT_EQ(RoundUpToMultiple(static_cast<T>(16), static_cast<T>(8)) , 16);
EXPECT_EQ(RoundUpToMultiple(static_cast<T>(17), static_cast<T>(8)) , 24);
EXPECT_EQ(RoundUpToMultiple(static_cast<T>(0) , static_cast<T>(13)), 0);
EXPECT_EQ(RoundUpToMultiple(static_cast<T>(1) , static_cast<T>(13)), 13);
EXPECT_EQ(RoundUpToMultiple(static_cast<T>(9) , static_cast<T>(13)), 13);
EXPECT_EQ(RoundUpToMultiple(static_cast<T>(12), static_cast<T>(13)), 13);
EXPECT_EQ(RoundUpToMultiple(static_cast<T>(13), static_cast<T>(13)), 13);
EXPECT_EQ(RoundUpToMultiple(static_cast<T>(14), static_cast<T>(13)), 26);
EXPECT_EQ(RoundUpToMultiple(static_cast<T>(25), static_cast<T>(13)), 26);
EXPECT_EQ(RoundUpToMultiple(static_cast<T>(26), static_cast<T>(13)), 26);
EXPECT_EQ(RoundUpToMultiple(static_cast<T>(27), static_cast<T>(13)), 39);
EXPECT_EQ(RoundUpToMultiple(static_cast<T>(0), AZStd::numeric_limits<T>::max()), 0);
T aVeryLargeNumberThatStillWontOverflow = AZStd::numeric_limits<T>::max() - 4;
EXPECT_EQ(RoundUpToMultiple(static_cast<T>(1), aVeryLargeNumberThatStillWontOverflow), aVeryLargeNumberThatStillWontOverflow);
EXPECT_EQ(RoundUpToMultiple(aVeryLargeNumberThatStillWontOverflow, static_cast<T>(1)), aVeryLargeNumberThatStillWontOverflow);
}
TEST(RoundUpToMultipleTest, RoundUpToMultipleUInt32_ValidInput_IsCorrect)
{
TestRoundUpToMultipleIsCorrect<uint32_t>();
}
TEST(RoundUpToMultipleTest, RoundUpToMultipleUInt64_ValidInput_IsCorrect)
{
TestRoundUpToMultipleIsCorrect<uint64_t>();
}
template<typename T>
void TestDivideAndRoundUpIsCorrect()
{
//! Example: alignment: 3
//! Value: 0 1 2 3 4 5 6 7 8
//! Result: 0 1 1 1 2 2 2 3 3
EXPECT_EQ(DivideAndRoundUp(static_cast<T>(0), static_cast<T>(3)), 0);
EXPECT_EQ(DivideAndRoundUp(static_cast<T>(1), static_cast<T>(3)), 1);
EXPECT_EQ(DivideAndRoundUp(static_cast<T>(2), static_cast<T>(3)), 1);
EXPECT_EQ(DivideAndRoundUp(static_cast<T>(3), static_cast<T>(3)), 1);
EXPECT_EQ(DivideAndRoundUp(static_cast<T>(4), static_cast<T>(3)), 2);
EXPECT_EQ(DivideAndRoundUp(static_cast<T>(5), static_cast<T>(3)), 2);
EXPECT_EQ(DivideAndRoundUp(static_cast<T>(6), static_cast<T>(3)), 2);
EXPECT_EQ(DivideAndRoundUp(static_cast<T>(7), static_cast<T>(3)), 3);
EXPECT_EQ(DivideAndRoundUp(static_cast<T>(8), static_cast<T>(3)), 3);
EXPECT_EQ(DivideAndRoundUp(static_cast<T>(0), AZStd::numeric_limits<T>::max()), 0);
T aVeryLargeNumberThatStillWontOverflow = AZStd::numeric_limits<T>::max() - 4;
EXPECT_EQ(DivideAndRoundUp(static_cast<T>(1), aVeryLargeNumberThatStillWontOverflow), static_cast<T>(1));
EXPECT_EQ(DivideAndRoundUp(aVeryLargeNumberThatStillWontOverflow, static_cast<T>(1)), aVeryLargeNumberThatStillWontOverflow);
}
TEST(DivideAndRoundUpTest, DivideAndRoundUpUInt32_ValidInput_IsCorrect)
{
TestDivideAndRoundUpIsCorrect<uint32_t>();
}
TEST(DivideAndRoundUpTest, DivideAndRoundUpUInt64_ValidInput_IsCorrect)
{
TestDivideAndRoundUpIsCorrect<uint64_t>();
}
class RoundUpInvalidInputTestsFixture : public ScopedAllocatorSetupFixture
{
};
TEST_F(RoundUpInvalidInputTestsFixture, DividAndRoundUp_AlignmentZeroUint32_Assert)
{
AZ_TEST_START_TRACE_SUPPRESSION;
DivideAndRoundUp(static_cast<uint32_t>(0), static_cast<uint32_t>(0));
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
}
TEST_F(RoundUpInvalidInputTestsFixture, DividAndRoundUp_AlignmentZeroUint64_Assert)
{
AZ_TEST_START_TRACE_SUPPRESSION;
DivideAndRoundUp(static_cast<uint64_t>(0), static_cast<uint64_t>(0));
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
}
TEST_F(RoundUpInvalidInputTestsFixture, DividAndRoundUp_OverflowUint32_Assert)
{
AZ_TEST_START_TRACE_SUPPRESSION;
DivideAndRoundUp(
static_cast<uint32_t>((AZStd::numeric_limits<uint32_t>::max() / 2) + 1),
static_cast<uint32_t>((AZStd::numeric_limits<uint32_t>::max() / 2) + 1));
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
}
TEST_F(RoundUpInvalidInputTestsFixture, DividAndRoundUp_OverflowUint64_Assert)
{
AZ_TEST_START_TRACE_SUPPRESSION;
DivideAndRoundUp(
static_cast<uint64_t>((AZStd::numeric_limits<uint64_t>::max() / 2) + 1),
static_cast<uint64_t>((AZStd::numeric_limits<uint64_t>::max() / 2) + 1));
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
}
}

@ -196,19 +196,6 @@ namespace AZ
ASSERT_EQ(joinResult, expectedResult);
}
TEST_F(StringFuncTest, Join_NonPathJoin_CanJoinRange)
{
AZStd::string result;
AZ::StringFunc::Join(result, AZStd::initializer_list<const char*>{ "1", "2", "3", "4", "3" }, '/');
EXPECT_EQ("1/2/3/4/3", result);
result.clear();
// Try joining with a string literal instead of a char literal
AZ::StringFunc::Join(result, AZStd::initializer_list<const char*>{ "1", "2", "3", "4", "3" }, "/");
EXPECT_EQ("1/2/3/4/3", result);
}
TEST_F(StringFuncTest, Tokenize_SingleDelimeter_Empty)
{
AZStd::string input = "";

@ -64,7 +64,7 @@ namespace AzFramework::ProjectManager
// If we were able to locate a path to a project, we're done
if (!projectRootPath.empty())
{
AZ::IO::FixedMaxPath projectJsonPath = projectRootPath / "project.json";
AZ::IO::FixedMaxPath projectJsonPath = engineRootPath / projectRootPath / "project.json";
if (AZ::IO::SystemFile::Exists(projectJsonPath.c_str()))
{
return ProjectPathCheckResult::ProjectPathFound;

@ -190,67 +190,9 @@ namespace AzFramework
return nextCamera;
}
bool Cameras::AddCamera(AZStd::shared_ptr<CameraInput> cameraInput)
void Cameras::AddCamera(AZStd::shared_ptr<CameraInput> cameraInput)
{
const auto idleCameraIt = AZStd::find(m_idleCameraInputs.begin(), m_idleCameraInputs.end(), cameraInput);
const auto activeCameraIt = AZStd::find(m_activeCameraInputs.begin(), m_activeCameraInputs.end(), cameraInput);
if (idleCameraIt == m_idleCameraInputs.end() && activeCameraIt == m_activeCameraInputs.end())
{
m_idleCameraInputs.push_back(AZStd::move(cameraInput));
return true;
}
return false;
}
bool Cameras::AddCameras(const AZStd::vector<AZStd::shared_ptr<AzFramework::CameraInput>>& cameraInputs)
{
bool allAdded = true;
for (auto cameraInput : cameraInputs)
{
allAdded = AddCamera(AZStd::move(cameraInput)) && allAdded;
}
return allAdded;
}
bool Cameras::RemoveCamera(const AZStd::shared_ptr<CameraInput>& cameraInput)
{
if (const auto idleCameraIt = AZStd::find(m_idleCameraInputs.begin(), m_idleCameraInputs.end(), cameraInput);
idleCameraIt != m_idleCameraInputs.end())
{
const auto idleIndex = idleCameraIt - m_idleCameraInputs.begin();
using AZStd::swap;
swap(m_idleCameraInputs[idleIndex], m_idleCameraInputs[m_idleCameraInputs.size() - 1]);
m_idleCameraInputs.pop_back();
return true;
}
if (const auto activeCameraIt = AZStd::find(m_activeCameraInputs.begin(), m_activeCameraInputs.end(), cameraInput);
activeCameraIt != m_activeCameraInputs.end())
{
(*activeCameraIt)->Reset();
const auto activeIndex = activeCameraIt - m_idleCameraInputs.begin();
using AZStd::swap;
swap(m_activeCameraInputs[activeIndex], m_activeCameraInputs[m_activeCameraInputs.size() - 1]);
m_activeCameraInputs.pop_back();
return true;
}
return false;
}
bool Cameras::RemoveCameras(const AZStd::vector<AZStd::shared_ptr<AzFramework::CameraInput>>& cameraInputs)
{
bool allRemoved = true;
for (const auto& cameraInput : cameraInputs)
{
allRemoved = RemoveCamera(cameraInput) && allRemoved;
}
return allRemoved;
m_idleCameraInputs.push_back(AZStd::move(cameraInput));
}
bool Cameras::HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, const float scrollDelta)
@ -703,7 +645,7 @@ namespace AzFramework
m_orbitChannelId = orbitChanneId;
}
OrbitScrollDollyCameraInput::OrbitScrollDollyCameraInput()
OrbitDollyScrollCameraInput::OrbitDollyScrollCameraInput()
{
m_scrollSpeedFn = []() constexpr
{
@ -711,7 +653,7 @@ namespace AzFramework
};
}
bool OrbitScrollDollyCameraInput::HandleEvents(
bool OrbitDollyScrollCameraInput::HandleEvents(
const InputEvent& event, [[maybe_unused]] const ScreenVector& cursorDelta, [[maybe_unused]] const float scrollDelta)
{
if (const auto* scroll = AZStd::get_if<ScrollEvent>(&event))
@ -749,7 +691,7 @@ namespace AzFramework
return nextCamera;
}
Camera OrbitScrollDollyCameraInput::StepCamera(
Camera OrbitDollyScrollCameraInput::StepCamera(
const Camera& targetCamera,
[[maybe_unused]] const ScreenVector& cursorDelta,
const float scrollDelta,
@ -760,7 +702,7 @@ namespace AzFramework
return nextCamera;
}
OrbitMotionDollyCameraInput::OrbitMotionDollyCameraInput(const InputChannelId& dollyChannelId)
OrbitDollyMotionCameraInput::OrbitDollyMotionCameraInput(const InputChannelId& dollyChannelId)
: m_dollyChannelId(dollyChannelId)
{
m_motionSpeedFn = []() constexpr
@ -769,14 +711,14 @@ namespace AzFramework
};
}
bool OrbitMotionDollyCameraInput::HandleEvents(
bool OrbitDollyMotionCameraInput::HandleEvents(
const InputEvent& event, [[maybe_unused]] const ScreenVector& cursorDelta, [[maybe_unused]] const float scrollDelta)
{
HandleActivationEvents(event, m_dollyChannelId, cursorDelta, m_clickDetector, *this);
return CameraInputUpdatingAfterMotion(*this);
}
Camera OrbitMotionDollyCameraInput::StepCamera(
Camera OrbitDollyMotionCameraInput::StepCamera(
const Camera& targetCamera,
const ScreenVector& cursorDelta,
[[maybe_unused]] const float scrollDelta,
@ -785,7 +727,7 @@ namespace AzFramework
return OrbitDolly(targetCamera, aznumeric_cast<float>(cursorDelta.m_y) * m_motionSpeedFn());
}
void OrbitMotionDollyCameraInput::SetDollyInputChannelId(const InputChannelId& dollyChannelId)
void OrbitDollyMotionCameraInput::SetDollyInputChannelId(const InputChannelId& dollyChannelId)
{
m_dollyChannelId = dollyChannelId;
}

@ -289,17 +289,7 @@ namespace AzFramework
//! Add a camera input (behavior) to run in this set of camera inputs.
//! The camera inputs added here will determine the overall behavior of the camera.
//! @return Returns if the camera was successfully added (if the camera already exists it is not added and AddCamera returns false).
bool AddCamera(AZStd::shared_ptr<CameraInput> cameraInput);
//! Add a collection of camera inputs (behaviors) to run in this set of camera inputs.
//! @return Returns if all cameras were added successfully.
bool AddCameras(const AZStd::vector<AZStd::shared_ptr<AzFramework::CameraInput>>& cameraInputs);
//! Remove a camera input (behavior) to stop it running in the set of camera inputs.
//! @return Returns if the camera was removed successfully (if the could not be found RemoveCamera returns false).
bool RemoveCamera(const AZStd::shared_ptr<CameraInput>& cameraInput);
//! Remove a collection of camera inputs (behaviors) to stop them running in the set of camera inputs.
//! @return Returns if all cameras were removed successfully.
bool RemoveCameras(const AZStd::vector<AZStd::shared_ptr<AzFramework::CameraInput>>& cameraInputs);
void AddCamera(AZStd::shared_ptr<CameraInput> cameraInput);
//! Reset the state of all cameras.
void Reset();
//! Remove all cameras that were added.
@ -309,10 +299,9 @@ namespace AzFramework
bool Exclusive() const;
private:
//! Active camera inputs updating the camera (empty initially).
AZStd::vector<AZStd::shared_ptr<CameraInput>> m_activeCameraInputs;
//! Idle camera inputs not contributing to the update (filled initially).
AZStd::vector<AZStd::shared_ptr<CameraInput>> m_idleCameraInputs;
AZStd::vector<AZStd::shared_ptr<CameraInput>> m_activeCameraInputs; //!< Active camera inputs updating the camera (empty initially).
AZStd::vector<AZStd::shared_ptr<CameraInput>>
m_idleCameraInputs; //!< Idle camera inputs not contributing to the update (filled initially).
};
//! Responsible for updating a series of cameras given various inputs.
@ -597,10 +586,10 @@ namespace AzFramework
};
//! A camera input to handle discrete scroll events that can modify the camera offset.
class OrbitScrollDollyCameraInput : public CameraInput
class OrbitDollyScrollCameraInput : public CameraInput
{
public:
OrbitScrollDollyCameraInput();
OrbitDollyScrollCameraInput();
// CameraInput overrides ...
bool HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override;
@ -610,10 +599,10 @@ namespace AzFramework
};
//! A camera input to handle motion deltas that can modify the camera offset.
class OrbitMotionDollyCameraInput : public CameraInput
class OrbitDollyMotionCameraInput : public CameraInput
{
public:
explicit OrbitMotionDollyCameraInput(const InputChannelId& dollyChannelId);
explicit OrbitDollyMotionCameraInput(const InputChannelId& dollyChannelId);
// CameraInput overrides ...
bool HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override;

@ -490,40 +490,4 @@ namespace UnitTest
EXPECT_THAT(m_orbitCamera->Ending(), IsFalse());
EXPECT_THAT(m_orbitCamera->Idle(), IsTrue());
}
TEST_F(CameraInputFixture, NewCameraInputCanBeAddedToCameraSystem)
{
auto firstPersonPanCamera = AZStd::make_shared<AzFramework::PanCameraInput>(
AzFramework::InputDeviceMouse::Button::Middle, AzFramework::LookPan, AzFramework::TranslatePivotLook);
const bool added =
m_cameraSystem->m_cameras.AddCameras(AZStd::vector<AZStd::shared_ptr<AzFramework::CameraInput>>{ firstPersonPanCamera });
EXPECT_THAT(added, ::testing::IsTrue());
}
TEST_F(CameraInputFixture, ExistingCameraInputCannotBeAddedToCameraSystem)
{
const bool added =
m_cameraSystem->m_cameras.AddCameras(AZStd::vector<AZStd::shared_ptr<AzFramework::CameraInput>>{ m_firstPersonRotateCamera });
EXPECT_THAT(added, ::testing::IsFalse());
}
TEST_F(CameraInputFixture, ExistingCameraInputCanBeRemovedFromCameraSystem)
{
const bool removed = m_cameraSystem->m_cameras.RemoveCameras(
AZStd::vector<AZStd::shared_ptr<AzFramework::CameraInput>>{ m_firstPersonRotateCamera });
EXPECT_THAT(removed, ::testing::IsTrue());
}
TEST_F(CameraInputFixture, NonExistentCameraInputCannotBeRemovedFromCameraSystem)
{
auto firstPersonPanCamera = AZStd::make_shared<AzFramework::PanCameraInput>(
AzFramework::InputDeviceMouse::Button::Middle, AzFramework::LookPan, AzFramework::TranslatePivotLook);
const bool removed = m_cameraSystem->m_cameras.RemoveCameras(
AZStd::vector<AZStd::shared_ptr<AzFramework::CameraInput>>{ firstPersonPanCamera });
EXPECT_THAT(removed, ::testing::IsFalse());
}
} // namespace UnitTest

@ -17,7 +17,6 @@
#include <AzNetworking/Utilities/NetworkCommon.h>
#include <AzCore/Console/IConsole.h>
#include <AzCore/Console/ILogger.h>
#include <AzCore/Math/MathUtils.h>
namespace AzNetworking
{
@ -540,7 +539,7 @@ namespace AzNetworking
// Each fragmented packet we send adds an extra fragmented packet header, need to deduct that from our chunk size, otherwise we infinitely loop
// SSL encryption can also inflate our payload so we pre-emptively deduct an estimated tax
const uint32_t chunkSize = connection.GetConnectionMtu() - net_FragmentedHeaderOverhead - net_SslInflationOverhead;
const uint32_t numChunks = AZ::DivideAndRoundUp(packetSize, chunkSize); // We want to round up on the remainder
const uint32_t numChunks = (packetSize + chunkSize - 1) / chunkSize; // We want to round up on the remainder
const uint8_t* chunkStart = packetData;
const SequenceId fragmentedSequence = connection.m_fragmentQueue.GetNextFragmentedSequenceId();
uint32_t bytesRemaining = packetSize;

@ -8,7 +8,6 @@
#pragma once
#include <AzCore/EBus/EBus.h>
#include <AzCore/Math/Vector2.h>
#include <AzCore/Outcome/Outcome.h>
#include <AzCore/std/any.h>
#include <AzCore/std/string/string.h>

@ -208,6 +208,10 @@ namespace LegacyFramework
*/
virtual bool IsRunningInGUIMode() = 0;
/** Retrieve a Command Line Parser object that you can then use to check for values on the command line
*/
virtual const AzFramework::CommandLine* GetCommandLineParser() = 0;
/** (Windows) retrieves the main module of the executable.
* This is always going to be the main executable except in the situation where the framework may be running as a DLL belonging to another process or program.
*/

@ -97,10 +97,6 @@ namespace LegacyFramework
}
Application::Application()
: Application(0, nullptr)
{}
Application::Application(int argc, char** argv)
: ComponentApplication(argc, argv)
{
m_isPrimary = true;
m_desiredExitCode = 0;
@ -195,6 +191,9 @@ namespace LegacyFramework
::SetConsoleCtrlHandler(CTRL_BREAK_HandlerRoutine, true);
#endif
m_ptrCommandLineParser = aznew AzFramework::CommandLine();
m_ptrCommandLineParser->Parse(m_desc.m_argc, m_desc.m_argv);
// If we don't have one create a serialize context
if (GetSerializeContext() == nullptr)
{
@ -207,7 +206,7 @@ namespace LegacyFramework
m_ptrSystemEntity->Activate();
// If we aren't the primary, RunAsAnotherInstance unless we are being forcestarted
if (!m_isPrimary && !m_commandLine.HasSwitch("forcestart"))
if (!m_isPrimary && !m_ptrCommandLineParser->HasSwitch("forcestart"))
{
// Required for the application component to handle RunAsAnotherInstance
CreateApplicationComponent();
@ -247,6 +246,9 @@ namespace LegacyFramework
::SetConsoleCtrlHandler(CTRL_BREAK_HandlerRoutine, false);
#endif
delete m_ptrCommandLineParser;
m_ptrCommandLineParser = nullptr;
CoreMessageBus::Handler::BusDisconnect();
FrameworkApplicationMessages::Handler::BusDisconnect();
@ -269,6 +271,11 @@ namespace LegacyFramework
}
}
const AzFramework::CommandLine* Application::GetCommandLineParser()
{
return m_ptrCommandLineParser;
}
// returns TRUE if the component already existed, FALSE if it had to create one.
bool Application::EnsureComponentCreated(AZ::Uuid componentCRC)
{

@ -56,7 +56,6 @@ namespace LegacyFramework
using CoreMessageBus::Handler::Run;
virtual int Run(const ApplicationDesc& desc);
Application();
Application(int argc, char** argv);
void CreateReflectionManager() override;
@ -71,6 +70,7 @@ namespace LegacyFramework
const char* GetApplicationName() override;
const char* GetApplicationModule() override;
const char* GetApplicationDirectory() override;
const AzFramework::CommandLine* GetCommandLineParser() override;
void TeardownApplicationComponent() override;
void RunAssetProcessor() override;
// ------------------------------------------------------------------
@ -138,6 +138,7 @@ namespace LegacyFramework
volatile bool m_abortRequested; // if you CTRL+C in a console app, this becomes true. its up to you to check...
char m_applicationFilePath[AZ_MAX_PATH_LEN];
ApplicationDesc m_desc;
AzFramework::CommandLine* m_ptrCommandLineParser;
};
}

@ -16,7 +16,7 @@
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/Settings/CommandLine.h>
#include <AzFramework/CommandLine/CommandLine.h>
#include <AzToolsFramework/UI/UICore/QWidgetSavedState.h>
#include <AzToolsFramework/UI/LegacyFramework/Core/EditorFrameworkAPI.h>
@ -34,6 +34,7 @@ AZ_PUSH_DISABLE_WARNING(4251, "-Wunknown-warning-option") // '...' needs to have
#include <QProxyStyle>
AZ_POP_DISABLE_WARNING
#include <AzFramework/StringFunc/StringFunc.h>
#ifndef AZ_PLATFORM_WINDOWS
int __argc = 0;
@ -200,11 +201,8 @@ namespace AzToolsFramework
// enable the built-in stylesheet by default:
bool enableStyleSheet = true;
const AZ::CommandLine* comp = nullptr;
AZ::ComponentApplicationBus::Broadcast([&comp](AZ::ComponentApplicationRequests* requests)
{
comp = requests->GetAzCommandLine();
});
const AzFramework::CommandLine* comp = nullptr;
EBUS_EVENT_RESULT(comp, LegacyFramework::FrameworkApplicationMessages::Bus, GetCommandLineParser);
if (comp != nullptr)
{
if (comp->HasSwitch("nostyle"))

@ -253,68 +253,6 @@ namespace AzToolsFramework
}
}
// Edit/Inspect/Close Prefab
{
if (selectedEntities.size() == 1)
{
AZ::EntityId selectedEntity = selectedEntities[0];
if (s_prefabPublicInterface->IsInstanceContainerEntity(selectedEntity))
{
if (!s_prefabFocusPublicInterface->IsOwningPrefabBeingFocused(selectedEntity))
{
if (s_prefabPublicInterface->IsOwnedByProceduralPrefabInstance(selectedEntity))
{
// Inspect Prefab
QAction* editAction = menu->addAction(QObject::tr("Inspect Procedural Prefab"));
editAction->setShortcut(QKeySequence(Qt::Key_Plus));
editAction->setToolTip(QObject::tr("See the procedural prefab contents in focus mode."));
QObject::connect(
editAction, &QAction::triggered, editAction,
[selectedEntity]
{
ContextMenu_EditPrefab(selectedEntity);
}
);
}
else
{
// Edit Prefab
QAction* editAction = menu->addAction(QObject::tr("Open/Edit Prefab"));
editAction->setShortcut(QKeySequence(Qt::Key_Plus));
editAction->setToolTip(QObject::tr("Edit the prefab in focus mode."));
QObject::connect(
editAction, &QAction::triggered, editAction,
[selectedEntity]
{
ContextMenu_EditPrefab(selectedEntity);
}
);
}
}
else
{
// Close Prefab
QAction* closeAction = menu->addAction(QObject::tr("Close Prefab"));
closeAction->setShortcut(QKeySequence(Qt::Key_Minus));
closeAction->setToolTip(QObject::tr("Close focus mode for this prefab and move one level up."));
QObject::connect(
closeAction, &QAction::triggered, closeAction,
[]
{
ContextMenu_ClosePrefab();
}
);
}
menu->addSeparator();
}
}
}
bool itemWasShown = false;
// Create Prefab
@ -353,8 +291,7 @@ namespace AzToolsFramework
[selectedEntities]
{
ContextMenu_CreatePrefab(selectedEntities);
}
);
});
itemWasShown = true;
}
@ -362,21 +299,6 @@ namespace AzToolsFramework
}
}
// Detach Prefab
if (onlySelectedEntityIsClosedPrefabContainer)
{
AZ::EntityId selectedEntityId = selectedEntities.front();
QAction* detachPrefabAction = menu->addAction(QObject::tr("Detach Prefab..."));
QObject::connect(
detachPrefabAction, &QAction::triggered, detachPrefabAction,
[selectedEntityId]
{
ContextMenu_DetachPrefab(selectedEntityId);
}
);
}
// Instantiate Prefab
if (selectedEntities.size() == 0 ||
selectedEntities.size() == 1 && !readOnlyEntityInSelection && !onlySelectedEntityIsClosedPrefabContainer)
@ -389,8 +311,7 @@ namespace AzToolsFramework
[]
{
ContextMenu_InstantiatePrefab();
}
);
});
// Instantiate Procedural Prefab
if (AZ::Prefab::ProceduralPrefabAsset::UseProceduralPrefabs())
@ -403,8 +324,7 @@ namespace AzToolsFramework
[]
{
ContextMenu_InstantiateProceduralPrefab();
}
);
});
}
itemWasShown = true;
@ -415,7 +335,9 @@ namespace AzToolsFramework
menu->addSeparator();
}
// Save Prefab
itemWasShown = false;
// Edit/Save Prefab
{
if (selectedEntities.size() == 1)
{
@ -423,6 +345,52 @@ namespace AzToolsFramework
if (s_prefabPublicInterface->IsInstanceContainerEntity(selectedEntity))
{
if (!s_prefabFocusPublicInterface->IsOwningPrefabBeingFocused(selectedEntity))
{
if (s_prefabPublicInterface->IsOwnedByProceduralPrefabInstance(selectedEntity))
{
// Inspect Prefab
QAction* editAction = menu->addAction(QObject::tr("Inspect Procedural Prefab"));
editAction->setShortcut(QKeySequence(Qt::Key_Plus));
editAction->setToolTip(QObject::tr("See the procedural prefab contents in focus mode."));
QObject::connect(
editAction, &QAction::triggered, editAction,
[selectedEntity]
{
ContextMenu_EditPrefab(selectedEntity);
});
}
else
{
// Edit Prefab
QAction* editAction = menu->addAction(QObject::tr("Open/Edit Prefab"));
editAction->setShortcut(QKeySequence(Qt::Key_Plus));
editAction->setToolTip(QObject::tr("Edit the prefab in focus mode."));
QObject::connect(
editAction, &QAction::triggered, editAction,
[selectedEntity]
{
ContextMenu_EditPrefab(selectedEntity);
});
}
}
else
{
// Close Prefab
QAction* closeAction = menu->addAction(QObject::tr("Close Prefab"));
closeAction->setShortcut(QKeySequence(Qt::Key_Minus));
closeAction->setToolTip(QObject::tr("Close focus mode for this prefab and move one level up."));
QObject::connect(
closeAction, &QAction::triggered, closeAction,
[]
{
ContextMenu_ClosePrefab();
});
}
// Save Prefab
AZ::IO::Path prefabFilePath = s_prefabPublicInterface->GetOwningInstancePrefabPath(selectedEntity);
auto dirtyOutcome = s_prefabPublicInterface->HasUnsavedChanges(prefabFilePath);
@ -437,43 +405,17 @@ namespace AzToolsFramework
[selectedEntity]
{
ContextMenu_SavePrefab(selectedEntity);
}
);
menu->addSeparator();
});
}
itemWasShown = true;
}
}
}
if (!selectedEntities.empty())
if (itemWasShown)
{
// Don't allow duplication if any of the selected entities are direct descendants of a read-only entity
bool selectionContainsDescendantOfReadOnlyEntity = false;
for (const auto& entityId : selectedEntities)
{
AZ::EntityId parentEntityId;
AZ::TransformBus::EventResult(parentEntityId, entityId, &AZ::TransformBus::Events::GetParentId);
if (parentEntityId.IsValid() && m_readOnlyEntityPublicInterface->IsReadOnly(parentEntityId))
{
selectionContainsDescendantOfReadOnlyEntity = true;
break;
}
}
if (!selectionContainsDescendantOfReadOnlyEntity)
{
QAction* duplicateAction = menu->addAction(QObject::tr("Duplicate"));
duplicateAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_D));
QObject::connect(
duplicateAction, &QAction::triggered, duplicateAction,
[]
{
ContextMenu_Duplicate();
}
);
}
menu->addSeparator();
}
if (!selectedEntities.empty() &&
@ -482,17 +424,27 @@ namespace AzToolsFramework
!readOnlyEntityInSelection)
{
QAction* deleteAction = menu->addAction(QObject::tr("Delete"));
deleteAction->setShortcut(QKeySequence(Qt::Key_Delete));
QObject::connect(
deleteAction, &QAction::triggered, deleteAction,
[]
{
ContextMenu_DeleteSelected();
}
);
});
}
menu->addSeparator();
// Detach Prefab
if (onlySelectedEntityIsClosedPrefabContainer)
{
AZ::EntityId selectedEntityId = selectedEntities.front();
QAction* detachPrefabAction = menu->addAction(QObject::tr("Detach Prefab..."));
QObject::connect(
detachPrefabAction, &QAction::triggered, detachPrefabAction,
[selectedEntityId]
{
ContextMenu_DetachPrefab(selectedEntityId);
});
}
}
void PrefabIntegrationManager::OnEscape()
@ -701,12 +653,6 @@ namespace AzToolsFramework
}
}
void PrefabIntegrationManager::ContextMenu_Duplicate()
{
bool handled = true;
AzToolsFramework::EditorRequestBus::Broadcast(&AzToolsFramework::EditorRequests::CloneSelection, handled);
}
void PrefabIntegrationManager::ContextMenu_DeleteSelected()
{
AzToolsFramework::EntityIdList selectedEntityIds;

@ -92,7 +92,6 @@ namespace AzToolsFramework
static void ContextMenu_ClosePrefab();
static void ContextMenu_EditPrefab(AZ::EntityId containerEntity);
static void ContextMenu_SavePrefab(AZ::EntityId containerEntity);
static void ContextMenu_Duplicate();
static void ContextMenu_DeleteSelected();
static void ContextMenu_DetachPrefab(AZ::EntityId containerEntity);

@ -20,7 +20,6 @@
#include <GridMate/Containers/unordered_set.h>
#include <GridMate/Carrier/DriverEvents.h>
#include <AzCore/Math/MathUtils.h>
#include <AzCore/std/chrono/types.h>
#include <AzCore/std/string/conversions.h>
#include <AzCore/std/string/memorytoascii.h>
@ -1952,7 +1951,7 @@ namespace GridMate
char *SocketDriverCommon::RIOPlatformSocketDriver::AllocRIOBuffer(AZ::u64 bufferSize, AZ::u64 numBuffers, AZ::u64* amountAllocated /*=nullptr*/)
{
// calculate how much memory we are really asking for, and this must be page aligned.
AZ::u64 totalBufferSize = AZ::RoundUpToMultiple(bufferSize * numBuffers, m_pageSize);
AZ::u64 totalBufferSize = RoundUp(bufferSize * numBuffers, m_pageSize);
if (amountAllocated != nullptr)
{

@ -221,6 +221,18 @@ namespace GridMate
void StopWaitForData() override;
private:
AZ::u64 RoundUpAndDivide(AZ::u64 Value, AZ::u64 RoundTo) const
{
return ((Value + RoundTo - 1) / RoundTo);
}
AZ::u64 RoundUp(AZ::u64 Value, AZ::u64 RoundTo) const
{
// rounds value up to multiple of RoundTo
// Example: RoundTo: 4
// Value: 0 1 2 3 4 5 6 7 8
// Result: 0 4 4 4 4 8 8 8 8
return RoundUpAndDivide(Value, RoundTo) * RoundTo;
}
char *AllocRIOBuffer(AZ::u64 bufferSize, AZ::u64 numBuffers, AZ::u64* amountAllocated=nullptr);
bool FreeRIOBuffer(char *buffer);

@ -21,11 +21,11 @@
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
#include <AzCore/std/string/conversions.h>
#include <AzCore/std/string/regex.h>
#include <AzCore/StringFunc/StringFunc.h>
#include <AzFramework/Asset/AssetSystemBus.h>
#include <AzFramework/Asset/AssetSystemComponent.h>
#include <AzFramework/Asset/AssetCatalogBus.h>
#include <AzFramework/StringFunc/StringFunc.h>
#include <AzFramework/Asset/AssetProcessorMessages.h>
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
@ -244,7 +244,7 @@ namespace LUAEditor
}
AZStd::vector<AZStd::string> files;
AZ::StringFunc::Tokenize(parameters.c_str(), files, ";");
AzFramework::StringFunc::Tokenize(parameters.c_str(), files, ";");
if (!files.empty())
{
for (const auto& file : files)
@ -669,12 +669,9 @@ namespace LUAEditor
return;
}
const AZ::CommandLine* commandLine = nullptr;
const AzFramework::CommandLine* commandLine = nullptr;
AZ::ComponentApplicationBus::Broadcast([&commandLine](AZ::ComponentApplicationRequests* requests)
{
commandLine = requests->GetAzCommandLine();
});
EBUS_EVENT_RESULT(commandLine, LegacyFramework::FrameworkApplicationMessages::Bus, GetCommandLineParser);
bool forceShow = false;
bool forceHide = false;
@ -853,7 +850,7 @@ namespace LUAEditor
DocumentInfo& info = infoEntry.first->second;
info.m_assetId = normalizedAssetId;
info.m_assetName = assetId;
AZ::StringFunc::Path::GetFullFileName(assetId.c_str(), info.m_displayName);
AzFramework::StringFunc::Path::GetFullFileName(assetId.c_str(), info.m_displayName);
info.m_bSourceControl_Ready = true;
info.m_bSourceControl_CanWrite = true;
info.m_bUntitledDocument = false;
@ -948,7 +945,7 @@ namespace LUAEditor
// do not allow SaveAs onto an existing asset, even if it could be checked out and modified "safely."
// end user must check out and modify contents directly if they want this
if (AZ::StringFunc::Find(newAssetName.c_str(), ".lua") == AZStd::string::npos)
if (AzFramework::StringFunc::Find(newAssetName.c_str(), ".lua") == AZStd::string::npos)
{
newAssetName += ".lua";
}
@ -964,7 +961,7 @@ namespace LUAEditor
trySaveAs = false;
docInfoIter->second.m_bUntitledDocument = false;
AZ::StringFunc::Path::GetFullFileName(newAssetName.c_str(), docInfoIter->second.m_displayName);
AzFramework::StringFunc::Path::GetFullFileName(newAssetName.c_str(), docInfoIter->second.m_displayName);
// when you 'save as' you can write to it, even if it started out not that way.
docInfoIter->second.m_bSourceControl_Ready = true;
@ -1492,7 +1489,7 @@ namespace LUAEditor
DocumentInfo info;
info.m_assetName = assetIdLower;
AZ::StringFunc::Path::GetFullFileName(assetId.c_str(), info.m_displayName);
AzFramework::StringFunc::Path::GetFullFileName(assetId.c_str(), info.m_displayName);
info.m_assetId = assetIdLower;
info.m_bSourceControl_BusyGettingStats = true;
info.m_bSourceControl_BusyGettingStats = false;
@ -1558,10 +1555,7 @@ namespace LUAEditor
const AZStd::string k_luaScriptFileString = "files";
const AzFramework::CommandLine* commandLine = nullptr;
AZ::ComponentApplicationBus::Broadcast([&commandLine](AZ::ComponentApplicationRequests* requests)
{
commandLine = requests->GetAzCommandLine();
});
EBUS_EVENT_RESULT(commandLine, LegacyFramework::FrameworkApplicationMessages::Bus, GetCommandLineParser);
AZStd::string parameters = "";
size_t numSwitchValues = commandLine->GetNumSwitchValues(k_luaScriptFileString);
@ -2454,7 +2448,7 @@ namespace LUAEditor
if (matchFound)
{
int lineNumber = 0;
if (AZ::StringFunc::LooksLikeInt(match[1].str().c_str(), &lineNumber))
if (AzFramework::StringFunc::LooksLikeInt(match[1].str().c_str(), &lineNumber))
{
errorData->m_lineNumber = lineNumber;
finalMessage = match[2].str().c_str();
@ -2473,6 +2467,6 @@ namespace LUAEditor
bool Context::IsLuaAsset(const AZStd::string& assetPath)
{
return AZ::StringFunc::Path::IsExtension(assetPath.c_str(), ".lua");
return AzFramework::StringFunc::Path::IsExtension(assetPath.c_str(), ".lua");
}
}

@ -27,8 +27,7 @@
namespace LUAEditor
{
Application::Application(int argc, char **argv)
: BaseApplication(argc, argv)
Application::Application(int &argc, char **argv) : BaseApplication(argc, argv)
{
AzToolsFramework::SourceControlNotificationBus::Handler::BusConnect();
}

@ -17,7 +17,7 @@ namespace LUAEditor
, protected AzToolsFramework::SourceControlNotificationBus::Handler
{
public:
Application(int argc, char **argv);
Application(int &argc, char **argv);
~Application() override;
protected:

@ -20,8 +20,8 @@
namespace StandaloneTools
{
BaseApplication::BaseApplication(int argc, char** argv)
: LegacyFramework::Application(argc, argv)
BaseApplication::BaseApplication(int&, char**)
: LegacyFramework::Application()
{
AZ::UserSettingsFileLocatorBus::Handler::BusConnect();
}

@ -25,7 +25,7 @@ namespace StandaloneTools
{
public:
BaseApplication(int argc, char **argv);
BaseApplication(int &argc, char **argv);
~BaseApplication() override;
protected:

@ -179,7 +179,7 @@ namespace ImageProcessingAtom
// Create a context based on the configuration
astcenc_context* context;
AZ::u32 blockCount = AZ::DivideAndRoundUp(srcImage->GetWidth(0), dstFormatInfo->blockWidth) * AZ::DivideAndRoundUp(srcImage->GetHeight(0), dstFormatInfo->blockHeight);
AZ::u32 blockCount = ((srcImage->GetWidth(0)+ dstFormatInfo->blockWidth-1)/dstFormatInfo->blockWidth) * ((srcImage->GetHeight(0) + dstFormatInfo->blockHeight-1)/dstFormatInfo->blockHeight);
AZ::u32 threadCount = AZStd::min(AZStd::thread::hardware_concurrency()/2, blockCount);
status = astcenc_context_alloc(&config, threadCount, &context);
AZ_Assert( status == ASTCENC_SUCCESS, "ERROR: Codec context alloc failed: %s\n", astcenc_get_error_string(status));

@ -10,8 +10,6 @@
#include <Processing/PixelFormatInfo.h>
#include <Processing/DDSHeader.h>
#include <AzCore/Math/MathUtils.h>
namespace ImageProcessingAtom
{
CPixelFormats* CPixelFormats::s_instance = nullptr;
@ -372,11 +370,11 @@ namespace ImageProcessingAtom
{
if (outWidth % pFormatInfo->blockWidth != 0)
{
outWidth = AZ::RoundUpToMultiple(outWidth, pFormatInfo->blockWidth);
outWidth = ((outWidth + pFormatInfo->blockWidth - 1) / pFormatInfo->blockWidth) * pFormatInfo->blockWidth;
}
if (outHeight % pFormatInfo->blockHeight != 0)
{
outHeight = AZ::RoundUpToMultiple(outHeight, pFormatInfo->blockHeight);
outHeight = ((outHeight + pFormatInfo->blockHeight - 1) / pFormatInfo->blockHeight) * pFormatInfo->blockHeight;
}
}
}
@ -392,11 +390,10 @@ namespace ImageProcessingAtom
return 0;
}
// get number of blocks and multiply with bits per block. Divided by 8 to get
// get number of blocks (ceiling round up for block count) and multiply with bits per block. Divided by 8 to get
// final byte size
return (AZ::DivideAndRoundUp(imageWidth, pFormatInfo->blockWidth) *
AZ::DivideAndRoundUp(imageHeight, pFormatInfo->blockHeight) *
pFormatInfo->bitsPerBlock) / 8;
return (((imageWidth + pFormatInfo->blockWidth - 1) / pFormatInfo->blockWidth) *
((imageHeight + pFormatInfo->blockHeight - 1) / pFormatInfo->blockHeight) * pFormatInfo->bitsPerBlock) / 8;
}
bool CPixelFormats::IsFormatSingleChannel(EPixelFormat fmt)

@ -8,7 +8,6 @@
#pragma once
#include <AzCore/base.h>
#include <AzCore/Math/MathUtils.h>
#ifndef AZ_BIT
#define AZ_BIT(x) (1u << x)
@ -238,7 +237,6 @@ namespace AZ
}
/**
* O3DE_DEPRECATION_NOTICE(GHI-7407)
* Returns the value divided by alignment, where the result is rounded up if the remainder is non-zero.
*/
template <typename T> inline T DivideByMultiple(T value, size_t alignment)

@ -228,7 +228,7 @@ namespace AZ
{
AZStd::span<const uint8_t> constantBytes = GetConstantRaw(inputIndex);
const size_t elementSize = sizeof(T);
const size_t elementCount = AZ::DivideAndRoundUp(constantBytes.size(), elementSize);
const size_t elementCount = DivideByMultiple(constantBytes.size(), elementSize);
const size_t sizeInBytes = elementCount * elementSize;
if (ValidateConstantAccess(inputIndex, ValidateConstantAccessExpect::Complete, 0, sizeInBytes))
{

@ -41,17 +41,17 @@ namespace AZ
uint16_t GetNumberOfGroupsX() const
{
return aznumeric_cast<uint16_t>(DivideAndRoundUp(m_totalNumberOfThreadsX, aznumeric_caster(m_threadsPerGroupX)));
return aznumeric_cast<uint16_t>((m_totalNumberOfThreadsX + m_threadsPerGroupX - 1) / m_threadsPerGroupX);
}
uint16_t GetNumberOfGroupsY() const
{
return aznumeric_cast<uint16_t>(DivideAndRoundUp(m_totalNumberOfThreadsY, aznumeric_caster(m_threadsPerGroupY)));
return aznumeric_cast<uint16_t>((m_totalNumberOfThreadsY + m_threadsPerGroupY - 1) / m_threadsPerGroupY);
}
uint16_t GetNumberOfGroupsZ() const
{
return aznumeric_cast<uint16_t>(DivideAndRoundUp(m_totalNumberOfThreadsZ, aznumeric_caster(m_threadsPerGroupZ)));
return aznumeric_cast<uint16_t>((m_totalNumberOfThreadsZ + m_threadsPerGroupZ - 1) / m_threadsPerGroupZ);
}
// Different platforms require number of groups or number of threads or both in their Dispatch() call

@ -358,7 +358,8 @@ namespace AZ
}
else
{
subresourceLayout.m_bytesPerRow = imageSize.m_width * RHI::GetFormatSize(imageFormat);
const uint32_t bitsPerPixel = RHI::GetFormatSize(imageFormat) * 8;
subresourceLayout.m_bytesPerRow = (imageSize.m_width * bitsPerPixel + 7) / 8; // round up to nearest byte
subresourceLayout.m_rowCount = imageSize.m_height;
subresourceLayout.m_size.m_width = imageSize.m_width;
subresourceLayout.m_size.m_height = imageSize.m_height;

@ -20,7 +20,7 @@ namespace AZ
return DrawListView{};
}
const size_t itemsPerPartition = AZ::DivideAndRoundUp(drawList.size(), partitionCount);
const size_t itemsPerPartition = DivideByMultiple(drawList.size(), partitionCount);
const size_t itemOffset = partitionIndex * itemsPerPartition;
const size_t itemCount = AZStd::min(drawList.size() - itemOffset, itemsPerPartition);
return DrawListView(&drawList[itemOffset], itemCount);

@ -281,7 +281,7 @@ namespace AZ
{
srgPool->CompileGroupsBegin();
const uint32_t compilesInPool = srgPool->GetGroupsToCompileCount();
const uint32_t jobCount = AZ::DivideAndRoundUp(compilesInPool, compilesPerJob);
const uint32_t jobCount = DivideByMultiple(compilesInPool, compilesPerJob);
AZ::TaskDescriptor srgCompileDesc{"SrgCompile", "Graphics"};
AZ::TaskDescriptor srgCompileEndDesc{"SrgCompileEnd", "Graphics"};
@ -332,7 +332,7 @@ namespace AZ
const auto compileIntervalsFunction = [compilesPerJob, &jobCompletion](ShaderResourceGroupPool* srgPool)
{
const uint32_t compilesInPool = srgPool->GetGroupsToCompileCount();
const uint32_t jobCount = AZ::DivideAndRoundUp(compilesInPool, compilesPerJob);
const uint32_t jobCount = DivideByMultiple(compilesInPool, compilesPerJob);
for (uint32_t i = 0; i < jobCount; ++i)
{

@ -100,7 +100,7 @@ namespace AZ
// The frame attachment has tight control over lifecycle here.
[[maybe_unused]] const bool isAttach = (!m_frameAttachment && frameAttachment);
[[maybe_unused]] const bool isDetach = (m_frameAttachment && !frameAttachment);
AZ_Assert(isAttach || isDetach, "The frame attachment for resource '%s' was not assigned properly.", GetName().GetCStr());
AZ_Assert(isAttach || isDetach, "The frame attachment for resource '%s' was not assigned properly.");
}
m_frameAttachment = frameAttachment;

@ -92,7 +92,7 @@ namespace AZ
const uint32_t CommandListCostThreshold =
AZStd::max(
m_frameGraphExecuterData.m_commandListCostThresholdMin,
AZ::DivideAndRoundUp(estimatedItemCount, m_frameGraphExecuterData.m_commandListsPerScopeMax));
RHI::DivideByMultiple(estimatedItemCount, m_frameGraphExecuterData.m_commandListsPerScopeMax));
/**
* Computes a cost heuristic based on the number of items and number of attachments in
@ -145,7 +145,7 @@ namespace AZ
else
{
// And then create a new group for the current scope with dedicated [1, N] command lists.
const uint32_t commandListCount = AZStd::max(AZ::DivideAndRoundUp(totalScopeCost, CommandListCostThreshold), 1u);
const uint32_t commandListCount = AZStd::max(RHI::DivideByMultiple(totalScopeCost, CommandListCostThreshold), 1u);
FrameGraphExecuteGroup* scopeContextGroup = AddGroup<FrameGraphExecuteGroup>();
scopeContextGroup->Init(device, scope, commandListCount, GetJobPolicy());

@ -81,7 +81,7 @@ namespace AZ
const uint32_t CommandListCostThreshold =
AZStd::max(
m_frameGraphExecuterData.m_commandListCostThresholdMin,
AZ::DivideAndRoundUp(estimatedItemCount, m_frameGraphExecuterData.m_commandListsPerScopeMax));
RHI::DivideByMultiple(estimatedItemCount, m_frameGraphExecuterData.m_commandListsPerScopeMax));
/**
* Computes a cost heuristic based on the number of items and number of attachments in
@ -136,7 +136,7 @@ namespace AZ
else
{
// And then create a new group for the current scope with dedicated [1, N] command lists.
const uint32_t commandListCount = AZStd::max(AZ::DivideAndRoundUp(totalScopeCost, CommandListCostThreshold), 1u);
const uint32_t commandListCount = AZStd::max(RHI::DivideByMultiple(totalScopeCost, CommandListCostThreshold), 1u);
FrameGraphExecuteGroup* scopeContextGroup = AddGroup<FrameGraphExecuteGroup>();
scopeContextGroup->Init(device, scope, commandListCount, GetJobPolicy());

@ -1,72 +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
*
*/
#pragma once
#if !defined(Q_MOC_RUN)
#include <AtomToolsFramework/Document/AtomToolsDocumentNotificationBus.h>
#include <AtomToolsFramework/Inspector/InspectorWidget.h>
#include <AzCore/std/containers/unordered_set.h>
#include <AzToolsFramework/UI/PropertyEditor/PropertyEditorAPI_Internals.h>
#endif
namespace AtomToolsFramework
{
//! This is a specialized inspector widget that populates itself by inspecting document reflected object info.
//! Each element of an AtomToolsDocument object info vector will be displayed in a collapsible RPE group in the inspector.
//! Property changes emitted from each RPE will be tracked and used to signal undo/redo events in the document.
class AtomToolsDocumentInspector
: public InspectorWidget
, public AtomToolsDocumentNotificationBus::Handler
, public AzToolsFramework::IPropertyEditorNotify
{
Q_OBJECT
public:
AZ_CLASS_ALLOCATOR(AtomToolsDocumentInspector, AZ::SystemAllocator, 0);
AtomToolsDocumentInspector(const AZ::Crc32& toolId, QWidget* parent = nullptr);
~AtomToolsDocumentInspector() override;
//! Set the ID of the document that will be used to populate the inspector
void SetDocumentId(const AZ::Uuid& documentId);
//! Set a prefix string for storing registry settings
void SetDocumentSettingsPrefix(const AZStd::string& prefix);
using NodeIndicatorFunction = AZStd::function<const char*(const AzToolsFramework::InstanceDataNode*)>;
//! Set a function that will be used to determine what, if any, icon should be displayed next to a property in the inspector
void SetIndicatorFunction(const NodeIndicatorFunction& indicatorFunction);
// InspectorRequestBus::Handler overrides...
void Reset() override;
private:
// AtomToolsDocumentNotificationBus::Handler implementation
void OnDocumentObjectInfoChanged(const AZ::Uuid& documentId, const DocumentObjectInfo& objectInfo, bool rebuilt) override;
// AzToolsFramework::IPropertyEditorNotify overrides...
void BeforePropertyModified(AzToolsFramework::InstanceDataNode* pNode) override;
void AfterPropertyModified([[maybe_unused]] AzToolsFramework::InstanceDataNode* pNode) override {}
void SetPropertyEditingActive([[maybe_unused]] AzToolsFramework::InstanceDataNode* pNode) override {}
void SetPropertyEditingComplete(AzToolsFramework::InstanceDataNode* pNode) override;
void SealUndoStack() override {}
void RequestPropertyContextMenu([[maybe_unused]] AzToolsFramework::InstanceDataNode* pNode, const QPoint&) override {}
void PropertySelectionChanged([[maybe_unused]] AzToolsFramework::InstanceDataNode* pNode, bool) override {}
const AZ::Crc32 m_toolId = {};
bool m_editInProgress = {};
AZ::Uuid m_documentId = AZ::Uuid::CreateNull();
NodeIndicatorFunction m_nodeIndicatorFunction;
AZStd::string m_documentSettingsPrefix = "/O3DE/AtomToolsFramework/AtomToolsDocumentInspector";
};
} // namespace AtomToolsFramework

@ -9,12 +9,8 @@
#pragma once
#if !defined(Q_MOC_RUN)
#include <AtomToolsFramework/Inspector/InspectorRequestBus.h>
#include <AzCore/Memory/SystemAllocator.h>
#include <AzCore/RTTI/RTTI.h>
#include <AzCore/RTTI/ReflectContext.h>
#include <AzCore/std/containers/unordered_map.h>
#include <AzCore/std/string/string.h>
#include <AtomToolsFramework/Inspector/InspectorRequestBus.h>
AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option") // disable warnings spawned by QT
#include <QVBoxLayout>
@ -40,10 +36,8 @@ namespace AtomToolsFramework
Q_OBJECT
public:
AZ_CLASS_ALLOCATOR(InspectorWidget, AZ::SystemAllocator, 0);
AZ_RTTI(AtomToolsFramework::InspectorWidget, "{D77A5F5F-0536-4249-916F-328B272E1AAB}");
static void Reflect(AZ::ReflectContext* context);
InspectorWidget(QWidget* parent = nullptr);
explicit InspectorWidget(QWidget* parent = nullptr);
~InspectorWidget() override;
// InspectorRequestBus::Handler overrides...
@ -80,8 +74,6 @@ namespace AtomToolsFramework
void ExpandAll() override;
void CollapseAll() override;
void SetGroupSettingsPrefix(const AZStd::string& prefix);
protected:
virtual bool ShouldGroupAutoExpanded(const AZStd::string& groupName) const;
virtual void OnGroupExpanded(const AZStd::string& groupName);
@ -89,15 +81,14 @@ namespace AtomToolsFramework
virtual void OnHeaderClicked(const AZStd::string& groupName, QMouseEvent* event);
private:
QScopedPointer<Ui::InspectorWidget> m_ui;
struct GroupWidgetPair
{
InspectorGroupHeaderWidget* m_header;
QWidget* m_panel;
};
QScopedPointer<Ui::InspectorWidget> m_ui;
AZStd::string m_collapsedGroupSettingName;
AZStd::unordered_set<AZ::u32> m_collapsedGroups;
AZStd::unordered_map<AZStd::string, GroupWidgetPair> m_groups;
};
} // namespace AtomToolsFramework

@ -11,8 +11,14 @@
#include <Atom/RPI.Reflect/Material/MaterialPropertyDescriptor.h>
#include <Atom/RPI.Reflect/Material/MaterialPropertyValue.h>
#include <AtomToolsFramework/DynamicProperty/DynamicProperty.h>
#include <AzCore/IO/Path/Path.h>
#include <AzCore/std/any.h>
namespace AzToolsFramework
{
class InstanceDataNode;
}
namespace AtomToolsFramework
{
//! Convert an editor property stored in a AZStd::any into a material property value
@ -46,4 +52,14 @@ namespace AtomToolsFramework
[[maybe_unused]] const AZ::Name& propertyId,
const AZ::RPI::MaterialTypeSourceData::PropertyDefinition& propertyDefinition,
AZ::RPI::MaterialPropertyValue& propertyValue);
//! Generate a file path that is relative to either the source asset root or the export path
//! @param exportPath absolute path of the file being saved
//! @param referencePath absolute path of a file that will be treated as an external reference
//! @param relativeToExportPath specifies if the path is relative to the source asset root or the export path
AZStd::string GetExteralReferencePath(
const AZStd::string& exportPath, const AZStd::string& referencePath, const bool relativeToExportPath = false);
//! Traverse up the instance data node hierarchy to find the containing dynamic property object
const AtomToolsFramework::DynamicProperty* FindDynamicPropertyForInstanceDataNode(const AzToolsFramework::InstanceDataNode* pNode);
} // namespace AtomToolsFramework

@ -9,12 +9,9 @@
#pragma once
#include <AzCore/Asset/AssetManager.h>
#include <AzCore/IO/Path/Path.h>
#include <AzCore/PlatformDef.h>
#include <AzCore/Settings/SettingsRegistry.h>
#include <AzCore/std/any.h>
#include <AzCore/std/containers/vector.h>
#include <AzToolsFramework/UI/PropertyEditor/InstanceDataHierarchy.h>
AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option") // disable warnings spawned by QT
#include <QFileInfo>
@ -26,72 +23,20 @@ class QImage;
namespace AtomToolsFramework
{
using LoadImageAsyncCallback = AZStd::function<void(const QImage&)>;
void LoadImageAsync(const AZStd::string& path, LoadImageAsyncCallback callback);
QFileInfo GetSaveFileInfo(const QString& initialPath);
QFileInfo GetOpenFileInfo(const AZStd::vector<AZ::Data::AssetType>& assetTypes);
QFileInfo GetUniqueFileInfo(const QString& initialPath);
QFileInfo GetDuplicationFileInfo(const QString& initialPath);
bool LaunchTool(const QString& baseName, const QStringList& arguments);
//! Generate a file path that is relative to either the source asset root or the export path
//! @param exportPath absolute path of the file being saved
//! @param referencePath absolute path of a file that will be treated as an external reference
//! @param relativeToExportPath specifies if the path is relative to the source asset root or the export path
AZStd::string GetExteralReferencePath(
const AZStd::string& exportPath, const AZStd::string& referencePath, const bool relativeToExportPath = false);
//! Traverse up the instance data hierarchy to find a node containing the corresponding type
template<typename T>
const T* FindAncestorInstanceDataNodeByType(const AzToolsFramework::InstanceDataNode* pNode)
{
// Traverse up the hierarchy from the input node to search for an instance matching the specified type
for (const auto* currentNode = pNode; currentNode; currentNode = currentNode->GetParent())
{
const auto* context = currentNode->GetSerializeContext();
const auto* classData = currentNode->GetClassMetadata();
if (context && classData)
{
if (context->CanDowncast(classData->m_typeId, azrtti_typeid<T>(), classData->m_azRtti, nullptr))
{
return static_cast<const T*>(currentNode->FirstInstance());
}
}
}
return nullptr;
}
template<typename T>
T GetSettingsValue(AZStd::string_view path, const T& defaultValue = {})
T GetSettingOrDefault(AZStd::string_view path, const T& defaultValue)
{
T result;
auto settingsRegistry = AZ::SettingsRegistry::Get();
return (settingsRegistry && settingsRegistry->Get(result, path)) ? result : defaultValue;
}
template<typename T>
bool SetSettingsValue(AZStd::string_view path, const T& value)
{
auto settingsRegistry = AZ::SettingsRegistry::Get();
return settingsRegistry && settingsRegistry->Set(path, value);
}
template<typename T>
T GetSettingsObject(AZStd::string_view path, const T& defaultValue = {})
{
T result;
auto settingsRegistry = AZ::SettingsRegistry::Get();
return (settingsRegistry && settingsRegistry->GetObject<T>(result, path)) ? result : defaultValue;
}
template<typename T>
bool SetSettingsObject(AZStd::string_view path, const T& value)
{
auto settingsRegistry = AZ::SettingsRegistry::Get();
return settingsRegistry && settingsRegistry->SetObject<T>(path, value);
}
using LoadImageAsyncCallback = AZStd::function<void(const QImage&)>;
void LoadImageAsync(const AZStd::string& path, LoadImageAsyncCallback callback);
bool SaveSettingsToFile(const AZ::IO::FixedMaxPath& savePath, const AZStd::vector<AZStd::string>& filters);
QFileInfo GetSaveFileInfo(const QString& initialPath);
QFileInfo GetOpenFileInfo(const AZStd::vector<AZ::Data::AssetType>& assetTypes);
QFileInfo GetUniqueFileInfo(const QString& initialPath);
QFileInfo GetDuplicationFileInfo(const QString& initialPath);
bool LaunchTool(const QString& baseName, const QStringList& arguments);
} // namespace AtomToolsFramework

@ -10,7 +10,6 @@
#include <Atom/RPI.Public/ViewportContext.h>
#include <AtomToolsFramework/Viewport/ModularViewportCameraControllerRequestBus.h>
#include <AzCore/std/smart_ptr/shared_ptr.h>
#include <AzFramework/Viewport/CameraInput.h>
#include <AzFramework/Viewport/MultiViewportController.h>
@ -121,8 +120,6 @@ namespace AtomToolsFramework
void SetCameraPivotAttached(const AZ::Vector3& pivot) override;
void SetCameraPivotDetached(const AZ::Vector3& pivot) override;
void SetCameraOffset(const AZ::Vector3& offset) override;
bool AddCameras(const AZStd::vector<AZStd::shared_ptr<AzFramework::CameraInput>>& cameraInputs) override;
bool RemoveCameras(const AZStd::vector<AZStd::shared_ptr<AzFramework::CameraInput>>& cameraInputs) override;
private:
//! Combine the current camera transform with any potential roll from the tracked

@ -9,7 +9,6 @@
#pragma once
#include <AzCore/EBus/EBus.h>
#include <AzCore/std/smart_ptr/shared_ptr.h>
#include <AzFramework/Viewport/ViewportId.h>
namespace AZ
@ -17,11 +16,6 @@ namespace AZ
class Transform;
}
namespace AzFramework
{
class CameraInput;
}
namespace AtomToolsFramework
{
//! Provides an interface to control the modern viewport camera controller from the Editor.
@ -60,10 +54,6 @@ namespace AtomToolsFramework
//! @note The offset value is in the current space of the camera, not world space. Setting
//! a negative Z value will move the camera backwards from the pivot.
virtual void SetCameraOffset(const AZ::Vector3& offset) = 0;
//! Add one or more camera inputs (behaviors) to run for the current camera.
virtual bool AddCameras(const AZStd::vector<AZStd::shared_ptr<AzFramework::CameraInput>>& cameraInputs) = 0;
//! Remove one or more camera inputs (behaviors) to stop them running for the current camera.
virtual bool RemoveCameras(const AZStd::vector<AZStd::shared_ptr<AzFramework::CameraInput>>& cameraInputs) = 0;
protected:
~ModularViewportCameraControllerRequests() = default;

@ -29,7 +29,6 @@ namespace AtomToolsFramework
~AtomToolsMainWindow();
protected:
// AtomToolsMainWindowRequestBus::Handler overrides...
void ActivateWindow() override;
bool AddDockWidget(const AZStd::string& name, QWidget* widget, uint32_t area, uint32_t orientation) override;
void RemoveDockWidget(const AZStd::string& name) override;

@ -70,9 +70,9 @@ namespace AtomToolsFramework
m_styleManager->initialize(this, engineRootPath);
const int updateIntervalWhenActive =
aznumeric_cast<int>(GetSettingsValue<AZ::u64>("/O3DE/AtomToolsFramework/Application/UpdateIntervalWhenActive", 1));
aznumeric_cast<int>(GetSettingOrDefault<AZ::u64>("/O3DE/AtomToolsFramework/Application/UpdateIntervalWhenActive", 1));
const int updateIntervalWhenNotActive =
aznumeric_cast<int>(GetSettingsValue<AZ::u64>("/O3DE/AtomToolsFramework/Application/UpdateIntervalWhenNotActive", 64));
aznumeric_cast<int>(GetSettingOrDefault<AZ::u64>("/O3DE/AtomToolsFramework/Application/UpdateIntervalWhenNotActive", 64));
m_timer.setInterval(updateIntervalWhenActive);
connect(&m_timer, &QTimer::timeout, this, [this]()
@ -188,7 +188,7 @@ namespace AtomToolsFramework
Base::StartCommon(systemEntity);
const bool clearLogFile = GetSettingsValue("/O3DE/AtomToolsFramework/Application/ClearLogOnStart", false);
const bool clearLogFile = GetSettingOrDefault("/O3DE/AtomToolsFramework/Application/ClearLogOnStart", false);
m_traceLogger.OpenLogFile(m_targetName + ".log", clearLogFile);
ConnectToAssetProcessor();
@ -197,7 +197,7 @@ namespace AtomToolsFramework
AzToolsFramework::AssetBrowser::AssetDatabaseLocationNotificationBus::Broadcast(
&AzToolsFramework::AssetBrowser::AssetDatabaseLocationNotifications::OnDatabaseInitialized);
const bool enableSourceControl = GetSettingsValue("/O3DE/AtomToolsFramework/Application/EnableSourceControl", true);
const bool enableSourceControl = GetSettingOrDefault("/O3DE/AtomToolsFramework/Application/EnableSourceControl", true);
AzToolsFramework::SourceControlConnectionRequestBus::Broadcast(
&AzToolsFramework::SourceControlConnectionRequests::EnableSourceControl, enableSourceControl);
@ -238,12 +238,6 @@ namespace AtomToolsFramework
void AtomToolsApplication::Destroy()
{
m_styleManager.reset();
// Save application settings to settings registry file
AZ::IO::FixedMaxPath savePath = AZ::Utils::GetProjectPath();
savePath /= AZStd::string::format("user/Registry/%s.setreg", m_targetName.c_str());
SaveSettingsToFile(savePath, { "/O3DE/AtomToolsFramework", AZStd::string::format("/O3DE/Atom/%s", m_targetName.c_str()) });
UnloadSettings();
AzToolsFramework::EditorPythonConsoleNotificationBus::Handler::BusDisconnect();

@ -106,9 +106,9 @@ namespace AtomToolsFramework
const AZStd::vector<AssetBrowserEntry*> entries = m_ui->m_assetBrowserTreeViewWidget->GetSelectedAssets();
const bool promptToOpenMultipleFiles =
GetSettingsValue<bool>("/O3DE/AtomToolsFramework/AssetBrowser/PromptToOpenMultipleFiles", true);
GetSettingOrDefault<bool>("/O3DE/AtomToolsFramework/AssetBrowser/PromptToOpenMultipleFiles", true);
const AZ::u64 promptToOpenMultipleFilesThreshold =
GetSettingsValue<AZ::u64>("/O3DE/AtomToolsFramework/AssetBrowser/PromptToOpenMultipleFilesThreshold", 10);
GetSettingOrDefault<AZ::u64>("/O3DE/AtomToolsFramework/AssetBrowser/PromptToOpenMultipleFilesThreshold", 10);
if (promptToOpenMultipleFiles && promptToOpenMultipleFilesThreshold <= entries.size())
{

@ -71,11 +71,11 @@ namespace AtomToolsFramework
QListWidgetItem* AssetGridDialog::CreateListItem(const SelectableAsset& selectableAsset)
{
const int itemBorder = aznumeric_cast<int>(
AtomToolsFramework::GetSettingsValue<AZ::u64>("/O3DE/AtomToolsFramework/AssetGridDialog/ItemBorder", 4));
AtomToolsFramework::GetSettingOrDefault<AZ::u64>("/O3DE/Atom/AtomToolsFramework/AssetGridDialog/ItemBorder", 4));
const int itemSpacing = aznumeric_cast<int>(
AtomToolsFramework::GetSettingsValue<AZ::u64>("/O3DE/AtomToolsFramework/AssetGridDialog/ItemSpacing", 10));
AtomToolsFramework::GetSettingOrDefault<AZ::u64>("/O3DE/Atom/AtomToolsFramework/AssetGridDialog/ItemSpacing", 10));
const int headerHeight = aznumeric_cast<int>(
AtomToolsFramework::GetSettingsValue<AZ::u64>("/O3DE/AtomToolsFramework/AssetGridDialog/HeaderHeight", 15));
AtomToolsFramework::GetSettingOrDefault<AZ::u64>("/O3DE/Atom/AtomToolsFramework/AssetGridDialog/HeaderHeight", 15));
const QSize gridSize = m_ui->m_assetList->gridSize();
m_ui->m_assetList->setGridSize(QSize(

@ -13,7 +13,6 @@
#include <AtomToolsFramework/Document/AtomToolsDocument.h>
#include <AtomToolsFramework/Document/AtomToolsDocumentSystem.h>
#include <AtomToolsFramework/DynamicProperty/DynamicPropertyGroup.h>
#include <AtomToolsFramework/Inspector/InspectorWidget.h>
#include <AtomToolsFrameworkSystemComponent.h>
namespace AtomToolsFramework
@ -24,7 +23,6 @@ namespace AtomToolsFramework
DynamicPropertyGroup::Reflect(context);
AtomToolsDocument::Reflect(context);
AtomToolsDocumentSystem::Reflect(context);
InspectorWidget::Reflect(context);
if (auto serialize = azrtti_cast<AZ::SerializeContext*>(context))
{

@ -1,120 +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
*
*/
#include <AtomToolsFramework/Document/AtomToolsDocumentInspector.h>
#include <AtomToolsFramework/Document/AtomToolsDocumentRequestBus.h>
#include <AtomToolsFramework/Inspector/InspectorPropertyGroupWidget.h>
namespace AtomToolsFramework
{
AtomToolsDocumentInspector::AtomToolsDocumentInspector(const AZ::Crc32& toolId, QWidget* parent)
: InspectorWidget(parent)
, m_toolId(toolId)
{
AtomToolsDocumentNotificationBus::Handler::BusConnect(m_toolId);
}
AtomToolsDocumentInspector::~AtomToolsDocumentInspector()
{
AtomToolsDocumentNotificationBus::Handler::BusDisconnect();
}
void AtomToolsDocumentInspector::SetDocumentId(const AZ::Uuid& documentId)
{
AddGroupsBegin();
m_documentId = documentId;
AtomToolsDocumentRequestBus::Event(
m_documentId,
[&](AtomToolsDocumentRequests* documentRequests)
{
if (documentRequests->IsOpen())
{
// Create a unique settings prefix string per document using a CRC of the document path
const AZStd::string groupSettingsPrefix = m_documentSettingsPrefix +
AZStd::string::format("/%08x/GroupSettings", aznumeric_cast<AZ::u32>(AZ::Crc32(documentRequests->GetAbsolutePath())));
SetGroupSettingsPrefix(groupSettingsPrefix);
// This will automatically expose all document contents to an inspector with a collapsible group per object.
// In the case of the material editor, this will be one inspector group per property group.
for (auto& objectInfo : documentRequests->GetObjectInfo())
{
// Passing in same main and comparison instance to enable custom value comparison
const AZ::Crc32 groupSaveStateKey(
AZStd::string::format("%s/%s", groupSettingsPrefix.c_str(), objectInfo.m_name.c_str()));
auto propertyGroupWidget = new InspectorPropertyGroupWidget(
objectInfo.m_objectPtr, objectInfo.m_objectPtr, objectInfo.m_objectType, this, this, groupSaveStateKey, {},
m_nodeIndicatorFunction, 0);
AddGroup(objectInfo.m_name, objectInfo.m_displayName, objectInfo.m_description, propertyGroupWidget);
SetGroupVisible(objectInfo.m_name, objectInfo.m_visible);
}
}
InspectorRequestBus::Handler::BusConnect(m_documentId);
});
AddGroupsEnd();
}
void AtomToolsDocumentInspector::SetDocumentSettingsPrefix(const AZStd::string& prefix)
{
m_documentSettingsPrefix = prefix;
}
void AtomToolsDocumentInspector::SetIndicatorFunction(const NodeIndicatorFunction& indicatorFunction)
{
m_nodeIndicatorFunction = indicatorFunction;
}
void AtomToolsDocumentInspector::Reset()
{
m_documentId = AZ::Uuid::CreateNull();
m_editInProgress = false;
InspectorWidget::Reset();
}
void AtomToolsDocumentInspector::OnDocumentObjectInfoChanged(
[[maybe_unused]] const AZ::Uuid& documentId, const DocumentObjectInfo& objectInfo, bool rebuilt)
{
if (m_documentId == documentId)
{
SetGroupVisible(objectInfo.m_name, objectInfo.m_visible);
if (rebuilt)
{
RebuildGroup(objectInfo.m_name);
}
else
{
RefreshGroup(objectInfo.m_name);
}
}
}
void AtomToolsDocumentInspector::BeforePropertyModified([[maybe_unused]] AzToolsFramework::InstanceDataNode* pNode)
{
if (!m_editInProgress)
{
m_editInProgress = true;
AtomToolsDocumentRequestBus::Event(m_documentId, &AtomToolsDocumentRequestBus::Events::BeginEdit);
}
}
void AtomToolsDocumentInspector::SetPropertyEditingComplete([[maybe_unused]] AzToolsFramework::InstanceDataNode* pNode)
{
if (m_editInProgress)
{
m_editInProgress = false;
AtomToolsDocumentRequestBus::Event(m_documentId, &AtomToolsDocumentRequestBus::Events::EndEdit);
}
}
} // namespace AtomToolsFramework
//#include <AtomToolsFramework/Document/moc_AtomToolsDocumentInspector.cpp>

@ -500,4 +500,4 @@ namespace AtomToolsFramework
}
} // namespace AtomToolsFramework
//#include <AtomToolsFramework/Document/moc_AtomToolsDocumentMainWindow.cpp>
//#include <Document/moc_AtomToolsDocumentMainWindow.cpp>

@ -368,7 +368,7 @@ namespace AtomToolsFramework
void AtomToolsDocumentSystem::ReopenDocuments()
{
const bool enableHotReload = GetSettingsValue<bool>("/O3DE/AtomToolsFramework/AtomToolsDocumentSystem/EnableHotReload", true);
const bool enableHotReload = GetSettingOrDefault<bool>("/O3DE/AtomToolsFramework/AtomToolsDocumentSystem/EnableHotReload", true);
if (!enableHotReload)
{
m_documentIdsWithDependencyChanges.clear();
@ -377,7 +377,7 @@ namespace AtomToolsFramework
}
const bool enableHotReloadPrompts =
GetSettingsValue<bool>("/O3DE/AtomToolsFramework/AtomToolsDocumentSystem/EnableHotReloadPrompts", true);
GetSettingOrDefault<bool>("/O3DE/AtomToolsFramework/AtomToolsDocumentSystem/EnableHotReloadPrompts", true);
for (const AZ::Uuid& documentId : m_documentIdsWithExternalChanges)
{

@ -6,69 +6,27 @@
*
*/
#include <AtomToolsFramework/Inspector/InspectorGroupHeaderWidget.h>
#include <AtomToolsFramework/Inspector/InspectorGroupWidget.h>
#include <AtomToolsFramework/Inspector/InspectorWidget.h>
#include <AtomToolsFramework/Util/Util.h>
#include <AzCore/RTTI/BehaviorContext.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <Inspector/ui_InspectorWidget.h>
#include <QMenu>
#include <QScrollArea>
#include <QScrollBar>
#include <QSizePolicy>
#include <AtomToolsFramework/Inspector/InspectorGroupHeaderWidget.h>
#include <AtomToolsFramework/Inspector/InspectorGroupWidget.h>
#include <AtomToolsFramework/Inspector/InspectorWidget.h>
#include <Inspector/ui_InspectorWidget.h>
namespace AtomToolsFramework
{
void InspectorWidget::Reflect(AZ::ReflectContext* context)
{
if (auto serialize = azrtti_cast<AZ::SerializeContext*>(context))
{
serialize->RegisterGenericType<AZStd::unordered_set<AZ::u32>>();
serialize->Class<InspectorWidget>()
->Version(0);
}
if (auto behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
{
behaviorContext->EBus<InspectorRequestBus>("InspectorRequestBus")
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
->Attribute(AZ::Script::Attributes::Category, "Editor")
->Attribute(AZ::Script::Attributes::Module, "atomtools")
->Event("ClearHeading", &InspectorRequestBus::Events::ClearHeading)
->Event("Reset", &InspectorRequestBus::Events::Reset)
->Event("AddGroupsBegin", &InspectorRequestBus::Events::AddGroupsBegin)
->Event("AddGroupsEnd", &InspectorRequestBus::Events::AddGroupsEnd)
->Event("SetGroupVisible", &InspectorRequestBus::Events::SetGroupVisible)
->Event("IsGroupVisible", &InspectorRequestBus::Events::IsGroupVisible)
->Event("IsGroupHidden", &InspectorRequestBus::Events::IsGroupHidden)
->Event("RefreshGroup", &InspectorRequestBus::Events::RefreshGroup)
->Event("RebuildGroup", &InspectorRequestBus::Events::RebuildGroup)
->Event("RefreshAll", &InspectorRequestBus::Events::RefreshAll)
->Event("RebuildAll", &InspectorRequestBus::Events::RebuildAll)
->Event("ExpandGroup", &InspectorRequestBus::Events::ExpandGroup)
->Event("CollapseGroup", &InspectorRequestBus::Events::CollapseGroup)
->Event("IsGroupExpanded", &InspectorRequestBus::Events::IsGroupExpanded)
->Event("ExpandAll", &InspectorRequestBus::Events::ExpandAll)
->Event("CollapseAll", &InspectorRequestBus::Events::CollapseAll)
;
}
}
InspectorWidget::InspectorWidget(QWidget* parent)
: QWidget(parent)
, m_ui(new Ui::InspectorWidget)
{
m_ui->setupUi(this);
SetGroupSettingsPrefix("/O3DE/AtomToolsFramework/InspectorWidget");
}
InspectorWidget::~InspectorWidget()
{
SetSettingsObject(m_collapsedGroupSettingName, m_collapsedGroups);
InspectorRequestBus::Handler::BusDisconnect();
}
void InspectorWidget::AddHeading(QWidget* headingWidget)
@ -94,7 +52,6 @@ namespace AtomToolsFramework
delete child;
}
m_groups.clear();
InspectorRequestBus::Handler::BusDisconnect();
}
void InspectorWidget::AddGroupsBegin()
@ -245,31 +202,20 @@ namespace AtomToolsFramework
}
}
void InspectorWidget::SetGroupSettingsPrefix(const AZStd::string& prefix)
{
if (!m_collapsedGroupSettingName.empty())
{
SetSettingsObject(m_collapsedGroupSettingName, m_collapsedGroups);
}
m_collapsedGroupSettingName = prefix + "/CollapsedGroups";
m_collapsedGroups = GetSettingsObject<AZStd::unordered_set<AZ::u32>>(m_collapsedGroupSettingName);
}
bool InspectorWidget::ShouldGroupAutoExpanded(const AZStd::string& groupName) const
{
auto stateItr = m_collapsedGroups.find(AZ::Crc32(groupName));
return stateItr == m_collapsedGroups.end();
AZ_UNUSED(groupName);
return true;
}
void InspectorWidget::OnGroupExpanded(const AZStd::string& groupName)
{
m_collapsedGroups.erase(AZ::Crc32(groupName));
AZ_UNUSED(groupName);
}
void InspectorWidget::OnGroupCollapsed(const AZStd::string& groupName)
{
m_collapsedGroups.insert(AZ::Crc32(groupName));
AZ_UNUSED(groupName);
}
void InspectorWidget::OnHeaderClicked(const AZStd::string& groupName, QMouseEvent* event)

@ -6,18 +6,21 @@
*
*/
#include <AtomToolsFramework/DynamicProperty/DynamicProperty.h>
#include <AtomToolsFramework/Util/MaterialPropertyUtil.h>
#include <Atom/RPI.Edit/Common/AssetUtils.h>
#include <Atom/RPI.Reflect/Image/ImageAsset.h>
#include <Atom/RPI.Reflect/Image/StreamingImageAsset.h>
#include <Atom/RPI.Reflect/Material/MaterialAsset.h>
#include <Atom/RPI.Reflect/Material/MaterialTypeAsset.h>
#include <AtomToolsFramework/DynamicProperty/DynamicProperty.h>
#include <AtomToolsFramework/Util/MaterialPropertyUtil.h>
#include <AtomToolsFramework/Util/Util.h>
#include <AzCore/Math/Color.h>
#include <AzCore/Math/Vector2.h>
#include <AzCore/Math/Vector3.h>
#include <AzCore/Math/Vector4.h>
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
#include <AzToolsFramework/UI/PropertyEditor/InstanceDataHierarchy.h>
namespace AtomToolsFramework
{
@ -220,4 +223,51 @@ namespace AtomToolsFramework
return true;
}
AZStd::string GetExteralReferencePath(
const AZStd::string& exportPath, const AZStd::string& referencePath, const bool relativeToExportPath)
{
if (referencePath.empty())
{
return {};
}
if (!relativeToExportPath)
{
AZStd::string watchFolder;
AZ::Data::AssetInfo assetInfo;
bool sourceInfoFound = false;
AzToolsFramework::AssetSystemRequestBus::BroadcastResult(
sourceInfoFound, &AzToolsFramework::AssetSystemRequestBus::Events::GetSourceInfoBySourcePath, referencePath.c_str(),
assetInfo, watchFolder);
if (sourceInfoFound)
{
return assetInfo.m_relativePath;
}
}
AZ::IO::BasicPath<AZStd::string> exportFolder(exportPath);
exportFolder.RemoveFilename();
return AZ::IO::PathView(referencePath).LexicallyRelative(exportFolder).StringAsPosix();
}
const AtomToolsFramework::DynamicProperty* FindDynamicPropertyForInstanceDataNode(const AzToolsFramework::InstanceDataNode* pNode)
{
// Traverse up the hierarchy from the input node to search for an instance corresponding to material inspector property
for (const AzToolsFramework::InstanceDataNode* currentNode = pNode; currentNode; currentNode = currentNode->GetParent())
{
const AZ::SerializeContext* context = currentNode->GetSerializeContext();
const AZ::SerializeContext::ClassData* classData = currentNode->GetClassMetadata();
if (context && classData)
{
if (context->CanDowncast(
classData->m_typeId, azrtti_typeid<AtomToolsFramework::DynamicProperty>(), classData->m_azRtti, nullptr))
{
return static_cast<const AtomToolsFramework::DynamicProperty*>(currentNode->FirstInstance());
}
}
}
return nullptr;
}
} // namespace AtomToolsFramework

@ -8,18 +8,13 @@
#include <Atom/ImageProcessing/ImageObject.h>
#include <Atom/ImageProcessing/ImageProcessingBus.h>
#include <Atom/RPI.Edit/Common/AssetUtils.h>
#include <AtomToolsFramework/Util/Util.h>
#include <AzCore/IO/ByteContainerStream.h>
#include <AzCore/IO/SystemFile.h>
#include <AzCore/Jobs/JobFunction.h>
#include <AzCore/Settings/SettingsRegistry.h>
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
#include <AzCore/StringFunc/StringFunc.h>
#include <AzCore/Utils/Utils.h>
#include <AzFramework/API/ApplicationAPI.h>
#include <AzQtComponents/Components/Widgets/FileDialog.h>
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
#include <AzToolsFramework/AssetBrowser/AssetBrowserBus.h>
#include <AzToolsFramework/AssetBrowser/AssetBrowserEntry.h>
#include <AzToolsFramework/AssetBrowser/AssetSelectionModel.h>
@ -183,74 +178,4 @@ namespace AtomToolsFramework
return QProcess::startDetached(launchPath.c_str(), arguments, engineRoot.c_str());
}
AZStd::string GetExteralReferencePath(
const AZStd::string& exportPath, const AZStd::string& referencePath, const bool relativeToExportPath)
{
if (referencePath.empty())
{
return {};
}
if (!relativeToExportPath)
{
AZStd::string watchFolder;
AZ::Data::AssetInfo assetInfo;
bool sourceInfoFound = false;
AzToolsFramework::AssetSystemRequestBus::BroadcastResult(
sourceInfoFound, &AzToolsFramework::AssetSystemRequestBus::Events::GetSourceInfoBySourcePath, referencePath.c_str(),
assetInfo, watchFolder);
if (sourceInfoFound)
{
return assetInfo.m_relativePath;
}
}
AZ::IO::BasicPath<AZStd::string> exportFolder(exportPath);
exportFolder.RemoveFilename();
return AZ::IO::PathView(referencePath).LexicallyRelative(exportFolder).StringAsPosix();
}
bool SaveSettingsToFile(const AZ::IO::FixedMaxPath& savePath, const AZStd::vector<AZStd::string>& filters)
{
auto registry = AZ::SettingsRegistry::Get();
if (registry == nullptr)
{
AZ_Warning("AtomToolsFramework", false, "Unable to access global settings registry.");
return false;
}
AZ::SettingsRegistryMergeUtils::DumperSettings dumperSettings;
dumperSettings.m_prettifyOutput = true;
dumperSettings.m_includeFilter = [filters](AZStd::string_view path)
{
for (const auto& filter : filters)
{
if (filter.starts_with(path.substr(0, filter.size())))
{
return true;
}
}
return false;
};
AZStd::string stringBuffer;
AZ::IO::ByteContainerStream stringStream(&stringBuffer);
if (!AZ::SettingsRegistryMergeUtils::DumpSettingsRegistryToStream(*registry, "", stringStream, dumperSettings))
{
AZ_Warning("AtomToolsFramework", false, R"(Unable to save changes to the registry file at "%s"\n)", savePath.c_str());
return false;
}
bool saved = false;
constexpr auto configurationMode =
AZ::IO::SystemFile::SF_OPEN_CREATE | AZ::IO::SystemFile::SF_OPEN_CREATE_PATH | AZ::IO::SystemFile::SF_OPEN_WRITE_ONLY;
if (AZ::IO::SystemFile outputFile; outputFile.Open(savePath.c_str(), configurationMode))
{
saved = outputFile.Write(stringBuffer.data(), stringBuffer.size()) == stringBuffer.size();
}
AZ_Warning("AtomToolsFramework", saved, R"(Unable to save registry file to path "%s"\n)", savePath.c_str());
return saved;
}
} // namespace AtomToolsFramework
}

@ -294,17 +294,6 @@ namespace AtomToolsFramework
m_targetCamera.m_offset = offset;
}
bool ModularViewportCameraControllerInstance::AddCameras(const AZStd::vector<AZStd::shared_ptr<AzFramework::CameraInput>>& cameraInputs)
{
return m_cameraSystem.m_cameras.AddCameras(cameraInputs);
}
bool ModularViewportCameraControllerInstance::RemoveCameras(
const AZStd::vector<AZStd::shared_ptr<AzFramework::CameraInput>>& cameraInputs)
{
return m_cameraSystem.m_cameras.RemoveCameras(cameraInputs);
}
bool ModularViewportCameraControllerInstance::IsInterpolating() const
{
return m_cameraMode == CameraMode::Animation;

@ -8,7 +8,7 @@
#include <AzTest/AzTest.h>
#include <Atom/Utils/TestUtils/AssetSystemStub.h>
#include <AtomToolsFramework/Util/Util.h>
#include <AtomToolsFramework/Util/MaterialPropertyUtil.h>
namespace UnitTest
{

@ -15,7 +15,6 @@ set(FILES
Include/AtomToolsFramework/Communication/LocalSocket.h
Include/AtomToolsFramework/Debug/TraceRecorder.h
Include/AtomToolsFramework/Document/AtomToolsDocument.h
Include/AtomToolsFramework/Document/AtomToolsDocumentInspector.h
Include/AtomToolsFramework/Document/AtomToolsDocumentSystem.h
Include/AtomToolsFramework/Document/AtomToolsDocumentApplication.h
Include/AtomToolsFramework/Document/AtomToolsDocumentMainWindow.h
@ -52,7 +51,6 @@ set(FILES
Source/Communication/LocalSocket.cpp
Source/Debug/TraceRecorder.cpp
Source/Document/AtomToolsDocument.cpp
Source/Document/AtomToolsDocumentInspector.cpp
Source/Document/AtomToolsDocumentApplication.cpp
Source/Document/AtomToolsDocumentMainWindow.cpp
Source/Document/AtomToolsDocumentSystem.cpp

@ -18,7 +18,6 @@
#include <AtomCore/Instance/Instance.h>
#include <AtomToolsFramework/Document/AtomToolsDocumentNotificationBus.h>
#include <AtomToolsFramework/Util/MaterialPropertyUtil.h>
#include <AtomToolsFramework/Util/Util.h>
#include <AzCore/RTTI/BehaviorContext.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/Serialization/SerializeContext.h>

@ -64,7 +64,7 @@ namespace MaterialEditor
m_ui->m_materialTypeComboBox->model()->sort(0, Qt::AscendingOrder);
const AZStd::string defaultMaterialType = AtomToolsFramework::GetSettingsValue<AZStd::string>(
const AZStd::string defaultMaterialType = AtomToolsFramework::GetSettingOrDefault<AZStd::string>(
"/O3DE/Atom/MaterialEditor/CreateMaterialDialog/DefaultMaterialType", "StandardPBR");
const int index = m_ui->m_materialTypeComboBox->findText(defaultMaterialType.c_str());

@ -9,8 +9,6 @@
#include <Atom/RPI.Edit/Material/MaterialSourceData.h>
#include <Atom/RPI.Edit/Material/MaterialTypeSourceData.h>
#include <AtomToolsFramework/Document/AtomToolsDocumentSystemRequestBus.h>
#include <AtomToolsFramework/DynamicProperty/DynamicProperty.h>
#include <AtomToolsFramework/Util/MaterialPropertyUtil.h>
#include <AtomToolsFramework/Util/Util.h>
#include <AzQtComponents/Components/StyleManager.h>
#include <AzQtComponents/Components/WindowDecorationWrapper.h>
@ -19,6 +17,7 @@
#include <Window/CreateMaterialDialog/CreateMaterialDialog.h>
#include <Window/MaterialEditorWindow.h>
#include <Window/MaterialEditorWindowSettings.h>
#include <Window/MaterialInspector/MaterialInspector.h>
#include <Window/SettingsDialog/SettingsDialog.h>
#include <Window/ViewportSettingsInspector/ViewportSettingsInspector.h>
@ -79,20 +78,7 @@ namespace MaterialEditor
QDesktopServices::openUrl(QUrl::fromLocalFile(absolutePath.c_str()));
});
m_materialInspector = new AtomToolsFramework::AtomToolsDocumentInspector(m_toolId, this);
m_materialInspector->SetDocumentSettingsPrefix("/O3DE/Atom/MaterialEditor/MaterialInspector");
m_materialInspector->SetIndicatorFunction(
[](const AzToolsFramework::InstanceDataNode* node)
{
const auto property = AtomToolsFramework::FindAncestorInstanceDataNodeByType<AtomToolsFramework::DynamicProperty>(node);
if (property && !AtomToolsFramework::ArePropertyValuesEqual(property->GetValue(), property->GetConfig().m_parentValue))
{
return ":/Icons/changed_property.svg";
}
return ":/Icons/blank.png";
});
AddDockWidget("Inspector", m_materialInspector, Qt::RightDockWidgetArea, Qt::Vertical);
AddDockWidget("Inspector", new MaterialInspector(m_toolId), Qt::RightDockWidgetArea, Qt::Vertical);
AddDockWidget("Viewport Settings", new ViewportSettingsInspector, Qt::LeftDockWidgetArea, Qt::Vertical);
SetDockWidgetVisible("Viewport Settings", false);
@ -112,12 +98,6 @@ namespace MaterialEditor
OnDocumentOpened(AZ::Uuid::CreateNull());
}
void MaterialEditorWindow::OnDocumentOpened(const AZ::Uuid& documentId)
{
Base::OnDocumentOpened(documentId);
m_materialInspector->SetDocumentId(documentId);
}
void MaterialEditorWindow::ResizeViewportRenderTarget(uint32_t width, uint32_t height)
{
QSize requestedViewportSize = QSize(width, height) / devicePixelRatioF();

@ -9,7 +9,6 @@
#pragma once
#if !defined(Q_MOC_RUN)
#include <AtomToolsFramework/Document/AtomToolsDocumentInspector.h>
#include <AtomToolsFramework/Document/AtomToolsDocumentMainWindow.h>
AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option") // disable warnings spawned by QT
@ -36,15 +35,10 @@ namespace MaterialEditor
MaterialEditorWindow(const AZ::Crc32& toolId, QWidget* parent = 0);
protected:
// AtomToolsFramework::AtomToolsMainWindowRequestBus::Handler overrides...
void ResizeViewportRenderTarget(uint32_t width, uint32_t height) override;
void LockViewportRenderTargetSize(uint32_t width, uint32_t height) override;
void UnlockViewportRenderTargetSize() override;
// AtomToolsFramework::AtomToolsDocumentNotificationBus::Handler overrides...
void OnDocumentOpened(const AZ::Uuid& documentId) override;
// AtomToolsFramework::AtomToolsDocumentMainWindow overrides...
bool GetCreateDocumentParams(AZStd::string& openPath, AZStd::string& savePath) override;
bool GetOpenDocumentParams(AZStd::string& openPath) override;
void OpenSettings() override;
@ -53,7 +47,6 @@ namespace MaterialEditor
void closeEvent(QCloseEvent* closeEvent) override;
AtomToolsFramework::AtomToolsDocumentInspector* m_materialInspector = {};
MaterialViewportWidget* m_materialViewport = {};
MaterialEditorToolBar* m_toolBar = {};
};

@ -19,6 +19,7 @@ namespace MaterialEditor
serializeContext->Class<MaterialEditorWindowSettings, AZ::UserSettings>()
->Version(1)
->Field("mainWindowState", &MaterialEditorWindowSettings::m_mainWindowState)
->Field("inspectorCollapsedGroups", &MaterialEditorWindowSettings::m_inspectorCollapsedGroups)
;
if (auto editContext = serializeContext->GetEditContext())

@ -27,5 +27,6 @@ namespace MaterialEditor
static void Reflect(AZ::ReflectContext* context);
AZStd::vector<char> m_mainWindowState;
AZStd::unordered_set<AZ::u32> m_inspectorCollapsedGroups;
};
} // namespace MaterialEditor

@ -0,0 +1,159 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <Atom/RPI.Edit/Common/AssetUtils.h>
#include <AtomToolsFramework/Document/AtomToolsDocumentRequestBus.h>
#include <AtomToolsFramework/DynamicProperty/DynamicPropertyGroup.h>
#include <AtomToolsFramework/Inspector/InspectorPropertyGroupWidget.h>
#include <AtomToolsFramework/Util/MaterialPropertyUtil.h>
#include <Window/MaterialInspector/MaterialInspector.h>
namespace MaterialEditor
{
MaterialInspector::MaterialInspector(const AZ::Crc32& toolId, QWidget* parent)
: AtomToolsFramework::InspectorWidget(parent)
, m_toolId(toolId)
{
m_windowSettings = AZ::UserSettings::CreateFind<MaterialEditorWindowSettings>(
AZ::Crc32("MaterialEditorWindowSettings"), AZ::UserSettings::CT_GLOBAL);
AtomToolsFramework::AtomToolsDocumentNotificationBus::Handler::BusConnect(m_toolId);
}
MaterialInspector::~MaterialInspector()
{
AtomToolsFramework::AtomToolsDocumentNotificationBus::Handler::BusDisconnect();
AtomToolsFramework::InspectorRequestBus::Handler::BusDisconnect();
}
void MaterialInspector::Reset()
{
m_documentPath.clear();
m_documentId = AZ::Uuid::CreateNull();
m_activeProperty = {};
AtomToolsFramework::InspectorRequestBus::Handler::BusDisconnect();
AtomToolsFramework::InspectorWidget::Reset();
}
bool MaterialInspector::ShouldGroupAutoExpanded(const AZStd::string& groupName) const
{
auto stateItr = m_windowSettings->m_inspectorCollapsedGroups.find(GetGroupSaveStateKey(groupName));
return stateItr == m_windowSettings->m_inspectorCollapsedGroups.end();
}
void MaterialInspector::OnGroupExpanded(const AZStd::string& groupName)
{
m_windowSettings->m_inspectorCollapsedGroups.erase(GetGroupSaveStateKey(groupName));
}
void MaterialInspector::OnGroupCollapsed(const AZStd::string& groupName)
{
m_windowSettings->m_inspectorCollapsedGroups.insert(GetGroupSaveStateKey(groupName));
}
void MaterialInspector::OnDocumentOpened(const AZ::Uuid& documentId)
{
AddGroupsBegin();
m_documentId = documentId;
bool isOpen = false;
AtomToolsFramework::AtomToolsDocumentRequestBus::EventResult(
isOpen, m_documentId, &AtomToolsFramework::AtomToolsDocumentRequestBus::Events::IsOpen);
AtomToolsFramework::AtomToolsDocumentRequestBus::EventResult(
m_documentPath, m_documentId, &AtomToolsFramework::AtomToolsDocumentRequestBus::Events::GetAbsolutePath);
if (!m_documentId.IsNull() && isOpen)
{
// This will automatically expose all document contents to an inspector with a collapsible group per object. In the case of the
// material editor, this will be one inspector group per property group.
AZStd::vector<AtomToolsFramework::DocumentObjectInfo> objects;
AtomToolsFramework::AtomToolsDocumentRequestBus::EventResult(
objects, m_documentId, &AtomToolsFramework::AtomToolsDocumentRequestBus::Events::GetObjectInfo);
for (auto& objectInfo : objects)
{
// Passing in same main and comparison instance to enable custom value comparison for highlighting modified properties
auto propertyGroupWidget = new AtomToolsFramework::InspectorPropertyGroupWidget(
objectInfo.m_objectPtr, objectInfo.m_objectPtr, objectInfo.m_objectType, this, this,
GetGroupSaveStateKey(objectInfo.m_name), {},
[this](const auto node) { return GetInstanceNodePropertyIndicator(node); }, 0);
AddGroup(objectInfo.m_name, objectInfo.m_displayName, objectInfo.m_description, propertyGroupWidget);
SetGroupVisible(objectInfo.m_name, objectInfo.m_visible);
}
AtomToolsFramework::InspectorRequestBus::Handler::BusConnect(m_documentId);
}
AddGroupsEnd();
}
AZ::Crc32 MaterialInspector::GetGroupSaveStateKey(const AZStd::string& groupName) const
{
return AZ::Crc32(AZStd::string::format("MaterialInspector::PropertyGroup::%s::%s", m_documentPath.c_str(), groupName.c_str()));
}
bool MaterialInspector::IsInstanceNodePropertyModifed(const AzToolsFramework::InstanceDataNode* node) const
{
const AtomToolsFramework::DynamicProperty* property = AtomToolsFramework::FindDynamicPropertyForInstanceDataNode(node);
return property && !AtomToolsFramework::ArePropertyValuesEqual(property->GetValue(), property->GetConfig().m_parentValue);
}
const char* MaterialInspector::GetInstanceNodePropertyIndicator(const AzToolsFramework::InstanceDataNode* node) const
{
if (IsInstanceNodePropertyModifed(node))
{
return ":/Icons/changed_property.svg";
}
return ":/Icons/blank.png";
}
void MaterialInspector::OnDocumentObjectInfoChanged(
[[maybe_unused]] const AZ::Uuid& documentId, const AtomToolsFramework::DocumentObjectInfo& objectInfo, bool rebuilt)
{
SetGroupVisible(objectInfo.m_name, objectInfo.m_visible);
if (rebuilt)
{
RebuildGroup(objectInfo.m_name);
}
else
{
RefreshGroup(objectInfo.m_name);
}
}
void MaterialInspector::BeforePropertyModified(AzToolsFramework::InstanceDataNode* pNode)
{
// This function is called before every single property change whether it's a button click or dragging a slider. We only want to
// begin tracking undo state for the first change in the sequence, when the user begins to drag the slider.
const AtomToolsFramework::DynamicProperty* property = AtomToolsFramework::FindDynamicPropertyForInstanceDataNode(pNode);
if (!m_activeProperty && property)
{
m_activeProperty = property;
AtomToolsFramework::AtomToolsDocumentRequestBus::Event(
m_documentId, &AtomToolsFramework::AtomToolsDocumentRequestBus::Events::BeginEdit);
}
}
void MaterialInspector::SetPropertyEditingComplete(AzToolsFramework::InstanceDataNode* pNode)
{
// If tracking has started and editing has completed then we can stop tracking undue state for this sequence of changes.
const AtomToolsFramework::DynamicProperty* property = AtomToolsFramework::FindDynamicPropertyForInstanceDataNode(pNode);
if (m_activeProperty && m_activeProperty == property)
{
AtomToolsFramework::AtomToolsDocumentRequestBus::Event(
m_documentId, &AtomToolsFramework::AtomToolsDocumentRequestBus::Events::EndEdit);
m_activeProperty = {};
}
}
} // namespace MaterialEditor
#include <Window/MaterialInspector/moc_MaterialInspector.cpp>

@ -0,0 +1,71 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#if !defined(Q_MOC_RUN)
#include <AtomToolsFramework/Document/AtomToolsDocumentNotificationBus.h>
#include <AtomToolsFramework/DynamicProperty/DynamicPropertyGroup.h>
#include <AtomToolsFramework/Inspector/InspectorWidget.h>
#include <AzCore/std/containers/unordered_map.h>
#include <AzToolsFramework/UI/PropertyEditor/PropertyEditorAPI_Internals.h>
#include <Window/MaterialEditorWindowSettings.h>
#endif
namespace MaterialEditor
{
//! Provides controls for viewing and editing document settings.
class MaterialInspector
: public AtomToolsFramework::InspectorWidget
, public AtomToolsFramework::AtomToolsDocumentNotificationBus::Handler
, public AzToolsFramework::IPropertyEditorNotify
{
Q_OBJECT
public:
AZ_CLASS_ALLOCATOR(MaterialInspector, AZ::SystemAllocator, 0);
MaterialInspector(const AZ::Crc32& toolId, QWidget* parent = nullptr);
~MaterialInspector() override;
// AtomToolsFramework::InspectorRequestBus::Handler overrides...
void Reset() override;
protected:
bool ShouldGroupAutoExpanded(const AZStd::string& groupName) const override;
void OnGroupExpanded(const AZStd::string& groupName) override;
void OnGroupCollapsed(const AZStd::string& groupName) override;
private:
AZ::Crc32 GetGroupSaveStateKey(const AZStd::string& groupName) const;
bool IsInstanceNodePropertyModifed(const AzToolsFramework::InstanceDataNode* node) const;
const char* GetInstanceNodePropertyIndicator(const AzToolsFramework::InstanceDataNode* node) const;
// AtomToolsDocumentNotificationBus::Handler implementation
void OnDocumentOpened(const AZ::Uuid& documentId) override;
void OnDocumentObjectInfoChanged(
const AZ::Uuid& documentId, const AtomToolsFramework::DocumentObjectInfo& objectInfo, bool rebuilt) override;
// AzToolsFramework::IPropertyEditorNotify overrides...
void BeforePropertyModified(AzToolsFramework::InstanceDataNode* pNode) override;
void AfterPropertyModified([[maybe_unused]] AzToolsFramework::InstanceDataNode* pNode) override {}
void SetPropertyEditingActive([[maybe_unused]] AzToolsFramework::InstanceDataNode* pNode) override {}
void SetPropertyEditingComplete(AzToolsFramework::InstanceDataNode* pNode) override;
void SealUndoStack() override {}
void RequestPropertyContextMenu([[maybe_unused]] AzToolsFramework::InstanceDataNode* pNode, const QPoint&) override {}
void PropertySelectionChanged([[maybe_unused]] AzToolsFramework::InstanceDataNode* pNode, bool) override {}
const AZ::Crc32 m_toolId = {};
// Tracking the property that is activiley being edited in the inspector
const AtomToolsFramework::DynamicProperty* m_activeProperty = {};
AZ::Uuid m_documentId = AZ::Uuid::CreateNull();
AZStd::string m_documentPath;
AZStd::intrusive_ptr<MaterialEditorWindowSettings> m_windowSettings;
};
} // namespace MaterialEditor

@ -6,19 +6,19 @@
*
*/
#include <AtomToolsFramework/Inspector/InspectorPropertyGroupWidget.h>
#include <Window/SettingsDialog/SettingsWidget.h>
#include <AtomToolsFramework/Inspector/InspectorPropertyGroupWidget.h>
namespace MaterialEditor
{
SettingsWidget::SettingsWidget(QWidget* parent)
: AtomToolsFramework::InspectorWidget(parent)
{
SetGroupSettingsPrefix("/O3DE/Atom/MaterialEditor/SettingsWidget");
}
SettingsWidget::~SettingsWidget()
{
AtomToolsFramework::InspectorRequestBus::Handler::BusDisconnect();
}
void SettingsWidget::Populate()
@ -29,6 +29,7 @@ namespace MaterialEditor
void SettingsWidget::Reset()
{
AtomToolsFramework::InspectorRequestBus::Handler::BusDisconnect();
AtomToolsFramework::InspectorWidget::Reset();
}
} // namespace MaterialEditor

@ -32,7 +32,9 @@ namespace MaterialEditor
m_viewportSettings =
AZ::UserSettings::CreateFind<MaterialViewportSettings>(AZ::Crc32("MaterialViewportSettings"), AZ::UserSettings::CT_GLOBAL);
SetGroupSettingsPrefix("/O3DE/Atom/MaterialEditor/ViewportSettingsInspector");
m_windowSettings = AZ::UserSettings::CreateFind<MaterialEditorWindowSettings>(
AZ::Crc32("MaterialEditorWindowSettings"), AZ::UserSettings::CT_GLOBAL);
MaterialViewportNotificationBus::Handler::BusConnect();
}
@ -41,6 +43,7 @@ namespace MaterialEditor
m_lightingPreset.reset();
m_modelPreset.reset();
MaterialViewportNotificationBus::Handler::BusDisconnect();
AtomToolsFramework::InspectorRequestBus::Handler::BusDisconnect();
}
void ViewportSettingsInspector::Populate()
@ -141,7 +144,7 @@ namespace MaterialEditor
});
const int itemSize = aznumeric_cast<int>(
AtomToolsFramework::GetSettingsValue<AZ::u64>("/O3DE/Atom/MaterialEditor/AssetGridDialog/ModelItemSize", 180));
AtomToolsFramework::GetSettingOrDefault<AZ::u64>("/O3DE/Atom/MaterialEditor/AssetGridDialog/ModelItemSize", 180));
AtomToolsFramework::AssetGridDialog dialog(
"Model Preset Browser", selectableAssets, selectedAsset, QSize(itemSize, itemSize), QApplication::activeWindow());
@ -267,7 +270,7 @@ namespace MaterialEditor
});
const int itemSize = aznumeric_cast<int>(
AtomToolsFramework::GetSettingsValue<AZ::u64>("/O3DE/Atom/MaterialEditor/AssetGridDialog/LightingItemSize", 180));
AtomToolsFramework::GetSettingOrDefault<AZ::u64>("/O3DE/Atom/MaterialEditor/AssetGridDialog/LightingItemSize", 180));
AtomToolsFramework::AssetGridDialog dialog(
"Lighting Preset Browser", selectableAssets, selectedAsset, QSize(itemSize, itemSize), QApplication::activeWindow());
@ -335,6 +338,7 @@ namespace MaterialEditor
m_viewportSettings->m_displayMapperOperationType = viewportRequests->GetDisplayMapperOperationType();
});
AtomToolsFramework::InspectorRequestBus::Handler::BusDisconnect();
AtomToolsFramework::InspectorWidget::Reset();
}
@ -429,6 +433,23 @@ namespace MaterialEditor
{
return AZ::Crc32(AZStd::string::format("ViewportSettingsInspector::PropertyGroup::%s", groupName.c_str()));
}
bool ViewportSettingsInspector::ShouldGroupAutoExpanded(const AZStd::string& groupName) const
{
auto stateItr = m_windowSettings->m_inspectorCollapsedGroups.find(GetGroupSaveStateKey(groupName));
return stateItr == m_windowSettings->m_inspectorCollapsedGroups.end();
}
void ViewportSettingsInspector::OnGroupExpanded(const AZStd::string& groupName)
{
m_windowSettings->m_inspectorCollapsedGroups.erase(GetGroupSaveStateKey(groupName));
}
void ViewportSettingsInspector::OnGroupCollapsed(const AZStd::string& groupName)
{
m_windowSettings->m_inspectorCollapsedGroups.insert(GetGroupSaveStateKey(groupName));
}
} // namespace MaterialEditor
#include <Window/ViewportSettingsInspector/moc_ViewportSettingsInspector.cpp>

@ -16,6 +16,7 @@
#include <AzToolsFramework/UI/PropertyEditor/PropertyEditorAPI_Internals.h>
#include <Viewport/MaterialViewportNotificationBus.h>
#include <Viewport/MaterialViewportSettings.h>
#include <Window/MaterialEditorWindowSettings.h>
#endif
namespace MaterialEditor
@ -74,9 +75,13 @@ namespace MaterialEditor
AZStd::string GetDefaultUniqueSaveFilePath(const AZStd::string& baseName) const;
AZ::Crc32 GetGroupSaveStateKey(const AZStd::string& groupName) const;
bool ShouldGroupAutoExpanded(const AZStd::string& groupName) const override;
void OnGroupExpanded(const AZStd::string& groupName) override;
void OnGroupCollapsed(const AZStd::string& groupName) override;
AZ::Render::ModelPresetPtr m_modelPreset;
AZ::Render::LightingPresetPtr m_lightingPreset;
AZStd::intrusive_ptr<MaterialViewportSettings> m_viewportSettings;
AZStd::intrusive_ptr<MaterialEditorWindowSettings> m_windowSettings;
};
} // namespace MaterialEditor

@ -46,6 +46,8 @@ set(FILES
Source/Window/ToolBar/ModelPresetComboBox.cpp
Source/Window/ToolBar/LightingPresetComboBox.h
Source/Window/ToolBar/LightingPresetComboBox.cpp
Source/Window/MaterialInspector/MaterialInspector.h
Source/Window/MaterialInspector/MaterialInspector.cpp
Source/Window/ViewportSettingsInspector/ViewportSettingsInspector.h
Source/Window/ViewportSettingsInspector/ViewportSettingsInspector.cpp
)

@ -14,11 +14,8 @@
#include <Atom/RPI.Edit/Material/MaterialPropertyId.h>
#include <Atom/RPI.Edit/Material/MaterialUtils.h>
#include <Atom/RPI.Reflect/Material/MaterialFunctor.h>
#include <Atom/RPI.Reflect/Material/MaterialNameContext.h>
#include <Atom/RPI.Reflect/Material/MaterialPropertiesLayout.h>
#include <AtomLyIntegration/CommonFeatures/Material/EditorMaterialSystemComponentRequestBus.h>
#include <AtomLyIntegration/CommonFeatures/Material/MaterialComponentBus.h>
#include <AtomLyIntegration/CommonFeatures/Material/MaterialComponentConfig.h>
#include <Atom/RPI.Reflect/Material/MaterialNameContext.h>
#include <AtomToolsFramework/Inspector/InspectorPropertyGroupWidget.h>
#include <AtomToolsFramework/Util/MaterialPropertyUtil.h>
#include <AtomToolsFramework/Util/Util.h>
@ -27,6 +24,9 @@
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
#include <AzToolsFramework/API/EditorWindowRequestBus.h>
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
#include <AtomLyIntegration/CommonFeatures/Material/EditorMaterialSystemComponentRequestBus.h>
#include <AtomLyIntegration/CommonFeatures/Material/MaterialComponentBus.h>
#include <AtomLyIntegration/CommonFeatures/Material/MaterialComponentConfig.h>
AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option") // disable warnings spawned by QT
#include <QApplication>
@ -54,6 +54,7 @@ namespace AZ
MaterialPropertyInspector::~MaterialPropertyInspector()
{
AtomToolsFramework::InspectorRequestBus::Handler::BusDisconnect();
AZ::TickBus::Handler::BusDisconnect();
AZ::EntitySystemBus::Handler::BusDisconnect();
EditorMaterialSystemComponentNotificationBus::Handler::BusDisconnect();
@ -136,6 +137,7 @@ namespace AZ
m_dirtyPropertyFlags.set();
m_internalEditNotification = {};
AtomToolsFramework::InspectorRequestBus::Handler::BusDisconnect();
AtomToolsFramework::InspectorWidget::Reset();
}
@ -588,7 +590,7 @@ namespace AZ
bool MaterialPropertyInspector::IsInstanceNodePropertyModifed(const AzToolsFramework::InstanceDataNode* node) const
{
const auto property = AtomToolsFramework::FindAncestorInstanceDataNodeByType<AtomToolsFramework::DynamicProperty>(node);
const AtomToolsFramework::DynamicProperty* property = AtomToolsFramework::FindDynamicPropertyForInstanceDataNode(node);
return property && !AtomToolsFramework::ArePropertyValuesEqual(property->GetValue(), property->GetConfig().m_parentValue);
}
@ -717,7 +719,7 @@ namespace AZ
// This function is called continuously anytime a property changes until the edit has completed
// Because of that, we have to track whether or not we are continuing to edit the same property to know when editing has
// started and ended
const auto property = AtomToolsFramework::FindAncestorInstanceDataNodeByType<AtomToolsFramework::DynamicProperty>(pNode);
const AtomToolsFramework::DynamicProperty* property = AtomToolsFramework::FindDynamicPropertyForInstanceDataNode(pNode);
if (property)
{
if (m_activeProperty != property)
@ -729,7 +731,7 @@ namespace AZ
void MaterialPropertyInspector::AfterPropertyModified(AzToolsFramework::InstanceDataNode* pNode)
{
const auto property = AtomToolsFramework::FindAncestorInstanceDataNodeByType<AtomToolsFramework::DynamicProperty>(pNode);
const AtomToolsFramework::DynamicProperty* property = AtomToolsFramework::FindDynamicPropertyForInstanceDataNode(pNode);
if (property)
{
if (m_activeProperty == property)
@ -746,7 +748,7 @@ namespace AZ
// As above, there are symmetrical functions on the notification interface for when editing begins and ends and has been
// completed but they are not being called following that pattern. when this function executes the changes to the property
// are ready to be committed or reverted
const auto property = AtomToolsFramework::FindAncestorInstanceDataNodeByType<AtomToolsFramework::DynamicProperty>(pNode);
const AtomToolsFramework::DynamicProperty* property = AtomToolsFramework::FindDynamicPropertyForInstanceDataNode(pNode);
if (property)
{
if (m_activeProperty == property)

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

Loading…
Cancel
Save