Merge branch 'development' of https://github.com/o3de/o3de into jckand/PrefabTestOptimization

Signed-off-by: jckand-amzn <82226555+jckand-amzn@users.noreply.github.com>
monroegm-disable-blank-issue-2
jckand-amzn 4 years ago
commit 02fbf31311

@ -8,6 +8,7 @@
import azlmbr.bus
import azlmbr.math
from scene_api.scene_data import PrimitiveShape, DecompositionMode
from scene_helpers import *
@ -41,6 +42,35 @@ def add_material_component(entity_id):
raise RuntimeError("UpdateComponentForEntity for editor_material_component failed")
def add_physx_meshes(scene_manifest: sceneData.SceneManifest, source_file_name: str, mesh_name_list: List, all_node_paths: List[str]):
first_mesh = mesh_name_list[0].get_path()
# Add a Box Primitive PhysX mesh with a comment
physx_box = scene_manifest.add_physx_primitive_mesh_group(source_file_name + "_box", PrimitiveShape.BOX, 0.0, None)
scene_manifest.physx_mesh_group_add_comment(physx_box, "This is a box primitive")
# Select the first mesh, unselect every other node
scene_manifest.physx_mesh_group_add_selected_node(physx_box, first_mesh)
for node in all_node_paths:
if node != first_mesh:
scene_manifest.physx_mesh_group_add_unselected_node(physx_box, node)
# Add a Convex Mesh PhysX mesh with a comment
convex_mesh = scene_manifest.add_physx_convex_mesh_group(source_file_name + "_convex", 0.08, .0004,
True, True, True, True, True, 24, True, "Glass")
scene_manifest.physx_mesh_group_add_comment(convex_mesh, "This is a convex mesh")
# Select/Unselect nodes using lists
all_except_first_mesh = [x for x in all_node_paths if x != first_mesh]
scene_manifest.physx_mesh_group_add_selected_unselected_nodes(convex_mesh, [first_mesh], all_except_first_mesh)
# Configure mesh decomposition for this mesh
scene_manifest.physx_mesh_group_decompose_meshes(convex_mesh, 512, 32, .002, 100100, DecompositionMode.TETRAHEDRON,
0.06, 0.055, 0.00015, 3, 3, True, False)
# Add a Triangle mesh
triangle = scene_manifest.add_physx_triangle_mesh_group(source_file_name + "_triangle", False, True, True, True, True, True)
scene_manifest.physx_mesh_group_add_selected_unselected_nodes(triangle, [first_mesh], all_except_first_mesh)
def update_manifest(scene):
import uuid, os
import azlmbr.scene.graph
@ -62,6 +92,8 @@ def update_manifest(scene):
previous_entity_id = azlmbr.entity.InvalidEntityId
first_mesh = True
add_physx_meshes(scene_manifest, source_filename_only, mesh_name_list, all_node_paths)
# Loop every mesh node in the scene
for activeMeshIndex in range(len(mesh_name_list)):
mesh_name = mesh_name_list[activeMeshIndex]
@ -106,6 +138,26 @@ def update_manifest(scene):
if not result:
raise RuntimeError("UpdateComponentForEntity failed for Mesh component")
# Add a physics component referencing the triangle mesh we made for the first node
if previous_entity_id is None:
physx_mesh_component = azlmbr.entity.EntityUtilityBus(azlmbr.bus.Broadcast, "GetOrAddComponentByTypeName",
entity_id, "{FD429282-A075-4966-857F-D0BBF186CFE6} EditorColliderComponent")
json_update = json.dumps({
"ShapeConfiguration": {
"PhysicsAsset": {
"Asset": {
"assetHint": os.path.join(source_relative_path, source_filename_only + "_triangle.pxmesh")
}
}
}
})
result = azlmbr.entity.EntityUtilityBus(azlmbr.bus.Broadcast, "UpdateComponentForEntity", entity_id, physx_mesh_component, json_update)
if not result:
raise RuntimeError("UpdateComponentForEntity failed for PhysX mesh component")
# an example of adding a material component to override the default material
if previous_entity_id is not None and first_mesh:
first_mesh = False

@ -12,6 +12,7 @@ import pytest
import ly_test_tools.environment.file_system as file_system
import editor_python_test_tools.hydra_test_utils as hydra
from ly_test_tools.o3de.editor_test import EditorSharedTest, EditorTestSuite
from Atom.atom_utils.atom_constants import LIGHT_TYPES
logger = logging.getLogger(__name__)
@ -159,3 +160,17 @@ class TestMaterialEditorBasicTests(object):
enable_prefab_system=False,
)
@pytest.mark.parametrize("project", ["AutomatedTesting"])
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
class TestAutomation(EditorTestSuite):
enable_prefab_system = False
@pytest.mark.test_case_id("C36529666")
class AtomEditorComponentsLevel_DiffuseGlobalIlluminationAdded(EditorSharedTest):
from Atom.tests import hydra_AtomEditorComponentsLevel_DiffuseGlobalIlluminationAdded as test_module
@pytest.mark.test_case_id("C36525660")
class AtomEditorComponentsLevel_DisplayMapperAdded(EditorSharedTest):
from Atom.tests import hydra_AtomEditorComponentsLevel_DisplayMapperAdded as test_module

@ -18,6 +18,13 @@ LIGHT_TYPES = {
'simple_spot': 7,
}
# Qualiity Level settings for Diffuse Global Illumination level component
GLOBAL_ILLUMINATION_QUALITY = {
'Low': 0,
'Medium': 1,
'High': 2,
}
class AtomComponentProperties:
"""
@ -116,6 +123,21 @@ class AtomComponentProperties:
}
return properties[property]
@staticmethod
def diffuse_global_illumination(property: str = 'name') -> str:
"""
Diffuse Global Illumination level component properties.
Controls global settings for Diffuse Probe Grid components.
- 'Quality Level' from atom_constants.py GLOBAL_ILLUMINATION_QUALITY
:param property: From the last element of the property tree path. Default 'name' for component name string.
:return: Full property path OR component name if no property specified.
"""
properties = {
'name': 'Diffuse Global Illumination',
'Quality Level': 'Controller|Configuration|Quality Level'
}
return properties[property]
@staticmethod
def diffuse_probe_grid(property: str = 'name') -> str:
"""
@ -148,7 +170,8 @@ class AtomComponentProperties:
@staticmethod
def display_mapper(property: str = 'name') -> str:
"""
Display Mapper component properties.
Display Mapper level component properties.
- 'Enable LDR color grading LUT' toggles the use of LDR color grading LUT
- 'LDR color Grading LUT' is the Low Definition Range (LDR) color grading for Look-up Textures (LUT) which is
an Asset.id value corresponding to a lighting asset file.
:param property: From the last element of the property tree path. Default 'name' for component name string.
@ -156,6 +179,7 @@ class AtomComponentProperties:
"""
properties = {
'name': 'Display Mapper',
'Enable LDR color grading LUT': 'Controller|Configuration|Enable LDR color grading LUT',
'LDR color Grading LUT': 'Controller|Configuration|LDR color Grading LUT',
}
return properties[property]

@ -0,0 +1,109 @@
"""
Copyright (c) Contributors to the Open 3D Engine Project.
For complete copyright and license terms please see the LICENSE at the root of this distribution.
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
class Tests:
creation_undo = (
"UNDO Level component addition success",
"UNDO Level component addition failed")
creation_redo = (
"REDO Level component addition success",
"REDO Level component addition failed")
diffuse_global_illumination_component = (
"Level has a Diffuse Global Illumination component",
"Level failed to find Diffuse Global Illumination component")
diffuse_global_illumination_quality = (
"Quality Level set",
"Quality Level could not be set")
enter_game_mode = (
"Entered game mode",
"Failed to enter game mode")
exit_game_mode = (
"Exited game mode",
"Couldn't exit game mode")
def AtomEditorComponentsLevel_DiffuseGlobalIllumination_AddedToEntity():
"""
Summary:
Tests the Diffuse Global Illumination level component can be added to the level entity and is stable.
Test setup:
- Wait for Editor idle loop.
- Open the "Base" level.
Expected Behavior:
The component can be added, used in game mode, and has accurate required components.
Creation and deletion undo/redo should also work.
Test Steps:
1) Add Diffuse Global Illumination level component to the level entity.
2) UNDO the level component addition.
3) REDO the level component addition.
4) Set Quality Level property to Low
5) Enter/Exit game mode.
6) Look for errors and asserts.
:return: None
"""
import azlmbr.legacy.general as general
from editor_python_test_tools.editor_entity_utils import EditorLevelEntity
from editor_python_test_tools.utils import Report, Tracer, TestHelper
from Atom.atom_utils.atom_constants import AtomComponentProperties, GLOBAL_ILLUMINATION_QUALITY
with Tracer() as error_tracer:
# Test setup begins.
# Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
TestHelper.init_idle()
TestHelper.open_level("", "Base")
# Test steps begin.
# 1. Add Diffuse Global Illumination level component to the level entity.
diffuse_global_illumination_component = EditorLevelEntity.add_component(
AtomComponentProperties.diffuse_global_illumination())
Report.critical_result(
Tests.diffuse_global_illumination_component,
EditorLevelEntity.has_component(AtomComponentProperties.diffuse_global_illumination()))
# 2. UNDO the level component addition.
# -> UNDO component addition.
general.undo()
general.idle_wait_frames(1)
Report.result(Tests.creation_undo,
not EditorLevelEntity.has_component(AtomComponentProperties.diffuse_global_illumination()))
# 3. REDO the level component addition.
# -> REDO component addition.
general.redo()
general.idle_wait_frames(1)
Report.result(Tests.creation_redo,
EditorLevelEntity.has_component(AtomComponentProperties.diffuse_global_illumination()))
# 4. Set Quality Level property to Low
diffuse_global_illumination_component.set_component_property_value(
AtomComponentProperties.diffuse_global_illumination('Quality Level', GLOBAL_ILLUMINATION_QUALITY['Low']))
quality = diffuse_global_illumination_component.get_component_property_value(
AtomComponentProperties.diffuse_global_illumination('Quality Level'))
Report.result(diffuse_global_illumination_quality, quality == GLOBAL_ILLUMINATION_QUALITY['Low'])
# 5. Enter/Exit game mode.
TestHelper.enter_game_mode(Tests.enter_game_mode)
general.idle_wait_frames(1)
TestHelper.exit_game_mode(Tests.exit_game_mode)
# 6. Look for errors and asserts.
TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0)
for error_info in error_tracer.errors:
Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}")
for assert_info in error_tracer.asserts:
Report.info(f"Assert: {assert_info.filename} {assert_info.function} | {assert_info.message}")
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(AtomEditorComponentsLevel_DiffuseGlobalIllumination_AddedToEntity)

@ -0,0 +1,124 @@
"""
Copyright (c) Contributors to the Open 3D Engine Project.
For complete copyright and license terms please see the LICENSE at the root of this distribution.
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
class Tests:
creation_undo = (
"UNDO level component addition success",
"UNDO level component addition failed")
creation_redo = (
"REDO Level component addition success",
"REDO Level component addition failed")
display_mapper_component = (
"Level has a Display Mapper component",
"Level failed to find Display Mapper component")
ldr_color_grading_lut = (
"LDR color Grading LUT asset set",
"LDR color Grading LUT asset could not be set")
enable_ldr_color_grading_lut = (
"Enable LDR color grading LUT set",
"Enable LDR color grading LUT could not be set")
enter_game_mode = (
"Entered game mode",
"Failed to enter game mode")
exit_game_mode = (
"Exited game mode",
"Couldn't exit game mode")
def AtomEditorComponentsLevel_DisplayMapper_AddedToEntity():
"""
Summary:
Tests the Display Mapper level component can be added to the level entity and has the expected functionality.
Test setup:
- Wait for Editor idle loop.
- Open the "Base" level.
Expected Behavior:
The component can be added, used in game mode, and has accurate required components.
Creation and deletion undo/redo should also work.
Test Steps:
1) Add Display Mapper level component to the level entity.
2) UNDO the level component addition.
3) REDO the level component addition.
4) Set LDR color Grading LUT asset.
5) Set Enable LDR color grading LUT property True
6) Enter/Exit game mode.
7) Look for errors and asserts.
:return: None
"""
import os
import azlmbr.legacy.general as general
from editor_python_test_tools.asset_utils import Asset
from editor_python_test_tools.editor_entity_utils import EditorLevelEntity
from editor_python_test_tools.utils import Report, Tracer, TestHelper
from Atom.atom_utils.atom_constants import AtomComponentProperties
with Tracer() as error_tracer:
# Test setup begins.
# Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
TestHelper.init_idle()
TestHelper.open_level("", "Base")
# Test steps begin.
# 1. Add Display Mapper level component to the level entity.
display_mapper_component = EditorLevelEntity.add_component(AtomComponentProperties.display_mapper())
Report.critical_result(
Tests.display_mapper_component,
EditorLevelEntity.has_component(AtomComponentProperties.display_mapper()))
# 2. UNDO the level component addition.
# -> UNDO component addition.
general.undo()
general.idle_wait_frames(1)
Report.result(Tests.creation_undo, not EditorLevelEntity.has_component(AtomComponentProperties.display_mapper()))
# 3. REDO the level component addition.
# -> REDO component addition.
general.redo()
general.idle_wait_frames(1)
Report.result(Tests.creation_redo, EditorLevelEntity.has_component(AtomComponentProperties.display_mapper()))
# 4. Set LDR color Grading LUT asset.
display_mapper_asset_path = os.path.join("TestData", "test.lightingpreset.azasset")
display_mapper_asset = Asset.find_asset_by_path(display_mapper_asset_path, False)
display_mapper_component.set_component_property_value(
AtomComponentProperties.display_mapper('LDR color Grading LUT'), display_mapper_asset.id)
Report.result(
Tests.ldr_color_grading_lut,
display_mapper_component.get_component_property_value(
AtomComponentProperties.display_mapper('LDR color Grading LUT')) == display_mapper_asset.id)
# 5. Set Enable LDR color grading LUT property True
display_mapper_component.set_component_property_value(
AtomComponentProperties.display_mapper('Enable LDR color grading LUT'), True)
Report.result(
Test.enable_ldr_color_grading_lut,
display_mapper_component.get_component_property_value(
AtomComponentProperties.display_mapper('Enable LDR color grading LUT')) is True)
# 6. Enter/Exit game mode.
TestHelper.enter_game_mode(Tests.enter_game_mode)
general.idle_wait_frames(1)
TestHelper.exit_game_mode(Tests.exit_game_mode)
# 7. Look for errors and asserts.
TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0)
for error_info in error_tracer.errors:
Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}")
for assert_info in error_tracer.asserts:
Report.info(f"Assert: {assert_info.filename} {assert_info.function} | {assert_info.message}")
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(AtomEditorComponentsLevel_DisplayMapper_AddedToEntity)

@ -7,15 +7,6 @@ SPDX-License-Identifier: Apache-2.0 OR MIT
class Tests:
camera_creation = (
"Camera Entity successfully created",
"Camera Entity failed to be created")
camera_component_added = (
"Camera component was added to entity",
"Camera component failed to be added to entity")
camera_component_check = (
"Entity has a Camera component",
"Entity failed to find Camera component")
creation_undo = (
"UNDO Entity creation success",
"UNDO Entity creation failed")
@ -43,6 +34,9 @@ class Tests:
ldr_color_grading_lut = (
"LDR color Grading LUT asset set",
"LDR color Grading LUT asset could not be set")
enable_ldr_color_grading_lut = (
"Enable LDR color grading LUT set",
"Enable LDR color grading LUT could not be set")
entity_deleted = (
"Entity deleted",
"Entity was not deleted")
@ -72,14 +66,15 @@ def AtomEditorComponents_DisplayMapper_AddedToEntity():
2) Add Display Mapper component to Display Mapper entity.
3) UNDO the entity creation and component addition.
4) REDO the entity creation and component addition.
5) Enter/Exit game mode.
6) Test IsHidden.
7) Test IsVisible.
8) Set LDR color Grading LUT asset.
9) Delete Display Mapper entity.
10) UNDO deletion.
11) REDO deletion.
12) Look for errors and asserts.
5) Set LDR color Grading LUT asset.
6) Set Enable LDR color grading LUT property True
7) Enter/Exit game mode.
8) Test IsHidden.
9) Test IsVisible.
10) Delete Display Mapper entity.
11) UNDO deletion.
12) REDO deletion.
13) Look for errors and asserts.
:return: None
"""
@ -133,43 +128,51 @@ def AtomEditorComponents_DisplayMapper_AddedToEntity():
general.idle_wait_frames(1)
Report.result(Tests.creation_redo, display_mapper_entity.exists())
# 5. Enter/Exit game mode.
# 5. Set LDR color Grading LUT asset.
display_mapper_asset_path = os.path.join("TestData", "test.lightingpreset.azasset")
display_mapper_asset = Asset.find_asset_by_path(display_mapper_asset_path, False)
display_mapper_component.set_component_property_value(
AtomComponentProperties.display_mapper("LDR color Grading LUT"), display_mapper_asset.id)
Report.result(
Tests.ldr_color_grading_lut,
display_mapper_component.get_component_property_value(
AtomComponentProperties.display_mapper("LDR color Grading LUT")) == display_mapper_asset.id)
# 6. Set Enable LDR color grading LUT property True
display_mapper_component.set_component_property_value(
AtomComponentProperties.display_mapper('Enable LDR color grading LUT'), True)
Report.result(
Tests.enable_ldr_color_grading_lut,
display_mapper_component.get_component_property_value(
AtomComponentProperties.display_mapper('Enable LDR color grading LUT')) is True)
# 7. Enter/Exit game mode.
TestHelper.enter_game_mode(Tests.enter_game_mode)
general.idle_wait_frames(1)
TestHelper.exit_game_mode(Tests.exit_game_mode)
# 6. Test IsHidden.
# 8. Test IsHidden.
display_mapper_entity.set_visibility_state(False)
Report.result(Tests.is_hidden, display_mapper_entity.is_hidden() is True)
# 7. Test IsVisible.
# 9. Test IsVisible.
display_mapper_entity.set_visibility_state(True)
general.idle_wait_frames(1)
Report.result(Tests.is_visible, display_mapper_entity.is_visible() is True)
# 8. Set LDR color Grading LUT asset.
display_mapper_asset_path = os.path.join("TestData", "test.lightingpreset.azasset")
display_mapper_asset = Asset.find_asset_by_path(display_mapper_asset_path, False)
display_mapper_component.set_component_property_value(
AtomComponentProperties.display_mapper("LDR color Grading LUT"), display_mapper_asset.id)
Report.result(
Tests.ldr_color_grading_lut,
display_mapper_component.get_component_property_value(
AtomComponentProperties.display_mapper("LDR color Grading LUT")) == display_mapper_asset.id)
# 9. Delete Display Mapper entity.
# 10. Delete Display Mapper entity.
display_mapper_entity.delete()
Report.result(Tests.entity_deleted, not display_mapper_entity.exists())
# 10. UNDO deletion.
# 11. UNDO deletion.
general.undo()
Report.result(Tests.deletion_undo, display_mapper_entity.exists())
# 11. REDO deletion.
# 12. REDO deletion.
general.redo()
Report.result(Tests.deletion_redo, not display_mapper_entity.exists())
# 12. Look for errors and asserts.
# 13. Look for errors and asserts.
TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0)
for error_info in error_tracer.errors:
Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}")

@ -107,7 +107,6 @@ class EditorComponent:
return type_ids
def convert_to_azvector3(xyz) -> azlmbr.math.Vector3:
"""
Converts a vector3-like element into a azlmbr.math.Vector3
@ -120,6 +119,7 @@ def convert_to_azvector3(xyz) -> azlmbr.math.Vector3:
else:
raise ValueError("vector must be a 3 element list/tuple or azlmbr.math.Vector3")
class EditorEntity:
"""
Entity class is used to create and interact with Editor Entities.
@ -470,3 +470,99 @@ class EditorEntity:
assert self.id.isValid(), "A valid entity id is required to focus on its owning prefab."
focus_prefab_result = azlmbr.prefab.PrefabFocusPublicRequestBus(bus.Broadcast, "FocusOnOwningPrefab", self.id)
assert focus_prefab_result.IsSuccess(), f"Prefab operation 'FocusOnOwningPrefab' failed. Error: {focus_prefab_result.GetError()}"
class EditorLevelEntity:
"""
EditorLevel class used to add and fetch level components.
Level entity is a special entity that you do not create/destroy independently of larger systems of level creation.
This collects a number of staticmethods that do not rely on entityId since Level entity is found internally by
EditorLevelComponentAPIBus requests.
"""
@staticmethod
def get_type_ids(component_names: list) -> list:
"""
Used to get type ids of given components list for EntityType Level
:param: component_names: List of components to get type ids
:return: List of type ids of given components.
"""
type_ids = editor.EditorComponentAPIBus(
bus.Broadcast, "FindComponentTypeIdsByEntityType", component_names, azlmbr.entity.EntityType().Level
)
return type_ids
@staticmethod
def add_component(component_name: str) -> EditorComponent:
"""
Used to add new component to Level.
:param component_name: String of component name to add.
:return: Component object of newly added component.
"""
component = EditorLevelEntity.add_components([component_name])[0]
return component
@staticmethod
def add_components(component_names: list) -> List[EditorComponent]:
"""
Used to add multiple components
:param: component_names: List of components to add to level
:return: List of newly added components to the level
"""
components = []
type_ids = EditorLevelEntity.get_type_ids(component_names)
for type_id in type_ids:
new_comp = EditorComponent()
new_comp.type_id = type_id
add_component_outcome = editor.EditorLevelComponentAPIBus(
bus.Broadcast, "AddComponentsOfType", [type_id]
)
assert (
add_component_outcome.IsSuccess()
), f"Failure: Could not add component: '{new_comp.get_component_name()}' to level"
new_comp.id = add_component_outcome.GetValue()[0]
components.append(new_comp)
return components
@staticmethod
def get_components_of_type(component_names: list) -> List[EditorComponent]:
"""
Used to get components of type component_name that already exists on the level
:param component_names: List of names of components to check
:return: List of Level Component objects of given component name
"""
component_list = []
type_ids = EditorLevelEntity.get_type_ids(component_names)
for type_id in type_ids:
component = EditorComponent()
component.type_id = type_id
get_component_of_type_outcome = editor.EditorLevelComponentAPIBus(
bus.Broadcast, "GetComponentOfType", type_id
)
assert (
get_component_of_type_outcome.IsSuccess()
), f"Failure: Level does not have component:'{component.get_component_name()}'"
component.id = get_component_of_type_outcome.GetValue()
component_list.append(component)
return component_list
@staticmethod
def has_component(component_name: str) -> bool:
"""
Used to verify if the level has the specified component
:param component_name: Name of component to check for
:return: True, if level has specified component. Else, False
"""
type_ids = EditorLevelEntity.get_type_ids([component_name])
return editor.EditorLevelComponentAPIBus(bus.Broadcast, "HasComponentOfType", type_ids[0])
@staticmethod
def count_components_of_type(component_name: str) -> int:
"""
Used to get a count of the specified level component attached to the level
:param component_name: Name of component to check for
:return: integer count of occurences of level component attached to level or zero if none are present
"""
type_ids = EditorLevelEntity.get_type_ids([component_name])
return editor.EditorLevelComponentAPIBus(bus.Broadcast, "CountComponentsOfType", type_ids[0])

@ -98,38 +98,32 @@ class FileManagement:
"""
file_map = FileManagement._load_file_map()
backup_path = FileManagement.backup_folder_path
backup_file_name = "{}.bak".format(file_name)
backup_file = os.path.join(backup_path, backup_file_name)
# If backup directory DNE, make one
if not os.path.exists(backup_path):
os.mkdir(backup_path)
# If "traditional" backup file exists, delete it (myFile.txt.bak)
if os.path.exists(backup_file):
fs.delete([backup_file], True, False)
# Find my next storage name (myFile_1.txt.bak)
backup_storage_file_name = FileManagement._next_available_name(backup_file_name, file_map)
if backup_storage_file_name is None:
# Find my next storage name (myFile_1.txt)
backup_file_name = FileManagement._next_available_name(file_name, file_map)
if backup_file_name is None:
# If _next_available_name returns None, we have backed up MAX_BACKUPS of files name [file_name]
raise Exception(
"FileManagement class ran out of backups per name. Max: {}".format(FileManagement.MAX_BACKUPS)
)
backup_storage_file = os.path.join(backup_path, backup_storage_file_name)
# If this backup file already exists, delete it.
backup_storage_file = "{}.bak".format(os.path.normpath(os.path.join(backup_path, backup_file_name)))
if os.path.exists(backup_storage_file):
# This file should not exists, but if it does it's about to get clobbered!
fs.unlock_file(backup_storage_file)
# Create "traditional" backup file (myFile.txt.bak)
fs.create_backup(os.path.join(file_path, file_name), backup_path)
# Copy "traditional" backup file into storage backup (myFile_1.txt.bak)
FileManagement._copy_file(backup_file_name, backup_path, backup_storage_file_name, backup_path)
fs.lock_file(backup_storage_file)
# Delete "traditional" back up file
fs.unlock_file(backup_file)
fs.delete([backup_file], True, False)
fs.delete([backup_storage_file], True, False)
# Create backup file (myFile_1.txt.bak)
original_file = os.path.normpath(os.path.join(file_path, file_name))
fs.create_backup(original_file, backup_path, backup_file_name)
# Update file map with new file
file_map[os.path.join(file_path, file_name)] = backup_storage_file_name
file_map[original_file] = backup_file_name
FileManagement._save_file_map(file_map)
# Unlock original file to get it ready to be edited by the test
fs.unlock_file(os.path.join(file_path, file_name))
fs.unlock_file(original_file)
@staticmethod
def _restore_file(file_name, file_path):
@ -143,20 +137,15 @@ class FileManagement:
"""
file_map = FileManagement._load_file_map()
backup_path = FileManagement.backup_folder_path
src_file = os.path.join(file_path, file_name)
src_file = os.path.normpath(os.path.join(file_path, file_name))
if src_file in file_map:
backup_file = os.path.join(backup_path, file_map[src_file])
if os.path.exists(backup_file):
fs.unlock_file(backup_file)
fs.unlock_file(src_file)
# Make temporary copy of backed up file to restore from
temp_file = "{}.bak".format(file_name)
FileManagement._copy_file(file_map[src_file], backup_path, temp_file, backup_path)
fs.restore_backup(src_file, backup_path)
fs.lock_file(src_file)
# Delete backup file
fs.delete([os.path.join(backup_path, temp_file)], True, False)
backup_file_name = file_map[src_file]
backup_file = "{}.bak".format(os.path.join(backup_path, backup_file_name))
fs.unlock_file(src_file)
if fs.restore_backup(src_file, backup_path, backup_file_name):
fs.delete([backup_file], True, False)
# Remove from file map
del file_map[src_file]
FileManagement._save_file_map(file_map)

@ -24,6 +24,7 @@ def CreatePrefab_WithSingleEntity():
# Creates a prefab from the new entity
Prefab.create_prefab(car_prefab_entities, CAR_PREFAB_FILE_NAME)
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(CreatePrefab_WithSingleEntity)

@ -0,0 +1,144 @@
"""
Copyright (c) Contributors to the Open 3D Engine Project.
For complete copyright and license terms please see the LICENSE at the root of this distribution.
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
class HeightTests:
single_gradient_height_correct = (
"Successfully retrieved height for gradient1.",
"Failed to retrieve height for gradient1."
)
double_gradient_height_correct = (
"Successfully retrieved height when two gradients exist.",
"Failed to retrieve height when two gradients exist."
)
triple_gradient_height_correct = (
"Successfully retrieved height when three gradients exist.",
"Failed to retrieve height when three gradients exist."
)
terrain_data_changed_call_count_correct = (
"OnTerrainDataChanged called expected number of times.",
"OnTerrainDataChanged call count incorrect."
)
def TerrainHeightGradientList_AddRemoveGradientWorks():
"""
Summary:
Test aspects of the TerrainHeightGradientList through the BehaviorContext and the Property Tree.
:return: None
"""
import os
import math as sys_math
import azlmbr.legacy.general as general
import azlmbr.bus as bus
import azlmbr.math as math
import azlmbr.terrain as terrain
import azlmbr.editor as editor
import azlmbr.vegetation as vegetation
import azlmbr.entity as EntityId
import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.utils import Report
from editor_python_test_tools.utils import TestHelper as helper
import editor_python_test_tools.pyside_utils as pyside_utils
from editor_python_test_tools.editor_entity_utils import EditorEntity
terrain_changed_call_count = 0
expected_terrain_changed_calls = 0
aabb_component_name = "Axis Aligned Box Shape"
gradientlist_component_name = "Terrain Height Gradient List"
layerspawner_component_name = "Terrain Layer Spawner"
gradient_value_path = "Configuration|Value"
def create_entity_at(entity_name, components_to_add, x, y, z):
entity = hydra.Entity(entity_name)
entity.create_entity(math.Vector3(x, y, z), components_to_add)
return entity
def on_terrain_changed(args):
nonlocal terrain_changed_call_count
terrain_changed_call_count += 1
def set_component_path_val(entity, component, path, value):
entity.get_set_test(component, path, value)
def set_gradients_check_height(main_entity, gradient_list, expected_height, test_results):
nonlocal expected_terrain_changed_calls
test_tolerance = 0.01
gradient_list_path = "Configuration|Gradient Entities"
set_component_path_val(main_entity, 1, gradient_list_path, gradient_list)
expected_terrain_changed_calls += 1
# Wait until the terrain data has been updated.
helper.wait_for_condition(lambda: terrain_changed_call_count == expected_terrain_changed_calls, 2.0)
# Get the height at the origin.
height = terrain.TerrainDataRequestBus(bus.Broadcast, "GetHeightFromFloats", 0.0, 0.0, 0)
Report.result(test_results, sys_math.isclose(height, expected_height, abs_tol=test_tolerance))
helper.init_idle()
# Open a level.
helper.open_level("Physics", "Base")
helper.wait_for_condition(lambda: general.get_current_level_name() == "Base", 2.0)
general.idle_wait_frames(1)
# Add a terrain world component
world_component = hydra.add_level_component("Terrain World")
aabb_height = 1024.0
box_dimensions = math.Vector3(1.0, 1.0, aabb_height);
# Create a main entity with a LayerSpawner, AAbb and HeightGradientList.
main_entity = create_entity_at("entity2", [layerspawner_component_name, gradientlist_component_name, aabb_component_name], 0.0, 0.0, aabb_height/2.0)
# Create three gradient entities.
gradient_entity1 = create_entity_at("Constant Gradient1", ["Constant Gradient"], 0.0, 0.0, 0.0);
gradient_entity2 = create_entity_at("Constant Gradient2", ["Constant Gradient"], 0.0, 0.0, 0.0);
gradient_entity3 = create_entity_at("Constant Gradient3", ["Constant Gradient"], 0.0, 0.0, 0.0);
# Give everything a chance to finish initializing.
general.idle_wait_frames(1)
# Set the gradients to different values.
gradient_values = [0.5, 0.8, 0.3]
set_component_path_val(gradient_entity1, 0, gradient_value_path, gradient_values[0])
set_component_path_val(gradient_entity2, 0, gradient_value_path, gradient_values[1])
set_component_path_val(gradient_entity3, 0, gradient_value_path, gradient_values[2])
# Give the TerrainSystem time to tick.
general.idle_wait_frames(1)
# Set the dimensions of the Aabb.
set_component_path_val(main_entity, 2, "Axis Aligned Box Shape|Box Configuration|Dimensions", box_dimensions)
# Set up a handler to wait for notifications from the TerrainSystem.
handler = azlmbr.terrain.TerrainDataNotificationBusHandler()
handler.connect()
handler.add_callback("OnTerrainDataChanged", on_terrain_changed)
# Add a gradient to GradientList, then check the height returned from the TerrainSystem is correct.
set_gradients_check_height(main_entity, [gradient_entity1.id], aabb_height * gradient_values[0], HeightTests.single_gradient_height_correct)
# Add gradient2 and check height at the origin, this should have changed to match the second gradient value.
set_gradients_check_height(main_entity, [gradient_entity1.id, gradient_entity2.id], aabb_height * gradient_values[1], HeightTests.double_gradient_height_correct)
# Add gradient3, the height should still be the second value, as that was the highest.
set_gradients_check_height(main_entity, [gradient_entity1.id, gradient_entity2.id, gradient_entity3.id], aabb_height * gradient_values[1], HeightTests.triple_gradient_height_correct)
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(TerrainHeightGradientList_AddRemoveGradientWorks)

