Merge branch 'main' into Atom/dmcdiar/ATOM-15555

This commit is contained in:
Doug McDiarmid
2021-05-27 19:24:16 -07:00
342 changed files with 4335 additions and 5205 deletions
@@ -31,13 +31,13 @@ class TestPythonAssetProcessing(object):
unexpected_lines = []
expected_lines = [
'Mock asset exists',
'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_z_positive_1.azmodel) found',
'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_z_negative_1.azmodel) found',
'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_y_positive_1.azmodel) found',
'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_y_negative_1.azmodel) found',
'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_x_positive_1.azmodel) found',
'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_x_negative_1.azmodel) found',
'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_center_1.azmodel) found'
'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_z_positive.azmodel) found',
'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_z_negative.azmodel) found',
'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_y_positive.azmodel) found',
'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_y_negative.azmodel) found',
'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_x_positive.azmodel) found',
'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_x_negative.azmodel) found',
'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_center.azmodel) found'
]
timeout = 180
halt_on_unexpected = False
@@ -38,16 +38,16 @@ def test_azmodel_product(generatedModelAssetPath, expectedSubId):
assetId = azlmbr.asset.AssetCatalogRequestBus(azlmbr.bus.Broadcast, 'GetAssetIdByPath', generatedModelAssetPath, azModelAssetType, False)
assetIdString = assetId.to_string()
if (assetIdString.endswith(':' + expectedSubId) is False):
raise_and_stop(f'Asset has unexpected asset ID ({assetIdString}) for ({generatedModelAssetPath})!')
raise_and_stop(f'Asset at path {generatedModelAssetPath} has unexpected asset ID ({assetIdString}) for ({generatedModelAssetPath}), expected {expectedSubId}!')
else:
print(f'Expected subId for asset ({generatedModelAssetPath}) found')
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_z_positive_1.azmodel', '10315ae0')
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_z_negative_1.azmodel', '10661093')
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_y_positive_1.azmodel', '10af8810')
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_y_negative_1.azmodel', '10f8c263')
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_x_positive_1.azmodel', '100ac47f')
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_x_negative_1.azmodel', '105d8e0c')
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_center_1.azmodel', '1002d464')
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_z_positive.azmodel', '1024be55')
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_z_negative.azmodel', '1052c94e')
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_y_positive.azmodel', '10130556')
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_y_negative.azmodel', '1065724d')
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_x_positive.azmodel', '10d16e68')
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_x_negative.azmodel', '10a71973')
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_center.azmodel', '10412075')
azlmbr.editor.EditorToolsApplicationRequestBus(azlmbr.bus.Broadcast, 'ExitNoPrompt')
@@ -23,6 +23,25 @@ class TestSurfaceMaskFilter_BasicSurfaceTagCreation(EditorTestHelper):
EditorTestHelper.__init__(self, log_prefix="TestSurfaceMaskFilter_BasicSurfaceTagCreation", args=["level"])
def run_test(self):
"""
Summary:
Verifies basic surface tag value equality
Expected Behavior:
Surface tags of the same name are equal, and different names aren't.
Test Steps:
1) Open level
2) Create 2 new surface tags of identical names and verify they resolve as equal.
3) Create another new tag of a different name and verify they resolve as different.
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
self.log("SurfaceTag test started")
# Create a level
@@ -33,6 +33,25 @@ class TestVegetationInstances_DespawnWhenOutOfRange(EditorTestHelper):
EditorTestHelper.__init__(self, log_prefix='VegetationInstances_DespawnWhenOutOfRange', args=['level'])
def run_test(self):
"""
Summary:
Verifies that vegetation instances properly spawn/despawn based on camera range.
Expected Behavior:
Vegetation instances despawn when out of camera range.
Test Steps:
1) Create a new level
2) Create a simple vegetation area, and set the view position near the spawner. Verify instances plant.
3) Move the view position away from the spawner. Verify instances despawn.
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
# Create a new level
self.test_success = self.create_level(
@@ -28,8 +28,21 @@ class TestGradientGeneratorIncompatibilities(EditorTestHelper):
def run_test(self):
"""
Summary:
Verify that Entities are not active when a Gradient Generator and incompatible component are both present
on the same Entity.
This test verifies that components are disabled when conflicting components are present on the same entity.
Expected Behavior:
Gradient Generator components are incompatible with Vegetation area components.
Test Steps:
1) Create a new level
2) Create a new entity in the level
3) Add each Gradient Generator component to an entity, and add a Vegetation Area component to the same entity
4) Verify that components are only enabled when entity is free of a conflicting component
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
@@ -28,8 +28,21 @@ class TestGradientModifiersIncompatibilities(EditorTestHelper):
def run_test(self):
"""
Summary:
Verify that Entities are not active when a Gradient Modifier and incompatible component are both present
on the same Entity.
This test verifies that components are disabled when conflicting components are present on the same entity.
Expected Behavior:
Gradient Modifier components are incompatible with Vegetation area components.
Test Steps:
1) Create a new level
2) Create a new entity in the level
3) Add each Gradient Modifier component to an entity, and add a Vegetation Area component to the same entity
4) Verify that components are only enabled when entity is free of a conflicting component
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
@@ -9,19 +9,6 @@ remove or modify any license notices. This file is distributed on an "AS IS" BAS
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
"""
The below cases are combined in this script
C2676829
C3961326
C3980659
C3980664
C3980669
C3416548
C2676823
C3961321
C2676826
"""
import os
import sys
@@ -44,7 +44,21 @@ class TestGradientPreviewSettings(EditorTestHelper):
def run_test(self):
"""
Summary:
Verify if the current entity is set to the pin preview to shape entity by default for several components.
This test verifies default values for the pinned entity for Gradient Preview settings.
Expected Behavior:
Pinned entity is self for all gradient generator/modifiers.
Test Steps:
1) Create a new level
2) Create a new entity in the level
3) Add each Gradient Generator component to an entity, and verify the Pin Preview to Shape property is set to
self
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
@@ -31,11 +31,21 @@ class TestGradientSurfaceTagEmitterDependencies(EditorTestHelper):
def run_test(self):
"""
Summary:
Component has a dependency on a Gradient component
This test verifies that the Gradient Surface Tag Emitter component is dependent on a gradient component.
Expected Result:
Component is disabled until a Gradient Generator, Modifier or Gradient Reference component
(and any sub-dependencies) is added to the entity.
Gradient Surface Tag Emitter component is disabled until a Gradient Generator, Modifier or Gradient Reference
component (and any sub-dependencies) is added to the entity.
Test Steps:
1) Open level
2) Create a new entity with a Gradient Surface Tag Emitter component
3) Verify the component is disabled until a dependent component is also added to the entity
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
@@ -28,8 +28,20 @@ class TestGradientTransformRequiresShape(EditorTestHelper):
def run_test(self):
"""
Summary:
Verify that Gradient Transform Modifier component requires a
Shape component before the Entity can become active.
This test verifies that the Gradient Transform Modifier component is dependent on a shape component.
Expected Result:
Gradient Transform Modifier component is disabled until a shape component is added to the entity.
Test Steps:
1) Open level
2) Create a new entity with a Gradient Transform Modifier component
3) Verify the component is disabled until a shape component is also added to the entity
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
@@ -28,8 +28,20 @@ class TestImageGradientRequiresShape(EditorTestHelper):
def run_test(self):
"""
Summary:
Verify that Image Gradient component requires a
Shape component before the Entity can become active.
This test verifies that the Image Gradient component is dependent on a shape component.
Expected Result:
Gradient Transform Modifier component is disabled until a shape component is added to the entity.
Test Steps:
1) Open level
2) Create a new entity with a Image Gradient component
3) Verify the component is disabled until a shape component is also added to the entity
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
@@ -33,6 +33,26 @@ class TestAreaNodeComponentDependency(EditorTestHelper):
EditorTestHelper.__init__(self, log_prefix="AreaNodeComponentDependency", args=["level"])
def run_test(self):
"""
Summary:
This test verifies that the Landscape Canvas nodes can be added to a graph, and correctly create entities with
proper dependent components.
Expected Behavior:
All expected component dependencies are met when adding an area node to a graph.
Test Steps:
1) Create a new level
2) Open Landscape Canvas and create a new graph
3) Drag each of the area nodes to the graph area, and ensure the proper dependent components are added
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
def onEntityCreated(parameters):
global newEntityId
@@ -33,7 +33,25 @@ class TestGradientNodeEntityCreate(EditorTestHelper):
EditorTestHelper.__init__(self, log_prefix="AreaNodeEntityCreate", args=["level"])
def run_test(self):
"""
Summary:
This test verifies that the Landscape Canvas nodes can be added to a graph, and correctly create entities.
Expected Behavior:
New entities are created when dragging area nodes to graph area.
Test Steps:
1) Create a new level
2) Open Landscape Canvas and create a new graph
3) Drag each of the area nodes to the graph area, and ensure a new entity is created
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
def onEntityCreated(parameters):
global newEntityId
newEntityId = parameters[0]
@@ -34,7 +34,26 @@ class TestAreaNodeEntityDelete(EditorTestHelper):
EditorTestHelper.__init__(self, log_prefix="AreaNodeEntityDelete", args=["level"])
def run_test(self):
"""
Summary:
This test verifies that the Landscape Canvas node deletion properly cleans up entities in the Editor.
Expected Behavior:
Entities are removed when area nodes are deleted from a graph.
Test Steps:
1) Create a new level
2) Open Landscape Canvas and create a new graph
3) Drag each of the area nodes to the graph area, and ensure a new entity is created
4) Delete the nodes, and ensure the newly created entities are removed
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
def onEntityCreated(parameters):
global createdEntityId
createdEntityId = parameters[0]
@@ -9,24 +9,6 @@ remove or modify any license notices. This file is distributed on an "AS IS" BAS
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
"""
C22602072 - Graph is updated when underlying components are added/removed
1. Open Level.
2. Find LandscapeCanvas named entity.
3. Ensure Vegetation Distribution Component is present on the BushSpawner entity.
4. Open graph and ensure Distribution Filter wrapped node is present.
5. Delete the Vegetation Distribution Filter component from the BushSpawner entity via Entity Inspector.
6. Ensure the Vegetation Distribution Filter component was deleted from the BushSpawner entity and node is no longer
present in the graph.
7. Add Vegetation Altitude Filter to the BushSpawner entity through Entity Inspector.
8. Ensure Altitude Filter was added to the BushSpawner node in the open graph.
9. Add a new entity with unique name as a child of the Landscape Canvas entity.
10. Add a Box Shape component to the new child entity.
11. Ensure Box Shape node is present on the open graph.
"""
import os
import sys
@@ -50,6 +32,36 @@ class TestComponentUpdatesUpdateGraph(EditorTestHelper):
EditorTestHelper.__init__(self, log_prefix="ComponentUpdatesUpdateGraph", args=["level"])
def run_test(self):
"""
Summary:
This test verifies that the Landscape Canvas graphs update properly when components are added/removed outside of
Landscape Canvas.
Expected Behavior:
Graphs properly reflect component changes made to entities outside of Landscape Canvas.
Test Steps:
1. Open Level
2. Find LandscapeCanvas named entity
3. Ensure Vegetation Distribution Component is present on the BushSpawner entity
4. Open graph and ensure Distribution Filter wrapped node is present
5. Delete the Vegetation Distribution Filter component from the BushSpawner entity via Entity Inspector
6. Ensure the Vegetation Distribution Filter component was deleted from the BushSpawner entity and node is
no longer present in the graph
7. Add Vegetation Altitude Filter to the BushSpawner entity through Entity Inspector
8. Ensure Altitude Filter was added to the BushSpawner node in the open graph
9. Add a new entity with unique name as a child of the Landscape Canvas entity
10. Add a Box Shape component to the new child entity
11. Ensure Box Shape node is present on the open graph
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
# Create a new empty level and instantiate LC_BushFlowerBlender.slice
self.test_success = self.create_level(
self.args["level"],
@@ -37,6 +37,25 @@ class TestCreateNewGraph(EditorTestHelper):
print("New root entity created")
def run_test(self):
"""
Summary:
This test verifies that new graphs can be created in Landscape Canvas.
Expected Behavior:
New graphs can be created, and proper entity is created to hold graph data with a Landscape Canvas component.
Test Steps:
1) Create a new level
2) Open Landscape Canvas and create a new graph
3) Ensures the root entity created contains a Landscape Canvas component
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
self.test_success = self.create_level(
self.args["level"],
heightmap_resolution=128,
@@ -33,7 +33,25 @@ class TestDisabledNodeDuplication(EditorTestHelper):
EditorTestHelper.__init__(self, log_prefix="DisabledNodeDuplication", args=["level"])
def run_test(self):
"""
Summary:
This test verifies Editor stability after duplicating disabled Landscape Canvas nodes.
Expected Behavior:
Editor remains stable and free of crashes.
Test Steps:
1) Create a new level
2) Open Landscape Canvas and create a new graph
3) Create several new nodes, disable the nodes via disabling/deleting components, and duplicate the nodes
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
def onEntityCreated(parameters):
global newEntityId
newEntityId = parameters[0]
@@ -9,17 +9,6 @@ remove or modify any license notices. This file is distributed on an "AS IS" BAS
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
"""
C30813586 - Editor remains stable after Undoing deletion of a node on a slice entity
1. Open level with instantiated slice.
2. Open the graph.
3. Find the BushSpawner's Vegetation Layer Spawner node.
4. Delete the node.
5. Undo to restore the node.
"""
import os
import sys
@@ -44,7 +33,26 @@ class TestUndoNodeDeleteSlice(EditorTestHelper):
EditorTestHelper.__init__(self, log_prefix="UndoNodeDeleteSlice", args=["level"])
def run_test(self):
"""
Summary:
This test verifies Editor stability after undoing the deletion of nodes on a slice entity.
Expected Behavior:
Editor remains stable and free of crashes.
Test Steps:
1) Create a new level
2) Instantiate a slice with a Landscape Canvas setup
3) Find a specific node on the graph, and delete it
4) Restore the node with Undo
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
# Create a new empty level and instantiate LC_BushFlowerBlender.slice
self.test_success = self.create_level(
self.args["level"],
@@ -34,6 +34,27 @@ class TestGradientMixerNodeConstruction(EditorTestHelper):
EditorTestHelper.__init__(self, log_prefix="GradientMixerNodeConstruction", args=["level"])
def run_test(self):
"""
Summary:
This test verifies a Gradient Mixer vegetation setup can be constructed through Landscape Canvas.
Expected Behavior:
Entities contain all required components and component references after creating nodes and setting connections
on a Landscape Canvas graph.
Test Steps:
1) Create a new level
2) Open Landscape Canvas and create a new graph
3) Add all necessary nodes to the graph and set connections to form a Gradient Mixer setup
4) Verify all components and component references were properly set during graph construction
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
def onEntityCreated(parameters):
global newEntityId
@@ -33,6 +33,25 @@ class TestGradientModifierNodeEntityCreate(EditorTestHelper):
EditorTestHelper.__init__(self, log_prefix="GradientModifierNodeEntityCreate", args=["level"])
def run_test(self):
"""
Summary:
This test verifies that the Landscape Canvas nodes can be added to a graph, and correctly create entities.
Expected Behavior:
New entities are created when dragging Gradient Modifier nodes to graph area.
Test Steps:
1) Create a new level
2) Open Landscape Canvas and create a new graph
3) Drag each of the Gradient Modifier nodes to the graph area, and ensure a new entity is created
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
def onEntityCreated(parameters):
global newEntityId
@@ -34,7 +34,26 @@ class TestGradientModifierNodeEntityDelete(EditorTestHelper):
EditorTestHelper.__init__(self, log_prefix="GradientModifierNodeEntityDelete", args=["level"])
def run_test(self):
"""
Summary:
This test verifies that the Landscape Canvas node deletion properly cleans up entities in the Editor.
Expected Behavior:
Entities are removed when Gradient Modifier nodes are deleted from a graph.
Test Steps:
1) Create a new level
2) Open Landscape Canvas and create a new graph
3) Drag each of the Gradient Modifier nodes to the graph area, and ensure a new entity is created
4) Delete the nodes, and ensure the newly created entities are removed
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
def onEntityCreated(parameters):
global createdEntityId
createdEntityId = parameters[0]
@@ -33,6 +33,27 @@ class TestGradientNodeComponentDependency(EditorTestHelper):
EditorTestHelper.__init__(self, log_prefix="GradientNodeComponentDependency", args=["level"])
def run_test(self):
"""
Summary:
This test verifies that the Landscape Canvas nodes can be added to a graph, and correctly create entities with
proper dependent components.
Expected Behavior:
All expected component dependencies are met when adding a Gradient Modifier node to a graph.
Test Steps:
1) Create a new level
2) Open Landscape Canvas and create a new graph
3) Drag each of the Gradient Modifier nodes to the graph area, and ensure the proper dependent components are
added
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
def onEntityCreated(parameters):
global newEntityId
@@ -32,6 +32,25 @@ class TestGradientNodeEntityCreate(EditorTestHelper):
EditorTestHelper.__init__(self, log_prefix="GradientNodeEntityCreate", args=["level"])
def run_test(self):
"""
Summary:
This test verifies that the Landscape Canvas nodes can be added to a graph, and correctly create entities.
Expected Behavior:
New entities are created when dragging Gradient nodes to graph area.
Test Steps:
1) Create a new level
2) Open Landscape Canvas and create a new graph
3) Drag each of the Gradient nodes to the graph area, and ensure a new entity is created
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
def onEntityCreated(parameters):
global newEntityId
@@ -34,6 +34,26 @@ class TestGradientNodeEntityDelete(EditorTestHelper):
EditorTestHelper.__init__(self, log_prefix="GradientNodeEntityDelete", args=["level"])
def run_test(self):
"""
Summary:
This test verifies that the Landscape Canvas node deletion properly cleans up entities in the Editor.
Expected Behavior:
Entities are removed when Gradient nodes are deleted from a graph.
Test Steps:
1) Create a new level
2) Open Landscape Canvas and create a new graph
3) Drag each of the Gradient nodes to the graph area, and ensure a new entity is created
4) Delete the nodes, and ensure the newly created entities are removed
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
def onEntityCreated(parameters):
global createdEntityId
@@ -31,6 +31,26 @@ class TestGraphClosedOnEntityDelete(EditorTestHelper):
EditorTestHelper.__init__(self, log_prefix="GraphClosedOnEntityDelete", args=["level"])
def run_test(self):
"""
Summary:
This test verifies that Landscape Canvas graphs are auto-closed when the corresponding entity is deleted.
Expected Behavior:
When a Landscape Canvas root entity is deleted, the corresponding graph automatically closes.
Test Steps:
1) Create a new level
2) Open Landscape Canvas and create a new graph
3) Delete the automatically created entity
4) Verify the open graph is closed
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
def onEntityCreated(parameters):
global newRootEntityId
@@ -29,7 +29,26 @@ class TestGraphClosedOnLevelChange(EditorTestHelper):
EditorTestHelper.__init__(self, log_prefix="GraphClosedOnLevelChange", args=["level"])
def run_test(self):
"""
Summary:
This test verifies that Landscape Canvas graphs are auto-closed when the currently open level changes.
Expected Behavior:
When a new level is loaded in the Editor, open Landscape Canvas graphs are automatically closed.
Test Steps:
1) Create a new level
2) Open Landscape Canvas and create a new graph
3) Open a different level
4) Verify the open graph is closed
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
# Create a new empty level
self.test_success = self.create_level(
self.args["level"],
@@ -29,6 +29,26 @@ class TestGraphClosedTabbedGraph(EditorTestHelper):
EditorTestHelper.__init__(self, log_prefix="GraphClosedTabbedGraph", args=["level"])
def run_test(self):
"""
Summary:
This test verifies that Landscape Canvas tabbed graphs can be independently closed.
Expected Behavior:
Closing a tabbed graph only closes the appropriate graph.
Test Steps:
1) Create a new level
2) Open Landscape Canvas and create several new graphs
3) Close one of the open graphs
4) Ensure the graph properly closed, and other open graphs remain open
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
# Create a new empty level
self.test_success = self.create_level(
@@ -9,21 +9,6 @@ remove or modify any license notices. This file is distributed on an "AS IS" BAS
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
"""
C22715182 - Components are updated when nodes are added/removed/updated
1. Open Level.
2. Open the graph on LC_BushFlowerBlender.slice
3. Find the Rotation Modifier node on the BushSpawner entity
4. Delete the Rotation Modifier node
5. Ensure the Vegetation Rotation Modifier component is removed from the BushSpawner entity
6. Delete the Vegetation Layer Spawner node from the graph
7. Ensure BushSpawner entity is deleted
8. Change connection from second Rotation Modifier node to a different Gradient
9. Ensure Gradient reference on component is updated
"""
import os
import sys
@@ -50,6 +35,31 @@ class TestGraphUpdatesUpdateComponents(EditorTestHelper):
EditorTestHelper.__init__(self, log_prefix="GraphUpdatesUpdateComponents", args=["level"])
def run_test(self):
"""
Summary:
This test verifies that components are properly updated as nodes are added/removed/updated.
Expected Behavior:
Landscape Canvas node CRUD properly updates component entities.
Test Steps:
1. Open Level.
2. Open the graph on LC_BushFlowerBlender.slice
3. Find the Rotation Modifier node on the BushSpawner entity
4. Delete the Rotation Modifier node
5. Ensure the Vegetation Rotation Modifier component is removed from the BushSpawner entity
6. Delete the Vegetation Layer Spawner node from the graph
7. Ensure BushSpawner entity is deleted
8. Change connection from second Rotation Modifier node to a different Gradient
9. Ensure Gradient reference on component is updated
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
# Create a new empty level and instantiate LC_BushFlowerBlender.slice
self.test_success = self.create_level(
self.args["level"],
@@ -30,6 +30,26 @@ class TestLandscapeCanvasComponentAddedRemoved(EditorTestHelper):
EditorTestHelper.__init__(self, log_prefix="LandscapeCanvasComponentAddedRemoved", args=["level"])
def run_test(self):
"""
Summary:
This test verifies that the Landscape Canvas component can be added to/removed from an entity.
Expected Behavior:
Closing a tabbed graph only closes the appropriate graph.
Test Steps:
1) Create a new level
2) Create a new entity
3) Add a Landscape Canvas component to the entity
4) Remove the Landscape Canvas component from the entity
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
# Create a new empty level
self.test_success = self.create_level(
@@ -30,12 +30,21 @@ class TestLandscapeCanvasSliceCreateInstantiate(EditorTestHelper):
def run_test(self):
"""
Summary:
C22602016 A slice containing the LandscapeCanvas component can be created/instantiated.
A slice containing the LandscapeCanvas component can be created/instantiated.
Expected Result:
Slice is created and processed successfully and free of errors/warnings.
Another copy of the slice is instantiated.
Slice is created/processed/instantiated successfully and free of errors/warnings.
Test Steps:
1) Create a new level
2) Create a new entity with a Landscape Canvas component
3) Create a slice of the new entity
4) Instantiate a new copy of the slice
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
@@ -34,6 +34,27 @@ class TestLayerBlenderNodeConstruction(EditorTestHelper):
EditorTestHelper.__init__(self, log_prefix="LayerBlenderNodeConstruction", args=["level"])
def run_test(self):
"""
Summary:
This test verifies a Layer Blender vegetation setup can be constructed through Landscape Canvas.
Expected Behavior:
Entities contain all required components and component references after creating nodes and setting connections
on a Landscape Canvas graph.
Test Steps:
1) Create a new level
2) Open Landscape Canvas and create a new graph
3) Add all necessary nodes to the graph and set connections to form a Layer Blender setup
4) Verify all components and component references were properly set during graph construction
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
def onEntityCreated(parameters):
global newEntityId
@@ -34,6 +34,25 @@ class TestLayerExtenderNodeComponentEntitySync(EditorTestHelper):
EditorTestHelper.__init__(self, log_prefix="LayerExtenderNodeComponentEntitySync", args=["level"])
def run_test(self):
"""
Summary:
This test verifies that all wrapped nodes can be successfully added to/removed from parent nodes.
Expected Behavior:
All wrapped extender nodes can be added to/removed from appropriate parent nodes.
Test Steps:
1) Create a new level
2) Open Landscape Canvas and create a new graph
3) Add Area Blender and Layer Spawner nodes to the graph, and add/remove each extender node to/from each
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
def onEntityCreated(parameters):
global newEntityId
@@ -33,6 +33,25 @@ class TestShapeNodeEntityCreate(EditorTestHelper):
EditorTestHelper.__init__(self, log_prefix="ShapeNodeEntityCreate", args=["level"])
def run_test(self):
"""
Summary:
This test verifies that the Landscape Canvas nodes can be added to a graph, and correctly create entities.
Expected Behavior:
New entities are created when dragging shape nodes to graph area.
Test Steps:
1) Create a new level
2) Open Landscape Canvas and create a new graph
3) Drag each of the shape nodes to the graph area, and ensure a new entity is created
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
def onEntityCreated(parameters):
global newEntityId
@@ -34,7 +34,27 @@ class TestShapeNodeEntityDelete(EditorTestHelper):
EditorTestHelper.__init__(self, log_prefix="ShapeNodeEntityDelete", args=["level"])
def run_test(self):
"""
Summary:
This test verifies that the Landscape Canvas node deletion properly cleans up entities in the Editor.
Expected Behavior:
Entities are removed when shape nodes are deleted from a graph.
Test Steps:
1) Create a new level
2) Open Landscape Canvas and create a new graph
3) Drag each of the shape nodes to the graph area, and ensure a new entity is created
4) Delete the nodes, and ensure the newly created entities are removed
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
def onEntityCreated(parameters):
global createdEntityId
createdEntityId = parameters[0]
@@ -33,6 +33,27 @@ class TestSlotConnectionsUpdateComponents(EditorTestHelper):
EditorTestHelper.__init__(self, log_prefix="SlotConnectionsUpdateComponents", args=["level"])
def run_test(self):
"""
Summary:
This test verifies that the Landscape Canvas slot connections properly update component references.
Expected Behavior:
A reference created through slot connections in Landscape Canvas is reflected in the Entity Inspector.
Test Steps:
1) Create a new level
2) Open Landscape Canvas and create a new graph
3) Several nodes are added to a graph, and connections are set between the nodes
4) Component references are verified via Entity Inspector
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
# Retrieve the proper component TypeIds per component name
componentNames = [
'Random Noise Gradient',
@@ -172,78 +172,10 @@ namespace AZ
//! Rotation modifiers
//! @{
//! @deprecated Use SetLocalRotation()
//! Sets the entity's rotation in the world.
//! The origin of the axes is the entity's position in world space.
//! @param eulerAnglesRadians A three-dimensional vector, containing Euler angles in radians, to rotate the entity by.
virtual void SetRotation([[maybe_unused]] const AZ::Vector3& eulerAnglesRadians) {}
//! @deprecated Use SetLocalRotation()
//! Sets the entity's rotation around the world's X axis.
//! The origin of the axis is the entity's position in world space.
//! @param eulerAngleRadians The X coordinate Euler angle in radians to use for the entity's rotation.
virtual void SetRotationX([[maybe_unused]] float eulerAngleRadian) {}
//! @deprecated Use SetLocalRotation()
//! Sets the entity's rotation around the world's Y axis.
//! The origin of the axis is the entity's position in world space.
//! @param eulerAngleRadians The Y coordinate Euler angle in radians to use for the entity's rotation.
virtual void SetRotationY([[maybe_unused]] float eulerAngleRadian) {}
//! @deprecated Use SetLocalRotation()
//! Sets the entity's rotation around the world's Z axis.
//! The origin of the axis is the entity's position in world space.
//! @param eulerAngleRadians The Z coordinate Euler angle in radians to use for the entity's rotation.
virtual void SetRotationZ([[maybe_unused]] float eulerAngleRadian) {}
//! @deprecated Use SetLocalRotationQuaternion()
//! Sets the entity's rotation in the world in quaternion notation.
//! The origin of the axes is the entity's position in world space.
//! @param quaternion A quaternion that represents the rotation to use for the entity.
virtual void SetRotationQuaternion([[maybe_unused]] const AZ::Quaternion& quaternion) {}
//! @deprecated Use RotateAroundLocalX()
//! Rotates the entity around the world's X axis.
//! The origin of the axis is the entity's position in world space.
//! @param eulerAngleRadians The Euler angle in radians by which to rotate the entity around the X axis.
virtual void RotateByX([[maybe_unused]] float eulerAngleRadian) {}
//! @deprecated Use RotateAroundLocalY()
//! Rotates the entity around the world's Y axis.
//! The origin of the axis is the entity's position in world space.
//! @param eulerAngleRadians The Euler angle in radians by which to rotate the entity around the Y axis.
virtual void RotateByY([[maybe_unused]] float eulerAngleRadian) {}
//! @deprecated Use RotateAroundLocalZ()
//! Rotates the entity around the world's Z axis.
//! The origin of the axis is the entity's position in world space.
//! @param eulerAngleRadians The Euler angle in radians by which to rotate the entity around the Z axis.
virtual void RotateByZ([[maybe_unused]] float eulerAngleRadian) {}
//! @deprecated Use GetLocalRotation()
//! Gets the entity's rotation in the world in Euler angles rotation in radians.
//! @return A three-dimensional vector, containing Euler angles in radians, that represents the entity's rotation.
virtual AZ::Vector3 GetRotationEulerRadians() { return AZ::Vector3(FLT_MAX); }
//! @deprecated Use GetLocalRotationQuaternion()
//! Gets the entity's rotation in the world in quaternion format.
//! @return A quaternion that represents the entity's rotation in world space.
virtual AZ::Quaternion GetRotationQuaternion() { return AZ::Quaternion::CreateZero(); }
//! @deprecated Use GetLocalRotation()
//! Gets the entity's rotation around the world's X axis.
//! @return The Euler angle in radians by which the the entity is rotated around the X axis in world space.
virtual float GetRotationX() { return FLT_MAX; }
//! @deprecated Use GetLocalRotation()
//! Gets the entity's rotation around the world's Y axis.
//! @return The Euler angle in radians by which the the entity is rotated around the Y axis in world space.
virtual float GetRotationY() { return FLT_MAX; }
//! @deprecated Use GetLocalRotation()
//! Gets the entity's rotation around the world's Z axis.
//! @return The Euler angle in radians by which the the entity is rotated around the Z axis in world space.
virtual float GetRotationZ() { return FLT_MAX; }
virtual void SetWorldRotationQuaternion([[maybe_unused]] const AZ::Quaternion& quaternion) {}
//! Get angles in radian for each principle axis around which the world transform is
//! rotated in the order of z-axis and y-axis and then x-axis.
@@ -35,7 +35,7 @@ namespace AZ
return "Android";
case AZ::IOS:
return "iOS";
case AZ::MAC:
case AZ::MAC_ID:
return "Mac";
case AZ::PROVO:
return "Provo";
@@ -213,7 +213,7 @@ namespace AZ
case PlatformId::IOS:
platformCodes.emplace_back(PlatformCodeNameiOS);
break;
case PlatformId::MAC:
case PlatformId::MAC_ID:
platformCodes.emplace_back(PlatformCodeNameMac);
break;
case PlatformId::PROVO:
@@ -56,7 +56,7 @@ namespace AZ
PC,
ANDROID_ID,
IOS,
MAC,
MAC_ID,
PROVO,
SALEM,
JASPER,
@@ -75,7 +75,7 @@ namespace AZ
Platform_PC = 1 << PlatformId::PC,
Platform_ANDROID = 1 << PlatformId::ANDROID_ID,
Platform_IOS = 1 << PlatformId::IOS,
Platform_MAC = 1 << PlatformId::MAC,
Platform_MAC = 1 << PlatformId::MAC_ID,
Platform_PROVO = 1 << PlatformId::PROVO,
Platform_SALEM = 1 << PlatformId::SALEM,
Platform_JASPER = 1 << PlatformId::JASPER,
@@ -13,5 +13,5 @@
namespace AZ
{
static const PlatformID g_currentPlatform = PlatformID::PLATFORM_APPLE_OSX;
static const PlatformID g_currentPlatform = PlatformID::PLATFORM_APPLE_MAC;
}
@@ -2008,13 +2008,12 @@ namespace AZ::IO
// if no bind root is specified, compute one:
strBindRoot = !bindRoot.empty() ? bindRoot : szFullPath->ParentPath().Native();
// Check if archive file disk exist on disk or inside of pak.
bool bFileExists = IsFileExist(szFullPath->Native());
if (!bFileExists && (nFactoryFlags & ZipDir::CacheFactory::FLAGS_READ_ONLY))
// Check if archive file disk exist on disk.
const bool pakOnDisk = FileIOBase::GetDirectInstance()->Exists(szFullPath->c_str());
if (!pakOnDisk && (nFactoryFlags & ZipDir::CacheFactory::FLAGS_READ_ONLY))
{
// Archive file not found.
AZ_TracePrintf("Archive", "Cannot open Archive file %s\n", szFullPath->c_str());
AZ_TracePrintf("Archive", "Archive file %s does not exist\n", szFullPath->c_str());
return nullptr;
}
@@ -2492,8 +2491,6 @@ namespace AZ::IO
void Archive::FindCompressionInfo(bool& found, AZ::IO::CompressionInfo& info, const AZStd::string_view filename)
{
constexpr uint32_t s_compressionTag = static_cast<uint32_t>('Z') << 24 | static_cast<uint32_t>('C') << 16 | static_cast<uint32_t>('R') << 8 | static_cast<uint32_t>('Y');
if (!found)
{
auto correctedFilename = AZ::IO::FileIOBase::GetDirectInstance()->ResolvePath(filename);
@@ -2519,7 +2516,6 @@ namespace AZ::IO
found = true;
info.m_archiveFilename.InitFromRelativePath(archive->GetFilePath());
info.m_compressionTag.m_code = s_compressionTag;
info.m_offset = pFileData->GetFileDataOffset();
info.m_compressedSize = entry->desc.lSizeCompressed;
info.m_uncompressedSize = entry->desc.lSizeUncompressed;
@@ -2539,9 +2535,8 @@ namespace AZ::IO
break;
}
info.m_decompressor = [&s_compressionTag]([[maybe_unused]] const AZ::IO::CompressionInfo& info, const void* compressed, size_t compressedSize, void* uncompressed, size_t uncompressedBufferSize)->bool
info.m_decompressor = []([[maybe_unused]] const AZ::IO::CompressionInfo& info, const void* compressed, size_t compressedSize, void* uncompressed, size_t uncompressedBufferSize)->bool
{
AZ_Assert(info.m_compressionTag.m_code == s_compressionTag, "Provided compression info isn't supported by this decompressor.");
size_t nSizeUncompressed = uncompressedBufferSize;
return ZipDir::ZipRawUncompress(uncompressed, &nSizeUncompressed, compressed, compressedSize) == 0;
};
@@ -50,6 +50,7 @@ namespace AZ::IO
, tWrite{ writeTime }
{
}
ArchiveFileIterator::ArchiveFileIterator(FindData* findData, AZStd::string_view filename, const FileDesc& fileDesc)
: m_findData{ findData }
, m_filename{ filename }
@@ -108,13 +109,10 @@ namespace AZ::IO
AZ::StringFunc::Path::GetFullPath(directory.c_str(), searchDirectory);
AZ::StringFunc::Path::GetFullFileName(directory.c_str(), pattern);
}
AZ::IO::FileIOBase::GetDirectInstance()->FindFiles(searchDirectory.c_str(), pattern.c_str(), [&](const char* filePath) -> bool
{
AZ::IO::FileDesc fileDesc;
AZStd::string fullFilePath;
AZ::StringFunc::Path::GetFullFileName(filePath, fullFilePath);
AZStd::string filePathEntry{filePath};
if (AZ::IO::FileIOBase::GetDirectInstance()->IsDirectory(filePath))
{
@@ -135,9 +133,8 @@ namespace AZ::IO
fileDesc.tAccess = fileDesc.tWrite;
fileDesc.tCreate = fileDesc.tWrite;
}
[[maybe_unused]] auto result = m_mapFiles.emplace(AZStd::move(fullFilePath), fileDesc);
AZ_Assert(result.second, "Failed to insert FindData entry for %s", fullFilePath.c_str());
[[maybe_unused]] auto result = m_mapFiles.emplace(AZStd::move(filePathEntry), fileDesc);
AZ_Assert(result.second, "Failed to insert FindData entry for filePath %s", filePath);
return true;
});
}
@@ -273,7 +270,9 @@ namespace AZ::IO
}
auto pakFileIter = m_mapFiles.begin();
fileIterator.m_filename = pakFileIter->first;
AZStd::string fullFilePath;
AZ::StringFunc::Path::GetFullFileName(pakFileIter->first.c_str(), fullFilePath);
fileIterator.m_filename = AZStd::move(fullFilePath);
fileIterator.m_fileDesc = pakFileIter->second;
fileIterator.m_lastFetchValid = true;
@@ -1,22 +1,22 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/Component/Component.h>
#include <AzCore/RTTI/RTTI.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/Serialization/EditContextConstants.inl>
#include <AzCore/Serialization/SerializeContext.h>
namespace AzFramework
{
@@ -64,15 +64,13 @@ namespace AzFramework
the EditContext. TController can friend itself to the editor component to make this work if required.
*/
template<typename TController, typename TConfiguration = AZ::ComponentConfig>
class ComponentAdapter
: public AZ::Component
class ComponentAdapter : public AZ::Component
{
public:
AZ_RTTI((ComponentAdapter, "{644A9187-4FDB-42C1-9D59-DD75304B551A}", TController, TConfiguration), AZ::Component);
ComponentAdapter() = default;
ComponentAdapter(const TConfiguration& configuration);
explicit ComponentAdapter(const TConfiguration& configuration);
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& services);
static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& services);
@@ -85,7 +83,6 @@ namespace AzFramework
void Deactivate() override;
protected:
static void Reflect(AZ::ReflectContext* context);
// AZ::Component overrides ...
@@ -1,14 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <AzFramework/Components/ComponentAdapterHelpers.h>
@@ -32,10 +32,12 @@ namespace AzFramework
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
{
// clang-format off
serializeContext->Class<ComponentAdapter, Component>()
->Version(1)
->Field("Controller", &ComponentAdapter::m_controller)
;
// clang-format on
}
}
@@ -66,9 +68,6 @@ namespace AzFramework
GetDependentServicesHelper<TController>(services, typename AZ::HasComponentDependentServices<TController>::type());
}
//////////////////////////////////////////////////////////////////////////
// AZ::Component interface implementation
template<typename TController, typename TConfiguration>
void ComponentAdapter<TController, TConfiguration>::Init()
{
@@ -78,7 +77,7 @@ namespace AzFramework
template<typename TController, typename TConfiguration>
void ComponentAdapter<TController, TConfiguration>::Activate()
{
m_controller.Activate(GetEntityId());
ComponentActivateHelper<TController>::Activate(m_controller, AZ::EntityComponentIdPair(GetEntityId(), GetId()));
}
template<typename TController, typename TConfiguration>
@@ -13,6 +13,7 @@
#pragma once
#include <AzCore/Component/Component.h>
#include <AzCore/Component/EntityBus.h>
namespace AzFramework
{
@@ -27,18 +28,43 @@ namespace AzFramework
template<typename T, typename = void>
struct ComponentInitHelper
{
static void Init(T& common)
static void Init([[maybe_unused]] T& controller)
{
AZ_UNUSED(common);
}
};
template<typename T>
struct ComponentInitHelper<T, AZStd::void_t<decltype(AZStd::declval<T>().Init())>>
{
static void Init(T& common)
static void Init(T& controller)
{
common.Init();
controller.Init();
}
};
template<typename T, typename = void>
struct ComponentActivateHelper
{
static void Activate([[maybe_unused]] T& controller, [[maybe_unused]] const AZ::EntityComponentIdPair& entityComponentIdPair)
{
}
};
template<typename T>
struct ComponentActivateHelper<T, AZStd::void_t<decltype(AZStd::declval<T>().Activate(AZ::EntityId()))>>
{
static void Activate(T& controller, const AZ::EntityComponentIdPair& entityComponentIdPair)
{
controller.Activate(entityComponentIdPair.GetEntityId());
}
};
template<typename T>
struct ComponentActivateHelper<T, AZStd::void_t<decltype(AZStd::declval<T>().Activate(AZ::EntityComponentIdPair()))>>
{
static void Activate(T& controller, const AZ::EntityComponentIdPair& entityComponentIdPair)
{
controller.Activate(entityComponentIdPair);
}
};
@@ -327,99 +327,13 @@ namespace AzFramework
return localZ;
}
void TransformComponent::SetRotation(const AZ::Vector3& eulerAnglesRadian)
void TransformComponent::SetWorldRotationQuaternion(const AZ::Quaternion& quaternion)
{
AZ_Warning("TransformComponent", false, "SetRotation is deprecated, please use SetLocalRotation");
AZ::Transform newWorldTransform = m_worldTM;
newWorldTransform.SetRotation(AZ::ConvertEulerRadiansToQuaternion(eulerAnglesRadian));
SetWorldTM(newWorldTransform);
}
void TransformComponent::SetRotationQuaternion(const AZ::Quaternion& quaternion)
{
AZ_Warning("TransformComponent", false, "SetRotationQuaternion is deprecated, please use SetLocalRotationQuaternion");
AZ::Transform newWorldTransform = m_worldTM;
newWorldTransform.SetRotation(quaternion);
SetWorldTM(newWorldTransform);
}
void TransformComponent::SetRotationX(float eulerAngleRadian)
{
AZ_Warning("TransformComponent", false, "SetRotationX is deprecated, please use SetLocalRotation");
AZ::Transform newWorldTransform = m_worldTM;
newWorldTransform.SetRotation(AZ::Quaternion::CreateRotationX(eulerAngleRadian));
SetWorldTM(newWorldTransform);
}
void TransformComponent::SetRotationY(float eulerAngleRadian)
{
AZ_Warning("TransformComponent", false, "SetRotationY is deprecated, please use SetLocalRotation");
AZ::Transform newWorldTransform = m_worldTM;
newWorldTransform.SetRotation(AZ::Quaternion::CreateRotationY(eulerAngleRadian));
SetWorldTM(newWorldTransform);
}
void TransformComponent::SetRotationZ(float eulerAngleRadian)
{
AZ_Warning("TransformComponent", false, "SetRotationZ is deprecated, please use SetLocalRotation");
AZ::Transform newWorldTransform = m_worldTM;
newWorldTransform.SetRotation(AZ::Quaternion::CreateRotationZ(eulerAngleRadian));
SetWorldTM(newWorldTransform);
}
void TransformComponent::RotateByX(float eulerAngleRadian)
{
AZ_Warning("TransformComponent", false, "RotateByX is deprecated, please use RotateAroundLocalX");
RotateAroundLocalX(eulerAngleRadian);
}
void TransformComponent::RotateByY(float eulerAngleRadian)
{
AZ_Warning("TransformComponent", false, "RotateByY is deprecated, please use RotateAroundLocalY");
RotateAroundLocalY(eulerAngleRadian);
}
void TransformComponent::RotateByZ(float eulerAngleRadian)
{
AZ_Warning("TransformComponent", false, "RotateByZ is deprecated, please use RotateAroundLocalZ");
RotateAroundLocalZ(eulerAngleRadian);
}
AZ::Vector3 TransformComponent::GetRotationEulerRadians()
{
AZ_Warning("TransformComponent", false, "GetRotationEulerRadians is deprecated, please use GetWorldRotation");
return m_worldTM.GetRotation().GetEulerRadians();
}
AZ::Quaternion TransformComponent::GetRotationQuaternion()
{
AZ_Warning("TransformComponent", false, "GetRotationQuaternion is deprecated, please use GetWorldRotationQuaternion");
return m_worldTM.GetRotation();
}
float TransformComponent::GetRotationX()
{
AZ_Warning("TransformComponent", false, "GetRotationX is deprecated, please use GetWorldRotation");
return GetRotationEulerRadians().GetX();
}
float TransformComponent::GetRotationY()
{
AZ_Warning("TransformComponent", false, "GetRotationY is deprecated, please use GetWorldRotation");
return GetRotationEulerRadians().GetY();
}
float TransformComponent::GetRotationZ()
{
AZ_Warning("TransformComponent", false, "GetRotationZ is deprecated, please use GetWorldRotation");
return GetRotationEulerRadians().GetZ();
}
AZ::Vector3 TransformComponent::GetWorldRotation()
{
return m_worldTM.GetRotation().GetEulerRadians();
@@ -830,45 +744,7 @@ namespace AzFramework
->Event("GetLocalX", &AZ::TransformBus::Events::GetLocalX)
->Event("GetLocalY", &AZ::TransformBus::Events::GetLocalY)
->Event("GetLocalZ", &AZ::TransformBus::Events::GetLocalZ)
->Event("RotateByX", &AZ::TransformBus::Events::RotateByX)
->Attribute(AZ::Script::Attributes::Deprecated, true)
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
->Event("RotateByY", &AZ::TransformBus::Events::RotateByY)
->Attribute(AZ::Script::Attributes::Deprecated, true)
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
->Event("RotateByZ", &AZ::TransformBus::Events::RotateByZ)
->Attribute(AZ::Script::Attributes::Deprecated, true)
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
->Event("SetEulerRotation", &AZ::TransformBus::Events::SetRotation)
->Attribute(AZ::Script::Attributes::Deprecated, true)
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
->Event("SetRotationQuaternion", &AZ::TransformBus::Events::SetRotationQuaternion)
->Attribute(AZ::Script::Attributes::Deprecated, true)
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
->Event("SetRotationX", &AZ::TransformBus::Events::SetRotationX)
->Attribute(AZ::Script::Attributes::Deprecated, true)
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
->Event("SetRotationY", &AZ::TransformBus::Events::SetRotationY)
->Attribute(AZ::Script::Attributes::Deprecated, true)
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
->Event("SetRotationZ", &AZ::TransformBus::Events::SetRotationZ)
->Attribute(AZ::Script::Attributes::Deprecated, true)
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
->Event("GetEulerRotation", &AZ::TransformBus::Events::GetRotationEulerRadians)
->Attribute(AZ::Script::Attributes::Deprecated, true)
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
->Event("GetRotationQuaternion", &AZ::TransformBus::Events::GetRotationQuaternion)
->Attribute(AZ::Script::Attributes::Deprecated, true)
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
->Event("GetRotationX", &AZ::TransformBus::Events::GetRotationX)
->Attribute(AZ::Script::Attributes::Deprecated, true)
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
->Event("GetRotationY", &AZ::TransformBus::Events::GetRotationY)
->Attribute(AZ::Script::Attributes::Deprecated, true)
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
->Event("GetRotationZ", &AZ::TransformBus::Events::GetRotationZ)
->Attribute(AZ::Script::Attributes::Deprecated, true)
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
->Event("SetWorldRotationQuaternion", &AZ::TransformBus::Events::SetWorldRotationQuaternion)
->Event("GetWorldRotation", &AZ::TransformBus::Events::GetWorldRotation)
->Event("GetWorldRotationQuaternion", &AZ::TransformBus::Events::GetWorldRotationQuaternion)
->Event("SetLocalRotation", &AZ::TransformBus::Events::SetLocalRotation)
@@ -112,22 +112,7 @@ namespace AzFramework
float GetLocalZ() override;
// Rotation modifiers
void SetRotation(const AZ::Vector3& eulerAnglesRadian) override;
void SetRotationQuaternion(const AZ::Quaternion& quaternion) override;
void SetRotationX(float eulerAngleRadian) override;
void SetRotationY(float eulerAngleRadian) override;
void SetRotationZ(float eulerAngleRadian) override;
void RotateByX(float eulerAngleRadian) override;
void RotateByY(float eulerAngleRadian) override;
void RotateByZ(float eulerAngleRadian) override;
AZ::Vector3 GetRotationEulerRadians() override;
AZ::Quaternion GetRotationQuaternion() override;
float GetRotationX() override;
float GetRotationY() override;
float GetRotationZ() override;
void SetWorldRotationQuaternion(const AZ::Quaternion& quaternion) override;
AZ::Vector3 GetWorldRotation() override;
AZ::Quaternion GetWorldRotationQuaternion() override;
@@ -102,7 +102,7 @@ namespace Physics
/// Is the ragdoll currently simulated?
/// @result True in case the ragdoll is simulated, false if not.
virtual bool IsSimulated() = 0;
virtual bool IsSimulated() const = 0;
/// Writes the state for all of the bodies in the ragdoll to the provided output.
/// The caller owns the output state and can safely manipulate it without affecting the physics simulation.
@@ -41,6 +41,7 @@ namespace AzManipulatorTestFramework
AZStd::optional<AZ::Vector3> ViewportScreenToWorld(const AzFramework::ScreenPoint& screenPosition, float depth) override;
AZStd::optional<AzToolsFramework::ViewportInteraction::ProjectedViewportRay> ViewportScreenToWorldRay(
const AzFramework::ScreenPoint& screenPosition) override;
float DeviceScalingFactor() override;
private:
// ViewportInteractionRequestBus ...
bool GridSnappingEnabled();
@@ -127,4 +127,9 @@ namespace AzManipulatorTestFramework
{
return {};
}
} // namespace AzManipulatorTestFramework
float ViewportInteraction::DeviceScalingFactor()
{
return 1.0f;
}
}// namespace AzManipulatorTestFramework
@@ -57,6 +57,6 @@ namespace AzToolsFramework
virtual void StartPlayInEditor() = 0;
virtual void StopPlayInEditor() = 0;
virtual void CreateNewLevelPrefab(AZStd::string_view filename) = 0;
virtual void CreateNewLevelPrefab(AZStd::string_view filename, const AZStd::string& templateFilename) = 0;
};
}
@@ -265,7 +265,7 @@ namespace AzToolsFramework
return false;
}
void PrefabEditorEntityOwnershipService::CreateNewLevelPrefab(AZStd::string_view filename)
void PrefabEditorEntityOwnershipService::CreateNewLevelPrefab(AZStd::string_view filename, const AZStd::string& templateFilename)
{
AZ::IO::Path relativePath = m_loaderInterface->GetRelativePathToProject(filename);
AzToolsFramework::Prefab::TemplateId templateId = m_prefabSystemComponent->GetTemplateIdFromFilePath(relativePath);
@@ -276,7 +276,7 @@ namespace AzToolsFramework
AZ::Data::AssetInfo assetInfo;
bool sourceInfoFound = false;
AzToolsFramework::AssetSystemRequestBus::BroadcastResult(
sourceInfoFound, &AzToolsFramework::AssetSystemRequestBus::Events::GetSourceInfoBySourcePath, DefaultLevelTemplateName,
sourceInfoFound, &AzToolsFramework::AssetSystemRequestBus::Events::GetSourceInfoBySourcePath, templateFilename.c_str(),
assetInfo, watchFolder);
if (sourceInfoFound)
@@ -292,7 +292,7 @@ namespace AzToolsFramework
levelDefaultDom.CopyFrom(dom, levelDefaultDom.GetAllocator());
Prefab::PrefabDomPath sourcePath("/Source");
sourcePath.Set(levelDefaultDom, assetInfo.m_relativePath.c_str());
sourcePath.Set(levelDefaultDom, relativePath.c_str());
templateId = m_prefabSystemComponent->AddTemplate(relativePath, AZStd::move(levelDefaultDom));
}
@@ -170,7 +170,7 @@ namespace AzToolsFramework
void StartPlayInEditor() override;
void StopPlayInEditor() override;
void CreateNewLevelPrefab(AZStd::string_view filename) override;
void CreateNewLevelPrefab(AZStd::string_view filename, const AZStd::string& templateFilename) override;
protected:
@@ -218,7 +218,5 @@ namespace AzToolsFramework
Prefab::PrefabLoaderInterface* m_loaderInterface;
AzFramework::EntityContextId m_entityContextId;
AZ::SerializeContext m_serializeContext;
static inline constexpr const char* DefaultLevelTemplateName = "Prefabs/Default_Level.prefab";
};
}
@@ -614,7 +614,7 @@ namespace AzToolsFramework
AZ::Quaternion oldEntityRotation;
AZ::TransformBus::EventResult(oldEntityRotation, id, &AZ::TransformBus::Events::GetWorldRotationQuaternion);
transformComponent->SetRotationQuaternion(oldEntityRotation);
transformComponent->SetWorldRotationQuaternion(oldEntityRotation);
// Ensure the existing hierarchy is maintained
AZ::EntityId oldParentEntityId;
@@ -31,7 +31,7 @@ namespace AzToolsFramework
rayProportion, lineSegmentProportion, worldClosestPositionRay, worldClosestPositionLineSegment);
AZ::Transform worldFromLocalNormalized = worldFromLocal;
const AZ::Vector3 scale = worldFromLocalNormalized.ExtractScale() * nonUniformScale;
const AZ::Vector3 scale = worldFromLocalNormalized.ExtractUniformScale() * nonUniformScale;
const AZ::Transform localFromWorldNormalized = worldFromLocalNormalized.GetInverse();
return { (localFromWorldNormalized.TransformPoint(worldClosestPositionLineSegment)) / scale };
@@ -59,7 +59,7 @@ namespace AzToolsFramework
? CalculateSnappedOffset(localTransform.GetTranslation(), axis, gridSize * scaleRecip)
: AZ::Vector3::CreateZero();
const AZ::Vector3 localScale = localTransform.GetScale();
const AZ::Vector3 localScale = AZ::Vector3(localTransform.GetUniformScale());
const AZ::Quaternion localRotation = QuaternionFromTransformNoScaling(localTransform);
// calculate scale amount to snap, to align to round scale value
const AZ::Vector3 scaleSnapOffset = snapping && !gridSnapAction.m_localSnapping
@@ -113,7 +113,7 @@ namespace AzToolsFramework
/// noise in the value returned when dealing with values far from the origin.
inline float ScaleReciprocal(const AZ::Transform& transform)
{
return Round3(transform.GetScale().GetReciprocal().GetMinElement());
return Round3(1.0f / transform.GetUniformScale());
}
/// Find the reciprocal of the non-uniform scale.
@@ -39,7 +39,7 @@ namespace AzToolsFramework
AZ::Transform result;
result.SetRotation(m_space.GetRotation() * localTransform.GetRotation());
result.SetTranslation(m_space.TransformPoint(m_nonUniformScale * localTransform.GetTranslation()));
result.SetScale(m_space.GetScale() * localTransform.GetScale());
result.SetScale(m_space.GetScale() * localTransform.GetUniformScale());
return result;
}
@@ -1,22 +1,22 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzToolsFramework/ToolsComponents/EditorComponentBase.h>
#include <AzToolsFramework/ToolsComponents/EditorVisibilityBus.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/Serialization/EditContextConstants.inl>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzToolsFramework/ToolsComponents/EditorComponentBase.h>
#include <AzToolsFramework/ToolsComponents/EditorVisibilityBus.h>
namespace AzToolsFramework
{
@@ -31,7 +31,7 @@ namespace AzToolsFramework
To use the EditorComponentAdapter, 3 classes are required:
- a class that implements the functions required for TController (see below)
- a configuration struct/class which extends AZ::ComponentConfig
- A runtime component that will be generated by the editor comoinent on export
- A runtime component that will be generated by the editor component on export
The concrete component extends the adapter and implements behavior which is unique to the component.
@@ -64,15 +64,15 @@ namespace AzToolsFramework
the EditContext. TController can friend itself to the editor component to make this work if required.
*/
template<typename TController, typename TRuntimeComponent, typename TConfiguration = AZ::ComponentConfig>
class EditorComponentAdapter
: public EditorComponentBase
class EditorComponentAdapter : public EditorComponentBase
{
public:
AZ_RTTI((EditorComponentAdapter, "{2F5A3669-FFE9-4CD7-B9E2-7FC8100CF1A2}", TController, TRuntimeComponent, TConfiguration), EditorComponentBase);
AZ_RTTI(
(EditorComponentAdapter, "{2F5A3669-FFE9-4CD7-B9E2-7FC8100CF1A2}", TController, TRuntimeComponent, TConfiguration),
EditorComponentBase);
EditorComponentAdapter() = default;
EditorComponentAdapter(const TConfiguration& configuration);
explicit EditorComponentAdapter(const TConfiguration& configuration);
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& services);
static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& services);
@@ -86,7 +86,6 @@ namespace AzToolsFramework
void BuildGameEntity(AZ::Entity* gameEntity) override;
protected:
static void Reflect(AZ::ReflectContext* context);
// AZ::Component overrides ...
@@ -1,14 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <AzFramework/Components/ComponentAdapterHelpers.h>
@@ -28,23 +28,21 @@ namespace AzToolsFramework
template<typename TController, typename TRuntimeComponent, typename TConfiguration>
void EditorComponentAdapter<TController, TRuntimeComponent, TConfiguration>::Reflect(AZ::ReflectContext* context)
{
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
{
serializeContext->Class<EditorComponentAdapter, EditorComponentBase>()
->Version(1)
->Field("Controller", &EditorComponentAdapter::m_controller)
;
serializeContext->Class<EditorComponentAdapter, EditorComponentBase>()->Version(1)->Field(
"Controller", &EditorComponentAdapter::m_controller);
if (AZ::EditContext* editContext = serializeContext->GetEditContext())
{
editContext->Class<EditorComponentAdapter>(
"EditorComponentAdapter", "")
// clang-format off
editContext->Class<EditorComponentAdapter>("EditorComponentAdapter", "")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
->DataElement(AZ::Edit::UIHandlers::Default, &EditorComponentAdapter::m_controller, "Controller", "")
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
->Attribute(AZ::Edit::Attributes::ChangeNotify, &EditorComponentAdapter::OnConfigurationChanged)
;
->Attribute(AZ::Edit::Attributes::ChangeNotify, &EditorComponentAdapter::OnConfigurationChanged);
// clang-format on
}
}
}
@@ -53,27 +51,35 @@ namespace AzToolsFramework
// Get*Services functions
template<typename TController, typename TRuntimeComponent, typename TConfiguration>
void EditorComponentAdapter<TController, TRuntimeComponent, TConfiguration>::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& services)
void EditorComponentAdapter<TController, TRuntimeComponent, TConfiguration>::GetProvidedServices(
AZ::ComponentDescriptor::DependencyArrayType& services)
{
AzFramework::Components::GetProvidedServicesHelper<TController>(services, typename AZ::HasComponentProvidedServices<TController>::type());
AzFramework::Components::GetProvidedServicesHelper<TController>(
services, typename AZ::HasComponentProvidedServices<TController>::type());
}
template<typename TController, typename TRuntimeComponent, typename TConfiguration>
void EditorComponentAdapter<TController, TRuntimeComponent, TConfiguration>::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& services)
void EditorComponentAdapter<TController, TRuntimeComponent, TConfiguration>::GetRequiredServices(
AZ::ComponentDescriptor::DependencyArrayType& services)
{
AzFramework::Components::GetRequiredServicesHelper<TController>(services, typename AZ::HasComponentRequiredServices<TController>::type());
AzFramework::Components::GetRequiredServicesHelper<TController>(
services, typename AZ::HasComponentRequiredServices<TController>::type());
}
template<typename TController, typename TRuntimeComponent, typename TConfiguration>
void EditorComponentAdapter<TController, TRuntimeComponent, TConfiguration>::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& services)
void EditorComponentAdapter<TController, TRuntimeComponent, TConfiguration>::GetIncompatibleServices(
AZ::ComponentDescriptor::DependencyArrayType& services)
{
AzFramework::Components::GetIncompatibleServicesHelper<TController>(services, typename AZ::HasComponentIncompatibleServices<TController>::type());
AzFramework::Components::GetIncompatibleServicesHelper<TController>(
services, typename AZ::HasComponentIncompatibleServices<TController>::type());
}
template<typename TController, typename TRuntimeComponent, typename TConfiguration>
void EditorComponentAdapter<TController, TRuntimeComponent, TConfiguration>::GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& services)
void EditorComponentAdapter<TController, TRuntimeComponent, TConfiguration>::GetDependentServices(
AZ::ComponentDescriptor::DependencyArrayType& services)
{
AzFramework::Components::GetDependentServicesHelper<TController>(services, typename AZ::HasComponentDependentServices<TController>::type());
AzFramework::Components::GetDependentServicesHelper<TController>(
services, typename AZ::HasComponentDependentServices<TController>::type());
}
//////////////////////////////////////////////////////////////////////////
@@ -99,7 +105,8 @@ namespace AzToolsFramework
if (ShouldActivateController())
{
m_controller.Activate(GetEntityId());
AzFramework::Components::ComponentActivateHelper<TController>::Activate(
m_controller, AZ::EntityComponentIdPair(GetEntityId(), GetId()));
}
}
@@ -122,7 +129,8 @@ namespace AzToolsFramework
}
template<typename TController, typename TRuntimeComponent, typename TConfiguration>
bool EditorComponentAdapter<TController, TRuntimeComponent, TConfiguration>::WriteOutConfig(AZ::ComponentConfig* outBaseConfig) const
bool EditorComponentAdapter<TController, TRuntimeComponent, TConfiguration>::WriteOutConfig(
AZ::ComponentConfig* outBaseConfig) const
{
if (auto config = azrtti_cast<TConfiguration*>(outBaseConfig))
{
@@ -139,7 +147,8 @@ namespace AzToolsFramework
if (ShouldActivateController())
{
m_controller.Activate(GetEntityId());
AzFramework::Components::ComponentActivateHelper<TController>::Activate(
m_controller, AZ::EntityComponentIdPair(GetEntityId(), GetId()));
}
return AZ::Edit::PropertyRefreshLevels::None;
@@ -520,91 +520,13 @@ namespace AzToolsFramework
return m_editorTransform.m_translate.GetZ();
}
void TransformComponent::SetRotation(const AZ::Vector3& eulerAnglesRadians)
void TransformComponent::SetWorldRotationQuaternion(const AZ::Quaternion& quaternion)
{
AZ_Warning("AzToolsFramework::TransformComponent", false, "SetRotation is deprecated, please use SetLocalRotation");
AZ::Transform newWorldTransform = GetWorldTM();
newWorldTransform.SetRotation(AZ::ConvertEulerRadiansToQuaternion(eulerAnglesRadians));
SetWorldTM(newWorldTransform);
}
void TransformComponent::SetRotationQuaternion(const AZ::Quaternion& quaternion)
{
AZ_Warning("AzToolsFramework::TransformComponent", false, "SetRotationQuaternion is deprecated, please use SetLocalRotation");
AZ::Transform newWorldTransform = GetWorldTM();
newWorldTransform.SetRotation(quaternion);
SetWorldTM(newWorldTransform);
}
void TransformComponent::SetRotationX(float eulerAngleRadians)
{
AZ_Warning("AzToolsFramework::TransformComponent", false, "SetRotationX is deprecated, please use SetLocalRotation");
AZ::Transform newWorldTransform = GetWorldTM();
newWorldTransform.SetRotation(AZ::Quaternion::CreateRotationX(eulerAngleRadians));
SetWorldTM(newWorldTransform);
}
void TransformComponent::SetRotationY(float eulerAngleRadians)
{
AZ_Warning("AzToolsFramework::TransformComponent", false, "SetRotationY is deprecated, please use SetLocalRotation");
AZ::Transform newWorldTransform = GetWorldTM();
newWorldTransform.SetRotation(AZ::Quaternion::CreateRotationY(eulerAngleRadians));
SetWorldTM(newWorldTransform);
}
void TransformComponent::SetRotationZ(float eulerAngleRadians)
{
AZ_Warning("AzToolsFramework::TransformComponent", false, "SetRotationZ is deprecated, please use SetLocalRotation");
AZ::Transform newWorldTransform = GetWorldTM();
newWorldTransform.SetRotation(AZ::Quaternion::CreateRotationZ(eulerAngleRadians));
SetWorldTM(newWorldTransform);
}
void TransformComponent::RotateByX(float eulerAngleRadians)
{
AZ_Warning("AzToolsFramework::TransformComponent", false, "RotateByX is deprecated, please use RotateAroundLocalX");
SetWorldTM(GetWorldTM() * AZ::Transform::CreateRotationX(eulerAngleRadians));
}
void TransformComponent::RotateByY(float eulerAngleRadians)
{
AZ_Warning("AzToolsFramework::TransformComponent", false, "RotateByY is deprecated, please use RotateAroundLocalY");
SetWorldTM(GetWorldTM() * AZ::Transform::CreateRotationY(eulerAngleRadians));
}
void TransformComponent::RotateByZ(float eulerAngleRadians)
{
AZ_Warning("AzToolsFramework::TransformComponent", false, "RotateByZ is deprecated, please use RotateAroundLocalZ");
SetWorldTM(GetWorldTM() * AZ::Transform::CreateRotationZ(eulerAngleRadians));
}
AZ::Vector3 TransformComponent::GetRotationEulerRadians()
{
AZ_Warning("AzToolsFramework::TransformComponent", false, "GetRotationEulerRadians is deprecated, please use GetWorldRotation");
return GetWorldTM().GetRotation().GetEulerRadians();
}
AZ::Quaternion TransformComponent::GetRotationQuaternion()
{
AZ_Warning("AzToolsFramework::TransformComponent", false, "GetRotationQuaternion is deprecated, please use GetWorldRotationQuaternion");
return GetWorldTM().GetRotation();
}
float TransformComponent::GetRotationX()
{
return GetRotationEulerRadians().GetX();
}
float TransformComponent::GetRotationY()
{
return GetRotationEulerRadians().GetY();
}
float TransformComponent::GetRotationZ()
{
return GetRotationEulerRadians().GetZ();
}
AZ::Vector3 TransformComponent::GetWorldRotation()
{
return GetWorldTM().GetRotation().GetEulerRadians();
@@ -99,22 +99,7 @@ namespace AzToolsFramework
float GetLocalZ() override;
// Rotation modifiers
void SetRotation(const AZ::Vector3& eulerAnglesRadians) override;
void SetRotationQuaternion(const AZ::Quaternion& quaternion) override;
void SetRotationX(float eulerAngleRadians) override;
void SetRotationY(float eulerAngleRadians) override;
void SetRotationZ(float eulerAngleRadians) override;
void RotateByX(float eulerAngleRadians) override;
void RotateByY(float eulerAngleRadians) override;
void RotateByZ(float eulerAngleRadians) override;
AZ::Vector3 GetRotationEulerRadians() override;
AZ::Quaternion GetRotationQuaternion() override;
float GetRotationX() override;
float GetRotationY() override;
float GetRotationZ() override;
void SetWorldRotationQuaternion(const AZ::Quaternion& quaternion) override;
AZ::Vector3 GetWorldRotation() override;
AZ::Quaternion GetWorldRotationQuaternion() override;
@@ -165,15 +165,18 @@ namespace AzToolsFramework
virtual bool AngleSnappingEnabled() = 0;
/// Return the angle snapping/step size.
virtual float AngleStep() = 0;
/// Transform a point in world space to screen space coordinates.
/// Transform a point in world space to screen space coordinates in Qt Widget space.
/// Multiply by DeviceScalingFactor to get the position in viewport pixel space.
virtual AzFramework::ScreenPoint ViewportWorldToScreen(const AZ::Vector3& worldPosition) = 0;
/// Transform a point in screen space coordinates to a vector in world space based on clip space depth.
/// Transform a point from Qt widget screen space to world space based on the given clip space depth.
/// Depth specifies a relative camera depth to project in the range of [0.f, 1.f].
/// Returns the world space position if successful.
virtual AZStd::optional<AZ::Vector3> ViewportScreenToWorld(const AzFramework::ScreenPoint& screenPosition, float depth) = 0;
/// Casts a point in screen space to a ray in world space originating from the viewport camera frustum's near plane.
/// Returns a ray containing the ray's origin and a direction normal, if successful.
virtual AZStd::optional<ProjectedViewportRay> ViewportScreenToWorldRay(const AzFramework::ScreenPoint& screenPosition) = 0;
/// Gets the DPI scaling factor that translates Qt widget space into viewport pixel space.
virtual float DeviceScalingFactor() = 0;
protected:
~ViewportInteractionRequests() = default;
@@ -809,14 +809,12 @@ namespace AzToolsFramework
EntityIdManipulators& entityIdManipulators,
OptionalFrame& pivotOverrideFrame,
ViewportInteraction::KeyboardModifiers& prevModifiers,
bool& transformChangedInternally, SpaceCluster spaceCluster)
bool& transformChangedInternally, const AZStd::optional<ReferenceFrame> spaceLock)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
entityIdManipulators.m_manipulators->SetLocalPosition(action.LocalPosition());
const ReferenceFrame referenceFrame = spaceCluster.m_spaceLock ? spaceCluster.m_currentSpace : ReferenceFrameFromModifiers(action.m_modifiers);
if (action.m_modifiers.Ctrl())
{
// moving with ctrl - setting override
@@ -826,6 +824,8 @@ namespace AzToolsFramework
}
else
{
const ReferenceFrame referenceFrame = spaceLock.value_or(ReferenceFrameFromModifiers(action.m_modifiers));
// note: used for parent and world depending on the current reference frame
const auto pivotOrientation =
ETCS::CalculateSelectionPivotOrientation(
@@ -1298,7 +1298,7 @@ namespace AzToolsFramework
{
UpdateTranslationManipulator(
action, manipulatorEntityIds->m_entityIds, m_entityIdManipulators, m_pivotOverrideFrame, prevModifiers,
m_transformChangedInternally, m_spaceCluster);
m_transformChangedInternally, m_spaceCluster.m_spaceLock);
});
translationManipulators->InstallLinearManipulatorMouseUpCallback(
@@ -1329,7 +1329,7 @@ namespace AzToolsFramework
{
UpdateTranslationManipulator(
action, manipulatorEntityIds->m_entityIds, m_entityIdManipulators, m_pivotOverrideFrame, prevModifiers,
m_transformChangedInternally, m_spaceCluster);
m_transformChangedInternally, m_spaceCluster.m_spaceLock);
});
translationManipulators->InstallPlanarManipulatorMouseUpCallback(
@@ -1359,7 +1359,7 @@ namespace AzToolsFramework
{
UpdateTranslationManipulator(
action, manipulatorEntityIds->m_entityIds, m_entityIdManipulators, m_pivotOverrideFrame, prevModifiers,
m_transformChangedInternally, m_spaceCluster);
m_transformChangedInternally, m_spaceCluster.m_spaceLock);
});
translationManipulators->InstallSurfaceManipulatorMouseUpCallback(
@@ -1437,8 +1437,7 @@ namespace AzToolsFramework
[this, prevModifiers, sharedRotationState]
(const AngularManipulator::Action& action) mutable -> void
{
const ReferenceFrame referenceFrame = m_spaceCluster.m_spaceLock ? m_spaceCluster.m_currentSpace : ReferenceFrameFromModifiers(action.m_modifiers);
const ReferenceFrame referenceFrame = m_spaceCluster.m_spaceLock.value_or(ReferenceFrameFromModifiers(action.m_modifiers));
const AZ::Quaternion manipulatorOrientation = action.m_start.m_rotation * action.m_current.m_delta;
// store the pivot override frame when positioning the manipulator manually (ctrl)
// so we don't lose the orientation when adding/removing entities from the selection
@@ -2605,40 +2604,37 @@ namespace AzToolsFramework
if (buttonId == m_spaceCluster.m_localButtonId)
{
// Unlock
if (m_spaceCluster.m_spaceLock && m_spaceCluster.m_currentSpace == ReferenceFrame::Local)
if (m_spaceCluster.m_spaceLock.has_value() && m_spaceCluster.m_spaceLock.value() == ReferenceFrame::Local)
{
m_spaceCluster.m_spaceLock = false;
m_spaceCluster.m_spaceLock = AZStd::nullopt;
}
else
{
m_spaceCluster.m_spaceLock = true;
m_spaceCluster.m_currentSpace = ReferenceFrame::Local;
m_spaceCluster.m_spaceLock = ReferenceFrame::Local;
}
}
else if (buttonId == m_spaceCluster.m_parentButtonId)
{
// Unlock
if (m_spaceCluster.m_spaceLock && m_spaceCluster.m_currentSpace == ReferenceFrame::Parent)
if (m_spaceCluster.m_spaceLock.has_value() && m_spaceCluster.m_spaceLock.value() == ReferenceFrame::Parent)
{
m_spaceCluster.m_spaceLock = false;
m_spaceCluster.m_spaceLock = AZStd::nullopt;
}
else
{
m_spaceCluster.m_spaceLock = true;
m_spaceCluster.m_currentSpace = ReferenceFrame::Parent;
m_spaceCluster.m_spaceLock = ReferenceFrame::Parent;
}
}
else if (buttonId == m_spaceCluster.m_worldButtonId)
{
// Unlock
if (m_spaceCluster.m_spaceLock && m_spaceCluster.m_currentSpace == ReferenceFrame::World)
if (m_spaceCluster.m_spaceLock.has_value() && m_spaceCluster.m_spaceLock.value() == ReferenceFrame::World)
{
m_spaceCluster.m_spaceLock = false;
m_spaceCluster.m_spaceLock = AZStd::nullopt;
}
else
{
m_spaceCluster.m_spaceLock = true;
m_spaceCluster.m_currentSpace = ReferenceFrame::World;
m_spaceCluster.m_spaceLock = ReferenceFrame::World;
}
}
};
@@ -3361,8 +3357,7 @@ namespace AzToolsFramework
ViewportInteraction::BuildMouseButtons(
QGuiApplication::mouseButtons()), m_boxSelect.Active());
const ReferenceFrame referenceFrame =
m_spaceCluster.m_spaceLock ? m_spaceCluster.m_currentSpace : ReferenceFrameFromModifiers(modifiers);
const ReferenceFrame referenceFrame = m_spaceCluster.m_spaceLock.value_or(ReferenceFrameFromModifiers(modifiers));
UpdateSpaceCluster(referenceFrame);
@@ -106,15 +106,20 @@ namespace AzToolsFramework
World, //!< World space (space aligned to world axes - identity).
};
//! Grouping of viewport ui related state for controlling the current reference space of the Editor.
struct SpaceCluster
{
ViewportUi::ClusterId m_spaceClusterId;
ViewportUi::ButtonId m_localButtonId;
ViewportUi::ButtonId m_parentButtonId;
ViewportUi::ButtonId m_worldButtonId;
AZ::Event<ViewportUi::ButtonId>::Handler m_spaceSelectionHandler;
ReferenceFrame m_currentSpace = ReferenceFrame::Parent;
bool m_spaceLock = false;
SpaceCluster() = default;
// disable copying and moving (implicit)
SpaceCluster(const SpaceCluster&) = delete;
SpaceCluster& operator=(const SpaceCluster&) = delete;
ViewportUi::ClusterId m_spaceClusterId; //!< The id identifying the reference space cluster.
ViewportUi::ButtonId m_localButtonId; //!< Local reference space button id.
ViewportUi::ButtonId m_parentButtonId; //!< Parent reference space button id.
ViewportUi::ButtonId m_worldButtonId; //!< World reference space button id.
AZ::Event<ViewportUi::ButtonId>::Handler m_spaceSelectionHandler; //!< Callback for when a space cluster button is pressed.
AZStd::optional<ReferenceFrame> m_spaceLock; //!< Locked reference frame to use if set.
};
//! Entity selection/interaction handling.
@@ -265,6 +270,9 @@ namespace AzToolsFramework
void SetEntityLocalScale(AZ::EntityId entityId, float localScale);
void SetEntityLocalRotation(AZ::EntityId entityId, const AZ::Vector3& localRotation);
// Responsible for keeping the space cluster in sync with the current reference frame.
void UpdateSpaceCluster(ReferenceFrame referenceFrame);
AZ::EntityId m_hoveredEntityId; //!< What EntityId is the mouse currently hovering over (if any).
AZ::EntityId m_cachedEntityIdUnderCursor; //!< Store the EntityId on each mouse move for use in Display.
AZ::EntityId m_editorCameraComponentEntityId; //!< The EditorCameraComponent EntityId if it is set.
@@ -297,9 +305,7 @@ namespace AzToolsFramework
AZ::Event<ViewportUi::ButtonId>::Handler m_transformModeSelectionHandler; //!< Event handler for the Viewport UI cluster.
AzFramework::ClickDetector m_clickDetector; //!< Detect different types of mouse click.
AzFramework::CursorState m_cursorState; //!< Track the mouse position and delta movement each frame.
SpaceCluster m_spaceCluster;
void UpdateSpaceCluster(ReferenceFrame referenceFrame);
SpaceCluster m_spaceCluster; //!< Related viewport ui state for controlling the current reference space.
};
//! The ETCS (EntityTransformComponentSelection) namespace contains functions and data used exclusively by
@@ -137,8 +137,20 @@ namespace AzAssetBrowserRequestHandlerPrivate
entityName = AZStd::string::format("Entity%d", GetIEditor()->GetObjectManager()->GetObjectCount());
}
AZ::Entity* newEntity = aznew AZ::Entity(entityName.c_str());
EditorEntityContextRequestBus::Broadcast(&EditorEntityContextRequests::AddRequiredComponents, *newEntity);
AZ::EntityId targetEntityId;
EditorRequests::Bus::BroadcastResult(targetEntityId, &EditorRequests::CreateNewEntityAtPosition, worldTransform.GetTranslation(), AZ::EntityId());
AZ::Entity* newEntity = nullptr;
AZ::ComponentApplicationBus::BroadcastResult(newEntity, &AZ::ComponentApplicationRequests::FindEntity, targetEntityId);
if (newEntity == nullptr)
{
return;
}
newEntity->SetName(entityName);
newEntity->Deactivate();
// Create component.
AZ::Component* newComponent = newEntity->CreateComponent(componentTypeId);
@@ -151,15 +163,7 @@ namespace AzAssetBrowserRequestHandlerPrivate
newEntity->AddComponent(newComponent);
}
// Set entity position.
auto* transformComponent = newEntity->FindComponent<Components::TransformComponent>();
if (transformComponent)
{
transformComponent->SetWorldTM(worldTransform);
}
// Add the entity to the editor context, which activates it and creates the sandbox object.
EditorEntityContextRequestBus::Broadcast(&EditorEntityContextRequests::AddEditorEntity, newEntity);
newEntity->Activate();
// set asset after components have been activated in AddEditorEntity method
if (newComponent)
+1
View File
@@ -173,6 +173,7 @@ ly_add_target(
RUNTIME_DEPENDENCIES
Legacy::CrySystem
Legacy::EditorLib
ProjectManager
)
ly_add_translations(
TARGETS Editor
+1 -1
View File
@@ -3111,7 +3111,7 @@ CCryEditApp::ECreateLevelResult CCryEditApp::CreateLevel(const QString& levelNam
auto* service = AZ::Interface<AzToolsFramework::PrefabEditorEntityOwnershipInterface>::Get();
if (service)
{
service->CreateNewLevelPrefab((const char*)fullyQualifiedLevelName.toUtf8());
service->CreateNewLevelPrefab(fullyQualifiedLevelName.toUtf8().constData(), DefaultLevelTemplateName);
}
}
+2
View File
@@ -358,6 +358,8 @@ AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
private:
static inline constexpr const char* DefaultLevelTemplateName = "Prefabs/Default_Level.prefab";
struct PythonOutputHandler;
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
AZStd::shared_ptr<PythonOutputHandler> m_pythonOutputHandler;
+1
View File
@@ -200,6 +200,7 @@ public:
{
return {};
}
float DeviceScalingFactor() override { return 1.0f; }
// AzToolsFramework::ViewportFreezeRequestBus
bool IsViewportInputFrozen() override;
+2 -2
View File
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c042fce57915fc749abc7b37de765fd697c3c4d7de045a3d44805aa0ce29901a
size 107016
oid sha256:d717f77fe01f45df934a61bbc215e5322447d21e16f3cebcf2a02f148178f266
size 106449
@@ -14,6 +14,7 @@
#include <AssetImporterPlugin.h>
#include <AssetImporterWindow.h>
#include <QtViewPaneManager.h>
#include <SceneAPI/SceneCore/Events/AssetImportRequest.h>
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
#include <LyViewPaneNames.h>
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
@@ -37,6 +38,10 @@ AssetImporterPlugin::AssetImporterPlugin(IEditor* editor)
opt.showInMenu = false; // this view pane is used to display scene settings, but the user never opens it directly through the Tools menu
opt.saveKeyName = "Scene Settings (PREVIEW)"; // user settings for this pane were originally saved with PREVIEW, so ensure that's how they are loaded as well, even after the PREVIEW is removed from the name
AzToolsFramework::RegisterViewPane<AssetImporterWindow>(m_toolName.c_str(), LyViewPane::CategoryTools, opt);
AzToolsFramework::ToolsApplicationRequestBus::Broadcast(
&AzToolsFramework::ToolsApplicationRequests::CreateAndAddEntityFromComponentTags,
AZStd::vector<AZ::Crc32>({ AZ::SceneAPI::Events::AssetImportRequest::GetAssetImportRequestComponentTag() }), "AssetImportersEntity");
}
void AssetImporterPlugin::Release()
@@ -622,13 +622,14 @@ bool ApplicationManager::Activate()
{
if (!AssetUtilities::ComputeAssetRoot(m_systemRoot))
{
AZ_Error(AssetProcessor::ConsoleChannel, false, "Unable to compute the asset root for the project, this application cannot launch until this is fixed.");
return false;
}
auto projectName = AssetUtilities::ComputeProjectName();
if (projectName.isEmpty())
{
AZ_Error(AssetProcessor::ConsoleChannel, false, "Unable to detect name of current game project. Is bootstrap.cfg appropriately configured?");
AZ_Error(AssetProcessor::ConsoleChannel, false, "Unable to detect name of current game project. Configure your game project name to launch this application.");
return false;
}
@@ -1191,6 +1191,7 @@ bool ApplicationManagerBase::Activate()
QDir projectCache;
if (!AssetUtilities::ComputeProjectCacheRoot(projectCache))
{
AZ_Error("AssetProcessor", false, "Could not compute project cache root, please configure your project correctly to launch Asset Processor.");
return false;
}
@@ -1200,22 +1201,27 @@ bool ApplicationManagerBase::Activate()
// Shutdown if the disk has less than 128MB of free space
if (!CheckSufficientDiskSpace(projectCache.absolutePath(), 128 * 1024 * 1024, true))
{
// CheckSufficientDiskSpace reports an error if disk space is low.
return false;
}
bool appInited = InitApplicationServer();
if (!appInited)
{
AZ_Error(
"AssetProcessor", false, "InitApplicationServer failed, something internal to Asset Processor has failed, please report this to support if you encounter this error.");
return false;
}
if (!InitAssetDatabase())
{
// AssetDatabaseConnection::OpenDatabase reports any errors it encounters.
return false;
}
if (!ApplicationManager::Activate())
{
// ApplicationManager::Activate() reports any errors it encounters.
return false;
}
@@ -1230,6 +1236,7 @@ bool ApplicationManagerBase::Activate()
m_isCurrentlyLoadingGems = true;
if (!ActivateModules())
{
// ActivateModules reports any errors it encounters.
m_isCurrentlyLoadingGems = false;
return false;
}
@@ -1299,6 +1306,7 @@ bool ApplicationManagerBase::Activate()
{
if (!m_applicationServer->startListening())
{
// startListening reports any errors it encounters.
return false;
}
}
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c042fce57915fc749abc7b37de765fd697c3c4d7de045a3d44805aa0ce29901a
size 107016
oid sha256:d717f77fe01f45df934a61bbc215e5322447d21e16f3cebcf2a02f148178f266
size 106449
@@ -38,21 +38,8 @@ namespace AZ
{
namespace FbxSceneBuilder
{
static AZ::SceneAPI::FbxSceneImporter::FbxImportRequestHandler* g_fbxImporter = nullptr;
static AZStd::vector<AZ::ComponentDescriptor*> g_componentDescriptors;
void Initialize()
{
// Currently it's still needed to explicitly create an instance of this instead of letting
// it be a normal component. This is because ResourceCompilerScene needs to return
// the list of available extensions before it can start the application.
if (!g_fbxImporter)
{
g_fbxImporter = aznew AZ::SceneAPI::FbxSceneImporter::FbxImportRequestHandler();
g_fbxImporter->Activate();
}
}
void Reflect(AZ::SerializeContext* /*context*/)
{
// Descriptor registration is done in Reflect instead of Initialize because the ResourceCompilerScene initializes the libraries before
@@ -64,6 +51,7 @@ namespace AZ
{
// Global importer and behavior
g_componentDescriptors.push_back(FbxSceneBuilder::FbxImporter::CreateDescriptor());
g_componentDescriptors.push_back(FbxSceneImporter::FbxImportRequestHandler::CreateDescriptor());
// Node and attribute importers
g_componentDescriptors.push_back(AssImpBitangentStreamImporter::CreateDescriptor());
@@ -110,13 +98,6 @@ namespace AZ
g_componentDescriptors.clear();
g_componentDescriptors.shrink_to_fit();
}
if (g_fbxImporter)
{
g_fbxImporter->Deactivate();
delete g_fbxImporter;
g_fbxImporter = nullptr;
}
}
} // namespace FbxSceneBuilder
} // namespace SceneAPI
@@ -125,7 +106,6 @@ namespace AZ
extern "C" AZ_DLL_EXPORT void InitializeDynamicModule(void* env)
{
AZ::Environment::Attach(static_cast<AZ::EnvironmentInstance>(env));
AZ::SceneAPI::FbxSceneBuilder::Initialize();
}
extern "C" AZ_DLL_EXPORT void Reflect(AZ::SerializeContext* context)
{
@@ -10,12 +10,16 @@
*
*/
#include <AssetProcessor/AssetBuilderSDK/AssetBuilderSDK/AssetBuilderSDK.h>
#include <AzCore/Serialization/EditContextConstants.inl>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzFramework/StringFunc/StringFunc.h>
#include <AzCore/Serialization/Json/JsonSerialization.h>
#include <AzCore/Settings/SettingsRegistry.h>
#include <AzCore/StringFunc/StringFunc.h>
#include <SceneAPI/FbxSceneBuilder/FbxImportRequestHandler.h>
#include <SceneAPI/SceneCore/Containers/Scene.h>
#include <SceneAPI/SceneCore/Events/CallProcessorBus.h>
#include <SceneAPI/SceneCore/Events/ImportEventContext.h>
#include <SceneAPI/FbxSceneBuilder/FbxImportRequestHandler.h>
namespace AZ
{
@@ -23,10 +27,23 @@ namespace AZ
{
namespace FbxSceneImporter
{
const char* FbxImportRequestHandler::s_extension = ".fbx";
void SceneImporterSettings::Reflect(AZ::ReflectContext* context)
{
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context); serializeContext)
{
serializeContext->Class<SceneImporterSettings>()
->Version(2)
->Field("SupportedFileTypeExtensions", &SceneImporterSettings::m_supportedFileTypeExtensions);
}
}
void FbxImportRequestHandler::Activate()
{
if (auto* settingsRegistry = AZ::SettingsRegistry::Get())
{
settingsRegistry->GetObject(m_settings, "/O3DE/SceneAPI/AssetImporter");
}
BusConnect();
}
@@ -37,21 +54,31 @@ namespace AZ
void FbxImportRequestHandler::Reflect(ReflectContext* context)
{
SceneImporterSettings::Reflect(context);
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
if (serializeContext)
{
serializeContext->Class<FbxImportRequestHandler, SceneCore::BehaviorComponent>()->Version(1);
serializeContext->Class<FbxImportRequestHandler, AZ::Component>()->Version(1)->Attribute(
AZ::Edit::Attributes::SystemComponentTags,
AZStd::vector<AZ::Crc32>(
{AssetBuilderSDK::ComponentTags::AssetBuilder,
AssetImportRequest::GetAssetImportRequestComponentTag()}));
}
}
void FbxImportRequestHandler::GetSupportedFileExtensions(AZStd::unordered_set<AZStd::string>& extensions)
{
extensions.insert(s_extension);
extensions.insert(m_settings.m_supportedFileTypeExtensions.begin(), m_settings.m_supportedFileTypeExtensions.end());
}
Events::LoadingResult FbxImportRequestHandler::LoadAsset(Containers::Scene& scene, const AZStd::string& path, const Uuid& guid, [[maybe_unused]] RequestingApplication requester)
{
if (!AzFramework::StringFunc::Path::IsExtension(path.c_str(), s_extension))
AZStd::string extension;
StringFunc::Path::GetExtension(path.c_str(), extension);
if (!m_settings.m_supportedFileTypeExtensions.contains(extension))
{
return Events::LoadingResult::Ignored;
}
@@ -73,6 +100,11 @@ namespace AZ
return Events::LoadingResult::AssetFailure;
}
}
void FbxImportRequestHandler::GetProvidedServices(ComponentDescriptor::DependencyArrayType& provided)
{
provided.emplace_back(AZ_CRC_CE("AssetImportRequestHandler"));
}
} // namespace Import
} // namespace SceneAPI
} // namespace AZ
@@ -21,12 +21,21 @@ namespace AZ
{
namespace FbxSceneImporter
{
struct SceneImporterSettings
{
AZ_TYPE_INFO(SceneImporterSettings, "{8BB6C7AD-BF99-44DC-9DA1-E7AD3F03DC10}");
static void Reflect(AZ::ReflectContext* context);
AZStd::unordered_set<AZStd::string> m_supportedFileTypeExtensions;
};
class FbxImportRequestHandler
: public SceneCore::BehaviorComponent
: public AZ::Component
, public Events::AssetImportRequestBus::Handler
{
public:
AZ_COMPONENT(FbxImportRequestHandler, "{9F4B189C-0A96-4F44-A5F0-E087FF1561F8}", SceneCore::BehaviorComponent);
AZ_COMPONENT(FbxImportRequestHandler, "{9F4B189C-0A96-4F44-A5F0-E087FF1561F8}");
~FbxImportRequestHandler() override = default;
@@ -38,8 +47,13 @@ namespace AZ
Events::LoadingResult LoadAsset(Containers::Scene& scene, const AZStd::string& path, const Uuid& guid,
RequestingApplication requester) override;
static void GetProvidedServices(ComponentDescriptor::DependencyArrayType& provided);
private:
static const char* s_extension;
SceneImporterSettings m_settings;
static constexpr const char* SettingsFilename = "AssetImporterSettings.json";
};
} // namespace FbxSceneImporter
} // namespace SceneAPI
@@ -37,7 +37,7 @@ namespace AZ
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
if (serializeContext)
{
serializeContext->Class<AssImpMeshImporter, SceneCore::LoadingComponent>()->Version(1);
serializeContext->Class<AssImpMeshImporter, SceneCore::LoadingComponent>()->Version(2);
}
}
@@ -71,6 +71,11 @@ namespace AZ
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple;
using MutexType = AZStd::recursive_mutex;
static AZ::Crc32 GetAssetImportRequestComponentTag()
{
return AZ_CRC_CE("AssetImportRequest");
}
virtual ~AssetImportRequest() = 0;
//! Fills the given list with all available file extensions, excluding the extension for the manifest.
@@ -0,0 +1,45 @@
{
"Type": "JsonSerialization",
"Version": 1,
"ClassName": "MultiplatformPresetSettings",
"ClassData": {
"DefaultPreset": {
"UUID": "{10D4D7D8-23E2-4FC5-BE6A-DA9949D2C603}",
"Name": "LUT_R32F",
"FileMasks": ["_lutr32f"],
"SourceColor": "Linear",
"DestColor": "Linear",
"PixelFormat": "R32F"
},
"PlatformsPresets": {
"es3": {
"UUID": "{10D4D7D8-23E2-4FC5-BE6A-DA9949D2C603}",
"Name": "LUT_R32F",
"SourceColor": "Linear",
"DestColor": "Linear",
"PixelFormat": "R32F"
},
"ios": {
"UUID": "{10D4D7D8-23E2-4FC5-BE6A-DA9949D2C603}",
"Name": "LUT_R32F",
"SourceColor": "Linear",
"DestColor": "Linear",
"PixelFormat": "R32F"
},
"osx_gl": {
"UUID": "{10D4D7D8-23E2-4FC5-BE6A-DA9949D2C603}",
"Name": "LUT_R32F",
"SourceColor": "Linear",
"DestColor": "Linear",
"PixelFormat": "R32F"
},
"provo": {
"UUID": "{10D4D7D8-23E2-4FC5-BE6A-DA9949D2C603}",
"Name": "LUT_R32F",
"SourceColor": "Linear",
"DestColor": "Linear",
"PixelFormat": "R32F"
}
}
}
}
@@ -0,0 +1,59 @@
{
"Type": "JsonSerialization",
"Version": 1,
"ClassName": "MultiplatformPresetSettings",
"ClassData": {
"DefaultPreset": {
"UUID": "{ABDFCED1-0565-4B7B-9BC1-82C473BCEEA2}",
"Name": "LUT_RGBA16",
"SourceColor": "Linear",
"DestColor": "Linear",
"FileMasks": [
"_lutrgba16"
],
"PixelFormat": "R16G16B16A16"
},
"PlatformsPresets": {
"es3": {
"UUID": "{ABDFCED1-0565-4B7B-9BC1-82C473BCEEA2}",
"Name": "LUT_RGBA16",
"SourceColor": "Linear",
"DestColor": "Linear",
"FileMasks": [
"_lutrgba16"
],
"PixelFormat": "R16G16B16A16"
},
"ios": {
"UUID": "{ABDFCED1-0565-4B7B-9BC1-82C473BCEEA2}",
"Name": "LUT_RGBA16",
"SourceColor": "Linear",
"DestColor": "Linear",
"FileMasks": [
"_lutrgba16"
],
"PixelFormat": "R16G16B16A16"
},
"osx_gl": {
"UUID": "{ABDFCED1-0565-4B7B-9BC1-82C473BCEEA2}",
"Name": "LUT_RGBA16",
"SourceColor": "Linear",
"DestColor": "Linear",
"FileMasks": [
"_lutrgba16"
],
"PixelFormat": "R16G16B16A16"
},
"provo": {
"UUID": "{ABDFCED1-0565-4B7B-9BC1-82C473BCEEA2}",
"Name": "LUT_RGBA16",
"SourceColor": "Linear",
"DestColor": "Linear",
"FileMasks": [
"_lutrgba16"
],
"PixelFormat": "R16G16B16A16"
}
}
}
}
@@ -0,0 +1,59 @@
{
"Type": "JsonSerialization",
"Version": 1,
"ClassName": "MultiplatformPresetSettings",
"ClassData": {
"DefaultPreset": {
"UUID": "{6D75F093-C826-437A-AD94-8631A5A4E8A2}",
"Name": "LUT_RGBA16F",
"SourceColor": "Linear",
"DestColor": "Linear",
"FileMasks": [
"_lutrgba16f"
],
"PixelFormat": "R16G16B16A16F"
},
"PlatformsPresets": {
"es3": {
"UUID": "{6D75F093-C826-437A-AD94-8631A5A4E8A2}",
"Name": "LUT_RGBA16F",
"SourceColor": "Linear",
"DestColor": "Linear",
"FileMasks": [
"_lutrgba16f"
],
"PixelFormat": "R16G16B16A16F"
},
"ios": {
"UUID": "{6D75F093-C826-437A-AD94-8631A5A4E8A2}",
"Name": "LUT_RGBA16F",
"SourceColor": "Linear",
"DestColor": "Linear",
"FileMasks": [
"_lutrgba16f"
],
"PixelFormat": "R16G16B16A16F"
},
"osx_gl": {
"UUID": "{6D75F093-C826-437A-AD94-8631A5A4E8A2}",
"Name": "LUT_RGBA16F",
"SourceColor": "Linear",
"DestColor": "Linear",
"FileMasks": [
"_lutrgba16f"
],
"PixelFormat": "R16G16B16A16F"
},
"provo": {
"UUID": "{6D75F093-C826-437A-AD94-8631A5A4E8A2}",
"Name": "LUT_RGBA16F",
"SourceColor": "Linear",
"DestColor": "Linear",
"FileMasks": [
"_lutrgba16f"
],
"PixelFormat": "R16G16B16A16F"
}
}
}
}
@@ -738,7 +738,7 @@ namespace AZ
}
else if (platformIdentifier == "mac")
{
platformId = AzFramework::PlatformId::MAC;
platformId = AzFramework::PlatformId::MAC_ID;
}
else if (platformIdentifier == "android")
{
@@ -790,7 +790,7 @@ namespace AZ
}
else if (platform == "mac")
{
platformId = AzFramework::PlatformId::MAC;
platformId = AzFramework::PlatformId::MAC_ID;
}
else if (platform == "android")
{
File diff suppressed because it is too large Load Diff
@@ -267,16 +267,16 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float
// Directional light shadow coordinates
lightingData.shadowCoords = IN.m_shadowCoords;
// ------- Occlusion -------
lightingData.diffuseAmbientOcclusion = GetOcclusionInput(MaterialSrg::m_diffuseOcclusionMap, MaterialSrg::m_sampler, IN.m_uv[MaterialSrg::m_diffuseOcclusionMapUvIndex], MaterialSrg::m_diffuseOcclusionFactor, o_diffuseOcclusion_useTexture);
lightingData.specularOcclusion = GetOcclusionInput(MaterialSrg::m_specularOcclusionMap, MaterialSrg::m_sampler, IN.m_uv[MaterialSrg::m_specularOcclusionMapUvIndex], MaterialSrg::m_specularOcclusionFactor, o_specularOcclusion_useTexture);
// ------- Emissive -------
float2 emissiveUv = IN.m_uv[MaterialSrg::m_emissiveMapUvIndex];
lightingData.emissiveLighting = GetEmissiveInput(MaterialSrg::m_emissiveMap, MaterialSrg::m_sampler, emissiveUv, MaterialSrg::m_emissiveIntensity, MaterialSrg::m_emissiveColor.rgb, o_emissiveEnabled, o_emissive_useTexture);
// ------- Occlusion -------
lightingData.diffuseAmbientOcclusion = GetOcclusionInput(MaterialSrg::m_diffuseOcclusionMap, MaterialSrg::m_sampler, IN.m_uv[MaterialSrg::m_diffuseOcclusionMapUvIndex], MaterialSrg::m_diffuseOcclusionFactor, o_diffuseOcclusion_useTexture);
lightingData.specularOcclusion = GetOcclusionInput(MaterialSrg::m_specularOcclusionMap, MaterialSrg::m_sampler, IN.m_uv[MaterialSrg::m_specularOcclusionMapUvIndex], MaterialSrg::m_specularOcclusionFactor, o_specularOcclusion_useTexture);
// ------- Clearcoat -------
// [GFX TODO][ATOM-14603]: Clean up the double uses of these clear coat flags
@@ -287,6 +287,13 @@
"id": "m_specularF0Map"
}
},
{
"id": "useTexture",
"displayName": "Use Texture",
"description": "Whether to use the texture map, or just default to the Factor value.",
"type": "Bool",
"defaultValue": true
},
{
"id": "textureMapUv",
"displayName": "UV",
@@ -299,13 +306,7 @@
"id": "m_specularF0MapUvIndex"
}
},
{
"id": "useTexture",
"displayName": "Use Texture",
"description": "Whether to use the texture map, or just default to the Factor value.",
"type": "Bool",
"defaultValue": true
},
// Consider moving this to the "general" group to be consistent with StandardMultilayerPBR
{
"id": "enableMultiScatterCompensation",
"displayName": "Multiscattering Compensation",
@@ -616,7 +617,7 @@
"type": "float",
"defaultValue": 6.0,
"min": 0.0,
"softMax": 20.0
"softMax": 20.0
},
{
"id": "transmissionDistortion",
@@ -909,7 +910,7 @@
"description": "Center point for scaling and rotation transformations.",
"type": "vector2",
"vectorLabels": [ "U", "V" ],
"defaultValue": [ 0.0, 0.0 ]
"defaultValue": [ 0.5, 0.5 ]
},
{
"id": "tileU",
@@ -1011,18 +1012,18 @@
"type": "HandleSubsurfaceScatteringParameters",
"args": {
"mode": "subsurfaceScattering.transmissionMode",
"scale" : "subsurfaceScattering.transmissionScale",
"power" : "subsurfaceScattering.transmissionPower",
"distortion" : "subsurfaceScattering.transmissionDistortion",
"attenuation" : "subsurfaceScattering.transmissionAttenuation",
"tintColor" : "subsurfaceScattering.transmissionTint",
"thickness" : "subsurfaceScattering.thickness",
"scale": "subsurfaceScattering.transmissionScale",
"power": "subsurfaceScattering.transmissionPower",
"distortion": "subsurfaceScattering.transmissionDistortion",
"attenuation": "subsurfaceScattering.transmissionAttenuation",
"tintColor": "subsurfaceScattering.transmissionTint",
"thickness": "subsurfaceScattering.thickness",
"enabled": "subsurfaceScattering.enableSubsurfaceScattering",
"scatterDistanceColor" : "subsurfaceScattering.scatterColor",
"scatterDistanceIntensity" : "subsurfaceScattering.scatterDistance",
"scatterDistanceShaderInput" : "m_scatterDistance",
"parametersShaderInput" : "m_transmissionParams",
"tintThickenssShaderInput" : "m_transmissionTintThickness"
"scatterDistanceColor": "subsurfaceScattering.scatterColor",
"scatterDistanceIntensity": "subsurfaceScattering.scatterDistance",
"scatterDistanceShaderInput": "m_scatterDistance",
"parametersShaderInput": "m_transmissionParams",
"tintThickenssShaderInput": "m_transmissionTintThickness"
}
},
{
@@ -1038,8 +1039,8 @@
"type": "UseTexture",
"args": {
"textureProperty": "specularF0.textureMap",
"dependentProperties": ["specularF0.textureMapUv"],
"useTextureProperty": "specularF0.useTexture",
"dependentProperties": ["specularF0.textureMapUv"],
"shaderOption": "o_specularF0_useTexture"
}
},
@@ -369,15 +369,14 @@
],
"parallax": [
{
// Note parallax is enabled by default so that as soon as a user hooks up displacement settings they will see some parallax applied.
// The functor that controls parallax will set o_parallax_feature_enabled=false when all the individual layers have no displacement, so
// a default value of true here will not have any initial impact on performance.
"id": "enable",
"displayName": "Enable",
"description": "Whether to enable the parallax feature for this material.",
"type": "Bool",
"defaultValue": false,
"connection": {
"type": "ShaderOption",
"id": "o_parallax_feature_enabled"
}
"defaultValue": true
},
{
"id": "parallaxUv",
@@ -409,7 +408,7 @@
"description": "Quality of parallax mapping.",
"type": "Enum",
"enumValues": [ "Low", "Medium", "High", "Ultra" ],
"defaultValue": "Medium",
"defaultValue": "Low",
"connection": {
"type": "ShaderOption",
"id": "o_parallax_quality"
@@ -445,7 +444,7 @@
"description": "Center point for scaling and rotation transformations.",
"type": "vector2",
"vectorLabels": [ "U", "V" ],
"defaultValue": [ 0.0, 0.0 ]
"defaultValue": [ 0.5, 0.5 ]
},
{
"id": "tileU",
@@ -1141,7 +1140,7 @@
"displayName": "Scale",
"description": "The total height of the displacement texture map in local model units.",
"type": "Float",
"defaultValue": 0.0,
"defaultValue": 0.05,
"min": 0.0,
"softMax": 0.1,
"connection": {
@@ -1170,7 +1169,7 @@
"description": "Center point for scaling and rotation transformations.",
"type": "vector2",
"vectorLabels": [ "U", "V" ],
"defaultValue": [ 0.0, 0.0 ]
"defaultValue": [ 0.5, 0.5 ]
},
{
"id": "tileU",
@@ -1847,7 +1846,7 @@
"displayName": "Scale",
"description": "The total height of the displacement texture map in local model units.",
"type": "Float",
"defaultValue": 0.0,
"defaultValue": 0.05,
"min": 0.0,
"softMax": 0.1,
"connection": {
@@ -1876,7 +1875,7 @@
"description": "Center point for scaling and rotation transformations.",
"type": "vector2",
"vectorLabels": [ "U", "V" ],
"defaultValue": [ 0.0, 0.0 ]
"defaultValue": [ 0.5, 0.5 ]
},
{
"id": "tileU",
@@ -2553,7 +2552,7 @@
"displayName": "Scale",
"description": "The total height of the displacement texture map in local model units.",
"type": "Float",
"defaultValue": 0.0,
"defaultValue": 0.05,
"min": 0.0,
"softMax": 0.1,
"connection": {
@@ -2582,7 +2581,7 @@
"description": "Center point for scaling and rotation transformations.",
"type": "vector2",
"vectorLabels": [ "U", "V" ],
"defaultValue": [ 0.0, 0.0 ]
"defaultValue": [ 0.5, 0.5 ]
},
{
"id": "tileU",
@@ -35,6 +35,10 @@ function GetMaterialPropertyDependencies()
}
end
function GetShaderOptionDependencies()
return {"o_parallax_feature_enabled"}
end
-- These values must align with LayerBlendSource in StandardMultilayerPBR_Common.azsli.
LayerBlendSource_BlendMaskTexture = 0
LayerBlendSource_BlendMaskVertexColors = 1
@@ -50,6 +54,39 @@ function BlendSourceUsesDisplacement(context)
return blendSourceIncludesDisplacement
end
function IsParallaxNeededForLayer(context, layerNumber)
local enableLayer = true
if(layerNumber > 1) then -- layer 1 is always enabled, it is the implicit base layer
enableLayer = context:GetMaterialPropertyValue_bool("blend.enableLayer" .. layerNumber)
end
if not enableLayer then
return false
end
local parallaxGroupName = "layer" .. layerNumber .. "_parallax."
local factor = context:GetMaterialPropertyValue_float(parallaxGroupName .. "factor")
local offset = context:GetMaterialPropertyValue_float(parallaxGroupName .. "offset")
if factor == 0.0 and offset == 0.0 then
return false
end
local hasTexture = nil ~= context:GetMaterialPropertyValue_Image(parallaxGroupName .. "textureMap")
local useTexture = context:GetMaterialPropertyValue_bool(parallaxGroupName .. "useTexture")
if not hasTexture or not useTexture then
factorLayer = 0.0
end
if factor == 0.0 and offset == 0.0 then
return false
end
return true
end
-- Calculates the min and max displacement height values encompassing all enabled layers.
-- @return a table with two values {min,max}. Negative values are below the surface and positive values are above the surface.
function CalcOverallHeightRange(context)
@@ -114,21 +151,32 @@ function Process(context)
local heightMinMax = CalcOverallHeightRange(context)
context:SetShaderConstant_float("m_displacementMin", heightMinMax[0])
context:SetShaderConstant_float("m_displacementMax", heightMinMax[1])
local parallaxFeatureEnabled = context:GetMaterialPropertyValue_bool("parallax.enable")
if parallaxFeatureEnabled then
if not IsParallaxNeededForLayer(context, 1) and
not IsParallaxNeededForLayer(context, 2) and
not IsParallaxNeededForLayer(context, 3) then
parallaxFeatureEnabled = false
end
end
context:SetShaderOptionValue_bool("o_parallax_feature_enabled", parallaxFeatureEnabled)
end
function ProcessEditor(context)
local enable = context:GetMaterialPropertyValue_bool("parallax.enable")
local enableParallaxSettings = context:GetMaterialPropertyValue_bool("parallax.enable")
local visibility = MaterialPropertyVisibility_Enabled
if(not enable) then
visibility = MaterialPropertyVisibility_Hidden
local parallaxSettingVisibility = MaterialPropertyVisibility_Enabled
if(not enableParallaxSettings) then
parallaxSettingVisibility = MaterialPropertyVisibility_Hidden
end
context:SetMaterialPropertyVisibility("parallax.parallaxUv", visibility)
context:SetMaterialPropertyVisibility("parallax.algorithm", visibility)
context:SetMaterialPropertyVisibility("parallax.quality", visibility)
context:SetMaterialPropertyVisibility("parallax.pdo", visibility)
context:SetMaterialPropertyVisibility("parallax.showClipping", visibility)
context:SetMaterialPropertyVisibility("parallax.parallaxUv", parallaxSettingVisibility)
context:SetMaterialPropertyVisibility("parallax.algorithm", parallaxSettingVisibility)
context:SetMaterialPropertyVisibility("parallax.quality", parallaxSettingVisibility)
context:SetMaterialPropertyVisibility("parallax.pdo", parallaxSettingVisibility)
context:SetMaterialPropertyVisibility("parallax.showClipping", parallaxSettingVisibility)
if BlendSourceUsesDisplacement(context) then
context:SetMaterialPropertyVisibility("blend.displacementBlendDistance", MaterialPropertyVisibility_Enabled)
@@ -601,7 +601,7 @@
"displayName": "Opacity Mode",
"description": "Opacity mode for this texture.",
"type": "Enum",
"enumValues": [ "Opaque", "Cutout", "Blended" ],
"enumValues": [ "Opaque", "Cutout", "Blended", "TintedTransparent" ],
"defaultValue": "Opaque",
"connection": {
"type": "ShaderOption",
@@ -669,12 +669,12 @@
"description": "Center point for scaling and rotation transformations.",
"type": "vector2",
"vectorLabels": [ "U", "V" ],
"defaultValue": [ 0.0, 0.0 ]
"defaultValue": [ 0.5, 0.5 ]
},
{
"id": "tileU",
"displayName": "Tile U",
"description": "Scales texture coordinates in V.",
"description": "Scales texture coordinates in U.",
"type": "float",
"defaultValue": 1.0,
"step": 0.1
@@ -879,13 +879,6 @@
}
],
"parallax": [
{
"id": "enable",
"displayName": "Enable",
"description": "Whether to enable the parallax feature.",
"type": "Bool",
"defaultValue": false
},
{
"id": "textureMap",
"displayName": "Texture Map",
@@ -896,6 +889,13 @@
"id": "m_depthMap"
}
},
{
"id": "useTexture",
"displayName": "Use Texture",
"description": "Whether to use the texture map.",
"type": "Bool",
"defaultValue": true
},
{
"id": "textureMapUv",
"displayName": "UV",
@@ -913,7 +913,7 @@
"displayName": "Heightmap Scale",
"description": "The total height of the heightmap in local model units.",
"type": "Float",
"defaultValue": 0.0,
"defaultValue": 0.05,
"min": 0.0,
"softMax": 0.1,
"connection": {
@@ -951,7 +951,7 @@
"description": "Select the algorithm to use for parallax mapping.",
"type": "Enum",
"enumValues": [ "Basic", "Steep", "POM", "Relief", "ContactRefinement" ],
"defaultValue": "Basic",
"defaultValue": "POM",
"connection": {
"type": "ShaderOption",
"id": "o_parallax_algorithm"
@@ -1139,7 +1139,7 @@
"type": "float",
"defaultValue": 6.0,
"min": 0.0,
"softMax": 20.0
"softMax": 20.0
},
{
"id": "transmissionDistortion",
@@ -1170,7 +1170,7 @@
}
],
"irradiance": [
// Note: this property group is used in the DiffuseGlobalIllumination pass, it is not read by the StandardPBR shader
// Note: this property group is used in the DiffuseGlobalIllumination pass and not by the main forward shader
{
"id": "color",
"displayName": "Color",
@@ -1277,18 +1277,18 @@
"type": "HandleSubsurfaceScatteringParameters",
"args": {
"mode": "subsurfaceScattering.transmissionMode",
"scale" : "subsurfaceScattering.transmissionScale",
"power" : "subsurfaceScattering.transmissionPower",
"distortion" : "subsurfaceScattering.transmissionDistortion",
"attenuation" : "subsurfaceScattering.transmissionAttenuation",
"tintColor" : "subsurfaceScattering.transmissionTint",
"thickness" : "subsurfaceScattering.thickness",
"scale": "subsurfaceScattering.transmissionScale",
"power": "subsurfaceScattering.transmissionPower",
"distortion": "subsurfaceScattering.transmissionDistortion",
"attenuation": "subsurfaceScattering.transmissionAttenuation",
"tintColor": "subsurfaceScattering.transmissionTint",
"thickness": "subsurfaceScattering.thickness",
"enabled": "subsurfaceScattering.enableSubsurfaceScattering",
"scatterDistanceColor" : "subsurfaceScattering.scatterColor",
"scatterDistanceIntensity" : "subsurfaceScattering.scatterDistance",
"scatterDistanceShaderInput" : "m_scatterDistance",
"parametersShaderInput" : "m_transmissionParams",
"tintThickenssShaderInput" : "m_transmissionTintThickness"
"scatterDistanceColor": "subsurfaceScattering.scatterColor",
"scatterDistanceIntensity": "subsurfaceScattering.scatterDistance",
"scatterDistanceShaderInput": "m_scatterDistance",
"parametersShaderInput": "m_transmissionParams",
"tintThickenssShaderInput": "m_transmissionTintThickness"
}
},
{
@@ -1387,15 +1387,6 @@
"file": "StandardPBR_HandleOpacityDoubleSided.lua"
}
},
{
"type": "OverrideDrawList",
"args": {
"triggerProperty": "opacity.mode",
"triggerValue": "Blended",
"shaderIndex": 1,
"drawList": "transparent"
}
},
{
"type": "Lua",
"args": {
@@ -294,6 +294,24 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float
lightingOutput.m_diffuseColor.rgb *= lightingOutput.m_diffuseColor.w; // pre-multiply diffuse
lightingOutput.m_diffuseColor.rgb += lightingOutput.m_specularColor.rgb; // add specular
}
else if (o_opacity_mode == OpacityMode::TintedTransparent)
{
// See OpacityMode::Blended above for the basic method. TintedTransparent adds onto the above concept by supporting
// colored alpha. This is currently a very basic calculation that uses the baseColor as a multiplier with strength
// determined by the alpha. We'll modify this later to be more physically accurate and allow surface depth,
// absorption, and interior color to be specified.
//
// The technique uses dual source blending to allow two separate sources to be part of the blending equation
// even though ultimately only a single render target is being written to. m_diffuseColor is render target 0 and
// m_specularColor render target 1, and the blend mode is (dest * source1color) + (source * 1.0).
//
// This means that m_specularColor.rgb (source 1) is multiplied against the destination, then
// m_diffuseColor.rgb (source) is added to that, and the final result is stored in render target 0.
lightingOutput.m_diffuseColor.rgb *= lightingOutput.m_diffuseColor.w; // pre-multiply diffuse
lightingOutput.m_diffuseColor.rgb += lightingOutput.m_specularColor.rgb; // add specular
lightingOutput.m_specularColor.rgb = baseColor * (1.0 - lightingOutput.m_diffuseColor.w);
}
else
{
// Pack factor and quality, drawback: because of precision limit of float16 cannot represent exact 1, maximum representable value is 0.9961
@@ -60,10 +60,13 @@ function Process(context)
if(opacityMode == OpacityMode_Blended) then
ConfigureAlphaBlending(context:GetShader(ForwardPassIndex))
context:GetShader(ForwardPassIndex):SetDrawListTagOverride("transparent")
elseif(opacityMode == OpacityMode_TintedTransparent) then
ConfigureDualSourceBlending(context:GetShader(ForwardPassIndex))
context:GetShader(ForwardPassIndex):SetDrawListTagOverride("transparent")
else
ResetAlphaBlending(context:GetShader(ForwardPassIndex))
context:GetShader(ForwardPassIndex):SetDrawListTagOverride("") -- reset to default draw list
end
end
@@ -13,7 +13,7 @@
----------------------------------------------------------------------------------------------------
function GetMaterialPropertyDependencies()
return {"parallax.enable", "parallax.textureMap"}
return {"parallax.textureMap", "parallax.useTexture"}
end
function GetShaderOptionDependencies()
@@ -21,27 +21,31 @@ function GetShaderOptionDependencies()
end
function Process(context)
local enable = context:GetMaterialPropertyValue_bool("parallax.enable")
local textureMap = context:GetMaterialPropertyValue_Image("parallax.textureMap")
local useTexture = context:GetMaterialPropertyValue_bool("parallax.useTexture")
local enable = textureMap ~= nil and useTexture
context:SetShaderOptionValue_bool("o_parallax_feature_enabled", enable)
context:SetShaderOptionValue_bool("o_useDepthMap", enable and textureMap ~= nil)
context:SetShaderOptionValue_bool("o_useDepthMap", enable)
end
function ProcessEditor(context)
local enable = context:GetMaterialPropertyValue_bool("parallax.enable")
if enable then
context:SetMaterialPropertyVisibility("parallax.textureMap", MaterialPropertyVisibility_Enabled)
else
context:SetMaterialPropertyVisibility("parallax.textureMap", MaterialPropertyVisibility_Hidden)
end
local textureMap = context:GetMaterialPropertyValue_Image("parallax.textureMap")
local visibility = MaterialPropertyVisibility_Enabled
if(not enable or textureMap == nil) then
visibility = MaterialPropertyVisibility_Hidden
if textureMap ~= nil then
context:SetMaterialPropertyVisibility("parallax.useTexture", MaterialPropertyVisibility_Enabled)
else
context:SetMaterialPropertyVisibility("parallax.useTexture", MaterialPropertyVisibility_Hidden)
end
local useTexture = context:GetMaterialPropertyValue_bool("parallax.useTexture")
local visibility = MaterialPropertyVisibility_Enabled
if(textureMap == nil) then
visibility = MaterialPropertyVisibility_Hidden
elseif not useTexture then
visibility = MaterialPropertyVisibility_Disabled
end
context:SetMaterialPropertyVisibility("parallax.factor", visibility)
context:SetMaterialPropertyVisibility("parallax.offset", visibility)
context:SetMaterialPropertyVisibility("parallax.showClipping", visibility)
@@ -13,7 +13,7 @@
----------------------------------------------------------------------------------------------------
function GetMaterialPropertyDependencies()
return {"opacity.mode", "parallax.enable", "parallax.pdo"}
return {"opacity.mode", "parallax.textureMap", "parallax.useTexture", "parallax.pdo"}
end
OpacityMode_Opaque = 0
@@ -21,41 +21,61 @@ OpacityMode_Cutout = 1
OpacityMode_Blended = 2
OpacityMode_TintedTransparent = 3
function TryGetShaderByTag(context, shaderTag)
if context:HasShaderWithTag(shaderTag) then
return context:GetShaderByTag(shaderTag)
else
return nil
end
end
function TrySetShaderEnabled(shader, enabled)
if shader then
shader:SetEnabled(enabled)
end
end
function Process(context)
local opacityMode = context:GetMaterialPropertyValue_enum("opacity.mode")
local parallaxEnabled = context:GetMaterialPropertyValue_bool("parallax.enable")
local displacementMap = context:GetMaterialPropertyValue_Image("parallax.textureMap")
local useDisplacementMap = context:GetMaterialPropertyValue_bool("parallax.useTexture")
local parallaxEnabled = displacementMap ~= nil and useDisplacementMap
local parallaxPdoEnabled = context:GetMaterialPropertyValue_bool("parallax.pdo")
local depthPass = context:GetShaderByTag("DepthPass")
local shadowMap = context:GetShaderByTag("Shadowmap")
local forwardPassEDS = context:GetShaderByTag("ForwardPass_EDS")
local lowEndForwardEDS = context:GetShaderByTag("LowEndForward_EDS")
local depthPassWithPS = context:GetShaderByTag("DepthPass_WithPS")
local shadowMapWithPS = context:GetShaderByTag("Shadowmap_WithPS")
local forwardPass = context:GetShaderByTag("ForwardPass")
local lowEndForward = context:GetShaderByTag("LowEndForward")
-- Use TryGetShaderByTag because these shaders only exist in StandardPBR but this script is also used for EnhancedPBR
local lowEndForwardEDS = TryGetShaderByTag(context, "LowEndForward_EDS")
local lowEndForward = TryGetShaderByTag(context, "LowEndForward")
if parallaxEnabled and parallaxPdoEnabled then
depthPass:SetEnabled(false)
shadowMap:SetEnabled(false)
forwardPassEDS:SetEnabled(false)
lowEndForwardEDS:SetEnabled(false)
depthPassWithPS:SetEnabled(true)
shadowMapWithPS:SetEnabled(true)
forwardPass:SetEnabled(true)
lowEndForward:SetEnabled(true)
TrySetShaderEnabled(lowEndForwardEDS, false)
TrySetShaderEnabled(lowEndForward, true)
else
depthPass:SetEnabled(opacityMode == OpacityMode_Opaque)
shadowMap:SetEnabled(opacityMode == OpacityMode_Opaque)
forwardPassEDS:SetEnabled((opacityMode == OpacityMode_Opaque) or (opacityMode == OpacityMode_Blended) or (opacityMode == OpacityMode_TintedTransparent))
lowEndForwardEDS:SetEnabled((opacityMode == OpacityMode_Opaque) or (opacityMode == OpacityMode_Blended) or (opacityMode == OpacityMode_TintedTransparent))
depthPassWithPS:SetEnabled(opacityMode == OpacityMode_Cutout)
shadowMapWithPS:SetEnabled(opacityMode == OpacityMode_Cutout)
forwardPass:SetEnabled(opacityMode == OpacityMode_Cutout)
lowEndForward:SetEnabled(opacityMode == OpacityMode_Cutout)
TrySetShaderEnabled(lowEndForwardEDS, (opacityMode == OpacityMode_Opaque) or (opacityMode == OpacityMode_Blended) or (opacityMode == OpacityMode_TintedTransparent))
TrySetShaderEnabled(lowEndForward, opacityMode == OpacityMode_Cutout)
end
context:GetShaderByTag("DepthPassTransparentMin"):SetEnabled((opacityMode == OpacityMode_Blended) or (opacityMode == OpacityMode_TintedTransparent))
@@ -14,6 +14,9 @@
#include <AzCore/base.h>
#include <Atom/RPI.Public/FeatureProcessor.h>
#include <Atom/RHI.Reflect/Size.h>
#include <Atom/RPI.Reflect/Image/StreamingImageAsset.h>
#include <Atom/RPI.Reflect/Image/Image.h>
namespace AZ
{
@@ -23,6 +26,57 @@ namespace AZ
using DiffuseProbeGridHandle = AZStd::shared_ptr<DiffuseProbeGrid>;
enum class DiffuseProbeGridMode : uint8_t
{
RealTime,
Baked,
AutoSelect
};
enum class DiffuseProbeGridTextureNotificationType
{
None,
Ready,
Error
};
struct DiffuseProbeGridTexture
{
const AZStd::shared_ptr<AZStd::vector<uint8_t>> m_data;
RHI::Format m_format;
RHI::Size m_size;
};
static const char* DiffuseProbeGridIrradianceFileName = "Irradiance_lutrgba16.dds";
static const char* DiffuseProbeGridDistanceFileName = "Distance_lutrg32f.dds";
static const char* DiffuseProbeGridRelocationFileName = "Relocation_lutrgba16f.dds";
static const char* DiffuseProbeGridClassificationFileName = "Classification_lutr32f.dds";
using DiffuseProbeGridBakeTexturesCallback = AZStd::function<void(
DiffuseProbeGridTexture irradianceTexture,
DiffuseProbeGridTexture distanceTexture,
DiffuseProbeGridTexture relocationTexture,
DiffuseProbeGridTexture classificationTexture)>;
struct DiffuseProbeGridBakedTextures
{
// irradiance and distance images can be used directly
Data::Instance<RPI::Image> m_irradianceImage;
AZStd::string m_irradianceImageRelativePath;
Data::Instance<RPI::Image> m_distanceImage;
AZStd::string m_distanceImageRelativePath;
// relocation and classification images need to be recreated as RW textures
RHI::ImageDescriptor m_relocationImageDescriptor;
AZStd::array_view<uint8_t> m_relocationImageData;
AZStd::string m_relocationImageRelativePath;
RHI::ImageDescriptor m_classificationImageDescriptor;
AZStd::array_view<uint8_t> m_classificationImageData;
AZStd::string m_classificationImageRelativePath;
};
// DiffuseProbeGridFeatureProcessorInterface provides an interface to the feature processor for code outside of Atom
class DiffuseProbeGridFeatureProcessorInterface
: public RPI::FeatureProcessor
@@ -44,6 +98,29 @@ namespace AZ
virtual void Enable(const DiffuseProbeGridHandle& probeGrid, bool enable) = 0;
virtual void SetGIShadows(const DiffuseProbeGridHandle& probeGrid, bool giShadows) = 0;
virtual void SetUseDiffuseIbl(const DiffuseProbeGridHandle& probeGrid, bool useDiffuseIbl) = 0;
virtual void SetMode(const DiffuseProbeGridHandle& probeGrid, DiffuseProbeGridMode mode) = 0;
virtual void SetBakedTextures(const DiffuseProbeGridHandle& probeGrid, const DiffuseProbeGridBakedTextures& bakedTextures) = 0;
virtual void BakeTextures(
const DiffuseProbeGridHandle& probeGrid,
DiffuseProbeGridBakeTexturesCallback callback,
const AZStd::string& irradianceTextureRelativePath,
const AZStd::string& distanceTextureRelativePath,
const AZStd::string& relocationTextureRelativePath,
const AZStd::string& classificationTextureRelativePath) = 0;
// check for and retrieve a new baked texture asset (does not apply to hot-reloaded assets, only initial bakes)
virtual bool CheckTextureAssetNotification(
const AZStd::string& relativePath,
Data::Asset<RPI::StreamingImageAsset>& outTextureAsset,
DiffuseProbeGridTextureNotificationType& outNotificationType) = 0;
virtual bool AreBakedTexturesReferenced(
const AZStd::string& irradianceTextureRelativePath,
const AZStd::string& distanceTextureRelativePath,
const AZStd::string& relocationTextureRelativePath,
const AZStd::string& classificationTextureRelativePath) = 0;
};
} // namespace Render
} // namespace AZ
@@ -1,14 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
@@ -26,14 +26,15 @@ namespace AZ
, public AzToolsFramework::EditorEntityVisibilityNotificationBus::Handler
{
public:
using BaseClass = AzToolsFramework::Components::EditorComponentAdapter<TController, TRuntimeComponent, TConfiguration>;
AZ_RTTI((EditorRenderComponentAdapter, "{AAF38BE4-EA2F-408B-9C44-63C7FBAC6B33}", TController, TRuntimeComponent, TConfiguration), BaseClass);
AZ_RTTI(
(EditorRenderComponentAdapter, "{AAF38BE4-EA2F-408B-9C44-63C7FBAC6B33}", TController, TRuntimeComponent, TConfiguration),
BaseClass);
static void Reflect(AZ::ReflectContext* context);
EditorRenderComponentAdapter() = default;
EditorRenderComponentAdapter(const TConfiguration& config);
explicit EditorRenderComponentAdapter(const TConfiguration& config);
// AzToolsFramework::Components::EditorComponentAdapter overrides
void Activate() override;
@@ -50,7 +51,8 @@ namespace AZ
// Convert pre-existing EditorCompnentAdapter based serialized data to EditorRenderComponentAdapter
template<int TVersion>
static bool ConvertToEditorRenderComponentAdapter(AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& classElement);
static bool ConvertToEditorRenderComponentAdapter(
AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& classElement);
};
} // namespace Render
} // namespace AZ
@@ -1,14 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <Atom/Feature/Utils/EditorRenderComponentAdapter.h>
#include <AzToolsFramework/Entity/EditorEntityInfoBus.h>
@@ -19,11 +19,12 @@ namespace AZ
{
template<typename TController, typename TRuntimeComponent, typename TConfiguration>
template<int TVersion>
bool EditorRenderComponentAdapter<TController, TRuntimeComponent, TConfiguration>::ConvertToEditorRenderComponentAdapter(AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& classElement)
bool EditorRenderComponentAdapter<TController, TRuntimeComponent, TConfiguration>::ConvertToEditorRenderComponentAdapter(
AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& classElement)
{
if (classElement.GetVersion() < TVersion)
{
// Get the and remove the EditorComponentAdapter base class data that was previpously serialized
// Get the and remove the EditorComponentAdapter base class data that was previously serialized
AzToolsFramework::Components::EditorComponentAdapter<TController, TRuntimeComponent, TConfiguration> oldBaseClassData;
if (!classElement.FindSubElementAndGetData(AZ_CRC("BaseClass1", 0xd4925735), oldBaseClassData))
@@ -41,8 +42,8 @@ namespace AZ
// Replace the old base class data with EditorRenderComponentAdapter
EditorRenderComponentAdapter<TController, TRuntimeComponent, TConfiguration> newBaseClassData;
AZ::SerializeContext::DataElementNode& newBaseClassElement = classElement.GetSubElement(
classElement.AddElementWithData(context, "BaseClass1", newBaseClassData));
AZ::SerializeContext::DataElementNode& newBaseClassElement =
classElement.GetSubElement(classElement.AddElementWithData(context, "BaseClass1", newBaseClassData));
// Overwrite EditorRenderComponentAdapter base class data with retrieved EditorComponentAdapter base class data
if (!newBaseClassElement.RemoveElementByName(AZ_CRC("BaseClass1", 0xd4925735)))
@@ -62,25 +63,24 @@ namespace AZ
{
BaseClass::Reflect(context);
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
{
serializeContext->Class<EditorRenderComponentAdapter, BaseClass>()
->Version(0)
;
serializeContext->Class<EditorRenderComponentAdapter, BaseClass>()->Version(0);
if (AZ::EditContext* editContext = serializeContext->GetEditContext())
{
editContext->Class<EditorRenderComponentAdapter>(
"EditorRenderComponentAdapter", "")
// clang-format off
editContext->Class<EditorRenderComponentAdapter>("EditorRenderComponentAdapter", "")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
;
->Attribute(AZ::Edit::Attributes::AutoExpand, true);
// clang-format on
}
}
}
template<typename TController, typename TRuntimeComponent, typename TConfiguration>
EditorRenderComponentAdapter<TController, TRuntimeComponent, TConfiguration>::EditorRenderComponentAdapter(const TConfiguration& config)
EditorRenderComponentAdapter<TController, TRuntimeComponent, TConfiguration>::EditorRenderComponentAdapter(
const TConfiguration& config)
: BaseClass(config)
{
}
@@ -103,7 +103,8 @@ namespace AZ
bool EditorRenderComponentAdapter<TController, TRuntimeComponent, TConfiguration>::IsVisible() const
{
bool visible = true;
AzToolsFramework::EditorEntityInfoRequestBus::EventResult(visible, this->GetEntityId(), &AzToolsFramework::EditorEntityInfoRequestBus::Events::IsVisible);
AzToolsFramework::EditorEntityInfoRequestBus::EventResult(
visible, this->GetEntityId(), &AzToolsFramework::EditorEntityInfoRequestBus::Events::IsVisible);
return visible;
}
@@ -114,15 +115,16 @@ namespace AZ
}
template<typename TController, typename TRuntimeComponent, typename TConfiguration>
void EditorRenderComponentAdapter<TController, TRuntimeComponent, TConfiguration>::OnEntityVisibilityChanged([[maybe_unused]] bool visibility)
void EditorRenderComponentAdapter<TController, TRuntimeComponent, TConfiguration>::OnEntityVisibilityChanged(
[[maybe_unused]] bool visibility)
{
this->m_controller.Deactivate();
if (this->ShouldActivateController())
{
this->m_controller.Activate(this->GetEntityId());
AzFramework::Components::ComponentActivateHelper<TController>::Activate(
this->m_controller, AZ::EntityComponentIdPair(this->GetEntityId(), this->GetId()));
}
}
} // namespace Render
} // namespace AZ
@@ -14,8 +14,6 @@
#include <Source/Material/UseTextureFunctor.h>
#include <Source/Material/SubsurfaceTransmissionParameterFunctor.h>
#include <Source/Material/Transform2DFunctor.h>
#include <Source/Material/ShaderEnableFunctor.h>
#include <Source/Material/PropertyVisibilityFunctor.h>
#include <Source/Material/DrawListFunctor.h>
#include <Source/Material/ConvertEmissiveUnitFunctor.h>
@@ -116,7 +114,6 @@ namespace AZ
ProjectedShadowFeatureProcessor::Reflect(context);
SkyBoxFeatureProcessor::Reflect(context);
UseTextureFunctor::Reflect(context);
PropertyVisibilityFunctor::Reflect(context);
DrawListFunctor::Reflect(context);
SubsurfaceTransmissionParameterFunctor::Reflect(context);
Transform2DFunctor::Reflect(context);
@@ -128,7 +125,6 @@ namespace AZ
DisplayMapperPassData::Reflect(context);
ConvertEmissiveUnitFunctor::Reflect(context);
LookupTableAsset::Reflect(context);
ShaderEnableFunctor::Reflect(context);
ReflectionProbeFeatureProcessor::Reflect(context);
DecalTextureArrayFeatureProcessor::Reflect(context);
SMAAFeatureProcessor::Reflect(context);
@@ -279,7 +279,7 @@ namespace AZ
if (handle.IsValid())
{
Quaternion orientation = world.GetRotation();
Vector3 scale = world.GetScale() * nonUniformScale;
Vector3 scale = world.GetUniformScale() * nonUniformScale;
SetDecalHalfSize(handle, scale);
SetDecalPosition(handle, world.GetTranslation());
@@ -285,7 +285,7 @@ namespace AZ
{
if (handle.IsValid())
{
SetDecalHalfSize(handle, nonUniformScale * world.GetScale());
SetDecalHalfSize(handle, nonUniformScale * world.GetUniformScale());
SetDecalPosition(handle, world.GetTranslation());
SetDecalOrientation(handle, world.GetRotation());
@@ -13,6 +13,7 @@
#include <Atom/RHI.Reflect/ShaderResourceGroupLayoutDescriptor.h>
#include <Atom/RPI.Public/Shader/ShaderResourceGroup.h>
#include <DiffuseProbeGrid/DiffuseProbeGrid.h>
#include <Atom/RPI.Public/Image/StreamingImage.h>
#include <Atom/RPI.Public/View.h>
#include <Atom/RHI/RHISystemInterface.h>
#include <Atom/RHI/Factory.h>
@@ -23,6 +24,11 @@ namespace AZ
{
namespace Render
{
DiffuseProbeGrid::DiffuseProbeGrid()
: m_textureReadback(this)
{
}
DiffuseProbeGrid::~DiffuseProbeGrid()
{
m_scene->GetCullingScene()->UnregisterCullable(m_cullable);
@@ -166,6 +172,84 @@ namespace AZ
m_updateRenderObjectSrg = true;
}
void DiffuseProbeGrid::SetMode(DiffuseProbeGridMode mode)
{
// handle auto-select
if (mode == DiffuseProbeGridMode::AutoSelect)
{
RHI::Ptr<RHI::Device> device = RHI::RHISystemInterface::Get()->GetDevice();
m_mode = (device->GetFeatures().m_rayTracing) ? DiffuseProbeGridMode::RealTime : DiffuseProbeGridMode::Baked;
}
else
{
m_mode = mode;
}
m_updateTextures = true;
}
void DiffuseProbeGrid::SetBakedTextures(const DiffuseProbeGridBakedTextures& bakedTextures)
{
AZ_Assert(bakedTextures.m_irradianceImage.get(), "Invalid Irradiance image passed to SetBakedTextures");
AZ_Assert(bakedTextures.m_distanceImage.get(), "Invalid Distance image passed to SetBakedTextures");
AZ_Assert(bakedTextures.m_relocationImageData.size() > 0, "Invalid Relocation image data passed to SetBakedTextures");
AZ_Assert(bakedTextures.m_classificationImageData.size() > 0, "Invalid Classification image data passed to SetBakedTextures");
m_bakedIrradianceImage = bakedTextures.m_irradianceImage;
m_bakedDistanceImage = bakedTextures.m_distanceImage;
m_bakedIrradianceRelativePath = bakedTextures.m_irradianceImageRelativePath;
m_bakedDistanceRelativePath = bakedTextures.m_distanceImageRelativePath;
m_bakedRelocationRelativePath = bakedTextures.m_relocationImageRelativePath;
m_bakedClassificationRelativePath = bakedTextures.m_classificationImageRelativePath;
m_bakedRelocationImageData.resize(bakedTextures.m_relocationImageData.size());
memcpy(m_bakedRelocationImageData.data(), bakedTextures.m_relocationImageData.data(), bakedTextures.m_relocationImageData.size());
m_bakedClassificationImageData.resize(bakedTextures.m_classificationImageData.size());
memcpy(m_bakedClassificationImageData.data(), bakedTextures.m_classificationImageData.data(), bakedTextures.m_classificationImageData.size());
// create the relocation and distance RW textures now, these are needed for shader compatibility
// (image data is copied in UpdateTextures)
{
m_bakedRelocationImage = RHI::Factory::Get().CreateImage();
RHI::ImageInitRequest initRequest;
initRequest.m_image = m_bakedRelocationImage.get();
initRequest.m_descriptor = RHI::ImageDescriptor::Create2D(
RHI::ImageBindFlags::ShaderReadWrite | RHI::ImageBindFlags::CopyRead,
bakedTextures.m_relocationImageDescriptor.m_size.m_width,
bakedTextures.m_relocationImageDescriptor.m_size.m_height,
bakedTextures.m_relocationImageDescriptor.m_format);
[[maybe_unused]] RHI::ResultCode result = m_renderData->m_imagePool->InitImage(initRequest);
AZ_Assert(result == RHI::ResultCode::Success, "Failed to initialize Relocation image");
}
{
m_bakedClassificationImage = RHI::Factory::Get().CreateImage();
RHI::ImageInitRequest initRequest;
initRequest.m_image = m_bakedClassificationImage.get();
initRequest.m_descriptor = RHI::ImageDescriptor::Create2D(
RHI::ImageBindFlags::ShaderReadWrite | RHI::ImageBindFlags::CopyRead,
bakedTextures.m_classificationImageDescriptor.m_size.m_width,
bakedTextures.m_classificationImageDescriptor.m_size.m_height,
bakedTextures.m_classificationImageDescriptor.m_format);
[[maybe_unused]] RHI::ResultCode result = m_renderData->m_imagePool->InitImage(initRequest);
AZ_Assert(result == RHI::ResultCode::Success, "Failed to initialize Classification image");
}
m_updateTextures = true;
}
bool DiffuseProbeGrid::HasValidBakedTextures() const
{
return m_bakedIrradianceImage.get() &&
m_bakedDistanceImage.get() &&
m_bakedRelocationImage.get() &&
m_bakedClassificationImage.get();
}
uint32_t DiffuseProbeGrid::GetTotalProbeCount() const
{
return m_probeCountX * m_probeCountY * m_probeCountZ;
@@ -188,83 +272,117 @@ namespace AZ
RHI::Ptr<RHI::Device> device = RHI::RHISystemInterface::Get()->GetDevice();
// advance to the next image in the frame image array
m_currentImageIndex = (m_currentImageIndex + 1) % ImageFrameCount;
// probe raytrace
{
uint32_t width = m_numRaysPerProbe;
uint32_t height = GetTotalProbeCount();
m_rayTraceImage[m_currentImageIndex] = RHI::Factory::Get().CreateImage();
RHI::ImageInitRequest request;
request.m_image = m_rayTraceImage[m_currentImageIndex].get();
request.m_descriptor = RHI::ImageDescriptor::Create2D(RHI::ImageBindFlags::ShaderReadWrite, width, height, DiffuseProbeGridRenderData::RayTraceImageFormat);
[[maybe_unused]] RHI::ResultCode result = m_renderData->m_imagePool->InitImage(request);
AZ_Assert(result == RHI::ResultCode::Success, "Failed to initialize m_probeRayTraceImage image");
}
uint32_t probeCountX;
uint32_t probeCountY;
GetTexture2DProbeCount(probeCountX, probeCountY);
// probe irradiance
if (m_mode == DiffuseProbeGridMode::RealTime)
{
uint32_t width = probeCountX * (DefaultNumIrradianceTexels + 2);
uint32_t height = probeCountY * (DefaultNumIrradianceTexels + 2);
// advance to the next image in the frame image array
m_currentImageIndex = (m_currentImageIndex + 1) % ImageFrameCount;
m_irradianceImage[m_currentImageIndex] = RHI::Factory::Get().CreateImage();
// probe raytrace
{
uint32_t width = m_numRaysPerProbe;
uint32_t height = GetTotalProbeCount();
RHI::ImageInitRequest request;
request.m_image = m_irradianceImage[m_currentImageIndex].get();
request.m_descriptor = RHI::ImageDescriptor::Create2D(RHI::ImageBindFlags::ShaderReadWrite, width, height, DiffuseProbeGridRenderData::IrradianceImageFormat);
RHI::ClearValue clearValue = RHI::ClearValue::CreateVector4Float(0.0f, 0.0f, 0.0f, 0.0f);
request.m_optimizedClearValue = &clearValue;
[[maybe_unused]] RHI::ResultCode result = m_renderData->m_imagePool->InitImage(request);
AZ_Assert(result == RHI::ResultCode::Success, "Failed to initialize m_probeIrradianceImage image");
m_rayTraceImage[m_currentImageIndex] = RHI::Factory::Get().CreateImage();
RHI::ImageInitRequest request;
request.m_image = m_rayTraceImage[m_currentImageIndex].get();
request.m_descriptor = RHI::ImageDescriptor::Create2D(RHI::ImageBindFlags::ShaderReadWrite | RHI::ImageBindFlags::CopyRead, width, height, DiffuseProbeGridRenderData::RayTraceImageFormat);
[[maybe_unused]] RHI::ResultCode result = m_renderData->m_imagePool->InitImage(request);
AZ_Assert(result == RHI::ResultCode::Success, "Failed to initialize m_probeRayTraceImage image");
}
// probe irradiance
{
uint32_t width = probeCountX * (DefaultNumIrradianceTexels + 2);
uint32_t height = probeCountY * (DefaultNumIrradianceTexels + 2);
m_irradianceImage[m_currentImageIndex] = RHI::Factory::Get().CreateImage();
RHI::ImageInitRequest request;
request.m_image = m_irradianceImage[m_currentImageIndex].get();
request.m_descriptor = RHI::ImageDescriptor::Create2D(RHI::ImageBindFlags::ShaderReadWrite | RHI::ImageBindFlags::CopyRead, width, height, DiffuseProbeGridRenderData::IrradianceImageFormat);
RHI::ClearValue clearValue = RHI::ClearValue::CreateVector4Float(0.0f, 0.0f, 0.0f, 0.0f);
request.m_optimizedClearValue = &clearValue;
[[maybe_unused]] RHI::ResultCode result = m_renderData->m_imagePool->InitImage(request);
AZ_Assert(result == RHI::ResultCode::Success, "Failed to initialize m_probeIrradianceImage image");
}
// probe distance
{
uint32_t width = probeCountX * (DefaultNumDistanceTexels + 2);
uint32_t height = probeCountY * (DefaultNumDistanceTexels + 2);
m_distanceImage[m_currentImageIndex] = RHI::Factory::Get().CreateImage();
RHI::ImageInitRequest request;
request.m_image = m_distanceImage[m_currentImageIndex].get();
request.m_descriptor = RHI::ImageDescriptor::Create2D(RHI::ImageBindFlags::ShaderReadWrite | RHI::ImageBindFlags::CopyRead, width, height, DiffuseProbeGridRenderData::DistanceImageFormat);
[[maybe_unused]] RHI::ResultCode result = m_renderData->m_imagePool->InitImage(request);
AZ_Assert(result == RHI::ResultCode::Success, "Failed to initialize m_probeDistanceImage image");
}
// probe relocation
{
uint32_t width = probeCountX;
uint32_t height = probeCountY;
m_relocationImage[m_currentImageIndex] = RHI::Factory::Get().CreateImage();
RHI::ImageInitRequest request;
request.m_image = m_relocationImage[m_currentImageIndex].get();
request.m_descriptor = RHI::ImageDescriptor::Create2D(RHI::ImageBindFlags::ShaderReadWrite | RHI::ImageBindFlags::CopyRead, width, height, DiffuseProbeGridRenderData::RelocationImageFormat);
[[maybe_unused]] RHI::ResultCode result = m_renderData->m_imagePool->InitImage(request);
AZ_Assert(result == RHI::ResultCode::Success, "Failed to initialize m_probeRelocationImage image");
}
// probe classification
{
uint32_t width = probeCountX;
uint32_t height = probeCountY;
m_classificationImage[m_currentImageIndex] = RHI::Factory::Get().CreateImage();
RHI::ImageInitRequest request;
request.m_image = m_classificationImage[m_currentImageIndex].get();
request.m_descriptor = RHI::ImageDescriptor::Create2D(RHI::ImageBindFlags::ShaderReadWrite | RHI::ImageBindFlags::CopyRead, width, height, DiffuseProbeGridRenderData::ClassificationImageFormat);
[[maybe_unused]] RHI::ResultCode result = m_renderData->m_imagePool->InitImage(request);
AZ_Assert(result == RHI::ResultCode::Success, "Failed to initialize m_probeClassificationImage image");
}
}
// probe distance
else if (m_mode == DiffuseProbeGridMode::Baked && HasValidBakedTextures())
{
uint32_t width = probeCountX * (DefaultNumDistanceTexels + 2);
uint32_t height = probeCountY * (DefaultNumDistanceTexels + 2);
// copy the baked relocation and classification texture data to the RW textures
// (these need to be RW for shader compatibility)
RHI::ImageSubresourceRange range{ 0, 0, 0 ,0 };
RHI::ImageSubresourceLayoutPlaced layout;
m_distanceImage[m_currentImageIndex] = RHI::Factory::Get().CreateImage();
// relocation
{
m_bakedRelocationImage->GetSubresourceLayouts(range, &layout, nullptr);
RHI::ImageInitRequest request;
request.m_image = m_distanceImage[m_currentImageIndex].get();
request.m_descriptor = RHI::ImageDescriptor::Create2D(RHI::ImageBindFlags::ShaderReadWrite, width, height, DiffuseProbeGridRenderData::DistanceImageFormat);
[[maybe_unused]] RHI::ResultCode result = m_renderData->m_imagePool->InitImage(request);
AZ_Assert(result == RHI::ResultCode::Success, "Failed to initialize m_probeDistanceImage image");
}
RHI::ImageUpdateRequest updateRequest;
updateRequest.m_image = m_bakedRelocationImage.get();
updateRequest.m_sourceSubresourceLayout = layout;
updateRequest.m_sourceData = m_bakedRelocationImageData.data();
updateRequest.m_imageSubresourcePixelOffset = RHI::Origin(0, 0, 0);
m_renderData->m_imagePool->UpdateImageContents(updateRequest);
}
// probe relocation
{
uint32_t width = probeCountX;
uint32_t height = probeCountY;
// classification
{
m_bakedClassificationImage->GetSubresourceLayouts(range, &layout, nullptr);
m_relocationImage[m_currentImageIndex] = RHI::Factory::Get().CreateImage();
RHI::ImageInitRequest request;
request.m_image = m_relocationImage[m_currentImageIndex].get();
request.m_descriptor = RHI::ImageDescriptor::Create2D(RHI::ImageBindFlags::ShaderReadWrite, width, height, DiffuseProbeGridRenderData::RelocationImageFormat);
[[maybe_unused]] RHI::ResultCode result = m_renderData->m_imagePool->InitImage(request);
AZ_Assert(result == RHI::ResultCode::Success, "Failed to initialize m_probeRelocationImage image");
}
// probe classification
{
uint32_t width = probeCountX;
uint32_t height = probeCountY;
m_classificationImage[m_currentImageIndex] = RHI::Factory::Get().CreateImage();
RHI::ImageInitRequest request;
request.m_image = m_classificationImage[m_currentImageIndex].get();
request.m_descriptor = RHI::ImageDescriptor::Create2D(RHI::ImageBindFlags::ShaderReadWrite, width, height, DiffuseProbeGridRenderData::ClassificationImageFormat);
[[maybe_unused]] RHI::ResultCode result = m_renderData->m_imagePool->InitImage(request);
AZ_Assert(result == RHI::ResultCode::Success, "Failed to initialize m_probeClassificationImage image");
RHI::ImageUpdateRequest updateRequest;
updateRequest.m_image = m_bakedClassificationImage.get();
updateRequest.m_sourceSubresourceLayout = layout;
updateRequest.m_sourceData = m_bakedClassificationImageData.data();
updateRequest.m_imageSubresourcePixelOffset = RHI::Origin(0, 0, 0);
m_renderData->m_imagePool->UpdateImageContents(updateRequest);
}
}
m_updateTextures = false;
@@ -639,16 +757,16 @@ namespace AZ
m_renderObjectSrg->SetConstant(constantIndex, m_ambientMultiplier);
imageIndex = srgLayout->FindShaderInputImageIndex(Name("m_probeIrradiance"));
m_renderObjectSrg->SetImageView(imageIndex, m_irradianceImage[m_currentImageIndex]->GetImageView(m_renderData->m_probeIrradianceImageViewDescriptor).get());
m_renderObjectSrg->SetImageView(imageIndex, GetIrradianceImage()->GetImageView(m_renderData->m_probeIrradianceImageViewDescriptor).get());
imageIndex = srgLayout->FindShaderInputImageIndex(Name("m_probeDistance"));
m_renderObjectSrg->SetImageView(imageIndex, m_distanceImage[m_currentImageIndex]->GetImageView(m_renderData->m_probeDistanceImageViewDescriptor).get());
m_renderObjectSrg->SetImageView(imageIndex, GetDistanceImage()->GetImageView(m_renderData->m_probeDistanceImageViewDescriptor).get());
imageIndex = srgLayout->FindShaderInputImageIndex(Name("m_probeOffsets"));
m_renderObjectSrg->SetImageView(imageIndex, m_relocationImage[m_currentImageIndex]->GetImageView(m_renderData->m_probeRelocationImageViewDescriptor).get());
m_renderObjectSrg->SetImageView(imageIndex, GetRelocationImage()->GetImageView(m_renderData->m_probeRelocationImageViewDescriptor).get());
imageIndex = srgLayout->FindShaderInputImageIndex(Name("m_probeStates"));
m_renderObjectSrg->SetImageView(imageIndex, m_classificationImage[m_currentImageIndex]->GetImageView(m_renderData->m_probeClassificationImageViewDescriptor).get());
m_renderObjectSrg->SetImageView(imageIndex, GetClassificationImage()->GetImageView(m_renderData->m_probeClassificationImageViewDescriptor).get());
SetGridConstants(m_renderObjectSrg);

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