Merge branch 'main' into JsonSerializationPointerFix

main
AMZN-koppersr 5 years ago
commit 2d4a17a2fb

@ -1 +0,0 @@
<CacheBuildConfiguration Name="Game" UpAxis="Y" MeshPrediction="1" UseBFrames="1" IndexFrameDistance="10" BlockCompressionFormat="deflate" PlaybackFromMemory="0" PositionPrecision="1" UVmax="0"/>

@ -1 +0,0 @@
<CacheBuildConfiguration Name="Game (fast decode)" UpAxis="Y" MeshPrediction="1" UseBFrames="1" IndexFrameDistance="10" BlockCompressionFormat="lz4hc" PlaybackFromMemory="0" PositionPrecision="1" UVmax="0"/>

@ -1 +0,0 @@
<CacheBuildConfiguration Name="Game (Z-up)" UpAxis="Z" MeshPrediction="1" UseBFrames="1" IndexFrameDistance="10" BlockCompressionFormat="deflate" PlaybackFromMemory="0" PositionPrecision="1" UVmax="0"/>

@ -1 +0,0 @@
<CacheBuildConfiguration Name="Game (fast decode, Z-up)" UpAxis="Z" MeshPrediction="1" UseBFrames="1" IndexFrameDistance="10" BlockCompressionFormat="lz4hc" PlaybackFromMemory="0" PositionPrecision="1" UVmax="0"/>

@ -1 +0,0 @@
<CacheBuildConfiguration Name="Prerendered" UpAxis="Y" MeshPrediction="1" UseBFrames="1" IndexFrameDistance="10" BlockCompressionFormat="deflate" PlaybackFromMemory="0" PositionPrecision="0" UVmax="0"/>

@ -1 +0,0 @@
<CacheBuildConfiguration Name="Prerendered (Z-up)" UpAxis="Z" MeshPrediction="1" UseBFrames="1" IndexFrameDistance="10" BlockCompressionFormat="deflate" PlaybackFromMemory="0" PositionPrecision="0" UVmax="0"/>

@ -1 +0,0 @@
<CacheBuildConfiguration Name="Rigids Only" UpAxis="Y" MeshPrediction="0" UseBFrames="0" IndexFrameDistance="10" BlockCompressionFormat="deflate" PlaybackFromMemory="1" PositionPrecision="0" UVmax="0"/>

@ -1 +0,0 @@
<CacheBuildConfiguration Name="Rigids Only (Z-up)" UpAxis="Z" MeshPrediction="0" UseBFrames="0" IndexFrameDistance="10" BlockCompressionFormat="deflate" PlaybackFromMemory="1" PositionPrecision="0" UVmax="0"/>

@ -1 +0,0 @@
<CacheBuildConfiguration Name="Uncompressed (fastest compile)" UpAxis="Y" MeshPrediction="0" UseBFrames="0" IndexFrameDistance="10" BlockCompressionFormat="store" PlaybackFromMemory="0" PositionPrecision="0" UVmax="0"/>

@ -1 +0,0 @@
<CacheBuildConfiguration Name="Uncompressed (fastest compile, Z-up)" UpAxis="Z" MeshPrediction="0" UseBFrames="0" IndexFrameDistance="10" BlockCompressionFormat="store" PlaybackFromMemory="0" PositionPrecision="0" UVmax="0"/>

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

@ -1 +0,0 @@
<CacheBuildConfiguration UpAxis="Y" MeshPrediction="1" UseBFrames="1" IndexFrameDistance="15" BlockCompressionFormat="deflate" PlaybackFromMemory="1"/>

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

@ -1,17 +0,0 @@
<Material MtlFlags="524544" vertModifType="0">
<SubMaterials>
<Material Name="mat01_white" MtlFlags="524416" Shader="Illum" GenMask="12000020040003" StringGenMask="%ALLOW_SILHOUETTE_POM%ALLOW_SPECULAR_ANTIALIASING%EMITTANCE_MAP%NORMAL_MAP%SPECULAR_MAP%SUBSURFACE_SCATTERING" SurfaceType="mat_default" Diffuse="1,1,1,1" Specular="0.5,0.5,0.5,1" Opacity="1" Shininess="174.72" vertModifType="0" LayerAct="1">
<Textures>
<Texture Map="Diffuse" File="engineassets/textures/white.dds"/>
</Textures>
<PublicParams EmittanceMapGamma="1" SSSIndex="0" IndirectColor="0.25,0.25,0.25"/>
</Material>
<Material Name="mat02_grey" MtlFlags="524416" Shader="Illum" GenMask="10000000000003" StringGenMask="%ALLOW_SILHOUETTE_POM%ALLOW_SPECULAR_ANTIALIASING%SUBSURFACE_SCATTERING" SurfaceType="mat_default" Diffuse="0.5,0.5,0.5,1" Specular="0.5,0.5,0.5,1" Opacity="1" Shininess="10" vertModifType="0" LayerAct="1">
<Textures>
<Texture Map="Diffuse" File="engineassets/textures/white.dds"/>
</Textures>
<PublicParams EmittanceMapGamma="1" SSSIndex="0" IndirectColor="0.25,0.25,0.25"/>
</Material>
</SubMaterials>
<PublicParams EmittanceMapGamma="1" SSSIndex="0" IndirectColor="0.25,0.25,0.25"/>
</Material>

@ -1,75 +0,0 @@
"""
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.
"""
#
# This is a pytest module to test the in-Editor Python API from ViewPane.h
#
import pytest
pytest.importorskip('ly_test_tools')
import sys
import os
sys.path.append(os.path.dirname(__file__))
from hydra_utils import launch_test_case
@pytest.mark.SUITE_sandbox
@pytest.mark.parametrize('launcher_platform', ['windows_editor'])
@pytest.mark.parametrize('project', ['AutomatedTesting'])
@pytest.mark.parametrize('level', ['auto_test'])
class TestLegacyCryMaterialsCommandsAutomation(object):
def test_Legacy_CryMaterials(self, request, editor, level, launcher_platform):
unexpected_lines=[]
expected_lines = [
# "Material Settings/Shader updated correctly", # Disabled, SPEC-3590
# "Material Settings/Surface Type updated correctly", # Disabled, SPEC-3590
"Texture Maps/Diffuse/Tiling/IsTileU updated correctly",
"Texture Maps/Diffuse/Tiling/TileU updated correctly",
"Texture Maps/Diffuse/Rotator/Type updated correctly",
"Texture Maps/Diffuse/Rotator/Amplitude updated correctly",
"Texture Maps/Diffuse/Oscillator/AmplitudeU updated correctly",
"Opacity Settings/Opacity updated correctly",
"Opacity Settings/AlphaTest updated correctly",
"Opacity Settings/Additive updated correctly",
"Lighting Settings/Diffuse Color updated correctly",
"Lighting Settings/Specular Color updated correctly",
"Lighting Settings/Emissive Intensity updated correctly",
"Lighting Settings/Emissive Color updated correctly",
"Advanced/Allow layer activation updated correctly",
"Advanced/2 Sided updated correctly",
"Advanced/No Shadow updated correctly",
"Advanced/Use Scattering updated correctly",
"Advanced/Hide After Breaking updated correctly",
"Advanced/Fog Volume Shading Quality High updated correctly",
"Advanced/Blend Terrain Color updated correctly",
"Advanced/Voxel Coverage updated correctly",
"Advanced/Propagate Opacity Settings updated correctly",
"Advanced/Propagate Lighting Settings updated correctly",
"Advanced/Propagate Advanced Settings updated correctly",
"Advanced/Propagate Texture Maps updated correctly",
"Advanced/Propagate Shader Params updated correctly",
"Advanced/Propagate Shader Generation updated correctly",
"Advanced/Propagate Vertex Deformation updated correctly",
# "Shader Params/Blend Factor updated correctly", # Disabled, SPEC-3590
# "Shader Params/Indirect bounce color updated correctly", # Disabled, SPEC-3590
"Vertex Deformation/Type updated correctly",
"Vertex Deformation/Wave Length X updated correctly",
"Vertex Deformation/Wave X/Level updated correctly",
"Vertex Deformation/Wave X/Amplitude updated correctly",
"Vertex Deformation/Wave X/Phase updated correctly",
"Vertex Deformation/Wave X/Frequency updated correctly"
]
test_case_file = os.path.join(os.path.dirname(__file__), 'CryMaterialsCommands_test_case.py')
launch_test_case(editor, test_case_file, expected_lines, unexpected_lines)

@ -1,116 +0,0 @@
"""
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.
"""
# Tests the legacy Python API for CryMaterials while the Editor is running
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.legacy.material as material
import azlmbr.math as math
materialName = 'materials/ter_layer_green'
print(f'Starting CryMaterial test case using material {materialName}')
def MaterialPropertyTest(property, value, doReset=True):
try:
# get old value and attempt to set new value
oldValue = material.get_property(materialName, property)
if oldValue == value:
print(f'>>> `{property}` already set to {oldValue}')
return
material.set_property(materialName, property, value)
# test that the set new value worked
newValue = material.get_property(materialName, property)
if oldValue != newValue:
print(f"{property} updated correctly")
# reset back to old value
if doReset:
material.set_property(materialName, property, oldValue)
except:
print(f'!!! hit an exception when setting `{property}` to {value}')
color = math.Color()
color.r = 255.0
color.g = 128.0
color.b = 64.0
color.a = 0.0
# Material Settings
# MaterialPropertyTest("Material Settings/Shader", "Geometrybeam") # Disabled, SPEC-3590
# MaterialPropertyTest("Material Settings/Surface Type", "grass") # Disabled, SPEC-3590
# Texture Maps
MaterialPropertyTest("Texture Maps/Diffuse/Tiling/IsTileU", False)
MaterialPropertyTest("Texture Maps/Diffuse/Tiling/IsTileV", False)
MaterialPropertyTest("Texture Maps/Diffuse/Tiling/TileU", 0.42)
MaterialPropertyTest("Texture Maps/Diffuse/Rotator/Type", 'Oscillated Rotation')
MaterialPropertyTest("Texture Maps/Diffuse/Rotator/Amplitude", 42.0)
MaterialPropertyTest("Texture Maps/Diffuse/Oscillator/TypeU", 'Fixed Moving')
MaterialPropertyTest("Texture Maps/Diffuse/Oscillator/AmplitudeU", 42.0)
# Vertex Deformation
MaterialPropertyTest("Vertex Deformation/Type", 'Sin Wave')
MaterialPropertyTest("Vertex Deformation/Wave Length X", 42.0)
MaterialPropertyTest("Vertex Deformation/Type", 'Perlin 3D')
MaterialPropertyTest("Vertex Deformation/Noise Scale", math.Vector3(1.1, 2.2, 3.3))
# Opacity Settings
MaterialPropertyTest("Opacity Settings/Opacity", 42)
MaterialPropertyTest("Opacity Settings/AlphaTest", 2)
MaterialPropertyTest("Opacity Settings/Additive", True)
# Lighting Settings
MaterialPropertyTest("Lighting Settings/Diffuse Color", color)
MaterialPropertyTest("Lighting Settings/Specular Color", color)
MaterialPropertyTest("Lighting Settings/Emissive Intensity", 42.0)
MaterialPropertyTest("Lighting Settings/Emissive Color", color)
MaterialPropertyTest("Lighting Settings/Specular Level", 2.0)
# Advanced
MaterialPropertyTest("Advanced/Allow layer activation", False)
MaterialPropertyTest("Advanced/2 Sided", True)
MaterialPropertyTest("Advanced/No Shadow", True)
MaterialPropertyTest("Advanced/Use Scattering", True)
MaterialPropertyTest("Advanced/Hide After Breaking", True)
MaterialPropertyTest("Advanced/Fog Volume Shading Quality High", True)
MaterialPropertyTest("Advanced/Blend Terrain Color", True)
MaterialPropertyTest("Advanced/Voxel Coverage", 0.42)
# --- MaterialPropertyTest("Advanced/Link to Material", "materials/ter_layer_blue") # Works, but clears on UI refresh
MaterialPropertyTest("Advanced/Propagate Opacity Settings", True)
MaterialPropertyTest("Advanced/Propagate Lighting Settings", True)
MaterialPropertyTest("Advanced/Propagate Advanced Settings", True)
MaterialPropertyTest("Advanced/Propagate Texture Maps", True)
MaterialPropertyTest("Advanced/Propagate Shader Params", True)
MaterialPropertyTest("Advanced/Propagate Shader Generation", True)
MaterialPropertyTest("Advanced/Propagate Vertex Deformation", True)
# Shader parameters vary with each Shader, just testing a couple of them...
# MaterialPropertyTest("Shader Params/Blend Factor", 7.0, False) # Disabled, SPEC-3590
# MaterialPropertyTest("Shader Params/Indirect bounce color", color, False) # Disabled, SPEC-3590
### These values are reset to False when set. Left them here commented for reference.
# MaterialPropertyTest("Shader Generation Params/Dust & Turbulence", True)
# MaterialPropertyTest("Shader Generation Params/Receive Shadows", True)
# MaterialPropertyTest("Shader Generation Params/UV Vignetting", True)
# Vertex Deformation
MaterialPropertyTest("Vertex Deformation/Type", "Sin Wave")
MaterialPropertyTest("Vertex Deformation/Wave Length X", 42.0)
MaterialPropertyTest("Vertex Deformation/Wave X/Level", 42.0)
MaterialPropertyTest("Vertex Deformation/Wave X/Amplitude", 42.0)
MaterialPropertyTest("Vertex Deformation/Wave X/Phase", 42.0)
MaterialPropertyTest("Vertex Deformation/Wave X/Frequency", 42.0)
editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'ExitNoPrompt')

