Merge branch 'development' of https://github.com/aws-lumberyard-dev/o3de into mnaumov/2372
This commit is contained in:
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"Amazon": {
|
||||
"AssetProcessor": {
|
||||
"Settings": {
|
||||
"RC cgf": {
|
||||
"ignore": true
|
||||
},
|
||||
"RC fbx": {
|
||||
"ignore": true
|
||||
},
|
||||
"ScanFolder AtomTestData": {
|
||||
"watch": "@ENGINEROOT@/Gems/Atom/TestData",
|
||||
"recursive": 1,
|
||||
"order": 1000
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
TEST_SUITE main
|
||||
TEST_SERIAL TRUE
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Active.py
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
AZ::AssetProcessor
|
||||
|
||||
+30
@@ -8,6 +8,7 @@ SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.entity as entity
|
||||
import azlmbr.legacy.general as general
|
||||
import azlmbr.object
|
||||
|
||||
from typing import List
|
||||
@@ -428,3 +429,32 @@ def get_component_type_id_map(component_name_list):
|
||||
type_ids_by_component[component_names[i]] = typeId
|
||||
|
||||
return type_ids_by_component
|
||||
|
||||
|
||||
def attach_component_to_entity(entity_id, component_name):
|
||||
# type: (azlmbr.entity.EntityId, str) -> azlmbr.entity.EntityComponentIdPair
|
||||
"""
|
||||
Adds the component if not added already.
|
||||
:param entity_id: EntityId of the entity to attach the component to
|
||||
:param component_name: name of the component
|
||||
:return: If successful, returns the EntityComponentIdPair, otherwise returns None.
|
||||
"""
|
||||
type_ids_list = editor.EditorComponentAPIBus(
|
||||
bus.Broadcast, 'FindComponentTypeIdsByEntityType', [component_name], 0)
|
||||
general.log(f"Components found = {len(type_ids_list)}")
|
||||
if len(type_ids_list) < 1:
|
||||
general.log(f"ERROR: A component class with name {component_name} doesn't exist")
|
||||
return None
|
||||
elif len(type_ids_list) > 1:
|
||||
general.log(f"ERROR: Found more than one component classes with same name: {component_name}")
|
||||
return None
|
||||
# Before adding the component let's check if it is already attached to the entity.
|
||||
component_outcome = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentOfType', entity_id, type_ids_list[0])
|
||||
if component_outcome.IsSuccess():
|
||||
return component_outcome.GetValue() # In this case the value is not a list.
|
||||
component_outcome = editor.EditorComponentAPIBus(bus.Broadcast, 'AddComponentsOfType', entity_id, type_ids_list)
|
||||
if component_outcome.IsSuccess():
|
||||
general.log(f"{component_name} Component added to entity.")
|
||||
return component_outcome.GetValue()[0]
|
||||
general.log(f"ERROR: Failed to add component [{component_name}] to entity")
|
||||
return None
|
||||
|
||||
+13
-2
@@ -29,7 +29,7 @@ def teardown_editor(editor):
|
||||
|
||||
def launch_and_validate_results(request, test_directory, editor, editor_script, expected_lines, unexpected_lines=[],
|
||||
halt_on_unexpected=False, run_python="--runpythontest", auto_test_mode=True, null_renderer=True, cfg_args=[],
|
||||
timeout=300):
|
||||
timeout=300, log_file_name="Editor.log"):
|
||||
"""
|
||||
Runs the Editor with the specified script, and monitors for expected log lines.
|
||||
:param request: Special fixture providing information of the requesting test function.
|
||||
@@ -44,6 +44,7 @@ def launch_and_validate_results(request, test_directory, editor, editor_script,
|
||||
:param null_renderer: Specifies the test does not require the renderer. Defaults to True.
|
||||
:param cfg_args: Additional arguments for CFG, such as LevelName.
|
||||
:param timeout: Length of time for test to run. Default is 60.
|
||||
:param log_file_name: Name of the log file created by the editor. Defaults to 'Editor.log'
|
||||
"""
|
||||
test_case = os.path.join(test_directory, editor_script)
|
||||
request.addfinalizer(lambda: teardown_editor(editor))
|
||||
@@ -58,7 +59,17 @@ def launch_and_validate_results(request, test_directory, editor, editor_script,
|
||||
|
||||
with editor.start():
|
||||
|
||||
editorlog_file = os.path.join(editor.workspace.paths.project_log(), 'Editor.log')
|
||||
editorlog_file = os.path.join(editor.workspace.paths.project_log(), log_file_name)
|
||||
|
||||
# Log monitor requires the file to exist.
|
||||
logger.debug(f"Waiting until log file <{editorlog_file}> exists...")
|
||||
waiter.wait_for(
|
||||
lambda: os.path.exists(editorlog_file),
|
||||
timeout=60,
|
||||
exc=f"Log file '{editorlog_file}' was never created by another process.",
|
||||
interval=1,
|
||||
)
|
||||
logger.debug(f"Done! log file <{editorlog_file}> exists.")
|
||||
|
||||
# Initialize the log monitor and set time to wait for log creation
|
||||
log_monitor = ly_test_tools.log.log_monitor.LogMonitor(launcher=editor, log_file_path=editorlog_file)
|
||||
|
||||
@@ -13,7 +13,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
TEST_REQUIRES gpu
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Active.py
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
AZ::AssetProcessor
|
||||
|
||||
@@ -12,7 +12,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
TEST_SUITE periodic
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
AZ::AssetProcessor
|
||||
|
||||
@@ -12,7 +12,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
TEST_SUITE main
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Active.py
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
AZ::AssetProcessor
|
||||
|
||||
+11
-13
@@ -92,17 +92,17 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
AZ::AssetProcessor
|
||||
)
|
||||
|
||||
ly_add_pytest(
|
||||
NAME AssetPipelineTests.AssetBundler
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/asset_bundler_batch_tests.py
|
||||
EXCLUDE_TEST_RUN_TARGET_FROM_IDE
|
||||
TEST_SERIAL
|
||||
TIMEOUT 2400
|
||||
TEST_SUITE periodic
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
AZ::AssetBundlerBatch
|
||||
)
|
||||
# Issue #3017
|
||||
#ly_add_pytest(
|
||||
# NAME AssetPipelineTests.AssetBundler
|
||||
# PATH ${CMAKE_CURRENT_LIST_DIR}/asset_bundler_batch_tests.py
|
||||
# EXCLUDE_TEST_RUN_TARGET_FROM_IDE
|
||||
# TEST_SERIAL
|
||||
# TEST_SUITE periodic
|
||||
# RUNTIME_DEPENDENCIES
|
||||
# AZ::AssetProcessor
|
||||
# AZ::AssetBundlerBatch
|
||||
#)
|
||||
|
||||
ly_add_pytest(
|
||||
NAME AssetPipelineTests.AssetBundler_SandBox
|
||||
@@ -111,7 +111,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
PYTEST_MARKS "SUITE_sandbox" # run only sandbox tests in this file
|
||||
EXCLUDE_TEST_RUN_TARGET_FROM_IDE
|
||||
TEST_SERIAL
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
AZ::AssetBundlerBatch
|
||||
@@ -133,7 +132,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/missing_dependency_tests.py
|
||||
EXCLUDE_TEST_RUN_TARGET_FROM_IDE
|
||||
TEST_SERIAL
|
||||
TIMEOUT 1500
|
||||
TEST_SUITE periodic
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessorBatch
|
||||
|
||||
@@ -39,7 +39,7 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_BUILD_TESTS_SUPPORTED AND AutomatedT
|
||||
TEST_SUITE main
|
||||
TEST_REQUIRES gpu
|
||||
TEST_SERIAL
|
||||
TIMEOUT 800
|
||||
TIMEOUT 1200
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/test_Atom_GPUTests.py
|
||||
RUNTIME_DEPENDENCIES
|
||||
AssetProcessor
|
||||
|
||||
+2
-2
@@ -206,8 +206,8 @@ def run():
|
||||
# PostFX Layer Component
|
||||
ComponentTests("PostFX Layer")
|
||||
|
||||
# Radius Weight Modifier Component
|
||||
ComponentTests("Radius Weight Modifier")
|
||||
# PostFX Radius Weight Modifier Component
|
||||
ComponentTests("PostFX Radius Weight Modifier")
|
||||
|
||||
# Light Component
|
||||
ComponentTests("Light")
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ import azlmbr.legacy.general as general
|
||||
sys.path.append(os.path.join(azlmbr.paths.devassets, "Gem", "PythonTests"))
|
||||
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from atom_renderer.atom_utils.atom_component_helper import LIGHT_TYPES
|
||||
from atom_renderer.atom_utils.atom_constants import LIGHT_TYPES
|
||||
|
||||
LIGHT_TYPE_PROPERTY = 'Controller|Configuration|Light type'
|
||||
SPHERE_AND_SPOT_DISK_LIGHT_PROPERTIES = [
|
||||
|
||||
+183
@@ -0,0 +1,183 @@
|
||||
"""
|
||||
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
|
||||
|
||||
import azlmbr.materialeditor will fail with a ModuleNotFound error when using this script with Editor.exe
|
||||
This is because azlmbr.materialeditor only binds to MaterialEditor.exe and not Editor.exe
|
||||
You need to launch this script with MaterialEditor.exe in order for azlmbr.materialeditor to appear.
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
|
||||
import azlmbr.math as math
|
||||
import azlmbr.paths
|
||||
|
||||
sys.path.append(os.path.join(azlmbr.paths.devassets, "Gem", "PythonTests"))
|
||||
|
||||
import atom_renderer.atom_utils.material_editor_utils as material_editor
|
||||
|
||||
NEW_MATERIAL = "test_material.material"
|
||||
NEW_MATERIAL_1 = "test_material_1.material"
|
||||
NEW_MATERIAL_2 = "test_material_2.material"
|
||||
TEST_MATERIAL_1 = "001_DefaultWhite.material"
|
||||
TEST_MATERIAL_2 = "002_BaseColorLerp.material"
|
||||
TEST_MATERIAL_3 = "003_MetalMatte.material"
|
||||
TEST_DATA_PATH = os.path.join(
|
||||
azlmbr.paths.devroot, "Gems", "Atom", "TestData", "TestData", "Materials", "StandardPbrTestCases"
|
||||
)
|
||||
MATERIAL_TYPE_PATH = os.path.join(
|
||||
azlmbr.paths.devroot, "Gems", "Atom", "Feature", "Common", "Assets",
|
||||
"Materials", "Types", "StandardPBR.materialtype",
|
||||
)
|
||||
|
||||
|
||||
def run():
|
||||
"""
|
||||
Summary:
|
||||
Material Editor basic tests including the below
|
||||
1. Opening an Existing Asset
|
||||
2. Creating a New Asset
|
||||
3. Closing Selected Material
|
||||
4. Closing All Materials
|
||||
5. Closing all but Selected Material
|
||||
6. Saving Material
|
||||
7. Saving as a New Material
|
||||
8. Saving as a Child Material
|
||||
9. Saving all Open Materials
|
||||
|
||||
Expected Result:
|
||||
All the above functions work as expected in Material Editor.
|
||||
|
||||
:return: None
|
||||
"""
|
||||
|
||||
# 1) Test Case: Opening an Existing Asset
|
||||
document_id = material_editor.open_material(MATERIAL_TYPE_PATH)
|
||||
print(f"Material opened: {material_editor.is_open(document_id)}")
|
||||
|
||||
# Verify if the test material exists initially
|
||||
target_path = os.path.join(azlmbr.paths.devroot, "AutomatedTesting", "Materials", NEW_MATERIAL)
|
||||
print(f"Test asset doesn't exist initially: {not os.path.exists(target_path)}")
|
||||
|
||||
# 2) Test Case: Creating a New Material Using Existing One
|
||||
material_editor.save_document_as_child(document_id, target_path)
|
||||
material_editor.wait_for_condition(lambda: os.path.exists(target_path), 2.0)
|
||||
print(f"New asset created: {os.path.exists(target_path)}")
|
||||
|
||||
# Verify if the newly created document is open
|
||||
new_document_id = material_editor.open_material(target_path)
|
||||
material_editor.wait_for_condition(lambda: material_editor.is_open(new_document_id))
|
||||
print(f"New Material opened: {material_editor.is_open(new_document_id)}")
|
||||
|
||||
# 3) Test Case: Closing Selected Material
|
||||
print(f"Material closed: {material_editor.close_document(new_document_id)}")
|
||||
|
||||
# Open materials initially
|
||||
document1_id, document2_id, document3_id = (
|
||||
material_editor.open_material(os.path.join(TEST_DATA_PATH, material))
|
||||
for material in [TEST_MATERIAL_1, TEST_MATERIAL_2, TEST_MATERIAL_3]
|
||||
)
|
||||
|
||||
# 4) Test Case: Closing All Materials
|
||||
print(f"All documents closed: {material_editor.close_all_documents()}")
|
||||
|
||||
# 5) Test Case: Closing all but Selected Material
|
||||
document1_id, document2_id, document3_id = (
|
||||
material_editor.open_material(os.path.join(TEST_DATA_PATH, material))
|
||||
for material in [TEST_MATERIAL_1, TEST_MATERIAL_2, TEST_MATERIAL_3]
|
||||
)
|
||||
result = material_editor.close_all_except_selected(document1_id)
|
||||
print(f"Close All Except Selected worked as expected: {result and material_editor.is_open(document1_id)}")
|
||||
|
||||
# 6) Test Case: Saving Material
|
||||
document_id = material_editor.open_material(os.path.join(TEST_DATA_PATH, TEST_MATERIAL_1))
|
||||
property_name = azlmbr.name.Name("baseColor.color")
|
||||
initial_color = material_editor.get_property(document_id, property_name)
|
||||
# Assign new color to the material file and save the actual material
|
||||
expected_color = math.Color(0.25, 0.25, 0.25, 1.0)
|
||||
material_editor.set_property(document_id, property_name, expected_color)
|
||||
material_editor.save_document(document_id)
|
||||
|
||||
# 7) Test Case: Saving as a New Material
|
||||
# Assign new color to the material file and save the document as copy
|
||||
expected_color_1 = math.Color(0.5, 0.5, 0.5, 1.0)
|
||||
material_editor.set_property(document_id, property_name, expected_color_1)
|
||||
target_path_1 = os.path.join(azlmbr.paths.devroot, "AutomatedTesting", "Materials", NEW_MATERIAL_1)
|
||||
material_editor.save_document_as_copy(document_id, target_path_1)
|
||||
time.sleep(2.0)
|
||||
|
||||
# 8) Test Case: Saving as a Child Material
|
||||
# Assign new color to the material file save the document as child
|
||||
expected_color_2 = math.Color(0.75, 0.75, 0.75, 1.0)
|
||||
material_editor.set_property(document_id, property_name, expected_color_2)
|
||||
target_path_2 = os.path.join(azlmbr.paths.devroot, "AutomatedTesting", "Materials", NEW_MATERIAL_2)
|
||||
material_editor.save_document_as_child(document_id, target_path_2)
|
||||
time.sleep(2.0)
|
||||
|
||||
# Close/Reopen documents
|
||||
material_editor.close_all_documents()
|
||||
document_id = material_editor.open_material(os.path.join(TEST_DATA_PATH, TEST_MATERIAL_1))
|
||||
document1_id = material_editor.open_material(target_path_1)
|
||||
document2_id = material_editor.open_material(target_path_2)
|
||||
|
||||
# Verify if the changes are saved in the actual document
|
||||
actual_color = material_editor.get_property(document_id, property_name)
|
||||
print(f"Actual Document saved with changes: {material_editor.compare_colors(actual_color, expected_color)}")
|
||||
|
||||
# Verify if the changes are saved in the document saved as copy
|
||||
actual_color = material_editor.get_property(document1_id, property_name)
|
||||
result_copy = material_editor.compare_colors(actual_color, expected_color_1)
|
||||
print(f"Document saved as copy is saved with changes: {result_copy}")
|
||||
|
||||
# Verify if the changes are saved in the document saved as child
|
||||
actual_color = material_editor.get_property(document2_id, property_name)
|
||||
result_child = material_editor.compare_colors(actual_color, expected_color_2)
|
||||
print(f"Document saved as child is saved with changes: {result_child}")
|
||||
|
||||
# Revert back the changes in the actual document
|
||||
material_editor.set_property(document_id, property_name, initial_color)
|
||||
material_editor.save_document(document_id)
|
||||
material_editor.close_all_documents()
|
||||
|
||||
# 9) Test Case: Saving all Open Materials
|
||||
# Open first material and make change to the values
|
||||
document1_id = material_editor.open_material(os.path.join(TEST_DATA_PATH, TEST_MATERIAL_1))
|
||||
property1_name = azlmbr.name.Name("metallic.factor")
|
||||
initial_metallic_factor = material_editor.get_property(document1_id, property1_name)
|
||||
expected_metallic_factor = 0.444
|
||||
material_editor.set_property(document1_id, property1_name, expected_metallic_factor)
|
||||
|
||||
# Open second material and make change to the values
|
||||
document2_id = material_editor.open_material(os.path.join(TEST_DATA_PATH, TEST_MATERIAL_2))
|
||||
property2_name = azlmbr.name.Name("baseColor.color")
|
||||
initial_color = material_editor.get_property(document2_id, property2_name)
|
||||
expected_color = math.Color(0.4156, 0.0196, 0.6862, 1.0)
|
||||
material_editor.set_property(document2_id, property2_name, expected_color)
|
||||
|
||||
# Save all and close all documents
|
||||
material_editor.save_all()
|
||||
material_editor.close_all_documents()
|
||||
|
||||
# Reopen materials and verify values
|
||||
document1_id = material_editor.open_material(os.path.join(TEST_DATA_PATH, TEST_MATERIAL_1))
|
||||
result = material_editor.is_close(
|
||||
material_editor.get_property(document1_id, property1_name), expected_metallic_factor, 0.00001
|
||||
)
|
||||
document2_id = material_editor.open_material(os.path.join(TEST_DATA_PATH, TEST_MATERIAL_2))
|
||||
result = result and material_editor.compare_colors(
|
||||
expected_color, material_editor.get_property(document2_id, property2_name))
|
||||
print(f"Save All worked as expected: {result}")
|
||||
|
||||
# Revert the changes made
|
||||
material_editor.set_property(document1_id, property1_name, initial_metallic_factor)
|
||||
material_editor.set_property(document2_id, property2_name, initial_color)
|
||||
material_editor.save_all()
|
||||
material_editor.close_all_documents()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
run()
|
||||
+267
@@ -0,0 +1,267 @@
|
||||
"""
|
||||
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
|
||||
|
||||
Hydra script that is used to create an entity with a Light component attached.
|
||||
It then updates the property values of the Light component and takes a screenshot.
|
||||
The screenshot is compared against an expected golden image for test verification.
|
||||
|
||||
See the run() function for more in-depth test info.
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
|
||||
import azlmbr.asset as asset
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.math as math
|
||||
import azlmbr.paths
|
||||
import azlmbr.legacy.general as general
|
||||
|
||||
sys.path.append(os.path.join(azlmbr.paths.devroot, "AutomatedTesting", "Gem", "PythonTests"))
|
||||
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from atom_renderer.atom_utils import atom_component_helper, atom_constants, screenshot_utils
|
||||
from editor_python_test_tools.editor_test_helper import EditorTestHelper
|
||||
|
||||
helper = EditorTestHelper(log_prefix="Atom_EditorTestHelper")
|
||||
|
||||
LEVEL_NAME = "auto_test"
|
||||
LIGHT_COMPONENT = "Light"
|
||||
LIGHT_TYPE_PROPERTY = 'Controller|Configuration|Light type'
|
||||
DEGREE_RADIAN_FACTOR = 0.0174533
|
||||
|
||||
|
||||
def run():
|
||||
"""
|
||||
Sets up the tests by making sure the required level is created & setup correctly.
|
||||
It then executes 2 test cases - see each associated test function's docstring for more info.
|
||||
|
||||
Finally prints the string "Light component tests completed" after completion
|
||||
|
||||
Tests will fail immediately if any of these log lines are found:
|
||||
1. Trace::Assert
|
||||
2. Trace::Error
|
||||
3. Traceback (most recent call last):
|
||||
|
||||
:return: None
|
||||
"""
|
||||
atom_component_helper.create_basic_atom_level(level_name=LEVEL_NAME)
|
||||
|
||||
# Run tests.
|
||||
area_light_test()
|
||||
spot_light_test()
|
||||
general.log("Light component tests completed.")
|
||||
|
||||
|
||||
def area_light_test():
|
||||
"""
|
||||
Basic test for the "Light" component attached to an "area_light" entity.
|
||||
|
||||
Test Case - Light Component: Capsule, Spot (disk), and Point (sphere):
|
||||
1. Creates "area_light" entity w/ a Light component that has a Capsule Light type w/ the color set to 255, 0, 0
|
||||
2. Enters game mode to take a screenshot for comparison, then exits game mode.
|
||||
3. Sets the Light component Intensity Mode to Lumens (default).
|
||||
4. Ensures the Light component Mode is Automatic (default).
|
||||
5. Sets the Intensity value of the Light component to 0.0
|
||||
6. Enters game mode again, takes another screenshot for comparison, then exits game mode.
|
||||
7. Updates the Intensity value of the Light component to 1000.0
|
||||
8. Enters game mode again, takes another screenshot for comparison, then exits game mode.
|
||||
9. Swaps the Capsule light type option to Spot (disk) light type on the Light component
|
||||
10. Updates "area_light" entity Transform rotate value to x: 90.0, y:0.0, z:0.0
|
||||
11. Enters game mode again, takes another screenshot for comparison, then exits game mode.
|
||||
12. Swaps the Spot (disk) light type for the Point (sphere) light type in the Light component.
|
||||
13. Enters game mode again, takes another screenshot for comparison, then exits game mode.
|
||||
14. Deletes the Light component from the "area_light" entity and verifies its successful.
|
||||
"""
|
||||
# Create an "area_light" entity with "Light" component using Light type of "Capsule"
|
||||
area_light_entity_name = "area_light"
|
||||
area_light = hydra.Entity(area_light_entity_name)
|
||||
area_light.create_entity(math.Vector3(-1.0, -2.0, 3.0), [LIGHT_COMPONENT])
|
||||
general.log(
|
||||
f"{area_light_entity_name}_test: Component added to the entity: "
|
||||
f"{hydra.has_components(area_light.id, [LIGHT_COMPONENT])}")
|
||||
light_component_id_pair = hydra.attach_component_to_entity(area_light.id, LIGHT_COMPONENT)
|
||||
|
||||
# Select the "Capsule" light type option.
|
||||
azlmbr.editor.EditorComponentAPIBus(
|
||||
azlmbr.bus.Broadcast,
|
||||
'SetComponentProperty',
|
||||
light_component_id_pair,
|
||||
LIGHT_TYPE_PROPERTY,
|
||||
atom_constants.LIGHT_TYPES['capsule']
|
||||
)
|
||||
|
||||
# Update color and take screenshot in game mode
|
||||
color = math.Color(255.0, 0.0, 0.0, 0.0)
|
||||
area_light.get_set_test(0, "Controller|Configuration|Color", color)
|
||||
general.idle_wait(1.0)
|
||||
screenshot_utils.take_screenshot_game_mode("AreaLight_1", area_light_entity_name)
|
||||
|
||||
# Update intensity value to 0.0 and take screenshot in game mode
|
||||
area_light.get_set_test(0, "Controller|Configuration|Attenuation Radius|Mode", 1)
|
||||
area_light.get_set_test(0, "Controller|Configuration|Intensity", 0.0)
|
||||
general.idle_wait(1.0)
|
||||
screenshot_utils.take_screenshot_game_mode("AreaLight_2", area_light_entity_name)
|
||||
|
||||
# Update intensity value to 1000.0 and take screenshot in game mode
|
||||
area_light.get_set_test(0, "Controller|Configuration|Intensity", 1000.0)
|
||||
general.idle_wait(1.0)
|
||||
screenshot_utils.take_screenshot_game_mode("AreaLight_3", area_light_entity_name)
|
||||
|
||||
# Swap the "Capsule" light type option to "Spot (disk)" light type
|
||||
azlmbr.editor.EditorComponentAPIBus(
|
||||
azlmbr.bus.Broadcast,
|
||||
'SetComponentProperty',
|
||||
light_component_id_pair,
|
||||
LIGHT_TYPE_PROPERTY,
|
||||
atom_constants.LIGHT_TYPES['spot_disk']
|
||||
)
|
||||
area_light_rotation = math.Vector3(DEGREE_RADIAN_FACTOR * 90.0, 0.0, 0.0)
|
||||
azlmbr.components.TransformBus(azlmbr.bus.Event, "SetLocalRotation", area_light.id, area_light_rotation)
|
||||
general.idle_wait(1.0)
|
||||
screenshot_utils.take_screenshot_game_mode("AreaLight_4", area_light_entity_name)
|
||||
|
||||
# Swap the "Spot (disk)" light type to the "Point (sphere)" light type and take screenshot.
|
||||
azlmbr.editor.EditorComponentAPIBus(
|
||||
azlmbr.bus.Broadcast,
|
||||
'SetComponentProperty',
|
||||
light_component_id_pair,
|
||||
LIGHT_TYPE_PROPERTY,
|
||||
atom_constants.LIGHT_TYPES['sphere']
|
||||
)
|
||||
general.idle_wait(1.0)
|
||||
screenshot_utils.take_screenshot_game_mode("AreaLight_5", area_light_entity_name)
|
||||
|
||||
editor.ToolsApplicationRequestBus(bus.Broadcast, "DeleteEntityById", area_light.id)
|
||||
|
||||
|
||||
def spot_light_test():
|
||||
"""
|
||||
Basic test for the Light component attached to a "spot_light" entity.
|
||||
|
||||
Test Case - Light Component: Spot (disk) with shadows & colors:
|
||||
1. Creates "spot_light" entity w/ a Light component attached to it.
|
||||
2. Selects the "directional_light" entity already present in the level and disables it.
|
||||
3. Selects the "global_skylight" entity already present in the level and disables the HDRi Skybox component,
|
||||
as well as the Global Skylight (IBL) component.
|
||||
4. Enters game mode to take a screenshot for comparison, then exits game mode.
|
||||
5. Selects the "ground_plane" entity and changes updates the material to a new material.
|
||||
6. Enters game mode to take a screenshot for comparison, then exits game mode.
|
||||
7. Selects the "spot_light" entity and increases the Light component Intensity to 800 lm
|
||||
8. Enters game mode to take a screenshot for comparison, then exits game mode.
|
||||
9. Selects the "spot_light" entity and sets the Light component Color to 47, 75, 37
|
||||
10. Enters game mode to take a screenshot for comparison, then exits game mode.
|
||||
11. Selects the "spot_light" entity and modifies the Shutter controls to the following values:
|
||||
- Enable shutters: True
|
||||
- Inner Angle: 60.0
|
||||
- Outer Angle: 75.0
|
||||
12. Enters game mode to take a screenshot for comparison, then exits game mode.
|
||||
13. Selects the "spot_light" entity and modifies the Shadow controls to the following values:
|
||||
- Enable Shadow: True
|
||||
- ShadowmapSize: 256
|
||||
14. Modifies the world translate position of the "spot_light" entity to 0.7, -2.0, 1.9 (for casting shadows better)
|
||||
15. Enters game mode to take a screenshot for comparison, then exits game mode.
|
||||
"""
|
||||
# Disable "Directional Light" component for the "directional_light" entity
|
||||
# "directional_light" entity is created by the create_basic_atom_level() function by default.
|
||||
directional_light_entity_id = hydra.find_entity_by_name("directional_light")
|
||||
directional_light = hydra.Entity(name='directional_light', id=directional_light_entity_id)
|
||||
directional_light_component_type = azlmbr.editor.EditorComponentAPIBus(
|
||||
azlmbr.bus.Broadcast, 'FindComponentTypeIdsByEntityType', ["Directional Light"], 0)[0]
|
||||
directional_light_component = azlmbr.editor.EditorComponentAPIBus(
|
||||
azlmbr.bus.Broadcast, 'GetComponentOfType', directional_light.id, directional_light_component_type
|
||||
).GetValue()
|
||||
editor.EditorComponentAPIBus(bus.Broadcast, "DisableComponents", [directional_light_component])
|
||||
general.idle_wait(0.5)
|
||||
|
||||
# Disable "Global Skylight (IBL)" and "HDRi Skybox" components for the "global_skylight" entity
|
||||
global_skylight_entity_id = hydra.find_entity_by_name("global_skylight")
|
||||
global_skylight = hydra.Entity(name='global_skylight', id=global_skylight_entity_id)
|
||||
global_skylight_component_type = azlmbr.editor.EditorComponentAPIBus(
|
||||
azlmbr.bus.Broadcast, 'FindComponentTypeIdsByEntityType', ["Global Skylight (IBL)"], 0)[0]
|
||||
global_skylight_component = azlmbr.editor.EditorComponentAPIBus(
|
||||
azlmbr.bus.Broadcast, 'GetComponentOfType', global_skylight.id, global_skylight_component_type
|
||||
).GetValue()
|
||||
editor.EditorComponentAPIBus(bus.Broadcast, "DisableComponents", [global_skylight_component])
|
||||
hdri_skybox_component_type = azlmbr.editor.EditorComponentAPIBus(
|
||||
azlmbr.bus.Broadcast, 'FindComponentTypeIdsByEntityType', ["HDRi Skybox"], 0)[0]
|
||||
hdri_skybox_component = azlmbr.editor.EditorComponentAPIBus(
|
||||
azlmbr.bus.Broadcast, 'GetComponentOfType', global_skylight.id, hdri_skybox_component_type
|
||||
).GetValue()
|
||||
editor.EditorComponentAPIBus(bus.Broadcast, "DisableComponents", [hdri_skybox_component])
|
||||
general.idle_wait(0.5)
|
||||
|
||||
# Create a "spot_light" entity with "Light" component using Light Type of "Spot (disk)"
|
||||
spot_light_entity_name = "spot_light"
|
||||
spot_light = hydra.Entity(spot_light_entity_name)
|
||||
spot_light.create_entity(math.Vector3(0.7, -2.0, 1.0), [LIGHT_COMPONENT])
|
||||
general.log(
|
||||
f"{spot_light_entity_name}_test: Component added to the entity: "
|
||||
f"{hydra.has_components(spot_light.id, [LIGHT_COMPONENT])}")
|
||||
rotation = math.Vector3(DEGREE_RADIAN_FACTOR * 300.0, 0.0, 0.0)
|
||||
azlmbr.components.TransformBus(azlmbr.bus.Event, "SetLocalRotation", spot_light.id, rotation)
|
||||
light_component_type = hydra.attach_component_to_entity(spot_light.id, LIGHT_COMPONENT)
|
||||
editor.EditorComponentAPIBus(
|
||||
azlmbr.bus.Broadcast,
|
||||
'SetComponentProperty',
|
||||
light_component_type,
|
||||
LIGHT_TYPE_PROPERTY,
|
||||
atom_constants.LIGHT_TYPES['spot_disk']
|
||||
)
|
||||
|
||||
general.idle_wait(1.0)
|
||||
screenshot_utils.take_screenshot_game_mode("SpotLight_1", spot_light_entity_name)
|
||||
|
||||
# Change default material of ground plane entity and take screenshot
|
||||
ground_plane_entity_id = hydra.find_entity_by_name("ground_plane")
|
||||
ground_plane = hydra.Entity(name='ground_plane', id=ground_plane_entity_id)
|
||||
ground_plane_asset_path = os.path.join("Materials", "Presets", "MacBeth", "22_neutral_5-0_0-70d.azmaterial")
|
||||
ground_plane_asset_value = asset.AssetCatalogRequestBus(
|
||||
bus.Broadcast, "GetAssetIdByPath", ground_plane_asset_path, math.Uuid(), False)
|
||||
material_property_path = "Default Material|Material Asset"
|
||||
material_component_type = azlmbr.editor.EditorComponentAPIBus(
|
||||
azlmbr.bus.Broadcast, 'FindComponentTypeIdsByEntityType', ["Material"], 0)[0]
|
||||
material_component = azlmbr.editor.EditorComponentAPIBus(
|
||||
azlmbr.bus.Broadcast, 'GetComponentOfType', ground_plane.id, material_component_type).GetValue()
|
||||
editor.EditorComponentAPIBus(
|
||||
azlmbr.bus.Broadcast,
|
||||
'SetComponentProperty',
|
||||
material_component,
|
||||
material_property_path,
|
||||
ground_plane_asset_value
|
||||
)
|
||||
general.idle_wait(1.0)
|
||||
screenshot_utils.take_screenshot_game_mode("SpotLight_2", spot_light_entity_name)
|
||||
|
||||
# Increase intensity value of the Spot light and take screenshot in game mode
|
||||
spot_light.get_set_test(0, "Controller|Configuration|Intensity", 800.0)
|
||||
general.idle_wait(1.0)
|
||||
screenshot_utils.take_screenshot_game_mode("SpotLight_3", spot_light_entity_name)
|
||||
|
||||
# Update the Spot light color and take screenshot in game mode
|
||||
color_value = math.Color(47.0 / 255.0, 75.0 / 255.0, 37.0 / 255.0, 255.0 / 255.0)
|
||||
spot_light.get_set_test(0, "Controller|Configuration|Color", color_value)
|
||||
general.idle_wait(1.0)
|
||||
screenshot_utils.take_screenshot_game_mode("SpotLight_4", spot_light_entity_name)
|
||||
|
||||
# Update the Shutter controls of the Light component and take screenshot
|
||||
spot_light.get_set_test(0, "Controller|Configuration|Shutters|Enable shutters", True)
|
||||
spot_light.get_set_test(0, "Controller|Configuration|Shutters|Inner angle", 60.0)
|
||||
spot_light.get_set_test(0, "Controller|Configuration|Shutters|Outer angle", 75.0)
|
||||
general.idle_wait(1.0)
|
||||
screenshot_utils.take_screenshot_game_mode("SpotLight_5", spot_light_entity_name)
|
||||
|
||||
# Update the Shadow controls, move the spot_light entity world translate position and take screenshot
|
||||
spot_light.get_set_test(0, "Controller|Configuration|Shadows|Enable shadow", True)
|
||||
spot_light.get_set_test(0, "Controller|Configuration|Shadows|Shadowmap size", 256.0)
|
||||
azlmbr.components.TransformBus(
|
||||
azlmbr.bus.Event, "SetWorldTranslation", spot_light.id, math.Vector3(0.7, -2.0, 1.9))
|
||||
general.idle_wait(1.0)
|
||||
screenshot_utils.take_screenshot_game_mode("SpotLight_6", spot_light_entity_name)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
run()
|
||||
+179
-12
@@ -3,17 +3,184 @@ Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright
|
||||
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
|
||||
File to assist with common hydra component functions or constants used across various Atom tests.
|
||||
File to assist with common hydra component functions used across various Atom tests.
|
||||
"""
|
||||
import os
|
||||
|
||||
# Light type options for the Light component.
|
||||
LIGHT_TYPES = {
|
||||
'unknown': 0,
|
||||
'sphere': 1,
|
||||
'spot_disk': 2,
|
||||
'capsule': 3,
|
||||
'quad': 4,
|
||||
'polygon': 5,
|
||||
'simple_point': 6,
|
||||
'simple_spot': 7,
|
||||
}
|
||||
from editor_python_test_tools.editor_test_helper import EditorTestHelper
|
||||
|
||||
helper = EditorTestHelper(log_prefix="Atom_EditorTestHelper")
|
||||
|
||||
|
||||
def create_basic_atom_level(level_name):
|
||||
"""
|
||||
Creates a new level inside the Editor matching level_name & adds the following:
|
||||
1. "default_level" entity to hold all other entities.
|
||||
2. Adds Grid, Global Skylight (IBL), ground Mesh, Directional Light, Sphere w/ material+mesh, & Camera components.
|
||||
3. Each of these components has its settings tweaked slightly to match the ideal scene to test Atom rendering.
|
||||
:param level_name: name of the level to create and apply this basic setup to.
|
||||
:return: None
|
||||
"""
|
||||
import azlmbr.asset as asset
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.camera as camera
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.entity as entity
|
||||
import azlmbr.legacy.general as general
|
||||
import azlmbr.math as math
|
||||
import azlmbr.object
|
||||
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
|
||||
# Create a new level.
|
||||
new_level_name = level_name
|
||||
heightmap_resolution = 512
|
||||
heightmap_meters_per_pixel = 1
|
||||
terrain_texture_resolution = 412
|
||||
use_terrain = False
|
||||
|
||||
# Return codes are ECreateLevelResult defined in CryEdit.h
|
||||
return_code = general.create_level_no_prompt(
|
||||
new_level_name, heightmap_resolution, heightmap_meters_per_pixel, terrain_texture_resolution, use_terrain)
|
||||
if return_code == 1:
|
||||
general.log(f"{new_level_name} level already exists")
|
||||
elif return_code == 2:
|
||||
general.log("Failed to create directory")
|
||||
elif return_code == 3:
|
||||
general.log("Directory length is too long")
|
||||
elif return_code != 0:
|
||||
general.log("Unknown error, failed to create level")
|
||||
else:
|
||||
general.log(f"{new_level_name} level created successfully")
|
||||
|
||||
# Enable idle and update viewport.
|
||||
general.idle_enable(True)
|
||||
general.idle_wait(1.0)
|
||||
general.update_viewport()
|
||||
general.idle_wait(0.5) # half a second is more than enough for updating the viewport.
|
||||
|
||||
# Close out problematic windows, FPS meters, and anti-aliasing.
|
||||
if general.is_helpers_shown(): # Turn off the helper gizmos if visible
|
||||
general.toggle_helpers()
|
||||
general.idle_wait(1.0)
|
||||
if general.is_pane_visible("Error Report"): # Close Error Report windows that block focus.
|
||||
general.close_pane("Error Report")
|
||||
if general.is_pane_visible("Error Log"): # Close Error Log windows that block focus.
|
||||
general.close_pane("Error Log")
|
||||
general.idle_wait(1.0)
|
||||
general.run_console("r_displayInfo=0")
|
||||
general.run_console("r_antialiasingmode=0")
|
||||
general.idle_wait(1.0)
|
||||
|
||||
# Delete all existing entities & create default_level entity
|
||||
search_filter = azlmbr.entity.SearchFilter()
|
||||
all_entities = entity.SearchBus(azlmbr.bus.Broadcast, "SearchEntities", search_filter)
|
||||
editor.ToolsApplicationRequestBus(bus.Broadcast, "DeleteEntities", all_entities)
|
||||
default_level = hydra.Entity("default_level")
|
||||
default_position = math.Vector3(0.0, 0.0, 0.0)
|
||||
default_level.create_entity(default_position, ["Grid"])
|
||||
default_level.get_set_test(0, "Controller|Configuration|Secondary Grid Spacing", 1.0)
|
||||
|
||||
# Set the viewport up correctly after adding the parent default_level entity.
|
||||
screen_width = 1280
|
||||
screen_height = 720
|
||||
degree_radian_factor = 0.0174533 # Used by "Rotation" property for the Transform component.
|
||||
general.set_viewport_size(screen_width, screen_height)
|
||||
general.update_viewport()
|
||||
helper.wait_for_condition(
|
||||
function=lambda: helper.isclose(a=general.get_viewport_size().x, b=screen_width, rel_tol=0.1)
|
||||
and helper.isclose(a=general.get_viewport_size().y, b=screen_height, rel_tol=0.1),
|
||||
timeout_in_seconds=4.0
|
||||
)
|
||||
result = helper.isclose(a=general.get_viewport_size().x, b=screen_width, rel_tol=0.1) and helper.isclose(
|
||||
a=general.get_viewport_size().y, b=screen_height, rel_tol=0.1)
|
||||
general.log(general.get_viewport_size().x)
|
||||
general.log(general.get_viewport_size().y)
|
||||
general.log(general.get_viewport_size().z)
|
||||
general.log(f"Viewport is set to the expected size: {result}")
|
||||
general.log("Basic level created")
|
||||
general.run_console("r_DisplayInfo = 0")
|
||||
|
||||
# Create global_skylight entity and set the properties
|
||||
global_skylight = hydra.Entity("global_skylight")
|
||||
global_skylight.create_entity(
|
||||
entity_position=default_position,
|
||||
components=["HDRi Skybox", "Global Skylight (IBL)"],
|
||||
parent_id=default_level.id)
|
||||
global_skylight_asset_path = os.path.join(
|
||||
"LightingPresets", "greenwich_park_02_4k_iblskyboxcm_iblspecular.exr.streamingimage")
|
||||
global_skylight_asset_value = asset.AssetCatalogRequestBus(
|
||||
bus.Broadcast, "GetAssetIdByPath", global_skylight_asset_path, math.Uuid(), False)
|
||||
global_skylight.get_set_test(0, "Controller|Configuration|Cubemap Texture", global_skylight_asset_value)
|
||||
global_skylight.get_set_test(1, "Controller|Configuration|Diffuse Image", global_skylight_asset_value)
|
||||
global_skylight.get_set_test(1, "Controller|Configuration|Specular Image", global_skylight_asset_value)
|
||||
|
||||
# Create ground_plane entity and set the properties
|
||||
ground_plane = hydra.Entity("ground_plane")
|
||||
ground_plane.create_entity(
|
||||
entity_position=default_position,
|
||||
components=["Material"],
|
||||
parent_id=default_level.id)
|
||||
azlmbr.components.TransformBus(azlmbr.bus.Event, "SetLocalUniformScale", ground_plane.id, 32.0)
|
||||
ground_plane_material_asset_path = os.path.join(
|
||||
"Materials", "Presets", "PBR", "metal_chrome.azmaterial")
|
||||
ground_plane_material_asset_value = asset.AssetCatalogRequestBus(
|
||||
bus.Broadcast, "GetAssetIdByPath", ground_plane_material_asset_path, math.Uuid(), False)
|
||||
ground_plane.get_set_test(0, "Default Material|Material Asset", ground_plane_material_asset_value)
|
||||
|
||||
# Work around to add the correct Atom Mesh component
|
||||
mesh_type_id = azlmbr.globals.property.EditorMeshComponentTypeId
|
||||
ground_plane.components.append(
|
||||
editor.EditorComponentAPIBus(
|
||||
bus.Broadcast, "AddComponentsOfType", ground_plane.id, [mesh_type_id]
|
||||
).GetValue()[0]
|
||||
)
|
||||
ground_plane_mesh_asset_path = os.path.join("Models", "plane.azmodel")
|
||||
ground_plane_mesh_asset_value = asset.AssetCatalogRequestBus(
|
||||
bus.Broadcast, "GetAssetIdByPath", ground_plane_mesh_asset_path, math.Uuid(), False)
|
||||
ground_plane.get_set_test(1, "Controller|Configuration|Mesh Asset", ground_plane_mesh_asset_value)
|
||||
|
||||
# Create directional_light entity and set the properties
|
||||
directional_light = hydra.Entity("directional_light")
|
||||
directional_light.create_entity(
|
||||
entity_position=math.Vector3(0.0, 0.0, 10.0),
|
||||
components=["Directional Light"],
|
||||
parent_id=default_level.id)
|
||||
directional_light_rotation = math.Vector3(degree_radian_factor * -90.0, 0.0, 0.0)
|
||||
azlmbr.components.TransformBus(
|
||||
azlmbr.bus.Event, "SetLocalRotation", directional_light.id, directional_light_rotation)
|
||||
|
||||
# Create sphere entity and set the properties
|
||||
sphere_entity = hydra.Entity("sphere")
|
||||
sphere_entity.create_entity(
|
||||
entity_position=math.Vector3(0.0, 0.0, 1.0),
|
||||
components=["Material"],
|
||||
parent_id=default_level.id)
|
||||
sphere_material_asset_path = os.path.join("Materials", "Presets", "PBR", "metal_brass_polished.azmaterial")
|
||||
sphere_material_asset_value = asset.AssetCatalogRequestBus(
|
||||
bus.Broadcast, "GetAssetIdByPath", sphere_material_asset_path, math.Uuid(), False)
|
||||
sphere_entity.get_set_test(0, "Default Material|Material Asset", sphere_material_asset_value)
|
||||
|
||||
# Work around to add the correct Atom Mesh component
|
||||
sphere_entity.components.append(
|
||||
editor.EditorComponentAPIBus(
|
||||
bus.Broadcast, "AddComponentsOfType", sphere_entity.id, [mesh_type_id]
|
||||
).GetValue()[0]
|
||||
)
|
||||
sphere_mesh_asset_path = os.path.join("Models", "sphere.azmodel")
|
||||
sphere_mesh_asset_value = asset.AssetCatalogRequestBus(
|
||||
bus.Broadcast, "GetAssetIdByPath", sphere_mesh_asset_path, math.Uuid(), False)
|
||||
sphere_entity.get_set_test(1, "Controller|Configuration|Mesh Asset", sphere_mesh_asset_value)
|
||||
|
||||
# Create camera component and set the properties
|
||||
camera_entity = hydra.Entity("camera")
|
||||
camera_entity.create_entity(
|
||||
entity_position=math.Vector3(5.5, -12.0, 9.0),
|
||||
components=["Camera"],
|
||||
parent_id=default_level.id)
|
||||
rotation = math.Vector3(
|
||||
degree_radian_factor * -27.0, degree_radian_factor * -12.0, degree_radian_factor * 25.0
|
||||
)
|
||||
azlmbr.components.TransformBus(azlmbr.bus.Event, "SetLocalRotation", camera_entity.id, rotation)
|
||||
camera_entity.get_set_test(0, "Controller|Configuration|Field of view", 60.0)
|
||||
camera.EditorCameraViewRequestBus(azlmbr.bus.Event, "ToggleCameraAsActiveView", camera_entity.id)
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
"""
|
||||
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
|
||||
|
||||
Hold constants used across both hydra and non-hydra scripts.
|
||||
"""
|
||||
|
||||
# Light type options for the Light component.
|
||||
LIGHT_TYPES = {
|
||||
'unknown': 0,
|
||||
'sphere': 1,
|
||||
'spot_disk': 2,
|
||||
'capsule': 3,
|
||||
'quad': 4,
|
||||
'polygon': 5,
|
||||
'simple_point': 6,
|
||||
'simple_spot': 7,
|
||||
}
|
||||
@@ -0,0 +1,274 @@
|
||||
"""
|
||||
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
|
||||
|
||||
import azlmbr.materialeditor will fail with a ModuleNotFound error when using this script with Editor.exe
|
||||
This is because azlmbr.materialeditor only binds to MaterialEditor.exe and not Editor.exe
|
||||
You need to launch this script with MaterialEditor.exe in order for azlmbr.materialeditor to appear.
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import azlmbr.atom
|
||||
import azlmbr.atomtools as atomtools
|
||||
import azlmbr.materialeditor as materialeditor
|
||||
import azlmbr.bus as bus
|
||||
|
||||
|
||||
def is_close(actual, expected, buffer=sys.float_info.min):
|
||||
"""
|
||||
:param actual: actual value
|
||||
:param expected: expected value
|
||||
:param buffer: acceptable variation from expected
|
||||
:return: bool
|
||||
"""
|
||||
return abs(actual - expected) < buffer
|
||||
|
||||
|
||||
def compare_colors(color1, color2, buffer=0.00001):
|
||||
"""
|
||||
Compares the red, green and blue properties of a color allowing a slight variance of buffer
|
||||
:param color1: first color to compare
|
||||
:param color2: second color
|
||||
:param buffer: allowed variance in individual color value
|
||||
:return: bool
|
||||
"""
|
||||
return (
|
||||
is_close(color1.r, color2.r, buffer)
|
||||
and is_close(color1.g, color2.g, buffer)
|
||||
and is_close(color1.b, color2.b, buffer)
|
||||
)
|
||||
|
||||
|
||||
def open_material(file_path):
|
||||
"""
|
||||
:return: uuid of material document opened
|
||||
"""
|
||||
return materialeditor.MaterialDocumentSystemRequestBus(bus.Broadcast, "OpenDocument", file_path)
|
||||
|
||||
|
||||
def is_open(document_id):
|
||||
"""
|
||||
:return: bool
|
||||
"""
|
||||
return materialeditor.MaterialDocumentRequestBus(bus.Event, "IsOpen", document_id)
|
||||
|
||||
|
||||
def save_document(document_id):
|
||||
"""
|
||||
:return: bool success
|
||||
"""
|
||||
return materialeditor.MaterialDocumentSystemRequestBus(bus.Broadcast, "SaveDocument", document_id)
|
||||
|
||||
|
||||
def save_document_as_copy(document_id, target_path):
|
||||
"""
|
||||
:return: bool success
|
||||
"""
|
||||
return materialeditor.MaterialDocumentSystemRequestBus(
|
||||
bus.Broadcast, "SaveDocumentAsCopy", document_id, target_path
|
||||
)
|
||||
|
||||
|
||||
def save_document_as_child(document_id, target_path):
|
||||
"""
|
||||
:return: bool success
|
||||
"""
|
||||
return materialeditor.MaterialDocumentSystemRequestBus(
|
||||
bus.Broadcast, "SaveDocumentAsChild", document_id, target_path
|
||||
)
|
||||
|
||||
|
||||
def save_all():
|
||||
"""
|
||||
:return: bool success
|
||||
"""
|
||||
return materialeditor.MaterialDocumentSystemRequestBus(bus.Broadcast, "SaveAllDocuments")
|
||||
|
||||
|
||||
def close_document(document_id):
|
||||
"""
|
||||
:return: bool success
|
||||
"""
|
||||
return materialeditor.MaterialDocumentSystemRequestBus(bus.Broadcast, "CloseDocument", document_id)
|
||||
|
||||
|
||||
def close_all_documents():
|
||||
"""
|
||||
:return: bool success
|
||||
"""
|
||||
return materialeditor.MaterialDocumentSystemRequestBus(bus.Broadcast, "CloseAllDocuments")
|
||||
|
||||
|
||||
def close_all_except_selected(document_id):
|
||||
"""
|
||||
:return: bool success
|
||||
"""
|
||||
return materialeditor.MaterialDocumentSystemRequestBus(bus.Broadcast, "CloseAllDocumentsExcept", document_id)
|
||||
|
||||
|
||||
def get_property(document_id, property_name):
|
||||
"""
|
||||
:return: property value or invalid value if the document is not open or the property_name can't be found
|
||||
"""
|
||||
return materialeditor.MaterialDocumentRequestBus(bus.Event, "GetPropertyValue", document_id, property_name)
|
||||
|
||||
|
||||
def set_property(document_id, property_name, value):
|
||||
materialeditor.MaterialDocumentRequestBus(bus.Event, "SetPropertyValue", document_id, property_name, value)
|
||||
|
||||
|
||||
def is_pane_visible(pane_name):
|
||||
"""
|
||||
:return: bool
|
||||
"""
|
||||
return atomtools.AtomToolsWindowRequestBus(bus.Broadcast, "IsDockWidgetVisible", pane_name)
|
||||
|
||||
|
||||
def set_pane_visibility(pane_name, value):
|
||||
atomtools.AtomToolsWindowRequestBus(bus.Broadcast, "SetDockWidgetVisible", pane_name, value)
|
||||
|
||||
|
||||
def select_lighting_config(config_name):
|
||||
azlmbr.materialeditor.MaterialViewportRequestBus(azlmbr.bus.Broadcast, "SelectLightingPresetByName", config_name)
|
||||
|
||||
|
||||
def set_grid_enable_disable(value):
|
||||
azlmbr.materialeditor.MaterialViewportRequestBus(azlmbr.bus.Broadcast, "SetGridEnabled", value)
|
||||
|
||||
|
||||
def get_grid_enable_disable():
|
||||
"""
|
||||
:return: bool
|
||||
"""
|
||||
return azlmbr.materialeditor.MaterialViewportRequestBus(azlmbr.bus.Broadcast, "GetGridEnabled")
|
||||
|
||||
|
||||
def set_shadowcatcher_enable_disable(value):
|
||||
azlmbr.materialeditor.MaterialViewportRequestBus(azlmbr.bus.Broadcast, "SetShadowCatcherEnabled", value)
|
||||
|
||||
|
||||
def get_shadowcatcher_enable_disable():
|
||||
"""
|
||||
:return: bool
|
||||
"""
|
||||
return azlmbr.materialeditor.MaterialViewportRequestBus(azlmbr.bus.Broadcast, "GetShadowCatcherEnabled")
|
||||
|
||||
|
||||
def select_model_config(configname):
|
||||
azlmbr.materialeditor.MaterialViewportRequestBus(azlmbr.bus.Broadcast, "SelectModelPresetByName", configname)
|
||||
|
||||
|
||||
def wait_for_condition(function, timeout_in_seconds=1.0):
|
||||
# type: (function, float) -> bool
|
||||
"""
|
||||
Function to run until it returns True or timeout is reached
|
||||
the function can have no parameters and
|
||||
waiting idle__wait_* is handled here not in the function
|
||||
|
||||
:param function: a function that returns a boolean indicating a desired condition is achieved
|
||||
:param timeout_in_seconds: when reached, function execution is abandoned and False is returned
|
||||
"""
|
||||
with Timeout(timeout_in_seconds) as t:
|
||||
while True:
|
||||
try:
|
||||
atomtools.general.idle_wait_frames(1)
|
||||
except Exception:
|
||||
print("WARNING: Couldn't wait for frame")
|
||||
|
||||
if t.timed_out:
|
||||
return False
|
||||
|
||||
ret = function()
|
||||
if not isinstance(ret, bool):
|
||||
raise TypeError("return value for wait_for_condition function must be a bool")
|
||||
if ret:
|
||||
return True
|
||||
|
||||
|
||||
class Timeout:
|
||||
# type: (float) -> None
|
||||
"""
|
||||
contextual timeout
|
||||
:param seconds: float seconds to allow before timed_out is True
|
||||
"""
|
||||
|
||||
def __init__(self, seconds):
|
||||
self.seconds = seconds
|
||||
|
||||
def __enter__(self):
|
||||
self.die_after = time.time() + self.seconds
|
||||
return self
|
||||
|
||||
def __exit__(self, type, value, traceback):
|
||||
pass
|
||||
|
||||
@property
|
||||
def timed_out(self):
|
||||
return time.time() > self.die_after
|
||||
|
||||
|
||||
screenshotsFolder = os.path.join(azlmbr.paths.devroot, "AtomTest", "Cache" "pc", "Screenshots")
|
||||
|
||||
|
||||
class ScreenshotHelper:
|
||||
"""
|
||||
A helper to capture screenshots and wait for them.
|
||||
"""
|
||||
|
||||
def __init__(self, idle_wait_frames_callback):
|
||||
super().__init__()
|
||||
self.done = False
|
||||
self.capturedScreenshot = False
|
||||
self.max_frames_to_wait = 60
|
||||
|
||||
self.idle_wait_frames_callback = idle_wait_frames_callback
|
||||
|
||||
def capture_screenshot_blocking(self, filename):
|
||||
"""
|
||||
Capture a screenshot and block the execution until the screenshot has been written to the disk.
|
||||
"""
|
||||
self.handler = azlmbr.atom.FrameCaptureNotificationBusHandler()
|
||||
self.handler.connect()
|
||||
self.handler.add_callback("OnCaptureFinished", self.on_screenshot_captured)
|
||||
|
||||
self.done = False
|
||||
self.capturedScreenshot = False
|
||||
success = azlmbr.atom.FrameCaptureRequestBus(azlmbr.bus.Broadcast, "CaptureScreenshot", filename)
|
||||
if success:
|
||||
self.wait_until_screenshot()
|
||||
print("Screenshot taken.")
|
||||
else:
|
||||
print("screenshot failed")
|
||||
return self.capturedScreenshot
|
||||
|
||||
def on_screenshot_captured(self, parameters):
|
||||
# the parameters come in as a tuple
|
||||
if parameters[0]:
|
||||
print("screenshot saved: {}".format(parameters[1]))
|
||||
self.capturedScreenshot = True
|
||||
else:
|
||||
print("screenshot failed: {}".format(parameters[1]))
|
||||
self.done = True
|
||||
self.handler.disconnect()
|
||||
|
||||
def wait_until_screenshot(self):
|
||||
frames_waited = 0
|
||||
while self.done == False:
|
||||
self.idle_wait_frames_callback(1)
|
||||
if frames_waited > self.max_frames_to_wait:
|
||||
print("timeout while waiting for the screenshot to be written")
|
||||
self.handler.disconnect()
|
||||
break
|
||||
else:
|
||||
frames_waited = frames_waited + 1
|
||||
print("(waited {} frames)".format(frames_waited))
|
||||
|
||||
|
||||
def capture_screenshot(file_path):
|
||||
return ScreenshotHelper(atomtools.general.idle_wait_frames).capture_screenshot_blocking(
|
||||
os.path.join(file_path)
|
||||
)
|
||||
@@ -91,3 +91,20 @@ class ScreenshotHelper(object):
|
||||
else:
|
||||
frames_waited = frames_waited + 1
|
||||
general.log(f"(waited {frames_waited} frames)")
|
||||
|
||||
|
||||
def take_screenshot_game_mode(screenshot_name, entity_name=None):
|
||||
"""
|
||||
Enters game mode & takes a screenshot, then exits game mode after.
|
||||
:param screenshot_name: name to give the captured screenshot .ppm file.
|
||||
:param entity_name: name of the entity being tested (for generating unique log lines).
|
||||
:return: None
|
||||
"""
|
||||
general.enter_game_mode()
|
||||
helper.wait_for_condition(lambda: general.is_in_game_mode(), 2.0)
|
||||
general.log(f"{entity_name}_test: Entered game mode: {general.is_in_game_mode()}")
|
||||
ScreenshotHelper(general.idle_wait_frames).capture_screenshot_blocking(f"{screenshot_name}.ppm")
|
||||
general.idle_wait(1.0)
|
||||
general.exit_game_mode()
|
||||
helper.wait_for_condition(lambda: not general.is_in_game_mode(), 2.0)
|
||||
general.log(f"{entity_name}_test: Exit game mode: {not general.is_in_game_mode()}")
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:954d7d0df47c840a24e313893800eb3126d0c0d47c3380926776b51833778db7
|
||||
size 6220817
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:e81c19128f42ba362a2d5f3ccf159dfbc942d67ceeb1ac8c21f295a6fd9d2ce5
|
||||
size 6220817
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:5e20801213e065b6ea8c95ede81c23faa9b6dc70a2002dc5bced293e1bed989f
|
||||
size 6220817
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:e250f812e594e5152bf2d6f23caa8b53b78276bfdf344d7a8d355dd96cb995c0
|
||||
size 6220817
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:95be359041f8291c74b335297a4dfe9902a180510f24a181b15e1a5ba4d3b024
|
||||
size 6220817
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:118e43e4b915e262726183467cc4b82f244565213fea5b6bfe02be07f0851ab1
|
||||
size 6220817
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:dc2ce3256a6552975962c9e113c52c1a22bf3817d417151f6f60640dd568e0fa
|
||||
size 6220817
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:287d98890b35427688999760f9d066bcbff1a3bc9001534241dc212b32edabd8
|
||||
size 6220817
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:66e91c92c868167c850078cd91714db47e10a96e23cc30191994486bd79c353f
|
||||
size 6220817
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:d950d173f5101820c5e18205401ca08ce5feeff2302ac2920b292750d86a8fa4
|
||||
size 6220817
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:72eddb7126eae0c839b933886e0fb69d78229f72d49ef13199de28df2b7879db
|
||||
size 6220817
|
||||
@@ -15,11 +15,11 @@ import pytest
|
||||
import ly_test_tools.environment.file_system as file_system
|
||||
from ly_test_tools.image.screenshot_compare_qssim import qssim as compare_screenshots
|
||||
from ly_test_tools.benchmark.data_aggregator import BenchmarkDataAggregator
|
||||
|
||||
import editor_python_test_tools.hydra_test_utils as hydra
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
DEFAULT_SUBFOLDER_PATH = 'user/PythonTests/Automated/Screenshots'
|
||||
EDITOR_TIMEOUT = 600
|
||||
TEST_DIRECTORY = os.path.join(os.path.dirname(__file__), "atom_hydra_scripts")
|
||||
|
||||
|
||||
@@ -67,6 +67,7 @@ class TestAllComponentsIndepthTests(object):
|
||||
"Trace::Assert",
|
||||
"Trace::Error",
|
||||
"Traceback (most recent call last):",
|
||||
"Screenshot failed"
|
||||
]
|
||||
|
||||
hydra.launch_and_validate_results(
|
||||
@@ -74,7 +75,7 @@ class TestAllComponentsIndepthTests(object):
|
||||
TEST_DIRECTORY,
|
||||
editor,
|
||||
"hydra_GPUTest_BasicLevelSetup.py",
|
||||
timeout=EDITOR_TIMEOUT,
|
||||
timeout=180,
|
||||
expected_lines=level_creation_expected_lines,
|
||||
unexpected_lines=unexpected_lines,
|
||||
halt_on_unexpected=True,
|
||||
@@ -85,6 +86,60 @@ class TestAllComponentsIndepthTests(object):
|
||||
for test_screenshot, golden_screenshot in zip(test_screenshots, golden_images):
|
||||
compare_screenshots(test_screenshot, golden_screenshot)
|
||||
|
||||
def test_LightComponent_ScreenshotMatchesGoldenImage(
|
||||
self, request, editor, workspace, project, launcher_platform, level):
|
||||
"""
|
||||
Please review the hydra script run by this test for more specific test info.
|
||||
Tests that the Light component screenshots in a rendered level appear the same as the golden images.
|
||||
"""
|
||||
screenshot_names = [
|
||||
"AreaLight_1.ppm",
|
||||
"AreaLight_2.ppm",
|
||||
"AreaLight_3.ppm",
|
||||
"AreaLight_4.ppm",
|
||||
"AreaLight_5.ppm",
|
||||
"SpotLight_1.ppm",
|
||||
"SpotLight_2.ppm",
|
||||
"SpotLight_3.ppm",
|
||||
"SpotLight_4.ppm",
|
||||
"SpotLight_5.ppm",
|
||||
"SpotLight_6.ppm",
|
||||
]
|
||||
test_screenshots = []
|
||||
for screenshot in screenshot_names:
|
||||
screenshot_path = os.path.join(workspace.paths.project(), DEFAULT_SUBFOLDER_PATH, screenshot)
|
||||
test_screenshots.append(screenshot_path)
|
||||
file_system.delete(test_screenshots, True, True)
|
||||
|
||||
golden_images = []
|
||||
for golden_image in screenshot_names:
|
||||
golden_image_path = os.path.join(golden_images_directory(), golden_image)
|
||||
golden_images.append(golden_image_path)
|
||||
|
||||
expected_lines = ["Light component tests completed."]
|
||||
unexpected_lines = [
|
||||
"Trace::Assert",
|
||||
"Trace::Error",
|
||||
"Traceback (most recent call last):",
|
||||
"Screenshot failed",
|
||||
]
|
||||
hydra.launch_and_validate_results(
|
||||
request,
|
||||
TEST_DIRECTORY,
|
||||
editor,
|
||||
"hydra_GPUTest_LightComponent.py",
|
||||
timeout=180,
|
||||
expected_lines=expected_lines,
|
||||
unexpected_lines=unexpected_lines,
|
||||
halt_on_unexpected=True,
|
||||
cfg_args=[level],
|
||||
null_renderer=False,
|
||||
)
|
||||
|
||||
for test_screenshot, golden_screenshot in zip(test_screenshots, golden_images):
|
||||
compare_screenshots(test_screenshot, golden_screenshot)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('rhi', ['dx12', 'vulkan'])
|
||||
@pytest.mark.parametrize("project", ["AutomatedTesting"])
|
||||
@pytest.mark.parametrize("launcher_platform", ["windows_editor"])
|
||||
@@ -116,7 +171,7 @@ class TestPerformanceBenchmarkSuite(object):
|
||||
TEST_DIRECTORY,
|
||||
editor,
|
||||
"hydra_GPUTest_AtomFeatureIntegrationBenchmark.py",
|
||||
timeout=EDITOR_TIMEOUT,
|
||||
timeout=600,
|
||||
expected_lines=expected_lines,
|
||||
unexpected_lines=unexpected_lines,
|
||||
halt_on_unexpected=True,
|
||||
|
||||
@@ -11,8 +11,9 @@ import os
|
||||
|
||||
import pytest
|
||||
|
||||
import ly_test_tools.environment.file_system as file_system
|
||||
import editor_python_test_tools.hydra_test_utils as hydra
|
||||
from atom_renderer.atom_utils.atom_component_helper import LIGHT_TYPES
|
||||
from atom_renderer.atom_utils.atom_constants import LIGHT_TYPES
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
EDITOR_TIMEOUT = 120
|
||||
@@ -31,7 +32,7 @@ class TestAtomEditorComponentsMain(object):
|
||||
Tests the following Atom components and verifies all "expected_lines" appear in Editor.log:
|
||||
1. Display Mapper
|
||||
2. Light
|
||||
3. Radius Weight Modifier
|
||||
3. PostFX Radius Weight Modifier
|
||||
4. PostFX Layer
|
||||
5. Physical Sky
|
||||
6. Global Skylight (IBL)
|
||||
@@ -125,18 +126,18 @@ class TestAtomEditorComponentsMain(object):
|
||||
"PostFX Layer_test: Entity deleted: True",
|
||||
"PostFX Layer_test: UNDO entity deletion works: True",
|
||||
"PostFX Layer_test: REDO entity deletion works: True",
|
||||
# Radius Weight Modifier Component
|
||||
"Radius Weight Modifier Entity successfully created",
|
||||
"Radius Weight Modifier_test: Component added to the entity: True",
|
||||
"Radius Weight Modifier_test: Component removed after UNDO: True",
|
||||
"Radius Weight Modifier_test: Component added after REDO: True",
|
||||
"Radius Weight Modifier_test: Entered game mode: True",
|
||||
"Radius Weight Modifier_test: Exit game mode: True",
|
||||
"Radius Weight Modifier_test: Entity is hidden: True",
|
||||
"Radius Weight Modifier_test: Entity is shown: True",
|
||||
"Radius Weight Modifier_test: Entity deleted: True",
|
||||
"Radius Weight Modifier_test: UNDO entity deletion works: True",
|
||||
"Radius Weight Modifier_test: REDO entity deletion works: True",
|
||||
# PostFX Radius Weight Modifier Component
|
||||
"PostFX Radius Weight Modifier Entity successfully created",
|
||||
"PostFX Radius Weight Modifier_test: Component added to the entity: True",
|
||||
"PostFX Radius Weight Modifier_test: Component removed after UNDO: True",
|
||||
"PostFX Radius Weight Modifier_test: Component added after REDO: True",
|
||||
"PostFX Radius Weight Modifier_test: Entered game mode: True",
|
||||
"PostFX Radius Weight Modifier_test: Exit game mode: True",
|
||||
"PostFX Radius Weight Modifier_test: Entity is hidden: True",
|
||||
"PostFX Radius Weight Modifier_test: Entity is shown: True",
|
||||
"PostFX Radius Weight Modifier_test: Entity deleted: True",
|
||||
"PostFX Radius Weight Modifier_test: UNDO entity deletion works: True",
|
||||
"PostFX Radius Weight Modifier_test: REDO entity deletion works: True",
|
||||
# Light Component
|
||||
"Light Entity successfully created",
|
||||
"Light_test: Component added to the entity: True",
|
||||
@@ -242,3 +243,65 @@ class TestAtomEditorComponentsMain(object):
|
||||
null_renderer=True,
|
||||
cfg_args=cfg_args,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("project", ["AutomatedTesting"])
|
||||
@pytest.mark.parametrize("launcher_platform", ['windows_generic'])
|
||||
@pytest.mark.system
|
||||
class TestMaterialEditorBasicTests(object):
|
||||
@pytest.fixture(autouse=True)
|
||||
def setup_teardown(self, request, workspace, project):
|
||||
def delete_files():
|
||||
file_system.delete(
|
||||
[
|
||||
os.path.join(workspace.paths.project(), "Materials", "test_material.material"),
|
||||
os.path.join(workspace.paths.project(), "Materials", "test_material_1.material"),
|
||||
os.path.join(workspace.paths.project(), "Materials", "test_material_2.material"),
|
||||
],
|
||||
True,
|
||||
True,
|
||||
)
|
||||
# Cleanup our newly created materials
|
||||
delete_files()
|
||||
|
||||
def teardown():
|
||||
# Cleanup our newly created materials
|
||||
delete_files()
|
||||
|
||||
request.addfinalizer(teardown)
|
||||
|
||||
@pytest.mark.parametrize("exe_file_name", ["MaterialEditor"])
|
||||
def test_MaterialEditorBasicTests(
|
||||
self, request, workspace, project, launcher_platform, generic_launcher, exe_file_name):
|
||||
|
||||
expected_lines = [
|
||||
"Material opened: True",
|
||||
"Test asset doesn't exist initially: True",
|
||||
"New asset created: True",
|
||||
"New Material opened: True",
|
||||
"Material closed: True",
|
||||
"All documents closed: True",
|
||||
"Close All Except Selected worked as expected: True",
|
||||
"Actual Document saved with changes: True",
|
||||
"Document saved as copy is saved with changes: True",
|
||||
"Document saved as child is saved with changes: True",
|
||||
"Save All worked as expected: True",
|
||||
]
|
||||
unexpected_lines = [
|
||||
# "Trace::Assert",
|
||||
# "Trace::Error",
|
||||
"Traceback (most recent call last):"
|
||||
]
|
||||
|
||||
hydra.launch_and_validate_results(
|
||||
request,
|
||||
TEST_DIRECTORY,
|
||||
generic_launcher,
|
||||
"hydra_AtomMaterialEditor_BasicTests.py",
|
||||
run_python="--runpython",
|
||||
timeout=80,
|
||||
expected_lines=expected_lines,
|
||||
unexpected_lines=unexpected_lines,
|
||||
halt_on_unexpected=True,
|
||||
log_file_name="MaterialEditor.log",
|
||||
)
|
||||
|
||||
@@ -13,7 +13,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}
|
||||
PYTEST_MARKS "SUITE_main and not REQUIRES_gpu"
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
AZ::AssetProcessor
|
||||
@@ -28,7 +27,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}
|
||||
PYTEST_MARKS "SUITE_periodic and not REQUIRES_gpu"
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
AZ::AssetProcessor
|
||||
@@ -44,7 +42,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
|
||||
TEST_REQUIRES gpu
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}
|
||||
PYTEST_MARKS "SUITE_main and REQUIRES_gpu"
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
AZ::AssetProcessor
|
||||
@@ -59,7 +56,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}
|
||||
PYTEST_MARKS "SUITE_sandbox"
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
AZ::AssetProcessor
|
||||
|
||||
@@ -16,7 +16,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
|
||||
TEST_SUITE main
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg
|
||||
PYTEST_MARKS "not SUITE_sandbox and not SUITE_periodic and not SUITE_benchmark"
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
Legacy::Editor
|
||||
@@ -33,7 +32,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
|
||||
TEST_SUITE sandbox
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg
|
||||
PYTEST_MARKS "SUITE_sandbox"
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
Legacy::Editor
|
||||
@@ -49,7 +47,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
|
||||
TEST_SUITE periodic
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg
|
||||
PYTEST_MARKS "SUITE_periodic and dynveg_filter"
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
Legacy::Editor
|
||||
@@ -64,7 +61,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
|
||||
TEST_SUITE periodic
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg
|
||||
PYTEST_MARKS "SUITE_periodic and dynveg_modifier"
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
Legacy::Editor
|
||||
@@ -79,7 +75,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
|
||||
TEST_SUITE periodic
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg
|
||||
PYTEST_MARKS "SUITE_periodic and dynveg_regression"
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
Legacy::Editor
|
||||
@@ -94,7 +89,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
|
||||
TEST_SUITE periodic
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg
|
||||
PYTEST_MARKS "SUITE_periodic and dynveg_area"
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
Legacy::Editor
|
||||
@@ -109,7 +103,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
|
||||
TEST_SUITE periodic
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg
|
||||
PYTEST_MARKS "SUITE_periodic and dynveg_misc"
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
Legacy::Editor
|
||||
@@ -124,7 +117,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
|
||||
TEST_SUITE periodic
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg
|
||||
PYTEST_MARKS "SUITE_periodic and dynveg_surfacetagemitter"
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
Legacy::Editor
|
||||
@@ -140,7 +132,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
|
||||
TEST_SUITE main
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/landscape_canvas
|
||||
PYTEST_MARKS "not SUITE_sandbox and not SUITE_periodic and not SUITE_benchmark"
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
Legacy::Editor
|
||||
@@ -155,7 +146,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
|
||||
TEST_SUITE periodic
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/landscape_canvas
|
||||
PYTEST_MARKS "SUITE_periodic"
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
Legacy::Editor
|
||||
@@ -170,7 +160,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
|
||||
TEST_SERIAL
|
||||
TEST_SUITE periodic
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/gradient_signal
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
Legacy::Editor
|
||||
|
||||
Executable → Regular
+1
-1
@@ -105,7 +105,7 @@ class TestGeneralGraphFunctionality(object):
|
||||
|
||||
@pytest.mark.test_case_id("C17488412")
|
||||
@pytest.mark.SUITE_periodic
|
||||
@pytest.mark.xfail # https://github.com/o3de/o3de/issues/2201
|
||||
@pytest.mark.xfail(reason="https://github.com/o3de/o3de/issues/2201")
|
||||
def test_LandscapeCanvas_GraphClosed_OnEntityDelete(self, request, editor, level, launcher_platform):
|
||||
cfg_args = [level]
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
TEST_SUITE main
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Main.py
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
AZ::AssetProcessor
|
||||
@@ -25,7 +24,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
TEST_SUITE periodic
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Periodic.py
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
AZ::AssetProcessor
|
||||
@@ -38,7 +36,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
TEST_SUITE sandbox
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Sandbox.py
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
AZ::AssetProcessor
|
||||
|
||||
@@ -13,7 +13,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
TEST_SUITE main
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Main.py
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
AZ::AssetProcessor
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
"""
|
||||
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
|
||||
"""
|
||||
|
||||
# fmt:off
|
||||
class Tests():
|
||||
create_new_entity = ("Entity: 'CreateNewEntity' passed", "Entity: 'CreateNewEntity' failed")
|
||||
create_prefab = ("Prefab: 'CreatePrefab' passed", "Prefab: 'CreatePrefab' failed")
|
||||
instantiate_prefab = ("Prefab: 'InstantiatePrefab' passed", "Prefab: 'InstantiatePrefab' failed")
|
||||
new_prefab_position = ("Prefab: new prefab's position is at the expected position", "Prefab: new prefab's position is *not* at the expected position")
|
||||
# fmt:on
|
||||
|
||||
def PrefabLevel_BasicWorkflow():
|
||||
"""
|
||||
This test will help verify if the following functions related to Prefab work as expected:
|
||||
- CreatePrefab
|
||||
- InstantiatePrefab
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.entity as entity
|
||||
from azlmbr.entity import EntityId
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.prefab as prefab
|
||||
from azlmbr.math import Vector3
|
||||
import azlmbr.legacy.general as general
|
||||
|
||||
EXPECTED_NEW_PREFAB_POSITION = Vector3(10.00, 20.0, 30.0)
|
||||
|
||||
helper.init_idle()
|
||||
helper.open_level("Prefab", "Base")
|
||||
|
||||
# Create a new Entity at the root level
|
||||
new_entity_id = editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', EntityId())
|
||||
Report.result(Tests.create_new_entity, new_entity_id.IsValid())
|
||||
|
||||
# Checks for prefab creation passed or not
|
||||
new_prefab_file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'new_prefab.prefab')
|
||||
create_prefab_result = prefab.PrefabPublicRequestBus(bus.Broadcast, 'CreatePrefabInMemory', [new_entity_id], new_prefab_file_path)
|
||||
Report.result(Tests.create_prefab, create_prefab_result)
|
||||
|
||||
# Checks for prefab instantiation passed or not
|
||||
container_entity_id = prefab.PrefabPublicRequestBus(bus.Broadcast, 'InstantiatePrefab', new_prefab_file_path, EntityId(), EXPECTED_NEW_PREFAB_POSITION)
|
||||
Report.result(Tests.instantiate_prefab, container_entity_id.IsValid())
|
||||
|
||||
# Checks if the new prefab is at the correct position and if it fails, it will provide the expected postion and the actual postion of the entity in the Editor log
|
||||
new_prefab_position = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", container_entity_id)
|
||||
is_at_position = new_prefab_position.IsClose(EXPECTED_NEW_PREFAB_POSITION)
|
||||
Report.result(Tests.new_prefab_position, is_at_position)
|
||||
if not is_at_position:
|
||||
Report.info(f'Expected position: {EXPECTED_NEW_PREFAB_POSITION.ToString()}, actual position: {new_prefab_position.ToString()}')
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(PrefabLevel_BasicWorkflow)
|
||||
@@ -16,6 +16,7 @@ from ly_test_tools import LAUNCHERS
|
||||
|
||||
sys.path.append (os.path.dirname (os.path.abspath (__file__)) + '/../automatedtesting_shared')
|
||||
|
||||
import ly_test_tools.environment.file_system as file_system
|
||||
from base import TestAutomationBase
|
||||
|
||||
@pytest.mark.SUITE_main
|
||||
@@ -29,3 +30,8 @@ class TestAutomation(TestAutomationBase):
|
||||
def test_PrefabLevel_OpensLevelWithEntities(self, request, workspace, editor, launcher_platform):
|
||||
from . import PrefabLevel_OpensLevelWithEntities as test_module
|
||||
self._run_prefab_test(request, workspace, editor, test_module)
|
||||
|
||||
def test_PrefabLevel_BasicWorkflow(self, request, workspace, editor, launcher_platform):
|
||||
from . import PrefabLevel_BasicWorkflow as test_module
|
||||
self._run_prefab_test(request, workspace, editor, test_module)
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
TEST_SUITE periodic
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Periodic.py
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
AZ::AssetProcessor
|
||||
@@ -25,7 +24,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
TEST_SUITE sandbox
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Sandbox.py
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
AZ::AssetProcessor
|
||||
|
||||
@@ -18,7 +18,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}
|
||||
PYTEST_MARKS "SUITE_smoke"
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
AZ::PythonBindingsExample
|
||||
@@ -74,5 +73,17 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
AutomatedTesting.GameLauncher
|
||||
AutomatedTesting.Assets
|
||||
)
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::LoadLevelCPU
|
||||
TEST_SUITE sandbox
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/test_RemoteConsole_CPULoadLevel_Works.py
|
||||
TIMEOUT 100
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
AZ::PythonBindingsExample
|
||||
Legacy::Editor
|
||||
AutomatedTesting.GameLauncher
|
||||
AutomatedTesting.Assets
|
||||
)
|
||||
|
||||
endif()
|
||||
|
||||
@@ -24,7 +24,7 @@ from ly_remote_console.remote_console_commands import (
|
||||
@pytest.mark.parametrize("launcher_platform", ["windows"])
|
||||
@pytest.mark.parametrize("project", ["AutomatedTesting"])
|
||||
@pytest.mark.parametrize("level", ["Simple"])
|
||||
@pytest.mark.SUITE_smoke
|
||||
@pytest.mark.SUITE_sandbox
|
||||
class TestRemoteConsoleLoadLevelWorks(object):
|
||||
@pytest.fixture
|
||||
def remote_console_instance(self, request):
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"ContainerEntity": {
|
||||
"Id": "Entity_[1146574390643]",
|
||||
"Name": "Level",
|
||||
"Components": {
|
||||
"Component_[10641544592923449938]": {
|
||||
"$type": "EditorInspectorComponent",
|
||||
"Id": 10641544592923449938
|
||||
},
|
||||
"Component_[12039882709170782873]": {
|
||||
"$type": "EditorOnlyEntityComponent",
|
||||
"Id": 12039882709170782873
|
||||
},
|
||||
"Component_[12265484671603697631]": {
|
||||
"$type": "EditorPendingCompositionComponent",
|
||||
"Id": 12265484671603697631
|
||||
},
|
||||
"Component_[14126657869720434043]": {
|
||||
"$type": "EditorEntitySortComponent",
|
||||
"Id": 14126657869720434043
|
||||
},
|
||||
"Component_[15230859088967841193]": {
|
||||
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
|
||||
"Id": 15230859088967841193,
|
||||
"Parent Entity": ""
|
||||
},
|
||||
"Component_[16239496886950819870]": {
|
||||
"$type": "EditorDisabledCompositionComponent",
|
||||
"Id": 16239496886950819870
|
||||
},
|
||||
"Component_[5688118765544765547]": {
|
||||
"$type": "EditorEntityIconComponent",
|
||||
"Id": 5688118765544765547
|
||||
},
|
||||
"Component_[6545738857812235305]": {
|
||||
"$type": "SelectionComponent",
|
||||
"Id": 6545738857812235305
|
||||
},
|
||||
"Component_[7247035804068349658]": {
|
||||
"$type": "EditorPrefabComponent",
|
||||
"Id": 7247035804068349658
|
||||
},
|
||||
"Component_[9307224322037797205]": {
|
||||
"$type": "EditorLockComponent",
|
||||
"Id": 9307224322037797205
|
||||
},
|
||||
"Component_[9562516168917670048]": {
|
||||
"$type": "EditorVisibilityComponent",
|
||||
"Id": 9562516168917670048
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:ba9a2cd047a5ee696aaeed882869017a02fd4f5eeee91b6b2bfb830ad1e5ee15
|
||||
size 10927631
|
||||
oid sha256:c285cdf72ebe4c274f8d1fbab6ff558f9344d4fa62fb9d07cf11f7511ffaaac9
|
||||
size 2177072
|
||||
|
||||
@@ -0,0 +1,328 @@
|
||||
{
|
||||
"values": [
|
||||
{
|
||||
"$type": "ActorGroup",
|
||||
"name": "Jack",
|
||||
"selectedRootBone": "RootNode.jack_root",
|
||||
"id": "{B7194F91-D8A1-5D5D-AC6D-DDEBC087D80D}",
|
||||
"rules": {
|
||||
"rules": [
|
||||
{
|
||||
"$type": "MetaDataRule",
|
||||
"metaData": "AdjustActor -actorID $(ACTORID) -name \"Jack\"\nActorSetCollisionMeshes -actorID $(ACTORID) -lod 0 -nodeList \"\"\nAdjustActor -actorID $(ACTORID) -nodesExcludedFromBounds \"\" -nodeAction \"select\"\nAdjustActor -actorID $(ACTORID) -nodeAction \"replace\" -attachmentNodes \"\"\nAdjustActor -actorID $(ACTORID) -motionExtractionNodeName \"jack_root\"\nAdjustActor -actorID $(ACTORID) -mirrorSetup \"\"\n"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"$type": "{5B03C8E6-8CEE-4DA0-A7FA-CD88689DD45B} MeshGroup",
|
||||
"id": "{BF2CCF49-9BE0-5103-987A-84649A974991}",
|
||||
"name": "Jack",
|
||||
"NodeSelectionList": {
|
||||
"unselectedNodes": [
|
||||
"RootNode",
|
||||
"RootNode.jack_root",
|
||||
"RootNode.jack_meshZUp",
|
||||
"RootNode.jack_root.Bip01__pelvis",
|
||||
"RootNode.jack_meshZUp.jack_meshZUp_1",
|
||||
"RootNode.jack_meshZUp.jack_meshZUp_2",
|
||||
"RootNode.jack_root.Bip01__pelvis.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.l_upLeg",
|
||||
"RootNode.jack_root.Bip01__pelvis.r_upLeg",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1",
|
||||
"RootNode.jack_meshZUp.jack_meshZUp_1.Bitangent",
|
||||
"RootNode.jack_meshZUp.jack_meshZUp_1.SkinWeight_",
|
||||
"RootNode.jack_meshZUp.jack_meshZUp_1.transform",
|
||||
"RootNode.jack_meshZUp.jack_meshZUp_1.Tangent",
|
||||
"RootNode.jack_meshZUp.jack_meshZUp_1.map1",
|
||||
"RootNode.jack_meshZUp.jack_meshZUp_1.jack",
|
||||
"RootNode.jack_meshZUp.jack_meshZUp_2.Bitangent",
|
||||
"RootNode.jack_meshZUp.jack_meshZUp_2.SkinWeight_",
|
||||
"RootNode.jack_meshZUp.jack_meshZUp_2.transform",
|
||||
"RootNode.jack_meshZUp.jack_meshZUp_2.Tangent",
|
||||
"RootNode.jack_meshZUp.jack_meshZUp_2.map1",
|
||||
"RootNode.jack_meshZUp.jack_meshZUp_2.jack",
|
||||
"RootNode.jack_root.Bip01__pelvis.l_upLeg.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.l_upLeg.l_upLegRoll",
|
||||
"RootNode.jack_root.Bip01__pelvis.l_upLeg.l_loLeg",
|
||||
"RootNode.jack_root.Bip01__pelvis.r_upLeg.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.r_upLeg.r_upLegRoll",
|
||||
"RootNode.jack_root.Bip01__pelvis.r_upLeg.r_loLeg",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2",
|
||||
"RootNode.jack_root.Bip01__pelvis.l_upLeg.l_upLegRoll.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.l_upLeg.l_loLeg.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.l_upLeg.l_loLeg.l_ankle",
|
||||
"RootNode.jack_root.Bip01__pelvis.r_upLeg.r_upLegRoll.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.r_upLeg.r_loLeg.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.r_upLeg.r_loLeg.r_ankle",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3",
|
||||
"RootNode.jack_root.Bip01__pelvis.l_upLeg.l_loLeg.l_ankle.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.l_upLeg.l_loLeg.l_ankle.l_ball",
|
||||
"RootNode.jack_root.Bip01__pelvis.r_upLeg.r_loLeg.r_ankle.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.r_upLeg.r_loLeg.r_ankle.r_ball",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.neck",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr",
|
||||
"RootNode.jack_root.Bip01__pelvis.l_upLeg.l_loLeg.l_ankle.l_ball.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.r_upLeg.r_loLeg.r_ankle.r_ball.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.neck.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.neck.head",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.neck.head.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_upArmRoll",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_upArmRoll",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_upArmRoll.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_loArmRoll",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_upArmRoll.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_loArmRoll",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_loArmRoll.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_thumb1",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_index1",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_mid1",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_metacarpal",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_handProp",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_loArmRoll.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_thumb1",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_index1",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_mid1",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_metacarpal",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_handProp",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_thumb1.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_thumb1.l_thumb2",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_index1.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_index1.l_index2",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_mid1.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_mid1.l_mid2",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_metacarpal.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_metacarpal.l_ring1",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_metacarpal.l_pinky1",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_handProp.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_thumb1.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_thumb1.r_thumb2",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_index1.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_index1.r_index2",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_mid1.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_mid1.r_mid2",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_metacarpal.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_metacarpal.r_ring1",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_metacarpal.r_pinky1",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_handProp.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_thumb1.l_thumb2.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_thumb1.l_thumb2.l_thumb3",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_index1.l_index2.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_index1.l_index2.l_index3",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_mid1.l_mid2.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_mid1.l_mid2.l_mid3",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_metacarpal.l_ring1.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_metacarpal.l_ring1.l_ring2",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_metacarpal.l_pinky1.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_metacarpal.l_pinky1.l_pinky2",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_thumb1.r_thumb2.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_thumb1.r_thumb2.r_thumb3",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_index1.r_index2.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_index1.r_index2.r_index3",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_mid1.r_mid2.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_mid1.r_mid2.r_mid3",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_metacarpal.r_ring1.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_metacarpal.r_ring1.r_ring2",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_metacarpal.r_pinky1.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_metacarpal.r_pinky1.r_pinky2",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_thumb1.l_thumb2.l_thumb3.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_index1.l_index2.l_index3.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_mid1.l_mid2.l_mid3.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_metacarpal.l_ring1.l_ring2.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_metacarpal.l_ring1.l_ring2.l_ring3",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_metacarpal.l_pinky1.l_pinky2.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_metacarpal.l_pinky1.l_pinky2.l_pinky3",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_thumb1.r_thumb2.r_thumb3.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_index1.r_index2.r_index3.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_mid1.r_mid2.r_mid3.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_metacarpal.r_ring1.r_ring2.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_metacarpal.r_ring1.r_ring2.r_ring3",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_metacarpal.r_pinky1.r_pinky2.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_metacarpal.r_pinky1.r_pinky2.r_pinky3",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_metacarpal.l_ring1.l_ring2.l_ring3.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_metacarpal.l_pinky1.l_pinky2.l_pinky3.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_metacarpal.r_ring1.r_ring2.r_ring3.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_metacarpal.r_pinky1.r_pinky2.r_pinky3.transform"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"$type": "{07B356B7-3635-40B5-878A-FAC4EFD5AD86} MeshGroup",
|
||||
"name": "Jack",
|
||||
"nodeSelectionList": {
|
||||
"selectedNodes": [
|
||||
"RootNode",
|
||||
"RootNode.jack_root",
|
||||
"RootNode.jack_meshZUp",
|
||||
"RootNode.jack_root.Bip01__pelvis",
|
||||
"RootNode.jack_meshZUp.jack_meshZUp_1",
|
||||
"RootNode.jack_meshZUp.jack_meshZUp_2",
|
||||
"RootNode.jack_root.Bip01__pelvis.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.l_upLeg",
|
||||
"RootNode.jack_root.Bip01__pelvis.r_upLeg",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1",
|
||||
"RootNode.jack_meshZUp.jack_meshZUp_1.Bitangent",
|
||||
"RootNode.jack_meshZUp.jack_meshZUp_1.SkinWeight_",
|
||||
"RootNode.jack_meshZUp.jack_meshZUp_1.transform",
|
||||
"RootNode.jack_meshZUp.jack_meshZUp_1.Tangent",
|
||||
"RootNode.jack_meshZUp.jack_meshZUp_1.map1",
|
||||
"RootNode.jack_meshZUp.jack_meshZUp_1.jack",
|
||||
"RootNode.jack_meshZUp.jack_meshZUp_2.Bitangent",
|
||||
"RootNode.jack_meshZUp.jack_meshZUp_2.SkinWeight_",
|
||||
"RootNode.jack_meshZUp.jack_meshZUp_2.transform",
|
||||
"RootNode.jack_meshZUp.jack_meshZUp_2.Tangent",
|
||||
"RootNode.jack_meshZUp.jack_meshZUp_2.map1",
|
||||
"RootNode.jack_meshZUp.jack_meshZUp_2.jack",
|
||||
"RootNode.jack_root.Bip01__pelvis.l_upLeg.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.l_upLeg.l_upLegRoll",
|
||||
"RootNode.jack_root.Bip01__pelvis.l_upLeg.l_loLeg",
|
||||
"RootNode.jack_root.Bip01__pelvis.r_upLeg.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.r_upLeg.r_upLegRoll",
|
||||
"RootNode.jack_root.Bip01__pelvis.r_upLeg.r_loLeg",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2",
|
||||
"RootNode.jack_root.Bip01__pelvis.l_upLeg.l_upLegRoll.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.l_upLeg.l_loLeg.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.l_upLeg.l_loLeg.l_ankle",
|
||||
"RootNode.jack_root.Bip01__pelvis.r_upLeg.r_upLegRoll.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.r_upLeg.r_loLeg.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.r_upLeg.r_loLeg.r_ankle",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3",
|
||||
"RootNode.jack_root.Bip01__pelvis.l_upLeg.l_loLeg.l_ankle.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.l_upLeg.l_loLeg.l_ankle.l_ball",
|
||||
"RootNode.jack_root.Bip01__pelvis.r_upLeg.r_loLeg.r_ankle.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.r_upLeg.r_loLeg.r_ankle.r_ball",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.neck",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr",
|
||||
"RootNode.jack_root.Bip01__pelvis.l_upLeg.l_loLeg.l_ankle.l_ball.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.r_upLeg.r_loLeg.r_ankle.r_ball.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.neck.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.neck.head",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.neck.head.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_upArmRoll",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_upArmRoll",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_upArmRoll.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_loArmRoll",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_upArmRoll.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_loArmRoll",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_loArmRoll.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_thumb1",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_index1",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_mid1",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_metacarpal",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_handProp",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_loArmRoll.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_thumb1",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_index1",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_mid1",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_metacarpal",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_handProp",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_thumb1.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_thumb1.l_thumb2",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_index1.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_index1.l_index2",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_mid1.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_mid1.l_mid2",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_metacarpal.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_metacarpal.l_ring1",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_metacarpal.l_pinky1",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_handProp.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_thumb1.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_thumb1.r_thumb2",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_index1.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_index1.r_index2",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_mid1.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_mid1.r_mid2",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_metacarpal.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_metacarpal.r_ring1",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_metacarpal.r_pinky1",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_handProp.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_thumb1.l_thumb2.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_thumb1.l_thumb2.l_thumb3",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_index1.l_index2.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_index1.l_index2.l_index3",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_mid1.l_mid2.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_mid1.l_mid2.l_mid3",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_metacarpal.l_ring1.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_metacarpal.l_ring1.l_ring2",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_metacarpal.l_pinky1.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_metacarpal.l_pinky1.l_pinky2",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_thumb1.r_thumb2.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_thumb1.r_thumb2.r_thumb3",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_index1.r_index2.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_index1.r_index2.r_index3",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_mid1.r_mid2.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_mid1.r_mid2.r_mid3",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_metacarpal.r_ring1.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_metacarpal.r_ring1.r_ring2",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_metacarpal.r_pinky1.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_metacarpal.r_pinky1.r_pinky2",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_thumb1.l_thumb2.l_thumb3.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_index1.l_index2.l_index3.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_mid1.l_mid2.l_mid3.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_metacarpal.l_ring1.l_ring2.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_metacarpal.l_ring1.l_ring2.l_ring3",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_metacarpal.l_pinky1.l_pinky2.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_metacarpal.l_pinky1.l_pinky2.l_pinky3",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_thumb1.r_thumb2.r_thumb3.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_index1.r_index2.r_index3.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_mid1.r_mid2.r_mid3.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_metacarpal.r_ring1.r_ring2.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_metacarpal.r_ring1.r_ring2.r_ring3",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_metacarpal.r_pinky1.r_pinky2.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_metacarpal.r_pinky1.r_pinky2.r_pinky3",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_metacarpal.l_ring1.l_ring2.l_ring3.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_metacarpal.l_pinky1.l_pinky2.l_pinky3.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_metacarpal.r_ring1.r_ring2.r_ring3.transform",
|
||||
"RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_metacarpal.r_pinky1.r_pinky2.r_pinky3.transform"
|
||||
]
|
||||
},
|
||||
"rules": {
|
||||
"rules": [
|
||||
{
|
||||
"$type": "SkinRule"
|
||||
},
|
||||
{
|
||||
"$type": "MaterialRule"
|
||||
}
|
||||
]
|
||||
},
|
||||
"id": "{59B1DB76-5B27-5569-8DF6-55296FD0E5D8}"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
<Material MtlFlags="524544" DccMaterialHash="0" vertModifType="0">
|
||||
<SubMaterials>
|
||||
<Material Name="Jack:jack" MtlFlags="524416" DccMaterialHash="0" Shader="Illum" GenMask="A00080000003" StringGenMask="%ALLOW_SILHOUETTE_POM%ALLOW_SPECULAR_ANTIALIASING%FX_DISSOLVE%SPECULAR_MAP%SUBSURFACE_SCATTERING" SurfaceType="" Diffuse="0.80000001,0.80000001,0.80000001,1" Specular="0.5,0.5,0.5,1" Opacity="1" Shininess="3.4240739" vertModifType="0" LayerAct="1">
|
||||
<Textures>
|
||||
<Texture Map="Diffuse" File="objects/characters/jack/textures/jack_diff.dds"/>
|
||||
<Texture Map="Specular" File="objects/characters/jack/textures/jack_spec.dds"/>
|
||||
</Textures>
|
||||
<PublicParams DissolveColor="1,1,1" EmittanceMapGamma="1" DissolveEdgeThickness="0" SSSIndex="0" DissolvePercentage="0" IndirectColor="0.25,0.25,0.25"/>
|
||||
</Material>
|
||||
</SubMaterials>
|
||||
<PublicParams EmittanceMapGamma="1" SSSIndex="0" IndirectColor="0.25,0.25,0.25"/>
|
||||
</Material>
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:bb1c97394454a0a0c3b4aaf8380878aac3f7bedc9091ec920963932ad6ad2290
|
||||
size 30484
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:d090219fc20e7c1d9f0c187f976a7cb55e5b27b39e087aa8281ac794f314cb32
|
||||
size 22364
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:8fa78264ca46a2f201e24c3ba6a543e713bf9fd984df0a10f52b191d21077227
|
||||
size 106676
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:ebf610eecec9a4da2d5c9260c48b81f6a04eaf7686d69850ad9f5d06fdbcf183
|
||||
size 12940
|
||||
@@ -1,14 +0,0 @@
|
||||
<Material MtlFlags="524544" vertModifType="0">
|
||||
<SubMaterials>
|
||||
<Material Name="jack" MtlFlags="524416" Shader="Illum" GenMask="4001010020001" StringGenMask="%ALLOW_SILHOUETTE_POM%EMITTANCE_MAP%NORMAL_MAP%SPECULAR_MAP%SUBSURFACE_SCATTERING" SurfaceType="mat_metal" Diffuse="1,1,1,1" Specular="1,1,1,1" Emittance="1,1,1,200" Opacity="1" Shininess="255" vertModifType="0" LayerAct="1">
|
||||
<Textures>
|
||||
<Texture Map="Diffuse" File="objects/characters/jack/textures/brokenrobot_black_diff.dds"/>
|
||||
<Texture Map="Bumpmap" File="objects/characters/jack/textures/brokenrobot_01_ddna.dds"/>
|
||||
<Texture Map="Specular" File="objects/characters/jack/textures/brokenrobot_spec.dds"/>
|
||||
<Texture Map="Emittance" File="objects/characters/jack/textures/jack_emis.dds"/>
|
||||
</Textures>
|
||||
<PublicParams EmittanceMapGamma="1" SSSIndex="0" IndirectColor="0.25,0.25,0.25"/>
|
||||
</Material>
|
||||
</SubMaterials>
|
||||
<PublicParams EmittanceMapGamma="1" SSSIndex="0" IndirectColor="0.25,0.25,0.25"/>
|
||||
</Material>
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:30afe8cf6e4aca846b07ef81747607afb47c0ff88283f363aca29ded9818c3db
|
||||
size 8148
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:dba25dd8b3840d01aefb69007919b07befc5365fff714493c87cf1eff644d5dc
|
||||
size 8148
|
||||
@@ -1,8 +0,0 @@
|
||||
<Material MtlFlags="524544" >
|
||||
<SubMaterials>
|
||||
<Material Name="dummyPlane_mat" MtlFlags="1152" Shader="Nodraw" GenMask="0" SurfaceType="" MatTemplate="" Diffuse="0.500000,0.500000,0.500000" Specular="0.000000,0.000000,0.000000" Emissive="0.000000,0.000000,0.000000" Shininess="10" Opacity="1" >
|
||||
<Textures>
|
||||
</Textures>
|
||||
</Material>
|
||||
</SubMaterials>
|
||||
</Material>
|
||||
@@ -1,14 +0,0 @@
|
||||
<Material MtlFlags="524544" vertModifType="0">
|
||||
<SubMaterials>
|
||||
<Material Name="jack" MtlFlags="524416" Shader="Illum" GenMask="4001010020001" StringGenMask="%ALLOW_SILHOUETTE_POM%EMITTANCE_MAP%NORMAL_MAP%SPECULAR_MAP%SUBSURFACE_SCATTERING" SurfaceType="mat_player_collider" Diffuse="1,1,1,1" Specular="1,1,1,1" Emittance="0.99110222,0.0056053922,0.0056053922,200" Opacity="1" Shininess="255" vertModifType="0" LayerAct="1">
|
||||
<Textures>
|
||||
<Texture Map="Diffuse" File="objects/characters/jack/textures/brokenrobot_white_diff.dds"/>
|
||||
<Texture Map="Bumpmap" File="objects/characters/jack/textures/brokenrobot_01_ddna.dds"/>
|
||||
<Texture Map="Specular" File="objects/characters/jack/textures/brokenrobot_spec.dds"/>
|
||||
<Texture Map="Emittance" File="objects/characters/jack/textures/brokenrobot_emis.dds"/>
|
||||
</Textures>
|
||||
<PublicParams EmittanceMapGamma="1" SSSIndex="0" IndirectColor="0.25,0.25,0.25"/>
|
||||
</Material>
|
||||
</SubMaterials>
|
||||
<PublicParams EmittanceMapGamma="1" SSSIndex="0" IndirectColor="0.25,0.25,0.25"/>
|
||||
</Material>
|
||||
@@ -1,14 +0,0 @@
|
||||
<Material MtlFlags="524544" vertModifType="0">
|
||||
<SubMaterials>
|
||||
<Material Name="jack" MtlFlags="524416" Shader="Illum" GenMask="4001010020001" StringGenMask="%ALLOW_SILHOUETTE_POM%EMITTANCE_MAP%NORMAL_MAP%SPECULAR_MAP%SUBSURFACE_SCATTERING" SurfaceType="mat_player_collider" Diffuse="1,1,1,1" Specular="1,1,1,1" Emittance="0.00091058103,0.70837593,0.76815128,160" Opacity="1" Shininess="255" vertModifType="0" LayerAct="1">
|
||||
<Textures>
|
||||
<Texture Map="Diffuse" File="objects/characters/jack/textures/brokenrobot_white_diff.dds"/>
|
||||
<Texture Map="Bumpmap" File="objects/characters/jack/textures/brokenrobot_01_ddna.dds"/>
|
||||
<Texture Map="Specular" File="objects/characters/jack/textures/brokenrobot_spec.dds"/>
|
||||
<Texture Map="Emittance" File="objects/characters/jack/textures/jack_emis.dds"/>
|
||||
</Textures>
|
||||
<PublicParams EmittanceMapGamma="1" SSSIndex="0" IndirectColor="0.25,0.25,0.25"/>
|
||||
</Material>
|
||||
</SubMaterials>
|
||||
<PublicParams EmittanceMapGamma="1" SSSIndex="0" IndirectColor="0.25,0.25,0.25"/>
|
||||
</Material>
|
||||
@@ -1,14 +0,0 @@
|
||||
<Material MtlFlags="524544" vertModifType="0">
|
||||
<SubMaterials>
|
||||
<Material Name="jack" MtlFlags="524416" Shader="Illum" GenMask="4001010020001" StringGenMask="%ALLOW_SILHOUETTE_POM%EMITTANCE_MAP%NORMAL_MAP%SPECULAR_MAP%SUBSURFACE_SCATTERING" SurfaceType="mat_player_collider" Diffuse="1,1,1,1" Specular="1,1,1,1" Emittance="0.98225069,0.00030352699,0.00030352699,200" Opacity="1" Shininess="255" vertModifType="0" LayerAct="1">
|
||||
<Textures>
|
||||
<Texture Map="Diffuse" File="objects/characters/jack/textures/brokenrobot_black_diff.dds"/>
|
||||
<Texture Map="Bumpmap" File="objects/characters/jack/textures/brokenrobot_01_ddna.dds"/>
|
||||
<Texture Map="Specular" File="objects/characters/jack/textures/brokenrobot_spec.dds"/>
|
||||
<Texture Map="Emittance" File="objects/characters/jack/textures/brokenrobot_emis.dds"/>
|
||||
</Textures>
|
||||
<PublicParams EmittanceMapGamma="1" SSSIndex="0" IndirectColor="0.25,0.25,0.25"/>
|
||||
</Material>
|
||||
</SubMaterials>
|
||||
<PublicParams EmittanceMapGamma="1" SSSIndex="0" IndirectColor="0.25,0.25,0.25"/>
|
||||
</Material>
|
||||
@@ -1,14 +0,0 @@
|
||||
<Material MtlFlags="524544" vertModifType="0">
|
||||
<SubMaterials>
|
||||
<Material Name="jack" MtlFlags="524416" Shader="Illum" GenMask="4001010020001" StringGenMask="%ALLOW_SILHOUETTE_POM%EMITTANCE_MAP%NORMAL_MAP%SPECULAR_MAP%SUBSURFACE_SCATTERING" SurfaceType="mat_player_collider" Diffuse="1,1,1,1" Specular="1,1,1,1" Emittance="0.00091058103,0.70837593,0.76815128,160" Opacity="1" Shininess="255" vertModifType="0" LayerAct="1">
|
||||
<Textures>
|
||||
<Texture Map="Diffuse" File="objects/characters/jack/textures/jack_diff.dds"/>
|
||||
<Texture Map="Bumpmap" File="objects/characters/jack/textures/jack_ddna.dds"/>
|
||||
<Texture Map="Specular" File="objects/characters/jack/textures/jack_spec_02_spec.dds"/>
|
||||
<Texture Map="Emittance" File="objects/characters/jack/textures/jack_emis.dds"/>
|
||||
</Textures>
|
||||
<PublicParams EmittanceMapGamma="1" SSSIndex="0" IndirectColor="0.25,0.25,0.25"/>
|
||||
</Material>
|
||||
</SubMaterials>
|
||||
<PublicParams EmittanceMapGamma="1" SSSIndex="0" IndirectColor="0.25,0.25,0.25"/>
|
||||
</Material>
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:ca5c900fabf8b5c8c9313a0144886f4da3f812c82e8cffd652d9c61b9bb5b953
|
||||
size 4221960
|
||||
-1
@@ -1 +0,0 @@
|
||||
/autooptimizefile=0 /preset=NormalsWithSmoothness /reduce=0
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:80f40a78e4b21dd27f5ddf34337e7d0e2119b7cfa08f0eea38d4b1d63808821f
|
||||
size 3178996
|
||||
-1
@@ -1 +0,0 @@
|
||||
/autooptimizefile=0 /preset=Albedo /reduce=0
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:e5f5e327624e0f1fd35fac141019941b12ad0642c25853be9f7fd5b9b6f91bc5
|
||||
size 3168212
|
||||
-1
@@ -1 +0,0 @@
|
||||
/autooptimizefile=0 /preset=Albedo /reduce=0
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:089e74ca9a41967038e16a9107099a73f8e93d39c487ff5bacdde18f418bf761
|
||||
size 3176732
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:d45cd564d2b52575d1ad37b907a7d378871f05f6c9e5569ec73d7973d56599c9
|
||||
size 3167984
|
||||
@@ -1 +0,0 @@
|
||||
/autooptimizefile=0 /preset=Albedo /reduce=0
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:83a872c07f7cbbcb868903429dd8d5a71e8c0b7b0e2cb16cb08b5cb26b02251c
|
||||
size 3177492
|
||||
-1
@@ -1 +0,0 @@
|
||||
/autooptimizefile=0 /preset=Albedo /reduce=0
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:81c1bc9545a17232523fd97561013534221b3bf8927feefa52bdc757e294c2e2
|
||||
size 3179140
|
||||
-1
@@ -1 +0,0 @@
|
||||
/autooptimizefile=0 /preset=Albedo /reduce=0
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:99f476a56205c80878be7472857a6430ce6dc40f2eb1558de4933a5b79fa2420
|
||||
size 814244
|
||||
@@ -1 +0,0 @@
|
||||
/autooptimizefile=0 /preset=Reflectance /reduce=0
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:366959c8a31356669d47f58d07157171ed369b3e7549b3b65a8b8d153a1477a6
|
||||
size 3179956
|
||||
-1
@@ -1 +0,0 @@
|
||||
/autooptimizefile=0 /preset=Albedo /reduce=0
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:e839924e03ba99459547df1cf5334de3bdad75b18e76176e430e343a979d9f05
|
||||
size 3168472
|
||||
-1
@@ -1 +0,0 @@
|
||||
/autooptimizefile=0 /preset=Albedo /reduce=0
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:36f537bb5be89fccba1502e9e8f8dfffbf05ea8aa82ac439305e8c2502b01691
|
||||
size 16804800
|
||||
@@ -1 +0,0 @@
|
||||
/autooptimizefile=0 /M=50,50,0,50,50,50 /preset=NormalsWithSmoothness /reduce=0
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:b0457cbbbe1fe7e52fdb9af7ee2bc32df96a453fe248738b35ffe0b8087a28c5
|
||||
size 12615988
|
||||
@@ -1 +0,0 @@
|
||||
/autooptimizefile=0 /M=50,50,50,0,50,50 /preset=Albedo /reduce=0
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:4ba741103d039bddf72d4834c92a5e069285e31b8be2e7f4e8103f9c5c81694f
|
||||
size 3167864
|
||||
@@ -1 +0,0 @@
|
||||
/autooptimizefile=0 /M=50,50,0,50,50,50 /preset=Albedo /reduce=0
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:4d7cb58f48e4df76214509fc01d5170fd38bc447d56af61f008c04a1653c2d20
|
||||
size 12614884
|
||||
@@ -1 +0,0 @@
|
||||
/autooptimizefile=0 /M=50,50,50,0,50,50 /preset=Reflectance /reduce=0
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:80a2c56bfcb8c98bf5a72ec9fdb5fcc6eae28ba1c3c26efad5c8a36e6105f1d0
|
||||
size 3173936
|
||||
@@ -1 +0,0 @@
|
||||
/autooptimizefile=0 /preset=Reflectance /reduce=0
|
||||
@@ -1,149 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "EditorDefs.h"
|
||||
#include "SkeletonHierarchy.h"
|
||||
|
||||
using namespace Skeleton;
|
||||
|
||||
/*
|
||||
|
||||
CHierarchy
|
||||
|
||||
*/
|
||||
|
||||
CHierarchy::CHierarchy()
|
||||
{
|
||||
}
|
||||
|
||||
CHierarchy::~CHierarchy()
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
uint32 CHierarchy::AddNode(const char* name, const QuatT& pose, int32 parent)
|
||||
{
|
||||
int32 index = FindNodeIndexByName(name);
|
||||
|
||||
if (index < 0)
|
||||
{
|
||||
m_nodes.push_back(SNode());
|
||||
index = int32(m_nodes.size() - 1);
|
||||
}
|
||||
|
||||
m_nodes[index].name = name;
|
||||
m_nodes[index].pose = pose;
|
||||
m_nodes[index].parent = parent;
|
||||
return uint32(index);
|
||||
}
|
||||
|
||||
int32 CHierarchy::FindNodeIndexByName(const char* name) const
|
||||
{
|
||||
uint32 count = uint32(m_nodes.size());
|
||||
for (uint32 i = 0; i < count; ++i)
|
||||
{
|
||||
if (::_stricmp(m_nodes[i].name, name))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
const CHierarchy::SNode* CHierarchy::FindNode(const char* name) const
|
||||
{
|
||||
int32 index = FindNodeIndexByName(name);
|
||||
return index < 0 ? nullptr : &m_nodes[index];
|
||||
}
|
||||
|
||||
void CHierarchy::CreateFrom(IDefaultSkeleton* pIDefaultSkeleton)
|
||||
{
|
||||
const uint32 jointCount = pIDefaultSkeleton->GetJointCount();
|
||||
|
||||
m_nodes.clear();
|
||||
m_nodes.reserve(jointCount);
|
||||
for (uint32 i = 0; i < jointCount; ++i)
|
||||
{
|
||||
m_nodes.push_back(SNode());
|
||||
|
||||
m_nodes.back().name = pIDefaultSkeleton->GetJointNameByID(int32(i));
|
||||
m_nodes.back().pose = pIDefaultSkeleton->GetDefaultAbsJointByID(int32(i));
|
||||
|
||||
m_nodes.back().parent = pIDefaultSkeleton->GetJointParentIDByID(int32(i));
|
||||
}
|
||||
|
||||
ValidateReferences();
|
||||
}
|
||||
|
||||
void CHierarchy::ValidateReferences()
|
||||
{
|
||||
uint32 nodeCount = m_nodes.size();
|
||||
if (!nodeCount)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint32 i = 0; i < nodeCount; ++i)
|
||||
{
|
||||
if (m_nodes[i].parent < nodeCount)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
m_nodes[i].parent = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void CHierarchy::AbsoluteToRelative(const QuatT* pSource, QuatT* pDestination)
|
||||
{
|
||||
uint32 count = uint32(m_nodes.size());
|
||||
std::vector<QuatT> absolutes(count);
|
||||
for (uint32 i = 0; i < count; ++i)
|
||||
{
|
||||
absolutes[i] = pSource[i];
|
||||
}
|
||||
|
||||
for (uint32 i = 0; i < count; ++i)
|
||||
{
|
||||
int32 parent = m_nodes[i].parent;
|
||||
if (parent < 0)
|
||||
{
|
||||
pDestination[i] = absolutes[i];
|
||||
continue;
|
||||
}
|
||||
|
||||
pDestination[i].t = (absolutes[i].t - absolutes[parent].t) * absolutes[parent].q;
|
||||
pDestination[i].q = absolutes[parent].q.GetInverted() * absolutes[i].q;
|
||||
}
|
||||
}
|
||||
|
||||
bool CHierarchy::SerializeTo(XmlNodeRef& node)
|
||||
{
|
||||
XmlNodeRef hierarchy = node->newChild("Hierarchy");
|
||||
|
||||
uint32 nodeCount = uint32(m_nodes.size());
|
||||
std::vector<IXmlNode*> nodes(nodeCount);
|
||||
for (uint32 i = 0; i < nodeCount; ++i)
|
||||
{
|
||||
XmlNodeRef parent = hierarchy;
|
||||
if (m_nodes[i].parent > -1)
|
||||
{
|
||||
parent = nodes[m_nodes[i].parent];
|
||||
}
|
||||
|
||||
nodes[i] = parent->newChild("Node");
|
||||
nodes[i]->setAttr("name", m_nodes[i].name);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef CRYINCLUDE_EDITOR_ANIMATION_SKELETONHIERARCHY_H
|
||||
#define CRYINCLUDE_EDITOR_ANIMATION_SKELETONHIERARCHY_H
|
||||
#pragma once
|
||||
|
||||
namespace Skeleton {
|
||||
class CHierarchy
|
||||
: public _reference_target_t
|
||||
{
|
||||
public:
|
||||
struct SNode
|
||||
{
|
||||
string name;
|
||||
QuatT pose;
|
||||
|
||||
int32 parent;
|
||||
|
||||
/* TODO: Implement
|
||||
uint32 childrenIndex;
|
||||
uint32 childrenCount;
|
||||
*/
|
||||
};
|
||||
|
||||
public:
|
||||
CHierarchy();
|
||||
~CHierarchy();
|
||||
|
||||
public:
|
||||
uint32 AddNode(const char* name, const QuatT& pose, int32 parent = -1);
|
||||
uint32 GetNodeCount() const { return uint32(m_nodes.size()); }
|
||||
SNode* GetNode(uint32 index) { return &m_nodes[index]; }
|
||||
const SNode* GetNode(uint32 index) const { return &m_nodes[index]; }
|
||||
int32 FindNodeIndexByName(const char* name) const;
|
||||
const SNode* FindNode(const char* name) const;
|
||||
void ClearNodes() { m_nodes.clear(); }
|
||||
|
||||
void CreateFrom(IDefaultSkeleton* rIDefaultSkeleton);
|
||||
void ValidateReferences();
|
||||
|
||||
void AbsoluteToRelative(const QuatT* pSource, QuatT* pDestination);
|
||||
|
||||
bool SerializeTo(XmlNodeRef& node);
|
||||
|
||||
private:
|
||||
std::vector<SNode> m_nodes;
|
||||
};
|
||||
} // namespace Skeleton
|
||||
|
||||
#endif // CRYINCLUDE_EDITOR_ANIMATION_SKELETONHIERARCHY_H
|
||||
@@ -1,368 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "EditorDefs.h"
|
||||
|
||||
#include "SkeletonMapper.h"
|
||||
|
||||
using namespace Skeleton;
|
||||
|
||||
/*
|
||||
|
||||
CMapper
|
||||
|
||||
*/
|
||||
|
||||
CMapper::CMapper()
|
||||
{
|
||||
}
|
||||
|
||||
CMapper::~CMapper()
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
void CMapper::CreateFromHierarchy()
|
||||
{
|
||||
m_nodes.clear();
|
||||
|
||||
uint32 nodeCount = m_hierarchy.GetNodeCount();
|
||||
m_nodes.resize(nodeCount);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
uint32 CMapper::CreateLocation(const char* name)
|
||||
{
|
||||
int32 index = FindLocation(name);
|
||||
if (index < 1)
|
||||
{
|
||||
CMapperLocation* pLocation = new CMapperLocation();
|
||||
pLocation->SetName(name);
|
||||
m_locations.push_back(pLocation);
|
||||
}
|
||||
return uint32(m_locations.size() - 1);
|
||||
}
|
||||
|
||||
void CMapper::ClearLocations()
|
||||
{
|
||||
uint32 count = uint32(m_nodes.size());
|
||||
for (uint32 i = 0; i < count; ++i)
|
||||
{
|
||||
m_nodes[i].position = nullptr;
|
||||
m_nodes[i].orientation = nullptr;
|
||||
}
|
||||
|
||||
m_locations.clear();
|
||||
}
|
||||
|
||||
int32 CMapper::FindLocation(const char* name) const
|
||||
{
|
||||
uint32 count = uint32(m_locations.size());
|
||||
for (uint32 i = 0; i < count; ++i)
|
||||
{
|
||||
if (::_stricmp(m_locations[i]->GetName(), name))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
return int32(i);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void CMapper::SetLocation(CMapperLocation& location)
|
||||
{
|
||||
int32 index = FindLocation(location.GetName());
|
||||
if (index < 0)
|
||||
{
|
||||
m_locations.push_back(&location);
|
||||
return;
|
||||
}
|
||||
|
||||
m_locations[index] = &location;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
bool CMapper::CreateLocationsHierarchy(uint32 index, CHierarchy& hierarchy, int32 hierarchyParent)
|
||||
{
|
||||
if (NodeHasLocation(index))
|
||||
{
|
||||
const CHierarchy::SNode* pNode = m_hierarchy.GetNode(index);
|
||||
uint32 nodeIndex = hierarchy.AddNode(pNode->name, pNode->pose, hierarchyParent);
|
||||
hierarchyParent = uint32(nodeIndex);
|
||||
}
|
||||
|
||||
std::vector<uint32> children;
|
||||
GetChildrenIndices(index, children);
|
||||
uint32 childCount = uint32(children.size());
|
||||
for (uint32 i = 0; i < childCount; ++i)
|
||||
{
|
||||
CreateLocationsHierarchy(children[i], hierarchy, hierarchyParent);
|
||||
}
|
||||
|
||||
return hierarchy.GetNodeCount() != 0;
|
||||
}
|
||||
|
||||
bool CMapper::CreateLocationsHierarchy(CHierarchy& hierarchy)
|
||||
{
|
||||
hierarchy.ClearNodes();
|
||||
if (!CreateLocationsHierarchy(0, hierarchy, -1))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
hierarchy.ValidateReferences();
|
||||
return true;
|
||||
}
|
||||
|
||||
void CMapper::Map(QuatT* pResult)
|
||||
{
|
||||
uint32 outputCount = m_hierarchy.GetNodeCount();
|
||||
std::vector<Quat> absolutes(outputCount);
|
||||
for (uint32 i = 0; i < outputCount; ++i)
|
||||
{
|
||||
pResult[i].SetIdentity();
|
||||
absolutes[i].SetIdentity();
|
||||
|
||||
CHierarchy::SNode* pNode = m_hierarchy.GetNode(i);
|
||||
if (!pNode)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
CHierarchy::SNode* pParent = pNode->parent < 0 ?
|
||||
nullptr : m_hierarchy.GetNode(pNode->parent);
|
||||
if (pParent)
|
||||
{
|
||||
pResult[i].t =
|
||||
(pNode->pose.t - pParent->pose.t) * pParent->pose.q;
|
||||
}
|
||||
|
||||
if (m_nodes[i].position)
|
||||
{
|
||||
pResult[i].t = m_nodes[i].position->Compute().t;
|
||||
}
|
||||
|
||||
if (m_nodes[i].orientation)
|
||||
{
|
||||
absolutes[i] = m_nodes[i].orientation->Compute().q;
|
||||
}
|
||||
else if (pParent)
|
||||
{
|
||||
Quat relative = pParent->pose.q.GetInverted() * pNode->pose.q;
|
||||
absolutes[i] = absolutes[pNode->parent] * relative;
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32 i = 0; i < outputCount; ++i)
|
||||
{
|
||||
CHierarchy::SNode* pNode = m_hierarchy.GetNode(i);
|
||||
if (!pNode)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
CHierarchy::SNode* pParent = pNode->parent < 0 ?
|
||||
nullptr : m_hierarchy.GetNode(pNode->parent);
|
||||
if (!pParent)
|
||||
{
|
||||
pResult[i].q = absolutes[i];
|
||||
continue;
|
||||
}
|
||||
|
||||
pResult[i].q = absolutes[i];
|
||||
if (!m_nodes[i].position)
|
||||
{
|
||||
pResult[i].t = pResult[pNode->parent].t +
|
||||
pResult[i].t * absolutes[pNode->parent].GetInverted();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
bool CMapper::NodeHasLocation(uint32 index)
|
||||
{
|
||||
if (CMapperOperator* pOperator = m_nodes[index].position)
|
||||
{
|
||||
if (pOperator->IsOfClass("Location"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (pOperator->HasLinksOfClass("Location"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (CMapperOperator* pOperator = m_nodes[index].orientation)
|
||||
{
|
||||
if (pOperator->IsOfClass("Location"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (pOperator->HasLinksOfClass("Location"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CMapper::GetChildrenIndices(uint32 parent, std::vector<uint32>& children)
|
||||
{
|
||||
uint32 nodeCount = m_hierarchy.GetNodeCount();
|
||||
for (uint32 i = 0; i < nodeCount; ++i)
|
||||
{
|
||||
if (m_hierarchy.GetNode(i)->parent != parent)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
children.push_back(i);
|
||||
}
|
||||
}
|
||||
|
||||
bool CMapper::ChildrenHaveLocation(uint32 index)
|
||||
{
|
||||
std::vector<uint32> children;
|
||||
GetChildrenIndices(index, children);
|
||||
|
||||
uint32 childrenCount = uint32(children.size());
|
||||
for (uint32 i = 0; i < childrenCount; ++i)
|
||||
{
|
||||
if (ChildrenHaveLocation(children[i]))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CMapper::NodeOrChildrenHaveLocation(uint32 index)
|
||||
{
|
||||
if (NodeHasLocation(index))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<uint32> children;
|
||||
GetChildrenIndices(index, children);
|
||||
|
||||
uint32 childrenCount = uint32(children.size());
|
||||
for (uint32 i = 0; i < childrenCount; ++i)
|
||||
{
|
||||
if (NodeOrChildrenHaveLocation(children[i]))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CMapper::SerializeTo(XmlNodeRef& node)
|
||||
{
|
||||
XmlNodeRef hierarchy = node->newChild("Hierarchy");
|
||||
|
||||
uint32 nodeCount = GetNodeCount();
|
||||
std::vector<IXmlNode*> nodes(nodeCount);
|
||||
for (uint32 i = 0; i < nodeCount; ++i)
|
||||
{
|
||||
if (!NodeOrChildrenHaveLocation(i))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
CHierarchy::SNode* pNode = m_hierarchy.GetNode(i);
|
||||
if (!pNode)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
XmlNodeRef xmlParent = hierarchy;
|
||||
int32 parent = pNode->parent;
|
||||
if (parent > -1)
|
||||
{
|
||||
xmlParent = nodes[parent];
|
||||
}
|
||||
|
||||
nodes[i] = xmlParent->newChild("Node");
|
||||
nodes[i]->setAttr("name", pNode->name);
|
||||
|
||||
if (CMapperOperator* pOperator = m_nodes[i].position)
|
||||
{
|
||||
XmlNodeRef position = nodes[i]->newChild("Position");
|
||||
XmlNodeRef child = position->newChild("Operator");
|
||||
if (!pOperator->SerializeWithLinksTo(child))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (CMapperOperator* pOperator = m_nodes[i].orientation)
|
||||
{
|
||||
XmlNodeRef orientation = nodes[i]->newChild("Orientation");
|
||||
XmlNodeRef child = orientation->newChild("Operator");
|
||||
if (!pOperator->SerializeWithLinksTo(child))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMapper::SerializeFrom(XmlNodeRef& node, int32 parent)
|
||||
{
|
||||
int childCount = uint32(node->getChildCount());
|
||||
for (int i = 0; i < childCount; ++i)
|
||||
{
|
||||
XmlNodeRef child = node->getChild(i);
|
||||
if (::_stricmp(child->getTag(), "Node"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
uint32 index = m_hierarchy.AddNode(child->getAttr("name"), QuatT(IDENTITY), parent);
|
||||
if (!SerializeFrom(child, int32(index)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMapper::SerializeFrom(XmlNodeRef& node)
|
||||
{
|
||||
XmlNodeRef hierarchy = node->findChild("Hierarchy");
|
||||
if (!hierarchy)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
m_hierarchy.ClearNodes();
|
||||
|
||||
if (!SerializeFrom(hierarchy, -1))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
m_nodes.resize(m_hierarchy.GetNodeCount());
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef CRYINCLUDE_EDITOR_ANIMATION_SKELETONMAPPER_H
|
||||
#define CRYINCLUDE_EDITOR_ANIMATION_SKELETONMAPPER_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "SkeletonHierarchy.h"
|
||||
#include "SkeletonMapperOperator.h"
|
||||
|
||||
namespace Skeleton {
|
||||
class CMapper
|
||||
{
|
||||
public:
|
||||
struct SNode
|
||||
{
|
||||
_smart_ptr<CMapperOperator> position;
|
||||
_smart_ptr<CMapperOperator> orientation;
|
||||
};
|
||||
|
||||
public:
|
||||
CMapper();
|
||||
~CMapper();
|
||||
|
||||
public:
|
||||
CHierarchy& GetHierarchy() { return m_hierarchy; }
|
||||
void CreateFromHierarchy();
|
||||
|
||||
uint32 GetNodeCount() const { return uint32(m_nodes.size()); }
|
||||
SNode* GetNode(uint32 index) { return &m_nodes[index]; }
|
||||
const SNode* GetNode(uint32 index) const { return &m_nodes[index]; }
|
||||
|
||||
uint32 CreateLocation(const char* name);
|
||||
void ClearLocations();
|
||||
int32 FindLocation(const char* name) const;
|
||||
|
||||
uint32 GetLocationCount() const { return uint32(m_locations.size()); }
|
||||
void SetLocation(CMapperLocation& location);
|
||||
CMapperLocation* GetLocation(uint32 index) { return m_locations[index]; }
|
||||
const CMapperLocation* GetLocation(uint32 index) const { return m_locations[index]; }
|
||||
|
||||
bool CreateLocationsHierarchy(CHierarchy& hierarchy);
|
||||
|
||||
void Map(QuatT* pResult);
|
||||
|
||||
bool SerializeTo(XmlNodeRef& node);
|
||||
bool SerializeFrom(XmlNodeRef& node);
|
||||
|
||||
private:
|
||||
bool NodeHasLocation(uint32 index);
|
||||
bool ChildrenHaveLocation(uint32 index);
|
||||
bool NodeOrChildrenHaveLocation(uint32 index);
|
||||
|
||||
bool SerializeFrom(XmlNodeRef& node, int32 parent);
|
||||
|
||||
bool CreateLocationsHierarchy(uint32 index, CHierarchy& hierarchy, int32 hierarchyParent = -1);
|
||||
|
||||
// TEMP
|
||||
void GetChildrenIndices(uint32 parent, std::vector<uint32>& children);
|
||||
|
||||
private:
|
||||
CHierarchy m_hierarchy;
|
||||
std::vector<_smart_ptr<CMapperLocation> > m_locations;
|
||||
|
||||
std::vector<SNode> m_nodes;
|
||||
};
|
||||
} // namespace Skeleton
|
||||
|
||||
#endif // CRYINCLUDE_EDITOR_ANIMATION_SKELETONMAPPER_H
|
||||
@@ -1,284 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "EditorDefs.h"
|
||||
|
||||
#include "SkeletonMapperOperator.h"
|
||||
|
||||
using namespace Skeleton;
|
||||
|
||||
/*
|
||||
|
||||
CMapperOperatorDesc
|
||||
|
||||
*/
|
||||
|
||||
std::vector<CMapperOperatorDesc*> CMapperOperatorDesc::s_descs;
|
||||
|
||||
//
|
||||
|
||||
CMapperOperatorDesc::CMapperOperatorDesc(const char* name)
|
||||
{
|
||||
s_descs.push_back(this);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
CMapperOperator
|
||||
|
||||
*/
|
||||
|
||||
CMapperOperator::CMapperOperator(const char* className, uint32 positionCount, uint32 orientationCount)
|
||||
{
|
||||
m_className = className;
|
||||
m_position.resize(positionCount, nullptr);
|
||||
m_orientation.resize(orientationCount, nullptr);
|
||||
}
|
||||
|
||||
CMapperOperator::~CMapperOperator()
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
bool CMapperOperator::IsOfClass(const char* className)
|
||||
{
|
||||
if (::_stricmp(m_className, className))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32 CMapperOperator::HasLinksOfClass(const char* className)
|
||||
{
|
||||
uint32 count = 0;
|
||||
|
||||
uint32 positionCount = m_position.size();
|
||||
for (uint32 i = 0; i < positionCount; ++i)
|
||||
{
|
||||
CMapperOperator* pOperator = m_position[i];
|
||||
if (!pOperator)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pOperator->IsOfClass(className))
|
||||
{
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 orientationCount = m_orientation.size();
|
||||
for (uint32 i = 0; i < orientationCount; ++i)
|
||||
{
|
||||
CMapperOperator* pOperator = m_orientation[i];
|
||||
if (!pOperator)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pOperator->IsOfClass(className))
|
||||
{
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
bool CMapperOperator::SerializeTo(XmlNodeRef& node)
|
||||
{
|
||||
node->setAttr("class", m_className);
|
||||
|
||||
uint32 parameterCount = uint32(m_parameters.size());
|
||||
for (uint32 i = 0; i < parameterCount; ++i)
|
||||
{
|
||||
m_parameters[i]->Serialize(node, false);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMapperOperator::SerializeFrom(XmlNodeRef& node)
|
||||
{
|
||||
uint32 parameterCount = uint32(m_parameters.size());
|
||||
for (uint32 i = 0; i < parameterCount; ++i)
|
||||
{
|
||||
m_parameters[i]->Serialize(node, true);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMapperOperator::SerializeWithLinksTo(XmlNodeRef& node)
|
||||
{
|
||||
if (!SerializeTo(node))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 positionCount = uint32(m_position.size());
|
||||
for (uint32 i = 0; i < positionCount; ++i)
|
||||
{
|
||||
CMapperOperator* pOperator = m_position[i];
|
||||
if (!pOperator)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
XmlNodeRef position = node->newChild("Position");
|
||||
position->setAttr("index", i);
|
||||
|
||||
XmlNodeRef child = position->newChild("Operator");
|
||||
if (!pOperator->SerializeWithLinksTo(child))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 orientationCount = uint32(m_orientation.size());
|
||||
for (uint32 i = 0; i < orientationCount; ++i)
|
||||
{
|
||||
CMapperOperator* pOperator = m_orientation[i];
|
||||
if (!pOperator)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
XmlNodeRef orientation = node->newChild("Orientation");
|
||||
orientation->setAttr("index", i);
|
||||
|
||||
XmlNodeRef child = orientation->newChild("Operator");
|
||||
if (!pOperator->SerializeWithLinksTo(child))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMapperOperator::SerializeWithLinksFrom(XmlNodeRef& node)
|
||||
{
|
||||
if (!SerializeFrom(node))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
/*
|
||||
|
||||
CMapperOperator_Transform
|
||||
|
||||
*/
|
||||
|
||||
class CMapperOperator_Transform
|
||||
: public CMapperOperator
|
||||
{
|
||||
public:
|
||||
CMapperOperator_Transform()
|
||||
: CMapperOperator("Transform", 1, 1)
|
||||
{
|
||||
m_pAngles = new CVariable<Vec3>();
|
||||
m_pAngles->SetName("rotation");
|
||||
m_pAngles->Set(Vec3(0.0f, 0.0f, 0.0f));
|
||||
m_pAngles->SetLimits(-180.0f, 180.0f);
|
||||
AddParameter(*m_pAngles);
|
||||
|
||||
m_pVector = new CVariable<Vec3>();
|
||||
m_pVector->SetName("vector");
|
||||
m_pVector->Set(Vec3(0.0f, 0.0f, 0.0f));
|
||||
AddParameter(*m_pVector);
|
||||
|
||||
m_pScale = new CVariable<Vec3>();
|
||||
m_pScale->SetName("scale");
|
||||
m_pScale->Set(Vec3(1.0f, 1.0f, 1.0f));
|
||||
AddParameter(*m_pScale);
|
||||
}
|
||||
|
||||
// CMapperOperator
|
||||
public:
|
||||
virtual QuatT CMapperOperator_Transform::Compute()
|
||||
{
|
||||
QuatT result(IDENTITY);
|
||||
m_pVector->Get(result.t);
|
||||
|
||||
Vec3 scale;
|
||||
m_pScale->Get(scale);
|
||||
|
||||
Vec3 angles;
|
||||
m_pAngles->Get(angles);
|
||||
|
||||
result.q = Quat::CreateRotationXYZ(
|
||||
Ang3(DEG2RAD(angles.x), DEG2RAD(angles.y), DEG2RAD(angles.z)));
|
||||
|
||||
if (CMapperOperator* pOperator = GetPosition(0))
|
||||
{
|
||||
result.t = pOperator->Compute().t.CompMul(scale) + result.t;
|
||||
}
|
||||
if (CMapperOperator* pOperator = GetOrientation(0))
|
||||
{
|
||||
result.q = pOperator->Compute().q * result.q;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
CVariable<Vec3>* m_pVector;
|
||||
CVariable<Vec3>* m_pAngles;
|
||||
CVariable<Vec3>* m_pScale;
|
||||
};
|
||||
|
||||
SkeletonMapperOperatorRegister(Transform, CMapperOperator_Transform)
|
||||
|
||||
class CMapperOperator_PositionsToOrientation
|
||||
: public CMapperOperator
|
||||
{
|
||||
public:
|
||||
CMapperOperator_PositionsToOrientation()
|
||||
: CMapperOperator("PositionsToOrientation", 3, 0)
|
||||
{
|
||||
}
|
||||
|
||||
// CMapperOperator
|
||||
public:
|
||||
virtual QuatT Compute()
|
||||
{
|
||||
CMapperOperator* pOperator0 = GetPosition(0);
|
||||
CMapperOperator* pOperator1 = GetPosition(1);
|
||||
CMapperOperator* pOperator2 = GetPosition(2);
|
||||
if (!pOperator0 || !pOperator1 || !pOperator2)
|
||||
{
|
||||
return QuatT(IDENTITY);
|
||||
}
|
||||
|
||||
Vec3 p0 = pOperator0->Compute().t;
|
||||
Vec3 p1 = pOperator1->Compute().t;
|
||||
Vec3 p2 = pOperator2->Compute().t;
|
||||
|
||||
Vec3 m = (p1 + p2) * 0.5f;
|
||||
Vec3 y = (m - p0).GetNormalized();
|
||||
Vec3 z = (p1 - p2).GetNormalized();
|
||||
Vec3 x = y % z;
|
||||
z = x % y;
|
||||
|
||||
Matrix33 m33;
|
||||
m33.SetFromVectors(x, y, z);
|
||||
QuatT result(IDENTITY);
|
||||
result.q = Quat(m33);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
SkeletonMapperOperatorRegister(PositionsToOrientation, CMapperOperator_PositionsToOrientation)
|
||||
@@ -1,164 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef CRYINCLUDE_EDITOR_ANIMATION_SKELETONMAPPEROPERATOR_H
|
||||
#define CRYINCLUDE_EDITOR_ANIMATION_SKELETONMAPPEROPERATOR_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "../Util/Variable.h"
|
||||
|
||||
#undef GetClassName
|
||||
|
||||
#define SkeletonMapperOperatorRegister(name, className) \
|
||||
class CMapperOperatorDesc_##name \
|
||||
: public CMapperOperatorDesc \
|
||||
{ \
|
||||
public: \
|
||||
CMapperOperatorDesc_##name() \
|
||||
: CMapperOperatorDesc(#name) { } \
|
||||
protected: \
|
||||
virtual const char* GetName() { return #name; } \
|
||||
virtual CMapperOperator* Create() { return new className(); } \
|
||||
} mapperOperatorDesc__##name;
|
||||
|
||||
namespace Skeleton {
|
||||
class CMapperOperator;
|
||||
|
||||
class CMapperOperatorDesc
|
||||
{
|
||||
public:
|
||||
static uint32 GetCount() { return uint32(s_descs.size()); }
|
||||
static const char* GetName(uint32 index) { return s_descs[index]->GetName(); }
|
||||
static CMapperOperator* Create(uint32 index) { return s_descs[index]->Create(); }
|
||||
|
||||
private:
|
||||
static std::vector<CMapperOperatorDesc*> s_descs;
|
||||
|
||||
public:
|
||||
CMapperOperatorDesc(const char* name);
|
||||
|
||||
protected:
|
||||
virtual const char* GetName() = 0;
|
||||
virtual CMapperOperator* Create() = 0;
|
||||
};
|
||||
|
||||
class CMapperOperator
|
||||
: public _reference_target_t
|
||||
{
|
||||
protected:
|
||||
CMapperOperator(const char* className, uint32 positionCount, uint32 orientationCount);
|
||||
~CMapperOperator();
|
||||
|
||||
public:
|
||||
const char* GetClassName() { return m_className; }
|
||||
|
||||
uint32 GetPositionCount() const { return uint32(m_position.size()); }
|
||||
void SetPosition(uint32 index, CMapperOperator* pOperator) { m_position[index] = pOperator; }
|
||||
CMapperOperator* GetPosition(uint32 index) { return m_position[index]; }
|
||||
|
||||
uint32 GetOrientationCount() const { return uint32(m_orientation.size()); }
|
||||
void SetOrientation(uint32 index, CMapperOperator* pOperator) { m_orientation[index] = pOperator; }
|
||||
CMapperOperator* GetOrientation(uint32 index) { return m_orientation[index]; }
|
||||
|
||||
uint32 GetParameterCount() { return uint32(m_parameters.size()); }
|
||||
IVariable* GetParameter(uint32 index) { return m_parameters[index]; }
|
||||
|
||||
bool IsOfClass(const char* className);
|
||||
uint32 HasLinksOfClass(const char* className);
|
||||
|
||||
bool SerializeTo(XmlNodeRef& node);
|
||||
bool SerializeFrom(XmlNodeRef& node);
|
||||
|
||||
bool SerializeWithLinksTo(XmlNodeRef& node);
|
||||
bool SerializeWithLinksFrom(XmlNodeRef& node);
|
||||
|
||||
protected:
|
||||
void AddParameter(IVariable& variable) { m_parameters.push_back(&variable); }
|
||||
|
||||
public:
|
||||
virtual QuatT Compute() = 0;
|
||||
|
||||
private:
|
||||
const char* m_className;
|
||||
std::vector<_smart_ptr<CMapperOperator> > m_position;
|
||||
std::vector<_smart_ptr<CMapperOperator> > m_orientation;
|
||||
|
||||
std::vector<IVariablePtr> m_parameters;
|
||||
};
|
||||
|
||||
class CMapperLocation
|
||||
: public CMapperOperator
|
||||
{
|
||||
public:
|
||||
CMapperLocation()
|
||||
: CMapperOperator("Location", 0, 0)
|
||||
{
|
||||
m_pName = new CVariable<CString>();
|
||||
m_pName->SetName("name");
|
||||
m_pName->SetFlags(m_pName->GetFlags() | IVariable::UI_INVISIBLE);
|
||||
AddParameter(*m_pName);
|
||||
|
||||
m_pAxis = new CVariable<Vec3>();
|
||||
m_pAxis->SetName("axis");
|
||||
m_pAxis->SetLimits(-3.0f, +3.0f);
|
||||
m_pAxis->Set(Vec3(1.0f, 2.0f, 3.0f));
|
||||
AddParameter(*m_pAxis);
|
||||
|
||||
m_location = QuatT(IDENTITY);
|
||||
}
|
||||
|
||||
public:
|
||||
void SetName(const char* name) { m_pName->Set(name); }
|
||||
CString GetName() const { CString s; m_pName->Get(s); return s; }
|
||||
|
||||
void SetLocation(const QuatT& location) { m_location = location; }
|
||||
const QuatT& GetLocation() const { return m_location; }
|
||||
|
||||
// CMapperOperator
|
||||
public:
|
||||
virtual QuatT Compute()
|
||||
{
|
||||
Vec3 axis;
|
||||
m_pAxis->Get(axis);
|
||||
|
||||
uint32 x = fabs_tpl(axis.x);
|
||||
uint32 y = fabs_tpl(axis.y);
|
||||
uint32 z = fabs_tpl(axis.z);
|
||||
if (x < 1 || y < 1 || z < 1 ||
|
||||
x > 3 || y > 3 || y > 3 ||
|
||||
x == y || x == z || y == z)
|
||||
{
|
||||
return QuatT(IDENTITY);
|
||||
}
|
||||
|
||||
Matrix33 matrix;
|
||||
matrix.SetFromVectors(
|
||||
m_location.q.GetColumn(x - 1) * f32(::sgn(axis.x)),
|
||||
m_location.q.GetColumn(y - 1) * f32(::sgn(axis.y)),
|
||||
m_location.q.GetColumn(z - 1) * f32(::sgn(axis.z)));
|
||||
if (!matrix.IsOrthonormalRH(0.01f))
|
||||
{
|
||||
return QuatT(IDENTITY);
|
||||
}
|
||||
|
||||
QuatT result = m_location;
|
||||
result.q = Quat(matrix);
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
CVariable<CString>* m_pName;
|
||||
CVariable<Vec3>* m_pAxis;
|
||||
|
||||
QuatT m_location;
|
||||
};
|
||||
} // namespace Skeleton
|
||||
|
||||
#endif // CRYINCLUDE_EDITOR_ANIMATION_SKELETONMAPPEROPERATOR_H
|
||||
@@ -258,9 +258,8 @@ bool CBaseLibrary::SaveLibrary(const char* name, bool saveEmptyLibrary)
|
||||
}
|
||||
if (!bRes)
|
||||
{
|
||||
string strMessage;
|
||||
QByteArray filenameUtf8 = fileName.toUtf8();
|
||||
strMessage.Format("The file %s is read-only and the save of the library couldn't be performed. Try to remove the \"read-only\" flag or check-out the file and then try again.", filenameUtf8.data());
|
||||
AZStd::string strMessage = AZStd::string::format("The file %s is read-only and the save of the library couldn't be performed. Try to remove the \"read-only\" flag or check-out the file and then try again.", filenameUtf8.data());
|
||||
CryMessageBox(strMessage.c_str(), "Saving Error", MB_OK | MB_ICONWARNING);
|
||||
}
|
||||
return bRes;
|
||||
|
||||
@@ -526,7 +526,7 @@ void CBaseLibraryManager::Serialize(XmlNodeRef& node, bool bLoading)
|
||||
QString CBaseLibraryManager::MakeUniqueItemName(const QString& srcName, const QString& libName)
|
||||
{
|
||||
// unlikely we'll ever encounter more than 16
|
||||
std::vector<string> possibleDuplicates;
|
||||
std::vector<AZStd::string> possibleDuplicates;
|
||||
possibleDuplicates.reserve(16);
|
||||
|
||||
// search for strings in the database that might have a similar name (ignore case)
|
||||
@@ -550,7 +550,7 @@ QString CBaseLibraryManager::MakeUniqueItemName(const QString& srcName, const QS
|
||||
const QString& name = pItem->GetName();
|
||||
if (name.startsWith(srcName, Qt::CaseInsensitive))
|
||||
{
|
||||
possibleDuplicates.push_back(string(name.toUtf8().data()));
|
||||
possibleDuplicates.push_back(AZStd::string(name.toUtf8().data()));
|
||||
}
|
||||
}
|
||||
pEnum->Release();
|
||||
@@ -560,7 +560,7 @@ QString CBaseLibraryManager::MakeUniqueItemName(const QString& srcName, const QS
|
||||
return srcName;
|
||||
}
|
||||
|
||||
std::sort(possibleDuplicates.begin(), possibleDuplicates.end(), [](const string& strOne, const string& strTwo)
|
||||
std::sort(possibleDuplicates.begin(), possibleDuplicates.end(), [](const AZStd::string& strOne, const AZStd::string& strTwo)
|
||||
{
|
||||
// I can assume size sorting since if the length is different, either one of the two strings doesn't
|
||||
// closely match the string we are trying to duplicate, or it's a bigger number (X1 vs X10)
|
||||
|
||||
@@ -79,9 +79,9 @@ CEditorCommandManager::~CEditorCommandManager()
|
||||
m_uiCommands.clear();
|
||||
}
|
||||
|
||||
string CEditorCommandManager::GetFullCommandName(const string& module, const string& name)
|
||||
AZStd::string CEditorCommandManager::GetFullCommandName(const AZStd::string& module, const AZStd::string& name)
|
||||
{
|
||||
string fullName = module;
|
||||
AZStd::string fullName = module;
|
||||
fullName += ".";
|
||||
fullName += name;
|
||||
return fullName;
|
||||
@@ -91,10 +91,10 @@ bool CEditorCommandManager::AddCommand(CCommand* pCommand, TPfnDeleter deleter)
|
||||
{
|
||||
assert(pCommand);
|
||||
|
||||
string module = pCommand->GetModule();
|
||||
string name = pCommand->GetName();
|
||||
AZStd::string module = pCommand->GetModule();
|
||||
AZStd::string name = pCommand->GetName();
|
||||
|
||||
if (IsRegistered(module, name) && m_bWarnDuplicate)
|
||||
if (IsRegistered(module.c_str(), name.c_str()) && m_bWarnDuplicate)
|
||||
{
|
||||
QString errMsg;
|
||||
|
||||
@@ -118,7 +118,7 @@ bool CEditorCommandManager::AddCommand(CCommand* pCommand, TPfnDeleter deleter)
|
||||
|
||||
bool CEditorCommandManager::UnregisterCommand(const char* module, const char* name)
|
||||
{
|
||||
string fullName = GetFullCommandName(module, name);
|
||||
AZStd::string fullName = GetFullCommandName(module, name);
|
||||
CommandTable::iterator itr = m_commands.find(fullName);
|
||||
|
||||
if (itr != m_commands.end())
|
||||
@@ -154,7 +154,7 @@ bool CEditorCommandManager::RegisterUICommand(
|
||||
return false;
|
||||
}
|
||||
|
||||
return AttachUIInfo(GetFullCommandName(module, name), uiInfo);
|
||||
return AttachUIInfo(GetFullCommandName(module, name).c_str(), uiInfo);
|
||||
}
|
||||
|
||||
bool CEditorCommandManager::AttachUIInfo(const char* fullCmdName, const CCommand0::SUIInfo& uiInfo)
|
||||
@@ -190,14 +190,14 @@ bool CEditorCommandManager::AttachUIInfo(const char* fullCmdName, const CCommand
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CEditorCommandManager::GetUIInfo(const string& module, const string& name, CCommand0::SUIInfo& uiInfo) const
|
||||
bool CEditorCommandManager::GetUIInfo(const AZStd::string& module, const AZStd::string& name, CCommand0::SUIInfo& uiInfo) const
|
||||
{
|
||||
string fullName = GetFullCommandName(module, name);
|
||||
AZStd::string fullName = GetFullCommandName(module, name);
|
||||
|
||||
return GetUIInfo(fullName, uiInfo);
|
||||
}
|
||||
|
||||
bool CEditorCommandManager::GetUIInfo(const string& fullCmdName, CCommand0::SUIInfo& uiInfo) const
|
||||
bool CEditorCommandManager::GetUIInfo(const AZStd::string& fullCmdName, CCommand0::SUIInfo& uiInfo) const
|
||||
{
|
||||
CommandTable::const_iterator iter = m_commands.find(fullCmdName);
|
||||
|
||||
@@ -223,9 +223,9 @@ int CEditorCommandManager::GenNewCommandId()
|
||||
return uniqueId++;
|
||||
}
|
||||
|
||||
QString CEditorCommandManager::Execute(const string& module, const string& name, const CCommand::CArgs& args)
|
||||
QString CEditorCommandManager::Execute(const AZStd::string& module, const AZStd::string& name, const CCommand::CArgs& args)
|
||||
{
|
||||
string fullName = GetFullCommandName(module, name);
|
||||
AZStd::string fullName = GetFullCommandName(module, name);
|
||||
CommandTable::iterator iter = m_commands.find(fullName);
|
||||
|
||||
if (iter != m_commands.end())
|
||||
@@ -245,18 +245,18 @@ QString CEditorCommandManager::Execute(const string& module, const string& name,
|
||||
return "";
|
||||
}
|
||||
|
||||
QString CEditorCommandManager::Execute(const string& cmdLine)
|
||||
QString CEditorCommandManager::Execute(const AZStd::string& cmdLine)
|
||||
{
|
||||
string cmdTxt, argsTxt;
|
||||
AZStd::string cmdTxt, argsTxt;
|
||||
size_t argStart = cmdLine.find_first_of(' ');
|
||||
|
||||
cmdTxt = cmdLine.substr(0, argStart);
|
||||
argsTxt = "";
|
||||
|
||||
if (argStart != string::npos)
|
||||
if (argStart != AZStd::string::npos)
|
||||
{
|
||||
argsTxt = cmdLine.substr(argStart + 1);
|
||||
argsTxt.Trim();
|
||||
AZ::StringFunc::TrimWhiteSpace(argsTxt, true, true);
|
||||
}
|
||||
|
||||
CommandTable::iterator itr = m_commands.find(cmdTxt);
|
||||
@@ -301,7 +301,7 @@ void CEditorCommandManager::Execute(int commandId)
|
||||
}
|
||||
}
|
||||
|
||||
void CEditorCommandManager::GetCommandList(std::vector<string>& cmds) const
|
||||
void CEditorCommandManager::GetCommandList(std::vector<AZStd::string>& cmds) const
|
||||
{
|
||||
cmds.clear();
|
||||
cmds.reserve(m_commands.size());
|
||||
@@ -315,9 +315,9 @@ void CEditorCommandManager::GetCommandList(std::vector<string>& cmds) const
|
||||
std::sort(cmds.begin(), cmds.end());
|
||||
}
|
||||
|
||||
string CEditorCommandManager::AutoComplete(const string& substr) const
|
||||
AZStd::string CEditorCommandManager::AutoComplete(const AZStd::string& substr) const
|
||||
{
|
||||
std::vector<string> cmds;
|
||||
std::vector<AZStd::string> cmds;
|
||||
GetCommandList(cmds);
|
||||
|
||||
// If substring is empty return first command.
|
||||
@@ -358,7 +358,7 @@ string CEditorCommandManager::AutoComplete(const string& substr) const
|
||||
|
||||
bool CEditorCommandManager::IsRegistered(const char* module, const char* name) const
|
||||
{
|
||||
string fullName = GetFullCommandName(module, name);
|
||||
AZStd::string fullName = GetFullCommandName(module, name);
|
||||
CommandTable::const_iterator iter = m_commands.find(fullName);
|
||||
|
||||
if (iter != m_commands.end())
|
||||
@@ -373,7 +373,7 @@ bool CEditorCommandManager::IsRegistered(const char* module, const char* name) c
|
||||
|
||||
bool CEditorCommandManager::IsRegistered(const char* cmdLine_) const
|
||||
{
|
||||
string cmdTxt, argsTxt, cmdLine(cmdLine_);
|
||||
AZStd::string cmdTxt, argsTxt, cmdLine(cmdLine_);
|
||||
size_t argStart = cmdLine.find_first_of(' ');
|
||||
cmdTxt = cmdLine.substr(0, argStart);
|
||||
CommandTable::const_iterator iter = m_commands.find(cmdTxt);
|
||||
@@ -402,9 +402,9 @@ bool CEditorCommandManager::IsRegistered(int commandId) const
|
||||
return false;
|
||||
}
|
||||
|
||||
void CEditorCommandManager::SetCommandAvailableInScripting(const string& module, const string& name)
|
||||
void CEditorCommandManager::SetCommandAvailableInScripting(const AZStd::string& module, const AZStd::string& name)
|
||||
{
|
||||
string fullName = GetFullCommandName(module, name);
|
||||
AZStd::string fullName = GetFullCommandName(module, name);
|
||||
CommandTable::iterator iter = m_commands.find(fullName);
|
||||
|
||||
if (iter != m_commands.end())
|
||||
@@ -413,7 +413,7 @@ void CEditorCommandManager::SetCommandAvailableInScripting(const string& module,
|
||||
}
|
||||
}
|
||||
|
||||
bool CEditorCommandManager::IsCommandAvailableInScripting(const string& fullCmdName) const
|
||||
bool CEditorCommandManager::IsCommandAvailableInScripting(const AZStd::string& fullCmdName) const
|
||||
{
|
||||
CommandTable::const_iterator iter = m_commands.find(fullCmdName);
|
||||
|
||||
@@ -425,16 +425,16 @@ bool CEditorCommandManager::IsCommandAvailableInScripting(const string& fullCmdN
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CEditorCommandManager::IsCommandAvailableInScripting(const string& module, const string& name) const
|
||||
bool CEditorCommandManager::IsCommandAvailableInScripting(const AZStd::string& module, const AZStd::string& name) const
|
||||
{
|
||||
string fullName = GetFullCommandName(module, name);
|
||||
AZStd::string fullName = GetFullCommandName(module, name);
|
||||
|
||||
return IsCommandAvailableInScripting(fullName);
|
||||
}
|
||||
|
||||
void CEditorCommandManager::LogCommand(const string& fullCmdName, const CCommand::CArgs& args) const
|
||||
void CEditorCommandManager::LogCommand(const AZStd::string& fullCmdName, const CCommand::CArgs& args) const
|
||||
{
|
||||
string cmdLine = fullCmdName;
|
||||
AZStd::string cmdLine = fullCmdName;
|
||||
|
||||
for (int i = 0; i < args.GetArgCount(); ++i)
|
||||
{
|
||||
@@ -509,7 +509,7 @@ void CEditorCommandManager::LogCommand(const string& fullCmdName, const CCommand
|
||||
|
||||
if (pScriptTermDialog)
|
||||
{
|
||||
string text = "> ";
|
||||
AZStd::string text = "> ";
|
||||
text += cmdLine;
|
||||
text += "\r\n";
|
||||
pScriptTermDialog->AppendText(text.c_str());
|
||||
@@ -526,14 +526,14 @@ QString CEditorCommandManager::ExecuteAndLogReturn(CCommand* pCommand, const CCo
|
||||
return result;
|
||||
}
|
||||
|
||||
void CEditorCommandManager::GetArgsFromString(const string& argsTxt, CCommand::CArgs& argList)
|
||||
void CEditorCommandManager::GetArgsFromString(const AZStd::string& argsTxt, CCommand::CArgs& argList)
|
||||
{
|
||||
const char quoteSymbol = '\'';
|
||||
int curPos = 0;
|
||||
int prevPos = 0;
|
||||
string arg = argsTxt.Tokenize(" ", curPos);
|
||||
|
||||
while (!arg.empty())
|
||||
AZStd::vector<AZStd::string> tokens;
|
||||
AZ::StringFunc::Tokenize(argsTxt, tokens, ' ');
|
||||
for(AZStd::string& arg : tokens)
|
||||
{
|
||||
if (arg[0] == quoteSymbol) // A special consideration for a quoted string
|
||||
{
|
||||
@@ -542,11 +542,11 @@ void CEditorCommandManager::GetArgsFromString(const string& argsTxt, CCommand::C
|
||||
size_t openingQuotePos = argsTxt.find(quoteSymbol, prevPos);
|
||||
size_t closingQuotePos = argsTxt.find(quoteSymbol, curPos);
|
||||
|
||||
if (closingQuotePos != string::npos)
|
||||
if (closingQuotePos != AZStd::string::npos)
|
||||
{
|
||||
arg = argsTxt.substr(openingQuotePos + 1, closingQuotePos - openingQuotePos - 1);
|
||||
size_t nextArgPos = argsTxt.find(' ', closingQuotePos + 1);
|
||||
curPos = nextArgPos != string::npos ? nextArgPos + 1 : argsTxt.length();
|
||||
curPos = nextArgPos != AZStd::string::npos ? nextArgPos + 1 : argsTxt.length();
|
||||
|
||||
for (; curPos < argsTxt.length(); ++curPos) // Skip spaces.
|
||||
{
|
||||
@@ -565,6 +565,5 @@ void CEditorCommandManager::GetArgsFromString(const string& argsTxt, CCommand::C
|
||||
|
||||
argList.Add(arg.c_str());
|
||||
prevPos = curPos;
|
||||
arg = argsTxt.Tokenize(" ", curPos);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,20 +48,20 @@ public:
|
||||
const AZStd::function<void()>& functor,
|
||||
const CCommand0::SUIInfo& uiInfo);
|
||||
bool AttachUIInfo(const char* fullCmdName, const CCommand0::SUIInfo& uiInfo);
|
||||
bool GetUIInfo(const string& module, const string& name, CCommand0::SUIInfo& uiInfo) const;
|
||||
bool GetUIInfo(const string& fullCmdName, CCommand0::SUIInfo& uiInfo) const;
|
||||
QString Execute(const string& cmdLine);
|
||||
QString Execute(const string& module, const string& name, const CCommand::CArgs& args);
|
||||
bool GetUIInfo(const AZStd::string& module, const AZStd::string& name, CCommand0::SUIInfo& uiInfo) const;
|
||||
bool GetUIInfo(const AZStd::string& fullCmdName, CCommand0::SUIInfo& uiInfo) const;
|
||||
QString Execute(const AZStd::string& cmdLine);
|
||||
QString Execute(const AZStd::string& module, const AZStd::string& name, const CCommand::CArgs& args);
|
||||
void Execute(int commandId);
|
||||
void GetCommandList(std::vector<string>& cmds) const;
|
||||
void GetCommandList(std::vector<AZStd::string>& cmds) const;
|
||||
//! Used in the console dialog
|
||||
string AutoComplete(const string& substr) const;
|
||||
AZStd::string AutoComplete(const AZStd::string& substr) const;
|
||||
bool IsRegistered(const char* module, const char* name) const;
|
||||
bool IsRegistered(const char* cmdLine) const;
|
||||
bool IsRegistered(int commandId) const;
|
||||
void SetCommandAvailableInScripting(const string& module, const string& name);
|
||||
bool IsCommandAvailableInScripting(const string& module, const string& name) const;
|
||||
bool IsCommandAvailableInScripting(const string& fullCmdName) const;
|
||||
void SetCommandAvailableInScripting(const AZStd::string& module, const AZStd::string& name);
|
||||
bool IsCommandAvailableInScripting(const AZStd::string& module, const AZStd::string& name) const;
|
||||
bool IsCommandAvailableInScripting(const AZStd::string& fullCmdName) const;
|
||||
//! Turning off the warning is needed for reloading the ribbon bar.
|
||||
void TurnDuplicateWarningOn() { m_bWarnDuplicate = true; }
|
||||
void TurnDuplicateWarningOff() { m_bWarnDuplicate = false; }
|
||||
@@ -74,7 +74,7 @@ protected:
|
||||
};
|
||||
|
||||
//! A full command name to an actual command mapping
|
||||
typedef std::map<string, SCommandTableEntry> CommandTable;
|
||||
typedef std::map<AZStd::string, SCommandTableEntry> CommandTable;
|
||||
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
CommandTable m_commands;
|
||||
|
||||
@@ -86,9 +86,9 @@ protected:
|
||||
bool m_bWarnDuplicate;
|
||||
|
||||
static int GenNewCommandId();
|
||||
static string GetFullCommandName(const string& module, const string& name);
|
||||
static void GetArgsFromString(const string& argsTxt, CCommand::CArgs& argList);
|
||||
void LogCommand(const string& fullCmdName, const CCommand::CArgs& args) const;
|
||||
static AZStd::string GetFullCommandName(const AZStd::string& module, const AZStd::string& name);
|
||||
static void GetArgsFromString(const AZStd::string& argsTxt, CCommand::CArgs& argList);
|
||||
void LogCommand(const AZStd::string& fullCmdName, const CCommand::CArgs& args) const;
|
||||
QString ExecuteAndLogReturn(CCommand* pCommand, const CCommand::CArgs& args);
|
||||
};
|
||||
|
||||
|
||||
@@ -127,9 +127,9 @@ namespace Config
|
||||
|
||||
case IConfigVar::eType_STRING:
|
||||
{
|
||||
string currentValue = nullptr;
|
||||
AZStd::string currentValue;
|
||||
var->Get(¤tValue);
|
||||
node->setAttr(szName, currentValue);
|
||||
node->setAttr(szName, currentValue.c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -186,7 +186,7 @@ namespace Config
|
||||
|
||||
case IConfigVar::eType_STRING:
|
||||
{
|
||||
string currentValue = nullptr;
|
||||
AZStd::string currentValue;
|
||||
var->GetDefault(¤tValue);
|
||||
QString readValue(currentValue.c_str());
|
||||
if (node->getAttr(szName, readValue))
|
||||
|
||||
@@ -47,12 +47,12 @@ namespace Config
|
||||
return m_type;
|
||||
}
|
||||
|
||||
ILINE const string& GetName() const
|
||||
ILINE const AZStd::string& GetName() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
ILINE const string& GetDescription() const
|
||||
ILINE const AZStd::string& GetDescription() const
|
||||
{
|
||||
return m_description;
|
||||
}
|
||||
@@ -71,13 +71,13 @@ namespace Config
|
||||
static EType TranslateType(const bool&) { return eType_BOOL; }
|
||||
static EType TranslateType(const int&) { return eType_INT; }
|
||||
static EType TranslateType(const float&) { return eType_FLOAT; }
|
||||
static EType TranslateType(const string&) { return eType_STRING; }
|
||||
static EType TranslateType(const AZStd::string&) { return eType_STRING; }
|
||||
|
||||
protected:
|
||||
EType m_type;
|
||||
uint8 m_flags;
|
||||
string m_name;
|
||||
string m_description;
|
||||
AZStd::string m_name;
|
||||
AZStd::string m_description;
|
||||
void* m_ptr;
|
||||
ICVar* m_pCVar;
|
||||
};
|
||||
|
||||
@@ -1,135 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "EditorDefs.h"
|
||||
#include "ControlMRU.h"
|
||||
|
||||
IMPLEMENT_XTP_CONTROL(CControlMRU, CXTPControlRecentFileList)
|
||||
|
||||
bool CControlMRU::DoesFileExist(CString& sFileName)
|
||||
{
|
||||
return (_access(sFileName.GetBuffer(), 0) == 0);
|
||||
}
|
||||
|
||||
void CControlMRU::OnCalcDynamicSize(DWORD dwMode)
|
||||
{
|
||||
CRecentFileList* pRecentFileList = GetRecentFileList();
|
||||
|
||||
if (!pRecentFileList)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CString* pArrNames = pRecentFileList->m_arrNames;
|
||||
|
||||
assert(pArrNames != nullptr);
|
||||
if (!pArrNames)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
while (m_nIndex + 1 < m_pControls->GetCount())
|
||||
{
|
||||
CXTPControl* pControl = m_pControls->GetAt(m_nIndex + 1);
|
||||
assert(pControl);
|
||||
if (pControl->GetID() >= GetFirstMruID()
|
||||
&& pControl->GetID() <= GetFirstMruID() + pRecentFileList->m_nSize)
|
||||
{
|
||||
m_pControls->Remove(pControl);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_pParent->IsCustomizeMode())
|
||||
{
|
||||
m_dwHideFlags = 0;
|
||||
SetEnabled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (pArrNames[0].IsEmpty())
|
||||
{
|
||||
SetCaption(CString(MAKEINTRESOURCE(IDS_NORECENTFILE_CAPTION)));
|
||||
SetDescription("No recently opened files");
|
||||
m_dwHideFlags = 0;
|
||||
SetEnabled(false);
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetCaption(CString(MAKEINTRESOURCE(IDS_RECENTFILE_CAPTION)));
|
||||
SetDescription("Open this document");
|
||||
}
|
||||
|
||||
m_dwHideFlags |= xtpHideGeneric;
|
||||
|
||||
CString sCurDir = (Path::GetEditingGameDataFolder() + "\\").c_str();
|
||||
int nCurDir = sCurDir.GetLength();
|
||||
|
||||
CString strName;
|
||||
CString strTemp;
|
||||
int iLastValidMRU = 0;
|
||||
|
||||
for (int iMRU = 0; iMRU < pRecentFileList->m_nSize; iMRU++)
|
||||
{
|
||||
if (!pRecentFileList->GetDisplayName(strName, iMRU, sCurDir.GetBuffer(), nCurDir))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (DoesFileExist(pArrNames[iMRU]))
|
||||
{
|
||||
CString sCurEntryDir = pArrNames[iMRU].Left(nCurDir);
|
||||
|
||||
if (sCurEntryDir.CompareNoCase(sCurDir) != 0)
|
||||
{
|
||||
//unavailable entry (wrong directory)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//invalid entry (not existing)
|
||||
continue;
|
||||
}
|
||||
|
||||
int nId = iMRU + GetFirstMruID();
|
||||
|
||||
CXTPControl* pControl = m_pControls->Add(xtpControlButton, nId, _T(""), m_nIndex + iLastValidMRU + 1, true);
|
||||
assert(pControl);
|
||||
|
||||
pControl->SetCaption(CXTPControlWindowList::ConstructCaption(strName, iLastValidMRU + 1));
|
||||
pControl->SetFlags(xtpFlagManualUpdate);
|
||||
pControl->SetBeginGroup(iLastValidMRU == 0 && m_nIndex != 0);
|
||||
pControl->SetParameter(pArrNames[iMRU]);
|
||||
|
||||
CString sDescription = "Open file: " + pArrNames[iMRU];
|
||||
pControl->SetDescription(sDescription);
|
||||
|
||||
if ((GetFlags() & xtpFlagWrapRow) && iMRU == 0)
|
||||
{
|
||||
pControl->SetFlags(pControl->GetFlags() | xtpFlagWrapRow);
|
||||
}
|
||||
|
||||
++iLastValidMRU;
|
||||
}
|
||||
|
||||
//if no entry was valid, treat as none would exist
|
||||
if (iLastValidMRU == 0)
|
||||
{
|
||||
SetCaption(CString(MAKEINTRESOURCE(IDS_NORECENTFILE_CAPTION)));
|
||||
SetDescription("No recently opened files");
|
||||
m_dwHideFlags = 0;
|
||||
SetEnabled(false);
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
#ifndef CRYINCLUDE_EDITOR_CONTROLMRU_H
|
||||
#define CRYINCLUDE_EDITOR_CONTROLMRU_H
|
||||
|
||||
class CControlMRU
|
||||
: public CXTPControlRecentFileList
|
||||
{
|
||||
protected:
|
||||
virtual void OnCalcDynamicSize(DWORD dwMode);
|
||||
|
||||
private:
|
||||
DECLARE_XTP_CONTROL(CControlMRU)
|
||||
bool DoesFileExist(CString& sFileName);
|
||||
};
|
||||
#endif // CRYINCLUDE_EDITOR_CONTROLMRU_H
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user