Merge branch 'development' into cleanup/SPEC-1670

This commit is contained in:
Esteban Papp
2021-07-14 14:53:59 -07:00
116 changed files with 6068 additions and 3529 deletions
@@ -6,13 +6,13 @@ SPDX-License-Identifier: Apache-2.0 OR MIT
import logging
import os
import tempfile
import psutil
import ly_test_tools.log.log_monitor
import ly_test_tools.environment.process_utils as process_utils
import ly_test_tools.environment.waiter as waiter
from ly_remote_console.remote_console_commands import RemoteConsole as RemoteConsole
from ly_remote_console.remote_console_commands import send_command_and_expect_response as send_command_and_expect_response
logger = logging.getLogger(__name__)
@@ -95,7 +95,7 @@ def launch_and_validate_results_launcher(launcher, level, remote_console_instanc
return port_listening
if null_renderer:
launcher.args.extend(["-NullRenderer"])
launcher.args.extend(["-rhi=Null"])
# Start the Launcher
with launcher.start():
@@ -110,8 +110,8 @@ def launch_and_validate_results_launcher(launcher, level, remote_console_instanc
# Load the specified level in the launcher
send_command_and_expect_response(remote_console_instance,
f"map {level}",
"LEVEL_LOAD_COMPLETE", timeout=30)
f"LoadLevel {level}",
"LEVEL_LOAD_END", timeout=30)
# Monitor the console for expected lines
for line in expected_lines:
@@ -77,7 +77,6 @@ class TestAllComponentsIndepthTests(object):
unexpected_lines=unexpected_lines,
halt_on_unexpected=True,
cfg_args=[level],
auto_test_mode=False,
null_renderer=False,
)
@@ -60,24 +60,7 @@ class TestEditMenuOptions(EditorTestHelper):
("Modify", "Transform Mode", "Rotate"),
("Modify", "Transform Mode", "Scale"),
("Editor Settings", "Global Preferences"),
("Editor Settings", "Graphics Settings"),
("Editor Settings", "Editor Settings Manager"),
("Editor Settings", "Graphics Performance", "PC", "Very High"),
("Editor Settings", "Graphics Performance", "PC", "High"),
("Editor Settings", "Graphics Performance", "PC", "Medium"),
("Editor Settings", "Graphics Performance", "PC", "Low"),
("Editor Settings", "Graphics Performance", "OSX Metal", "Very High"),
("Editor Settings", "Graphics Performance", "OSX Metal", "High"),
("Editor Settings", "Graphics Performance", "OSX Metal", "Medium"),
("Editor Settings", "Graphics Performance", "OSX Metal", "Low"),
("Editor Settings", "Graphics Performance", "Android", "Very High"),
("Editor Settings", "Graphics Performance", "Android", "High"),
("Editor Settings", "Graphics Performance", "Android", "Medium"),
("Editor Settings", "Graphics Performance", "Android", "Low"),
("Editor Settings", "Graphics Performance", "iOS", "Very High"),
("Editor Settings", "Graphics Performance", "iOS", "High"),
("Editor Settings", "Graphics Performance", "iOS", "Medium"),
("Editor Settings", "Graphics Performance", "iOS", "Low"),
("Editor Settings", "Keyboard Customization", "Customize Keyboard"),
("Editor Settings", "Keyboard Customization", "Export Keyboard Settings"),
("Editor Settings", "Keyboard Customization", "Import Keyboard Settings"),
@@ -55,12 +55,7 @@ class TestMenus(object):
"Rotate Action triggered",
"Scale Action triggered",
"Global Preferences Action triggered",
"Graphics Settings Action triggered",
"Editor Settings Manager Action triggered",
"Very High Action triggered",
"High Action triggered",
"Medium Action triggered",
"Low Action triggered",
"Customize Keyboard Action triggered",
"Export Keyboard Settings Action triggered",
"Import Keyboard Settings Action triggered",
@@ -36,8 +36,8 @@ class TestAltitudeFilterFilterStageToggle(EditorTestHelper):
:return: None
"""
PREPROCESS_INSTANCE_COUNT = 24
POSTPROCESS_INSTANCE_COUNT = 18
PREPROCESS_INSTANCE_COUNT = 44
POSTPROCESS_INSTANCE_COUNT = 34
# Create empty level
self.test_success = self.create_level(
@@ -62,25 +62,7 @@ class TestAltitudeFilterFilterStageToggle(EditorTestHelper):
dynveg.create_surface_entity("Surface_Entity_Parent", position, 16.0, 16.0, 1.0)
# Add entity with Mesh to replicate creation of hills
hill_entity = dynveg.create_mesh_surface_entity_with_slopes("hill", position, 40.0, 40.0, 40.0)
# Disable/Re-enable Mesh component due to ATOM-14299
general.idle_wait(1.0)
editor.EditorComponentAPIBus(bus.Broadcast, 'DisableComponents', [hill_entity.components[0]])
is_enabled = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', hill_entity.components[0])
if is_enabled:
print("Mesh component is still enabled")
else:
print("Mesh component was disabled")
editor.EditorComponentAPIBus(bus.Broadcast, 'EnableComponents', [hill_entity.components[0]])
is_enabled = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', hill_entity.components[0])
if is_enabled:
print("Mesh component is now enabled")
else:
print("Mesh component is still disabled")
# Increase Box Shape size to encompass the hills
vegetation.get_set_test(1, "Box Shape|Box Configuration|Dimensions", math.Vector3(100.0, 100.0, 100.0))
hill_entity = dynveg.create_mesh_surface_entity_with_slopes("hill", position, 10.0)
# Set a Min Altitude of 38 and Max of 40 in Vegetation Altitude Filter
vegetation.get_set_test(3, "Configuration|Altitude Min", 38.0)
@@ -9,9 +9,10 @@ import sys
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
import azlmbr.asset as asset
import azlmbr.components as components
import azlmbr.legacy.general as general
import azlmbr.bus as bus
import azlmbr.entity as EntityId
import azlmbr.entity as entity
import azlmbr.editor as editor
import azlmbr.math as math
import azlmbr.paths
@@ -83,18 +84,12 @@ class TestDynamicSliceInstanceSpawnerEmbeddedEditor(EditorTestHelper):
self.log(f"Expected {num_expected_instances} instances - Found {num_found} instances")
self.test_success = self.test_success and num_found == num_expected_instances
# 5) Create a new entity with a Camera component for testing in the launcher
# 5) Move the default Camera entity for testing in the launcher
cam_position = math.Vector3(512.0, 500.0, 35.0)
camera_component = ["Camera"]
new_entity_id2 = editor.ToolsApplicationRequestBus(
bus.Broadcast, "CreateNewEntityAtPosition", cam_position, EntityId.EntityId()
)
if new_entity_id2.IsValid():
self.log("Camera entity created")
camera_entity = hydra.Entity("Camera Entity", new_entity_id2)
camera_entity.components = []
for component in camera_component:
camera_entity.components.append(hydra.add_component(component, new_entity_id2))
search_filter = entity.SearchFilter()
search_filter.names = ["Camera"]
search_entity_ids = entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter)
components.TransformBus(bus.Event, "MoveEntity", search_entity_ids[0], cam_position)
# 6) Save and export to engine
general.save_level()
@@ -11,7 +11,8 @@ sys.path.append(os.path.dirname(os.path.abspath(__file__)))
import azlmbr.legacy.general as general
import azlmbr.asset as asset
import azlmbr.bus as bus
import azlmbr.entity as EntityId
import azlmbr.components as components
import azlmbr.entity as entity
import azlmbr.editor as editor
import azlmbr.math as math
import azlmbr.paths
@@ -68,7 +69,7 @@ class TestDynamicSliceInstanceSpawnerExternalEditor(EditorTestHelper):
veg_area_required_components = ["Vegetation Layer Spawner", "Box Shape", "Vegetation Asset List",
"Script Canvas"]
new_entity_id = editor.ToolsApplicationRequestBus(
bus.Broadcast, "CreateNewEntityAtPosition", entity_position, EntityId.EntityId()
bus.Broadcast, "CreateNewEntityAtPosition", entity_position, entity.EntityId()
)
if new_entity_id.IsValid():
self.log("Spawner entity created")
@@ -106,18 +107,12 @@ class TestDynamicSliceInstanceSpawnerExternalEditor(EditorTestHelper):
self.log(f"Expected {num_expected_instances} instances - Found {num_found} instances")
self.test_success = self.test_success and num_found == num_expected_instances
# 5) Create a new entity with a Camera component for testing in the launcher
entity_position = math.Vector3(512.0, 500.0, 35.0)
camera_component = ["Camera"]
new_entity_id2 = editor.ToolsApplicationRequestBus(
bus.Broadcast, "CreateNewEntityAtPosition", entity_position, EntityId.EntityId()
)
if new_entity_id2.IsValid():
self.log("Camera entity created")
camera_entity = hydra.Entity("Camera Entity", new_entity_id2)
camera_entity.components = []
for component in camera_component:
camera_entity.components.append(hydra.add_component(component, new_entity_id2))
# 5) Move the default Camera entity for testing in the launcher
cam_position = math.Vector3(512.0, 500.0, 35.0)
search_filter = entity.SearchFilter()
search_filter.names = ["Camera"]
search_entity_ids = entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter)
components.TransformBus(bus.Event, "MoveEntity", search_entity_ids[0], cam_position)
# 6) Save and export to engine
general.save_level()
@@ -18,9 +18,9 @@ import azlmbr.areasystem as areasystem
import azlmbr.legacy.general as general
import azlmbr
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.components as components
import azlmbr.math as math
import azlmbr.entity as EntityId
import azlmbr.entity as entity
import azlmbr.paths
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
@@ -134,20 +134,14 @@ class TestVegLayerBlenderCreated(EditorTestHelper):
purple_count += 1
self.test_success = pink_count == purple_count and (pink_count + purple_count == num_expected) and self.test_success
# 5) Create a new entity with a Camera component for testing in the launcher
entity_position = math.Vector3(500.0, 500.0, 47.0)
rot_degrees_vector = math.Vector3(radians(-55.0), radians(28.5), radians(-17.0))
camera_component = ["Camera"]
camera_id = editor.ToolsApplicationRequestBus(
bus.Broadcast, "CreateNewEntityAtPosition", entity_position, EntityId.EntityId()
)
if camera_id.IsValid():
self.log("Camera entity created")
camera_entity = hydra.Entity("Camera Entity", camera_id)
camera_entity.components = []
for component in camera_component:
camera_entity.components.append(hydra.add_component(component, camera_id))
azlmbr.components.TransformBus(bus.Event, "SetLocalRotation", camera_id, rot_degrees_vector)
# 5) Move the default Camera entity for testing in the launcher
cam_position = math.Vector3(500.0, 500.0, 47.0)
cam_rot_degrees_vector = math.Vector3(radians(-55.0), radians(28.5), radians(-17.0))
search_filter = entity.SearchFilter()
search_filter.names = ["Camera"]
search_entity_ids = entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter)
components.TransformBus(bus.Event, "MoveEntity", search_entity_ids[0], cam_position)
azlmbr.components.TransformBus(bus.Event, "SetLocalRotation", search_entity_ids[0], cam_rot_degrees_vector)
# 6) Save and export level
general.save_level()
@@ -34,8 +34,8 @@ class TestLayerSpawnerFilterStageToggle(EditorTestHelper):
:return: None
"""
PREPROCESS_INSTANCE_COUNT = 425
POSTPROCESS_INSTANCE_COUNT = 430
PREPROCESS_INSTANCE_COUNT = 21
POSTPROCESS_INSTANCE_COUNT = 19
# Create empty level
self.test_success = self.create_level(
@@ -56,7 +56,6 @@ class TestLayerSpawnerFilterStageToggle(EditorTestHelper):
vegetation_entity.add_component("Vegetation Altitude Filter")
vegetation_entity.add_component("Vegetation Position Modifier")
# Create a child entity under vegetation area
child_entity = hydra.Entity("child_entity")
components_to_add = ["Random Noise Gradient", "Gradient Transform Modifier", "Box Shape"]
@@ -66,29 +65,13 @@ class TestLayerSpawnerFilterStageToggle(EditorTestHelper):
vegetation_entity.get_set_test(4, "Configuration|Position X|Gradient|Gradient Entity Id", child_entity.id)
vegetation_entity.get_set_test(4, "Configuration|Position Y|Gradient|Gradient Entity Id", child_entity.id)
# Set the min and max values for Altitude Filter
vegetation_entity.get_set_test(3, "Configuration|Altitude Min", 32.0)
vegetation_entity.get_set_test(3, "Configuration|Altitude Max", 35.0)
vegetation_entity.get_set_test(3, "Configuration|Altitude Min", 34.0)
vegetation_entity.get_set_test(3, "Configuration|Altitude Max", 38.0)
# Add entity with Mesh to replicate creation of hills and a flat surface to plant on
dynveg.create_surface_entity("Flat Surface", position, 32.0, 32.0, 1.0)
hill_entity = dynveg.create_mesh_surface_entity_with_slopes("hill", position, 4.0, 4.0, 4.0)
# Disable/Re-enable Mesh component due to ATOM-14299
general.idle_wait(1.0)
editor.EditorComponentAPIBus(bus.Broadcast, 'DisableComponents', [hill_entity.components[0]])
is_enabled = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', hill_entity.components[0])
if is_enabled:
print("Mesh component is still enabled")
else:
print("Mesh component was disabled")
editor.EditorComponentAPIBus(bus.Broadcast, 'EnableComponents', [hill_entity.components[0]])
is_enabled = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', hill_entity.components[0])
if is_enabled:
print("Mesh component is now enabled")
else:
print("Mesh component is still disabled")
hill_entity = dynveg.create_mesh_surface_entity_with_slopes("hill", position, 4.0)
# Set the filter stage to preprocess and postprocess respectively and verify instance count
vegetation_entity.get_set_test(0, "Configuration|Filter Stage", 1)
@@ -13,7 +13,7 @@ import azlmbr.legacy.general as general
import azlmbr.math as math
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
from automatedtesting_shared.editor_test_helper import EditorTestHelper
from editor_python_test_tools.editor_test_helper import EditorTestHelper
from largeworlds.large_worlds_utils import editor_dynveg_test_helper as dynveg
@@ -82,22 +82,7 @@ class test_MeshBlocker_InstancesBlockedByMesh(EditorTestHelper):
bus.Broadcast, "GetAssetIdByPath", os.path.join("objects", "_primitives", "_box_1x1.azmodel"), math.Uuid(),
False)
blocker_entity.get_set_test(1, "Controller|Configuration|Mesh Asset", cubeId)
components.TransformBus(bus.Event, "SetLocalScale", blocker_entity.id, math.Vector3(2.0, 2.0, 2.0))
# Disable/Re-enable Mesh component due to ATOM-14299
general.idle_wait(1.0)
editor.EditorComponentAPIBus(bus.Broadcast, 'DisableComponents', [blocker_entity.components[1]])
is_enabled = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', blocker_entity.components[1])
if is_enabled:
print("Mesh component is still enabled")
else:
print("Mesh component was disabled")
editor.EditorComponentAPIBus(bus.Broadcast, 'EnableComponents', [blocker_entity.components[1]])
is_enabled = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', blocker_entity.components[1])
if is_enabled:
print("Mesh component is now enabled")
else:
print("Mesh component is still disabled")
components.TransformBus(bus.Event, "SetLocalUniformScale", blocker_entity.id, 2.0)
# Verify spawned instance counts are accurate after addition of Blocker Entity
num_expected = 160 # Number of "PurpleFlower"s that plant on a 10 x 10 surface minus 2m blocker cube
@@ -88,24 +88,9 @@ class test_MeshBlocker_InstancesBlockedByMeshHeightTuning(EditorTestHelper):
bus.Broadcast, "GetAssetIdByPath", os.path.join("objects", "_primitives", "_box_1x1.azmodel"), math.Uuid(),
False)
blocker_entity.get_set_test(1, "Controller|Configuration|Mesh Asset", sphere_id)
components.TransformBus(bus.Event, "SetLocalScale", blocker_entity.id, math.Vector3(5.0, 5.0, 5.0))
components.TransformBus(bus.Event, "SetLocalUniformScale", blocker_entity.id, 5.0)
components.TransformBus(bus.Event, "SetLocalRotation", blocker_entity.id, math.Vector3(0.0, y_rotation, 0.0))
# Disable/Re-enable Mesh component due to ATOM-14299
general.idle_wait(1.0)
editor.EditorComponentAPIBus(bus.Broadcast, 'DisableComponents', [blocker_entity.components[1]])
is_enabled = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', blocker_entity.components[1])
if is_enabled:
print("Mesh component is still enabled")
else:
print("Mesh component was disabled")
editor.EditorComponentAPIBus(bus.Broadcast, 'EnableComponents', [blocker_entity.components[1]])
is_enabled = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', blocker_entity.components[1])
if is_enabled:
print("Mesh component is now enabled")
else:
print("Mesh component is still disabled")
# 5) Adjust the height Max percentage values of blocker
blocker_entity.get_set_test(0, "Configuration|Mesh Height Percent Max", 0.8)
@@ -90,7 +90,6 @@ class TestDynamicSliceInstanceSpawner(object):
@pytest.mark.SUITE_periodic
@pytest.mark.dynveg_area
@pytest.mark.parametrize("launcher_platform", ['windows'])
@pytest.mark.skip # ATOM-14703
def test_DynamicSliceInstanceSpawner_Embedded_E2E_Launcher(self, workspace, launcher, level,
remote_console_instance, project, launcher_platform):
@@ -126,7 +125,6 @@ class TestDynamicSliceInstanceSpawner(object):
@pytest.mark.SUITE_periodic
@pytest.mark.dynveg_area
@pytest.mark.parametrize("launcher_platform", ['windows'])
@pytest.mark.skip # ATOM-14703
def test_DynamicSliceInstanceSpawner_External_E2E_Launcher(self, workspace, launcher, level,
remote_console_instance, project, launcher_platform):
@@ -68,7 +68,6 @@ class TestLayerBlender(object):
"Entity has a Box Shape component",
"Blender Configuration|Vegetation Areas: SUCCESS",
"Blender Box Shape|Box Configuration|Dimensions: SUCCESS",
"Camera entity created",
"LayerBlender_E2E_Editor: result=SUCCESS"
]
@@ -85,12 +84,11 @@ class TestLayerBlender(object):
@pytest.mark.BAT
@pytest.mark.SUITE_periodic
@pytest.mark.dynveg_area
@pytest.mark.xfail
@pytest.mark.parametrize("launcher_platform", ['windows'])
def test_LayerBlender_E2E_Launcher(self, workspace, project, launcher, level, remote_console_instance,
launcher_platform):
launcher.args.extend(["-NullRenderer"])
launcher.args.extend(["-rhi=Null"])
launcher.start()
assert launcher.is_alive(), "Launcher failed to start"
@@ -121,7 +121,7 @@ class TestLayerSpawner(object):
@pytest.mark.test_case_id("C30000751")
@pytest.mark.SUITE_sandbox
@pytest.mark.dynveg_misc
@pytest.mark.skip # ATOM-14828
@pytest.mark.skip # https://github.com/o3de/o3de/issues/2038
def test_LayerSpawner_InstancesRefreshUsingCorrectViewportCamera(self, request, editor, level, launcher_platform):
expected_lines = [
@@ -136,5 +136,6 @@ class TestLayerSpawner(object):
editor,
"LayerSpawner_InstancesRefreshUsingCorrectViewportCamera.py",
expected_lines,
cfg_args=[level]
cfg_args=[level],
null_renderer=False
)
@@ -34,7 +34,7 @@ def create_surface_entity(name, center_point, box_size_x, box_size_y, box_size_z
return surface_entity
def create_mesh_surface_entity_with_slopes(name, center_point, scale_x, scale_y, scale_z):
def create_mesh_surface_entity_with_slopes(name, center_point, uniform_scale):
# Creates an entity with the assigned mesh_asset as the specified scale and sets up as a planting surface
mesh_asset_path = os.path.join("models", "sphere.azmodel")
mesh_asset = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", mesh_asset_path, math.Uuid(),
@@ -47,7 +47,7 @@ def create_mesh_surface_entity_with_slopes(name, center_point, scale_x, scale_y,
if surface_entity.id.IsValid():
print(f"'{surface_entity.name}' created")
hydra.get_set_test(surface_entity, 0, "Controller|Configuration|Mesh Asset", mesh_asset)
components.TransformBus(bus.Event, "SetLocalScale", surface_entity.id, math.Vector3(scale_x, scale_y, scale_z))
components.TransformBus(bus.Event, "SetLocalUniformScale", surface_entity.id, uniform_scale)
return surface_entity
@@ -742,14 +742,14 @@
</Class>
<Class name="int" field="methodType" value="2" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
<Class name="AZStd::string" field="methodName" value="GetOnPostsimulateEvent" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="className" value="System Interface" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="className" value="PhysicsSystemInterface" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::vector" field="namespaces" type="{99DAD0BC-740E-5E82-826B-8FC7968CC02C}"/>
<Class name="AZStd::vector" field="resultSlotIDs" type="{D0B13803-101B-54D8-914C-0DA49FDFA268}">
<Class name="SlotId" field="element" version="2" type="{14C629F6-467B-46FE-8B63-48FDFCA42175}">
<Class name="AZ::Uuid" field="m_id" value="{00000000-0000-0000-0000-000000000000}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
</Class>
</Class>
<Class name="AZStd::string" field="prettyClassName" value="System Interface" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="prettyClassName" value="PhysicsSystemInterface" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
</Class>
</Class>
<Class name="bool" field="IsDependencyReady" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
@@ -1045,14 +1045,14 @@
</Class>
<Class name="int" field="methodType" value="2" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
<Class name="AZStd::string" field="methodName" value="GetOnPostsimulateEvent" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="className" value="System Interface" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="className" value="PhysicsSystemInterface" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::vector" field="namespaces" type="{99DAD0BC-740E-5E82-826B-8FC7968CC02C}"/>
<Class name="AZStd::vector" field="resultSlotIDs" type="{D0B13803-101B-54D8-914C-0DA49FDFA268}">
<Class name="SlotId" field="element" version="2" type="{14C629F6-467B-46FE-8B63-48FDFCA42175}">
<Class name="AZ::Uuid" field="m_id" value="{00000000-0000-0000-0000-000000000000}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
</Class>
</Class>
<Class name="AZStd::string" field="prettyClassName" value="System Interface" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="prettyClassName" value="PhysicsSystemInterface" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
</Class>
</Class>
<Class name="bool" field="IsDependencyReady" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
@@ -1085,14 +1085,14 @@
</Class>
<Class name="int" field="methodType" value="2" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
<Class name="AZStd::string" field="methodName" value="GetOnPresimulateEvent" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="className" value="System Interface" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="className" value="PhysicsSystemInterface" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::vector" field="namespaces" type="{99DAD0BC-740E-5E82-826B-8FC7968CC02C}"/>
<Class name="AZStd::vector" field="resultSlotIDs" type="{D0B13803-101B-54D8-914C-0DA49FDFA268}">
<Class name="SlotId" field="element" version="2" type="{14C629F6-467B-46FE-8B63-48FDFCA42175}">
<Class name="AZ::Uuid" field="m_id" value="{00000000-0000-0000-0000-000000000000}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
</Class>
</Class>
<Class name="AZStd::string" field="prettyClassName" value="System Interface" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="prettyClassName" value="PhysicsSystemInterface" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
</Class>
</Class>
<Class name="bool" field="IsDependencyReady" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
-1
View File
@@ -138,7 +138,6 @@ ly_add_source_properties(
ly_add_source_properties(
SOURCES
Core/LevelEditorMenuHandler.cpp
GraphicsSettingsDialog.cpp
MainWindow.cpp
PROPERTY COMPILE_DEFINITIONS
VALUES ${LY_PAL_TOOLS_DEFINES}
+7 -41
View File
@@ -497,9 +497,15 @@ void LevelEditorMenuHandler::PopulateEditMenu(ActionManager::MenuWrapper& editMe
// Hide Selection
editMenu.AddAction(AzToolsFramework::HideSelection);
// Unhide All
// Show All
editMenu.AddAction(AzToolsFramework::ShowAll);
// Lock Selection
editMenu.AddAction(AzToolsFramework::LockSelection);
// UnLock All
editMenu.AddAction(AzToolsFramework::UnlockAll);
/*
* The following block of code is part of the feature "Isolation Mode" and is temporarily
* disabled for 1.10 release.
@@ -552,49 +558,9 @@ void LevelEditorMenuHandler::PopulateEditMenu(ActionManager::MenuWrapper& editMe
// Global Preferences...
editorSettingsMenu.AddAction(ID_TOOLS_PREFERENCES);
// Graphics Settings...
editorSettingsMenu.AddAction(ID_GRAPHICS_SETTINGS);
// Editor Settings Manager
AddOpenViewPaneAction(editorSettingsMenu, LyViewPane::EditorSettingsManager);
// Graphics Performance
auto graphicPerformanceSubMenu = editorSettingsMenu.AddMenu(QObject::tr("Graphics Performance"));
auto pcMenu = graphicPerformanceSubMenu.AddMenu(tr("PC"));
pcMenu.AddAction(ID_GAME_PC_ENABLEVERYHIGHSPEC);
pcMenu.AddAction(ID_GAME_PC_ENABLEHIGHSPEC);
pcMenu.AddAction(ID_GAME_PC_ENABLEMEDIUMSPEC);
pcMenu.AddAction(ID_GAME_PC_ENABLELOWSPEC);
auto osxmetalMenu = graphicPerformanceSubMenu.AddMenu(tr("OSX Metal"));
osxmetalMenu.AddAction(ID_GAME_OSXMETAL_ENABLEVERYHIGHSPEC);
osxmetalMenu.AddAction(ID_GAME_OSXMETAL_ENABLEHIGHSPEC);
osxmetalMenu.AddAction(ID_GAME_OSXMETAL_ENABLEMEDIUMSPEC);
osxmetalMenu.AddAction(ID_GAME_OSXMETAL_ENABLELOWSPEC);
auto androidMenu = graphicPerformanceSubMenu.AddMenu(tr("Android"));
androidMenu.AddAction(ID_GAME_ANDROID_ENABLEVERYHIGHSPEC);
androidMenu.AddAction(ID_GAME_ANDROID_ENABLEHIGHSPEC);
androidMenu.AddAction(ID_GAME_ANDROID_ENABLEMEDIUMSPEC);
androidMenu.AddAction(ID_GAME_ANDROID_ENABLELOWSPEC);
auto iosMenu = graphicPerformanceSubMenu.AddMenu(tr("iOS"));
iosMenu.AddAction(ID_GAME_IOS_ENABLEVERYHIGHSPEC);
iosMenu.AddAction(ID_GAME_IOS_ENABLEHIGHSPEC);
iosMenu.AddAction(ID_GAME_IOS_ENABLEMEDIUMSPEC);
iosMenu.AddAction(ID_GAME_IOS_ENABLELOWSPEC);
#if defined(AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS)
#define AZ_RESTRICTED_PLATFORM_EXPANSION(CodeName, CODENAME, codename, PrivateName, PRIVATENAME, privatename, PublicName, PUBLICNAME, publicname, PublicAuxName1, PublicAuxName2, PublicAuxName3)\
auto publicname##Menu = graphicPerformanceSubMenu.AddMenu(tr(PublicAuxName2));\
publicname##Menu.AddAction(ID_GAME_##CODENAME##_ENABLEHIGHSPEC);\
publicname##Menu.AddAction(ID_GAME_##CODENAME##_ENABLEMEDIUMSPEC);\
publicname##Menu.AddAction(ID_GAME_##CODENAME##_ENABLELOWSPEC);
AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS
#undef AZ_RESTRICTED_PLATFORM_EXPANSION
#endif
// Keyboard Customization
auto keyboardCustomizationMenu = editorSettingsMenu.AddMenu(tr("Keyboard Customization"));
keyboardCustomizationMenu.AddAction(ID_TOOLS_CUSTOMIZEKEYBOARD);
-102
View File
@@ -111,7 +111,6 @@ AZ_POP_DISABLE_WARNING
#include "ToolBox.h"
#include "LevelInfo.h"
#include "EditorPreferencesDialog.h"
#include "GraphicsSettingsDialog.h"
#include "AnimationContext.h"
#include "GotoPositionDlg.h"
@@ -440,7 +439,6 @@ void CCryEditApp::RegisterActionHandlers()
ON_COMMAND(ID_CLEAR_REGISTRY, OnClearRegistryData)
ON_COMMAND(ID_VALIDATELEVEL, OnValidatelevel)
ON_COMMAND(ID_TOOLS_PREFERENCES, OnToolsPreferences)
ON_COMMAND(ID_GRAPHICS_SETTINGS, OnGraphicsSettings)
ON_COMMAND(ID_SWITCHCAMERA_DEFAULTCAMERA, OnSwitchToDefaultCamera)
ON_COMMAND(ID_SWITCHCAMERA_SEQUENCECAMERA, OnSwitchToSequenceCamera)
ON_COMMAND(ID_SWITCHCAMERA_SELECTEDCAMERA, OnSwitchToSelectedcamera)
@@ -453,14 +451,6 @@ void CCryEditApp::RegisterActionHandlers()
ON_COMMAND(ID_OPEN_TRACKVIEW, OnOpenTrackView)
ON_COMMAND(ID_OPEN_UICANVASEDITOR, OnOpenUICanvasEditor)
ON_COMMAND_RANGE(ID_GAME_PC_ENABLELOWSPEC, ID_GAME_PC_ENABLEVERYHIGHSPEC, OnChangeGameSpec)
ON_COMMAND_RANGE(ID_GAME_OSXMETAL_ENABLELOWSPEC, ID_GAME_OSXMETAL_ENABLEVERYHIGHSPEC, OnChangeGameSpec)
ON_COMMAND_RANGE(ID_GAME_ANDROID_ENABLELOWSPEC, ID_GAME_ANDROID_ENABLEVERYHIGHSPEC, OnChangeGameSpec)
ON_COMMAND_RANGE(ID_GAME_IOS_ENABLELOWSPEC, ID_GAME_IOS_ENABLEVERYHIGHSPEC, OnChangeGameSpec)
#if defined(AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS)
#define AZ_RESTRICTED_PLATFORM_EXPANSION(CodeName, CODENAME, codename, PrivateName, PRIVATENAME, privatename, PublicName, PUBLICNAME, publicname, PublicAuxName1, PublicAuxName2, PublicAuxName3)\
ON_COMMAND_RANGE(ID_GAME_##CODENAME##_ENABLELOWSPEC, ID_GAME_##CODENAME##_ENABLEHIGHSPEC, OnChangeGameSpec)
@@ -3674,13 +3664,6 @@ void CCryEditApp::OnToolsPreferences()
dlg.exec();
}
//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnGraphicsSettings()
{
GraphicsSettingsDialog dlg(MainWindow::instance());
dlg.exec();
}
//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnSwitchToDefaultCamera()
{
@@ -3815,91 +3798,6 @@ void CCryEditApp::OnOpenUICanvasEditor()
QtViewPaneManager::instance()->OpenPane(LyViewPane::UiEditor);
}
//////////////////////////////////////////////////////////////////////////
void CCryEditApp::SetGameSpecCheck(ESystemConfigSpec spec, ESystemConfigPlatform platform, int &nCheck, bool &enable)
{
if (GetIEditor()->GetEditorConfigSpec() == spec && GetIEditor()->GetEditorConfigPlatform() == platform)
{
nCheck = 1;
}
enable = spec <= GetIEditor()->GetSystem()->GetMaxConfigSpec();
}
//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnUpdateGameSpec(QAction* action)
{
Q_ASSERT(action->isCheckable());
int nCheck = 0;
bool enable = true;
switch (action->data().toInt())
{
case ID_GAME_PC_ENABLELOWSPEC:
SetGameSpecCheck(CONFIG_LOW_SPEC, CONFIG_PC, nCheck, enable);
break;
case ID_GAME_PC_ENABLEMEDIUMSPEC:
SetGameSpecCheck(CONFIG_MEDIUM_SPEC, CONFIG_PC, nCheck, enable);
break;
case ID_GAME_PC_ENABLEHIGHSPEC:
SetGameSpecCheck(CONFIG_HIGH_SPEC, CONFIG_PC, nCheck, enable);
break;
case ID_GAME_PC_ENABLEVERYHIGHSPEC:
SetGameSpecCheck(CONFIG_VERYHIGH_SPEC, CONFIG_PC, nCheck, enable);
break;
case ID_GAME_OSXMETAL_ENABLELOWSPEC:
SetGameSpecCheck(CONFIG_LOW_SPEC, CONFIG_OSX_METAL, nCheck, enable);
break;
case ID_GAME_OSXMETAL_ENABLEMEDIUMSPEC:
SetGameSpecCheck(CONFIG_MEDIUM_SPEC, CONFIG_OSX_METAL, nCheck, enable);
break;
case ID_GAME_OSXMETAL_ENABLEHIGHSPEC:
SetGameSpecCheck(CONFIG_HIGH_SPEC, CONFIG_OSX_METAL, nCheck, enable);
break;
case ID_GAME_OSXMETAL_ENABLEVERYHIGHSPEC:
SetGameSpecCheck(CONFIG_VERYHIGH_SPEC, CONFIG_OSX_METAL, nCheck, enable);
break;
case ID_GAME_ANDROID_ENABLELOWSPEC:
SetGameSpecCheck(CONFIG_LOW_SPEC, CONFIG_ANDROID, nCheck, enable);
break;
case ID_GAME_ANDROID_ENABLEMEDIUMSPEC:
SetGameSpecCheck(CONFIG_MEDIUM_SPEC, CONFIG_ANDROID, nCheck, enable);
break;
case ID_GAME_ANDROID_ENABLEHIGHSPEC:
SetGameSpecCheck(CONFIG_HIGH_SPEC, CONFIG_ANDROID, nCheck, enable);
break;
case ID_GAME_ANDROID_ENABLEVERYHIGHSPEC:
SetGameSpecCheck(CONFIG_VERYHIGH_SPEC, CONFIG_ANDROID, nCheck, enable);
break;
case ID_GAME_IOS_ENABLELOWSPEC:
SetGameSpecCheck(CONFIG_LOW_SPEC, CONFIG_IOS, nCheck, enable);
break;
case ID_GAME_IOS_ENABLEMEDIUMSPEC:
SetGameSpecCheck(CONFIG_MEDIUM_SPEC, CONFIG_IOS, nCheck, enable);
break;
case ID_GAME_IOS_ENABLEHIGHSPEC:
SetGameSpecCheck(CONFIG_HIGH_SPEC, CONFIG_IOS, nCheck, enable);
break;
case ID_GAME_IOS_ENABLEVERYHIGHSPEC:
SetGameSpecCheck(CONFIG_VERYHIGH_SPEC, CONFIG_IOS, nCheck, enable);
break;
#if defined(AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS)
#define AZ_RESTRICTED_PLATFORM_EXPANSION(CodeName, CODENAME, codename, PrivateName, PRIVATENAME, privatename, PublicName, PUBLICNAME, publicname, PublicAuxName1, PublicAuxName2, PublicAuxName3)\
case ID_GAME_##CODENAME##_ENABLELOWSPEC:\
SetGameSpecCheck(CONFIG_LOW_SPEC, CONFIG_##CODENAME, nCheck, enable);\
break;\
case ID_GAME_##CODENAME##_ENABLEMEDIUMSPEC:\
SetGameSpecCheck(CONFIG_MEDIUM_SPEC, CONFIG_##CODENAME, nCheck, enable);\
break;\
case ID_GAME_##CODENAME##_ENABLEHIGHSPEC:\
SetGameSpecCheck(CONFIG_HIGH_SPEC, CONFIG_##CODENAME, nCheck, enable);\
break;
AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS
#undef AZ_RESTRICTED_PLATFORM_EXPANSION
#endif
}
action->setChecked(nCheck);
action->setEnabled(enable);
}
//////////////////////////////////////////////////////////////////////////
RecentFileList* CCryEditApp::GetRecentFileList()
{
-4
View File
@@ -403,7 +403,6 @@ private:
void OnClearRegistryData();
void OnValidatelevel();
void OnToolsPreferences();
void OnGraphicsSettings();
void OnSwitchToDefaultCamera();
void OnUpdateSwitchToDefaultCamera(QAction* action);
void OnSwitchToSequenceCamera();
@@ -416,9 +415,6 @@ private:
void OnOpenTrackView();
void OnOpenAudioControlsEditor();
void OnOpenUICanvasEditor();
void OnChangeGameSpec(UINT nID);
void SetGameSpecCheck(ESystemConfigSpec spec, ESystemConfigPlatform platform, int &nCheck, bool &enable);
void OnUpdateGameSpec(QAction* action);
void OnOpenQuickAccessBar();
public:
-72
View File
@@ -407,78 +407,6 @@ inline namespace Commands
}
}
//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnChangeGameSpec(UINT nID)
{
switch (nID)
{
case ID_GAME_PC_ENABLELOWSPEC:
Commands::PySetConfigSpec(CONFIG_LOW_SPEC, CONFIG_PC);
break;
case ID_GAME_PC_ENABLEMEDIUMSPEC:
Commands::PySetConfigSpec(CONFIG_MEDIUM_SPEC, CONFIG_PC);
break;
case ID_GAME_PC_ENABLEHIGHSPEC:
Commands::PySetConfigSpec(CONFIG_HIGH_SPEC, CONFIG_PC);
break;
case ID_GAME_PC_ENABLEVERYHIGHSPEC:
Commands::PySetConfigSpec(CONFIG_VERYHIGH_SPEC, CONFIG_PC);
break;
case ID_GAME_OSXMETAL_ENABLELOWSPEC:
Commands::PySetConfigSpec(CONFIG_LOW_SPEC, CONFIG_OSX_METAL);
break;
case ID_GAME_OSXMETAL_ENABLEMEDIUMSPEC:
Commands::PySetConfigSpec(CONFIG_MEDIUM_SPEC, CONFIG_OSX_METAL);
break;
case ID_GAME_OSXMETAL_ENABLEHIGHSPEC:
Commands::PySetConfigSpec(CONFIG_HIGH_SPEC, CONFIG_OSX_METAL);
break;
case ID_GAME_OSXMETAL_ENABLEVERYHIGHSPEC:
Commands::PySetConfigSpec(CONFIG_VERYHIGH_SPEC, CONFIG_OSX_METAL);
break;
case ID_GAME_ANDROID_ENABLELOWSPEC:
Commands::PySetConfigSpec(CONFIG_LOW_SPEC, CONFIG_ANDROID);
break;
case ID_GAME_ANDROID_ENABLEMEDIUMSPEC:
Commands::PySetConfigSpec(CONFIG_MEDIUM_SPEC, CONFIG_ANDROID);
break;
case ID_GAME_ANDROID_ENABLEHIGHSPEC:
Commands::PySetConfigSpec(CONFIG_HIGH_SPEC, CONFIG_ANDROID);
break;
case ID_GAME_ANDROID_ENABLEVERYHIGHSPEC:
Commands::PySetConfigSpec(CONFIG_VERYHIGH_SPEC, CONFIG_ANDROID);
break;
case ID_GAME_IOS_ENABLELOWSPEC:
Commands::PySetConfigSpec(CONFIG_LOW_SPEC, CONFIG_IOS);
break;
case ID_GAME_IOS_ENABLEMEDIUMSPEC:
Commands::PySetConfigSpec(CONFIG_MEDIUM_SPEC, CONFIG_IOS);
break;
case ID_GAME_IOS_ENABLEHIGHSPEC:
Commands::PySetConfigSpec(CONFIG_HIGH_SPEC, CONFIG_IOS);
break;
case ID_GAME_IOS_ENABLEVERYHIGHSPEC:
Commands::PySetConfigSpec(CONFIG_VERYHIGH_SPEC, CONFIG_IOS);
break;
#if defined(AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS)
#define AZ_RESTRICTED_PLATFORM_EXPANSION(CodeName, CODENAME, codename, PrivateName, PRIVATENAME, privatename, PublicName, PUBLICNAME, publicname, PublicAuxName1, PublicAuxName2, PublicAuxName3)\
case ID_GAME_##CODENAME##_ENABLELOWSPEC:\
Commands::PySetConfigSpec(CONFIG_LOW_SPEC, CONFIG_##CODENAME);\
break;\
case ID_GAME_##CODENAME##_ENABLEMEDIUMSPEC:\
Commands::PySetConfigSpec(CONFIG_MEDIUM_SPEC, CONFIG_##CODENAME);\
break;\
case ID_GAME_##CODENAME##_ENABLEHIGHSPEC:\
Commands::PySetConfigSpec(CONFIG_HIGH_SPEC, CONFIG_##CODENAME);\
break;
AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS
#undef AZ_RESTRICTED_PLATFORM_EXPANSION
#endif
}
}
namespace AzToolsFramework
{
void CryEditPythonHandler::Reflect(AZ::ReflectContext* context)
+4 -2
View File
@@ -1896,7 +1896,7 @@ void EditorViewportWidget::SetViewTM(const Matrix34& viewTM, bool bMoveOnly)
if (m_pressedKeyState != KeyPressedState::PressedInPreviousFrame)
{
CUndo undo("Move Camera");
AzToolsFramework::ScopedUndoBatch undo("Move Camera");
if (bMoveOnly)
{
// specify eObjectUpdateFlags_UserInput so that an undo command gets logged
@@ -1932,7 +1932,7 @@ void EditorViewportWidget::SetViewTM(const Matrix34& viewTM, bool bMoveOnly)
if (m_pressedKeyState != KeyPressedState::PressedInPreviousFrame)
{
CUndo undo("Move Camera");
AzToolsFramework::ScopedUndoBatch undo("Move Camera");
if (bMoveOnly)
{
AZ::TransformBus::Event(
@@ -1945,6 +1945,8 @@ void EditorViewportWidget::SetViewTM(const Matrix34& viewTM, bool bMoveOnly)
m_viewEntityId, &AZ::TransformInterface::SetWorldTM,
LYTransformToAZTransform(camMatrix));
}
AzToolsFramework::ToolsApplicationRequestBus::Broadcast(&AzToolsFramework::ToolsApplicationRequests::AddDirtyEntity, m_viewEntityId);
}
else
{
File diff suppressed because it is too large Load Diff
-284
View File
@@ -1,284 +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 <QDialog>
#include <QTreeView>
#include <QStandardItemModel>
#include <QHeaderView>
#include <AzQtComponents/Components/Widgets/SpinBox.h>
#include <AzCore/std/containers/vector.h>
#include <AzCore/std/any.h>
#include <ISystem.h>
#endif
class QGridLayout;
class QLabel;
namespace Ui
{
class GraphicsSettingsDialog;
}
// Description:
// Status of cvar for a specifc platform and spec level
// editedValue - current setting within Graphics Settings Dialog box
// overwrittenValue - original setting from platform config file (set to originalValue if not found)
// originalValue - original settings from sys_spec config file index
struct CVarFileStatus
{
AZStd::any editedValue;
AZStd::any overwrittenValue;
AZStd::any originalValue;
CVarFileStatus(AZStd::any edit, AZStd::any over, AZStd::any orig) : editedValue(edit), overwrittenValue(over), originalValue(orig) {}
};
// Description:
// Status of specific cvar for Editor mapping
// type - CVAR_INT / CVAR_FLOAT / CVAR_STRING
// cvarGroup - source of cvar (sys_spec_particles, sys_spec_physics, etc.) or "miscellaneous" if only specified in platform config file
// fileVals = CVarFileStatus for each spec level of a specific platform
struct CVarInfo
{
int type;
AZStd::string cvarGroup;
AZStd::vector<CVarFileStatus> fileVals;
};
enum class GraphicsSettings
{
GameEffects,
Light,
ObjectDetail,
Particles,
Physics,
PostProcessing,
Quality,
Shading,
Shadows,
Sound,
Texture,
TextureResolution,
VolumetricEffects,
Water,
Miscellaneous,
numSettings
};
class GraphicsSettingsHeaderView;
class GraphicsSettingsTreeView
: public QTreeView
{
Q_OBJECT
public:
GraphicsSettingsTreeView(QWidget* parent = nullptr);
};
class GraphicsSettingsModel
: public QStandardItemModel
{
Q_OBJECT
public:
explicit GraphicsSettingsModel(QObject* parent = 0);
Qt::ItemFlags flags(const QModelIndex& index) const override;
};
class GraphicsSettingsDialog
: public QDialog,
public ILoadConfigurationEntrySink
{
Q_OBJECT
public:
explicit GraphicsSettingsDialog(QWidget* parent = nullptr);
virtual ~GraphicsSettingsDialog();
bool IsCustom(void) { return m_showCustomSpec; }
void UnloadCustomSpec(int specLevel);
// ILoadConfigurationEntrySink
void OnLoadConfigurationEntry(const char* szKey, const char* szValue, const char* szGroup) override;
public slots:
//Accept and reject
void reject() override;
void accept() override;
private slots:
//Update UIs
void PlatformChanged(const QString& platform);
bool CVarChanged(AZStd::any val, const char* cvarName, int specLevel);
void CVarChanged(int i);
void CVarChanged(double d);
void CVarChanged(const QString& s);
private:
// The struct ParameterWidget is used to store the parameter widget
// m_parameterName will be the name of the parameter the widget represent.
struct ParameterWidget
{
ParameterWidget(QWidget* widget, QString parameterName = "");
QString GetToolTip() const;
const char* PARAMETER_TOOLTIP = "The variable will update render parameter \"%1\".";
QWidget* m_widget;
QString m_parameterName;
};
struct CollapseGroup
{
QString m_groupName;
QStandardItem* m_groupRow;
QTreeView* m_treeView;
bool m_isCollapsed;
CollapseGroup(QTreeView* treeView);
void ToggleCollapsed();
};
void OpenCustomSpecDialog();
void ApplyCustomSpec(const QString& customFilePath);
bool IsCustomSpecAlreadyLoaded(const AZStd::string& filename) const;
void SetSettingsTree(int numColumns);
void SetCollapsed(const QModelIndex& index, bool flag);
enum CVarStateComparison
{
EDITED_OVERWRITTEN_COMPARE = 1,
EDITED_ORIGINAL_COMPARE = 2,
OVERWRITTEN_ORIGINAL_COMPARE = 3,
END_CVARSTATE_COMPARE,
};
bool CheckCVarStatesForDiff(AZStd::pair<AZStd::string, CVarInfo>* it, int cfgFileIndex, CVarStateComparison cmp);
// Save out settings into project-level cfg files
void SaveSystemSettings();
// Load in project-level cfg files for current platform
void LoadPlatformConfigurations();
// Build UI column for spec level of current platform
void BuildColumn(int specLevel);
// Initial UI building
void BuildUI();
// Cleaning out UI before loading new platform information
void CleanUI();
// Shows/hides custom spec option
void ShowCustomSpecOption(bool show);
// Shows/hides category labels and dropdowns
void ShowCategories(bool show);
// Warns about unsaved changes (returns true if accepted)
bool SendUnsavedChangesWarning(bool cancel);
void LoadCVarGroupDirectory(const AZStd::string& path);
/////////////////////////////////////////////
// UI help functions
// Setup collapsed buttons
void SetCollapsedLayout(const QString& groupName, QStandardItem* groupItem);
// Sets the platform entry index for the given platform
void SetPlatformEntry(ESystemConfigPlatform platform);
// Gets the platform enum given the platform name
ESystemConfigPlatform GetConfigPlatformFromName(const AZStd::string& platformName);
////////////////////////////////////////////
// Members
// Qt values
const int INPUT_MIN_WIDTH = 100;
const int INPUT_MIN_HEIGHT = 20;
const int INPUT_ROW_SPAN = 1;
const int INPUT_COLUMN_SPAN = 1;
const int CVAR_ROW_OFFSET = 2;
const int CVAR_VALUE_COLUMN_OFFSET = 1;
const int PLATFORM_LABEL_ROW = 1;
const int CVAR_LABEL_COLUMN = 1;
// Tool tips
const QString SETTINGS_FILE_PATH = "Config/spec/";
const char* CFG_FILEFILTER = "Cfg File(*.cfg);;All files(*)";
const int m_numSpecLevels = 4;
bool m_showCustomSpec;
bool m_showCategories;
GraphicsSettingsModel* m_graphicsSettingsModel;
GraphicsSettingsHeaderView* m_headerView;
int m_numColumns{ 0 };
const char* m_cvarGroupsFolder = "Config/CVarGroups";
QScopedPointer<Ui::GraphicsSettingsDialog> m_ui;
QVector<CollapseGroup*> m_uiCollapseGroup;
QVector<ParameterWidget*> m_parameterWidgets;
AZStd::string m_currentConfigFilename;
size_t m_currentSpecIndex;
// cvar name --> pair(type, CVarStatus for each file)
AZStd::unordered_map<AZStd::string, CVarInfo> m_cVarTracker;
AZStd::unordered_map<ESystemConfigPlatform, AZStd::vector<AZStd::string> > m_cfgFiles;
AZStd::vector<AZStd::pair<AZStd::string, ESystemConfigPlatform> > m_platformStrings;
struct CVarGroupInfo
{
QVector<QLabel*> m_platformLabels;
QVector<QLabel*> m_cvarLabels;
QVector<AzQtComponents::SpinBox*> m_cvarSpinBoxes;
QVector<AzQtComponents::DoubleSpinBox*> m_cvarDoubleSpinBoxes;
QVector<QLineEdit*> m_cvarLineEdits;
QVector<QToolButton*> m_specFileArea;
QVector<QWidget*> m_widgetInsertOrder;
QStandardItem* m_treeRowItem;
int m_currentRow;
};
AZStd::unordered_map<AZStd::string, CVarGroupInfo> m_cvarGroupData;
AZStd::vector<AZStd::string> m_cvarGroupOrder;
ESystemConfigPlatform m_currentPlatform;
int m_dirtyCVarCount;
};
class GraphicsSettingsHeaderView
: public QHeaderView
{
Q_OBJECT
public:
GraphicsSettingsHeaderView(GraphicsSettingsDialog* dialog, Qt::Orientation orientation, QWidget* parent = nullptr);
private:
bool event(QEvent* e) override;
void mouseMoveEvent(QMouseEvent* e) override;
void mouseReleaseEvent(QMouseEvent* e) override;
GraphicsSettingsDialog* m_dialog;
int m_index{ -1 };
};
+19 -20
View File
@@ -83,9 +83,9 @@ AZ::RPI::ViewportContextPtr LegacyViewportCameraControllerInstance::GetViewportC
}
bool LegacyViewportCameraControllerInstance::HandleMouseMove(
const AzFramework::ScreenPoint& currentMousePos, const AzFramework::ScreenPoint& previousMousePos)
int dx, int dy)
{
if (previousMousePos == currentMousePos)
if (dx == 0 && dy == 0)
{
return false;
}
@@ -105,7 +105,7 @@ bool LegacyViewportCameraControllerInstance::HandleMouseMove(
if (m_inMoveMode || m_inOrbitMode || m_inRotateMode || m_inZoomMode)
{
m_totalMouseMoveDelta += (QPoint(currentMousePos.m_x, currentMousePos.m_y)-QPoint(previousMousePos.m_x, previousMousePos.m_y)).manhattanLength();
m_totalMouseMoveDelta += AZStd::abs(dx) + AZStd::abs(dy);
}
if ((m_inRotateMode && m_inMoveMode) || m_inZoomMode)
@@ -115,7 +115,7 @@ bool LegacyViewportCameraControllerInstance::HandleMouseMove(
Vec3 ydir = m.GetColumn1().GetNormalized();
Vec3 pos = m.GetTranslation();
const float posDelta = 0.2f * (previousMousePos.m_y - currentMousePos.m_y) * speedScale;
const float posDelta = 0.2f * dy * speedScale;
pos = pos - ydir * posDelta;
m_orbitDistance = m_orbitDistance + posDelta;
m_orbitDistance = fabs(m_orbitDistance);
@@ -126,7 +126,7 @@ bool LegacyViewportCameraControllerInstance::HandleMouseMove(
}
else if (m_inRotateMode)
{
Ang3 angles(-currentMousePos.m_y + previousMousePos.m_y, 0, -currentMousePos.m_x + previousMousePos.m_x);
Ang3 angles(dy, 0, dx);
angles = angles * 0.002f * gSettings.cameraRotateSpeed;
if (gSettings.invertYRotation)
{
@@ -158,7 +158,7 @@ bool LegacyViewportCameraControllerInstance::HandleMouseMove(
}
Vec3 pos = m.GetTranslation();
pos += 0.1f * xdir * (currentMousePos.m_x - previousMousePos.m_x) * speedScale + 0.1f * zdir * (previousMousePos.m_y - currentMousePos.m_y) * speedScale;
pos += 0.1f * xdir * dx * speedScale + 0.1f * zdir * dy * speedScale;
m.SetTranslation(pos);
AZ::Transform transform = viewportContext->GetCameraTransform();
@@ -168,7 +168,7 @@ bool LegacyViewportCameraControllerInstance::HandleMouseMove(
}
else if (m_inOrbitMode)
{
Ang3 angles(-currentMousePos.m_y + previousMousePos.m_y, 0, -currentMousePos.m_x + previousMousePos.m_x);
Ang3 angles(dy, 0, dx);
angles = angles * 0.002f * gSettings.cameraRotateSpeed;
if (gSettings.invertPan)
@@ -302,20 +302,19 @@ bool LegacyViewportCameraControllerInstance::HandleInputChannelEvent(const AzFra
bool shouldCaptureCursor = m_capturingCursor;
bool shouldConsumeEvent = false;
if (id == AzFramework::InputDeviceMouse::SystemCursorPosition)
if (id == AzFramework::InputDeviceMouse::Movement::X || id == AzFramework::InputDeviceMouse::Movement::Y)
{
bool result = false;
AzToolsFramework::ViewportInteraction::ViewportMouseCursorRequestBus::Event(
GetViewportId(),
[this, &result](AzToolsFramework::ViewportInteraction::ViewportMouseCursorRequests* mouseRequests)
{
if (auto previousMousePosition = mouseRequests->PreviousViewportCursorScreenPosition();
previousMousePosition.has_value())
{
result = HandleMouseMove(mouseRequests->ViewportCursorScreenPosition(), previousMousePosition.value());
}
});
return result;
int dx = 0;
int dy = 0;
if (id == AzFramework::InputDeviceMouse::Movement::X)
{
dx = -aznumeric_cast<int>(event.m_inputChannel.GetValue());
}
else
{
dy = -aznumeric_cast<int>(event.m_inputChannel.GetValue());
}
return HandleMouseMove(dx, dy);
}
else if (id == MouseButton::Left)
{
+1 -1
View File
@@ -69,7 +69,7 @@ namespace SandboxEditor
AZ::RPI::ViewportContextPtr GetViewportContext();
bool HandleMouseMove(const AzFramework::ScreenPoint& currentMousePos, const AzFramework::ScreenPoint& previousMousePos);
bool HandleMouseMove(int dx, int dy);
bool HandleMouseWheel(float zDelta);
bool IsKeyDown(Qt::Key key) const;
void UpdateCursorCapture(bool shouldCaptureCursor);
-44
View File
@@ -687,49 +687,6 @@ void MainWindow::InitActions()
am->AddAction(ID_FILE_PROJECT_MANAGER_SETTINGS, tr("Edit Project Settings..."));
am->AddAction(ID_FILE_PROJECT_MANAGER_NEW, tr("New Project..."));
am->AddAction(ID_FILE_PROJECT_MANAGER_OPEN, tr("Open Project..."));
am->AddAction(ID_GAME_PC_ENABLEVERYHIGHSPEC, tr("Very High")).SetCheckable(true)
.RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateGameSpec);
am->AddAction(ID_GAME_PC_ENABLEHIGHSPEC, tr("High")).SetCheckable(true)
.RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateGameSpec);
am->AddAction(ID_GAME_PC_ENABLEMEDIUMSPEC, tr("Medium")).SetCheckable(true)
.RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateGameSpec);
am->AddAction(ID_GAME_PC_ENABLELOWSPEC, tr("Low")).SetCheckable(true)
.RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateGameSpec);
am->AddAction(ID_GAME_OSXMETAL_ENABLEVERYHIGHSPEC, tr("Very High")).SetCheckable(true)
.RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateGameSpec);
am->AddAction(ID_GAME_OSXMETAL_ENABLEHIGHSPEC, tr("High")).SetCheckable(true)
.RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateGameSpec);
am->AddAction(ID_GAME_OSXMETAL_ENABLEMEDIUMSPEC, tr("Medium")).SetCheckable(true)
.RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateGameSpec);
am->AddAction(ID_GAME_OSXMETAL_ENABLELOWSPEC, tr("Low")).SetCheckable(true)
.RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateGameSpec);
am->AddAction(ID_GAME_ANDROID_ENABLEVERYHIGHSPEC, tr("Very High")).SetCheckable(true)
.RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateGameSpec);
am->AddAction(ID_GAME_ANDROID_ENABLEHIGHSPEC, tr("High")).SetCheckable(true)
.RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateGameSpec);
am->AddAction(ID_GAME_ANDROID_ENABLEMEDIUMSPEC, tr("Medium")).SetCheckable(true)
.RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateGameSpec);
am->AddAction(ID_GAME_ANDROID_ENABLELOWSPEC, tr("Low")).SetCheckable(true)
.RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateGameSpec);
am->AddAction(ID_GAME_IOS_ENABLEVERYHIGHSPEC, tr("Very High")).SetCheckable(true)
.RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateGameSpec);
am->AddAction(ID_GAME_IOS_ENABLEHIGHSPEC, tr("High")).SetCheckable(true)
.RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateGameSpec);
am->AddAction(ID_GAME_IOS_ENABLEMEDIUMSPEC, tr("Medium")).SetCheckable(true)
.RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateGameSpec);
am->AddAction(ID_GAME_IOS_ENABLELOWSPEC, tr("Low")).SetCheckable(true)
.RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateGameSpec);
#if defined(AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS)
#if defined(TOOLS_SUPPORT_JASPER)
#include AZ_RESTRICTED_FILE_EXPLICIT(MainWindow_cpp, jasper)
#endif
#if defined(TOOLS_SUPPORT_PROVO)
#include AZ_RESTRICTED_FILE_EXPLICIT(MainWindow_cpp, provo)
#endif
#if defined(TOOLS_SUPPORT_SALEM)
#include AZ_RESTRICTED_FILE_EXPLICIT(MainWindow_cpp, salem)
#endif
#endif
am->AddAction(ID_TOOLS_CUSTOMIZEKEYBOARD, tr("Customize &Keyboard..."))
.Connect(&QAction::triggered, this, &MainWindow::ShowKeyboardCustomization);
am->AddAction(ID_TOOLS_EXPORT_SHORTCUTS, tr("&Export Keyboard Settings..."))
@@ -737,7 +694,6 @@ void MainWindow::InitActions()
am->AddAction(ID_TOOLS_IMPORT_SHORTCUTS, tr("&Import Keyboard Settings..."))
.Connect(&QAction::triggered, this, &MainWindow::ImportKeyboardShortcuts);
am->AddAction(ID_TOOLS_PREFERENCES, tr("Global Preferences..."));
am->AddAction(ID_GRAPHICS_SETTINGS, tr("&Graphics Settings..."));
for (int i = ID_FILE_MRU_FIRST; i <= ID_FILE_MRU_LAST; ++i)
{
+1 -1
View File
@@ -5,7 +5,7 @@
<key>CFBundleExecutable</key>
<string>Editor</string>
<key>CFBundleIdentifier</key>
<string>com.Amazon.Lumberyard.Editor</string>
<string>org.O3DE.Editor</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleSignature</key>
@@ -46,4 +46,8 @@ ly_add_target(
AZ::AzCore
AZ::AzToolsFramework
AZ::AzQtComponents
RUNTIME_DEPENDENCIES
AZ::AzCore
AZ::AzToolsFramework
AZ::AzQtComponents
)
@@ -20,12 +20,12 @@
#include "ValidationHandler.h"
#include <AzCore/Component/ComponentApplicationBus.h>
#include <AzCore/IO/Path/Path.h>
#include "AzToolsFramework/UI/PropertyEditor/InstanceDataHierarchy.h"
#include <AzToolsFramework/UI/PropertyEditor/InstanceDataHierarchy.h>
#include <AzToolsFramework/UI/PropertyEditor/PropertyManagerComponent.h>
#include <AzToolsFramework/UI/PropertyEditor/ReflectedPropertyEditor.hxx>
#include <AzToolsFramework/UI/UICore/WidgetHelpers.h>
#include <Util/FileUtil.h>
#include <QMessageBox>
#include <QCloseEvent>
@@ -52,7 +52,7 @@ namespace ProjectSettingsTool
PlatformEnabled(PlatformId::Ios) ?
ProjectSettingsContainer::PlistInitVector({
ProjectSettingsContainer::PlatformAndPath
{ PlatformId::Ios, m_projectRoot + PlatformResourcesFolder(PlatformId::Ios) }
{ PlatformId::Ios, GetPlatformResource(PlatformId::Ios) }
})
:
ProjectSettingsContainer::PlistInitVector())
@@ -647,33 +647,38 @@ namespace ProjectSettingsTool
// iOS can be disabled if the plist file is missing
if (platformId == PlatformId::Ios)
{
const AZStd::string filename = m_projectRoot + PlatformResourcesFolder(platformId);
return CFileUtil::FileExists(filename.c_str());
AZStd::string plistPath = GetPlatformResource(platformId);
return !plistPath.empty();
}
return true;
}
const char* ProjectSettingsToolWindow::PlatformResourcesFolder(PlatformId platformId)
AZStd::string ProjectSettingsToolWindow::GetPlatformResource(PlatformId platformId)
{
if (platformId == PlatformId::Ios)
{
const AZStd::string firstfilename = m_projectRoot + "/Gem/Resources/Platform/iOS/Info.plist";
if (CFileUtil::FileExists(firstfilename.c_str()))
const char* searchPaths[] = {
"Resources/Platform/iOS/Info.plist",
// legacy paths
"Gem/Resources/Platform/iOS/Info.plist",
"Gem/Resources/IOSLauncher/Info.plist",
};
for (auto relPath : searchPaths)
{
return "/Gem/Resources/Platform/iOS/Info.plist";
}
else
{
const AZStd::string filename = m_projectRoot + "/Gem/Resources/IOSLauncher/Info.plist";
if (CFileUtil::FileExists(filename.c_str()))
AZ::IO::FixedMaxPath projectPlist{ m_projectRoot };
projectPlist /= relPath;
if (AZ::IO::SystemFile::Exists(projectPlist.c_str()))
{
return "/Gem/Resources/IOSLauncher/Info.plist";
return projectPlist.LexicallyNormal().String();
}
}
}
return nullptr;
return AZStd::string();
}
#include <moc_ProjectSettingsToolWindow.cpp>
@@ -137,8 +137,8 @@ namespace ProjectSettingsTool
// returns true if the platform is enabled
bool PlatformEnabled(PlatformId platformId);
// returns the resource folder
const char* PlatformResourcesFolder(PlatformId platformId);
// returns the main platform specific resource file e.g. for iOS it would be the Info.plist
AZStd::string GetPlatformResource(PlatformId platformId);
// The ui for the window
QScopedPointer<Ui::ProjectSettingsToolWidget> m_ui;
-26
View File
@@ -187,7 +187,6 @@
#define ID_SWITCHCAMERA_SEQUENCECAMERA 33701
#define ID_SWITCHCAMERA_SELECTEDCAMERA 33702
#define ID_TV_RECORD_AUTO 33703
#define ID_GRAPHICS_SETTINGS 33705
#define ID_VIEW_OPENVIEWPANE 33709
#define ID_VIEW_OPENPANE_FIRST 33712
#define ID_VIEW_OPENPANE_LAST 33811
@@ -219,10 +218,6 @@
#define ID_SPLINE_SNAP_GRID_X 33933
#define ID_SPLINE_SNAP_GRID_Y 33934
#define ID_FREEZE_TANGENTS 33935
#define ID_GAME_PC_ENABLELOWSPEC 33960
#define ID_GAME_PC_ENABLEMEDIUMSPEC 33961
#define ID_GAME_PC_ENABLEHIGHSPEC 33962
#define ID_GAME_PC_ENABLEVERYHIGHSPEC 33963
#define ID_PANEL_VEG_CREATE_SEL 33990
#define ID_TOOLS_UPDATEPROCEDURALVEGETATION 33999
#define ID_DISPLAY_GOTOPOSITION 34004
@@ -287,14 +282,6 @@
#define ID_CLEAR_REGISTRY 34470
#define ID_SOUND_STOPALLSOUNDS 34476
#define ID_AUDIO_REFRESH_AUDIO_SYSTEM 34477
#define ID_GAME_ANDROID_ENABLELOWSPEC 34490
#define ID_GAME_ANDROID_ENABLEMEDIUMSPEC 34491
#define ID_GAME_ANDROID_ENABLEHIGHSPEC 34492
#define ID_GAME_ANDROID_ENABLEVERYHIGHSPEC 34493
#define ID_GAME_IOS_ENABLELOWSPEC 34494
#define ID_GAME_IOS_ENABLEMEDIUMSPEC 34495
#define ID_GAME_IOS_ENABLEHIGHSPEC 34496
#define ID_GAME_IOS_ENABLEVERYHIGHSPEC 34497
#define ID_OPEN_AUDIO_CONTROLS_BROWSER 34580
#define ID_CREATE_GLOBAL_FG_MODULE_FROM_SELECTION 35076
#define ID_CREATE_LEVEL_FG_MODULE_FROM_SELECTION 35077
@@ -324,19 +311,6 @@
#define ID_DOCUMENTATION_FEEDBACK 36043
#define ID_OPEN_SUBSTANCE_EDITOR 36060
#define ID_IMPORT_ASSET 36069
#define ID_GAME_PROVO_ENABLELOWSPEC 34603
#define ID_GAME_PROVO_ENABLEMEDIUMSPEC 34604
#define ID_GAME_PROVO_ENABLEHIGHSPEC 34605
#define ID_GAME_OSXMETAL_ENABLELOWSPEC 34606
#define ID_GAME_OSXMETAL_ENABLEMEDIUMSPEC 34607
#define ID_GAME_OSXMETAL_ENABLEHIGHSPEC 34608
#define ID_GAME_OSXMETAL_ENABLEVERYHIGHSPEC 34609
#define ID_GAME_SALEM_ENABLELOWSPEC 34610
#define ID_GAME_SALEM_ENABLEMEDIUMSPEC 34611
#define ID_GAME_SALEM_ENABLEHIGHSPEC 34612
#define ID_GAME_JASPER_ENABLELOWSPEC 34613
#define ID_GAME_JASPER_ENABLEMEDIUMSPEC 34614
#define ID_GAME_JASPER_ENABLEHIGHSPEC 34615
#define ID_FILE_RESAVESLICES 36210
#define FIRST_QT_ACTION 50000
#define ID_VIEW_CONSOLEWINDOW 50001
@@ -1,25 +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
*
*/
#GraphicsSettingsDialog QHeaderView::section
{
background: #2D2D2D;
}
#GraphicsSettingsDialog QHeaderView::down-arrow
{
width: 14px;
height: 14px;
image: url(:/Gallery/Delete.svg);
}
#GraphicsSettingsDialog QHeaderView::up-arrow
{
width: 14px;
height: 14px;
image: url(:/Gallery/Delete.svg);
}
-1
View File
@@ -3,6 +3,5 @@
<file alias="Assets/Editor/Style/Editor.qss">Editor.qss</file>
<file alias="Assets/Editor/Style/EditorPreferencesDialog.qss">EditorPreferencesDialog.qss</file>
<file alias="Assets/Editor/Style/LayoutConfigDialog.qss">LayoutConfigDialog.qss</file>
<file alias="Assets/Editor/Style/GraphicsSettingsDialog.qss">GraphicsSettingsDialog.qss</file>
</qresource>
</RCC>
-3
View File
@@ -583,9 +583,6 @@ set(FILES
SettingsManager.h
SettingsManagerDialog.h
SettingsManagerDialog.ui
GraphicsSettingsDialog.h
GraphicsSettingsDialog.cpp
graphicssettingsdialog.ui
AboutDialog.cpp
ErrorReportTableModel.h
ErrorReportTableModel.cpp
-270
View File
@@ -1,270 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>GraphicsSettingsDialog</class>
<widget class="QDialog" name="GraphicsSettingsDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1292</width>
<height>565</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>800</width>
<height>400</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="windowTitle">
<string>Graphics Settings</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QWidget" name="widget" native="true">
<layout class="QGridLayout" name="m_generalLayout">
<property name="horizontalSpacing">
<number>0</number>
</property>
<property name="verticalSpacing">
<number>6</number>
</property>
<item row="2" column="3">
<widget class="QWidget" name="m_platform" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>20</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>20</height>
</size>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_7">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QComboBox" name="m_platformEntry"/>
</item>
</layout>
</widget>
</item>
<item row="2" column="0">
<widget class="QPushButton" name="m_selectCustomSpecButton">
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>20</height>
</size>
</property>
<property name="text">
<string>Add Resource</string>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QLabel" name="m_platformLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>60</width>
<height>20</height>
</size>
</property>
<property name="text">
<string>Platform</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="Line" name="m_lineSpacer">
<property name="minimumSize">
<size>
<width>13</width>
<height>0</height>
</size>
</property>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="Line" name="line_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QScrollArea" name="m_scrollArea">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="m_scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1272</width>
<height>452</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="GraphicsSettingsTreeView" name="m_graphicsSettingsTreeView">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="indentation">
<number>8</number>
</property>
<attribute name="headerStretchLastSection">
<bool>false</bool>
</attribute>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="m_horizontalLayout">
<item>
<spacer name="m_horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="m_applyButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgb(233, 118, 17);</string>
</property>
<property name="text">
<string>Save</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="m_cancelButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Cancel</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
</layout>
<zorder>line</zorder>
<zorder>m_scrollArea</zorder>
<zorder>line_2</zorder>
<zorder>widget</zorder>
</widget>
<customwidgets>
<customwidget>
<class>GraphicsSettingsTreeView</class>
<extends>QTreeView</extends>
<header>GraphicsSettingsDialog.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>m_cancelButton</tabstop>
<tabstop>m_applyButton</tabstop>
<tabstop>m_scrollArea</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>
@@ -116,7 +116,7 @@ namespace AZ
{
const char* uuidString = nullptr;
unsigned int uuidStringLength = 0;
if (dc.ReadArg(0, uuidString) && dc.ReadValue(1, uuidStringLength))
if (dc.ReadArg(0, uuidString) && dc.ReadArg(1, uuidStringLength))
{
dc.PushResult(Uuid(uuidString, uuidStringLength));
}
@@ -6,6 +6,7 @@
*/
#include <AzCore/Math/Vector3.h>
#include <AzCore/Serialization/Json/JsonSerializationSettings.h>
#include <AzCore/std/string/string_view.h>
#include <Tests/Serialization/Json/JsonSerializationTests.h>
@@ -43,7 +44,9 @@ namespace JsonSerializationTests
}
void CheckApplyPatchOutcome(const char* target, const char* patch,
AZ::JsonSerializationResult::Outcomes outcome, AZ::JsonSerializationResult::Processing processing)
AZ::JsonSerializationResult::Outcomes outcome,
AZ::JsonSerializationResult::Processing processing,
const AZ::JsonApplyPatchSettings& settings = AZ::JsonApplyPatchSettings{})
{
m_jsonDocument->Parse(target);
ASSERT_FALSE(m_jsonDocument->HasParseError());
@@ -53,12 +56,24 @@ namespace JsonSerializationTests
ASSERT_FALSE(patchDocument.HasParseError());
AZ::JsonSerializationResult::ResultCode result = AZ::JsonSerialization::ApplyPatch(*m_jsonDocument,
m_jsonDocument->GetAllocator(), patchDocument, AZ::JsonMergeApproach::JsonPatch);
m_jsonDocument->GetAllocator(), patchDocument, AZ::JsonMergeApproach::JsonPatch, settings);
EXPECT_EQ(result.GetTask(), AZ::JsonSerializationResult::Tasks::Merge);
EXPECT_EQ(result.GetOutcome(), outcome);
EXPECT_EQ(result.GetProcessing(), processing);
}
void CheckApplyPatchOutcome(
const char* target,
const char* patch,
const char* expectedPatchedResult,
AZ::JsonSerializationResult::Outcomes outcome,
AZ::JsonSerializationResult::Processing processing,
const AZ::JsonApplyPatchSettings& settings = AZ::JsonApplyPatchSettings{})
{
CheckApplyPatchOutcome(target, patch, outcome, processing, settings);
Expect_DocStrEq(expectedPatchedResult);
}
void CheckCreatePatch_Core(const char* source, AZStd::string_view patch, const char* target,
AZ::JsonMergeApproach approach)
{
@@ -262,6 +277,36 @@ namespace JsonSerializationTests
Outcomes::TypeMismatch, Processing::Halted);
}
TEST_F(JsonPatchingSerializationTests, ApplyPatch_UseJsonPatchWithCustomReportingCallback_ReportPartialSkip)
{
using namespace AZ::JsonSerializationResult;
auto issueReportingCallback = [](AZStd::string_view, AZ::JsonSerializationResult::ResultCode result,
AZStd::string_view) -> AZ::JsonSerializationResult::ResultCode
{
using namespace AZ::JsonSerializationResult;
if (result.GetProcessing() == Processing::Halted)
{
return ResultCode(result.GetTask(), Outcomes::PartialSkip);
}
return result;
};
AZ::JsonApplyPatchSettings applyPatchSettings;
applyPatchSettings.m_reporting = AZStd::move(issueReportingCallback);
CheckApplyPatchOutcome(
R"({})",
R"([
{ "op": "add", "path": "/nonexistent_key/new_member", "value": "someValue" },
{ "op": "add", "path": "/test", "value": "someValue" }
])",
R"(
{ "test": "someValue" }
)",
Outcomes::PartialSkip,
Processing::Completed,
AZStd::move(applyPatchSettings));
}
TEST_F(JsonPatchingSerializationTests, ApplyPatch_UseJsonPatchAddUnnamedMember_ReportsSuccess)
{
CheckApplyPatch(
@@ -97,6 +97,9 @@ namespace AzFramework
//! This is called when the window is deactivated from code or if the user closes the window.
virtual void OnWindowClosed() {};
//! This is called when vsync interval is changed.
virtual void OnVsyncIntervalChanged(uint32_t interval) { AZ_UNUSED(interval); };
};
using WindowNotificationBus = AZ::EBus<WindowNotifications>;
@@ -41,7 +41,7 @@ namespace AzNetworking
void TcpSocketManager::ProcessEvents(AZ::TimeMs maxBlockMs, const SocketEventCallback& readCallback, const SocketEventCallback& writeCallback)
{
if(static_cast<int32_t>(m_maxFd) <= 0 && m_socketFds.empty())
if(static_cast<int32_t>(m_maxFd) <= 0 || m_socketFds.empty())
{
// There are no available sockets to process
return;
@@ -63,6 +63,9 @@ namespace AzToolsFramework
//! Signal the Python handler to stop
virtual bool StopPython(bool silenceWarnings = false) = 0;
//! Query to determine if the Python VM has been initialized indicating an active state
virtual bool IsPythonActive() = 0;
//! Determines if the caller needs to wait for the Python VM to initialize (non-main thread only)
virtual void WaitForInitialization() {}
@@ -11,6 +11,7 @@
#include <AzFramework/Input/Buses/Notifications/InputChannelNotificationBus.h>
#include <AzFramework/Input/Buses/Requests/InputChannelRequestBus.h>
#include <AzQtComponents/Utilities/QtWindowUtilities.h>
#include <QApplication>
#include <QCursor>
@@ -187,12 +188,6 @@ namespace AzToolsFramework
bool QtEventToAzInputMapper::HandlesInputEvent(const AzFramework::InputChannel& channel) const
{
const AzFramework::InputChannelId& channelId = channel.GetInputChannelId();
if (channelId == AzFramework::InputDeviceMouse::Movement::X || channelId == AzFramework::InputDeviceMouse::Movement::Y)
{
return false;
}
// We map keyboard and mouse events from Qt, so flag all events coming from those devices
// as handled by our synthetic event system.
const AzFramework::InputDeviceId& deviceId = channel.GetInputDevice().GetInputDeviceId();
@@ -210,6 +205,22 @@ namespace AzToolsFramework
}
}
void QtEventToAzInputMapper::SetCursorCaptureEnabled(bool enabled)
{
if (m_capturingCursor != enabled)
{
m_capturingCursor = enabled;
if (m_capturingCursor)
{
qApp->setOverrideCursor(Qt::BlankCursor);
}
else
{
qApp->restoreOverrideCursor();
}
}
}
bool QtEventToAzInputMapper::eventFilter(QObject* object, QEvent* event)
{
// Abort if processing isn't enabled.
@@ -284,13 +295,25 @@ namespace AzToolsFramework
{
auto systemCursorChannel =
GetInputChannel<AzFramework::InputChannelDeltaWithSharedPosition2D>(AzFramework::InputDeviceMouse::SystemCursorPosition);
auto movementXChannel =
GetInputChannel<AzFramework::InputChannelDeltaWithSharedPosition2D>(AzFramework::InputDeviceMouse::Movement::X);
auto movementYChannel =
GetInputChannel<AzFramework::InputChannelDeltaWithSharedPosition2D>(AzFramework::InputDeviceMouse::Movement::Y);
auto mouseWheelChannel =
GetInputChannel<AzFramework::InputChannelDeltaWithSharedPosition2D>(AzFramework::InputDeviceMouse::Movement::Z);
systemCursorChannel->ProcessRawInputEvent(m_cursorPosition->m_normalizedPositionDelta.GetLength());
// Generate movement events based on the pixel delta divided by the DPI scaling factor, to calculate a rough approximation
// of cursor movement velocity.
movementXChannel->ProcessRawInputEvent(
m_cursorPosition->m_normalizedPositionDelta.GetX() * aznumeric_cast<float>(m_sourceWidget->width()) / m_sourceWidget->devicePixelRatioF());
movementYChannel->ProcessRawInputEvent(
m_cursorPosition->m_normalizedPositionDelta.GetY() * aznumeric_cast<float>(m_sourceWidget->height()) / m_sourceWidget->devicePixelRatioF());
mouseWheelChannel->ProcessRawInputEvent(0.f);
NotifyUpdateChannelIfNotIdle(systemCursorChannel, nullptr);
NotifyUpdateChannelIfNotIdle(movementXChannel, nullptr);
NotifyUpdateChannelIfNotIdle(movementYChannel, nullptr);
NotifyUpdateChannelIfNotIdle(mouseWheelChannel, nullptr);
}
@@ -318,16 +341,42 @@ namespace AzToolsFramework
}
}
AZ::Vector2 QtEventToAzInputMapper::WidgetPositionToNormalizedPosition(QPoint position)
{
const float normalizedX = aznumeric_cast<float>(position.x()) / aznumeric_cast<float>(m_sourceWidget->width());
const float normalizedY = aznumeric_cast<float>(position.y()) / aznumeric_cast<float>(m_sourceWidget->height());
return AZ::Vector2{normalizedX, normalizedY};
}
QPoint QtEventToAzInputMapper::NormalizedPositionToWidgetPosition(AZ::Vector2 normalizedPosition)
{
const int denormalizedX = aznumeric_cast<int>(normalizedPosition.GetX() * m_sourceWidget->width());
const int denormalizedY = aznumeric_cast<int>(normalizedPosition.GetY() * m_sourceWidget->height());
return QPoint{denormalizedX, denormalizedY};
}
void QtEventToAzInputMapper::HandleMouseMoveEvent(QMouseEvent* mouseEvent)
{
AZ::Vector2 lastCursorPosition = m_cursorPosition->m_normalizedPosition;
const QPoint mousePos = mouseEvent->pos();
const float normalizedX = aznumeric_cast<float>(mousePos.x()) / aznumeric_cast<float>(m_sourceWidget->width());
const float normalizedY = aznumeric_cast<float>(mousePos.y()) / aznumeric_cast<float>(m_sourceWidget->height());
const AZ::Vector2 normalizedPosition(normalizedX, normalizedY);
const AZ::Vector2 normalizedPosition = WidgetPositionToNormalizedPosition(mousePos);
m_cursorPosition->m_normalizedPositionDelta = normalizedPosition - m_cursorPosition->m_normalizedPosition;
m_cursorPosition->m_normalizedPosition = normalizedPosition;
ProcessPendingMouseEvents();
m_mouseChannelsNeedUpdate = true;
if (m_capturingCursor)
{
// Reset our cursor position to the previous point.
QPoint targetScreenPosition = m_sourceWidget->mapToGlobal(NormalizedPositionToWidgetPosition(lastCursorPosition));
AzQtComponents::SetCursorPos(targetScreenPosition);
// Even though we just set the cursor position, there are edge cases such as remote desktop that will leave
// the cursor position unchanged. For safety, we re-cache our last cursor position for delta generation.
QPoint actualWidgetPosition = m_sourceWidget->mapFromGlobal(QCursor::pos());
m_cursorPosition->m_normalizedPosition = WidgetPositionToNormalizedPosition(actualWidgetPosition);
}
}
void QtEventToAzInputMapper::HandleKeyEvent(QKeyEvent* keyEvent)
@@ -47,6 +47,12 @@ namespace AzToolsFramework
//! Sets whether or not this input mapper should be updating its input channels from Qt events.
void SetEnabled(bool enabled);
//! Sets whether or not the cursor should be constrained to the source widget and invisible.
//! Internally, this will reset the cursor position after each move event to ensure movement
//! events don't allow the cursor to escape. This can be used for typical camera controls
//! like a dolly or rotation, where mouse movement is important but cursor location is not.
void SetCursorCaptureEnabled(bool enabled);
// QObject overrides...
bool eventFilter(QObject* object, QEvent* event) override;
@@ -106,6 +112,11 @@ namespace AzToolsFramework
// Processes any pending mouse movement events, this allows mouse movement channels to close themselves.
void ProcessPendingMouseEvents();
// Converts a point in logical source widget space [0..m_sourceWidget->size()] to normalized [0..1] space.
AZ::Vector2 WidgetPositionToNormalizedPosition(QPoint position);
// Converts a point in normalized [0..1] space to logical source widget space [0..m_sourceWidget->size()].
QPoint NormalizedPositionToWidgetPosition(AZ::Vector2 normalizedPosition);
// Handle mouse click events.
void HandleMouseButtonEvent(QMouseEvent* mouseEvent);
// Handle mouse move events.
@@ -144,6 +155,8 @@ namespace AzToolsFramework
bool m_mouseChannelsNeedUpdate = false;
// Flags whether or not Qt events should currently be processed.
bool m_enabled = true;
// Flags whether or not the cursor is being constrained to the source widget (for invisible mouse movement).
bool m_capturingCursor = false;
// Our viewport-specific AZ devices. We control their internal input channel states.
AZStd::unique_ptr<EditorQtMouseDevice> m_mouseDevice;
@@ -172,20 +172,23 @@ namespace AzToolsFramework
PrefabDom& templateDomReference = m_prefabSystemComponentInterface->FindTemplateDom(templateId);
//apply patch to template
AZ::JsonSerializationResult::ResultCode result = AZ::JsonSerialization::ApplyPatch(templateDomReference,
templateDomReference.GetAllocator(), providedPatch, AZ::JsonMergeApproach::JsonPatch);
AZ::JsonSerializationResult::ResultCode result =
PrefabDomUtils::ApplyPatches(templateDomReference, templateDomReference.GetAllocator(), providedPatch);
//trigger propagation
if (result.GetOutcome() == AZ::JsonSerializationResult::Outcomes::Success)
if (result.GetOutcome() != AZ::JsonSerializationResult::Outcomes::Success)
{
m_prefabSystemComponentInterface->SetTemplateDirtyFlag(templateId, true);
m_prefabSystemComponentInterface->PropagateTemplateChanges(templateId, instanceToExclude);
return true;
AZ_Error("Prefab", false, "Patch was not successfully applied.");
return false;
}
else
{
AZ_Error("Prefab", false, "Patch was not successfully applied");
return false;
AZ_Error(
"Prefab", result.GetOutcome() != AZ::JsonSerializationResult::Outcomes::PartialSkip,
"Some of the patches are not successfully applied.");
m_prefabSystemComponentInterface->SetTemplateDirtyFlag(templateId, true);
m_prefabSystemComponentInterface->PropagateTemplateChanges(templateId, instanceToExclude);
return true;
}
}
@@ -176,12 +176,17 @@ namespace AzToolsFramework
}
else
{
AZ::JsonSerializationResult::ResultCode applyPatchResult = AZ::JsonSerialization::ApplyPatch(
sourceTemplateDomCopy,
targetTemplatePrefabDom.GetAllocator(),
patchesReference->get(),
AZ::JsonMergeApproach::JsonPatch);
AZ::JsonSerializationResult::ResultCode applyPatchResult =
PrefabDomUtils::ApplyPatches(sourceTemplateDomCopy, targetTemplatePrefabDom.GetAllocator(), patchesReference->get());
linkedInstanceDom.CopyFrom(sourceTemplateDomCopy, targetTemplatePrefabDom.GetAllocator());
PrefabDomValueReference sourceTemplateName =
PrefabDomUtils::FindPrefabDomValue(sourceTemplateDomCopy, PrefabDomUtils::SourceName);
AZ_Assert(sourceTemplateName && sourceTemplateName->get().IsString(), "A valid source template name couldn't be found");
PrefabDomValueReference targetTemplateName =
PrefabDomUtils::FindPrefabDomValue(targetTemplatePrefabDom, PrefabDomUtils::SourceName);
AZ_Assert(targetTemplateName && targetTemplateName->get().IsString(), "A valid target template name couldn't be found");
if (applyPatchResult.GetProcessing() != AZ::JsonSerializationResult::Processing::Completed)
{
AZ_Error(
@@ -190,6 +195,14 @@ namespace AzToolsFramework
m_sourceTemplateId, m_targetTemplateId);
return false;
}
if (applyPatchResult.GetOutcome() == AZ::JsonSerializationResult::Outcomes::PartialSkip)
{
AZ_Error(
"Prefab", false,
"Link::UpdateTarget - Some of the patches couldn't be applied on the source template '%s' present under the "
"target Template '%s'.",
sourceTemplateName->get().GetString(), targetTemplateName->get().GetString());
}
}
// This is a guardrail to ensure the linked instance dom always has the LinkId value
@@ -236,6 +236,26 @@ namespace AzToolsFramework
return findInstancesResult->get();
}
AZ::JsonSerializationResult::ResultCode ApplyPatches(
PrefabDomValue& prefabDomToApplyPatchesOn, PrefabDom::AllocatorType& allocator, const PrefabDomValue& patches)
{
auto issueReportingCallback = [](AZStd::string_view, AZ::JsonSerializationResult::ResultCode result,
AZStd::string_view) -> AZ::JsonSerializationResult::ResultCode
{
using namespace AZ::JsonSerializationResult;
if (result.GetProcessing() == Processing::Halted)
{
return ResultCode(result.GetTask(), Outcomes::PartialSkip);
}
return result;
};
AZ::JsonApplyPatchSettings applyPatchSettings;
applyPatchSettings.m_reporting = AZStd::move(issueReportingCallback);
return AZ::JsonSerialization::ApplyPatch(
prefabDomToApplyPatchesOn, allocator, patches, AZ::JsonMergeApproach::JsonPatch, applyPatchSettings);
}
void PrintPrefabDomValue(
[[maybe_unused]] const AZStd::string_view printMessage,
[[maybe_unused]] const PrefabDomValue& prefabDomValue)
@@ -7,6 +7,7 @@
#pragma once
#include <AzCore/Serialization/Json/JsonSerializationResult.h>
#include <AzCore/std/optional.h>
#include <AzCore/Asset/AssetCommon.h>
#include <AzToolsFramework/Prefab/Instance/Instance.h>
@@ -122,6 +123,11 @@ namespace AzToolsFramework
*/
PrefabDomValueConstReference GetInstancesValue(const PrefabDomValue& prefabDom);
AZ::JsonSerializationResult::ResultCode ApplyPatches(
PrefabDomValue& prefabDomToApplyPatchesOn,
PrefabDom::AllocatorType& allocator,
const PrefabDomValue& patches);
/**
* Prints the contents of the given prefab DOM value to the debug output console in a readable format.
* @param printMessage The message that will be printed before printing the PrefabDomValue
@@ -261,8 +261,13 @@ namespace AzToolsFramework
instanceDom.CopyFrom(instanceDomRef->get(), instanceDom.GetAllocator());
//apply the patch to the template within the target
AZ::JsonSerializationResult::ResultCode result = AZ::JsonSerialization::ApplyPatch(instanceDom,
instanceDom.GetAllocator(), patch, AZ::JsonMergeApproach::JsonPatch);
AZ::JsonSerializationResult::ResultCode result = PrefabDomUtils::ApplyPatches(instanceDom, instanceDom.GetAllocator(), patch);
AZ_Error(
"Prefab",
result.GetOutcome() == AZ::JsonSerializationResult::Outcomes::PartialSkip ||
result.GetOutcome() == AZ::JsonSerializationResult::Outcomes::Success,
"Some of the patches are not successfully applied.");
//remove the link id placed into the instance
auto linkIdIter = instanceDom.FindMember(PrefabDomUtils::LinkIdName);
@@ -22,11 +22,11 @@ namespace AzToolsFramework
/// @name Reverse URLs.
/// Used to identify common actions and override them when necessary.
//@{
static const AZ::Crc32 s_backAction = AZ_CRC("com.amazon.action.common.back", 0xd772a2af);
static const AZ::Crc32 s_deleteAction = AZ_CRC("com.amazon.action.common.delete", 0x5731f6cb);
static const AZ::Crc32 s_duplicateAction = AZ_CRC("com.amazon.action.common.duplicate", 0x08ccf461);
static const AZ::Crc32 s_nextComponentMode = AZ_CRC("com.amazon.action.common.nextComponentMode", 0xcc26094f);
static const AZ::Crc32 s_previousComponentMode = AZ_CRC("com.amazon.action.common.previousComponentMode", 0x0d18ff39);
static const AZ::Crc32 s_backAction = AZ_CRC("com.o3de.action.common.back", 0xd772a2af);
static const AZ::Crc32 s_deleteAction = AZ_CRC("com.o3de.action.common.delete", 0x5731f6cb);
static const AZ::Crc32 s_duplicateAction = AZ_CRC("com.o3de.action.common.duplicate", 0x08ccf461);
static const AZ::Crc32 s_nextComponentMode = AZ_CRC("com.o3de.action.common.nextComponentMode", 0xcc26094f);
static const AZ::Crc32 s_previousComponentMode = AZ_CRC("com.o3de.action.common.previousComponentMode", 0x0d18ff39);
//@}
/// Specific Action properties to be sent to a type implementing
@@ -276,11 +276,6 @@ namespace AzToolsFramework
virtual void EndCursorCapture() = 0;
//! Gets the most recent recorded cursor position in the viewport in screen space coordinates.
virtual AzFramework::ScreenPoint ViewportCursorScreenPosition() = 0;
//! Gets the cursor position recorded prior to the most recent cursor position.
//! Note: The cursor may be captured by the viewport, in which case this may not correspond to the last result
//! from ViewportCursorScreenPosition. This method will always return the correct position to generate a mouse
//! position delta.
virtual AZStd::optional<AzFramework::ScreenPoint> PreviousViewportCursorScreenPosition() = 0;
//! Is mouse over viewport.
virtual bool IsMouseOver() const = 0;
@@ -98,7 +98,7 @@ namespace AzToolsFramework
{
}
AZ::Crc32 m_uri; //!< Unique identifier for the Action. (In the form 'com.amazon.action.---").
AZ::Crc32 m_uri; //!< Unique identifier for the Action. (In the form 'com.o3de.action.---").
AZStd::vector<AZStd::function<void()>> m_callbacks; //!< Callbacks associated with this Action (note: with multi-selections
//!< there will be a callback per Entity/Component).
AZStd::unique_ptr<QAction> m_action; //!< The QAction associated with the overrideWidget for all ComponentMode actions.
@@ -196,7 +196,7 @@ namespace AzToolsFramework
AZStd::vector<AzToolsFramework::ActionOverride> PlaceHolderComponentMode::PopulateActionsImpl()
{
const AZ::Crc32 placeHolderComponentModeAction = AZ_CRC_CE("com.amazon.action.placeholder.test");
const AZ::Crc32 placeHolderComponentModeAction = AZ_CRC_CE("com.o3de.action.placeholder.test");
return AZStd::vector<AzToolsFramework::ActionOverride>
{
@@ -96,8 +96,8 @@ namespace UnitTest
//apply the patch
PrefabDom& templateDomReference = m_prefabSystemComponent->FindTemplateDom(nestedTemplateId);
AZ::JsonSerializationResult::ResultCode result = AZ::JsonSerialization::ApplyPatch(templateDomReference,
templateDomReference.GetAllocator(), patch, AZ::JsonMergeApproach::JsonPatch);
AZ::JsonSerializationResult::ResultCode result =
PrefabDomUtils::ApplyPatches(templateDomReference, templateDomReference.GetAllocator(), patch);
AZ_Error("Prefab", result.GetOutcome() == AZ::JsonSerializationResult::Outcomes::Success,
"Patch was not successfully applied");
@@ -25,6 +25,8 @@ namespace AWSNativeSDKInit
#if defined(PLATFORM_SUPPORTS_AWS_NATIVE_SDK)
void CustomizeSDKOptions(Aws::SDKOptions& options);
void CustomizeShutdown();
void CopyCaCertBundle();
#endif
}
@@ -44,6 +46,8 @@ namespace AWSNativeSDKInit
void InitializationManager::InitAwsApi()
{
s_initManager = AZ::Environment::CreateVariable<InitializationManager>(initializationManagerTag);
Platform::CopyCaCertBundle();
}
void InitializationManager::Shutdown()
@@ -0,0 +1,89 @@
/*
* 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 <AzCore/PlatformDef.h>
// The AWS Native SDK AWSAllocator triggers a warning due to accessing members of std::allocator directly.
// AWSAllocator.h(70): warning C4996: 'std::allocator<T>::pointer': warning STL4010: Various members of std::allocator are deprecated in
// C++17. Use std::allocator_traits instead of accessing these members directly. You can define
// _SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING or _SILENCE_ALL_CXX17_DEPRECATION_WARNINGS to acknowledge that you have received
// this warning.
AZ_PUSH_DISABLE_WARNING(4251 4996, "-Wunknown-warning-option")
#include <aws/core/utils/memory/stl/AWSString.h>
AZ_POP_DISABLE_WARNING
#include <AzCore/Android/Utils.h>
#include <AzCore/IO/FileIO.h>
#include <AzCore/IO/SystemFile.h>
#include <AzCore/std/containers/vector.h>
namespace AWSNativeSDKInit
{
namespace Platform
{
void CopyCaCertBundle()
{
AZStd::vector<char> contents;
AZStd::string certificatePath = "@assets@/certificates/aws/cacert.pem";
AZStd::string publicStoragePath = AZ::Android::Utils::GetAppPublicStoragePath();
publicStoragePath.append("/certificates/aws/cacert.pem");
AZ::IO::FileIOBase* fileBase = AZ::IO::FileIOBase::GetInstance();
if (!fileBase->Exists(certificatePath.c_str()))
{
AZ_Error("AWSNativeSDKInit", false, "Certificate File(%s) does not exist.\n", certificatePath.c_str());
}
AZ::IO::HandleType fileHandle;
AZ::IO::Result fileResult = fileBase->Open(certificatePath.c_str(), AZ::IO::OpenMode::ModeRead, fileHandle);
if (!fileResult)
{
AZ_Error("AWSNativeSDKInit", false, "Failed to open certificate file with result %i\n", fileResult.GetResultCode());
}
AZ::u64 fileSize = 0;
fileBase->Size(fileHandle, fileSize);
if (fileSize == 0)
{
AZ_Error("AWSNativeSDKInit", false, "Given empty file(%s) as the certificate bundle.\n", certificatePath.c_str());
}
contents.resize(fileSize + 1);
fileResult = fileBase->Read(fileHandle, contents.data(), fileSize);
if (!fileResult)
{
AZ_Error(
"AWSNativeSDKInit", false, "Failed to read from the certificate bundle(%s) with result code(%i).\n", certificatePath.c_str(),
fileResult.GetResultCode());
}
AZ_Printf("AWSNativeSDKInit", "Certificate bundle is read successfully from %s", certificatePath.c_str());
AZ::IO::HandleType outFileHandle;
AZ::IO::Result outFileResult = fileBase->Open(publicStoragePath.c_str(), AZ::IO::OpenMode::ModeWrite, outFileHandle);
if (!outFileResult)
{
AZ_Error("AWSNativeSDKInit", false, "Failed to open the certificate bundle with result %i\n", fileResult.GetResultCode());
}
AZ::IO::Result writeFileResult = fileBase->Write(outFileHandle, contents.data(), fileSize);
if (!writeFileResult)
{
AZ_Error("AWSNativeSDKInit", false, "Failed to write the certificate bundle with result %i\n", writeFileResult.GetResultCode());
}
fileBase->Close(fileHandle);
fileBase->Close(outFileHandle);
AZ_Printf("AWSNativeSDKInit", "Certificate bundle successfully copied to %s", publicStoragePath.c_str());
}
} // namespace Platform
}
@@ -7,4 +7,5 @@
set(FILES
../Common/Default/AWSNativeSDKInit_Default.cpp
InitializeCerts_Android.cpp
)
@@ -0,0 +1,16 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
namespace AWSNativeSDKInit
{
namespace Platform
{
void CopyCaCertBundle()
{
}
} // namespace Platform
} // namespace AWSCore
@@ -7,4 +7,5 @@
set(FILES
../Common/Default/AWSNativeSDKInit_Default.cpp
../Common/Default/InitializeCerts_Null.cpp
)
@@ -7,4 +7,5 @@
set(FILES
../Common/Default/AWSNativeSDKInit_Default.cpp
../Common/Default/InitializeCerts_Null.cpp
)
@@ -7,4 +7,5 @@
set(FILES
../Common/Default/AWSNativeSDKInit_Default.cpp
../Common/Default/InitializeCerts_Null.cpp
)
@@ -7,4 +7,5 @@
set(FILES
../Common/Default/AWSNativeSDKInit_Default.cpp
../Common/Default/InitializeCerts_Null.cpp
)
@@ -7,6 +7,8 @@
#include <AzCore/Serialization/SerializeContext.h>
#include <SceneAPI/SceneCore/Components/ExportingComponent.h>
#include <SceneAPI/SceneCore/Events/ExportProductList.h>
#include <AzCore/RTTI/BehaviorContext.h>
namespace AZ
{
@@ -31,6 +33,12 @@ namespace AZ
{
serializeContext->Class<ExportingComponent, AZ::Component>()->Version(2);
}
AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context);
if (behaviorContext)
{
Events::ExportProductList::Reflect(behaviorContext);
}
}
} // namespace SceneCore
} // namespace SceneAPI
@@ -211,6 +211,7 @@ namespace AZ
AZ::SceneAPI::Containers::SceneGraph::Reflect(context);
AZ::SceneAPI::Containers::SceneManifest::Reflect(context);
AZ::SceneAPI::Containers::RuleContainer::Reflect(context);
AZ::SceneAPI::SceneCore::ExportingComponent::Reflect(context);
}
void Activate()
@@ -6,6 +6,8 @@
*/
#include <SceneAPI/SceneCore/Events/ExportProductList.h>
#include <AzCore/RTTI/BehaviorContext.h>
#include <AzCore/std/limits.h>
namespace AZ
{
@@ -49,6 +51,45 @@ namespace AZ
return *this;
}
void ExportProductList::Reflect(ReflectContext* context)
{
if (auto* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
{
serializeContext->Class<ExportProduct>()->Version(1);
serializeContext->Class<ExportProductList>()->Version(1);
}
if (auto* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
{
behaviorContext->Class<ExportProduct>("ExportProduct")
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
->Attribute(AZ::Script::Attributes::Module, "scene")
->Property("filename", BehaviorValueProperty(&ExportProduct::m_filename))
->Property("sourceId", BehaviorValueProperty(&ExportProduct::m_id))
->Property("assetType", BehaviorValueProperty(&ExportProduct::m_assetType))
->Property("productDependencies", BehaviorValueProperty(&ExportProduct::m_productDependencies))
->Property("subId",
[](ExportProduct* self) { return self->m_subId.has_value() ? self->m_subId.value() : 0; },
[](ExportProduct* self, u32 subId) { self->m_subId = AZStd::optional<u32>(subId); });
behaviorContext->Class<ExportProductList>("ExportProductList")
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
->Attribute(AZ::Script::Attributes::Module, "scene")
->Method("AddProduct", [](ExportProductList& self, ExportProduct& product)
{
self.AddProduct(
product.m_filename,
product.m_id,
product.m_assetType,
product.m_lod,
product.m_subId,
product.m_dependencyFlags);
})
->Method("GetProducts", &ExportProductList::GetProducts)
->Method("AddDependencyToProduct", &ExportProductList::AddDependencyToProduct);
}
}
ExportProduct& ExportProductList::AddProduct(const AZStd::string& filename, Uuid id, Data::AssetType assetType, AZStd::optional<u8> lod, AZStd::optional<u32> subId,
Data::ProductDependencyInfo::ProductDependencyFlags dependencyFlags)
{
@@ -14,6 +14,8 @@
namespace AZ
{
class ReflectContext;
namespace SceneAPI
{
namespace Events
@@ -24,6 +26,7 @@ namespace AZ
Data::ProductDependencyInfo::ProductDependencyFlags dependencyFlags = Data::ProductDependencyInfo::CreateFlags(Data::AssetLoadBehavior::NoLoad));
SCENE_CORE_API ExportProduct(AZStd::string&& filename, Uuid id, Data::AssetType assetType, AZStd::optional<u8> lod, AZStd::optional<u32> subId,
Data::ProductDependencyInfo::ProductDependencyFlags dependencyFlags = Data::ProductDependencyInfo::CreateFlags(Data::AssetLoadBehavior::NoLoad));
ExportProduct() = default;
ExportProduct(const ExportProduct& rhs) = default;
SCENE_CORE_API ExportProduct(ExportProduct&& rhs);
@@ -54,6 +57,8 @@ namespace AZ
class ExportProductList
{
public:
static void Reflect(ReflectContext* context);
SCENE_CORE_API ExportProduct& AddProduct(const AZStd::string& filename, Uuid id, Data::AssetType assetType, AZStd::optional<u8> lod, AZStd::optional<u32> subId,
Data::ProductDependencyInfo::ProductDependencyFlags dependencyFlags = Data::ProductDependencyInfo::CreateFlags(Data::AssetLoadBehavior::NoLoad));
SCENE_CORE_API ExportProduct& AddProduct(AZStd::string&& filename, Uuid id, Data::AssetType assetType, AZStd::optional<u8> lod, AZStd::optional<u32> subId,
@@ -69,3 +74,9 @@ namespace AZ
} // namespace Events
} // namespace SceneAPI
} // namespace AZ
namespace AZ
{
AZ_TYPE_INFO_SPECIALIZE(SceneAPI::Events::ExportProduct, "{6054EDCB-4C04-4D96-BF26-704999FFB725}");
AZ_TYPE_INFO_SPECIALIZE(SceneAPI::Events::ExportProductList, "{1C76A51F-431B-4987-B653-CFCC940D0D0F}");
}
@@ -10,6 +10,7 @@
#include <AzCore/IO/SystemFile.h>
#include <AzCore/IO/GenericStreams.h>
#include <AzCore/Memory/SystemAllocator.h>
#include <AzCore/Utils/Utils.h>
#include <AzFramework/API/ApplicationAPI.h>
#include <AzFramework/StringFunc/StringFunc.h>
#include <SceneAPI/SceneCore/Import/ManifestImportRequestHandler.h>
@@ -75,15 +76,16 @@ namespace AZ
filename += s_extension;
filename += s_generated;
AZStd::string altManifestPath = path;
AZStd::string altManifestFolder = path;
AzFramework::ApplicationRequests::Bus::Broadcast(
&AzFramework::ApplicationRequests::Bus::Events::MakePathRootRelative,
altManifestPath);
&AzFramework::ApplicationRequests::Bus::Events::MakePathRelative,
altManifestFolder,
AZ::Utils::GetProjectPath().c_str());
AZ::StringFunc::Path::GetFolderPath(altManifestPath.c_str(), altManifestPath);
AZ::StringFunc::Path::GetFolderPath(altManifestFolder.c_str(), altManifestFolder);
AZStd::string generatedAssetInfoPath;
AZ::StringFunc::Path::Join(assetCacheRoot.c_str(), altManifestPath.c_str(), generatedAssetInfoPath);
AZ::StringFunc::Path::Join(assetCacheRoot.c_str(), altManifestFolder.c_str(), generatedAssetInfoPath);
AZ::StringFunc::Path::ConstructFull(generatedAssetInfoPath.c_str(), filename.c_str(), generatedAssetInfoPath);
if (!AZ::IO::FileIOBase::GetInstance()->Exists(generatedAssetInfoPath.c_str()))
File diff suppressed because it is too large Load Diff
@@ -25,213 +25,319 @@
#include <SceneAPI/SceneCore/Containers/Views/PairIterator.h>
#include <SceneAPI/SceneData/Rules/ScriptProcessorRule.h>
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
#include <SceneAPI/SceneCore/Events/ExportProductList.h>
namespace AZ
namespace AZ::SceneAPI::Behaviors
{
namespace SceneAPI
class EditorPythonConsoleNotificationHandler final
: protected AzToolsFramework::EditorPythonConsoleNotificationBus::Handler
{
namespace Behaviors
public:
EditorPythonConsoleNotificationHandler()
{
class EditorPythonConsoleNotificationHandler final
: protected AzToolsFramework::EditorPythonConsoleNotificationBus::Handler
BusConnect();
}
~EditorPythonConsoleNotificationHandler()
{
BusDisconnect();
}
////////////////////////////////////////////////////////////////////////////////////////////
// AzToolsFramework::EditorPythonConsoleNotifications
void OnTraceMessage([[maybe_unused]] AZStd::string_view message) override
{
using namespace AZ::SceneAPI::Utilities;
AZ_TracePrintf(LogWindow, "%.*s \n", AZ_STRING_ARG(message));
}
void OnErrorMessage([[maybe_unused]] AZStd::string_view message) override
{
using namespace AZ::SceneAPI::Utilities;
AZ_TracePrintf(ErrorWindow, "[ERROR] %.*s \n", AZ_STRING_ARG(message));
}
void OnExceptionMessage([[maybe_unused]] AZStd::string_view message) override
{
using namespace AZ::SceneAPI::Utilities;
AZ_TracePrintf(ErrorWindow, "[EXCEPTION] %.*s \n", AZ_STRING_ARG(message));
}
};
using ExportProductList = AZ::SceneAPI::Events::ExportProductList;
// a event bus to signal during scene building
struct ScriptBuildingNotifications
: public AZ::EBusTraits
{
virtual AZStd::string OnUpdateManifest(Containers::Scene& scene) = 0;
virtual ExportProductList OnPrepareForExport(
const Containers::Scene& scene,
AZStd::string_view outputDirectory,
AZStd::string_view platformIdentifier,
const ExportProductList& productList) = 0;
};
using ScriptBuildingNotificationBus = AZ::EBus<ScriptBuildingNotifications>;
// a back end to handle scene builder events for a script
struct ScriptBuildingNotificationBusHandler final
: public ScriptBuildingNotificationBus::Handler
, public AZ::BehaviorEBusHandler
{
AZ_EBUS_BEHAVIOR_BINDER(
ScriptBuildingNotificationBusHandler,
"{DF2B51DE-A4D0-4139-B5D0-DF185832380D}",
AZ::SystemAllocator,
OnUpdateManifest,
OnPrepareForExport);
virtual ~ScriptBuildingNotificationBusHandler() = default;
AZStd::string OnUpdateManifest(Containers::Scene& scene) override
{
AZStd::string result;
CallResult(result, FN_OnUpdateManifest, scene);
return result;
}
ExportProductList OnPrepareForExport(
const Containers::Scene& scene,
AZStd::string_view outputDirectory,
AZStd::string_view platformIdentifier,
const ExportProductList& productList) override
{
ExportProductList result;
CallResult(result, FN_OnPrepareForExport, scene, outputDirectory, platformIdentifier, productList);
return result;
}
static void Reflect(AZ::ReflectContext* context)
{
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
{
public:
EditorPythonConsoleNotificationHandler()
{
BusConnect();
}
behaviorContext->EBus<ScriptBuildingNotificationBus>("ScriptBuildingNotificationBus")
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation)
->Attribute(AZ::Script::Attributes::Module, "scene")
->Handler<ScriptBuildingNotificationBusHandler>()
->Event("OnUpdateManifest", &ScriptBuildingNotificationBus::Events::OnUpdateManifest)
->Event("OnPrepareForExport", &ScriptBuildingNotificationBus::Events::OnPrepareForExport);
}
}
};
~EditorPythonConsoleNotificationHandler()
{
BusDisconnect();
}
struct ScriptProcessorRuleBehavior::ExportEventHandler final
: public AZ::SceneAPI::SceneCore::ExportingComponent
{
using PreExportEventContextFunction = AZStd::function<bool(Events::PreExportEventContext&)>;
PreExportEventContextFunction m_preExportEventContextFunction;
////////////////////////////////////////////////////////////////////////////////////////////
// AzToolsFramework::EditorPythonConsoleNotifications
void OnTraceMessage([[maybe_unused]] AZStd::string_view message) override
{
using namespace AZ::SceneAPI::Utilities;
AZ_TracePrintf(LogWindow, "%.*s \n", AZ_STRING_ARG(message));
}
ExportEventHandler(PreExportEventContextFunction preExportEventContextFunction)
: m_preExportEventContextFunction(preExportEventContextFunction)
{
BindToCall(&ExportEventHandler::PrepareForExport);
AZ::SceneAPI::SceneCore::ExportingComponent::Activate();
}
void OnErrorMessage([[maybe_unused]] AZStd::string_view message) override
{
using namespace AZ::SceneAPI::Utilities;
AZ_TracePrintf(ErrorWindow, "[ERROR] %.*s \n", AZ_STRING_ARG(message));
}
~ExportEventHandler()
{
AZ::SceneAPI::SceneCore::ExportingComponent::Deactivate();
}
void OnExceptionMessage([[maybe_unused]] AZStd::string_view message) override
{
using namespace AZ::SceneAPI::Utilities;
AZ_TracePrintf(ErrorWindow, "[EXCEPTION] %.*s \n", AZ_STRING_ARG(message));
}
};
// this allows a Python script to add product assets on "scene export"
Events::ProcessingResult PrepareForExport(Events::PreExportEventContext& context)
{
return m_preExportEventContextFunction(context) ? Events::ProcessingResult::Success : Events::ProcessingResult::Failure;
}
};
// a event bus to signal during scene building
struct ScriptBuildingNotifications
: public AZ::EBusTraits
void ScriptProcessorRuleBehavior::Activate()
{
Events::AssetImportRequestBus::Handler::BusConnect();
m_exportEventHandler = AZStd::make_shared<ExportEventHandler>([this](Events::PreExportEventContext& context)
{
return this->DoPrepareForExport(context);
});
}
void ScriptProcessorRuleBehavior::Deactivate()
{
m_exportEventHandler.reset();
Events::AssetImportRequestBus::Handler::BusDisconnect();
UnloadPython();
}
bool ScriptProcessorRuleBehavior::LoadPython(const AZ::SceneAPI::Containers::Scene& scene)
{
if (m_editorPythonEventsInterface && !m_scriptFilename.empty())
{
return true;
}
// get project folder
auto settingsRegistry = AZ::SettingsRegistry::Get();
AZ::IO::FixedMaxPath projectPath;
if (!settingsRegistry->Get(projectPath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_ProjectPath))
{
return false;
}
const AZ::SceneAPI::Containers::SceneManifest& manifest = scene.GetManifest();
auto view = Containers::MakeDerivedFilterView<DataTypes::IScriptProcessorRule>(manifest.GetValueStorage());
for (const auto& scriptItem : view)
{
AZ::IO::FixedMaxPath scriptFilename(scriptItem.GetScriptFilename());
if (scriptFilename.empty())
{
virtual AZStd::string OnUpdateManifest(Containers::Scene& scene) = 0;
};
using ScriptBuildingNotificationBus = AZ::EBus<ScriptBuildingNotifications>;
AZ_Warning("scene", false, "Skipping an empty script filename in (%s)", scene.GetManifestFilename().c_str());
continue;
}
// a back end to handle scene builder events for a script
struct ScriptBuildingNotificationBusHandler final
: public ScriptBuildingNotificationBus::Handler
, public AZ::BehaviorEBusHandler
// check for file exist via absolute path
if (!IO::FileIOBase::GetInstance()->Exists(scriptFilename.c_str()))
{
AZ_EBUS_BEHAVIOR_BINDER(
ScriptBuildingNotificationBusHandler,
"{DF2B51DE-A4D0-4139-B5D0-DF185832380D}",
AZ::SystemAllocator,
OnUpdateManifest);
virtual ~ScriptBuildingNotificationBusHandler() = default;
AZStd::string OnUpdateManifest(Containers::Scene& scene) override
// check for script in the project folder
AZ::IO::FixedMaxPath projectScriptPath = projectPath / scriptFilename;
if (!IO::FileIOBase::GetInstance()->Exists(projectScriptPath.c_str()))
{
AZStd::string result;
CallResult(result, FN_OnUpdateManifest, scene);
return result;
AZ_Warning("scene", false, "Skipping a missing script (%s) in manifest file (%s)",
scriptFilename.c_str(),
scene.GetManifestFilename().c_str());
continue;
}
scriptFilename = AZStd::move(projectScriptPath);
}
static void Reflect(AZ::ReflectContext* context)
// lazy load the Python interface
auto editorPythonEventsInterface = AZ::Interface<AzToolsFramework::EditorPythonEventsInterface>::Get();
if (editorPythonEventsInterface->IsPythonActive() == false)
{
const bool silenceWarnings = false;
if (editorPythonEventsInterface->StartPython(silenceWarnings) == false)
{
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
{
behaviorContext->EBus<ScriptBuildingNotificationBus>("ScriptBuildingNotificationBus")
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation)
->Attribute(AZ::Script::Attributes::Module, "scene")
->Handler<ScriptBuildingNotificationBusHandler>()
->Event("OnUpdateManifest", &ScriptBuildingNotificationBus::Events::OnUpdateManifest);
}
editorPythonEventsInterface = nullptr;
}
}
// both Python and the script need to be ready
if (editorPythonEventsInterface == nullptr || scriptFilename.empty())
{
AZ_Warning("scene", false,"The scene manifest (%s) attempted to use script(%s) but Python is not enabled;"
"please add the EditorPythonBinding gem & PythonAssetBuilder gem to your project.",
scene.GetManifestFilename().c_str(), scriptFilename.c_str());
return false;
}
m_editorPythonEventsInterface = editorPythonEventsInterface;
m_scriptFilename = scriptFilename.c_str();
return true;
}
return false;
}
void ScriptProcessorRuleBehavior::UnloadPython()
{
if (m_editorPythonEventsInterface)
{
const bool silenceWarnings = true;
m_editorPythonEventsInterface->StopPython(silenceWarnings);
m_editorPythonEventsInterface = nullptr;
}
}
bool ScriptProcessorRuleBehavior::DoPrepareForExport(Events::PreExportEventContext& context)
{
using namespace AzToolsFramework;
auto executeCallback = [this, &context]()
{
// set up script's hook callback
EditorPythonRunnerRequestBus::Broadcast(&EditorPythonRunnerRequestBus::Events::ExecuteByFilename,
m_scriptFilename.c_str());
// call script's callback to allow extra products
ExportProductList extraProducts;
ScriptBuildingNotificationBus::BroadcastResult(extraProducts, &ScriptBuildingNotificationBus::Events::OnPrepareForExport,
context.GetScene(),
context.GetOutputDirectory(),
context.GetPlatformIdentifier(),
context.GetProductList()
);
// add new products
for (const auto& product : extraProducts.GetProducts())
{
context.GetProductList().AddProduct(
product.m_filename,
product.m_id,
product.m_assetType,
product.m_lod,
product.m_subId,
product.m_dependencyFlags);
}
};
if (LoadPython(context.GetScene()))
{
EditorPythonConsoleNotificationHandler logger;
m_editorPythonEventsInterface->ExecuteWithLock(executeCallback);
}
return true;
}
void ScriptProcessorRuleBehavior::Reflect(ReflectContext* context)
{
ScriptBuildingNotificationBusHandler::Reflect(context);
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
if (serializeContext)
{
serializeContext->Class<ScriptProcessorRuleBehavior, BehaviorComponent>()->Version(1);
}
}
Events::ProcessingResult ScriptProcessorRuleBehavior::UpdateManifest(
Containers::Scene& scene,
Events::AssetImportRequest::ManifestAction action,
[[maybe_unused]] Events::AssetImportRequest::RequestingApplication requester)
{
using namespace AzToolsFramework;
if (action != ManifestAction::Update)
{
return Events::ProcessingResult::Ignored;
}
if (LoadPython(scene))
{
AZStd::string manifestUpdate;
auto executeCallback = [this, &scene, &manifestUpdate]()
{
EditorPythonRunnerRequestBus::Broadcast(&EditorPythonRunnerRequestBus::Events::ExecuteByFilename,
m_scriptFilename.c_str());
ScriptBuildingNotificationBus::BroadcastResult(manifestUpdate, &ScriptBuildingNotificationBus::Events::OnUpdateManifest,
scene);
};
void ScriptProcessorRuleBehavior::Activate()
EditorPythonConsoleNotificationHandler logger;
m_editorPythonEventsInterface->ExecuteWithLock(executeCallback);
// attempt to load the manifest string back to a JSON-scene-manifest
auto sceneManifestLoader = AZStd::make_unique<AZ::SceneAPI::Containers::SceneManifest>();
auto loadOutcome = sceneManifestLoader->LoadFromString(manifestUpdate);
if (loadOutcome.IsSuccess())
{
Events::AssetImportRequestBus::Handler::BusConnect();
scene.GetManifest().Clear();
for (size_t entryIndex = 0; entryIndex < sceneManifestLoader->GetEntryCount(); ++entryIndex)
{
scene.GetManifest().AddEntry(sceneManifestLoader->GetValue(entryIndex));
}
return Events::ProcessingResult::Success;
}
}
return Events::ProcessingResult::Ignored;
}
void ScriptProcessorRuleBehavior::Deactivate()
{
Events::AssetImportRequestBus::Handler::BusDisconnect();
if (m_editorPythonEventsInterface)
{
const bool silenceWarnings = true;
m_editorPythonEventsInterface->StopPython(silenceWarnings);
m_editorPythonEventsInterface = nullptr;
}
}
void ScriptProcessorRuleBehavior::Reflect(ReflectContext* context)
{
ScriptBuildingNotificationBusHandler::Reflect(context);
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
if (serializeContext)
{
serializeContext->Class<ScriptProcessorRuleBehavior, BehaviorComponent>()->Version(1);
}
}
Events::ProcessingResult ScriptProcessorRuleBehavior::UpdateManifest(
Containers::Scene& scene,
Events::AssetImportRequest::ManifestAction action,
[[maybe_unused]] Events::AssetImportRequest::RequestingApplication requester)
{
using namespace AzToolsFramework;
if (action != ManifestAction::Update)
{
return Events::ProcessingResult::Ignored;
}
// get project folder
auto settingsRegistry = AZ::SettingsRegistry::Get();
AZ::IO::FixedMaxPath projectPath;
if (!settingsRegistry->Get(projectPath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_ProjectPath))
{
return Events::ProcessingResult::Ignored;
}
auto& sceneManifest = scene.GetManifest();
auto view = Containers::MakeDerivedFilterView<DataTypes::IScriptProcessorRule>(sceneManifest.GetValueStorage());
for (const auto& scriptItem : view)
{
AZ::IO::FixedMaxPath scriptFilename(scriptItem.GetScriptFilename());
if (scriptFilename.empty())
{
AZ_Warning("scene", false, "Skipping an empty script filename in (%s)", scene.GetManifestFilename().c_str());
continue;
}
// check for file exist via absolute path
if (!IO::FileIOBase::GetInstance()->Exists(scriptFilename.c_str()))
{
// check for script in the project folder
AZ::IO::FixedMaxPath projectScriptPath = projectPath / scriptFilename;
if (!IO::FileIOBase::GetInstance()->Exists(projectScriptPath.c_str()))
{
AZ_Warning("scene", false, "Skipping a missing script (%s) in manifest file (%s)",
scriptFilename.c_str(),
scene.GetManifestFilename().c_str());
continue;
}
scriptFilename = AZStd::move(projectScriptPath);
}
// lazy load the Python interface
if (!m_editorPythonEventsInterface)
{
m_editorPythonEventsInterface = AZ::Interface<AzToolsFramework::EditorPythonEventsInterface>::Get();
const bool silenceWarnings = true;
m_editorPythonEventsInterface->StartPython(silenceWarnings);
}
if (!m_editorPythonEventsInterface && !scriptFilename.empty())
{
AZ_Warning("scene", false,
"The scene manifest (%s) attempted to use script(%s) but Python is not enabled;"
"please add the EditorPythonBinding gem & PythonAssetBuilder gem to your project.",
scene.GetManifestFilename().c_str(), scriptFilename.c_str());
return Events::ProcessingResult::Ignored;
}
AZStd::string manifestUpdate;
auto executeCallback = [&scene, &scriptFilename, &manifestUpdate]()
{
EditorPythonRunnerRequestBus::Broadcast(
&EditorPythonRunnerRequestBus::Events::ExecuteByFilename,
scriptFilename.c_str());
ScriptBuildingNotificationBus::BroadcastResult(
manifestUpdate,
&ScriptBuildingNotificationBus::Events::OnUpdateManifest,
scene);
};
EditorPythonConsoleNotificationHandler logger;
m_editorPythonEventsInterface->ExecuteWithLock(executeCallback);
// attempt to load the manifest string back to a JSON-scene-manifest
auto sceneManifestLoader = AZStd::make_unique<AZ::SceneAPI::Containers::SceneManifest>();
auto loadOutcome = sceneManifestLoader->LoadFromString(manifestUpdate);
if (loadOutcome.IsSuccess())
{
sceneManifest.Clear();
for (size_t entryIndex = 0; entryIndex < sceneManifestLoader->GetEntryCount(); ++entryIndex)
{
sceneManifest.AddEntry(sceneManifestLoader->GetValue(entryIndex));
}
return Events::ProcessingResult::Success;
}
}
return Events::ProcessingResult::Ignored;
}
} // namespace Behaviors
} // namespace SceneAPI
} // namespace AZ
@@ -11,40 +11,56 @@
#include <AzCore/std/string/string.h>
#include <SceneAPI/SceneCore/Components/BehaviorComponent.h>
#include <SceneAPI/SceneCore/Events/AssetImportRequest.h>
#include <SceneAPI/SceneCore/Components/ExportingComponent.h>
#include <SceneAPI/SceneCore/Events/ExportEventContext.h>
namespace AzToolsFramework
{
class EditorPythonEventsInterface;
}
namespace AZ
namespace AZ::SceneAPI::Events
{
namespace SceneAPI
class PreExportEventContext;
}
namespace AZ::SceneAPI::Containers
{
class Scene;
}
namespace AZ::SceneAPI::Behaviors
{
class SCENE_DATA_CLASS ScriptProcessorRuleBehavior
: public SceneCore::BehaviorComponent
, public Events::AssetImportRequestBus::Handler
{
namespace Behaviors
{
class SCENE_DATA_CLASS ScriptProcessorRuleBehavior
: public SceneCore::BehaviorComponent
, public Events::AssetImportRequestBus::Handler
{
public:
AZ_COMPONENT(ScriptProcessorRuleBehavior, "{24054E73-1B92-43B0-AC13-174B2F0E3F66}", SceneCore::BehaviorComponent);
public:
AZ_COMPONENT(ScriptProcessorRuleBehavior, "{24054E73-1B92-43B0-AC13-174B2F0E3F66}", SceneCore::BehaviorComponent);
~ScriptProcessorRuleBehavior() override = default;
~ScriptProcessorRuleBehavior() override = default;
SCENE_DATA_API void Activate() override;
SCENE_DATA_API void Deactivate() override;
static void Reflect(ReflectContext* context);
SCENE_DATA_API void Activate() override;
SCENE_DATA_API void Deactivate() override;
static void Reflect(ReflectContext* context);
// AssetImportRequestBus::Handler
SCENE_DATA_API Events::ProcessingResult UpdateManifest(
Containers::Scene& scene,
ManifestAction action,
RequestingApplication requester) override;
// AssetImportRequestBus::Handler
SCENE_DATA_API Events::ProcessingResult UpdateManifest(
Containers::Scene& scene,
ManifestAction action,
RequestingApplication requester) override;
private:
AzToolsFramework::EditorPythonEventsInterface* m_editorPythonEventsInterface = nullptr;
};
} // namespace SceneData
} // namespace SceneAPI
} // namespace AZ
protected:
bool LoadPython(const AZ::SceneAPI::Containers::Scene& scene);
void UnloadPython();
bool DoPrepareForExport(Events::PreExportEventContext& context);
private:
AzToolsFramework::EditorPythonEventsInterface* m_editorPythonEventsInterface = nullptr;
AZStd::string m_scriptFilename;
struct ExportEventHandler;
AZStd::shared_ptr<ExportEventHandler> m_exportEventHandler;
};
} // namespace AZ::SceneAPI::Behaviors
@@ -13,6 +13,7 @@
#include <Authorization/AWSCognitoAuthorizationController.h>
#include <AzCore/std/smart_ptr/make_shared.h>
#include <ResourceMapping/AWSResourceMappingBus.h>
#include <Framework/AWSApiJobConfig.h>
#include <aws/cognito-identity/CognitoIdentityClient.h>
#include <aws/cognito-idp/CognitoIdentityProviderClient.h>
@@ -163,7 +164,11 @@ namespace AWSClientAuth
void AWSClientAuthSystemComponent::OnSDKInitialized()
{
Aws::Client::ClientConfiguration clientConfiguration;
AWSCore::AwsApiJobConfig* defaultConfig;
AWSCore::AWSCoreRequestBus::BroadcastResult(defaultConfig, &AWSCore::AWSCoreRequests::GetDefaultConfig);
Aws::Client::ClientConfiguration clientConfiguration =
defaultConfig ? defaultConfig->GetClientConfiguration() : Aws::Client::ClientConfiguration();
AZStd::string region;
AWSCore::AWSResourceMappingRequestBus::BroadcastResult(region, &AWSCore::AWSResourceMappingRequests::GetDefaultRegion);
@@ -113,6 +113,27 @@ namespace AWSClientAuthUnitTest
MOCK_METHOD1(ReloadConfigFile, void(bool isReloadingConfigFileName));
};
class AWSCoreRequestBusMock
: public AWSCore::AWSCoreRequestBus::Handler
{
public:
AWSCoreRequestBusMock()
{
AWSCore::AWSCoreRequestBus::Handler::BusConnect();
ON_CALL(*this, GetDefaultJobContext).WillByDefault(testing::Return(nullptr));
ON_CALL(*this, GetDefaultConfig).WillByDefault(testing::Return(nullptr));
}
~AWSCoreRequestBusMock()
{
AWSCore::AWSCoreRequestBus::Handler::BusDisconnect();
}
MOCK_METHOD0(GetDefaultJobContext, AZ::JobContext*());
MOCK_METHOD0(GetDefaultConfig, AWSCore::AwsApiJobConfig*());
};
class HttpRequestorRequestBusMock
: public HttpRequestor::HttpRequestorRequestBus::Handler
{
@@ -161,6 +161,7 @@ public:
testing::NiceMock<AWSClientAuthUnitTest::AWSClientAuthSystemComponentMock> *m_awsClientAuthSystemsComponent;
testing::NiceMock<AWSClientAuthUnitTest::AWSCoreSystemComponentMock> *m_awsCoreSystemsComponent;
testing::NiceMock<AWSClientAuthUnitTest::AWSResourceMappingRequestBusMock> m_awsResourceMappingRequestBusMock;
testing::NiceMock<AWSClientAuthUnitTest::AWSCoreRequestBusMock> m_awsCoreRequestBusMock;
AZ::Entity* m_entity = nullptr;
};
@@ -176,6 +177,7 @@ TEST_F(AWSClientAuthSystemComponentTest, ActivateDeactivate_Success)
EXPECT_CALL(*m_awsCoreSystemsComponent, Init()).Times(1).InSequence(s1);
EXPECT_CALL(*m_awsClientAuthSystemsComponent, Init()).Times(1).InSequence(s1);
EXPECT_CALL(*m_awsCoreSystemsComponent, Activate()).Times(1).InSequence(s1);
EXPECT_CALL(m_awsCoreRequestBusMock, GetDefaultConfig()).Times(1).InSequence(s1);
EXPECT_CALL(m_awsResourceMappingRequestBusMock, GetDefaultRegion()).Times(1).InSequence(s1);
EXPECT_CALL(*m_awsClientAuthSystemsComponent, Activate()).Times(1).InSequence(s1);
File diff suppressed because it is too large Load Diff
+2
View File
@@ -6,12 +6,14 @@
#
ly_get_list_relative_pal_filename(pal_editor_include_dir ${CMAKE_CURRENT_LIST_DIR}/Include/Private/Editor/Platform/${PAL_PLATFORM_NAME})
ly_get_list_relative_pal_filename(pal_cafile_include_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Framework/Platform/${PAL_PLATFORM_NAME})
ly_add_target(
NAME AWSCore.Static STATIC
NAMESPACE Gem
FILES_CMAKE
awscore_files.cmake
${pal_cafile_include_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake
INCLUDE_DIRECTORIES
PUBLIC
Include/Public
@@ -9,6 +9,10 @@
namespace AWSCore
{
namespace Platform
{
Aws::String GetCaCertBundlePath();
}
const char* AwsApiJob::COMPONENT_DISPLAY_NAME = "AWSCoreFramework";
@@ -29,6 +33,14 @@ namespace AWSCore
config.userAgent = "/O3DE_AwsApiJob";
config.requestTimeoutMs = 30000;
config.connectTimeoutMs = 30000;
// Instructs the HTTP client where to find the SSL certificate trust store.
// It is required to copy the cacert.pem to the expected file path for running the Android client.
Aws::String caFilePath = Platform::GetCaCertBundlePath();
if (!caFilePath.empty())
{
config.caFile = caFilePath;
}
}
);
};
@@ -0,0 +1,32 @@
/*
* 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 <AzCore/PlatformDef.h>
// The AWS Native SDK AWSAllocator triggers a warning due to accessing members of std::allocator directly.
// AWSAllocator.h(70): warning C4996: 'std::allocator<T>::pointer': warning STL4010: Various members of std::allocator are deprecated in
// C++17. Use std::allocator_traits instead of accessing these members directly. You can define
// _SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING or _SILENCE_ALL_CXX17_DEPRECATION_WARNINGS to acknowledge that you have received
// this warning.
AZ_PUSH_DISABLE_WARNING(4251 4996, "-Wunknown-warning-option")
#include <aws/core/utils/memory/stl/AWSString.h>
AZ_POP_DISABLE_WARNING
#include <AzCore/Android/Utils.h>
#include <AzCore/std/string/string.h>
namespace AWSCore
{
namespace Platform
{
Aws::String GetCaCertBundlePath()
{
AZStd::string publicStoragePath = AZ::Android::Utils::GetAppPublicStoragePath();
publicStoragePath.append("/certificates/aws/cacert.pem");
return publicStoragePath.c_str();
}
} // namespace Platform
}
@@ -0,0 +1,10 @@
#
# 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
#
#
set(FILES
GetCertsPath_Android.cpp
)
@@ -0,0 +1,27 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <AzCore/PlatformDef.h>
// The AWS Native SDK AWSAllocator triggers a warning due to accessing members of std::allocator directly.
// AWSAllocator.h(70): warning C4996: 'std::allocator<T>::pointer': warning STL4010: Various members of std::allocator are deprecated in
// C++17. Use std::allocator_traits instead of accessing these members directly. You can define
// _SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING or _SILENCE_ALL_CXX17_DEPRECATION_WARNINGS to acknowledge that you have received
// this warning.
AZ_PUSH_DISABLE_WARNING(4251 4996, "-Wunknown-warning-option")
#include <aws/core/utils/memory/stl/AWSString.h>
AZ_POP_DISABLE_WARNING
namespace AWSCore
{
namespace Platform
{
Aws::String GetCaCertBundlePath()
{
return ""; // no-op
}
} // namespace Platform
} // namespace GridMate
@@ -0,0 +1,10 @@
#
# 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
#
#
set(FILES
../Common/GetCertsPath_Null.cpp
)
@@ -0,0 +1,10 @@
#
# 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
#
#
set(FILES
../Common/GetCertsPath_Null.cpp
)
@@ -0,0 +1,10 @@
#
# 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
#
#
set(FILES
../Common/GetCertsPath_Null.cpp
)
@@ -0,0 +1,10 @@
#
# 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
#
#
set(FILES
../Common/GetCertsPath_Null.cpp
)
@@ -95,7 +95,7 @@ namespace AZ
shaderVariantAssetBuilderDescriptor.m_name = "Shader Variant Asset Builder";
// Both "Shader Variant Asset Builder" and "Shader Asset Builder" produce ShaderVariantAsset products. If you update
// ShaderVariantAsset you will need to update BOTH version numbers, not just "Shader Variant Asset Builder".
shaderVariantAssetBuilderDescriptor.m_version = 23; // ATOM-15472
shaderVariantAssetBuilderDescriptor.m_version = 24; // ATOM-15978
shaderVariantAssetBuilderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern(AZStd::string::format("*.%s", RPI::ShaderVariantListSourceData::Extension), AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard));
shaderVariantAssetBuilderDescriptor.m_busId = azrtti_typeid<ShaderVariantAssetBuilder>();
shaderVariantAssetBuilderDescriptor.m_createJobFunction = AZStd::bind(&ShaderVariantAssetBuilder::CreateJobs, &m_shaderVariantAssetBuilder, AZStd::placeholders::_1, AZStd::placeholders::_2);
@@ -48,6 +48,7 @@
#include "ShaderAssetBuilder.h"
#include "ShaderBuilderUtility.h"
#include "SrgLayoutUtility.h"
#include "AzslData.h"
#include "AzslCompiler.h"
#include <CommonFiles/Preprocessor.h>
@@ -520,6 +521,96 @@ namespace AZ
return;
}
}
static bool LoadSrgLayoutListFromShaderAssetBuilder(
const RHI::ShaderPlatformInterface* shaderPlatformInterface,
const AssetBuilderSDK::PlatformInfo& platformInfo,
const AzslCompiler& azslCompiler, const AZStd::string& shaderSourceFileFullPath,
const RPI::SupervariantIndex supervariantIndex,
const bool platformUsesRegisterSpaces,
RPI::ShaderResourceGroupLayoutList& srgLayoutList,
RootConstantData& rootConstantData)
{
auto srgJsonPathOutcome = ShaderBuilderUtility::ObtainBuildArtifactPathFromShaderAssetBuilder(
shaderPlatformInterface->GetAPIUniqueIndex(), platformInfo.m_identifier, shaderSourceFileFullPath, supervariantIndex.GetIndex(), AZ::RPI::ShaderAssetSubId::SrgJson);
if (!srgJsonPathOutcome.IsSuccess())
{
AZ_Error(ShaderVariantAssetBuilderName, false, "%s", srgJsonPathOutcome.GetError().c_str());
return false;
}
auto srgJsonPath = srgJsonPathOutcome.TakeValue();
auto jsonOutcome = JsonSerializationUtils::ReadJsonFile(srgJsonPath);
if (!jsonOutcome.IsSuccess())
{
AZ_Error(ShaderVariantAssetBuilderName, false, "%s", jsonOutcome.GetError().c_str());
return false;
}
SrgDataContainer srgData;
if (!azslCompiler.ParseSrgPopulateSrgData(jsonOutcome.GetValue(), srgData))
{
AZ_Error(ShaderVariantAssetBuilderName, false, "Failed to parse srg data");
return false;
}
// Add all Shader Resource Group Assets that were defined in the shader code to the shader asset
if (!SrgLayoutUtility::LoadShaderResourceGroupLayouts(ShaderVariantAssetBuilderName, srgData, platformUsesRegisterSpaces, srgLayoutList))
{
AZ_Error(ShaderVariantAssetBuilderName, false, "Failed to load ShaderResourceGroupLayouts");
return false;
}
for (auto srgLayout : srgLayoutList)
{
if (!srgLayout->Finalize())
{
AZ_Error(ShaderVariantAssetBuilderName, false,
"Failed to finalize SrgLayout %s", srgLayout->GetName().GetCStr());
return false;
}
}
// Access the root constants reflection
if (!azslCompiler.ParseSrgPopulateRootConstantData(
jsonOutcome.GetValue(),
rootConstantData)) // consuming data from --srg ("InlineConstantBuffer" subjson section)
{
AZ_Error(ShaderVariantAssetBuilderName, false, "Failed to obtain root constant data reflection");
return false;
}
return true;
}
static bool LoadBindingDependenciesFromShaderAssetBuilder(
const RHI::ShaderPlatformInterface* shaderPlatformInterface,
const AssetBuilderSDK::PlatformInfo& platformInfo,
const AzslCompiler& azslCompiler, const AZStd::string& shaderSourceFileFullPath,
const RPI::SupervariantIndex supervariantIndex,
BindingDependencies& bindingDependencies)
{
auto bindingsJsonPathOutcome = ShaderBuilderUtility::ObtainBuildArtifactPathFromShaderAssetBuilder(
shaderPlatformInterface->GetAPIUniqueIndex(), platformInfo.m_identifier, shaderSourceFileFullPath, supervariantIndex.GetIndex(), AZ::RPI::ShaderAssetSubId::BindingdepJson);
if (!bindingsJsonPathOutcome.IsSuccess())
{
AZ_Error(ShaderVariantAssetBuilderName, false, "%s", bindingsJsonPathOutcome.GetError().c_str());
return false;
}
auto bindingsJsonPath = bindingsJsonPathOutcome.TakeValue();
auto jsonOutcome = JsonSerializationUtils::ReadJsonFile(bindingsJsonPath);
if (!jsonOutcome.IsSuccess())
{
AZ_Error(ShaderVariantAssetBuilderName, false, "%s", jsonOutcome.GetError().c_str());
return false;
}
if (!azslCompiler.ParseBindingdepPopulateBindingDependencies(jsonOutcome.GetValue(), bindingDependencies))
{
AZ_Error(ShaderVariantAssetBuilderName, false, "Failed to parse binding dependencies data");
return false;
}
return true;
}
// Returns the content of the hlsl file for the given supervariant as produced by ShaderAsssetBuilder.
@@ -773,6 +864,50 @@ namespace AZ
response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Failed;
return;
}
//! It is important to keep this refcounted pointer outside of the if block to prevent it from being destroyed.
RHI::Ptr<RHI::PipelineLayoutDescriptor> pipelineLayoutDescriptor;
if (shaderPlatformInterface->VariantCompilationRequiresSrgLayoutData())
{
AZStd::string azslcCompilerParameters =
shaderPlatformInterface->GetAzslCompilerParameters(buildOptions.m_compilerArguments);
const bool platformUsesRegisterSpaces =
(AzFramework::StringFunc::Find(azslcCompilerParameters, "--use-spaces") != AZStd::string::npos);
RPI::ShaderResourceGroupLayoutList srgLayoutList;
RootConstantData rootConstantData;
if (!LoadSrgLayoutListFromShaderAssetBuilder(
shaderPlatformInterface, request.m_platformInfo, azslc, shaderSourceFileFullPath, supervariantIndex,
platformUsesRegisterSpaces,
srgLayoutList,
rootConstantData))
{
response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Failed;
return;
}
BindingDependencies bindingDependencies;
if (!LoadBindingDependenciesFromShaderAssetBuilder(
shaderPlatformInterface, request.m_platformInfo, azslc, shaderSourceFileFullPath, supervariantIndex,
bindingDependencies))
{
response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Failed;
return;
}
pipelineLayoutDescriptor =
ShaderBuilderUtility::BuildPipelineLayoutDescriptorForApi(
ShaderVariantAssetBuilderName, srgLayoutList, shaderEntryPoints, buildOptions.m_compilerArguments, rootConstantData,
shaderPlatformInterface, bindingDependencies);
if (!pipelineLayoutDescriptor)
{
AZ_Error(
ShaderVariantAssetBuilderName, false, "Failed to build pipeline layout descriptor for api=[%s]",
shaderPlatformInterface->GetAPIName().GetCStr());
response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Failed;
return;
}
}
// Setup the shader variant creation context:
ShaderVariantCreationContext shaderVariantCreationContext =
@@ -144,6 +144,12 @@ namespace AZ
const ShaderResourceGroupInfoList& srgInfoList,
const RootConstantsInfo& rootConstantsInfo,
const ShaderCompilerArguments& shaderCompilerArguments) = 0;
//! In general, shader compilation doesn't require SRG Layout data, but RHIs like
//! Metal don't do well if unused resources (descriptors) are not bound. If this function returns TRUE
//! the ShaderVariantAssetBuilder will invoke BuildPipelineLayoutDescriptor() so the RHI gets the chance to
//! build SRG Layout data which will be useful when compiling MetalISL to Metal byte code.
virtual bool VariantCompilationRequiresSrgLayoutData() const { return false; }
//! See AZ::RHI::Factory::GetAPIUniqueIndex() for details.
//! See AZ::RHI::Limits::APIType::PerPlatformApiUniqueIndexMax.
@@ -123,6 +123,11 @@ namespace AZ
/// Returns the index of the current image after the swap.
virtual uint32_t PresentInternal() = 0;
virtual void SetVerticalSyncIntervalInternal(uint32_t previousVerticalSyncInterval)
{
AZ_UNUSED(previousVerticalSyncInterval);
}
//////////////////////////////////////////////////////////////////////////
SwapChainDescriptor m_descriptor;
@@ -159,7 +159,13 @@ namespace AZ
arguments += " -Zi"; // Generate debug information
arguments += " -Zss"; // Compute Shader Hash considering source information
}
arguments += " " + m_dxcAdditionalFreeArguments;
// strip spaces at both sides
AZStd::string dxcAdditionalFreeArguments = m_dxcAdditionalFreeArguments;
AzFramework::StringFunc::TrimWhiteSpace(dxcAdditionalFreeArguments, true, true);
if (!dxcAdditionalFreeArguments.empty())
{
arguments += " " + dxcAdditionalFreeArguments;
}
return arguments;
}
}
@@ -168,7 +168,11 @@ namespace AZ
void SwapChain::SetVerticalSyncInterval(uint32_t verticalSyncInterval)
{
uint32_t previousVsyncInterval = m_descriptor.m_verticalSyncInterval;
m_descriptor.m_verticalSyncInterval = verticalSyncInterval;
SetVerticalSyncIntervalInternal(previousVsyncInterval);
}
const AttachmentId& SwapChain::GetAttachmentId() const
@@ -40,6 +40,8 @@ namespace AZ
const ShaderResourceGroupInfoList& srgInfoList,
const RootConstantsInfo& rootConstantsInfo,
const RHI::ShaderCompilerArguments& shaderCompilerArguments) override;
bool VariantCompilationRequiresSrgLayoutData() const override { return true; }
bool CompilePlatformInternal(
const AssetBuilderSDK::PlatformInfo& platform,
@@ -30,6 +30,7 @@ namespace AZ
{
AZ_UNUSED(device);
m_hardwareQueueClass = hardwareQueueClass;
m_supportsInterDrawTimestamps = AZ::RHI::QueryTypeFlags::Timestamp == (device->GetFeatures().m_queryTypesMask[static_cast<uint32_t>(hardwareQueueClass)] & AZ::RHI::QueryTypeFlags::Timestamp);
}
void CommandListBase::Reset()
@@ -64,7 +65,10 @@ namespace AZ
[m_encoder endEncoding];
m_encoder = nil;
#if AZ_TRAIT_ATOM_METAL_COUNTER_SAMPLING
m_timeStampQueue.clear();
if (m_supportsInterDrawTimestamps)
{
m_timeStampQueue.clear();
}
#endif
}
}
@@ -144,9 +148,12 @@ namespace AZ
m_isEncoded = true;
#if AZ_TRAIT_ATOM_METAL_COUNTER_SAMPLING
for(auto& timeStamp: m_timeStampQueue)
if (m_supportsInterDrawTimestamps)
{
SampleCounters(timeStamp.m_counterSampleBuffer, timeStamp.m_timeStampIndex);
for(auto& timeStamp: m_timeStampQueue)
{
SampleCounters(timeStamp.m_counterSampleBuffer, timeStamp.m_timeStampIndex);
}
}
#endif
}
@@ -195,6 +202,11 @@ namespace AZ
#if AZ_TRAIT_ATOM_METAL_COUNTER_SAMPLING
void CommandListBase::SampleCounters(id<MTLCounterSampleBuffer> counterSampleBuffer, uint32_t sampleIndex)
{
if (!m_supportsInterDrawTimestamps)
{
return;
}
AZ_Assert(sampleIndex >= 0, "Invalid sample index");
//useBarrier - Inserting a barrier ensures that encoded work is complete before the GPU samples the hardware counters.
//If it is true there is a performance penalty but you will get consistent results
@@ -231,6 +243,11 @@ namespace AZ
void CommandListBase::SamplePassCounters(id<MTLCounterSampleBuffer> counterSampleBuffer, uint32_t sampleIndex)
{
if (!m_supportsInterDrawTimestamps)
{
return;
}
if(m_encoder == nil)
{
//Queue the query to be activated upon encoder creation. Applies to timestamp queries
@@ -101,6 +101,8 @@ namespace AZ
const AZStd::set<id<MTLHeap>>* m_residentHeaps = nullptr;
bool m_supportsInterDrawTimestamps = AZ_TRAIT_ATOM_METAL_COUNTER_SAMPLING; // iOS/TVOS = false, MacOS = defaults to true
#if AZ_TRAIT_ATOM_METAL_COUNTER_SAMPLING
struct TimeStampData
{
+19 -5
View File
@@ -328,14 +328,28 @@ namespace AZ
m_features.m_indirectDrawSupport = false;
RHI::QueryTypeFlags counterSamplingFlags = RHI::QueryTypeFlags::None;
#if AZ_TRAIT_ATOM_METAL_COUNTER_SAMPLING
counterSamplingFlags |= (RHI::QueryTypeFlags::Timestamp | RHI::QueryTypeFlags::PipelineStatistics);
m_features.m_queryTypesMask[static_cast<uint32_t>(RHI::HardwareQueueClass::Copy)] = RHI::QueryTypeFlags::Timestamp;
bool supportsInterDrawTimestamps = true;
#if defined(__IPHONE_14_0) || defined(__MAC_11_0) || defined(__TVOS_14_0)
if (@available(macOS 11.0, iOS 14, tvOS 14, *))
{
supportsInterDrawTimestamps = [m_metalDevice supportsCounterSampling:MTLCounterSamplingPointAtDrawBoundary];
}
else
#endif
{
supportsInterDrawTimestamps = ![m_metalDevice.name containsString:@"Apple"]; // Apple GPU's don't support inter draw timestamps at the M1/A14 generation
}
if (supportsInterDrawTimestamps)
{
counterSamplingFlags |= (RHI::QueryTypeFlags::Timestamp | RHI::QueryTypeFlags::PipelineStatistics);
m_features.m_queryTypesMask[static_cast<uint32_t>(RHI::HardwareQueueClass::Copy)] = RHI::QueryTypeFlags::Timestamp;
}
m_features.m_queryTypesMask[static_cast<uint32_t>(RHI::HardwareQueueClass::Graphics)] = RHI::QueryTypeFlags::Occlusion | counterSamplingFlags;
//Compute queue can do gfx work
m_features.m_queryTypesMask[static_cast<uint32_t>(RHI::HardwareQueueClass::Compute)] = RHI::QueryTypeFlags::Occlusion |counterSamplingFlags;
m_features.m_queryTypesMask[static_cast<uint32_t>(RHI::HardwareQueueClass::Compute)] = RHI::QueryTypeFlags::Occlusion | counterSamplingFlags;
m_features.m_occlusionQueryPrecise = true;
//Values taken from https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf
@@ -218,7 +218,8 @@ namespace AZ
createInfo.extent = extent;
createInfo.mipLevels = AZStd::min<uint32_t>(descriptor.m_mipLevels, formatProps.maxMipLevels);
createInfo.arrayLayers = AZStd::min<uint32_t>(descriptor.m_arraySize, formatProps.maxArrayLayers);
createInfo.samples = static_cast<VkSampleCountFlagBits>(RHI::FilterBits(static_cast<VkSampleCountFlags>(ConvertSampleCount(descriptor.m_multisampleState.m_samples)), formatProps.sampleCounts));
VkSampleCountFlagBits sampleCountFlagBits = static_cast<VkSampleCountFlagBits>(RHI::FilterBits(static_cast<VkSampleCountFlags>(ConvertSampleCount(descriptor.m_multisampleState.m_samples)), formatProps.sampleCounts));
createInfo.samples = (static_cast<uint32_t>(sampleCountFlagBits) > 0) ? sampleCountFlagBits : VK_SAMPLE_COUNT_1_BIT;
createInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
createInfo.usage = GetImageUsageFlags();
createInfo.sharingMode = exclusiveOwnership ? VK_SHARING_MODE_EXCLUSIVE : VK_SHARING_MODE_CONCURRENT;
@@ -56,6 +56,18 @@ namespace AZ
m_swapChainBarrier.m_isValid = true;
}
void SwapChain::SetVerticalSyncIntervalInternal(uint32_t previousVsyncInterval)
{
uint32_t verticalSyncInterval = GetDescriptor().m_verticalSyncInterval;
if (verticalSyncInterval == 0 || previousVsyncInterval == 0)
{
// The presentation mode may change when transitioning to or from a vsynced presentation mode
// In this case, the swapchain must be recreated.
InvalidateNativeSwapChain();
BuildNativeSwapChain(GetDescriptor().m_dimensions, verticalSyncInterval);
}
}
void SwapChain::SetNameInternal(const AZStd::string_view& name)
{
if (IsInitialized() && !name.empty())
@@ -84,7 +96,7 @@ namespace AZ
auto& presentationQueue = device.GetCommandQueueContext().GetOrCreatePresentationCommandQueue(*this);
m_presentationQueue = &presentationQueue;
result = BuildNativeSwapChain(swapchainDimensions);
result = BuildNativeSwapChain(swapchainDimensions, descriptor.m_verticalSyncInterval);
RETURN_RESULT_IF_UNSUCCESSFUL(result);
uint32_t imageCount = 0;
VkResult vkResult = vkGetSwapchainImagesKHR(device.GetNativeDevice(), m_nativeSwapChain, &imageCount, nullptr);
@@ -166,7 +178,7 @@ namespace AZ
auto& presentationQueue = device.GetCommandQueueContext().GetOrCreatePresentationCommandQueue(*this);
m_presentationQueue = &presentationQueue;
BuildNativeSwapChain(resizeDimensions);
BuildNativeSwapChain(resizeDimensions, GetDescriptor().m_verticalSyncInterval);
resizeDimensions.m_imageCount = 0;
VkResult vkResult = vkGetSwapchainImagesKHR(device.GetNativeDevice(), m_nativeSwapChain, &resizeDimensions.m_imageCount, nullptr);
@@ -256,7 +268,8 @@ namespace AZ
info.pImageIndices = &imageIndex;
info.pResults = nullptr;
const VkResult result = vkQueuePresentKHR(vulkanQueue->GetNativeQueue(), &info);
VkResult result = vkQueuePresentKHR(vulkanQueue->GetNativeQueue(), &info);
// Resizing window cause recreation of SwapChain after calling this method,
// so VK_SUBOPTIMAL_KHR or VK_ERROR_OUT_OF_DATE_KHR should not happen at this point.
AZ_Assert(result == VK_SUCCESS || result == VK_SUBOPTIMAL_KHR, "Failed to present swapchain %s", GetName().GetCStr());
@@ -321,9 +334,17 @@ namespace AZ
return surfaceFormats[0];
}
VkPresentModeKHR SwapChain::GetSupportedPresentMode() const
VkPresentModeKHR SwapChain::GetSupportedPresentMode(uint32_t verticalSyncInterval) const
{
AZ_Assert(m_surface, "Surface has not been initialized.");
if (verticalSyncInterval > 0)
{
// When a non-zero vsync interval is requested, the FIFO presentation mode (always available)
// is usable without needing to query available presentation modes.
return VK_PRESENT_MODE_FIFO_KHR;
}
auto& device = static_cast<Device&>(GetDevice());
const auto& physicalDevice = static_cast<const PhysicalDevice&>(device.GetPhysicalDevice());
@@ -335,12 +356,12 @@ namespace AZ
AZStd::vector<VkPresentModeKHR> supportedModes(modeCount);
AssertSuccess(vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice.GetNativePhysicalDevice(), m_surface->GetNativeSurface(), &modeCount, supportedModes.data()));
VkPresentModeKHR preferedModes[] = {VK_PRESENT_MODE_IMMEDIATE_KHR, VK_PRESENT_MODE_MAILBOX_KHR};
for (VkPresentModeKHR preferedMode : preferedModes)
VkPresentModeKHR preferredModes[] = {VK_PRESENT_MODE_IMMEDIATE_KHR, VK_PRESENT_MODE_MAILBOX_KHR};
for (VkPresentModeKHR preferredMode : preferredModes)
{
for (VkPresentModeKHR supportedMode : supportedModes)
{
if (supportedMode == preferedMode)
if (supportedMode == preferredMode)
{
return supportedMode;
}
@@ -370,7 +391,7 @@ namespace AZ
return VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
}
RHI::ResultCode SwapChain::BuildNativeSwapChain(const RHI::SwapChainDimensions& dimensions)
RHI::ResultCode SwapChain::BuildNativeSwapChain(const RHI::SwapChainDimensions& dimensions, uint32_t verticalSyncInterval)
{
AZ_Assert(m_nativeSwapChain == VK_NULL_HANDLE, "Vulkan's native SwapChain has been initialized already.");
auto& device = static_cast<Device&>(GetDevice());
@@ -421,7 +442,7 @@ namespace AZ
createInfo.pQueueFamilyIndices = familyIndices.empty() ? nullptr : familyIndices.data();
createInfo.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
createInfo.compositeAlpha = GetSupportedCompositeAlpha();
createInfo.presentMode = GetSupportedPresentMode();
createInfo.presentMode = GetSupportedPresentMode(verticalSyncInterval);
createInfo.clipped = VK_FALSE;
createInfo.oldSwapchain = VK_NULL_HANDLE;
@@ -442,6 +463,7 @@ namespace AZ
imageAvailableSemaphore->GetNativeSemaphore(),
VK_NULL_HANDLE,
acquiredImageIndex);
// Resizing window cause recreation of SwapChain before calling this method,
// so VK_SUBOPTIMAL_KHR or VK_ERROR_OUT_OF_DATE_KHR should not happen.
AssertSuccess(vkResult);
@@ -49,7 +49,7 @@ namespace AZ
const CommandQueue& GetPresentationQueue() const;
void QueueBarrier(const VkPipelineStageFlags src, const VkPipelineStageFlags dst, const VkImageMemoryBarrier& imageBarrier);
private:
SwapChain() = default;
@@ -65,14 +65,15 @@ namespace AZ
RHI::ResultCode InitImageInternal(const RHI::SwapChain::InitImageRequest& request) override;
RHI::ResultCode ResizeInternal(const RHI::SwapChainDimensions& dimensions, RHI::SwapChainDimensions* nativeDimensions) override;
uint32_t PresentInternal() override;
void SetVerticalSyncIntervalInternal(uint32_t previousVsyncInterval) override;
//////////////////////////////////////////////////////////////////////
RHI::ResultCode BuildSurface(const RHI::SwapChainDescriptor& descriptor);
bool ValidateSurfaceDimensions(const RHI::SwapChainDimensions& dimensions);
VkSurfaceFormatKHR GetSupportedSurfaceFormat(const RHI::Format format) const;
VkPresentModeKHR GetSupportedPresentMode() const;
VkPresentModeKHR GetSupportedPresentMode(uint32_t verticalSyncInterval) const;
VkCompositeAlphaFlagBitsKHR GetSupportedCompositeAlpha() const;
RHI::ResultCode BuildNativeSwapChain(const RHI::SwapChainDimensions& dimensions);
RHI::ResultCode BuildNativeSwapChain(const RHI::SwapChainDimensions& dimensions, uint32_t verticalSyncInterval);
RHI::ResultCode AcquireNewImage(uint32_t* acquiredImageIndex);
void InvalidateSurface();
@@ -71,6 +71,7 @@ namespace AZ
// WindowNotificationBus::Handler overrides ...
void OnWindowResized(uint32_t width, uint32_t height) override;
void OnWindowClosed() override;
void OnVsyncIntervalChanged(uint32_t interval) override;
// ExclusiveFullScreenRequestBus::Handler overrides ...
bool IsExclusiveFullScreenPreferred() const override;
@@ -116,7 +116,7 @@ namespace AZ
{
AZ_Assert(IsQueryTypeValid(queryType), "Provided QueryType is invalid");
return static_cast<uint32_t>(m_queryTypeSupport) & static_cast<uint32_t>(queryType);
return static_cast<uint32_t>(m_queryTypeSupport) & AZ_BIT(static_cast<uint32_t>(queryType));
}
RPI::QueryPool* GpuQuerySystem::GetQueryPoolByType(RHI::QueryType queryType)

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