@ -27,3 +27,6 @@ class TestAutomation(EditorTestSuite):
class test_Terrain_SupportsPhysics(EditorSharedTest):
from .EditorScripts import Terrain_SupportsPhysics as test_module
class test_TerrainHeightGradientList_AddRemoveGradientWorks(EditorSharedTest):
from .EditorScripts import TerrainHeightGradientList_AddRemoveGradientWorks as test_module

@ -15,6 +15,7 @@ import logging
# Import LyTestTools
import ly_test_tools.o3de.asset_processor as asset_processor_commands
import ly_test_tools.o3de.asset_processor_utils
logger = logging.getLogger(__name__)
@ -36,5 +37,8 @@ def asset_processor(request: pytest.fixture, workspace: pytest.fixture) -> asset
ap.stop()
request.addfinalizer(teardown)
for n in ly_test_tools.o3de.asset_processor_utils.processList:
assert not ly_test_tools.o3de.asset_processor_utils.check_ap_running(n), f"{n} process did not shutdown correctly."
return ap

@ -8,6 +8,8 @@ General Asset Processor Batch Tests
"""
# Import builtin libraries
from os import listdir
import pytest
import logging
import os
@ -724,3 +726,11 @@ class TestsAssetProcessorBatch_AllPlatforms(object):
assert error_line_found, "The error could not be found in the newest run of the AP Batch log."
@pytest.mark.assetpipeline
def test_AssetProcessor_Log_On_Failure(self, asset_processor, ap_setup_fixture, workspace):
asset_processor.prepare_test_environment(ap_setup_fixture["tests_dir"], "test_AP_Logs")
result, output = asset_processor.batch_process(expect_failure=True, capture_output=True)
assert result == False, f'AssetProcessorBatch should have failed because there is a bad asset, output was {output}'
jobLogs = listdir(workspace.paths.ap_job_logs() + "/test_AP_Logs")
assert not len(jobLogs) == 0, 'No job logs where output during failure.'

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

@ -8,7 +8,7 @@ SPDX-License-Identifier: Apache-2.0 OR MIT
import os
import logging
import subprocess
import sys
import pytest
import time
@ -128,7 +128,8 @@ class TestAutomationBase:
errors.append(TestRunError("FAILED TEST", error_str))
if return_code and return_code != TestAutomationBase.TEST_FAIL_RETCODE: # Crashed
crash_info = "-- No crash log available --"
crash_log = os.path.join(workspace.paths.project_log(), 'error.log')
crash_log = workspace.paths.crash_log()
try:
waiter.wait_for(lambda: os.path.exists(crash_log), timeout=TestAutomationBase.WAIT_FOR_CRASH_LOG)
except AssertionError:

@ -10,6 +10,8 @@
#include "EditorPreferencesPageViewportManipulator.h"
#include <AzToolsFramework/Viewport/ViewportSettings.h>
// Editor
#include "EditorViewportSettings.h"
#include "Settings.h"
@ -19,7 +21,17 @@ void CEditorPreferencesPage_ViewportManipulator::Reflect(AZ::SerializeContext& s
serialize.Class<Manipulators>()
->Version(1)
->Field("LineBoundWidth", &Manipulators::m_manipulatorLineBoundWidth)
->Field("CircleBoundWidth", &Manipulators::m_manipulatorCircleBoundWidth);
->Field("CircleBoundWidth", &Manipulators::m_manipulatorCircleBoundWidth)
->Field("LinearManipulatorAxisLength", &Manipulators::m_linearManipulatorAxisLength)
->Field("PlanarManipulatorAxisLength", &Manipulators::m_planarManipulatorAxisLength)
->Field("SurfaceManipulatorRadius", &Manipulators::m_surfaceManipulatorRadius)
->Field("SurfaceManipulatorOpacity", &Manipulators::m_surfaceManipulatorOpacity)
->Field("LinearManipulatorConeLength", &Manipulators::m_linearManipulatorConeLength)
->Field("LinearManipulatorConeRadius", &Manipulators::m_linearManipulatorConeRadius)
->Field("ScaleManipulatorBoxHalfExtent", &Manipulators::m_scaleManipulatorBoxHalfExtent)
->Field("RotationManipulatorRadius", &Manipulators::m_rotationManipulatorRadius)
->Field("ManipulatorViewBaseScale", &Manipulators::m_manipulatorViewBaseScale)
->Field("FlipManipulatorAxesTowardsView", &Manipulators::m_flipManipulatorAxesTowardsView);
serialize.Class<CEditorPreferencesPage_ViewportManipulator>()->Version(2)->Field(
"Manipulators", &CEditorPreferencesPage_ViewportManipulator::m_manipulators);
@ -36,7 +48,55 @@ void CEditorPreferencesPage_ViewportManipulator::Reflect(AZ::SerializeContext& s
AZ::Edit::UIHandlers::SpinBox, &Manipulators::m_manipulatorCircleBoundWidth, "Circle Bound Width",
"Manipulator Circle Bound Width")
->Attribute(AZ::Edit::Attributes::Min, 0.001f)
->Attribute(AZ::Edit::Attributes::Max, 2.0f);
->Attribute(AZ::Edit::Attributes::Max, 2.0f)
->DataElement(
AZ::Edit::UIHandlers::SpinBox, &Manipulators::m_linearManipulatorAxisLength, "Linear Manipulator Axis Length",
"Length of default Linear Manipulator (for Translation and Scale Manipulators)")
->Attribute(AZ::Edit::Attributes::Min, 0.1f)
->Attribute(AZ::Edit::Attributes::Max, 5.0f)
->DataElement(
AZ::Edit::UIHandlers::SpinBox, &Manipulators::m_planarManipulatorAxisLength, "Planar Manipulator Axis Length",
"Length of default Planar Manipulator (for Translation Manipulators)")
->Attribute(AZ::Edit::Attributes::Min, 0.1f)
->Attribute(AZ::Edit::Attributes::Max, 5.0f)
->DataElement(
AZ::Edit::UIHandlers::SpinBox, &Manipulators::m_surfaceManipulatorRadius, "Surface Manipulator Radius",
"Radius of default Surface Manipulator (for Translation Manipulators)")
->Attribute(AZ::Edit::Attributes::Min, 0.05f)
->Attribute(AZ::Edit::Attributes::Max, 1.0f)
->DataElement(
AZ::Edit::UIHandlers::SpinBox, &Manipulators::m_surfaceManipulatorOpacity, "Surface Manipulator Opacity",
"Opacity of default Surface Manipulator (for Translation Manipulators)")
->Attribute(AZ::Edit::Attributes::Min, 0.01f)
->Attribute(AZ::Edit::Attributes::Max, 1.0f)
->DataElement(
AZ::Edit::UIHandlers::SpinBox, &Manipulators::m_linearManipulatorConeLength, "Linear Manipulator Cone Length",
"Length of cone for default Linear Manipulator (for Translation Manipulators)")
->Attribute(AZ::Edit::Attributes::Min, 0.05f)
->Attribute(AZ::Edit::Attributes::Max, 1.0f)
->DataElement(
AZ::Edit::UIHandlers::SpinBox, &Manipulators::m_linearManipulatorConeRadius, "Linear Manipulator Cone Radius",
"Radius of cone for default Linear Manipulator (for Translation Manipulators)")
->Attribute(AZ::Edit::Attributes::Min, 0.05f)
->Attribute(AZ::Edit::Attributes::Max, 0.5f)
->DataElement(
AZ::Edit::UIHandlers::SpinBox, &Manipulators::m_scaleManipulatorBoxHalfExtent, "Scale Manipulator Box Half Extent",
"Half extent of box for default Scale Manipulator")
->Attribute(AZ::Edit::Attributes::Min, 0.05f)
->Attribute(AZ::Edit::Attributes::Max, 1.0f)
->DataElement(
AZ::Edit::UIHandlers::SpinBox, &Manipulators::m_rotationManipulatorRadius, "Rotation Manipulator Radius",
"Radius of default Angular Manipulators (for Rotation Manipulators)")
->Attribute(AZ::Edit::Attributes::Min, 0.5f)
->Attribute(AZ::Edit::Attributes::Max, 5.0f)
->DataElement(
AZ::Edit::UIHandlers::SpinBox, &Manipulators::m_manipulatorViewBaseScale, "Manipulator View Base Scale",
"The base scale to apply to all Manipulator Views (default is 1.0)")
->Attribute(AZ::Edit::Attributes::Min, 0.5f)
->Attribute(AZ::Edit::Attributes::Max, 2.0f)
->DataElement(
AZ::Edit::UIHandlers::CheckBox, &Manipulators::m_flipManipulatorAxesTowardsView, "Flip Manipulator Axes Towards View",
"Determines whether Planar and Linear Manipulators should switch to face the view (camera) in the Editor");
editContext
->Class<CEditorPreferencesPage_ViewportManipulator>("Manipulator Viewport Preferences", "Manipulator Viewport Preferences")
@ -82,10 +142,32 @@ void CEditorPreferencesPage_ViewportManipulator::OnApply()
{
SandboxEditor::SetManipulatorLineBoundWidth(m_manipulators.m_manipulatorLineBoundWidth);
SandboxEditor::SetManipulatorCircleBoundWidth(m_manipulators.m_manipulatorCircleBoundWidth);
AzToolsFramework::SetLinearManipulatorAxisLength(m_manipulators.m_linearManipulatorAxisLength);
AzToolsFramework::SetPlanarManipulatorAxisLength(m_manipulators.m_planarManipulatorAxisLength);
AzToolsFramework::SetSurfaceManipulatorRadius(m_manipulators.m_surfaceManipulatorRadius);
AzToolsFramework::SetSurfaceManipulatorOpacity(m_manipulators.m_surfaceManipulatorOpacity);
AzToolsFramework::SetLinearManipulatorConeLength(m_manipulators.m_linearManipulatorConeLength);
AzToolsFramework::SetLinearManipulatorConeRadius(m_manipulators.m_linearManipulatorConeRadius);
AzToolsFramework::SetScaleManipulatorBoxHalfExtent(m_manipulators.m_scaleManipulatorBoxHalfExtent);
AzToolsFramework::SetRotationManipulatorRadius(m_manipulators.m_rotationManipulatorRadius);
AzToolsFramework::SetFlipManipulatorAxesTowardsView(m_manipulators.m_flipManipulatorAxesTowardsView);
AzToolsFramework::SetManipulatorViewBaseScale(m_manipulators.m_manipulatorViewBaseScale);
}
void CEditorPreferencesPage_ViewportManipulator::InitializeSettings()
{
m_manipulators.m_manipulatorLineBoundWidth = SandboxEditor::ManipulatorLineBoundWidth();
m_manipulators.m_manipulatorCircleBoundWidth = SandboxEditor::ManipulatorCircleBoundWidth();
m_manipulators.m_linearManipulatorAxisLength = AzToolsFramework::LinearManipulatorAxisLength();
m_manipulators.m_planarManipulatorAxisLength = AzToolsFramework::PlanarManipulatorAxisLength();
m_manipulators.m_surfaceManipulatorRadius = AzToolsFramework::SurfaceManipulatorRadius();
m_manipulators.m_surfaceManipulatorOpacity = AzToolsFramework::SurfaceManipulatorOpacity();
m_manipulators.m_linearManipulatorConeLength = AzToolsFramework::LinearManipulatorConeLength();
m_manipulators.m_linearManipulatorConeRadius = AzToolsFramework::LinearManipulatorConeRadius();
m_manipulators.m_scaleManipulatorBoxHalfExtent = AzToolsFramework::ScaleManipulatorBoxHalfExtent();
m_manipulators.m_rotationManipulatorRadius = AzToolsFramework::RotationManipulatorRadius();
m_manipulators.m_flipManipulatorAxesTowardsView = AzToolsFramework::FlipManipulatorAxesTowardsView();
m_manipulators.m_manipulatorViewBaseScale = AzToolsFramework::ManipulatorViewBaseScale();
}

@ -41,6 +41,16 @@ private:
float m_manipulatorLineBoundWidth = 0.0f;
float m_manipulatorCircleBoundWidth = 0.0f;
float m_linearManipulatorAxisLength = 0.0f;
float m_planarManipulatorAxisLength = 0.0f;
float m_surfaceManipulatorRadius = 0.0f;
float m_surfaceManipulatorOpacity = 0.0f;
float m_linearManipulatorConeLength = 0.0f;
float m_linearManipulatorConeRadius = 0.0f;
float m_scaleManipulatorBoxHalfExtent = 0.0f;
float m_rotationManipulatorRadius = 0.0f;
float m_manipulatorViewBaseScale = 0.0f;
bool m_flipManipulatorAxesTowardsView = false;
};
Manipulators m_manipulators;

@ -12,6 +12,7 @@
#include <AzCore/Settings/SettingsRegistry.h>
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
#include <AzCore/std/string/string_view.h>
#include <AzToolsFramework/Viewport/ViewportSettings.h>
namespace SandboxEditor
{
@ -57,31 +58,6 @@ namespace SandboxEditor
constexpr AZStd::string_view CameraDefaultStartingPositionY = "/Amazon/Preferences/Editor/Camera/DefaultStartingPosition/y";
constexpr AZStd::string_view CameraDefaultStartingPositionZ = "/Amazon/Preferences/Editor/Camera/DefaultStartingPosition/z";
template<typename T>
void SetRegistry(const AZStd::string_view setting, T&& value)
{
if (auto* registry = AZ::SettingsRegistry::Get())
{
registry->Set(setting, AZStd::forward<T>(value));
}
}
template<typename T>
AZStd::remove_cvref_t<T> GetRegistry(const AZStd::string_view setting, T&& defaultValue)
{
AZStd::remove_cvref_t<T> value = AZStd::forward<T>(defaultValue);
if (const auto* registry = AZ::SettingsRegistry::Get())
{
T potentialValue;
if (registry->Get(potentialValue, setting))
{
value = AZStd::move(potentialValue);
}
}
return value;
}
struct EditorViewportSettingsCallbacksImpl : public EditorViewportSettingsCallbacks
{
EditorViewportSettingsCallbacksImpl()
@ -118,399 +94,409 @@ namespace SandboxEditor
AZ::Vector3 CameraDefaultEditorPosition()
{
return AZ::Vector3(
aznumeric_cast<float>(GetRegistry(CameraDefaultStartingPositionX, 0.0)),
aznumeric_cast<float>(GetRegistry(CameraDefaultStartingPositionY, -10.0)),
aznumeric_cast<float>(GetRegistry(CameraDefaultStartingPositionZ, 4.0)));
aznumeric_cast<float>(AzToolsFramework::GetRegistry(CameraDefaultStartingPositionX, 0.0)),
aznumeric_cast<float>(AzToolsFramework::GetRegistry(CameraDefaultStartingPositionY, -10.0)),
aznumeric_cast<float>(AzToolsFramework::GetRegistry(CameraDefaultStartingPositionZ, 4.0)));
}
void SetCameraDefaultEditorPosition(const AZ::Vector3& defaultCameraPosition)
{
SetRegistry(CameraDefaultStartingPositionX, defaultCameraPosition.GetX());
SetRegistry(CameraDefaultStartingPositionY, defaultCameraPosition.GetY());
SetRegistry(CameraDefaultStartingPositionZ, defaultCameraPosition.GetZ());
AzToolsFramework::SetRegistry(CameraDefaultStartingPositionX, defaultCameraPosition.GetX());
AzToolsFramework::SetRegistry(CameraDefaultStartingPositionY, defaultCameraPosition.GetY());
AzToolsFramework::SetRegistry(CameraDefaultStartingPositionZ, defaultCameraPosition.GetZ());
}
AZ::u64 MaxItemsShownInAssetBrowserSearch()
{
return GetRegistry(AssetBrowserMaxItemsShownInSearchSetting, aznumeric_cast<AZ::u64>(50));
return AzToolsFramework::GetRegistry(AssetBrowserMaxItemsShownInSearchSetting, aznumeric_cast<AZ::u64>(50));
}
void SetMaxItemsShownInAssetBrowserSearch(const AZ::u64 numberOfItemsShown)
{
SetRegistry(AssetBrowserMaxItemsShownInSearchSetting, numberOfItemsShown);
AzToolsFramework::SetRegistry(AssetBrowserMaxItemsShownInSearchSetting, numberOfItemsShown);
}
bool GridSnappingEnabled()
{
return GetRegistry(GridSnappingSetting, false);
return AzToolsFramework::GetRegistry(GridSnappingSetting, false);
}
void SetGridSnapping(const bool enabled)
{
SetRegistry(GridSnappingSetting, enabled);
AzToolsFramework::SetRegistry(GridSnappingSetting, enabled);
}
float GridSnappingSize()
{
return aznumeric_cast<float>(GetRegistry(GridSizeSetting, 0.1));
return aznumeric_cast<float>(AzToolsFramework::GetRegistry(GridSizeSetting, 0.1));
}
void SetGridSnappingSize(const float size)
{
SetRegistry(GridSizeSetting, size);
AzToolsFramework::SetRegistry(GridSizeSetting, size);
}
bool AngleSnappingEnabled()
{
return GetRegistry(AngleSnappingSetting, false);
return AzToolsFramework::GetRegistry(AngleSnappingSetting, false);
}
void SetAngleSnapping(const bool enabled)
{
SetRegistry(AngleSnappingSetting, enabled);
AzToolsFramework::SetRegistry(AngleSnappingSetting, enabled);
}
float AngleSnappingSize()
{
return aznumeric_cast<float>(GetRegistry(AngleSizeSetting, 5.0));
return aznumeric_cast<float>(AzToolsFramework::GetRegistry(AngleSizeSetting, 5.0));
}
void SetAngleSnappingSize(const float size)
{
SetRegistry(AngleSizeSetting, size);
AzToolsFramework::SetRegistry(AngleSizeSetting, size);
}
bool ShowingGrid()
{
return GetRegistry(ShowGridSetting, false);
return AzToolsFramework::GetRegistry(ShowGridSetting, false);
}
void SetShowingGrid(const bool showing)
{
SetRegistry(ShowGridSetting, showing);
AzToolsFramework::SetRegistry(ShowGridSetting, showing);
}
bool StickySelectEnabled()
{
return GetRegistry(StickySelectSetting, false);
return AzToolsFramework::GetRegistry(StickySelectSetting, false);
}
void SetStickySelectEnabled(const bool enabled)
{
SetRegistry(StickySelectSetting, enabled);
AzToolsFramework::SetRegistry(StickySelectSetting, enabled);
}
float ManipulatorLineBoundWidth()
{
return aznumeric_cast<float>(GetRegistry(ManipulatorLineBoundWidthSetting, 0.1));
return aznumeric_cast<float>(AzToolsFramework::GetRegistry(ManipulatorLineBoundWidthSetting, 0.1));
}
void SetManipulatorLineBoundWidth(const float lineBoundWidth)
{
SetRegistry(ManipulatorLineBoundWidthSetting, lineBoundWidth);
AzToolsFramework::SetRegistry(ManipulatorLineBoundWidthSetting, lineBoundWidth);
}
float ManipulatorCircleBoundWidth()
{
return aznumeric_cast<float>(GetRegistry(ManipulatorCircleBoundWidthSetting, 0.1));
return aznumeric_cast<float>(AzToolsFramework::GetRegistry(ManipulatorCircleBoundWidthSetting, 0.1));
}
void SetManipulatorCircleBoundWidth(const float circleBoundWidth)
{
SetRegistry(ManipulatorCircleBoundWidthSetting, circleBoundWidth);
AzToolsFramework::SetRegistry(ManipulatorCircleBoundWidthSetting, circleBoundWidth);
}
float CameraTranslateSpeed()
{
return aznumeric_cast<float>(GetRegistry(CameraTranslateSpeedSetting, 10.0));
return aznumeric_cast<float>(AzToolsFramework::GetRegistry(CameraTranslateSpeedSetting, 10.0));
}
void SetCameraTranslateSpeed(const float speed)
{
SetRegistry(CameraTranslateSpeedSetting, speed);
AzToolsFramework::SetRegistry(CameraTranslateSpeedSetting, speed);
}
float CameraBoostMultiplier()
{
return aznumeric_cast<float>(GetRegistry(CameraBoostMultiplierSetting, 3.0));
return aznumeric_cast<float>(AzToolsFramework::GetRegistry(CameraBoostMultiplierSetting, 3.0));
}
void SetCameraBoostMultiplier(const float multiplier)
{
SetRegistry(CameraBoostMultiplierSetting, multiplier);
AzToolsFramework::SetRegistry(CameraBoostMultiplierSetting, multiplier);
}
float CameraRotateSpeed()
{
return aznumeric_cast<float>(GetRegistry(CameraRotateSpeedSetting, 0.005));
return aznumeric_cast<float>(AzToolsFramework::GetRegistry(CameraRotateSpeedSetting, 0.005));
}
void SetCameraRotateSpeed(const float speed)
{
SetRegistry(CameraRotateSpeedSetting, speed);
AzToolsFramework::SetRegistry(CameraRotateSpeedSetting, speed);
}
float CameraScrollSpeed()
{
return aznumeric_cast<float>(GetRegistry(CameraScrollSpeedSetting, 0.02));
return aznumeric_cast<float>(AzToolsFramework::GetRegistry(CameraScrollSpeedSetting, 0.02));
}
void SetCameraScrollSpeed(const float speed)
{
SetRegistry(CameraScrollSpeedSetting, speed);
AzToolsFramework::SetRegistry(CameraScrollSpeedSetting, speed);
}
float CameraDollyMotionSpeed()
{
return aznumeric_cast<float>(GetRegistry(CameraDollyMotionSpeedSetting, 0.01));
return aznumeric_cast<float>(AzToolsFramework::GetRegistry(CameraDollyMotionSpeedSetting, 0.01));
}
void SetCameraDollyMotionSpeed(const float speed)
{
SetRegistry(CameraDollyMotionSpeedSetting, speed);
AzToolsFramework::SetRegistry(CameraDollyMotionSpeedSetting, speed);
}
bool CameraOrbitYawRotationInverted()
{
return GetRegistry(CameraOrbitYawRotationInvertedSetting, false);
return AzToolsFramework::GetRegistry(CameraOrbitYawRotationInvertedSetting, false);
}
void SetCameraOrbitYawRotationInverted(const bool inverted)
{
SetRegistry(CameraOrbitYawRotationInvertedSetting, inverted);
AzToolsFramework::SetRegistry(CameraOrbitYawRotationInvertedSetting, inverted);
}
bool CameraPanInvertedX()
{
return GetRegistry(CameraPanInvertedXSetting, true);
return AzToolsFramework::GetRegistry(CameraPanInvertedXSetting, true);
}
void SetCameraPanInvertedX(const bool inverted)
{
SetRegistry(CameraPanInvertedXSetting, inverted);
AzToolsFramework::SetRegistry(CameraPanInvertedXSetting, inverted);
}
bool CameraPanInvertedY()
{
return GetRegistry(CameraPanInvertedYSetting, true);
return AzToolsFramework::GetRegistry(CameraPanInvertedYSetting, true);
}
void SetCameraPanInvertedY(const bool inverted)
{
SetRegistry(CameraPanInvertedYSetting, inverted);
AzToolsFramework::SetRegistry(CameraPanInvertedYSetting, inverted);
}
float CameraPanSpeed()
{
return aznumeric_cast<float>(GetRegistry(CameraPanSpeedSetting, 0.01));
return aznumeric_cast<float>(AzToolsFramework::GetRegistry(CameraPanSpeedSetting, 0.01));
}
void SetCameraPanSpeed(float speed)
{
SetRegistry(CameraPanSpeedSetting, speed);
AzToolsFramework::SetRegistry(CameraPanSpeedSetting, speed);
}
float CameraRotateSmoothness()
{
return aznumeric_cast<float>(GetRegistry(CameraRotateSmoothnessSetting, 5.0));
return aznumeric_cast<float>(AzToolsFramework::GetRegistry(CameraRotateSmoothnessSetting, 5.0));
}
void SetCameraRotateSmoothness(const float smoothness)
{
SetRegistry(CameraRotateSmoothnessSetting, smoothness);
AzToolsFramework::SetRegistry(CameraRotateSmoothnessSetting, smoothness);
}
float CameraTranslateSmoothness()
{
return aznumeric_cast<float>(GetRegistry(CameraTranslateSmoothnessSetting, 5.0));
return aznumeric_cast<float>(AzToolsFramework::GetRegistry(CameraTranslateSmoothnessSetting, 5.0));
}
void SetCameraTranslateSmoothness(const float smoothness)
{
SetRegistry(CameraTranslateSmoothnessSetting, smoothness);
AzToolsFramework::SetRegistry(CameraTranslateSmoothnessSetting, smoothness);
}
bool CameraRotateSmoothingEnabled()
{
return GetRegistry(CameraRotateSmoothingSetting, true);
return AzToolsFramework::GetRegistry(CameraRotateSmoothingSetting, true);
}
void SetCameraRotateSmoothingEnabled(const bool enabled)
{
SetRegistry(CameraRotateSmoothingSetting, enabled);
AzToolsFramework::SetRegistry(CameraRotateSmoothingSetting, enabled);
}
bool CameraTranslateSmoothingEnabled()
{
return GetRegistry(CameraTranslateSmoothingSetting, true);
return AzToolsFramework::GetRegistry(CameraTranslateSmoothingSetting, true);
}
void SetCameraTranslateSmoothingEnabled(const bool enabled)
{
SetRegistry(CameraTranslateSmoothingSetting, enabled);
AzToolsFramework::SetRegistry(CameraTranslateSmoothingSetting, enabled);
}
bool CameraCaptureCursorForLook()
{
return GetRegistry(CameraCaptureCursorLookSetting, true);
return AzToolsFramework::GetRegistry(CameraCaptureCursorLookSetting, true);
}
void SetCameraCaptureCursorForLook(const bool capture)
{
SetRegistry(CameraCaptureCursorLookSetting, capture);
AzToolsFramework::SetRegistry(CameraCaptureCursorLookSetting, capture);
}
float CameraDefaultOrbitDistance()
{
return aznumeric_cast<float>(GetRegistry(CameraDefaultOrbitDistanceSetting, 20.0));
return aznumeric_cast<float>(AzToolsFramework::GetRegistry(CameraDefaultOrbitDistanceSetting, 20.0));
}
void SetCameraDefaultOrbitDistance(const float distance)
{
SetRegistry(CameraDefaultOrbitDistanceSetting, distance);
AzToolsFramework::SetRegistry(CameraDefaultOrbitDistanceSetting, distance);
}
AzFramework::InputChannelId CameraTranslateForwardChannelId()
{
return AzFramework::InputChannelId(
GetRegistry(CameraTranslateForwardIdSetting, AZStd::string("keyboard_key_alphanumeric_W")).c_str());
AzToolsFramework::GetRegistry(CameraTranslateForwardIdSetting, AZStd::string("keyboard_key_alphanumeric_W")).c_str());
}
void SetCameraTranslateForwardChannelId(AZStd::string_view cameraTranslateForwardId)
{
SetRegistry(CameraTranslateForwardIdSetting, cameraTranslateForwardId);
AzToolsFramework::SetRegistry(CameraTranslateForwardIdSetting, cameraTranslateForwardId);
}
AzFramework::InputChannelId CameraTranslateBackwardChannelId()
{
return AzFramework::InputChannelId(
GetRegistry(CameraTranslateBackwardIdSetting, AZStd::string("keyboard_key_alphanumeric_S")).c_str());
AzToolsFramework::GetRegistry(CameraTranslateBackwardIdSetting, AZStd::string("keyboard_key_alphanumeric_S")).c_str());
}
void SetCameraTranslateBackwardChannelId(AZStd::string_view cameraTranslateBackwardId)
{
SetRegistry(CameraTranslateBackwardIdSetting, cameraTranslateBackwardId);
AzToolsFramework::SetRegistry(CameraTranslateBackwardIdSetting, cameraTranslateBackwardId);
}
AzFramework::InputChannelId CameraTranslateLeftChannelId()
{
return AzFramework::InputChannelId(GetRegistry(CameraTranslateLeftIdSetting, AZStd::string("keyboard_key_alphanumeric_A")).c_str());
return AzFramework::InputChannelId(
AzToolsFramework::GetRegistry(CameraTranslateLeftIdSetting, AZStd::string("keyboard_key_alphanumeric_A")).c_str());
}
void SetCameraTranslateLeftChannelId(AZStd::string_view cameraTranslateLeftId)
{
SetRegistry(CameraTranslateLeftIdSetting, cameraTranslateLeftId);
AzToolsFramework::SetRegistry(CameraTranslateLeftIdSetting, cameraTranslateLeftId);
}
AzFramework::InputChannelId CameraTranslateRightChannelId()
{
return AzFramework::InputChannelId(
GetRegistry(CameraTranslateRightIdSetting, AZStd::string("keyboard_key_alphanumeric_D")).c_str());
AzToolsFramework::GetRegistry(CameraTranslateRightIdSetting, AZStd::string("keyboard_key_alphanumeric_D")).c_str());
}
void SetCameraTranslateRightChannelId(AZStd::string_view cameraTranslateRightId)
{
SetRegistry(CameraTranslateRightIdSetting, cameraTranslateRightId);
AzToolsFramework::SetRegistry(CameraTranslateRightIdSetting, cameraTranslateRightId);
}
AzFramework::InputChannelId CameraTranslateUpChannelId()
{
return AzFramework::InputChannelId(GetRegistry(CameraTranslateUpIdSetting, AZStd::string("keyboard_key_alphanumeric_E")).c_str());
return AzFramework::InputChannelId(
AzToolsFramework::GetRegistry(CameraTranslateUpIdSetting, AZStd::string("keyboard_key_alphanumeric_E")).c_str());
}
void SetCameraTranslateUpChannelId(AZStd::string_view cameraTranslateUpId)
{
SetRegistry(CameraTranslateUpIdSetting, cameraTranslateUpId);
AzToolsFramework::SetRegistry(CameraTranslateUpIdSetting, cameraTranslateUpId);
}
AzFramework::InputChannelId CameraTranslateDownChannelId()
{
return AzFramework::InputChannelId(GetRegistry(CameraTranslateDownIdSetting, AZStd::string("keyboard_key_alphanumeric_Q")).c_str());
return AzFramework::InputChannelId(
AzToolsFramework::GetRegistry(CameraTranslateDownIdSetting, AZStd::string("keyboard_key_alphanumeric_Q")).c_str());
}
void SetCameraTranslateDownChannelId(AZStd::string_view cameraTranslateDownId)
{
SetRegistry(CameraTranslateDownIdSetting, cameraTranslateDownId);
AzToolsFramework::SetRegistry(CameraTranslateDownIdSetting, cameraTranslateDownId);
}
AzFramework::InputChannelId CameraTranslateBoostChannelId()
{
return AzFramework::InputChannelId(
GetRegistry(CameraTranslateBoostIdSetting, AZStd::string("keyboard_key_modifier_shift_l")).c_str());
AzToolsFramework::GetRegistry(CameraTranslateBoostIdSetting, AZStd::string("keyboard_key_modifier_shift_l")).c_str());
}
void SetCameraTranslateBoostChannelId(AZStd::string_view cameraTranslateBoostId)
{
SetRegistry(CameraTranslateBoostIdSetting, cameraTranslateBoostId);
AzToolsFramework::SetRegistry(CameraTranslateBoostIdSetting, cameraTranslateBoostId);
}
AzFramework::InputChannelId CameraOrbitChannelId()
{
return AzFramework::InputChannelId(GetRegistry(CameraOrbitIdSetting, AZStd::string("keyboard_key_modifier_alt_l")).c_str());
return AzFramework::InputChannelId(
AzToolsFramework::GetRegistry(CameraOrbitIdSetting, AZStd::string("keyboard_key_modifier_alt_l")).c_str());
}
void SetCameraOrbitChannelId(AZStd::string_view cameraOrbitId)
{
SetRegistry(CameraOrbitIdSetting, cameraOrbitId);
AzToolsFramework::SetRegistry(CameraOrbitIdSetting, cameraOrbitId);
}
AzFramework::InputChannelId CameraFreeLookChannelId()
{
return AzFramework::InputChannelId(GetRegistry(CameraFreeLookIdSetting, AZStd::string("mouse_button_right")).c_str());
return AzFramework::InputChannelId(
AzToolsFramework::GetRegistry(CameraFreeLookIdSetting, AZStd::string("mouse_button_right")).c_str());
}
void SetCameraFreeLookChannelId(AZStd::string_view cameraFreeLookId)
{
SetRegistry(CameraFreeLookIdSetting, cameraFreeLookId);
AzToolsFramework::SetRegistry(CameraFreeLookIdSetting, cameraFreeLookId);
}
AzFramework::InputChannelId CameraFreePanChannelId()
{
return AzFramework::InputChannelId(GetRegistry(CameraFreePanIdSetting, AZStd::string("mouse_button_middle")).c_str());
return AzFramework::InputChannelId(
AzToolsFramework::GetRegistry(CameraFreePanIdSetting, AZStd::string("mouse_button_middle")).c_str());
}
void SetCameraFreePanChannelId(AZStd::string_view cameraFreePanId)
{
SetRegistry(CameraFreePanIdSetting, cameraFreePanId);
AzToolsFramework::SetRegistry(CameraFreePanIdSetting, cameraFreePanId);
}
AzFramework::InputChannelId CameraOrbitLookChannelId()
{
return AzFramework::InputChannelId(GetRegistry(CameraOrbitLookIdSetting, AZStd::string("mouse_button_left")).c_str());
return AzFramework::InputChannelId(
AzToolsFramework::GetRegistry(CameraOrbitLookIdSetting, AZStd::string("mouse_button_left")).c_str());
}
void SetCameraOrbitLookChannelId(AZStd::string_view cameraOrbitLookId)
{
SetRegistry(CameraOrbitLookIdSetting, cameraOrbitLookId);
AzToolsFramework::SetRegistry(CameraOrbitLookIdSetting, cameraOrbitLookId);
}
AzFramework::InputChannelId CameraOrbitDollyChannelId()
{
return AzFramework::InputChannelId(GetRegistry(CameraOrbitDollyIdSetting, AZStd::string("mouse_button_right")).c_str());
return AzFramework::InputChannelId(
AzToolsFramework::GetRegistry(CameraOrbitDollyIdSetting, AZStd::string("mouse_button_right")).c_str());
}
void SetCameraOrbitDollyChannelId(AZStd::string_view cameraOrbitDollyId)
{
SetRegistry(CameraOrbitDollyIdSetting, cameraOrbitDollyId);
AzToolsFramework::SetRegistry(CameraOrbitDollyIdSetting, cameraOrbitDollyId);
}
AzFramework::InputChannelId CameraOrbitPanChannelId()
{
return AzFramework::InputChannelId(GetRegistry(CameraOrbitPanIdSetting, AZStd::string("mouse_button_middle")).c_str());
return AzFramework::InputChannelId(
AzToolsFramework::GetRegistry(CameraOrbitPanIdSetting, AZStd::string("mouse_button_middle")).c_str());
}
void SetCameraOrbitPanChannelId(AZStd::string_view cameraOrbitPanId)
{
SetRegistry(CameraOrbitPanIdSetting, cameraOrbitPanId);
AzToolsFramework::SetRegistry(CameraOrbitPanIdSetting, cameraOrbitPanId);
}
AzFramework::InputChannelId CameraFocusChannelId()
{
return AzFramework::InputChannelId(GetRegistry(CameraFocusIdSetting, AZStd::string("keyboard_key_alphanumeric_X")).c_str());
return AzFramework::InputChannelId(
AzToolsFramework::GetRegistry(CameraFocusIdSetting, AZStd::string("keyboard_key_alphanumeric_X")).c_str());
}
void SetCameraFocusChannelId(AZStd::string_view cameraFocusId)
{
SetRegistry(CameraFocusIdSetting, cameraFocusId);
AzToolsFramework::SetRegistry(CameraFocusIdSetting, cameraFocusId);
}
} // namespace SandboxEditor

@ -35,7 +35,6 @@
// CryCommon
#include <CryCommon/INavigationSystem.h>
#include <CryCommon/LyShine/ILyShine.h>
#include <CryCommon/MainThreadRenderRequestBus.h>
// Editor
@ -595,13 +594,6 @@ void CGameEngine::SwitchToInEditor()
// Enable accelerators.
GetIEditor()->EnableAcceleratos(true);
// reset UI system
if (gEnv->pLyShine)
{
gEnv->pLyShine->Reset();
}
// [Anton] - order changed, see comments for CGameEngine::SetSimulationMode
//! Send event to switch out of game.
GetIEditor()->GetObjectManager()->SendEvent(EVENT_OUTOFGAME);

@ -13,7 +13,6 @@ set(FILES
EditorCommonAPI.h
ActionOutput.h
ActionOutput.cpp
UiEditorDLLBus.h
DockTitleBarWidget.cpp
DockTitleBarWidget.h
SaveUtilities/AsyncSaveRunner.h

@ -486,9 +486,11 @@ namespace AZ
// Merge Command Line arguments
constexpr bool executeRegDumpCommands = false;
SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(*m_settingsRegistry, m_commandLine, executeRegDumpCommands);
#if defined(AZ_DEBUG_BUILD) || defined(AZ_PROFILE_BUILD)
// Skip over merging the User Registry in non-debug and profile configurations
SettingsRegistryMergeUtils::MergeSettingsToRegistry_O3deUserRegistry(*m_settingsRegistry, AZ_TRAIT_OS_PLATFORM_CODENAME, {});
#endif
SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(*m_settingsRegistry, m_commandLine, executeRegDumpCommands);
SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(*m_settingsRegistry);

@ -914,11 +914,11 @@ namespace UnitTest
m_testAssetManager->SetParallelDependentLoadingEnabled(true);
}
#if AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS || AZ_TRAIT_DISABLE_FAILED_ASSET_LOAD_TESTS
#if AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS
TEST_F(AssetJobsFloodTest, DISABLED_LoadTest_SameAsset_DifferentFilters)
#else
TEST_F(AssetJobsFloodTest, LoadTest_SameAsset_DifferentFilters)
#endif // AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS || AZ_TRAIT_DISABLE_FAILED_ASSET_LOAD_TESTS
#endif // AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS
{
m_assetHandlerAndCatalog->AssetCatalogRequestBus::Handler::BusConnect();
@ -1263,11 +1263,11 @@ namespace UnitTest
m_assetHandlerAndCatalog->AssetCatalogRequestBus::Handler::BusDisconnect();
}
#if AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS || AZ_TRAIT_DISABLE_FAILED_ASSET_LOAD_TESTS
#if AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS
TEST_F(AssetJobsFloodTest, DISABLED_AssetWithNoLoadReference_LoadDependencies_NoLoadNotLoaded)
#else
TEST_F(AssetJobsFloodTest, AssetWithNoLoadReference_LoadDependencies_NoLoadNotLoaded)
#endif // AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS || AZ_TRAIT_DISABLE_FAILED_ASSET_LOAD_TESTS
#endif // AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS
{
m_assetHandlerAndCatalog->AssetCatalogRequestBus::Handler::BusConnect();
// Setup has already created/destroyed assets
@ -1304,11 +1304,11 @@ namespace UnitTest
m_assetHandlerAndCatalog->AssetCatalogRequestBus::Handler::BusDisconnect();
}
#if AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS || AZ_TRAIT_DISABLE_FAILED_ASSET_LOAD_TESTS
#if AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS
TEST_F(AssetJobsFloodTest, DISABLED_AssetWithNoLoadReference_LoadContainerDependencies_LoadAllLoadsNoLoad)
#else
TEST_F(AssetJobsFloodTest, AssetWithNoLoadReference_LoadContainerDependencies_LoadAllLoadsNoLoad)
#endif // AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS || AZ_TRAIT_DISABLE_FAILED_ASSET_LOAD_TESTS
#endif // AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS
{
m_assetHandlerAndCatalog->AssetCatalogRequestBus::Handler::BusConnect();
// Setup has already created/destroyed assets
@ -1343,11 +1343,11 @@ namespace UnitTest
m_assetHandlerAndCatalog->AssetCatalogRequestBus::Handler::BusDisconnect();
}
#if AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS || AZ_TRAIT_DISABLE_FAILED_ASSET_LOAD_TESTS
#if AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS
TEST_F(AssetJobsFloodTest, DISABLED_AssetWithNoLoadReference_LoadDependencies_BehaviorObeyed)
#else
TEST_F(AssetJobsFloodTest, AssetWithNoLoadReference_LoadDependencies_BehaviorObeyed)
#endif // AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS || AZ_TRAIT_DISABLE_FAILED_ASSET_LOAD_TESTS
#endif // AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS
{
m_assetHandlerAndCatalog->AssetCatalogRequestBus::Handler::BusConnect();
// Setup has already created/destroyed assets

@ -12,13 +12,57 @@
namespace AzFramework::Terrain
{
// Create a handler that can be accessed from Python scripts to receive terrain change notifications.
class TerrainDataNotificationHandler final
: public AzFramework::Terrain::TerrainDataNotificationBus::Handler
, public AZ::BehaviorEBusHandler
{
public:
AZ_EBUS_BEHAVIOR_BINDER(
TerrainDataNotificationHandler,
"{A83EF103-295A-4653-8279-F30FBF3F9037}",
AZ::SystemAllocator,
OnTerrainDataCreateBegin,
OnTerrainDataCreateEnd,
OnTerrainDataDestroyBegin,
OnTerrainDataDestroyEnd,
OnTerrainDataChanged);
void OnTerrainDataCreateBegin() override
{
Call(FN_OnTerrainDataCreateBegin);
}
void OnTerrainDataCreateEnd() override
{
Call(FN_OnTerrainDataCreateEnd);
}
void OnTerrainDataDestroyBegin() override
{
Call(FN_OnTerrainDataDestroyBegin);
}
void OnTerrainDataDestroyEnd() override
{
Call(FN_OnTerrainDataDestroyEnd);
}
void OnTerrainDataChanged(
const AZ::Aabb& dirtyRegion, AzFramework::Terrain::TerrainDataNotifications::TerrainDataChangedMask dataChangedMask) override
{
Call(FN_OnTerrainDataChanged, dirtyRegion, dataChangedMask);
}
};
void TerrainDataRequests::Reflect(AZ::ReflectContext* context)
{
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
{
behaviorContext->EBus<AzFramework::Terrain::TerrainDataRequestBus>("TerrainDataRequestBus")
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
->Attribute(AZ::Script::Attributes::Category, "Terrain")
->Event("GetHeight", &AzFramework::Terrain::TerrainDataRequestBus::Events::GetHeight)
->Attribute(AZ::Script::Attributes::Module, "terrain")
->Event("GetNormal", &AzFramework::Terrain::TerrainDataRequestBus::Events::GetNormal)
->Event("GetMaxSurfaceWeight", &AzFramework::Terrain::TerrainDataRequestBus::Events::GetMaxSurfaceWeight)
->Event("GetMaxSurfaceWeightFromVector2",
@ -34,8 +78,24 @@ namespace AzFramework::Terrain
->Event("GetTerrainAabb", &AzFramework::Terrain::TerrainDataRequestBus::Events::GetTerrainAabb)
->Event("GetTerrainHeightQueryResolution",
&AzFramework::Terrain::TerrainDataRequestBus::Events::GetTerrainHeightQueryResolution)
->Event("GetHeight", &AzFramework::Terrain::TerrainDataRequestBus::Events::GetHeightVal)
->Event("GetHeightFromVector2", &AzFramework::Terrain::TerrainDataRequestBus::Events::GetHeightValFromVector2)
->Event("GetHeightFromFloats", &AzFramework::Terrain::TerrainDataRequestBus::Events::GetHeightValFromFloats)
;
behaviorContext->EBus<AzFramework::Terrain::TerrainDataNotificationBus>("TerrainDataNotificationBus")
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
->Attribute(AZ::Script::Attributes::Category, "Terrain")
->Attribute(AZ::Script::Attributes::Module, "terrain")
->Event("OnTerrainDataCreateBegin", &AzFramework::Terrain::TerrainDataNotifications::OnTerrainDataCreateBegin)
->Event("OnTerrainDataCreateEnd", &AzFramework::Terrain::TerrainDataNotifications::OnTerrainDataCreateEnd)
->Event("OnTerrainDataDestroyBegin", &AzFramework::Terrain::TerrainDataNotifications::OnTerrainDataDestroyBegin)
->Event("OnTerrainDataDestroyEnd", &AzFramework::Terrain::TerrainDataNotifications::OnTerrainDataDestroyEnd)
->Event("OnTerrainDataChanged", &AzFramework::Terrain::TerrainDataNotifications::OnTerrainDataChanged)
->Handler<AzFramework::Terrain::TerrainDataNotificationHandler>()
;
}
//TerrainDataNotificationHandler::Reflect(context);
}
} // namespace AzFramework::Terrain

@ -144,13 +144,31 @@ namespace AzFramework
return result;
}
SurfaceData::SurfacePoint BehaviorContextGetSurfacePointFromVector2(
const AZ::Vector2& inPosition,
Sampler sampleFilter = Sampler::DEFAULT) const
const AZ::Vector2& inPosition, Sampler sampleFilter = Sampler::DEFAULT) const
{
SurfaceData::SurfacePoint result;
GetSurfacePointFromVector2(inPosition, result, sampleFilter);
return result;
}
// Functions without the optional bool* parameter that can be used from Python tests.
float GetHeightVal(AZ::Vector3 position, Sampler sampler = Sampler::BILINEAR) const
{
bool terrainExists;
return GetHeight(position, sampler, &terrainExists);
}
float GetHeightValFromVector2(AZ::Vector2 position, Sampler sampler = Sampler::BILINEAR) const
{
bool terrainExists;
return GetHeightFromVector2(position, sampler, &terrainExists);
}
float GetHeightValFromFloats(float x, float y, Sampler sampler = Sampler::BILINEAR) const
{
bool terrainExists;
return GetHeightFromFloats(x, y, sampler, &terrainExists);
}
};
using TerrainDataRequestBus = AZ::EBus<TerrainDataRequests>;

@ -13,6 +13,13 @@
namespace UnitTest
{
//! Null implementation of DebugDisplayRequests for dummy draw calls.
class NullDebugDisplayRequests : public AzFramework::DebugDisplayRequests
{
public:
virtual ~NullDebugDisplayRequests() = default;
};
//! Minimal implementation of DebugDisplayRequests to support testing shapes.
//! Stores a list of points based on received draw calls to delineate the exterior of the object requested to be drawn.
class TestDebugDisplayRequests : public AzFramework::DebugDisplayRequests

@ -5,6 +5,7 @@
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzFramework/Input/Devices/Keyboard/InputDeviceKeyboard.h>
#include <AzFramework/XcbEventHandler.h>

@ -29,6 +29,13 @@ namespace InputUnitTests
////////////////////////////////////////////////////////////////////////////////////////////////
class InputTest : public ScopedAllocatorSetupFixture
{
public:
InputTest() : ScopedAllocatorSetupFixture()
{
// Many input tests are only valid if the GamePad device is supported on this platform.
m_gamepadSupported = InputDeviceGamepad::GetMaxSupportedGamepads() > 0;
}
protected:
////////////////////////////////////////////////////////////////////////////////////////////
void SetUp() override
@ -46,6 +53,7 @@ namespace InputUnitTests
////////////////////////////////////////////////////////////////////////////////////////////
AZStd::unique_ptr<InputSystemComponent> m_inputSystemComponent;
bool m_gamepadSupported;
};
////////////////////////////////////////////////////////////////////////////////////////////////
@ -78,12 +86,17 @@ namespace InputUnitTests
}
////////////////////////////////////////////////////////////////////////////////////////////////
#if AZ_TRAIT_DISABLE_FAILED_INPUT_TESTS
TEST_F(InputTest, DISABLED_InputContext_ActivateDeactivate_Successfull)
#else
TEST_F(InputTest, InputContext_ActivateDeactivate_Successfull)
#endif // AZ_TRAIT_DISABLE_FAILED_INPUT_TESTS
{
if (!m_gamepadSupported)
{
#if defined(GTEST_SKIP)
GTEST_SKIP() << "Skipping test InputContext_ActivateDeactivate_Successfull";
#else
SUCCEED() << "Skipping test InputContext_ActivateDeactivate_Successfull";
#endif
return;
}
// Create an input context (they are inactive by default).
InputContext inputContext("TestInputContext");
@ -148,12 +161,18 @@ namespace InputUnitTests
}
////////////////////////////////////////////////////////////////////////////////////////////////
#if AZ_TRAIT_DISABLE_FAILED_INPUT_TESTS
TEST_F(InputTest, DISABLED_InputContext_AddRemoveInputMapping_Successfull)
#else
TEST_F(InputTest, InputContext_AddRemoveInputMapping_Successfull)
#endif // AZ_TRAIT_DISABLE_FAILED_INPUT_TESTS
{
if (!m_gamepadSupported)
{
#if defined(GTEST_SKIP)
GTEST_SKIP() << "Skipping test InputContext_AddRemoveInputMapping_Successfull";
#else
SUCCEED() << "Skipping test InputContext_AddRemoveInputMapping_Successfull";
#endif
return;
}
// Create an input context and activate it.
InputContext inputContext("TestInputContext");
inputContext.Activate();
@ -256,12 +275,18 @@ namespace InputUnitTests
}
////////////////////////////////////////////////////////////////////////////////////////////////
#if AZ_TRAIT_DISABLE_FAILED_INPUT_TESTS
TEST_F(InputTest, DISABLED_InputContext_ConsumeProcessedInput_Consumed)
#else
TEST_F(InputTest, InputContext_ConsumeProcessedInput_Consumed)
#endif // AZ_TRAIT_DISABLE_FAILED_INPUT_TESTS
{
if (!m_gamepadSupported)
{
#if defined(GTEST_SKIP)
GTEST_SKIP() << "Skipping test InputContext_ConsumeProcessedInput_Consumed";
#else
SUCCEED() << "Skipping test InputContext_ConsumeProcessedInput_Consumed";
#endif
return;
}
InputContext::InitData initData;
// Create a high priority input context that consumes input processed by any of its mappings.
@ -340,12 +365,18 @@ namespace InputUnitTests
}
////////////////////////////////////////////////////////////////////////////////////////////////
#if AZ_TRAIT_DISABLE_FAILED_INPUT_TESTS
TEST_F(InputTest, DISABLED_InputContext_FilteredInput_Mapped)
#else
TEST_F(InputTest, InputContext_FilteredInput_Mapped)
#endif // AZ_TRAIT_DISABLE_FAILED_INPUT_TESTS
{
if (!m_gamepadSupported)
{
#if defined(GTEST_SKIP)
GTEST_SKIP() << "Skipping test InputContext_FilteredInput_Mapped";
#else
SUCCEED() << "Skipping test InputContext_FilteredInput_Mapped";
#endif
return;
}
// Create an input context that initially only listens for keyboard input.
InputContext::InitData initData;
initData.autoActivate = true;
@ -413,12 +444,18 @@ namespace InputUnitTests
}
////////////////////////////////////////////////////////////////////////////////////////////////
#if AZ_TRAIT_DISABLE_FAILED_INPUT_TESTS
TEST_F(InputTest, DISABLED_InputMappingOr_AddRemoveSourceInput_Successful)
#else
TEST_F(InputTest, InputMappingOr_AddRemoveSourceInput_Successful)
#endif // AZ_TRAIT_DISABLE_FAILED_INPUT_TESTS
{
if (!m_gamepadSupported)
{
#if defined(GTEST_SKIP)
GTEST_SKIP() << "Skipping test InputMappingOr_AddRemoveSourceInput_Successful";
#else
SUCCEED() << "Skipping test InputMappingOr_AddRemoveSourceInput_Successful";
#endif
return;
}
// Create an input context and activate it.
InputContext inputContext("TestInputContext");
inputContext.Activate();
@ -491,12 +528,18 @@ namespace InputUnitTests
}
////////////////////////////////////////////////////////////////////////////////////////////////
#if AZ_TRAIT_DISABLE_FAILED_INPUT_TESTS
TEST_F(InputTest, DISABLED_InputMappingOr_SingleSourceInput_Mapped)
#else
TEST_F(InputTest, InputMappingOr_SingleSourceInput_Mapped)
#endif // AZ_TRAIT_DISABLE_FAILED_INPUT_TESTS
{
if (!m_gamepadSupported)
{
#if defined(GTEST_SKIP)
GTEST_SKIP() << "Skipping test InputMappingOr_SingleSourceInput_Mapped";
#else
SUCCEED() << "Skipping test InputMappingOr_SingleSourceInput_Mapped";
#endif
return;
}
// Create an input context and activate it.
InputContext inputContext("TestInputContext");
inputContext.Activate();
@ -558,12 +601,18 @@ namespace InputUnitTests
}
////////////////////////////////////////////////////////////////////////////////////////////////
#if AZ_TRAIT_DISABLE_FAILED_INPUT_TESTS
TEST_F(InputTest, DISABLED_InputMappingOr_MultipleSourceInputs_Mapped)
#else
TEST_F(InputTest, InputMappingOr_MultipleSourceInputs_Mapped)
#endif // AZ_TRAIT_DISABLE_FAILED_INPUT_TESTS
{
if (!m_gamepadSupported)
{
#if defined(GTEST_SKIP)
GTEST_SKIP() << "Skipping test InputMappingOr_MultipleSourceInputs_Mapped";
#else
SUCCEED() << "Skipping test InputMappingOr_MultipleSourceInputs_Mapped";
#endif
return;
}
// Create an input context and activate it.
InputContext inputContext("TestInputContext");
inputContext.Activate();
@ -650,12 +699,18 @@ namespace InputUnitTests
}
////////////////////////////////////////////////////////////////////////////////////////////////
#if AZ_TRAIT_DISABLE_FAILED_INPUT_TESTS
TEST_F(InputTest, DISABLED_InputMappingAnd_AddRemoveSourceInput_Successful)
#else
TEST_F(InputTest, InputMappingAnd_AddRemoveSourceInput_Successful)
#endif // AZ_TRAIT_DISABLE_FAILED_INPUT_TESTS
{
if (!m_gamepadSupported)
{
#if defined(GTEST_SKIP)
GTEST_SKIP() << "Skipping test InputMappingAnd_AddRemoveSourceInput_Successful";
#else
SUCCEED() << "Skipping test InputMappingAnd_AddRemoveSourceInput_Successful";
#endif
return;
}
// Create an input context and activate it.
InputContext inputContext("TestInputContext");
inputContext.Activate();
@ -728,12 +783,18 @@ namespace InputUnitTests
}
////////////////////////////////////////////////////////////////////////////////////////////////
#if AZ_TRAIT_DISABLE_FAILED_INPUT_TESTS
TEST_F(InputTest, DISABLED_InputMappingAnd_SingleSourceInput_Mapped)
#else
TEST_F(InputTest, InputMappingAnd_SingleSourceInput_Mapped)
#endif // AZ_TRAIT_DISABLE_FAILED_INPUT_TESTS
{
if (!m_gamepadSupported)
{
#if defined(GTEST_SKIP)
GTEST_SKIP() << "Skipping test InputMappingAnd_SingleSourceInput_Mapped";
#else
SUCCEED() << "Skipping test InputMappingAnd_SingleSourceInput_Mapped";
#endif
return;
}
// Create an input context and activate it.
InputContext inputContext("TestInputContext");
inputContext.Activate();
@ -795,12 +856,18 @@ namespace InputUnitTests
}
////////////////////////////////////////////////////////////////////////////////////////////////
#if AZ_TRAIT_DISABLE_FAILED_INPUT_TESTS
TEST_F(InputTest, DISABLED_InputMappingAnd_MultipleSourceInputs_Mapped)
#else
TEST_F(InputTest, InputMappingAnd_MultipleSourceInputs_Mapped)
#endif // AZ_TRAIT_DISABLE_FAILED_INPUT_TESTS
{
if (!m_gamepadSupported)
{
#if defined(GTEST_SKIP)
GTEST_SKIP() << "Skipping test InputMappingAnd_MultipleSourceInputs_Mapped";
#else
SUCCEED() << "Skipping test InputMappingAnd_MultipleSourceInputs_Mapped";
#endif
return;
}
// Create an input context and activate it.
InputContext inputContext("TestInputContext");
inputContext.Activate();
@ -909,12 +976,18 @@ namespace InputUnitTests
}
////////////////////////////////////////////////////////////////////////////////////////////////
#if AZ_TRAIT_DISABLE_FAILED_INPUT_TESTS
TEST_F(InputTest, DISABLED_InputMappingAnd_MultipleSourceInputsWithDifferentValues_ValuesAveraged)
#else
TEST_F(InputTest, InputMappingAnd_MultipleSourceInputsWithDifferentValues_ValuesAveraged)
#endif // AZ_TRAIT_DISABLE_FAILED_INPUT_TESTS
{
if (!m_gamepadSupported)
{
#if defined(GTEST_SKIP)
GTEST_SKIP() << "Skipping test InputMappingAnd_MultipleSourceInputsWithDifferentValues_ValuesAveraged";
#else
SUCCEED() << "Skipping test InputMappingAnd_MultipleSourceInputsWithDifferentValues_ValuesAveraged";
#endif
return;
}
// Create an input context and activate it.
InputContext inputContext("TestInputContext");
inputContext.Activate();
@ -969,12 +1042,18 @@ namespace InputUnitTests
}
////////////////////////////////////////////////////////////////////////////////////////////////
#if AZ_TRAIT_DISABLE_FAILED_INPUT_TESTS
TEST_F(InputTest, DISABLED_InputMappingAnd_MultipleSourceInputsFromTheSameInputDeviceTypeWithDifferentIndicies_NotMapped)
#else
TEST_F(InputTest, InputMappingAnd_MultipleSourceInputsFromTheSameInputDeviceTypeWithDifferentIndicies_NotMapped)
#endif // AZ_TRAIT_DISABLE_FAILED_INPUT_TESTS
{
if (!m_gamepadSupported)
{
#if defined(GTEST_SKIP)
GTEST_SKIP() << "Skipping test InputMappingAnd_MultipleSourceInputsFromTheSameInputDeviceTypeWithDifferentIndicies_NotMapped";
#else
SUCCEED() << "Skipping test InputMappingAnd_MultipleSourceInputsFromTheSameInputDeviceTypeWithDifferentIndicies_NotMapped";
#endif
return;
}
// Create an input context and activate it.
InputContext inputContext("TestInputContext");
inputContext.Activate();

@ -29,7 +29,8 @@ namespace UnitTest
void SetUpEditorFixtureImpl() override
{
ToolsApplicationFixtureT::SetUpEditorFixtureImpl();
m_viewportManipulatorInteraction = AZStd::make_unique<IndirectCallManipulatorViewportInteraction>();
m_viewportManipulatorInteraction =
AZStd::make_unique<IndirectCallManipulatorViewportInteraction>(ToolsApplicationFixtureT::CreateDebugDisplayRequests());
m_actionDispatcher = AZStd::make_unique<ImmediateModeActionDispatcher>(*m_viewportManipulatorInteraction);
m_cameraState =
AzFramework::CreateIdentityDefaultCamera(AZ::Vector3::CreateZero(), AzManipulatorTestFramework::DefaultViewportSize);

@ -17,11 +17,10 @@ namespace AzManipulatorTestFramework
class ViewportInteraction;
//! Implementation of manipulator viewport interaction that manipulates the manager directly.
class DirectCallManipulatorViewportInteraction
: public ManipulatorViewportInteraction
class DirectCallManipulatorViewportInteraction : public ManipulatorViewportInteraction
{
public:
DirectCallManipulatorViewportInteraction();
explicit DirectCallManipulatorViewportInteraction(AZStd::shared_ptr<AzFramework::DebugDisplayRequests> debugDisplayRequests);
~DirectCallManipulatorViewportInteraction();
// ManipulatorViewportInteractionInterface ...

@ -21,7 +21,7 @@ namespace AzManipulatorTestFramework
class IndirectCallManipulatorViewportInteraction : public ManipulatorViewportInteraction
{
public:
IndirectCallManipulatorViewportInteraction();
explicit IndirectCallManipulatorViewportInteraction(AZStd::shared_ptr<AzFramework::DebugDisplayRequests> debugDisplayRequests);
~IndirectCallManipulatorViewportInteraction();
// ManipulatorViewportInteractionInterface ...

@ -11,10 +11,13 @@
#include <AzFramework/Visibility/EntityVisibilityQuery.h>
#include <AzManipulatorTestFramework/AzManipulatorTestFramework.h>
namespace AzManipulatorTestFramework
namespace AzFramework
{
class NullDebugDisplayRequests;
class DebugDisplayRequests;
}
namespace AzManipulatorTestFramework
{
//! Implementation of the viewport interaction model to handle viewport interaction requests.
class ViewportInteraction
: public ViewportInteractionInterface
@ -23,7 +26,7 @@ namespace AzManipulatorTestFramework
, private AzToolsFramework::ViewportInteraction::EditorEntityViewportInteractionRequestBus::Handler
{
public:
ViewportInteraction();
explicit ViewportInteraction(AZStd::shared_ptr<AzFramework::DebugDisplayRequests> debugDisplayRequests);
~ViewportInteraction();
// ViewportInteractionInterface overrides ...
@ -63,7 +66,7 @@ namespace AzManipulatorTestFramework
static constexpr AzFramework::ViewportId m_viewportId = 1234; //!< Arbitrary viewport id for manipulator tests.
AzFramework::EntityVisibilityQuery m_entityVisibilityQuery;
AZStd::unique_ptr<NullDebugDisplayRequests> m_nullDebugDisplayRequests;
AZStd::shared_ptr<AzFramework::DebugDisplayRequests> m_debugDisplayRequests;
AzFramework::CameraState m_cameraState;
bool m_gridSnapping = false;
bool m_angularSnapping = false;

@ -118,10 +118,11 @@ namespace AzManipulatorTestFramework
return m_manipulatorManager->Interacting();
}
DirectCallManipulatorViewportInteraction::DirectCallManipulatorViewportInteraction()
DirectCallManipulatorViewportInteraction::DirectCallManipulatorViewportInteraction(
AZStd::shared_ptr<AzFramework::DebugDisplayRequests> debugDisplayRequests)
: m_customManager(
AZStd::make_unique<CustomManipulatorManager>(AzToolsFramework::ManipulatorManagerId(AZ::Crc32("TestManipulatorManagerId"))))
, m_viewportInteraction(AZStd::make_unique<ViewportInteraction>())
, m_viewportInteraction(AZStd::make_unique<ViewportInteraction>(AZStd::move(debugDisplayRequests)))
, m_manipulatorManager(AZStd::make_unique<DirectCallManipulatorManager>(m_viewportInteraction.get(), m_customManager))
{
}

@ -76,8 +76,9 @@ namespace AzManipulatorTestFramework
return manipulatorInteracting;
}
IndirectCallManipulatorViewportInteraction::IndirectCallManipulatorViewportInteraction()
: m_viewportInteraction(AZStd::make_unique<ViewportInteraction>())
IndirectCallManipulatorViewportInteraction::IndirectCallManipulatorViewportInteraction(
AZStd::shared_ptr<AzFramework::DebugDisplayRequests> debugDisplayRequests)
: m_viewportInteraction(AZStd::make_unique<ViewportInteraction>(AZStd::move(debugDisplayRequests)))
, m_manipulatorManager(AZStd::make_unique<IndirectCallManipulatorManager>(*m_viewportInteraction))
{
}

@ -13,15 +13,8 @@
namespace AzManipulatorTestFramework
{
// Null debug display for dummy draw calls
class NullDebugDisplayRequests : public AzFramework::DebugDisplayRequests
{
public:
virtual ~NullDebugDisplayRequests() = default;
};
ViewportInteraction::ViewportInteraction()
: m_nullDebugDisplayRequests(AZStd::make_unique<NullDebugDisplayRequests>())
ViewportInteraction::ViewportInteraction(AZStd::shared_ptr<AzFramework::DebugDisplayRequests> debugDisplayRequests)
: m_debugDisplayRequests(AZStd::move(debugDisplayRequests))
{
AzToolsFramework::ViewportInteraction::ViewportInteractionRequestBus::Handler::BusConnect(m_viewportId);
AzToolsFramework::ViewportInteraction::ViewportSettingsRequestBus::Handler::BusConnect(m_viewportId);
@ -102,7 +95,7 @@ namespace AzManipulatorTestFramework
AzFramework::DebugDisplayRequests& ViewportInteraction::GetDebugDisplay()
{
return *m_nullDebugDisplayRequests;
return *m_debugDisplayRequests;
}
void ViewportInteraction::SetGridSnapping(const bool enabled)

@ -26,7 +26,8 @@ namespace UnitTest
{
public:
GridSnappingFixture()
: m_viewportManipulatorInteraction(AZStd::make_unique<AzManipulatorTestFramework::DirectCallManipulatorViewportInteraction>())
: m_viewportManipulatorInteraction(AZStd::make_unique<AzManipulatorTestFramework::DirectCallManipulatorViewportInteraction>(
AZStd::make_shared<NullDebugDisplayRequests>()))
, m_actionDispatcher(
AZStd::make_unique<AzManipulatorTestFramework::ImmediateModeActionDispatcher>(*m_viewportManipulatorInteraction))
{

@ -15,7 +15,8 @@ namespace UnitTest
{
public:
AValidViewportInteraction()
: m_viewportInteraction(AZStd::make_unique<AzManipulatorTestFramework::ViewportInteraction>())
: m_viewportInteraction(
AZStd::make_unique<AzManipulatorTestFramework::ViewportInteraction>(AZStd::make_shared<NullDebugDisplayRequests>()))
{
}

@ -75,9 +75,11 @@ namespace UnitTest
void SetUpEditorFixtureImpl() override
{
m_directState =
AZStd::make_unique<State>(AZStd::make_unique<AzManipulatorTestFramework::DirectCallManipulatorViewportInteraction>());
AZStd::make_unique<State>(AZStd::make_unique<AzManipulatorTestFramework::DirectCallManipulatorViewportInteraction>(
AZStd::make_shared<NullDebugDisplayRequests>()));
m_busState =
AZStd::make_unique<State>(AZStd::make_unique<AzManipulatorTestFramework::IndirectCallManipulatorViewportInteraction>());
AZStd::make_unique<State>(AZStd::make_unique<AzManipulatorTestFramework::IndirectCallManipulatorViewportInteraction>(
AZStd::make_shared<NullDebugDisplayRequests>()));
m_cameraState =
AzFramework::CreateIdentityDefaultCamera(AZ::Vector3::CreateZero(), AzManipulatorTestFramework::DefaultViewportSize);
}

@ -14,7 +14,6 @@
#define AZ_TRAIT_UNIT_TEST_DILLER_TRIGGER_EVENT_COUNT 100000
#define AZ_TRAIT_DISABLE_FAILED_AP_CONNECTION_TESTS true
#define AZ_TRAIT_DISABLE_FAILED_ASSET_LOAD_TESTS true
#define AZ_TRAIT_DISABLE_FAILED_ATOM_RPI_TESTS true
#define AZ_TRAIT_DISABLE_FAILED_ARCHIVE_TESTS true
@ -23,7 +22,6 @@
#define AZ_TRAIT_DISABLE_FAILED_FRAMEWORK_TESTS true
#define AZ_TRAIT_DISABLE_FAILED_GRADIENT_SIGNAL_TESTS true
#define AZ_TRAIT_DISABLE_FAILED_MULTIPLAYER_GRIDMATE_TESTS true
#define AZ_TRAIT_DISABLE_FAILED_INPUT_TESTS true
#define AZ_TRAIT_DISABLE_FAILED_NATIVE_WINDOWS_TESTS true
#define AZ_TRAIT_DISABLE_FAILED_PROCESS_LAUNCHER_TESTS true
#define AZ_TRAIT_DISABLE_FAILED_EMOTION_FX_TESTS true

@ -52,7 +52,7 @@ namespace AzToolsFramework
void ReadOnlyEntitySystemComponent::RefreshReadOnlyState(const EntityIdList& entityIds)
{
for (const AZ::EntityId entityId : entityIds)
for (const AZ::EntityId& entityId : entityIds)
{
bool wasReadOnly = m_readOnlystates[entityId];
QueryReadOnlyStateForEntity(entityId);
@ -67,10 +67,10 @@ namespace AzToolsFramework
void ReadOnlyEntitySystemComponent::RefreshReadOnlyStateForAllEntities()
{
for (auto elem : m_readOnlystates)
for (auto& elem : m_readOnlystates)
{
AZ::EntityId entityId = elem.first;
bool wasReadOnly = m_readOnlystates[entityId];
bool wasReadOnly = elem.second;
QueryReadOnlyStateForEntity(entityId);
if (bool isReadOnly = m_readOnlystates[entityId]; wasReadOnly != isReadOnly)

@ -50,7 +50,7 @@ namespace AzToolsFramework
return false;
}
void TraceLogger::PrepareLogFile(const AZStd::string& logFileName)
void TraceLogger::OpenLogFile(const AZStd::string& logFileName, bool clearLogFile)
{
using namespace AzFramework;
@ -73,7 +73,7 @@ namespace AzToolsFramework
AZStd::string logPath;
StringFunc::Path::Join(logDirectory.c_str(), logFileName.c_str(), logPath);
m_logFile.reset(aznew LogFile(logPath.c_str()));
m_logFile.reset(aznew LogFile(logPath.c_str(), clearLogFile));
if (m_logFile)
{
m_logFile->SetMachineReadable(false);
@ -81,7 +81,7 @@ namespace AzToolsFramework
{
m_logFile->AppendLog(LogFile::SEV_NORMAL, message.window.c_str(), message.message.c_str());
}
m_startupLogSink = {};
m_startupLogSink.clear();
m_logFile->FlushLog();
}
}

@ -23,7 +23,7 @@ namespace AzToolsFramework
~TraceLogger();
//! Open log file and dump log sink into it
void PrepareLogFile(const AZStd::string& logFileName);
void OpenLogFile(const AZStd::string& logFileName, bool clearLogFile);
//! Add filter to ignore messages for windows with matching names
void AddWindowFilter(const AZStd::string& filter);
@ -55,7 +55,8 @@ namespace AzToolsFramework
AZStd::string window;
AZStd::string message;
};
AZStd::vector<LogMessage> m_startupLogSink;
AZStd::list<LogMessage> m_startupLogSink;
AZStd::unordered_set<AZStd::string> m_windowFilters;
AZStd::unordered_set<AZStd::string> m_messageFilters;
AZStd::unique_ptr<AzFramework::LogFile> m_logFile;

@ -191,8 +191,8 @@ namespace AzToolsFramework
{
m_manipulatorView->Draw(
GetManipulatorManagerId(), managerState, GetManipulatorId(),
{ ApplySpace(GetLocalTransform()), GetNonUniformScale(), AZ::Vector3::CreateZero(), MouseOver() }, debugDisplay, cameraState,
mouseInteraction);
ManipulatorState{ ApplySpace(GetLocalTransform()), GetNonUniformScale(), AZ::Vector3::CreateZero(), MouseOver() }, debugDisplay,
cameraState, mouseInteraction);
}
void AngularManipulator::SetAxis(const AZ::Vector3& axis)

@ -14,7 +14,7 @@
namespace AzToolsFramework
{
AZ_CVAR(bool, cl_manipulatorDrawDebug, false, nullptr, AZ::ConsoleFunctorFlags::Null, "Enable debug drawing for Manipulators");
AZ_CVAR(bool, ed_manipulatorDrawDebug, false, nullptr, AZ::ConsoleFunctorFlags::Null, "Enable debug drawing for Manipulators");
const AZ::Color BaseManipulator::s_defaultMouseOverColor = AZ::Color(1.0f, 1.0f, 0.0f, 1.0f); // yellow

@ -28,7 +28,7 @@ namespace AzFramework
namespace AzToolsFramework
{
AZ_CVAR_EXTERNED(bool, cl_manipulatorDrawDebug);
AZ_CVAR_EXTERNED(bool, ed_manipulatorDrawDebug);
namespace UndoSystem
{

@ -116,8 +116,8 @@ namespace AzToolsFramework
{
m_manipulatorView->Draw(
GetManipulatorManagerId(), managerState, GetManipulatorId(),
{ TransformUniformScale(GetSpace()), GetNonUniformScale(), m_localStart, MouseOver() }, debugDisplay, cameraState,
mouseInteraction);
ManipulatorState{ TransformUniformScale(GetSpace()), GetNonUniformScale(), m_localStart, MouseOver() }, debugDisplay,
cameraState, mouseInteraction);
}
}

@ -207,7 +207,7 @@ namespace AzToolsFramework
? AZ::Transform::CreateFromQuaternionAndTranslation(m_visualOrientationOverride, GetLocalPosition())
: GetLocalTransform();
if (cl_manipulatorDrawDebug)
if (ed_manipulatorDrawDebug)
{
if (PerformingAction())
{
@ -239,8 +239,8 @@ namespace AzToolsFramework
view->Draw(
GetManipulatorManagerId(), managerState, GetManipulatorId(),
{ ApplySpace(localTransform), GetNonUniformScale(), AZ::Vector3::CreateZero(), MouseOver() }, debugDisplay, cameraState,
mouseInteraction);
ManipulatorState{ ApplySpace(localTransform), GetNonUniformScale(), AZ::Vector3::CreateZero(), MouseOver() }, debugDisplay,
cameraState, mouseInteraction);
}
}

@ -146,7 +146,7 @@ namespace AzToolsFramework
for (const auto& pair : m_manipulatorIdToPtrMap)
{
pair.second->Draw({ Interacting() }, debugDisplay, cameraState, mouseInteraction);
pair.second->Draw(ManipulatorManagerState{ Interacting() }, debugDisplay, cameraState, mouseInteraction);
}
RefreshMouseOverState(mouseInteraction.m_mousePick);

@ -10,6 +10,15 @@
namespace AzToolsFramework
{
AZ::Transform ApplySpace(const AZ::Transform& localTransform, const AZ::Transform& space, const AZ::Vector3& nonUniformScale)
{
AZ::Transform result;
result.SetRotation(space.GetRotation() * localTransform.GetRotation());
result.SetTranslation(space.TransformPoint(nonUniformScale * localTransform.GetTranslation()));
result.SetUniformScale(space.GetUniformScale() * localTransform.GetUniformScale());
return result;
}
const AZ::Transform& ManipulatorSpace::GetSpace() const
{
return m_space;
@ -32,11 +41,7 @@ namespace AzToolsFramework
AZ::Transform ManipulatorSpace::ApplySpace(const AZ::Transform& localTransform) const
{
AZ::Transform result;
result.SetRotation(m_space.GetRotation() * localTransform.GetRotation());
result.SetTranslation(m_space.TransformPoint(m_nonUniformScale * localTransform.GetTranslation()));
result.SetUniformScale(m_space.GetUniformScale() * localTransform.GetUniformScale());
return result;
return AzToolsFramework::ApplySpace(localTransform, m_space, m_nonUniformScale);
}
const AZ::Vector3& ManipulatorSpaceWithLocalPosition::GetLocalPosition() const

@ -17,6 +17,8 @@ namespace AZ
namespace AzToolsFramework
{
AZ::Transform ApplySpace(const AZ::Transform& localTransform, const AZ::Transform& space, const AZ::Vector3& nonUniformScale);
//! Handles location for manipulators which have a global space but no local transformation.
class ManipulatorSpace
{

@ -21,6 +21,7 @@
#include <AzToolsFramework/Manipulators/PlanarManipulator.h>
#include <AzToolsFramework/Manipulators/SplineSelectionManipulator.h>
#include <AzToolsFramework/Maths/TransformUtils.h>
#include <AzToolsFramework/Viewport/ViewportSettings.h>
#include <AzToolsFramework/ViewportSelection/EditorSelectionUtil.h>
AZ_CVAR(
@ -30,6 +31,13 @@ AZ_CVAR(
nullptr,
AZ::ConsoleFunctorFlags::Null,
"Display additional debug drawing for manipulator bounds");
AZ_CVAR(
float,
ed_planarManipulatorBoundScaleFactor,
1.75f,
nullptr,
AZ::ConsoleFunctorFlags::Null,
"The scale factor to apply to the planar manipulator bounds");
namespace AzToolsFramework
{
@ -78,7 +86,8 @@ namespace AzToolsFramework
{
// check if we actually needed to flip the axis, if so, write to shouldCorrect
// so we know and are able to draw it differently if we wish (e.g. hollow if flipped)
const bool correcting = ShouldFlipCameraAxis(worldFromLocal, localPosition, axis, cameraState);
const bool correcting =
FlipManipulatorAxesTowardsView() && ShouldFlipCameraAxis(worldFromLocal, localPosition, axis, cameraState);
// the corrected axis, if no flip was required, output == input
correctedAxis = correcting ? -axis : axis;
@ -325,7 +334,8 @@ namespace AzToolsFramework
float ManipulatorView::ManipulatorViewScaleMultiplier(
const AZ::Vector3& worldPosition, const AzFramework::CameraState& cameraState) const
{
return ScreenSizeFixed() ? CalculateScreenToWorldMultiplier(worldPosition, cameraState) : 1.0f;
const float screenScale = ScreenSizeFixed() ? CalculateScreenToWorldMultiplier(worldPosition, cameraState) : 1.0f;
return screenScale * ManipulatorViewBaseScale();
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -342,47 +352,77 @@ namespace AzToolsFramework
const AZ::Vector3 axis1 = m_axis1;
const AZ::Vector3 axis2 = m_axis2;
CameraCorrectAxis(
axis1, m_cameraCorrectedAxis1, managerState, mouseInteraction, manipulatorState.m_worldFromLocal,
manipulatorState.m_localPosition, cameraState);
CameraCorrectAxis(
axis2, m_cameraCorrectedAxis2, managerState, mouseInteraction, manipulatorState.m_worldFromLocal,
manipulatorState.m_localPosition, cameraState);
// support partial application of CameraCorrectAxis to reduce redundant call site parameters
auto cameraCorrectAxisPartialFn =
[&manipulatorState, &managerState, &mouseInteraction, &cameraState](const AZ::Vector3& inAxis, AZ::Vector3& outAxis)
{
CameraCorrectAxis(
inAxis, outAxis, managerState, mouseInteraction, manipulatorState.m_worldFromLocal, manipulatorState.m_localPosition,
cameraState);
};
const Picking::BoundShapeQuad quadBound = CalculateQuadBound(
manipulatorState.m_localPosition, manipulatorState, m_cameraCorrectedAxis1, m_cameraCorrectedAxis2,
m_size *
ManipulatorViewScaleMultiplier(
manipulatorState.m_worldFromLocal.TransformPoint(manipulatorState.m_localPosition), cameraState));
cameraCorrectAxisPartialFn(axis1, m_cameraCorrectedAxis1);
cameraCorrectAxisPartialFn(axis2, m_cameraCorrectedAxis2);
cameraCorrectAxisPartialFn(axis1 * axis1.Dot(m_offset), m_cameraCorrectedOffsetAxis1);
cameraCorrectAxisPartialFn(axis2 * axis2.Dot(m_offset), m_cameraCorrectedOffsetAxis2);
const AZ::Vector3 totalScale =
manipulatorState.m_nonUniformScale * AZ::Vector3(manipulatorState.m_worldFromLocal.GetUniformScale());
const auto cameraCorrectedVisualOffset = (m_cameraCorrectedOffsetAxis1 + m_cameraCorrectedOffsetAxis2) * totalScale.GetReciprocal();
const auto viewScale =
ManipulatorViewScaleMultiplier(manipulatorState.m_worldFromLocal.TransformPoint(manipulatorState.m_localPosition), cameraState);
const Picking::BoundShapeQuad quadBoundVisual = CalculateQuadBound(
manipulatorState.m_localPosition + (cameraCorrectedVisualOffset * viewScale), manipulatorState, m_cameraCorrectedAxis1,
m_cameraCorrectedAxis2, m_size * viewScale);
debugDisplay.SetLineWidth(defaultLineWidth(manipulatorState.m_mouseOver));
debugDisplay.SetColor(ViewColor(manipulatorState.m_mouseOver, m_axis1Color, m_mouseOverColor).GetAsVector4());
debugDisplay.DrawLine(quadBound.m_corner4, quadBound.m_corner3);
debugDisplay.DrawLine(quadBoundVisual.m_corner4, quadBoundVisual.m_corner3);
debugDisplay.DrawLine(quadBoundVisual.m_corner1, quadBoundVisual.m_corner2);
debugDisplay.SetColor(ViewColor(manipulatorState.m_mouseOver, m_axis2Color, m_mouseOverColor).GetAsVector4());
debugDisplay.DrawLine(quadBound.m_corner2, quadBound.m_corner3);
debugDisplay.DrawLine(quadBoundVisual.m_corner4, quadBoundVisual.m_corner1);
debugDisplay.DrawLine(quadBoundVisual.m_corner2, quadBoundVisual.m_corner3);
if (manipulatorState.m_mouseOver)
{
debugDisplay.SetColor(Vector3ToVector4(m_mouseOverColor.GetAsVector3(), 0.5f));
debugDisplay.CullOff();
debugDisplay.DrawQuad(quadBound.m_corner1, quadBound.m_corner2, quadBound.m_corner3, quadBound.m_corner4);
debugDisplay.DrawQuad(
quadBoundVisual.m_corner1, quadBoundVisual.m_corner2, quadBoundVisual.m_corner3, quadBoundVisual.m_corner4);
debugDisplay.CullOn();
}
RefreshBoundInternal(managerId, manipulatorId, quadBound);
// total size of bounds to use for mouse intersection
const float hitSize = m_size * ed_planarManipulatorBoundScaleFactor;
// size of edge bounds (the 'margin/border' outside the visual representation)
const float edgeSize = (hitSize - m_size) * 0.5f;
const AZ::Vector3 edgeOffset =
((m_cameraCorrectedAxis1 * edgeSize + m_cameraCorrectedAxis2 * edgeSize) * totalScale.GetReciprocal());
const auto cameraCorrectedHitOffset = cameraCorrectedVisualOffset - edgeOffset;
const Picking::BoundShapeQuad quadBoundHit = CalculateQuadBound(
manipulatorState.m_localPosition + (cameraCorrectedHitOffset * viewScale), manipulatorState, m_cameraCorrectedAxis1,
m_cameraCorrectedAxis2, hitSize * viewScale);
if (ed_manipulatorDisplayBoundDebug)
{
debugDisplay.DrawQuad(quadBoundHit.m_corner1, quadBoundHit.m_corner2, quadBoundHit.m_corner3, quadBoundHit.m_corner4);
}
RefreshBoundInternal(managerId, manipulatorId, quadBoundHit);
}
void ManipulatorViewQuadBillboard::Draw(
const ManipulatorManagerId managerId,
const ManipulatorManagerState& /*managerState*/,
[[maybe_unused]] const ManipulatorManagerState& managerState,
const ManipulatorId manipulatorId,
const ManipulatorState& manipulatorState,
AzFramework::DebugDisplayRequests& debugDisplay,
const AzFramework::CameraState& cameraState,
const ViewportInteraction::MouseInteraction& /*mouseInteraction*/)
[[maybe_unused]] const ViewportInteraction::MouseInteraction& mouseInteraction)
{
const Picking::BoundShapeQuad quadBound = CalculateQuadBoundBillboard(
manipulatorState.m_localPosition, manipulatorState.m_worldFromLocal,
@ -442,7 +482,7 @@ namespace AzToolsFramework
void ManipulatorViewLineSelect::Draw(
const ManipulatorManagerId managerId,
const ManipulatorManagerState& /*managerState*/,
[[maybe_unused]] const ManipulatorManagerState& managerState,
const ManipulatorId manipulatorId,
const ManipulatorState& manipulatorState,
AzFramework::DebugDisplayRequests& debugDisplay,
@ -570,7 +610,7 @@ namespace AzToolsFramework
void ManipulatorViewSphere::Draw(
const ManipulatorManagerId managerId,
const ManipulatorManagerState& /*managerState*/,
[[maybe_unused]] const ManipulatorManagerState& managerState,
const ManipulatorId manipulatorId,
const ManipulatorState& manipulatorState,
AzFramework::DebugDisplayRequests& debugDisplay,
@ -599,12 +639,12 @@ namespace AzToolsFramework
void ManipulatorViewCircle::Draw(
const ManipulatorManagerId managerId,
const ManipulatorManagerState& /*managerState*/,
[[maybe_unused]] const ManipulatorManagerState& managerState,
const ManipulatorId manipulatorId,
const ManipulatorState& manipulatorState,
AzFramework::DebugDisplayRequests& debugDisplay,
const AzFramework::CameraState& cameraState,
const ViewportInteraction::MouseInteraction& /*mouseInteraction*/)
[[maybe_unused]] const ViewportInteraction::MouseInteraction& mouseInteraction)
{
const float viewScale =
ManipulatorViewScaleMultiplier(manipulatorState.m_worldFromLocal.TransformPoint(manipulatorState.m_localPosition), cameraState);
@ -665,7 +705,7 @@ namespace AzToolsFramework
void ManipulatorViewSplineSelect::Draw(
const ManipulatorManagerId managerId,
const ManipulatorManagerState& /*managerState*/,
[[maybe_unused]] const ManipulatorManagerState& managerState,
const ManipulatorId manipulatorId,
const ManipulatorState& manipulatorState,
AzFramework::DebugDisplayRequests& debugDisplay,
@ -698,12 +738,18 @@ namespace AzToolsFramework
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
AZStd::unique_ptr<ManipulatorViewQuad> CreateManipulatorViewQuad(
const PlanarManipulator& planarManipulator, const AZ::Color& axis1Color, const AZ::Color& axis2Color, const float size)
const AZ::Vector3& axis1,
const AZ::Vector3& axis2,
const AZ::Color& axis1Color,
const AZ::Color& axis2Color,
const AZ::Vector3& offset,
const float size)
{
AZStd::unique_ptr<ManipulatorViewQuad> viewQuad = AZStd::make_unique<ManipulatorViewQuad>();
viewQuad->m_axis1 = planarManipulator.GetAxis1();
viewQuad->m_axis2 = planarManipulator.GetAxis2();
viewQuad->m_axis1 = axis1;
viewQuad->m_axis2 = axis2;
viewQuad->m_size = size;
viewQuad->m_offset = offset;
viewQuad->m_axis1Color = axis1Color;
viewQuad->m_axis2Color = axis2Color;
return viewQuad;

@ -54,7 +54,7 @@ namespace AzToolsFramework
AZ_RTTI(ManipulatorView, "{7529E3E9-39B3-4D15-899A-FA13770113B2}")
ManipulatorView();
ManipulatorView(bool screenSizeFixed);
explicit ManipulatorView(bool screenSizeFixed);
virtual ~ManipulatorView();
ManipulatorView(ManipulatorView&&) = default;
ManipulatorView& operator=(ManipulatorView&&) = default;
@ -117,13 +117,16 @@ namespace AzToolsFramework
AZ::Vector3 m_axis1 = AZ::Vector3(1.0f, 0.0f, 0.0f);
AZ::Vector3 m_axis2 = AZ::Vector3(0.0f, 1.0f, 0.0f);
AZ::Vector3 m_offset = AZ::Vector3::CreateZero();
AZ::Color m_axis1Color = AZ::Color(1.0f, 0.0f, 0.0f, 1.0f);
AZ::Color m_axis2Color = AZ::Color(1.0f, 0.0f, 0.0f, 1.0f);
float m_size = 0.06f; //!< size to render and do mouse ray intersection tests against.
private:
AZ::Vector3 m_cameraCorrectedAxis1;
AZ::Vector3 m_cameraCorrectedAxis2;
AZ::Vector3 m_cameraCorrectedAxis1; //!< First axis of quad (should be orthogonal to second axis).
AZ::Vector3 m_cameraCorrectedAxis2; //!< Second axis of quad (should be orthogonal to first axis).
AZ::Vector3 m_cameraCorrectedOffsetAxis1; //!< Offset along first axis (parallel with first axis).
AZ::Vector3 m_cameraCorrectedOffsetAxis2; //!< Offset along second axis (parallel with second axis).
};
//! A screen aligned quad, centered at the position of the manipulator, display filled.
@ -379,7 +382,12 @@ namespace AzToolsFramework
// Helpers to create various manipulator views.
AZStd::unique_ptr<ManipulatorViewQuad> CreateManipulatorViewQuad(
const PlanarManipulator& planarManipulator, const AZ::Color& axis1Color, const AZ::Color& axis2Color, float size);
const AZ::Vector3& axis1,
const AZ::Vector3& axis2,
const AZ::Color& axis1Color,
const AZ::Color& axis2Color,
const AZ::Vector3& offset,
float size);
AZStd::unique_ptr<ManipulatorViewQuadBillboard> CreateManipulatorViewQuadBillboard(const AZ::Color& color, float size);

@ -132,7 +132,7 @@ namespace AzToolsFramework
const AzFramework::CameraState& cameraState,
const ViewportInteraction::MouseInteraction& mouseInteraction)
{
if (cl_manipulatorDrawDebug)
if (ed_manipulatorDrawDebug)
{
const AZ::Transform combined = TransformUniformScale(GetSpace()) * GetLocalTransform();
for (const auto& fixed : m_fixedAxes)
@ -145,8 +145,8 @@ namespace AzToolsFramework
{
view->Draw(
GetManipulatorManagerId(), managerState, GetManipulatorId(),
{ ApplySpace(GetLocalTransform()), GetNonUniformScale(), AZ::Vector3::CreateZero(), MouseOver() }, debugDisplay,
cameraState, mouseInteraction);
ManipulatorState{ ApplySpace(GetLocalTransform()), GetNonUniformScale(), AZ::Vector3::CreateZero(), MouseOver() },
debugDisplay, cameraState, mouseInteraction);
}
}

@ -171,7 +171,7 @@ namespace AzToolsFramework
const AzFramework::CameraState& cameraState,
const ViewportInteraction::MouseInteraction& mouseInteraction)
{
if (cl_manipulatorDrawDebug)
if (ed_manipulatorDrawDebug)
{
if (PerformingAction())
{
@ -202,8 +202,8 @@ namespace AzToolsFramework
{
view->Draw(
GetManipulatorManagerId(), managerState, GetManipulatorId(),
{ ApplySpace(GetLocalTransform()), GetNonUniformScale(), AZ::Vector3::CreateZero(), MouseOver() }, debugDisplay,
cameraState, mouseInteraction);
ManipulatorState{ ApplySpace(GetLocalTransform()), GetNonUniformScale(), AZ::Vector3::CreateZero(), MouseOver() },
debugDisplay, cameraState, mouseInteraction);
}
}

@ -9,6 +9,7 @@
#include "ScaleManipulators.h"
#include <AzToolsFramework/Maths/TransformUtils.h>
#include <AzToolsFramework/Viewport/ViewportSettings.h>
namespace AzToolsFramework
{
@ -120,25 +121,25 @@ namespace AzToolsFramework
void ScaleManipulators::ConfigureView(
const float axisLength, const AZ::Color& axis1Color, const AZ::Color& axis2Color, const AZ::Color& axis3Color)
{
const float boxSize = 0.1f;
const float boxHalfExtent = ScaleManipulatorBoxHalfExtent();
const AZ::Color colors[] = { axis1Color, axis2Color, axis3Color };
for (size_t manipulatorIndex = 0; manipulatorIndex < m_axisScaleManipulators.size(); ++manipulatorIndex)
{
const auto lineLength = axisLength - boxSize;
const auto lineLength = axisLength - (2.0f * boxHalfExtent);
ManipulatorViews views;
views.emplace_back(
CreateManipulatorViewLine(*m_axisScaleManipulators[manipulatorIndex], colors[manipulatorIndex], axisLength, m_lineBoundWidth));
views.emplace_back(CreateManipulatorViewLine(
*m_axisScaleManipulators[manipulatorIndex], colors[manipulatorIndex], axisLength, m_lineBoundWidth));
views.emplace_back(CreateManipulatorViewBox(
AZ::Transform::CreateIdentity(), colors[manipulatorIndex],
m_axisScaleManipulators[manipulatorIndex]->GetAxis() * lineLength, AZ::Vector3(boxSize)));
m_axisScaleManipulators[manipulatorIndex]->GetAxis() * (lineLength + boxHalfExtent), AZ::Vector3(boxHalfExtent)));
m_axisScaleManipulators[manipulatorIndex]->SetViews(AZStd::move(views));
}
ManipulatorViews views;
views.emplace_back(CreateManipulatorViewBox(
AZ::Transform::CreateIdentity(), AZ::Color::CreateOne(), AZ::Vector3::CreateZero(), AZ::Vector3(boxSize)));
AZ::Transform::CreateIdentity(), AZ::Color::CreateOne(), AZ::Vector3::CreateZero(), AZ::Vector3(boxHalfExtent)));
m_uniformScaleManipulator->SetViews(AZStd::move(views));
}

@ -90,8 +90,8 @@ namespace AzToolsFramework
{
view->Draw(
GetManipulatorManagerId(), managerState, GetManipulatorId(),
{ TransformUniformScale(GetSpace()), GetNonUniformScale(), GetLocalPosition(), MouseOver() }, debugDisplay, cameraState,
mouseInteraction);
ManipulatorState{ TransformUniformScale(GetSpace()), GetNonUniformScale(), GetLocalPosition(), MouseOver() }, debugDisplay,
cameraState, mouseInteraction);
}
}

@ -94,8 +94,8 @@ namespace AzToolsFramework
{
m_manipulatorView->Draw(
GetManipulatorManagerId(), managerState, GetManipulatorId(),
{ TransformUniformScale(GetSpace()), GetNonUniformScale(), AZ::Vector3::CreateZero(), MouseOver() }, debugDisplay,
cameraState, mouseInteraction);
ManipulatorState{ TransformUniformScale(GetSpace()), GetNonUniformScale(), AZ::Vector3::CreateZero(), MouseOver() },
debugDisplay, cameraState, mouseInteraction);
}
}

@ -166,8 +166,8 @@ namespace AzToolsFramework
{
m_manipulatorView->Draw(
GetManipulatorManagerId(), managerState, GetManipulatorId(),
{ TransformUniformScale(GetSpace()), GetNonUniformScale(), GetLocalPosition(), MouseOver() }, debugDisplay, cameraState,
mouseInteraction);
ManipulatorState{ TransformUniformScale(GetSpace()), GetNonUniformScale(), GetLocalPosition(), MouseOver() }, debugDisplay,
cameraState, mouseInteraction);
}
void SurfaceManipulator::InvalidateImpl()

@ -10,18 +10,30 @@
#include <AzCore/Math/VectorConversions.h>
#include <AzToolsFramework/Manipulators/ManipulatorView.h>
#include <AzToolsFramework/Viewport/ViewportSettings.h>
namespace AzToolsFramework
{
static const float SurfaceManipulatorTransparency = 0.75f;
static const float LinearManipulatorAxisLength = 2.0f;
static const float SurfaceManipulatorRadius = 0.1f;
static const AZ::Color LinearManipulatorXAxisColor = AZ::Color(1.0f, 0.0f, 0.0f, 1.0f);
static const AZ::Color LinearManipulatorYAxisColor = AZ::Color(0.0f, 1.0f, 0.0f, 1.0f);
static const AZ::Color LinearManipulatorZAxisColor = AZ::Color(0.0f, 0.0f, 1.0f, 1.0f);
static const AZ::Color SurfaceManipulatorColor = AZ::Color(1.0f, 1.0f, 0.0f, 0.5f);
static TranslationManipulatorsViewCreateInfo DefaultTranslationManipulatorViewCreateInfo()
{
TranslationManipulatorsViewCreateInfo createInfo;
createInfo.axis1Color = LinearManipulatorXAxisColor;
createInfo.axis2Color = LinearManipulatorYAxisColor;
createInfo.axis3Color = LinearManipulatorZAxisColor;
createInfo.surfaceColor = SurfaceManipulatorColor;
createInfo.linearAxisLength = LinearManipulatorAxisLength();
createInfo.linearConeLength = LinearManipulatorConeLength();
createInfo.linearConeRadius = LinearManipulatorConeRadius();
createInfo.planarAxisLength = PlanarManipulatorAxisLength();
createInfo.surfaceRadius = SurfaceManipulatorRadius();
return createInfo;
}
TranslationManipulators::TranslationManipulators(
const Dimensions dimensions, const AZ::Transform& worldFromLocal, const AZ::Vector3& nonUniformScale)
: m_dimensions(dimensions)
@ -234,15 +246,32 @@ namespace AzToolsFramework
}
}
void TranslationManipulators::ConfigureView2d(const TranslationManipulatorsViewCreateInfo& translationManipulatorViewCreateInfo)
{
ConfigureLinearView(
translationManipulatorViewCreateInfo.linearAxisLength, translationManipulatorViewCreateInfo.linearConeLength,
translationManipulatorViewCreateInfo.linearConeRadius, translationManipulatorViewCreateInfo.axis1Color,
translationManipulatorViewCreateInfo.axis2Color, translationManipulatorViewCreateInfo.axis3Color);
ConfigurePlanarView(
translationManipulatorViewCreateInfo.planarAxisLength, translationManipulatorViewCreateInfo.linearAxisLength,
translationManipulatorViewCreateInfo.linearConeLength, translationManipulatorViewCreateInfo.axis1Color,
translationManipulatorViewCreateInfo.axis2Color, translationManipulatorViewCreateInfo.axis3Color);
}
void TranslationManipulators::ConfigureView3d(const TranslationManipulatorsViewCreateInfo& translationManipulatorViewCreateInfo)
{
ConfigureView2d(translationManipulatorViewCreateInfo);
ConfigureSurfaceView(translationManipulatorViewCreateInfo.surfaceRadius, translationManipulatorViewCreateInfo.surfaceColor);
}
void TranslationManipulators::ConfigureLinearView(
const float axisLength,
const float coneLength,
const float coneRadius,
const AZ::Color& axis1Color,
const AZ::Color& axis2Color,
const AZ::Color& axis3Color /*= AZ::Color(0.0f, 0.0f, 1.0f, 0.5f)*/)
{
const float coneLength = 0.28f;
const float coneRadius = 0.07f;
const AZ::Color axesColor[] = { axis1Color, axis2Color, axis3Color };
const auto configureLinearView = [lineBoundWidth = m_lineBoundWidth, coneLength, axisLength,
@ -251,7 +280,7 @@ namespace AzToolsFramework
const auto lineLength = axisLength - coneLength;
ManipulatorViews views;
views.emplace_back(CreateManipulatorViewLine(*linearManipulator, color, lineLength, lineBoundWidth));
views.emplace_back(CreateManipulatorViewLine(*linearManipulator, color, axisLength, lineBoundWidth));
views.emplace_back(
CreateManipulatorViewCone(*linearManipulator, color, linearManipulator->GetAxis() * lineLength, coneLength, coneRadius));
linearManipulator->SetViews(AZStd::move(views));
@ -264,19 +293,21 @@ namespace AzToolsFramework
}
void TranslationManipulators::ConfigurePlanarView(
const float planarAxisLength,
const float linearAxisLength,
const float linearConeLength,
const AZ::Color& plane1Color,
const AZ::Color& plane2Color /*= AZ::Color(0.0f, 1.0f, 0.0f, 0.5f)*/,
const AZ::Color& plane3Color /*= AZ::Color(0.0f, 0.0f, 1.0f, 0.5f)*/)
{
const float planeSize = 0.6f;
const AZ::Color planesColor[] = { plane1Color, plane2Color, plane3Color };
for (size_t manipulatorIndex = 0; manipulatorIndex < m_planarManipulators.size(); ++manipulatorIndex)
{
const AZStd::shared_ptr<ManipulatorViewQuad> manipulatorView = CreateManipulatorViewQuad(
*m_planarManipulators[manipulatorIndex], planesColor[manipulatorIndex], planesColor[(manipulatorIndex + 1) % 3], planeSize);
m_planarManipulators[manipulatorIndex]->SetViews(ManipulatorViews{ manipulatorView });
const auto& planarManipulator = *m_planarManipulators[manipulatorIndex];
m_planarManipulators[manipulatorIndex]->SetViews(ManipulatorViews{ CreateManipulatorViewQuadForPlanarTranslationManipulator(
planarManipulator.GetAxis1(), planarManipulator.GetAxis2(), planesColor[manipulatorIndex],
planesColor[(manipulatorIndex + 1) % 3], linearAxisLength, linearConeLength, planarAxisLength) });
}
}
@ -286,12 +317,11 @@ namespace AzToolsFramework
{
m_surfaceManipulator->SetView(CreateManipulatorViewSphere(
color, radius,
[](const ViewportInteraction::MouseInteraction& /*mouseInteraction*/, bool mouseOver,
[]([[maybe_unused]] const ViewportInteraction::MouseInteraction& mouseInteraction, bool mouseOver,
const AZ::Color& defaultColor) -> AZ::Color
{
const AZ::Color color[2] = {
defaultColor,
Vector3ToVector4(BaseManipulator::s_defaultMouseOverColor.GetAsVector3(), SurfaceManipulatorTransparency)
defaultColor, Vector3ToVector4(BaseManipulator::s_defaultMouseOverColor.GetAsVector3(), SurfaceManipulatorOpacity())
};
return color[mouseOver];
@ -325,16 +355,25 @@ namespace AzToolsFramework
void ConfigureTranslationManipulatorAppearance3d(TranslationManipulators* translationManipulators)
{
translationManipulators->SetAxes(AZ::Vector3::CreateAxisX(), AZ::Vector3::CreateAxisY(), AZ::Vector3::CreateAxisZ());
translationManipulators->ConfigurePlanarView(LinearManipulatorXAxisColor, LinearManipulatorYAxisColor, LinearManipulatorZAxisColor);
translationManipulators->ConfigureLinearView(
LinearManipulatorAxisLength, LinearManipulatorXAxisColor, LinearManipulatorYAxisColor, LinearManipulatorZAxisColor);
translationManipulators->ConfigureSurfaceView(SurfaceManipulatorRadius, SurfaceManipulatorColor);
translationManipulators->ConfigureView3d(DefaultTranslationManipulatorViewCreateInfo());
}
void ConfigureTranslationManipulatorAppearance2d(TranslationManipulators* translationManipulators)
{
translationManipulators->SetAxes(AZ::Vector3::CreateAxisX(), AZ::Vector3::CreateAxisY());
translationManipulators->ConfigurePlanarView(LinearManipulatorXAxisColor);
translationManipulators->ConfigureLinearView(LinearManipulatorAxisLength, LinearManipulatorXAxisColor, LinearManipulatorYAxisColor);
translationManipulators->ConfigureView2d(DefaultTranslationManipulatorViewCreateInfo());
}
AZStd::shared_ptr<ManipulatorViewQuad> CreateManipulatorViewQuadForPlanarTranslationManipulator(
const AZ::Vector3& axis1,
const AZ::Vector3& axis2,
const AZ::Color& axis1Color,
const AZ::Color& axis2Color,
const float linearAxisLength,
const float linearConeLength,
const float planarAxisLength)
{
const AZ::Vector3 offset = (axis1 + axis2) * (((linearAxisLength - linearConeLength) * 0.5f) - (planarAxisLength * 0.5f));
return CreateManipulatorViewQuad(axis1, axis2, axis1Color, axis2Color, offset, planarAxisLength);
}
} // namespace AzToolsFramework

@ -15,6 +15,20 @@
namespace AzToolsFramework
{
//! Parameters to configure the appearance of the TranslationManipulators view(s).
struct TranslationManipulatorsViewCreateInfo
{
float linearAxisLength;
float linearConeLength;
float linearConeRadius;
float planarAxisLength;
float surfaceRadius;
AZ::Color axis1Color;
AZ::Color axis2Color;
AZ::Color axis3Color;
AZ::Color surfaceColor;
};
//! TranslationManipulators is an aggregation of 3 linear manipulators, 3 planar manipulators
//! and one surface manipulator who share the same transform.
class TranslationManipulators : public Manipulators
@ -23,6 +37,9 @@ namespace AzToolsFramework
AZ_RTTI(TranslationManipulators, "{D5E49EA2-30E0-42BC-A51D-6A7F87818260}")
AZ_CLASS_ALLOCATOR(TranslationManipulators, AZ::SystemAllocator, 0)
TranslationManipulators(TranslationManipulators&&) = delete;
TranslationManipulators& operator=(TranslationManipulators&&) = delete;
//! How many dimensions does this translation manipulator have.
enum class Dimensions
{
@ -52,25 +69,31 @@ namespace AzToolsFramework
void SetAxes(const AZ::Vector3& axis1, const AZ::Vector3& axis2, const AZ::Vector3& axis3 = AZ::Vector3::CreateAxisZ());
void ConfigureView2d(const TranslationManipulatorsViewCreateInfo& translationManipulatorViewCreateInfo);
void ConfigureView3d(const TranslationManipulatorsViewCreateInfo& translationManipulatorViewCreateInfo);
//! Sets the bound width to use for the line/axis of a linear manipulator.
void SetLineBoundWidth(float lineBoundWidth);
private:
void ConfigurePlanarView(
float planeSize,
float linearAxisLength,
float linearConeLength,
const AZ::Color& plane1Color,
const AZ::Color& plane2Color = AZ::Color(0.0f, 1.0f, 0.0f, 0.5f),
const AZ::Color& plane3Color = AZ::Color(0.0f, 0.0f, 1.0f, 0.5f));
void ConfigureLinearView(
float axisLength,
float coneLength,
float coneRadius,
const AZ::Color& axis1Color,
const AZ::Color& axis2Color,
const AZ::Color& axis3Color = AZ::Color(0.0f, 0.0f, 1.0f, 0.5f));
void ConfigureSurfaceView(float radius, const AZ::Color& color);
//! Sets the bound width to use for the line/axis of a linear manipulator.
void SetLineBoundWidth(float lineBoundWidth);
private:
AZ_DISABLE_COPY_MOVE(TranslationManipulators)
// Manipulators
void ProcessManipulators(const AZStd::function<void(BaseManipulator*)>&) override;
@ -130,4 +153,12 @@ namespace AzToolsFramework
void ConfigureTranslationManipulatorAppearance3d(TranslationManipulators* translationManipulators);
void ConfigureTranslationManipulatorAppearance2d(TranslationManipulators* translationManipulators);
AZStd::shared_ptr<ManipulatorViewQuad> CreateManipulatorViewQuadForPlanarTranslationManipulator(
const AZ::Vector3& axis1,
const AZ::Vector3& axis2,
const AZ::Color& axis1Color,
const AZ::Color& axis2Color,
float linearAxisLength,
float linearConeLength,
float planarAxisLength);
} // namespace AzToolsFramework

@ -8,10 +8,12 @@
#include <API/ToolsApplicationAPI.h>
#include <AzCore/Component/ComponentApplicationBus.h>
#include <AzCore/Component/Entity.h>
#include <AzCore/RTTI/BehaviorContext.h>
#include <AzToolsFramework/ToolsComponents/EditorLockComponent.h>
#include <AzToolsFramework/ToolsComponents/EditorVisibilityComponent.h>
#include <Prefab/PrefabSystemComponentInterface.h>
#include <Prefab/PrefabSystemScriptingHandler.h>
#include <AzCore/Component/Entity.h>
#include <Prefab/EditorPrefabComponent.h>
#include <ToolsComponents/TransformComponent.h>
@ -72,6 +74,9 @@ namespace AzToolsFramework::Prefab
entities, commonRoot, &topLevelEntities);
auto containerEntity = AZStd::make_unique<AZ::Entity>();
containerEntity->CreateComponent<Components::TransformComponent>();
containerEntity->CreateComponent<Components::EditorLockComponent>();
containerEntity->CreateComponent<Components::EditorVisibilityComponent>();
containerEntity->CreateComponent<Prefab::EditorPrefabComponent>();
for (AZ::Entity* entity : topLevelEntities)

@ -565,9 +565,7 @@ namespace AzToolsFramework
EditorRequestBus::BroadcastResult(position, &EditorRequestBus::Events::GetWorldPositionAtViewportCenter);
}
// Instantiating from context menu always puts the instance at the root level
auto createPrefabOutcome = s_prefabPublicInterface->InstantiatePrefab(prefabFilePath, parentId, position);
if (!createPrefabOutcome.IsSuccess())
{
WarnUserOfError("Prefab Instantiation Error",createPrefabOutcome.GetError());
@ -594,15 +592,13 @@ namespace AzToolsFramework
}
else
{
// otherwise return since it needs to be inside an authored prefab
return;
EditorRequestBus::BroadcastResult(position, &EditorRequestBus::Events::GetWorldPositionAtViewportCenter);
}
// Instantiating from context menu always puts the instance at the root level
auto createPrefabOutcome = s_prefabPublicInterface->InstantiatePrefab(prefabAssetPath, parentId, position);
if (!createPrefabOutcome.IsSuccess())
{
WarnUserOfError("Prefab Instantiation Error", createPrefabOutcome.GetError());
WarnUserOfError("Procedural Prefab Instantiation Error", createPrefabOutcome.GetError());
}
}
}

@ -45,6 +45,7 @@ AZ_POP_DISABLE_WARNING
#include <AzToolsFramework/AssetBrowser/EBusFindAssetTypeByName.h>
#include <AzToolsFramework/ComponentMode/ComponentModeDelegate.h>
#include <AzToolsFramework/Entity/EditorEntityHelpers.h>
#include <AzToolsFramework/Entity/ReadOnly/ReadOnlyEntityInterface.h>
#include <AzToolsFramework/Prefab/PrefabFocusPublicInterface.h>
#include <AzToolsFramework/Prefab/PrefabPublicInterface.h>
#include <AzToolsFramework/Slice/SliceDataFlagsCommand.h>
@ -497,6 +498,9 @@ namespace AzToolsFramework
m_prefabPublicInterface = AZ::Interface<Prefab::PrefabPublicInterface>::Get();
AZ_Assert(m_prefabPublicInterface != nullptr, "EntityPropertyEditor requires a PrefabPublicInterface instance on Initialize.");
m_readOnlyEntityPublicInterface = AZ::Interface<ReadOnlyEntityPublicInterface>::Get();
AZ_Assert(m_readOnlyEntityPublicInterface != nullptr, "EntityPropertyEditor requires a ReadOnlyEntityPublicInterface instance on Initialize.");
setObjectName("EntityPropertyEditor");
setAcceptDrops(true);
@ -535,10 +539,6 @@ namespace AzToolsFramework
model->setItem(row, 0, m_comboItems[row]);
}
m_gui->m_statusComboBox->setModel(model);
m_gui->m_statusComboBox->setStyleSheet("QComboBox {border: 0px; border-radius:3px; background-color:#555555; color:white}"
"QComboBox:on {background-color:#e9e9e9; color:black; border:0px}"
"QComboBox::down-arrow:on {image: url(:/stylesheet/img/dropdowns/black_down_arrow.png)}"
"QComboBox::drop-down {border-radius: 3p}");
AzQtComponents::ComboBox::addCustomCheckStateStyle(m_gui->m_statusComboBox);
EnableEditor(true);
m_sceneIsNew = true;
@ -565,6 +565,12 @@ namespace AzToolsFramework
AZ::EntitySystemBus::Handler::BusConnect();
EntityPropertyEditorRequestBus::Handler::BusConnect();
EditorWindowUIRequestBus::Handler::BusConnect();
AzFramework::EntityContextId editorEntityContextId = AzFramework::EntityContextId::CreateNull();
EditorEntityContextRequestBus::BroadcastResult(
editorEntityContextId, &EditorEntityContextRequests::GetEditorEntityContextId);
ReadOnlyEntityPublicNotificationBus::Handler::BusConnect(editorEntityContextId);
m_spacer = nullptr;
m_emptyIcon = QIcon();
@ -614,6 +620,7 @@ namespace AzToolsFramework
{
qApp->removeEventFilter(this);
ReadOnlyEntityPublicNotificationBus::Handler::BusDisconnect();
EditorWindowUIRequestBus::Handler::BusDisconnect();
EntityPropertyEditorRequestBus::Handler::BusDisconnect();
ToolsApplicationEvents::Bus::Handler::BusDisconnect();
@ -973,7 +980,7 @@ namespace AzToolsFramework
m_gui->m_entityDetailsLabel->setVisible(false);
// If we're in edit mode, make the name field editable.
m_gui->m_entityNameEditor->setReadOnly(!m_gui->m_componentListContents->isEnabled());
m_gui->m_entityNameEditor->setReadOnly(!m_gui->m_componentListContents->isEnabled() || m_selectionContainsReadOnlyEntity);
// get the name of the entity.
auto entity = GetSelectedEntityById(entityId);
@ -1062,6 +1069,12 @@ namespace AzToolsFramework
bool EntityPropertyEditor::CanAddComponentsToSelection(const SelectionEntityTypeInfo& selectionEntityTypeInfo) const
{
if (m_selectionContainsReadOnlyEntity)
{
// Can't add components if there is a read only entity in the selection
return false;
}
if (selectionEntityTypeInfo == SelectionEntityTypeInfo::Mixed ||
selectionEntityTypeInfo == SelectionEntityTypeInfo::None)
{
@ -1126,6 +1139,17 @@ namespace AzToolsFramework
m_selectedEntityIds.clear();
GetSelectedEntities(m_selectedEntityIds);
// Check if any of the selected entities are marked as read only
m_selectionContainsReadOnlyEntity = false;
for (const auto& entityId : m_selectedEntityIds)
{
if (m_readOnlyEntityPublicInterface->IsReadOnly(entityId))
{
m_selectionContainsReadOnlyEntity = true;
break;
}
}
SourceControlFileInfo scFileInfo;
ToolsApplicationRequests::Bus::BroadcastResult(scFileInfo, &ToolsApplicationRequests::GetSceneSourceControlInfo);
@ -1681,6 +1705,12 @@ namespace AzToolsFramework
componentEditor->UpdateExpandability();
componentEditor->InvalidateAll(!componentInFilter ? m_filterString.c_str() : nullptr);
// If we are in read only mode, then show the components as disabled
if (m_selectionContainsReadOnlyEntity)
{
componentEditor->mockDisabledState(true);
}
if (!componentEditor->GetPropertyEditor()->HasFilteredOutNodes() || componentEditor->GetPropertyEditor()->HasVisibleNodes())
{
for (AZ::Component* componentInstance : componentInstances)
@ -3077,6 +3107,7 @@ namespace AzToolsFramework
}
}
m_gui->m_statusComboBox->setDisabled(m_selectionContainsReadOnlyEntity);
m_gui->m_statusComboBox->setVisible(!m_isSystemEntityEditor && !m_isLevelEntityEditor);
m_gui->m_statusComboBox->style()->unpolish(m_gui->m_statusComboBox);
m_gui->m_statusComboBox->style()->polish(m_gui->m_statusComboBox);
@ -3304,7 +3335,8 @@ namespace AzToolsFramework
const auto& componentsToEdit = GetSelectedComponents();
const bool hasComponents = !m_selectedEntityIds.empty() && !componentsToEdit.empty();
const bool allowRemove = hasComponents && AreComponentsRemovable(componentsToEdit);
// Don't allow components to be removed/cut/enabled/disabled if read only
const bool allowRemove = hasComponents && AreComponentsRemovable(componentsToEdit) && !m_selectionContainsReadOnlyEntity;
const bool allowCopy = hasComponents && AreComponentsCopyable(componentsToEdit);
m_actionToDeleteComponents->setEnabled(allowRemove);
@ -3366,6 +3398,12 @@ namespace AzToolsFramework
return false;
}
if (m_selectionContainsReadOnlyEntity)
{
// Can't paste components if there is a read only entity in the selection
return false;
}
// Grab component data from clipboard, if exists
const QMimeData* mimeData = ComponentMimeData::GetComponentMimeDataFromClipboard();
@ -5727,6 +5765,14 @@ namespace AzToolsFramework
SaveComponentEditorState();
}
void EntityPropertyEditor::OnReadOnlyEntityStatusChanged(const AZ::EntityId& entityId, [[maybe_unused]] bool readOnly)
{
if (IsEntitySelected(entityId))
{
UpdateContents();
}
}
void EntityPropertyEditor::OnEditorModeActivated(
[[maybe_unused]] const AzToolsFramework::ViewportEditorModesInterface& editorModeState, AzToolsFramework::ViewportEditorMode mode)
{

@ -29,6 +29,7 @@
#include <AzToolsFramework/API/ViewportEditorModeTrackerNotificationBus.h>
#include <AzToolsFramework/ComponentMode/EditorComponentModeBus.h>
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
#include <AzToolsFramework/Entity/ReadOnly/ReadOnlyEntityBus.h>
#include <AzToolsFramework/ToolsComponents/ComponentMimeData.h>
#include <AzToolsFramework/ToolsComponents/EditorInspectorComponentBus.h>
#include <AzQtComponents/Components/O3DEStylesheet.h>
@ -62,6 +63,7 @@ namespace AzToolsFramework
class ComponentPaletteWidget;
class ComponentModeCollectionInterface;
struct SourceControlFileInfo;
class ReadOnlyEntityPublicInterface;
namespace AssetBrowser
{
@ -116,6 +118,7 @@ namespace AzToolsFramework
, public AZ::EntitySystemBus::Handler
, public AZ::TickBus::Handler
, private EditorWindowUIRequestBus::Handler
, private ReadOnlyEntityPublicNotificationBus::Handler
{
Q_OBJECT;
public:
@ -253,6 +256,9 @@ namespace AzToolsFramework
// EditorWindowRequestBus overrides
void SetEditorUiEnabled(bool enable) override;
// ReadOnlyEntityPublicNotificationBus overrides ...
void OnReadOnlyEntityStatusChanged(const AZ::EntityId& entityId, bool readOnly) override;
bool IsEntitySelected(const AZ::EntityId& id) const;
bool IsSingleEntitySelected(const AZ::EntityId& id) const;
@ -623,6 +629,9 @@ namespace AzToolsFramework
Prefab::PrefabPublicInterface* m_prefabPublicInterface = nullptr;
bool m_prefabsAreEnabled = false;
ReadOnlyEntityPublicInterface* m_readOnlyEntityPublicInterface = nullptr;
bool m_selectionContainsReadOnlyEntity = false;
// Reordering row widgets within the RPE.
static constexpr float MoveFadeSeconds = 0.5f;

@ -191,7 +191,7 @@
</size>
</property>
<property name="styleSheet">
<string notr="true">background-color:rgb(51, 51, 51)</string>
<string notr="true">QWidget#m_darkBox { background-color:rgb(51, 51, 51) }</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<property name="spacing">
@ -444,6 +444,9 @@
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="styleSheet">
<string notr="true">background-color:rgb(51, 51, 51)</string>
</property>
</widget>
</item>
<item>

@ -15,12 +15,14 @@
#include <AzCore/Slice/SliceComponent.h>
#include <AzCore/std/containers/unordered_map.h>
#include <AzCore/std/parallel/binary_semaphore.h>
#include <AzCore/std/smart_ptr/make_shared.h>
#include <AzCore/std/smart_ptr/unique_ptr.h>
#include <AzCore/UnitTest/TestTypes.h>
#include <AzCore/UserSettings/UserSettingsComponent.h>
#include <AzTest/AzTest.h>
#include <AZTestShared/Math/MathTestHelpers.h>
#include <AZTestShared/Utils/Utils.h>
#include <AzFramework/UnitTest/TestDebugDisplayRequests.h>
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
#include <AzToolsFramework/API/ViewportEditorModeTrackerInterface.h>
#include <AzToolsFramework/API/ViewportEditorModeTrackerNotificationBus.h>
@ -235,6 +237,13 @@ namespace UnitTest
return toolsApp;
}
//! It is possible to override this in classes deriving from ToolsApplicationFixture to provide alternate
//! implementations of the DebugDisplayRequests interface (e.g. TestDebugDisplayRequests).
virtual AZStd::shared_ptr<AzFramework::DebugDisplayRequests> CreateDebugDisplayRequests()
{
return AZStd::make_shared<NullDebugDisplayRequests>();
}
protected:
TestEditorActions m_editorActions;
ToolsApplicationMessageHandler m_messageHandler; // used to suppress trace messages in test output

@ -0,0 +1,123 @@
/*
* 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 <AzToolsFramework/Viewport/ViewportSettings.h>
namespace AzToolsFramework
{
constexpr AZStd::string_view FlipManipulatorAxesTowardsViewSetting = "/Amazon/Preferences/Editor/Manipulator/FlipManipulatorAxesTowardsView";
constexpr AZStd::string_view LinearManipulatorAxisLengthSetting = "/Amazon/Preferences/Editor/Manipulator/LinearManipulatorAxisLength";
constexpr AZStd::string_view PlanarManipulatorAxisLengthSetting = "/Amazon/Preferences/Editor/Manipulator/PlanarManipulatorAxisLength";
constexpr AZStd::string_view SurfaceManipulatorRadiusSetting = "/Amazon/Preferences/Editor/Manipulator/SurfaceManipulatorRadius";
constexpr AZStd::string_view SurfaceManipulatorOpacitySetting = "/Amazon/Preferences/Editor/Manipulator/SurfaceManipulatorOpacity";
constexpr AZStd::string_view LinearManipulatorConeLengthSetting = "/Amazon/Preferences/Editor/Manipulator/LinearManipulatorConeLength";
constexpr AZStd::string_view LinearManipulatorConeRadiusSetting = "/Amazon/Preferences/Editor/Manipulator/LinearManipulatorConeRadius";
constexpr AZStd::string_view ScaleManipulatorBoxHalfExtentSetting = "/Amazon/Preferences/Editor/Manipulator/ScaleManipulatorBoxHalfExtent";
constexpr AZStd::string_view RotationManipulatorRadiusSetting = "/Amazon/Preferences/Editor/Manipulator/RotationManipulatorRadius";
constexpr AZStd::string_view ManipulatorViewBaseScaleSetting = "/Amazon/Preferences/Editor/Manipulator/ViewBaseScale";
bool FlipManipulatorAxesTowardsView()
{
return GetRegistry(FlipManipulatorAxesTowardsViewSetting, true);
}
void SetFlipManipulatorAxesTowardsView(const bool enabled)
{
SetRegistry(FlipManipulatorAxesTowardsViewSetting, enabled);
}
float LinearManipulatorAxisLength()
{
return aznumeric_cast<float>(GetRegistry(LinearManipulatorAxisLengthSetting, 2.0));
}
void SetLinearManipulatorAxisLength(const float length)
{
SetRegistry(LinearManipulatorAxisLengthSetting, length);
}
float PlanarManipulatorAxisLength()
{
return aznumeric_cast<float>(GetRegistry(PlanarManipulatorAxisLengthSetting, 0.6));
}
void SetPlanarManipulatorAxisLength(const float length)
{
SetRegistry(PlanarManipulatorAxisLengthSetting, length);
}
float SurfaceManipulatorRadius()
{
return aznumeric_cast<float>(GetRegistry(SurfaceManipulatorRadiusSetting, 0.1));
}
void SetSurfaceManipulatorRadius(const float radius)
{
SetRegistry(SurfaceManipulatorRadiusSetting, radius);
}
float SurfaceManipulatorOpacity()
{
return aznumeric_cast<float>(GetRegistry(SurfaceManipulatorOpacitySetting, 0.75));
}
void SetSurfaceManipulatorOpacity(const float opacity)
{
SetRegistry(SurfaceManipulatorOpacitySetting, opacity);
}
float LinearManipulatorConeLength()
{
return aznumeric_cast<float>(GetRegistry(LinearManipulatorConeLengthSetting, 0.28));
}
void SetLinearManipulatorConeLength(const float length)
{
SetRegistry(LinearManipulatorConeLengthSetting, length);
}
float LinearManipulatorConeRadius()
{
return aznumeric_cast<float>(GetRegistry(LinearManipulatorConeRadiusSetting, 0.1));
}
void SetLinearManipulatorConeRadius(const float radius)
{
SetRegistry(LinearManipulatorConeRadiusSetting, radius);
}
float ScaleManipulatorBoxHalfExtent()
{
return aznumeric_cast<float>(GetRegistry(ScaleManipulatorBoxHalfExtentSetting, 0.1));
}
void SetScaleManipulatorBoxHalfExtent(const float size)
{
SetRegistry(ScaleManipulatorBoxHalfExtentSetting, size);
}
float RotationManipulatorRadius()
{
return aznumeric_cast<float>(GetRegistry(RotationManipulatorRadiusSetting, 2.0));
}
void SetRotationManipulatorRadius(const float radius)
{
SetRegistry(RotationManipulatorRadiusSetting, radius);
}
float ManipulatorViewBaseScale()
{
return aznumeric_cast<float>(GetRegistry(ManipulatorViewBaseScaleSetting, 1.0));
}
void SetManipulatorViewBaseScale(const float scale)
{
SetRegistry(ManipulatorViewBaseScaleSetting, scale);
}
} // namespace AzToolsFramework

@ -0,0 +1,69 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/Settings/SettingsRegistry.h>
namespace AzToolsFramework
{
template<typename T>
void SetRegistry(const AZStd::string_view setting, T&& value)
{
if (auto* registry = AZ::SettingsRegistry::Get())
{
registry->Set(setting, AZStd::forward<T>(value));
}
}
template<typename T>
AZStd::remove_cvref_t<T> GetRegistry(const AZStd::string_view setting, T&& defaultValue)
{
AZStd::remove_cvref_t<T> value = AZStd::forward<T>(defaultValue);
if (const auto* registry = AZ::SettingsRegistry::Get())
{
T potentialValue;
if (registry->Get(potentialValue, setting))
{
value = AZStd::move(potentialValue);
}
}
return value;
}
bool FlipManipulatorAxesTowardsView();
void SetFlipManipulatorAxesTowardsView(bool enabled);
float LinearManipulatorAxisLength();
void SetLinearManipulatorAxisLength(float length);
float PlanarManipulatorAxisLength();
void SetPlanarManipulatorAxisLength(float length);
float SurfaceManipulatorRadius();
void SetSurfaceManipulatorRadius(float radius);
float SurfaceManipulatorOpacity();
void SetSurfaceManipulatorOpacity(float opacity);
float LinearManipulatorConeLength();
void SetLinearManipulatorConeLength(float length);
float LinearManipulatorConeRadius();
void SetLinearManipulatorConeRadius(float radius);
float ScaleManipulatorBoxHalfExtent();
void SetScaleManipulatorBoxHalfExtent(float halfExtent);
float RotationManipulatorRadius();
void SetRotationManipulatorRadius(float radius);
float ManipulatorViewBaseScale();
void SetManipulatorViewBaseScale(float scale);
} // namespace AzToolsFramework

@ -33,6 +33,7 @@
#include <AzToolsFramework/ToolsComponents/EditorVisibilityBus.h>
#include <AzToolsFramework/ToolsComponents/TransformComponent.h>
#include <AzToolsFramework/Viewport/ActionBus.h>
#include <AzToolsFramework/Viewport/ViewportSettings.h>
#include <AzToolsFramework/ViewportSelection/EditorSelectionUtil.h>
#include <AzToolsFramework/ViewportSelection/EditorVisibleEntityDataCache.h>
#include <Entity/EditorEntityContextBus.h>
@ -1376,7 +1377,7 @@ namespace AzToolsFramework
// view
rotationManipulators->SetLocalAxes(AZ::Vector3::CreateAxisX(), AZ::Vector3::CreateAxisY(), AZ::Vector3::CreateAxisZ());
rotationManipulators->ConfigureView(
2.0f, AzFramework::ViewportColors::XAxisColor, AzFramework::ViewportColors::YAxisColor,
RotationManipulatorRadius(), AzFramework::ViewportColors::XAxisColor, AzFramework::ViewportColors::YAxisColor,
AzFramework::ViewportColors::ZAxisColor);
struct SharedRotationState
@ -1535,7 +1536,8 @@ namespace AzToolsFramework
RecalculateAverageManipulatorTransform(m_entityIdManipulators.m_lookups, m_pivotOverrideFrame, m_pivotMode, m_referenceFrame));
scaleManipulators->SetAxes(AZ::Vector3::CreateAxisX(), AZ::Vector3::CreateAxisY(), AZ::Vector3::CreateAxisZ());
scaleManipulators->ConfigureView(2.0f, AZ::Color::CreateOne(), AZ::Color::CreateOne(), AZ::Color::CreateOne());
scaleManipulators->ConfigureView(
LinearManipulatorAxisLength(), AZ::Color::CreateOne(), AZ::Color::CreateOne(), AZ::Color::CreateOne());
struct SharedScaleState
{

@ -506,6 +506,8 @@ set(FILES
Viewport/ViewportMessages.cpp
Viewport/ViewportTypes.h
Viewport/ViewportTypes.cpp
Viewport/ViewportSettings.h
Viewport/ViewportSettings.cpp
ViewportUi/Button.h
ViewportUi/Button.cpp
ViewportUi/ButtonGroup.h

@ -7,12 +7,16 @@
*/
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/UnitTest/TestTypes.h>
#include <AzManipulatorTestFramework/AzManipulatorTestFramework.h>
#include <AzManipulatorTestFramework/DirectManipulatorViewportInteraction.h>
#include <AzManipulatorTestFramework/ImmediateModeActionDispatcher.h>
#include <AzTest/AzTest.h>
#include <AzToolsFramework/Application/ToolsApplication.h>
#include <AzToolsFramework/Manipulators/RotationManipulators.h>
#include <AzToolsFramework/Manipulators/ManipulatorManager.h>
#include <AzToolsFramework/Manipulators/ManipulatorView.h>
#include <AzCore/UnitTest/TestTypes.h>
#include <AzToolsFramework/Manipulators/RotationManipulators.h>
#include <AzToolsFramework/Manipulators/TranslationManipulators.h>
#include <AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.h>
#include <AzToolsFramework/UnitTest/ToolsTestApplication.h>
#include <AzToolsFramework/ViewportSelection/EditorSelectionUtil.h>
@ -21,8 +25,7 @@ namespace UnitTest
{
using namespace AzToolsFramework;
class ManipulatorViewTest
: public AllocatorsTestFixture
class ManipulatorViewTest : public AllocatorsTestFixture
{
AZStd::unique_ptr<AZ::SerializeContext> m_serializeContext;
@ -32,7 +35,7 @@ namespace UnitTest
m_serializeContext = AZStd::make_unique<AZ::SerializeContext>();
m_app.Start(AzFramework::Application::Descriptor());
// Without this, the user settings component would attempt to save on finalize/shutdown. Since the file is
// shared across the whole engine, if multiple tests are run in parallel, the saving could cause a crash
// shared across the whole engine, if multiple tests are run in parallel, the saving could cause a crash
// in the unit tests.
AZ::UserSettingsComponentRequestBus::Broadcast(&AZ::UserSettingsComponentRequests::DisableSaveOnFinalize);
}
@ -51,12 +54,9 @@ namespace UnitTest
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Given
const AZ::Transform orientation =
AZ::Transform::CreateFromQuaternion(
AZ::Quaternion::CreateFromAxisAngle(
AZ::Vector3::CreateAxisX(), AZ::DegToRad(-90.0f)));
AZ::Transform::CreateFromQuaternion(AZ::Quaternion::CreateRotationX(AZ::DegToRad(-90.0f)));
const AZ::Transform translation =
AZ::Transform::CreateTranslation(AZ::Vector3(5.0f, 0.0f, 10.0f));
const AZ::Transform translation = AZ::Transform::CreateTranslation(AZ::Vector3(5.0f, 0.0f, 10.0f));
const AZ::Transform manipulatorSpace = translation * orientation;
// create a rotation manipulator in an arbitrary space
@ -67,8 +67,7 @@ namespace UnitTest
// When
const AZ::Vector3 worldCameraPosition = AZ::Vector3(5.0f, -10.0f, 10.0f);
// transform the view direction to the space of the manipulator (space + local transform)
const AZ::Vector3 viewDirection =
CalculateViewDirection(rotationManipulators, worldCameraPosition);
const AZ::Vector3 viewDirection = CalculateViewDirection(rotationManipulators, worldCameraPosition);
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -84,8 +83,7 @@ namespace UnitTest
cameraState.m_position = AZ::Vector3::CreateAxisY(20.0f);
cameraState.m_forward = -AZ::Vector3::CreateAxisY();
const float scale =
AzToolsFramework::CalculateScreenToWorldMultiplier(AZ::Vector3::CreateZero(), cameraState);
const float scale = AzToolsFramework::CalculateScreenToWorldMultiplier(AZ::Vector3::CreateZero(), cameraState);
EXPECT_NEAR(scale, 2.0f, std::numeric_limits<float>::epsilon());
}
@ -96,9 +94,57 @@ namespace UnitTest
cameraState.m_position = AZ::Vector3::CreateAxisY(20.0f);
cameraState.m_forward = -AZ::Vector3::CreateAxisY();
const float scale =
AzToolsFramework::CalculateScreenToWorldMultiplier(AZ::Vector3::CreateAxisX(-10.0f), cameraState);
const float scale = AzToolsFramework::CalculateScreenToWorldMultiplier(AZ::Vector3::CreateAxisX(-10.0f), cameraState);
EXPECT_NEAR(scale, 2.0f, std::numeric_limits<float>::epsilon());
}
TEST_F(ManipulatorViewTest, ManipulatorViewQuadDrawsAtCorrectPositionWhenManipulatorSpaceIsScaledUniformlyAndNonUniformly)
{
// Given
// simulate a custom manipulator space (e.g. entity transform) and a local offset within that space (e.g. spline vertex position)
const AZ::Transform space =
AZ::Transform::CreateTranslation(AZ::Vector3(2.0f, -3.0f, -4.0f)) * AZ::Transform::CreateUniformScale(2.0f);
const AZ::Vector3 localPosition = AZ::Vector3(2.0f, -2.0f, 0.0f);
const AZ::Vector3 nonUniformScale = AZ::Vector3(2.0f, 3.0f, 4.0f);
const AZ::Transform combinedTransform =
AzToolsFramework::ApplySpace(AZ::Transform::CreateTranslation(localPosition), space, nonUniformScale);
// create a manipulator state based on the space and local position
AzToolsFramework::ManipulatorState manipulatorState{};
manipulatorState.m_worldFromLocal = combinedTransform;
manipulatorState.m_nonUniformScale = nonUniformScale;
// note: This is zero as the localPosition is already encoded in the combinedTransform
manipulatorState.m_localPosition = AZ::Vector3::CreateZero();
// camera (go to position format) - 10.00, -15.00, 6.00, -90.00, 0.00
const AzFramework::CameraState cameraState = AzFramework::CreateDefaultCamera(
AZ::Transform::CreateFromMatrix3x3AndTranslation(
AZ::Matrix3x3::CreateRotationX(AZ::DegToRad(-90.0f)), AZ::Vector3(10.0f, -15.0f, 6.0f)),
AZ::Vector2(1280, 720));
// test debug display instance to record vertices that were output
auto testDebugDisplayRequests = AZStd::make_shared<TestDebugDisplayRequests>();
auto planarTranslationViewQuad = CreateManipulatorViewQuadForPlanarTranslationManipulator(
AZ::Vector3::CreateAxisX(), AZ::Vector3::CreateAxisY(), AZ::Color::CreateZero(), AZ::Color::CreateZero(), 2.2f, 0.2f, 1.0f);
// When
// draw the quad as it would be for a manipulator
planarTranslationViewQuad->Draw(
AzToolsFramework::ManipulatorManagerId(1), AzToolsFramework::ManipulatorManagerState{ false },
AzToolsFramework::ManipulatorId(1), manipulatorState, *testDebugDisplayRequests, cameraState,
AzToolsFramework::ViewportInteraction::MouseInteraction{});
const AZStd::vector<AZ::Vector3> expectedDisplayPositions = {
AZ::Vector3(10.5f, -13.5f, -4.0f), AZ::Vector3(11.5f, -13.5f, -4.0f), AZ::Vector3(10.5f, -14.5f, -4.0f),
AZ::Vector3(11.5f, -14.5f, -4.0f), AZ::Vector3(10.5f, -13.5f, -4.0f), AZ::Vector3(10.5f, -14.5f, -4.0f),
AZ::Vector3(11.5f, -14.5f, -4.0f), AZ::Vector3(11.5f, -13.5f, -4.0f)
};
// Then
const auto points = testDebugDisplayRequests->GetPoints();
// quad vertices appear in the expected position (not offset or scaled incorrectly by space scale)
using ::testing::UnorderedPointwise;
EXPECT_THAT(points, UnorderedPointwise(ContainerIsClose(), expectedDisplayPositions));
}
} // namespace UnitTest

@ -299,7 +299,7 @@ void android_main(android_app* appState)
{
// Adding a start up banner so you can see when the game is starting up in amongst the logcat spam
LOGI("****************************************************************");
LOGI("* Amazon Lumberyard - Launching Game... *");
LOGI("* Launching Game... *");
LOGI("****************************************************************");
// setup the system command handler which are guaranteed to be called on the same

@ -100,85 +100,8 @@ set(FILES
platform_impl.cpp
Win32specific.h
Win64specific.h
LyShine/IDraw2d.h
LyShine/ILyShine.h
LyShine/ISprite.h
LyShine/IRenderGraph.h
LyShine/UiAssetTypes.h
LyShine/UiComponentTypes.h
LyShine/UiBase.h
LyShine/UiEntityContext.h
LyShine/UiLayoutCellBase.h
LyShine/UiSerializeHelpers.h
LyShine/Animation/IUiAnimation.h
LyShine/Bus/UiAnimateEntityBus.h
LyShine/Bus/UiAnimationBus.h
LyShine/Bus/UiButtonBus.h
LyShine/Bus/UiCanvasBus.h
LyShine/Bus/UiCanvasManagerBus.h
LyShine/Bus/UiCanvasUpdateNotificationBus.h
LyShine/Bus/UiCheckboxBus.h
LyShine/Bus/UiCursorBus.h
LyShine/Bus/UiDraggableBus.h
LyShine/Bus/UiDropdownBus.h
LyShine/Bus/UiDropdownOptionBus.h
LyShine/Bus/UiDropTargetBus.h
LyShine/Bus/UiDynamicLayoutBus.h
LyShine/Bus/UiDynamicScrollBoxBus.h
LyShine/Bus/UiEditorBus.h
LyShine/Bus/UiEditorCanvasBus.h
LyShine/Bus/UiEditorChangeNotificationBus.h
LyShine/Bus/UiElementBus.h
LyShine/Bus/UiEntityContextBus.h
LyShine/Bus/UiFaderBus.h
LyShine/Bus/UiFlipbookAnimationBus.h
LyShine/Bus/UiGameEntityContextBus.h
LyShine/Bus/UiImageBus.h
LyShine/Bus/UiImageSequenceBus.h
LyShine/Bus/UiIndexableImageBus.h
LyShine/Bus/UiInitializationBus.h
LyShine/Bus/UiInteractableActionsBus.h
LyShine/Bus/UiInteractableBus.h
LyShine/Bus/UiInteractableStatesBus.h
LyShine/Bus/UiInteractionMaskBus.h
LyShine/Bus/UiLayoutBus.h
LyShine/Bus/UiLayoutCellBus.h
LyShine/Bus/UiLayoutCellDefaultBus.h
LyShine/Bus/UiLayoutColumnBus.h
LyShine/Bus/UiLayoutControllerBus.h
LyShine/Bus/UiLayoutFitterBus.h
LyShine/Bus/UiLayoutGridBus.h
LyShine/Bus/UiLayoutManagerBus.h
LyShine/Bus/UiLayoutRowBus.h
LyShine/Bus/UiMarkupButtonBus.h
LyShine/Bus/UiMaskBus.h
LyShine/Bus/UiNavigationBus.h
LyShine/Bus/UiParticleEmitterBus.h
LyShine/Bus/UiRadioButtonBus.h
LyShine/Bus/UiRadioButtonCommunicationBus.h
LyShine/Bus/UiRadioButtonGroupBus.h
LyShine/Bus/UiRadioButtonGroupCommunicationBus.h
LyShine/Bus/UiRenderBus.h
LyShine/Bus/UiRenderControlBus.h
LyShine/Bus/UiScrollableBus.h
LyShine/Bus/UiScrollBarBus.h
LyShine/Bus/UiScrollBoxBus.h
LyShine/Bus/UiScrollerBus.h
LyShine/Bus/UiSliderBus.h
LyShine/Bus/UiSpawnerBus.h
LyShine/Bus/UiSystemBus.h
LyShine/Bus/UiTextBus.h
LyShine/Bus/UiTextInputBus.h
LyShine/Bus/UiTooltipBus.h
LyShine/Bus/UiTooltipDataPopulatorBus.h
LyShine/Bus/UiTooltipDisplayBus.h
LyShine/Bus/UiTransform2dBus.h
LyShine/Bus/UiTransformBus.h
LyShine/Bus/UiVisualBus.h
LyShine/Bus/Sprite/UiSpriteBus.h
LyShine/Bus/World/UiCanvasOnMeshBus.h
LyShine/Bus/World/UiCanvasRefBus.h
LyShine/Bus/Tools/UiSystemToolsBus.h
Maestro/Bus/EditorSequenceAgentComponentBus.h
Maestro/Bus/EditorSequenceBus.h
Maestro/Bus/EditorSequenceComponentBus.h

@ -27,7 +27,6 @@
#include <AzFramework/Spawnable/RootSpawnableInterface.h>
#include "MainThreadRenderRequestBus.h"
#include <LyShine/ILyShine.h>
#include <AzCore/Component/TickBus.h>
#include <AzCore/IO/Path/Path.h>
#include <AzCore/StringFunc/StringFunc.h>
@ -882,12 +881,6 @@ void CLevelSystem::UnloadLevel()
// Normally the GC step is triggered at the end of this method (by the ESYSTEM_EVENT_LEVEL_POST_UNLOAD event).
EBUS_EVENT(AZ::ScriptSystemRequestBus, GarbageCollect);
// Perform level unload procedures for the LyShine UI system
if (gEnv && gEnv->pLyShine)
{
gEnv->pLyShine->OnLevelUnload();
}
m_bLevelLoaded = false;
[[maybe_unused]] const AZ::TimeMs unloadTimeMs = AZ::GetRealElapsedTimeMs() - beginTimeMs;

@ -19,7 +19,6 @@
#include <AzFramework/Input/Buses/Requests/InputChannelRequestBus.h>
#include "MainThreadRenderRequestBus.h"
#include <LyShine/ILyShine.h>
#include <AzCore/Component/TickBus.h>
#include <AzCore/IO/Path/Path.h>
#include <AzCore/Settings/SettingsRegistryVisitorUtils.h>
@ -558,12 +557,6 @@ namespace LegacyLevelSystem
// Normally the GC step is triggered at the end of this method (by the ESYSTEM_EVENT_LEVEL_POST_UNLOAD event).
EBUS_EVENT(AZ::ScriptSystemRequestBus, GarbageCollect);
// Perform level unload procedures for the LyShine UI system
if (gEnv && gEnv->pLyShine)
{
gEnv->pLyShine->OnLevelUnload();
}
m_bLevelLoaded = false;
[[maybe_unused]] const AZ::TimeMs unloadTimeMs = AZ::GetRealElapsedTimeMs() - beginTimeMs;

@ -116,7 +116,6 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
#include <ILog.h>
#include <IAudioSystem.h>
#include <IProcess.h>
#include <LyShine/ILyShine.h>
#include <LoadScreenBus.h>
@ -373,14 +372,7 @@ void CSystem::ShutDown()
m_pSystemEventDispatcher->OnSystemEvent(ESYSTEM_EVENT_FULL_SHUTDOWN, 0, 0);
}
if (gEnv && gEnv->pLyShine)
{
gEnv->pLyShine->Release();
gEnv->pLyShine = nullptr;
}
SAFE_RELEASE(m_env.pMovieSystem);
SAFE_RELEASE(m_env.pLyShine);
SAFE_RELEASE(m_env.pCryFont);
if (m_env.pConsole)
{

@ -52,7 +52,6 @@
#include <AzFramework/Archive/ArchiveFileIO.h>
#include <LoadScreenBus.h>
#include <LyShine/Bus/UiSystemBus.h>
#include <AzFramework/Logging/MissingAssetLogger.h>
#include <AzFramework/Platform/PlatformDefaults.h>
#include <AzCore/Interface/Interface.h>
@ -77,7 +76,6 @@
#include <IAudioSystem.h>
#include <ICmdLine.h>
#include <IProcess.h>
#include <LyShine/ILyShine.h>
#include <AzFramework/Archive/Archive.h>
#include "XConsole.h"
@ -1105,11 +1103,6 @@ AZ_POP_DISABLE_WARNING
InlineInitializationProcessing("CSystem::Init Level System");
if (m_env.pLyShine)
{
m_env.pLyShine->PostInit();
}
InlineInitializationProcessing("CSystem::Init InitLmbrAWS");
// Az to Cry console binding

@ -294,7 +294,7 @@ namespace O3DE::ProjectManager
}
else if (numChangedDependencies > 1)
{
notification += tr("%1 Gem %2").arg(QString(numChangedDependencies), tr("dependencies"));
notification += tr("%1 Gem %2").arg(numChangedDependencies).arg(tr("dependencies"));
}
notification += (added ? tr(" activated") : tr(" deactivated"));

@ -28,6 +28,7 @@
#include <QFileInfo>
#include <QDesktopServices>
#include <QMessageBox>
#include <QMouseEvent>
namespace O3DE::ProjectManager
{
@ -109,11 +110,11 @@ namespace O3DE::ProjectManager
vLayout->addWidget(m_progressBar);
}
void LabelButton::mousePressEvent([[maybe_unused]] QMouseEvent* event)
void LabelButton::mousePressEvent(QMouseEvent* event)
{
if(m_enabled)
{
emit triggered();
emit triggered(event);
}
}
@ -201,52 +202,64 @@ namespace O3DE::ProjectManager
projectNameLabel->setToolTip(m_projectInfo.m_path);
hLayout->addWidget(projectNameLabel);
QMenu* menu = new QMenu(this);
menu->addAction(tr("Edit Project Settings..."), this, [this]() { emit EditProject(m_projectInfo.m_path); });
menu->addAction(tr("Configure Gems..."), this, [this]() { emit EditProjectGems(m_projectInfo.m_path); });
menu->addAction(tr("Build"), this, [this]() { emit BuildProject(m_projectInfo); });
menu->addAction(tr("Open CMake GUI..."), this, [this]() { emit OpenCMakeGUI(m_projectInfo); });
menu->addSeparator();
menu->addAction(tr("Open Project folder..."), this, [this]()
{
AzQtComponents::ShowFileOnDesktop(m_projectInfo.m_path);
});
#if AZ_TRAIT_PROJECT_MANAGER_CREATE_DESKTOP_SHORTCUT
menu->addAction(tr("Create Editor desktop shortcut..."), this, [this]()
{
AZ::IO::FixedMaxPath editorExecutablePath = ProjectUtils::GetEditorExecutablePath(m_projectInfo.m_path.toUtf8().constData());
const QString shortcutName = QString("%1 Editor").arg(m_projectInfo.m_displayName);
const QString arg = QString("--regset=\"/Amazon/AzCore/Bootstrap/project_path=%1\"").arg(m_projectInfo.m_path);
auto result = ProjectUtils::CreateDesktopShortcut(shortcutName, editorExecutablePath.c_str(), { arg });
if(result.IsSuccess())
{
QMessageBox::information(this, tr("Desktop Shortcut Created"), result.GetValue());
}
else
{
QMessageBox::critical(this, tr("Failed to create shortcut"), result.GetError());
}
});
#endif // AZ_TRAIT_PROJECT_MANAGER_CREATE_DESKTOP_SHORTCUT
menu->addSeparator();
menu->addAction(tr("Duplicate"), this, [this]() { emit CopyProject(m_projectInfo); });
menu->addSeparator();
menu->addAction(tr("Remove from O3DE"), this, [this]() { emit RemoveProject(m_projectInfo.m_path); });
menu->addAction(tr("Delete this Project"), this, [this]() { emit DeleteProject(m_projectInfo.m_path); });
m_projectMenuButton = new QPushButton(this);
m_projectMenuButton->setObjectName("projectMenuButton");
m_projectMenuButton->setMenu(menu);
m_projectMenuButton->setMenu(CreateProjectMenu());
hLayout->addWidget(m_projectMenuButton);
}
vLayout->addWidget(projectFooter);
connect(m_projectImageLabel->GetOpenEditorButton(), &QPushButton::clicked, [this](){ emit OpenProject(m_projectInfo.m_path); });
connect(m_projectImageLabel, &LabelButton::triggered, [this](QMouseEvent* event) {
if (event->button() == Qt::RightButton)
{
m_projectMenuButton->menu()->move(event->globalPos());
m_projectMenuButton->menu()->show();
}
});
}
QMenu* ProjectButton::CreateProjectMenu()
{
QMenu* menu = new QMenu(this);
menu->addAction(tr("Edit Project Settings..."), this, [this]() { emit EditProject(m_projectInfo.m_path); });
menu->addAction(tr("Configure Gems..."), this, [this]() { emit EditProjectGems(m_projectInfo.m_path); });
menu->addAction(tr("Build"), this, [this]() { emit BuildProject(m_projectInfo); });
menu->addAction(tr("Open CMake GUI..."), this, [this]() { emit OpenCMakeGUI(m_projectInfo); });
menu->addSeparator();
menu->addAction(tr("Open Project folder..."), this, [this]()
{
AzQtComponents::ShowFileOnDesktop(m_projectInfo.m_path);
});
#if AZ_TRAIT_PROJECT_MANAGER_CREATE_DESKTOP_SHORTCUT
menu->addAction(tr("Create Editor desktop shortcut..."), this, [this]()
{
AZ::IO::FixedMaxPath editorExecutablePath = ProjectUtils::GetEditorExecutablePath(m_projectInfo.m_path.toUtf8().constData());
const QString shortcutName = QString("%1 Editor").arg(m_projectInfo.m_displayName);
const QString arg = QString("--regset=\"/Amazon/AzCore/Bootstrap/project_path=%1\"").arg(m_projectInfo.m_path);
auto result = ProjectUtils::CreateDesktopShortcut(shortcutName, editorExecutablePath.c_str(), { arg });
if(result.IsSuccess())
{
QMessageBox::information(this, tr("Desktop Shortcut Created"), result.GetValue());
}
else
{
QMessageBox::critical(this, tr("Failed to create shortcut"), result.GetError());
}
});
#endif // AZ_TRAIT_PROJECT_MANAGER_CREATE_DESKTOP_SHORTCUT
menu->addSeparator();
menu->addAction(tr("Duplicate"), this, [this]() { emit CopyProject(m_projectInfo); });
menu->addSeparator();
menu->addAction(tr("Remove from O3DE"), this, [this]() { emit RemoveProject(m_projectInfo.m_path); });
menu->addAction(tr("Delete this Project"), this, [this]() { emit DeleteProject(m_projectInfo.m_path); });
return menu;
}
const ProjectInfo& ProjectButton::GetProjectInfo() const

@ -24,6 +24,7 @@ QT_FORWARD_DECLARE_CLASS(QProgressBar)
QT_FORWARD_DECLARE_CLASS(QLayout)
QT_FORWARD_DECLARE_CLASS(QVBoxLayout)
QT_FORWARD_DECLARE_CLASS(QEvent)
QT_FORWARD_DECLARE_CLASS(QMenu)
namespace O3DE::ProjectManager
{
@ -49,7 +50,7 @@ namespace O3DE::ProjectManager
QLayout* GetBuildOverlayLayout();
signals:
void triggered();
void triggered(QMouseEvent* event);
public slots:
void mousePressEvent(QMouseEvent* event) override;
@ -108,6 +109,8 @@ namespace O3DE::ProjectManager
void ShowWarning(bool show, const QString& warning);
void ShowDefaultBuildButton();
QMenu* CreateProjectMenu();
ProjectInfo m_projectInfo;
LabelButton* m_projectImageLabel = nullptr;

@ -11,6 +11,11 @@
"Name": "Depth",
"SlotType": "Input",
"ScopeAttachmentUsage": "Shader",
"ImageViewDesc": {
"AspectFlags": [
"Depth"
]
},
"ShaderImageDimensionsConstant": "m_fullResDimensions"
},
{

@ -26,6 +26,7 @@ partial ShaderResourceGroup ViewSrg
// circle of confusion to screen ratio;
float m_cocToScreenRatio;
[[pad_to(16)]]
};

@ -68,6 +68,8 @@ namespace AZ
: Base(descriptor)
, AzFramework::InputChannelEventListener(AzFramework::InputChannelEventListener::GetPriorityDebugUI() - 1) // Give ImGui manager priority over the pass
, AzFramework::InputTextEventListener(AzFramework::InputTextEventListener::GetPriorityDebugUI() - 1) // Give ImGui manager priority over the pass
, m_tickHandlerFrameStart(*this)
, m_tickHandlerFrameEnd(*this)
{
const ImGuiPassData* imguiPassData = RPI::PassUtils::GetPassData<ImGuiPassData>(descriptor);
@ -102,7 +104,6 @@ namespace AZ
Init();
ImGui::NewFrame();
TickBus::Handler::BusConnect();
AzFramework::InputChannelEventListener::Connect();
AzFramework::InputTextEventListener::Connect();
}
@ -127,7 +128,6 @@ namespace AZ
AzFramework::InputTextEventListener::BusDisconnect();
AzFramework::InputChannelEventListener::BusDisconnect();
TickBus::Handler::BusDisconnect();
}
ImGuiContext* ImGuiPass::GetContext()
@ -140,23 +140,61 @@ namespace AZ
m_drawData.push_back(drawData);
}
int ImGuiPass::GetTickOrder()
ImGuiPass::TickHandlerFrameStart::TickHandlerFrameStart(ImGuiPass& imGuiPass)
: m_imGuiPass(imGuiPass)
{
TickBus::Handler::BusConnect();
}
int ImGuiPass::TickHandlerFrameStart::GetTickOrder()
{
// We have to call ImGui::NewFrame (which happens in ImGuiPass::OnTick) after setting
// ImGui::GetIO().NavInputs (which happens in ImGuiPass::OnInputChannelEventFiltered),
// but before ImGui::Render (which happens in ImGuiPass::SetupFrameGraphDependencies).
return AZ::ComponentTickBus::TICK_PRE_RENDER;
}
void ImGuiPass::OnTick(float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint timePoint)
void ImGuiPass::TickHandlerFrameStart::OnTick(float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint timePoint)
{
auto imguiContextScope = ImguiContextScope(m_imguiContext);
auto imguiContextScope = ImguiContextScope(m_imGuiPass.m_imguiContext);
ImGui::NewFrame();
auto& io = ImGui::GetIO();
io.DeltaTime = deltaTime;
}
ImGuiPass::TickHandlerFrameEnd::TickHandlerFrameEnd(ImGuiPass& imGuiPass)
: m_imGuiPass(imGuiPass)
{
TickBus::Handler::BusConnect();
}
int ImGuiPass::TickHandlerFrameEnd::GetTickOrder()
{
// ImGui::NewFrame() must be called (see ImGuiPass::TickHandlerFrameStart::OnTick) after populating
// ImGui::GetIO().NavInputs (see ImGuiPass::OnInputChannelEventFiltered), and paired with a call to
// ImGui::EndFrame() (see ImGuiPass::TickHandlerFrameEnd::OnTick); if this is not called explicitly
// then it will be called from inside ImGui::Render() (see ImGuiPass::SetupFrameGraphDependencies).
//
// ImGui::Render() gets called (indirectly) from OnSystemTick, so we cannot rely on it being paired
// with a matching call to ImGui::NewFrame() that gets called from OnTick, because OnSystemTick and
// OnTick can be called at different frequencies under some circumstances (namely from the editor).
//
// To account for this we must explicitly call ImGui::EndFrame() once a frame from OnTick to ensure
// that every call to ImGui::NewFrame() has been matched with a call to ImGui::EndFrame(), but only
// after ImGui::Render() has had the chance first (if so calling ImGui::EndFrame() again is benign).
//
// Because ImGui::Render() gets called (indirectly) from OnSystemTick, which usually happens at the
// start of every frame, we give TickHandlerFrameEnd::OnTick() the order of TICK_FIRST such that it
// will be called first on the regular tick bus, which is invoked immediately after the system tick.
//
// So while returning TICK_FIRST is incredibly counter-intuitive, hopefully that all explains why.
return AZ::ComponentTickBus::TICK_FIRST;
}
void ImGuiPass::TickHandlerFrameEnd::OnTick([[maybe_unused]] float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint timePoint)
{
auto imguiContextScope = ImguiContextScope(m_imGuiPass.m_imguiContext);
ImGui::EndFrame();
}
bool ImGuiPass::OnInputTextEventFiltered(const AZStd::string& textUTF8)
{
auto imguiContextScope = ImguiContextScope(m_imguiContext);

@ -54,7 +54,6 @@ namespace AZ
//! This pass owns and manages activation of an Imgui context.
class ImGuiPass
: public RPI::RenderPass
, private TickBus::Handler
, private AzFramework::InputChannelEventListener
, private AzFramework::InputTextEventListener
{
@ -76,10 +75,6 @@ namespace AZ
//! Allows draw data from other imgui contexts to be rendered on this context.
void RenderImguiDrawData(const ImDrawData& drawData);
// TickBus::Handler overrides...
int GetTickOrder() override;
void OnTick(float deltaTime, AZ::ScriptTimePoint timePoint) override;
// AzFramework::InputTextEventListener overrides...
bool OnInputTextEventFiltered(const AZStd::string& textUTF8) override;
@ -99,6 +94,35 @@ namespace AZ
void BuildCommandListInternal(const RHI::FrameGraphExecuteContext& context) override;
private:
//! Class which connects to the tick handler using the tick order required at the start of an ImGui frame.
class TickHandlerFrameStart : protected TickBus::Handler
{
public:
TickHandlerFrameStart(ImGuiPass& imGuiPass);
protected:
// TickBus::Handler overrides...
int GetTickOrder() override;
void OnTick(float deltaTime, AZ::ScriptTimePoint timePoint) override;
private:
ImGuiPass& m_imGuiPass;
};
//! Class which connects to the tick handler using the tick order required at the end of an ImGui frame.
class TickHandlerFrameEnd : protected TickBus::Handler
{
public:
TickHandlerFrameEnd(ImGuiPass& imGuiPass);
protected:
// TickBus::Handler overrides...
int GetTickOrder() override;
void OnTick(float deltaTime, AZ::ScriptTimePoint timePoint) override;
private:
ImGuiPass& m_imGuiPass;
};
struct DrawInfo
{
@ -112,6 +136,8 @@ namespace AZ
void Init();
ImGuiContext* m_imguiContext = nullptr;
TickHandlerFrameStart m_tickHandlerFrameStart;
TickHandlerFrameEnd m_tickHandlerFrameEnd;
RHI::Ptr<RPI::PipelineStateForDraw> m_pipelineState;
Data::Instance<RPI::Shader> m_shader;

@ -63,8 +63,9 @@ namespace AZ
#if defined(USE_RENDERDOC)
// If RenderDoc is requested, we need to load the library as early as possible (before device queries/factories are made)
bool enableRenderDoc = RHI::QueryCommandLineOption("enableRenderDoc");
#if defined(USE_PIX)
s_pixGpuMarkersEnabled = s_pixGpuMarkersEnabled || enableRenderDoc;
#endif
if (enableRenderDoc && AZ_TRAIT_RENDERDOC_MODULE && !s_renderDocModule)
{
s_renderDocModule = DynamicModuleHandle::Create(AZ_TRAIT_RENDERDOC_MODULE);

@ -56,6 +56,9 @@ AZ_POP_DISABLE_WARNING
// This define controls whether DXR ray tracing support is available on the platform.
#define AZ_DX12_DXR_SUPPORT
// This define is used to initialize the D3D12_ROOT_SIGNATURE_DESC::Flags property.
#define AZ_DX12_ROOT_SIGNATURE_FLAGS D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT
using ID3D12CommandAllocatorX = ID3D12CommandAllocator;
using ID3D12CommandQueueX = ID3D12CommandQueue;
using ID3D12DeviceX = ID3D12Device5;

@ -417,7 +417,7 @@ namespace AZ
}
D3D12_ROOT_SIGNATURE_DESC rootSignatureDesc;
rootSignatureDesc.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT;
rootSignatureDesc.Flags = AZ_DX12_ROOT_SIGNATURE_FLAGS;
rootSignatureDesc.NumParameters = static_cast<uint32_t>(parameters.size());
rootSignatureDesc.pParameters = parameters.data();
rootSignatureDesc.NumStaticSamplers = static_cast<uint32_t>(staticSamplers.size());

@ -86,7 +86,7 @@ namespace AZ
AZStd::wstring shaderExportNameWstring;
AZStd::to_wstring(shaderExportNameWstring, record.m_shaderExportName.GetStringView());
void* shaderIdentifier = stateObjectProperties->GetShaderIdentifier(shaderExportNameWstring.c_str());
const void* shaderIdentifier = stateObjectProperties->GetShaderIdentifier(shaderExportNameWstring.c_str());
memcpy(mappedData, shaderIdentifier, D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES);
mappedData += D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES;

@ -43,6 +43,10 @@ namespace AZ
// Rendering -> Idle
// -> Queued (Rendering will transition to Queued if a pass was queued with the PassSystem during Rendering)
//
// Any State -> Orphaned (transition to Orphaned state can be outside the jurisdiction of the pass and so can happen from any state)
// Orphaned -> Queued (When coming out of Orphaned state, pass will queue itself for build. In practice this
// (almost?) never happens as orphaned passes are re-created in most if not all cases.)
//
enum class PassState : u8
{
// Default value, you should only ever see this in the Pass constructor
@ -92,7 +96,10 @@ namespace AZ
// |
// V
// Pass is currently rendering. Pass must be in Idle state before entering this state
Rendering
Rendering,
// Special state: Orphaned State, pass was removed from it's parent and is awaiting deletion
Orphaned
};
// This enum keeps track of what actions the pass is queued for with the pass system

@ -147,6 +147,11 @@ namespace AZ
m_treeDepth = m_parent->m_treeDepth + 1;
m_path = ConcatPassName(m_parent->m_path, m_name);
m_flags.m_partOfHierarchy = m_parent->m_flags.m_partOfHierarchy;
if (m_state == PassState::Orphaned)
{
QueueForBuildAndInitialization();
}
}
void Pass::RemoveFromParent()
@ -154,7 +159,7 @@ namespace AZ
AZ_RPI_PASS_ASSERT(m_parent != nullptr, "Trying to remove pass from parent but pointer to the parent pass is null.");
m_parent->RemoveChild(Ptr<Pass>(this));
m_queueState = PassQueueState::NoQueue;
m_state = PassState::Idle;
m_state = PassState::Orphaned;
}
void Pass::OnOrphan()
@ -162,6 +167,8 @@ namespace AZ
m_parent = nullptr;
m_flags.m_partOfHierarchy = false;
m_treeDepth = 0;
m_queueState = PassQueueState::NoQueue;
m_state = PassState::Orphaned;
}
// --- Getters & Setters ---

@ -175,7 +175,8 @@ namespace AtomToolsFramework
Base::StartCommon(systemEntity);
m_traceLogger.PrepareLogFile(GetBuildTargetName() + ".log");
const bool clearLogFile = GetSettingOrDefault("/O3DE/AtomToolsFramework/Application/ClearLogOnStart", false);
m_traceLogger.OpenLogFile(GetBuildTargetName() + ".log", clearLogFile);
AzToolsFramework::AssetDatabase::AssetDatabaseRequestsBus::Handler::BusConnect();
AzToolsFramework::AssetBrowser::AssetDatabaseLocationNotificationBus::Broadcast(

@ -146,11 +146,17 @@ namespace AtomToolsFramework
if (auto existingScene = scene->FindSubsystem<AZ::RPI::ScenePtr>())
{
m_viewportContext->SetRenderScene(*existingScene);
if (auto auxGeomFP = existingScene->get()->GetFeatureProcessor<AZ::RPI::AuxGeomFeatureProcessorInterface>())
// If we have a render pipeline, use it and ensure an AuxGeom feature processor is installed.
// Otherwise, fall through and ensure a render pipeline is installed for this scene.
if (m_viewportContext->GetCurrentPipeline())
{
m_auxGeom = auxGeomFP->GetOrCreateDrawQueueForView(m_defaultCamera.get());
if (auto auxGeomFP = existingScene->get()->GetFeatureProcessor<AZ::RPI::AuxGeomFeatureProcessorInterface>())
{
m_auxGeom = auxGeomFP->GetOrCreateDrawQueueForView(m_defaultCamera.get());
}
return;
}
return;
}
AZ::RPI::ScenePtr atomScene;

@ -306,7 +306,6 @@ namespace MaterialEditor
{
if (!preset)
{
AZ_Warning("MaterialViewportRenderer", false, "Attempting to set invalid lighting preset.");
return;
}
@ -347,7 +346,6 @@ namespace MaterialEditor
{
if (!preset)
{
AZ_Warning("MaterialViewportRenderer", false, "Attempting to set invalid model preset.");
return;
}

@ -46,6 +46,14 @@ namespace AZ::Render
return;
}
// Update the mesh deformers (perform cpu skinning and morphing) when needed.
if (renderFlags[EMotionFX::ActorRenderFlag::RENDER_AABB] || renderFlags[EMotionFX::ActorRenderFlag::RENDER_FACENORMALS] ||
renderFlags[EMotionFX::ActorRenderFlag::RENDER_TANGENTS] || renderFlags[EMotionFX::ActorRenderFlag::RENDER_VERTEXNORMALS] ||
renderFlags[EMotionFX::ActorRenderFlag::RENDER_WIREFRAME])
{
instance->UpdateMeshDeformers(0.0f, true);
}
const RPI::Scene* scene = RPI::Scene::GetSceneForEntityId(m_entityId);
const RPI::ViewportContextPtr viewport = AZ::Interface<AZ::RPI::ViewportContextRequestsInterface>::Get()->GetViewportContextByScene(scene);
AzFramework::DebugDisplayRequests* debugDisplay = GetDebugDisplay(viewport->GetId());

@ -322,6 +322,10 @@ namespace AudioControls
connection->m_value = value;
return connection;
}
case EACEControlType::eACET_ENVIRONMENT:
{
return AZStd::make_shared<IAudioConnection>(control->GetId());
}
}
}
else
@ -571,11 +575,11 @@ namespace AudioControls
case eACET_RTPC:
return eWCT_WWISE_RTPC;
case eACET_SWITCH:
return AUDIO_IMPL_INVALID_TYPE;
return (eWCT_WWISE_SWITCH | eWCT_WWISE_GAME_STATE);
case eACET_SWITCH_STATE:
return (eWCT_WWISE_SWITCH | eWCT_WWISE_GAME_STATE | eWCT_WWISE_RTPC);
case eACET_ENVIRONMENT:
return (eWCT_WWISE_AUX_BUS | eWCT_WWISE_SWITCH | eWCT_WWISE_GAME_STATE | eWCT_WWISE_RTPC);
return (eWCT_WWISE_AUX_BUS | eWCT_WWISE_RTPC);
case eACET_PRELOAD:
return eWCT_WWISE_SOUND_BANK;
}

@ -168,6 +168,12 @@ namespace AudioControls
m_pATLControlsTree->setModel(pProxyModel);
m_pProxyModel = pProxyModel;
QAction* pAction = new QAction(tr("Delete"), this);
pAction->setShortcutContext(Qt::WidgetWithChildrenShortcut);
pAction->setShortcut(QKeySequence::Delete);
connect(pAction, SIGNAL(triggered()), this, SLOT(DeleteSelectedControl()));
m_pATLControlsTree->addAction(pAction);
connect(m_pATLControlsTree->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), this, SIGNAL(SelectedControlChanged()));
connect(m_pATLControlsTree->selectionModel(), SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)), this, SLOT(StopControlExecution()));
connect(m_pTreeModel, SIGNAL(itemChanged(QStandardItem*)), this, SLOT(ItemModified(QStandardItem*)));
@ -802,6 +808,21 @@ namespace AudioControls
{
AZ::StringFunc::Path::StripExtension(sControlName);
}
else if (eControlType == eACET_SWITCH_STATE)
{
if (!pATLParent->SwitchStateConnectionCheck(pAudioSystemControl))
{
QMessageBox messageBox(this);
messageBox.setStandardButtons(QMessageBox::Ok);
messageBox.setDefaultButton(QMessageBox::Ok);
messageBox.setWindowTitle("Audio Controls Editor");
messageBox.setText("Not in the same switch group, connection failed.");
if (messageBox.exec() == QMessageBox::Ok)
{
return;
}
}
}
CATLControl* pTargetControl2 = m_pTreeModel->CreateControl(eControlType, sControlName, pATLParent);
if (pTargetControl2)
{

@ -368,4 +368,36 @@ namespace AudioControls
}
}
bool CATLControl::SwitchStateConnectionCheck(IAudioSystemControl* middlewareControl)
{
if (IAudioSystemEditor* audioSystemImpl = CAudioControlsEditorPlugin::GetImplementationManager()->GetImplementation())
{
CID parentID = middlewareControl->GetParent()->GetId();
EACEControlType compatibleType = audioSystemImpl->ImplTypeToATLType(middlewareControl->GetType());
if (compatibleType == EACEControlType::eACET_SWITCH_STATE && m_type == EACEControlType::eACET_SWITCH)
{
for (auto& child : m_children)
{
for (int j = 0; child && j < child->ConnectionCount(); ++j)
{
TConnectionPtr tmpConnection = child->GetConnectionAt(j);
if (tmpConnection)
{
IAudioSystemControl* tmpMiddlewareControl = audioSystemImpl->GetControl(tmpConnection->GetID());
EACEControlType controlType = audioSystemImpl->ImplTypeToATLType(tmpMiddlewareControl->GetType());
if (tmpMiddlewareControl && controlType == EACEControlType::eACET_SWITCH_STATE)
{
if (parentID != ACE_INVALID_CID && tmpMiddlewareControl->GetParent()->GetId() != parentID)
{
return false;
}
}
}
}
}
}
}
return true;
}
} // namespace AudioControls

@ -144,6 +144,8 @@ namespace AudioControls
void SignalConnectionAdded(IAudioSystemControl* middlewareControl);
void SignalConnectionRemoved(IAudioSystemControl* middlewareControl);
bool SwitchStateConnectionCheck(IAudioSystemControl* middlewareControl);
private:
void SetId(CID id);
void SetType(EACEControlType type);

@ -11,7 +11,7 @@
#include <ATLControlsModel.h>
#include <AudioControlsEditorPlugin.h>
#include <ImplementationManager.h>
#include <QStandardItemModel>
#include <QList>
@ -273,6 +273,51 @@ namespace AudioControls
pControl->m_connectedControls = m_connectedControls;
pModel->OnControlModified(pControl);
auto& tmpConnectedControls1 =
connectedControls.size() > m_connectedControls.size() ? connectedControls : m_connectedControls;
auto& tmpConnectedControls2 =
connectedControls.size() > m_connectedControls.size() ? m_connectedControls : connectedControls;
for (auto& connection1 : tmpConnectedControls1)
{
bool bCheck = true;
for (auto& connection2 : tmpConnectedControls2)
{
if (connection1 == connection2)
{
bCheck = false;
break;
}
}
if (!bCheck)
{
continue;
}
if (IAudioSystemEditor* audioSystemImpl = CAudioControlsEditorPlugin::GetImplementationManager()->GetImplementation())
{
if (IAudioSystemControl* middlewareControl = audioSystemImpl->GetControl(connection1->GetID()))
{
if (connectedControls.size() > m_connectedControls.size())
{
audioSystemImpl->ConnectionRemoved(middlewareControl);
pControl->SignalConnectionRemoved(middlewareControl);
}
else
{
TConnectionPtr connection =
audioSystemImpl->CreateConnectionToControl(pControl->GetType(), middlewareControl);
if (connection)
{
pControl->SignalConnectionAdded(middlewareControl);
}
}
pControl->SignalControlModified();
}
}
}
m_name = name;
m_scope = scope;
m_isAutoLoad = isAutoLoad;

@ -128,6 +128,22 @@ namespace AudioControls
}
else
{
if (m_control->GetType() == EACEControlType::eACET_SWITCH_STATE)
{
if (!m_control->GetParent()->SwitchStateConnectionCheck(middlewareControl))
{
QMessageBox messageBox(this);
messageBox.setStandardButtons(QMessageBox::Ok);
messageBox.setDefaultButton(QMessageBox::Ok);
messageBox.setWindowTitle("Audio Controls Editor");
messageBox.setText("Not in the same switch group, connection failed.");
if (messageBox.exec() == QMessageBox::Ok)
{
return;
}
}
}
connection = audioSystemImpl->CreateConnectionToControl(m_control->GetType(), middlewareControl);
if (connection)
{

@ -225,6 +225,36 @@ namespace AudioControls
{
pItem->setFlags(pItem->flags() & ~Qt::ItemIsDragEnabled);
}
if (compatibleType == EACEControlType::eACET_SWITCH_STATE)
{
IAudioSystemControl* pControl = pAudioSystemEditorImpl->GetControl(GetItemId(pItem));
if (pControl && !pControl->IsLocalized())
{
size_t nConnect = 0;
for (int i = 0; i < pControl->GetParent()->ChildCount(); ++i)
{
IAudioSystemControl* child = pControl->GetParent()->GetChildAt(i);
if (child && child->IsConnected())
{
++nConnect;
}
}
QTreeWidgetItem* pParentItem = GetItem(pControl->GetParent()->GetId(), pControl->GetParent()->IsLocalized());
if (pParentItem)
{
if (nConnect > 0 && nConnect == pControl->GetParent()->ChildCount())
{
pParentItem->setForeground(0, m_connectedColor);
}
else
{
pParentItem->setForeground(0, m_disconnectedColor);
}
}
}
}
}
}

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

Loading…
Cancel
Save