@ -20,7 +20,10 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
class Tests():
enter_game_mode = ("Entered game mode", "Failed to enter game mode")
find_cylinder = ("Cylinder entity found", "Cylinder entity not found")
find_terrain = ("Terrain found", "Terrain not found")
create_terrain = ("Terrain entity created successfully", "Failed to create Terrain Entity")
find_terrain = ("Terrain entity found", "Terrain entity not found")
add_physx_shape_collider = ("Added PhysX Shape Collider", "Failed to add PhysX Shape Collider")
add_box_shape = ("Added Box Shape", "Failed to add Box Shape")
cylinder_above_terrain = ("Cylinder position above ground", "Cylinder is not above the ground")
time_out = ("No time out occurred", "A time out occurred, please validate level setup")
touched_ground = ("Touched ground before time out", "Did not touch ground before time out")
@ -40,11 +43,12 @@ def C24308873_CylinderShapeCollider_CollidesWithPhysXTerrain():
Once game mode is entered, the cylinder should fall toward and collide with the terrain.
Steps:
1) Open level and enter game mode
2) Retrieve entities and positions
3) Wait for cylinder to collide with terrain OR time out
4) Exit game mode
5) Close the editor
1) Open level and create terrain Entity.
2) Enter Game Mode.
3) Retrieve entities and positions
4) Wait for cylinder to collide with terrain OR time out
5) Exit game mode
6) Close the editor
:return:
"""
@ -54,29 +58,48 @@ def C24308873_CylinderShapeCollider_CollidesWithPhysXTerrain():
import ImportPathHelper as imports
imports.init()
from editor_python_test_tools.editor_entity_utils import EditorEntity
import azlmbr.legacy.general as general
import azlmbr.bus
import azlmbr.math as math
from editor_python_test_tools.utils import Report
from editor_python_test_tools.utils import TestHelper as helper
# Global time out
TIME_OUT = 1.0
# 1) Open level / Enter game mode
# 1) Open level
helper.init_idle()
helper.open_level("Physics", "C24308873_CylinderShapeCollider_CollidesWithPhysXTerrain")
# Create terrain entity
terrain = EditorEntity.create_editor_entity_at([30.0, 30.0, 33.96], "Terrain")
Report.result(Tests.create_terrain, terrain.id.IsValid())
terrain.add_component("PhysX Shape Collider")
Report.result(Tests.add_physx_shape_collider, terrain.has_component("PhysX Shape Collider"))
box_shape_component = terrain.add_component("Box Shape")
Report.result(Tests.add_box_shape, terrain.has_component("Box Shape"))
box_shape_component.set_component_property_value("Box Shape|Box Configuration|Dimensions",
math.Vector3(1024.0, 1024.0, 0.01))
# 2)Enter game mode
helper.enter_game_mode(Tests.enter_game_mode)
# 2) Retrieve entities and positions
# 3) Retrieve entities and positions
cylinder_id = general.find_game_entity("PhysX_Cylinder")
Report.critical_result(Tests.find_cylinder, cylinder_id.IsValid())
terrain_id = general.find_game_entity("Terrain")
Report.critical_result(Tests.find_terrain, terrain_id.IsValid())
terrain_id = general.find_game_entity("PhysX_Terrain")
Report.critical_result(Tests.find_terrain, terrain_id.IsValid())
cylinder_pos = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTM", cylinder_id).GetPosition()
terrain_pos = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTM", terrain_id).GetPosition()
cylinder_pos = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", cylinder_id)
#Cylinder position is 64,84,35
terrain_pos = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", terrain_id)
Report.info_vector3(cylinder_pos, "Cylinder:")
Report.info_vector3(terrain_pos, "Terrain:")
Report.critical_result(
@ -104,13 +127,13 @@ def C24308873_CylinderShapeCollider_CollidesWithPhysXTerrain():
handler.connect(cylinder_id)
handler.add_callback("OnCollisionBegin", on_collision_begin)
# 3) Wait for the cylinder to hit the ground OR time out
# 4) Wait for the cylinder to hit the ground OR time out
test_completed = helper.wait_for_condition((lambda: TouchGround.value), TIME_OUT)
Report.critical_result(Tests.time_out, test_completed)
Report.result(Tests.touched_ground, TouchGround.value)
# 4) Exit game mode
# 5) Exit game mode
helper.exit_game_mode(Tests.exit_game_mode)

@ -34,4 +34,61 @@ class TestAutomation(TestAutomationBase):
def test_C111111_RigidBody_EnablingGravityWorksUsingNotificationsPoC(self, request, workspace, editor, launcher_platform):
from . import C111111_RigidBody_EnablingGravityWorksUsingNotificationsPoC as test_module
self._run_test(request, workspace, editor, test_module)
@revert_physics_config
def test_C5932041_PhysXForceRegion_LocalSpaceForceOnRigidBodies(self, request, workspace, editor, launcher_platform):
from . import C5932041_PhysXForceRegion_LocalSpaceForceOnRigidBodies as test_module
self._run_test(request, workspace, editor, test_module)
@revert_physics_config
def test_C4044459_Material_DynamicFriction(self, request, workspace, editor, launcher_platform):
from . import C4044459_Material_DynamicFriction as test_module
self._run_test(request, workspace, editor, test_module)
@revert_physics_config
def test_C15425929_Undo_Redo(self, request, workspace, editor, launcher_platform):
from . import C15425929_Undo_Redo as test_module
self._run_test(request, workspace, editor, test_module)
@revert_physics_config
def test_C4976243_Collision_SameCollisionGroupDiffCollisionLayers(self, request, workspace, editor,
launcher_platform):
from . import C4976243_Collision_SameCollisionGroupDiffCollisionLayers as test_module
self._run_test(request, workspace, editor, test_module)
@revert_physics_config
def test_C14654881_CharacterController_SwitchLevels(self, request, workspace, editor, launcher_platform):
from . import C14654881_CharacterController_SwitchLevels as test_module
self._run_test(request, workspace, editor, test_module)
def test_C17411467_AddPhysxRagdollComponent(self, request, workspace, editor, launcher_platform):
from . import C17411467_AddPhysxRagdollComponent as test_module
self._run_test(request, workspace, editor, test_module)
@revert_physics_config
def test_C12712453_ScriptCanvas_MultipleRaycastNode(self, request, workspace, editor, launcher_platform):
from . import C12712453_ScriptCanvas_MultipleRaycastNode as test_module
# Fixme: unexpected_lines = ["Assert"] + test_module.Lines.unexpected
self._run_test(request, workspace, editor, test_module)
@revert_physics_config
@fm.file_override('physxsystemconfiguration.setreg','C4982593_PhysXCollider_CollisionLayer.setreg', 'AutomatedTesting/Registry')
def test_C4982593_PhysXCollider_CollisionLayerTest(self, request, workspace, editor, launcher_platform):
from . import C4982593_PhysXCollider_CollisionLayerTest as test_module
self._run_test(request, workspace, editor, test_module)
@revert_physics_config
def test_C18243586_Joints_HingeLeadFollowerCollide(self, request, workspace, editor, launcher_platform):
from . import C18243586_Joints_HingeLeadFollowerCollide as test_module
self._run_test(request, workspace, editor, test_module)
@revert_physics_config
def test_C4982803_Enable_PxMesh_Option(self, request, workspace, editor, launcher_platform):
from . import C4982803_Enable_PxMesh_Option as test_module
self._run_test(request, workspace, editor, test_module)
@revert_physics_config
def test_C24308873_CylinderShapeCollider_CollidesWithPhysXTerrain(self, request, workspace, editor, launcher_platform):
from . import C24308873_CylinderShapeCollider_CollidesWithPhysXTerrain as test_module
self._run_test(request, workspace, editor, test_module)

@ -52,11 +52,6 @@ class TestAutomation(TestAutomationBase):
from . import C4976207_PhysXRigidBodies_KinematicBehavior as test_module
self._run_test(request, workspace, editor, test_module)
@revert_physics_config
def test_C5932041_PhysXForceRegion_LocalSpaceForceOnRigidBodies(self, request, workspace, editor, launcher_platform):
from . import C5932041_PhysXForceRegion_LocalSpaceForceOnRigidBodies as test_module
self._run_test(request, workspace, editor, test_module)
@revert_physics_config
def test_C5932042_PhysXForceRegion_LinearDamping(self, request, workspace, editor, launcher_platform):
from . import C5932042_PhysXForceRegion_LinearDamping as test_module
@ -92,11 +87,6 @@ class TestAutomation(TestAutomationBase):
from . import C4976194_RigidBody_PhysXComponentIsValid as test_module
self._run_test(request, workspace, editor, test_module)
@revert_physics_config
def test_C4044459_Material_DynamicFriction(self, request, workspace, editor, launcher_platform):
from . import C4044459_Material_DynamicFriction as test_module
self._run_test(request, workspace, editor, test_module)
@revert_physics_config
def test_C5932045_ForceRegion_Spline(self, request, workspace, editor, launcher_platform):
from . import C5932045_ForceRegion_Spline as test_module
@ -208,26 +198,11 @@ class TestAutomation(TestAutomationBase):
from . import C18981526_Material_RestitutionCombinePriority as test_module
self._run_test(request, workspace, editor, test_module)
@revert_physics_config
def test_C15425929_Undo_Redo(self, request, workspace, editor, launcher_platform):
from . import C15425929_Undo_Redo as test_module
self._run_test(request, workspace, editor, test_module)
@revert_physics_config
def test_C15308217_NoCrash_LevelSwitch(self, request, workspace, editor, launcher_platform):
from . import C15308217_NoCrash_LevelSwitch as test_module
self._run_test(request, workspace, editor, test_module)
@revert_physics_config
def test_C12868580_ForceRegion_SplineModifiedTransform(self, request, workspace, editor, launcher_platform):
from . import C12868580_ForceRegion_SplineModifiedTransform as test_module
self._run_test(request, workspace, editor, test_module)
@revert_physics_config
def test_C4976243_Collision_SameCollisionGroupDiffCollisionLayers(self, request, workspace, editor, launcher_platform):
from . import C4976243_Collision_SameCollisionGroupDiffCollisionLayers as test_module
self._run_test(request, workspace, editor, test_module)
@revert_physics_config
def test_C12712455_ScriptCanvas_ShapeCastVerification(self, request, workspace, editor, launcher_platform):
from . import C12712455_ScriptCanvas_ShapeCastVerification as test_module
@ -248,17 +223,6 @@ class TestAutomation(TestAutomationBase):
from . import C6131473_StaticSlice_OnDynamicSliceSpawn as test_module
self._run_test(request, workspace, editor, test_module)
@revert_physics_config
def test_C4982798_Collider_ColliderRotationOffset(self, request, workspace, editor, launcher_platform):
from . import C4982798_Collider_ColliderRotationOffset as test_module
self._run_test(request, workspace, editor, test_module)
@revert_physics_config
def test_C12712453_ScriptCanvas_MultipleRaycastNode(self, request, workspace, editor, launcher_platform):
from . import C12712453_ScriptCanvas_MultipleRaycastNode as test_module
# Fixme: unexpected_lines = ["Assert"] + test_module.Lines.unexpected
self._run_test(request, workspace, editor, test_module)
@revert_physics_config
def test_C5959808_ForceRegion_PositionOffset(self, request, workspace, editor, launcher_platform):
from . import C5959808_ForceRegion_PositionOffset as test_module
@ -275,7 +239,7 @@ class TestAutomation(TestAutomationBase):
def test_C13895144_Ragdoll_ChangeLevel(self, request, workspace, editor, launcher_platform):
from . import C13895144_Ragdoll_ChangeLevel as test_module
self._run_test(request, workspace, editor, test_module)
@revert_physics_config
def test_C5968759_ForceRegion_ExertsSeveralForcesOnRigidBody(self, request, workspace, editor, launcher_platform):
from . import C5968759_ForceRegion_ExertsSeveralForcesOnRigidBody as test_module
@ -305,11 +269,6 @@ class TestAutomation(TestAutomationBase):
from . import C5296614_PhysXMaterial_ColliderShape as test_module
self._run_test(request, workspace, editor, test_module)
@revert_physics_config
def test_C6090547_ForceRegion_ParentChildForceRegions(self, request, workspace, editor, launcher_platform):
from . import C6090547_ForceRegion_ParentChildForceRegions as test_module
self._run_test(request, workspace, editor, test_module)
@revert_physics_config
def test_C4982595_Collider_TriggerDisablesCollision(self, request, workspace, editor, launcher_platform):
from . import C4982595_Collider_TriggerDisablesCollision as test_module
@ -320,11 +279,6 @@ class TestAutomation(TestAutomationBase):
from . import C14976307_Gravity_SetGravityWorks as test_module
self._run_test(request, workspace, editor, test_module)
@revert_physics_config
def test_C14654881_CharacterController_SwitchLevels(self, request, workspace, editor, launcher_platform):
from . import C14654881_CharacterController_SwitchLevels as test_module
self._run_test(request, workspace, editor, test_module)
@revert_physics_config
def test_C15556261_PhysXMaterials_CharacterControllerMaterialAssignment(self, request, workspace, editor, launcher_platform):
from . import C15556261_PhysXMaterials_CharacterControllerMaterialAssignment as test_module
@ -374,18 +328,6 @@ class TestAutomation(TestAutomationBase):
from . import C4044461_Material_Restitution as test_module
self._run_test(request, workspace, editor, test_module)
@revert_physics_config
@fm.file_override('physxsystemconfiguration.setreg','C4982593_PhysXCollider_CollisionLayer.setreg', 'AutomatedTesting/Registry')
def test_C4982593_PhysXCollider_CollisionLayerTest(self, request, workspace, editor, launcher_platform):
from . import C4982593_PhysXCollider_CollisionLayerTest as test_module
self._run_test(request, workspace, editor, test_module)
@revert_physics_config
@fm.file_override('physxsystemconfiguration.setreg','C3510644_Collider_CollisionGroups.setreg', 'AutomatedTesting/Registry')
def test_C3510644_Collider_CollisionGroups(self, request, workspace, editor, launcher_platform):
from . import C3510644_Collider_CollisionGroups as test_module
self._run_test(request, workspace, editor, test_module)
@revert_physics_config
@fm.file_override('physxdefaultsceneconfiguration.setreg','C14902097_ScriptCanvas_PreUpdateEvent.setreg', 'AutomatedTesting/Registry')
def test_C14902097_ScriptCanvas_PreUpdateEvent(self, request, workspace, editor, launcher_platform):
@ -415,11 +357,6 @@ class TestAutomation(TestAutomationBase):
from . import C18243589_Joints_BallSoftLimitsConstrained as test_module
self._run_test(request, workspace, editor, test_module)
@revert_physics_config
def test_C18243586_Joints_HingeLeadFollowerCollide(self, request, workspace, editor, launcher_platform):
from . import C18243586_Joints_HingeLeadFollowerCollide as test_module
self._run_test(request, workspace, editor, test_module)
@revert_physics_config
def test_C18243591_Joints_BallLeadFollowerCollide(self, request, workspace, editor, launcher_platform):
from . import C18243591_Joints_BallLeadFollowerCollide as test_module
@ -441,21 +378,11 @@ class TestAutomation(TestAutomationBase):
from . import C14861500_DefaultSetting_ColliderShape as test_module
self._run_test(request, workspace, editor, test_module)
@revert_physics_config
def test_C19578021_ShapeCollider_CanBeAdded(self, request, workspace, editor, launcher_platform):
from . import C19578021_ShapeCollider_CanBeAdded as test_module
self._run_test(request, workspace, editor, test_module)
@revert_physics_config
def test_C19723164_ShapeCollider_WontCrashEditor(self, request, workspace, editor, launcher_platform):
from . import C19723164_ShapeColliders_WontCrashEditor as test_module
self._run_test(request, workspace, editor, test_module)
@revert_physics_config
def test_C4982803_Enable_PxMesh_Option(self, request, workspace, editor, launcher_platform):
from . import C4982803_Enable_PxMesh_Option as test_module
self._run_test(request, workspace, editor, test_module)
@revert_physics_config
def test_C4982800_PhysXColliderShape_CanBeSelected(self, request, workspace, editor, launcher_platform):
from . import C4982800_PhysXColliderShape_CanBeSelected as test_module
@ -471,10 +398,6 @@ class TestAutomation(TestAutomationBase):
from . import C4982802_PhysXColliderShape_CanBeSelected as test_module
self._run_test(request, workspace, editor, test_module)
def test_C17411467_AddPhysxRagdollComponent(self, request, workspace, editor, launcher_platform):
from . import C17411467_AddPhysxRagdollComponent as test_module
self._run_test(request, workspace, editor, test_module)
def test_C12905528_ForceRegion_WithNonTriggerCollider(self, request, workspace, editor, launcher_platform):
from . import C12905528_ForceRegion_WithNonTriggerCollider as test_module
# Fixme: expected_lines = ["[Warning] (PhysX Force Region) - Please ensure collider component marked as trigger exists in entity"]
@ -522,4 +445,35 @@ class TestAutomation(TestAutomationBase):
def test_C100000_RigidBody_EnablingGravityWorksPoC(self, request, workspace, editor, launcher_platform):
from . import C100000_RigidBody_EnablingGravityWorksPoC as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module)
@revert_physics_config
@fm.file_override('physxsystemconfiguration.setreg','C3510644_Collider_CollisionGroups.setreg', 'AutomatedTesting/Registry')
def test_C3510644_Collider_CollisionGroups(self, request, workspace, editor, launcher_platform):
from . import C3510644_Collider_CollisionGroups as test_module
self._run_test(request, workspace, editor, test_module)
@revert_physics_config
def test_C4982798_Collider_ColliderRotationOffset(self, request, workspace, editor, launcher_platform):
from . import C4982798_Collider_ColliderRotationOffset as test_module
self._run_test(request, workspace, editor, test_module)
@revert_physics_config
def test_C15308217_NoCrash_LevelSwitch(self, request, workspace, editor, launcher_platform):
from . import C15308217_NoCrash_LevelSwitch as test_module
self._run_test(request, workspace, editor, test_module)
@revert_physics_config
def test_C6090547_ForceRegion_ParentChildForceRegions(self, request, workspace, editor, launcher_platform):
from . import C6090547_ForceRegion_ParentChildForceRegions as test_module
self._run_test(request, workspace, editor, test_module)
@revert_physics_config
def test_C19578021_ShapeCollider_CanBeAdded(self, request, workspace, editor, launcher_platform):
from . import C19578021_ShapeCollider_CanBeAdded as test_module
self._run_test(request, workspace, editor, test_module)
@revert_physics_config
def test_C15425929_Undo_Redo(self, request, workspace, editor, launcher_platform):
from . import C15425929_Undo_Redo as test_module
self._run_test(request, workspace, editor, test_module)

@ -1,49 +1,49 @@
"""
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.
"""
# This suite consists of all test cases that are passing and have been verified.
import pytest
import os
import sys
from .FileManagement import FileManagement as fm
from ly_test_tools import LAUNCHERS
sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../automatedtesting_shared')
from base import TestAutomationBase
revert_physics_config = fm.file_revert_list(['physxdebugconfiguration.setreg', 'physxdefaultsceneconfiguration.setreg', 'physxsystemconfiguration.setreg'], 'AutomatedTesting/Registry')
@pytest.mark.SUITE_sandbox
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
@pytest.mark.parametrize("project", ["AutomatedTesting"])
class TestAutomation(TestAutomationBase):
## Seems to be flaky, need to investigate
def test_C19536274_GetCollisionName_PrintsName(self, request, workspace, editor, launcher_platform):
from . import C19536274_GetCollisionName_PrintsName as test_module
# Fixme: expected_lines=["Layer Name: Right"]
self._run_test(request, workspace, editor, test_module)
## Seems to be flaky, need to investigate
def test_C19536277_GetCollisionName_PrintsNothing(self, request, workspace, editor, launcher_platform):
from . import C19536277_GetCollisionName_PrintsNothing as test_module
# All groups present in the PhysX Collider that could show up in test
# Fixme: collision_groups = ["All", "None", "All_NoTouchBend", "All_3", "None_1", "All_NoTouchBend_1", "All_2", "None_1_1", "All_NoTouchBend_1_1", "All_1", "None_1_1_1", "All_NoTouchBend_1_1_1", "All_4", "None_1_1_1_1", "All_NoTouchBend_1_1_1_1", "GroupLeft", "GroupRight"]
# Fixme: for group in collision_groups:
# Fixme: unexpected_lines.append(f"GroupName: {group}")
# Fixme: expected_lines=["GroupName: "]
self._run_test(request, workspace, editor, test_module)
"""
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.
"""
# This suite consists of all test cases that are passing and have been verified.
import pytest
import os
import sys
from .FileManagement import FileManagement as fm
from ly_test_tools import LAUNCHERS
sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../automatedtesting_shared')
from base import TestAutomationBase
revert_physics_config = fm.file_revert_list(['physxdebugconfiguration.setreg', 'physxdefaultsceneconfiguration.setreg', 'physxsystemconfiguration.setreg'], 'AutomatedTesting/Registry')
@pytest.mark.SUITE_sandbox
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
@pytest.mark.parametrize("project", ["AutomatedTesting"])
class TestAutomation(TestAutomationBase):
## Seems to be flaky, need to investigate
def test_C19536274_GetCollisionName_PrintsName(self, request, workspace, editor, launcher_platform):
from . import C19536274_GetCollisionName_PrintsName as test_module
# Fixme: expected_lines=["Layer Name: Right"]
self._run_test(request, workspace, editor, test_module)
## Seems to be flaky, need to investigate
def test_C19536277_GetCollisionName_PrintsNothing(self, request, workspace, editor, launcher_platform):
from . import C19536277_GetCollisionName_PrintsNothing as test_module
# All groups present in the PhysX Collider that could show up in test
# Fixme: collision_groups = ["All", "None", "All_NoTouchBend", "All_3", "None_1", "All_NoTouchBend_1", "All_2", "None_1_1", "All_NoTouchBend_1_1", "All_1", "None_1_1_1", "All_NoTouchBend_1_1_1", "All_4", "None_1_1_1_1", "All_NoTouchBend_1_1_1_1", "GroupLeft", "GroupRight"]
# Fixme: for group in collision_groups:
# Fixme: unexpected_lines.append(f"GroupName: {group}")
# Fixme: expected_lines=["GroupName: "]
self._run_test(request, workspace, editor, test_module)

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:231d5ac32c95334eeb1cbf77ea0bceae1d8010de3290dfdbd991abb46d18bae6
size 6844
oid sha256:83af66a6db4ff2b4df7212099b661a96668cfb326d8984e41b16506ec0062141
size 5844

@ -75,7 +75,9 @@ foreach(restricted_platform ${PAL_RESTRICTED_PLATFORMS})
endif()
endforeach()
add_subdirectory(scripts)
if(NOT INSTALLED_ENGINE)
add_subdirectory(scripts)
endif()
# SPEC-1417 will investigate and fix this
if(NOT PAL_PLATFORM_NAME STREQUAL "Mac")
@ -125,5 +127,5 @@ if(NOT INSTALLED_ENGINE)
ly_setup_o3de_install()
# IMPORTANT: must be included last
include(cmake/CPack.cmake)
include(cmake/Packaging.cmake)
endif()

@ -55,7 +55,7 @@ public:
Matrix34 m_matInv;
Vec3 m_eyePosInWS;
Vec3 m_eyePosInOS;
Plane m_volumeTraceStartPlane;
Plane_tpl<f32> m_volumeTraceStartPlane;
AABB m_renderBoundsOS;
bool m_viewerInsideVolume;
bool m_nearPlaneIntersectsVolume;

@ -25,7 +25,7 @@ public:
virtual void mfPrepare(bool bCheckOverflow);
virtual bool mfDraw(CShader* ef, SShaderPass* sfm);
virtual void mfGetPlane(Plane& pl);
virtual void mfGetPlane(Plane_tpl<f32>& pl);
virtual void Create(uint32 nVerticesCount, SVF_P3F_C4B_T2F* pVertices, uint32 nIndicesCount, const void* pIndices, uint32 nIndexSizeof);
void ReleaseOcean();

@ -27,7 +27,7 @@ public:
virtual ~CREWaterVolume();
virtual void mfPrepare(bool bCheckOverflow);
virtual bool mfDraw(CShader* ef, SShaderPass* sfm);
virtual void mfGetPlane(Plane& pl);
virtual void mfGetPlane(Plane_tpl<f32>& pl);
virtual void mfCenter(Vec3& vCenter, CRenderObject* pObj);
virtual void GetMemoryUsage(ICrySizer* pSizer) const
@ -69,7 +69,7 @@ public:
Vec3 m_center;
AABB m_WSBBox;
Plane m_fogPlane;
Plane_tpl<f32> m_fogPlane;
float m_fogDensity;
Vec3 m_fogColor;
bool m_fogColorAffectedBySun;

@ -594,7 +594,7 @@ public:
ILINE const Vec3& GetFPVertex(int nId) const; //get far-plane vertices
ILINE const Vec3& GetPPVertex(int nId) const; //get projection-plane vertices
ILINE const Plane* GetFrustumPlane(int numplane) const { return &m_fp[numplane]; }
ILINE const Plane_tpl<f32>* GetFrustumPlane(int numplane) const { return &m_fp[numplane]; }
//////////////////////////////////////////////////////////////////////////
// Z-Buffer ranges.
@ -720,7 +720,7 @@ private:
Vec3 m_cltn, m_crtn, m_clbn, m_crbn; //this are the 4 vertices of the near-plane in cam-space
Vec3 m_cltf, m_crtf, m_clbf, m_crbf; //this are the 4 vertices of the farclip-plane in cam-space
Plane m_fp [FRUSTUM_PLANES]; //
Plane_tpl<f32> m_fp [FRUSTUM_PLANES]; //
uint32 m_idx1[FRUSTUM_PLANES], m_idy1[FRUSTUM_PLANES], m_idz1[FRUSTUM_PLANES]; //
uint32 m_idx2[FRUSTUM_PLANES], m_idy2[FRUSTUM_PLANES], m_idz2[FRUSTUM_PLANES]; //
@ -742,7 +742,7 @@ public:
m_crtp = arrvVerts[2];
m_crbp = arrvVerts[3];
}
inline void SetFrustumPlane(int i, const Plane& plane)
inline void SetFrustumPlane(int i, const Plane_tpl<f32>& plane)
{
m_fp[i] = plane;
//do not break strict aliasing rules, use union instead of reinterpret_casts
@ -1180,12 +1180,12 @@ inline void CCamera::UpdateFrustum()
//-------------------------------------------------------------------------------
//--- calculate the six frustum-planes using the frustum edges in world-space ---
//-------------------------------------------------------------------------------
m_fp[FR_PLANE_NEAR ] = Plane::CreatePlane(m_crtn + GetPosition(), m_cltn + GetPosition(), m_crbn + GetPosition());
m_fp[FR_PLANE_RIGHT ] = Plane::CreatePlane(m_crbf + GetPosition(), m_crtf + GetPosition(), GetPosition());
m_fp[FR_PLANE_LEFT ] = Plane::CreatePlane(m_cltf + GetPosition(), m_clbf + GetPosition(), GetPosition());
m_fp[FR_PLANE_TOP ] = Plane::CreatePlane(m_crtf + GetPosition(), m_cltf + GetPosition(), GetPosition());
m_fp[FR_PLANE_BOTTOM] = Plane::CreatePlane(m_clbf + GetPosition(), m_crbf + GetPosition(), GetPosition());
m_fp[FR_PLANE_FAR ] = Plane::CreatePlane(m_crtf + GetPosition(), m_crbf + GetPosition(), m_cltf + GetPosition()); //clip-plane
m_fp[FR_PLANE_NEAR ] = Plane_tpl<f32>::CreatePlane(m_crtn + GetPosition(), m_cltn + GetPosition(), m_crbn + GetPosition());
m_fp[FR_PLANE_RIGHT ] = Plane_tpl<f32>::CreatePlane(m_crbf + GetPosition(), m_crtf + GetPosition(), GetPosition());
m_fp[FR_PLANE_LEFT ] = Plane_tpl<f32>::CreatePlane(m_cltf + GetPosition(), m_clbf + GetPosition(), GetPosition());
m_fp[FR_PLANE_TOP ] = Plane_tpl<f32>::CreatePlane(m_crtf + GetPosition(), m_cltf + GetPosition(), GetPosition());
m_fp[FR_PLANE_BOTTOM] = Plane_tpl<f32>::CreatePlane(m_clbf + GetPosition(), m_crbf + GetPosition(), GetPosition());
m_fp[FR_PLANE_FAR ] = Plane_tpl<f32>::CreatePlane(m_crtf + GetPosition(), m_crbf + GetPosition(), m_cltf + GetPosition()); //clip-plane
uint32 rh = m_Matrix.IsOrthonormalRH();
if (rh == 0)

@ -1168,17 +1168,6 @@ namespace Distance {
return fDist2;
}
// Compute both the min and max distances of a box to a plane, in the sense of the plane normal.
inline void AABB_Plane(float* pfDistMin, float* pfDistMax, const AABB& box, const Plane& pl)
{
float fDist0 = pl.DistFromPlane(box.min),
fDistX = (box.max.x - box.min.x) * pl.n.x,
fDistY = (box.max.y - box.min.y) * pl.n.y,
fDistZ = (box.max.z - box.min.z) * pl.n.z;
*pfDistMin = fDist0 + min(fDistX, 0.f) + min(fDistY, 0.f) + min(fDistZ, 0.f);
*pfDistMax = fDist0 + max(fDistX, 0.f) + max(fDistY, 0.f) + max(fDistZ, 0.f);
}
//----------------------------------------------------------------------------------
// Distance: Sphere_Triangle
//----------------------------------------------------------------------------------

@ -22,7 +22,7 @@
#include <Cry_Geo.h>
namespace Intersect {
inline bool Ray_Plane(const Ray& ray, const Plane& plane, Vec3& output, bool bSingleSidePlane = true)
inline bool Ray_Plane(const Ray& ray, const Plane_tpl<f32>& plane, Vec3& output, bool bSingleSidePlane = true)
{
float cosine = plane.n | ray.direction;
@ -49,7 +49,7 @@ namespace Intersect {
return true; //intersection occurred
}
inline bool Line_Plane(const Line& line, const Plane& plane, Vec3& output, bool bSingleSidePlane = true)
inline bool Line_Plane(const Line& line, const Plane_tpl<f32>& plane, Vec3& output, bool bSingleSidePlane = true)
{
float cosine = plane.n | line.direction;

@ -945,29 +945,6 @@ namespace Overlap {
}
}
/*!
*
* we use the SEPARATING-AXIS-TEST for OBB/Plane overlap.
*
* Example:
* bool result=Overlap::OBB_Plane( pos,obb, plane );
*
*/
inline bool OBB_Plane(const Vec3& pos, const OBB& obb, const Plane& plane)
{
//the new center-position in world-space
Vec3 p = obb.m33 * obb.c + pos;
//extract the orientation-vectors from the columns of the 3x3 matrix
//and scale them by the half-lengths
Vec3 ax = Vec3(obb.m33.m00, obb.m33.m10, obb.m33.m20) * obb.h.x;
Vec3 ay = Vec3(obb.m33.m01, obb.m33.m11, obb.m33.m21) * obb.h.y;
Vec3 az = Vec3(obb.m33.m02, obb.m33.m12, obb.m33.m22) * obb.h.z;
//check OBB against Plane, using the plane-normal as separating axis
return fabsf(plane | p) < (fabsf(plane.n | ax) + fabsf(plane.n | ay) + fabsf(plane.n | az));
}
/*!
*
* we use the SEPARATING AXIS TEST to check if a triangle and AABB overlap.
@ -1214,7 +1191,7 @@ namespace Overlap {
//test if the box intersects the plane of the triangle
//compute plane equation of triangle: normal*x+d=0
Plane plane = Plane::CreatePlane((e0 % e1), v0);
Plane_tpl<f32> plane = Plane_tpl<f32>::CreatePlane((e0 % e1), v0);
Vec3 vmin, vmax;
if (plane.n.x > 0.0f)
@ -1505,7 +1482,7 @@ namespace Overlap {
//test if the box overlaps the plane of the triangle
//compute plane equation of triangle: normal*x+d=0
Plane plane = Plane::CreatePlane((e0 % e1), v0);
Plane_tpl<f32> plane = Plane_tpl<f32>::CreatePlane((e0 % e1), v0);
Vec3 vmin, vmax;
if (plane.n.x > 0.0f)

@ -458,7 +458,7 @@ struct SClipVolumeBlendInfo
{
static const int BlendPlaneCount = 2;
Plane blendPlanes[BlendPlaneCount];
Plane_tpl<f32> blendPlanes[BlendPlaneCount];
struct IClipVolume* blendVolumes[BlendPlaneCount];
};

@ -731,8 +731,8 @@ struct IWaterVolumeRenderNode
virtual void SetAuxPhysParams(pe_params_area*) = 0;
virtual void CreateOcean(uint64 volumeID, /* TBD */ bool keepSerializationParams = false) = 0;
virtual void CreateArea(uint64 volumeID, const Vec3* pVertices, unsigned int numVertices, const Vec2& surfUVScale, const Plane& fogPlane, bool keepSerializationParams = false, int nSID = -1) = 0;
virtual void CreateRiver(uint64 volumeID, const Vec3* pVertices, unsigned int numVertices, float uTexCoordBegin, float uTexCoordEnd, const Vec2& surfUVScale, const Plane& fogPlane, bool keepSerializationParams = false, int nSID = -1) = 0;
virtual void CreateArea(uint64 volumeID, const Vec3* pVertices, unsigned int numVertices, const Vec2& surfUVScale, const Plane_tpl<f32>& fogPlane, bool keepSerializationParams = false, int nSID = -1) = 0;
virtual void CreateRiver(uint64 volumeID, const Vec3* pVertices, unsigned int numVertices, float uTexCoordBegin, float uTexCoordEnd, const Vec2& surfUVScale, const Plane_tpl<f32>& fogPlane, bool keepSerializationParams = false, int nSID = -1) = 0;
virtual void CreateRiver(uint64 volumeID, const AZStd::vector<AZ::Vector3>& verticies, const AZ::Transform& transform, float uTexCoordBegin, float uTexCoordEnd, const AZ::Vector2& surfUVScale, const AZ::Plane& fogPlane, bool keepSerializationParams = false, int nSID = -1) = 0;
virtual void SetAreaPhysicsArea(const Vec3* pVertices, unsigned int numVertices, bool keepSerializationParams = false) = 0;

@ -52,7 +52,6 @@ struct SShaderItem;
class ITexture;
struct IMaterial;
struct SParam;
class CMaterial;
struct SShaderSerializeContext;
struct IAnimNode;
struct SSkinningData;

@ -119,7 +119,7 @@ struct IRenderElement
virtual void mfCenter(Vec3& centr, CRenderObject* pObj) = 0;
virtual void mfGetBBox(Vec3& vMins, Vec3& vMaxs) = 0;
virtual void mfReset() = 0;
virtual void mfGetPlane(Plane& pl) = 0;
virtual void mfGetPlane(Plane_tpl<f32>& pl) = 0;
virtual void mfExport(struct SShaderSerializeContext& SC) = 0;
virtual void mfImport(struct SShaderSerializeContext& SC, uint32& offset) = 0;
virtual void mfPrecache(const SShaderItem& SH) = 0;
@ -265,7 +265,7 @@ public:
void mfPrecache([[maybe_unused]] const SShaderItem& SH) override {}
void mfExport([[maybe_unused]] struct SShaderSerializeContext& SC) override { CryFatalError("mfExport has not been implemented for this render element type"); }
void mfImport([[maybe_unused]] struct SShaderSerializeContext& SC, [[maybe_unused]] uint32& offset) override { CryFatalError("mfImport has not been implemented for this render element type"); }
void mfGetPlane(Plane& pl) override;
void mfGetPlane(Plane_tpl<f32>& pl) override;
void* mfGetPointer([[maybe_unused]] ESrcPointer ePT, [[maybe_unused]] int* Stride, [[maybe_unused]] EParamType Type, [[maybe_unused]] ESrcPointer Dst, [[maybe_unused]] int Flags) override { return nullptr; }
uint16 mfGetFlags() override { return m_Flags; }

@ -31,7 +31,6 @@
#include <AzCore/Interface/Interface.h>
#include <AzFramework/Logging/MissingAssetLogger.h>
#include <AzFramework/Entity/EntityDebugDisplayBus.h>
#include <AzFramework/API/AtomActiveInterface.h>
#include <AzCore/Interface/Interface.h>
@ -1162,31 +1161,6 @@ void CSystem::SleepIfInactive()
{
return;
}
#if defined(WIN32)
if (!AZ::Interface<AzFramework::AtomActiveInterface>::Get())
{
WIN_HWND hRendWnd = GetIRenderer()->GetHWND();
if (!hRendWnd)
{
return;
}
AZ_TRACE_METHOD();
// Loop here waiting for window to be activated.
for (int nLoops = 0; nLoops < 5; nLoops++)
{
WIN_HWND hActiveWnd = ::GetActiveWindow();
if (hActiveWnd == hRendWnd)
{
break;
}
AzFramework::ApplicationRequests::Bus::Broadcast(&AzFramework::ApplicationRequests::PumpSystemEventLoopUntilEmpty);
Sleep(5);
}
}
#endif
}
//////////////////////////////////////////////////////////////////////////

@ -68,7 +68,6 @@
#include <LyShine/Bus/UiSystemBus.h>
#include <AzFramework/Logging/MissingAssetLogger.h>
#include <AzFramework/Platform/PlatformDefaults.h>
#include <AzFramework/API/AtomActiveInterface.h>
#include <AzCore/Interface/Interface.h>
#include <AzCore/Utils/Utils.h>
@ -2462,21 +2461,6 @@ AZ_POP_DISABLE_WARNING
m_env.pRenderer->SetViewport(0, 0, screenWidth, screenHeight);
// Skip splash screen rendering
if (!AZ::Interface<AzFramework::AtomActiveInterface>::Get())
{
// make sure it's rendered in full screen mode when triple buffering is enabled as well
for (size_t n = 0; n < 3; n++)
{
m_env.pRenderer->BeginFrame();
m_env.pRenderer->SetCullMode(R_CULL_NONE);
m_env.pRenderer->SetState(GS_BLSRC_SRCALPHA | GS_BLDST_ONEMINUSSRCALPHA | GS_NODEPTHTEST);
m_env.pRenderer->Draw2dImageStretchMode(true);
m_env.pRenderer->Draw2dImage(x * vx, y * vy, w * vx, h * vy, pTex->GetTextureID(), 0.0f, 1.0f, 1.0f, 0.0f);
m_env.pRenderer->Draw2dImageStretchMode(false);
m_env.pRenderer->EndFrame();
}
}
#if defined(AZ_PLATFORM_IOS) || defined(AZ_PLATFORM_MAC)
// Pump system events in order to update the screen
AzFramework::ApplicationRequests::Bus::Broadcast(&AzFramework::ApplicationRequests::PumpSystemEventLoopUntilEmpty);

@ -239,8 +239,13 @@ namespace AZ
return;
}
CheckReady();
m_initComplete = true;
// *After* setting initComplete to true, check to see if the assets are already ready.
// This check needs to wait until after setting initComplete because if they *are* ready, we want the final call to
// RemoveWaitingAsset to trigger the OnAssetContainerReady/Canceled event. If we call CheckReady() *before* setting
// initComplete, if all the assets are ready, the event will never get triggered.
CheckReady();
}
bool AssetContainer::IsReady() const

@ -142,27 +142,44 @@ namespace AZ
void SetBasis(const Vector3& basisX, const Vector3& basisY, const Vector3& basisZ);
//! @}
Matrix3x3 operator*(const Matrix3x3& rhs) const;
//! Calculates (this->GetTranspose() * rhs).
Matrix3x3 TransposedMultiply(const Matrix3x3& rhs) const;
//! Post-multiplies the matrix by a vector.
Vector3 operator*(const Vector3& rhs) const;
Matrix3x3 operator+(const Matrix3x3& rhs) const;
Matrix3x3 operator-(const Matrix3x3& rhs) const;
Matrix3x3 operator*(float multiplier) const;
Matrix3x3 operator/(float divisor) const;
//! Operator for matrix-matrix addition.
//! @{
[[nodiscard]] Matrix3x3 operator+(const Matrix3x3& rhs) const;
Matrix3x3& operator+=(const Matrix3x3& rhs);
//! @}
Matrix3x3 operator-() const;
//! Operator for matrix-matrix substraction.
//! @{
[[nodiscard]] Matrix3x3 operator-(const Matrix3x3& rhs) const;
Matrix3x3& operator-=(const Matrix3x3& rhs);
//! @}
//! Operator for matrix-matrix multiplication.
//! @{
[[nodiscard]] Matrix3x3 operator*(const Matrix3x3& rhs) const;
Matrix3x3& operator*=(const Matrix3x3& rhs);
Matrix3x3& operator+=(const Matrix3x3& rhs);
Matrix3x3& operator-=(const Matrix3x3& rhs);
//! @}
//! Operator for multiplying all matrix's elements with a scalar
//! @{
[[nodiscard]] Matrix3x3 operator*(float multiplier) const;
Matrix3x3& operator*=(float multiplier);
//! @}
//! Operator for dividing all matrix's elements with a scalar
//! @{
[[nodiscard]] Matrix3x3 operator/(float divisor) const;
Matrix3x3& operator/=(float divisor);
//! @}
//! Operator for negating all matrix's elements
[[nodiscard]] Matrix3x3 operator-() const;
bool operator==(const Matrix3x3& rhs) const;
bool operator!=(const Matrix3x3& rhs) const;
@ -187,7 +204,10 @@ namespace AZ
//! @}
//! Gets the scale part of the transformation, i.e. the length of the scale components.
Vector3 RetrieveScale() const;
[[nodiscard]] Vector3 RetrieveScale() const;
//! Gets the squared scale part of the transformation (the squared length of the basis vectors).
[[nodiscard]] Vector3 RetrieveScaleSq() const;
//! Gets the scale part of the transformation as in RetrieveScale, and also removes this scaling from the matrix.
Vector3 ExtractScale();
@ -195,6 +215,9 @@ namespace AZ
//! Quick multiplication by a scale matrix, equivalent to m*=Matrix3x3::CreateScale(scale).
void MultiplyByScale(const Vector3& scale);
//! Returns a matrix with the reciprocal scale, keeping the same rotation and translation.
[[nodiscard]] Matrix3x3 GetReciprocalScaled() const;
//! Polar decomposition, M=U*H, U is orthogonal (unitary) and H is symmetric (hermitian).
//! This function returns the orthogonal part only
Matrix3x3 GetPolarDecomposition() const;
@ -241,7 +264,9 @@ namespace AZ
//! Note that this is not the usual multiplication order for transformations.
Vector3& operator*=(Vector3& lhs, const Matrix3x3& rhs);
//! Pre-multiplies the matrix by a scalar.
Matrix3x3 operator*(float lhs, const Matrix3x3& rhs);
}
} // namespace AZ
#include <AzCore/Math/Matrix3x3.inl>

@ -392,14 +392,6 @@ namespace AZ
}
AZ_MATH_INLINE Matrix3x3 Matrix3x3::operator*(const Matrix3x3& rhs) const
{
Matrix3x3 result;
Simd::Vec3::Mat3x3Multiply(GetSimdValues(), rhs.GetSimdValues(), result.GetSimdValues());
return result;
}
AZ_MATH_INLINE Matrix3x3 Matrix3x3::TransposedMultiply(const Matrix3x3& rhs) const
{
Matrix3x3 result;
@ -416,44 +408,45 @@ namespace AZ
AZ_MATH_INLINE Matrix3x3 Matrix3x3::operator+(const Matrix3x3& rhs) const
{
return Matrix3x3(Simd::Vec3::Add(m_rows[0].GetSimdValue(), rhs.m_rows[0].GetSimdValue())
, Simd::Vec3::Add(m_rows[1].GetSimdValue(), rhs.m_rows[1].GetSimdValue())
, Simd::Vec3::Add(m_rows[2].GetSimdValue(), rhs.m_rows[2].GetSimdValue()));
return Matrix3x3
(
Simd::Vec3::Add(m_rows[0].GetSimdValue(), rhs.m_rows[0].GetSimdValue()),
Simd::Vec3::Add(m_rows[1].GetSimdValue(), rhs.m_rows[1].GetSimdValue()),
Simd::Vec3::Add(m_rows[2].GetSimdValue(), rhs.m_rows[2].GetSimdValue())
);
}
AZ_MATH_INLINE Matrix3x3 Matrix3x3::operator-(const Matrix3x3& rhs) const
AZ_MATH_INLINE Matrix3x3& Matrix3x3::operator+=(const Matrix3x3& rhs)
{
return Matrix3x3(Simd::Vec3::Sub(m_rows[0].GetSimdValue(), rhs.m_rows[0].GetSimdValue())
, Simd::Vec3::Sub(m_rows[1].GetSimdValue(), rhs.m_rows[1].GetSimdValue())
, Simd::Vec3::Sub(m_rows[2].GetSimdValue(), rhs.m_rows[2].GetSimdValue()));
*this = *this + rhs;
return *this;
}
AZ_MATH_INLINE Matrix3x3 Matrix3x3::operator*(float multiplier) const
AZ_MATH_INLINE Matrix3x3 Matrix3x3::operator-(const Matrix3x3& rhs) const
{
const Simd::Vec3::FloatType mulVec = Simd::Vec3::Splat(multiplier);
return Matrix3x3(Simd::Vec3::Mul(m_rows[0].GetSimdValue(), mulVec)
, Simd::Vec3::Mul(m_rows[1].GetSimdValue(), mulVec)
, Simd::Vec3::Mul(m_rows[2].GetSimdValue(), mulVec));
return Matrix3x3
(
Simd::Vec3::Sub(m_rows[0].GetSimdValue(), rhs.m_rows[0].GetSimdValue()),
Simd::Vec3::Sub(m_rows[1].GetSimdValue(), rhs.m_rows[1].GetSimdValue()),
Simd::Vec3::Sub(m_rows[2].GetSimdValue(), rhs.m_rows[2].GetSimdValue())
);
}
AZ_MATH_INLINE Matrix3x3 Matrix3x3::operator/(float divisor) const
AZ_MATH_INLINE Matrix3x3& Matrix3x3::operator-=(const Matrix3x3& rhs)
{
const Simd::Vec3::FloatType divVec = Simd::Vec3::Splat(divisor);
return Matrix3x3(Simd::Vec3::Div(m_rows[0].GetSimdValue(), divVec)
, Simd::Vec3::Div(m_rows[1].GetSimdValue(), divVec)
, Simd::Vec3::Div(m_rows[2].GetSimdValue(), divVec));
*this = *this - rhs;
return *this;
}
AZ_MATH_INLINE Matrix3x3 Matrix3x3::operator-() const
AZ_MATH_INLINE Matrix3x3 Matrix3x3::operator*(const Matrix3x3& rhs) const
{
const Simd::Vec3::FloatType zeroVec = Simd::Vec3::ZeroFloat();
return Matrix3x3(Simd::Vec3::Sub(zeroVec, m_rows[0].GetSimdValue())
, Simd::Vec3::Sub(zeroVec, m_rows[1].GetSimdValue())
, Simd::Vec3::Sub(zeroVec, m_rows[2].GetSimdValue()));
Matrix3x3 result;
Simd::Vec3::Mat3x3Multiply(GetSimdValues(), rhs.GetSimdValues(), result.GetSimdValues());
return result;
}
@ -464,24 +457,34 @@ namespace AZ
}
AZ_MATH_INLINE Matrix3x3& Matrix3x3::operator+=(const Matrix3x3& rhs)
AZ_MATH_INLINE Matrix3x3 Matrix3x3::operator*(float multiplier) const
{
*this = *this + rhs;
return *this;
const Simd::Vec3::FloatType mulVec = Simd::Vec3::Splat(multiplier);
return Matrix3x3
(
Simd::Vec3::Mul(m_rows[0].GetSimdValue(), mulVec),
Simd::Vec3::Mul(m_rows[1].GetSimdValue(), mulVec),
Simd::Vec3::Mul(m_rows[2].GetSimdValue(), mulVec)
);
}
AZ_MATH_INLINE Matrix3x3& Matrix3x3::operator-=(const Matrix3x3& rhs)
AZ_MATH_INLINE Matrix3x3& Matrix3x3::operator*=(float multiplier)
{
*this = *this - rhs;
*this = *this * multiplier;
return *this;
}
AZ_MATH_INLINE Matrix3x3& Matrix3x3::operator*=(float multiplier)
AZ_MATH_INLINE Matrix3x3 Matrix3x3::operator/(float divisor) const
{
*this = *this * multiplier;
return *this;
const Simd::Vec3::FloatType divVec = Simd::Vec3::Splat(divisor);
return Matrix3x3
(
Simd::Vec3::Div(m_rows[0].GetSimdValue(), divVec),
Simd::Vec3::Div(m_rows[1].GetSimdValue(), divVec),
Simd::Vec3::Div(m_rows[2].GetSimdValue(), divVec)
);
}
@ -492,6 +495,18 @@ namespace AZ
}
AZ_MATH_INLINE Matrix3x3 Matrix3x3::operator-() const
{
const Simd::Vec3::FloatType zeroVec = Simd::Vec3::ZeroFloat();
return Matrix3x3
(
Simd::Vec3::Sub(zeroVec, m_rows[0].GetSimdValue()),
Simd::Vec3::Sub(zeroVec, m_rows[1].GetSimdValue()),
Simd::Vec3::Sub(zeroVec, m_rows[2].GetSimdValue())
);
}
AZ_MATH_INLINE bool Matrix3x3::operator==(const Matrix3x3& rhs) const
{
return (Simd::Vec3::CmpAllEq(m_rows[0].GetSimdValue(), rhs.m_rows[0].GetSimdValue())
@ -552,6 +567,12 @@ namespace AZ
}
AZ_MATH_INLINE Vector3 Matrix3x3::RetrieveScaleSq() const
{
return Vector3(GetBasisX().GetLengthSq(), GetBasisY().GetLengthSq(), GetBasisZ().GetLengthSq());
}
AZ_MATH_INLINE Vector3 Matrix3x3::ExtractScale()
{
const Vector3 x = GetBasisX();
@ -584,6 +605,14 @@ namespace AZ
}
AZ_MATH_INLINE Matrix3x3 Matrix3x3::GetReciprocalScaled() const
{
Matrix3x3 result = *this;
result.MultiplyByScale(RetrieveScaleSq().GetReciprocal());
return result;
}
AZ_MATH_INLINE void Matrix3x3::GetPolarDecomposition(Matrix3x3* orthogonalOut, Matrix3x3* symmetricOut) const
{
*orthogonalOut = GetPolarDecomposition();
@ -679,8 +708,6 @@ namespace AZ
AZ_MATH_INLINE Matrix3x3 operator*(float lhs, const Matrix3x3& rhs)
{
const Simd::Vec3::FloatType lhsVec = Simd::Vec3::Splat(lhs);
const Simd::Vec3::FloatType* rows = rhs.GetSimdValues();
return Matrix3x3(Simd::Vec3::Mul(lhsVec, rows[0]), Simd::Vec3::Mul(lhsVec, rows[1]), Simd::Vec3::Mul(lhsVec, rows[2]));
return rhs * lhs;
}
}
} // namespace AZ

@ -225,11 +225,38 @@ namespace AZ
//! Sets the three basis vectors and the translation.
void SetBasisAndTranslation(const Vector3& basisX, const Vector3& basisY, const Vector3& basisZ, const Vector3& translation);
//! Operator for matrix-matrix addition.
//! @{
[[nodiscard]] Matrix3x4 operator+(const Matrix3x4& rhs) const;
Matrix3x4& operator+=(const Matrix3x4& rhs);
//! @}
//! Operator for matrix-matrix substraction.
//! @{
[[nodiscard]] Matrix3x4 operator-(const Matrix3x4& rhs) const;
Matrix3x4& operator-=(const Matrix3x4& rhs);
//! @}
//! Operator for matrix-matrix multiplication.
//! @{
[[nodiscard]] Matrix3x4 operator*(const Matrix3x4& rhs) const;
//! Compound assignment operator for matrix-matrix multiplication.
Matrix3x4& operator*=(const Matrix3x4& rhs);
//! @}
//! Operator for multiplying all matrix's elements with a scalar
//! @{
[[nodiscard]] Matrix3x4 operator*(float multiplier) const;
Matrix3x4& operator*=(float multiplier);
//! @}
//! Operator for dividing all matrix's elements with a scalar
//! @{
[[nodiscard]] Matrix3x4 operator/(float divisor) const;
Matrix3x4& operator/=(float divisor);
//! @}
//! Operator for negating all matrix's elements
[[nodiscard]] Matrix3x4 operator-() const;
//! Operator for transforming a Vector3.
[[nodiscard]] Vector3 operator*(const Vector3& rhs) const;
@ -274,12 +301,18 @@ namespace AZ
//! Gets the scale part of the transformation (the length of the basis vectors).
[[nodiscard]] Vector3 RetrieveScale() const;
//! Gets the squared scale part of the transformation (the squared length of the basis vectors).
[[nodiscard]] Vector3 RetrieveScaleSq() const;
//! Gets the scale part of the transformation as in RetrieveScale, and also removes this scaling from the matrix.
Vector3 ExtractScale();
//! Multiplies the basis vectors of the matrix by the elements of the scale specified.
void MultiplyByScale(const Vector3& scale);
//! Returns a matrix with the reciprocal scale, keeping the same rotation and translation.
[[nodiscard]] Matrix3x4 GetReciprocalScaled() const;
//! Tests if the 3x3 part of the matrix is orthogonal.
bool IsOrthogonal(float tolerance = Constants::Tolerance) const;
@ -335,6 +368,10 @@ namespace AZ
Vector4 m_rows[RowCount];
};
//! Pre-multiplies the matrix by a scalar.
Matrix3x4 operator*(float lhs, const Matrix3x4& rhs);
} // namespace AZ
#include <AzCore/Math/Matrix3x4.inl>

@ -472,6 +472,42 @@ namespace AZ
}
AZ_MATH_INLINE Matrix3x4 Matrix3x4::operator+(const Matrix3x4& rhs) const
{
return Matrix3x4
(
Simd::Vec4::Add(m_rows[0].GetSimdValue(), rhs.m_rows[0].GetSimdValue()),
Simd::Vec4::Add(m_rows[1].GetSimdValue(), rhs.m_rows[1].GetSimdValue()),
Simd::Vec4::Add(m_rows[2].GetSimdValue(), rhs.m_rows[2].GetSimdValue())
);
}
AZ_MATH_INLINE Matrix3x4& Matrix3x4::operator+=(const Matrix3x4& rhs)
{
*this = *this + rhs;
return *this;
}
AZ_MATH_INLINE Matrix3x4 Matrix3x4::operator-(const Matrix3x4& rhs) const
{
return Matrix3x4
(
Simd::Vec4::Sub(m_rows[0].GetSimdValue(), rhs.m_rows[0].GetSimdValue()),
Simd::Vec4::Sub(m_rows[1].GetSimdValue(), rhs.m_rows[1].GetSimdValue()),
Simd::Vec4::Sub(m_rows[2].GetSimdValue(), rhs.m_rows[2].GetSimdValue())
);
}
AZ_MATH_INLINE Matrix3x4& Matrix3x4::operator-=(const Matrix3x4& rhs)
{
*this = *this - rhs;
return *this;
}
AZ_MATH_INLINE Matrix3x4 Matrix3x4::operator*(const Matrix3x4& rhs) const
{
Matrix3x4 result;
@ -487,6 +523,56 @@ namespace AZ
}
AZ_MATH_INLINE Matrix3x4 Matrix3x4::operator*(float multiplier) const
{
const Simd::Vec4::FloatType mulVec = Simd::Vec4::Splat(multiplier);
return Matrix3x4
(
Simd::Vec4::Mul(m_rows[0].GetSimdValue(), mulVec),
Simd::Vec4::Mul(m_rows[1].GetSimdValue(), mulVec),
Simd::Vec4::Mul(m_rows[2].GetSimdValue(), mulVec)
);
}
AZ_MATH_INLINE Matrix3x4& Matrix3x4::operator*=(float multiplier)
{
*this = *this * multiplier;
return *this;
}
AZ_MATH_INLINE Matrix3x4 Matrix3x4::operator/(float divisor) const
{
const Simd::Vec4::FloatType divVec = Simd::Vec4::Splat(divisor);
return Matrix3x4
(
Simd::Vec4::Div(m_rows[0].GetSimdValue(), divVec),
Simd::Vec4::Div(m_rows[1].GetSimdValue(), divVec),
Simd::Vec4::Div(m_rows[2].GetSimdValue(), divVec)
);
}
AZ_MATH_INLINE Matrix3x4& Matrix3x4::operator/=(float divisor)
{
*this = *this / divisor;
return *this;
}
AZ_MATH_INLINE Matrix3x4 Matrix3x4::operator-() const
{
const Simd::Vec4::FloatType zeroVec = Simd::Vec4::ZeroFloat();
return Matrix3x4
(
Simd::Vec4::Sub(zeroVec, m_rows[0].GetSimdValue()),
Simd::Vec4::Sub(zeroVec, m_rows[1].GetSimdValue()),
Simd::Vec4::Sub(zeroVec, m_rows[2].GetSimdValue())
);
}
AZ_MATH_INLINE Vector3 Matrix3x4::operator*(const Vector3& rhs) const
{
return Vector3
@ -583,6 +669,12 @@ namespace AZ
}
AZ_MATH_INLINE Vector3 Matrix3x4::RetrieveScaleSq() const
{
return Vector3(GetColumn(0).GetLengthSq(), GetColumn(1).GetLengthSq(), GetColumn(2).GetLengthSq());
}
AZ_MATH_INLINE Vector3 Matrix3x4::ExtractScale()
{
const Vector3 scale = RetrieveScale();
@ -600,6 +692,14 @@ namespace AZ
}
AZ_MATH_INLINE Matrix3x4 Matrix3x4::GetReciprocalScaled() const
{
Matrix3x4 result = *this;
result.MultiplyByScale(RetrieveScaleSq().GetReciprocal());
return result;
}
AZ_MATH_INLINE void Matrix3x4::Orthogonalize()
{
*this = GetOrthogonalized();
@ -660,4 +760,10 @@ namespace AZ
{
return reinterpret_cast<Simd::Vec4::FloatType*>(m_rows);
}
AZ_MATH_INLINE Matrix3x4 operator*(float lhs, const Matrix3x4& rhs)
{
return rhs * lhs;
}
} // namespace AZ

@ -171,14 +171,38 @@ namespace AZ
void SetTranslation(const Vector3& v);
//! @}
Matrix4x4 operator+(const Matrix4x4& rhs) const;
//! Operator for matrix-matrix addition.
//! @{
[[nodiscard]] Matrix4x4 operator+(const Matrix4x4& rhs) const;
Matrix4x4& operator+=(const Matrix4x4& rhs);
//! @}
Matrix4x4 operator-(const Matrix4x4& rhs) const;
//! Operator for matrix-matrix substraction.
//! @{
[[nodiscard]] Matrix4x4 operator-(const Matrix4x4& rhs) const;
Matrix4x4& operator-=(const Matrix4x4& rhs);
//! @}
Matrix4x4 operator*(const Matrix4x4& rhs) const;
//! Operator for matrix-matrix multiplication.
//! @{
[[nodiscard]] Matrix4x4 operator*(const Matrix4x4& rhs) const;
Matrix4x4& operator*=(const Matrix4x4& rhs);
//! @}
//! Operator for multiplying all matrix's elements with a scalar
//! @{
[[nodiscard]] Matrix4x4 operator*(float multiplier) const;
Matrix4x4& operator*=(float multiplier);
//! @}
//! Operator for dividing all matrix's elements with a scalar
//! @{
[[nodiscard]] Matrix4x4 operator/(float divisor) const;
Matrix4x4& operator/=(float divisor);
//! @}
//! Operator for negating all matrix's elements
[[nodiscard]] Matrix4x4 operator-() const;
//! Post-multiplies the matrix by a vector.
//! Assumes that the w-component of the Vector3 is 1.0.
@ -222,7 +246,10 @@ namespace AZ
//! @}
//! Gets the scale part of the transformation, i.e. the length of the scale components.
Vector3 RetrieveScale() const;
[[nodiscard]] Vector3 RetrieveScale() const;
//! Gets the squared scale part of the transformation (the squared length of the basis vectors).
[[nodiscard]] Vector3 RetrieveScaleSq() const;
//! Gets the scale part of the transformation as in RetrieveScale, and also removes this scaling from the matrix.
Vector3 ExtractScale();
@ -230,6 +257,9 @@ namespace AZ
//! Quick multiplication by a scale matrix, equivalent to m*=Matrix4x4::CreateScale(scale).
void MultiplyByScale(const Vector3& scale);
//! Returns a matrix with the reciprocal scale, keeping the same rotation and translation.
[[nodiscard]] Matrix4x4 GetReciprocalScaled() const;
bool IsClose(const Matrix4x4& rhs, float tolerance = Constants::Tolerance) const;
bool operator==(const Matrix4x4& rhs) const;
@ -270,6 +300,10 @@ namespace AZ
//! Pre-multiplies the matrix by a vector in-place.
//! Note that this is not the usual multiplication order for transformations.
Vector4& operator*=(Vector4& lhs, const Matrix4x4& rhs);
}
//! Pre-multiplies the matrix by a scalar.
Matrix4x4 operator*(float lhs, const Matrix4x4& rhs);
} // namespace AZ
#include <AzCore/Math/Matrix4x4.inl>

@ -480,20 +480,12 @@ namespace AZ
AZ_MATH_INLINE Matrix4x4 Matrix4x4::operator+(const Matrix4x4& rhs) const
{
return Matrix4x4
( Simd::Vec4::Add(m_rows[0].GetSimdValue(), rhs.m_rows[0].GetSimdValue())
, Simd::Vec4::Add(m_rows[1].GetSimdValue(), rhs.m_rows[1].GetSimdValue())
, Simd::Vec4::Add(m_rows[2].GetSimdValue(), rhs.m_rows[2].GetSimdValue())
, Simd::Vec4::Add(m_rows[3].GetSimdValue(), rhs.m_rows[3].GetSimdValue()));
}
AZ_MATH_INLINE Matrix4x4 Matrix4x4::operator-(const Matrix4x4& rhs) const
{
return Matrix4x4
( Simd::Vec4::Sub(m_rows[0].GetSimdValue(), rhs.m_rows[0].GetSimdValue())
, Simd::Vec4::Sub(m_rows[1].GetSimdValue(), rhs.m_rows[1].GetSimdValue())
, Simd::Vec4::Sub(m_rows[2].GetSimdValue(), rhs.m_rows[2].GetSimdValue())
, Simd::Vec4::Sub(m_rows[3].GetSimdValue(), rhs.m_rows[3].GetSimdValue()));
(
Simd::Vec4::Add(m_rows[0].GetSimdValue(), rhs.m_rows[0].GetSimdValue()),
Simd::Vec4::Add(m_rows[1].GetSimdValue(), rhs.m_rows[1].GetSimdValue()),
Simd::Vec4::Add(m_rows[2].GetSimdValue(), rhs.m_rows[2].GetSimdValue()),
Simd::Vec4::Add(m_rows[3].GetSimdValue(), rhs.m_rows[3].GetSimdValue())
);
}
AZ_MATH_INLINE Matrix4x4& Matrix4x4::operator+=(const Matrix4x4& rhs)
@ -502,6 +494,18 @@ namespace AZ
return *this;
}
AZ_MATH_INLINE Matrix4x4 Matrix4x4::operator-(const Matrix4x4& rhs) const
{
return Matrix4x4
(
Simd::Vec4::Sub(m_rows[0].GetSimdValue(), rhs.m_rows[0].GetSimdValue()),
Simd::Vec4::Sub(m_rows[1].GetSimdValue(), rhs.m_rows[1].GetSimdValue()),
Simd::Vec4::Sub(m_rows[2].GetSimdValue(), rhs.m_rows[2].GetSimdValue()),
Simd::Vec4::Sub(m_rows[3].GetSimdValue(), rhs.m_rows[3].GetSimdValue())
);
}
AZ_MATH_INLINE Matrix4x4& Matrix4x4::operator-=(const Matrix4x4& rhs)
{
*this = *this - rhs;
@ -523,6 +527,59 @@ namespace AZ
}
AZ_MATH_INLINE Matrix4x4 Matrix4x4::operator*(float multiplier) const
{
const Simd::Vec4::FloatType mulVec = Simd::Vec4::Splat(multiplier);
return Matrix4x4
(
Simd::Vec4::Mul(m_rows[0].GetSimdValue(), mulVec),
Simd::Vec4::Mul(m_rows[1].GetSimdValue(), mulVec),
Simd::Vec4::Mul(m_rows[2].GetSimdValue(), mulVec),
Simd::Vec4::Mul(m_rows[3].GetSimdValue(), mulVec)
);
}
AZ_MATH_INLINE Matrix4x4& Matrix4x4::operator*=(float multiplier)
{
*this = *this * multiplier;
return *this;
}
AZ_MATH_INLINE Matrix4x4 Matrix4x4::operator/(float divisor) const
{
const Simd::Vec4::FloatType divVec = Simd::Vec4::Splat(divisor);
return Matrix4x4
(
Simd::Vec4::Div(m_rows[0].GetSimdValue(), divVec),
Simd::Vec4::Div(m_rows[1].GetSimdValue(), divVec),
Simd::Vec4::Div(m_rows[2].GetSimdValue(), divVec),
Simd::Vec4::Div(m_rows[3].GetSimdValue(), divVec)
);
}
AZ_MATH_INLINE Matrix4x4& Matrix4x4::operator/=(float divisor)
{
*this = *this / divisor;
return *this;
}
AZ_MATH_INLINE Matrix4x4 Matrix4x4::operator-() const
{
const Simd::Vec4::FloatType zeroVec = Simd::Vec4::ZeroFloat();
return Matrix4x4
(
Simd::Vec4::Sub(zeroVec, m_rows[0].GetSimdValue()),
Simd::Vec4::Sub(zeroVec, m_rows[1].GetSimdValue()),
Simd::Vec4::Sub(zeroVec, m_rows[2].GetSimdValue()),
Simd::Vec4::Sub(zeroVec, m_rows[3].GetSimdValue())
);
}
AZ_MATH_INLINE Vector3 Matrix4x4::operator*(const Vector3& rhs) const
{
return Vector3(Simd::Vec4::Mat4x4TransformPoint3(GetSimdValues(), rhs.GetSimdValue()));
@ -595,6 +652,12 @@ namespace AZ
}
AZ_MATH_INLINE Vector3 Matrix4x4::RetrieveScaleSq() const
{
return Vector3(GetBasisX().GetLengthSq(), GetBasisY().GetLengthSq(), GetBasisZ().GetLengthSq());
}
AZ_MATH_INLINE Vector3 Matrix4x4::ExtractScale()
{
Vector4 x = GetBasisX();
@ -619,6 +682,14 @@ namespace AZ
}
AZ_MATH_INLINE Matrix4x4 Matrix4x4::GetReciprocalScaled() const
{
Matrix4x4 result = *this;
result.MultiplyByScale(RetrieveScaleSq().GetReciprocal());
return result;
}
AZ_MATH_INLINE bool Matrix4x4::IsClose(const Matrix4x4& rhs, float tolerance) const
{
const Simd::Vec4::FloatType vecTolerance = Simd::Vec4::Splat(tolerance);
@ -702,4 +773,10 @@ namespace AZ
lhs = lhs * rhs;
return lhs;
}
}
AZ_MATH_INLINE Matrix4x4 operator*(float lhs, const Matrix4x4& rhs)
{
return rhs * lhs;
}
} // namespace AZ

@ -816,7 +816,7 @@ namespace AZ
template<size_t Index>
static void ReflectUnpackMethodFold(BehaviorContext::ClassBuilder<ContainerType>& builder)
{
AZStd::string methodName = AZStd::string::format("Get%ld", Index);
const AZStd::string methodName = AZStd::string::format("Get%zu", Index);
builder->Method(methodName.data(), [](ContainerType& value) { return AZStd::get<Index>(value); })
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
->Attribute(AZ::ScriptCanvasAttributes::TupleGetFunctionIndex, Index)

@ -330,4 +330,163 @@ namespace UnitTest
}
}
}
// The AssetManagerStreamerImmediateCompletionTests class adjusts the asset loading to force it to complete immediately,
// while still within the callstack for GetAsset(). This can be used to test various conditions in which the load thread
// completes more rapidly than expected, and can expose subtle race conditions.
// There are a few key things that this class does to make this work:
// - The file I/O streamer is mocked
// - The asset stream data is mocked to a 0-byte length for the asset so that the stream load will bypass the I/O streamer and
// just immediately return completion.
// - The number of JobManager threads is set to 0, forcing jobs to execute synchronously inline when they are started.
// With these changes, GetAssetInternal() will queue the stream, which will immediately call the callback that creates LoadAssetJob,
// which immediately executes in-place to process the asset due to the synchronous JobManager.
// Note that if we just created the asset in a Ready state, most of the asset loading code is completely bypassed, and so we
// wouldn't be able to test for race conditions in the AssetContainer.
//
// This class also unregisters the catalog and asset handler before shutting down the asset manager. This is done to catch
// any outstanding asset references that exist due to loads not completing and cleaning up successfully.
struct AssetManagerStreamerImmediateCompletionTests : public BaseAssetManagerTest,
public AZ::Data::AssetCatalogRequestBus::Handler,
public AZ::Data::AssetHandler,
public AZ::Data::AssetCatalog
{
static inline const AZ::Uuid TestAssetId{"{E970B177-5F45-44EB-A2C4-9F29D9A0B2A2}"};
static inline constexpr AZStd::string_view TestAssetPath = "test";
void SetUp() override
{
BaseAssetManagerTest::SetUp();
AssetManager::Descriptor desc;
AssetManager::Create(desc);
// Register the handler and catalog after creation, because we intend to destroy them before AssetManager destruction.
// The specific asset we load is irrelevant, so register EmptyAsset.
AZ::Data::AssetManager::Instance().RegisterHandler(this, AZ::AzTypeInfo<EmptyAsset>::Uuid());
AZ::Data::AssetManager::Instance().RegisterCatalog(this, AZ::AzTypeInfo<EmptyAsset>::Uuid());
// Intercept messages for finding assets by name so that we can mock out the asset we're loading.
AZ::Data::AssetCatalogRequestBus::Handler::BusConnect();
}
void TearDown() override
{
// Unregister before destroying AssetManager.
// This will catch any assets that got stuck in a loading state without getting cleaned up.
AZ::Data::AssetManager::Instance().UnregisterCatalog(this);
AZ::Data::AssetManager::Instance().UnregisterHandler(this);
AZ::Data::AssetCatalogRequestBus::Handler::BusDisconnect();
AssetManager::Destroy();
BaseAssetManagerTest::TearDown();
}
size_t GetNumJobManagerThreads() const override
{
// Return 0 threads so that the Job Manager executes jobs synchronously inline. This lets us finish a load while still
// in the callstack that initiates the load.
return 0;
}
// Create a mock streamer instead of a real one, since we don't really want to load an asset.
IO::IStreamer* CreateStreamer() override
{
m_mockStreamer = AZStd::make_unique<StreamerWrapper>();
return &(m_mockStreamer->m_mockStreamer);
}
void DestroyStreamer([[maybe_unused]] IO::IStreamer* streamer) override
{
m_mockStreamer = nullptr;
}
// AssetHandler implementation
// Minimalist mock to create a new EmptyAsset with the desired asset ID.
AZ::Data::AssetPtr CreateAsset(const AZ::Data::AssetId& id, [[maybe_unused]] const AZ::Data::AssetType& type) override
{
return new EmptyAsset(id);
}
void DestroyAsset(AZ::Data::AssetPtr ptr) override
{
delete ptr;
}
// The mocked-out Asset Catalog handles EmptyAsset types.
void GetHandledAssetTypes(AZStd::vector<AZ::Data::AssetType>& assetTypes) override
{
assetTypes.push_back(AZ::AzTypeInfo<EmptyAsset>::Uuid());
}
// This is a mocked-out load, so just immediately return completion without doing anything.
AZ::Data::AssetHandler::LoadResult LoadAssetData(
[[maybe_unused]] const AZ::Data::Asset<AZ::Data::AssetData>& asset,
[[maybe_unused]] AZStd::shared_ptr<AZ::Data::AssetDataStream> stream,
[[maybe_unused]] const AZ::Data::AssetFilterCB& assetLoadFilterCB)
{
return AZ::Data::AssetHandler::LoadResult::LoadComplete;
}
// AssetCatalogRequestBus implementation
// Minimalist mocks to provide our desired asset path or asset id
AZStd::string GetAssetPathById([[maybe_unused]] const AZ::Data::AssetId& id) override
{
return TestAssetPath;
}
AZ::Data::AssetId GetAssetIdByPath(
[[maybe_unused]] const char* path, [[maybe_unused]] const AZ::Data::AssetType& typeToRegister,
[[maybe_unused]] bool autoRegisterIfNotFound) override
{
return TestAssetId;
}
// Return the mocked-out information for our test asset
AZ::Data::AssetInfo GetAssetInfoById([[maybe_unused]] const AZ::Data::AssetId& id) override
{
AZ::Data::AssetInfo assetInfo;
assetInfo.m_assetId = TestAssetId;
assetInfo.m_assetType = AZ::AzTypeInfo<EmptyAsset>::Uuid();
assetInfo.m_relativePath = TestAssetPath;
return assetInfo;
}
// AssetCatalog implementation
// Set the mocked-out asset load to have a 0-byte length so that the load skips I/O and immediately returns success
AZ::Data::AssetStreamInfo GetStreamInfoForLoad(
[[maybe_unused]] const AZ::Data::AssetId& id, const AZ::Data::AssetType& type) override
{
EXPECT_TRUE(type == AZ::AzTypeInfo<EmptyAsset>::Uuid());
AZ::Data::AssetStreamInfo info;
info.m_dataOffset = 0;
info.m_streamName = TestAssetPath;
info.m_dataLen = 0;
info.m_streamFlags = AZ::IO::OpenMode::ModeRead;
return info;
}
AZStd::unique_ptr<StreamerWrapper> m_mockStreamer;
};
// This test will verify that even if the asset loading stream/job returns immediately, all of the loading
// code works successfully. The test here is fairly simple - it just loads the asset and verifies that it
// loaded successfully. The bulk of the test is really in the setup class above, where the load is forced
// to complete immediately. Also, the true failure condition is caught in the setup class too, which is
// the presence of any assets at the point that the asset handler is unregistered. If they're present, then
// the immediate load wasn't truly successful, as it left around extra references to the asset that haven't
// been cleaned up.
TEST_F(AssetManagerStreamerImmediateCompletionTests, LoadAssetWithImmediateJobCompletion_WorksSuccessfully)
{
AZ::Data::AssetLoadParameters loadParams;
auto testAsset =
AssetManager::Instance().GetAsset<EmptyAsset>(TestAssetId, AZ::Data::AssetLoadBehavior::Default, loadParams);
AZ::Data::AssetManager::Instance().DispatchEvents();
EXPECT_TRUE(testAsset.IsReady());
}
} // namespace UnitTest

@ -24,6 +24,13 @@ namespace UnitTest
public:
AZ_CLASS_ALLOCATOR(EmptyAsset, AZ::SystemAllocator, 0);
AZ_RTTI(EmptyAsset, "{098E3F7F-13AC-414B-9B4E-49B5AD1BD7FE}", AZ::Data::AssetData);
EmptyAsset(
const AZ::Data::AssetId& assetId = AZ::Data::AssetId(),
AZ::Data::AssetData::AssetStatus status = AZ::Data::AssetData::AssetStatus::NotLoaded)
: AZ::Data::AssetData(assetId, status)
{
}
};
// EmptyAssetWithNoHandler: no data contained within, and no AssetHandler registered for this type

@ -14,6 +14,7 @@
#include <AzCore/Math/Transform.h>
#include <AzCore/Math/Quaternion.h>
#include <AzCore/UnitTest/TestTypes.h>
#include <AZTestShared/Math/MathTestHelpers.h>
using namespace AZ;
@ -251,19 +252,19 @@ namespace UnitTest
m2.SetRow(2, 13.0f, 14.0f, 15.0f);
Matrix3x3 m3 = m1 * m2;
AZ_TEST_ASSERT(m3.GetRow(0).IsClose(Vector3(66.0f, 72.0f, 78.0f)));
AZ_TEST_ASSERT(m3.GetRow(1).IsClose(Vector3(156.0f, 171.0f, 186.0f)));
AZ_TEST_ASSERT(m3.GetRow(2).IsClose(Vector3(246.0f, 270.0f, 294.0f)));
EXPECT_THAT(m3.GetRow(0), IsClose(Vector3(66.0f, 72.0f, 78.0f)));
EXPECT_THAT(m3.GetRow(1), IsClose(Vector3(156.0f, 171.0f, 186.0f)));
EXPECT_THAT(m3.GetRow(2), IsClose(Vector3(246.0f, 270.0f, 294.0f)));
Matrix3x3 m4 = m1;
m4 *= m2;
AZ_TEST_ASSERT(m4.GetRow(0).IsClose(Vector3(66.0f, 72.0f, 78.0f)));
AZ_TEST_ASSERT(m4.GetRow(1).IsClose(Vector3(156.0f, 171.0f, 186.0f)));
AZ_TEST_ASSERT(m4.GetRow(2).IsClose(Vector3(246.0f, 270.0f, 294.0f)));
EXPECT_THAT(m4.GetRow(0), IsClose(Vector3(66.0f, 72.0f, 78.0f)));
EXPECT_THAT(m4.GetRow(1), IsClose(Vector3(156.0f, 171.0f, 186.0f)));
EXPECT_THAT(m4.GetRow(2), IsClose(Vector3(246.0f, 270.0f, 294.0f)));
m3 = m1.TransposedMultiply(m2);
AZ_TEST_ASSERT(m3.GetRow(0).IsClose(Vector3(138.0f, 150.0f, 162.0f)));
AZ_TEST_ASSERT(m3.GetRow(1).IsClose(Vector3(168.0f, 183.0f, 198.0f)));
AZ_TEST_ASSERT(m3.GetRow(2).IsClose(Vector3(198.0f, 216.0f, 234.0f)));
EXPECT_THAT(m3.GetRow(0), IsClose(Vector3(138.0f, 150.0f, 162.0f)));
EXPECT_THAT(m3.GetRow(1), IsClose(Vector3(168.0f, 183.0f, 198.0f)));
EXPECT_THAT(m3.GetRow(2), IsClose(Vector3(198.0f, 216.0f, 234.0f)));
}
TEST(MATH_Matrix3x3, TestVectorMultiplication)
@ -277,11 +278,11 @@ namespace UnitTest
m2.SetRow(1, 10.0f, 11.0f, 12.0f);
m2.SetRow(2, 13.0f, 14.0f, 15.0f);
AZ_TEST_ASSERT((m1 * Vector3(1.0f, 2.0f, 3.0f)).IsClose(Vector3(14.0f, 32.0f, 50.0f)));
EXPECT_THAT((m1 * Vector3(1.0f, 2.0f, 3.0f)), IsClose(Vector3(14.0f, 32.0f, 50.0f)));
Vector3 v1(1.0f, 2.0f, 3.0f);
AZ_TEST_ASSERT((v1 * m1).IsClose(Vector3(30.0f, 36.0f, 42.0f)));
EXPECT_THAT((v1 * m1), IsClose(Vector3(30.0f, 36.0f, 42.0f)));
v1 *= m1;
AZ_TEST_ASSERT(v1.IsClose(Vector3(30.0f, 36.0f, 42.0f)));
EXPECT_THAT(v1, IsClose(Vector3(30.0f, 36.0f, 42.0f)));
}
TEST(MATH_Matrix3x3, TestSum)
@ -296,15 +297,15 @@ namespace UnitTest
m2.SetRow(2, 13.0f, 14.0f, 15.0f);
Matrix3x3 m3 = m1 + m2;
AZ_TEST_ASSERT(m3.GetRow(0).IsClose(Vector3(8.0f, 10.0f, 12.0f)));
AZ_TEST_ASSERT(m3.GetRow(1).IsClose(Vector3(14.0f, 16.0f, 18.0f)));
AZ_TEST_ASSERT(m3.GetRow(2).IsClose(Vector3(20.0f, 22.0f, 24.0f)));
EXPECT_THAT(m3.GetRow(0), IsClose(Vector3(8.0f, 10.0f, 12.0f)));
EXPECT_THAT(m3.GetRow(1), IsClose(Vector3(14.0f, 16.0f, 18.0f)));
EXPECT_THAT(m3.GetRow(2), IsClose(Vector3(20.0f, 22.0f, 24.0f)));
m3 = m1;
m3 += m2;
AZ_TEST_ASSERT(m3.GetRow(0).IsClose(Vector3(8.0f, 10.0f, 12.0f)));
AZ_TEST_ASSERT(m3.GetRow(1).IsClose(Vector3(14.0f, 16.0f, 18.0f)));
AZ_TEST_ASSERT(m3.GetRow(2).IsClose(Vector3(20.0f, 22.0f, 24.0f)));
EXPECT_THAT(m3.GetRow(0), IsClose(Vector3(8.0f, 10.0f, 12.0f)));
EXPECT_THAT(m3.GetRow(1), IsClose(Vector3(14.0f, 16.0f, 18.0f)));
EXPECT_THAT(m3.GetRow(2), IsClose(Vector3(20.0f, 22.0f, 24.0f)));
}
TEST(MATH_Matrix3x3, TestDifference)
@ -319,14 +320,14 @@ namespace UnitTest
m2.SetRow(2, 13.0f, 14.0f, 15.0f);
Matrix3x3 m3 = m1 - m2;
AZ_TEST_ASSERT(m3.GetRow(0).IsClose(Vector3(-6.0f, -6.0f, -6.0f)));
AZ_TEST_ASSERT(m3.GetRow(1).IsClose(Vector3(-6.0f, -6.0f, -6.0f)));
AZ_TEST_ASSERT(m3.GetRow(2).IsClose(Vector3(-6.0f, -6.0f, -6.0f)));
EXPECT_THAT(m3.GetRow(0), IsClose(Vector3(-6.0f, -6.0f, -6.0f)));
EXPECT_THAT(m3.GetRow(1), IsClose(Vector3(-6.0f, -6.0f, -6.0f)));
EXPECT_THAT(m3.GetRow(2), IsClose(Vector3(-6.0f, -6.0f, -6.0f)));
m3 = m1;
m3 -= m2;
AZ_TEST_ASSERT(m3.GetRow(0).IsClose(Vector3(-6.0f, -6.0f, -6.0f)));
AZ_TEST_ASSERT(m3.GetRow(1).IsClose(Vector3(-6.0f, -6.0f, -6.0f)));
AZ_TEST_ASSERT(m3.GetRow(2).IsClose(Vector3(-6.0f, -6.0f, -6.0f)));
EXPECT_THAT(m3.GetRow(0), IsClose(Vector3(-6.0f, -6.0f, -6.0f)));
EXPECT_THAT(m3.GetRow(1), IsClose(Vector3(-6.0f, -6.0f, -6.0f)));
EXPECT_THAT(m3.GetRow(2), IsClose(Vector3(-6.0f, -6.0f, -6.0f)));
}
TEST(MATH_Matrix3x3, TestScalarMultiplication)
@ -341,18 +342,18 @@ namespace UnitTest
m2.SetRow(2, 13.0f, 14.0f, 15.0f);
Matrix3x3 m3 = m1 * 2.0f;
AZ_TEST_ASSERT(m3.GetRow(0).IsClose(Vector3(2.0f, 4.0f, 6.0f)));
AZ_TEST_ASSERT(m3.GetRow(1).IsClose(Vector3(8.0f, 10.0f, 12.0f)));
AZ_TEST_ASSERT(m3.GetRow(2).IsClose(Vector3(14.0f, 16.0f, 18.0f)));
EXPECT_THAT(m3.GetRow(0), IsClose(Vector3(2.0f, 4.0f, 6.0f)));
EXPECT_THAT(m3.GetRow(1), IsClose(Vector3(8.0f, 10.0f, 12.0f)));
EXPECT_THAT(m3.GetRow(2), IsClose(Vector3(14.0f, 16.0f, 18.0f)));
m3 = m1;
m3 *= 2.0f;
AZ_TEST_ASSERT(m3.GetRow(0).IsClose(Vector3(2.0f, 4.0f, 6.0f)));
AZ_TEST_ASSERT(m3.GetRow(1).IsClose(Vector3(8.0f, 10.0f, 12.0f)));
AZ_TEST_ASSERT(m3.GetRow(2).IsClose(Vector3(14.0f, 16.0f, 18.0f)));
EXPECT_THAT(m3.GetRow(0), IsClose(Vector3(2.0f, 4.0f, 6.0f)));
EXPECT_THAT(m3.GetRow(1), IsClose(Vector3(8.0f, 10.0f, 12.0f)));
EXPECT_THAT(m3.GetRow(2), IsClose(Vector3(14.0f, 16.0f, 18.0f)));
m3 = 2.0f * m1;
AZ_TEST_ASSERT(m3.GetRow(0).IsClose(Vector3(2.0f, 4.0f, 6.0f)));
AZ_TEST_ASSERT(m3.GetRow(1).IsClose(Vector3(8.0f, 10.0f, 12.0f)));
AZ_TEST_ASSERT(m3.GetRow(2).IsClose(Vector3(14.0f, 16.0f, 18.0f)));
EXPECT_THAT(m3.GetRow(0), IsClose(Vector3(2.0f, 4.0f, 6.0f)));
EXPECT_THAT(m3.GetRow(1), IsClose(Vector3(8.0f, 10.0f, 12.0f)));
EXPECT_THAT(m3.GetRow(2), IsClose(Vector3(14.0f, 16.0f, 18.0f)));
}
TEST(MATH_Matrix3x3, TestScalarDivision)
@ -367,18 +368,32 @@ namespace UnitTest
m2.SetRow(2, 13.0f, 14.0f, 15.0f);
Matrix3x3 m3 = m1 / 0.5f;
AZ_TEST_ASSERT(m3.GetRow(0).IsClose(Vector3(2.0f, 4.0f, 6.0f)));
AZ_TEST_ASSERT(m3.GetRow(1).IsClose(Vector3(8.0f, 10.0f, 12.0f)));
AZ_TEST_ASSERT(m3.GetRow(2).IsClose(Vector3(14.0f, 16.0f, 18.0f)));
EXPECT_THAT(m3.GetRow(0), IsClose(Vector3(2.0f, 4.0f, 6.0f)));
EXPECT_THAT(m3.GetRow(1), IsClose(Vector3(8.0f, 10.0f, 12.0f)));
EXPECT_THAT(m3.GetRow(2), IsClose(Vector3(14.0f, 16.0f, 18.0f)));
m3 = m1;
m3 /= 0.5f;
AZ_TEST_ASSERT(m3.GetRow(0).IsClose(Vector3(2.0f, 4.0f, 6.0f)));
AZ_TEST_ASSERT(m3.GetRow(1).IsClose(Vector3(8.0f, 10.0f, 12.0f)));
AZ_TEST_ASSERT(m3.GetRow(2).IsClose(Vector3(14.0f, 16.0f, 18.0f)));
m3 = -m1;
AZ_TEST_ASSERT(m3.GetRow(0).IsClose(Vector3(-1.0f, -2.0f, -3.0f)));
AZ_TEST_ASSERT(m3.GetRow(1).IsClose(Vector3(-4.0f, -5.0f, -6.0f)));
AZ_TEST_ASSERT(m3.GetRow(2).IsClose(Vector3(-7.0f, -8.0f, -9.0f)));
EXPECT_THAT(m3.GetRow(0), IsClose(Vector3(2.0f, 4.0f, 6.0f)));
EXPECT_THAT(m3.GetRow(1), IsClose(Vector3(8.0f, 10.0f, 12.0f)));
EXPECT_THAT(m3.GetRow(2), IsClose(Vector3(14.0f, 16.0f, 18.0f)));
}
TEST(MATH_Matrix3x3, TestNegation)
{
Matrix3x3 m1;
m1.SetRow(0, 1.0f, 2.0f, 3.0f);
m1.SetRow(1, 4.0f, 5.0f, 6.0f);
m1.SetRow(2, 7.0f, 8.0f, 9.0f);
EXPECT_THAT(-(-m1), IsClose(m1));
EXPECT_THAT(-Matrix3x3::CreateZero(), IsClose(Matrix3x3::CreateZero()));
Matrix3x3 m2 = -m1;
EXPECT_THAT(m2.GetRow(0), IsClose(Vector3(-1.0f, -2.0f, -3.0f)));
EXPECT_THAT(m2.GetRow(1), IsClose(Vector3(-4.0f, -5.0f, -6.0f)));
EXPECT_THAT(m2.GetRow(2), IsClose(Vector3(-7.0f, -8.0f, -9.0f)));
Matrix3x3 m3 = m1 + (-m1);
EXPECT_THAT(m3, IsClose(Matrix3x3::CreateZero()));
}
TEST(MATH_Matrix3x3, TestTranspose)
@ -425,11 +440,33 @@ namespace UnitTest
TEST(MATH_Matrix3x3, TestScaleAccess)
{
Matrix3x3 m1 = Matrix3x3::CreateRotationX(DegToRad(40.0f)) * Matrix3x3::CreateScale(Vector3(2.0f, 3.0f, 4.0f));
AZ_TEST_ASSERT(m1.RetrieveScale().IsClose(Vector3(2.0f, 3.0f, 4.0f)));
AZ_TEST_ASSERT(m1.ExtractScale().IsClose(Vector3(2.0f, 3.0f, 4.0f)));
AZ_TEST_ASSERT(m1.RetrieveScale().IsClose(Vector3::CreateOne()));
EXPECT_THAT(m1.RetrieveScale(), IsClose(Vector3(2.0f, 3.0f, 4.0f)));
EXPECT_THAT(m1.ExtractScale(), IsClose(Vector3(2.0f, 3.0f, 4.0f)));
EXPECT_THAT(m1.RetrieveScale(), IsClose(Vector3::CreateOne()));
m1.MultiplyByScale(Vector3(3.0f, 4.0f, 5.0f));
AZ_TEST_ASSERT(m1.RetrieveScale().IsClose(Vector3(3.0f, 4.0f, 5.0f)));
EXPECT_THAT(m1.RetrieveScale(), IsClose(Vector3(3.0f, 4.0f, 5.0f)));
}
TEST(MATH_Matrix3x3, TestScaleSqAccess)
{
Matrix3x3 m1 = Matrix3x3::CreateRotationX(DegToRad(40.0f)) * Matrix3x3::CreateScale(Vector3(2.0f, 3.0f, 4.0f));
EXPECT_THAT(m1.RetrieveScaleSq(), IsClose(Vector3(4.0f, 9.0f, 16.0f)));
m1.ExtractScale();
EXPECT_THAT(m1.RetrieveScaleSq(), IsClose(Vector3::CreateOne()));
m1.MultiplyByScale(Vector3(3.0f, 4.0f, 5.0f));
EXPECT_THAT(m1.RetrieveScaleSq(), IsClose(Vector3(9.0f, 16.0f, 25.0f)));
}
TEST(MATH_Matrix3x3, TestReciprocalScaled)
{
Matrix3x3 orthogonalMatrix = Matrix3x3::CreateRotationX(DegToRad(40.0f));
EXPECT_THAT(orthogonalMatrix.GetReciprocalScaled(), IsClose(orthogonalMatrix));
const AZ::Vector3 scale(2.8f, 0.7f, 1.3f);
AZ::Matrix3x3 scaledMatrix = orthogonalMatrix;
scaledMatrix.MultiplyByScale(scale);
AZ::Matrix3x3 reciprocalScaledMatrix = orthogonalMatrix;
reciprocalScaledMatrix.MultiplyByScale(scale.GetReciprocal());
EXPECT_THAT(scaledMatrix.GetReciprocalScaled(), IsClose(reciprocalScaledMatrix));
}
TEST(MATH_Matrix3x3, TestPolarDecomposition)

@ -467,21 +467,136 @@ namespace UnitTest
EXPECT_THAT(matrix.Multiply3x3(axisDirection), IsClose(forwardDirection));
}
TEST(MATH_Matrix3x4, MultiplyByMatrix3x4)
{
const AZ::Matrix3x4 matrix1 = AZ::Matrix3x4::CreateFromValue(1.2f);
const AZ::Matrix3x4 matrix2 = AZ::Matrix3x4::CreateDiagonal(AZ::Vector3(1.3f, 1.5f, 0.4f));
const AZ::Matrix3x4 matrix3 = AZ::Matrix3x4::CreateFromQuaternionAndTranslation(
AZ::Quaternion(0.42f, 0.46f, -0.66f, 0.42f), AZ::Vector3(2.8f, -3.7f, 1.6f));
const AZ::Matrix3x4 matrix4 = AZ::Matrix3x4::CreateRotationX(-0.7f) * AZ::Matrix3x4::CreateScale(AZ::Vector3(0.6f, 1.3f, 0.7f));
AZ::Matrix3x4 matrix5 = matrix1;
matrix5 *= matrix4;
const AZ::Vector3 vector(1.9f, 2.3f, 0.2f);
EXPECT_TRUE((matrix1 * (matrix2 * matrix3)).IsClose((matrix1 * matrix2) * matrix3));
EXPECT_THAT((matrix3 * matrix4) * vector, IsClose(matrix3 * (matrix4 * vector)));
EXPECT_TRUE((matrix2 * AZ::Matrix3x4::Identity()).IsClose(matrix2));
EXPECT_TRUE((matrix3 * AZ::Matrix3x4::Identity()).IsClose(AZ::Matrix3x4::Identity() * matrix3));
EXPECT_TRUE(matrix5.IsClose(matrix1 * matrix4));
TEST(MATH_Matrix3x4, TestMatrixMultiplication)
{
AZ::Matrix3x4 m1;
m1.SetRow(0, 1.0f, 2.0f, 3.0f, 4.0f);
m1.SetRow(1, 5.0f, 6.0f, 7.0f, 8.0f);
m1.SetRow(2, 9.0f, 10.0f, 11.0f, 12.0f);
AZ::Matrix3x4 m2;
m2.SetRow(0, 7.0f, 8.0f, 9.0f, 10.0f);
m2.SetRow(1, 11.0f, 12.0f, 13.0f, 14.0f);
m2.SetRow(2, 15.0f, 16.0f, 17.0f, 18.0f);
AZ::Matrix3x4 m3 = m1 * m2;
EXPECT_THAT(m3.GetRow(0), IsClose(AZ::Vector4(74.0f, 80.0f, 86.0f, 96.0f)));
EXPECT_THAT(m3.GetRow(1), IsClose(AZ::Vector4(206.0f, 224.0f, 242.0f, 268.0f)));
EXPECT_THAT(m3.GetRow(2), IsClose(AZ::Vector4(338.0f, 368.0f, 398.0f, 440.0f)));
AZ::Matrix3x4 m4 = m1;
m4 *= m2;
EXPECT_THAT(m4.GetRow(0), IsClose(AZ::Vector4(74.0f, 80.0f, 86.0f, 96.0f)));
EXPECT_THAT(m4.GetRow(1), IsClose(AZ::Vector4(206.0f, 224.0f, 242.0f, 268.0f)));
EXPECT_THAT(m4.GetRow(2), IsClose(AZ::Vector4(338.0f, 368.0f, 398.0f, 440.0f)));
}
TEST(MATH_Matrix3x4, TestSum)
{
AZ::Matrix3x4 m1;
m1.SetRow(0, 1.0f, 2.0f, 3.0f, 4.0f);
m1.SetRow(1, 5.0f, 6.0f, 7.0f, 8.0f);
m1.SetRow(2, 9.0f, 10.0f, 11.0f, 12.0f);
AZ::Matrix3x4 m2;
m2.SetRow(0, 7.0f, 8.0f, 9.0f, 10.0f);
m2.SetRow(1, 11.0f, 12.0f, 13.0f, 14.0f);
m2.SetRow(2, 15.0f, 16.0f, 17.0f, 18.0f);
AZ::Matrix3x4 m3 = m1 + m2;
EXPECT_THAT(m3.GetRow(0), IsClose(AZ::Vector4(8.0f, 10.0f, 12.0f, 14.0f)));
EXPECT_THAT(m3.GetRow(1), IsClose(AZ::Vector4(16.0f, 18.0f, 20.0f, 22.0f)));
EXPECT_THAT(m3.GetRow(2), IsClose(AZ::Vector4(24.0f, 26.0f, 28.0f, 30.0f)));
m3 = m1;
m3 += m2;
EXPECT_THAT(m3.GetRow(0), IsClose(AZ::Vector4(8.0f, 10.0f, 12.0f, 14.0f)));
EXPECT_THAT(m3.GetRow(1), IsClose(AZ::Vector4(16.0f, 18.0f, 20.0f, 22.0f)));
EXPECT_THAT(m3.GetRow(2), IsClose(AZ::Vector4(24.0f, 26.0f, 28.0f, 30.0f)));
}
TEST(MATH_Matrix3x4, TestDifference)
{
AZ::Matrix3x4 m1;
m1.SetRow(0, 1.0f, 2.0f, 3.0f, 4.0f);
m1.SetRow(1, 5.0f, 6.0f, 7.0f, 8.0f);
m1.SetRow(2, 9.0f, 10.0f, 11.0f, 12.0f);
AZ::Matrix3x4 m2;
m2.SetRow(0, 7.0f, 8.0f, 9.0f, 10.0f);
m2.SetRow(1, 11.0f, 12.0f, 13.0f, 14.0f);
m2.SetRow(2, 15.0f, 16.0f, 17.0f, 18.0f);
AZ::Matrix3x4 m3 = m1 - m2;
EXPECT_THAT(m3.GetRow(0), IsClose(AZ::Vector4(-6.0f, -6.0f, -6.0f, -6.0f)));
EXPECT_THAT(m3.GetRow(1), IsClose(AZ::Vector4(-6.0f, -6.0f, -6.0f, -6.0f)));
EXPECT_THAT(m3.GetRow(2), IsClose(AZ::Vector4(-6.0f, -6.0f, -6.0f, -6.0f)));
m3 = m1;
m3 -= m2;
EXPECT_THAT(m3.GetRow(0), IsClose(AZ::Vector4(-6.0f, -6.0f, -6.0f, -6.0f)));
EXPECT_THAT(m3.GetRow(1), IsClose(AZ::Vector4(-6.0f, -6.0f, -6.0f, -6.0f)));
EXPECT_THAT(m3.GetRow(2), IsClose(AZ::Vector4(-6.0f, -6.0f, -6.0f, -6.0f)));
}
TEST(MATH_Matrix3x4, TestScalarMultiplication)
{
AZ::Matrix3x4 m1;
m1.SetRow(0, 1.0f, 2.0f, 3.0f, 4.0f);
m1.SetRow(1, 5.0f, 6.0f, 7.0f, 8.0f);
m1.SetRow(2, 9.0f, 10.0f, 11.0f, 12.0f);
AZ::Matrix3x4 m2;
m2.SetRow(0, 7.0f, 8.0f, 9.0f, 10.0f);
m2.SetRow(1, 11.0f, 12.0f, 13.0f, 14.0f);
m2.SetRow(2, 15.0f, 16.0f, 17.0f, 18.0f);
AZ::Matrix3x4 m3 = m1 * 2.0f;
EXPECT_THAT(m3.GetRow(0), IsClose(AZ::Vector4(2.0f, 4.0f, 6.0f, 8.0f)));
EXPECT_THAT(m3.GetRow(1), IsClose(AZ::Vector4(10.0f, 12.0f, 14.0f, 16.0f)));
EXPECT_THAT(m3.GetRow(2), IsClose(AZ::Vector4(18.0f, 20.0f, 22.0f, 24.0f)));
m3 = m1;
m3 *= 2.0f;
EXPECT_THAT(m3.GetRow(0), IsClose(AZ::Vector4(2.0f, 4.0f, 6.0f, 8.0f)));
EXPECT_THAT(m3.GetRow(1), IsClose(AZ::Vector4(10.0f, 12.0f, 14.0f, 16.0f)));
EXPECT_THAT(m3.GetRow(2), IsClose(AZ::Vector4(18.0f, 20.0f, 22.0f, 24.0f)));
m3 = 2.0f * m1;
EXPECT_THAT(m3.GetRow(0), IsClose(AZ::Vector4(2.0f, 4.0f, 6.0f, 8.0f)));
EXPECT_THAT(m3.GetRow(1), IsClose(AZ::Vector4(10.0f, 12.0f, 14.0f, 16.0f)));
EXPECT_THAT(m3.GetRow(2), IsClose(AZ::Vector4(18.0f, 20.0f, 22.0f, 24.0f)));
}
TEST(MATH_Matrix3x4, TestScalarDivision)
{
AZ::Matrix3x4 m1;
m1.SetRow(0, 1.0f, 2.0f, 3.0f, 4.0f);
m1.SetRow(1, 5.0f, 6.0f, 7.0f, 8.0f);
m1.SetRow(2, 9.0f, 10.0f, 11.0f, 12.0f);
AZ::Matrix3x4 m2;
m2.SetRow(0, 7.0f, 8.0f, 9.0f, 10.0f);
m2.SetRow(1, 11.0f, 12.0f, 13.0f, 14.0f);
m2.SetRow(2, 15.0f, 16.0f, 17.0f, 18.0f);
AZ::Matrix3x4 m3 = m1 / 0.5f;
EXPECT_THAT(m3.GetRow(0), IsClose(AZ::Vector4(2.0f, 4.0f, 6.0f, 8.0f)));
EXPECT_THAT(m3.GetRow(1), IsClose(AZ::Vector4(10.0f, 12.0f, 14.0f, 16.0f)));
EXPECT_THAT(m3.GetRow(2), IsClose(AZ::Vector4(18.0f, 20.0f, 22.0f, 24.0f)));
m3 = m1;
m3 /= 0.5f;
EXPECT_THAT(m3.GetRow(0), IsClose(AZ::Vector4(2.0f, 4.0f, 6.0f, 8.0f)));
EXPECT_THAT(m3.GetRow(1), IsClose(AZ::Vector4(10.0f, 12.0f, 14.0f, 16.0f)));
EXPECT_THAT(m3.GetRow(2), IsClose(AZ::Vector4(18.0f, 20.0f, 22.0f, 24.0f)));
}
TEST(MATH_Matrix3x4, TestNegation)
{
AZ::Matrix3x4 m1;
m1.SetRow(0, 1.0f, 2.0f, 3.0f, 4.0f);
m1.SetRow(1, 5.0f, 6.0f, 7.0f, 8.0f);
m1.SetRow(2, 9.0f, 10.0f, 11.0f, 12.0f);
EXPECT_THAT(-(-m1), IsClose(m1));
EXPECT_THAT(-AZ::Matrix3x4::CreateZero(), IsClose(AZ::Matrix3x4::CreateZero()));
AZ::Matrix3x4 m2 = -m1;
EXPECT_THAT(m2.GetRow(0), IsClose(AZ::Vector4(-1.0f, -2.0f, -3.0f, -4.0f)));
EXPECT_THAT(m2.GetRow(1), IsClose(AZ::Vector4(-5.0f, -6.0f, -7.0f, -8.0f)));
EXPECT_THAT(m2.GetRow(2), IsClose(AZ::Vector4(-9.0f, -10.0f, -11.0f, -12.0f)));
AZ::Matrix3x4 m3 = m1 + (-m1);
EXPECT_THAT(m3, IsClose(AZ::Matrix3x4::CreateZero()));
}
TEST(MATH_Matrix3x4, MultiplyByVector3)
@ -652,6 +767,34 @@ namespace UnitTest
EXPECT_THAT(scaledMatrix.RetrieveScale(), IsClose(AZ::Vector3::CreateOne()));
}
TEST_P(Matrix3x4ScaleFixture, ScaleSq)
{
const AZ::Matrix3x4 orthogonalMatrix = GetParam();
EXPECT_THAT(orthogonalMatrix.RetrieveScaleSq(), IsClose(AZ::Vector3::CreateOne()));
AZ::Matrix3x4 unscaledMatrix = orthogonalMatrix;
unscaledMatrix.ExtractScale();
EXPECT_THAT(unscaledMatrix.RetrieveScaleSq(), IsClose(AZ::Vector3::CreateOne()));
const AZ::Vector3 scale(2.8f, 0.7f, 1.3f);
AZ::Matrix3x4 scaledMatrix = orthogonalMatrix;
scaledMatrix.MultiplyByScale(scale);
EXPECT_THAT(scaledMatrix.RetrieveScaleSq(), IsClose(scale * scale));
EXPECT_THAT(scaledMatrix.RetrieveScaleSq(), IsClose(scaledMatrix.RetrieveScale() * scaledMatrix.RetrieveScale()));
scaledMatrix.ExtractScale();
EXPECT_THAT(scaledMatrix.RetrieveScaleSq(), IsClose(AZ::Vector3::CreateOne()));
}
TEST_P(Matrix3x4ScaleFixture, GetReciprocalScaled)
{
const AZ::Matrix3x4 orthogonalMatrix = GetParam();
EXPECT_THAT(orthogonalMatrix.GetReciprocalScaled(), IsClose(orthogonalMatrix));
const AZ::Vector3 scale(2.8f, 0.7f, 1.3f);
AZ::Matrix3x4 scaledMatrix = orthogonalMatrix;
scaledMatrix.MultiplyByScale(scale);
AZ::Matrix3x4 reciprocalScaledMatrix = orthogonalMatrix;
reciprocalScaledMatrix.MultiplyByScale(scale.GetReciprocal());
EXPECT_THAT(scaledMatrix.GetReciprocalScaled(), IsClose(reciprocalScaledMatrix));
}
INSTANTIATE_TEST_CASE_P(MATH_Matrix3x4, Matrix3x4ScaleFixture, ::testing::ValuesIn(MathTestData::OrthogonalMatrix3x4s));
TEST(MATH_Matrix3x4, IsOrthogonal)

@ -246,16 +246,16 @@ namespace UnitTest
m2.SetRow(2, 15.0f, 16.0f, 17.0f, 18.0f);
m2.SetRow(3, 19.0f, 20.0f, 21.0f, 22.0f);
Matrix4x4 m3 = m1 * m2;
AZ_TEST_ASSERT(m3.GetRow(0).IsClose(Vector4(150.0f, 160.0f, 170.0f, 180.0f)));
AZ_TEST_ASSERT(m3.GetRow(1).IsClose(Vector4(358.0f, 384.0f, 410.0f, 436.0f)));
AZ_TEST_ASSERT(m3.GetRow(2).IsClose(Vector4(566.0f, 608.0f, 650.0f, 692.0f)));
AZ_TEST_ASSERT(m3.GetRow(3).IsClose(Vector4(774.0f, 832.0f, 890.0f, 948.0f)));
EXPECT_THAT(m3.GetRow(0), IsClose(Vector4(150.0f, 160.0f, 170.0f, 180.0f)));
EXPECT_THAT(m3.GetRow(1), IsClose(Vector4(358.0f, 384.0f, 410.0f, 436.0f)));
EXPECT_THAT(m3.GetRow(2), IsClose(Vector4(566.0f, 608.0f, 650.0f, 692.0f)));
EXPECT_THAT(m3.GetRow(3), IsClose(Vector4(774.0f, 832.0f, 890.0f, 948.0f)));
Matrix4x4 m4 = m1;
m4 *= m2;
AZ_TEST_ASSERT(m4.GetRow(0).IsClose(Vector4(150.0f, 160.0f, 170.0f, 180.0f)));
AZ_TEST_ASSERT(m4.GetRow(1).IsClose(Vector4(358.0f, 384.0f, 410.0f, 436.0f)));
AZ_TEST_ASSERT(m4.GetRow(2).IsClose(Vector4(566.0f, 608.0f, 650.0f, 692.0f)));
AZ_TEST_ASSERT(m4.GetRow(3).IsClose(Vector4(774.0f, 832.0f, 890.0f, 948.0f)));
EXPECT_THAT(m4.GetRow(0), IsClose(Vector4(150.0f, 160.0f, 170.0f, 180.0f)));
EXPECT_THAT(m4.GetRow(1), IsClose(Vector4(358.0f, 384.0f, 410.0f, 436.0f)));
EXPECT_THAT(m4.GetRow(2), IsClose(Vector4(566.0f, 608.0f, 650.0f, 692.0f)));
EXPECT_THAT(m4.GetRow(3), IsClose(Vector4(774.0f, 832.0f, 890.0f, 948.0f)));
}
TEST(MATH_Matrix4x4, TestVectorMultiplication)
@ -265,18 +265,148 @@ namespace UnitTest
m1.SetRow(1, 5.0f, 6.0f, 7.0f, 8.0f);
m1.SetRow(2, 9.0f, 10.0f, 11.0f, 12.0f);
m1.SetRow(3, 13.0f, 14.0f, 15.0f, 16.0f);
AZ_TEST_ASSERT((m1 * Vector3(1.0f, 2.0f, 3.0f)).IsClose(Vector3(18.0f, 46.0f, 74.0f)));
AZ_TEST_ASSERT((m1 * Vector4(1.0f, 2.0f, 3.0f, 4.0f)).IsClose(Vector4(30.0f, 70.0f, 110.0f, 150.0f)));
AZ_TEST_ASSERT(m1.TransposedMultiply3x3(Vector3(1.0f, 2.0f, 3.0f)).IsClose(Vector3(38.0f, 44.0f, 50.0f)));
AZ_TEST_ASSERT(m1.Multiply3x3(Vector3(1.0f, 2.0f, 3.0f)).IsClose(Vector3(14.0f, 38.0f, 62.0f)));
EXPECT_THAT((m1 * Vector3(1.0f, 2.0f, 3.0f)), IsClose(Vector3(18.0f, 46.0f, 74.0f)));
EXPECT_THAT((m1 * Vector4(1.0f, 2.0f, 3.0f, 4.0f)), IsClose(Vector4(30.0f, 70.0f, 110.0f, 150.0f)));
EXPECT_THAT(m1.TransposedMultiply3x3(Vector3(1.0f, 2.0f, 3.0f)), IsClose(Vector3(38.0f, 44.0f, 50.0f)));
EXPECT_THAT(m1.Multiply3x3(Vector3(1.0f, 2.0f, 3.0f)), IsClose(Vector3(14.0f, 38.0f, 62.0f)));
Vector3 v1(1.0f, 2.0f, 3.0f);
AZ_TEST_ASSERT((v1 * m1).IsClose(Vector3(51.0f, 58.0f, 65.0f)));
EXPECT_THAT((v1 * m1), IsClose(Vector3(51.0f, 58.0f, 65.0f)));
v1 *= m1;
AZ_TEST_ASSERT(v1.IsClose(Vector3(51.0f, 58.0f, 65.0f)));
EXPECT_THAT(v1, IsClose(Vector3(51.0f, 58.0f, 65.0f)));
Vector4 v2(1.0f, 2.0f, 3.0f, 4.0f);
AZ_TEST_ASSERT((v2 * m1).IsClose(Vector4(90.0f, 100.0f, 110.0f, 120.0f)));
EXPECT_THAT((v2 * m1), IsClose(Vector4(90.0f, 100.0f, 110.0f, 120.0f)));
v2 *= m1;
AZ_TEST_ASSERT(v2.IsClose(Vector4(90.0f, 100.0f, 110.0f, 120.0f)));
EXPECT_THAT(v2, IsClose(Vector4(90.0f, 100.0f, 110.0f, 120.0f)));
}
TEST(MATH_Matrix4x4, TestSum)
{
Matrix4x4 m1;
m1.SetRow(0, 1.0f, 2.0f, 3.0f, 4.0f);
m1.SetRow(1, 5.0f, 6.0f, 7.0f, 8.0f);
m1.SetRow(2, 9.0f, 10.0f, 11.0f, 12.0f);
m1.SetRow(3, 13.0f, 14.0f, 15.0f, 16.0f);
Matrix4x4 m2;
m2.SetRow(0, 7.0f, 8.0f, 9.0f, 10.0f);
m2.SetRow(1, 11.0f, 12.0f, 13.0f, 14.0f);
m2.SetRow(2, 15.0f, 16.0f, 17.0f, 18.0f);
m2.SetRow(3, 19.0f, 20.0f, 21.0f, 22.0f);
Matrix4x4 m3 = m1 + m2;
EXPECT_THAT(m3.GetRow(0), IsClose(Vector4(8.0f, 10.0f, 12.0f, 14.0f)));
EXPECT_THAT(m3.GetRow(1), IsClose(Vector4(16.0f, 18.0f, 20.0f, 22.0f)));
EXPECT_THAT(m3.GetRow(2), IsClose(Vector4(24.0f, 26.0f, 28.0f, 30.0f)));
EXPECT_THAT(m3.GetRow(3), IsClose(Vector4(32.0f, 34.0f, 36.0f, 38.0f)));
m3 = m1;
m3 += m2;
EXPECT_THAT(m3.GetRow(0), IsClose(Vector4(8.0f, 10.0f, 12.0f, 14.0f)));
EXPECT_THAT(m3.GetRow(1), IsClose(Vector4(16.0f, 18.0f, 20.0f, 22.0f)));
EXPECT_THAT(m3.GetRow(2), IsClose(Vector4(24.0f, 26.0f, 28.0f, 30.0f)));
EXPECT_THAT(m3.GetRow(3), IsClose(Vector4(32.0f, 34.0f, 36.0f, 38.0f)));
}
TEST(MATH_Matrix4x4, TestDifference)
{
Matrix4x4 m1;
m1.SetRow(0, 1.0f, 2.0f, 3.0f, 4.0f);
m1.SetRow(1, 5.0f, 6.0f, 7.0f, 8.0f);
m1.SetRow(2, 9.0f, 10.0f, 11.0f, 12.0f);
m1.SetRow(3, 13.0f, 14.0f, 15.0f, 16.0f);
Matrix4x4 m2;
m2.SetRow(0, 7.0f, 8.0f, 9.0f, 10.0f);
m2.SetRow(1, 11.0f, 12.0f, 13.0f, 14.0f);
m2.SetRow(2, 15.0f, 16.0f, 17.0f, 18.0f);
m2.SetRow(3, 19.0f, 20.0f, 21.0f, 22.0f);
Matrix4x4 m3 = m1 - m2;
EXPECT_THAT(m3.GetRow(0), IsClose(Vector4(-6.0f, -6.0f, -6.0f, -6.0f)));
EXPECT_THAT(m3.GetRow(1), IsClose(Vector4(-6.0f, -6.0f, -6.0f, -6.0f)));
EXPECT_THAT(m3.GetRow(2), IsClose(Vector4(-6.0f, -6.0f, -6.0f, -6.0f)));
EXPECT_THAT(m3.GetRow(3), IsClose(Vector4(-6.0f, -6.0f, -6.0f, -6.0f)));
m3 = m1;
m3 -= m2;
EXPECT_THAT(m3.GetRow(0), IsClose(Vector4(-6.0f, -6.0f, -6.0f, -6.0f)));
EXPECT_THAT(m3.GetRow(1), IsClose(Vector4(-6.0f, -6.0f, -6.0f, -6.0f)));
EXPECT_THAT(m3.GetRow(2), IsClose(Vector4(-6.0f, -6.0f, -6.0f, -6.0f)));
EXPECT_THAT(m3.GetRow(3), IsClose(Vector4(-6.0f, -6.0f, -6.0f, -6.0f)));
}
TEST(MATH_Matrix4x4, TestScalarMultiplication)
{
Matrix4x4 m1;
m1.SetRow(0, 1.0f, 2.0f, 3.0f, 4.0f);
m1.SetRow(1, 5.0f, 6.0f, 7.0f, 8.0f);
m1.SetRow(2, 9.0f, 10.0f, 11.0f, 12.0f);
m1.SetRow(3, 13.0f, 14.0f, 15.0f, 16.0f);
Matrix4x4 m2;
m2.SetRow(0, 7.0f, 8.0f, 9.0f, 10.0f);
m2.SetRow(1, 11.0f, 12.0f, 13.0f, 14.0f);
m2.SetRow(2, 15.0f, 16.0f, 17.0f, 18.0f);
m2.SetRow(3, 19.0f, 20.0f, 21.0f, 22.0f);
Matrix4x4 m3 = m1 * 2.0f;
EXPECT_THAT(m3.GetRow(0), IsClose(Vector4(2.0f, 4.0f, 6.0f, 8.0f)));
EXPECT_THAT(m3.GetRow(1), IsClose(Vector4(10.0f, 12.0f, 14.0f, 16.0f)));
EXPECT_THAT(m3.GetRow(2), IsClose(Vector4(18.0f, 20.0f, 22.0f, 24.0f)));
EXPECT_THAT(m3.GetRow(3), IsClose(Vector4(26.0f, 28.0f, 30.0f, 32.0f)));
m3 = m1;
m3 *= 2.0f;
EXPECT_THAT(m3.GetRow(0), IsClose(Vector4(2.0f, 4.0f, 6.0f, 8.0f)));
EXPECT_THAT(m3.GetRow(1), IsClose(Vector4(10.0f, 12.0f, 14.0f, 16.0f)));
EXPECT_THAT(m3.GetRow(2), IsClose(Vector4(18.0f, 20.0f, 22.0f, 24.0f)));
EXPECT_THAT(m3.GetRow(3), IsClose(Vector4(26.0f, 28.0f, 30.0f, 32.0f)));
m3 = 2.0f * m1;
EXPECT_THAT(m3.GetRow(0), IsClose(Vector4(2.0f, 4.0f, 6.0f, 8.0f)));
EXPECT_THAT(m3.GetRow(1), IsClose(Vector4(10.0f, 12.0f, 14.0f, 16.0f)));
EXPECT_THAT(m3.GetRow(2), IsClose(Vector4(18.0f, 20.0f, 22.0f, 24.0f)));
EXPECT_THAT(m3.GetRow(3), IsClose(Vector4(26.0f, 28.0f, 30.0f, 32.0f)));
}
TEST(MATH_Matrix4x4, TestScalarDivision)
{
Matrix4x4 m1;
m1.SetRow(0, 1.0f, 2.0f, 3.0f, 4.0f);
m1.SetRow(1, 5.0f, 6.0f, 7.0f, 8.0f);
m1.SetRow(2, 9.0f, 10.0f, 11.0f, 12.0f);
m1.SetRow(3, 13.0f, 14.0f, 15.0f, 16.0f);
Matrix4x4 m2;
m2.SetRow(0, 7.0f, 8.0f, 9.0f, 10.0f);
m2.SetRow(1, 11.0f, 12.0f, 13.0f, 14.0f);
m2.SetRow(2, 15.0f, 16.0f, 17.0f, 18.0f);
m2.SetRow(3, 19.0f, 20.0f, 21.0f, 22.0f);
Matrix4x4 m3 = m1 / 0.5f;
EXPECT_THAT(m3.GetRow(0), IsClose(Vector4(2.0f, 4.0f, 6.0f, 8.0f)));
EXPECT_THAT(m3.GetRow(1), IsClose(Vector4(10.0f, 12.0f, 14.0f, 16.0f)));
EXPECT_THAT(m3.GetRow(2), IsClose(Vector4(18.0f, 20.0f, 22.0f, 24.0f)));
EXPECT_THAT(m3.GetRow(3), IsClose(Vector4(26.0f, 28.0f, 30.0f, 32.0f)));
m3 = m1;
m3 /= 0.5f;
EXPECT_THAT(m3.GetRow(0), IsClose(Vector4(2.0f, 4.0f, 6.0f, 8.0f)));
EXPECT_THAT(m3.GetRow(1), IsClose(Vector4(10.0f, 12.0f, 14.0f, 16.0f)));
EXPECT_THAT(m3.GetRow(2), IsClose(Vector4(18.0f, 20.0f, 22.0f, 24.0f)));
EXPECT_THAT(m3.GetRow(3), IsClose(Vector4(26.0f, 28.0f, 30.0f, 32.0f)));
}
TEST(MATH_Matrix4x4, TestNegation)
{
Matrix4x4 m1;
m1.SetRow(0, 1.0f, 2.0f, 3.0f, 4.0f);
m1.SetRow(1, 5.0f, 6.0f, 7.0f, 8.0f);
m1.SetRow(2, 9.0f, 10.0f, 11.0f, 12.0f);
m1.SetRow(3, 13.0f, 14.0f, 15.0f, 16.0f);
EXPECT_THAT(-(-m1), IsClose(m1));
EXPECT_THAT(-Matrix4x4::CreateZero(), IsClose(Matrix4x4::CreateZero()));
Matrix4x4 m2 = -m1;
EXPECT_THAT(m2.GetRow(0), IsClose(Vector4(-1.0f, -2.0f, -3.0f, -4.0f)));
EXPECT_THAT(m2.GetRow(1), IsClose(Vector4(-5.0f, -6.0f, -7.0f, -8.0f)));
EXPECT_THAT(m2.GetRow(2), IsClose(Vector4(-9.0f, -10.0f, -11.0f, -12.0f)));
EXPECT_THAT(m2.GetRow(3), IsClose(Vector4(-13.0f, -14.0f, -15.0f, -16.0f)));
Matrix4x4 m3 = m1 + (-m1);
EXPECT_THAT(m3, IsClose(Matrix4x4::CreateZero()));
}
TEST(MATH_Matrix4x4, TestTranspose)
@ -368,4 +498,36 @@ namespace UnitTest
m1.SetRow(3, 13.0f, 14.0f, 15.0f, 16.0f);
AZ_TEST_ASSERT(m1.GetDiagonal() == Vector4(1.0f, 6.0f, 11.0f, 16.0f));
}
TEST(MATH_Matrix4x4, TestScaleAccess)
{
Matrix4x4 m1 = Matrix4x4::CreateRotationX(DegToRad(40.0f)) * Matrix4x4::CreateScale(Vector3(2.0f, 3.0f, 4.0f));
EXPECT_THAT(m1.RetrieveScale(), IsClose(Vector3(2.0f, 3.0f, 4.0f)));
EXPECT_THAT(m1.ExtractScale(), IsClose(Vector3(2.0f, 3.0f, 4.0f)));
EXPECT_THAT(m1.RetrieveScale(), IsClose(Vector3::CreateOne()));
m1.MultiplyByScale(Vector3(3.0f, 4.0f, 5.0f));
EXPECT_THAT(m1.RetrieveScale(), IsClose(Vector3(3.0f, 4.0f, 5.0f)));
}
TEST(MATH_Matrix4x4, TestScaleSqAccess)
{
Matrix4x4 m1 = Matrix4x4::CreateRotationX(DegToRad(40.0f)) * Matrix4x4::CreateScale(Vector3(2.0f, 3.0f, 4.0f));
EXPECT_THAT(m1.RetrieveScaleSq(), IsClose(Vector3(4.0f, 9.0f, 16.0f)));
m1.ExtractScale();
EXPECT_THAT(m1.RetrieveScaleSq(), IsClose(Vector3::CreateOne()));
m1.MultiplyByScale(Vector3(3.0f, 4.0f, 5.0f));
EXPECT_THAT(m1.RetrieveScaleSq(), IsClose(Vector3(9.0f, 16.0f, 25.0f)));
}
TEST(MATH_Matrix4x4, TestReciprocalScaled)
{
Matrix4x4 orthogonalMatrix = Matrix4x4::CreateRotationX(DegToRad(40.0f));
EXPECT_THAT(orthogonalMatrix.GetReciprocalScaled(), IsClose(orthogonalMatrix));
const AZ::Vector3 scale(2.8f, 0.7f, 1.3f);
AZ::Matrix4x4 scaledMatrix = orthogonalMatrix;
scaledMatrix.MultiplyByScale(scale);
AZ::Matrix4x4 reciprocalScaledMatrix = orthogonalMatrix;
reciprocalScaledMatrix.MultiplyByScale(scale.GetReciprocal());
EXPECT_THAT(scaledMatrix.GetReciprocalScaled(), IsClose(reciprocalScaledMatrix));
}
}

@ -1,26 +0,0 @@
/*
* 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/RTTI/RTTI.h>
namespace AzFramework
{
class AtomActiveInterface
{
public:
AZ_RTTI(AtomActiveInterface, "{4BB59C86-0848-485D-AB28-700540470B2B}");
AtomActiveInterface() = default;
virtual ~AtomActiveInterface() = default;
};
} // namespace AzFramework

@ -137,7 +137,7 @@ namespace AzFramework::ProjectManager
}
AZ::IO::FixedMaxPath pythonPath = engineRootPath / "python";
pythonPath /= AZ_TRAIT_AZFRAMEWORK_PYTHON_SHELL;
auto cmdPath = AZ::IO::FixedMaxPathString::format("%s %s%s --executable_path=%s --parent_pid=%" PRId64, pythonPath.Native().c_str(),
auto cmdPath = AZ::IO::FixedMaxPathString::format("%s %s%s --executable_path=%s --parent_pid=%" PRIu32, pythonPath.Native().c_str(),
debugOption.c_str(), (projectManagerPath / projectsScript).c_str(), executablePath.c_str(), AZ::Platform::GetCurrentProcessId());
AzFramework::ProcessLauncher::ProcessLaunchInfo processLaunchInfo;

@ -12,14 +12,150 @@
#include "CameraInput.h"
#include <AzCore/Console/IConsole.h>
#include <AzCore/Math/MathUtils.h>
#include <AzCore/Math/Plane.h>
#include <AzFramework/Input/Devices/Keyboard/InputDeviceKeyboard.h>
#include <AzFramework/Input/Devices/Mouse/InputDeviceMouse.h>
#include <AzFramework/Windowing/WindowBus.h>
namespace AzFramework
{
void CameraSystem::HandleEvents(const InputEvent& event)
AZ_CVAR(
float, ed_cameraSystemDefaultPlaneHeight, 34.0f, nullptr, AZ::ConsoleFunctorFlags::Null,
"The default height of the ground plane to do intersection tests against when orbiting");
AZ_CVAR(float, ed_cameraSystemBoostMultiplier, 3.0f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
AZ_CVAR(float, ed_cameraSystemTranslateSpeed, 10.0f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
AZ_CVAR(float, ed_cameraSystemOrbitDollyScrollSpeed, 0.02f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
AZ_CVAR(float, ed_cameraSystemOrbitDollyCursorSpeed, 0.01f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
AZ_CVAR(float, ed_cameraSystemScrollTranslateSpeed, 0.02f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
AZ_CVAR(float, ed_cameraSystemDefaultOrbitDistance, 60.0f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
AZ_CVAR(float, ed_cameraSystemMaxOrbitDistance, 100.0f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
AZ_CVAR(float, ed_cameraSystemLookSmoothness, 5.0f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
AZ_CVAR(float, ed_cameraSystemTranslateSmoothness, 5.0f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
AZ_CVAR(float, ed_cameraSystemRotateSpeed, 0.005f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
AZ_CVAR(float, ed_cameraSystemPanSpeed, 0.01f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
AZ_CVAR(bool, ed_cameraSystemPanInvertX, true, nullptr, AZ::ConsoleFunctorFlags::Null, "");
AZ_CVAR(bool, ed_cameraSystemPanInvertY, true, nullptr, AZ::ConsoleFunctorFlags::Null, "");
AZ_CVAR(
AZ::CVarFixedString, ed_cameraSystemTranslateForwardKey, "keyboard_key_alphanumeric_W", nullptr, AZ::ConsoleFunctorFlags::Null, "");
AZ_CVAR(
AZ::CVarFixedString, ed_cameraSystemTranslateBackwardKey, "keyboard_key_alphanumeric_S", nullptr, AZ::ConsoleFunctorFlags::Null,
"");
AZ_CVAR(
AZ::CVarFixedString, ed_cameraSystemTranslateLeftKey, "keyboard_key_alphanumeric_A", nullptr, AZ::ConsoleFunctorFlags::Null, "");
AZ_CVAR(
AZ::CVarFixedString, ed_cameraSystemTranslateRightKey, "keyboard_key_alphanumeric_D", nullptr, AZ::ConsoleFunctorFlags::Null, "");
AZ_CVAR(AZ::CVarFixedString, ed_cameraSystemTranslateUpKey, "keyboard_key_alphanumeric_E", nullptr, AZ::ConsoleFunctorFlags::Null, "");
AZ_CVAR(
AZ::CVarFixedString, ed_cameraSystemTranslateDownKey, "keyboard_key_alphanumeric_Q", nullptr, AZ::ConsoleFunctorFlags::Null, "");
AZ_CVAR(
AZ::CVarFixedString, ed_cameraSystemTranslateBoostKey, "keyboard_key_modifier_shift_l", nullptr, AZ::ConsoleFunctorFlags::Null, "");
AZ_CVAR(AZ::CVarFixedString, ed_cameraSystemOrbitKey, "keyboard_key_modifier_alt_l", nullptr, AZ::ConsoleFunctorFlags::Null, "");
AZ_CVAR(AZ::CVarFixedString, ed_cameraSystemFreeLookButton, "mouse_button_right", nullptr, AZ::ConsoleFunctorFlags::Null, "");
AZ_CVAR(AZ::CVarFixedString, ed_cameraSystemFreePanButton, "mouse_button_middle", nullptr, AZ::ConsoleFunctorFlags::Null, "");
AZ_CVAR(AZ::CVarFixedString, ed_cameraSystemOrbitLookButton, "mouse_button_left", nullptr, AZ::ConsoleFunctorFlags::Null, "");
AZ_CVAR(AZ::CVarFixedString, ed_cameraSystemOrbitDollyButton, "mouse_button_right", nullptr, AZ::ConsoleFunctorFlags::Null, "");
AZ_CVAR(AZ::CVarFixedString, ed_cameraSystemOrbitPanButton, "mouse_button_middle", nullptr, AZ::ConsoleFunctorFlags::Null, "");
static InputChannelId CameraTranslateForwardId;
static InputChannelId CameraTranslateBackwardId;
static InputChannelId CameraTranslateLeftId;
static InputChannelId CameraTranslateRightId;
static InputChannelId CameraTranslateDownId;
static InputChannelId CameraTranslateUpId;
static InputChannelId CameraTranslateBoostId;
static InputChannelId CameraOrbitId;
// externed elsewhere
InputChannelId CameraFreeLookButton;
InputChannelId CameraFreePanButton;
InputChannelId CameraOrbitLookButton;
InputChannelId CameraOrbitDollyButton;
InputChannelId CameraOrbitPanButton;
void ReloadCameraKeyBindings()
{
const AZ::CVarFixedString& forward = ed_cameraSystemTranslateForwardKey;
CameraTranslateForwardId = InputChannelId(forward.c_str());
const AZ::CVarFixedString& backward = ed_cameraSystemTranslateBackwardKey;
CameraTranslateBackwardId = InputChannelId(backward.c_str());
const AZ::CVarFixedString& left = ed_cameraSystemTranslateLeftKey;
CameraTranslateLeftId = InputChannelId(left.c_str());
const AZ::CVarFixedString& right = ed_cameraSystemTranslateRightKey;
CameraTranslateRightId = InputChannelId(right.c_str());
const AZ::CVarFixedString& down = ed_cameraSystemTranslateDownKey;
CameraTranslateDownId = InputChannelId(down.c_str());
const AZ::CVarFixedString& up = ed_cameraSystemTranslateUpKey;
CameraTranslateUpId = InputChannelId(up.c_str());
const AZ::CVarFixedString& boost = ed_cameraSystemTranslateBoostKey;
CameraTranslateBoostId = InputChannelId(boost.c_str());
const AZ::CVarFixedString& orbit = ed_cameraSystemOrbitKey;
CameraOrbitId = InputChannelId(orbit.c_str());
const AZ::CVarFixedString& freeLook = ed_cameraSystemFreeLookButton;
CameraFreeLookButton = InputChannelId(freeLook.c_str());
const AZ::CVarFixedString& freePan = ed_cameraSystemFreePanButton;
CameraFreePanButton = InputChannelId(freePan.c_str());
const AZ::CVarFixedString& orbitLook = ed_cameraSystemOrbitLookButton;
CameraOrbitLookButton = InputChannelId(orbitLook.c_str());
const AZ::CVarFixedString& orbitDolly = ed_cameraSystemOrbitDollyButton;
CameraOrbitDollyButton = InputChannelId(orbitDolly.c_str());
const AZ::CVarFixedString& orbitPan = ed_cameraSystemOrbitPanButton;
CameraOrbitPanButton = InputChannelId(orbitPan.c_str());
}
static void ReloadCameraKeyBindingsConsole(const AZ::ConsoleCommandContainer&)
{
ReloadCameraKeyBindings();
}
AZ_CONSOLEFREEFUNC(ReloadCameraKeyBindingsConsole, AZ::ConsoleFunctorFlags::Null, "Reload keybindings for the modern camera system");
// Based on paper by David Eberly - https://www.geometrictools.com/Documentation/EulerAngles.pdf
AZ::Vector3 EulerAngles(const AZ::Matrix3x3& orientation)
{
float x;
float y;
float z;
// 2.4 Factor as RzRyRx
if (orientation.GetElement(2, 0) < 1.0f)
{
if (orientation.GetElement(2, 0) > -1.0f)
{
x = std::atan2(orientation.GetElement(2, 1), orientation.GetElement(2, 2));
y = std::asin(-orientation.GetElement(2, 0));
z = std::atan2(orientation.GetElement(1, 0), orientation.GetElement(0, 0));
}
else
{
x = 0.0f;
y = AZ::Constants::Pi * 0.5f;
z = -std::atan2(-orientation.GetElement(2, 1), orientation.GetElement(1, 1));
}
}
else
{
x = 0.0f;
y = -AZ::Constants::Pi * 0.5f;
z = std::atan2(-orientation.GetElement(1, 2), orientation.GetElement(1, 1));
}
return {x, y, z};
}
void UpdateCameraFromTransform(Camera& camera, const AZ::Transform& transform)
{
const auto eulerAngles = AzFramework::EulerAngles(AZ::Matrix3x3::CreateFromTransform(transform));
camera.m_lookAt = transform.GetTranslation();
camera.m_pitch = eulerAngles.GetX();
camera.m_yaw = eulerAngles.GetZ();
}
bool CameraSystem::HandleEvents(const InputEvent& event)
{
if (const auto& cursor_motion = AZStd::get_if<CursorMotionEvent>(&event))
{
@ -30,10 +166,10 @@ namespace AzFramework
m_scrollDelta = scroll->m_delta;
}
m_cameras.HandleEvents(event);
return m_cameras.HandleEvents(event);
}
Camera CameraSystem::StepCamera(const Camera& targetCamera, float deltaTime)
Camera CameraSystem::StepCamera(const Camera& targetCamera, const float deltaTime)
{
const auto cursorDelta = m_currentCursorPosition.has_value() && m_lastCursorPosition.has_value()
? m_currentCursorPosition.value() - m_lastCursorPosition.value()
@ -51,36 +187,41 @@ namespace AzFramework
return nextCamera;
}
void Cameras::AddCamera(AZStd::shared_ptr<CameraInput> camera_input)
void Cameras::AddCamera(AZStd::shared_ptr<CameraInput> cameraInput)
{
m_idleCameraInputs.push_back(AZStd::move(camera_input));
m_idleCameraInputs.push_back(AZStd::move(cameraInput));
}
void Cameras::HandleEvents(const InputEvent& event)
bool Cameras::HandleEvents(const InputEvent& event)
{
for (auto& camera_input : m_activeCameraInputs)
bool handling = false;
for (auto& cameraInput : m_activeCameraInputs)
{
camera_input->HandleEvents(event);
cameraInput->HandleEvents(event);
handling = !cameraInput->Idle() || handling;
}
for (auto& camera_input : m_idleCameraInputs)
for (auto& cameraInput : m_idleCameraInputs)
{
camera_input->HandleEvents(event);
cameraInput->HandleEvents(event);
}
return handling;
}
Camera Cameras::StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, const float deltaTime)
Camera Cameras::StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, const float scrollDelta, const float deltaTime)
{
for (int i = 0; i < m_idleCameraInputs.size();)
{
auto& camera_input = m_idleCameraInputs[i];
const bool can_begin = camera_input->Beginning() &&
auto& cameraInput = m_idleCameraInputs[i];
const bool canBegin = cameraInput->Beginning() &&
std::all_of(m_activeCameraInputs.cbegin(), m_activeCameraInputs.cend(),
[](const auto& input) { return !input->Exclusive(); }) &&
(!camera_input->Exclusive() || (camera_input->Exclusive() && m_activeCameraInputs.empty()));
if (can_begin)
(!cameraInput->Exclusive() || (cameraInput->Exclusive() && m_activeCameraInputs.empty()));
if (canBegin)
{
m_activeCameraInputs.push_back(camera_input);
m_activeCameraInputs.push_back(cameraInput);
using AZStd::swap;
swap(m_idleCameraInputs[i], m_idleCameraInputs[m_idleCameraInputs.size() - 1]);
m_idleCameraInputs.pop_back();
@ -93,25 +234,25 @@ namespace AzFramework
// accumulate
Camera nextCamera = targetCamera;
for (auto& camera_input : m_activeCameraInputs)
for (auto& cameraInput : m_activeCameraInputs)
{
nextCamera = camera_input->StepCamera(nextCamera, cursorDelta, scrollDelta, deltaTime);
nextCamera = cameraInput->StepCamera(nextCamera, cursorDelta, scrollDelta, deltaTime);
}
for (int i = 0; i < m_activeCameraInputs.size();)
{
auto& camera_input = m_activeCameraInputs[i];
if (camera_input->Ending())
auto& cameraInput = m_activeCameraInputs[i];
if (cameraInput->Ending())
{
camera_input->ClearActivation();
m_idleCameraInputs.push_back(camera_input);
cameraInput->ClearActivation();
m_idleCameraInputs.push_back(cameraInput);
using AZStd::swap;
swap(m_activeCameraInputs[i], m_activeCameraInputs[m_activeCameraInputs.size() - 1]);
m_activeCameraInputs.pop_back();
}
else
{
camera_input->ContinueActivation();
cameraInput->ContinueActivation();
i++;
}
}
@ -134,7 +275,7 @@ namespace AzFramework
{
if (const auto& input = AZStd::get_if<DiscreteInputEvent>(&event))
{
if (input->m_channelId == m_channelId)
if (input->m_channelId == m_rotateChannelId)
{
if (input->m_state == InputChannel::State::Began)
{
@ -154,14 +295,14 @@ namespace AzFramework
{
Camera nextCamera = targetCamera;
nextCamera.m_pitch += float(cursorDelta.m_y) * m_props.m_rotateSpeed;
nextCamera.m_yaw += float(cursorDelta.m_x) * m_props.m_rotateSpeed;
nextCamera.m_pitch -= float(cursorDelta.m_y) * ed_cameraSystemRotateSpeed;
nextCamera.m_yaw -= float(cursorDelta.m_x) * ed_cameraSystemRotateSpeed;
auto clamp_rotation = [](const float angle) { return std::fmod(angle + AZ::Constants::TwoOverPi, AZ::Constants::TwoOverPi); };
const auto clampRotation = [](const float angle) { return std::fmod(angle + AZ::Constants::TwoPi, AZ::Constants::TwoPi); };
nextCamera.m_yaw = clamp_rotation(nextCamera.m_yaw);
nextCamera.m_yaw = clampRotation(nextCamera.m_yaw);
// clamp pitch to be +-90 degrees
nextCamera.m_pitch = AZ::GetClamp(nextCamera.m_pitch, -AZ::Constants::Pi * 0.5f, AZ::Constants::Pi * 0.5f);
nextCamera.m_pitch = AZ::GetClamp(nextCamera.m_pitch, -AZ::Constants::HalfPi, AZ::Constants::HalfPi);
return nextCamera;
}
@ -170,7 +311,7 @@ namespace AzFramework
{
if (const auto& input = AZStd::get_if<DiscreteInputEvent>(&event))
{
if (input->m_channelId == InputDeviceMouse::Button::Middle)
if (input->m_channelId == m_panChannelId)
{
if (input->m_state == InputChannel::State::Began)
{
@ -190,51 +331,50 @@ namespace AzFramework
{
Camera nextCamera = targetCamera;
const auto pan_axes = m_panAxesFn(nextCamera);
const auto panAxes = m_panAxesFn(nextCamera);
const auto delta_pan_x = float(cursorDelta.m_x) * pan_axes.m_horizontalAxis * m_props.m_panSpeed;
const auto delta_pan_y = float(cursorDelta.m_y) * pan_axes.m_verticalAxis * m_props.m_panSpeed;
const auto deltaPanX = float(cursorDelta.m_x) * panAxes.m_horizontalAxis * ed_cameraSystemPanSpeed;
const auto deltaPanY = float(cursorDelta.m_y) * panAxes.m_verticalAxis * ed_cameraSystemPanSpeed;
const auto inv = [](const bool invert) {
constexpr float Dir[] = {1.0f, -1.0f};
return Dir[static_cast<int>(invert)];
};
nextCamera.m_lookAt += delta_pan_x * inv(m_props.m_panInvertX);
nextCamera.m_lookAt += delta_pan_y * -inv(m_props.m_panInvertY);
nextCamera.m_lookAt += deltaPanX * inv(ed_cameraSystemPanInvertX);
nextCamera.m_lookAt += deltaPanY * -inv(ed_cameraSystemPanInvertY);
return nextCamera;
}
TranslateCameraInput::TranslationType TranslateCameraInput::translationFromKey(InputChannelId channelId)
{
// note: remove hard-coded InputDevice keys
if (channelId == InputDeviceKeyboard::Key::AlphanumericW)
if (channelId == CameraTranslateForwardId)
{
return TranslationType::Forward;
}
if (channelId == InputDeviceKeyboard::Key::AlphanumericS)
if (channelId == CameraTranslateBackwardId)
{
return TranslationType::Backward;
}
if (channelId == InputDeviceKeyboard::Key::AlphanumericA)
if (channelId == CameraTranslateLeftId)
{
return TranslationType::Left;
}
if (channelId == InputDeviceKeyboard::Key::AlphanumericD)
if (channelId == CameraTranslateRightId)
{
return TranslationType::Right;
}
if (channelId == InputDeviceKeyboard::Key::AlphanumericQ)
if (channelId == CameraTranslateDownId)
{
return TranslationType::Down;
}
if (channelId == InputDeviceKeyboard::Key::AlphanumericE)
if (channelId == CameraTranslateUpId)
{
return TranslationType::Up;
}
@ -259,19 +399,19 @@ namespace AzFramework
BeginActivation();
}
if (input->m_channelId == InputDeviceKeyboard::Key::ModifierShiftL)
if (input->m_channelId == CameraTranslateBoostId)
{
m_boost = true;
}
}
else if (input->m_state == InputChannel::State::Ended)
{
m_translation ^= translationFromKey(input->m_channelId);
m_translation &= ~(translationFromKey(input->m_channelId));
if (m_translation == TranslationType::Nil)
{
EndActivation();
}
if (input->m_channelId == InputDeviceKeyboard::Key::ModifierShiftL)
if (input->m_channelId == CameraTranslateBoostId)
{
m_boost = false;
}
@ -285,13 +425,13 @@ namespace AzFramework
{
Camera nextCamera = targetCamera;
const auto translation_basis = m_translationAxesFn(nextCamera);
const auto axisX = translation_basis.GetBasisX();
const auto axisY = translation_basis.GetBasisY();
const auto axisZ = translation_basis.GetBasisZ();
const auto translationBasis = m_translationAxesFn(nextCamera);
const auto axisX = translationBasis.GetBasisX();
const auto axisY = translationBasis.GetBasisY();
const auto axisZ = translationBasis.GetBasisZ();
const float speed = [boost = m_boost, props = m_props]() {
return props.m_translateSpeed * (boost ? props.m_boostMultiplier : 1.0f);
const float speed = [boost = m_boost]() {
return ed_cameraSystemTranslateSpeed * (boost ? ed_cameraSystemBoostMultiplier : 1.0f);
}();
if ((m_translation & TranslationType::Forward) == TranslationType::Forward)
@ -342,12 +482,8 @@ namespace AzFramework
{
if (const auto* input = AZStd::get_if<DiscreteInputEvent>(&event))
{
if (input->m_channelId == InputDeviceKeyboard::Key::ModifierAltL)
if (input->m_channelId == CameraOrbitId)
{
if (input->m_state == InputChannel::State::Updated)
{
goto end;
}
if (input->m_state == InputChannel::State::Began)
{
BeginActivation();
@ -358,7 +494,7 @@ namespace AzFramework
}
}
}
end:
if (Active())
{
m_orbitCameras.HandleEvents(event);
@ -366,29 +502,29 @@ namespace AzFramework
}
Camera OrbitCameraInput::StepCamera(
const Camera& targetCamera, const ScreenVector& cursorDelta, const float scrollDelta, float deltaTime)
const Camera& targetCamera, const ScreenVector& cursorDelta, const float scrollDelta, const float deltaTime)
{
Camera nextCamera = targetCamera;
if (Beginning())
{
float hit_distance = 0.0f;
if (AZ::Plane::CreateFromNormalAndPoint(AZ::Vector3::CreateAxisZ(), AZ::Vector3::CreateZero())
.CastRay(targetCamera.Translation(), targetCamera.Rotation().GetBasisY() * m_props.m_maxOrbitDistance, hit_distance))
if (AZ::Plane::CreateFromNormalAndPoint(AZ::Vector3::CreateAxisZ(), AZ::Vector3::CreateAxisZ(ed_cameraSystemDefaultPlaneHeight))
.CastRay(targetCamera.Translation(), targetCamera.Rotation().GetBasisY(), hit_distance))
{
hit_distance = AZStd::min<float>(hit_distance, ed_cameraSystemMaxOrbitDistance);
nextCamera.m_lookDist = -hit_distance;
nextCamera.m_lookAt = targetCamera.Translation() + targetCamera.Rotation().GetBasisY() * hit_distance;
}
else
{
nextCamera.m_lookDist = -m_props.m_defaultOrbitDistance;
nextCamera.m_lookAt = targetCamera.Translation() + targetCamera.Rotation().GetBasisY() * m_props.m_defaultOrbitDistance;
nextCamera.m_lookDist = -ed_cameraSystemMaxOrbitDistance;
nextCamera.m_lookAt = targetCamera.Translation() + targetCamera.Rotation().GetBasisY() * ed_cameraSystemMaxOrbitDistance;
}
}
if (Active())
{
// todo: need to return nested cameras to idle state when ending
nextCamera = m_orbitCameras.StepCamera(nextCamera, cursorDelta, scrollDelta, deltaTime);
}
@ -413,10 +549,10 @@ namespace AzFramework
Camera OrbitDollyScrollCameraInput::StepCamera(
const Camera& targetCamera, [[maybe_unused]] const ScreenVector& cursorDelta, const float scrollDelta,
[[maybe_unused]] float deltaTime)
[[maybe_unused]] const float deltaTime)
{
Camera nextCamera = targetCamera;
nextCamera.m_lookDist = AZ::GetMin(nextCamera.m_lookDist + scrollDelta * m_props.m_dollySpeed, 0.0f);
nextCamera.m_lookDist = AZ::GetMin(nextCamera.m_lookDist + scrollDelta * ed_cameraSystemOrbitDollyScrollSpeed, 0.0f);
EndActivation();
return nextCamera;
}
@ -425,7 +561,7 @@ namespace AzFramework
{
if (const auto& input = AZStd::get_if<DiscreteInputEvent>(&event))
{
if (input->m_channelId == InputDeviceMouse::Button::Right)
if (input->m_channelId == m_dollyChannelId)
{
if (input->m_state == InputChannel::State::Began)
{
@ -444,7 +580,7 @@ namespace AzFramework
[[maybe_unused]] const float deltaTime)
{
Camera nextCamera = targetCamera;
nextCamera.m_lookDist = AZ::GetMin(nextCamera.m_lookDist + float(cursorDelta.m_y) * m_props.m_dollySpeed, 0.0f);
nextCamera.m_lookDist = AZ::GetMin(nextCamera.m_lookDist + float(cursorDelta.m_y) * ed_cameraSystemOrbitDollyCursorSpeed, 0.0f);
return nextCamera;
}
@ -457,7 +593,7 @@ namespace AzFramework
}
Camera ScrollTranslationCameraInput::StepCamera(
const Camera& targetCamera, [[maybe_unused]] const ScreenVector& cursorDelta, float scrollDelta,
const Camera& targetCamera, [[maybe_unused]] const ScreenVector& cursorDelta, const float scrollDelta,
[[maybe_unused]] const float deltaTime)
{
Camera nextCamera = targetCamera;
@ -465,38 +601,39 @@ namespace AzFramework
const auto translation_basis = LookTranslation(nextCamera);
const auto axisY = translation_basis.GetBasisY();
nextCamera.m_lookAt += axisY * scrollDelta * m_props.m_translateSpeed;
nextCamera.m_lookAt += axisY * scrollDelta * ed_cameraSystemScrollTranslateSpeed;
EndActivation();
return nextCamera;
}
Camera SmoothCamera(const Camera& currentCamera, const Camera& targetCamera, const SmoothProps& props, const float deltaTime)
Camera SmoothCamera(const Camera& currentCamera, const Camera& targetCamera, const float deltaTime)
{
const auto clamp_rotation = [](const float angle) { return std::fmod(angle + AZ::Constants::TwoPi, AZ::Constants::TwoPi); };
// keep yaw in 0 - 360 range
float target_yaw = clamp_rotation(targetCamera.m_yaw);
const float current_yaw = clamp_rotation(currentCamera.m_yaw);
float targetYaw = clamp_rotation(targetCamera.m_yaw);
const float currentYaw = clamp_rotation(currentCamera.m_yaw);
auto sign = [](const float value) { return static_cast<float>((0.0f < value) - (value < 0.0f)); };
// return the sign of the float input (-1, 0, 1)
const auto sign = [](const float value) { return aznumeric_cast<float>((0.0f < value) - (value < 0.0f)); };
// ensure smooth transition when moving across 0 - 360 boundary
const float yaw_delta = target_yaw - current_yaw;
if (std::abs(yaw_delta) >= AZ::Constants::Pi)
const float yawDelta = targetYaw - currentYaw;
if (std::abs(yawDelta) >= AZ::Constants::Pi)
{
target_yaw -= AZ::Constants::TwoPi * sign(yaw_delta);
targetYaw -= AZ::Constants::TwoPi * sign(yawDelta);
}
Camera camera;
// note: the math for the lerp smoothing implementation for camera rotation and translation was inspired by this excellent
// note: the math for the lerp smoothing implementation for camera rotation and translation was inspired by this excellent
// article by Scott Lembcke: https://www.gamasutra.com/blogs/ScottLembcke/20180404/316046/Improved_Lerp_Smoothing.php
const float lookRate = std::exp2(props.m_lookSmoothness);
const float lookRate = std::exp2(ed_cameraSystemLookSmoothness);
const float lookT = std::exp2(-lookRate * deltaTime);
camera.m_pitch = AZ::Lerp(targetCamera.m_pitch, currentCamera.m_pitch, lookT);
camera.m_yaw = AZ::Lerp(target_yaw, current_yaw, lookT);
const float moveRate = std::exp2(props.m_moveSmoothness);
camera.m_yaw = AZ::Lerp(targetYaw, currentYaw, lookT);
const float moveRate = std::exp2(ed_cameraSystemTranslateSmoothness);
const float moveT = std::exp2(-moveRate * deltaTime);
camera.m_lookDist = AZ::Lerp(targetCamera.m_lookDist, currentCamera.m_lookDist, moveT);
camera.m_lookAt = targetCamera.m_lookAt.Lerp(currentCamera.m_lookAt, moveT);
@ -508,20 +645,24 @@ namespace AzFramework
const auto& inputChannelId = inputChannel.GetInputChannelId();
const auto& inputDeviceId = inputChannel.GetInputDevice().GetInputDeviceId();
if (inputChannelId == InputDeviceMouse::SystemCursorPosition)
const bool wasMouseButton =
AZStd::any_of(InputDeviceMouse::Button::All.begin(), InputDeviceMouse::Button::All.end(), [inputChannelId](const auto& button) {
return button == inputChannelId;
});
if (inputChannelId == InputDeviceMouse::Movement::X || inputChannelId == InputDeviceMouse::Movement::Y)
{
AZ::Vector2 systemCursorPositionNormalized = AZ::Vector2::CreateZero();
InputSystemCursorRequestBus::EventResult(
systemCursorPositionNormalized, inputDeviceId, &InputSystemCursorRequestBus::Events::GetSystemCursorPositionNormalized);
const auto* position = inputChannel.GetCustomData<AzFramework::InputChannel::PositionData2D>();
AZ_Assert(position, "Expected PositionData2D but found nullptr");
return CursorMotionEvent{ScreenPoint(
systemCursorPositionNormalized.GetX() * windowSize.m_width, systemCursorPositionNormalized.GetY() * windowSize.m_height)};
position->m_normalizedPosition.GetX() * windowSize.m_width, position->m_normalizedPosition.GetY() * windowSize.m_height)};
}
else if (inputChannelId == InputDeviceMouse::Movement::Z)
{
return ScrollEvent{inputChannel.GetValue()};
}
else if (InputDeviceMouse::IsMouseDevice(inputDeviceId) || InputDeviceKeyboard::IsKeyboardDevice(inputDeviceId))
else if (wasMouseButton || InputDeviceKeyboard::IsKeyboardDevice(inputDeviceId))
{
return DiscreteInputEvent{inputChannelId, inputChannel.GetState()};
}

@ -17,13 +17,16 @@
#include <AzCore/std/containers/variant.h>
#include <AzCore/std/optional.h>
#include <AzFramework/Input/Channels/InputChannel.h>
#include <AzFramework/Input/Devices/Keyboard/InputDeviceKeyboard.h>
#include <AzFramework/Input/Devices/Mouse/InputDeviceMouse.h>
#include <AzFramework/Viewport/ScreenGeometry.h>
#include <AzFramework/Viewport/ViewportId.h>
namespace AzFramework
{
struct WindowSize;
//! Update camera key bindings that can be overridden with AZ console vars (invoke from console to update)
void ReloadCameraKeyBindings();
//! Return Euler angles (pitch, roll, yaw) for the incoming orientation.
AZ::Vector3 EulerAngles(const AZ::Matrix3x3& orientation);
struct Camera
{
@ -51,8 +54,8 @@ namespace AzFramework
inline AZ::Transform Camera::Transform() const
{
return AZ::Transform::CreateTranslation(m_lookAt) * AZ::Transform::CreateRotationX(m_pitch) *
AZ::Transform::CreateRotationZ(m_yaw) * AZ::Transform::CreateTranslation(AZ::Vector3::CreateAxisZ(m_lookDist));
return AZ::Transform::CreateTranslation(m_lookAt) * AZ::Transform::CreateRotationZ(m_yaw) *
AZ::Transform::CreateRotationX(m_pitch) * AZ::Transform::CreateTranslation(AZ::Vector3::CreateAxisY(m_lookDist));
}
inline AZ::Matrix3x3 Camera::Rotation() const
@ -65,6 +68,8 @@ namespace AzFramework
return Transform().GetTranslation();
}
void UpdateCameraFromTransform(Camera& camera, const AZ::Transform& transform);
struct CursorMotionEvent
{
ScreenPoint m_position;
@ -159,19 +164,13 @@ namespace AzFramework
Activation m_activation = Activation::Idle;
};
struct SmoothProps
{
float m_lookSmoothness = 5.0f;
float m_moveSmoothness = 5.0f;
};
Camera SmoothCamera(const Camera& currentCamera, const Camera& targetCamera, const SmoothProps& props, float deltaTime);
Camera SmoothCamera(const Camera& currentCamera, const Camera& targetCamera, float deltaTime);
class Cameras
{
public:
void AddCamera(AZStd::shared_ptr<CameraInput> cameraInput);
void HandleEvents(const InputEvent& event);
bool HandleEvents(const InputEvent& event);
Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime);
void Reset();
@ -183,7 +182,7 @@ namespace AzFramework
class CameraSystem
{
public:
void HandleEvents(const InputEvent& event);
bool HandleEvents(const InputEvent& event);
Camera StepCamera(const Camera& targetCamera, float deltaTime);
Cameras m_cameras;
@ -197,19 +196,16 @@ namespace AzFramework
class RotateCameraInput : public CameraInput
{
public:
explicit RotateCameraInput(const InputChannelId channelId)
: m_channelId(channelId)
explicit RotateCameraInput(const InputChannelId rotateChannelId)
: m_rotateChannelId(rotateChannelId)
{
}
void HandleEvents(const InputEvent& event) override;
Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override;
InputChannelId m_channelId;
struct Props
{
float m_rotateSpeed = 0.005f;
} m_props;
private:
InputChannelId m_rotateChannelId;
};
struct PanAxes
@ -242,22 +238,17 @@ namespace AzFramework
class PanCameraInput : public CameraInput
{
public:
explicit PanCameraInput(PanAxesFn panAxesFn)
PanCameraInput(const InputChannelId panChannelId, PanAxesFn panAxesFn)
: m_panAxesFn(AZStd::move(panAxesFn))
, m_panChannelId(panChannelId)
{
}
void HandleEvents(const InputEvent& event) override;
Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override;
struct Props
{
float m_panSpeed = 0.01f;
bool m_panInvertX = true;
bool m_panInvertY = true;
} m_props;
private:
PanAxesFn m_panAxesFn;
InputChannelId m_panChannelId;
};
using TranslationAxesFn = AZStd::function<AZ::Matrix3x3(const Camera& camera)>;
@ -298,17 +289,11 @@ namespace AzFramework
Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override;
void ResetImpl() override;
struct Props
{
float m_translateSpeed = 10.0f;
float m_boostMultiplier = 3.0f;
} m_props;
private:
enum class TranslationType
{
// clang-format off
Nil = 0,
Nil = 0,
Forward = 1 << 0,
Backward = 1 << 1,
Left = 1 << 2,
@ -354,6 +339,11 @@ namespace AzFramework
return lhs;
}
friend TranslationType operator~(const TranslationType lhs)
{
return static_cast<TranslationType>(~static_cast<std::underlying_type_t<TranslationType>>(lhs));
}
static TranslationType translationFromKey(InputChannelId channelId);
TranslationType m_translation = TranslationType::Nil;
@ -366,23 +356,19 @@ namespace AzFramework
public:
void HandleEvents(const InputEvent& event) override;
Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override;
struct Props
{
float m_dollySpeed = 0.2f;
} m_props;
};
class OrbitDollyCursorMoveCameraInput : public CameraInput
{
public:
explicit OrbitDollyCursorMoveCameraInput(const InputChannelId dollyChannelId)
: m_dollyChannelId(dollyChannelId) {}
void HandleEvents(const InputEvent& event) override;
Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override;
struct Props
{
float m_dollySpeed = 0.1f;
} m_props;
private:
InputChannelId m_dollyChannelId;
};
class ScrollTranslationCameraInput : public CameraInput
@ -390,11 +376,6 @@ namespace AzFramework
public:
void HandleEvents(const InputEvent& event) override;
Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override;
struct Props
{
float m_translateSpeed = 0.2f;
} m_props;
};
class OrbitCameraInput : public CameraInput
@ -408,13 +389,10 @@ namespace AzFramework
}
Cameras m_orbitCameras;
struct Props
{
float m_defaultOrbitDistance = 15.0f;
float m_maxOrbitDistance = 100.0f;
} m_props;
};
struct WindowSize;
//! Map from a generic InputChannel event to a camera specific InputEvent.
InputEvent BuildInputEvent(const InputChannel& inputChannel, const WindowSize& windowSize);
} // namespace AzFramework

@ -14,7 +14,6 @@ set(FILES
AzFrameworkModule.h
AzFrameworkModule.cpp
API/ApplicationAPI.h
API/AtomActiveInterface.h
Application/Application.cpp
Application/Application.h
Archive/Archive.cpp

@ -16,7 +16,6 @@
#include <AzCore/std/string/string.h>
#include <AzCore/std/containers/fixed_vector.h>
#include <AzFramework/API/AtomActiveInterface.h>
#include <AzCore/Interface/Interface.h>
namespace AzQtComponents

@ -13,6 +13,12 @@
#include <AzCore/EBus/EBus.h>
#include <AzCore/Interface/Interface.h>
#include <AzCore/std/string/string.h>
namespace AZ
{
struct BehaviorParameter;
}
namespace AzToolsFramework
{
@ -40,6 +46,8 @@ namespace AzToolsFramework
};
using GlobalFunctionCollection = AZStd::vector<GlobalFunction>;
virtual void GetGlobalFunctionList(GlobalFunctionCollection& globalFunctionCollection) const = 0;
virtual AZStd::string FetchPythonTypeName(const AZ::BehaviorParameter& param) = 0;
};
//! Interface to signal the phases for the Python virtual machine

@ -17,7 +17,7 @@
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/Serialization/Utils.h>
#include <AzCore/std/parallel/thread.h>
#include <AzCore/Component/ComponentApplicationBus.h>
#include <AzCore/Utils/Utils.h>
#include <AzFramework/Asset/AssetBundleManifest.h>
#include <AzFramework/StringFunc/StringFunc.h>
#include <AzFramework/API/ApplicationAPI.h>
@ -250,7 +250,7 @@ namespace AzToolsFramework
AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance();
AZ_Assert(fileIO != nullptr, "AZ::IO::FileIOBase must be ready for use.\n");
AZStd::string bundleFilePath = assetBundleSettings.m_bundleFilePath;
AZ::IO::Path bundleFilePath = AZ::IO::Path(AZStd::string_view{ AZ::Utils::GetEnginePath() }) / assetBundleSettings.m_bundleFilePath;
AzFramework::PlatformId platformId = static_cast<AzFramework::PlatformId>(AzFramework::PlatformHelper::GetPlatformIndexFromName(assetBundleSettings.m_platform.c_str()));
@ -259,22 +259,13 @@ namespace AzToolsFramework
return false;
}
const char* appRoot = nullptr;
AzFramework::ApplicationRequests::Bus::BroadcastResult(appRoot, &AzFramework::ApplicationRequests::GetAppRoot);
if (AzFramework::StringFunc::Path::IsRelative(bundleFilePath.c_str()))
{
AzFramework::StringFunc::Path::ConstructFull(appRoot, bundleFilePath.c_str(), bundleFilePath, true);
}
AZ::u64 maxSizeInBytes = static_cast<AZ::u64>(assetBundleSettings.m_maxBundleSizeInMB * NumOfBytesInMB);
AZ::u64 assetCatalogFileSizeBuffer = static_cast<AZ::u64>(AssetCatalogFileSizeBufferPercentage * assetBundleSettings.m_maxBundleSizeInMB * NumOfBytesInMB) / 100;
AZ::u64 bundleSize = 0;
AZ::u64 totalFileSize = 0;
int bundleIndex = 0;
AZStd::string bundleFullPath = bundleFilePath;
AZStd::string tempBundleFilePath = bundleFullPath + "_temp";
AZStd::string tempBundleFilePath = bundleFilePath.Native() + "_temp";
AZStd::vector<AZStd::string> dependentBundleNames;
AZStd::vector<AZStd::string> levelDirs;
@ -301,7 +292,7 @@ namespace AzToolsFramework
if (fileIO->Exists(bundleFilePath.c_str()))
{
// This will delete both the parent bundle as well as all the dependent bundles mentioned in the manifest file of the parent bundle.
if (!DeleteBundleFiles(bundleFilePath))
if (!DeleteBundleFiles(bundleFilePath.Native()))
{
return false;
}
@ -390,7 +381,7 @@ namespace AzToolsFramework
// we need to find a bundle which does not exist on disk;
bundleIndex++;
numOfTries--;
dependentBundleFileName = CreateAssetBundleFileName(bundleFilePath, bundleIndex);
dependentBundleFileName = CreateAssetBundleFileName(bundleFilePath.Native(), bundleIndex);
AzFramework::StringFunc::Path::ReplaceFullName(tempBundleFilePath, (dependentBundleFileName + tempBundleFileSuffix).c_str());
} while (numOfTries && fileIO->Exists(tempBundleFilePath.c_str()));
@ -463,15 +454,7 @@ namespace AzToolsFramework
AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance();
AZStd::string assetFileInfoListPath = assetBundleSettings.m_assetFileInfoListPath;
const char* appRoot = nullptr;
AzFramework::ApplicationRequests::Bus::BroadcastResult(appRoot, &AzFramework::ApplicationRequests::GetAppRoot);
if (AzFramework::StringFunc::Path::IsRelative(assetFileInfoListPath.c_str()))
{
AzFramework::StringFunc::Path::ConstructFull(appRoot, assetFileInfoListPath.c_str(), assetFileInfoListPath, true);
}
AZ::IO::Path assetFileInfoListPath = AZ::IO::Path{ AZStd::string_view{AZ::Utils::GetEnginePath()} } / assetBundleSettings.m_assetFileInfoListPath;
if (!fileIO->Exists(assetFileInfoListPath.c_str()))
{

@ -53,7 +53,6 @@
#include <AzToolsFramework/UI/EditorEntityUi/EditorEntityUiSystemComponent.h>
#include <AzToolsFramework/Thumbnails/ThumbnailerComponent.h>
#include <AzToolsFramework/AssetBrowser/AssetBrowserComponent.h>
#include <AzToolsFramework/MaterialBrowser/MaterialBrowserComponent.h>
#include <AzToolsFramework/ViewportSelection/EditorInteractionSystemComponent.h>
namespace AzToolsFramework
@ -93,7 +92,6 @@ namespace AzToolsFramework
AzToolsFramework::SliceDependencyBrowserComponent::CreateDescriptor(),
AzToolsFramework::Thumbnailer::ThumbnailerComponent::CreateDescriptor(),
AzToolsFramework::AssetBrowser::AssetBrowserComponent::CreateDescriptor(),
AzToolsFramework::MaterialBrowser::MaterialBrowserComponent::CreateDescriptor(),
AzToolsFramework::EditorInteractionSystemComponent::CreateDescriptor(),
AzToolsFramework::Components::EditorComponentAPIComponent::CreateDescriptor(),
AzToolsFramework::Components::EditorLevelComponentAPIComponent::CreateDescriptor(),

@ -1,43 +0,0 @@
/*
* 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/EBus/EBus.h>
namespace AZ
{
namespace Data
{
struct AssetId;
}
}
namespace AzToolsFramework
{
namespace MaterialBrowser
{
class MaterialBrowserRequests
: public AZ::EBusTraits
{
public:
// Only a single handler is allowed
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
virtual bool HasRecord(const AZ::Data::AssetId& assetId) = 0;
virtual bool IsMultiMaterial(const AZ::Data::AssetId& assetId) = 0;
};
using MaterialBrowserRequestBus = AZ::EBus<MaterialBrowserRequests>;
} // namespace MaterialBrowser
} // namespace AzToolsFramework

@ -1,65 +0,0 @@
/*
* 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 <AzCore/Serialization/SerializeContext.h>
#include <AzToolsFramework/MaterialBrowser/MaterialBrowserComponent.h>
#include <AzToolsFramework/Thumbnails/ThumbnailerBus.h>
#include <AzToolsFramework/AssetBrowser/Thumbnails/FolderThumbnail.h>
#include <AzToolsFramework/AssetBrowser/Thumbnails/SourceThumbnail.h>
#include <AzToolsFramework/MaterialBrowser/MaterialThumbnail.h>
#include <AzToolsFramework/Thumbnails/SourceControlThumbnail.h>
#include <QApplication>
AZ_PUSH_DISABLE_WARNING(4251, "-Wunknown-warning-option") // 4251: 'QBrush::d': class 'QScopedPointer<QBrushData,QBrushDataPointerDeleter>' needs to have dll-interface to be used by clients of class 'QBrush'
#include <QStyle>
AZ_POP_DISABLE_WARNING
namespace AzToolsFramework
{
namespace MaterialBrowser
{
MaterialBrowserComponent::MaterialBrowserComponent()
{
}
void MaterialBrowserComponent::Activate()
{
using namespace Thumbnailer;
using namespace AssetBrowser;
const char* contextName = "MaterialBrowser";
ThumbnailerRequestsBus::Broadcast(&ThumbnailerRequests::RegisterContext, contextName);
ThumbnailerRequestsBus::Broadcast(&ThumbnailerRequests::RegisterThumbnailProvider, MAKE_TCACHE(FolderThumbnailCache), contextName);
ThumbnailerRequestsBus::Broadcast(&ThumbnailerRequests::RegisterThumbnailProvider, MAKE_TCACHE(SourceThumbnailCache), contextName);
ThumbnailerRequestsBus::Broadcast(&ThumbnailerRequests::RegisterThumbnailProvider, MAKE_TCACHE(MaterialThumbnailCache), contextName);
ThumbnailerRequestsBus::Broadcast(&ThumbnailerRequests::RegisterThumbnailProvider, MAKE_TCACHE(SourceControlThumbnailCache), contextName);
}
void MaterialBrowserComponent::Deactivate()
{
}
void MaterialBrowserComponent::Reflect(AZ::ReflectContext* context)
{
AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context);
if (serialize)
{
serialize->Class<MaterialBrowserComponent, AZ::Component>();
}
}
void MaterialBrowserComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
{
required.push_back(AZ_CRC("ThumbnailerService", 0x65422b97));
}
} // namespace MaterialBrowser
} // namespace AzToolsFramework

@ -1,41 +0,0 @@
/*
* 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/Memory/SystemAllocator.h>
#include <AzCore/Component/Component.h>
namespace AzToolsFramework
{
namespace MaterialBrowser
{
//! MaterialBrowserComponent allows initialization of MaterialBrowser systems, such as thumbnails
class MaterialBrowserComponent
: public AZ::Component
{
public:
AZ_COMPONENT(MaterialBrowserComponent, "{121F3F3B-2412-490D-9E3E-C205C677F476}")
MaterialBrowserComponent();
virtual ~MaterialBrowserComponent() = default;
//////////////////////////////////////////////////////////////////////////
// AZ::Component
//////////////////////////////////////////////////////////////////////////
void Activate() override;
void Deactivate() override;
static void Reflect(AZ::ReflectContext* context);
static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required);
};
} // namespace MaterialBrowser
} // namespace AzToolsFramework

@ -1,67 +0,0 @@
/*
* 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 <AzToolsFramework/MaterialBrowser/MaterialThumbnail.h>
#include <QPixmap>
namespace AzToolsFramework
{
namespace MaterialBrowser
{
static constexpr const char* SimpleMaterialIconPath = ":/MaterialBrowser/images/material_04.png";
static constexpr const char* MultiMaterialIconPath = ":/MaterialBrowser/images/material_06.png";
//////////////////////////////////////////////////////////////////////////
// MaterialThumbnail
//////////////////////////////////////////////////////////////////////////
MaterialThumbnail::MaterialThumbnail(Thumbnailer::SharedThumbnailKey key)
: Thumbnail(key)
{
auto productKey = azrtti_cast<const AzToolsFramework::AssetBrowser::ProductThumbnailKey*>(m_key.data());
AZ_Assert(productKey, "Incorrect key type, excpected ProductThumbnailKey");
bool multiMat = false;
MaterialBrowserRequestBus::BroadcastResult(multiMat, &MaterialBrowserRequests::IsMultiMaterial, productKey->GetAssetId());
QString iconPath = multiMat ? MultiMaterialIconPath : SimpleMaterialIconPath;
m_pixmap.load(iconPath);
m_state = m_pixmap.isNull() ? State::Failed : State::Ready;
}
//////////////////////////////////////////////////////////////////////////
// MaterialThumbnailCache
//////////////////////////////////////////////////////////////////////////
MaterialThumbnailCache::MaterialThumbnailCache()
: ThumbnailCache<MaterialThumbnail, MaterialKeyHash, MaterialKeyEqual>() {}
MaterialThumbnailCache::~MaterialThumbnailCache() = default;
int MaterialThumbnailCache::GetPriority() const
{
return 1;
}
const char* MaterialThumbnailCache::GetProviderName() const
{
return ProviderName;
}
bool MaterialThumbnailCache::IsSupportedThumbnail(Thumbnailer::SharedThumbnailKey key) const
{
return azrtti_istypeof<const AzToolsFramework::AssetBrowser::ProductThumbnailKey*>(key.data());
}
} // namespace MaterialBrowser
} // namespace AzToolsFramework
#include "MaterialBrowser/moc_MaterialThumbnail.cpp"

@ -1,86 +0,0 @@
/*
* 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
#if !defined(Q_MOC_RUN)
#include <AzToolsFramework/Thumbnails/Thumbnail.h>
#include <AzToolsFramework/AssetBrowser/Thumbnails/ProductThumbnail.h>
#include <AzToolsFramework/MaterialBrowser/MaterialBrowserBus.h>
#endif
namespace AzToolsFramework
{
namespace MaterialBrowser
{
//! Material Browser uses only 2 thumbnails: simple and multimaterial
class MaterialThumbnail
: public Thumbnailer::Thumbnail
{
Q_OBJECT
public:
MaterialThumbnail(Thumbnailer::SharedThumbnailKey key);
};
namespace
{
class MaterialKeyHash
{
public:
size_t operator()(const Thumbnailer::SharedThumbnailKey& /*val*/) const
{
return 0; // there is only 2 thumbnails in this cache
}
};
class MaterialKeyEqual
{
public:
bool operator()(const Thumbnailer::SharedThumbnailKey& val1, const Thumbnailer::SharedThumbnailKey& val2) const
{
auto productThumbnailKey1 = azrtti_cast<const AzToolsFramework::AssetBrowser::ProductThumbnailKey*>(val1.data());
auto productThumbnailKey2 = azrtti_cast<const AzToolsFramework::AssetBrowser::ProductThumbnailKey*>(val2.data());
if (!productThumbnailKey1 || !productThumbnailKey2)
{
return false;
}
// check whether keys point to single or multimaterial asset type
bool multiMat1 = false;
bool multiMat2 = false;
MaterialBrowserRequestBus::BroadcastResult(multiMat1, &MaterialBrowserRequests::IsMultiMaterial, productThumbnailKey1->GetAssetId());
MaterialBrowserRequestBus::BroadcastResult(multiMat2, &MaterialBrowserRequests::IsMultiMaterial, productThumbnailKey2->GetAssetId());
return multiMat1 == multiMat2;
}
};
}
//! MaterialBrowserEntry thumbnails
class MaterialThumbnailCache
: public Thumbnailer::ThumbnailCache<MaterialThumbnail, MaterialKeyHash, MaterialKeyEqual>
{
public:
MaterialThumbnailCache();
~MaterialThumbnailCache() override;
int GetPriority() const override;
const char* GetProviderName() const override;
static constexpr const char* ProviderName = "CryMaterial Thumbnails";
protected:
bool IsSupportedThumbnail(Thumbnailer::SharedThumbnailKey key) const override;
};
} // namespace MaterialBrowser
} // namespace AzToolsFramework

@ -96,9 +96,7 @@ namespace AzToolsFramework
// target templates of the other instances.
for (auto& nestedInstance : instances)
{
PrefabUndoHelpers::RemoveLink(
nestedInstance->GetTemplateId(), commonRootEntityOwningInstance->get().GetTemplateId(),
nestedInstance->GetInstanceAlias(), nestedInstance->GetLinkId(), undoBatch.GetUndoBatch());
RemoveLink(nestedInstance, commonRootEntityOwningInstance->get().GetTemplateId(), undoBatch.GetUndoBatch());
}
PrefabUndoHelpers::UpdatePrefabInstance(
@ -238,14 +236,9 @@ namespace AzToolsFramework
// Retrieve the owning instance of the common root entity, which will be our new instance's parent instance.
commonRootEntityOwningInstance = GetOwnerInstanceByEntityId(commonRootEntityId);
if (!commonRootEntityOwningInstance)
{
AZ_Assert(
false,
"Failed to create prefab : Couldn't get a valid owning instance for the common root entity of the enities provided");
return AZ::Failure(AZStd::string(
"Failed to create prefab : Couldn't get a valid owning instance for the common root entity of the enities provided"));
}
AZ_Assert(
commonRootEntityOwningInstance.has_value(),
"Failed to create prefab : Couldn't get a valid owning instance for the common root entity of the enities provided");
return AZ::Success();
}
@ -287,6 +280,34 @@ namespace AzToolsFramework
m_prefabUndoCache.Store(containerEntityId, AZStd::move(containerEntityDomAfter));
}
void PrefabPublicHandler::RemoveLink(
AZStd::unique_ptr<Instance>& sourceInstance, TemplateId targetTemplateId, UndoSystem::URSequencePoint* undoBatch)
{
LinkReference nestedInstanceLink = m_prefabSystemComponentInterface->FindLink(sourceInstance->GetLinkId());
AZ_Assert(
nestedInstanceLink.has_value(),
"A valid link was not found for one of the instances provided as input for the CreatePrefab operation.");
PrefabDomReference nestedInstanceLinkDom = nestedInstanceLink->get().GetLinkDom();
AZ_Assert(
nestedInstanceLinkDom.has_value(),
"A valid DOM was not found for the link corresponding to one of the instances provided as input for the "
"CreatePrefab operation.");
PrefabDomValueReference nestedInstanceLinkPatches =
PrefabDomUtils::FindPrefabDomValue(nestedInstanceLinkDom->get(), PrefabDomUtils::PatchesName);
AZ_Assert(
nestedInstanceLinkPatches.has_value(),
"A valid DOM for patches was not found for the link corresponding to one of the instances provided as input for the "
"CreatePrefab operation.");
PrefabDom patchesCopyForUndoSupport;
patchesCopyForUndoSupport.CopyFrom(nestedInstanceLinkPatches->get(), patchesCopyForUndoSupport.GetAllocator());
PrefabUndoHelpers::RemoveLink(
sourceInstance->GetTemplateId(), targetTemplateId, sourceInstance->GetInstanceAlias(), sourceInstance->GetLinkId(),
patchesCopyForUndoSupport, undoBatch);
}
PrefabOperationResult PrefabPublicHandler::SavePrefab(AZ::IO::Path filePath)
{
auto templateId = m_prefabSystemComponentInterface->GetTemplateIdFromFilePath(filePath.c_str());

@ -82,6 +82,16 @@ namespace AzToolsFramework
const EntityList& topLevelEntities, Instance& sourceInstance, TemplateId targetTemplateId,
UndoSystem::URSequencePoint* undoBatch, AZ::EntityId commonRootEntityId);
/**
* Removes the link between template of the sourceInstance and the template corresponding to targetTemplateId.
*
* \param sourceInstance The instance corresponding to the source template of the link to be removed.
* \param targetTemplateId The id of the target template of the link to be removed.
* \param undoBatch The undo batch to set as parent for this remove link action.
*/
void RemoveLink(
AZStd::unique_ptr<Instance>& sourceInstance, TemplateId targetTemplateId, UndoSystem::URSequencePoint* undoBatch);
/**
* Given a list of entityIds, finds the prefab instance that owns the common root entity of the entityIds.
*

@ -663,8 +663,9 @@ namespace AzToolsFramework
newLink.SetSourceTemplateId(linkSourceId);
newLink.SetInstanceName(instanceAlias.c_str());
newLink.GetLinkDom().SetObject();
newLink.GetLinkDom().AddMember(rapidjson::StringRef(PrefabDomUtils::SourceName),
rapidjson::StringRef(sourceTemplate.GetFilePath().c_str()), newLink.GetLinkDom().GetAllocator());
newLink.GetLinkDom().AddMember(
rapidjson::StringRef(PrefabDomUtils::SourceName), rapidjson::StringRef(sourceTemplate.GetFilePath().c_str()),
newLink.GetLinkDom().GetAllocator());
if (linkPatch && linkPatch->get().IsArray() && !(linkPatch->get().Empty()))
{

@ -113,7 +113,7 @@ namespace AzToolsFramework
, m_sourceId(InvalidTemplateId)
, m_instanceAlias("")
, m_linkId(InvalidLinkId)
, m_linkDom(PrefabDom())
, m_linkPatches(PrefabDom())
, m_linkStatus(LinkStatus::LINKSTATUS)
{
m_prefabSystemComponentInterface = AZ::Interface<PrefabSystemComponentInterface>::Get();
@ -124,7 +124,7 @@ namespace AzToolsFramework
const TemplateId& targetId,
const TemplateId& sourceId,
const InstanceAlias& instanceAlias,
PrefabDomReference linkDom,
PrefabDomReference linkPatches,
const LinkId linkId)
{
m_targetId = targetId;
@ -132,9 +132,9 @@ namespace AzToolsFramework
m_instanceAlias = instanceAlias;
m_linkId = linkId;
if (linkDom.has_value())
if (linkPatches.has_value())
{
m_linkDom = AZStd::move(linkDom->get());
m_linkPatches = AZStd::move(linkPatches->get());
}
//if linkId is invalid, set as ADD
@ -193,7 +193,7 @@ namespace AzToolsFramework
void PrefabUndoInstanceLink::AddLink()
{
m_linkId = m_prefabSystemComponentInterface->CreateLink(m_targetId, m_sourceId, m_instanceAlias, m_linkDom, m_linkId);
m_linkId = m_prefabSystemComponentInterface->CreateLink(m_targetId, m_sourceId, m_instanceAlias, m_linkPatches, m_linkId);
}
void PrefabUndoInstanceLink::RemoveLink()

@ -101,7 +101,7 @@ namespace AzToolsFramework
const TemplateId& targetId,
const TemplateId& sourceId,
const InstanceAlias& instanceAlias,
PrefabDomReference linkDom = PrefabDomReference(),
PrefabDomReference linkPatches = PrefabDomReference(),
const LinkId linkId = InvalidLinkId);
void Undo() override;
@ -120,7 +120,7 @@ namespace AzToolsFramework
InstanceAlias m_instanceAlias;
LinkId m_linkId;
PrefabDom m_linkDom; //data for delete/update
PrefabDom m_linkPatches; //data for delete/update
LinkStatus m_linkStatus;
PrefabSystemComponentInterface* m_prefabSystemComponentInterface = nullptr;

@ -46,13 +46,11 @@ namespace AzToolsFramework
}
void RemoveLink(
TemplateId sourceTemplateId, TemplateId targetTemplateId, const InstanceAlias& instanceAlias,
LinkId linkId, UndoSystem::URSequencePoint* undoBatch)
TemplateId sourceTemplateId, TemplateId targetTemplateId, const InstanceAlias& instanceAlias, LinkId linkId,
PrefabDomReference linkPatches, UndoSystem::URSequencePoint* undoBatch)
{
auto linkRemoveUndo = aznew PrefabUndoInstanceLink("Remove Link");
PrefabDom emptyLinkDom;
linkRemoveUndo->Capture(
targetTemplateId, sourceTemplateId, instanceAlias, emptyLinkDom, linkId);
linkRemoveUndo->Capture(targetTemplateId, sourceTemplateId, instanceAlias, linkPatches, linkId);
linkRemoveUndo->SetParent(undoBatch);
linkRemoveUndo->Redo();
}

@ -25,8 +25,8 @@ namespace AzToolsFramework
TemplateId sourceTemplateId, TemplateId targetTemplateId, PrefabDomReference patch,
const InstanceAlias& instanceAlias, UndoSystem::URSequencePoint* undoBatch);
void RemoveLink(
TemplateId sourceTemplateId, TemplateId targetTemplateId, const InstanceAlias& instanceAlias,
LinkId linkId, UndoSystem::URSequencePoint* undoBatch);
TemplateId sourceTemplateId, TemplateId targetTemplateId, const InstanceAlias& instanceAlias, LinkId linkId,
PrefabDomReference linkPatches, UndoSystem::URSequencePoint* undoBatch);
}
} // namespace Prefab
} // namespace AzToolsFramework

@ -70,11 +70,6 @@ set(FILES
AssetCatalog/PlatformAddressedAssetCatalog.cpp
AssetCatalog/PlatformAddressedAssetCatalogManager.h
AssetCatalog/PlatformAddressedAssetCatalogManager.cpp
MaterialBrowser/MaterialBrowserBus.h
MaterialBrowser/MaterialBrowserComponent.cpp
MaterialBrowser/MaterialBrowserComponent.h
MaterialBrowser/MaterialThumbnail.cpp
MaterialBrowser/MaterialThumbnail.h
Thumbnails/ThumbnailerComponent.cpp
Thumbnails/ThumbnailerComponent.h
Thumbnails/LoadingThumbnail.cpp

@ -365,10 +365,6 @@ bool CPreviewModelCtrl::Render()
}
_smart_ptr<IMaterial> pMaterial;
if (m_pCurrentMaterial)
{
pMaterial = m_pCurrentMaterial->GetMatInfo();
}
if (m_bPrecacheMaterial)
{
@ -430,11 +426,6 @@ bool CPreviewModelCtrl::Render()
m_pRenderer->EF_ADDDlight(&m_lights[i], passInfo);
}
if (m_pCurrentMaterial)
{
m_pCurrentMaterial->DisableHighlightForFrame();
}
if (m_bShowObject)
{
RenderObject(pMaterial, passInfo);
@ -778,32 +769,6 @@ void CPreviewModelCtrl::SetRotation(bool bEnable)
m_bRotate = bEnable;
}
void CPreviewModelCtrl::SetMaterial(CMaterial* pMaterial)
{
if (pMaterial)
{
if ((pMaterial->GetFlags() & MTL_FLAG_NOPREVIEW))
{
m_pCurrentMaterial = 0;
if (isVisible())
{
update();
}
return;
}
}
m_pCurrentMaterial = pMaterial;
if (isVisible())
{
update();
}
}
CMaterial* CPreviewModelCtrl::GetMaterial()
{
return m_pCurrentMaterial;
}
void CPreviewModelCtrl::OnEditorNotifyEvent(EEditorNotifyEvent event)
{
switch (event)

@ -22,8 +22,6 @@
#include <IStatObj.h>
#include <Editor/Material/Material.h>
#endif
struct IRenderNode;
@ -71,9 +69,6 @@ public:
int heightForWidth(int w) const override;
bool hasHeightForWidth() const override;
void SetMaterial(CMaterial* pMaterial);
CMaterial* GetMaterial();
void GetImageOffscreen(CImageEx& image, const QSize& customSize = QSize(0, 0));
void GetCameraTM(Matrix34& cameraTM);
@ -192,7 +187,6 @@ protected:
float m_tileY;
float m_tileSizeX;
float m_tileSizeY;
_smart_ptr<CMaterial> m_pCurrentMaterial;
CameraChangeCallback m_cameraChangeCallback;
void* m_pCameraChangeUserData;

@ -29,7 +29,6 @@ void RegisterReflectedVarHandlers()
EBUS_EVENT(AzToolsFramework::PropertyTypeRegistrationMessages::Bus, RegisterPropertyType, aznew AnimationPropertyWidgetHandler());
EBUS_EVENT(AzToolsFramework::PropertyTypeRegistrationMessages::Bus, RegisterPropertyType, aznew FileResourceSelectorWidgetHandler());
EBUS_EVENT(AzToolsFramework::PropertyTypeRegistrationMessages::Bus, RegisterPropertyType, aznew ShaderPropertyHandler());
EBUS_EVENT(AzToolsFramework::PropertyTypeRegistrationMessages::Bus, RegisterPropertyType, aznew MaterialPropertyHandler());
EBUS_EVENT(AzToolsFramework::PropertyTypeRegistrationMessages::Bus, RegisterPropertyType, aznew ReverbPresetPropertyHandler());
EBUS_EVENT(AzToolsFramework::PropertyTypeRegistrationMessages::Bus, RegisterPropertyType, aznew SequencePropertyHandler());
EBUS_EVENT(AzToolsFramework::PropertyTypeRegistrationMessages::Bus, RegisterPropertyType, aznew SequenceIdPropertyHandler());

@ -27,7 +27,6 @@
// Editor
#include "ShadersDialog.h"
#include "Material/MaterialManager.h"
#include "SelectLightAnimationDialog.h"
#include "SelectSequenceDialog.h"
#include "SelectEAXPresetDlg.h"
@ -88,25 +87,6 @@ void ShaderPropertyEditor::onEditClicked()
}
}
void MaterialPropertyEditor::onEditClicked()
{
}
void MaterialPropertyEditor::onButton2Clicked()
{
// Open material browser dialog.
IDataBaseItem *pItem = GetIEditor()->GetMaterialManager()->GetSelectedItem();
if (pItem)
{
QString value = pItem->GetName();
value.replace('\\', '/');
if (value.length() >= MAX_PATH)
value = value.left(MAX_PATH);
SetValue(value);
}
else
SetValue(QString());
}
void ReverbPresetPropertyEditor::onEditClicked()
{

@ -109,16 +109,6 @@ public:
void onEditClicked() override;
};
class MaterialPropertyEditor
: public GenericPopupPropertyEditor
{
public:
MaterialPropertyEditor(QWidget* pParent = nullptr)
: GenericPopupPropertyEditor(pParent, true){}
void onEditClicked() override;
void onButton2Clicked() override;
};
class ReverbPresetPropertyEditor
: public GenericPopupPropertyEditor
{
@ -179,7 +169,6 @@ public:
#define CONST_AZ_CRC(name, value) AZ::u32(value)
using ShaderPropertyHandler = GenericPopupWidgetHandler<ShaderPropertyEditor, CONST_AZ_CRC("ePropertyShader", 0xc40932f1)>;
using MaterialPropertyHandler = GenericPopupWidgetHandler<MaterialPropertyEditor, CONST_AZ_CRC("ePropertyMaterial", 0xf324dffa)>;
using ReverbPresetPropertyHandler = GenericPopupWidgetHandler<ReverbPresetPropertyEditor, CONST_AZ_CRC("ePropertyReverbPreset", 0x51469f38)>;
using MissionObjPropertyHandler = GenericPopupWidgetHandler<MissionObjPropertyEditor, CONST_AZ_CRC("ePropertyMissionObj", 0x4a2d0dc8)>;
using SequencePropertyHandler = GenericPopupWidgetHandler<SequencePropertyEditor, CONST_AZ_CRC("ePropertySequence", 0xdd1c7d44)>;

@ -111,14 +111,12 @@ private:
{
case ePropertyTexture:
case ePropertyModel:
case ePropertyMaterial:
newPath.replace("\\\\", "/");
}
switch (m_propertyType)
{
case ePropertyTexture:
case ePropertyModel:
case ePropertyMaterial:
case ePropertyFile:
if (newPath.size() > MAX_PATH)
{

@ -361,16 +361,6 @@ void ReflectedPropertyControl::CreateItems(XmlNodeRef node, CVarBlockPtr& outBlo
textureVar->Set(textureName);
}
}
else if (!azstricmp(type, "material"))
{
CSmartVariable<QString> materialVar;
AddVariable(group, materialVar, child->getTag(), humanReadableName.toUtf8().data(), strDescription.toUtf8().data(), func, pUserData, IVariable::DT_MATERIAL);
const char* materialName;
if (child->getAttr("value", &materialName))
{
materialVar->Set(materialName);
}
}
else if (!azstricmp(type, "color"))
{
CSmartVariable<Vec3> colorVar;

@ -269,7 +269,6 @@ void ReflectedPropertyItem::SetVariable(IVariable *var)
m_reflectedVarAdapter = new ReflectedVarUserAdapter;
break;
case ePropertyShader:
case ePropertyMaterial:
case ePropertyEquip:
case ePropertyReverbPreset:
case ePropertyGameToken:
@ -576,7 +575,6 @@ void ReflectedPropertyItem::SetValue(const QString& sValue, bool bRecordUndo, bo
case ePropertyTexture:
case ePropertyModel:
case ePropertyMaterial:
value.replace('\\', '/');
break;
}
@ -586,7 +584,6 @@ void ReflectedPropertyItem::SetValue(const QString& sValue, bool bRecordUndo, bo
{
case ePropertyTexture:
case ePropertyModel:
case ePropertyMaterial:
case ePropertyFile:
if (value.length() >= MAX_PATH)
{

@ -286,8 +286,6 @@ AZ::u32 CReflectedVarGenericProperty::handler()
{
case ePropertyShader:
return AZ_CRC("ePropertyShader", 0xc40932f1);
case ePropertyMaterial:
return AZ_CRC("ePropertyMaterial", 0xf324dffa);
case ePropertyEquip:
return AZ_CRC("ePropertyEquip", 0x66ffd290);
case ePropertyReverbPreset:

@ -455,8 +455,6 @@ void ReflectedVarGenericPropertyAdapter::SyncReflectedVarToIVar(IVariable *pVari
{
QString value;
pVariable->Get(value);
if (m_reflectedVar->m_propertyType == ePropertyMaterial)
value.replace('\\', '/');
m_reflectedVar->m_value = value.toUtf8().data();
}

@ -23,7 +23,6 @@
#include "Objects/SelectionGroup.h"
#include "ViewManager.h"
#include <AzFramework/API/AtomActiveInterface.h>
#include <AzCore/Interface/Interface.h>
// Qt

@ -102,7 +102,6 @@ AZ_POP_DISABLE_WARNING
#include "ModelViewport.h"
#include "FileTypeUtils.h"
#include "PluginManager.h"
#include "Material/MaterialManager.h"
#include "IEditorImpl.h"
#include "StartupLogoDialog.h"
@ -157,9 +156,6 @@ AZ_POP_DISABLE_WARNING
#include "Plugins/ComponentEntityEditorPlugin/Objects/ComponentEntityObject.h"
// LmbrCentral
#include <LmbrCentral/Rendering/MeshComponentBus.h>
// AWSNativeSDK
#include <AzToolsFramework/Undo/UndoSystem.h>
#include <AWSNativeSDKInit/AWSNativeSDKInit.h>
@ -459,9 +455,6 @@ void CCryEditApp::RegisterActionHandlers()
ON_COMMAND(ID_CHANGEMOVESPEED_INCREASE, OnChangemovespeedIncrease)
ON_COMMAND(ID_CHANGEMOVESPEED_DECREASE, OnChangemovespeedDecrease)
ON_COMMAND(ID_CHANGEMOVESPEED_CHANGESTEP, OnChangemovespeedChangestep)
ON_COMMAND(ID_MATERIAL_ASSIGNCURRENT, OnMaterialAssigncurrent)
ON_COMMAND(ID_MATERIAL_RESETTODEFAULT, OnMaterialResettodefault)
ON_COMMAND(ID_MATERIAL_GETMATERIAL, OnMaterialGetmaterial)
ON_COMMAND(ID_FILE_SAVELEVELRESOURCES, OnFileSavelevelresources)
ON_COMMAND(ID_CLEAR_REGISTRY, OnClearRegistryData)
ON_COMMAND(ID_VALIDATELEVEL, OnValidatelevel)
@ -4180,25 +4173,6 @@ void CCryEditApp::OnSwitchcameraNext()
}
}
//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnMaterialAssigncurrent()
{
CUndo undo("Assign Material To Selection");
GetIEditor()->GetMaterialManager()->Command_AssignToSelection();
}
//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnMaterialResettodefault()
{
GetIEditor()->GetMaterialManager()->Command_ResetSelection();
}
//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnMaterialGetmaterial()
{
GetIEditor()->GetMaterialManager()->Command_SelectFromObject();
}
//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnOpenAssetBrowserView()
{

@ -417,9 +417,6 @@ private:
void OnChangemovespeedIncrease();
void OnChangemovespeedDecrease();
void OnChangemovespeedChangestep();
void OnMaterialAssigncurrent();
void OnMaterialResettodefault();
void OnMaterialGetmaterial();
void OnFileSavelevelresources();
void OnClearRegistryData();
void OnValidatelevel();

@ -27,7 +27,6 @@
// AzFramework
#include <AzFramework/Archive/IArchive.h>
#include <AzFramework/API/ApplicationAPI.h>
#include <AzFramework/API/AtomActiveInterface.h>
// AzToolsFramework
#include <AzToolsFramework/Slice/SliceUtilities.h>
@ -51,7 +50,6 @@
#include "CryEdit.h"
#include "ActionManager.h"
#include "Include/IObjectManager.h"
#include "Material/MaterialManager.h"
#include "ErrorReportDialog.h"
#include "SurfaceTypeValidator.h"
#include "ShaderCache.h"
@ -64,6 +62,9 @@
#include "StatObjBus.h"
// LmbrCentral
#include <ModernViewportCameraController.h>
#include <Atom/RPI.Public/ViewportContext.h>
#include <Atom/RPI.Public/ViewportContextBus.h>
#include <LmbrCentral/Rendering/EditorLightComponentBus.h> // for LmbrCentral::EditorLightComponentRequestBus
@ -357,8 +358,6 @@ void CCryEditDoc::Save(TDocMultiArchive& arrXmlAr)
SerializeFogSettings((*arrXmlAr[DMAS_GENERAL]));
// Serialize Missions //////////////////////////////////////////////////
SerializeMissions(arrXmlAr, currentMissionName, false);
//! Serialize material manager.
GetIEditor()->GetMaterialManager()->Serialize((*arrXmlAr[DMAS_GENERAL]).root, (*arrXmlAr[DMAS_GENERAL]).bLoading);
SerializeShaderCache((*arrXmlAr[DMAS_GENERAL_NAMED_DATA]));
SerializeNameSelection((*arrXmlAr[DMAS_GENERAL]));
@ -513,14 +512,6 @@ void CCryEditDoc::Load(TDocMultiArchive& arrXmlAr, const QString& szFilename)
//////////////////////////////////////////////////////////////////////////
(*arrXmlAr[DMAS_GENERAL]).root->getAttr("WaterColor", m_waterColor);
//////////////////////////////////////////////////////////////////////////
// Load materials.
//////////////////////////////////////////////////////////////////////////
{
CAutoLogTime logtime("Load MaterialManager");
GetIEditor()->GetMaterialManager()->Serialize((*arrXmlAr[DMAS_GENERAL]).root, (*arrXmlAr[DMAS_GENERAL]).bLoading);
}
//////////////////////////////////////////////////////////////////////////
// Load View Settings
//////////////////////////////////////////////////////////////////////////
@ -658,6 +649,7 @@ void CCryEditDoc::SerializeViewSettings(CXmlArchive& xmlAr)
CViewport* pVP = GetIEditor()->GetViewManager()->GetView(i);
if (pVP)
{
Matrix34 tm = Matrix34::CreateRotationXYZ(va);
@ -2415,44 +2407,9 @@ void CCryEditDoc::InitEmptyLevel(int /*resolution*/, int /*unitSize*/, bool /*bU
GetIEditor()->SetStatusText("Ready");
}
void CCryEditDoc::CreateDefaultLevelAssets(int resolution, int unitSize)
void CCryEditDoc::CreateDefaultLevelAssets([[maybe_unused]] int resolution, [[maybe_unused]] int unitSize)
{
if (AZ::Interface<AzFramework::AtomActiveInterface>::Get())
{
AzToolsFramework::EditorLevelNotificationBus::Broadcast(&AzToolsFramework::EditorLevelNotificationBus::Events::OnNewLevelCreated);
}
else
{
bool isPrefabSystemEnabled = false;
AzFramework::ApplicationRequests::Bus::BroadcastResult(
isPrefabSystemEnabled, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
if (!isPrefabSystemEnabled)
{
AZ::Data::AssetCatalogRequestBus::BroadcastResult(
m_envProbeSliceAssetId, &AZ::Data::AssetCatalogRequests::GetAssetIdByPath, m_envProbeSliceRelativePath,
azrtti_typeid<AZ::SliceAsset>(), false);
if (m_envProbeSliceAssetId.IsValid())
{
AZ::Data::Asset<AZ::Data::AssetData> asset = AZ::Data::AssetManager::Instance().FindOrCreateAsset<AZ::SliceAsset>(
m_envProbeSliceAssetId, AZ::Data::AssetLoadBehavior::Default);
if (asset)
{
m_terrainSize = resolution * unitSize;
const float halfTerrainSize = m_terrainSize / 2.0f;
AZ::Transform worldTransform = AZ::Transform::CreateIdentity();
worldTransform = AZ::Transform::CreateTranslation(AZ::Vector3(halfTerrainSize, halfTerrainSize, m_envProbeHeight / 2));
AzToolsFramework::SliceEditorEntityOwnershipServiceNotificationBus::Handler::BusConnect();
GetIEditor()->SuspendUndo();
AzToolsFramework::SliceEditorEntityOwnershipServiceRequestBus::Broadcast(
&AzToolsFramework::SliceEditorEntityOwnershipServiceRequests::InstantiateEditorSlice, asset, worldTransform);
}
}
}
}
AzToolsFramework::EditorLevelNotificationBus::Broadcast(&AzToolsFramework::EditorLevelNotificationBus::Events::OnNewLevelCreated);
}
void CCryEditDoc::OnEnvironmentPropertyChanged(IVariable* pVar)

@ -22,7 +22,6 @@
// Editor
#include "Settings.h"
#include "Material/MaterialManager.h"
@ -112,30 +111,6 @@ void CDisplaySettings::SetDebugFlags(int flags)
//SetCVarInt( "sys_enable_budgetmonitoring",(m_debugFlags&DBG_BUDGET_MONITORING) ? 4:0 );
//SetCVarInt( "Profile",(m_debugFlags&DBG_FRAMEPROFILE) ? 1:0 );
if (CMaterialManager* pMaterialManager = GetIEditor()->GetMaterialManager())
{
int mask = pMaterialManager->GetHighlightMask();
if (m_debugFlags & DBG_HIGHLIGHT_BREAKABLE)
{
mask |= eHighlight_Breakable;
}
else
{
mask &= ~eHighlight_Breakable;
}
if (m_debugFlags & DBG_HIGHLIGHT_MISSING_SURFACE_TYPE)
{
mask |= eHighlight_NoSurfaceType;
}
else
{
mask &= ~eHighlight_NoSurfaceType;
}
pMaterialManager->SetHighlightMask(mask);
}
}
//////////////////////////////////////////////////////////////////////////

@ -21,14 +21,12 @@
#include <AzToolsFramework/UI/UICore/WidgetHelpers.h>
#include <AzToolsFramework/Thumbnails/ThumbnailerComponent.h>
#include <AzToolsFramework/AssetBrowser/AssetBrowserComponent.h>
#include <AzToolsFramework/MaterialBrowser/MaterialBrowserComponent.h>
// Editor
#include "MainWindow.h"
#include "CryEdit.h"
#include "DisplaySettingsPythonFuncs.h"
#include "GameEngine.h"
#include "Material/MaterialPythonFuncs.h"
#include "PythonEditorFuncs.h"
#include "TrackView/TrackViewPythonFuncs.h"
#include "Include/IObjectManager.h"
@ -65,7 +63,6 @@ namespace EditorInternal
RegisterComponentDescriptor(AzToolsFramework::DisplaySettingsPythonFuncsHandler::CreateDescriptor());
RegisterComponentDescriptor(AzToolsFramework::MainWindowEditorFuncsHandler::CreateDescriptor());
RegisterComponentDescriptor(AzToolsFramework::ObjectManagerFuncsHandler::CreateDescriptor());
RegisterComponentDescriptor(AzToolsFramework::MaterialPythonFuncsHandler::CreateDescriptor());
RegisterComponentDescriptor(AzToolsFramework::PythonEditorComponent::CreateDescriptor());
RegisterComponentDescriptor(AzToolsFramework::PythonEditorFuncsHandler::CreateDescriptor());
RegisterComponentDescriptor(AzToolsFramework::DisplaySettingsComponent::CreateDescriptor());
@ -81,7 +78,6 @@ namespace EditorInternal
components.emplace_back(azrtti_typeid<AzToolsFramework::Thumbnailer::ThumbnailerComponent>());
components.emplace_back(azrtti_typeid<AzToolsFramework::AssetBrowser::AssetBrowserComponent>());
components.emplace_back(azrtti_typeid<AzToolsFramework::MaterialBrowser::MaterialBrowserComponent>());
// Add new Bus-based Python Bindings
components.emplace_back(azrtti_typeid<AzToolsFramework::DisplaySettingsComponent>());

@ -40,7 +40,6 @@
# include <AzFramework/Input/Buses/Notifications/RawInputNotificationBus_Platform.h>
#endif // defined(AZ_PLATFORM_WINDOWS)
#include <AzFramework/Input/Devices/Mouse/InputDeviceMouse.h> // for AzFramework::InputDeviceMouse
#include <AzFramework/API/AtomActiveInterface.h>
#include <AzFramework/Viewport/ViewportControllerList.h>
// AzQtComponents
@ -1234,6 +1233,7 @@ void EditorViewportWidget::SetViewportId(int id)
if (ed_useNewCameraSystem)
{
AzFramework::ReloadCameraKeyBindings();
m_renderViewport->GetControllerList()->Add(AZStd::make_shared<SandboxEditor::ModernViewportCameraController>());
}
else
@ -1626,8 +1626,8 @@ void EditorViewportWidget::keyPressEvent(QKeyEvent* event)
QCoreApplication::sendEvent(GetIEditor()->GetEditorMainWindow(), event);
}
// NOTE: we keep track of keypresses and releases explicitly because the OS/Qt will insert a slight delay between sending
// keyevents when the key is held down. This is standard, but makes responding to key events for game style input silly
// NOTE: we keep track of key presses and releases explicitly because the OS/Qt will insert a slight delay between sending
// key events when the key is held down. This is standard, but makes responding to key events for game style input silly
// because we want the movement to be butter smooth.
if (!event->isAutoRepeat())
{

@ -19,7 +19,6 @@
#pragma once
// forward declarations.
class CMaterial;
class CParticleItem;
#include "BaseLibraryItem.h"

@ -23,7 +23,6 @@
// Editor
#include "Geometry/EdGeometry.h"
#include "Material/Material.h"
#include "ViewManager.h"
#include "OBJExporter.h"
#include "OCMExporter.h"
@ -79,47 +78,6 @@ Export::CMesh::CMesh()
}
void Export::CMesh::SetMaterial(CMaterial* pMtl, CBaseObject* pBaseObj)
{
if (!pMtl)
{
cry_strcpy(material.name, pBaseObj->GetName().toUtf8().data());
return;
}
cry_strcpy(material.name, pMtl->GetFullName().toUtf8().data());
_smart_ptr<IMaterial> matInfo = pMtl->GetMatInfo();
IRenderShaderResources* pRes = matInfo->GetShaderItem().m_pShaderResources;
if (!pRes)
{
return;
}
ColorF difColor = pRes->GetColorValue(EFTT_DIFFUSE);
material.diffuse.r = difColor.r;
material.diffuse.g = difColor.g;
material.diffuse.b = difColor.b;
material.diffuse.a = difColor.a;
ColorF specColor = pRes->GetColorValue(EFTT_SPECULAR);
material.specular.r = specColor.r;
material.specular.g = specColor.g;
material.specular.b = specColor.b;
material.specular.a = specColor.a;
material.opacity = pRes->GetStrengthValue(EFTT_OPACITY);
material.smoothness = pRes->GetStrengthValue(EFTT_SMOOTHNESS);
SetTexture(material.mapDiffuse, pRes, EFTT_DIFFUSE);
SetTexture(material.mapSpecular, pRes, EFTT_SPECULAR);
SetTexture(material.mapOpacity, pRes, EFTT_OPACITY);
SetTexture(material.mapNormals, pRes, EFTT_NORMALS);
SetTexture(material.mapDecal, pRes, EFTT_DECAL_OVERLAY);
SetTexture(material.mapDisplacement, pRes, EFTT_HEIGHT);
}
//////////////////////////////////////////////////////////
// CObject
Export::CObject::CObject(const char* pName)
@ -416,18 +374,6 @@ void CExportManager::AddMesh(Export::CObject* pObj, const IIndexedMesh* pIndMesh
pObj->m_texCoords.push_back(tc);
}
CMaterial* pMtl = 0;
if (m_pBaseObj)
{
pMtl = m_pBaseObj->GetRenderMaterial();
}
if (pMtl)
{
pObj->SetMaterialName(pMtl->GetFullName().toUtf8().data());
}
if (pIndMesh->GetSubSetCount() && !(pIndMesh->GetSubSetCount() == 1 && pIndMesh->GetSubSet(0).nNumIndices == 0))
{
for (int i = 0; i < pIndMesh->GetSubSetCount(); ++i)
@ -447,23 +393,6 @@ void CExportManager::AddMesh(Export::CObject* pObj, const IIndexedMesh* pIndMesh
pMesh->m_faces.push_back(face);
}
if (pMtl)
{
if (pMtl->IsMultiSubMaterial())
{
CMaterial* pSubMtl = 0;
if (sms.nMatID < pMtl->GetSubMaterialCount())
{
pSubMtl = pMtl->GetSubMaterial(sms.nMatID);
}
pMesh->SetMaterial(pSubMtl, m_pBaseObj);
}
else
{
pMesh->SetMaterial(pMtl, m_pBaseObj);
}
}
pObj->m_meshes.push_back(pMesh);
}
}
@ -497,10 +426,6 @@ void CExportManager::AddMesh(Export::CObject* pObj, const IIndexedMesh* pIndMesh
}
}
if (m_pBaseObj && pMtl)
{
pMesh->SetMaterial(pMtl, m_pBaseObj);
}
pObj->m_meshes.push_back(pMesh);
}
}

@ -43,8 +43,6 @@ namespace Export
virtual int GetFaceCount() const { return m_faces.size(); }
virtual const Face* GetFaceBuffer() const { return m_faces.size() ? &m_faces[0] : 0; }
void SetMaterial(CMaterial* pMtl, CBaseObject* pBaseObj);
private:
std::vector<Face> m_faces;

@ -27,8 +27,6 @@
#include "Mission.h"
#include "ShaderCache.h"
#include "UsedResources.h"
#include "Material/MaterialManager.h"
#include "Material/MaterialLibrary.h"
#include "WaitProgress.h"
#include "Util/CryMemFile.h"
#include "Objects/ObjectManager.h"
@ -336,11 +334,6 @@ void CGameExporter::ExportLevelData(const QString& path, bool bExportMission)
ExportMapInfo(root);
//////////////////////////////////////////////////////////////////////////
// Export materials.
ExportMaterials(root, path);
//////////////////////////////////////////////////////////////////////////
CCryEditDoc* pDocument = pEditor->GetDocument();
CMission* pCurrentMission = 0;
@ -508,48 +501,6 @@ void CGameExporter::ExportMapInfo(XmlNodeRef& node)
xmlAr.root = node;
}
//////////////////////////////////////////////////////////////////////////
void CGameExporter::ExportMaterials(XmlNodeRef& levelDataNode, const QString& path)
{
//////////////////////////////////////////////////////////////////////////
// Export materials manager.
CMaterialManager* pManager = GetIEditor()->GetMaterialManager();
pManager->Export(levelDataNode);
QString filename = Path::Make(path, MATERIAL_LEVEL_LIBRARY_FILE);
bool bHaveItems = true;
int numMtls = 0;
XmlNodeRef nodeMaterials = XmlHelpers::CreateXmlNode("MaterialsLibrary");
// Export Materials local level library.
for (int i = 0; i < pManager->GetLibraryCount(); i++)
{
XmlNodeRef nodeLib = nodeMaterials->newChild("Library");
CMaterialLibrary* pLib = (CMaterialLibrary*)pManager->GetLibrary(i);
if (pLib->GetItemCount() > 0)
{
bHaveItems = false;
// Export this library.
numMtls += pManager->ExportLib(pLib, nodeLib);
}
}
if (!bHaveItems)
{
XmlString xmlData = nodeMaterials->getXML();
CCryMemFile file;
file.Write(xmlData.c_str(), xmlData.length());
m_levelPak.m_pakFile.UpdateFile(filename.toUtf8().data(), file);
}
else
{
m_levelPak.m_pakFile.RemoveFile(filename.toUtf8().data());
}
m_numExportedMaterials = numMtls;
}
//////////////////////////////////////////////////////////////////////////
void CGameExporter::ExportLevelResourceList(const QString& path)
{

@ -98,7 +98,6 @@ private:
void ExportLevelResourceList(const QString& path);
void ExportLevelUsedResourceList(const QString& path);
void ExportLevelShaderCache(const QString& path);
void ExportMaterials(XmlNodeRef& levelDataNode, const QString& path);
void ExportGameData(const QString& path);
void ExportFileList(const QString& path, const QString& levelName);

@ -21,7 +21,6 @@
// Editor
#include "UsedResources.h"
#include "GameEngine.h"
#include "Material/MaterialManager.h"
#include "Include/IObjectManager.h"
#include "WaitProgress.h"
@ -51,7 +50,7 @@ void CGameResourcesExporter::ChooseDirectory()
void CGameResourcesExporter::GatherAllLoadedResources()
{
m_files.clear();
m_files.reserve(100000); // count from GetResourceList, GetFilesFromObjects, GetFilesFromMaterials ... is unknown
m_files.reserve(100000); // count from GetResourceList, GetFilesFromObjects ... is unknown
auto pResList = gEnv->pCryPak->GetResourceList(AZ::IO::IArchive::RFOM_Level);
{
@ -62,7 +61,6 @@ void CGameResourcesExporter::GatherAllLoadedResources()
}
GetFilesFromObjects();
GetFilesFromMaterials();
}
//////////////////////////////////////////////////////////////////////////
@ -158,12 +156,3 @@ void CGameResourcesExporter::GetFilesFromObjects()
Append(m_files, rs.files);
}
//////////////////////////////////////////////////////////////////////////
void CGameResourcesExporter::GetFilesFromMaterials()
{
CUsedResources rs;
GetIEditor()->GetMaterialManager()->GatherUsedResources(rs);
Append(m_files, rs.files);
}

@ -44,7 +44,6 @@ private:
void GetFilesFromObjects();
void GetFilesFromVarBlock(CVarBlock* pVB);
void GetFilesFromVariable(IVariable* pVar);
void GetFilesFromMaterials();
};
#endif // CRYINCLUDE_EDITOR_GAMERESOURCESEXPORTER_H

@ -46,9 +46,7 @@ class CGameEngine;
struct IIconManager;
class CToolBoxManager;
class CClassFactory;
class CMaterialManager;
class CMusicManager;
class CMaterail;
struct IEditorParticleManager;
class CEAXPresetManager;
class CErrorReport;
@ -544,8 +542,6 @@ struct IEditor
virtual CSettingsManager* GetSettingsManager() = 0;
//! Get DB manager that own items of specified type.
virtual IDataBaseManager* GetDBItemManager(EDataBaseItemType itemType) = 0;
//! Get Manager of Materials.
virtual CMaterialManager* GetMaterialManager() = 0;
virtual IBaseLibraryManager* GetMaterialManagerLibrary() = 0; // Vladimir@conffx
virtual IEditorMaterialManager* GetIEditorMaterialManager() = 0; // Vladimir@Conffx
//! Returns IconManager.

@ -53,7 +53,6 @@ AZ_POP_DISABLE_WARNING
#include "KeyboardCustomizationSettings.h"
#include "Export/ExportManager.h"
#include "LevelIndependentFileMan.h"
#include "Material/MaterialManager.h"
#include "TrackView/TrackViewSequenceManager.h"
#include "AnimationContext.h"
#include "GameEngine.h"
@ -167,7 +166,6 @@ CEditorImpl::CEditorImpl()
, m_pAnimationContext(nullptr)
, m_pSequenceManager(nullptr)
, m_pToolBoxManager(nullptr)
, m_pMaterialManager(nullptr)
, m_pMusicManager(nullptr)
, m_pErrorReport(nullptr)
, m_pLasLoadedLevelErrorReport(nullptr)
@ -222,7 +220,6 @@ CEditorImpl::CEditorImpl()
m_pIconManager = new CIconManager;
m_pUndoManager = new CUndoManager;
m_pToolBoxManager = new CToolBoxManager;
m_pMaterialManager = new CMaterialManager(regCtx);
m_pAlembicCompiler = new CAlembicCompiler();
m_pSequenceManager = new CTrackViewSequenceManager;
m_pAnimationContext = new CAnimationContext;
@ -342,7 +339,6 @@ CEditorImpl::~CEditorImpl()
m_bExiting = true; // Can't save level after this point (while Crash)
SAFE_RELEASE(m_pSourceControl);
SAFE_DELETE(m_pMaterialManager)
SAFE_DELETE(m_pAlembicCompiler)
SAFE_DELETE(m_pIconManager)
SAFE_DELETE(m_pViewManager)
@ -412,7 +408,6 @@ void CEditorImpl::SetGameEngine(CGameEngine* ge)
m_pObjectManager->LoadClassTemplates("Editor");
m_pObjectManager->RegisterCVars();
m_pMaterialManager->Set3DEngine();
m_pAnimationContext->Init();
}
@ -1000,13 +995,8 @@ void CEditorImpl::CloseView(const GUID& classId)
}
}
IDataBaseManager* CEditorImpl::GetDBItemManager(EDataBaseItemType itemType)
IDataBaseManager* CEditorImpl::GetDBItemManager([[maybe_unused]] EDataBaseItemType itemType)
{
switch (itemType)
{
case EDB_TYPE_MATERIAL:
return m_pMaterialManager;
}
return 0;
}
@ -1772,13 +1762,13 @@ SEditorSettings* CEditorImpl::GetEditorSettings()
// Vladimir@Conffx
IBaseLibraryManager* CEditorImpl::GetMaterialManagerLibrary()
{
return m_pMaterialManager;
return nullptr;
}
// Vladimir@Conffx
IEditorMaterialManager* CEditorImpl::GetIEditorMaterialManager()
{
return m_pMaterialManager;
return nullptr;
}
IImageUtil* CEditorImpl::GetImageUtil()

@ -180,7 +180,6 @@ public:
bool IsSelectionLocked();
IDataBaseManager* GetDBItemManager(EDataBaseItemType itemType);
CMaterialManager* GetMaterialManager() { return m_pMaterialManager; }
CMusicManager* GetMusicManager() { return m_pMusicManager; };
IBackgroundTaskManager* GetBackgroundTaskManager() override;
@ -379,7 +378,6 @@ protected:
CAnimationContext* m_pAnimationContext;
CTrackViewSequenceManager* m_pSequenceManager;
CToolBoxManager* m_pToolBoxManager;
CMaterialManager* m_pMaterialManager;
CAlembicCompiler* m_pAlembicCompiler;
CMusicManager* m_pMusicManager;
CErrorReport* m_pErrorReport;

@ -15,7 +15,6 @@
#include "IconManager.h"
#include <AzFramework/API/AtomActiveInterface.h>
#include <AzCore/Interface/Interface.h>
// AzToolsFramework
@ -115,71 +114,6 @@ int CIconManager::GetIconTexture(const char* iconName)
return 0;
}
if (AZ::Interface<AzFramework::AtomActiveInterface>::Get())
{
ITexture* texture = GetIEditor()->GetRenderer() ? GetIEditor()->GetRenderer()->EF_LoadTexture(iconName) : nullptr;
if (texture)
{
id = texture->GetTextureID();
m_textures[iconName] = id;
}
}
else
{
QString ext = Path::GetExt(iconName);
QString actualName = iconName;
char iconPath[AZ_MAX_PATH_LEN] = { 0 };
gEnv->pFileIO->ResolvePath(actualName.toUtf8().data(), iconPath, AZ_MAX_PATH_LEN);
// if we can't find it at the resolved path, try the devroot if necessary:
if (!gEnv->pFileIO->Exists(iconPath))
{
if (iconName[0] != '@') // it has no specified alias
{
if (QString::compare(ext, "dds", Qt::CaseInsensitive) != 0) // if its a DDS, it comes out of processed files in @assets@, and assets is assumed by default (legacy renderer)
{
// check for a source file
AZStd::string iconFullPath;
bool pathFound = false;
using AssetSysReqBus = AzToolsFramework::AssetSystemRequestBus;
AssetSysReqBus::BroadcastResult(pathFound, &AssetSysReqBus::Events::GetFullSourcePathFromRelativeProductPath, iconName, iconFullPath);
if (pathFound)
{
azstrncpy(iconPath, AZ_MAX_PATH_LEN, iconFullPath.c_str(), iconFullPath.length() + 1);
}
}
}
}
CImageEx image;
// Load icon.
if (CImageUtil::LoadImage(iconPath, image))
{
IRenderer* pRenderer(GetIEditor()->GetRenderer());
if (pRenderer->GetRenderType() != eRT_DX11)
{
image.SwapRedAndBlue();
}
if (QString::compare(ext, "bmp", Qt::CaseInsensitive) == 0 || QString::compare(ext, "jpg", Qt::CaseInsensitive) == 0)
{
int sz = image.GetWidth() * image.GetHeight();
uint8* buf = (uint8*)image.GetData();
for (int i = 0; i < sz; i++)
{
uint32 alpha = max(max(buf[i * 4], buf[i * 4 + 1]), buf[i * 4 + 2]);
alpha *= 2;
buf[i * 4 + 3] = (alpha > 255) ? 255 : alpha;
}
}
id = pRenderer->DownLoadToVideoMemory((unsigned char*)image.GetData(), image.GetWidth(), image.GetHeight(), eTF_R8G8B8A8, eTF_R8G8B8A8, 0, 0, 0);
m_textures[iconName] = id;
}
}
return id;
}

@ -21,7 +21,6 @@
#include <IValidator.h>
// forward declarations.
class CMaterial;
class CParticleItem;
class CBaseObject;
class CBaseLibraryItem;

@ -24,7 +24,6 @@
#include <QTextDocumentFragment>
#include <AzCore/Interface/Interface.h>
#include <AzFramework/API/AtomActiveInterface.h>
#include <AzQtComponents/Components/Style.h> // for AzQtComponents::Style
// Editor

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

Loading…
Cancel
Save