Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6ffc2620e4 | |||
| d31200ee5c | |||
| 60adc098da | |||
| b69ae11ec6 | |||
| 1f4b62dc72 | |||
| 445385e146 | |||
| 464b225042 | |||
| 7de6bc5b23 | |||
| 49dba84fee | |||
| feb4088446 | |||
| 26c23d9ec0 | |||
| c6ca903e5f | |||
| 669caca9cc | |||
| 606b4e9ec3 | |||
| b22032e40a | |||
| fdb9c053ce | |||
| bb93b2e498 | |||
| f4d68a0b0d | |||
| 01786b2966 | |||
| f94ec80d9f | |||
| 26190a47eb | |||
| 8685be877b | |||
| 4d8c8fdda3 | |||
| 4ca71fd96a | |||
| 9da156d0a6 |
@@ -9,27 +9,17 @@ SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
# This suite consists of all test cases that are passing and have been verified.
|
||||
|
||||
import pytest
|
||||
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
|
||||
from ly_test_tools.o3de.editor_test import EditorTestSuite, EditorSharedTest
|
||||
|
||||
@pytest.mark.SUITE_main
|
||||
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
|
||||
@pytest.mark.parametrize("project", ["AutomatedTesting"])
|
||||
class TestAutomation(TestAutomationBase):
|
||||
def test_WhiteBox_AddComponentToEntity(self, request, workspace, editor, launcher_platform):
|
||||
class TestAutomation(EditorTestSuite):
|
||||
class test_WhiteBox_AddComponentToEntity(EditorSharedTest):
|
||||
from .tests import WhiteBox_AddComponentToEntity as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
|
||||
def test_WhiteBox_SetDefaultShape(self, request, workspace, editor, launcher_platform):
|
||||
class test_WhiteBox_SetDefaultShape(EditorSharedTest):
|
||||
from .tests import WhiteBox_SetDefaultShape as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
|
||||
def test_WhiteBox_SetInvisible(self, request, workspace, editor, launcher_platform):
|
||||
class test_WhiteBox_SetInvisible(EditorSharedTest):
|
||||
from .tests import WhiteBox_SetInvisible as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
|
||||
@@ -18,21 +18,17 @@ 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
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
import WhiteBoxInit as init
|
||||
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
from editor_python_test_tools.utils import Report
|
||||
|
||||
# open level
|
||||
helper.init_idle()
|
||||
helper.open_level("WhiteBox", "EmptyLevel", no_prompt=False)
|
||||
hydra.open_base_level()
|
||||
|
||||
# create white box entity and attach component
|
||||
white_box_entity = init.create_white_box_entity()
|
||||
@@ -46,10 +42,6 @@ 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,17 +22,13 @@ 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 azlmbr.legacy.general as general
|
||||
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
import WhiteBoxInit as init
|
||||
|
||||
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)
|
||||
@@ -53,8 +49,7 @@ def C29279329_WhiteBox_SetDefaultShape():
|
||||
}
|
||||
|
||||
# open level
|
||||
helper.init_idle()
|
||||
helper.open_level("WhiteBox", "EmptyLevel", no_prompt=False)
|
||||
hydra.open_base_level()
|
||||
|
||||
# create white box entity and attach component
|
||||
white_box_entity = init.create_white_box_entity()
|
||||
@@ -95,10 +90,6 @@ 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,25 +21,16 @@ 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 azlmbr.entity as entity
|
||||
import azlmbr.legacy.general as general
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
import WhiteBoxInit as init
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
# open level
|
||||
helper.init_idle()
|
||||
helper.open_level("WhiteBox", "EmptyLevel", no_prompt=False)
|
||||
hydra.open_base_level()
|
||||
|
||||
white_box_entity_name = 'WhiteBox-Visibility'
|
||||
white_box_visibility_path = 'White Box Material|Visible'
|
||||
@@ -57,9 +48,6 @@ 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)
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:2dfc16cf4e47fc73c40d8a30ce08c34fe7805d369bf6ca69bd0d00ede4509902
|
||||
size 4542
|
||||
@@ -1,118 +0,0 @@
|
||||
{
|
||||
"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
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
<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>
|
||||
@@ -1,7 +0,0 @@
|
||||
<TerrainTexture TileCountX="1" TileCountY="1" TileResolution="512">
|
||||
<RGBLayer>
|
||||
<Tiles>
|
||||
<tile X="0" Y="0" Size="512"/>
|
||||
</Tiles>
|
||||
</RGBLayer>
|
||||
</TerrainTexture>
|
||||
@@ -1,356 +0,0 @@
|
||||
<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>
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:0e6a5435c928079b27796f6b202bbc2623e7e454244ddc099a3cadf33b7cb9e9
|
||||
size 63
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:8739c76e681f900923b900c9df0ef75cf421d39cabb54650c4b9ad19b6a76d85
|
||||
size 22
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:9799510badafd54e2a47574ea7e0112b8cb7eb23facf4dff8adc6f51fa624953
|
||||
size 7955
|
||||
+57
-159
@@ -43,13 +43,14 @@ 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>
|
||||
|
||||
@@ -104,7 +105,6 @@ AZ_POP_DISABLE_WARNING
|
||||
#include "WaitProgress.h"
|
||||
|
||||
#include "ToolBox.h"
|
||||
#include "LevelInfo.h"
|
||||
#include "EditorPreferencesDialog.h"
|
||||
#include "AnimationContext.h"
|
||||
|
||||
@@ -422,7 +422,6 @@ 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)
|
||||
@@ -770,28 +769,6 @@ 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.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -1504,7 +1481,7 @@ void CCryEditApp::RunInitPythonScript(CEditCommandLineInfo& cmdInfo)
|
||||
|
||||
// We support specifying multiple files in the cmdline by separating them with ';'
|
||||
AZStd::vector<AZStd::string_view> fileList;
|
||||
AzFramework::StringFunc::TokenizeVisitor(
|
||||
AZ::StringFunc::TokenizeVisitor(
|
||||
fileStr.constData(),
|
||||
[&fileList](AZStd::string_view elem)
|
||||
{
|
||||
@@ -1516,7 +1493,7 @@ void CCryEditApp::RunInitPythonScript(CEditCommandLineInfo& cmdInfo)
|
||||
{
|
||||
QByteArray pythonArgsStr = cmdInfo.m_pythonArgs.toUtf8();
|
||||
AZStd::vector<AZStd::string_view> pythonArgs;
|
||||
AzFramework::StringFunc::TokenizeVisitor(pythonArgsStr.constData(),
|
||||
AZ::StringFunc::TokenizeVisitor(pythonArgsStr.constData(),
|
||||
[&pythonArgs](AZStd::string_view elem)
|
||||
{
|
||||
pythonArgs.push_back(elem);
|
||||
@@ -1531,7 +1508,7 @@ void CCryEditApp::RunInitPythonScript(CEditCommandLineInfo& cmdInfo)
|
||||
testcaseList.resize(fileList.size());
|
||||
{
|
||||
int i = 0;
|
||||
AzFramework::StringFunc::TokenizeVisitor(
|
||||
AZ::StringFunc::TokenizeVisitor(
|
||||
pythonTestCase.constData(),
|
||||
[&i, &testcaseList](AZStd::string_view elem)
|
||||
{
|
||||
@@ -1595,7 +1572,6 @@ bool CCryEditApp::InitInstance()
|
||||
{
|
||||
QElapsedTimer startupTimer;
|
||||
startupTimer.start();
|
||||
InitDirectory();
|
||||
|
||||
// create / attach to the environment:
|
||||
AttachEditorCoreAZEnvironment(AZ::Environment::GetInstance());
|
||||
@@ -1606,8 +1582,6 @@ bool CCryEditApp::InitInstance()
|
||||
|
||||
InitFromCommandLine(cmdInfo);
|
||||
|
||||
InitDirectory();
|
||||
|
||||
qobject_cast<Editor::EditorQtApplication*>(qApp)->Initialize(); // Must be done after CEditorImpl() is created
|
||||
m_pEditor->Initialize();
|
||||
|
||||
@@ -3644,14 +3618,6 @@ void CCryEditApp::OnClearRegistryData()
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CCryEditApp::OnValidatelevel()
|
||||
{
|
||||
// TODO: Add your command handler code here
|
||||
CLevelInfo levelInfo;
|
||||
levelInfo.Validate();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CCryEditApp::OnToolsPreferences()
|
||||
{
|
||||
@@ -3827,131 +3793,68 @@ CMainFrame * CCryEditApp::GetMainFrame() const
|
||||
return MainWindow::instance()->GetOldMainFrame();
|
||||
}
|
||||
|
||||
void CCryEditApp::StartProcessDetached(const char* process, const char* args)
|
||||
{
|
||||
// Build the arguments as a QStringList
|
||||
AZStd::vector<AZStd::string> tokens;
|
||||
|
||||
// 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;
|
||||
|
||||
while (!currentStr.empty())
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QStringList argsList;
|
||||
for (const auto& arg : tokens)
|
||||
{
|
||||
argsList.push_back(QString(arg.c_str()));
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
void CCryEditApp::OpenLUAEditor(const char* files)
|
||||
{
|
||||
AZStd::string args = "-launch lua";
|
||||
if (files && strlen(files) > 0)
|
||||
AZ::IO::FixedMaxPathString enginePath = AZ::Utils::GetEnginePath();
|
||||
|
||||
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;
|
||||
|
||||
if (!AZ::IO::SystemFile::Exists(executablePath.c_str()))
|
||||
{
|
||||
AZStd::vector<AZStd::string> resolvedPaths;
|
||||
|
||||
AZStd::vector<AZStd::string> tokens;
|
||||
|
||||
AzFramework::StringFunc::Tokenize(files, tokens, '|');
|
||||
|
||||
for (const auto& file : tokens)
|
||||
{
|
||||
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))
|
||||
{
|
||||
AZStd::string current = '\"' + AZStd::string(resolved) + '\"';
|
||||
AZStd::replace(current.begin(), current.end(), '\\', '/');
|
||||
resolvedPaths.push_back(current);
|
||||
}
|
||||
}
|
||||
|
||||
if (!resolvedPaths.empty())
|
||||
{
|
||||
for (const auto& resolvedPath : resolvedPaths)
|
||||
{
|
||||
args.append(AZStd::string::format(" -files %s", resolvedPath.c_str()));
|
||||
}
|
||||
}
|
||||
AZ_Error("LuaIDE", false, "%s not found", executablePath.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
AZ::IO::FixedMaxPathString engineRoot = AZ::Utils::GetEnginePath();
|
||||
AZ_Assert(!engineRoot.empty(), "Unable to query Engine Path");
|
||||
AzFramework::ProcessLauncher::ProcessLaunchInfo processLaunchInfo;
|
||||
|
||||
AZStd::string_view exePath;
|
||||
AZ::ComponentApplicationBus::BroadcastResult(exePath, &AZ::ComponentApplicationRequests::GetExecutableFolder);
|
||||
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");
|
||||
|
||||
#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
|
||||
auto ParseFilesList = [&launchCmd](AZStd::string_view filePath)
|
||||
{
|
||||
bool fullPathFound = false;
|
||||
auto GetFullSourcePath = [&launchCmd, &filePath, &fullPathFound]
|
||||
(AzToolsFramework::AssetSystem::AssetSystemRequest* assetSystemRequests)
|
||||
{
|
||||
AZ::IO::Path assetFullPath;
|
||||
if(assetSystemRequests->GetFullSourcePathFromRelativeProductPath(filePath, assetFullPath.Native()))
|
||||
{
|
||||
fullPathFound = true;
|
||||
launchCmd.emplace_back("--files");
|
||||
launchCmd.emplace_back(AZStd::move(assetFullPath.Native()));
|
||||
}
|
||||
};
|
||||
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()))
|
||||
{
|
||||
launchCmd.emplace_back("--files");
|
||||
launchCmd.emplace_back(resolvedFilePath.String());
|
||||
}
|
||||
}
|
||||
};
|
||||
AZ::StringFunc::TokenizeVisitor(files, ParseFilesList, "|");
|
||||
|
||||
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);
|
||||
processLaunchInfo.m_commandlineParameters = AZStd::move(launchCmd);
|
||||
|
||||
AZStd::string processArgs = AZStd::string::format("%s -engine-path \"%s\"", args.c_str(), engineRoot.c_str());
|
||||
StartProcessDetached(process.c_str(), processArgs.c_str());
|
||||
AZ_VerifyError("LuaIDE", AzFramework::ProcessLauncher::LaunchUnwatchedProcess(processLaunchInfo),
|
||||
"Lua IDE has failed to launch at path %s", executablePath.c_str());
|
||||
}
|
||||
|
||||
void CCryEditApp::PrintAlways(const AZStd::string& output)
|
||||
@@ -4065,11 +3968,6 @@ 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,7 +138,6 @@ 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();
|
||||
@@ -159,11 +158,6 @@ 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);
|
||||
@@ -399,7 +393,6 @@ private:
|
||||
void OnDisplayGotoPosition();
|
||||
void OnFileSavelevelresources();
|
||||
void OnClearRegistryData();
|
||||
void OnValidatelevel();
|
||||
void OnToolsPreferences();
|
||||
void OnSwitchToDefaultCamera();
|
||||
void OnUpdateSwitchToDefaultCamera(QAction* action);
|
||||
|
||||
@@ -260,11 +260,6 @@ namespace
|
||||
|
||||
namespace
|
||||
{
|
||||
void PyStartProcessDetached(const char* process, const char* args)
|
||||
{
|
||||
CCryEditApp::instance()->StartProcessDetached(process, args);
|
||||
}
|
||||
|
||||
void PyLaunchLUAEditor(const char* files)
|
||||
{
|
||||
CCryEditApp::instance()->OpenLUAEditor(files);
|
||||
@@ -429,7 +424,6 @@ 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_orbitDollyScrollCamera = AZStd::make_shared<AzFramework::OrbitDollyScrollCameraInput>();
|
||||
m_orbitScrollDollyCamera = AZStd::make_shared<AzFramework::OrbitScrollDollyCameraInput>();
|
||||
|
||||
m_orbitDollyScrollCamera->m_scrollSpeedFn = []
|
||||
m_orbitScrollDollyCamera->m_scrollSpeedFn = []
|
||||
{
|
||||
return SandboxEditor::CameraScrollSpeed();
|
||||
};
|
||||
|
||||
m_orbitDollyMoveCamera = AZStd::make_shared<AzFramework::OrbitDollyMotionCameraInput>(SandboxEditor::CameraOrbitDollyChannelId());
|
||||
m_orbitMotionDollyCamera = AZStd::make_shared<AzFramework::OrbitMotionDollyCameraInput>(SandboxEditor::CameraOrbitDollyChannelId());
|
||||
|
||||
m_orbitDollyMoveCamera->m_motionSpeedFn = []
|
||||
m_orbitMotionDollyCamera->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_orbitDollyScrollCamera);
|
||||
m_orbitCamera->m_orbitCameras.AddCamera(m_orbitDollyMoveCamera);
|
||||
m_orbitCamera->m_orbitCameras.AddCamera(m_orbitScrollDollyCamera);
|
||||
m_orbitCamera->m_orbitCameras.AddCamera(m_orbitMotionDollyCamera);
|
||||
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_orbitDollyMoveCamera->SetDollyInputChannelId(SandboxEditor::CameraOrbitDollyChannelId());
|
||||
m_orbitMotionDollyCamera->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::OrbitDollyScrollCameraInput> m_orbitDollyScrollCamera;
|
||||
AZStd::shared_ptr<AzFramework::OrbitDollyMotionCameraInput> m_orbitDollyMoveCamera;
|
||||
AZStd::shared_ptr<AzFramework::OrbitScrollDollyCameraInput> m_orbitScrollDollyCamera;
|
||||
AZStd::shared_ptr<AzFramework::OrbitMotionDollyCameraInput> m_orbitMotionDollyCamera;
|
||||
AZStd::shared_ptr<AzFramework::PanCameraInput> m_orbitPanCamera;
|
||||
AZStd::shared_ptr<AzFramework::FocusCameraInput> m_orbitFocusCamera;
|
||||
|
||||
|
||||
@@ -1,178 +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 "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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,30 +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
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#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,7 +74,6 @@ 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,9 +1011,6 @@ 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."));
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* 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,6 +212,8 @@ 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)
|
||||
@@ -395,6 +397,8 @@ void SandboxIntegrationManager::GetEntitiesInSlices(
|
||||
|
||||
void SandboxIntegrationManager::Teardown()
|
||||
{
|
||||
m_contextMenuBottomHandler.Teardown();
|
||||
|
||||
AzToolsFramework::Layers::EditorLayerComponentNotificationBus::Handler::BusDisconnect();
|
||||
AzFramework::DisplayContextRequestBus::Handler::BusDisconnect();
|
||||
AzToolsFramework::SliceEditorEntityOwnershipServiceNotificationBus::Handler::BusDisconnect();
|
||||
@@ -651,12 +655,14 @@ 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)
|
||||
@@ -667,6 +673,7 @@ 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]
|
||||
@@ -694,33 +701,30 @@ void SandboxIntegrationManager::PopulateEditorGlobalContextMenu(QMenu* menu, con
|
||||
AzToolsFramework::SetupAddToLayerMenu(menu, flattenedSelection, [this] { return ContextMenu_NewLayer(); });
|
||||
|
||||
SetupSliceContextMenu(menu);
|
||||
}
|
||||
|
||||
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)
|
||||
if (!selected.empty())
|
||||
{
|
||||
AZ::EntityId parentEntityId;
|
||||
AZ::TransformBus::EventResult(parentEntityId, entityId, &AZ::TransformBus::Events::GetParentId);
|
||||
|
||||
if (parentEntityId.IsValid() && m_readOnlyEntityPublicInterface->IsReadOnly(parentEntityId))
|
||||
// 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)
|
||||
{
|
||||
selectionContainsDescendantOfReadOnlyEntity = true;
|
||||
break;
|
||||
AZ::EntityId parentEntityId;
|
||||
AZ::TransformBus::EventResult(parentEntityId, entityId, &AZ::TransformBus::Events::GetParentId);
|
||||
|
||||
if (parentEntityId.IsValid() && m_readOnlyEntityPublicInterface->IsReadOnly(parentEntityId))
|
||||
{
|
||||
selectionContainsDescendantOfReadOnlyEntity = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!selectionContainsDescendantOfReadOnlyEntity)
|
||||
{
|
||||
action = menu->addAction(QObject::tr("Duplicate"));
|
||||
QObject::connect(action, &QAction::triggered, action, [this] { ContextMenu_Duplicate(); });
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
@@ -733,20 +737,14 @@ void SandboxIntegrationManager::PopulateEditorGlobalContextMenu(QMenu* menu, con
|
||||
|
||||
if (selected.size() > 0)
|
||||
{
|
||||
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]
|
||||
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,6 +9,8 @@
|
||||
#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>
|
||||
@@ -273,6 +275,8 @@ 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
|
||||
|
||||
+2
@@ -10,6 +10,8 @@ set(FILES
|
||||
dllmain.cpp
|
||||
ComponentEntityEditorPlugin.h
|
||||
ComponentEntityEditorPlugin.cpp
|
||||
ContextMenuHandlers.h
|
||||
ContextMenuHandlers.cpp
|
||||
SandboxIntegration.h
|
||||
SandboxIntegration.cpp
|
||||
UI/QComponentEntityEditorMainWindow.h
|
||||
|
||||
@@ -86,7 +86,6 @@
|
||||
#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
|
||||
@@ -236,7 +235,6 @@
|
||||
#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,8 +532,6 @@ set(FILES
|
||||
ErrorReport.h
|
||||
IconManager.cpp
|
||||
IconManager.h
|
||||
LevelInfo.cpp
|
||||
LevelInfo.h
|
||||
ProcessInfo.cpp
|
||||
ProcessInfo.h
|
||||
TrackView/AtomOutputFrameCapture.cpp
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#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>
|
||||
@@ -20,6 +21,7 @@
|
||||
#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.
|
||||
@@ -256,13 +258,13 @@ namespace AZ
|
||||
struct ClampedIntegralLimits
|
||||
{
|
||||
//! If SourceType and ClampType are different, returns the greater value of
|
||||
//! std::numeric_limits<SourceType>::lowest() and std::numeric_limits<ClampType>::lowest(),
|
||||
//! otherwise returns std::numeric_limits<SourceType>::lowest().
|
||||
//! AZStd::numeric_limits<SourceType>::lowest() and AZStd::numeric_limits<ClampType>::lowest(),
|
||||
//! otherwise returns AZStd::numeric_limits<SourceType>::lowest().
|
||||
static constexpr SourceType Min();
|
||||
|
||||
//! If SourceType and ClampType are different, returns the lesser value of
|
||||
//! std::numeric_limits<SourceType>::max() and std::numeric_limits<ClampType>::max(),
|
||||
//! otherwise returns std::numeric_limits<SourceType>::max().
|
||||
//! AZStd::numeric_limits<SourceType>::max() and AZStd::numeric_limits<ClampType>::max(),
|
||||
//! otherwise returns AZStd::numeric_limits<SourceType>::max().
|
||||
static constexpr SourceType Max();
|
||||
|
||||
//! Safely clamps a value of type ValueType to the [Min(), Max()] range as determined by the
|
||||
@@ -375,12 +377,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, std::numeric_limits<float>::epsilon()) ? 0.0f : (value - a) / (b - a);
|
||||
return IsClose(a, b, AZStd::numeric_limits<float>::epsilon()) ? 0.0f : (value - a) / (b - a);
|
||||
}
|
||||
|
||||
inline double LerpInverse(double a, double b, double value)
|
||||
{
|
||||
return IsClose(a, b, std::numeric_limits<double>::epsilon()) ? 0.0 : (value - a) / (b - a);
|
||||
return IsClose(a, b, AZStd::numeric_limits<double>::epsilon()) ? 0.0 : (value - a) / (b - a);
|
||||
}
|
||||
|
||||
//! Returns true if the number provided is even.
|
||||
@@ -431,19 +433,19 @@ namespace AZ
|
||||
|
||||
AZ_MATH_INLINE float GetFloatQNaN()
|
||||
{
|
||||
return std::numeric_limits<float>::quiet_NaN();
|
||||
return AZStd::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 = std::numeric_limits<T>::epsilon())
|
||||
AZ_MATH_INLINE bool IsCloseMag(T x, T y, T epsilonValue = AZStd::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 = std::numeric_limits<T>::epsilon())
|
||||
AZ_MATH_INLINE T ClampIfCloseMag(T x, T y, T epsilonValue = AZStd::numeric_limits<T>::epsilon())
|
||||
{
|
||||
return IsCloseMag<T>(x, y, epsilonValue) ? y : x;
|
||||
}
|
||||
@@ -461,6 +463,44 @@ 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()
|
||||
@@ -474,8 +514,8 @@ namespace AZ
|
||||
{
|
||||
// Both SourceType and ClampType are signed, take the greater of the lower limits of each type
|
||||
return sizeof(SourceType) < sizeof(ClampType) ?
|
||||
(std::numeric_limits<SourceType>::lowest)() :
|
||||
static_cast<SourceType>((std::numeric_limits<ClampType>::lowest)());
|
||||
(AZStd::numeric_limits<SourceType>::lowest)() :
|
||||
static_cast<SourceType>((AZStd::numeric_limits<ClampType>::lowest)());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -486,12 +526,12 @@ namespace AZ
|
||||
if constexpr (sizeof(SourceType) < sizeof(ClampType))
|
||||
{
|
||||
// If SourceType is narrower than ClampType, the upper limit will be SourceType's
|
||||
return (std::numeric_limits<SourceType>::max)();
|
||||
return (AZStd::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>((std::numeric_limits<ClampType>::max)());
|
||||
return static_cast<SourceType>((AZStd::numeric_limits<ClampType>::max)());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -499,13 +539,13 @@ namespace AZ
|
||||
{
|
||||
// SourceType and ClampType are the same width, ClampType is signed
|
||||
// so our upper limit will be ClampType
|
||||
return static_cast<SourceType>((std::numeric_limits<ClampType>::max)());
|
||||
return static_cast<SourceType>((AZStd::numeric_limits<ClampType>::max)());
|
||||
}
|
||||
else
|
||||
{
|
||||
// SourceType and ClampType are the same width, ClampType is unsigned
|
||||
// then our upper limit will be SourceType
|
||||
return (std::numeric_limits<SourceType>::max)();
|
||||
return (AZStd::numeric_limits<SourceType>::max)();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -588,7 +628,7 @@ namespace AZ
|
||||
// LeftTypeSize <= RightTypeSize
|
||||
// LeftType is signed
|
||||
// RightType is unsigned
|
||||
RightType max = static_cast<RightType>((std::numeric_limits<LeftType>::max)());
|
||||
RightType max = static_cast<RightType>((AZStd::numeric_limits<LeftType>::max)());
|
||||
|
||||
if (rhs > max)
|
||||
{
|
||||
@@ -604,7 +644,7 @@ namespace AZ
|
||||
// LeftType < RightType
|
||||
// LeftType is unsigned
|
||||
// RightType is signed
|
||||
RightType max = static_cast<RightType>((std::numeric_limits<LeftType>::max)());
|
||||
RightType max = static_cast<RightType>((AZStd::numeric_limits<LeftType>::max)());
|
||||
|
||||
if (rhs < 0)
|
||||
{
|
||||
|
||||
@@ -85,6 +85,16 @@ 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{};
|
||||
@@ -209,8 +219,15 @@ namespace AZ::Internal
|
||||
return {};
|
||||
}
|
||||
|
||||
void InjectSettingToCommandLineBack(AZ::SettingsRegistryInterface& settingsRegistry,
|
||||
AZStd::string_view path, AZStd::string_view value)
|
||||
enum class InjectLocation : bool
|
||||
{
|
||||
Front,
|
||||
Back
|
||||
};
|
||||
|
||||
void InjectSettingToCommandLine(AZ::SettingsRegistryInterface& settingsRegistry,
|
||||
AZStd::string_view path, AZStd::string_view value,
|
||||
InjectLocation injectLocation = InjectLocation::Front)
|
||||
{
|
||||
AZ::CommandLine commandLine;
|
||||
AZ::SettingsRegistryMergeUtils::GetCommandLineFromRegistry(settingsRegistry, commandLine);
|
||||
@@ -219,7 +236,8 @@ 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());
|
||||
paramContainer.emplace(paramContainer.end(), AZStd::move(projectPathOverride));
|
||||
auto emplaceIter = injectLocation == InjectLocation::Front ? paramContainer.begin() : paramContainer.end();
|
||||
paramContainer.emplace(emplaceIter, AZStd::move(projectPathOverride));
|
||||
commandLine.Parse(paramContainer);
|
||||
AZ::SettingsRegistryMergeUtils::StoreCommandLineToRegistry(settingsRegistry, commandLine);
|
||||
}
|
||||
@@ -244,13 +262,26 @@ 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 at the end of the command line settings
|
||||
Internal::InjectSettingToCommandLineBack(settingsRegistry, engineRootKey, engineRoot.Native());
|
||||
// Inject the engine root to the front of the command line settings
|
||||
Internal::InjectSettingToCommandLine(settingsRegistry, engineRootKey, engineRoot.Native());
|
||||
return engineRoot;
|
||||
}
|
||||
}
|
||||
@@ -258,6 +289,14 @@ 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;
|
||||
}
|
||||
|
||||
@@ -298,13 +337,28 @@ 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 the end of the command line settings
|
||||
Internal::InjectSettingToCommandLineBack(settingsRegistry, projectRootKey, projectRoot.Native());
|
||||
// Inject the project root at to the front of the command line settings
|
||||
Internal::InjectSettingToCommandLine(settingsRegistry, projectRootKey, projectRoot.Native());
|
||||
|
||||
return projectRoot;
|
||||
}
|
||||
}
|
||||
@@ -312,6 +366,18 @@ 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;
|
||||
}
|
||||
|
||||
@@ -325,13 +391,22 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
constexpr auto projectCachePathKey = FixedValueString(BootstrapSettingsRootKey) + "/project_cache_path";
|
||||
|
||||
// Step 1 Check the project-cache-path key
|
||||
if (AZ::IO::FixedMaxPath projectCachePath; settingsRegistry.Get(projectCachePath.Native(), projectCachePathKey))
|
||||
AZ::IO::FixedMaxPath projectCachePath;
|
||||
if (!settingsRegistry.Get(projectCachePath.Native(), projectCachePathKey))
|
||||
{
|
||||
return projectCachePath;
|
||||
// Step 2 Append the "Cache" directory to the project-path
|
||||
projectCachePath = projectPath / Internal::ProductCacheDirectoryName;
|
||||
}
|
||||
|
||||
// Step 2 Append the "Cache" directory to the project-path
|
||||
return projectPath / Internal::ProductCacheDirectoryName;
|
||||
if (projectCachePath.IsRelative())
|
||||
{
|
||||
if (auto projectCacheAbsPath = AZ::Utils::ConvertToAbsolutePath(projectCachePath.Native());
|
||||
projectCacheAbsPath.has_value())
|
||||
{
|
||||
projectCachePath = AZStd::move(*projectCacheAbsPath);
|
||||
}
|
||||
}
|
||||
return projectCachePath;
|
||||
}
|
||||
|
||||
//! Set the user directory with the provided path or using <project-path>/user as default
|
||||
@@ -344,13 +419,22 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
constexpr auto projectUserPathKey = FixedValueString(BootstrapSettingsRootKey) + "/project_user_path";
|
||||
|
||||
// Step 1 Check the project-user-path key
|
||||
if (AZ::IO::FixedMaxPath projectUserPath; settingsRegistry.Get(projectUserPath.Native(), projectUserPathKey))
|
||||
AZ::IO::FixedMaxPath projectUserPath;
|
||||
if (!settingsRegistry.Get(projectUserPath.Native(), projectUserPathKey))
|
||||
{
|
||||
return projectUserPath;
|
||||
// Step 2 Append the "User" directory to the project-path
|
||||
projectUserPath = projectPath / "user";
|
||||
}
|
||||
|
||||
// Step 2 Append the "User" directory to the project-path
|
||||
return projectPath / "user";
|
||||
if (projectUserPath.IsRelative())
|
||||
{
|
||||
if (auto projectUserAbsPath = AZ::Utils::ConvertToAbsolutePath(projectUserPath.Native());
|
||||
projectUserAbsPath.has_value())
|
||||
{
|
||||
projectUserPath = AZStd::move(*projectUserAbsPath);
|
||||
}
|
||||
}
|
||||
return projectUserPath;
|
||||
}
|
||||
|
||||
//! Set the log directory using the settings registry path or using <project-user-path>/log as default
|
||||
@@ -363,20 +447,37 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
constexpr auto projectLogPathKey = FixedValueString(BootstrapSettingsRootKey) + "/project_log_path";
|
||||
|
||||
// Step 1 Check the project-user-path key
|
||||
if (AZ::IO::FixedMaxPath projectLogPath; settingsRegistry.Get(projectLogPath.Native(), projectLogPathKey))
|
||||
AZ::IO::FixedMaxPath projectLogPath;
|
||||
if (!settingsRegistry.Get(projectLogPath.Native(), projectLogPathKey))
|
||||
{
|
||||
return projectLogPath;
|
||||
// Step 2 Append the "Log" directory to the project-user-path
|
||||
projectLogPath = projectUserPath / "log";
|
||||
}
|
||||
|
||||
// Step 2 Append the "Log" directory to the project-user-path
|
||||
return projectUserPath / "log";
|
||||
if (projectLogPath.IsRelative())
|
||||
{
|
||||
if (auto projectLogAbsPath = AZ::Utils::ConvertToAbsolutePath(projectLogPath.Native()))
|
||||
{
|
||||
projectLogPath = AZStd::move(*projectLogAbsPath);
|
||||
}
|
||||
}
|
||||
|
||||
return projectLogPath;
|
||||
}
|
||||
|
||||
// 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();
|
||||
return devWriteStorage.has_value() ? *devWriteStorage : projectUserPath;
|
||||
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;
|
||||
}
|
||||
|
||||
// check for the project build path, which is a relative path from the project root
|
||||
@@ -669,15 +770,6 @@ 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?)"
|
||||
@@ -699,15 +791,6 @@ 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());
|
||||
}
|
||||
@@ -716,15 +799,6 @@ 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());
|
||||
|
||||
@@ -755,15 +829,6 @@ 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());
|
||||
}
|
||||
@@ -771,14 +836,6 @@ 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());
|
||||
}
|
||||
@@ -786,14 +843,6 @@ 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,15 +89,14 @@ 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 back of the command line parameters
|
||||
//! In the same step it injects the path into the front 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 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>"
|
||||
//! 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>"
|
||||
//! or --project_path=<path>
|
||||
AZ::IO::FixedMaxPath FindProjectRoot(SettingsRegistryInterface& settingsRegistry);
|
||||
|
||||
@@ -213,9 +212,15 @@ 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 and -regremove will run in the order in which they are parsed
|
||||
//! Registry related arguments. Note that --regset, --regset-file 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 TStringType, typename TConvertableToStringViewIterator, typename TSeparatorString>
|
||||
template<typename StringType, typename ConvertableToStringViewIterator, typename SeparatorString>
|
||||
inline void Join(
|
||||
TStringType& joinTarget,
|
||||
const TConvertableToStringViewIterator& iteratorBegin,
|
||||
const TConvertableToStringViewIterator& iteratorEnd,
|
||||
const TSeparatorString& separator)
|
||||
StringType& joinTarget,
|
||||
const ConvertableToStringViewIterator& iteratorBegin,
|
||||
const ConvertableToStringViewIterator& iteratorEnd,
|
||||
const SeparatorString& separator)
|
||||
{
|
||||
if (iteratorBegin == iteratorEnd)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
using CharType = typename TStringType::value_type;
|
||||
using CharTraitsType = typename TStringType::traits_type;
|
||||
using CharType = typename StringType::value_type;
|
||||
using CharTraitsType = typename StringType::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<TSeparatorString>, CharType>)
|
||||
if constexpr (AZStd::is_same_v<AZStd::remove_cvref_t<SeparatorString>, CharType>)
|
||||
{
|
||||
size += 1;
|
||||
}
|
||||
@@ -455,6 +455,19 @@ 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,7 +302,13 @@ 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; }
|
||||
inline AZStd::string to_string(bool 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;
|
||||
}
|
||||
|
||||
// In our engine we assume AZStd::string is Utf8 encoded!
|
||||
template<class Allocator>
|
||||
|
||||
@@ -656,18 +656,6 @@ 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);
|
||||
@@ -978,6 +966,47 @@ 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 = std::numeric_limits<float>::epsilon();
|
||||
const float doesntMatterF = std::numeric_limits<float>::signaling_NaN();
|
||||
const float epsilonF = AZStd::numeric_limits<float>::epsilon();
|
||||
const float doesntMatterF = AZStd::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 = std::numeric_limits<double>::epsilon();
|
||||
const double doesntMatterD = std::numeric_limits<double>::signaling_NaN();
|
||||
const double epsilonD = AZStd::numeric_limits<double>::epsilon();
|
||||
const double doesntMatterD = AZStd::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,4 +58,128 @@ 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,6 +196,19 @@ 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 = engineRootPath / projectRootPath / "project.json";
|
||||
AZ::IO::FixedMaxPath projectJsonPath = projectRootPath / "project.json";
|
||||
if (AZ::IO::SystemFile::Exists(projectJsonPath.c_str()))
|
||||
{
|
||||
return ProjectPathCheckResult::ProjectPathFound;
|
||||
|
||||
@@ -190,9 +190,67 @@ namespace AzFramework
|
||||
return nextCamera;
|
||||
}
|
||||
|
||||
void Cameras::AddCamera(AZStd::shared_ptr<CameraInput> cameraInput)
|
||||
bool Cameras::AddCamera(AZStd::shared_ptr<CameraInput> cameraInput)
|
||||
{
|
||||
m_idleCameraInputs.push_back(AZStd::move(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;
|
||||
}
|
||||
|
||||
bool Cameras::HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, const float scrollDelta)
|
||||
@@ -645,7 +703,7 @@ namespace AzFramework
|
||||
m_orbitChannelId = orbitChanneId;
|
||||
}
|
||||
|
||||
OrbitDollyScrollCameraInput::OrbitDollyScrollCameraInput()
|
||||
OrbitScrollDollyCameraInput::OrbitScrollDollyCameraInput()
|
||||
{
|
||||
m_scrollSpeedFn = []() constexpr
|
||||
{
|
||||
@@ -653,7 +711,7 @@ namespace AzFramework
|
||||
};
|
||||
}
|
||||
|
||||
bool OrbitDollyScrollCameraInput::HandleEvents(
|
||||
bool OrbitScrollDollyCameraInput::HandleEvents(
|
||||
const InputEvent& event, [[maybe_unused]] const ScreenVector& cursorDelta, [[maybe_unused]] const float scrollDelta)
|
||||
{
|
||||
if (const auto* scroll = AZStd::get_if<ScrollEvent>(&event))
|
||||
@@ -691,7 +749,7 @@ namespace AzFramework
|
||||
return nextCamera;
|
||||
}
|
||||
|
||||
Camera OrbitDollyScrollCameraInput::StepCamera(
|
||||
Camera OrbitScrollDollyCameraInput::StepCamera(
|
||||
const Camera& targetCamera,
|
||||
[[maybe_unused]] const ScreenVector& cursorDelta,
|
||||
const float scrollDelta,
|
||||
@@ -702,7 +760,7 @@ namespace AzFramework
|
||||
return nextCamera;
|
||||
}
|
||||
|
||||
OrbitDollyMotionCameraInput::OrbitDollyMotionCameraInput(const InputChannelId& dollyChannelId)
|
||||
OrbitMotionDollyCameraInput::OrbitMotionDollyCameraInput(const InputChannelId& dollyChannelId)
|
||||
: m_dollyChannelId(dollyChannelId)
|
||||
{
|
||||
m_motionSpeedFn = []() constexpr
|
||||
@@ -711,14 +769,14 @@ namespace AzFramework
|
||||
};
|
||||
}
|
||||
|
||||
bool OrbitDollyMotionCameraInput::HandleEvents(
|
||||
bool OrbitMotionDollyCameraInput::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 OrbitDollyMotionCameraInput::StepCamera(
|
||||
Camera OrbitMotionDollyCameraInput::StepCamera(
|
||||
const Camera& targetCamera,
|
||||
const ScreenVector& cursorDelta,
|
||||
[[maybe_unused]] const float scrollDelta,
|
||||
@@ -727,7 +785,7 @@ namespace AzFramework
|
||||
return OrbitDolly(targetCamera, aznumeric_cast<float>(cursorDelta.m_y) * m_motionSpeedFn());
|
||||
}
|
||||
|
||||
void OrbitDollyMotionCameraInput::SetDollyInputChannelId(const InputChannelId& dollyChannelId)
|
||||
void OrbitMotionDollyCameraInput::SetDollyInputChannelId(const InputChannelId& dollyChannelId)
|
||||
{
|
||||
m_dollyChannelId = dollyChannelId;
|
||||
}
|
||||
|
||||
@@ -289,7 +289,17 @@ 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.
|
||||
void AddCamera(AZStd::shared_ptr<CameraInput> cameraInput);
|
||||
//! @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);
|
||||
//! Reset the state of all cameras.
|
||||
void Reset();
|
||||
//! Remove all cameras that were added.
|
||||
@@ -299,9 +309,10 @@ namespace AzFramework
|
||||
bool Exclusive() const;
|
||||
|
||||
private:
|
||||
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).
|
||||
//! 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;
|
||||
};
|
||||
|
||||
//! Responsible for updating a series of cameras given various inputs.
|
||||
@@ -586,10 +597,10 @@ namespace AzFramework
|
||||
};
|
||||
|
||||
//! A camera input to handle discrete scroll events that can modify the camera offset.
|
||||
class OrbitDollyScrollCameraInput : public CameraInput
|
||||
class OrbitScrollDollyCameraInput : public CameraInput
|
||||
{
|
||||
public:
|
||||
OrbitDollyScrollCameraInput();
|
||||
OrbitScrollDollyCameraInput();
|
||||
|
||||
// CameraInput overrides ...
|
||||
bool HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override;
|
||||
@@ -599,10 +610,10 @@ namespace AzFramework
|
||||
};
|
||||
|
||||
//! A camera input to handle motion deltas that can modify the camera offset.
|
||||
class OrbitDollyMotionCameraInput : public CameraInput
|
||||
class OrbitMotionDollyCameraInput : public CameraInput
|
||||
{
|
||||
public:
|
||||
explicit OrbitDollyMotionCameraInput(const InputChannelId& dollyChannelId);
|
||||
explicit OrbitMotionDollyCameraInput(const InputChannelId& dollyChannelId);
|
||||
|
||||
// CameraInput overrides ...
|
||||
bool HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override;
|
||||
|
||||
@@ -490,4 +490,40 @@ 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,6 +17,7 @@
|
||||
#include <AzNetworking/Utilities/NetworkCommon.h>
|
||||
#include <AzCore/Console/IConsole.h>
|
||||
#include <AzCore/Console/ILogger.h>
|
||||
#include <AzCore/Math/MathUtils.h>
|
||||
|
||||
namespace AzNetworking
|
||||
{
|
||||
@@ -539,7 +540,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 = (packetSize + chunkSize - 1) / chunkSize; // We want to round up on the remainder
|
||||
const uint32_t numChunks = AZ::DivideAndRoundUp(packetSize, 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,6 +8,7 @@
|
||||
#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>
|
||||
|
||||
-4
@@ -208,10 +208,6 @@ 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.
|
||||
*/
|
||||
|
||||
+5
-12
@@ -97,6 +97,10 @@ namespace LegacyFramework
|
||||
}
|
||||
|
||||
Application::Application()
|
||||
: Application(0, nullptr)
|
||||
{}
|
||||
Application::Application(int argc, char** argv)
|
||||
: ComponentApplication(argc, argv)
|
||||
{
|
||||
m_isPrimary = true;
|
||||
m_desiredExitCode = 0;
|
||||
@@ -191,9 +195,6 @@ 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)
|
||||
{
|
||||
@@ -206,7 +207,7 @@ namespace LegacyFramework
|
||||
m_ptrSystemEntity->Activate();
|
||||
|
||||
// If we aren't the primary, RunAsAnotherInstance unless we are being forcestarted
|
||||
if (!m_isPrimary && !m_ptrCommandLineParser->HasSwitch("forcestart"))
|
||||
if (!m_isPrimary && !m_commandLine.HasSwitch("forcestart"))
|
||||
{
|
||||
// Required for the application component to handle RunAsAnotherInstance
|
||||
CreateApplicationComponent();
|
||||
@@ -246,9 +247,6 @@ namespace LegacyFramework
|
||||
::SetConsoleCtrlHandler(CTRL_BREAK_HandlerRoutine, false);
|
||||
#endif
|
||||
|
||||
delete m_ptrCommandLineParser;
|
||||
m_ptrCommandLineParser = nullptr;
|
||||
|
||||
CoreMessageBus::Handler::BusDisconnect();
|
||||
FrameworkApplicationMessages::Handler::BusDisconnect();
|
||||
|
||||
@@ -271,11 +269,6 @@ 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)
|
||||
{
|
||||
|
||||
+1
-2
@@ -56,6 +56,7 @@ namespace LegacyFramework
|
||||
using CoreMessageBus::Handler::Run;
|
||||
virtual int Run(const ApplicationDesc& desc);
|
||||
Application();
|
||||
Application(int argc, char** argv);
|
||||
|
||||
void CreateReflectionManager() override;
|
||||
|
||||
@@ -70,7 +71,6 @@ 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,7 +138,6 @@ 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 <AzFramework/CommandLine/CommandLine.h>
|
||||
#include <AzCore/Settings/CommandLine.h>
|
||||
|
||||
#include <AzToolsFramework/UI/UICore/QWidgetSavedState.h>
|
||||
#include <AzToolsFramework/UI/LegacyFramework/Core/EditorFrameworkAPI.h>
|
||||
@@ -34,7 +34,6 @@ 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;
|
||||
@@ -201,8 +200,11 @@ namespace AzToolsFramework
|
||||
// enable the built-in stylesheet by default:
|
||||
bool enableStyleSheet = true;
|
||||
|
||||
const AzFramework::CommandLine* comp = nullptr;
|
||||
EBUS_EVENT_RESULT(comp, LegacyFramework::FrameworkApplicationMessages::Bus, GetCommandLineParser);
|
||||
const AZ::CommandLine* comp = nullptr;
|
||||
AZ::ComponentApplicationBus::Broadcast([&comp](AZ::ComponentApplicationRequests* requests)
|
||||
{
|
||||
comp = requests->GetAzCommandLine();
|
||||
});
|
||||
if (comp != nullptr)
|
||||
{
|
||||
if (comp->HasSwitch("nostyle"))
|
||||
|
||||
+125
-71
@@ -253,6 +253,68 @@ 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
|
||||
@@ -291,7 +353,8 @@ namespace AzToolsFramework
|
||||
[selectedEntities]
|
||||
{
|
||||
ContextMenu_CreatePrefab(selectedEntities);
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
itemWasShown = true;
|
||||
}
|
||||
@@ -299,6 +362,21 @@ 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)
|
||||
@@ -311,7 +389,8 @@ namespace AzToolsFramework
|
||||
[]
|
||||
{
|
||||
ContextMenu_InstantiatePrefab();
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
// Instantiate Procedural Prefab
|
||||
if (AZ::Prefab::ProceduralPrefabAsset::UseProceduralPrefabs())
|
||||
@@ -324,7 +403,8 @@ namespace AzToolsFramework
|
||||
[]
|
||||
{
|
||||
ContextMenu_InstantiateProceduralPrefab();
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
itemWasShown = true;
|
||||
@@ -335,9 +415,7 @@ namespace AzToolsFramework
|
||||
menu->addSeparator();
|
||||
}
|
||||
|
||||
itemWasShown = false;
|
||||
|
||||
// Edit/Save Prefab
|
||||
// Save Prefab
|
||||
{
|
||||
if (selectedEntities.size() == 1)
|
||||
{
|
||||
@@ -345,52 +423,6 @@ 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);
|
||||
@@ -405,17 +437,43 @@ namespace AzToolsFramework
|
||||
[selectedEntity]
|
||||
{
|
||||
ContextMenu_SavePrefab(selectedEntity);
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
itemWasShown = true;
|
||||
menu->addSeparator();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (itemWasShown)
|
||||
if (!selectedEntities.empty())
|
||||
{
|
||||
menu->addSeparator();
|
||||
// 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();
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (!selectedEntities.empty() &&
|
||||
@@ -424,27 +482,17 @@ namespace AzToolsFramework
|
||||
!readOnlyEntityInSelection)
|
||||
{
|
||||
QAction* deleteAction = menu->addAction(QObject::tr("Delete"));
|
||||
deleteAction->setShortcut(QKeySequence(Qt::Key_Delete));
|
||||
QObject::connect(
|
||||
deleteAction, &QAction::triggered, deleteAction,
|
||||
[]
|
||||
{
|
||||
ContextMenu_DeleteSelected();
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// 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);
|
||||
});
|
||||
}
|
||||
menu->addSeparator();
|
||||
}
|
||||
|
||||
void PrefabIntegrationManager::OnEscape()
|
||||
@@ -653,6 +701,12 @@ namespace AzToolsFramework
|
||||
}
|
||||
}
|
||||
|
||||
void PrefabIntegrationManager::ContextMenu_Duplicate()
|
||||
{
|
||||
bool handled = true;
|
||||
AzToolsFramework::EditorRequestBus::Broadcast(&AzToolsFramework::EditorRequests::CloneSelection, handled);
|
||||
}
|
||||
|
||||
void PrefabIntegrationManager::ContextMenu_DeleteSelected()
|
||||
{
|
||||
AzToolsFramework::EntityIdList selectedEntityIds;
|
||||
|
||||
@@ -92,6 +92,7 @@ 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,6 +20,7 @@
|
||||
#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>
|
||||
@@ -1951,7 +1952,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 = RoundUp(bufferSize * numBuffers, m_pageSize);
|
||||
AZ::u64 totalBufferSize = AZ::RoundUpToMultiple(bufferSize * numBuffers, m_pageSize);
|
||||
|
||||
if (amountAllocated != nullptr)
|
||||
{
|
||||
|
||||
@@ -221,18 +221,6 @@ 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;
|
||||
AzFramework::StringFunc::Tokenize(parameters.c_str(), files, ";");
|
||||
AZ::StringFunc::Tokenize(parameters.c_str(), files, ";");
|
||||
if (!files.empty())
|
||||
{
|
||||
for (const auto& file : files)
|
||||
@@ -669,9 +669,12 @@ namespace LUAEditor
|
||||
return;
|
||||
}
|
||||
|
||||
const AzFramework::CommandLine* commandLine = nullptr;
|
||||
const AZ::CommandLine* commandLine = nullptr;
|
||||
|
||||
EBUS_EVENT_RESULT(commandLine, LegacyFramework::FrameworkApplicationMessages::Bus, GetCommandLineParser);
|
||||
AZ::ComponentApplicationBus::Broadcast([&commandLine](AZ::ComponentApplicationRequests* requests)
|
||||
{
|
||||
commandLine = requests->GetAzCommandLine();
|
||||
});
|
||||
|
||||
bool forceShow = false;
|
||||
bool forceHide = false;
|
||||
@@ -850,7 +853,7 @@ namespace LUAEditor
|
||||
DocumentInfo& info = infoEntry.first->second;
|
||||
info.m_assetId = normalizedAssetId;
|
||||
info.m_assetName = assetId;
|
||||
AzFramework::StringFunc::Path::GetFullFileName(assetId.c_str(), info.m_displayName);
|
||||
AZ::StringFunc::Path::GetFullFileName(assetId.c_str(), info.m_displayName);
|
||||
info.m_bSourceControl_Ready = true;
|
||||
info.m_bSourceControl_CanWrite = true;
|
||||
info.m_bUntitledDocument = false;
|
||||
@@ -945,7 +948,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 (AzFramework::StringFunc::Find(newAssetName.c_str(), ".lua") == AZStd::string::npos)
|
||||
if (AZ::StringFunc::Find(newAssetName.c_str(), ".lua") == AZStd::string::npos)
|
||||
{
|
||||
newAssetName += ".lua";
|
||||
}
|
||||
@@ -961,7 +964,7 @@ namespace LUAEditor
|
||||
|
||||
trySaveAs = false;
|
||||
docInfoIter->second.m_bUntitledDocument = false;
|
||||
AzFramework::StringFunc::Path::GetFullFileName(newAssetName.c_str(), docInfoIter->second.m_displayName);
|
||||
AZ::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;
|
||||
@@ -1489,7 +1492,7 @@ namespace LUAEditor
|
||||
|
||||
DocumentInfo info;
|
||||
info.m_assetName = assetIdLower;
|
||||
AzFramework::StringFunc::Path::GetFullFileName(assetId.c_str(), info.m_displayName);
|
||||
AZ::StringFunc::Path::GetFullFileName(assetId.c_str(), info.m_displayName);
|
||||
info.m_assetId = assetIdLower;
|
||||
info.m_bSourceControl_BusyGettingStats = true;
|
||||
info.m_bSourceControl_BusyGettingStats = false;
|
||||
@@ -1555,7 +1558,10 @@ namespace LUAEditor
|
||||
const AZStd::string k_luaScriptFileString = "files";
|
||||
|
||||
const AzFramework::CommandLine* commandLine = nullptr;
|
||||
EBUS_EVENT_RESULT(commandLine, LegacyFramework::FrameworkApplicationMessages::Bus, GetCommandLineParser);
|
||||
AZ::ComponentApplicationBus::Broadcast([&commandLine](AZ::ComponentApplicationRequests* requests)
|
||||
{
|
||||
commandLine = requests->GetAzCommandLine();
|
||||
});
|
||||
|
||||
AZStd::string parameters = "";
|
||||
size_t numSwitchValues = commandLine->GetNumSwitchValues(k_luaScriptFileString);
|
||||
@@ -2448,7 +2454,7 @@ namespace LUAEditor
|
||||
if (matchFound)
|
||||
{
|
||||
int lineNumber = 0;
|
||||
if (AzFramework::StringFunc::LooksLikeInt(match[1].str().c_str(), &lineNumber))
|
||||
if (AZ::StringFunc::LooksLikeInt(match[1].str().c_str(), &lineNumber))
|
||||
{
|
||||
errorData->m_lineNumber = lineNumber;
|
||||
finalMessage = match[2].str().c_str();
|
||||
@@ -2467,6 +2473,6 @@ namespace LUAEditor
|
||||
|
||||
bool Context::IsLuaAsset(const AZStd::string& assetPath)
|
||||
{
|
||||
return AzFramework::StringFunc::Path::IsExtension(assetPath.c_str(), ".lua");
|
||||
return AZ::StringFunc::Path::IsExtension(assetPath.c_str(), ".lua");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,8 @@
|
||||
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&, char**)
|
||||
: LegacyFramework::Application()
|
||||
BaseApplication::BaseApplication(int argc, char** argv)
|
||||
: LegacyFramework::Application(argc, argv)
|
||||
{
|
||||
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 = ((srcImage->GetWidth(0)+ dstFormatInfo->blockWidth-1)/dstFormatInfo->blockWidth) * ((srcImage->GetHeight(0) + dstFormatInfo->blockHeight-1)/dstFormatInfo->blockHeight);
|
||||
AZ::u32 blockCount = AZ::DivideAndRoundUp(srcImage->GetWidth(0), dstFormatInfo->blockWidth) * AZ::DivideAndRoundUp(srcImage->GetHeight(0), 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,6 +10,8 @@
|
||||
#include <Processing/PixelFormatInfo.h>
|
||||
#include <Processing/DDSHeader.h>
|
||||
|
||||
#include <AzCore/Math/MathUtils.h>
|
||||
|
||||
namespace ImageProcessingAtom
|
||||
{
|
||||
CPixelFormats* CPixelFormats::s_instance = nullptr;
|
||||
@@ -370,11 +372,11 @@ namespace ImageProcessingAtom
|
||||
{
|
||||
if (outWidth % pFormatInfo->blockWidth != 0)
|
||||
{
|
||||
outWidth = ((outWidth + pFormatInfo->blockWidth - 1) / pFormatInfo->blockWidth) * pFormatInfo->blockWidth;
|
||||
outWidth = AZ::RoundUpToMultiple(outWidth, pFormatInfo->blockWidth);
|
||||
}
|
||||
if (outHeight % pFormatInfo->blockHeight != 0)
|
||||
{
|
||||
outHeight = ((outHeight + pFormatInfo->blockHeight - 1) / pFormatInfo->blockHeight) * pFormatInfo->blockHeight;
|
||||
outHeight = AZ::RoundUpToMultiple(outHeight, pFormatInfo->blockHeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -390,10 +392,11 @@ namespace ImageProcessingAtom
|
||||
return 0;
|
||||
}
|
||||
|
||||
// get number of blocks (ceiling round up for block count) and multiply with bits per block. Divided by 8 to get
|
||||
// get number of blocks and multiply with bits per block. Divided by 8 to get
|
||||
// final byte size
|
||||
return (((imageWidth + pFormatInfo->blockWidth - 1) / pFormatInfo->blockWidth) *
|
||||
((imageHeight + pFormatInfo->blockHeight - 1) / pFormatInfo->blockHeight) * pFormatInfo->bitsPerBlock) / 8;
|
||||
return (AZ::DivideAndRoundUp(imageWidth, pFormatInfo->blockWidth) *
|
||||
AZ::DivideAndRoundUp(imageHeight, pFormatInfo->blockHeight) *
|
||||
pFormatInfo->bitsPerBlock) / 8;
|
||||
}
|
||||
|
||||
bool CPixelFormats::IsFormatSingleChannel(EPixelFormat fmt)
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/base.h>
|
||||
#include <AzCore/Math/MathUtils.h>
|
||||
|
||||
#ifndef AZ_BIT
|
||||
#define AZ_BIT(x) (1u << x)
|
||||
@@ -237,6 +238,7 @@ 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 = DivideByMultiple(constantBytes.size(), elementSize);
|
||||
const size_t elementCount = AZ::DivideAndRoundUp(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>((m_totalNumberOfThreadsX + m_threadsPerGroupX - 1) / m_threadsPerGroupX);
|
||||
return aznumeric_cast<uint16_t>(DivideAndRoundUp(m_totalNumberOfThreadsX, aznumeric_caster(m_threadsPerGroupX)));
|
||||
}
|
||||
|
||||
uint16_t GetNumberOfGroupsY() const
|
||||
{
|
||||
return aznumeric_cast<uint16_t>((m_totalNumberOfThreadsY + m_threadsPerGroupY - 1) / m_threadsPerGroupY);
|
||||
return aznumeric_cast<uint16_t>(DivideAndRoundUp(m_totalNumberOfThreadsY, aznumeric_caster(m_threadsPerGroupY)));
|
||||
}
|
||||
|
||||
uint16_t GetNumberOfGroupsZ() const
|
||||
{
|
||||
return aznumeric_cast<uint16_t>((m_totalNumberOfThreadsZ + m_threadsPerGroupZ - 1) / m_threadsPerGroupZ);
|
||||
return aznumeric_cast<uint16_t>(DivideAndRoundUp(m_totalNumberOfThreadsZ, aznumeric_caster(m_threadsPerGroupZ)));
|
||||
}
|
||||
|
||||
// Different platforms require number of groups or number of threads or both in their Dispatch() call
|
||||
|
||||
@@ -358,8 +358,7 @@ namespace AZ
|
||||
}
|
||||
else
|
||||
{
|
||||
const uint32_t bitsPerPixel = RHI::GetFormatSize(imageFormat) * 8;
|
||||
subresourceLayout.m_bytesPerRow = (imageSize.m_width * bitsPerPixel + 7) / 8; // round up to nearest byte
|
||||
subresourceLayout.m_bytesPerRow = imageSize.m_width * RHI::GetFormatSize(imageFormat);
|
||||
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 = DivideByMultiple(drawList.size(), partitionCount);
|
||||
const size_t itemsPerPartition = AZ::DivideAndRoundUp(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 = DivideByMultiple(compilesInPool, compilesPerJob);
|
||||
const uint32_t jobCount = AZ::DivideAndRoundUp(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 = DivideByMultiple(compilesInPool, compilesPerJob);
|
||||
const uint32_t jobCount = AZ::DivideAndRoundUp(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.");
|
||||
AZ_Assert(isAttach || isDetach, "The frame attachment for resource '%s' was not assigned properly.", GetName().GetCStr());
|
||||
}
|
||||
|
||||
m_frameAttachment = frameAttachment;
|
||||
|
||||
@@ -92,7 +92,7 @@ namespace AZ
|
||||
const uint32_t CommandListCostThreshold =
|
||||
AZStd::max(
|
||||
m_frameGraphExecuterData.m_commandListCostThresholdMin,
|
||||
RHI::DivideByMultiple(estimatedItemCount, m_frameGraphExecuterData.m_commandListsPerScopeMax));
|
||||
AZ::DivideAndRoundUp(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(RHI::DivideByMultiple(totalScopeCost, CommandListCostThreshold), 1u);
|
||||
const uint32_t commandListCount = AZStd::max(AZ::DivideAndRoundUp(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,
|
||||
RHI::DivideByMultiple(estimatedItemCount, m_frameGraphExecuterData.m_commandListsPerScopeMax));
|
||||
AZ::DivideAndRoundUp(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(RHI::DivideByMultiple(totalScopeCost, CommandListCostThreshold), 1u);
|
||||
const uint32_t commandListCount = AZStd::max(AZ::DivideAndRoundUp(totalScopeCost, CommandListCostThreshold), 1u);
|
||||
|
||||
FrameGraphExecuteGroup* scopeContextGroup = AddGroup<FrameGraphExecuteGroup>();
|
||||
scopeContextGroup->Init(device, scope, commandListCount, GetJobPolicy());
|
||||
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* 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
|
||||
+13
-4
@@ -9,8 +9,12 @@
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
#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>
|
||||
|
||||
AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option") // disable warnings spawned by QT
|
||||
#include <QVBoxLayout>
|
||||
@@ -36,8 +40,10 @@ 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);
|
||||
|
||||
explicit InspectorWidget(QWidget* parent = nullptr);
|
||||
InspectorWidget(QWidget* parent = nullptr);
|
||||
~InspectorWidget() override;
|
||||
|
||||
// InspectorRequestBus::Handler overrides...
|
||||
@@ -74,6 +80,8 @@ 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);
|
||||
@@ -81,14 +89,15 @@ 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
|
||||
|
||||
-16
@@ -11,14 +11,8 @@
|
||||
#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
|
||||
@@ -52,14 +46,4 @@ 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,9 +9,12 @@
|
||||
#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>
|
||||
@@ -23,14 +26,6 @@ class QImage;
|
||||
|
||||
namespace AtomToolsFramework
|
||||
{
|
||||
template<typename T>
|
||||
T GetSettingOrDefault(AZStd::string_view path, const T& defaultValue)
|
||||
{
|
||||
T result;
|
||||
auto settingsRegistry = AZ::SettingsRegistry::Get();
|
||||
return (settingsRegistry && settingsRegistry->Get(result, path)) ? result : defaultValue;
|
||||
}
|
||||
|
||||
using LoadImageAsyncCallback = AZStd::function<void(const QImage&)>;
|
||||
void LoadImageAsync(const AZStd::string& path, LoadImageAsyncCallback callback);
|
||||
|
||||
@@ -39,4 +34,64 @@ namespace AtomToolsFramework
|
||||
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 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);
|
||||
}
|
||||
|
||||
bool SaveSettingsToFile(const AZ::IO::FixedMaxPath& savePath, const AZStd::vector<AZStd::string>& filters);
|
||||
} // namespace AtomToolsFramework
|
||||
|
||||
+3
@@ -10,6 +10,7 @@
|
||||
|
||||
#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>
|
||||
|
||||
@@ -120,6 +121,8 @@ 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
|
||||
|
||||
+10
@@ -9,6 +9,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/EBus/EBus.h>
|
||||
#include <AzCore/std/smart_ptr/shared_ptr.h>
|
||||
#include <AzFramework/Viewport/ViewportId.h>
|
||||
|
||||
namespace AZ
|
||||
@@ -16,6 +17,11 @@ namespace AZ
|
||||
class Transform;
|
||||
}
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
class CameraInput;
|
||||
}
|
||||
|
||||
namespace AtomToolsFramework
|
||||
{
|
||||
//! Provides an interface to control the modern viewport camera controller from the Editor.
|
||||
@@ -54,6 +60,10 @@ 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;
|
||||
|
||||
+1
@@ -29,6 +29,7 @@ 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;
|
||||
|
||||
+10
-4
@@ -70,9 +70,9 @@ namespace AtomToolsFramework
|
||||
m_styleManager->initialize(this, engineRootPath);
|
||||
|
||||
const int updateIntervalWhenActive =
|
||||
aznumeric_cast<int>(GetSettingOrDefault<AZ::u64>("/O3DE/AtomToolsFramework/Application/UpdateIntervalWhenActive", 1));
|
||||
aznumeric_cast<int>(GetSettingsValue<AZ::u64>("/O3DE/AtomToolsFramework/Application/UpdateIntervalWhenActive", 1));
|
||||
const int updateIntervalWhenNotActive =
|
||||
aznumeric_cast<int>(GetSettingOrDefault<AZ::u64>("/O3DE/AtomToolsFramework/Application/UpdateIntervalWhenNotActive", 64));
|
||||
aznumeric_cast<int>(GetSettingsValue<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 = GetSettingOrDefault("/O3DE/AtomToolsFramework/Application/ClearLogOnStart", false);
|
||||
const bool clearLogFile = GetSettingsValue("/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 = GetSettingOrDefault("/O3DE/AtomToolsFramework/Application/EnableSourceControl", true);
|
||||
const bool enableSourceControl = GetSettingsValue("/O3DE/AtomToolsFramework/Application/EnableSourceControl", true);
|
||||
AzToolsFramework::SourceControlConnectionRequestBus::Broadcast(
|
||||
&AzToolsFramework::SourceControlConnectionRequests::EnableSourceControl, enableSourceControl);
|
||||
|
||||
@@ -238,6 +238,12 @@ 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();
|
||||
|
||||
+2
-2
@@ -106,9 +106,9 @@ namespace AtomToolsFramework
|
||||
const AZStd::vector<AssetBrowserEntry*> entries = m_ui->m_assetBrowserTreeViewWidget->GetSelectedAssets();
|
||||
|
||||
const bool promptToOpenMultipleFiles =
|
||||
GetSettingOrDefault<bool>("/O3DE/AtomToolsFramework/AssetBrowser/PromptToOpenMultipleFiles", true);
|
||||
GetSettingsValue<bool>("/O3DE/AtomToolsFramework/AssetBrowser/PromptToOpenMultipleFiles", true);
|
||||
const AZ::u64 promptToOpenMultipleFilesThreshold =
|
||||
GetSettingOrDefault<AZ::u64>("/O3DE/AtomToolsFramework/AssetBrowser/PromptToOpenMultipleFilesThreshold", 10);
|
||||
GetSettingsValue<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::GetSettingOrDefault<AZ::u64>("/O3DE/Atom/AtomToolsFramework/AssetGridDialog/ItemBorder", 4));
|
||||
AtomToolsFramework::GetSettingsValue<AZ::u64>("/O3DE/AtomToolsFramework/AssetGridDialog/ItemBorder", 4));
|
||||
const int itemSpacing = aznumeric_cast<int>(
|
||||
AtomToolsFramework::GetSettingOrDefault<AZ::u64>("/O3DE/Atom/AtomToolsFramework/AssetGridDialog/ItemSpacing", 10));
|
||||
AtomToolsFramework::GetSettingsValue<AZ::u64>("/O3DE/AtomToolsFramework/AssetGridDialog/ItemSpacing", 10));
|
||||
const int headerHeight = aznumeric_cast<int>(
|
||||
AtomToolsFramework::GetSettingOrDefault<AZ::u64>("/O3DE/Atom/AtomToolsFramework/AssetGridDialog/HeaderHeight", 15));
|
||||
AtomToolsFramework::GetSettingsValue<AZ::u64>("/O3DE/AtomToolsFramework/AssetGridDialog/HeaderHeight", 15));
|
||||
|
||||
const QSize gridSize = m_ui->m_assetList->gridSize();
|
||||
m_ui->m_assetList->setGridSize(QSize(
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#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
|
||||
@@ -23,6 +24,7 @@ namespace AtomToolsFramework
|
||||
DynamicPropertyGroup::Reflect(context);
|
||||
AtomToolsDocument::Reflect(context);
|
||||
AtomToolsDocumentSystem::Reflect(context);
|
||||
InspectorWidget::Reflect(context);
|
||||
|
||||
if (auto serialize = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
{
|
||||
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* 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>
|
||||
+1
-1
@@ -500,4 +500,4 @@ namespace AtomToolsFramework
|
||||
}
|
||||
} // namespace AtomToolsFramework
|
||||
|
||||
//#include <Document/moc_AtomToolsDocumentMainWindow.cpp>
|
||||
//#include <AtomToolsFramework/Document/moc_AtomToolsDocumentMainWindow.cpp>
|
||||
|
||||
@@ -368,7 +368,7 @@ namespace AtomToolsFramework
|
||||
|
||||
void AtomToolsDocumentSystem::ReopenDocuments()
|
||||
{
|
||||
const bool enableHotReload = GetSettingOrDefault<bool>("/O3DE/AtomToolsFramework/AtomToolsDocumentSystem/EnableHotReload", true);
|
||||
const bool enableHotReload = GetSettingsValue<bool>("/O3DE/AtomToolsFramework/AtomToolsDocumentSystem/EnableHotReload", true);
|
||||
if (!enableHotReload)
|
||||
{
|
||||
m_documentIdsWithDependencyChanges.clear();
|
||||
@@ -377,7 +377,7 @@ namespace AtomToolsFramework
|
||||
}
|
||||
|
||||
const bool enableHotReloadPrompts =
|
||||
GetSettingOrDefault<bool>("/O3DE/AtomToolsFramework/AtomToolsDocumentSystem/EnableHotReloadPrompts", true);
|
||||
GetSettingsValue<bool>("/O3DE/AtomToolsFramework/AtomToolsDocumentSystem/EnableHotReloadPrompts", true);
|
||||
|
||||
for (const AZ::Uuid& documentId : m_documentIdsWithExternalChanges)
|
||||
{
|
||||
|
||||
@@ -6,27 +6,69 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#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)
|
||||
@@ -52,6 +94,7 @@ namespace AtomToolsFramework
|
||||
delete child;
|
||||
}
|
||||
m_groups.clear();
|
||||
InspectorRequestBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
void InspectorWidget::AddGroupsBegin()
|
||||
@@ -202,20 +245,31 @@ 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
|
||||
{
|
||||
AZ_UNUSED(groupName);
|
||||
return true;
|
||||
auto stateItr = m_collapsedGroups.find(AZ::Crc32(groupName));
|
||||
return stateItr == m_collapsedGroups.end();
|
||||
}
|
||||
|
||||
void InspectorWidget::OnGroupExpanded(const AZStd::string& groupName)
|
||||
{
|
||||
AZ_UNUSED(groupName);
|
||||
m_collapsedGroups.erase(AZ::Crc32(groupName));
|
||||
}
|
||||
|
||||
void InspectorWidget::OnGroupCollapsed(const AZStd::string& groupName)
|
||||
{
|
||||
AZ_UNUSED(groupName);
|
||||
m_collapsedGroups.insert(AZ::Crc32(groupName));
|
||||
}
|
||||
|
||||
void InspectorWidget::OnHeaderClicked(const AZStd::string& groupName, QMouseEvent* event)
|
||||
|
||||
@@ -6,21 +6,18 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#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
|
||||
{
|
||||
@@ -223,51 +220,4 @@ 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,13 +8,18 @@
|
||||
|
||||
#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>
|
||||
@@ -178,4 +183,74 @@ 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
|
||||
|
||||
+11
@@ -294,6 +294,17 @@ 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/MaterialPropertyUtil.h>
|
||||
#include <AtomToolsFramework/Util/Util.h>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
|
||||
@@ -15,6 +15,7 @@ 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
|
||||
@@ -51,6 +52,7 @@ 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,6 +18,7 @@
|
||||
#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>
|
||||
|
||||
+1
-1
@@ -64,7 +64,7 @@ namespace MaterialEditor
|
||||
|
||||
m_ui->m_materialTypeComboBox->model()->sort(0, Qt::AscendingOrder);
|
||||
|
||||
const AZStd::string defaultMaterialType = AtomToolsFramework::GetSettingOrDefault<AZStd::string>(
|
||||
const AZStd::string defaultMaterialType = AtomToolsFramework::GetSettingsValue<AZStd::string>(
|
||||
"/O3DE/Atom/MaterialEditor/CreateMaterialDialog/DefaultMaterialType", "StandardPBR");
|
||||
|
||||
const int index = m_ui->m_materialTypeComboBox->findText(defaultMaterialType.c_str());
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
#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>
|
||||
@@ -17,7 +19,6 @@
|
||||
#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>
|
||||
|
||||
@@ -78,7 +79,20 @@ namespace MaterialEditor
|
||||
QDesktopServices::openUrl(QUrl::fromLocalFile(absolutePath.c_str()));
|
||||
});
|
||||
|
||||
AddDockWidget("Inspector", new MaterialInspector(m_toolId), Qt::RightDockWidgetArea, Qt::Vertical);
|
||||
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("Viewport Settings", new ViewportSettingsInspector, Qt::LeftDockWidgetArea, Qt::Vertical);
|
||||
SetDockWidgetVisible("Viewport Settings", false);
|
||||
|
||||
@@ -98,6 +112,12 @@ 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,6 +9,7 @@
|
||||
#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
|
||||
@@ -35,10 +36,15 @@ 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;
|
||||
@@ -47,6 +53,7 @@ namespace MaterialEditor
|
||||
|
||||
void closeEvent(QCloseEvent* closeEvent) override;
|
||||
|
||||
AtomToolsFramework::AtomToolsDocumentInspector* m_materialInspector = {};
|
||||
MaterialViewportWidget* m_materialViewport = {};
|
||||
MaterialEditorToolBar* m_toolBar = {};
|
||||
};
|
||||
|
||||
@@ -19,7 +19,6 @@ 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,6 +27,5 @@ namespace MaterialEditor
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
AZStd::vector<char> m_mainWindowState;
|
||||
AZStd::unordered_set<AZ::u32> m_inspectorCollapsedGroups;
|
||||
};
|
||||
} // namespace MaterialEditor
|
||||
|
||||
-159
@@ -1,159 +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 <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>
|
||||
-71
@@ -1,71 +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/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 <Window/SettingsDialog/SettingsWidget.h>
|
||||
#include <AtomToolsFramework/Inspector/InspectorPropertyGroupWidget.h>
|
||||
#include <Window/SettingsDialog/SettingsWidget.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,7 +29,6 @@ namespace MaterialEditor
|
||||
|
||||
void SettingsWidget::Reset()
|
||||
{
|
||||
AtomToolsFramework::InspectorRequestBus::Handler::BusDisconnect();
|
||||
AtomToolsFramework::InspectorWidget::Reset();
|
||||
}
|
||||
} // namespace MaterialEditor
|
||||
|
||||
+3
-24
@@ -32,9 +32,7 @@ namespace MaterialEditor
|
||||
m_viewportSettings =
|
||||
AZ::UserSettings::CreateFind<MaterialViewportSettings>(AZ::Crc32("MaterialViewportSettings"), AZ::UserSettings::CT_GLOBAL);
|
||||
|
||||
m_windowSettings = AZ::UserSettings::CreateFind<MaterialEditorWindowSettings>(
|
||||
AZ::Crc32("MaterialEditorWindowSettings"), AZ::UserSettings::CT_GLOBAL);
|
||||
|
||||
SetGroupSettingsPrefix("/O3DE/Atom/MaterialEditor/ViewportSettingsInspector");
|
||||
MaterialViewportNotificationBus::Handler::BusConnect();
|
||||
}
|
||||
|
||||
@@ -43,7 +41,6 @@ namespace MaterialEditor
|
||||
m_lightingPreset.reset();
|
||||
m_modelPreset.reset();
|
||||
MaterialViewportNotificationBus::Handler::BusDisconnect();
|
||||
AtomToolsFramework::InspectorRequestBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
void ViewportSettingsInspector::Populate()
|
||||
@@ -144,7 +141,7 @@ namespace MaterialEditor
|
||||
});
|
||||
|
||||
const int itemSize = aznumeric_cast<int>(
|
||||
AtomToolsFramework::GetSettingOrDefault<AZ::u64>("/O3DE/Atom/MaterialEditor/AssetGridDialog/ModelItemSize", 180));
|
||||
AtomToolsFramework::GetSettingsValue<AZ::u64>("/O3DE/Atom/MaterialEditor/AssetGridDialog/ModelItemSize", 180));
|
||||
|
||||
AtomToolsFramework::AssetGridDialog dialog(
|
||||
"Model Preset Browser", selectableAssets, selectedAsset, QSize(itemSize, itemSize), QApplication::activeWindow());
|
||||
@@ -270,7 +267,7 @@ namespace MaterialEditor
|
||||
});
|
||||
|
||||
const int itemSize = aznumeric_cast<int>(
|
||||
AtomToolsFramework::GetSettingOrDefault<AZ::u64>("/O3DE/Atom/MaterialEditor/AssetGridDialog/LightingItemSize", 180));
|
||||
AtomToolsFramework::GetSettingsValue<AZ::u64>("/O3DE/Atom/MaterialEditor/AssetGridDialog/LightingItemSize", 180));
|
||||
|
||||
AtomToolsFramework::AssetGridDialog dialog(
|
||||
"Lighting Preset Browser", selectableAssets, selectedAsset, QSize(itemSize, itemSize), QApplication::activeWindow());
|
||||
@@ -338,7 +335,6 @@ namespace MaterialEditor
|
||||
m_viewportSettings->m_displayMapperOperationType = viewportRequests->GetDisplayMapperOperationType();
|
||||
});
|
||||
|
||||
AtomToolsFramework::InspectorRequestBus::Handler::BusDisconnect();
|
||||
AtomToolsFramework::InspectorWidget::Reset();
|
||||
}
|
||||
|
||||
@@ -433,23 +429,6 @@ 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>
|
||||
|
||||
-5
@@ -16,7 +16,6 @@
|
||||
#include <AzToolsFramework/UI/PropertyEditor/PropertyEditorAPI_Internals.h>
|
||||
#include <Viewport/MaterialViewportNotificationBus.h>
|
||||
#include <Viewport/MaterialViewportSettings.h>
|
||||
#include <Window/MaterialEditorWindowSettings.h>
|
||||
#endif
|
||||
|
||||
namespace MaterialEditor
|
||||
@@ -75,13 +74,9 @@ 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,8 +46,6 @@ 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
|
||||
)
|
||||
|
||||
+8
-10
@@ -14,8 +14,11 @@
|
||||
#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/MaterialPropertiesLayout.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 <AtomToolsFramework/Inspector/InspectorPropertyGroupWidget.h>
|
||||
#include <AtomToolsFramework/Util/MaterialPropertyUtil.h>
|
||||
#include <AtomToolsFramework/Util/Util.h>
|
||||
@@ -24,9 +27,6 @@
|
||||
#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,7 +54,6 @@ namespace AZ
|
||||
|
||||
MaterialPropertyInspector::~MaterialPropertyInspector()
|
||||
{
|
||||
AtomToolsFramework::InspectorRequestBus::Handler::BusDisconnect();
|
||||
AZ::TickBus::Handler::BusDisconnect();
|
||||
AZ::EntitySystemBus::Handler::BusDisconnect();
|
||||
EditorMaterialSystemComponentNotificationBus::Handler::BusDisconnect();
|
||||
@@ -137,7 +136,6 @@ namespace AZ
|
||||
m_dirtyPropertyFlags.set();
|
||||
m_internalEditNotification = {};
|
||||
|
||||
AtomToolsFramework::InspectorRequestBus::Handler::BusDisconnect();
|
||||
AtomToolsFramework::InspectorWidget::Reset();
|
||||
}
|
||||
|
||||
@@ -590,7 +588,7 @@ namespace AZ
|
||||
|
||||
bool MaterialPropertyInspector::IsInstanceNodePropertyModifed(const AzToolsFramework::InstanceDataNode* node) const
|
||||
{
|
||||
const AtomToolsFramework::DynamicProperty* property = AtomToolsFramework::FindDynamicPropertyForInstanceDataNode(node);
|
||||
const auto property = AtomToolsFramework::FindAncestorInstanceDataNodeByType<AtomToolsFramework::DynamicProperty>(node);
|
||||
return property && !AtomToolsFramework::ArePropertyValuesEqual(property->GetValue(), property->GetConfig().m_parentValue);
|
||||
}
|
||||
|
||||
@@ -719,7 +717,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 AtomToolsFramework::DynamicProperty* property = AtomToolsFramework::FindDynamicPropertyForInstanceDataNode(pNode);
|
||||
const auto property = AtomToolsFramework::FindAncestorInstanceDataNodeByType<AtomToolsFramework::DynamicProperty>(pNode);
|
||||
if (property)
|
||||
{
|
||||
if (m_activeProperty != property)
|
||||
@@ -731,7 +729,7 @@ namespace AZ
|
||||
|
||||
void MaterialPropertyInspector::AfterPropertyModified(AzToolsFramework::InstanceDataNode* pNode)
|
||||
{
|
||||
const AtomToolsFramework::DynamicProperty* property = AtomToolsFramework::FindDynamicPropertyForInstanceDataNode(pNode);
|
||||
const auto property = AtomToolsFramework::FindAncestorInstanceDataNodeByType<AtomToolsFramework::DynamicProperty>(pNode);
|
||||
if (property)
|
||||
{
|
||||
if (m_activeProperty == property)
|
||||
@@ -748,7 +746,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 AtomToolsFramework::DynamicProperty* property = AtomToolsFramework::FindDynamicPropertyForInstanceDataNode(pNode);
|
||||
const auto property = AtomToolsFramework::FindAncestorInstanceDataNodeByType<AtomToolsFramework::DynamicProperty>(pNode);
|
||||
if (property)
|
||||
{
|
||||
if (m_activeProperty == property)
|
||||
|
||||
+2
-1
@@ -15,10 +15,11 @@
|
||||
#include <Atom/RPI.Edit/Material/MaterialTypeSourceData.h>
|
||||
#include <Atom/RPI.Edit/Material/MaterialUtils.h>
|
||||
#include <Atom/RPI.Reflect/Material/MaterialAsset.h>
|
||||
#include <Atom/RPI.Reflect/Material/MaterialNameContext.h>
|
||||
#include <Atom/RPI.Reflect/Material/MaterialPropertiesLayout.h>
|
||||
#include <Atom/RPI.Reflect/Material/MaterialTypeAsset.h>
|
||||
#include <Atom/RPI.Reflect/Material/MaterialNameContext.h>
|
||||
#include <AtomToolsFramework/Util/MaterialPropertyUtil.h>
|
||||
#include <AtomToolsFramework/Util/Util.h>
|
||||
#include <AzFramework/API/ApplicationAPI.h>
|
||||
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
|
||||
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user