Merge branch 'development' of https://github.com/o3de/o3de into TerrainMaterialsFix
This commit is contained in:
@@ -20,9 +20,14 @@ TEST_DIRECTORY = os.path.join(os.path.dirname(__file__), "tests")
|
||||
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
|
||||
class TestAutomation(EditorTestSuite):
|
||||
|
||||
enable_prefab_system = False
|
||||
enable_prefab_system = True
|
||||
|
||||
# this test is intermittently timing out without ever having executed. sandboxing while we investigate cause.
|
||||
@pytest.mark.test_case_id("C36525660")
|
||||
class AtomEditorComponents_DisplayMapperAdded(EditorSharedTest):
|
||||
from Atom.tests import hydra_AtomEditorComponents_DisplayMapperAdded as test_module
|
||||
|
||||
# The "Sponza" level is failing with a hard lock 4-12% of the time, needs root causing and fixing.
|
||||
@pytest.mark.test_case_id("C36529679")
|
||||
class AtomLevelLoadTest_Editor_Sandbox(EditorSharedTest):
|
||||
from Atom.tests import hydra_Atom_LevelLoadTest_Sandbox as test_module
|
||||
|
||||
@@ -33,7 +33,9 @@ GLOBAL_ILLUMINATION_QUALITY = {
|
||||
}
|
||||
|
||||
# Level list used in Editor Level Load Test
|
||||
LEVEL_LIST = ["hermanubis", "hermanubis_high", "macbeth_shaderballs", "PbrMaterialChart", "ShadowTest", "Sponza"]
|
||||
# WARNING: "Sponza" level is sandboxed due to an intermittent failure.
|
||||
LEVEL_LIST = ["hermanubis", "hermanubis_high", "macbeth_shaderballs", "PbrMaterialChart", "ShadowTest"]
|
||||
|
||||
|
||||
class AtomComponentProperties:
|
||||
"""
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
"""
|
||||
Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
|
||||
def Atom_LevelLoadTest():
|
||||
"""
|
||||
Summary:
|
||||
Loads all graphics levels within the AutomatedTesting project in editor. For each level this script will verify that
|
||||
the level loads, and can enter/exit gameplay without crashing the editor.
|
||||
|
||||
Test setup:
|
||||
- Store all available levels in a list.
|
||||
- Set up a for loop to run all checks for each level.
|
||||
|
||||
Expected Behavior:
|
||||
Test verifies that each level loads, enters/exits game mode, and reports success for all test actions.
|
||||
|
||||
Test Steps for each level:
|
||||
1) Create tuple with level load success and failure messages
|
||||
2) Open the level using the python test tools command
|
||||
3) Verify level is loaded using a separate command, and report success/failure
|
||||
4) Enter gameplay and report result using a tuple
|
||||
5) Exit Gameplay and report result using a tuple
|
||||
6) Look for errors or asserts.
|
||||
|
||||
:return: None
|
||||
"""
|
||||
SANDBOX_LEVEL_LIST = ["Sponza"]
|
||||
|
||||
import azlmbr.legacy.general as general
|
||||
|
||||
from editor_python_test_tools.utils import Report, Tracer, TestHelper
|
||||
|
||||
with Tracer() as error_tracer:
|
||||
|
||||
for level in SANDBOX_LEVEL_LIST:
|
||||
|
||||
# 1. Create tuple with level load success and failure messages
|
||||
level_check_tuple = (f"loaded {level}", f"failed to load {level}")
|
||||
|
||||
# 2. Open the level using the python test tools command
|
||||
TestHelper.init_idle()
|
||||
TestHelper.open_level("Graphics", level)
|
||||
|
||||
# 3. Verify level is loaded using a separate command, and report success/failure
|
||||
Report.result(level_check_tuple, level == general.get_current_level_name())
|
||||
|
||||
# 4. Enter gameplay and report result using a tuple
|
||||
enter_game_mode_tuple = (f"{level} entered gameplay successfully ", f"{level} failed to enter gameplay")
|
||||
TestHelper.enter_game_mode(enter_game_mode_tuple)
|
||||
general.idle_wait_frames(1)
|
||||
|
||||
# 5. Exit gameplay and report result using a tuple
|
||||
exit_game_mode_tuple = (f"{level} exited gameplay successfully ", f"{level} failed to exit gameplay")
|
||||
TestHelper.exit_game_mode(exit_game_mode_tuple)
|
||||
|
||||
# 6. Look for errors or asserts.
|
||||
TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0)
|
||||
for error_info in error_tracer.errors:
|
||||
Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}")
|
||||
for assert_info in error_tracer.asserts:
|
||||
Report.info(f"Assert: {assert_info.filename} {assert_info.function} | {assert_info.message}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(Atom_LevelLoadTest)
|
||||
@@ -54,7 +54,7 @@ class EditorSingleTest_WithFileOverrides(EditorSingleTest):
|
||||
fm._restore_file(f, file_list[f])
|
||||
|
||||
|
||||
# @pytest.mark.xfail(reason="Optimized tests are experimental, we will enable xfail and monitor them temporarily.")
|
||||
@pytest.mark.xfail(reason="Optimized tests are experimental, we will enable xfail and monitor them temporarily.")
|
||||
@pytest.mark.SUITE_main
|
||||
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
|
||||
@pytest.mark.parametrize("project", ["AutomatedTesting"])
|
||||
@@ -113,6 +113,9 @@ class TestAutomationWithPrefabSystemEnabled(EditorTestSuite):
|
||||
|
||||
class C14861504_RenderMeshAsset_WithNoPxAsset(EditorSharedTest):
|
||||
from .tests.collider import Collider_PxMeshNotAutoAssignedWhenNoPhysicsFbx as test_module
|
||||
|
||||
class C4976236_AddPhysxColliderComponent(EditorSharedTest):
|
||||
from .tests.collider import Collider_AddColliderComponent as test_module
|
||||
|
||||
|
||||
@pytest.mark.xfail(reason="Optimized tests are experimental, we will enable xfail and monitor them temporarily.")
|
||||
@@ -346,9 +349,6 @@ class TestAutomation(EditorTestSuite):
|
||||
class C5959809_ForceRegion_RotationalOffset(EditorSharedTest):
|
||||
from .tests.force_region import ForceRegion_RotationalOffset as test_module
|
||||
|
||||
class C4976236_AddPhysxColliderComponent(EditorSharedTest):
|
||||
from .tests.collider import Collider_AddColliderComponent as test_module
|
||||
|
||||
class C100000_RigidBody_EnablingGravityWorksPoC(EditorSharedTest):
|
||||
from .tests.rigid_body import RigidBody_EnablingGravityWorksPoC as test_module
|
||||
|
||||
|
||||
@@ -440,13 +440,9 @@ class TestAutomation(TestAutomationBase):
|
||||
from .tests.material import Material_LibraryClearingAssignsDefault as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
|
||||
@pytest.mark.xfail(reason=
|
||||
"Test failed due to an error message shown while in game mode: "
|
||||
"'(Prefab) - Invalid asset found referenced in scene while entering game mode. "
|
||||
"The asset was stored in an instance of Asset.'")
|
||||
def test_Collider_AddColliderComponent(self, request, workspace, editor, launcher_platform):
|
||||
from .tests.collider import Collider_AddColliderComponent as test_module
|
||||
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
|
||||
@pytest.mark.xfail(
|
||||
reason="This will fail due to this issue ATOM-15487.")
|
||||
|
||||
+3
-2
@@ -49,9 +49,10 @@ def Collider_AddColliderComponent():
|
||||
from editor_python_test_tools.utils import Tracer
|
||||
from editor_python_test_tools.asset_utils import Asset
|
||||
|
||||
helper.init_idle()
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
|
||||
# 1) Load the level
|
||||
helper.open_level("Physics", "Base")
|
||||
hydra.open_base_level()
|
||||
|
||||
# 2) Create test entity
|
||||
test_entity = EditorEntity.create_editor_entity("TestEntity")
|
||||
|
||||
@@ -49,9 +49,11 @@ class TestAutomationBase:
|
||||
time_info_str += f"{testcase_name}: (Full:{t} sec, Editor:{editor_t} sec)\n"
|
||||
|
||||
logger.info(time_info_str)
|
||||
if cls.asset_processor is not None:
|
||||
cls.asset_processor.teardown()
|
||||
|
||||
# Kill all ly processes
|
||||
cls.asset_processor.teardown()
|
||||
cls._kill_ly_processes()
|
||||
cls._kill_ly_processes(include_asset_processor=True)
|
||||
|
||||
def _run_test(self, request, workspace, editor, testcase_module, extra_cmdline_args=[], batch_mode=True,
|
||||
autotest_mode=True, use_null_renderer=True, enable_prefab_system=True):
|
||||
@@ -62,14 +64,16 @@ class TestAutomationBase:
|
||||
|
||||
#########
|
||||
# Setup #
|
||||
|
||||
if self.asset_processor is None:
|
||||
self._kill_ly_processes(include_asset_processor=True)
|
||||
self.__class__.asset_processor = AssetProcessor(workspace)
|
||||
self.asset_processor.backup_ap_settings()
|
||||
|
||||
self._kill_ly_processes(include_asset_processor=False)
|
||||
self.asset_processor.start()
|
||||
self.asset_processor.wait_for_idle()
|
||||
else:
|
||||
self._kill_ly_processes(include_asset_processor=False)
|
||||
|
||||
if not self.asset_processor.process_exists():
|
||||
self.asset_processor.start()
|
||||
self.asset_processor.wait_for_idle()
|
||||
|
||||
def teardown():
|
||||
if os.path.exists(workspace.paths.editor_log()):
|
||||
|
||||
@@ -61,6 +61,7 @@ class TestAutomation(TestAutomationBase):
|
||||
from . import Graph_HappyPath_ZoomInZoomOut as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
|
||||
@pytest.mark.xfail(reason="Test fails on nightly build builds, it needs to be fixed.")
|
||||
def test_NodePalette_HappyPath_CanSelectNode(self, request, workspace, editor, launcher_platform):
|
||||
from . import NodePalette_HappyPath_CanSelectNode as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
@@ -113,6 +114,7 @@ class TestAutomation(TestAutomationBase):
|
||||
from . import Debugger_HappyPath_TargetMultipleGraphs as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
|
||||
@pytest.mark.xfail(reason="Test fails on nightly build builds, it needs to be fixed.")
|
||||
@pytest.mark.parametrize("level", ["tmp_level"])
|
||||
def test_Debugger_HappyPath_TargetMultipleEntities(self, request, workspace, editor, launcher_platform, project, level):
|
||||
def teardown():
|
||||
@@ -174,6 +176,7 @@ class TestAutomation(TestAutomationBase):
|
||||
from . import ScriptEvents_ReturnSetType_Successfully as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
|
||||
@pytest.mark.xfail(reason="Test fails on nightly build builds, it needs to be fixed.")
|
||||
def test_NodeCategory_ExpandOnClick(self, request, workspace, editor, launcher_platform):
|
||||
from . import NodeCategory_ExpandOnClick as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
@@ -187,6 +190,7 @@ class TestAutomation(TestAutomationBase):
|
||||
from . import VariableManager_UnpinVariableType_Works as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
|
||||
@pytest.mark.xfail(reason="Test fails on nightly build builds, it needs to be fixed.")
|
||||
def test_Node_HappyPath_DuplicateNode(self, request, workspace, editor, launcher_platform):
|
||||
from . import Node_HappyPath_DuplicateNode as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
@@ -263,6 +267,7 @@ class TestScriptCanvasTests(object):
|
||||
timeout=60,
|
||||
)
|
||||
|
||||
@pytest.mark.xfail(reason="Test fails on nightly build builds, it needs to be fixed.")
|
||||
def test_VariableManager_Default_CreateDeleteVars(self, request, editor, launcher_platform):
|
||||
var_types = ["Boolean", "Color", "EntityID", "Number", "String", "Transform", "Vector2", "Vector3", "Vector4"]
|
||||
expected_lines = [f"Success: {var_type} variable is created" for var_type in var_types]
|
||||
|
||||
+20
-30
@@ -1,35 +1,25 @@
|
||||
{
|
||||
"description": "",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"parentMaterial": "",
|
||||
"materialTypeVersion": 3,
|
||||
"properties": {
|
||||
"baseColor": {
|
||||
"color": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
"emissive": {
|
||||
"color": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
"irradiance": {
|
||||
"color": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
"opacity": {
|
||||
"factor": 1.0
|
||||
}
|
||||
"propertyValues": {
|
||||
"baseColor.color": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0
|
||||
],
|
||||
"emissive.color": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0
|
||||
],
|
||||
"irradiance.color": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0
|
||||
],
|
||||
"opacity.factor": 1.0
|
||||
}
|
||||
}
|
||||
+20
-30
@@ -1,35 +1,25 @@
|
||||
{
|
||||
"description": "",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"parentMaterial": "",
|
||||
"materialTypeVersion": 3,
|
||||
"properties": {
|
||||
"baseColor": {
|
||||
"color": [
|
||||
0.0,
|
||||
1.0,
|
||||
0.0,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
"emissive": {
|
||||
"color": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
"irradiance": {
|
||||
"color": [
|
||||
0.0,
|
||||
1.0,
|
||||
0.0,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
"opacity": {
|
||||
"factor": 1.0
|
||||
}
|
||||
"propertyValues": {
|
||||
"baseColor.color": [
|
||||
0.0,
|
||||
1.0,
|
||||
0.0,
|
||||
1.0
|
||||
],
|
||||
"emissive.color": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0
|
||||
],
|
||||
"irradiance.color": [
|
||||
0.0,
|
||||
1.0,
|
||||
0.0,
|
||||
1.0
|
||||
],
|
||||
"opacity.factor": 1.0
|
||||
}
|
||||
}
|
||||
+24
-44
@@ -1,49 +1,29 @@
|
||||
{
|
||||
"description": "",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"parentMaterial": "",
|
||||
"materialTypeVersion": 3,
|
||||
"properties": {
|
||||
"baseColor": {
|
||||
"color": [
|
||||
0.800000011920929,
|
||||
0.800000011920929,
|
||||
0.800000011920929,
|
||||
1.0
|
||||
],
|
||||
"textureMap": "Textures/arch_1k_basecolor.png"
|
||||
},
|
||||
"general": {
|
||||
"applySpecularAA": true
|
||||
},
|
||||
"irradiance": {
|
||||
"color": [
|
||||
1.0,
|
||||
0.885053813457489,
|
||||
0.801281750202179,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
"metallic": {
|
||||
"textureMap": "Textures/arch_1k_metallic.png"
|
||||
},
|
||||
"normal": {
|
||||
"textureMap": "Textures/arch_1k_normal.jpg"
|
||||
},
|
||||
"occlusion": {
|
||||
"diffuseTextureMap": "Textures/arch_1k_ao.png"
|
||||
},
|
||||
"opacity": {
|
||||
"factor": 1.0
|
||||
},
|
||||
"parallax": {
|
||||
"factor": 0.050999999046325687,
|
||||
"pdo": true,
|
||||
"quality": "High",
|
||||
"useTexture": false
|
||||
},
|
||||
"roughness": {
|
||||
"textureMap": "Textures/arch_1k_roughness.png"
|
||||
}
|
||||
"propertyValues": {
|
||||
"baseColor.color": [
|
||||
0.800000011920929,
|
||||
0.800000011920929,
|
||||
0.800000011920929,
|
||||
1.0
|
||||
],
|
||||
"baseColor.textureMap": "Textures/arch_1k_basecolor.png",
|
||||
"general.applySpecularAA": true,
|
||||
"irradiance.color": [
|
||||
1.0,
|
||||
0.885053813457489,
|
||||
0.801281750202179,
|
||||
1.0
|
||||
],
|
||||
"metallic.textureMap": "Textures/arch_1k_metallic.png",
|
||||
"normal.textureMap": "Textures/arch_1k_normal.jpg",
|
||||
"occlusion.diffuseTextureMap": "Textures/arch_1k_ao.png",
|
||||
"opacity.factor": 1.0,
|
||||
"parallax.factor": 0.050999999046325684,
|
||||
"parallax.pdo": true,
|
||||
"parallax.quality": "High",
|
||||
"parallax.useTexture": false,
|
||||
"roughness.textureMap": "Textures/arch_1k_roughness.png"
|
||||
}
|
||||
}
|
||||
+27
-49
@@ -1,54 +1,32 @@
|
||||
{
|
||||
"description": "",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"parentMaterial": "",
|
||||
"materialTypeVersion": 3,
|
||||
"properties": {
|
||||
"baseColor": {
|
||||
"color": [
|
||||
0.800000011920929,
|
||||
0.800000011920929,
|
||||
0.800000011920929,
|
||||
1.0
|
||||
],
|
||||
"textureMap": "Textures/bricks_1k_basecolor.png"
|
||||
},
|
||||
"clearCoat": {
|
||||
"factor": 0.5,
|
||||
"normalMap": "Textures/bricks_1k_normal.jpg",
|
||||
"roughness": 0.5
|
||||
},
|
||||
"general": {
|
||||
"applySpecularAA": true
|
||||
},
|
||||
"irradiance": {
|
||||
"color": [
|
||||
1.0,
|
||||
0.9703211784362793,
|
||||
0.9703211784362793,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
"metallic": {
|
||||
"textureMap": "Textures/bricks_1k_metallic.png"
|
||||
},
|
||||
"normal": {
|
||||
"textureMap": "Textures/bricks_1k_normal.jpg"
|
||||
},
|
||||
"occlusion": {
|
||||
"diffuseTextureMap": "Textures/bricks_1k_ao.png"
|
||||
},
|
||||
"opacity": {
|
||||
"factor": 1.0
|
||||
},
|
||||
"parallax": {
|
||||
"algorithm": "ContactRefinement",
|
||||
"factor": 0.03500000014901161,
|
||||
"quality": "Medium",
|
||||
"useTexture": false
|
||||
},
|
||||
"roughness": {
|
||||
"textureMap": "Textures/bricks_1k_roughness.png"
|
||||
}
|
||||
"propertyValues": {
|
||||
"baseColor.color": [
|
||||
0.800000011920929,
|
||||
0.800000011920929,
|
||||
0.800000011920929,
|
||||
1.0
|
||||
],
|
||||
"baseColor.textureMap": "Textures/bricks_1k_basecolor.png",
|
||||
"clearCoat.factor": 0.5,
|
||||
"clearCoat.normalMap": "Textures/bricks_1k_normal.jpg",
|
||||
"clearCoat.roughness": 0.5,
|
||||
"general.applySpecularAA": true,
|
||||
"irradiance.color": [
|
||||
1.0,
|
||||
0.9703211784362793,
|
||||
0.9703211784362793,
|
||||
1.0
|
||||
],
|
||||
"metallic.textureMap": "Textures/bricks_1k_metallic.png",
|
||||
"normal.textureMap": "Textures/bricks_1k_normal.jpg",
|
||||
"occlusion.diffuseTextureMap": "Textures/bricks_1k_ao.png",
|
||||
"opacity.factor": 1.0,
|
||||
"parallax.algorithm": "ContactRefinement",
|
||||
"parallax.factor": 0.03500000014901161,
|
||||
"parallax.quality": "Medium",
|
||||
"parallax.useTexture": false,
|
||||
"roughness.textureMap": "Textures/bricks_1k_roughness.png"
|
||||
}
|
||||
}
|
||||
+26
-46
@@ -1,51 +1,31 @@
|
||||
{
|
||||
"description": "",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"parentMaterial": "",
|
||||
"materialTypeVersion": 3,
|
||||
"properties": {
|
||||
"baseColor": {
|
||||
"color": [
|
||||
0.800000011920929,
|
||||
0.800000011920929,
|
||||
0.800000011920929,
|
||||
1.0
|
||||
],
|
||||
"textureMap": "Textures/floor_1k_basecolor.png"
|
||||
},
|
||||
"clearCoat": {
|
||||
"enable": true,
|
||||
"influenceMap": "Textures/floor_1k_ao.png",
|
||||
"normalMap": "Textures/floor_1k_normal.png",
|
||||
"roughness": 0.25
|
||||
},
|
||||
"general": {
|
||||
"applySpecularAA": true
|
||||
},
|
||||
"irradiance": {
|
||||
"color": [
|
||||
1.0,
|
||||
0.9404135346412659,
|
||||
0.8688944578170776,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
"normal": {
|
||||
"textureMap": "Textures/floor_1k_normal.png"
|
||||
},
|
||||
"occlusion": {
|
||||
"diffuseTextureMap": "Textures/floor_1k_ao.png"
|
||||
},
|
||||
"opacity": {
|
||||
"factor": 1.0
|
||||
},
|
||||
"parallax": {
|
||||
"factor": 0.012000000104308129,
|
||||
"pdo": true,
|
||||
"useTexture": false
|
||||
},
|
||||
"roughness": {
|
||||
"textureMap": "Textures/floor_1k_roughness.png"
|
||||
}
|
||||
"propertyValues": {
|
||||
"baseColor.color": [
|
||||
0.800000011920929,
|
||||
0.800000011920929,
|
||||
0.800000011920929,
|
||||
1.0
|
||||
],
|
||||
"baseColor.textureMap": "Textures/floor_1k_basecolor.png",
|
||||
"clearCoat.enable": true,
|
||||
"clearCoat.influenceMap": "Textures/floor_1k_ao.png",
|
||||
"clearCoat.normalMap": "Textures/floor_1k_normal.png",
|
||||
"clearCoat.roughness": 0.25,
|
||||
"general.applySpecularAA": true,
|
||||
"irradiance.color": [
|
||||
1.0,
|
||||
0.9404135346412659,
|
||||
0.8688944578170776,
|
||||
1.0
|
||||
],
|
||||
"normal.textureMap": "Textures/floor_1k_normal.png",
|
||||
"occlusion.diffuseTextureMap": "Textures/floor_1k_ao.png",
|
||||
"opacity.factor": 1.0,
|
||||
"parallax.factor": 0.012000000104308128,
|
||||
"parallax.pdo": true,
|
||||
"parallax.useTexture": false,
|
||||
"roughness.textureMap": "Textures/floor_1k_roughness.png"
|
||||
}
|
||||
}
|
||||
+21
-39
@@ -1,44 +1,26 @@
|
||||
{
|
||||
"description": "",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"parentMaterial": "",
|
||||
"materialTypeVersion": 3,
|
||||
"properties": {
|
||||
"baseColor": {
|
||||
"color": [
|
||||
0.800000011920929,
|
||||
0.800000011920929,
|
||||
0.800000011920929,
|
||||
1.0
|
||||
],
|
||||
"textureBlendMode": "Lerp",
|
||||
"textureMap": "Textures/roof_1k_basecolor.png"
|
||||
},
|
||||
"general": {
|
||||
"applySpecularAA": true
|
||||
},
|
||||
"metallic": {
|
||||
"useTexture": false
|
||||
},
|
||||
"normal": {
|
||||
"factor": 0.5,
|
||||
"flipY": true,
|
||||
"textureMap": "Textures/roof_1k_normal.jpg"
|
||||
},
|
||||
"occlusion": {
|
||||
"diffuseTextureMap": "Textures/roof_1k_ao.png"
|
||||
},
|
||||
"opacity": {
|
||||
"factor": 1.0
|
||||
},
|
||||
"parallax": {
|
||||
"algorithm": "ContactRefinement",
|
||||
"factor": 0.019999999552965165,
|
||||
"quality": "Medium",
|
||||
"useTexture": false
|
||||
},
|
||||
"roughness": {
|
||||
"textureMap": "Textures/roof_1k_roughness.png"
|
||||
}
|
||||
"propertyValues": {
|
||||
"baseColor.color": [
|
||||
0.800000011920929,
|
||||
0.800000011920929,
|
||||
0.800000011920929,
|
||||
1.0
|
||||
],
|
||||
"baseColor.textureBlendMode": "Lerp",
|
||||
"baseColor.textureMap": "Textures/roof_1k_basecolor.png",
|
||||
"general.applySpecularAA": true,
|
||||
"metallic.useTexture": false,
|
||||
"normal.factor": 0.5,
|
||||
"normal.flipY": true,
|
||||
"normal.textureMap": "Textures/roof_1k_normal.jpg",
|
||||
"occlusion.diffuseTextureMap": "Textures/roof_1k_ao.png",
|
||||
"opacity.factor": 1.0,
|
||||
"parallax.algorithm": "ContactRefinement",
|
||||
"parallax.factor": 0.019999999552965164,
|
||||
"parallax.quality": "Medium",
|
||||
"parallax.useTexture": false,
|
||||
"roughness.textureMap": "Textures/roof_1k_roughness.png"
|
||||
}
|
||||
}
|
||||
+20
-30
@@ -1,35 +1,25 @@
|
||||
{
|
||||
"description": "",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"parentMaterial": "",
|
||||
"materialTypeVersion": 3,
|
||||
"properties": {
|
||||
"baseColor": {
|
||||
"color": [
|
||||
0.0,
|
||||
0.0,
|
||||
1.0,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
"emissive": {
|
||||
"color": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
"irradiance": {
|
||||
"color": [
|
||||
0.0,
|
||||
0.0,
|
||||
1.0,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
"opacity": {
|
||||
"factor": 1.0
|
||||
}
|
||||
"propertyValues": {
|
||||
"baseColor.color": [
|
||||
0.0,
|
||||
0.0,
|
||||
1.0,
|
||||
1.0
|
||||
],
|
||||
"emissive.color": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0
|
||||
],
|
||||
"irradiance.color": [
|
||||
0.0,
|
||||
0.0,
|
||||
1.0,
|
||||
1.0
|
||||
],
|
||||
"opacity.factor": 1.0
|
||||
}
|
||||
}
|
||||
+20
-30
@@ -1,35 +1,25 @@
|
||||
{
|
||||
"description": "",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"parentMaterial": "",
|
||||
"materialTypeVersion": 3,
|
||||
"properties": {
|
||||
"baseColor": {
|
||||
"color": [
|
||||
0.800000011920929,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
"emissive": {
|
||||
"color": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
"irradiance": {
|
||||
"color": [
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
"opacity": {
|
||||
"factor": 1.0
|
||||
}
|
||||
"propertyValues": {
|
||||
"baseColor.color": [
|
||||
0.800000011920929,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0
|
||||
],
|
||||
"emissive.color": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0
|
||||
],
|
||||
"irradiance.color": [
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0
|
||||
],
|
||||
"opacity.factor": 1.0
|
||||
}
|
||||
}
|
||||
+8
-14
@@ -1,19 +1,13 @@
|
||||
{
|
||||
"description": "",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"parentMaterial": "",
|
||||
"materialTypeVersion": 3,
|
||||
"properties": {
|
||||
"emissive": {
|
||||
"color": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
"opacity": {
|
||||
"factor": 1.0
|
||||
}
|
||||
"propertyValues": {
|
||||
"emissive.color": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0
|
||||
],
|
||||
"opacity.factor": 1.0
|
||||
}
|
||||
}
|
||||
@@ -1,19 +1,13 @@
|
||||
{
|
||||
"description": "",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"parentMaterial": "",
|
||||
"materialTypeVersion": 3,
|
||||
"properties": {
|
||||
"emissive": {
|
||||
"color": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
"opacity": {
|
||||
"factor": 1.0
|
||||
}
|
||||
"propertyValues": {
|
||||
"emissive.color": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0
|
||||
],
|
||||
"opacity.factor": 1.0
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,40 +1,22 @@
|
||||
{
|
||||
"description": "",
|
||||
"parentMaterial": "",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"materialTypeVersion": 4,
|
||||
"properties": {
|
||||
"baseColor": {
|
||||
"textureMap": "../Textures/arch_1k_basecolor.png"
|
||||
},
|
||||
"general": {
|
||||
"applySpecularAA": true
|
||||
},
|
||||
"irradiance": {
|
||||
"color": [
|
||||
0.2663614749908447,
|
||||
0.2383916974067688,
|
||||
0.18117037415504456,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
"normal": {
|
||||
"textureMap": "../Textures/arch_1k_normal.jpg"
|
||||
},
|
||||
"occlusion": {
|
||||
"diffuseTextureMap": "../Textures/arch_1k_ao.png"
|
||||
},
|
||||
"opacity": {
|
||||
"factor": 1.0
|
||||
},
|
||||
"parallax": {
|
||||
"factor": 0.050999999046325684,
|
||||
"pdo": true,
|
||||
"quality": "High",
|
||||
"useTexture": false
|
||||
},
|
||||
"roughness": {
|
||||
"textureMap": "../Textures/arch_1k_roughness.png"
|
||||
}
|
||||
"propertyValues": {
|
||||
"baseColor.textureMap": "../Textures/arch_1k_basecolor.png",
|
||||
"general.applySpecularAA": true,
|
||||
"irradiance.color": [
|
||||
0.2663614749908447,
|
||||
0.2383916974067688,
|
||||
0.18117037415504456,
|
||||
1.0
|
||||
],
|
||||
"normal.textureMap": "../Textures/arch_1k_normal.jpg",
|
||||
"occlusion.diffuseTextureMap": "../Textures/arch_1k_ao.png",
|
||||
"opacity.factor": 1.0,
|
||||
"parallax.factor": 0.050999999046325684,
|
||||
"parallax.pdo": true,
|
||||
"parallax.quality": "High",
|
||||
"parallax.useTexture": false,
|
||||
"roughness.textureMap": "../Textures/arch_1k_roughness.png"
|
||||
}
|
||||
}
|
||||
@@ -1,45 +1,25 @@
|
||||
{
|
||||
"description": "",
|
||||
"parentMaterial": "",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"materialTypeVersion": 4,
|
||||
"properties": {
|
||||
"baseColor": {
|
||||
"textureMap": "../Textures/background_1k_basecolor.png"
|
||||
},
|
||||
"clearCoat": {
|
||||
"factor": 0.5,
|
||||
"normalMap": "../Textures/background_1k_normal.jpg",
|
||||
"roughness": 0.4000000059604645
|
||||
},
|
||||
"general": {
|
||||
"applySpecularAA": true
|
||||
},
|
||||
"irradiance": {
|
||||
"color": [
|
||||
0.19806210696697235,
|
||||
0.1746547669172287,
|
||||
0.16513313353061676,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
"normal": {
|
||||
"textureMap": "../Textures/background_1k_normal.jpg"
|
||||
},
|
||||
"occlusion": {
|
||||
"diffuseTextureMap": "../Textures/background_1k_ao.png"
|
||||
},
|
||||
"opacity": {
|
||||
"factor": 1.0
|
||||
},
|
||||
"parallax": {
|
||||
"factor": 0.03099999949336052,
|
||||
"pdo": true,
|
||||
"quality": "High",
|
||||
"useTexture": false
|
||||
},
|
||||
"roughness": {
|
||||
"textureMap": "../Textures/background_1k_roughness.png"
|
||||
}
|
||||
"propertyValues": {
|
||||
"baseColor.textureMap": "../Textures/background_1k_basecolor.png",
|
||||
"clearCoat.factor": 0.5,
|
||||
"clearCoat.normalMap": "../Textures/background_1k_normal.jpg",
|
||||
"clearCoat.roughness": 0.4000000059604645,
|
||||
"general.applySpecularAA": true,
|
||||
"irradiance.color": [
|
||||
0.19806210696697235,
|
||||
0.1746547669172287,
|
||||
0.16513313353061676,
|
||||
1.0
|
||||
],
|
||||
"normal.textureMap": "../Textures/background_1k_normal.jpg",
|
||||
"occlusion.diffuseTextureMap": "../Textures/background_1k_ao.png",
|
||||
"opacity.factor": 1.0,
|
||||
"parallax.factor": 0.03099999949336052,
|
||||
"parallax.pdo": true,
|
||||
"parallax.quality": "High",
|
||||
"parallax.useTexture": false,
|
||||
"roughness.textureMap": "../Textures/background_1k_roughness.png"
|
||||
}
|
||||
}
|
||||
@@ -1,45 +1,25 @@
|
||||
{
|
||||
"description": "",
|
||||
"parentMaterial": "",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"materialTypeVersion": 4,
|
||||
"properties": {
|
||||
"baseColor": {
|
||||
"textureMap": "../Textures/bricks_1k_basecolor.png"
|
||||
},
|
||||
"clearCoat": {
|
||||
"factor": 0.5,
|
||||
"normalMap": "../Textures/bricks_1k_normal.jpg",
|
||||
"roughness": 0.5
|
||||
},
|
||||
"general": {
|
||||
"applySpecularAA": true
|
||||
},
|
||||
"irradiance": {
|
||||
"color": [
|
||||
0.27467766404151917,
|
||||
0.27467766404151917,
|
||||
0.270496666431427,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
"normal": {
|
||||
"textureMap": "../Textures/bricks_1k_normal.jpg"
|
||||
},
|
||||
"occlusion": {
|
||||
"diffuseTextureMap": "../Textures/bricks_1k_ao.png"
|
||||
},
|
||||
"opacity": {
|
||||
"factor": 1.0
|
||||
},
|
||||
"parallax": {
|
||||
"algorithm": "ContactRefinement",
|
||||
"factor": 0.03500000014901161,
|
||||
"quality": "Medium",
|
||||
"useTexture": false
|
||||
},
|
||||
"roughness": {
|
||||
"textureMap": "../Textures/bricks_1k_roughness.png"
|
||||
}
|
||||
"propertyValues": {
|
||||
"baseColor.textureMap": "../Textures/bricks_1k_basecolor.png",
|
||||
"clearCoat.factor": 0.5,
|
||||
"clearCoat.normalMap": "../Textures/bricks_1k_normal.jpg",
|
||||
"clearCoat.roughness": 0.5,
|
||||
"general.applySpecularAA": true,
|
||||
"irradiance.color": [
|
||||
0.27467766404151917,
|
||||
0.27467766404151917,
|
||||
0.270496666431427,
|
||||
1.0
|
||||
],
|
||||
"normal.textureMap": "../Textures/bricks_1k_normal.jpg",
|
||||
"occlusion.diffuseTextureMap": "../Textures/bricks_1k_ao.png",
|
||||
"opacity.factor": 1.0,
|
||||
"parallax.algorithm": "ContactRefinement",
|
||||
"parallax.factor": 0.03500000014901161,
|
||||
"parallax.quality": "Medium",
|
||||
"parallax.useTexture": false,
|
||||
"roughness.textureMap": "../Textures/bricks_1k_roughness.png"
|
||||
}
|
||||
}
|
||||
@@ -1,36 +1,22 @@
|
||||
{
|
||||
"description": "",
|
||||
"parentMaterial": "",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"materialTypeVersion": 4,
|
||||
"properties": {
|
||||
"baseColor": {
|
||||
"textureMap": "../Textures/ceiling_1k_basecolor.png"
|
||||
},
|
||||
"emissive": {
|
||||
"color": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
"irradiance": {
|
||||
"color": [
|
||||
0.29176774621009827,
|
||||
0.27888914942741394,
|
||||
0.2501564025878906,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
"normal": {
|
||||
"textureMap": "../Textures/ceiling_1k_normal.png"
|
||||
},
|
||||
"opacity": {
|
||||
"factor": 1.0
|
||||
},
|
||||
"roughness": {
|
||||
"textureMap": "../Textures/ceiling_1k_roughness.png"
|
||||
}
|
||||
"propertyValues": {
|
||||
"baseColor.textureMap": "../Textures/ceiling_1k_basecolor.png",
|
||||
"emissive.color": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0
|
||||
],
|
||||
"irradiance.color": [
|
||||
0.29176774621009827,
|
||||
0.27888914942741394,
|
||||
0.2501564025878906,
|
||||
1.0
|
||||
],
|
||||
"normal.textureMap": "../Textures/ceiling_1k_normal.png",
|
||||
"opacity.factor": 1.0,
|
||||
"roughness.textureMap": "../Textures/ceiling_1k_roughness.png"
|
||||
}
|
||||
}
|
||||
@@ -1,35 +1,21 @@
|
||||
{
|
||||
"description": "",
|
||||
"parentMaterial": "",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"materialTypeVersion": 4,
|
||||
"properties": {
|
||||
"baseColor": {
|
||||
"textureBlendMode": "Lerp",
|
||||
"textureMap": "../Textures/chain_basecolor.png"
|
||||
},
|
||||
"emissive": {
|
||||
"color": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
"general": {
|
||||
"doubleSided": true
|
||||
},
|
||||
"metallic": {
|
||||
"factor": 0.8899999856948853
|
||||
},
|
||||
"normal": {
|
||||
"textureMap": "../Textures/chain_normal.jpg"
|
||||
},
|
||||
"opacity": {
|
||||
"alphaSource": "Split",
|
||||
"factor": 1.0,
|
||||
"mode": "Cutout",
|
||||
"textureMap": "../Textures/chain_alpha.png"
|
||||
}
|
||||
"propertyValues": {
|
||||
"baseColor.textureBlendMode": "Lerp",
|
||||
"baseColor.textureMap": "../Textures/chain_basecolor.png",
|
||||
"emissive.color": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0
|
||||
],
|
||||
"general.doubleSided": true,
|
||||
"metallic.factor": 0.8899999856948853,
|
||||
"normal.textureMap": "../Textures/chain_normal.jpg",
|
||||
"opacity.alphaSource": "Split",
|
||||
"opacity.factor": 1.0,
|
||||
"opacity.mode": "Cutout",
|
||||
"opacity.textureMap": "../Textures/chain_alpha.png"
|
||||
}
|
||||
}
|
||||
@@ -1,45 +1,25 @@
|
||||
{
|
||||
"description": "",
|
||||
"parentMaterial": "",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"materialTypeVersion": 4,
|
||||
"properties": {
|
||||
"baseColor": {
|
||||
"textureMap": "../Textures/columnA_1k_basecolor.png"
|
||||
},
|
||||
"clearCoat": {
|
||||
"factor": 0.5,
|
||||
"normalMap": "../Textures/columnA_1k_normal.jpg",
|
||||
"roughness": 0.30000001192092896
|
||||
},
|
||||
"general": {
|
||||
"applySpecularAA": true
|
||||
},
|
||||
"irradiance": {
|
||||
"color": [
|
||||
1.0,
|
||||
0.8964369893074036,
|
||||
0.8264744281768799,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
"normal": {
|
||||
"textureMap": "../Textures/columnA_1k_normal.jpg"
|
||||
},
|
||||
"occlusion": {
|
||||
"diffuseTextureMap": "../Textures/columnA_1k_ao.png"
|
||||
},
|
||||
"opacity": {
|
||||
"factor": 1.0
|
||||
},
|
||||
"parallax": {
|
||||
"factor": 0.017000000923871994,
|
||||
"pdo": true,
|
||||
"quality": "High",
|
||||
"useTexture": false
|
||||
},
|
||||
"roughness": {
|
||||
"textureMap": "../Textures/columnA_1k_roughness.png"
|
||||
}
|
||||
"propertyValues": {
|
||||
"baseColor.textureMap": "../Textures/columnA_1k_basecolor.png",
|
||||
"clearCoat.factor": 0.5,
|
||||
"clearCoat.normalMap": "../Textures/columnA_1k_normal.jpg",
|
||||
"clearCoat.roughness": 0.30000001192092896,
|
||||
"general.applySpecularAA": true,
|
||||
"irradiance.color": [
|
||||
1.0,
|
||||
0.8964369893074036,
|
||||
0.8264744281768799,
|
||||
1.0
|
||||
],
|
||||
"normal.textureMap": "../Textures/columnA_1k_normal.jpg",
|
||||
"occlusion.diffuseTextureMap": "../Textures/columnA_1k_ao.png",
|
||||
"opacity.factor": 1.0,
|
||||
"parallax.factor": 0.017000000923871994,
|
||||
"parallax.pdo": true,
|
||||
"parallax.quality": "High",
|
||||
"parallax.useTexture": false,
|
||||
"roughness.textureMap": "../Textures/columnA_1k_roughness.png"
|
||||
}
|
||||
}
|
||||
@@ -1,45 +1,25 @@
|
||||
{
|
||||
"description": "",
|
||||
"parentMaterial": "",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"materialTypeVersion": 4,
|
||||
"properties": {
|
||||
"baseColor": {
|
||||
"textureMap": "../Textures/columnB_1k_basecolor.png"
|
||||
},
|
||||
"clearCoat": {
|
||||
"factor": 0.5,
|
||||
"normalMap": "../Textures/columnB_1k_normal.jpg",
|
||||
"roughness": 0.30000001192092896
|
||||
},
|
||||
"general": {
|
||||
"applySpecularAA": true
|
||||
},
|
||||
"irradiance": {
|
||||
"color": [
|
||||
0.41788357496261597,
|
||||
0.40723279118537903,
|
||||
0.4286869466304779,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
"normal": {
|
||||
"textureMap": "../Textures/columnB_1k_normal.jpg"
|
||||
},
|
||||
"occlusion": {
|
||||
"diffuseTextureMap": "../Textures/columnB_1k_ao.png"
|
||||
},
|
||||
"opacity": {
|
||||
"factor": 1.0
|
||||
},
|
||||
"parallax": {
|
||||
"factor": 0.020999999716877937,
|
||||
"pdo": true,
|
||||
"quality": "High",
|
||||
"useTexture": false
|
||||
},
|
||||
"roughness": {
|
||||
"textureMap": "../Textures/columnB_1k_roughness.png"
|
||||
}
|
||||
"propertyValues": {
|
||||
"baseColor.textureMap": "../Textures/columnB_1k_basecolor.png",
|
||||
"clearCoat.factor": 0.5,
|
||||
"clearCoat.normalMap": "../Textures/columnB_1k_normal.jpg",
|
||||
"clearCoat.roughness": 0.30000001192092896,
|
||||
"general.applySpecularAA": true,
|
||||
"irradiance.color": [
|
||||
0.41788357496261597,
|
||||
0.40723279118537903,
|
||||
0.4286869466304779,
|
||||
1.0
|
||||
],
|
||||
"normal.textureMap": "../Textures/columnB_1k_normal.jpg",
|
||||
"occlusion.diffuseTextureMap": "../Textures/columnB_1k_ao.png",
|
||||
"opacity.factor": 1.0,
|
||||
"parallax.factor": 0.020999999716877937,
|
||||
"parallax.pdo": true,
|
||||
"parallax.quality": "High",
|
||||
"parallax.useTexture": false,
|
||||
"roughness.textureMap": "../Textures/columnB_1k_roughness.png"
|
||||
}
|
||||
}
|
||||
@@ -1,45 +1,25 @@
|
||||
{
|
||||
"description": "",
|
||||
"parentMaterial": "",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"materialTypeVersion": 4,
|
||||
"properties": {
|
||||
"baseColor": {
|
||||
"textureMap": "../Textures/columnC_1k_basecolor.png"
|
||||
},
|
||||
"clearCoat": {
|
||||
"factor": 0.5,
|
||||
"normalMap": "../Textures/columnC_1k_normal.jpg",
|
||||
"roughness": 0.30000001192092896
|
||||
},
|
||||
"general": {
|
||||
"applySpecularAA": true
|
||||
},
|
||||
"irradiance": {
|
||||
"color": [
|
||||
0.32314029335975647,
|
||||
0.29176774621009827,
|
||||
0.24228274822235107,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
"normal": {
|
||||
"textureMap": "../Textures/columnC_1k_normal.jpg"
|
||||
},
|
||||
"occlusion": {
|
||||
"diffuseTextureMap": "../Textures/columnC_1k_ao.png"
|
||||
},
|
||||
"opacity": {
|
||||
"factor": 1.0
|
||||
},
|
||||
"parallax": {
|
||||
"factor": 0.014000000432133675,
|
||||
"pdo": true,
|
||||
"quality": "High",
|
||||
"useTexture": false
|
||||
},
|
||||
"roughness": {
|
||||
"textureMap": "../Textures/columnC_1k_roughness.png"
|
||||
}
|
||||
"propertyValues": {
|
||||
"baseColor.textureMap": "../Textures/columnC_1k_basecolor.png",
|
||||
"clearCoat.factor": 0.5,
|
||||
"clearCoat.normalMap": "../Textures/columnC_1k_normal.jpg",
|
||||
"clearCoat.roughness": 0.30000001192092896,
|
||||
"general.applySpecularAA": true,
|
||||
"irradiance.color": [
|
||||
0.32314029335975647,
|
||||
0.29176774621009827,
|
||||
0.24228274822235107,
|
||||
1.0
|
||||
],
|
||||
"normal.textureMap": "../Textures/columnC_1k_normal.jpg",
|
||||
"occlusion.diffuseTextureMap": "../Textures/columnC_1k_ao.png",
|
||||
"opacity.factor": 1.0,
|
||||
"parallax.factor": 0.014000000432133675,
|
||||
"parallax.pdo": true,
|
||||
"parallax.quality": "High",
|
||||
"parallax.useTexture": false,
|
||||
"roughness.textureMap": "../Textures/columnC_1k_roughness.png"
|
||||
}
|
||||
}
|
||||
@@ -1,52 +1,32 @@
|
||||
{
|
||||
"description": "",
|
||||
"parentMaterial": "",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"materialTypeVersion": 4,
|
||||
"properties": {
|
||||
"baseColor": {
|
||||
"color": [
|
||||
1.0,
|
||||
1.0,
|
||||
1.0,
|
||||
1.0
|
||||
],
|
||||
"textureMap": "../Textures/curtainBlue_1k_basecolor.png"
|
||||
},
|
||||
"emissive": {
|
||||
"color": [
|
||||
1.0,
|
||||
1.0,
|
||||
1.0,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
"general": {
|
||||
"applySpecularAA": true
|
||||
},
|
||||
"irradiance": {
|
||||
"color": [
|
||||
0.0,
|
||||
0.14901961386203766,
|
||||
1.0,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
"metallic": {
|
||||
"textureMap": "../Textures/curtain_metallic.png"
|
||||
},
|
||||
"normal": {
|
||||
"factor": 0.5,
|
||||
"textureMap": "../Textures/curtain_normal.jpg"
|
||||
},
|
||||
"occlusion": {
|
||||
"diffuseTextureMap": "../Textures/curtain_ao.png"
|
||||
},
|
||||
"roughness": {
|
||||
"textureMap": "../Textures/curtain_roughness.png"
|
||||
},
|
||||
"specularF0": {
|
||||
"enableMultiScatterCompensation": true
|
||||
}
|
||||
"propertyValues": {
|
||||
"baseColor.color": [
|
||||
1.0,
|
||||
1.0,
|
||||
1.0,
|
||||
1.0
|
||||
],
|
||||
"baseColor.textureMap": "../Textures/curtainBlue_1k_basecolor.png",
|
||||
"emissive.color": [
|
||||
1.0,
|
||||
1.0,
|
||||
1.0,
|
||||
1.0
|
||||
],
|
||||
"general.applySpecularAA": true,
|
||||
"irradiance.color": [
|
||||
0.0,
|
||||
0.14901961386203766,
|
||||
1.0,
|
||||
1.0
|
||||
],
|
||||
"metallic.textureMap": "../Textures/curtain_metallic.png",
|
||||
"normal.factor": 0.5,
|
||||
"normal.textureMap": "../Textures/curtain_normal.jpg",
|
||||
"occlusion.diffuseTextureMap": "../Textures/curtain_ao.png",
|
||||
"roughness.textureMap": "../Textures/curtain_roughness.png",
|
||||
"specularF0.enableMultiScatterCompensation": true
|
||||
}
|
||||
}
|
||||
@@ -1,38 +1,20 @@
|
||||
{
|
||||
"description": "",
|
||||
"parentMaterial": "",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"materialTypeVersion": 4,
|
||||
"properties": {
|
||||
"baseColor": {
|
||||
"textureMap": "../Textures/curtainGreen_1k_basecolor.png"
|
||||
},
|
||||
"general": {
|
||||
"applySpecularAA": true
|
||||
},
|
||||
"irradiance": {
|
||||
"color": [
|
||||
0.0,
|
||||
0.15294118225574493,
|
||||
0.0,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
"metallic": {
|
||||
"textureMap": "../Textures/curtain_metallic.png"
|
||||
},
|
||||
"normal": {
|
||||
"factor": 0.5,
|
||||
"textureMap": "../Textures/curtain_normal.jpg"
|
||||
},
|
||||
"occlusion": {
|
||||
"diffuseTextureMap": "../Textures/curtain_ao.png"
|
||||
},
|
||||
"opacity": {
|
||||
"factor": 1.0
|
||||
},
|
||||
"roughness": {
|
||||
"textureMap": "../Textures/curtain_roughness.png"
|
||||
}
|
||||
"propertyValues": {
|
||||
"baseColor.textureMap": "../Textures/curtainGreen_1k_basecolor.png",
|
||||
"general.applySpecularAA": true,
|
||||
"irradiance.color": [
|
||||
0.0,
|
||||
0.15294118225574493,
|
||||
0.0,
|
||||
1.0
|
||||
],
|
||||
"metallic.textureMap": "../Textures/curtain_metallic.png",
|
||||
"normal.factor": 0.5,
|
||||
"normal.textureMap": "../Textures/curtain_normal.jpg",
|
||||
"occlusion.diffuseTextureMap": "../Textures/curtain_ao.png",
|
||||
"opacity.factor": 1.0,
|
||||
"roughness.textureMap": "../Textures/curtain_roughness.png"
|
||||
}
|
||||
}
|
||||
@@ -1,43 +1,23 @@
|
||||
{
|
||||
"description": "",
|
||||
"parentMaterial": "",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"materialTypeVersion": 4,
|
||||
"properties": {
|
||||
"baseColor": {
|
||||
"textureMap": "../Textures/curtainRed_1k_basecolor.png"
|
||||
},
|
||||
"general": {
|
||||
"applySpecularAA": true
|
||||
},
|
||||
"irradiance": {
|
||||
"color": [
|
||||
0.41960784792900085,
|
||||
0.003921568859368563,
|
||||
0.003921568859368563,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
"metallic": {
|
||||
"textureMap": "../Textures/curtain_metallic.png"
|
||||
},
|
||||
"normal": {
|
||||
"textureMap": "../Textures/curtain_normal.jpg"
|
||||
},
|
||||
"occlusion": {
|
||||
"diffuseTextureMap": "../Textures/curtain_ao.png"
|
||||
},
|
||||
"opacity": {
|
||||
"factor": 1.0
|
||||
},
|
||||
"roughness": {
|
||||
"textureMap": "../Textures/curtain_roughness.png"
|
||||
},
|
||||
"uv": {
|
||||
"center": [
|
||||
16.0,
|
||||
0.0
|
||||
]
|
||||
}
|
||||
"propertyValues": {
|
||||
"baseColor.textureMap": "../Textures/curtainRed_1k_basecolor.png",
|
||||
"general.applySpecularAA": true,
|
||||
"irradiance.color": [
|
||||
0.41960784792900085,
|
||||
0.003921568859368563,
|
||||
0.003921568859368563,
|
||||
1.0
|
||||
],
|
||||
"metallic.textureMap": "../Textures/curtain_metallic.png",
|
||||
"normal.textureMap": "../Textures/curtain_normal.jpg",
|
||||
"occlusion.diffuseTextureMap": "../Textures/curtain_ao.png",
|
||||
"opacity.factor": 1.0,
|
||||
"roughness.textureMap": "../Textures/curtain_roughness.png",
|
||||
"uv.center": [
|
||||
16.0,
|
||||
0.0
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,39 +1,19 @@
|
||||
{
|
||||
"description": "",
|
||||
"parentMaterial": "",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"materialTypeVersion": 4,
|
||||
"properties": {
|
||||
"baseColor": {
|
||||
"textureMap": "../Textures/details_1k_basecolor.png"
|
||||
},
|
||||
"clearCoat": {
|
||||
"factor": 0.5,
|
||||
"normalMap": "../Textures/details_1k_normal.png",
|
||||
"roughness": 0.25
|
||||
},
|
||||
"general": {
|
||||
"applySpecularAA": true
|
||||
},
|
||||
"metallic": {
|
||||
"textureMap": "../Textures/details_1k_metallic.png"
|
||||
},
|
||||
"normal": {
|
||||
"textureMap": "../Textures/details_1k_normal.png"
|
||||
},
|
||||
"occlusion": {
|
||||
"diffuseTextureMap": "../Textures/details_1k_ao.png"
|
||||
},
|
||||
"opacity": {
|
||||
"factor": 1.0
|
||||
},
|
||||
"parallax": {
|
||||
"factor": 0.02500000037252903,
|
||||
"pdo": true,
|
||||
"useTexture": false
|
||||
},
|
||||
"roughness": {
|
||||
"textureMap": "../Textures/details_1k_roughness.png"
|
||||
}
|
||||
"propertyValues": {
|
||||
"baseColor.textureMap": "../Textures/details_1k_basecolor.png",
|
||||
"clearCoat.factor": 0.5,
|
||||
"clearCoat.normalMap": "../Textures/details_1k_normal.png",
|
||||
"clearCoat.roughness": 0.25,
|
||||
"general.applySpecularAA": true,
|
||||
"metallic.textureMap": "../Textures/details_1k_metallic.png",
|
||||
"normal.textureMap": "../Textures/details_1k_normal.png",
|
||||
"occlusion.diffuseTextureMap": "../Textures/details_1k_ao.png",
|
||||
"opacity.factor": 1.0,
|
||||
"parallax.factor": 0.02500000037252903,
|
||||
"parallax.pdo": true,
|
||||
"parallax.useTexture": false,
|
||||
"roughness.textureMap": "../Textures/details_1k_roughness.png"
|
||||
}
|
||||
}
|
||||
@@ -1,39 +1,21 @@
|
||||
{
|
||||
"description": "",
|
||||
"parentMaterial": "",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"materialTypeVersion": 4,
|
||||
"properties": {
|
||||
"baseColor": {
|
||||
"textureMap": "../Textures/fabricBlue_1k_basecolor.png"
|
||||
},
|
||||
"general": {
|
||||
"applySpecularAA": true
|
||||
},
|
||||
"irradiance": {
|
||||
"color": [
|
||||
0.0,
|
||||
0.15049973130226135,
|
||||
1.0,
|
||||
1.0
|
||||
],
|
||||
"factor": 0.30000001192092896
|
||||
},
|
||||
"metallic": {
|
||||
"textureMap": "../Textures/fabric_metallic.png"
|
||||
},
|
||||
"normal": {
|
||||
"factor": 0.5,
|
||||
"textureMap": "../Textures/fabric_normal.jpg"
|
||||
},
|
||||
"occlusion": {
|
||||
"diffuseTextureMap": "../Textures/fabric_ao.png"
|
||||
},
|
||||
"opacity": {
|
||||
"factor": 1.0
|
||||
},
|
||||
"roughness": {
|
||||
"textureMap": "../Textures/fabric_roughness.png"
|
||||
}
|
||||
"propertyValues": {
|
||||
"baseColor.textureMap": "../Textures/fabricBlue_1k_basecolor.png",
|
||||
"general.applySpecularAA": true,
|
||||
"irradiance.color": [
|
||||
0.0,
|
||||
0.15049973130226135,
|
||||
1.0,
|
||||
1.0
|
||||
],
|
||||
"irradiance.factor": 0.30000001192092896,
|
||||
"metallic.textureMap": "../Textures/fabric_metallic.png",
|
||||
"normal.factor": 0.5,
|
||||
"normal.textureMap": "../Textures/fabric_normal.jpg",
|
||||
"occlusion.diffuseTextureMap": "../Textures/fabric_ao.png",
|
||||
"opacity.factor": 1.0,
|
||||
"roughness.textureMap": "../Textures/fabric_roughness.png"
|
||||
}
|
||||
}
|
||||
@@ -1,39 +1,21 @@
|
||||
{
|
||||
"description": "",
|
||||
"parentMaterial": "",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"materialTypeVersion": 4,
|
||||
"properties": {
|
||||
"baseColor": {
|
||||
"textureMap": "../Textures/fabricGreen_1k_basecolor.png"
|
||||
},
|
||||
"general": {
|
||||
"applySpecularAA": true
|
||||
},
|
||||
"irradiance": {
|
||||
"color": [
|
||||
0.0,
|
||||
0.15292592346668243,
|
||||
0.0012207217514514923,
|
||||
1.0
|
||||
],
|
||||
"factor": 0.30000001192092896
|
||||
},
|
||||
"metallic": {
|
||||
"textureMap": "../Textures/fabric_metallic.png"
|
||||
},
|
||||
"normal": {
|
||||
"factor": 0.5,
|
||||
"textureMap": "../Textures/fabric_normal.jpg"
|
||||
},
|
||||
"occlusion": {
|
||||
"diffuseTextureMap": "../Textures/fabric_ao.png"
|
||||
},
|
||||
"opacity": {
|
||||
"factor": 1.0
|
||||
},
|
||||
"roughness": {
|
||||
"textureMap": "../Textures/fabric_roughness.png"
|
||||
}
|
||||
"propertyValues": {
|
||||
"baseColor.textureMap": "../Textures/fabricGreen_1k_basecolor.png",
|
||||
"general.applySpecularAA": true,
|
||||
"irradiance.color": [
|
||||
0.0,
|
||||
0.15292592346668243,
|
||||
0.0012207217514514923,
|
||||
1.0
|
||||
],
|
||||
"irradiance.factor": 0.30000001192092896,
|
||||
"metallic.textureMap": "../Textures/fabric_metallic.png",
|
||||
"normal.factor": 0.5,
|
||||
"normal.textureMap": "../Textures/fabric_normal.jpg",
|
||||
"occlusion.diffuseTextureMap": "../Textures/fabric_ao.png",
|
||||
"opacity.factor": 1.0,
|
||||
"roughness.textureMap": "../Textures/fabric_roughness.png"
|
||||
}
|
||||
}
|
||||
@@ -1,39 +1,21 @@
|
||||
{
|
||||
"description": "",
|
||||
"parentMaterial": "",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"materialTypeVersion": 4,
|
||||
"properties": {
|
||||
"baseColor": {
|
||||
"textureMap": "../Textures/fabricRed_1k_basecolor.png"
|
||||
},
|
||||
"general": {
|
||||
"applySpecularAA": true
|
||||
},
|
||||
"irradiance": {
|
||||
"color": [
|
||||
0.42040130496025085,
|
||||
0.004654001910239458,
|
||||
0.0037232013419270515,
|
||||
1.0
|
||||
],
|
||||
"factor": 0.30000001192092896
|
||||
},
|
||||
"metallic": {
|
||||
"textureMap": "../Textures/fabric_metallic.png"
|
||||
},
|
||||
"normal": {
|
||||
"factor": 0.5,
|
||||
"textureMap": "../Textures/fabric_normal.jpg"
|
||||
},
|
||||
"occlusion": {
|
||||
"diffuseTextureMap": "../Textures/fabric_ao.png"
|
||||
},
|
||||
"opacity": {
|
||||
"factor": 1.0
|
||||
},
|
||||
"roughness": {
|
||||
"textureMap": "../Textures/fabric_roughness.png"
|
||||
}
|
||||
"propertyValues": {
|
||||
"baseColor.textureMap": "../Textures/fabricRed_1k_basecolor.png",
|
||||
"general.applySpecularAA": true,
|
||||
"irradiance.color": [
|
||||
0.42040130496025085,
|
||||
0.004654001910239458,
|
||||
0.0037232013419270515,
|
||||
1.0
|
||||
],
|
||||
"irradiance.factor": 0.30000001192092896,
|
||||
"metallic.textureMap": "../Textures/fabric_metallic.png",
|
||||
"normal.factor": 0.5,
|
||||
"normal.textureMap": "../Textures/fabric_normal.jpg",
|
||||
"occlusion.diffuseTextureMap": "../Textures/fabric_ao.png",
|
||||
"opacity.factor": 1.0,
|
||||
"roughness.textureMap": "../Textures/fabric_roughness.png"
|
||||
}
|
||||
}
|
||||
@@ -1,46 +1,24 @@
|
||||
{
|
||||
"description": "",
|
||||
"parentMaterial": "",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"materialTypeVersion": 4,
|
||||
"properties": {
|
||||
"baseColor": {
|
||||
"textureMap": "../Textures/flagpole_1k_basecolor.png"
|
||||
},
|
||||
"general": {
|
||||
"applySpecularAA": true
|
||||
},
|
||||
"irradiance": {
|
||||
"color": [
|
||||
1.0,
|
||||
0.6520485281944275,
|
||||
0.7122911214828491,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
"metallic": {
|
||||
"textureMap": "../Textures/flagpole_1k_metallic.png"
|
||||
},
|
||||
"normal": {
|
||||
"textureMap": "../Textures/flagpole_1k_normal.png"
|
||||
},
|
||||
"occlusion": {
|
||||
"diffuseTextureMap": "../Textures/flagpole_1k_ao.png"
|
||||
},
|
||||
"opacity": {
|
||||
"factor": 1.0
|
||||
},
|
||||
"parallax": {
|
||||
"factor": 0.014000000432133675,
|
||||
"pdo": true,
|
||||
"quality": "High",
|
||||
"useTexture": false
|
||||
},
|
||||
"roughness": {
|
||||
"textureMap": "../Textures/flagpole_1k_roughness.png"
|
||||
},
|
||||
"specularF0": {
|
||||
"enableMultiScatterCompensation": true
|
||||
}
|
||||
"propertyValues": {
|
||||
"baseColor.textureMap": "../Textures/flagpole_1k_basecolor.png",
|
||||
"general.applySpecularAA": true,
|
||||
"irradiance.color": [
|
||||
1.0,
|
||||
0.6520485281944275,
|
||||
0.7122911214828491,
|
||||
1.0
|
||||
],
|
||||
"metallic.textureMap": "../Textures/flagpole_1k_metallic.png",
|
||||
"normal.textureMap": "../Textures/flagpole_1k_normal.png",
|
||||
"occlusion.diffuseTextureMap": "../Textures/flagpole_1k_ao.png",
|
||||
"opacity.factor": 1.0,
|
||||
"parallax.factor": 0.014000000432133675,
|
||||
"parallax.pdo": true,
|
||||
"parallax.quality": "High",
|
||||
"parallax.useTexture": false,
|
||||
"roughness.textureMap": "../Textures/flagpole_1k_roughness.png",
|
||||
"specularF0.enableMultiScatterCompensation": true
|
||||
}
|
||||
}
|
||||
@@ -1,44 +1,24 @@
|
||||
{
|
||||
"description": "",
|
||||
"parentMaterial": "",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"materialTypeVersion": 4,
|
||||
"properties": {
|
||||
"baseColor": {
|
||||
"textureMap": "../Textures/floor_1k_basecolor.png"
|
||||
},
|
||||
"clearCoat": {
|
||||
"influenceMap": "../Textures/floor_1k_ao.png",
|
||||
"normalMap": "../Textures/floor_1k_normal.png",
|
||||
"roughness": 0.25
|
||||
},
|
||||
"general": {
|
||||
"applySpecularAA": true
|
||||
},
|
||||
"irradiance": {
|
||||
"color": [
|
||||
1.0,
|
||||
0.9404135346412659,
|
||||
0.8688944578170776,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
"normal": {
|
||||
"textureMap": "../Textures/floor_1k_normal.png"
|
||||
},
|
||||
"occlusion": {
|
||||
"diffuseTextureMap": "../Textures/floor_1k_ao.png"
|
||||
},
|
||||
"opacity": {
|
||||
"factor": 1.0
|
||||
},
|
||||
"parallax": {
|
||||
"factor": 0.012000000104308128,
|
||||
"pdo": true,
|
||||
"useTexture": false
|
||||
},
|
||||
"roughness": {
|
||||
"textureMap": "../Textures/floor_1k_roughness.png"
|
||||
}
|
||||
"propertyValues": {
|
||||
"baseColor.textureMap": "../Textures/floor_1k_basecolor.png",
|
||||
"clearCoat.influenceMap": "../Textures/floor_1k_ao.png",
|
||||
"clearCoat.normalMap": "../Textures/floor_1k_normal.png",
|
||||
"clearCoat.roughness": 0.25,
|
||||
"general.applySpecularAA": true,
|
||||
"irradiance.color": [
|
||||
1.0,
|
||||
0.9404135346412659,
|
||||
0.8688944578170776,
|
||||
1.0
|
||||
],
|
||||
"normal.textureMap": "../Textures/floor_1k_normal.png",
|
||||
"occlusion.diffuseTextureMap": "../Textures/floor_1k_ao.png",
|
||||
"opacity.factor": 1.0,
|
||||
"parallax.factor": 0.012000000104308128,
|
||||
"parallax.pdo": true,
|
||||
"parallax.useTexture": false,
|
||||
"roughness.textureMap": "../Textures/floor_1k_roughness.png"
|
||||
}
|
||||
}
|
||||
@@ -1,43 +1,25 @@
|
||||
{
|
||||
"description": "",
|
||||
"parentMaterial": "",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"materialTypeVersion": 4,
|
||||
"properties": {
|
||||
"baseColor": {
|
||||
"textureMap": "../Textures/thorn_basecolor.png"
|
||||
},
|
||||
"clearCoat": {
|
||||
"factor": 0.05000000074505806,
|
||||
"normalMap": "../Textures/thorn_normal.jpg",
|
||||
"roughness": 0.10000000149011612
|
||||
},
|
||||
"general": {
|
||||
"applySpecularAA": true,
|
||||
"doubleSided": true
|
||||
},
|
||||
"irradiance": {
|
||||
"color": [
|
||||
0.46506446599960327,
|
||||
1.0,
|
||||
0.3944609761238098,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
"normal": {
|
||||
"textureMap": "../Textures/thorn_normal.jpg"
|
||||
},
|
||||
"opacity": {
|
||||
"alphaSource": "Split",
|
||||
"factor": 0.20000000298023224,
|
||||
"mode": "Cutout",
|
||||
"textureMap": "../Textures/thorn_alpha.png"
|
||||
},
|
||||
"parallax": {
|
||||
"useTexture": false
|
||||
},
|
||||
"roughness": {
|
||||
"textureMap": "../Textures/thorn_roughness.png"
|
||||
}
|
||||
"propertyValues": {
|
||||
"baseColor.textureMap": "../Textures/thorn_basecolor.png",
|
||||
"clearCoat.factor": 0.05000000074505806,
|
||||
"clearCoat.normalMap": "../Textures/thorn_normal.jpg",
|
||||
"clearCoat.roughness": 0.10000000149011612,
|
||||
"general.applySpecularAA": true,
|
||||
"general.doubleSided": true,
|
||||
"irradiance.color": [
|
||||
0.46506446599960327,
|
||||
1.0,
|
||||
0.3944609761238098,
|
||||
1.0
|
||||
],
|
||||
"normal.textureMap": "../Textures/thorn_normal.jpg",
|
||||
"opacity.alphaSource": "Split",
|
||||
"opacity.factor": 0.20000000298023224,
|
||||
"opacity.mode": "Cutout",
|
||||
"opacity.textureMap": "../Textures/thorn_alpha.png",
|
||||
"parallax.useTexture": false,
|
||||
"roughness.textureMap": "../Textures/thorn_roughness.png"
|
||||
}
|
||||
}
|
||||
@@ -1,36 +1,22 @@
|
||||
{
|
||||
"description": "",
|
||||
"parentMaterial": "",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"materialTypeVersion": 4,
|
||||
"properties": {
|
||||
"baseColor": {
|
||||
"textureMap": "../Textures/lion_1k_basecolor.png"
|
||||
},
|
||||
"emissive": {
|
||||
"color": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
"irradiance": {
|
||||
"color": [
|
||||
0.5583428740501404,
|
||||
0.496940553188324,
|
||||
0.4125429093837738,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
"normal": {
|
||||
"textureMap": "../Textures/lion_1k_normal.jpg"
|
||||
},
|
||||
"opacity": {
|
||||
"factor": 1.0
|
||||
},
|
||||
"roughness": {
|
||||
"textureMap": "../Textures/lion_1k_roughness.png"
|
||||
}
|
||||
"propertyValues": {
|
||||
"baseColor.textureMap": "../Textures/lion_1k_basecolor.png",
|
||||
"emissive.color": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0
|
||||
],
|
||||
"irradiance.color": [
|
||||
0.5583428740501404,
|
||||
0.496940553188324,
|
||||
0.4125429093837738,
|
||||
1.0
|
||||
],
|
||||
"normal.textureMap": "../Textures/lion_1k_normal.jpg",
|
||||
"opacity.factor": 1.0,
|
||||
"roughness.textureMap": "../Textures/lion_1k_roughness.png"
|
||||
}
|
||||
}
|
||||
@@ -1,47 +1,27 @@
|
||||
{
|
||||
"description": "",
|
||||
"parentMaterial": "",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"materialTypeVersion": 4,
|
||||
"properties": {
|
||||
"baseColor": {
|
||||
"textureBlendMode": "Lerp",
|
||||
"textureMap": "../Textures/roof_1k_basecolor.png"
|
||||
},
|
||||
"general": {
|
||||
"applySpecularAA": true
|
||||
},
|
||||
"irradiance": {
|
||||
"color": [
|
||||
0.29613184928894043,
|
||||
0.3324483036994934,
|
||||
0.45078203082084656,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
"metallic": {
|
||||
"textureMap": "../Textures/roof_1k_metallic.png",
|
||||
"useTexture": false
|
||||
},
|
||||
"normal": {
|
||||
"factor": 0.5,
|
||||
"flipY": true,
|
||||
"textureMap": "../Textures/roof_1k_normal.jpg"
|
||||
},
|
||||
"occlusion": {
|
||||
"diffuseTextureMap": "../Textures/roof_1k_ao.png"
|
||||
},
|
||||
"opacity": {
|
||||
"factor": 1.0
|
||||
},
|
||||
"parallax": {
|
||||
"algorithm": "ContactRefinement",
|
||||
"factor": 0.019999999552965164,
|
||||
"quality": "Medium",
|
||||
"useTexture": false
|
||||
},
|
||||
"roughness": {
|
||||
"textureMap": "../Textures/roof_1k_roughness.png"
|
||||
}
|
||||
"propertyValues": {
|
||||
"baseColor.textureBlendMode": "Lerp",
|
||||
"baseColor.textureMap": "../Textures/roof_1k_basecolor.png",
|
||||
"general.applySpecularAA": true,
|
||||
"irradiance.color": [
|
||||
0.29613184928894043,
|
||||
0.3324483036994934,
|
||||
0.45078203082084656,
|
||||
1.0
|
||||
],
|
||||
"metallic.textureMap": "../Textures/roof_1k_metallic.png",
|
||||
"metallic.useTexture": false,
|
||||
"normal.factor": 0.5,
|
||||
"normal.flipY": true,
|
||||
"normal.textureMap": "../Textures/roof_1k_normal.jpg",
|
||||
"occlusion.diffuseTextureMap": "../Textures/roof_1k_ao.png",
|
||||
"opacity.factor": 1.0,
|
||||
"parallax.algorithm": "ContactRefinement",
|
||||
"parallax.factor": 0.019999999552965164,
|
||||
"parallax.quality": "Medium",
|
||||
"parallax.useTexture": false,
|
||||
"roughness.textureMap": "../Textures/roof_1k_roughness.png"
|
||||
}
|
||||
}
|
||||
@@ -1,46 +1,24 @@
|
||||
{
|
||||
"description": "",
|
||||
"parentMaterial": "",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"materialTypeVersion": 4,
|
||||
"properties": {
|
||||
"baseColor": {
|
||||
"textureMap": "../Textures/vase_1k_basecolor.png"
|
||||
},
|
||||
"general": {
|
||||
"applySpecularAA": true
|
||||
},
|
||||
"irradiance": {
|
||||
"color": [
|
||||
1.0,
|
||||
0.8713664412498474,
|
||||
0.6021667718887329,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
"metallic": {
|
||||
"textureMap": "../Textures/vase_1k_metallic.png"
|
||||
},
|
||||
"normal": {
|
||||
"textureMap": "../Textures/vase_1k_normal.jpg"
|
||||
},
|
||||
"occlusion": {
|
||||
"diffuseTextureMap": "../Textures/vase_1k_ao.png"
|
||||
},
|
||||
"opacity": {
|
||||
"factor": 1.0
|
||||
},
|
||||
"parallax": {
|
||||
"factor": 0.027000000700354576,
|
||||
"pdo": true,
|
||||
"quality": "High",
|
||||
"useTexture": false
|
||||
},
|
||||
"roughness": {
|
||||
"textureMap": "../Textures/vase_1k_roughness.png"
|
||||
},
|
||||
"specularF0": {
|
||||
"enableMultiScatterCompensation": true
|
||||
}
|
||||
"propertyValues": {
|
||||
"baseColor.textureMap": "../Textures/vase_1k_basecolor.png",
|
||||
"general.applySpecularAA": true,
|
||||
"irradiance.color": [
|
||||
1.0,
|
||||
0.8713664412498474,
|
||||
0.6021667718887329,
|
||||
1.0
|
||||
],
|
||||
"metallic.textureMap": "../Textures/vase_1k_metallic.png",
|
||||
"normal.textureMap": "../Textures/vase_1k_normal.jpg",
|
||||
"occlusion.diffuseTextureMap": "../Textures/vase_1k_ao.png",
|
||||
"opacity.factor": 1.0,
|
||||
"parallax.factor": 0.027000000700354576,
|
||||
"parallax.pdo": true,
|
||||
"parallax.quality": "High",
|
||||
"parallax.useTexture": false,
|
||||
"roughness.textureMap": "../Textures/vase_1k_roughness.png",
|
||||
"specularF0.enableMultiScatterCompensation": true
|
||||
}
|
||||
}
|
||||
@@ -1,43 +1,23 @@
|
||||
{
|
||||
"description": "",
|
||||
"parentMaterial": "",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"materialTypeVersion": 4,
|
||||
"properties": {
|
||||
"baseColor": {
|
||||
"textureMap": "../Textures/vaseHanging_1k_basecolor.png"
|
||||
},
|
||||
"general": {
|
||||
"applySpecularAA": true
|
||||
},
|
||||
"irradiance": {
|
||||
"color": [
|
||||
0.765606164932251,
|
||||
1.0,
|
||||
0.7052567601203918,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
"metallic": {
|
||||
"textureMap": "../Textures/vaseHanging_1k_metallic.png"
|
||||
},
|
||||
"normal": {
|
||||
"textureMap": "../Textures/vaseHanging_1k_normal.png"
|
||||
},
|
||||
"occlusion": {
|
||||
"diffuseTextureMap": "../Textures/vaseHanging_1k_ao.png"
|
||||
},
|
||||
"opacity": {
|
||||
"factor": 1.0
|
||||
},
|
||||
"parallax": {
|
||||
"factor": 0.04600000008940697,
|
||||
"pdo": true,
|
||||
"quality": "High",
|
||||
"useTexture": false
|
||||
},
|
||||
"roughness": {
|
||||
"textureMap": "../Textures/vaseHanging_1k_roughness.png"
|
||||
}
|
||||
"propertyValues": {
|
||||
"baseColor.textureMap": "../Textures/vaseHanging_1k_basecolor.png",
|
||||
"general.applySpecularAA": true,
|
||||
"irradiance.color": [
|
||||
0.765606164932251,
|
||||
1.0,
|
||||
0.7052567601203918,
|
||||
1.0
|
||||
],
|
||||
"metallic.textureMap": "../Textures/vaseHanging_1k_metallic.png",
|
||||
"normal.textureMap": "../Textures/vaseHanging_1k_normal.png",
|
||||
"occlusion.diffuseTextureMap": "../Textures/vaseHanging_1k_ao.png",
|
||||
"opacity.factor": 1.0,
|
||||
"parallax.factor": 0.04600000008940697,
|
||||
"parallax.pdo": true,
|
||||
"parallax.quality": "High",
|
||||
"parallax.useTexture": false,
|
||||
"roughness.textureMap": "../Textures/vaseHanging_1k_roughness.png"
|
||||
}
|
||||
}
|
||||
@@ -1,36 +1,26 @@
|
||||
{
|
||||
"description": "",
|
||||
"parentMaterial": "",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"materialTypeVersion": 4,
|
||||
"properties": {
|
||||
"baseColor": {
|
||||
"color": [
|
||||
0.800000011920929,
|
||||
0.800000011920929,
|
||||
0.800000011920929,
|
||||
1.0
|
||||
],
|
||||
"textureBlendMode": "Lerp",
|
||||
"textureMap": "../Textures/vasePlant_1k_basecolor.png"
|
||||
},
|
||||
"general": {
|
||||
"applySpecularAA": true,
|
||||
"doubleSided": true
|
||||
},
|
||||
"irradiance": {
|
||||
"color": [
|
||||
0.09086747467517853,
|
||||
0.4111391007900238,
|
||||
0.0474097803235054,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
"opacity": {
|
||||
"alphaSource": "Split",
|
||||
"factor": 0.23999999463558197,
|
||||
"mode": "Cutout",
|
||||
"textureMap": "../Textures/vasePlant_1k_alpha.png"
|
||||
}
|
||||
"propertyValues": {
|
||||
"baseColor.color": [
|
||||
0.800000011920929,
|
||||
0.800000011920929,
|
||||
0.800000011920929,
|
||||
1.0
|
||||
],
|
||||
"baseColor.textureBlendMode": "Lerp",
|
||||
"baseColor.textureMap": "../Textures/vasePlant_1k_basecolor.png",
|
||||
"general.applySpecularAA": true,
|
||||
"general.doubleSided": true,
|
||||
"irradiance.color": [
|
||||
0.09086747467517853,
|
||||
0.4111391007900238,
|
||||
0.0474097803235054,
|
||||
1.0
|
||||
],
|
||||
"opacity.alphaSource": "Split",
|
||||
"opacity.factor": 0.23999999463558197,
|
||||
"opacity.mode": "Cutout",
|
||||
"opacity.textureMap": "../Textures/vasePlant_1k_alpha.png"
|
||||
}
|
||||
}
|
||||
@@ -1,49 +1,27 @@
|
||||
{
|
||||
"description": "",
|
||||
"parentMaterial": "",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"materialTypeVersion": 4,
|
||||
"properties": {
|
||||
"baseColor": {
|
||||
"textureMap": "../Textures/vaseRound_1k_basecolor.png"
|
||||
},
|
||||
"clearCoat": {
|
||||
"factor": 0.5,
|
||||
"influenceMap": "../Textures/vaseRound_1k_ao.png",
|
||||
"normalMap": "../Textures/vaseRound_1k_normal.jpg",
|
||||
"roughness": 0.25
|
||||
},
|
||||
"general": {
|
||||
"applySpecularAA": true
|
||||
},
|
||||
"irradiance": {
|
||||
"color": [
|
||||
0.46933698654174805,
|
||||
0.3824063539505005,
|
||||
0.47861447930336,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
"normal": {
|
||||
"textureMap": "../Textures/vaseRound_1k_normal.jpg"
|
||||
},
|
||||
"occlusion": {
|
||||
"diffuseTextureMap": "../Textures/vaseRound_1k_ao.png"
|
||||
},
|
||||
"opacity": {
|
||||
"factor": 1.0
|
||||
},
|
||||
"parallax": {
|
||||
"factor": 0.019999999552965164,
|
||||
"pdo": true,
|
||||
"quality": "High",
|
||||
"useTexture": false
|
||||
},
|
||||
"roughness": {
|
||||
"textureMap": "../Textures/vaseRound_1k_roughness.png"
|
||||
},
|
||||
"specularF0": {
|
||||
"enableMultiScatterCompensation": true
|
||||
}
|
||||
"propertyValues": {
|
||||
"baseColor.textureMap": "../Textures/vaseRound_1k_basecolor.png",
|
||||
"clearCoat.factor": 0.5,
|
||||
"clearCoat.influenceMap": "../Textures/vaseRound_1k_ao.png",
|
||||
"clearCoat.normalMap": "../Textures/vaseRound_1k_normal.jpg",
|
||||
"clearCoat.roughness": 0.25,
|
||||
"general.applySpecularAA": true,
|
||||
"irradiance.color": [
|
||||
0.46933698654174805,
|
||||
0.3824063539505005,
|
||||
0.47861447930336,
|
||||
1.0
|
||||
],
|
||||
"normal.textureMap": "../Textures/vaseRound_1k_normal.jpg",
|
||||
"occlusion.diffuseTextureMap": "../Textures/vaseRound_1k_ao.png",
|
||||
"opacity.factor": 1.0,
|
||||
"parallax.factor": 0.019999999552965164,
|
||||
"parallax.pdo": true,
|
||||
"parallax.quality": "High",
|
||||
"parallax.useTexture": false,
|
||||
"roughness.textureMap": "../Textures/vaseRound_1k_roughness.png",
|
||||
"specularF0.enableMultiScatterCompensation": true
|
||||
}
|
||||
}
|
||||
@@ -1,32 +1,26 @@
|
||||
{
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"materialTypeVersion": 1,
|
||||
"properties": {
|
||||
"baseColor": {
|
||||
"color": [ 1.0, 1.0, 1.0 ],
|
||||
"factor": 0.75,
|
||||
"useTexture": false,
|
||||
"textureMap": ""
|
||||
},
|
||||
"metallic": {
|
||||
"factor": 0.0,
|
||||
"useTexture": false,
|
||||
"textureMap": ""
|
||||
},
|
||||
"roughness": {
|
||||
"factor": 0.0,
|
||||
"useTexture": false,
|
||||
"textureMap": ""
|
||||
},
|
||||
"specularF0": {
|
||||
"factor": 0.5,
|
||||
"useTexture": false,
|
||||
"textureMap": ""
|
||||
},
|
||||
"normal": {
|
||||
"factor": 1.0,
|
||||
"useTexture": false,
|
||||
"textureMap": ""
|
||||
}
|
||||
"propertyValues": {
|
||||
"baseColor.color": [
|
||||
1.0,
|
||||
1.0,
|
||||
1.0
|
||||
],
|
||||
"baseColor.factor": 0.75,
|
||||
"baseColor.textureMap": "",
|
||||
"baseColor.useTexture": false,
|
||||
"metallic.factor": 0.0,
|
||||
"metallic.textureMap": "",
|
||||
"metallic.useTexture": false,
|
||||
"normal.factor": 1.0,
|
||||
"normal.textureMap": "",
|
||||
"normal.useTexture": false,
|
||||
"roughness.factor": 0.0,
|
||||
"roughness.textureMap": "",
|
||||
"roughness.useTexture": false,
|
||||
"specularF0.factor": 0.5,
|
||||
"specularF0.textureMap": "",
|
||||
"specularF0.useTexture": false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,9 @@
|
||||
{
|
||||
"parentMaterial": "./basic.material",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"materialTypeVersion": 1,
|
||||
"properties": {
|
||||
"metallic": {
|
||||
"factor": 0.0
|
||||
},
|
||||
"roughness": {
|
||||
"factor": 0.0
|
||||
}
|
||||
"parentMaterial": "./basic.material",
|
||||
"propertyValues": {
|
||||
"metallic.factor": 0.0,
|
||||
"roughness.factor": 0.0
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,9 @@
|
||||
{
|
||||
"parentMaterial": "./basic.material",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"materialTypeVersion": 1,
|
||||
"properties": {
|
||||
"metallic": {
|
||||
"factor": 0.0
|
||||
},
|
||||
"roughness": {
|
||||
"factor": 0.1
|
||||
}
|
||||
"parentMaterial": "./basic.material",
|
||||
"propertyValues": {
|
||||
"metallic.factor": 0.0,
|
||||
"roughness.factor": 0.10000000149011612
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,9 @@
|
||||
{
|
||||
"parentMaterial": "./basic.material",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"materialTypeVersion": 1,
|
||||
"properties": {
|
||||
"metallic": {
|
||||
"factor": 0.0
|
||||
},
|
||||
"roughness": {
|
||||
"factor": 0.2
|
||||
}
|
||||
"parentMaterial": "./basic.material",
|
||||
"propertyValues": {
|
||||
"metallic.factor": 0.0,
|
||||
"roughness.factor": 0.20000000298023224
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,9 @@
|
||||
{
|
||||
"parentMaterial": "./basic.material",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"materialTypeVersion": 1,
|
||||
"properties": {
|
||||
"metallic": {
|
||||
"factor": 0.0
|
||||
},
|
||||
"roughness": {
|
||||
"factor": 0.3
|
||||
}
|
||||
"parentMaterial": "./basic.material",
|
||||
"propertyValues": {
|
||||
"metallic.factor": 0.0,
|
||||
"roughness.factor": 0.30000001192092896
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,9 @@
|
||||
{
|
||||
"parentMaterial": "./basic.material",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"materialTypeVersion": 1,
|
||||
"properties": {
|
||||
"metallic": {
|
||||
"factor": 0.0
|
||||
},
|
||||
"roughness": {
|
||||
"factor": 0.4
|
||||
}
|
||||
"parentMaterial": "./basic.material",
|
||||
"propertyValues": {
|
||||
"metallic.factor": 0.0,
|
||||
"roughness.factor": 0.4000000059604645
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,9 @@
|
||||
{
|
||||
"parentMaterial": "./basic.material",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"materialTypeVersion": 1,
|
||||
"properties": {
|
||||
"metallic": {
|
||||
"factor": 0.0
|
||||
},
|
||||
"roughness": {
|
||||
"factor": 0.5
|
||||
}
|
||||
"parentMaterial": "./basic.material",
|
||||
"propertyValues": {
|
||||
"metallic.factor": 0.0,
|
||||
"roughness.factor": 0.5
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,9 @@
|
||||
{
|
||||
"parentMaterial": "./basic.material",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"materialTypeVersion": 1,
|
||||
"properties": {
|
||||
"metallic": {
|
||||
"factor": 0.0
|
||||
},
|
||||
"roughness": {
|
||||
"factor": 0.6
|
||||
}
|
||||
"parentMaterial": "./basic.material",
|
||||
"propertyValues": {
|
||||
"metallic.factor": 0.0,
|
||||
"roughness.factor": 0.6000000238418579
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,9 @@
|
||||
{
|
||||
"parentMaterial": "./basic.material",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"materialTypeVersion": 1,
|
||||
"properties": {
|
||||
"metallic": {
|
||||
"factor": 0.0
|
||||
},
|
||||
"roughness": {
|
||||
"factor": 0.7
|
||||
}
|
||||
"parentMaterial": "./basic.material",
|
||||
"propertyValues": {
|
||||
"metallic.factor": 0.0,
|
||||
"roughness.factor": 0.699999988079071
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,9 @@
|
||||
{
|
||||
"parentMaterial": "./basic.material",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"materialTypeVersion": 1,
|
||||
"properties": {
|
||||
"metallic": {
|
||||
"factor": 0.0
|
||||
},
|
||||
"roughness": {
|
||||
"factor": 0.8
|
||||
}
|
||||
"parentMaterial": "./basic.material",
|
||||
"propertyValues": {
|
||||
"metallic.factor": 0.0,
|
||||
"roughness.factor": 0.800000011920929
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,9 @@
|
||||
{
|
||||
"parentMaterial": "./basic.material",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"materialTypeVersion": 1,
|
||||
"properties": {
|
||||
"metallic": {
|
||||
"factor": 0.0
|
||||
},
|
||||
"roughness": {
|
||||
"factor": 0.9
|
||||
}
|
||||
"parentMaterial": "./basic.material",
|
||||
"propertyValues": {
|
||||
"metallic.factor": 0.0,
|
||||
"roughness.factor": 0.8999999761581421
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,9 @@
|
||||
{
|
||||
"parentMaterial": "./basic.material",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"materialTypeVersion": 1,
|
||||
"properties": {
|
||||
"metallic": {
|
||||
"factor": 0.0
|
||||
},
|
||||
"roughness": {
|
||||
"factor": 1.0
|
||||
}
|
||||
"parentMaterial": "./basic.material",
|
||||
"propertyValues": {
|
||||
"metallic.factor": 0.0,
|
||||
"roughness.factor": 1.0
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,9 @@
|
||||
{
|
||||
"parentMaterial": "./basic.material",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"materialTypeVersion": 1,
|
||||
"properties": {
|
||||
"metallic": {
|
||||
"factor": 1.0
|
||||
},
|
||||
"roughness": {
|
||||
"factor": 0.0
|
||||
}
|
||||
"parentMaterial": "./basic.material",
|
||||
"propertyValues": {
|
||||
"metallic.factor": 1.0,
|
||||
"roughness.factor": 0.0
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,9 @@
|
||||
{
|
||||
"parentMaterial": "./basic.material",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"materialTypeVersion": 1,
|
||||
"properties": {
|
||||
"metallic": {
|
||||
"factor": 1.0
|
||||
},
|
||||
"roughness": {
|
||||
"factor": 0.1
|
||||
}
|
||||
"parentMaterial": "./basic.material",
|
||||
"propertyValues": {
|
||||
"metallic.factor": 1.0,
|
||||
"roughness.factor": 0.10000000149011612
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,9 @@
|
||||
{
|
||||
"parentMaterial": "./basic.material",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"materialTypeVersion": 1,
|
||||
"properties": {
|
||||
"metallic": {
|
||||
"factor": 1.0
|
||||
},
|
||||
"roughness": {
|
||||
"factor": 0.2
|
||||
}
|
||||
"parentMaterial": "./basic.material",
|
||||
"propertyValues": {
|
||||
"metallic.factor": 1.0,
|
||||
"roughness.factor": 0.20000000298023224
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,9 @@
|
||||
{
|
||||
"parentMaterial": "./basic.material",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"materialTypeVersion": 1,
|
||||
"properties": {
|
||||
"metallic": {
|
||||
"factor": 1.0
|
||||
},
|
||||
"roughness": {
|
||||
"factor": 0.3
|
||||
}
|
||||
"parentMaterial": "./basic.material",
|
||||
"propertyValues": {
|
||||
"metallic.factor": 1.0,
|
||||
"roughness.factor": 0.30000001192092896
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,9 @@
|
||||
{
|
||||
"parentMaterial": "./basic.material",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"materialTypeVersion": 1,
|
||||
"properties": {
|
||||
"metallic": {
|
||||
"factor": 1.0
|
||||
},
|
||||
"roughness": {
|
||||
"factor": 0.4
|
||||
}
|
||||
"parentMaterial": "./basic.material",
|
||||
"propertyValues": {
|
||||
"metallic.factor": 1.0,
|
||||
"roughness.factor": 0.4000000059604645
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,9 @@
|
||||
{
|
||||
"parentMaterial": "./basic.material",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"materialTypeVersion": 1,
|
||||
"properties": {
|
||||
"metallic": {
|
||||
"factor": 1.0
|
||||
},
|
||||
"roughness": {
|
||||
"factor": 0.5
|
||||
}
|
||||
"parentMaterial": "./basic.material",
|
||||
"propertyValues": {
|
||||
"metallic.factor": 1.0,
|
||||
"roughness.factor": 0.5
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,9 @@
|
||||
{
|
||||
"parentMaterial": "./basic.material",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"materialTypeVersion": 1,
|
||||
"properties": {
|
||||
"metallic": {
|
||||
"factor": 1.0
|
||||
},
|
||||
"roughness": {
|
||||
"factor": 0.6
|
||||
}
|
||||
"parentMaterial": "./basic.material",
|
||||
"propertyValues": {
|
||||
"metallic.factor": 1.0,
|
||||
"roughness.factor": 0.6000000238418579
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,9 @@
|
||||
{
|
||||
"parentMaterial": "./basic.material",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"materialTypeVersion": 1,
|
||||
"properties": {
|
||||
"metallic": {
|
||||
"factor": 1.0
|
||||
},
|
||||
"roughness": {
|
||||
"factor": 0.7
|
||||
}
|
||||
"parentMaterial": "./basic.material",
|
||||
"propertyValues": {
|
||||
"metallic.factor": 1.0,
|
||||
"roughness.factor": 0.699999988079071
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,9 @@
|
||||
{
|
||||
"parentMaterial": "./basic.material",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"materialTypeVersion": 1,
|
||||
"properties": {
|
||||
"metallic": {
|
||||
"factor": 1.0
|
||||
},
|
||||
"roughness": {
|
||||
"factor": 0.8
|
||||
}
|
||||
"parentMaterial": "./basic.material",
|
||||
"propertyValues": {
|
||||
"metallic.factor": 1.0,
|
||||
"roughness.factor": 0.800000011920929
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,9 @@
|
||||
{
|
||||
"parentMaterial": "./basic.material",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"materialTypeVersion": 1,
|
||||
"properties": {
|
||||
"metallic": {
|
||||
"factor": 1.0
|
||||
},
|
||||
"roughness": {
|
||||
"factor": 0.9
|
||||
}
|
||||
"parentMaterial": "./basic.material",
|
||||
"propertyValues": {
|
||||
"metallic.factor": 1.0,
|
||||
"roughness.factor": 0.8999999761581421
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,9 @@
|
||||
{
|
||||
"parentMaterial": "./basic.material",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"materialTypeVersion": 1,
|
||||
"properties": {
|
||||
"metallic": {
|
||||
"factor": 1.0
|
||||
},
|
||||
"roughness": {
|
||||
"factor": 1.0
|
||||
}
|
||||
"parentMaterial": "./basic.material",
|
||||
"propertyValues": {
|
||||
"metallic.factor": 1.0,
|
||||
"roughness.factor": 1.0
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
{
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"parentMaterial": "Materials/Presets/PBR/default_grid.material"
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,8 @@
|
||||
{
|
||||
"description": "",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"parentMaterial": "Materials/Presets/PBR/default_grid.material",
|
||||
"materialTypeVersion": 3,
|
||||
"properties": {
|
||||
"opacity": {
|
||||
"mode": "Blended"
|
||||
}
|
||||
"parentMaterial": "Materials/Presets/PBR/default_grid.material",
|
||||
"propertyValues": {
|
||||
"opacity.mode": "Blended"
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,13 @@
|
||||
{
|
||||
"description": "",
|
||||
"parentMaterial": "",
|
||||
"materialType": "TestData/Materials/Types/MinimalPBR.materialtype",
|
||||
"materialTypeVersion": 3,
|
||||
"properties": {
|
||||
"settings": {
|
||||
"color": [
|
||||
0.08522164076566696,
|
||||
0.11898985505104065,
|
||||
1.0,
|
||||
1.0
|
||||
],
|
||||
"roughness": 0.33000001311302185
|
||||
}
|
||||
"propertyValues": {
|
||||
"settings.color": [
|
||||
0.08522164076566696,
|
||||
0.11898985505104065,
|
||||
1.0,
|
||||
1.0
|
||||
],
|
||||
"settings.roughness": 0.33000001311302185
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,3 @@
|
||||
{
|
||||
"materialType": "UVs.materialtype"
|
||||
}
|
||||
}
|
||||
@@ -1,32 +1,26 @@
|
||||
{
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"materialTypeVersion": 1,
|
||||
"properties": {
|
||||
"baseColor": {
|
||||
"color": [ 0.18, 0.18, 0.18 ],
|
||||
"factor": 1.0,
|
||||
"useTexture": false,
|
||||
"textureMap": ""
|
||||
},
|
||||
"metallic": {
|
||||
"factor": 0.0,
|
||||
"useTexture": false,
|
||||
"textureMap": ""
|
||||
},
|
||||
"roughness": {
|
||||
"factor": 1.0,
|
||||
"useTexture": false,
|
||||
"textureMap": ""
|
||||
},
|
||||
"specularF0": {
|
||||
"factor": 0.5,
|
||||
"useTexture": false,
|
||||
"textureMap": ""
|
||||
},
|
||||
"normal": {
|
||||
"factor": 1.0,
|
||||
"useTexture": false,
|
||||
"textureMap": ""
|
||||
}
|
||||
"propertyValues": {
|
||||
"baseColor.color": [
|
||||
0.18000000715255737,
|
||||
0.18000000715255737,
|
||||
0.18000000715255737
|
||||
],
|
||||
"baseColor.factor": 1.0,
|
||||
"baseColor.textureMap": "",
|
||||
"baseColor.useTexture": false,
|
||||
"metallic.factor": 0.0,
|
||||
"metallic.textureMap": "",
|
||||
"metallic.useTexture": false,
|
||||
"normal.factor": 1.0,
|
||||
"normal.textureMap": "",
|
||||
"normal.useTexture": false,
|
||||
"roughness.factor": 1.0,
|
||||
"roughness.textureMap": "",
|
||||
"roughness.useTexture": false,
|
||||
"specularF0.factor": 0.5,
|
||||
"specularF0.textureMap": "",
|
||||
"specularF0.useTexture": false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,36 +1,20 @@
|
||||
{
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"materialTypeVersion": 4,
|
||||
"properties": {
|
||||
"baseColor": {
|
||||
"textureMap": "Materials/decal/airship_symbol_decal.tif"
|
||||
},
|
||||
"general": {
|
||||
"doubleSided": true
|
||||
},
|
||||
"metallic": {
|
||||
"useTexture": false
|
||||
},
|
||||
"normal": {
|
||||
"useTexture": false
|
||||
},
|
||||
"opacity": {
|
||||
"alphaSource": "Split",
|
||||
"factor": 0.6899999976158142,
|
||||
"mode": "Cutout",
|
||||
"textureMap": "Materials/decal/airship_symbol_decal.tif"
|
||||
},
|
||||
"roughness": {
|
||||
"useTexture": false
|
||||
},
|
||||
"specularF0": {
|
||||
"useTexture": false
|
||||
},
|
||||
"uv": {
|
||||
"center": [
|
||||
0.0,
|
||||
1.0
|
||||
]
|
||||
}
|
||||
"propertyValues": {
|
||||
"baseColor.textureMap": "Materials/decal/airship_symbol_decal.tif",
|
||||
"general.doubleSided": true,
|
||||
"metallic.useTexture": false,
|
||||
"normal.useTexture": false,
|
||||
"opacity.alphaSource": "Split",
|
||||
"opacity.factor": 0.6899999976158142,
|
||||
"opacity.mode": "Cutout",
|
||||
"opacity.textureMap": "Materials/decal/airship_symbol_decal.tif",
|
||||
"roughness.useTexture": false,
|
||||
"specularF0.useTexture": false,
|
||||
"uv.center": [
|
||||
0.0,
|
||||
1.0
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,9 @@
|
||||
{
|
||||
"description": "",
|
||||
"materialType": "Materials/Types/Skin.materialtype",
|
||||
"parentMaterial": "",
|
||||
"materialTypeVersion": 3,
|
||||
"properties": {
|
||||
"wrinkleLayers": {
|
||||
"count": 3,
|
||||
"enable": true,
|
||||
"showBlendValues": true
|
||||
}
|
||||
"propertyValues": {
|
||||
"wrinkleLayers.count": 3,
|
||||
"wrinkleLayers.enable": true,
|
||||
"wrinkleLayers.showBlendValues": true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/DOM/DomComparison.h>
|
||||
#include <AzCore/std/containers/queue.h>
|
||||
#include <AzCore/std/containers/unordered_set.h>
|
||||
|
||||
namespace AZ::Dom
|
||||
{
|
||||
PatchUndoRedoInfo GenerateHierarchicalDeltaPatch(
|
||||
const Value& beforeState, const Value& afterState, const DeltaPatchGenerationParameters& params)
|
||||
{
|
||||
PatchUndoRedoInfo patches;
|
||||
|
||||
auto AddPatch = [&patches](PatchOperation op, PatchOperation inverse)
|
||||
{
|
||||
patches.m_forwardPatches.PushBack(AZStd::move(op));
|
||||
patches.m_inversePatches.PushFront(AZStd::move(inverse));
|
||||
};
|
||||
|
||||
AZStd::function<void(const Path&, const Value&, const Value&)> compareValues;
|
||||
|
||||
struct PendingComparison
|
||||
{
|
||||
Path m_path;
|
||||
const Value& m_before;
|
||||
const Value& m_after;
|
||||
|
||||
PendingComparison(Path path, const Value& before, const Value& after)
|
||||
: m_path(AZStd::move(path))
|
||||
, m_before(before)
|
||||
, m_after(after)
|
||||
{
|
||||
}
|
||||
};
|
||||
AZStd::queue<PendingComparison> entriesToCompare;
|
||||
|
||||
AZStd::unordered_set<AZ::Name::Hash> desiredKeys;
|
||||
auto compareObjects = [&](const Path& path, const Value& before, const Value& after)
|
||||
{
|
||||
desiredKeys.clear();
|
||||
Path subPath = path;
|
||||
for (auto it = after.MemberBegin(); it != after.MemberEnd(); ++it)
|
||||
{
|
||||
desiredKeys.insert(it->first.GetHash());
|
||||
subPath.Push(it->first);
|
||||
auto beforeIt = before.FindMember(it->first);
|
||||
if (beforeIt == before.MemberEnd())
|
||||
{
|
||||
AddPatch(PatchOperation::AddOperation(subPath, it->second), PatchOperation::RemoveOperation(subPath));
|
||||
}
|
||||
else
|
||||
{
|
||||
entriesToCompare.emplace(subPath, beforeIt->second, it->second);
|
||||
}
|
||||
subPath.Pop();
|
||||
}
|
||||
|
||||
for (auto it = before.MemberBegin(); it != before.MemberEnd(); ++it)
|
||||
{
|
||||
if (!desiredKeys.contains(it->first.GetHash()))
|
||||
{
|
||||
subPath.Push(it->first);
|
||||
AddPatch(PatchOperation::RemoveOperation(subPath), PatchOperation::AddOperation(subPath, it->second));
|
||||
subPath.Pop();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
auto compareArrays = [&](const Path& path, const Value& before, const Value& after)
|
||||
{
|
||||
const size_t beforeSize = before.ArraySize();
|
||||
const size_t afterSize = after.ArraySize();
|
||||
|
||||
// If more than replaceThreshold values differ, do a replace operation instead
|
||||
if (params.m_replaceThreshold != DeltaPatchGenerationParameters::NoReplace)
|
||||
{
|
||||
size_t changedValueCount = 0;
|
||||
const size_t entriesToEnumerate = AZStd::min(beforeSize, afterSize);
|
||||
for (size_t i = 0; i < entriesToEnumerate; ++i)
|
||||
{
|
||||
if (before[i] != after[i])
|
||||
{
|
||||
++changedValueCount;
|
||||
if (changedValueCount >= params.m_replaceThreshold)
|
||||
{
|
||||
AddPatch(PatchOperation::ReplaceOperation(path, after), PatchOperation::ReplaceOperation(path, before));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Path subPath = path;
|
||||
for (size_t i = 0; i < afterSize; ++i)
|
||||
{
|
||||
if (i >= beforeSize)
|
||||
{
|
||||
subPath.Push(PathEntry(PathEntry::EndOfArrayIndex));
|
||||
AddPatch(PatchOperation::AddOperation(subPath, after[i]), PatchOperation::RemoveOperation(subPath));
|
||||
subPath.Pop();
|
||||
}
|
||||
else
|
||||
{
|
||||
subPath.Push(PathEntry(i));
|
||||
entriesToCompare.emplace(subPath, before[i], after[i]);
|
||||
subPath.Pop();
|
||||
}
|
||||
}
|
||||
|
||||
if (beforeSize > afterSize)
|
||||
{
|
||||
subPath.Push(PathEntry(PathEntry::EndOfArrayIndex));
|
||||
for (size_t i = beforeSize; i > afterSize; --i)
|
||||
{
|
||||
AddPatch(PatchOperation::RemoveOperation(subPath), PatchOperation::AddOperation(subPath, before[i - 1]));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
auto compareNodes = [&](const Path& path, const Value& before, const Value& after)
|
||||
{
|
||||
if (before.GetNodeName() != after.GetNodeName())
|
||||
{
|
||||
AddPatch(PatchOperation::ReplaceOperation(path, after), PatchOperation::ReplaceOperation(path, before));
|
||||
}
|
||||
else
|
||||
{
|
||||
compareObjects(path, before, after);
|
||||
compareArrays(path, before, after);
|
||||
}
|
||||
};
|
||||
|
||||
compareValues = [&](const Path& path, const Value& before, const Value& after)
|
||||
{
|
||||
if (before.GetType() != after.GetType())
|
||||
{
|
||||
AddPatch(PatchOperation::ReplaceOperation(path, after), PatchOperation::ReplaceOperation(path, before));
|
||||
}
|
||||
else if (before == after)
|
||||
{
|
||||
// If a shallow comparison succeeds we're pointing to an identical value or container
|
||||
// and don't need to drill down.
|
||||
return;
|
||||
}
|
||||
else if (before.IsObject())
|
||||
{
|
||||
compareObjects(path, before, after);
|
||||
}
|
||||
else if (before.IsArray())
|
||||
{
|
||||
compareArrays(path, before, after);
|
||||
}
|
||||
else if (before.IsNode())
|
||||
{
|
||||
compareNodes(path, before, after);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddPatch(PatchOperation::ReplaceOperation(path, after), PatchOperation::ReplaceOperation(path, before));
|
||||
}
|
||||
};
|
||||
|
||||
entriesToCompare.emplace(Path(), beforeState, afterState);
|
||||
while (!entriesToCompare.empty())
|
||||
{
|
||||
PendingComparison& comparison = entriesToCompare.front();
|
||||
compareValues(comparison.m_path, comparison.m_before, comparison.m_after);
|
||||
entriesToCompare.pop();
|
||||
}
|
||||
return patches;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/DOM/DomPatch.h>
|
||||
|
||||
namespace AZ::Dom
|
||||
{
|
||||
//! A set of patches for applying a change and doing the inverse operation.
|
||||
struct PatchUndoRedoInfo
|
||||
{
|
||||
Patch m_forwardPatches;
|
||||
Patch m_inversePatches;
|
||||
};
|
||||
|
||||
//! Parameters for GenerateHierarchicalDeltaPatch.
|
||||
struct DeltaPatchGenerationParameters
|
||||
{
|
||||
static constexpr size_t NoReplace = AZStd::numeric_limits<size_t>::max();
|
||||
static constexpr size_t AlwaysFullReplace = 0;
|
||||
|
||||
//! The threshold of changed values in a node or array which, if exceeded, will cause the generation to create an
|
||||
//! entire "replace" oepration instead. If set to NoReplace, no replacement will occur.
|
||||
size_t m_replaceThreshold = 3;
|
||||
};
|
||||
|
||||
//! Generates a set of patches such that m_forwardPatches.Apply(beforeState) shall produce a document equivalent to afterState, and
|
||||
//! a subsequent m_inversePatches.Apply(beforeState) shall produce the original document. This patch generation strategy does a
|
||||
//! hierarchical comparison and is not guaranteed to create the minimal set of patches required to transform between the two states.
|
||||
PatchUndoRedoInfo GenerateHierarchicalDeltaPatch(const Value& beforeState, const Value& afterState, const DeltaPatchGenerationParameters& params = {});
|
||||
} // namespace AZ::Dom
|
||||
@@ -0,0 +1,799 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/DOM/DomPatch.h>
|
||||
#include <AzCore/DOM/DomUtils.h>
|
||||
|
||||
namespace AZ::Dom
|
||||
{
|
||||
PatchOperation::PatchOperation(Path destinationPath, Type type, Value value)
|
||||
: m_domPath(AZStd::move(destinationPath))
|
||||
, m_type(type)
|
||||
, m_value(AZStd::move(value))
|
||||
{
|
||||
}
|
||||
|
||||
PatchOperation::PatchOperation(Path destinationPath, Type type, Path sourcePath)
|
||||
: m_domPath(AZStd::move(destinationPath))
|
||||
, m_type(type)
|
||||
, m_value(AZStd::move(sourcePath))
|
||||
{
|
||||
}
|
||||
|
||||
PatchOperation::PatchOperation(Path destinationPath, Type type)
|
||||
: m_domPath(AZStd::move(destinationPath))
|
||||
, m_type(type)
|
||||
{
|
||||
}
|
||||
|
||||
bool PatchOperation::operator==(const PatchOperation& rhs) const
|
||||
{
|
||||
if (m_type != rhs.m_type)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (m_type)
|
||||
{
|
||||
case Type::Add:
|
||||
return m_domPath == rhs.m_domPath && Utils::DeepCompareIsEqual(GetValue(), rhs.GetValue());
|
||||
case Type::Remove:
|
||||
return m_domPath == rhs.m_domPath;
|
||||
case Type::Replace:
|
||||
return m_domPath == rhs.m_domPath && Utils::DeepCompareIsEqual(GetValue(), rhs.GetValue());
|
||||
case Type::Copy:
|
||||
return m_domPath == rhs.m_domPath && GetSourcePath() == rhs.GetSourcePath();
|
||||
case Type::Move:
|
||||
return m_domPath == rhs.m_domPath && GetSourcePath() == rhs.GetSourcePath();
|
||||
case Type::Test:
|
||||
return m_domPath == rhs.m_domPath && Utils::DeepCompareIsEqual(GetValue(), rhs.GetValue());
|
||||
default:
|
||||
AZ_Assert(false, "PatchOperation::GetDomRepresentation: invalid patch type specified");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool PatchOperation::operator!=(const PatchOperation& rhs) const
|
||||
{
|
||||
return !operator==(rhs);
|
||||
}
|
||||
|
||||
PatchOperation::Type PatchOperation::GetType() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
void PatchOperation::SetType(Type type)
|
||||
{
|
||||
m_type = type;
|
||||
}
|
||||
|
||||
const Path& PatchOperation::GetDestinationPath() const
|
||||
{
|
||||
return m_domPath;
|
||||
}
|
||||
|
||||
void PatchOperation::SetDestinationPath(Path path)
|
||||
{
|
||||
m_domPath = path;
|
||||
}
|
||||
|
||||
const Value& PatchOperation::GetValue() const
|
||||
{
|
||||
return AZStd::get<Value>(m_value);
|
||||
}
|
||||
|
||||
void PatchOperation::SetValue(Value value)
|
||||
{
|
||||
m_value = AZStd::move(value);
|
||||
}
|
||||
|
||||
const Path& PatchOperation::GetSourcePath() const
|
||||
{
|
||||
return AZStd::get<Path>(m_value);
|
||||
}
|
||||
|
||||
void PatchOperation::SetSourcePath(Path path)
|
||||
{
|
||||
m_value = AZStd::move(path);
|
||||
}
|
||||
|
||||
AZ::Outcome<Value, AZStd::string> PatchOperation::Apply(Value rootElement) const
|
||||
{
|
||||
PatchOutcome outcome = ApplyInPlace(rootElement);
|
||||
if (!outcome.IsSuccess())
|
||||
{
|
||||
return AZ::Failure(outcome.TakeError());
|
||||
}
|
||||
return AZ::Success(AZStd::move(rootElement));
|
||||
}
|
||||
|
||||
PatchOperation::PatchOutcome PatchOperation::ApplyInPlace(Value& rootElement) const
|
||||
{
|
||||
switch (m_type)
|
||||
{
|
||||
case Type::Add:
|
||||
return ApplyAdd(rootElement);
|
||||
case Type::Remove:
|
||||
return ApplyRemove(rootElement);
|
||||
case Type::Replace:
|
||||
return ApplyReplace(rootElement);
|
||||
case Type::Copy:
|
||||
return ApplyCopy(rootElement);
|
||||
case Type::Move:
|
||||
return ApplyMove(rootElement);
|
||||
case Type::Test:
|
||||
return ApplyTest(rootElement);
|
||||
}
|
||||
return AZ::Failure<AZStd::string>("Unsupported DOM patch operation specified");
|
||||
}
|
||||
|
||||
Value PatchOperation::GetDomRepresentation() const
|
||||
{
|
||||
Value serializedPatch(Dom::Type::Object);
|
||||
switch (m_type)
|
||||
{
|
||||
case Type::Add:
|
||||
serializedPatch["op"].SetString("add");
|
||||
serializedPatch["path"].CopyFromString(GetDestinationPath().ToString());
|
||||
serializedPatch["value"] = GetValue();
|
||||
break;
|
||||
case Type::Remove:
|
||||
serializedPatch["op"].SetString("remove");
|
||||
serializedPatch["path"].CopyFromString(GetDestinationPath().ToString());
|
||||
break;
|
||||
case Type::Replace:
|
||||
serializedPatch["op"].SetString("replace");
|
||||
serializedPatch["path"].CopyFromString(GetDestinationPath().ToString());
|
||||
serializedPatch["value"] = GetValue();
|
||||
break;
|
||||
case Type::Copy:
|
||||
serializedPatch["op"].SetString("copy");
|
||||
serializedPatch["from"].CopyFromString(GetSourcePath().ToString());
|
||||
serializedPatch["path"].CopyFromString(GetDestinationPath().ToString());
|
||||
break;
|
||||
case Type::Move:
|
||||
serializedPatch["op"].SetString("move");
|
||||
serializedPatch["from"].CopyFromString(GetSourcePath().ToString());
|
||||
serializedPatch["path"].CopyFromString(GetDestinationPath().ToString());
|
||||
break;
|
||||
case Type::Test:
|
||||
serializedPatch["op"].SetString("test");
|
||||
serializedPatch["path"].CopyFromString(GetDestinationPath().ToString());
|
||||
serializedPatch["value"] = GetValue();
|
||||
break;
|
||||
default:
|
||||
AZ_Assert(false, "PatchOperation::GetDomRepresentation: invalid patch type specified");
|
||||
}
|
||||
return serializedPatch;
|
||||
}
|
||||
|
||||
AZ::Outcome<PatchOperation, AZStd::string> PatchOperation::CreateFromDomRepresentation(Value domValue)
|
||||
{
|
||||
if (!domValue.IsObject())
|
||||
{
|
||||
return AZ::Failure<AZStd::string>("PatchOperation failed to load: PatchOperation must be specified as an Object");
|
||||
}
|
||||
|
||||
auto loadField = [&](const char* field, AZStd::optional<Dom::Type> type = {}) -> AZ::Outcome<Value, AZStd::string>
|
||||
{
|
||||
auto it = domValue.FindMember(field);
|
||||
if (it == domValue.MemberEnd())
|
||||
{
|
||||
return AZ::Failure(AZStd::string::format("PatchOperation failed to load: no \"%s\" specified", field));
|
||||
}
|
||||
|
||||
if (type.has_value() && it->second.GetType() != type)
|
||||
{
|
||||
return AZ::Failure(AZStd::string::format("PatchOperation failed to load: \"%s\" is invalid", field));
|
||||
}
|
||||
|
||||
return AZ::Success(it->second);
|
||||
};
|
||||
|
||||
auto opLoad = loadField("op", Dom::Type::String);
|
||||
if (!opLoad.IsSuccess())
|
||||
{
|
||||
return AZ::Failure(opLoad.TakeError());
|
||||
}
|
||||
AZStd::string_view op = opLoad.GetValue().GetString();
|
||||
if (op == "add")
|
||||
{
|
||||
auto pathLoad = loadField("path", Dom::Type::String);
|
||||
if (!pathLoad.IsSuccess())
|
||||
{
|
||||
return AZ::Failure(pathLoad.TakeError());
|
||||
}
|
||||
auto valueLoad = loadField("value");
|
||||
if (!valueLoad.IsSuccess())
|
||||
{
|
||||
return AZ::Failure(valueLoad.TakeError());
|
||||
}
|
||||
|
||||
return AZ::Success(PatchOperation::AddOperation(Path(pathLoad.GetValue().GetString()), valueLoad.TakeValue()));
|
||||
}
|
||||
else if (op == "remove")
|
||||
{
|
||||
auto pathLoad = loadField("path", Dom::Type::String);
|
||||
if (!pathLoad.IsSuccess())
|
||||
{
|
||||
return AZ::Failure(pathLoad.TakeError());
|
||||
}
|
||||
|
||||
return AZ::Success(PatchOperation::RemoveOperation(Path(pathLoad.GetValue().GetString())));
|
||||
}
|
||||
else if (op == "replace")
|
||||
{
|
||||
auto pathLoad = loadField("path", Dom::Type::String);
|
||||
if (!pathLoad.IsSuccess())
|
||||
{
|
||||
return AZ::Failure(pathLoad.TakeError());
|
||||
}
|
||||
auto valueLoad = loadField("value");
|
||||
if (!valueLoad.IsSuccess())
|
||||
{
|
||||
return AZ::Failure(valueLoad.TakeError());
|
||||
}
|
||||
|
||||
return AZ::Success(PatchOperation::ReplaceOperation(Path(pathLoad.GetValue().GetString()), valueLoad.TakeValue()));
|
||||
}
|
||||
else if (op == "copy")
|
||||
{
|
||||
auto destLoad = loadField("path", Dom::Type::String);
|
||||
if (!destLoad.IsSuccess())
|
||||
{
|
||||
return AZ::Failure(destLoad.TakeError());
|
||||
}
|
||||
auto sourceLoad = loadField("from", Dom::Type::String);
|
||||
if (!sourceLoad.IsSuccess())
|
||||
{
|
||||
return AZ::Failure(sourceLoad.TakeError());
|
||||
}
|
||||
|
||||
return AZ::Success(
|
||||
PatchOperation::CopyOperation(Path(destLoad.GetValue().GetString()), Path(sourceLoad.GetValue().GetString())));
|
||||
}
|
||||
else if (op == "move")
|
||||
{
|
||||
auto destLoad = loadField("path", Dom::Type::String);
|
||||
if (!destLoad.IsSuccess())
|
||||
{
|
||||
return AZ::Failure(destLoad.TakeError());
|
||||
}
|
||||
auto sourceLoad = loadField("from", Dom::Type::String);
|
||||
if (!sourceLoad.IsSuccess())
|
||||
{
|
||||
return AZ::Failure(sourceLoad.TakeError());
|
||||
}
|
||||
|
||||
return AZ::Success(
|
||||
PatchOperation::MoveOperation(Path(destLoad.GetValue().GetString()), Path(sourceLoad.GetValue().GetString())));
|
||||
}
|
||||
else if (op == "test")
|
||||
{
|
||||
auto pathLoad = loadField("path", Dom::Type::String);
|
||||
if (!pathLoad.IsSuccess())
|
||||
{
|
||||
return AZ::Failure(pathLoad.TakeError());
|
||||
}
|
||||
auto valueLoad = loadField("value");
|
||||
if (!valueLoad.IsSuccess())
|
||||
{
|
||||
return AZ::Failure(valueLoad.TakeError());
|
||||
}
|
||||
|
||||
return AZ::Success(PatchOperation::TestOperation(Path(pathLoad.GetValue().GetString()), valueLoad.TakeValue()));
|
||||
}
|
||||
else
|
||||
{
|
||||
return AZ::Failure<AZStd::string>("PatchOperation failed to create DOM representation: invalid \"op\" specified");
|
||||
}
|
||||
}
|
||||
|
||||
AZ::Outcome<AZStd::fixed_vector<PatchOperation, 2>, AZStd::string> PatchOperation::GetInverse(Value stateBeforeApplication) const
|
||||
{
|
||||
switch (m_type)
|
||||
{
|
||||
case Type::Add:
|
||||
{
|
||||
// Add -> Replace (if value already existed in an object) otherwise
|
||||
// Add -> Remove
|
||||
if (m_domPath.Size() > 0 && m_domPath[m_domPath.Size() - 1].IsKey())
|
||||
{
|
||||
const Value* existingValue = stateBeforeApplication.FindChild(m_domPath);
|
||||
if (existingValue != nullptr)
|
||||
{
|
||||
return AZ::Success<InversePatches>({PatchOperation::ReplaceOperation(m_domPath, *existingValue)});
|
||||
}
|
||||
}
|
||||
return AZ::Success<InversePatches>({PatchOperation::RemoveOperation(m_domPath)});
|
||||
}
|
||||
case Type::Remove:
|
||||
{
|
||||
// Remove -> Add
|
||||
const Value* existingValue = stateBeforeApplication.FindChild(m_domPath);
|
||||
if (existingValue == nullptr)
|
||||
{
|
||||
AZStd::string errorMessage = "Unable to invert DOM remove patch, source path not found: ";
|
||||
m_domPath.AppendToString(errorMessage);
|
||||
return AZ::Failure(AZStd::move(errorMessage));
|
||||
}
|
||||
return AZ::Success<InversePatches>({PatchOperation::AddOperation(m_domPath, *existingValue)});
|
||||
}
|
||||
case Type::Replace:
|
||||
{
|
||||
// Replace -> Replace (with old value)
|
||||
const Value* existingValue = stateBeforeApplication.FindChild(m_domPath);
|
||||
if (existingValue == nullptr)
|
||||
{
|
||||
AZStd::string errorMessage = "Unable to invert DOM replace patch, source path not found: ";
|
||||
m_domPath.AppendToString(errorMessage);
|
||||
return AZ::Failure(AZStd::move(errorMessage));
|
||||
}
|
||||
return AZ::Success<InversePatches>({PatchOperation::ReplaceOperation(m_domPath, *existingValue)});
|
||||
}
|
||||
case Type::Copy:
|
||||
{
|
||||
// Copy -> Replace (with old value)
|
||||
const Value* existingValue = stateBeforeApplication.FindChild(m_domPath);
|
||||
if (existingValue == nullptr)
|
||||
{
|
||||
AZStd::string errorMessage = "Unable to invert DOM copy patch, source path not found: ";
|
||||
m_domPath.AppendToString(errorMessage);
|
||||
return AZ::Failure(AZStd::move(errorMessage));
|
||||
}
|
||||
return AZ::Success<InversePatches>({PatchOperation::ReplaceOperation(m_domPath, *existingValue)});
|
||||
}
|
||||
case Type::Move:
|
||||
{
|
||||
const Value* sourceValue = stateBeforeApplication.FindChild(GetSourcePath());
|
||||
if (sourceValue == nullptr)
|
||||
{
|
||||
AZStd::string errorMessage = "Unable to invert DOM copy patch, source path not found: ";
|
||||
m_domPath.AppendToString(errorMessage);
|
||||
return AZ::Failure(AZStd::move(errorMessage));
|
||||
}
|
||||
|
||||
// If there was a value at the destination path, invert with an add / replace
|
||||
const Value* destinationValue = stateBeforeApplication.FindChild(GetDestinationPath());
|
||||
if (destinationValue != nullptr)
|
||||
{
|
||||
InversePatches result({PatchOperation::AddOperation(GetSourcePath(), *sourceValue)});
|
||||
result.push_back(PatchOperation::ReplaceOperation(GetDestinationPath(), *destinationValue));
|
||||
return AZ::Success<InversePatches>({
|
||||
PatchOperation::AddOperation(GetSourcePath(), *sourceValue),
|
||||
PatchOperation::ReplaceOperation(GetDestinationPath(), *destinationValue),
|
||||
});
|
||||
}
|
||||
// Otherwise, just do a move
|
||||
return AZ::Success<InversePatches>({PatchOperation::MoveOperation(GetDestinationPath(), GetSourcePath())});
|
||||
}
|
||||
case Type::Test:
|
||||
{
|
||||
// Test -> Test (no change)
|
||||
// When inverting a sequence of patches, applying them in reverse order should allow the test to continue to succeed
|
||||
return AZ::Success<InversePatches>({*this});
|
||||
}
|
||||
}
|
||||
return AZ::Failure<AZStd::string>("Unable to invert DOM patch, unknown type specified");
|
||||
}
|
||||
|
||||
AZ::Outcome<PatchOperation::PathContext, AZStd::string> PatchOperation::LookupPath(
|
||||
Value& rootElement, const Path& path, ExistenceCheckFlags flags)
|
||||
{
|
||||
const bool verifyFullPath = (flags & ExistenceCheckFlags::VerifyFullPath) != ExistenceCheckFlags::DefaultExistenceCheck;
|
||||
const bool allowEndOfArray = (flags & ExistenceCheckFlags::AllowEndOfArray) != ExistenceCheckFlags::DefaultExistenceCheck;
|
||||
|
||||
Path target = path;
|
||||
if (target.IsEmpty())
|
||||
{
|
||||
Value wrapper(Dom::Type::Array);
|
||||
wrapper.ArrayPushBack(rootElement);
|
||||
return AZ::Success<PathContext>({ wrapper, PathEntry(0) });
|
||||
}
|
||||
|
||||
if (verifyFullPath || !allowEndOfArray)
|
||||
{
|
||||
for (size_t i = 0; i < path.Size(); ++i)
|
||||
{
|
||||
const PathEntry& entry = path[i];
|
||||
if (entry.IsEndOfArray() && (!allowEndOfArray || i != path.Size() - 1))
|
||||
{
|
||||
return AZ::Failure<AZStd::string>("Append to array index (\"-\") specified for path that must already exist");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PathEntry destinationIndex = target[target.Size() - 1];
|
||||
target.Pop();
|
||||
|
||||
Value* targetValue = rootElement.FindMutableChild(target);
|
||||
if (targetValue == nullptr)
|
||||
{
|
||||
AZStd::string errorMessage = "Path not found: ";
|
||||
target.AppendToString(errorMessage);
|
||||
return AZ::Failure(AZStd::move(errorMessage));
|
||||
}
|
||||
|
||||
if (destinationIndex.IsIndex() || destinationIndex.IsEndOfArray())
|
||||
{
|
||||
if (!targetValue->IsArray() && !targetValue->IsNode())
|
||||
{
|
||||
return AZ::Failure<AZStd::string>("Array index specified for a value that is not an array or node");
|
||||
}
|
||||
|
||||
if (destinationIndex.IsIndex() && destinationIndex.GetIndex() >= targetValue->ArraySize())
|
||||
{
|
||||
return AZ::Failure<AZStd::string>("Array index out bounds");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!targetValue->IsObject() && !targetValue->IsNode())
|
||||
{
|
||||
return AZ::Failure<AZStd::string>("Key specified for a value that is not an object or node");
|
||||
}
|
||||
|
||||
if (verifyFullPath)
|
||||
{
|
||||
if (auto it = targetValue->FindMember(destinationIndex.GetKey()); it == targetValue->MemberEnd())
|
||||
{
|
||||
return AZ::Failure<AZStd::string>("Key not found in container");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return AZ::Success<PathContext>({ *targetValue, AZStd::move(destinationIndex) });
|
||||
}
|
||||
|
||||
PatchOperation::PatchOutcome PatchOperation::ApplyAdd(Value& rootElement) const
|
||||
{
|
||||
auto pathLookup = LookupPath(rootElement, m_domPath, ExistenceCheckFlags::AllowEndOfArray);
|
||||
if (!pathLookup.IsSuccess())
|
||||
{
|
||||
return AZ::Failure(pathLookup.TakeError());
|
||||
}
|
||||
const PathContext& context = pathLookup.GetValue();
|
||||
const PathEntry& destinationIndex = context.m_key;
|
||||
Value& targetValue = context.m_value;
|
||||
|
||||
if (destinationIndex.IsIndex() || destinationIndex.IsEndOfArray())
|
||||
{
|
||||
if (destinationIndex.IsEndOfArray())
|
||||
{
|
||||
targetValue.ArrayPushBack(GetValue());
|
||||
}
|
||||
else
|
||||
{
|
||||
const size_t index = destinationIndex.GetIndex();
|
||||
auto& arrayToChange = targetValue.GetMutableArray();
|
||||
arrayToChange.insert(arrayToChange.begin() + index, GetValue());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
targetValue[destinationIndex] = GetValue();
|
||||
}
|
||||
return AZ::Success();
|
||||
}
|
||||
|
||||
PatchOperation::PatchOutcome PatchOperation::ApplyRemove(Value& rootElement) const
|
||||
{
|
||||
auto pathLookup = LookupPath(rootElement, m_domPath, ExistenceCheckFlags::VerifyFullPath | ExistenceCheckFlags::AllowEndOfArray);
|
||||
if (!pathLookup.IsSuccess())
|
||||
{
|
||||
return AZ::Failure(pathLookup.TakeError());
|
||||
}
|
||||
const PathContext& context = pathLookup.GetValue();
|
||||
const PathEntry& destinationIndex = context.m_key;
|
||||
Value& targetValue = context.m_value;
|
||||
|
||||
if (destinationIndex.IsIndex() || destinationIndex.IsEndOfArray())
|
||||
{
|
||||
size_t index = destinationIndex.IsEndOfArray() ? targetValue.ArraySize() - 1 : destinationIndex.GetIndex();
|
||||
targetValue.ArrayErase(targetValue.MutableArrayBegin() + index);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto it = targetValue.FindMutableMember(destinationIndex.GetKey());
|
||||
targetValue.EraseMember(it);
|
||||
}
|
||||
return AZ::Success();
|
||||
}
|
||||
|
||||
PatchOperation::PatchOutcome PatchOperation::ApplyReplace(Value& rootElement) const
|
||||
{
|
||||
auto pathLookup = LookupPath(rootElement, m_domPath, ExistenceCheckFlags::VerifyFullPath);
|
||||
if (!pathLookup.IsSuccess())
|
||||
{
|
||||
return AZ::Failure(pathLookup.TakeError());
|
||||
}
|
||||
|
||||
rootElement[m_domPath] = GetValue();
|
||||
return AZ::Success();
|
||||
}
|
||||
|
||||
PatchOperation::PatchOutcome PatchOperation::ApplyCopy(Value& rootElement) const
|
||||
{
|
||||
auto sourceLookup = LookupPath(rootElement, GetSourcePath(), ExistenceCheckFlags::VerifyFullPath);
|
||||
if (!sourceLookup.IsSuccess())
|
||||
{
|
||||
return AZ::Failure(sourceLookup.TakeError());
|
||||
}
|
||||
|
||||
auto destLookup = LookupPath(rootElement, m_domPath, ExistenceCheckFlags::AllowEndOfArray);
|
||||
if (!destLookup.IsSuccess())
|
||||
{
|
||||
return AZ::Failure(destLookup.TakeError());
|
||||
}
|
||||
|
||||
rootElement[m_domPath] = rootElement[GetSourcePath()];
|
||||
return AZ::Success();
|
||||
}
|
||||
|
||||
PatchOperation::PatchOutcome PatchOperation::ApplyMove(Value& rootElement) const
|
||||
{
|
||||
auto sourceLookup = LookupPath(rootElement, GetSourcePath(), ExistenceCheckFlags::VerifyFullPath);
|
||||
if (!sourceLookup.IsSuccess())
|
||||
{
|
||||
return AZ::Failure(sourceLookup.TakeError());
|
||||
}
|
||||
|
||||
auto destLookup = LookupPath(rootElement, m_domPath, ExistenceCheckFlags::AllowEndOfArray);
|
||||
if (!destLookup.IsSuccess())
|
||||
{
|
||||
return AZ::Failure(destLookup.TakeError());
|
||||
}
|
||||
|
||||
Value valueToMove = rootElement[GetSourcePath()];
|
||||
const PathContext& sourceContext = sourceLookup.GetValue();
|
||||
if (sourceContext.m_key.IsEndOfArray())
|
||||
{
|
||||
sourceContext.m_value.ArrayPopBack();
|
||||
}
|
||||
else if (sourceContext.m_key.IsIndex())
|
||||
{
|
||||
sourceContext.m_value.ArrayErase(sourceContext.m_value.MutableArrayBegin() + sourceContext.m_key.GetIndex());
|
||||
}
|
||||
else
|
||||
{
|
||||
sourceContext.m_value.EraseMember(sourceContext.m_key.GetKey());
|
||||
}
|
||||
|
||||
rootElement[m_domPath] = AZStd::move(valueToMove);
|
||||
return AZ::Success();
|
||||
}
|
||||
|
||||
PatchOperation::PatchOutcome PatchOperation::ApplyTest(Value& rootElement) const
|
||||
{
|
||||
auto pathLookup = LookupPath(rootElement, m_domPath, ExistenceCheckFlags::VerifyFullPath);
|
||||
if (!pathLookup.IsSuccess())
|
||||
{
|
||||
return AZ::Failure(pathLookup.TakeError());
|
||||
}
|
||||
|
||||
if (!Utils::DeepCompareIsEqual(rootElement[m_domPath], GetValue()))
|
||||
{
|
||||
return AZ::Failure<AZStd::string>("Test failed, values don't match");
|
||||
}
|
||||
|
||||
return AZ::Success();
|
||||
}
|
||||
|
||||
namespace PatchApplicationStrategy
|
||||
{
|
||||
void HaltOnFailure(PatchApplicationState& state)
|
||||
{
|
||||
if (!state.m_outcome.IsSuccess())
|
||||
{
|
||||
state.m_shouldContinue = false;
|
||||
}
|
||||
}
|
||||
|
||||
void IgnoreFailureAndContinue([[maybe_unused]] PatchApplicationState& state)
|
||||
{
|
||||
}
|
||||
} // namespace PatchApplicationStrategy
|
||||
|
||||
Patch::Patch(AZStd::initializer_list<PatchOperation> init)
|
||||
: m_operations(init)
|
||||
{
|
||||
}
|
||||
|
||||
bool Patch::operator==(const Patch& rhs) const
|
||||
{
|
||||
if (m_operations.size() != rhs.m_operations.size())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < m_operations.size(); ++i)
|
||||
{
|
||||
if (m_operations[i] != rhs.m_operations[i])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Patch::operator!=(const Patch& rhs) const
|
||||
{
|
||||
return !operator==(rhs);
|
||||
}
|
||||
|
||||
const Patch::OperationsContainer& Patch::GetOperations() const
|
||||
{
|
||||
return m_operations;
|
||||
}
|
||||
|
||||
void Patch::PushBack(PatchOperation op)
|
||||
{
|
||||
m_operations.push_back(AZStd::move(op));
|
||||
}
|
||||
|
||||
void Patch::PushFront(PatchOperation op)
|
||||
{
|
||||
m_operations.insert(m_operations.begin(), AZStd::move(op));
|
||||
}
|
||||
|
||||
void Patch::Pop()
|
||||
{
|
||||
m_operations.pop_back();
|
||||
}
|
||||
|
||||
void Patch::Clear()
|
||||
{
|
||||
m_operations.clear();
|
||||
}
|
||||
|
||||
const PatchOperation& Patch::At(size_t index) const
|
||||
{
|
||||
return m_operations[index];
|
||||
}
|
||||
|
||||
size_t Patch::Size() const
|
||||
{
|
||||
return m_operations.size();
|
||||
}
|
||||
|
||||
PatchOperation& Patch::operator[](size_t index)
|
||||
{
|
||||
return m_operations[index];
|
||||
}
|
||||
|
||||
const PatchOperation& Patch::operator[](size_t index) const
|
||||
{
|
||||
return m_operations[index];
|
||||
}
|
||||
|
||||
auto Patch::begin() -> OperationsContainer::iterator
|
||||
{
|
||||
return m_operations.begin();
|
||||
}
|
||||
|
||||
auto Patch::end() -> OperationsContainer::iterator
|
||||
{
|
||||
return m_operations.end();
|
||||
}
|
||||
|
||||
auto Patch::begin() const -> OperationsContainer::const_iterator
|
||||
{
|
||||
return m_operations.begin();
|
||||
}
|
||||
|
||||
auto Patch::end() const -> OperationsContainer::const_iterator
|
||||
{
|
||||
return m_operations.end();
|
||||
}
|
||||
|
||||
auto Patch::cbegin() const -> OperationsContainer::const_iterator
|
||||
{
|
||||
return m_operations.begin();
|
||||
}
|
||||
|
||||
auto Patch::cend() const -> OperationsContainer::const_iterator
|
||||
{
|
||||
return m_operations.end();
|
||||
}
|
||||
|
||||
size_t Patch::size() const
|
||||
{
|
||||
return m_operations.size();
|
||||
}
|
||||
|
||||
AZ::Outcome<Value, AZStd::string> Patch::Apply(Value rootElement, StrategyFunctor strategy) const
|
||||
{
|
||||
auto result = ApplyInPlace(rootElement, strategy);
|
||||
if (!result.IsSuccess())
|
||||
{
|
||||
return AZ::Failure(result.TakeError());
|
||||
}
|
||||
return AZ::Success(AZStd::move(rootElement));
|
||||
}
|
||||
|
||||
AZ::Outcome<void, AZStd::string> Patch::ApplyInPlace(Value& rootElement, StrategyFunctor strategy) const
|
||||
{
|
||||
PatchApplicationState state;
|
||||
state.m_currentState = &rootElement;
|
||||
state.m_patch = this;
|
||||
|
||||
for (const PatchOperation& operation : m_operations)
|
||||
{
|
||||
state.m_lastOperation = &operation;
|
||||
state.m_outcome = operation.ApplyInPlace(rootElement);
|
||||
strategy(state);
|
||||
if (!state.m_shouldContinue)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return state.m_outcome;
|
||||
}
|
||||
|
||||
Value Patch::GetDomRepresentation() const
|
||||
{
|
||||
Value domValue(Dom::Type::Array);
|
||||
for (const PatchOperation& operation : m_operations)
|
||||
{
|
||||
domValue.ArrayPushBack(operation.GetDomRepresentation());
|
||||
}
|
||||
return domValue;
|
||||
}
|
||||
|
||||
AZ::Outcome<Patch, AZStd::string> Patch::CreateFromDomRepresentation(Value domValue)
|
||||
{
|
||||
if (!domValue.IsArray())
|
||||
{
|
||||
return AZ::Failure<AZStd::string>("Patch must be an array");
|
||||
}
|
||||
|
||||
Patch patch;
|
||||
for (auto it = domValue.ArrayBegin(); it != domValue.ArrayEnd(); ++it)
|
||||
{
|
||||
auto operationLoadResult = PatchOperation::CreateFromDomRepresentation(*it);
|
||||
if (!operationLoadResult.IsSuccess())
|
||||
{
|
||||
return AZ::Failure(operationLoadResult.TakeError());
|
||||
}
|
||||
patch.PushBack(operationLoadResult.TakeValue());
|
||||
}
|
||||
return AZ::Success(AZStd::move(patch));
|
||||
}
|
||||
|
||||
PatchOperation PatchOperation::AddOperation(Path destinationPath, Value value)
|
||||
{
|
||||
return PatchOperation(AZStd::move(destinationPath), PatchOperation::Type::Add, AZStd::move(value));
|
||||
}
|
||||
|
||||
PatchOperation PatchOperation::RemoveOperation(Path pathToRemove)
|
||||
{
|
||||
return PatchOperation(AZStd::move(pathToRemove), PatchOperation::Type::Remove);
|
||||
}
|
||||
|
||||
PatchOperation PatchOperation::ReplaceOperation(Path destinationPath, Value value)
|
||||
{
|
||||
return PatchOperation(AZStd::move(destinationPath), PatchOperation::Type::Replace, AZStd::move(value));
|
||||
}
|
||||
|
||||
PatchOperation PatchOperation::CopyOperation(Path destinationPath, Path sourcePath)
|
||||
{
|
||||
return PatchOperation(AZStd::move(destinationPath), PatchOperation::Type::Copy, AZStd::move(sourcePath));
|
||||
}
|
||||
|
||||
PatchOperation PatchOperation::MoveOperation(Path destinationPath, Path sourcePath)
|
||||
{
|
||||
return PatchOperation(AZStd::move(destinationPath), PatchOperation::Type::Move, AZStd::move(sourcePath));
|
||||
}
|
||||
|
||||
PatchOperation PatchOperation::TestOperation(Path testPath, Value value)
|
||||
{
|
||||
return PatchOperation(AZStd::move(testPath), PatchOperation::Type::Test, AZStd::move(value));
|
||||
}
|
||||
} // namespace AZ::Dom
|
||||
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/DOM/DomPath.h>
|
||||
#include <AzCore/DOM/DomValue.h>
|
||||
#include <AzCore/std/containers/deque.h>
|
||||
|
||||
namespace AZ::Dom
|
||||
{
|
||||
//! A patch operation that represents an atomic operation for mutating or validating a Value.
|
||||
//! PatchOperations can be created with helper methods in Patch. /see Patch
|
||||
class PatchOperation final
|
||||
{
|
||||
public:
|
||||
using PatchOutcome = AZ::Outcome<void, AZStd::string>;
|
||||
|
||||
//! The operation to perform.
|
||||
enum class Type
|
||||
{
|
||||
Add, //!< Inserts or replaces the value at DestinationPath with Value
|
||||
Remove, //!< Removes the entry at DestinationPath
|
||||
Replace, //!< Replaces the value at DestinationPath with Value
|
||||
Copy, //!< Copies the contents of SourcePath to DestinationPath
|
||||
Move, //!< Moves the contents of SourcePath to DestinationPath
|
||||
Test //!< Ensures the contents of DestinationPath match Value or fails, performs no mutations
|
||||
};
|
||||
|
||||
PatchOperation() = default;
|
||||
PatchOperation(const PatchOperation&) = default;
|
||||
PatchOperation(PatchOperation&&) = default;
|
||||
|
||||
PatchOperation(Path destionationPath, Type type, Value value);
|
||||
PatchOperation(Path destionationPath, Type type, Path sourcePath);
|
||||
PatchOperation(Path path, Type type);
|
||||
|
||||
static PatchOperation AddOperation(Path destinationPath, Value value);
|
||||
static PatchOperation RemoveOperation(Path pathToRemove);
|
||||
static PatchOperation ReplaceOperation(Path destinationPath, Value value);
|
||||
static PatchOperation CopyOperation(Path destinationPath, Path sourcePath);
|
||||
static PatchOperation MoveOperation(Path destinationPath, Path sourcePath);
|
||||
static PatchOperation TestOperation(Path testPath, Value value);
|
||||
|
||||
PatchOperation& operator=(const PatchOperation&) = default;
|
||||
PatchOperation& operator=(PatchOperation&&) = default;
|
||||
|
||||
bool operator==(const PatchOperation& rhs) const;
|
||||
bool operator!=(const PatchOperation& rhs) const;
|
||||
|
||||
Type GetType() const;
|
||||
void SetType(Type type);
|
||||
|
||||
const Path& GetDestinationPath() const;
|
||||
void SetDestinationPath(Path path);
|
||||
|
||||
const Value& GetValue() const;
|
||||
void SetValue(Value value);
|
||||
|
||||
const Path& GetSourcePath() const;
|
||||
void SetSourcePath(Path path);
|
||||
|
||||
AZ::Outcome<Value, AZStd::string> Apply(Value rootElement) const;
|
||||
PatchOutcome ApplyInPlace(Value& rootElement) const;
|
||||
|
||||
Value GetDomRepresentation() const;
|
||||
static AZ::Outcome<PatchOperation, AZStd::string> CreateFromDomRepresentation(Value domValue);
|
||||
|
||||
using InversePatches = AZStd::fixed_vector<PatchOperation, 2>;
|
||||
AZ::Outcome<AZStd::fixed_vector<PatchOperation, 2>, AZStd::string> GetInverse(Value stateBeforeApplication) const;
|
||||
|
||||
enum class ExistenceCheckFlags : AZ::u8
|
||||
{
|
||||
DefaultExistenceCheck = 0x0,
|
||||
VerifyFullPath = 0x1,
|
||||
AllowEndOfArray = 0x2,
|
||||
};
|
||||
|
||||
private:
|
||||
struct PathContext
|
||||
{
|
||||
Value& m_value;
|
||||
PathEntry m_key;
|
||||
};
|
||||
|
||||
static AZ::Outcome<PathContext, AZStd::string> LookupPath(
|
||||
Value& rootElement, const Path& path, ExistenceCheckFlags existenceCheckFlags = ExistenceCheckFlags::DefaultExistenceCheck);
|
||||
|
||||
PatchOutcome ApplyAdd(Value& rootElement) const;
|
||||
PatchOutcome ApplyRemove(Value& rootElement) const;
|
||||
PatchOutcome ApplyReplace(Value& rootElement) const;
|
||||
PatchOutcome ApplyCopy(Value& rootElement) const;
|
||||
PatchOutcome ApplyMove(Value& rootElement) const;
|
||||
PatchOutcome ApplyTest(Value& rootElement) const;
|
||||
|
||||
AZStd::variant<AZStd::monostate, Value, Path> m_value;
|
||||
Path m_domPath;
|
||||
Type m_type;
|
||||
};
|
||||
|
||||
AZ_DEFINE_ENUM_BITWISE_OPERATORS(PatchOperation::ExistenceCheckFlags);
|
||||
|
||||
class Patch;
|
||||
|
||||
//! The current state of a Patch application operation.
|
||||
struct PatchApplicationState
|
||||
{
|
||||
//! The outcome of the last operation, may be overridden to produce a different failure outcome.
|
||||
PatchOperation::PatchOutcome m_outcome;
|
||||
//! The patch being applied.
|
||||
const Patch* m_patch = nullptr;
|
||||
//! The last operation attempted.
|
||||
const PatchOperation* m_lastOperation = nullptr;
|
||||
//! The current state of the value being patched, will be returned if the patch operation succeeds.
|
||||
Value* m_currentState = nullptr;
|
||||
//! If set to false, the patch operation should halt.
|
||||
bool m_shouldContinue = true;
|
||||
};
|
||||
|
||||
namespace PatchApplicationStrategy
|
||||
{
|
||||
//! The default patching strategy. Applies all operations in a patch, but halts if any one operation fails.
|
||||
void HaltOnFailure(PatchApplicationState& state);
|
||||
//! Patching strategy that attemps to apply all operations in a patch, but ignores operation failures and continues.
|
||||
void IgnoreFailureAndContinue(PatchApplicationState& state);
|
||||
} // namespace PatchApplicationStrategy
|
||||
|
||||
//! A set of operations that can be applied to a Value to produce a new Value.
|
||||
//! \see PatchOperation
|
||||
class Patch final
|
||||
{
|
||||
public:
|
||||
using StrategyFunctor = AZStd::function<void(PatchApplicationState&)>;
|
||||
using OperationsContainer = AZStd::deque<PatchOperation>;
|
||||
|
||||
Patch() = default;
|
||||
Patch(const Patch&) = default;
|
||||
Patch(Patch&&) = default;
|
||||
Patch(AZStd::initializer_list<PatchOperation> init);
|
||||
|
||||
template<class InputIterator>
|
||||
Patch(InputIterator first, InputIterator last)
|
||||
: m_operations(first, last)
|
||||
{
|
||||
}
|
||||
|
||||
Patch& operator=(const Patch&) = default;
|
||||
Patch& operator=(Patch&&) = default;
|
||||
|
||||
bool operator==(const Patch& rhs) const;
|
||||
bool operator!=(const Patch& rhs) const;
|
||||
|
||||
const OperationsContainer& GetOperations() const;
|
||||
void PushBack(PatchOperation op);
|
||||
void PushFront(PatchOperation op);
|
||||
void Pop();
|
||||
void Clear();
|
||||
const PatchOperation& At(size_t index) const;
|
||||
size_t Size() const;
|
||||
|
||||
PatchOperation& operator[](size_t index);
|
||||
const PatchOperation& operator[](size_t index) const;
|
||||
|
||||
OperationsContainer::iterator begin();
|
||||
OperationsContainer::iterator end();
|
||||
OperationsContainer::const_iterator begin() const;
|
||||
OperationsContainer::const_iterator end() const;
|
||||
OperationsContainer::const_iterator cbegin() const;
|
||||
OperationsContainer::const_iterator cend() const;
|
||||
size_t size() const;
|
||||
|
||||
AZ::Outcome<Value, AZStd::string> Apply(Value rootElement, StrategyFunctor strategy = PatchApplicationStrategy::HaltOnFailure) const;
|
||||
AZ::Outcome<void, AZStd::string> ApplyInPlace(Value& rootElement, StrategyFunctor strategy = PatchApplicationStrategy::HaltOnFailure) const;
|
||||
|
||||
Value GetDomRepresentation() const;
|
||||
static AZ::Outcome<Patch, AZStd::string> CreateFromDomRepresentation(Value domValue);
|
||||
|
||||
private:
|
||||
OperationsContainer m_operations;
|
||||
};
|
||||
} // namespace AZ::Dom
|
||||
@@ -53,17 +53,20 @@ namespace AZ::Dom
|
||||
|
||||
bool PathEntry::operator==(size_t value) const
|
||||
{
|
||||
return IsIndex() && GetIndex() == value;
|
||||
const size_t* internalValue = AZStd::get_if<size_t>(&m_value);
|
||||
return internalValue != nullptr && *internalValue == value;
|
||||
}
|
||||
|
||||
bool PathEntry::operator==(const AZ::Name& key) const
|
||||
{
|
||||
return IsKey() && GetKey() == key;
|
||||
const AZ::Name* internalValue = AZStd::get_if<AZ::Name>(&m_value);
|
||||
return internalValue != nullptr && *internalValue == key;
|
||||
}
|
||||
|
||||
bool PathEntry::operator==(AZStd::string_view key) const
|
||||
{
|
||||
return IsKey() && GetKey() == AZ::Name(key);
|
||||
const AZ::Name* internalValue = AZStd::get_if<AZ::Name>(&m_value);
|
||||
return internalValue != nullptr && *internalValue == AZ::Name(key);
|
||||
}
|
||||
|
||||
bool PathEntry::operator!=(const PathEntry& other) const
|
||||
@@ -73,17 +76,17 @@ namespace AZ::Dom
|
||||
|
||||
bool PathEntry::operator!=(size_t value) const
|
||||
{
|
||||
return !IsIndex() || GetIndex() != value;
|
||||
return !operator==(value);
|
||||
}
|
||||
|
||||
bool PathEntry::operator!=(const AZ::Name& key) const
|
||||
{
|
||||
return !IsKey() || GetKey() != key;
|
||||
return !operator==(key);
|
||||
}
|
||||
|
||||
bool PathEntry::operator!=(AZStd::string_view key) const
|
||||
{
|
||||
return !IsKey() || GetKey() != AZ::Name(key);
|
||||
return !operator==(key);
|
||||
}
|
||||
|
||||
void PathEntry::SetEndOfArray()
|
||||
@@ -243,6 +246,11 @@ namespace AZ::Dom
|
||||
return m_entries.size();
|
||||
}
|
||||
|
||||
bool Path::IsEmpty() const
|
||||
{
|
||||
return m_entries.empty();
|
||||
}
|
||||
|
||||
PathEntry& Path::operator[](size_t index)
|
||||
{
|
||||
return m_entries[index];
|
||||
@@ -320,13 +328,13 @@ namespace AZ::Dom
|
||||
return size;
|
||||
}
|
||||
|
||||
void Path::FormatString(char* stringBuffer, size_t bufferSize) const
|
||||
size_t Path::FormatString(char* stringBuffer, size_t bufferSize) const
|
||||
{
|
||||
size_t bufferIndex = 0;
|
||||
|
||||
auto putChar = [&](char c)
|
||||
{
|
||||
if (bufferIndex == bufferSize)
|
||||
if (bufferIndex >= bufferSize)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -357,6 +365,11 @@ namespace AZ::Dom
|
||||
|
||||
for (const PathEntry& entry : m_entries)
|
||||
{
|
||||
if (bufferIndex >= bufferSize)
|
||||
{
|
||||
return bufferIndex;
|
||||
}
|
||||
|
||||
putChar(PathSeparator);
|
||||
if (entry.IsEndOfArray())
|
||||
{
|
||||
@@ -372,7 +385,10 @@ namespace AZ::Dom
|
||||
}
|
||||
}
|
||||
|
||||
size_t bytesWritten = bufferIndex;
|
||||
putChar('\0');
|
||||
|
||||
return bytesWritten;
|
||||
}
|
||||
|
||||
AZStd::string Path::ToString() const
|
||||
|
||||
@@ -111,6 +111,7 @@ namespace AZ::Dom
|
||||
void Clear();
|
||||
PathEntry At(size_t index) const;
|
||||
size_t Size() const;
|
||||
bool IsEmpty() const;
|
||||
|
||||
PathEntry& operator[](size_t index);
|
||||
const PathEntry& operator[](size_t index) const;
|
||||
@@ -128,10 +129,19 @@ namespace AZ::Dom
|
||||
size_t GetStringLength() const;
|
||||
//! Formats a JSON-pointer style path string into the target buffer.
|
||||
//! This operation will fail if bufferSize < GetStringLength() + 1
|
||||
void FormatString(char* stringBuffer, size_t bufferSize) const;
|
||||
//! \return The number of bytes written, excepting the null terminator.
|
||||
size_t FormatString(char* stringBuffer, size_t bufferSize) const;
|
||||
//! Returns a JSON-pointer style path string for this path.
|
||||
AZStd::string ToString() const;
|
||||
|
||||
void AppendToString(AZStd::string& output) const;
|
||||
template <class T>
|
||||
void AppendToString(T& output) const
|
||||
{
|
||||
const size_t startIndex = output.length();
|
||||
output.resize_no_construct(startIndex + FormatString(output.data() + startIndex, output.capacity() - startIndex));
|
||||
}
|
||||
|
||||
//! Reads a JSON-pointer style path from pathString and replaces this path's contents.
|
||||
//! Paths are accepted in the following forms:
|
||||
//! "/path/to/foo/0"
|
||||
|
||||
@@ -25,6 +25,11 @@ extern "C" {
|
||||
# include <Lua/lualib.h>
|
||||
# include <Lua/lauxlib.h>
|
||||
# include <Lua/lobject.h>
|
||||
|
||||
// versions of LUA before 5.3.x used to define a union that contained a double, a pointer, and a long
|
||||
// as L_Umaxalign. Newer versions define those inner types in the macro LUAI_MAXALIGN instead but
|
||||
// no longer actually declare a union around it. For backward compatibility we define the same one here
|
||||
union L_Umaxalign { LUAI_MAXALIGN; };
|
||||
}
|
||||
|
||||
#include <limits>
|
||||
@@ -1687,6 +1692,11 @@ LUA_API const Node* lua_getDummyNode()
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const char* ScriptDataContext::GetInterpreterVersion()
|
||||
{
|
||||
return LUA_VERSION;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
ScriptContext*
|
||||
ScriptDataContext::GetScriptContext() const
|
||||
@@ -4367,7 +4377,7 @@ LUA_API const Node* lua_getDummyNode()
|
||||
lua_pushlightuserdata(m_lua, m_owner);
|
||||
int tableRef = luaL_ref(m_lua, LUA_REGISTRYINDEX);
|
||||
(void)tableRef;
|
||||
AZ_Assert(tableRef == AZ_LUA_SCRIPT_CONTEXT_REF, "Table referece should match %d !", AZ_LUA_SCRIPT_CONTEXT_REF);
|
||||
AZ_Assert(tableRef == AZ_LUA_SCRIPT_CONTEXT_REF, "Table reference should match %d but is instead %d!", AZ_LUA_SCRIPT_CONTEXT_REF, tableRef);
|
||||
|
||||
// create a AZGlobals table, we can use internal unodered_map if it's faster (TODO: test which is faster, or if there is a benefit keeping in la)
|
||||
lua_createtable(m_lua, 0, 1024); // pre allocate some values in the hash
|
||||
|
||||
@@ -212,6 +212,10 @@ namespace AZ
|
||||
|
||||
~ScriptDataContext() { Reset(); }
|
||||
|
||||
//! Retrieve a string representing the current version of the interpreter.
|
||||
//! Example of use: To signal incompatibility with previously emitted bytecode, to invalidate
|
||||
static const char* GetInterpreterVersion();
|
||||
|
||||
ScriptContext* GetScriptContext() const;
|
||||
lua_State* GetNativeContext() const { return m_nativeContext; }
|
||||
|
||||
|
||||
@@ -14,38 +14,13 @@ extern "C" {
|
||||
# include <Lua/lauxlib.h>
|
||||
}
|
||||
|
||||
// Currently we support Lua 5.1 and later (we have tested with 5.2)
|
||||
|
||||
#if LUA_VERSION_NUM <= 502
|
||||
|
||||
inline void lua_pushunsigned(lua_State* l, unsigned int v)
|
||||
{
|
||||
lua_pushnumber(l, static_cast<lua_Number>(v));
|
||||
}
|
||||
|
||||
inline unsigned int lua_tounsigned(lua_State* l, int idx)
|
||||
{
|
||||
return static_cast<unsigned int>(lua_tonumber(l, idx));
|
||||
}
|
||||
|
||||
#define lua_pushglobaltable(L) lua_pushvalue(L, LUA_GLOBALSINDEX)
|
||||
|
||||
inline LUA_API int lua_load(lua_State* L, lua_Reader reader, void* data, const char* chunkname, const char* mode)
|
||||
{
|
||||
(void)mode;
|
||||
return lua_load(L, reader, data, chunkname);
|
||||
}
|
||||
|
||||
#define LUA_RIDX_LAST 0
|
||||
#define LUA_NUMTAGS 9
|
||||
|
||||
#endif
|
||||
|
||||
#define AZ_LUA_SCRIPT_CONTEXT_REF LUA_RIDX_LAST + 1
|
||||
#define AZ_LUA_GLOBALS_TABLE_REF LUA_RIDX_LAST + 2
|
||||
#define AZ_LUA_CLASS_TABLE_REF LUA_RIDX_LAST + 3
|
||||
#define AZ_LUA_WEAK_CACHE_TABLE_REF LUA_RIDX_LAST + 4
|
||||
#define AZ_LUA_ERROR_HANDLER_FUN_REF LUA_RIDX_LAST + 5
|
||||
// Currently we support Lua 5.4.4 and later
|
||||
// note that Lua 5.x defines LUA_RID_LAST + 1 to be an index of a free-list.
|
||||
#define AZ_LUA_SCRIPT_CONTEXT_REF LUA_RIDX_LAST + 2
|
||||
#define AZ_LUA_GLOBALS_TABLE_REF LUA_RIDX_LAST + 3
|
||||
#define AZ_LUA_CLASS_TABLE_REF LUA_RIDX_LAST + 4
|
||||
#define AZ_LUA_WEAK_CACHE_TABLE_REF LUA_RIDX_LAST + 5
|
||||
#define AZ_LUA_ERROR_HANDLER_FUN_REF LUA_RIDX_LAST + 6
|
||||
|
||||
#define AZ_LUA_CLASS_METATABLE_NAME_INDEX 1 // can we always read the name from the behavior class???
|
||||
#define AZ_LUA_CLASS_METATABLE_BEHAVIOR_CLASS 2
|
||||
|
||||
@@ -116,6 +116,8 @@ set(FILES
|
||||
Debug/TraceReflection.h
|
||||
DOM/DomBackend.cpp
|
||||
DOM/DomBackend.h
|
||||
DOM/DomPatch.cpp
|
||||
DOM/DomPatch.h
|
||||
DOM/DomPath.cpp
|
||||
DOM/DomPath.h
|
||||
DOM/DomUtils.cpp
|
||||
@@ -126,6 +128,8 @@ set(FILES
|
||||
DOM/DomValueWriter.h
|
||||
DOM/DomVisitor.cpp
|
||||
DOM/DomVisitor.h
|
||||
DOM/DomComparison.cpp
|
||||
DOM/DomComparison.h
|
||||
DOM/Backends/JSON/JsonBackend.h
|
||||
DOM/Backends/JSON/JsonSerializationUtils.cpp
|
||||
DOM/Backends/JSON/JsonSerializationUtils.h
|
||||
|
||||
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/DOM/DomPatch.h>
|
||||
#include <AzCore/DOM/DomUtils.h>
|
||||
#include <AzCore/DOM/DomValue.h>
|
||||
#include <AzCore/DOM/DomComparison.h>
|
||||
#include <AzCore/Name/NameDictionary.h>
|
||||
#include <AzCore/UnitTest/TestTypes.h>
|
||||
#include <Tests/DOM/DomFixtures.h>
|
||||
|
||||
namespace AZ::Dom::Benchmark
|
||||
{
|
||||
class DomPatchBenchmark : public Tests::DomBenchmarkFixture
|
||||
{
|
||||
public:
|
||||
void TearDownHarness() override
|
||||
{
|
||||
m_before = {};
|
||||
m_after = {};
|
||||
Tests::DomBenchmarkFixture::TearDownHarness();
|
||||
}
|
||||
|
||||
void SimpleReplace(benchmark::State& state, bool deepCopy, bool apply)
|
||||
{
|
||||
m_before = GenerateDomBenchmarkPayload(state.range(0), state.range(1));
|
||||
m_after = deepCopy ? Utils::DeepCopy(m_before) : m_before;
|
||||
m_after["entries"]["Key0"] = Value("replacement string", true);
|
||||
|
||||
RunBenchmarkInternal(state, apply);
|
||||
}
|
||||
|
||||
void TopLevelReplace(benchmark::State& state, bool apply)
|
||||
{
|
||||
m_before = GenerateDomBenchmarkPayload(state.range(0), state.range(1));
|
||||
m_after = Value(Type::Object);
|
||||
m_after["UnrelatedKey"] = Value(42);
|
||||
|
||||
RunBenchmarkInternal(state, apply);
|
||||
}
|
||||
|
||||
void KeyRemove(benchmark::State& state, bool deepCopy, bool apply)
|
||||
{
|
||||
m_before = GenerateDomBenchmarkPayload(state.range(0), state.range(1));
|
||||
m_after = deepCopy ? Utils::DeepCopy(m_before) : m_before;
|
||||
m_after["entries"].RemoveMember("Key1");
|
||||
|
||||
RunBenchmarkInternal(state, apply);
|
||||
}
|
||||
|
||||
void ArrayAppend(benchmark::State& state, bool deepCopy, bool apply)
|
||||
{
|
||||
m_before = GenerateDomBenchmarkPayload(state.range(0), state.range(1));
|
||||
m_after = deepCopy ? Utils::DeepCopy(m_before) : m_before;
|
||||
m_after["entries"]["Key2"].ArrayPushBack(Value(0));
|
||||
|
||||
RunBenchmarkInternal(state, apply);
|
||||
}
|
||||
|
||||
void ArrayPrepend(benchmark::State& state, bool deepCopy, bool apply)
|
||||
{
|
||||
m_before = GenerateDomBenchmarkPayload(state.range(0), state.range(1));
|
||||
m_after = deepCopy ? Utils::DeepCopy(m_before) : m_before;
|
||||
auto& arr = m_after["entries"]["Key2"].GetMutableArray();
|
||||
arr.insert(arr.begin(), Value(42));
|
||||
|
||||
RunBenchmarkInternal(state, apply);
|
||||
}
|
||||
|
||||
private:
|
||||
void RunBenchmarkInternal(benchmark::State& state, bool apply)
|
||||
{
|
||||
if (apply)
|
||||
{
|
||||
auto patchInfo = GenerateHierarchicalDeltaPatch(m_before, m_after);
|
||||
for (auto _ : state)
|
||||
{
|
||||
auto patchResult = patchInfo.m_forwardPatches.Apply(m_before);
|
||||
benchmark::DoNotOptimize(patchResult);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (auto _ : state)
|
||||
{
|
||||
auto patchInfo = GenerateHierarchicalDeltaPatch(m_before, m_after);
|
||||
benchmark::DoNotOptimize(patchInfo);
|
||||
}
|
||||
}
|
||||
|
||||
state.SetItemsProcessed(state.iterations());
|
||||
}
|
||||
|
||||
Value m_before;
|
||||
Value m_after;
|
||||
};
|
||||
|
||||
BENCHMARK_DEFINE_F(DomPatchBenchmark, AzDomPatch_Generate_SimpleReplace_ShallowCopy)(benchmark::State& state)
|
||||
{
|
||||
SimpleReplace(state, false, false);
|
||||
}
|
||||
DOM_REGISTER_SERIALIZATION_BENCHMARK_MS(DomPatchBenchmark, AzDomPatch_Generate_SimpleReplace_ShallowCopy)
|
||||
|
||||
BENCHMARK_DEFINE_F(DomPatchBenchmark, AzDomPatch_Generate_SimpleReplace_DeepCopy)(benchmark::State& state)
|
||||
{
|
||||
SimpleReplace(state, true, false);
|
||||
}
|
||||
DOM_REGISTER_SERIALIZATION_BENCHMARK_MS(DomPatchBenchmark, AzDomPatch_Generate_SimpleReplace_DeepCopy)
|
||||
|
||||
BENCHMARK_DEFINE_F(DomPatchBenchmark, AzDomPatch_Generate_TopLevelReplace)(benchmark::State& state)
|
||||
{
|
||||
TopLevelReplace(state, false);
|
||||
}
|
||||
DOM_REGISTER_SERIALIZATION_BENCHMARK_MS(DomPatchBenchmark, AzDomPatch_Generate_TopLevelReplace)
|
||||
|
||||
BENCHMARK_DEFINE_F(DomPatchBenchmark, AzDomPatch_Generate_KeyRemove_ShallowCopy)(benchmark::State& state)
|
||||
{
|
||||
KeyRemove(state, false, false);
|
||||
}
|
||||
DOM_REGISTER_SERIALIZATION_BENCHMARK_MS(DomPatchBenchmark, AzDomPatch_Generate_KeyRemove_ShallowCopy)
|
||||
|
||||
BENCHMARK_DEFINE_F(DomPatchBenchmark, AzDomPatch_Generate_KeyRemove_DeepCopy)(benchmark::State& state)
|
||||
{
|
||||
KeyRemove(state, true, false);
|
||||
}
|
||||
DOM_REGISTER_SERIALIZATION_BENCHMARK_MS(DomPatchBenchmark, AzDomPatch_Generate_KeyRemove_DeepCopy)
|
||||
|
||||
BENCHMARK_DEFINE_F(DomPatchBenchmark, AzDomPatch_Generate_ArrayAppend_ShallowCopy)(benchmark::State& state)
|
||||
{
|
||||
ArrayAppend(state, false, false);
|
||||
}
|
||||
DOM_REGISTER_SERIALIZATION_BENCHMARK_MS(DomPatchBenchmark, AzDomPatch_Generate_ArrayAppend_ShallowCopy)
|
||||
|
||||
BENCHMARK_DEFINE_F(DomPatchBenchmark, AzDomPatch_Generate_ArrayAppend_DeepCopy)(benchmark::State& state)
|
||||
{
|
||||
ArrayAppend(state, true, false);
|
||||
}
|
||||
DOM_REGISTER_SERIALIZATION_BENCHMARK_MS(DomPatchBenchmark, AzDomPatch_Generate_ArrayAppend_DeepCopy)
|
||||
|
||||
BENCHMARK_DEFINE_F(DomPatchBenchmark, AzDomPatch_Generate_ArrayPrepend)(benchmark::State& state)
|
||||
{
|
||||
ArrayPrepend(state, true, false);
|
||||
}
|
||||
DOM_REGISTER_SERIALIZATION_BENCHMARK_MS(DomPatchBenchmark, AzDomPatch_Generate_ArrayPrepend)
|
||||
|
||||
BENCHMARK_DEFINE_F(DomPatchBenchmark, AzDomPatch_Apply_SimpleReplace)(benchmark::State& state)
|
||||
{
|
||||
SimpleReplace(state, true, true);
|
||||
}
|
||||
DOM_REGISTER_SERIALIZATION_BENCHMARK_MS(DomPatchBenchmark, AzDomPatch_Apply_SimpleReplace)
|
||||
|
||||
BENCHMARK_DEFINE_F(DomPatchBenchmark, AzDomPatch_Apply_TopLevelReplace)(benchmark::State& state)
|
||||
{
|
||||
TopLevelReplace(state, true);
|
||||
}
|
||||
DOM_REGISTER_SERIALIZATION_BENCHMARK_MS(DomPatchBenchmark, AzDomPatch_Apply_TopLevelReplace)
|
||||
|
||||
BENCHMARK_DEFINE_F(DomPatchBenchmark, AzDomPatch_Apply_KeyRemove)(benchmark::State& state)
|
||||
{
|
||||
KeyRemove(state, true, true);
|
||||
}
|
||||
DOM_REGISTER_SERIALIZATION_BENCHMARK_MS(DomPatchBenchmark, AzDomPatch_Apply_KeyRemove)
|
||||
|
||||
BENCHMARK_DEFINE_F(DomPatchBenchmark, AzDomPatch_Apply_ArrayAppend)(benchmark::State& state)
|
||||
{
|
||||
ArrayAppend(state, true, true);
|
||||
}
|
||||
DOM_REGISTER_SERIALIZATION_BENCHMARK_MS(DomPatchBenchmark, AzDomPatch_Apply_ArrayAppend)
|
||||
|
||||
BENCHMARK_DEFINE_F(DomPatchBenchmark, AzDomPatch_Apply_ArrayPrepend)(benchmark::State& state)
|
||||
{
|
||||
ArrayPrepend(state, true, true);
|
||||
}
|
||||
DOM_REGISTER_SERIALIZATION_BENCHMARK_MS(DomPatchBenchmark, AzDomPatch_Apply_ArrayPrepend)
|
||||
} // namespace AZ::Dom::Benchmark
|
||||
@@ -0,0 +1,563 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/DOM/DomPatch.h>
|
||||
#include <AzCore/DOM/DomComparison.h>
|
||||
#include <Tests/DOM/DomFixtures.h>
|
||||
|
||||
namespace AZ::Dom::Tests
|
||||
{
|
||||
class DomPatchTests : public DomTestFixture
|
||||
{
|
||||
public:
|
||||
void SetUp() override
|
||||
{
|
||||
DomTestFixture::SetUp();
|
||||
|
||||
m_dataset = Value(Type::Object);
|
||||
m_dataset["arr"].SetArray();
|
||||
|
||||
m_dataset["node"].SetNode("SomeNode");
|
||||
m_dataset["node"]["int"] = 5;
|
||||
m_dataset["node"]["null"] = Value();
|
||||
|
||||
for (int i = 0; i < 5; ++i)
|
||||
{
|
||||
m_dataset["arr"].ArrayPushBack(Value(i));
|
||||
m_dataset["node"].ArrayPushBack(Value(i * 2));
|
||||
}
|
||||
|
||||
m_dataset["obj"].SetObject();
|
||||
m_dataset["obj"]["foo"] = true;
|
||||
m_dataset["obj"]["bar"] = false;
|
||||
|
||||
m_deltaDataset = m_dataset;
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
m_dataset = m_deltaDataset = Value();
|
||||
|
||||
DomTestFixture::TearDown();
|
||||
}
|
||||
|
||||
PatchUndoRedoInfo GenerateAndVerifyDelta()
|
||||
{
|
||||
PatchUndoRedoInfo info = GenerateHierarchicalDeltaPatch(m_dataset, m_deltaDataset);
|
||||
|
||||
auto result = info.m_forwardPatches.Apply(m_dataset);
|
||||
EXPECT_TRUE(result.IsSuccess());
|
||||
EXPECT_TRUE(Utils::DeepCompareIsEqual(result.GetValue(), m_deltaDataset));
|
||||
|
||||
result = info.m_inversePatches.Apply(result.GetValue());
|
||||
EXPECT_TRUE(result.IsSuccess());
|
||||
EXPECT_TRUE(Utils::DeepCompareIsEqual(result.GetValue(), m_dataset));
|
||||
|
||||
// Verify serialization of the patches
|
||||
auto VerifySerialization = [](const Patch& patch)
|
||||
{
|
||||
Value serializedPatch = patch.GetDomRepresentation();
|
||||
auto deserializePatchResult = Patch::CreateFromDomRepresentation(serializedPatch);
|
||||
EXPECT_TRUE(deserializePatchResult.IsSuccess());
|
||||
EXPECT_EQ(deserializePatchResult.GetValue(), patch);
|
||||
};
|
||||
VerifySerialization(info.m_forwardPatches);
|
||||
VerifySerialization(info.m_inversePatches);
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
Value m_dataset;
|
||||
Value m_deltaDataset;
|
||||
};
|
||||
|
||||
TEST_F(DomPatchTests, AddOperation_InsertInObject_Succeeds)
|
||||
{
|
||||
Path p("/obj/baz");
|
||||
PatchOperation op = PatchOperation::AddOperation(p, Value(42));
|
||||
auto result = op.Apply(m_dataset);
|
||||
ASSERT_TRUE(result.IsSuccess());
|
||||
EXPECT_EQ(result.GetValue()[p].GetInt64(), 42);
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, AddOperation_ReplaceInObject_Succeeds)
|
||||
{
|
||||
Path p("/obj/foo");
|
||||
PatchOperation op = PatchOperation::AddOperation(p, Value(false));
|
||||
auto result = op.Apply(m_dataset);
|
||||
ASSERT_TRUE(result.IsSuccess());
|
||||
EXPECT_EQ(result.GetValue()[p].GetBool(), false);
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, AddOperation_InsertObjectKeyInArray_Fails)
|
||||
{
|
||||
Path p("/arr/key");
|
||||
PatchOperation op = PatchOperation::AddOperation(p, Value(999));
|
||||
auto result = op.Apply(m_dataset);
|
||||
ASSERT_FALSE(result.IsSuccess());
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, AddOperation_AppendInArray_Succeeds)
|
||||
{
|
||||
Path p("/arr/-");
|
||||
PatchOperation op = PatchOperation::AddOperation(p, Value(42));
|
||||
auto result = op.Apply(m_dataset);
|
||||
ASSERT_TRUE(result.IsSuccess());
|
||||
EXPECT_EQ(result.GetValue()["arr"][5].GetInt64(), 42);
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, AddOperation_InsertKeyInNode_Succeeds)
|
||||
{
|
||||
Path p("/node/attr");
|
||||
PatchOperation op = PatchOperation::AddOperation(p, Value(500));
|
||||
auto result = op.Apply(m_dataset);
|
||||
ASSERT_TRUE(result.IsSuccess());
|
||||
EXPECT_EQ(result.GetValue()[p].GetInt64(), 500);
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, AddOperation_ReplaceIndexInNode_Succeeds)
|
||||
{
|
||||
Path p("/node/0");
|
||||
PatchOperation op = PatchOperation::AddOperation(p, Value(42));
|
||||
auto result = op.Apply(m_dataset);
|
||||
ASSERT_TRUE(result.IsSuccess());
|
||||
EXPECT_EQ(result.GetValue()[p].GetInt64(), 42);
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, AddOperation_AppendInNode_Succeeds)
|
||||
{
|
||||
Path p("/node/-");
|
||||
PatchOperation op = PatchOperation::AddOperation(p, Value(42));
|
||||
auto result = op.Apply(m_dataset);
|
||||
ASSERT_TRUE(result.IsSuccess());
|
||||
EXPECT_EQ(result.GetValue()["node"][5].GetInt64(), 42);
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, AddOperation_InvalidPath_Fails)
|
||||
{
|
||||
Path p("/non/existent/path");
|
||||
PatchOperation op = PatchOperation::AddOperation(p, Value(0));
|
||||
auto result = op.Apply(m_dataset);
|
||||
ASSERT_FALSE(result.IsSuccess());
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, RemoveOperation_RemoveKeyFromObject_Succeeds)
|
||||
{
|
||||
Path p("/obj/foo");
|
||||
PatchOperation op = PatchOperation::RemoveOperation(p);
|
||||
auto result = op.Apply(m_dataset);
|
||||
ASSERT_TRUE(result.IsSuccess());
|
||||
EXPECT_FALSE(result.GetValue()["obj"].HasMember("foo"));
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, RemoveOperation_RemoveIndexFromArray_Succeeds)
|
||||
{
|
||||
Path p("/arr/0");
|
||||
PatchOperation op = PatchOperation::RemoveOperation(p);
|
||||
auto result = op.Apply(m_dataset);
|
||||
ASSERT_TRUE(result.IsSuccess());
|
||||
EXPECT_EQ(result.GetValue()["arr"].ArraySize(), 4);
|
||||
EXPECT_EQ(result.GetValue()["arr"][0].GetInt64(), 1);
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, RemoveOperation_PopArray_Succeeds)
|
||||
{
|
||||
Path p("/arr/-");
|
||||
PatchOperation op = PatchOperation::RemoveOperation(p);
|
||||
auto result = op.Apply(m_dataset);
|
||||
EXPECT_EQ(result.GetValue()["arr"].ArraySize(), 4);
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, RemoveOperation_RemoveKeyFromNode_Succeeds)
|
||||
{
|
||||
Path p("/node/int");
|
||||
PatchOperation op = PatchOperation::RemoveOperation(p);
|
||||
auto result = op.Apply(m_dataset);
|
||||
ASSERT_TRUE(result.IsSuccess());
|
||||
EXPECT_FALSE(result.GetValue()["node"].HasMember("int"));
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, RemoveOperation_RemoveIndexFromNode_Succeeds)
|
||||
{
|
||||
Path p("/node/1");
|
||||
PatchOperation op = PatchOperation::RemoveOperation(p);
|
||||
auto result = op.Apply(m_dataset);
|
||||
ASSERT_TRUE(result.IsSuccess());
|
||||
EXPECT_EQ(result.GetValue()["node"].ArraySize(), 4);
|
||||
EXPECT_EQ(result.GetValue()["node"][1].GetInt64(), 4);
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, RemoveOperation_PopIndexFromNode_Succeeds)
|
||||
{
|
||||
Path p("/node/-");
|
||||
PatchOperation op = PatchOperation::RemoveOperation(p);
|
||||
auto result = op.Apply(m_dataset);
|
||||
ASSERT_TRUE(result.IsSuccess());
|
||||
EXPECT_EQ(result.GetValue()["node"].ArraySize(), 4);
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, RemoveOperation_RemoveKeyFromArray_Fails)
|
||||
{
|
||||
Path p("/arr/foo");
|
||||
PatchOperation op = PatchOperation::RemoveOperation(p);
|
||||
auto result = op.Apply(m_dataset);
|
||||
ASSERT_FALSE(result.IsSuccess());
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, RemoveOperation_InvalidPath_Fails)
|
||||
{
|
||||
Path p("/non/existent/path");
|
||||
PatchOperation op = PatchOperation::RemoveOperation(p);
|
||||
auto result = op.Apply(m_dataset);
|
||||
ASSERT_FALSE(result.IsSuccess());
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, ReplaceOperation_InsertInObject_Fails)
|
||||
{
|
||||
Path p("/obj/baz");
|
||||
PatchOperation op = PatchOperation::ReplaceOperation(p, Value(42));
|
||||
auto result = op.Apply(m_dataset);
|
||||
ASSERT_FALSE(result.IsSuccess());
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, ReplaceOperation_ReplaceInObject_Succeeds)
|
||||
{
|
||||
Path p("/obj/foo");
|
||||
PatchOperation op = PatchOperation::ReplaceOperation(p, Value(false));
|
||||
auto result = op.Apply(m_dataset);
|
||||
ASSERT_TRUE(result.IsSuccess());
|
||||
EXPECT_EQ(result.GetValue()[p].GetBool(), false);
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, ReplaceOperation_InsertObjectKeyInArray_Fails)
|
||||
{
|
||||
Path p("/arr/key");
|
||||
PatchOperation op = PatchOperation::ReplaceOperation(p, Value(999));
|
||||
auto result = op.Apply(m_dataset);
|
||||
ASSERT_FALSE(result.IsSuccess());
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, ReplaceOperation_AppendInArray_Fails)
|
||||
{
|
||||
Path p("/arr/-");
|
||||
PatchOperation op = PatchOperation::ReplaceOperation(p, Value(42));
|
||||
auto result = op.Apply(m_dataset);
|
||||
ASSERT_FALSE(result.IsSuccess());
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, ReplaceOperation_InsertKeyInNode_Fails)
|
||||
{
|
||||
Path p("/node/attr");
|
||||
PatchOperation op = PatchOperation::ReplaceOperation(p, Value(500));
|
||||
auto result = op.Apply(m_dataset);
|
||||
ASSERT_FALSE(result.IsSuccess());
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, ReplaceOperation_ReplaceIndexInNode_Succeeds)
|
||||
{
|
||||
Path p("/node/0");
|
||||
PatchOperation op = PatchOperation::ReplaceOperation(p, Value(42));
|
||||
auto result = op.Apply(m_dataset);
|
||||
ASSERT_TRUE(result.IsSuccess());
|
||||
EXPECT_EQ(result.GetValue()[p].GetInt64(), 42);
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, ReplaceOperation_AppendInNode_Fails)
|
||||
{
|
||||
Path p("/node/-");
|
||||
PatchOperation op = PatchOperation::ReplaceOperation(p, Value(42));
|
||||
auto result = op.Apply(m_dataset);
|
||||
ASSERT_FALSE(result.IsSuccess());
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, ReplaceOperation_InvalidPath_Fails)
|
||||
{
|
||||
Path p("/non/existent/path");
|
||||
PatchOperation op = PatchOperation::ReplaceOperation(p, Value(0));
|
||||
auto result = op.Apply(m_dataset);
|
||||
ASSERT_FALSE(result.IsSuccess());
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, CopyOperation_ArrayToObject_Succeeds)
|
||||
{
|
||||
Path dest("/obj/arr");
|
||||
Path src("/arr");
|
||||
PatchOperation op = PatchOperation::CopyOperation(dest, src);
|
||||
auto result = op.Apply(m_dataset);
|
||||
ASSERT_TRUE(result.IsSuccess());
|
||||
EXPECT_TRUE(Utils::DeepCompareIsEqual(m_dataset[src], result.GetValue()[dest]));
|
||||
EXPECT_TRUE(Utils::DeepCompareIsEqual(result.GetValue()[src], result.GetValue()[dest]));
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, CopyOperation_ObjectToArrayInRange_Succeeds)
|
||||
{
|
||||
Path dest("/arr/0");
|
||||
Path src("/obj");
|
||||
PatchOperation op = PatchOperation::CopyOperation(dest, src);
|
||||
auto result = op.Apply(m_dataset);
|
||||
ASSERT_TRUE(result.IsSuccess());
|
||||
EXPECT_TRUE(Utils::DeepCompareIsEqual(m_dataset[src], result.GetValue()[dest]));
|
||||
EXPECT_TRUE(Utils::DeepCompareIsEqual(result.GetValue()[src], result.GetValue()[dest]));
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, CopyOperation_ObjectToArrayOutOfRange_Fails)
|
||||
{
|
||||
Path dest("/arr/5");
|
||||
Path src("/obj");
|
||||
PatchOperation op = PatchOperation::CopyOperation(dest, src);
|
||||
auto result = op.Apply(m_dataset);
|
||||
ASSERT_FALSE(result.IsSuccess());
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, CopyOperation_ObjectToNodeChildInRange_Succeeds)
|
||||
{
|
||||
Path dest("/node/0");
|
||||
Path src("/obj");
|
||||
PatchOperation op = PatchOperation::CopyOperation(dest, src);
|
||||
auto result = op.Apply(m_dataset);
|
||||
ASSERT_TRUE(result.IsSuccess());
|
||||
EXPECT_TRUE(Utils::DeepCompareIsEqual(m_dataset[src], result.GetValue()[dest]));
|
||||
EXPECT_TRUE(Utils::DeepCompareIsEqual(result.GetValue()[src], result.GetValue()[dest]));
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, CopyOperation_ObjectToNodeChildOutOfRange_Fails)
|
||||
{
|
||||
Path dest("/node/5");
|
||||
Path src("/obj");
|
||||
PatchOperation op = PatchOperation::CopyOperation(dest, src);
|
||||
auto result = op.Apply(m_dataset);
|
||||
ASSERT_FALSE(result.IsSuccess());
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, CopyOperation_InvalidSourcePath_Fails)
|
||||
{
|
||||
Path dest("/node/0");
|
||||
Path src("/invalid/path");
|
||||
PatchOperation op = PatchOperation::CopyOperation(dest, src);
|
||||
auto result = op.Apply(m_dataset);
|
||||
ASSERT_FALSE(result.IsSuccess());
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, CopyOperation_InvalidDestinationPath_Fails)
|
||||
{
|
||||
Path dest("/invalid/path");
|
||||
Path src("/arr/0");
|
||||
PatchOperation op = PatchOperation::CopyOperation(dest, src);
|
||||
auto result = op.Apply(m_dataset);
|
||||
ASSERT_FALSE(result.IsSuccess());
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, MoveOperation_ArrayToObject_Succeeds)
|
||||
{
|
||||
Path dest("/obj/arr");
|
||||
Path src("/arr");
|
||||
PatchOperation op = PatchOperation::MoveOperation(dest, src);
|
||||
auto result = op.Apply(m_dataset);
|
||||
ASSERT_TRUE(result.IsSuccess());
|
||||
EXPECT_TRUE(Utils::DeepCompareIsEqual(m_dataset[src], result.GetValue()[dest]));
|
||||
EXPECT_FALSE(result.GetValue().HasMember("arr"));
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, MoveOperation_ObjectToArrayInRange_Succeeds)
|
||||
{
|
||||
Path dest("/arr/0");
|
||||
Path src("/obj");
|
||||
PatchOperation op = PatchOperation::MoveOperation(dest, src);
|
||||
auto result = op.Apply(m_dataset);
|
||||
ASSERT_TRUE(result.IsSuccess());
|
||||
EXPECT_TRUE(Utils::DeepCompareIsEqual(m_dataset[src], result.GetValue()[dest]));
|
||||
EXPECT_FALSE(result.GetValue().HasMember("obj"));
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, MoveOperation_ObjectToArrayOutOfRange_Fails)
|
||||
{
|
||||
Path dest("/arr/5");
|
||||
Path src("/obj");
|
||||
PatchOperation op = PatchOperation::MoveOperation(dest, src);
|
||||
auto result = op.Apply(m_dataset);
|
||||
ASSERT_FALSE(result.IsSuccess());
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, MoveOperation_ObjectToNodeChildInRange_Succeeds)
|
||||
{
|
||||
Path dest("/node/0");
|
||||
Path src("/obj");
|
||||
PatchOperation op = PatchOperation::MoveOperation(dest, src);
|
||||
auto result = op.Apply(m_dataset);
|
||||
ASSERT_TRUE(result.IsSuccess());
|
||||
EXPECT_TRUE(Utils::DeepCompareIsEqual(m_dataset[src], result.GetValue()[dest]));
|
||||
EXPECT_FALSE(result.GetValue().HasMember("obj"));
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, MoveOperation_ObjectToNodeChildOutOfRange_Fails)
|
||||
{
|
||||
Path dest("/node/5");
|
||||
Path src("/obj");
|
||||
PatchOperation op = PatchOperation::MoveOperation(dest, src);
|
||||
auto result = op.Apply(m_dataset);
|
||||
ASSERT_FALSE(result.IsSuccess());
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, MoveOperation_InvalidSourcePath_Fails)
|
||||
{
|
||||
Path dest("/node/0");
|
||||
Path src("/invalid/path");
|
||||
PatchOperation op = PatchOperation::MoveOperation(dest, src);
|
||||
auto result = op.Apply(m_dataset);
|
||||
ASSERT_FALSE(result.IsSuccess());
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, MoveOperation_InvalidDestinationPath_Fails)
|
||||
{
|
||||
Path dest("/invalid/path");
|
||||
Path src("/arr/0");
|
||||
PatchOperation op = PatchOperation::MoveOperation(dest, src);
|
||||
auto result = op.Apply(m_dataset);
|
||||
ASSERT_FALSE(result.IsSuccess());
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, TestOperation_TestCorrectValue_Succeeds)
|
||||
{
|
||||
Path path("/arr/1");
|
||||
Value value(1);
|
||||
PatchOperation op = PatchOperation::TestOperation(path, value);
|
||||
auto result = op.Apply(m_dataset);
|
||||
ASSERT_TRUE(result.IsSuccess());
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, TestOperation_TestIncorrectValue_Fails)
|
||||
{
|
||||
Path path("/arr/1");
|
||||
Value value(55);
|
||||
PatchOperation op = PatchOperation::TestOperation(path, value);
|
||||
auto result = op.Apply(m_dataset);
|
||||
ASSERT_FALSE(result.IsSuccess());
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, TestOperation_TestCorrectComplexValue_Succeeds)
|
||||
{
|
||||
Path path;
|
||||
Value value = m_dataset;
|
||||
PatchOperation op = PatchOperation::TestOperation(path, value);
|
||||
auto result = op.Apply(m_dataset);
|
||||
ASSERT_TRUE(result.IsSuccess());
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, TestOperation_TestIncorrectComplexValue_Fails)
|
||||
{
|
||||
Path path;
|
||||
Value value = m_dataset;
|
||||
value["arr"][4] = 9;
|
||||
PatchOperation op = PatchOperation::TestOperation(path, value);
|
||||
auto result = op.Apply(m_dataset);
|
||||
ASSERT_FALSE(result.IsSuccess());
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, TestOperation_TestInvalidPath_Fails)
|
||||
{
|
||||
Path path("/invalid/path");
|
||||
Value value;
|
||||
PatchOperation op = PatchOperation::TestOperation(path, value);
|
||||
auto result = op.Apply(m_dataset);
|
||||
ASSERT_FALSE(result.IsSuccess());
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, TestOperation_TestInsertArrayPath_Fails)
|
||||
{
|
||||
Path path("/arr/-");
|
||||
Value value(4);
|
||||
PatchOperation op = PatchOperation::TestOperation(path, value);
|
||||
auto result = op.Apply(m_dataset);
|
||||
ASSERT_FALSE(result.IsSuccess());
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, TestPatch_ReplaceArrayValue)
|
||||
{
|
||||
m_deltaDataset["arr"][0] = 5;
|
||||
GenerateAndVerifyDelta();
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, TestPatch_AppendArrayValue)
|
||||
{
|
||||
m_deltaDataset["arr"].ArrayPushBack(Value(7));
|
||||
auto result = GenerateAndVerifyDelta();
|
||||
|
||||
// Ensure the generated patch uses the array append operation
|
||||
ASSERT_EQ(result.m_forwardPatches.Size(), 1);
|
||||
EXPECT_TRUE(result.m_forwardPatches[0].GetDestinationPath()[1].IsEndOfArray());
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, TestPatch_AppendArrayValues)
|
||||
{
|
||||
m_deltaDataset["arr"].ArrayPushBack(Value(7));
|
||||
m_deltaDataset["arr"].ArrayPushBack(Value(8));
|
||||
m_deltaDataset["arr"].ArrayPushBack(Value(9));
|
||||
GenerateAndVerifyDelta();
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, TestPatch_InsertArrayValue)
|
||||
{
|
||||
auto& arr = m_deltaDataset["arr"].GetMutableArray();
|
||||
arr.insert(arr.begin(), Value(42));
|
||||
GenerateAndVerifyDelta();
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, TestPatch_InsertObjectKey)
|
||||
{
|
||||
m_deltaDataset["obj"]["newKey"].CopyFromString("test");
|
||||
GenerateAndVerifyDelta();
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, TestPatch_DeleteObjectKey)
|
||||
{
|
||||
m_deltaDataset["obj"].RemoveMember("foo");
|
||||
GenerateAndVerifyDelta();
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, TestPatch_AppendNodeValues)
|
||||
{
|
||||
m_deltaDataset["node"].ArrayPushBack(Value(7));
|
||||
m_deltaDataset["node"].ArrayPushBack(Value(8));
|
||||
m_deltaDataset["node"].ArrayPushBack(Value(9));
|
||||
GenerateAndVerifyDelta();
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, TestPatch_InsertNodeValue)
|
||||
{
|
||||
auto& node = m_deltaDataset["node"].GetMutableNode();
|
||||
node.GetChildren().insert(node.GetChildren().begin(), Value(42));
|
||||
GenerateAndVerifyDelta();
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, TestPatch_InsertNodeKey)
|
||||
{
|
||||
m_deltaDataset["node"]["newKey"].CopyFromString("test");
|
||||
GenerateAndVerifyDelta();
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, TestPatch_DeleteNodeKey)
|
||||
{
|
||||
m_deltaDataset["node"].RemoveMember("int");
|
||||
GenerateAndVerifyDelta();
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, TestPatch_RenameNode)
|
||||
{
|
||||
m_deltaDataset["node"].SetNodeName("RenamedNode");
|
||||
GenerateAndVerifyDelta();
|
||||
}
|
||||
|
||||
TEST_F(DomPatchTests, TestPatch_ReplaceRoot)
|
||||
{
|
||||
m_deltaDataset = Value(Type::Array);
|
||||
m_deltaDataset.ArrayPushBack(Value(2));
|
||||
m_deltaDataset.ArrayPushBack(Value(4));
|
||||
m_deltaDataset.ArrayPushBack(Value(6));
|
||||
GenerateAndVerifyDelta();
|
||||
}
|
||||
} // namespace AZ::Dom::Tests
|
||||
@@ -96,4 +96,25 @@ namespace AZ::Dom::Benchmark
|
||||
state.SetItemsProcessed(3 * state.iterations());
|
||||
}
|
||||
BENCHMARK_REGISTER_F(DomPathBenchmark, DomPathEntry_IsEndOfArray);
|
||||
|
||||
BENCHMARK_DEFINE_F(DomPathBenchmark, DomPathEntry_Comparison)(benchmark::State& state)
|
||||
{
|
||||
PathEntry name("name");
|
||||
PathEntry index(0);
|
||||
PathEntry endOfArray;
|
||||
endOfArray.SetEndOfArray();
|
||||
|
||||
for (auto _ : state)
|
||||
{
|
||||
benchmark::DoNotOptimize(name == name);
|
||||
benchmark::DoNotOptimize(name == index);
|
||||
benchmark::DoNotOptimize(name == endOfArray);
|
||||
benchmark::DoNotOptimize(index == index);
|
||||
benchmark::DoNotOptimize(index == endOfArray);
|
||||
benchmark::DoNotOptimize(endOfArray == endOfArray);
|
||||
}
|
||||
|
||||
state.SetItemsProcessed(6 * state.iterations());
|
||||
}
|
||||
BENCHMARK_REGISTER_F(DomPathBenchmark, DomPathEntry_Comparison);
|
||||
}
|
||||
|
||||
@@ -174,4 +174,23 @@ namespace AZ::Dom::Tests
|
||||
p.AppendToString(s);
|
||||
EXPECT_EQ(s, "/foo/0/foo/0");
|
||||
}
|
||||
|
||||
TEST_F(DomPathTests, MixedPath_AppendToFixedString)
|
||||
{
|
||||
Path p("/foo/0");
|
||||
|
||||
{
|
||||
AZStd::fixed_string<7> s;
|
||||
p.AppendToString(s);
|
||||
EXPECT_EQ(s, "/foo/0");
|
||||
}
|
||||
|
||||
{
|
||||
AZStd::fixed_string<9> s;
|
||||
p.AppendToString(s);
|
||||
EXPECT_EQ(s, "/foo/0");
|
||||
p.AppendToString(s);
|
||||
EXPECT_EQ(s, "/foo/0/fo");
|
||||
}
|
||||
}
|
||||
} // namespace AZ::Dom::Tests
|
||||
|
||||
@@ -224,6 +224,8 @@ set(FILES
|
||||
DOM/DomJsonBenchmarks.cpp
|
||||
DOM/DomPathTests.cpp
|
||||
DOM/DomPathBenchmarks.cpp
|
||||
DOM/DomPatchTests.cpp
|
||||
DOM/DomPatchBenchmarks.cpp
|
||||
DOM/DomValueTests.cpp
|
||||
DOM/DomValueBenchmarks.cpp
|
||||
)
|
||||
|
||||
@@ -292,7 +292,7 @@ namespace AzToolsFramework::Prefab
|
||||
return false;
|
||||
}
|
||||
|
||||
const InstanceOptionalConstReference instance = m_instanceEntityMapperInterface->FindOwningInstance(entityId);
|
||||
InstanceOptionalReference instance = m_instanceEntityMapperInterface->FindOwningInstance(entityId);
|
||||
if (!instance.has_value())
|
||||
{
|
||||
return false;
|
||||
@@ -308,7 +308,7 @@ namespace AzToolsFramework::Prefab
|
||||
return false;
|
||||
}
|
||||
|
||||
InstanceOptionalConstReference instance = m_instanceEntityMapperInterface->FindOwningInstance(entityId);
|
||||
InstanceOptionalReference instance = m_instanceEntityMapperInterface->FindOwningInstance(entityId);
|
||||
while (instance.has_value())
|
||||
{
|
||||
if (instance->get().GetAbsoluteInstanceAliasPath() == m_rootAliasFocusPath)
|
||||
|
||||
+1
-4
@@ -235,10 +235,7 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
|
||||
if (!asset->GetId().IsValid())
|
||||
{
|
||||
AZ_Error(
|
||||
"Prefab", false,
|
||||
"Invalid asset found referenced in scene while entering game mode. The asset was stored in an instance of %s.",
|
||||
classData->m_name);
|
||||
// Invalid asset found referenced in scene while entering game mode.
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
+9
-1
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
#include <AzToolsFramework/UI/EditorEntityUi/EditorEntityUiHandlerBase.h>
|
||||
#include <AzToolsFramework/UI/Outliner/EntityOutlinerListModel.hxx>
|
||||
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
|
||||
@@ -117,9 +118,16 @@ namespace AzToolsFramework
|
||||
{
|
||||
}
|
||||
|
||||
bool EditorEntityUiHandlerBase::OnEntityDoubleClick([[maybe_unused]] AZ::EntityId entityId) const
|
||||
bool EditorEntityUiHandlerBase::OnOutlinerItemDoubleClick([[maybe_unused]] const QModelIndex& index) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
AZ::EntityId EditorEntityUiHandlerBase::GetEntityIdFromIndex(const QModelIndex& index)
|
||||
{
|
||||
QModelIndex firstColumnIndex = index.siblingAtColumn(EntityOutlinerListModel::ColumnName);
|
||||
|
||||
return AZ::EntityId(firstColumnIndex.data(EntityOutlinerListModel::EntityIdRole).value<AZ::u64>());
|
||||
}
|
||||
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
+12
-8
@@ -21,7 +21,6 @@ class QTreeView;
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
//! Defines a handler that can customize entity UI appearance and behavior in the Entity Outliner.
|
||||
//! This class is meant to be abstract, entities do not have a handler by default.
|
||||
class EditorEntityUiHandlerBase
|
||||
{
|
||||
protected:
|
||||
@@ -33,7 +32,7 @@ namespace AzToolsFramework
|
||||
public:
|
||||
EditorEntityUiHandlerId GetHandlerId();
|
||||
|
||||
// # Entity Outliner
|
||||
// # Entity Outliner Item
|
||||
|
||||
//! Returns the item info string that is appended to the item name in the Outliner.
|
||||
virtual QString GenerateItemInfoString(AZ::EntityId entityId) const;
|
||||
@@ -41,10 +40,12 @@ namespace AzToolsFramework
|
||||
virtual QString GenerateItemTooltip(AZ::EntityId entityId) const;
|
||||
//! Returns the item icon pixmap to display in the Outliner.
|
||||
virtual QIcon GenerateItemIcon(AZ::EntityId entityId) const;
|
||||
//! Returns whether the element's lock and visibility state should be accessible in the Outliner
|
||||
virtual bool CanToggleLockVisibility(AZ::EntityId entityId) const;
|
||||
//! Returns whether the element's name should be editable
|
||||
virtual bool CanRename(AZ::EntityId entityId) const;
|
||||
//! Returns whether the element's lock and visibility state should be accessible in the Outliner
|
||||
virtual bool CanToggleLockVisibility(AZ::EntityId entityId) const;
|
||||
|
||||
// Qt-specific painting functions
|
||||
|
||||
//! Paints the background of the item in the Outliner.
|
||||
virtual void PaintItemBackground(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
|
||||
@@ -54,24 +55,27 @@ namespace AzToolsFramework
|
||||
//! Paints the background of the descendant branches of the item in the Outliner.
|
||||
virtual void PaintDescendantBranchBackground(QPainter* painter, const QTreeView* view, const QRect& rect,
|
||||
const QModelIndex& index, const QModelIndex& descendantIndex) const;
|
||||
|
||||
//! Paints visual elements on the foreground of the item in the Outliner.
|
||||
virtual void PaintItemForeground(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
|
||||
//! Paints visual elements on the foreground of the descendants of the item in the Outliner.
|
||||
virtual void PaintDescendantForeground(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index,
|
||||
const QModelIndex& descendantIndex) const;
|
||||
|
||||
// Outliner-specific interactions
|
||||
|
||||
//! Triggered when the entity is clicked in the Outliner.
|
||||
//! @return True if the click has been handled and should not be propagated, false otherwise.
|
||||
virtual bool OnOutlinerItemClick(const QPoint& position, const QStyleOptionViewItem& option, const QModelIndex& index) const;
|
||||
//! Triggered when the entity is double-clicked in the Outliner.
|
||||
//! @return True if the double-click has been handled and should not be propagated, false otherwise.
|
||||
virtual bool OnOutlinerItemDoubleClick(const QModelIndex& index) const;
|
||||
//! Triggered when an entity's children are expanded in the Outliner.
|
||||
virtual void OnOutlinerItemExpand(const QModelIndex& index) const;
|
||||
//! Triggered when an entity's children are collapsed in the Outliner.
|
||||
virtual void OnOutlinerItemCollapse(const QModelIndex& index) const;
|
||||
|
||||
//! Triggered when the entity is double clicked in the Outliner or in the Viewport.
|
||||
//! @return True if the double click has been handled and should not be propagated, false otherwise.
|
||||
virtual bool OnEntityDoubleClick(AZ::EntityId entityId) const;
|
||||
protected:
|
||||
static AZ::EntityId GetEntityIdFromIndex(const QModelIndex& index);
|
||||
|
||||
private:
|
||||
EditorEntityUiHandlerId m_handlerId = 0;
|
||||
|
||||
+1
-1
@@ -945,7 +945,7 @@ namespace AzToolsFramework
|
||||
{
|
||||
if (AZ::EntityId entityId = GetEntityIdFromIndex(index); auto entityUiHandler = m_editorEntityUiInterface->GetHandler(entityId))
|
||||
{
|
||||
entityUiHandler->OnEntityDoubleClick(entityId);
|
||||
entityUiHandler->OnOutlinerItemDoubleClick(index);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace AzToolsFramework
|
||||
}
|
||||
}
|
||||
|
||||
QIcon LevelRootUiHandler::GenerateItemIcon(AZ::EntityId /*entityId*/) const
|
||||
QIcon LevelRootUiHandler::GenerateItemIcon([[maybe_unused]] AZ::EntityId entityId) const
|
||||
{
|
||||
return QIcon(m_levelRootIconPath);
|
||||
}
|
||||
@@ -62,17 +62,18 @@ namespace AzToolsFramework
|
||||
return infoString;
|
||||
}
|
||||
|
||||
bool LevelRootUiHandler::CanToggleLockVisibility(AZ::EntityId /*entityId*/) const
|
||||
bool LevelRootUiHandler::CanToggleLockVisibility([[maybe_unused]] AZ::EntityId entityId) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LevelRootUiHandler::CanRename(AZ::EntityId /*entityId*/) const
|
||||
bool LevelRootUiHandler::CanRename([[maybe_unused]] AZ::EntityId entityId) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void LevelRootUiHandler::PaintItemBackground(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& /*index*/) const
|
||||
void LevelRootUiHandler::PaintItemBackground(
|
||||
QPainter* painter, const QStyleOptionViewItem& option, [[maybe_unused]] const QModelIndex& index) const
|
||||
{
|
||||
if (!painter)
|
||||
{
|
||||
@@ -94,8 +95,10 @@ namespace AzToolsFramework
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
bool LevelRootUiHandler::OnEntityDoubleClick(AZ::EntityId entityId) const
|
||||
bool LevelRootUiHandler::OnOutlinerItemDoubleClick(const QModelIndex& index) const
|
||||
{
|
||||
AZ::EntityId entityId = GetEntityIdFromIndex(index);
|
||||
|
||||
if (auto prefabFocusPublicInterface = AZ::Interface<Prefab::PrefabFocusPublicInterface>::Get();
|
||||
!prefabFocusPublicInterface->IsOwningPrefabBeingFocused(entityId))
|
||||
{
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace AzToolsFramework
|
||||
bool CanToggleLockVisibility(AZ::EntityId entityId) const override;
|
||||
bool CanRename(AZ::EntityId entityId) const override;
|
||||
void PaintItemBackground(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
|
||||
bool OnEntityDoubleClick(AZ::EntityId entityId) const override;
|
||||
bool OnOutlinerItemDoubleClick(const QModelIndex& index) const override;
|
||||
|
||||
private:
|
||||
Prefab::PrefabPublicInterface* m_prefabPublicInterface = nullptr;
|
||||
|
||||
@@ -99,7 +99,7 @@ namespace AzToolsFramework
|
||||
return;
|
||||
}
|
||||
|
||||
AZ::EntityId entityId(index.data(EntityOutlinerListModel::EntityIdRole).value<AZ::u64>());
|
||||
AZ::EntityId entityId = GetEntityIdFromIndex(index);
|
||||
const bool isFirstColumn = index.column() == EntityOutlinerListModel::ColumnName;
|
||||
const bool isLastColumn = index.column() == EntityOutlinerListModel::ColumnLockToggle;
|
||||
QModelIndex firstColumnIndex = index.siblingAtColumn(EntityOutlinerListModel::ColumnName);
|
||||
@@ -183,7 +183,7 @@ namespace AzToolsFramework
|
||||
return;
|
||||
}
|
||||
|
||||
AZ::EntityId entityId(index.data(EntityOutlinerListModel::EntityIdRole).value<AZ::u64>());
|
||||
AZ::EntityId entityId = GetEntityIdFromIndex(index);
|
||||
|
||||
const QTreeView* outlinerTreeView(qobject_cast<const QTreeView*>(option.widget));
|
||||
const int ancestorLeft = outlinerTreeView->visualRect(index).left() + (m_prefabBorderThickness / 2) - 1;
|
||||
@@ -283,7 +283,7 @@ namespace AzToolsFramework
|
||||
|
||||
void PrefabUiHandler::PaintItemForeground(QPainter* painter, const QStyleOptionViewItem& option, [[maybe_unused]] const QModelIndex& index) const
|
||||
{
|
||||
AZ::EntityId entityId(index.data(EntityOutlinerListModel::EntityIdRole).value<AZ::u64>());
|
||||
AZ::EntityId entityId = GetEntityIdFromIndex(index);
|
||||
const QPoint offset = QPoint(-18, 3);
|
||||
QModelIndex firstColumnIndex = index.siblingAtColumn(EntityOutlinerListModel::ColumnName);
|
||||
const int iconSize = 16;
|
||||
@@ -385,7 +385,7 @@ namespace AzToolsFramework
|
||||
|
||||
bool PrefabUiHandler::OnOutlinerItemClick(const QPoint& position, const QStyleOptionViewItem& option, const QModelIndex& index) const
|
||||
{
|
||||
AZ::EntityId entityId(index.data(EntityOutlinerListModel::EntityIdRole).value<AZ::u64>());
|
||||
AZ::EntityId entityId = GetEntityIdFromIndex(index);
|
||||
const QPoint offset = QPoint(-18, 3);
|
||||
|
||||
if (m_prefabFocusPublicInterface->IsOwningPrefabInFocusHierarchy(entityId))
|
||||
@@ -411,7 +411,7 @@ namespace AzToolsFramework
|
||||
|
||||
void PrefabUiHandler::OnOutlinerItemCollapse(const QModelIndex& index) const
|
||||
{
|
||||
AZ::EntityId entityId(index.data(EntityOutlinerListModel::EntityIdRole).value<AZ::u64>());
|
||||
AZ::EntityId entityId = GetEntityIdFromIndex(index);
|
||||
|
||||
if (m_prefabFocusPublicInterface->IsOwningPrefabBeingFocused(entityId))
|
||||
{
|
||||
@@ -420,8 +420,10 @@ namespace AzToolsFramework
|
||||
}
|
||||
}
|
||||
|
||||
bool PrefabUiHandler::OnEntityDoubleClick(AZ::EntityId entityId) const
|
||||
bool PrefabUiHandler::OnOutlinerItemDoubleClick(const QModelIndex& index) const
|
||||
{
|
||||
AZ::EntityId entityId = GetEntityIdFromIndex(index);
|
||||
|
||||
if (!m_prefabFocusPublicInterface->IsOwningPrefabBeingFocused(entityId))
|
||||
{
|
||||
// Focus on this prefab
|
||||
|
||||
@@ -43,8 +43,8 @@ namespace AzToolsFramework
|
||||
const QModelIndex& index,
|
||||
const QModelIndex& descendantIndex) const override;
|
||||
bool OnOutlinerItemClick(const QPoint& position, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
|
||||
bool OnOutlinerItemDoubleClick(const QModelIndex& index) const override;
|
||||
void OnOutlinerItemCollapse(const QModelIndex& index) const override;
|
||||
bool OnEntityDoubleClick(AZ::EntityId entityId) const override;
|
||||
|
||||
protected:
|
||||
Prefab::PrefabFocusPublicInterface* m_prefabFocusPublicInterface = nullptr;
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace UnitTest
|
||||
// When no containers are in the way, the function will just return the entityId of the entity that was clicked.
|
||||
|
||||
// Click on Car Entity
|
||||
ClickAtWorldPositionOnViewport(WorldCarEntityPosition);
|
||||
ClickAtWorldPositionOnViewport(s_worldCarEntityPosition);
|
||||
|
||||
// Verify the correct entity is selected
|
||||
auto selectedEntitiesAfter = GetSelectedEntities();
|
||||
@@ -29,7 +29,7 @@ namespace UnitTest
|
||||
m_containerEntityInterface->RegisterEntityAsContainer(m_entityMap[StreetEntityName]); // Containers are closed by default
|
||||
|
||||
// Click on Car Entity
|
||||
ClickAtWorldPositionOnViewport(WorldCarEntityPosition);
|
||||
ClickAtWorldPositionOnViewport(s_worldCarEntityPosition);
|
||||
|
||||
// Verify the correct entity is selected
|
||||
auto selectedEntitiesAfter = GetSelectedEntities();
|
||||
@@ -47,7 +47,7 @@ namespace UnitTest
|
||||
m_containerEntityInterface->SetContainerOpen(m_entityMap[StreetEntityName], true);
|
||||
|
||||
// Click on Car Entity
|
||||
ClickAtWorldPositionOnViewport(WorldCarEntityPosition);
|
||||
ClickAtWorldPositionOnViewport(s_worldCarEntityPosition);
|
||||
|
||||
// Verify the correct entity is selected
|
||||
auto selectedEntitiesAfter = GetSelectedEntities();
|
||||
@@ -65,7 +65,7 @@ namespace UnitTest
|
||||
m_containerEntityInterface->RegisterEntityAsContainer(m_entityMap[CityEntityName]);
|
||||
|
||||
// Click on Car Entity
|
||||
ClickAtWorldPositionOnViewport(WorldCarEntityPosition);
|
||||
ClickAtWorldPositionOnViewport(s_worldCarEntityPosition);
|
||||
|
||||
// Verify the correct entity is selected
|
||||
auto selectedEntitiesAfter = GetSelectedEntities();
|
||||
@@ -85,7 +85,7 @@ namespace UnitTest
|
||||
m_containerEntityInterface->SetContainerOpen(m_entityMap[CityEntityName], true);
|
||||
|
||||
// Click on Car Entity
|
||||
ClickAtWorldPositionOnViewport(WorldCarEntityPosition);
|
||||
ClickAtWorldPositionOnViewport(s_worldCarEntityPosition);
|
||||
|
||||
// Verify the correct entity is selected
|
||||
auto selectedEntitiesAfter = GetSelectedEntities();
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <Tests/FocusMode/EditorFocusModeFixture.h>
|
||||
|
||||
#include <AzCore/Component/TransformBus.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityHelpers.h>
|
||||
|
||||
#include <Tests/BoundsTestComponent.h>
|
||||
@@ -93,10 +94,13 @@ namespace UnitTest
|
||||
entity->CreateComponent<UnitTest::BoundsTestComponent>();
|
||||
entity->Activate();
|
||||
|
||||
// Move the CarEntity so it's out of the way.
|
||||
AZ::TransformBus::Event(m_entityMap[CarEntityName], &AZ::TransformBus::Events::SetWorldTranslation, WorldCarEntityPosition);
|
||||
// Move the City so that it is in view
|
||||
AZ::TransformBus::Event(m_entityMap[CityEntityName], &AZ::TransformBus::Events::SetWorldTranslation, s_worldCityEntityPosition);
|
||||
|
||||
// Setup the camera so the Car entity is in view.
|
||||
// Move the CarEntity so that it's not overlapping with the rest
|
||||
AZ::TransformBus::Event(m_entityMap[CarEntityName], &AZ::TransformBus::Events::SetWorldTranslation, s_worldCarEntityPosition);
|
||||
|
||||
// Setup the camera so the entities is in view.
|
||||
AzFramework::SetCameraTransform(
|
||||
m_cameraState,
|
||||
AZ::Transform::CreateFromQuaternionAndTranslation(
|
||||
@@ -113,4 +117,5 @@ namespace UnitTest
|
||||
|
||||
return entity->GetId();
|
||||
}
|
||||
|
||||
} // namespace UnitTest
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Component/TransformBus.h>
|
||||
#include <AzCore/UnitTest/TestTypes.h>
|
||||
#include <AzCore/UserSettings/UserSettingsComponent.h>
|
||||
|
||||
@@ -38,9 +37,6 @@ namespace UnitTest
|
||||
AzToolsFramework::EntityIdList GetSelectedEntities();
|
||||
|
||||
AzFramework::EntityContextId m_editorEntityContextId = AzFramework::EntityContextId::CreateNull();
|
||||
AzFramework::CameraState m_cameraState;
|
||||
|
||||
inline static const AZ::Vector3 CameraPosition = AZ::Vector3(10.0f, 15.0f, 10.0f);
|
||||
|
||||
inline static const char* CityEntityName = "City";
|
||||
inline static const char* StreetEntityName = "Street";
|
||||
@@ -49,7 +45,11 @@ namespace UnitTest
|
||||
inline static const char* Passenger1EntityName = "Passenger1";
|
||||
inline static const char* Passenger2EntityName = "Passenger2";
|
||||
|
||||
inline static AZ::Vector3 WorldCarEntityPosition = AZ::Vector3(5.0f, 15.0f, 0.0f);
|
||||
AzFramework::CameraState m_cameraState;
|
||||
|
||||
inline static const AZ::Vector3 CameraPosition = AZ::Vector3(10.0f, 15.0f, 10.0f);
|
||||
inline static AZ::Vector3 s_worldCityEntityPosition = AZ::Vector3(5.0f, 10.0f, 0.0f);
|
||||
inline static AZ::Vector3 s_worldCarEntityPosition = AZ::Vector3(5.0f, 15.0f, 0.0f);
|
||||
};
|
||||
|
||||
} // namespace UnitTest
|
||||
|
||||
@@ -45,5 +45,20 @@ namespace UnitTest
|
||||
// Click the entity in the viewport
|
||||
m_actionDispatcher->CameraState(m_cameraState)->MousePosition(carScreenPosition)->MouseLButtonDown()->MouseLButtonUp();
|
||||
}
|
||||
|
||||
void BoxSelectOnViewport()
|
||||
{
|
||||
// Calculate the position in screen space of where to begin and end the box select action
|
||||
const auto beginningPositionWorldBoxSelect = AzFramework::WorldToScreen(AZ::Vector3(-10.0f, 15.0f, 5.0f), m_cameraState);
|
||||
const auto endingPositionWorldBoxSelect = AzFramework::WorldToScreen(AZ::Vector3(10.0f, 15.0f, -5.0f), m_cameraState);
|
||||
|
||||
// Perform a box select in the viewport
|
||||
m_actionDispatcher->SetStickySelect(true)
|
||||
->CameraState(m_cameraState)
|
||||
->MousePosition(beginningPositionWorldBoxSelect)
|
||||
->MouseLButtonDown()
|
||||
->MousePosition(endingPositionWorldBoxSelect)
|
||||
->MouseLButtonUp();
|
||||
}
|
||||
};
|
||||
} // namespace UnitTest
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user