Merge branch 'main' into non-uniform-scale-mesh

This commit is contained in:
greerdv
2021-04-20 10:29:55 +01:00
82 changed files with 1573 additions and 798 deletions
@@ -0,0 +1,10 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
@@ -0,0 +1,13 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
import sys, os
sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../../PythonTests')
from PythonAssetBuilder import bootstrap_tests
@@ -134,6 +134,25 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
)
endif()
## Python Asset Builder ##
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
ly_add_pytest(
NAME AutomatedTesting::PythonAssetBuilder
TEST_SUITE periodic
TEST_SERIAL
PATH ${CMAKE_CURRENT_LIST_DIR}/PythonAssetBuilder
TIMEOUT 3600
RUNTIME_DEPENDENCIES
Legacy::Editor
Legacy::CryRenderNULL
AZ::AssetProcessor
AutomatedTesting.Assets
Gem::EditorPythonBindings.Editor
Gem::PythonAssetBuilder.Editor
COMPONENT TestTools
)
endif()
## Blast ##
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
ly_add_pytest(
@@ -0,0 +1,57 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
#
# This launches the AssetProcessor and Editor then attempts to find the expected
# assets created by a Python Asset Builder and the output of a scene pipeline script
#
import sys
import os
import pytest
import logging
pytest.importorskip('ly_test_tools')
import ly_test_tools.environment.file_system as file_system
import ly_test_tools.log.log_monitor
import ly_test_tools.environment.waiter as waiter
@pytest.mark.SUITE_sandbox
@pytest.mark.parametrize('launcher_platform', ['windows_editor'])
@pytest.mark.parametrize('project', ['AutomatedTesting'])
@pytest.mark.parametrize('level', ['auto_test'])
class TestPythonAssetProcessing(object):
def test_DetectPythonCreatedAsset(self, request, editor, level, launcher_platform):
unexpected_lines = []
expected_lines = [
'Mock asset exists',
'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_center.azmodel) found',
'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_X_negative.azmodel) found',
'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_X_positive.azmodel) found',
'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_center.azmodel) found',
'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_center.azmodel) found',
'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_center.azmodel) found',
'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_center.azmodel) found',
'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_center.azmodel) found'
]
timeout = 180
halt_on_unexpected = False
test_directory = os.path.join(os.path.dirname(__file__))
testFile = os.path.join(test_directory, 'AssetBuilder_test_case.py')
editor.args.extend(['-NullRenderer', "--skipWelcomeScreenDialog", "--autotest_mode", "--runpythontest", testFile])
with editor.start():
editorlog_file = os.path.join(editor.workspace.paths.project_log(), 'Editor.log')
log_monitor = ly_test_tools.log.log_monitor.LogMonitor(editor, editorlog_file)
waiter.wait_for(
lambda: editor.is_alive(),
timeout,
exc=("Log file '{}' was never opened by another process.".format(editorlog_file)),
interval=1)
log_monitor.monitor_log_for_lines(expected_lines, unexpected_lines, halt_on_unexpected, timeout)
@@ -0,0 +1,52 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
import azlmbr.bus
import azlmbr.asset
import azlmbr.editor
import azlmbr.math
import azlmbr.legacy.general
def raise_and_stop(msg):
print (msg)
azlmbr.editor.EditorToolsApplicationRequestBus(azlmbr.bus.Broadcast, 'ExitNoPrompt')
# These tests are meant to check that the test_asset.mock source asset turned into
# a test_asset.mock_asset product asset via the Python asset builder system
mockAssetType = azlmbr.math.Uuid_CreateString('{9274AD17-3212-4651-9F3B-7DCCB080E467}', 0)
mockAssetPath = 'gem/pythontests/pythonassetbuilder/test_asset.mock_asset'
assetId = azlmbr.asset.AssetCatalogRequestBus(azlmbr.bus.Broadcast, 'GetAssetIdByPath', mockAssetPath, mockAssetType, False)
if (assetId.is_valid() is False):
raise_and_stop(f'Mock AssetId is not valid! Got {assetId.to_string()} instead')
if (assetId.to_string().endswith(':54c06b89') is False):
raise_and_stop(f'Mock AssetId has unexpected sub-id for {mockAssetPath}!')
print ('Mock asset exists')
# These tests detect if the geom_group.fbx file turns into a number of azmodel product assets
def test_azmodel_product(generatedModelAssetPath, expectedSubId):
azModelAssetType = azlmbr.math.Uuid_CreateString('{2C7477B6-69C5-45BE-8163-BCD6A275B6D8}', 0)
assetId = azlmbr.asset.AssetCatalogRequestBus(azlmbr.bus.Broadcast, 'GetAssetIdByPath', generatedModelAssetPath, azModelAssetType, False)
assetIdString = assetId.to_string()
if (assetIdString.endswith(':' + expectedSubId) is False):
raise_and_stop(f'Asset has unexpected asset ID ({assetIdString}) for ({generatedModelAssetPath})!')
else:
print(f'Expected subId for asset ({generatedModelAssetPath}) found')
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_center.azmodel', '10412075')
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_X_positive.azmodel', '10d16e68')
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_X_negative.azmodel', '10a71973')
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_Y_positive.azmodel', '10130556')
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_Y_negative.azmodel', '1065724d')
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_Z_positive.azmodel', '1024be55')
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_Z_negative.azmodel', '1052c94e')
azlmbr.editor.EditorToolsApplicationRequestBus(azlmbr.bus.Broadcast, 'ExitNoPrompt')
@@ -0,0 +1,10 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
@@ -0,0 +1,17 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
import os
import sys
try:
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
import mock_asset_builder
except:
print ('skipping asset builder testing via mock_asset_builder')
@@ -0,0 +1,88 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
import uuid, os
import azlmbr.scene as sceneApi
import azlmbr.scene.graph
from scene_api import scene_data as sceneData
def get_mesh_node_names(sceneGraph):
meshDataList = []
node = sceneGraph.get_root()
children = []
while node.IsValid():
# store children to process after siblings
if sceneGraph.has_node_child(node):
children.append(sceneGraph.get_node_child(node))
# store any node that has mesh data content
nodeContent = sceneGraph.get_node_content(node)
if nodeContent is not None and nodeContent.CastWithTypeName('MeshData'):
if sceneGraph.is_node_end_point(node) is False:
meshDataList.append(sceneData.SceneGraphName(sceneGraph.get_node_name(node)))
# advance to next node
if sceneGraph.has_node_sibling(node):
node = sceneGraph.get_node_sibling(node)
elif children:
node = children.pop()
else:
node = azlmbr.scene.graph.NodeIndex()
return meshDataList
def update_manifest(scene):
graph = sceneData.SceneGraph(scene.graph)
meshNameList = get_mesh_node_names(graph)
sceneManifest = sceneData.SceneManifest()
sourceFilenameOnly = os.path.basename(scene.sourceFilename)
sourceFilenameOnly = sourceFilenameOnly.replace('.','_')
for activeMeshIndex in range(len(meshNameList)):
chunkName = meshNameList[activeMeshIndex]
chunkPath = chunkName.get_path()
meshGroupName = '{}_{}'.format(sourceFilenameOnly, chunkName.get_name())
meshGroup = sceneManifest.add_mesh_group(meshGroupName)
meshGroup['id'] = '{' + str(uuid.uuid5(uuid.NAMESPACE_DNS, sourceFilenameOnly + chunkPath)) + '}'
sceneManifest.mesh_group_add_comment(meshGroup, 'auto generated by scene manifest')
sceneManifest.mesh_group_add_advanced_coordinate_system(meshGroup, None, None, None, 1.0)
# create selection node list
pathSet = set()
for meshIndex in range(len(meshNameList)):
targetPath = meshNameList[meshIndex].get_path()
if (activeMeshIndex == meshIndex):
sceneManifest.mesh_group_select_node(meshGroup, targetPath)
else:
if targetPath not in pathSet:
pathSet.update(targetPath)
sceneManifest.mesh_group_unselect_node(meshGroup, targetPath)
return sceneManifest.export()
mySceneJobHandler = None
def on_update_manifest(args):
scene = args[0]
result = update_manifest(scene)
global mySceneJobHandler
mySceneJobHandler.disconnect()
mySceneJobHandler = None
return result
def main():
global mySceneJobHandler
mySceneJobHandler = sceneApi.ScriptBuildingNotificationBusHandler()
mySceneJobHandler.connect()
mySceneJobHandler.add_callback('OnUpdateManifest', on_update_manifest)
if __name__ == "__main__":
main()
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:66d38948309ef273adf74b63eaa38f8fc2e2bdfbab3933d2ee082ce6a8cb108e
size 30496
@@ -0,0 +1,9 @@
{
"values":
[
{
"$type": "ScriptProcessorRule",
"scriptFilename": "Gem/PythonTests/PythonAssetBuilder/export_chunks_builder.py"
}
]
}
@@ -0,0 +1,121 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
import azlmbr.asset
import azlmbr.asset.builder
import azlmbr.bus
import azlmbr.math
import os, traceback, binascii, sys
jobKeyName = 'Mock Asset'
def log_exception_traceback():
exc_type, exc_value, exc_tb = sys.exc_info()
data = traceback.format_exception(exc_type, exc_value, exc_tb)
print(str(data))
# creates a single job to compile for each platform
def create_jobs(request):
# create job descriptor for each platform
jobDescriptorList = []
for platformInfo in request.enabledPlatforms:
jobDesc = azlmbr.asset.builder.JobDescriptor()
jobDesc.jobKey = jobKeyName
jobDesc.set_platform_identifier(platformInfo.identifier)
jobDescriptorList.append(jobDesc)
response = azlmbr.asset.builder.CreateJobsResponse()
response.result = azlmbr.asset.builder.CreateJobsResponse_ResultSuccess
response.createJobOutputs = jobDescriptorList
return response
def on_create_jobs(args):
try:
request = args[0]
return create_jobs(request)
except:
log_exception_traceback()
# returing back a default CreateJobsResponse() records an asset error
return azlmbr.asset.builder.CreateJobsResponse()
def process_file(request):
# prepare output folder
basePath, _ = os.path.split(request.sourceFile)
outputPath = os.path.join(request.tempDirPath, basePath)
os.makedirs(outputPath, exist_ok=True)
# write out a mock file
basePath, sourceFile = os.path.split(request.sourceFile)
mockFilename = os.path.splitext(sourceFile)[0] + '.mock_asset'
mockFilename = os.path.join(basePath, mockFilename)
mockFilename = mockFilename.replace('\\', '/')
tempFilename = os.path.join(request.tempDirPath, mockFilename)
# write out a tempFilename like a JSON
fileOutput = open(tempFilename, "w")
fileOutput.write('{}')
fileOutput.close()
# generate a product asset file entry
subId = binascii.crc32(mockFilename.encode())
mockAssetType = azlmbr.math.Uuid_CreateString('{9274AD17-3212-4651-9F3B-7DCCB080E467}', 0)
product = azlmbr.asset.builder.JobProduct(mockFilename, mockAssetType, subId)
product.dependenciesHandled = True
productOutputs = []
productOutputs.append(product)
# fill out response object
response = azlmbr.asset.builder.ProcessJobResponse()
response.outputProducts = productOutputs
response.resultCode = azlmbr.asset.builder.ProcessJobResponse_Success
response.dependenciesHandled = True
return response
# using the incoming 'request' find the type of job via 'jobKey' to determine what to do
def on_process_job(args):
try:
request = args[0]
if (request.jobDescription.jobKey.startswith(jobKeyName)):
return process_file(request)
except:
log_exception_traceback()
# returning back an empty ProcessJobResponse() will record an error
return azlmbr.asset.builder.ProcessJobResponse()
# register asset builder
def register_asset_builder(busId):
assetPattern = azlmbr.asset.builder.AssetBuilderPattern()
assetPattern.pattern = '*.mock'
assetPattern.type = azlmbr.asset.builder.AssetBuilderPattern_Wildcard
builderDescriptor = azlmbr.asset.builder.AssetBuilderDesc()
builderDescriptor.name = "Mock Builder"
builderDescriptor.patterns = [assetPattern]
builderDescriptor.busId = busId
builderDescriptor.version = 1
outcome = azlmbr.asset.builder.PythonAssetBuilderRequestBus(azlmbr.bus.Broadcast, 'RegisterAssetBuilder', builderDescriptor)
if outcome.IsSuccess():
# created the asset builder to hook into the notification bus
handler = azlmbr.asset.builder.PythonBuilderNotificationBusHandler()
handler.connect(busId)
handler.add_callback('OnCreateJobsRequest', on_create_jobs)
handler.add_callback('OnProcessJobRequest', on_process_job)
return handler
# create the asset builder handler
busIdString = '{CF5C74C1-9ED4-5851-95B1-0B15090DBEC7}'
busId = azlmbr.math.Uuid_CreateString(busIdString, 0)
handler = None
try:
handler = register_asset_builder(busId)
except:
handler = None
log_exception_traceback()
@@ -0,0 +1 @@
mock data
@@ -1,7 +1,6 @@
{
"configurations": [
{
"autoSelect": false,
"displayName": "Greenwich Park 02",
"skyboxImageAsset": {
"assetId": {
@@ -64,7 +63,6 @@
"shadowCatcherOpacity": 0.20000000298023225
},
{
"autoSelect": false,
"displayName": "Greenwich Park 02 (Alt)",
"skyboxImageAsset": {
"assetId": {
@@ -506,6 +506,7 @@ namespace AZ::SettingsRegistryMergeUtils
void MergeSettingsToRegistry_AddRuntimeFilePaths(SettingsRegistryInterface& registry)
{
using FixedValueString = AZ::SettingsRegistryInterface::FixedValueString;
// Binary folder
AZ::IO::FixedMaxPath path = AZ::Utils::GetExecutableDirectory();
registry.Set(FilePathKey_BinaryFolder, path.LexicallyNormal().Native());
@@ -514,28 +515,25 @@ namespace AZ::SettingsRegistryMergeUtils
AZ::IO::FixedMaxPath engineRoot = FindEngineRoot(registry);
registry.Set(FilePathKey_EngineRootFolder, engineRoot.LexicallyNormal().Native());
constexpr size_t bufferSize = 64;
auto buffer = AZStd::fixed_string<bufferSize>::format("%s/project_path", BootstrapSettingsRootKey);
AZ::SettingsRegistryInterface::FixedValueString projectPathKey(buffer);
auto projectPathKey = FixedValueString::format("%s/project_path", BootstrapSettingsRootKey);
SettingsRegistryInterface::FixedValueString projectPathValue;
if (registry.Get(projectPathValue, projectPathKey))
{
// Cache folder
// Get the name of the asset platform assigned by the bootstrap. First check for platform version such as "windows_assets"
// and if that's missing just get "assets".
constexpr char platformName[] = AZ_TRAIT_OS_PLATFORM_CODENAME_LOWER;
buffer = AZStd::fixed_string<bufferSize>::format("%s/%s_assets", BootstrapSettingsRootKey, platformName);
AZStd::string_view assetPlatformKey(buffer);
// Use the platform codename to retrieve the default asset platform value
SettingsRegistryInterface::FixedValueString assetPlatform = AZ::OSPlatformToDefaultAssetPlatform(AZ_TRAIT_OS_PLATFORM_CODENAME);
if (!registry.Get(assetPlatform, assetPlatformKey))
FixedValueString assetPlatform;
if (auto assetPlatformKey = FixedValueString::format("%s/%s_assets", BootstrapSettingsRootKey, AZ_TRAIT_OS_PLATFORM_CODENAME_LOWER);
!registry.Get(assetPlatform, assetPlatformKey))
{
buffer = AZStd::fixed_string<bufferSize>::format("%s/assets", BootstrapSettingsRootKey);
assetPlatformKey = AZStd::string_view(buffer);
assetPlatformKey = FixedValueString::format("%s/assets", BootstrapSettingsRootKey);
registry.Get(assetPlatform, assetPlatformKey);
}
if (assetPlatform.empty())
{
// Use the platform codename to retrieve the default asset platform value
assetPlatform = AZ::OSPlatformToDefaultAssetPlatform(AZ_TRAIT_OS_PLATFORM_CODENAME);
}
// Project path - corresponds to the @devassets@ alias
// NOTE: Here we append to engineRoot, but if projectPathValue is absolute then engineRoot is discarded.
@@ -575,8 +573,7 @@ namespace AZ::SettingsRegistryMergeUtils
{
// Cache: project root - no corresponding fileIO alias, but this is where the asset database lives.
// A registry override is accepted using the "project_cache_path" key.
buffer = AZStd::fixed_string<bufferSize>::format("%s/project_cache_path", BootstrapSettingsRootKey);
AZStd::string_view projectCacheRootOverrideKey(buffer);
auto projectCacheRootOverrideKey = FixedValueString::format("%s/project_cache_path", BootstrapSettingsRootKey);
// Clear path to make sure that the `project_cache_path` value isn't concatenated to the project path
path.clear();
if (registry.Get(path.Native(), projectCacheRootOverrideKey))
@@ -136,6 +136,48 @@ namespace AzToolsFramework
return entity->GetName();
}
EntityList EntityIdListToEntityList(const EntityIdList& inputEntityIds)
{
EntityList entities;
entities.reserve(inputEntityIds.size());
for (AZ::EntityId entityId : inputEntityIds)
{
if (!entityId.IsValid())
{
continue;
}
if (auto entity = GetEntityById(entityId))
{
entities.emplace_back(entity);
}
}
return entities;
}
EntityList EntityIdSetToEntityList(const EntityIdSet& inputEntityIds)
{
EntityList entities;
entities.reserve(inputEntityIds.size());
for (AZ::EntityId entityId : inputEntityIds)
{
if (!entityId.IsValid())
{
continue;
}
if (auto entity = GetEntityById(entityId))
{
entities.emplace_back(entity);
}
}
return entities;
}
void GetAllComponentsForEntity(const AZ::Entity* entity, AZ::Entity::ComponentArrayType& componentsOnEntity)
{
if (entity)
@@ -1068,6 +1110,45 @@ namespace AzToolsFramework
return !allEntityClonesContainer.m_entities.empty();
}
EntityIdSet GetCulledEntityHierarchy(const EntityIdList& entities)
{
EntityIdSet culledEntities;
for (const AZ::EntityId& entityId : entities)
{
bool selectionIncludesTransformHeritage = false;
AZ::EntityId parentEntityId = entityId;
do
{
AZ::EntityId nextParentId;
AZ::TransformBus::EventResult(
/*result*/ nextParentId,
/*address*/ parentEntityId,
&AZ::TransformBus::Events::GetParentId);
parentEntityId = nextParentId;
if (!parentEntityId.IsValid())
{
break;
}
for (const AZ::EntityId& parentCheck : entities)
{
if (parentCheck == parentEntityId)
{
selectionIncludesTransformHeritage = true;
break;
}
}
} while (parentEntityId.IsValid() && !selectionIncludesTransformHeritage);
if (!selectionIncludesTransformHeritage)
{
culledEntities.insert(entityId);
}
}
return culledEntities;
}
namespace Internal
{
void CloneSliceEntitiesAndChildren(
@@ -47,6 +47,9 @@ namespace AzToolsFramework
AZStd::string GetEntityName(const AZ::EntityId& entityId, const AZStd::string_view& nameOverride = {});
EntityList EntityIdListToEntityList(const EntityIdList& inputEntityIds);
EntityList EntityIdSetToEntityList(const EntityIdSet& inputEntityIds);
template <typename... ComponentTypes>
struct AddComponents
{
@@ -202,4 +205,8 @@ namespace AzToolsFramework
/// Wrap EBus SetSelectedEntities call.
void SelectEntities(const AzToolsFramework::EntityIdList& entities);
/// Return a set of entities, culling any that have an ancestor in the list.
/// e.g. This is useful for getting a concise set of entities that need to be duplicated.
EntityIdSet GetCulledEntityHierarchy(const EntityIdList& entities);
}; // namespace AzToolsFramework
@@ -61,8 +61,7 @@ namespace AzToolsFramework
PrefabOperationResult PrefabPublicHandler::CreatePrefab(const AZStd::vector<AZ::EntityId>& entityIds, AZ::IO::PathView filePath)
{
// Retrieve entityList from entityIds
EntityList inputEntityList;
EntityIdListToEntityList(entityIds, inputEntityList);
EntityList inputEntityList = EntityIdListToEntityList(entityIds);
// Find common root and top level entities
bool entitiesHaveCommonRoot = false;
@@ -419,8 +418,7 @@ namespace AzToolsFramework
InstanceOptionalReference instance = GetOwnerInstanceByEntityId(entityIds[0]);
// Retrieve entityList from entityIds
EntityList inputEntityList;
EntityIdListToEntityList(entityIds, inputEntityList);
EntityList inputEntityList = EntityIdListToEntityList(entityIds);
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
@@ -767,18 +765,5 @@ namespace AzToolsFramework
return true;
}
void PrefabPublicHandler::EntityIdListToEntityList(const EntityIdList& inputEntityIds, EntityList& outEntities)
{
outEntities.reserve(inputEntityIds.size());
for (AZ::EntityId entityId : inputEntityIds)
{
if (entityId.IsValid())
{
outEntities.emplace_back(GetEntityById(entityId));
}
}
}
}
}
@@ -70,7 +70,6 @@ namespace AzToolsFramework
static Instance* GetParentInstance(Instance* instance);
static Instance* GetAncestorOfInstanceThatIsChildOfRoot(const Instance* ancestor, Instance* descendant);
static void GenerateContainerEntityTransform(const EntityList& topLevelEntities, AZ::Vector3& translation, AZ::Quaternion& rotation);
static void EntityIdListToEntityList(const EntityIdList& inputEntityIds, EntityList& outEntities);
InstanceEntityMapperInterface* m_instanceEntityMapperInterface = nullptr;
InstanceToTemplateInterface* m_instanceToTemplateInterface = nullptr;
@@ -1344,14 +1344,15 @@ namespace AzToolsFramework
emit EnableSelectionUpdates(false);
auto parentIndex = GetIndexFromEntity(parentId);
auto childIndex = GetIndexFromEntity(childId);
beginRemoveRows(parentIndex, childIndex.row(), childIndex.row());
beginResetModel();
}
void EntityOutlinerListModel::OnEntityInfoUpdatedRemoveChildEnd(AZ::EntityId parentId, AZ::EntityId childId)
{
(void)childId;
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
endRemoveRows();
endResetModel();
//must refresh partial lock/visibility of parents
m_isFilterDirty = true;
@@ -0,0 +1,57 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <AzTest/AzTest.h>
#include <AzToolsFramework/Application/ToolsApplication.h>
#include <AzToolsFramework/Entity/EditorEntityHelpers.h>
#include <AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.h>
namespace UnitTest
{
class EditorEntityHelpersTest
: public ToolsApplicationFixture
{
void SetUpEditorFixtureImpl() override
{
m_parent1 = CreateDefaultEditorEntity("Parent1");
m_child1 = CreateDefaultEditorEntity("Child1");
m_child2 = CreateDefaultEditorEntity("Child2");
m_grandChild1 = CreateDefaultEditorEntity("GrandChild1");
m_parent2 = CreateDefaultEditorEntity("Parent2");
AZ::TransformBus::Event(m_child1, &AZ::TransformBus::Events::SetParent, m_parent1);
AZ::TransformBus::Event(m_child2, &AZ::TransformBus::Events::SetParent, m_parent1);
AZ::TransformBus::Event(m_grandChild1, &AZ::TransformBus::Events::SetParent, m_child1);
}
public:
AZ::EntityId m_parent1;
AZ::EntityId m_child1;
AZ::EntityId m_child2;
AZ::EntityId m_grandChild1;
AZ::EntityId m_parent2;
};
TEST_F(EditorEntityHelpersTest, EditorEntityHelpersTests_GetCulledEntityHierarchy)
{
AzToolsFramework::EntityIdList testEntityIds{ m_parent1, m_child1, m_child2, m_grandChild1, m_parent2 };
AzToolsFramework::EntityIdSet culledSet = AzToolsFramework::GetCulledEntityHierarchy(testEntityIds);
// There should only be two EntityIds returned (m_parent1, and m_parent2),
// since all the others should be culled out since they have a common ancestor
// in the list already
using ::testing::UnorderedElementsAre;
EXPECT_THAT(culledSet, UnorderedElementsAre(m_parent1, m_parent2));
}
}
@@ -85,7 +85,9 @@ set(FILES
Prefab/SpawnableSortEntitiesTestFixture.cpp
Prefab/SpawnableSortEntitiesTestFixture.h
Entity/EditorEntityContextComponentTests.cpp
Entity/EditorEntityHelpersTests.cpp
Entity/EditorEntitySearchComponentTests.cpp
Entity/EditorEntitySelectionTests.cpp
SliceStabilityTests/SliceStabilityTestFramework.h
SliceStabilityTests/SliceStabilityTestFramework.cpp
SliceStabilityTests/SliceStabilityCreateTests.cpp
@@ -670,9 +670,13 @@ void SandboxIntegrationManager::PopulateEditorGlobalContextMenu(QMenu* menu, con
action = menu->addAction(QObject::tr("Create layer"));
QObject::connect(action, &QAction::triggered, [this] { ContextMenu_NewLayer(); });
AzToolsFramework::EntityIdList entities;
AzToolsFramework::ToolsApplicationRequests::Bus::BroadcastResult(
entities,
&AzToolsFramework::ToolsApplicationRequests::GetSelectedEntities);
SetupLayerContextMenu(menu);
AzToolsFramework::EntityIdSet flattenedSelection;
GetSelectedEntitiesSetWithFlattenedHierarchy(flattenedSelection);
AzToolsFramework::EntityIdSet flattenedSelection = AzToolsFramework::GetCulledEntityHierarchy(entities);
AzToolsFramework::SetupAddToLayerMenu(menu, flattenedSelection, [this] { return ContextMenu_NewLayer(); });
SetupSliceContextMenu(menu);
@@ -1220,10 +1224,14 @@ void SandboxIntegrationManager::CloneSelection(bool& handled)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
AzToolsFramework::EntityIdSet duplicationSet;
GetSelectedEntitiesSetWithFlattenedHierarchy(duplicationSet);
AzToolsFramework::EntityIdList entities;
AzToolsFramework::ToolsApplicationRequests::Bus::BroadcastResult(
entities,
&AzToolsFramework::ToolsApplicationRequests::GetSelectedEntities);
if (duplicationSet.size() > 0)
AzToolsFramework::EntityIdSet duplicationSet = AzToolsFramework::GetCulledEntityHierarchy(entities);
if (!duplicationSet.empty())
{
AZStd::unordered_set<AZ::EntityId> clonedEntities;
handled = AzToolsFramework::CloneInstantiatedEntities(duplicationSet, clonedEntities);
@@ -42,7 +42,108 @@ namespace AZ
// Downstream only supports 30 frames per second sample rate. Adjusting to 60 doubles the
// length of the animations, they still play back at 30 frames per second.
const double AssImpAnimationImporter::s_defaultTimeStepSampleRate = 1.0 / 30.0;
const double AssImpAnimationImporter::s_defaultTimeStepBetweenFrames = 1.0 / 30.0;
AZ::u32 GetNumKeyFrames(AZ::u32 keysSize, double duration, double ticksPerSecond)
{
if (AZ::IsClose(ticksPerSecond, 0))
{
AZ_Warning("AnimationImporter", false, "Animation ticks per second should not be zero, defaulting to %d keyframes for animation.", keysSize);
return keysSize;
}
const double totalTicks = duration / ticksPerSecond;
AZ::u32 numKeys = keysSize;
// +1 because the animation is from [0, duration] - we have a keyframe at the end of the duration which needs to be included
double totalFramesAtDefaultTimeStep = totalTicks / AssImpAnimationImporter::s_defaultTimeStepBetweenFrames + 1;
if (!AZ::IsClose(totalFramesAtDefaultTimeStep, numKeys, 1))
{
numKeys = AZStd::ceilf(totalFramesAtDefaultTimeStep);
}
return numKeys;
}
double GetTimeForFrame(AZ::u32 frame, double ticksPerSecond)
{
return frame * AssImpAnimationImporter::s_defaultTimeStepBetweenFrames * ticksPerSecond;
}
// Helper class to store key data, when translating from AssImp layout to the engine's scene format.
struct KeyData
{
KeyData(float value, float time) :
mValue(value),
mTime(time)
{
}
bool operator<(const KeyData& other) const
{
return mTime < other.mTime;
}
float mValue = 0;
float mTime = 0;
};
template<class T>
void LerpTemplate(T& start, const T& end, float t)
{
start = start * (1.0f - t) + end * t;
}
template<>
void LerpTemplate(aiQuaternion& start, const aiQuaternion& end, float t)
{
aiQuaternion::Interpolate(start, start, end, t);
}
template<>
void LerpTemplate(float& start, const float& end, float t)
{
start = AZ::Lerp(start, end, t);
}
template<class KeyContainerType, class FrameValueType>
bool SampleKeyFrame(FrameValueType& result, const KeyContainerType& keys, AZ::u32 numKeys, double time, AZ::u32& lastIndex)
{
if (numKeys == 0)
{
AZ_Error("AnimationImporter", numKeys > 0, "Animation key set must have at least 1 key");
return false;
}
if (numKeys == 1)
{
result = keys[0].mValue;
return true;
}
while (lastIndex < numKeys - 1 && time >= keys[lastIndex + 1].mTime)
{
++lastIndex;
}
result = keys[lastIndex].mValue;
if (lastIndex < numKeys - 1)
{
auto nextValue = keys[lastIndex + 1].mValue;
float normalizedTimeBetweenFrames = 0;
if (keys[lastIndex + 1].mTime != keys[lastIndex].mTime)
{
normalizedTimeBetweenFrames =
(time - keys[lastIndex].mTime) / (keys[lastIndex + 1].mTime - keys[lastIndex].mTime);
}
else
{
AZ_Warning("AnimationImporter", false,
"Animation has keys with duplicate time %5.5f, at indices %d and %d. The second will be ignored.",
keys[lastIndex].mTime,
lastIndex,
lastIndex + 1);
}
LerpTemplate(result, nextValue, normalizedTimeBetweenFrames);
}
return true;
}
AssImpAnimationImporter::AssImpAnimationImporter()
{
@@ -199,6 +300,14 @@ namespace AZ
for (AZ::u32 animIndex = 0; animIndex < scene->mNumAnimations; ++animIndex)
{
const aiAnimation* animation = scene->mAnimations[animIndex];
if (animation->mTicksPerSecond == 0)
{
AZ_Error(
"AnimationImporter", false,
"Animation name %s has a sample rate of 0 ticks per second and cannot be processed.",
animation->mName.C_Str());
return Events::ProcessingResult::Failure;
}
mapAnimationsFunc(animation->mNumChannels, animation->mChannels, animation, boneAnimations);
@@ -410,70 +519,38 @@ namespace AZ
anim->mNumPositionKeys, anim->mNumRotationKeys, anim->mNumScalingKeys);
return Events::ProcessingResult::Failure;
}
auto sampleKeyFrame = [](const auto& keys, AZ::u32 numKeys, double time, AZ::u32& lastIndex)
{
AZ_Error("AnimationImporter", numKeys > 0, "Animation key set must have at least 1 key");
if (numKeys == 1)
{
return keys[0].mValue;
}
auto returnValue = keys[0].mValue;
for (AZ::u32 keyIndex = lastIndex; keyIndex < numKeys; ++keyIndex)
{
const auto& key = keys[keyIndex];
lastIndex = keyIndex;
// We want to return the key that exactly matches the time if possible, otherwise we'll keep track of the previous time
// If we don't find an exact match and end up going past the desired time (or run out of keyframes) then we return the previous key
if (key.mTime < time)
{
returnValue = key.mValue;
}
else if (AZ::IsClose(key.mTime, time))
{
return key.mValue;
}
else
{
return returnValue;
}
}
return returnValue;
};
// Resample the animations at a fixed time step. This matches the behaviour of
// the previous SDK used. Longer term, this could be data driven, or based on the
// smallest time step between key frames.
// AssImp has an animation->mTicksPerSecond and animation->mDuration, but those
// are less predictable than just using a fixed time step.
const double duration = animation->mDuration / animation->mTicksPerSecond;
// AssImp documentation claims animation->mDuration is the duration of the animation in ticks, but
// not all animations we've tested follow that pattern. Sometimes duration is in seconds.
const AZ::u32 numKeyFrames = GetNumKeyFrames(
AZStd::max(AZStd::max(anim->mNumScalingKeys, anim->mNumPositionKeys), anim->mNumRotationKeys),
animation->mDuration,
animation->mTicksPerSecond);
AZ::u32 numKeyFrames = AZStd::max(AZStd::max(anim->mNumScalingKeys, anim->mNumPositionKeys), anim->mNumRotationKeys);
if (!AZ::IsClose(duration / s_defaultTimeStepSampleRate, numKeyFrames, 1))
{
double dT = duration / s_defaultTimeStepSampleRate;
numKeyFrames = AZStd::ceilf(dT) + 1; // +1 because the animation is from [0, duration] - we have a keyframe at the end of the duration which needs to be included
}
AZStd::shared_ptr<SceneData::GraphData::AnimationData> createdAnimationData =
AZStd::make_shared<SceneData::GraphData::AnimationData>();
createdAnimationData->ReserveKeyFrames(numKeyFrames);
createdAnimationData->SetTimeStepBetweenFrames(s_defaultTimeStepSampleRate);
createdAnimationData->SetTimeStepBetweenFrames(s_defaultTimeStepBetweenFrames);
AZ::u32 lastScaleIndex = 0;
AZ::u32 lastPositionIndex = 0;
AZ::u32 lastRotationIndex = 0;
for (AZ::u32 frame = 0; frame < numKeyFrames; ++frame)
{
double time = frame * s_defaultTimeStepSampleRate * animation->mTicksPerSecond;
aiVector3D scale = sampleKeyFrame(anim->mScalingKeys, anim->mNumScalingKeys, time, lastScaleIndex);
aiVector3D position = sampleKeyFrame(anim->mPositionKeys, anim->mNumPositionKeys, time, lastPositionIndex);
aiQuaternion rotation = sampleKeyFrame(anim->mRotationKeys, anim->mNumRotationKeys, time, lastRotationIndex);
const double time = GetTimeForFrame(frame, animation->mTicksPerSecond);
aiVector3D scale = aiVector3D(1.f, 1.f, 1.f), position = aiVector3D(0.f, 0.f, 0.f);
aiQuaternion rotation(1.f, 0.f, 0.f, 0.f);
if (!SampleKeyFrame(scale, anim->mScalingKeys, anim->mNumScalingKeys, time, lastScaleIndex) ||
!SampleKeyFrame(position, anim->mPositionKeys, anim->mNumPositionKeys, time, lastPositionIndex) ||
!SampleKeyFrame(rotation, anim->mRotationKeys, anim->mNumRotationKeys, time, lastRotationIndex))
{
return Events::ProcessingResult::Failure;
}
aiMatrix4x4 transform(scale, rotation, position);
@@ -520,28 +597,6 @@ namespace AZ
// SetTimeStepBetweenFrames set on the animation data
// Keyframes. Weights (Values in FBX SDK) per key time.
// Keyframes generated for every single frame of the animation.
// Helper class to store key data, when translating from AssImp layout to the engine's scene format.
struct KeyData
{
KeyData(float weight, float time) :
m_weight(weight),
m_time(time)
{
}
bool operator<(const KeyData& other) const
{
return m_time < other.m_time;
}
// Naming in the previous SDK (FBX SDK) and in the engine's scene format
// doesn't match AssImp's naming convention.
// weight here is the AssImp's name for the data, it was named value in FBX SDK.
float m_weight = 0;
float m_time = 0;
};
typedef AZStd::map<int, AZStd::vector<KeyData>> ValueToKeyDataMap;
ValueToKeyDataMap valueToKeyDataMap;
@@ -562,44 +617,27 @@ namespace AZ
{
AZStd::shared_ptr<SceneData::GraphData::BlendShapeAnimationData> morphAnimNode =
AZStd::make_shared<SceneData::GraphData::BlendShapeAnimationData>();
morphAnimNode->ReserveKeyFrames(animation->mDuration + 1);
morphAnimNode->SetTimeStepBetweenFrames(1.0 / animation->mTicksPerSecond);
const AZ::u32 numKeyFrames = GetNumKeyFrames(keys.size(), animation->mDuration, animation->mTicksPerSecond);
morphAnimNode->ReserveKeyFrames(numKeyFrames);
morphAnimNode->SetTimeStepBetweenFrames(s_defaultTimeStepBetweenFrames);
aiAnimMesh* aiAnimMesh = mesh->mAnimMeshes[meshIdx];
AZStd::string_view nodeName(aiAnimMesh->mName.C_Str());
const AZ::u32 maxKeys = keys.size();
AZ::u32 keyIdx = 0;
for (AZ::u32 time = 0; time <= animation->mDuration; ++time)
for (AZ::u32 frame = 0; frame <= numKeyFrames; ++frame)
{
if (keyIdx < maxKeys - 1 && time >= keys[keyIdx+1].m_time)
{
++keyIdx;
}
float weight_value = keys[keyIdx].m_weight;
if (keyIdx < maxKeys - 1)
{
float nextWeight = keys[keyIdx+1].m_weight;
float normalizedTimeBetweenFrames = 0;
const double time = GetTimeForFrame(frame, animation->mTicksPerSecond);
if (keys[keyIdx + 1].m_time != keys[keyIdx].m_time)
{
normalizedTimeBetweenFrames =
(time - keys[keyIdx].m_time) / (keys[keyIdx + 1].m_time - keys[keyIdx].m_time);
}
else
{
AZ_Warning("AnimationImporter", false,
"Morph target mesh %s has keys with duplicate time, at indices %d and %d. The second will be ignored.",
nodeName.data(),
keyIdx,
keyIdx+1);
}
// AssImp and FBX both only support linear interpolation for blend shapes.
weight_value = AZ::Lerp(weight_value, nextWeight, normalizedTimeBetweenFrames);
float weight = 0;
if (!SampleKeyFrame(weight, keys, keys.size(), time, keyIdx))
{
return Events::ProcessingResult::Failure;
}
morphAnimNode->AddKeyFrame(weight_value);
morphAnimNode->AddKeyFrame(weight);
}
@@ -45,7 +45,7 @@ namespace AZ
const aiMeshMorphAnim* meshMorphAnim,
const aiMesh* mesh);
static const double s_defaultTimeStepSampleRate;
static const double s_defaultTimeStepBetweenFrames;
protected:
static const char* s_animationNodeName;
@@ -43,7 +43,7 @@ namespace AZ
AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context);
if (behaviorContext)
{
behaviorContext->Class<SceneGraph::NodeIndex>()
behaviorContext->Class<SceneGraph::NodeIndex>("NodeIndex")
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
->Attribute(AZ::Script::Attributes::Module, "scene.graph")
->Constructor<>()
@@ -57,7 +57,7 @@ namespace AZ
->Attribute(AZ::Script::Attributes::Operator, AZ::Script::Attributes::OperatorType::ToString)
;
behaviorContext->Class<SceneGraph::Name>()
behaviorContext->Class<SceneGraph::Name>("SceneGraphName")
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
->Attribute(AZ::Script::Attributes::Module, "scene.graph")
->Constructor()
@@ -48,7 +48,7 @@ namespace AWSClientAuth
m_settingsRegistry = AZStd::make_shared<AZ::SettingsRegistryImpl>();
AZStd::array<char, AZ::IO::MaxPathLength> resolvedPath{};
AZ::IO::FileIOBase::GetInstance()->ResolvePath(settingsRegistryPath.data(), resolvedPath.data(), resolvedPath.size());
fileIO->ResolvePath(settingsRegistryPath.data(), resolvedPath.data(), resolvedPath.size());
if (!m_settingsRegistry->MergeSettingsFile(resolvedPath.data(), AZ::SettingsRegistryInterface::Format::JsonMergePatch))
@@ -78,7 +78,6 @@ namespace AZ
AZ_CLASS_ALLOCATOR(LightingPreset, AZ::SystemAllocator, 0);
static void Reflect(AZ::ReflectContext* context);
bool m_autoSelect = false;
AZStd::string m_displayName;
AZ::Data::Asset<AZ::RPI::StreamingImageAsset> m_iblDiffuseImageAsset;
AZ::Data::Asset<AZ::RPI::StreamingImageAsset> m_iblSpecularImageAsset;
@@ -32,7 +32,6 @@ namespace AZ
AZ_CLASS_ALLOCATOR(ModelPreset, AZ::SystemAllocator, 0);
static void Reflect(AZ::ReflectContext* context);
bool m_autoSelect = false;
AZStd::string m_displayName;
AZ::Data::Asset<AZ::RPI::ModelAsset> m_modelAsset;
AZ::Data::Asset<AZ::RPI::StreamingImageAsset> m_previewImageAsset;
@@ -112,7 +112,6 @@ namespace AZ
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
->DataElement(AZ::Edit::UIHandlers::Default, &LightingPreset::m_displayName, "Display Name", "Identifier used for display and selection")
->DataElement(AZ::Edit::UIHandlers::Default, &LightingPreset::m_autoSelect, "Auto Select", "When true, the configuration is automatically selected when loaded")
->DataElement(AZ::Edit::UIHandlers::Default, &LightingPreset::m_iblDiffuseImageAsset, "IBL Diffuse Image Asset", "IBL diffuse image asset reference")
->DataElement(AZ::Edit::UIHandlers::Default, &LightingPreset::m_iblSpecularImageAsset, "IBL Specular Image Asset", "IBL specular image asset reference")
->DataElement(AZ::Edit::UIHandlers::Default, &LightingPreset::m_skyboxImageAsset, "Skybox Image Asset", "Skybox image asset reference")
@@ -32,7 +32,6 @@ namespace AZ
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
->DataElement(AZ::Edit::UIHandlers::Default, &ModelPreset::m_displayName, "Display Name", "Identifier used for display and selection")
->DataElement(AZ::Edit::UIHandlers::Default, &ModelPreset::m_autoSelect, "Auto Select", "When true, the configuration is automatically selected when loaded")
->DataElement(AZ::Edit::UIHandlers::Default, &ModelPreset::m_modelAsset, "Model Asset", "Model asset reference")
->DataElement(AZ::Edit::UIHandlers::Default, &ModelPreset::m_previewImageAsset, "Preview Image Asset", "Preview image asset reference")
;
@@ -105,8 +105,7 @@ namespace AZ
serializeContext->RegisterGenericType<AZStd::vector<LightConfig>>();
serializeContext->Class<LightingPreset>()
->Version(4)
->Field("autoSelect", &LightingPreset::m_autoSelect)
->Version(5)
->Field("displayName", &LightingPreset::m_displayName)
->Field("iblDiffuseImageAsset", &LightingPreset::m_iblDiffuseImageAsset)
->Field("iblSpecularImageAsset", &LightingPreset::m_iblSpecularImageAsset)
@@ -128,7 +127,6 @@ namespace AZ
->Attribute(AZ::Script::Attributes::Module, "render")
->Constructor()
->Constructor<const LightingPreset&>()
->Property("autoSelect", BehaviorValueProperty(&LightingPreset::m_autoSelect))
->Property("displayName", BehaviorValueProperty(&LightingPreset::m_displayName))
->Property("alternateSkyboxImageAsset", BehaviorValueProperty(&LightingPreset::m_alternateSkyboxImageAsset))
->Property("skyboxImageAsset", BehaviorValueProperty(&LightingPreset::m_skyboxImageAsset))
@@ -25,8 +25,7 @@ namespace AZ
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
{
serializeContext->Class<ModelPreset>()
->Version(2)
->Field("autoSelect", &ModelPreset::m_autoSelect)
->Version(3)
->Field("displayName", &ModelPreset::m_displayName)
->Field("modelAsset", &ModelPreset::m_modelAsset)
->Field("previewImageAsset", &ModelPreset::m_previewImageAsset)
@@ -41,7 +40,6 @@ namespace AZ
->Attribute(AZ::Script::Attributes::Module, "render")
->Constructor()
->Constructor<const ModelPreset&>()
->Property("autoSelect", BehaviorValueProperty(&ModelPreset::m_autoSelect))
->Property("displayName", BehaviorValueProperty(&ModelPreset::m_displayName))
->Property("modelAsset", BehaviorValueProperty(&ModelPreset::m_modelAsset))
->Property("previewImageAsset", BehaviorValueProperty(&ModelPreset::m_previewImageAsset))
@@ -74,7 +74,8 @@ namespace AZ
const RHI::BufferView* Buffer::GetBufferView() const
{
if(RHI::CheckBitsAny(m_rhiBuffer->GetDescriptor().m_bindFlags, RHI::BufferBindFlags::InputAssembly | RHI::BufferBindFlags::DynamicInputAssembly))
if (m_rhiBuffer->GetDescriptor().m_bindFlags == RHI::BufferBindFlags::InputAssembly ||
m_rhiBuffer->GetDescriptor().m_bindFlags == RHI::BufferBindFlags::DynamicInputAssembly)
{
AZ_Assert(false, "Input assembly buffer doesn't need a regular buffer view, it requires a stream or index buffer view.");
@@ -3,7 +3,6 @@
"Version": 1,
"ClassName": "AZ::Render::LightingPreset",
"ClassData": {
"autoSelect": false,
"displayName": "Urban Street 02",
"skyboxImageAsset": {
"assetId": {
@@ -2,7 +2,6 @@
"configurations": [
{
"displayName": "Substance: <template>",
"autoSelect": false,
"iblSpecularImageFilePath": "materialeditor/lightingpresets/_Substance_/<latlong_image>_iblskyboxcm_iblspecular.exr.streamingimage",
"iblDiffuseImageFilePath": "materialeditor/lightingpresets/_Substance_/<latlong_image>_iblskyboxcm_ibldiffuse.exr.streamingimage",
"skyboxFilePath": "materialeditor/lightingpresets/_Substance_/<latlong_image>_iblskyboxcm.exr.streamingimage",
@@ -45,7 +44,6 @@
},
{
"displayName": "Substance: <template> (Alt)",
"autoSelect": false,
"iblSpecularImageFilePath": "materialeditor/lightingpresets/_Substance_/<latlong_image>_iblskyboxcm_iblspecular.exr.streamingimage",
"iblDiffuseImageFilePath": "materialeditor/lightingpresets/_Substance_/<latlong_image>_iblskyboxcm_ibldiffuse.exr.streamingimage",
"skyboxFilePath": "materialeditor/lightingpresets/_Substance_/<latlong_image>_iblskyboxcm_ibldiffuse.exr.streamingimage",
@@ -3,7 +3,6 @@
"Version": 1,
"ClassName": "AZ::Render::LightingPreset",
"ClassData": {
"autoSelect": true,
"displayName": "Neutral Urban",
"iblDiffuseImageAsset": {
"assetId": {
@@ -3,7 +3,6 @@
"Version": 1,
"ClassName": "AZ::Render::ModelPreset",
"ClassData": {
"autoSelect": true,
"displayName": "Shader Ball",
"modelAsset": {
"assetId": {
@@ -278,7 +278,7 @@ namespace MaterialEditor
MaterialViewportNotificationBus::Broadcast(&MaterialViewportNotificationBus::Events::OnLightingPresetAdded, presetPtr);
if (preset.m_autoSelect || m_lightingPresetVector.size() == 1)
if (m_lightingPresetVector.size() == 1)
{
SelectLightingPreset(presetPtr);
}
@@ -373,7 +373,7 @@ namespace MaterialEditor
MaterialViewportNotificationBus::Broadcast(&MaterialViewportNotificationBus::Events::OnModelPresetAdded, presetPtr);
if (preset.m_autoSelect || m_modelPresetVector.size() == 1)
if (m_modelPresetVector.size() == 1)
{
SelectModelPreset(presetPtr);
}
@@ -510,6 +510,13 @@ namespace MaterialEditor
void MaterialViewportComponent::OnCatalogLoaded([[maybe_unused]] const char* catalogFile)
{
AZ::TickBus::QueueFunction([this]() { ReloadContent(); });
AZ::TickBus::QueueFunction([this]() {
ReloadContent();
// Automatically select preferred default presets if they exist
// We will later data drive this with editor settings
SelectLightingPresetByName("Neutral Urban");
SelectModelPresetByName("Shader Ball");
});
}
}
@@ -10,36 +10,32 @@
*
*/
#include <AzQtComponents/Utilities/DesktopUtilities.h>
#include <AzToolsFramework/AssetBrowser/AssetBrowserModel.h>
#include <AzToolsFramework/AssetBrowser/AssetBrowserFilterModel.h>
#include <AzToolsFramework/AssetBrowser/Views/AssetBrowserTreeView.h>
#include <AzToolsFramework/AssetBrowser/AssetBrowserEntry.h>
#include <AzToolsFramework/AssetBrowser/Search/Filter.h>
#include <AzToolsFramework/AssetBrowser/AssetSelectionModel.h>
#include <AzToolsFramework/AssetBrowser/AssetBrowserBus.h>
#include <Atom/RPI.Reflect/Material/MaterialAsset.h>
#include <Atom/RPI.Reflect/Image/StreamingImageAsset.h>
#include <Atom/Document/MaterialDocumentSystemRequestBus.h>
#include <Atom/Document/MaterialDocumentRequestBus.h>
#include <Atom/Document/MaterialDocumentSystemRequestBus.h>
#include <Atom/RPI.Reflect/Image/StreamingImageAsset.h>
#include <Atom/RPI.Reflect/Material/MaterialAsset.h>
#include <AzQtComponents/Utilities/DesktopUtilities.h>
#include <AzToolsFramework/AssetBrowser/AssetBrowserBus.h>
#include <AzToolsFramework/AssetBrowser/AssetBrowserEntry.h>
#include <AzToolsFramework/AssetBrowser/AssetBrowserFilterModel.h>
#include <AzToolsFramework/AssetBrowser/AssetBrowserModel.h>
#include <AzToolsFramework/AssetBrowser/AssetSelectionModel.h>
#include <AzToolsFramework/AssetBrowser/Search/Filter.h>
#include <AzToolsFramework/AssetBrowser/Views/AssetBrowserTreeView.h>
#include <Source/Window/MaterialBrowserWidget.h>
#include <Source/Window/ui_MaterialBrowserWidget.h>
AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option") // disable warnings spawned by QT
#include <QDesktopServices>
#include <QUrl>
#include <QMessageBox>
#include <QMenu>
#include <QAction>
#include <QCursor>
#include <QPushButton>
#include <QList>
#include <QByteArray>
#include <QCursor>
#include <QDesktopServices>
#include <QList>
#include <QMenu>
#include <QMessageBox>
#include <QPushButton>
#include <QUrl>
AZ_POP_DISABLE_WARNING
namespace MaterialEditor
@@ -73,7 +69,7 @@ namespace MaterialEditor
m_filterModel->SetFilter(CreateFilter());
m_ui->m_assetBrowserTreeViewWidget->setModel(m_filterModel);
m_ui->m_assetBrowserTreeViewWidget->SetShowSourceControlIcons(true);
m_ui->m_assetBrowserTreeViewWidget->SetShowSourceControlIcons(false);
m_ui->m_assetBrowserTreeViewWidget->setSelectionMode(QAbstractItemView::SelectionMode::ExtendedSelection);
// Maintains the tree expansion state between runs
@@ -99,7 +95,6 @@ namespace MaterialEditor
}
});
AssetBrowserModelNotificationBus::Handler::BusConnect();
MaterialDocumentNotificationBus::Handler::BusConnect();
}
@@ -108,7 +103,7 @@ namespace MaterialEditor
// Maintains the tree expansion state between runs
m_ui->m_assetBrowserTreeViewWidget->SaveState();
MaterialDocumentNotificationBus::Handler::BusDisconnect();
AssetBrowserModelNotificationBus::Handler::BusDisconnect();
AZ::TickBus::Handler::BusDisconnect();
}
AzToolsFramework::AssetBrowser::FilterConstType MaterialBrowserWidget::CreateFilter() const
@@ -151,72 +146,65 @@ namespace MaterialEditor
for (const AssetBrowserEntry* entry : entries)
{
const SourceAssetBrowserEntry* sourceEntry = azrtti_cast<const SourceAssetBrowserEntry*>(entry);
if (!sourceEntry)
if (entry)
{
const ProductAssetBrowserEntry* productEntry = azrtti_cast<const ProductAssetBrowserEntry*>(entry);
if (productEntry)
if (AzFramework::StringFunc::Path::IsExtension(entry->GetFullPath().c_str(), MaterialExtension))
{
sourceEntry = azrtti_cast<const SourceAssetBrowserEntry*>(productEntry->GetParent());
MaterialDocumentSystemRequestBus::Broadcast(&MaterialDocumentSystemRequestBus::Events::OpenDocument, entry->GetFullPath());
}
}
if (sourceEntry)
{
if (AzFramework::StringFunc::Path::IsExtension(sourceEntry->GetFullPath().c_str(), MaterialExtension))
{
MaterialDocumentSystemRequestBus::Broadcast(&MaterialDocumentSystemRequestBus::Events::OpenDocument, sourceEntry->GetFullPath());
}
else if (AzFramework::StringFunc::Path::IsExtension(sourceEntry->GetFullPath().c_str(), MaterialTypeExtension))
else if (AzFramework::StringFunc::Path::IsExtension(entry->GetFullPath().c_str(), MaterialTypeExtension))
{
//ignore MaterialTypeExtension
}
else
{
QDesktopServices::openUrl(QUrl::fromLocalFile(sourceEntry->GetFullPath().c_str()));
QDesktopServices::openUrl(QUrl::fromLocalFile(entry->GetFullPath().c_str()));
}
}
}
}
void MaterialBrowserWidget::EntryAdded(const AssetBrowserEntry* entry)
{
if (m_pathToSelect.empty())
{
return;
}
const SourceAssetBrowserEntry* sourceEntry = azrtti_cast<const SourceAssetBrowserEntry*>(entry);
if (!sourceEntry)
{
const ProductAssetBrowserEntry* productEntry = azrtti_cast<const ProductAssetBrowserEntry*>(entry);
if (productEntry)
{
sourceEntry = azrtti_cast<const SourceAssetBrowserEntry*>(productEntry->GetParent());
}
}
if (sourceEntry)
{
AZStd::string sourcePath = sourceEntry->GetFullPath();
AzFramework::StringFunc::Path::Normalize(sourcePath);
if (m_pathToSelect == sourcePath)
{
m_ui->m_assetBrowserTreeViewWidget->SelectFileAtPath(m_pathToSelect);
m_pathToSelect.clear();
}
}
}
void MaterialBrowserWidget::OnDocumentOpened(const AZ::Uuid& documentId)
{
AZStd::string absolutePath;
MaterialDocumentRequestBus::EventResult(absolutePath, documentId, &MaterialDocumentRequestBus::Events::GetAbsolutePath);
if (!absolutePath.empty())
{
// Selecting a new asset in the browser is not guaranteed to happen immediately.
// The asset browser model notifications are sent before the model is updated.
// Instead of relying on the notifications, queue the selection and process it on tick until this change occurs.
m_pathToSelect = absolutePath;
AzFramework::StringFunc::Path::Normalize(m_pathToSelect);
m_ui->m_assetBrowserTreeViewWidget->SelectFileAtPath(m_pathToSelect);
AZ::TickBus::Handler::BusConnect();
}
}
void MaterialBrowserWidget::OnTick(float deltaTime, AZ::ScriptTimePoint time)
{
AZ_UNUSED(time);
AZ_UNUSED(deltaTime);
if (!m_pathToSelect.empty())
{
// Attempt to select the new path
AzToolsFramework::AssetBrowser::AssetBrowserViewRequestBus::Broadcast(
&AzToolsFramework::AssetBrowser::AssetBrowserViewRequestBus::Events::SelectFileAtPath, m_pathToSelect);
// Iterate over the selected entries to verify if the selection was made
for (const AssetBrowserEntry* entry : m_ui->m_assetBrowserTreeViewWidget->GetSelectedAssets())
{
if (entry)
{
AZStd::string sourcePath = entry->GetFullPath();
AzFramework::StringFunc::Path::Normalize(sourcePath);
if (m_pathToSelect == sourcePath)
{
// Once the selection is confirmed, cancel the operation and disconnect
AZ::TickBus::Handler::BusDisconnect();
m_pathToSelect.clear();
}
}
}
}
}
@@ -13,11 +13,11 @@
#pragma once
#if !defined(Q_MOC_RUN)
#include <Atom/Document/MaterialDocumentNotificationBus.h>
#include <AzCore/Component/TickBus.h>
#include <AzToolsFramework/AssetBrowser/AssetBrowserBus.h>
#include <AzToolsFramework/AssetBrowser/Search/Filter.h>
#include <AzToolsFramework/AssetBrowser/Entries/AssetBrowserEntry.h>
#include <AzToolsFramework/AssetBrowser/Search/Filter.h>
#include <Atom/Document/MaterialDocumentNotificationBus.h>
AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option") // disable warnings spawned by QT
#include <QWidget>
@@ -26,8 +26,6 @@ AZ_POP_DISABLE_WARNING
#endif
namespace AzToolsFramework
{
namespace AssetBrowser
@@ -50,8 +48,8 @@ namespace MaterialEditor
//! Provides a tree view of all available materials and other assets exposed by the MaterialEditor.
class MaterialBrowserWidget
: public QWidget
, public AzToolsFramework::AssetBrowser::AssetBrowserModelNotificationBus::Handler
, public MaterialDocumentNotificationBus::Handler
, protected AZ::TickBus::Handler
, protected MaterialDocumentNotificationBus::Handler
{
Q_OBJECT
public:
@@ -62,20 +60,20 @@ namespace MaterialEditor
AzToolsFramework::AssetBrowser::FilterConstType CreateFilter() const;
void OpenSelectedEntries();
// MaterialDocumentNotificationBus::Handler implementation
void OnDocumentOpened(const AZ::Uuid& documentId) override;
// AZ::TickBus::Handler
void OnTick(float deltaTime, AZ::ScriptTimePoint time) override;
void OpenOptionsMenu();
QScopedPointer<Ui::MaterialBrowserWidget> m_ui;
AzToolsFramework::AssetBrowser::AssetBrowserFilterModel* m_filterModel = nullptr;
//! if new asset is being created with this path it will automatically be selected
AZStd::string m_pathToSelect;
// AssetBrowserModelNotificationBus::Handler implementation
void EntryAdded(const AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry) override;
// MaterialDocumentNotificationBus::Handler implementation
void OnDocumentOpened(const AZ::Uuid& documentId) override;
void OpenOptionsMenu();
QByteArray m_materialBrowserState;
};
} // namespace MaterialEditor
@@ -1,7 +1,6 @@
{
"configurations": [
{
"autoSelect": false,
"displayName": "Photo Studio 01",
"skyboxImageAsset": {
"assetId": {
@@ -64,7 +63,6 @@
"shadowCatcherOpacity": 0.25
},
{
"autoSelect": false,
"displayName": "Photo Studio 01 (Alt)",
"skyboxImageAsset": {
"assetId": {
@@ -212,19 +212,26 @@ namespace AZ
void AtomActorInstance::SetModelAsset([[maybe_unused]] Data::Asset<RPI::ModelAsset> modelAsset)
{
// Atom Actor Instance is not based on an actual Model Asset yet,
// it's created at runtime from an Actor Asset.
// Changing model asset is not supported by Atom Actor Instance.
// The model asset is obtained from the Actor inside the ActorAsset,
// which is passed to the constructor. To set a different model asset
// this instance should use a different Actor.
AZ_Assert(false, "AtomActorInstance::SetModelAsset not supported");
}
const Data::Asset<RPI::ModelAsset>& AtomActorInstance::GetModelAsset() const
{
return m_skinnedMeshInstance->m_model->GetModelAsset();
AZ_Assert(GetActor(), "Expecting a Atom Actor Instance having a valid Actor.");
return GetActor()->GetMeshAsset();
}
void AtomActorInstance::SetModelAssetId([[maybe_unused]] Data::AssetId modelAssetId)
{
// Atom Actor Instance is not based on an actual Model Asset yet,
// it's created at runtime from an Actor Asset.
// Changing model asset is not supported by Atom Actor Instance.
// The model asset is obtained from the Actor inside the ActorAsset,
// which is passed to the constructor. To set a different model asset
// this instance should use a different Actor.
AZ_Assert(false, "AtomActorInstance::SetModelAssetId not supported");
}
Data::AssetId AtomActorInstance::GetModelAssetId() const
@@ -234,8 +241,11 @@ namespace AZ
void AtomActorInstance::SetModelAssetPath([[maybe_unused]] const AZStd::string& modelAssetPath)
{
// Atom Actor Instance is not based on an actual Model Asset yet,
// it's created at runtime from an Actor Asset.
// Changing model asset is not supported by Atom Actor Instance.
// The model asset is obtained from the Actor inside the ActorAsset,
// which is passed to the constructor. To set a different model asset
// this instance should use a different Actor.
AZ_Assert(false, "AtomActorInstance::SetModelAssetPath not supported");
}
AZStd::string AtomActorInstance::GetModelAssetPath() const
@@ -278,28 +288,6 @@ namespace AZ
return IsVisible();
}
void AtomActorInstance::SetMeshAsset(const AZ::Data::AssetId& id)
{
AZ::Data::Asset<EMotionFX::Integration::ActorAsset> asset =
AZ::Data::AssetManager::Instance().GetAsset<EMotionFX::Integration::ActorAsset>(
id, m_actorAsset.GetAutoLoadBehavior());
if (asset)
{
m_actorAsset = asset;
Create();
}
}
AZ::Data::Asset<AZ::Data::AssetData> AtomActorInstance::GetMeshAsset()
{
return m_actorAsset;
}
bool AtomActorInstance::GetVisibility()
{
return static_cast<const AtomActorInstance&>(*this).GetVisibility();
}
AZ::u32 AtomActorInstance::GetJointCount()
{
return m_actorInstance->GetActor()->GetSkeleton()->GetNumNodes();
@@ -469,7 +457,6 @@ namespace AZ
TransformNotificationBus::Handler::BusConnect(m_entityId);
MaterialComponentNotificationBus::Handler::BusConnect(m_entityId);
MeshComponentRequestBus::Handler::BusConnect(m_entityId);
LmbrCentral::MeshComponentRequestBus::Handler::BusConnect(m_entityId);
const Data::Instance<RPI::Model> model = m_meshFeatureProcessor->GetModel(*m_meshHandle);
MeshComponentNotificationBus::Event(m_entityId, &MeshComponentNotificationBus::Events::OnModelReady, model->GetModelAsset(), model);
@@ -479,7 +466,6 @@ namespace AZ
{
MeshComponentNotificationBus::Event(m_entityId, &MeshComponentNotificationBus::Events::OnModelPreDestroy);
LmbrCentral::MeshComponentRequestBus::Handler::BusDisconnect();
MeshComponentRequestBus::Handler::BusDisconnect();
MaterialComponentNotificationBus::Handler::BusDisconnect();
TransformNotificationBus::Handler::BusDisconnect();
@@ -62,7 +62,6 @@ namespace AZ
, public AzFramework::BoundsRequestBus::Handler
, public AZ::Render::MaterialComponentNotificationBus::Handler
, public AZ::Render::MeshComponentRequestBus::Handler
, public LmbrCentral::MeshComponentRequestBus::Handler
, private AZ::Render::SkinnedMeshFeatureProcessorNotificationBus::Handler
, private AZ::Render::SkinnedMeshOutputStreamNotificationBus::Handler
, private LmbrCentral::SkeletalHierarchyRequestBus::Handler
@@ -143,14 +142,6 @@ namespace AZ
bool GetVisibility() const override;
// GetWorldBounds/GetLocalBounds already overridden by BoundsRequestBus::Handler
//////////////////////////////////////////////////////////////////////////
// LmbrCentral::MeshComponentRequestBus::Handler
void SetMeshAsset(const AZ::Data::AssetId& id) override;
AZ::Data::Asset<AZ::Data::AssetData> GetMeshAsset() override;
bool GetVisibility() override;
// SetVisibility already overridden by MeshComponentRequestBus::Handler
// GetWorldBounds/GetLocalBounds already overridden by BoundsRequestBus::Handler
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SkeletalHierarchyRequestBus::Handler overrides...
AZ::u32 GetJointCount() override;
+1 -1
View File
@@ -69,4 +69,4 @@ namespace Blast
// DO NOT MODIFY THIS LINE UNLESS YOU RENAME THE GEM
// The first parameter should be GemName_GemIdLower
// The second should be the fully qualified name of the class above
AZ_DECLARE_MODULE_CLASS(Blast_414bd211c99d4f74aef3a266b9ca208c, Blast::BlastModule)
AZ_DECLARE_MODULE_CLASS(Gem_Blast, Blast::BlastModule)
@@ -14,4 +14,4 @@
// DO NOT MODIFY THIS LINE UNLESS YOU RENAME THE GEM
// The first parameter should be GemName_GemIdLower
// The second should be the fully qualified name of the class above
AZ_DECLARE_MODULE_CLASS(Blast_414bd211c99d4f74aef3a266b9ca208c, AZ::Module)
AZ_DECLARE_MODULE_CLASS(Gem_Blast, AZ::Module)
+2 -2
View File
@@ -9,5 +9,5 @@ remove or modify any license notices. This file is distributed on an "AS IS" BAS
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
import asset_builder_blast
# LYN-652 to re-enable the next line
# import asset_builder_blast
@@ -229,7 +229,7 @@ namespace EMotionFX
void MakeLoopable(float fadeTime = 0.3f);
/**
* Optimize the keytrack by removing redundent frames.
* Optimize the keytrack by removing redundant frames.
* The way this is done is by comparing differences between the resulting curves when removing specific keyframes.
* If the error (difference) between those curve before and after keyframe removal is within a given maximum error value, the keyframe can be
* safely removed since there will not be much "visual" difference.
@@ -346,13 +346,20 @@ namespace EMotionFX
void AnimGraphComponent::CreateSnapshot(bool isAuthoritative)
{
AZ_Error("EMotionFX", m_animGraphInstance, "Call create snapshot function only when anim graph is ready in this component.");
m_animGraphInstance->CreateSnapshot(isAuthoritative);
m_animGraphInstance->OnNetworkConnected();
if (m_animGraphInstance)
{
m_animGraphInstance->CreateSnapshot(isAuthoritative);
m_animGraphInstance->OnNetworkConnected();
// This will stop the MCore Job schedule update the actor instance and anim graph for authoritative entity.
// After doing so, we will have to update this actor manuelly in the networking update.
m_animGraphInstance->GetActorInstance()->SetIsEnabled(!isAuthoritative);
// This will stop the MCore Job schedule update the actor instance and anim graph for authoritative entity.
// After doing so, we will have to update this actor manually in the networking update.
m_animGraphInstance->GetActorInstance()->SetIsEnabled(!isAuthoritative);
}
else
{
AZ_Error("EMotionFX", false, "Cannot create snapshot as anim graph instance has not been created yet. "
"Please make sure you selected an anim graph in the anim graph component.");
}
}
void AnimGraphComponent::SetActiveStates(const AZStd::vector<AZ::u32>& activeStates)
@@ -437,5 +437,7 @@ namespace GraphCanvas
default:
return QGraphicsWidget::sizeHint(which, constraint);
}
return QGraphicsWidget::sizeHint(which, constraint);
}
}
@@ -1,362 +1,172 @@
<ObjectStream version="3">
<Class name="SceneManifest" version="1" type="{9274AD17-3212-4651-9F3B-7DCCB080E467}">
<Class name="AZStd::vector" field="values" type="{5D6A7C67-11CA-59A4-829B-0B20B781B292}">
<Class name="AZStd::shared_ptr" field="element" type="{EB7522F9-0E87-55A9-A191-E924DC5AE867}">
<Class name="ActorGroup" field="element" version="4" type="{D1AC3803-8282-46C5-8610-93CD39B0F843}">
<Class name="IActorGroup" field="BaseClass1" version="2" type="{C86945A8-AEE8-4CFC-8FBF-A20E9BC71348}">
<Class name="ISceneNodeGroup" field="BaseClass1" version="1" type="{1D20FA11-B184-429E-8C86-745852234845}">
<Class name="IGroup" field="BaseClass1" version="1" type="{DE008E67-790D-4672-A73A-5CA0F31EDD2D}">
<Class name="IManifestObject" field="BaseClass1" type="{3B839407-1884-4FF4-ABEA-CA9D347E83F7}"/>
</Class>
</Class>
</Class>
<Class name="AZStd::string" field="name" value="chicken" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="selectedRootBone" value="" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="SceneNodeSelectionList" field="nodeSelectionList" version="1" type="{D0CE66CE-1BAD-42F5-86ED-3923573B3A02}">
<Class name="ISceneNodeSelectionList" field="BaseClass1" version="1" type="{DC3F9996-E550-4780-A03B-80B0DDA1DA45}"/>
<Class name="AZStd::vector" field="selectedNodes" type="{99DAD0BC-740E-5E82-826B-8FC7968CC02C}">
<Class name="AZStd::string" field="element" value="RootNode.chicken_feet_skin" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_eyes_skin" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_body_skin" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_mohawk" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_feet_skin.SkinWeight_0" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_feet_skin.map1" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_feet_skin.chicken_body_mat" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_eyes_skin.SkinWeight_0" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_eyes_skin.uvSet1" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_eyes_skin.chicken_eye_mat" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_body_skin.SkinWeight_0" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_body_skin.map1" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_body_skin.chicken_body_mat" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_mohawk.SkinWeight_0" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_mohawk.colorSet1" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_mohawk.map1" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_mohawk.mohawkMat" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
</Class>
<Class name="AZStd::vector" field="unselectedNodes" type="{99DAD0BC-740E-5E82-826B-8FC7968CC02C}">
<Class name="AZStd::string" field="element" value="RootNode" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.transform" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.transform" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.transform" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_l_uprLeg_joint" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_r_uprLeg_joint" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.transform" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_l_uprLeg_joint.transform" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_l_uprLeg_joint.def_l_lwrLeg_joint" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_r_uprLeg_joint.transform" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_r_uprLeg_joint.def_r_lwrLeg_joint" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.transform" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_c_spine_end" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_l_wing1_joint" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_r_wing1_joint" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_l_uprLeg_joint.def_l_lwrLeg_joint.transform" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_l_uprLeg_joint.def_l_lwrLeg_joint.def_l_foot_joint" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_r_uprLeg_joint.def_r_lwrLeg_joint.transform" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_r_uprLeg_joint.def_r_lwrLeg_joint.def_r_foot_joint" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_c_spine_end.transform" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_c_spine_end.def_c_tail1_joint" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_c_spine_end.def_c_neck_joint" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_l_wing1_joint.transform" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_l_wing1_joint.def_l_wing2_joint" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_r_wing1_joint.transform" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_r_wing1_joint.def_r_wing2_joint" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_l_uprLeg_joint.def_l_lwrLeg_joint.def_l_foot_joint.transform" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_l_uprLeg_joint.def_l_lwrLeg_joint.def_l_foot_joint.def_l_ball_joint" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_r_uprLeg_joint.def_r_lwrLeg_joint.def_r_foot_joint.transform" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_r_uprLeg_joint.def_r_lwrLeg_joint.def_r_foot_joint.def_r_ball_joint" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_c_spine_end.def_c_tail1_joint.transform" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_c_spine_end.def_c_tail1_joint.def_c_tail2_joint" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_c_spine_end.def_c_neck_joint.transform" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_c_spine_end.def_c_neck_joint.def_c_head_joint" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_l_wing1_joint.def_l_wing2_joint.transform" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_l_wing1_joint.def_l_wing2_joint.def_l_wing_end" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_r_wing1_joint.def_r_wing2_joint.transform" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_r_wing1_joint.def_r_wing2_joint.def_r_wing_end" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_l_uprLeg_joint.def_l_lwrLeg_joint.def_l_foot_joint.def_l_ball_joint.transform" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_r_uprLeg_joint.def_r_lwrLeg_joint.def_r_foot_joint.def_r_ball_joint.transform" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_c_spine_end.def_c_tail1_joint.def_c_tail2_joint.transform" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_c_spine_end.def_c_neck_joint.def_c_head_joint.transform" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_c_spine_end.def_c_neck_joint.def_c_head_joint.def_c_feather1_joint" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_c_spine_end.def_c_neck_joint.def_c_head_joint.def_c_mouth_joint" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_c_spine_end.def_c_neck_joint.def_c_head_joint.def_c_waddle1_joint" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_l_wing1_joint.def_l_wing2_joint.def_l_wing_end.transform" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_r_wing1_joint.def_r_wing2_joint.def_r_wing_end.transform" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_c_spine_end.def_c_neck_joint.def_c_head_joint.def_c_feather1_joint.transform" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_c_spine_end.def_c_neck_joint.def_c_head_joint.def_c_feather1_joint.def_c_feather2_joint" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_c_spine_end.def_c_neck_joint.def_c_head_joint.def_c_mouth_joint.transform" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_c_spine_end.def_c_neck_joint.def_c_head_joint.def_c_mouth_joint.def_c_mouth_end" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_c_spine_end.def_c_neck_joint.def_c_head_joint.def_c_waddle1_joint.transform" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_c_spine_end.def_c_neck_joint.def_c_head_joint.def_c_waddle1_joint.def_c_waddle2_joint" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_c_spine_end.def_c_neck_joint.def_c_head_joint.def_c_feather1_joint.def_c_feather2_joint.transform" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_c_spine_end.def_c_neck_joint.def_c_head_joint.def_c_feather1_joint.def_c_feather2_joint.def_c_feather3_joint" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_c_spine_end.def_c_neck_joint.def_c_head_joint.def_c_mouth_joint.def_c_mouth_end.transform" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_c_spine_end.def_c_neck_joint.def_c_head_joint.def_c_waddle1_joint.def_c_waddle2_joint.transform" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_c_spine_end.def_c_neck_joint.def_c_head_joint.def_c_waddle1_joint.def_c_waddle2_joint.def_c_waddle3_joint" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_c_spine_end.def_c_neck_joint.def_c_head_joint.def_c_feather1_joint.def_c_feather2_joint.def_c_feather3_joint.transform" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_c_spine_end.def_c_neck_joint.def_c_head_joint.def_c_feather1_joint.def_c_feather2_joint.def_c_feather3_joint.def_c_feather4_joint" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_c_spine_end.def_c_neck_joint.def_c_head_joint.def_c_waddle1_joint.def_c_waddle2_joint.def_c_waddle3_joint.transform" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_c_spine_end.def_c_neck_joint.def_c_head_joint.def_c_waddle1_joint.def_c_waddle2_joint.def_c_waddle3_joint.def_c_waddle_end" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_c_spine_end.def_c_neck_joint.def_c_head_joint.def_c_feather1_joint.def_c_feather2_joint.def_c_feather3_joint.def_c_feather4_joint.transform" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_c_spine_end.def_c_neck_joint.def_c_head_joint.def_c_feather1_joint.def_c_feather2_joint.def_c_feather3_joint.def_c_feather4_joint.def_c_feather_end" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_c_spine_end.def_c_neck_joint.def_c_head_joint.def_c_waddle1_joint.def_c_waddle2_joint.def_c_waddle3_joint.def_c_waddle_end.transform" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="element" value="RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_c_spine_end.def_c_neck_joint.def_c_head_joint.def_c_feather1_joint.def_c_feather2_joint.def_c_feather3_joint.def_c_feather4_joint.def_c_feather_end.transform" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
</Class>
</Class>
<Class name="AZ::Uuid" field="id" value="{C086F309-EE7E-5AFD-A9C2-69DE5BA48461}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
<Class name="RuleContainer" field="rules" version="1" type="{2C20D3DF-57FF-4A31-8680-A4D45302B9CF}">
<Class name="AZStd::vector" field="rules" type="{B5BDB053-178F-5D55-8663-70897A71B7C9}">
<Class name="AZStd::shared_ptr" field="element" type="{0BB4AFBA-F087-55C7-95DF-01D71F6CB052}">
<Class name="CoordinateSystemRule" field="element" version="1" type="{603207E2-4F55-4C33-9AAB-98CA75C1E351}">
<Class name="IRule" field="BaseClass1" version="1" type="{81267F8B-3963-423B-9FF7-D276D82CD110}">
<Class name="IManifestObject" field="BaseClass1" type="{3B839407-1884-4FF4-ABEA-CA9D347E83F7}"/>
</Class>
<Class name="int" field="targetCoordinateSystem" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
</Class>
</Class>
<Class name="AZStd::shared_ptr" field="element" type="{0BB4AFBA-F087-55C7-95DF-01D71F6CB052}">
<Class name="TangentsRule" field="element" version="1" type="{4BD1CE13-D2EB-4CCF-AB21-4877EF69DE7D}">
<Class name="IRule" field="BaseClass1" version="1" type="{81267F8B-3963-423B-9FF7-D276D82CD110}">
<Class name="IManifestObject" field="BaseClass1" type="{3B839407-1884-4FF4-ABEA-CA9D347E83F7}"/>
</Class>
<Class name="int" field="tangentSpace" value="1" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
<Class name="int" field="bitangentMethod" value="1" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
<Class name="bool" field="normalize" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
<Class name="AZ::u64" field="uvSetIndex" value="0" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
</Class>
</Class>
<Class name="AZStd::shared_ptr" field="element" type="{0BB4AFBA-F087-55C7-95DF-01D71F6CB052}">
<Class name="SkinRule" field="element" version="2" type="{B26E7FC9-86A1-4711-8415-8BE4861C08BA}">
<Class name="ISkinRule" field="BaseClass1" version="1" type="{5496ECAF-B096-4455-AE72-D55C5B675443}">
<Class name="IRule" field="BaseClass1" version="1" type="{81267F8B-3963-423B-9FF7-D276D82CD110}">
<Class name="IManifestObject" field="BaseClass1" type="{3B839407-1884-4FF4-ABEA-CA9D347E83F7}"/>
</Class>
</Class>
<Class name="unsigned int" field="maxWeightsPerVertex" value="4" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
<Class name="float" field="weightThreshold" value="0.0010000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
</Class>
</Class>
<Class name="AZStd::shared_ptr" field="element" type="{0BB4AFBA-F087-55C7-95DF-01D71F6CB052}">
<Class name="MeshRule" field="element" version="4" type="{7F115A73-28A2-4E35-8C87-1A1982773034}">
<Class name="IMeshRule" field="BaseClass1" version="1" type="{299934A2-22EC-48AF-AB2B-953AFF8E0B19}">
<Class name="IRule" field="BaseClass1" version="1" type="{81267F8B-3963-423B-9FF7-D276D82CD110}">
<Class name="IManifestObject" field="BaseClass1" type="{3B839407-1884-4FF4-ABEA-CA9D347E83F7}"/>
</Class>
</Class>
<Class name="AZStd::string" field="vertexColorStreamName" value="" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="unsigned char" field="vertexColorMode" value="0" type="{72B9409A-7D1A-4831-9CFE-FCB3FADD3426}"/>
</Class>
</Class>
<Class name="AZStd::shared_ptr" field="element" type="{0BB4AFBA-F087-55C7-95DF-01D71F6CB052}">
<Class name="ClothRule" field="element" version="2" type="{2F5AC324-314A-4C53-AFFF-DDFA46605DDB}">
<Class name="IClothRule" field="BaseClass1" version="1" type="{5185510A-50BF-418A-ACB4-1A9E014C7E43}">
<Class name="IRule" field="BaseClass1" version="1" type="{81267F8B-3963-423B-9FF7-D276D82CD110}">
<Class name="IManifestObject" field="BaseClass1" type="{3B839407-1884-4FF4-ABEA-CA9D347E83F7}"/>
</Class>
</Class>
<Class name="AZStd::string" field="meshNodeName" value="RootNode.chicken_mohawk" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::string" field="inverseMassesStreamName" value="colorSet1" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="unsigned char" field="inverseMassesChannel" value="0" type="{72B9409A-7D1A-4831-9CFE-FCB3FADD3426}"/>
<Class name="AZStd::string" field="motionConstraintsStreamName" value="Default: 1.0" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="unsigned char" field="motionConstraintsChannel" value="0" type="{72B9409A-7D1A-4831-9CFE-FCB3FADD3426}"/>
<Class name="AZStd::string" field="backstopStreamName" value="None" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="unsigned char" field="backstopOffsetChannel" value="0" type="{72B9409A-7D1A-4831-9CFE-FCB3FADD3426}"/>
<Class name="unsigned char" field="backstopRadiusChannel" value="1" type="{72B9409A-7D1A-4831-9CFE-FCB3FADD3426}"/>
</Class>
</Class>
<Class name="AZStd::shared_ptr" field="element" type="{0BB4AFBA-F087-55C7-95DF-01D71F6CB052}">
<Class name="MetaDataRule" field="element" version="2" type="{8D759063-7D2E-4543-8EB3-AB510A5886CF}">
<Class name="IManifestObject" field="BaseClass1" type="{3B839407-1884-4FF4-ABEA-CA9D347E83F7}"/>
<Class name="AZStd::vector" field="commands" type="{C9984A24-DA9E-518F-9F81-27E51FAEB1F7}"/>
<Class name="AZStd::string" field="metaData" value='AdjustActor -actorID $(ACTORID) -name "chicken"
ActorSetCollisionMeshes -actorID $(ACTORID) -lod 0 -nodeList ""
AdjustActor -actorID $(ACTORID) -nodesExcludedFromBounds "" -nodeAction "select"
AdjustActor -actorID $(ACTORID) -nodeAction "replace" -attachmentNodes ""
' type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
</Class>
</Class>
<Class name="AZStd::shared_ptr" field="element" type="{0BB4AFBA-F087-55C7-95DF-01D71F6CB052}">
<Class name="ActorPhysicsSetupRule" field="element" version="1" type="{B18E9412-85DC-442D-9AA3-293B583EC1A6}">
<Class name="AZStd::shared_ptr" field="data" type="{40A77278-7D0F-51EB-A537-72AE8478D1C0}">
<Class name="PhysicsSetup" field="element" version="4" type="{4749DFCB-5CBE-434D-9551-34F4C0CCA428}">
<Class name="AnimationConfiguration" field="config" version="3" type="{6D53168F-470E-4B41-986A-612506F09B40}">
<Class name="CharacterColliderConfiguration" field="hitDetectionConfig" version="1" type="{4DFF1434-DF5B-4ED5-BE0F-D3E66F9B331A}">
<Class name="AZStd::vector" field="nodes" type="{70C9FE19-65A8-5FA9-A447-7561B0C9FA9A}"/>
</Class>
<Class name="RagdollConfiguration" field="ragdollConfig" version="2" type="{7C96D332-61D8-4C58-A2BF-707716D38D14}">
<Class name="WorldBodyConfiguration" field="BaseClass1" version="1" type="{6EEB377C-DC60-4E10-AF12-9626C0763B2D}">
<Class name="AZStd::string" field="name" value="" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
</Class>
<Class name="AZStd::vector" field="nodes" type="{023260FD-3D32-570B-A75E-4099359BE960}"/>
<Class name="CharacterColliderConfiguration" field="colliders" version="1" type="{4DFF1434-DF5B-4ED5-BE0F-D3E66F9B331A}">
<Class name="AZStd::vector" field="nodes" type="{70C9FE19-65A8-5FA9-A447-7561B0C9FA9A}"/>
</Class>
</Class>
<Class name="CharacterColliderConfiguration" field="clothConfig" version="1" type="{4DFF1434-DF5B-4ED5-BE0F-D3E66F9B331A}">
<Class name="AZStd::vector" field="nodes" type="{70C9FE19-65A8-5FA9-A447-7561B0C9FA9A}">
<Class name="CharacterColliderNodeConfiguration" field="element" version="1" type="{C16F3301-0979-400C-B734-692D83755C39}">
<Class name="AZStd::string" field="name" value="def_c_head_joint" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::vector" field="shapes" type="{EDCE8AC7-3324-5A75-9B44-27983A0CBFDB}">
<Class name="AZStd::pair" field="element" type="{9EEDBBE5-F74D-528D-8089-580876B248C5}">
<Class name="AZStd::shared_ptr" field="value1" type="{FBE2C86C-C034-57E1-A1A3-9066B3F60C0E}">
<Class name="ColliderConfiguration" field="element" version="4" type="{16206828-F867-4DA9-9E4E-549B7B2C6174}">
<Class name="CollisionLayer" field="CollisionLayer" version="1" type="{5AA459C8-2D92-46D2-9154-ED49EE4FE70E}">
<Class name="unsigned char" field="Index" value="0" type="{72B9409A-7D1A-4831-9CFE-FCB3FADD3426}"/>
</Class>
<Class name="Id" field="CollisionGroupId" version="1" type="{DFED4FE5-2292-4F07-A318-41C68DAEFE9C}">
<Class name="AZ::Uuid" field="GroupId" value="{00000000-0000-0000-0000-000000000000}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
</Class>
<Class name="bool" field="Visible" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
<Class name="bool" field="Trigger" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
<Class name="bool" field="Simulated" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
<Class name="bool" field="InSceneQueries" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
<Class name="bool" field="Exclusive" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
<Class name="Vector3" field="Position" value="-0.0850560 0.0000000 0.0093709" type="{8379EB7D-01FA-4538-B64B-A6543B4BE73D}"/>
<Class name="Quaternion" field="Rotation" value="0.7071437 0.0000000 0.0000000 0.7089844" type="{73103120-3DD3-4873-BAB3-9713FA2804FB}"/>
<Class name="MaterialSelection" field="MaterialSelection" version="2" type="{F571AFF4-C4BB-4590-A204-D11D9EEABBC4}">
<Class name="Asset" field="Material" value="id={00000000-0000-0000-0000-000000000000}:0,type={9E366D8C-33BB-4825-9A1F-FA3ADBE11D0F},hint={},loadBehavior=2" version="2" type="{77A19D40-8731-4D3C-9041-1B43047366A4}"/>
<Class name="AZStd::vector" field="MaterialIds" type="{82111EAD-9C65-57F0-BA72-46D6D931B434}">
<Class name="MaterialId" field="element" version="1" type="{744CCE6C-9F69-4E2F-B950-DAB8514F870B}">
<Class name="AZ::Uuid" field="MaterialId" value="{00000000-0000-0000-0000-000000000000}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
</Class>
</Class>
</Class>
<Class name="unsigned char" field="propertyVisibilityFlags" value="248" type="{72B9409A-7D1A-4831-9CFE-FCB3FADD3426}"/>
<Class name="AZStd::string" field="ColliderTag" value="" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="float" field="RestOffset" value="0.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
<Class name="float" field="ContactOffset" value="0.0200000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
</Class>
</Class>
<Class name="AZStd::shared_ptr" field="value2" type="{568500E4-F003-54B8-B728-711DB5DF0AE4}">
<Class name="CapsuleShapeConfiguration" field="element" version="1" type="{19C6A07E-5644-46B7-A49E-48703B56ED32}">
<Class name="ShapeConfiguration" field="BaseClass1" version="1" type="{1FD56C72-6055-4B35-9253-07D432B94E91}">
<Class name="Vector3" field="Scale" value="1.0000000 1.0000000 1.0000000" type="{8379EB7D-01FA-4538-B64B-A6543B4BE73D}"/>
</Class>
<Class name="float" field="Height" value="0.1912735" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
<Class name="float" field="Radius" value="0.0506367" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
</Class>
</Class>
</Class>
</Class>
</Class>
<Class name="CharacterColliderNodeConfiguration" field="element" version="1" type="{C16F3301-0979-400C-B734-692D83755C39}">
<Class name="AZStd::string" field="name" value="def_c_neck_joint" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::vector" field="shapes" type="{EDCE8AC7-3324-5A75-9B44-27983A0CBFDB}">
<Class name="AZStd::pair" field="element" type="{9EEDBBE5-F74D-528D-8089-580876B248C5}">
<Class name="AZStd::shared_ptr" field="value1" type="{FBE2C86C-C034-57E1-A1A3-9066B3F60C0E}">
<Class name="ColliderConfiguration" field="element" version="4" type="{16206828-F867-4DA9-9E4E-549B7B2C6174}">
<Class name="CollisionLayer" field="CollisionLayer" version="1" type="{5AA459C8-2D92-46D2-9154-ED49EE4FE70E}">
<Class name="unsigned char" field="Index" value="0" type="{72B9409A-7D1A-4831-9CFE-FCB3FADD3426}"/>
</Class>
<Class name="Id" field="CollisionGroupId" version="1" type="{DFED4FE5-2292-4F07-A318-41C68DAEFE9C}">
<Class name="AZ::Uuid" field="GroupId" value="{00000000-0000-0000-0000-000000000000}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
</Class>
<Class name="bool" field="Visible" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
<Class name="bool" field="Trigger" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
<Class name="bool" field="Simulated" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
<Class name="bool" field="InSceneQueries" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
<Class name="bool" field="Exclusive" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
<Class name="Vector3" field="Position" value="-0.0381019 0.0000000 -0.0313244" type="{8379EB7D-01FA-4538-B64B-A6543B4BE73D}"/>
<Class name="Quaternion" field="Rotation" value="0.0000000 0.0000000 0.0000000 1.0000000" type="{73103120-3DD3-4873-BAB3-9713FA2804FB}"/>
<Class name="MaterialSelection" field="MaterialSelection" version="2" type="{F571AFF4-C4BB-4590-A204-D11D9EEABBC4}">
<Class name="Asset" field="Material" value="id={00000000-0000-0000-0000-000000000000}:0,type={9E366D8C-33BB-4825-9A1F-FA3ADBE11D0F},hint={},loadBehavior=2" version="2" type="{77A19D40-8731-4D3C-9041-1B43047366A4}"/>
<Class name="AZStd::vector" field="MaterialIds" type="{82111EAD-9C65-57F0-BA72-46D6D931B434}">
<Class name="MaterialId" field="element" version="1" type="{744CCE6C-9F69-4E2F-B950-DAB8514F870B}">
<Class name="AZ::Uuid" field="MaterialId" value="{00000000-0000-0000-0000-000000000000}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
</Class>
</Class>
</Class>
<Class name="unsigned char" field="propertyVisibilityFlags" value="248" type="{72B9409A-7D1A-4831-9CFE-FCB3FADD3426}"/>
<Class name="AZStd::string" field="ColliderTag" value="" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="float" field="RestOffset" value="0.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
<Class name="float" field="ContactOffset" value="0.0200000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
</Class>
</Class>
<Class name="AZStd::shared_ptr" field="value2" type="{568500E4-F003-54B8-B728-711DB5DF0AE4}">
<Class name="SphereShapeConfiguration" field="element" version="1" type="{0B9F3D2E-0780-4B0B-BFEE-B41C5FDE774A}">
<Class name="ShapeConfiguration" field="BaseClass1" version="1" type="{1FD56C72-6055-4B35-9253-07D432B94E91}">
<Class name="Vector3" field="Scale" value="1.0000000 1.0000000 1.0000000" type="{8379EB7D-01FA-4538-B64B-A6543B4BE73D}"/>
</Class>
<Class name="float" field="Radius" value="0.1606994" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
</Class>
</Class>
</Class>
</Class>
</Class>
<Class name="CharacterColliderNodeConfiguration" field="element" version="1" type="{C16F3301-0979-400C-B734-692D83755C39}">
<Class name="AZStd::string" field="name" value="def_c_spine_end" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="AZStd::vector" field="shapes" type="{EDCE8AC7-3324-5A75-9B44-27983A0CBFDB}">
<Class name="AZStd::pair" field="element" type="{9EEDBBE5-F74D-528D-8089-580876B248C5}">
<Class name="AZStd::shared_ptr" field="value1" type="{FBE2C86C-C034-57E1-A1A3-9066B3F60C0E}">
<Class name="ColliderConfiguration" field="element" version="4" type="{16206828-F867-4DA9-9E4E-549B7B2C6174}">
<Class name="CollisionLayer" field="CollisionLayer" version="1" type="{5AA459C8-2D92-46D2-9154-ED49EE4FE70E}">
<Class name="unsigned char" field="Index" value="0" type="{72B9409A-7D1A-4831-9CFE-FCB3FADD3426}"/>
</Class>
<Class name="Id" field="CollisionGroupId" version="1" type="{DFED4FE5-2292-4F07-A318-41C68DAEFE9C}">
<Class name="AZ::Uuid" field="GroupId" value="{00000000-0000-0000-0000-000000000000}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
</Class>
<Class name="bool" field="Visible" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
<Class name="bool" field="Trigger" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
<Class name="bool" field="Simulated" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
<Class name="bool" field="InSceneQueries" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
<Class name="bool" field="Exclusive" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
<Class name="Vector3" field="Position" value="-0.0000002 0.0126462 -0.2410437" type="{8379EB7D-01FA-4538-B64B-A6543B4BE73D}"/>
<Class name="Quaternion" field="Rotation" value="0.0000000 0.0000000 0.0000000 1.0000000" type="{73103120-3DD3-4873-BAB3-9713FA2804FB}"/>
<Class name="MaterialSelection" field="MaterialSelection" version="2" type="{F571AFF4-C4BB-4590-A204-D11D9EEABBC4}">
<Class name="Asset" field="Material" value="id={00000000-0000-0000-0000-000000000000}:0,type={9E366D8C-33BB-4825-9A1F-FA3ADBE11D0F},hint={},loadBehavior=2" version="2" type="{77A19D40-8731-4D3C-9041-1B43047366A4}"/>
<Class name="AZStd::vector" field="MaterialIds" type="{82111EAD-9C65-57F0-BA72-46D6D931B434}">
<Class name="MaterialId" field="element" version="1" type="{744CCE6C-9F69-4E2F-B950-DAB8514F870B}">
<Class name="AZ::Uuid" field="MaterialId" value="{00000000-0000-0000-0000-000000000000}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
</Class>
</Class>
</Class>
<Class name="unsigned char" field="propertyVisibilityFlags" value="248" type="{72B9409A-7D1A-4831-9CFE-FCB3FADD3426}"/>
<Class name="AZStd::string" field="ColliderTag" value="" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
<Class name="float" field="RestOffset" value="0.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
<Class name="float" field="ContactOffset" value="0.0200000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
</Class>
</Class>
<Class name="AZStd::shared_ptr" field="value2" type="{568500E4-F003-54B8-B728-711DB5DF0AE4}">
<Class name="SphereShapeConfiguration" field="element" version="1" type="{0B9F3D2E-0780-4B0B-BFEE-B41C5FDE774A}">
<Class name="ShapeConfiguration" field="BaseClass1" version="1" type="{1FD56C72-6055-4B35-9253-07D432B94E91}">
<Class name="Vector3" field="Scale" value="1.0000000 1.0000000 1.0000000" type="{8379EB7D-01FA-4538-B64B-A6543B4BE73D}"/>
</Class>
<Class name="float" field="Radius" value="0.2487596" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
</Class>
</Class>
</Class>
</Class>
</Class>
</Class>
</Class>
<Class name="CharacterColliderConfiguration" field="simulatedObjectColliderConfig" version="1" type="{4DFF1434-DF5B-4ED5-BE0F-D3E66F9B331A}">
<Class name="AZStd::vector" field="nodes" type="{70C9FE19-65A8-5FA9-A447-7561B0C9FA9A}"/>
</Class>
</Class>
</Class>
</Class>
</Class>
</Class>
<Class name="AZStd::shared_ptr" field="element" type="{0BB4AFBA-F087-55C7-95DF-01D71F6CB052}">
<Class name="MaterialRule" field="element" version="2" type="{35620013-A27C-4F6D-87BF-72F11688ACAD}">
<Class name="IMaterialRule" field="BaseClass1" version="1" type="{428C9752-6EDF-4FA2-9BDF-DBDFCEB4CC0F}">
<Class name="IRule" field="BaseClass1" version="1" type="{81267F8B-3963-423B-9FF7-D276D82CD110}">
<Class name="IManifestObject" field="BaseClass1" type="{3B839407-1884-4FF4-ABEA-CA9D347E83F7}"/>
</Class>
</Class>
<Class name="bool" field="updateMaterials" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
<Class name="bool" field="removeMaterials" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
</Class>
</Class>
</Class>
</Class>
</Class>
</Class>
</Class>
</Class>
</ObjectStream>
{
"values": [
{
"$type": "ActorGroup",
"name": "chicken",
"id": "{C086F309-EE7E-5AFD-A9C2-69DE5BA48461}",
"rules": {
"rules": [
{
"$type": "MetaDataRule",
"metaData": "AdjustActor -actorID $(ACTORID) -name \"chicken\"\r\nActorSetCollisionMeshes -actorID $(ACTORID) -lod 0 -nodeList \"\"\r\nAdjustActor -actorID $(ACTORID) -nodesExcludedFromBounds \"\" -nodeAction \"select\"\r\nAdjustActor -actorID $(ACTORID) -nodeAction \"replace\" -attachmentNodes \"\"\r\n"
},
{
"$type": "ActorPhysicsSetupRule",
"data": {
"config": {
"clothConfig": {
"nodes": [
{
"name": "def_c_head_joint",
"shapes": [
[
{
"Visible": true,
"Position": [
-0.08505599945783615,
0.0,
0.009370899759232998
],
"Rotation": [
0.7071437239646912,
0.0,
0.0,
0.708984375
],
"propertyVisibilityFlags": 248
},
{
"$type": "CapsuleShapeConfiguration",
"Height": 0.191273495554924,
"Radius": 0.05063670128583908
}
]
]
},
{
"name": "def_c_neck_joint",
"shapes": [
[
{
"Visible": true,
"Position": [
-0.03810190036892891,
0.0,
-0.03132440149784088
],
"propertyVisibilityFlags": 248
},
{
"$type": "SphereShapeConfiguration",
"Radius": 0.16069939732551576
}
]
]
},
{
"name": "def_c_spine_end",
"shapes": [
[
{
"Visible": true,
"Position": [
-2.0000000233721949e-7,
0.012646200135350228,
-0.24104370176792146
],
"propertyVisibilityFlags": 248
},
{
"$type": "SphereShapeConfiguration",
"Radius": 0.24875959753990174
}
]
]
}
]
}
}
}
},
{
"$type": "CoordinateSystemRule"
}
]
}
},
{
"$type": "{07B356B7-3635-40B5-878A-FAC4EFD5AD86} MeshGroup",
"name": "chicken",
"nodeSelectionList": {
"selectedNodes": [
{},
"RootNode",
"RootNode.chicken_skeleton",
"RootNode.chicken_feet_skin",
"RootNode.chicken_eyes_skin",
"RootNode.chicken_body_skin",
"RootNode.chicken_mohawk",
"RootNode.chicken_skeleton.def_c_chickenRoot_joint",
"RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint",
"RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint",
"RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_l_uprLeg_joint",
"RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_r_uprLeg_joint",
"RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint",
"RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_l_uprLeg_joint.def_l_lwrLeg_joint",
"RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_r_uprLeg_joint.def_r_lwrLeg_joint",
"RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_c_spine_end",
"RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_l_wing1_joint",
"RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_r_wing1_joint",
"RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_l_uprLeg_joint.def_l_lwrLeg_joint.def_l_foot_joint",
"RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_r_uprLeg_joint.def_r_lwrLeg_joint.def_r_foot_joint",
"RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_c_spine_end.def_c_tail1_joint",
"RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_c_spine_end.def_c_neck_joint",
"RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_l_wing1_joint.def_l_wing2_joint",
"RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_r_wing1_joint.def_r_wing2_joint",
"RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_l_uprLeg_joint.def_l_lwrLeg_joint.def_l_foot_joint.def_l_ball_joint",
"RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_r_uprLeg_joint.def_r_lwrLeg_joint.def_r_foot_joint.def_r_ball_joint",
"RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_c_spine_end.def_c_tail1_joint.def_c_tail2_joint",
"RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_c_spine_end.def_c_neck_joint.def_c_head_joint",
"RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_l_wing1_joint.def_l_wing2_joint.def_l_wing_end",
"RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_r_wing1_joint.def_r_wing2_joint.def_r_wing_end",
"RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_c_spine_end.def_c_neck_joint.def_c_head_joint.def_c_feather1_joint",
"RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_c_spine_end.def_c_neck_joint.def_c_head_joint.def_c_mouth_joint",
"RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_c_spine_end.def_c_neck_joint.def_c_head_joint.def_c_waddle1_joint",
"RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_c_spine_end.def_c_neck_joint.def_c_head_joint.def_c_feather1_joint.def_c_feather2_joint",
"RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_c_spine_end.def_c_neck_joint.def_c_head_joint.def_c_mouth_joint.def_c_mouth_end",
"RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_c_spine_end.def_c_neck_joint.def_c_head_joint.def_c_waddle1_joint.def_c_waddle2_joint",
"RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_c_spine_end.def_c_neck_joint.def_c_head_joint.def_c_feather1_joint.def_c_feather2_joint.def_c_feather3_joint",
"RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_c_spine_end.def_c_neck_joint.def_c_head_joint.def_c_waddle1_joint.def_c_waddle2_joint.def_c_waddle3_joint",
"RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_c_spine_end.def_c_neck_joint.def_c_head_joint.def_c_feather1_joint.def_c_feather2_joint.def_c_feather3_joint.def_c_feather4_joint",
"RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_c_spine_end.def_c_neck_joint.def_c_head_joint.def_c_waddle1_joint.def_c_waddle2_joint.def_c_waddle3_joint.def_c_waddle_end",
"RootNode.chicken_skeleton.def_c_chickenRoot_joint.def_c_spine1_joint.def_c_spine2_joint.def_c_spine3_joint.def_c_spine_end.def_c_neck_joint.def_c_head_joint.def_c_feather1_joint.def_c_feather2_joint.def_c_feather3_joint.def_c_feather4_joint.def_c_feather_end"
]
},
"rules": {
"rules": [
{
"$type": "SkinRule"
},
{
"$type": "StaticMeshAdvancedRule",
"vertexColorStreamName": "Disabled"
},
{
"$type": "MaterialRule"
},
{
"$type": "CoordinateSystemRule"
},
{
"$type": "ClothRule",
"meshNodeName": "RootNode.chicken_mohawk",
"inverseMassesStreamName": "colorSet1",
"motionConstraintsStreamName": "Default: 1.0",
"backstopStreamName": "None"
}
]
},
"id": "{55E26F74-B35F-4BC1-87BB-83E3DE85C346}"
}
]
}
@@ -448,9 +448,18 @@ namespace NvCloth
const auto& renderTangents = renderData.m_tangents;
const auto& renderBitangents = renderData.m_bitangents;
AZ::Data::Asset<AZ::RPI::ModelAsset> modelAsset;
AZ::Render::MeshComponentRequestBus::EventResult(
modelAsset, m_entityId, &AZ::Render::MeshComponentRequestBus::Events::GetModelAsset);
// Since Atom has a 1:1 relation with between ModelAsset buffers and Model buffers,
// internally it created a new asset for the model instance. So it's important to
// get the asset from the model when we want to write to them, instead of getting the
// ModelAsset directly from the bus (which returns the original asset shared by all entities).
AZ::Data::Instance<AZ::RPI::Model> model;
AZ::Render::MeshComponentRequestBus::EventResult(model, m_entityId, &AZ::Render::MeshComponentRequestBus::Events::GetModel);
if (!model)
{
return;
}
AZ::Data::Asset<AZ::RPI::ModelAsset> modelAsset = model->GetModelAsset();
if (!modelAsset.IsReady())
{
return;
+3 -23
View File
@@ -13,11 +13,7 @@
#include <Utils/AssetHelper.h>
#include <Utils/MeshAssetHelper.h>
#include <Utils/ActorAssetHelper.h>
#include <AtomLyIntegration/CommonFeatures/Mesh/MeshComponentBus.h>
#include <Integration/ActorComponentBus.h>
namespace NvCloth
{
@@ -30,25 +26,9 @@ namespace NvCloth
AZStd::unique_ptr<AssetHelper> AssetHelper::CreateAssetHelper(AZ::EntityId entityId)
{
// Does the entity have an Actor Asset?
EMotionFX::ActorInstance* actorInstance = nullptr;
EMotionFX::Integration::ActorComponentRequestBus::EventResult(
actorInstance, entityId, &EMotionFX::Integration::ActorComponentRequestBus::Events::GetActorInstance);
if (actorInstance)
{
return AZStd::make_unique<ActorAssetHelper>(entityId);
}
AZ::Data::Asset<AZ::RPI::ModelAsset> modelAsset;
AZ::Render::MeshComponentRequestBus::EventResult(
modelAsset, entityId, &AZ::Render::MeshComponentRequestBus::Events::GetModelAsset);
if (modelAsset.GetId().IsValid())
{
return AZStd::make_unique<MeshAssetHelper>(entityId);
}
AZ_Warning("AssetHelper", false, "Unexpected asset type");
return nullptr;
return entityId.IsValid()
? AZStd::make_unique<MeshAssetHelper>(entityId)
: nullptr;
}
float AssetHelper::ConvertBackstopOffset(float backstopOffset)
@@ -14,11 +14,17 @@
#include <Utils/MeshAssetHelper.h>
#include <Integration/ActorComponentBus.h>
namespace NvCloth
{
MeshAssetHelper::MeshAssetHelper(AZ::EntityId entityId)
: AssetHelper(entityId)
{
EMotionFX::ActorInstance* actorInstance = nullptr;
EMotionFX::Integration::ActorComponentRequestBus::EventResult(
actorInstance, entityId, &EMotionFX::Integration::ActorComponentRequestBus::Events::GetActorInstance);
m_supportSkinnedAnimation = actorInstance != nullptr;
}
void MeshAssetHelper::GatherClothMeshNodes(MeshNodeList& meshNodes)
@@ -35,12 +35,14 @@ namespace NvCloth
MeshClothInfo& meshClothInfo) override;
bool DoesSupportSkinnedAnimation() const override
{
return false;
return m_supportSkinnedAnimation;
}
private:
bool CopyDataFromMeshes(
const AZStd::vector<const AZ::RPI::ModelLodAsset::Mesh*>& meshes,
MeshClothInfo& meshClothInfo);
bool m_supportSkinnedAnimation = false;
};
} // namespace NvCloth
@@ -145,8 +145,8 @@ namespace UnitTest
const AZStd::vector<NvCloth::CapsuleCollider>& capsuleColliders = actorClothColliders->GetCapsuleColliders();
const AZStd::vector<uint32_t>& nativeCapsuleIndices = actorClothColliders->GetCapsuleIndices();
EXPECT_EQ(sphereColliders.size(), 1);
EXPECT_EQ(nativeSpheres.size(), 1);
ASSERT_EQ(sphereColliders.size(), 1);
ASSERT_EQ(nativeSpheres.size(), 1);
EXPECT_TRUE(capsuleColliders.empty());
EXPECT_TRUE(nativeCapsuleIndices.empty());
@@ -189,9 +189,9 @@ namespace UnitTest
const AZStd::vector<uint32_t>& nativeCapsuleIndices = actorClothColliders->GetCapsuleIndices();
EXPECT_TRUE(sphereColliders.empty());
EXPECT_EQ(nativeSpheres.size(), 2); // Each capsule produces 2 spheres
EXPECT_EQ(capsuleColliders.size(), 1);
EXPECT_EQ(nativeCapsuleIndices.size(), 2); // Each capsule is 2 indices
ASSERT_EQ(nativeSpheres.size(), 2); // Each capsule produces 2 spheres
ASSERT_EQ(capsuleColliders.size(), 1);
ASSERT_EQ(nativeCapsuleIndices.size(), 2); // Each capsule is 2 indices
EXPECT_NEAR(capsuleColliders[0].m_height, height, Tolerance);
EXPECT_NEAR(capsuleColliders[0].m_radius, radius, Tolerance);
@@ -144,8 +144,12 @@ namespace UnitTest
EXPECT_TRUE(renderData.m_bitangents.empty());
EXPECT_TRUE(renderData.m_normals.empty());
}
TEST_F(NvClothComponentMesh, ClothComponentMesh_InitWithEntityActorWithNoClothData_TriggersError)
// [TODO LYN-1891]
// Revisit when Cloth Component Mesh works with Actors adapted to Atom models.
// Editor Cloth component now uses the new AZ::Render::MeshComponentNotificationBus::OnModelReady
// notification and this test does not setup a model yet.
TEST_F(NvClothComponentMesh, DISABLED_ClothComponentMesh_InitWithEntityActorWithNoClothData_TriggersError)
{
{
auto actor = AZStd::make_unique<ActorHelper>("actor_test");
@@ -165,8 +169,12 @@ namespace UnitTest
AZ_TEST_STOP_TRACE_SUPPRESSION(1); // Expect 1 error
}
TEST_F(NvClothComponentMesh, ClothComponentMesh_InitWithEntityActor_ReturnsValidRenderData)
// [TODO LYN-1891]
// Revisit when Cloth Component Mesh works with Actors adapted to Atom models.
// Editor Cloth component now uses the new AZ::Render::MeshComponentNotificationBus::OnModelReady
// notification and this test does not setup a model yet.
TEST_F(NvClothComponentMesh, DISABLED_ClothComponentMesh_InitWithEntityActor_ReturnsValidRenderData)
{
{
auto actor = AZStd::make_unique<ActorHelper>("actor_test");
@@ -265,7 +273,11 @@ namespace UnitTest
EXPECT_TRUE(renderData.m_normals.empty());
}
TEST_F(NvClothComponentMesh, ClothComponentMesh_UpdateConfigurationDifferentEntity_ReturnsRenderDataFromNewEntity)
// [TODO LYN-1891]
// Revisit when Cloth Component Mesh works with Actors adapted to Atom models.
// Editor Cloth component now uses the new AZ::Render::MeshComponentNotificationBus::OnModelReady
// notification and this test does not setup a model yet.
TEST_F(NvClothComponentMesh, DISABLED_ClothComponentMesh_UpdateConfigurationDifferentEntity_ReturnsRenderDataFromNewEntity)
{
{
auto actor = AZStd::make_unique<ActorHelper>("actor_test");
@@ -341,7 +353,11 @@ namespace UnitTest
EXPECT_TRUE(renderData.m_normals.empty());
}
TEST_F(NvClothComponentMesh, ClothComponentMesh_UpdateConfigurationNewMeshNode_ReturnsRenderDataFromNewMeshNode)
// [TODO LYN-1891]
// Revisit when Cloth Component Mesh works with Actors adapted to Atom models.
// Editor Cloth component now uses the new AZ::Render::MeshComponentNotificationBus::OnModelReady
// notification and this test does not setup a model yet.
TEST_F(NvClothComponentMesh, DISABLED_ClothComponentMesh_UpdateConfigurationNewMeshNode_ReturnsRenderDataFromNewMeshNode)
{
const AZStd::string meshNode2Name = "cloth_node_2";
@@ -184,7 +184,7 @@ namespace UnitTest
const NvCloth::MeshNodeList& meshNodeList = editorClothComponent->GetMeshNodeList();
EXPECT_EQ(meshNodeList.size(), 1);
ASSERT_EQ(meshNodeList.size(), 1);
EXPECT_TRUE(meshNodeList[0] == NvCloth::Internal::StatusMessageNoAsset);
}
@@ -208,7 +208,7 @@ namespace UnitTest
const NvCloth::MeshNodeList& meshNodeList = editorClothComponent->GetMeshNodeList();
EXPECT_EQ(meshNodeList.size(), 1);
ASSERT_EQ(meshNodeList.size(), 1);
EXPECT_TRUE(meshNodeList[0] == NvCloth::Internal::StatusMessageNoClothNodes);
}
@@ -234,7 +234,7 @@ namespace UnitTest
const NvCloth::MeshNodeList& meshNodeList = editorClothComponent->GetMeshNodeList();
EXPECT_EQ(meshNodeList.size(), 1);
ASSERT_EQ(meshNodeList.size(), 1);
EXPECT_TRUE(meshNodeList[0] == NvCloth::Internal::StatusMessageNoClothNodes);
}
@@ -261,7 +261,7 @@ namespace UnitTest
const NvCloth::MeshNodeList& meshNodeList = editorClothComponent->GetMeshNodeList();
EXPECT_EQ(meshNodeList.size(), 2);
ASSERT_EQ(meshNodeList.size(), 2);
EXPECT_TRUE(meshNodeList[0] == NvCloth::Internal::StatusMessageSelectNode);
EXPECT_TRUE(meshNodeList[1] == MeshNodeName);
}
@@ -322,9 +322,11 @@ namespace UnitTest
EXPECT_TRUE(meshNodesWithBackstopData.find(MeshNodeName) != meshNodesWithBackstopData.end());
}
// [TODO LYN-2252]
// Enable test once OnModelDestroyed is available.
TEST_F(NvClothEditorClothComponent, DISABLED_EditorClothComponent_OnMeshDestroyed_ReturnsMeshNodeListWithNoAssetMessage)
// [TODO LYN-1891]
// Revisit when Cloth Component Mesh works with Actors adapted to Atom models.
// Editor Cloth component now uses the new AZ::Render::MeshComponentNotificationBus::OnModelReady
// notification and this test does not setup a model yet.
TEST_F(NvClothEditorClothComponent, DISABLED_EditorClothComponent_OnModelPreDestroy_ReturnsMeshNodeListWithNoAssetMessage)
{
auto editorEntity = CreateInactiveEditorEntity("ClothComponentEditorEntity");
auto* editorClothComponent = editorEntity->CreateComponent<NvCloth::EditorClothComponent>();
@@ -341,12 +343,12 @@ namespace UnitTest
editorActorComponent->SetActorAsset(CreateAssetFromActor(AZStd::move(actor)));
}
//editorClothComponent->OnModelDestroyed();
editorClothComponent->OnModelPreDestroy();
const NvCloth::MeshNodeList& meshNodeList = editorClothComponent->GetMeshNodeList();
const auto& meshNodesWithBackstopData = editorClothComponent->GetMeshNodesWithBackstopData();
EXPECT_EQ(meshNodeList.size(), 1);
ASSERT_EQ(meshNodeList.size(), 1);
EXPECT_TRUE(meshNodeList[0] == NvCloth::Internal::StatusMessageNoAsset);
EXPECT_TRUE(meshNodesWithBackstopData.empty());
}
+1 -1
View File
@@ -506,7 +506,7 @@ namespace UnitTest
EXPECT_EQ(initialParticles.size(), nvClothCurrentParticles.size());
EXPECT_EQ(initialParticles.size(), nvClothPreviousParticles.size());
for (size_t i = 0; i < nvClothCurrentParticles.size(); ++i)
for (size_t i = 0; i < initialParticles.size(); ++i)
{
ExpectEq(initialParticles[i], nvClothCurrentParticles[i]);
ExpectEq(initialParticles[i], nvClothPreviousParticles[i]);
@@ -283,7 +283,7 @@ namespace UnitTest
AZStd::vector<int> remappedVertices;
NvCloth::Internal::WeldVertices(vertices, indices, weldedVertices, weldedIndices, remappedVertices);
EXPECT_EQ(weldedVertices.size(), expectedSizeAfterWelding);
ASSERT_EQ(weldedVertices.size(), expectedSizeAfterWelding);
EXPECT_THAT(weldedVertices[0].GetAsVector3(), IsCloseTolerance(vertexPosition, Tolerance));
EXPECT_NEAR(weldedVertices[0].GetW(), lowestInverseMass, Tolerance);
}
@@ -307,9 +307,9 @@ namespace UnitTest
AZStd::vector<int> remappedVertices;
NvCloth::Internal::WeldVertices(vertices, indices, weldedVertices, weldedIndices, remappedVertices);
EXPECT_EQ(weldedVertices.size(), expectedSizeAfterWelding);
EXPECT_EQ(weldedIndices.size(), indices.size());
EXPECT_EQ(remappedVertices.size(), vertices.size());
ASSERT_EQ(weldedVertices.size(), expectedSizeAfterWelding);
ASSERT_EQ(weldedIndices.size(), indices.size());
ASSERT_EQ(remappedVertices.size(), vertices.size());
for (size_t i = 0; i < remappedVertices.size(); ++i)
{
@@ -347,9 +347,9 @@ namespace UnitTest
// The result after calling WeldVertices is expected to have the same size.
// The vertices inside will be reordered though due to the welding process.
EXPECT_EQ(weldedVertices.size(), vertices.size());
EXPECT_EQ(weldedIndices.size(), indices.size());
EXPECT_EQ(remappedVertices.size(), vertices.size());
ASSERT_EQ(weldedVertices.size(), vertices.size());
ASSERT_EQ(weldedIndices.size(), indices.size());
ASSERT_EQ(remappedVertices.size(), vertices.size());
for (size_t i = 0; i < remappedVertices.size(); ++i)
{
@@ -422,9 +422,9 @@ namespace UnitTest
AZStd::vector<int> remappedVertices;
NvCloth::Internal::RemoveStaticTriangles(vertices, indices, simplifiedVertices, simplifiedIndices, remappedVertices);
EXPECT_EQ(simplifiedVertices.size(), expectedVerticesSizeAfterSimplification);
EXPECT_EQ(simplifiedIndices.size(), expectedIndicesSizeAfterSimplification);
EXPECT_EQ(remappedVertices.size(), vertices.size());
ASSERT_EQ(simplifiedVertices.size(), expectedVerticesSizeAfterSimplification);
ASSERT_EQ(simplifiedIndices.size(), expectedIndicesSizeAfterSimplification);
ASSERT_EQ(remappedVertices.size(), vertices.size());
for (size_t i = 0; i < remappedVertices.size(); ++i)
{
@@ -477,9 +477,9 @@ namespace UnitTest
AZStd::vector<int> remappedVertices;
NvCloth::Internal::RemoveStaticTriangles(vertices, indices, simplifiedVertices, simplifiedIndices, remappedVertices);
EXPECT_EQ(simplifiedVertices.size(), expectedVerticesSizeAfterSimplification);
EXPECT_EQ(simplifiedIndices.size(), expectedIndicesSizeAfterSimplification);
EXPECT_EQ(remappedVertices.size(), vertices.size());
ASSERT_EQ(simplifiedVertices.size(), expectedVerticesSizeAfterSimplification);
ASSERT_EQ(simplifiedIndices.size(), expectedIndicesSizeAfterSimplification);
ASSERT_EQ(remappedVertices.size(), vertices.size());
for (size_t i = 0; i < remappedVertices.size(); ++i)
{
@@ -532,9 +532,9 @@ namespace UnitTest
// The result after calling RemoveStaticTriangles is expected to have the same size.
// The vertices will be reordered though due to the processing during simplification.
EXPECT_EQ(simplifiedVertices.size(), vertices.size());
EXPECT_EQ(simplifiedIndices.size(), indices.size());
EXPECT_EQ(remappedVertices.size(), vertices.size());
ASSERT_EQ(simplifiedVertices.size(), vertices.size());
ASSERT_EQ(simplifiedIndices.size(), indices.size());
ASSERT_EQ(remappedVertices.size(), vertices.size());
for (size_t i = 0; i < remappedVertices.size(); ++i)
{
@@ -576,9 +576,9 @@ namespace UnitTest
AZStd::vector<int> remappedVertices;
AZ::Interface<NvCloth::IFabricCooker>::Get()->SimplifyMesh(vertices, indices, simplifiedVertices, simplifiedIndices, remappedVertices, removeStaticTriangles);
EXPECT_EQ(simplifiedVertices.size(), expectedVerticesSizeAfterSimplification);
EXPECT_EQ(simplifiedIndices.size(), expectedIndicesSizeAfterSimplification);
EXPECT_EQ(remappedVertices.size(), vertices.size());
ASSERT_EQ(simplifiedVertices.size(), expectedVerticesSizeAfterSimplification);
ASSERT_EQ(simplifiedIndices.size(), expectedIndicesSizeAfterSimplification);
ASSERT_EQ(remappedVertices.size(), vertices.size());
for (size_t i = 0; i < remappedVertices.size(); ++i)
{
@@ -635,9 +635,9 @@ namespace UnitTest
AZStd::vector<int> remappedVertices;
AZ::Interface<NvCloth::IFabricCooker>::Get()->SimplifyMesh(vertices, indices, simplifiedVertices, simplifiedIndices, remappedVertices, removeStaticTriangles);
EXPECT_EQ(simplifiedVertices.size(), expectedVerticesSizeAfterSimplification);
EXPECT_EQ(simplifiedIndices.size(), expectedIndicesSizeAfterSimplification);
EXPECT_EQ(remappedVertices.size(), vertices.size());
ASSERT_EQ(simplifiedVertices.size(), expectedVerticesSizeAfterSimplification);
ASSERT_EQ(simplifiedIndices.size(), expectedIndicesSizeAfterSimplification);
ASSERT_EQ(remappedVertices.size(), vertices.size());
for (size_t i = 0; i < remappedVertices.size(); ++i)
{
@@ -15,7 +15,7 @@
#include <AzCore/Component/Entity.h>
#include <AzFramework/Components/TransformComponent.h>
#include <Utils/ActorAssetHelper.h>
#include <Utils/MeshAssetHelper.h>
#include <UnitTestHelper.h>
#include <ActorHelper.h>
@@ -24,7 +24,7 @@
namespace UnitTest
{
//! Fixture to setup entity with actor component and the tests data.
class NvClothActorAssetHelper
class NvClothMeshAssetHelper
: public ::testing::Test
{
public:
@@ -75,7 +75,7 @@ namespace UnitTest
AZStd::unique_ptr<AZ::Entity> m_entity;
};
void NvClothActorAssetHelper::SetUp()
void NvClothMeshAssetHelper::SetUp()
{
m_entity = AZStd::make_unique<AZ::Entity>();
m_entity->CreateComponent<AzFramework::TransformComponent>();
@@ -84,14 +84,14 @@ namespace UnitTest
m_entity->Activate();
}
void NvClothActorAssetHelper::TearDown()
void NvClothMeshAssetHelper::TearDown()
{
m_entity->Deactivate();
m_actorComponent = nullptr;
m_entity.reset();
}
TEST_F(NvClothActorAssetHelper, ActorAssetHelper_CreateAssetHelperWithInvalidEntityId_ReturnsNull)
TEST_F(NvClothMeshAssetHelper, MeshAssetHelper_CreateAssetHelperWithInvalidEntityId_ReturnsNull)
{
AZ::EntityId entityId;
@@ -100,7 +100,18 @@ namespace UnitTest
EXPECT_TRUE(assetHelper.get() == nullptr);
}
TEST_F(NvClothActorAssetHelper, ActorAssetHelper_CreateAssetHelperWithActor_ReturnsValidActorAssetHelper)
TEST_F(NvClothMeshAssetHelper, MeshAssetHelper_CreateAssetHelperWithValidEntityId_ReturnsValidMeshAssetHelper)
{
AZStd::unique_ptr<AZ::Entity> entity = AZStd::make_unique<AZ::Entity>();
AZStd::unique_ptr<NvCloth::AssetHelper> assetHelper = NvCloth::AssetHelper::CreateAssetHelper(entity->GetId());
EXPECT_TRUE(assetHelper.get() != nullptr);
EXPECT_TRUE(azrtti_cast<NvCloth::MeshAssetHelper*>(assetHelper.get()) != nullptr);
EXPECT_FALSE(assetHelper->DoesSupportSkinnedAnimation());
}
TEST_F(NvClothMeshAssetHelper, MeshAssetHelper_CreateAssetHelperWithActor_ReturnsValidMeshAssetHelper)
{
{
auto actor = AZStd::make_unique<ActorHelper>("actor_test");
@@ -112,10 +123,11 @@ namespace UnitTest
AZStd::unique_ptr<NvCloth::AssetHelper> assetHelper = NvCloth::AssetHelper::CreateAssetHelper(m_actorComponent->GetEntityId());
EXPECT_TRUE(assetHelper.get() != nullptr);
EXPECT_TRUE(azrtti_cast<NvCloth::ActorAssetHelper*>(assetHelper.get()) != nullptr);
EXPECT_TRUE(azrtti_cast<NvCloth::MeshAssetHelper*>(assetHelper.get()) != nullptr);
EXPECT_TRUE(assetHelper->DoesSupportSkinnedAnimation());
}
TEST_F(NvClothActorAssetHelper, ActorAssetHelper_DoesSupportSkinnedAnimation_ReturnsTrue)
TEST_F(NvClothMeshAssetHelper, MeshAssetHelper_DoesSupportSkinnedAnimation_ReturnsTrue)
{
{
auto actor = AZStd::make_unique<ActorHelper>("actor_test");
@@ -129,7 +141,7 @@ namespace UnitTest
EXPECT_TRUE(assetHelper->DoesSupportSkinnedAnimation());
}
TEST_F(NvClothActorAssetHelper, ActorAssetHelper_GatherClothMeshNodesWithEmptyActor_ReturnsEmptyInfo)
TEST_F(NvClothMeshAssetHelper, MeshAssetHelper_GatherClothMeshNodesWithEmptyActor_ReturnsEmptyInfo)
{
{
auto actor = AZStd::make_unique<ActorHelper>("actor_test");
@@ -146,7 +158,7 @@ namespace UnitTest
EXPECT_TRUE(meshNodes.empty());
}
TEST_F(NvClothActorAssetHelper, ActorAssetHelper_ObtainClothMeshNodeInfoWithEmptyActor_ReturnsFalse)
TEST_F(NvClothMeshAssetHelper, MeshAssetHelper_ObtainClothMeshNodeInfoWithEmptyActor_ReturnsFalse)
{
{
auto actor = AZStd::make_unique<ActorHelper>("actor_test");
@@ -164,7 +176,11 @@ namespace UnitTest
EXPECT_FALSE(infoObtained);
}
TEST_F(NvClothActorAssetHelper, ActorAssetHelper_GatherClothMeshNodesWithActor_ReturnsCorrectMeshNodeList)
// [TODO LYN-1891]
// Revisit when Cloth Component Mesh works with Actors adapted to Atom models.
// Editor Cloth component now uses the new AZ::Render::MeshComponentNotificationBus::OnModelReady
// notification and this test does not setup a model yet.
TEST_F(NvClothMeshAssetHelper, DISABLED_MeshAssetHelper_GatherClothMeshNodesWithActor_ReturnsCorrectMeshNodeList)
{
{
auto actor = AZStd::make_unique<ActorHelper>("actor_test");
@@ -185,12 +201,16 @@ namespace UnitTest
NvCloth::MeshNodeList meshNodes;
assetHelper->GatherClothMeshNodes(meshNodes);
EXPECT_EQ(meshNodes.size(), 2);
ASSERT_EQ(meshNodes.size(), 2);
EXPECT_TRUE(meshNodes[0] == MeshNode1Name);
EXPECT_TRUE(meshNodes[1] == MeshNode2Name);
}
TEST_F(NvClothActorAssetHelper, ActorAssetHelper_ObtainClothMeshNodeInfoWithActor_ReturnsCorrectClothInfo)
// [TODO LYN-1891]
// Revisit when Cloth Component Mesh works with Actors adapted to Atom models.
// Editor Cloth component now uses the new AZ::Render::MeshComponentNotificationBus::OnModelReady
// notification and this test does not setup a model yet.
TEST_F(NvClothMeshAssetHelper, DISABLED_MeshAssetHelper_ObtainClothMeshNodeInfoWithActor_ReturnsCorrectClothInfo)
{
{
auto actor = AZStd::make_unique<ActorHelper>("actor_test");
@@ -215,7 +235,7 @@ namespace UnitTest
EXPECT_TRUE(infoObtained);
EXPECT_EQ(meshNodeInfo.m_lodLevel, LodLevel);
EXPECT_EQ(meshNodeInfo.m_subMeshes.size(), 1);
ASSERT_EQ(meshNodeInfo.m_subMeshes.size(), 1);
EXPECT_EQ(meshNodeInfo.m_subMeshes[0].m_primitiveIndex, 2);
EXPECT_EQ(meshNodeInfo.m_subMeshes[0].m_verticesFirstIndex, 0);
EXPECT_EQ(meshNodeInfo.m_subMeshes[0].m_numVertices, MeshVertices.size());
@@ -114,12 +114,17 @@ class SceneManifest():
def mesh_group_unselect_node(self, meshGroup, nodeName):
meshGroup['nodeSelectionList']['unselectedNodes'].append(nodeName)
def mesh_group_set_origin(self, meshGroup, originNodeName, x, y, z, scale):
def mesh_group_add_advanced_coordinate_system(self, meshGroup, originNodeName, translation, rotation, scale):
originRule = {}
originRule['$type'] = 'OriginRule'
originRule['originNodeName'] = 'World' if originNodeName is None else originNodeName
originRule['translation'] = [x, y, z]
originRule['scale'] = scale
originRule['$type'] = 'CoordinateSystemRule'
originRule['useAdvancedData'] = True
originRule['originNodeName'] = '' if originNodeName is None else originNodeName
if translation is not None:
originRule['translation'] = translation
if rotation is not None:
originRule['rotation'] = rotation
if scale != 1.0:
originRule['scale'] = scale
meshGroup['rules']['rules'].append(originRule)
def mesh_group_add_comment(self, meshGroup, comment):
@@ -2347,7 +2347,7 @@ namespace ScriptCanvasEditor
AZ::Outcome<ScriptCanvas::VariableId, AZStd::string> addOutcome;
// #functions2 slot<->variable re-use the activeDatum, send the pointer (actually, all of the source slot information, and make a special conversion)
ScriptCanvas::GraphVariableManagerRequestBus::EventResult(addOutcome, GetScriptCanvasId(), &ScriptCanvas::GraphVariableManagerRequests::AddVariable, variableName, variableDatum);
ScriptCanvas::GraphVariableManagerRequestBus::EventResult(addOutcome, GetScriptCanvasId(), &ScriptCanvas::GraphVariableManagerRequests::AddVariable, variableName, variableDatum, true);
if (addOutcome.IsSuccess())
{
@@ -172,7 +172,7 @@ namespace ScriptCanvasEditor
{
ScriptCanvas::Datum datum = ScriptCanvas::Datum(entityId);
AZ::Outcome<ScriptCanvas::VariableId, AZStd::string > addVariableOutcome = variableManagerRequests->AddVariable(variableName, datum);
AZ::Outcome<ScriptCanvas::VariableId, AZStd::string > addVariableOutcome = variableManagerRequests->AddVariable(variableName, datum, false);
if (addVariableOutcome.IsSuccess())
{
@@ -578,6 +578,14 @@ namespace
categoryPath.append(displayName.c_str());
}
for (auto property : behaviorClass->m_properties)
{
if (property.second->m_setter)
{
RegisterMethod(nodePaletteModel, behaviorContext, categoryPath, behaviorClass, property.first, *property.second->m_setter, behaviorClass->IsMethodOverloaded(property.first));
}
}
for (auto methodIter : behaviorClass->m_methods)
{
if (!IsExplicitOverload(*methodIter.second))
@@ -1011,7 +1011,7 @@ namespace ScriptCanvasEditor
ScriptCanvas::Datum datum(variableType, ScriptCanvas::Datum::eOriginality::Original);
AZ::Outcome<ScriptCanvas::VariableId, AZStd::string> outcome = AZ::Failure(AZStd::string());
ScriptCanvas::GraphVariableManagerRequestBus::EventResult(outcome, m_activeGraphIds.scriptCanvasId, &ScriptCanvas::GraphVariableManagerRequests::AddVariable, varName, datum);
ScriptCanvas::GraphVariableManagerRequestBus::EventResult(outcome, m_activeGraphIds.scriptCanvasId, &ScriptCanvas::GraphVariableManagerRequests::AddVariable, varName, datum, false);
if (outcome.IsSuccess())
{
@@ -41,6 +41,7 @@
#include <ScriptCanvas/Bus/EditorScriptCanvasBus.h>
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
#include <ScriptCanvas/Variable/GraphVariable.h>
namespace ScriptCanvasEditor
{
@@ -538,7 +539,24 @@ namespace ScriptCanvasEditor
}
else if (index.column() == ColumnIndex::Scope)
{
// Scope is not changed by users
ScriptCanvas::GraphVariable* graphVariable = nullptr;
ScriptCanvas::GraphVariableManagerRequestBus::EventResult(graphVariable, m_scriptCanvasId, &ScriptCanvas::GraphVariableManagerRequests::FindVariableById, varId.m_identifier);
if (graphVariable)
{
QString comboBoxValue = value.toString();
if (!comboBoxValue.isEmpty())
{
AZStd::string scopeLabel = ScriptCanvas::VariableFlags::GetScopeDisplayLabel(graphVariable->GetScope());
if (scopeLabel.compare(comboBoxValue.toUtf8().data()) != 0)
{
modifiedData = true;
graphVariable->SetScope(ScriptCanvas::VariableFlags::GetScopeFromLabel(comboBoxValue.toUtf8().data()));
AzToolsFramework::PropertyEditorGUIMessages::Bus::Broadcast(&AzToolsFramework::PropertyEditorGUIMessages::RequestRefresh, AzToolsFramework::Refresh_EntireTree);
}
}
}
}
else if (index.column() == ColumnIndex::InitialValueSource)
{
@@ -607,8 +625,17 @@ namespace ScriptCanvasEditor
}
else if (index.column() == ColumnIndex::Scope)
{
ScriptCanvas::GraphScopedVariableId varId = FindScopedVariableIdForIndex(index);
ScriptCanvas::GraphVariable* graphVariable = nullptr;
ScriptCanvas::GraphVariableManagerRequestBus::EventResult(graphVariable, m_scriptCanvasId, &ScriptCanvas::GraphVariableManagerRequests::FindVariableById, varId.m_identifier);
if (graphVariable->GetScope() != ScriptCanvas::VariableFlags::Scope::FunctionReadOnly)
{
itemFlags |= Qt::ItemIsEditable;
}
}
else if (index.column() == ColumnIndex::InitialValueSource)
{
itemFlags |= Qt::ItemIsEditable;
@@ -73,6 +73,8 @@ namespace ScriptCanvasEditor
{
ui->setupUi(this);
ui->variablePalette->SetActiveScene(scriptCanvasId);
ui->searchFilter->setClearButtonEnabled(true);
QObject::connect(ui->searchFilter, &QLineEdit::textChanged, this, &SlotTypeSelectorWidget::OnQuickFilterChanged);
QObject::connect(ui->slotName, &QLineEdit::returnPressed, this, &SlotTypeSelectorWidget::OnReturnPressed);
@@ -812,7 +812,7 @@ namespace ScriptCanvasEditor
ScriptCanvas::Datum datum(varType, ScriptCanvas::Datum::eOriginality::Original);
AZ::Outcome<ScriptCanvas::VariableId, AZStd::string> outcome = AZ::Failure(AZStd::string());
ScriptCanvas::GraphVariableManagerRequestBus::EventResult(outcome, m_scriptCanvasId, &ScriptCanvas::GraphVariableManagerRequests::AddVariable, variableName, datum);
ScriptCanvas::GraphVariableManagerRequestBus::EventResult(outcome, m_scriptCanvasId, &ScriptCanvas::GraphVariableManagerRequests::AddVariable, variableName, datum, false);
AZ_Warning("VariablePanel", outcome.IsSuccess(), "Could not create new variable: %s", outcome.GetError().c_str());
GeneralRequestBus::Broadcast(&GeneralRequests::PostUndoPoint, m_scriptCanvasId);
@@ -81,6 +81,8 @@ namespace ScriptCanvas
{
return ConstructCustomNodeIdentifier(scriptCanvasNode->RTTI_GetType());
}
return NodeTypeIdentifier(0);
}
NodeTypeIdentifier NodeUtils::ConstructEBusIdentifier(ScriptCanvas::EBusBusId ebusIdentifier)
@@ -43,20 +43,12 @@ namespace ScriptCanvas
{
const char* GetScopeDisplayLabel(Scope scopeType)
{
switch (scopeType)
{
case Scope::Graph:
return "Graph";
case Scope::Function:
return "Function";
default:
return "?";
}
return GraphVariable::s_ScopeNames[static_cast<int>(scopeType)];
}
Scope GetScopeFromLabel(const char* label)
{
if (strcmp("Function", label) == 0)
if (strcmp(GraphVariable::s_ScopeNames[static_cast<int>(VariableFlags::Scope::Function)], label) == 0)
{
return Scope::Function;
}
@@ -71,6 +63,7 @@ namespace ScriptCanvas
case Scope::Graph:
return "Variable is accessible in the entire graph.";
case Scope::Function:
case Scope::FunctionReadOnly:
return "Variable is accessible only in the execution path of the function that defined it";
default:
return "?";
@@ -162,6 +155,14 @@ namespace ScriptCanvas
"From Component"
};
const char* GraphVariable::s_ScopeNames[static_cast<int>(VariableFlags::Scope::COUNT)] =
{
"Graph",
"Function",
"Function",
};
void GraphVariable::Reflect(AZ::ReflectContext* context)
{
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
@@ -197,6 +198,13 @@ namespace ScriptCanvas
return choices;
};
auto scopeChoices = [] {
AZStd::vector< AZStd::pair<VariableFlags::Scope, AZStd::string>> choices;
choices.emplace_back(AZStd::make_pair(VariableFlags::Scope::Graph, s_ScopeNames[0]));
choices.emplace_back(AZStd::make_pair(VariableFlags::Scope::Function, s_ScopeNames[1]));
return choices;
};
editContext->Class<GraphVariable>("Variable", "Represents a Variable field within a Script Canvas Graph")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::Visibility, &GraphVariable::GetVisibility)
@@ -215,8 +223,8 @@ namespace ScriptCanvas
->Attribute(AZ::Edit::Attributes::ChangeNotify, &GraphVariable::OnValueChanged)
->DataElement(AZ::Edit::UIHandlers::ComboBox, &GraphVariable::m_scope, "Scope", "Controls the scope of this variable. i.e. If this is exposed as input to this script, or output from this script, or if the variable is just locally scoped.")
->Attribute(AZ::Edit::Attributes::Visibility, &GraphVariable::GetInputControlVisibility)
->Attribute(AZ::Edit::Attributes::GenericValueList, &GraphVariable::GetScopes)
->Attribute(AZ::Edit::Attributes::Visibility, &GraphVariable::GetScopeControlVisibility)
->Attribute(AZ::Edit::Attributes::GenericValueList, scopeChoices)
->Attribute(AZ::Edit::Attributes::ChangeNotify, &GraphVariable::OnScopeTypedChanged)
->DataElement(AZ::Edit::UIHandlers::Default, &GraphVariable::m_networkProperties, "Network Properties", "Enables whether or not this value should be network synchronized")
@@ -382,6 +390,16 @@ namespace ScriptCanvas
m_inputControlVisibility = inputControlVisibility;
}
AZ::Crc32 GraphVariable::GetScopeControlVisibility() const
{
if (m_scope == VariableFlags::Scope::FunctionReadOnly)
{
return AZ::Edit::PropertyVisibility::Hide;
}
return GetInputControlVisibility();
}
AZ::Crc32 GraphVariable::GetInputControlVisibility() const
{
return m_inputControlVisibility;
@@ -462,6 +480,8 @@ namespace ScriptCanvas
return m_scope == VariableFlags::Scope::Graph;
// All graph variables are in function local scope
case VariableFlags::Scope::Function:
case VariableFlags::Scope::FunctionReadOnly:
return true;
}
@@ -52,8 +52,10 @@ namespace ScriptCanvas
enum class Scope : AZ::u8
{
Graph = 0,
Function = 1,
Graph,
Function,
FunctionReadOnly,
COUNT
};
enum InitialValueSource : AZ::u8
@@ -142,6 +144,7 @@ namespace ScriptCanvas
void SetScriptInputControlVisibility(const AZ::Crc32& inputControlVisibility);
AZ::Crc32 GetInputControlVisibility() const;
AZ::Crc32 GetScopeControlVisibility() const;
AZ::Crc32 GetScriptInputControlVisibility() const;
AZ::Crc32 GetNetworkSettingsVisibility() const;
AZ::Crc32 GetFunctionInputControlVisibility() const;
@@ -181,6 +184,7 @@ namespace ScriptCanvas
int GetSortPriority() const;
static const char* s_InitialValueSourceNames[VariableFlags::InitialValueSource::COUNT];
static const char* s_ScopeNames[static_cast<int>(VariableFlags::Scope::COUNT)];
private:
@@ -225,7 +225,7 @@ namespace ScriptCanvas
}
// #functions2 slot<->variable add this to the graph, using the old datum
AZ::Outcome<VariableId, AZStd::string> GraphVariableManagerComponent::AddVariable(AZStd::string_view name, const Datum& value)
AZ::Outcome<VariableId, AZStd::string> GraphVariableManagerComponent::AddVariable(AZStd::string_view name, const Datum& value, bool functionScope)
{
if (FindVariable(name))
{
@@ -245,6 +245,10 @@ namespace ScriptCanvas
GraphVariable* variable = m_variableData.FindVariable(newId);
variable->SetOwningScriptCanvasId(GetScriptCanvasId());
if (functionScope)
{
variable->SetScope(VariableFlags::Scope::FunctionReadOnly);
}
VariableRequestBus::MultiHandler::BusConnect(GraphScopedVariableId(m_scriptCanvasId, newId));
GraphVariableManagerNotificationBus::Event(GetScriptCanvasId(), &GraphVariableManagerNotifications::OnVariableAddedToGraph, newId, name);
@@ -254,7 +258,7 @@ namespace ScriptCanvas
AZ::Outcome<VariableId, AZStd::string> GraphVariableManagerComponent::AddVariablePair(const AZStd::pair<AZStd::string_view, Datum>& keyValuePair)
{
return AddVariable(keyValuePair.first, keyValuePair.second);
return AddVariable(keyValuePair.first, keyValuePair.second, false);
}
VariableValidationOutcome GraphVariableManagerComponent::IsNameValid(AZStd::string_view varName)
@@ -63,7 +63,7 @@ namespace ScriptCanvas
//// GraphVariableManagerRequestBus
AZ::Outcome<VariableId, AZStd::string> CloneVariable(const GraphVariable& variableConfiguration) override;
AZ::Outcome<VariableId, AZStd::string> RemapVariable(const GraphVariable& variableConfiguration) override;
AZ::Outcome<VariableId, AZStd::string> AddVariable(AZStd::string_view name, const Datum& value) override;
AZ::Outcome<VariableId, AZStd::string> AddVariable(AZStd::string_view name, const Datum& value, bool functionScope) override;
AZ::Outcome<VariableId, AZStd::string> AddVariablePair(const AZStd::pair<AZStd::string_view, Datum>& nameValuePair) override;
VariableValidationOutcome IsNameValid(AZStd::string_view key) override;
@@ -90,7 +90,7 @@ namespace ScriptCanvas
//! returns an AZ::Outcome which on success contains the VariableId and on Failure contains a string with error information
virtual AZ::Outcome<VariableId, AZStd::string> CloneVariable(const GraphVariable& baseVariable) = 0;
virtual AZ::Outcome<VariableId, AZStd::string> RemapVariable(const GraphVariable& variableConfiguration) = 0;
virtual AZ::Outcome<VariableId, AZStd::string> AddVariable(AZStd::string_view key, const Datum& value) = 0;
virtual AZ::Outcome<VariableId, AZStd::string> AddVariable(AZStd::string_view key, const Datum& value, bool functionScope) = 0;
virtual AZ::Outcome<VariableId, AZStd::string> AddVariablePair(const AZStd::pair<AZStd::string_view, Datum>& keyValuePair) = 0;
virtual VariableValidationOutcome IsNameValid(AZStd::string_view variableName) = 0;
@@ -63,7 +63,7 @@ namespace ScriptCanvasDeveloperEditor
ScriptCanvas::Datum datum(dataType, ScriptCanvas::Datum::eOriginality::Original);
AZ::Outcome<ScriptCanvas::VariableId, AZStd::string> outcome = AZ::Failure(AZStd::string());
m_variableRequests->AddVariable(variableName, datum);
m_variableRequests->AddVariable(variableName, datum, false);
++m_variableCounter;
}
@@ -144,7 +144,7 @@ namespace ScriptCanvasDeveloper
{
ScriptCanvasEditor::SceneCounterRequestBus::EventResult(variableCounter, m_scriptCanvasId, &ScriptCanvasEditor::SceneCounterRequests::GetNewVariableCounter);
// Cribbed from VariableDockWidget. Shuld always be in sync with that.
// From VariableDockWidget, Should always be in sync with that.
variableName = AZStd::string::format("Variable %u", variableCounter);
ScriptCanvas::GraphVariableManagerRequestBus::EventResult(nameAvailable, m_scriptCanvasId, &ScriptCanvas::GraphVariableManagerRequests::IsNameAvailable, variableName);
@@ -154,7 +154,7 @@ namespace ScriptCanvasDeveloper
ScriptCanvas::Datum datum(m_dataType, ScriptCanvas::Datum::eOriginality::Original);
AZ::Outcome<ScriptCanvas::VariableId, AZStd::string> outcome = AZ::Failure(AZStd::string());
ScriptCanvas::GraphVariableManagerRequestBus::EventResult(outcome, m_scriptCanvasId, &ScriptCanvas::GraphVariableManagerRequests::AddVariable, variableName, datum);
ScriptCanvas::GraphVariableManagerRequestBus::EventResult(outcome, m_scriptCanvasId, &ScriptCanvas::GraphVariableManagerRequests::AddVariable, variableName, datum, false);
if (outcome)
{
@@ -96,7 +96,7 @@ namespace ScriptCanvasTests
{
using namespace ScriptCanvas;
AZ::Outcome<VariableId, AZStd::string> addVariableOutcome = AZ::Failure(AZStd::string());
GraphVariableManagerRequestBus::EventResult(addVariableOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, variableName, Datum(value));
GraphVariableManagerRequestBus::EventResult(addVariableOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, variableName, Datum(value), false);
if (!addVariableOutcome)
{
AZ_Warning("Script Canvas Test", false, "%s", addVariableOutcome.GetError().data());
@@ -104,27 +104,27 @@ TEST_F(ScriptCanvasTestFixture, CreateVariableTest)
auto stringArrayDatum = Datum(StringArray());
AZ::Outcome<VariableId, AZStd::string> addPropertyOutcome(AZ::Failure(AZStd::string("Uninitialized")));
GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, "FirstVector3", vector3Datum1);
GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, "FirstVector3", vector3Datum1, false);
EXPECT_TRUE(addPropertyOutcome);
EXPECT_TRUE(addPropertyOutcome.GetValue().IsValid());
addPropertyOutcome = AZ::Failure(AZStd::string("Uninitialized"));
GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, "SecondVector3", vector3Datum2);
GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, "SecondVector3", vector3Datum2, false);
EXPECT_TRUE(addPropertyOutcome);
EXPECT_TRUE(addPropertyOutcome.GetValue().IsValid());
addPropertyOutcome = AZ::Failure(AZStd::string("Uninitialized"));
GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, "FirstVector4", vector4Datum);
GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, "FirstVector4", vector4Datum, false);
EXPECT_TRUE(addPropertyOutcome);
EXPECT_TRUE(addPropertyOutcome.GetValue().IsValid());
addPropertyOutcome = AZ::Failure(AZStd::string("Uninitialized"));
GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, "ProjectionMatrix", behaviorMatrix4x4Datum);
GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, "ProjectionMatrix", behaviorMatrix4x4Datum, false);
EXPECT_TRUE(addPropertyOutcome);
EXPECT_TRUE(addPropertyOutcome.GetValue().IsValid());
addPropertyOutcome = AZ::Failure(AZStd::string("Uninitialized"));
GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, "My String Array", stringArrayDatum);
GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, "My String Array", stringArrayDatum, false);
EXPECT_TRUE(addPropertyOutcome);
EXPECT_TRUE(addPropertyOutcome.GetValue().IsValid());
@@ -169,12 +169,12 @@ TEST_F(ScriptCanvasTestFixture, AddVariableFailTest)
const AZStd::string_view propertyName = "SameName";
AZ::Outcome<VariableId, AZStd::string> addPropertyOutcome(AZ::Failure(AZStd::string("Uninitialized")));
GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, propertyName, vector3Datum1);
GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, propertyName, vector3Datum1, false);
EXPECT_TRUE(addPropertyOutcome);
EXPECT_TRUE(addPropertyOutcome.GetValue().IsValid());
addPropertyOutcome = AZ::Failure(AZStd::string("Uninitialized"));
GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, propertyName, vector3Datum2);
GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, propertyName, vector3Datum2, false);
EXPECT_FALSE(addPropertyOutcome);
propertyEntity.reset();
@@ -208,35 +208,35 @@ TEST_F(ScriptCanvasTestFixture, RemoveVariableTest)
size_t numVariablesAdded = 0U;
AZ::Outcome<VariableId, AZStd::string> addPropertyOutcome(AZ::Failure(AZStd::string("Uninitialized")));
GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, "FirstVector3", vector3Datum1);
GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, "FirstVector3", vector3Datum1, false);
EXPECT_TRUE(addPropertyOutcome);
EXPECT_TRUE(addPropertyOutcome.GetValue().IsValid());
const VariableId firstVector3Id = addPropertyOutcome.GetValue();
++numVariablesAdded;
addPropertyOutcome = AZ::Failure(AZStd::string("Uninitialized"));
GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, "SecondVector3", vector3Datum2);
GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, "SecondVector3", vector3Datum2, false);
EXPECT_TRUE(addPropertyOutcome);
EXPECT_TRUE(addPropertyOutcome.GetValue().IsValid());
const VariableId secondVector3Id = addPropertyOutcome.GetValue();
++numVariablesAdded;
addPropertyOutcome = AZ::Failure(AZStd::string("Uninitialized"));
GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, "FirstVector4", vector4Datum);
GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, "FirstVector4", vector4Datum, false);
EXPECT_TRUE(addPropertyOutcome);
EXPECT_TRUE(addPropertyOutcome.GetValue().IsValid());
const VariableId firstVector4Id = addPropertyOutcome.GetValue();
++numVariablesAdded;
addPropertyOutcome = AZ::Failure(AZStd::string("Uninitialized"));
GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, "ProjectionMatrix", behaviorMatrix4x4Datum);
GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, "ProjectionMatrix", behaviorMatrix4x4Datum, false);
EXPECT_TRUE(addPropertyOutcome);
EXPECT_TRUE(addPropertyOutcome.GetValue().IsValid());
const VariableId projectionMatrixId = addPropertyOutcome.GetValue();
++numVariablesAdded;
addPropertyOutcome = AZ::Failure(AZStd::string("Uninitialized"));
GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, "My String Array", stringArrayDatum);
GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, "My String Array", stringArrayDatum, false);
EXPECT_TRUE(addPropertyOutcome);
EXPECT_TRUE(addPropertyOutcome.GetValue().IsValid());
const VariableId stringArrayId = addPropertyOutcome.GetValue();
@@ -294,7 +294,7 @@ TEST_F(ScriptCanvasTestFixture, RemoveVariableTest)
{
// Re-add removed Property
addPropertyOutcome = AZ::Failure(AZStd::string("Uninitialized"));
GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, "ProjectionMatrix", behaviorMatrix4x4Datum);
GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, "ProjectionMatrix", behaviorMatrix4x4Datum, false);
EXPECT_TRUE(addPropertyOutcome);
EXPECT_TRUE(addPropertyOutcome.GetValue().IsValid());
@@ -332,7 +332,7 @@ TEST_F(ScriptCanvasTestFixture, FindVariableTest)
const AZStd::string_view propertyName = "StringProperty";
AZ::Outcome<VariableId, AZStd::string> addPropertyOutcome(AZ::Failure(AZStd::string("Uninitialized")));
GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, propertyName, stringVariableDatum);
GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, propertyName, stringVariableDatum, false);
EXPECT_TRUE(addPropertyOutcome);
EXPECT_TRUE(addPropertyOutcome.GetValue().IsValid());
const VariableId stringVariableId = addPropertyOutcome.GetValue();
@@ -391,7 +391,7 @@ TEST_F(ScriptCanvasTestFixture, ModifyVariableTest)
const AZStd::string_view propertyName = "StringProperty";
AZ::Outcome<VariableId, AZStd::string> addPropertyOutcome(AZ::Failure(AZStd::string("Uninitialized")));
GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, propertyName, stringVariableDatum);
GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, propertyName, stringVariableDatum, false);
EXPECT_TRUE(addPropertyOutcome);
EXPECT_TRUE(addPropertyOutcome.GetValue().IsValid());
const VariableId stringVariableId = addPropertyOutcome.GetValue();
@@ -449,7 +449,7 @@ TEST_F(ScriptCanvasTestFixture, SerializationTest)
auto stringArrayDatum = Datum(StringArray());
AZ::Outcome<VariableId, AZStd::string> addPropertyOutcome(AZ::Failure(AZStd::string("Uninitialized")));
GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, "My String Array", stringArrayDatum);
GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, "My String Array", stringArrayDatum, false);
EXPECT_TRUE(addPropertyOutcome);
EXPECT_TRUE(addPropertyOutcome.GetValue().IsValid());
@@ -493,7 +493,7 @@ TEST_F(ScriptCanvasTestFixture, SerializationTest)
auto identityMatrixDatum = Datum(Data::Matrix3x3Type::CreateIdentity());
addPropertyOutcome = AZ::Failure(AZStd::string("Uninitialized"));
GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, "Super Matrix Bros", identityMatrixDatum);
GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, "Super Matrix Bros", identityMatrixDatum, false);
EXPECT_TRUE(addPropertyOutcome);
EXPECT_TRUE(addPropertyOutcome.GetValue().IsValid());
@@ -0,0 +1,47 @@
#!/bin/bash
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# This script must be run as root
if [[ $EUID -ne 0 ]]
then
echo "This script must be run as root (sudo)"
exit 1
fi
#
# Install curl if its not installed
#
curl --version >/dev/null 2>&1
if [ $? -ne 0 ]
then
echo "Installing curl"
apt-get install curl -y
fi
#
# Setup AWS CLI if needed
#
aws --version >/dev/null 2>&1
if [ $? -ne 0 ]
then
echo Setting up AWS CLI
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
./aws/install
rm -rf ./aws
else
AWS_CLI_VERSION=`aws --version | awk '{print $1}' | awk -F/ '{print $2}'`
echo AWS CLI \(version $AWS_CLI_VERSION\) already installed
fi
@@ -0,0 +1,103 @@
#!/bin/bash
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# This script must be run as root
if [[ $EUID -ne 0 ]]
then
echo "This script must be run as root (sudo)"
exit 1
fi
#
# Make sure we are installing on a supported ubuntu distro
#
lsb_release -c >/dev/null 2>&1
if [ $? -ne 0 ]
then
echo This script is only supported on Ubuntu Distros
exit 1
fi
UBUNTU_DISTRO="`lsb_release -c | awk '{print $2}'`"
if [ "$UBUNTU_DISTRO" == "bionic" ]
then
echo "Setup for Ubuntu 18.04 LTS ($UBUNTU_DISTRO)"
elif [ "$UBUNTU_DISTRO" == "focal" ]
then
echo "Setup for Ubuntu 20.04 LTS ($UBUNTU_DISTRO)"
else
echo "Unsupported version of Ubuntu $UBUNTU_DISTRO"
exit 1
fi
#
# Install curl if its not installed
#
curl --version >/dev/null 2>&1
if [ $? -ne 0 ]
then
echo "Installing curl"
apt-get install curl -y
fi
#
# If the linux distro is 20.04 (focal), we need libffi.so.6, which is not part of the focal distro. We
# will install it from the bionic distro manually into focal. This is needed since Ubuntu 20.04 supports
# python 3.8 out of the box, but we are using 3.7
#
LIBFFI6_COUNT=`apt list --installed 2>/dev/null | grep libffi6 | wc -l`
if [ "$UBUNTU_DISTRO" == "focal" ] && [ $LIBFFI6_COUNT -eq 0 ]
then
echo "Installing libffi for Ubuntu 20.04"
pushd /tmp >/dev/null
LIBFFI_PACKAGE_NAME=libffi6_3.2.1-8_amd64.deb
LIBFFI_PACKAGE_URL=http://mirrors.kernel.org/ubuntu/pool/main/libf/libffi/
curl --location $LIBFFI_PACKAGE_URL/$LIBFFI_PACKAGE_NAME -o $LIBFFI_PACKAGE_NAME
if [ $? -ne 0 ]
then
echo Unable to download $LIBFFI_PACKAGE_URL/$LIBFFI_PACKAGE_NAME
popd
exit 1
fi
apt install ./$LIBFFI_PACKAGE_NAME -y
if [ $? -ne 0 ]
then
echo Unable to install $LIBFFI_PACKAGE_NAME
rm -f ./$LIBFFI_PACKAGE_NAME
popd
exit 1
fi
rm -f ./$LIBFFI_PACKAGE_NAME
popd
echo "libffi.so.6 installed"
fi
# Install the required build packages
apt-get install clang-6.0 -y # For the compiler and its dependencies
apt-get install libglu1-mesa-dev -y # For Qt (GL dependency)
# The following packages resolves a runtime error with Qt Plugins
apt-get install libxcb-xinerama0 -y # For Qt plugins at runtime
apt-get install libxcb-xinput0 -y # For Qt plugins at runtime
apt-get install libcurl4-openssl-dev -y # For HttpRequestor
apt-get install libsdl2-dev -y # For WWise
apt-get install libz-dev -y
apt-get install mesa-common-dev -y
echo Build Libraries Setup Complete
@@ -0,0 +1,74 @@
#!/bin/bash
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# This script must be run as root
if [[ $EUID -ne 0 ]]
then
echo "This script must be run as root (sudo)"
exit 1
fi
#
# Make sure we are installing on a supported ubuntu distro
#
lsb_release -c >/dev/null 2>&1
if [ $? -ne 0 ]
then
echo This script is only supported on Ubuntu Distros
exit 1
fi
UBUNTU_DISTRO="`lsb_release -c | awk '{print $2}'`"
if [ "$UBUNTU_DISTRO" == "bionic" ]
then
echo "Setup for Ubuntu 18.04 LTS ($UBUNTU_DISTRO)"
elif [ "$UBUNTU_DISTRO" == "focal" ]
then
echo "Setup for Ubuntu 20.04 LTS ($UBUNTU_DISTRO)"
else
echo "Unsupported version of Ubuntu $UBUNTU_DISTRO"
exit 1
fi
#
# Always install the latest version of cmake (from kitware)
#
echo Installing CMake package $CMAKE_DISTRO_VERSION
# Remove any pre-existing version of cmake
apt purge --auto-remove cmake -y
wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | gpg --dearmor - | sudo tee /etc/apt/trusted.gpg.d/kitware.gpg >/dev/null
CMAKE_DEB_REPO="'deb https://apt.kitware.com/ubuntu/ $UBUNTU_DISTRO main'"
# Add the appropriate kitware repository to apt
if [ "$UBUNTU_DISTRO" == "bionic" ]
then
CMAKE_DISTRO_VERSION=3.20.1-0kitware1ubuntu20.04.1
apt-add-repository 'deb https://apt.kitware.com/ubuntu/ bionic main'
elif [ "$UBUNTU_DISTRO" == "focal" ]
then
CMAKE_DISTRO_VERSION=3.20.1-0kitware1ubuntu18.04.1
apt-add-repository 'deb https://apt.kitware.com/ubuntu/ focal main'
fi
apt-get update
# Install cmake
apt-get install cmake $CMAKE_DISTRO_VERSION -y
#
# Make sure that Ninja is installed
#
echo Installing Ninja
apt-get install ninja-build -y
echo Build Tools Setup Complete
@@ -0,0 +1,96 @@
#!/bin/bash
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# This script must be run as root
if [[ $EUID -ne 0 ]]
then
echo "This script must be run as root (sudo)"
exit 1
fi
#
# Make sure we are installing on a supported ubuntu distro
#
lsb_release -c >/dev/null 2>&1
if [ $? -ne 0 ]
then
echo This script is only supported on Ubuntu Distros
exit 1
fi
UBUNTU_DISTRO="`lsb_release -c | awk '{print $2}'`"
if [ "$UBUNTU_DISTRO" == "bionic" ]
then
echo "Setup for Ubuntu 18.04 LTS ($UBUNTU_DISTRO)"
elif [ "$UBUNTU_DISTRO" == "focal" ]
then
echo "Setup for Ubuntu 20.04 LTS ($UBUNTU_DISTRO)"
else
echo "Unsupported version of Ubuntu $UBUNTU_DISTRO"
exit 1
fi
#
# Setup and get the latest from git if necessary
#
git --version > /dev/null 2>&1
if [ $? -ne 0 ]
then
echo Setting up latest version of GIT
add-apt-repository ppa:git-core/ppa -y
apt-get update
apt-get install git -y
else
GIT_VERSION=`git --version | awk '{print $3}'`
echo Git $GIT_VERSION already Installed. Skipping Git installation
fi
#
# Setup Git-LFS if needed
#
GIT_LFS_PACKAGE_COUNT=`apt list --installed 2>/dev/null | grep git-lfs/ | wc -l`
if [ $GIT_LFS_PACKAGE_COUNT -eq 0 ]
then
echo Setting up Git-LFS
pushd /tmp
wget https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh -o script.deb.sh
rm script.deb.sh
mv script.deb.sh.1 script.deb.sh
chmod +x script.deb.sh
./script.deb.sh
sudo apt-get install git-lfs -y
popd
else
echo Git LFS already installed. Skipping Git-LFS installation
fi
# Setup GCM if needed
git-credential-manager-core --version > /dev/null 2>&1
if [ $? -ne 0 ]
then
# Download and setup Git Credential Manager
GCM_PACKAGE_NAME=gcmcore-linux_amd64.2.0.394.50751.deb
GCM_PACKAGE_URL=https://github.com/microsoft/Git-Credential-Manager-Core/releases/download/v2.0.394-beta
echo Installing Git Credential Manager \($GCM_PACKAGE_NAME\)
pushd /tmp > /dev/null
curl --location $GCM_PACKAGE_URL/$GCM_PACKAGE_NAME -o $GCM_PACKAGE_NAME
dpkg -i $GCM_PACKAGE_NAME
popd
else
GCM_VERSION=`git-credential-manager-core --version`
echo Git Credential Manager \(GCM\) version $GCM_VERSION already installed. Skipping GCM installation
fi
# Setup pass (password manager) for git-credential-manager
apt-get install pass -y