Merge branch 'main' into Prefab/CreatePrefab
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:171f38d536d7b805cc644513d22dae5552a4eef2bffb88e97e089898cf769530
|
||||
size 2126
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:6388466c97009fd3993e5d3b59a2b0961f623c6becbd0a12a0a5eb7bd8da5d4e
|
||||
size 12302
|
||||
@@ -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
|
||||
+2
-2
@@ -77,13 +77,13 @@ class TestImageGradient(EditorTestHelper):
|
||||
# 3) Assign the processed gradient signal image as the Image Gradient's image asset and verify success
|
||||
|
||||
# First, check for the base image in the workspace
|
||||
base_image = "lumberyard_gsi.png"
|
||||
base_image = "image_grad_test_gsi.png"
|
||||
base_image_path = os.path.join("AutomatedTesting", "Assets", "ImageGradients", base_image)
|
||||
if os.path.isfile(base_image_path):
|
||||
print(f"{base_image} was found in the workspace")
|
||||
|
||||
# Next, assign the processed image to the Image Gradient's Image Asset property
|
||||
processed_image_path = os.path.join("Assets", "ImageGradients", "lumberyard_gsi.gradimage")
|
||||
processed_image_path = os.path.join("Assets", "ImageGradients", "image_grad_test_gsi.gradimage")
|
||||
asset_id = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", processed_image_path, math.Uuid(),
|
||||
False)
|
||||
hydra.get_set_test(image_gradient_entity, 0, "Configuration|Image Asset", asset_id)
|
||||
|
||||
@@ -57,7 +57,7 @@ class TestImageGradientRequiresShape(object):
|
||||
"Entity has a Image Gradient component",
|
||||
"Entity has a Gradient Transform Modifier component",
|
||||
"Entity has a Box Shape component",
|
||||
"lumberyard_gsi.png was found in the workspace",
|
||||
"image_grad_test_gsi.png was found in the workspace",
|
||||
"Entity Configuration|Image Asset: SUCCESS",
|
||||
"ImageGradient_ProcessedImageAssignedSucessfully: result=SUCCESS",
|
||||
]
|
||||
|
||||
@@ -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": {
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <AzCore/Component/EntityId.h>
|
||||
#include <AzCore/Math/Crc.h>
|
||||
#include <AzCore/Math/Quaternion.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
|
||||
#include <Range.h>
|
||||
#include <AnimKey.h>
|
||||
@@ -914,9 +915,18 @@ struct IAnimStringTable
|
||||
*/
|
||||
struct IAnimSequence
|
||||
{
|
||||
AZ_RTTI(IAnimSequence, "{A60F95F5-5A4A-47DB-B3BB-525BBC0BC8DB}")
|
||||
AZ_RTTI(IAnimSequence, "{A60F95F5-5A4A-47DB-B3BB-525BBC0BC8DB}");
|
||||
AZ_CLASS_ALLOCATOR(IAnimSequence, AZ::SystemAllocator, 0);
|
||||
|
||||
static const int kSequenceVersion = 4;
|
||||
static const int kSequenceVersion = 5;
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context); serializeContext != nullptr)
|
||||
{
|
||||
serializeContext->Class<IAnimSequence>();
|
||||
}
|
||||
}
|
||||
|
||||
//! Flags used for SetFlags(),GetFlags(),SetParentFlags(),GetParentFlags() methods.
|
||||
enum EAnimSequenceFlags
|
||||
|
||||
@@ -178,14 +178,16 @@ namespace AZ
|
||||
//! on an update to '/Amazon/AzCore/Bootstrap/project_path' key.
|
||||
struct UpdateProjectSettingsEventHandler
|
||||
{
|
||||
UpdateProjectSettingsEventHandler(AZ::SettingsRegistryInterface& registry)
|
||||
UpdateProjectSettingsEventHandler(AZ::SettingsRegistryInterface& registry, AZ::CommandLine& commandLine)
|
||||
: m_registry{ registry }
|
||||
, m_commandLine{ commandLine }
|
||||
{
|
||||
}
|
||||
|
||||
void operator()(AZStd::string_view path, AZ::SettingsRegistryInterface::Type)
|
||||
{
|
||||
using FixedValueString = AZ::SettingsRegistryInterface::FixedValueString;
|
||||
// #1 Update the project settings when the project path is set
|
||||
const auto projectPathKey = FixedValueString(AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey) + "/project_path";
|
||||
AZ::IO::FixedMaxPath newProjectPath;
|
||||
if (SettingsRegistryMergeUtils::IsPathAncestorDescendantOrEqual(projectPathKey, path)
|
||||
@@ -194,6 +196,7 @@ namespace AZ
|
||||
UpdateProjectSettingsFromProjectPath(AZ::IO::PathView(newProjectPath));
|
||||
}
|
||||
|
||||
// #2 Update the project specialization when the project name is set
|
||||
const auto projectNameKey = FixedValueString(AZ::SettingsRegistryMergeUtils::ProjectSettingsRootKey) + "/project_name";
|
||||
FixedValueString newProjectName;
|
||||
if (SettingsRegistryMergeUtils::IsPathAncestorDescendantOrEqual(projectNameKey, path)
|
||||
@@ -201,6 +204,12 @@ namespace AZ
|
||||
{
|
||||
UpdateProjectSpecializationFromProjectName(newProjectName);
|
||||
}
|
||||
|
||||
// #3 Update the ComponentApplication CommandLine instance when the command line settings are merged into the Settings Registry
|
||||
if (path == AZ::SettingsRegistryMergeUtils::CommandLineValueChangedKey)
|
||||
{
|
||||
UpdateCommandLine();
|
||||
}
|
||||
}
|
||||
|
||||
//! Add the project name as a specialization underneath the /Amazon/AzCore/Settings/Specializations path
|
||||
@@ -233,10 +242,16 @@ namespace AZ
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(m_registry);
|
||||
}
|
||||
|
||||
void UpdateCommandLine()
|
||||
{
|
||||
AZ::SettingsRegistryMergeUtils::GetCommandLineFromRegistry(m_registry, m_commandLine);
|
||||
}
|
||||
|
||||
private:
|
||||
AZ::IO::FixedMaxPath m_oldProjectPath;
|
||||
AZ::SettingsRegistryInterface::FixedValueString m_oldProjectName;
|
||||
AZ::SettingsRegistryInterface& m_registry;
|
||||
AZ::CommandLine& m_commandLine;
|
||||
};
|
||||
|
||||
void ComponentApplication::Descriptor::AllocatorRemapping::Reflect(ReflectContext* context, ComponentApplication* app)
|
||||
@@ -415,6 +430,12 @@ namespace AZ
|
||||
// Add the Command Line arguments into the SettingsRegistry
|
||||
SettingsRegistryMergeUtils::StoreCommandLineToRegistry(*m_settingsRegistry, m_commandLine);
|
||||
|
||||
// Add a notifier to update the project_settings when
|
||||
// 1. The 'project_path' key changes
|
||||
// 2. The project specialization when the 'project-name' key changes
|
||||
// 3. The ComponentApplication command line when the command line is stored to the registry
|
||||
m_projectChangedHandler = m_settingsRegistry->RegisterNotifier(UpdateProjectSettingsEventHandler{ *m_settingsRegistry, m_commandLine });
|
||||
|
||||
// Merge Command Line arguments
|
||||
constexpr bool executeRegDumpCommands = false;
|
||||
SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(*m_settingsRegistry, m_commandLine, executeRegDumpCommands);
|
||||
@@ -429,10 +450,6 @@ namespace AZ
|
||||
// for the application root.
|
||||
CalculateAppRoot();
|
||||
|
||||
// Add a notifier to update the /Amazon/AzCore/Settings/Specializations
|
||||
// when the 'project_path' property changes within the SettingsRegistry
|
||||
m_projectChangedHandler = m_settingsRegistry->RegisterNotifier(UpdateProjectSettingsEventHandler{ *m_settingsRegistry });
|
||||
|
||||
// Merge the bootstrap.cfg file into the Settings Registry as soon as the OSAllocator has been created.
|
||||
SettingsRegistryMergeUtils::MergeSettingsToRegistry_Bootstrap(*m_settingsRegistry);
|
||||
SettingsRegistryMergeUtils::MergeSettingsToRegistry_O3deUserRegistry(*m_settingsRegistry, AZ_TRAIT_OS_PLATFORM_CODENAME, {});
|
||||
@@ -909,6 +926,8 @@ namespace AZ
|
||||
SettingsRegistryMergeUtils::MergeSettingsToRegistry_ProjectUserRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer);
|
||||
SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, m_commandLine, true);
|
||||
#endif
|
||||
// Update the Runtime file paths in case the "{BootstrapSettingsRootKey}/assets" key was overriden by a setting registry
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(registry);
|
||||
}
|
||||
|
||||
void ComponentApplication::SetSettingsRegistrySpecializations(SettingsRegistryInterface::Specializations& specializations)
|
||||
|
||||
@@ -0,0 +1,340 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Casting/numeric_cast.h>
|
||||
#include <AzCore/PlatformId/PlatformDefaults.h>
|
||||
|
||||
#include <AzCore/StringFunc/StringFunc.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
inline namespace PlatformDefaults
|
||||
{
|
||||
static const char* PlatformNames[PlatformId::NumPlatformIds] = { PlatformPC, PlatformES3, PlatformIOS, PlatformOSX, PlatformProvo, PlatformSalem, PlatformJasper, PlatformServer, PlatformAll, PlatformAllClient };
|
||||
|
||||
const char* PlatformIdToPalFolder(AZ::PlatformId platform)
|
||||
{
|
||||
#ifdef IOS
|
||||
#define AZ_REDEFINE_IOS_AT_END IOS
|
||||
#undef IOS
|
||||
#endif
|
||||
switch (platform)
|
||||
{
|
||||
case AZ::PC:
|
||||
return "PC";
|
||||
case AZ::ES3:
|
||||
return "Android";
|
||||
case AZ::IOS:
|
||||
return "iOS";
|
||||
case AZ::OSX:
|
||||
return "Mac";
|
||||
case AZ::PROVO:
|
||||
return "Provo";
|
||||
case AZ::SALEM:
|
||||
return "Salem";
|
||||
case AZ::JASPER:
|
||||
return "Jasper";
|
||||
case AZ::SERVER:
|
||||
return "Server";
|
||||
case AZ::ALL:
|
||||
case AZ::ALL_CLIENT:
|
||||
case AZ::NumPlatformIds:
|
||||
case AZ::Invalid:
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
|
||||
#ifdef AZ_REDEFINE_IOS_AT_END
|
||||
#define IOS AZ_REDEFINE_IOS_AT_END
|
||||
#endif
|
||||
}
|
||||
|
||||
const char* OSPlatformToDefaultAssetPlatform(AZStd::string_view osPlatform)
|
||||
{
|
||||
if (osPlatform == PlatformCodeNameWindows || osPlatform == PlatformCodeNameLinux)
|
||||
{
|
||||
return PlatformPC;
|
||||
}
|
||||
else if (osPlatform == PlatformCodeNameMac)
|
||||
{
|
||||
return PlatformOSX;
|
||||
}
|
||||
else if (osPlatform == PlatformCodeNameAndroid)
|
||||
{
|
||||
return PlatformES3;
|
||||
}
|
||||
else if (osPlatform == PlatformCodeNameiOS)
|
||||
{
|
||||
return PlatformIOS;
|
||||
}
|
||||
else if (osPlatform == PlatformCodeNameProvo)
|
||||
{
|
||||
return PlatformProvo;
|
||||
}
|
||||
else if (osPlatform == PlatformCodeNameSalem)
|
||||
{
|
||||
return PlatformSalem;
|
||||
}
|
||||
else if (osPlatform == PlatformCodeNameJasper)
|
||||
{
|
||||
return PlatformJasper;
|
||||
}
|
||||
|
||||
AZ_Error("PlatformDefault", false, R"(Supplied OS platform "%.*s" does not have a corresponding default asset platform)",
|
||||
aznumeric_cast<int>(osPlatform.size()), osPlatform.data());
|
||||
return "";
|
||||
}
|
||||
|
||||
PlatformFlags PlatformHelper::GetPlatformFlagFromPlatformIndex(PlatformId platformIndex)
|
||||
{
|
||||
if (platformIndex < 0 || platformIndex > PlatformId::NumPlatformIds)
|
||||
{
|
||||
return PlatformFlags::Platform_NONE;
|
||||
}
|
||||
if (platformIndex == PlatformId::ALL)
|
||||
{
|
||||
return PlatformFlags::Platform_ALL;
|
||||
}
|
||||
if (platformIndex == PlatformId::ALL_CLIENT)
|
||||
{
|
||||
return PlatformFlags::Platform_ALL_CLIENT;
|
||||
}
|
||||
return static_cast<PlatformFlags>(1 << platformIndex);
|
||||
}
|
||||
|
||||
AZStd::fixed_vector<AZStd::string_view, PlatformId::NumPlatformIds> PlatformHelper::GetPlatforms(PlatformFlags platformFlags)
|
||||
{
|
||||
AZStd::fixed_vector<AZStd::string_view, PlatformId::NumPlatformIds> platforms;
|
||||
for (int platformNum = 0; platformNum < PlatformId::NumPlatformIds; ++platformNum)
|
||||
{
|
||||
const bool isAllPlatforms = PlatformId::ALL == static_cast<PlatformId>(platformNum)
|
||||
&& ((platformFlags & PlatformFlags::Platform_ALL) != PlatformFlags::Platform_NONE);
|
||||
|
||||
const bool isAllClientPlatforms = PlatformId::ALL_CLIENT == static_cast<PlatformId>(platformNum)
|
||||
&& ((platformFlags & PlatformFlags::Platform_ALL_CLIENT) != PlatformFlags::Platform_NONE);
|
||||
|
||||
if (isAllPlatforms || isAllClientPlatforms
|
||||
|| (platformFlags & static_cast<PlatformFlags>(1 << platformNum)) != PlatformFlags::Platform_NONE)
|
||||
{
|
||||
platforms.push_back(PlatformNames[platformNum]);
|
||||
}
|
||||
}
|
||||
|
||||
return platforms;
|
||||
}
|
||||
|
||||
AZStd::fixed_vector<AZStd::string_view, PlatformId::NumPlatformIds> PlatformHelper::GetPlatformsInterpreted(PlatformFlags platformFlags)
|
||||
{
|
||||
return GetPlatforms(GetPlatformFlagsInterpreted(platformFlags));
|
||||
}
|
||||
|
||||
AZStd::fixed_vector<PlatformId, PlatformId::NumPlatformIds> PlatformHelper::GetPlatformIndices(PlatformFlags platformFlags)
|
||||
{
|
||||
AZStd::fixed_vector<PlatformId, PlatformId::NumPlatformIds> platformIndices;
|
||||
for (int i = 0; i < PlatformId::NumPlatformIds; i++)
|
||||
{
|
||||
PlatformId index = static_cast<PlatformId>(i);
|
||||
if ((GetPlatformFlagFromPlatformIndex(index) & platformFlags) != PlatformFlags::Platform_NONE)
|
||||
{
|
||||
platformIndices.emplace_back(index);
|
||||
}
|
||||
}
|
||||
return platformIndices;
|
||||
}
|
||||
|
||||
AZStd::fixed_vector<PlatformId, PlatformId::NumPlatformIds> PlatformHelper::GetPlatformIndicesInterpreted(PlatformFlags platformFlags)
|
||||
{
|
||||
return GetPlatformIndices(GetPlatformFlagsInterpreted(platformFlags));
|
||||
}
|
||||
|
||||
PlatformFlags PlatformHelper::GetPlatformFlag(AZStd::string_view platform)
|
||||
{
|
||||
int platformIndex = GetPlatformIndexFromName(platform);
|
||||
if (platformIndex == PlatformId::Invalid)
|
||||
{
|
||||
AZ_Error("PlatformDefault", false, "Invalid Platform ( %.*s ).\n", static_cast<int>(platform.length()), platform.data());
|
||||
return PlatformFlags::Platform_NONE;
|
||||
}
|
||||
|
||||
if (platformIndex == PlatformId::ALL)
|
||||
{
|
||||
return PlatformFlags::Platform_ALL;
|
||||
}
|
||||
|
||||
if (platformIndex == PlatformId::ALL_CLIENT)
|
||||
{
|
||||
return PlatformFlags::Platform_ALL_CLIENT;
|
||||
}
|
||||
|
||||
return static_cast<PlatformFlags>(1 << platformIndex);
|
||||
}
|
||||
|
||||
const char* PlatformHelper::GetPlatformName(PlatformId platform)
|
||||
{
|
||||
if (platform < 0 || platform > PlatformId::NumPlatformIds)
|
||||
{
|
||||
return "invalid";
|
||||
}
|
||||
return PlatformNames[platform];
|
||||
}
|
||||
|
||||
void PlatformHelper::AppendPlatformCodeNames(AZStd::fixed_vector<AZStd::string_view, MaxPlatformCodeNames>& platformCodes, AZStd::string_view platformId)
|
||||
{
|
||||
PlatformId platform = GetPlatformIdFromName(platformId);
|
||||
AZ_Assert(platform != PlatformId::Invalid, "Unsupported Platform ID: %.*s", static_cast<int>(platformId.length()), platformId.data());
|
||||
AppendPlatformCodeNames(platformCodes, platform);
|
||||
}
|
||||
|
||||
void PlatformHelper::AppendPlatformCodeNames(AZStd::fixed_vector<AZStd::string_view, MaxPlatformCodeNames>& platformCodes, PlatformId platformId)
|
||||
{
|
||||
// The IOS SDK has a macro that defines IOS as 1 which causes the enum below to be incorrectly converted to "PlatformId::1".
|
||||
#pragma push_macro("IOS")
|
||||
#undef IOS
|
||||
// To reduce work the Asset Processor groups assets that can be shared between hardware platforms together. For this
|
||||
// reason "PC" can for instance cover both the Windows and Linux platforms and "IOS" can cover AppleTV and iOS.
|
||||
switch (platformId)
|
||||
{
|
||||
case PlatformId::PC:
|
||||
platformCodes.emplace_back(PlatformCodeNameWindows);
|
||||
platformCodes.emplace_back(PlatformCodeNameLinux);
|
||||
break;
|
||||
case PlatformId::ES3:
|
||||
platformCodes.emplace_back(PlatformCodeNameAndroid);
|
||||
break;
|
||||
case PlatformId::IOS:
|
||||
platformCodes.emplace_back(PlatformCodeNameiOS);
|
||||
break;
|
||||
case PlatformId::OSX:
|
||||
platformCodes.emplace_back(PlatformCodeNameMac);
|
||||
break;
|
||||
case PlatformId::PROVO:
|
||||
platformCodes.emplace_back(PlatformCodeNameProvo);
|
||||
break;
|
||||
case PlatformId::SALEM:
|
||||
platformCodes.emplace_back(PlatformCodeNameSalem);
|
||||
break;
|
||||
case PlatformId::JASPER:
|
||||
platformCodes.emplace_back(PlatformCodeNameJasper);
|
||||
break;
|
||||
case PlatformId::SERVER:
|
||||
// Server is not a hardware platform
|
||||
break;
|
||||
default:
|
||||
AZ_Assert(false, "Unsupported Platform ID: %i", platformId);
|
||||
break;
|
||||
}
|
||||
#pragma pop_macro("IOS")
|
||||
}
|
||||
|
||||
int PlatformHelper::GetPlatformIndexFromName(AZStd::string_view platformName)
|
||||
{
|
||||
for (int idx = 0; idx < PlatformId::NumPlatformIds; idx++)
|
||||
{
|
||||
if (platformName == PlatformNames[idx])
|
||||
{
|
||||
return idx;
|
||||
}
|
||||
}
|
||||
|
||||
return PlatformId::Invalid;
|
||||
}
|
||||
|
||||
PlatformId PlatformHelper::GetPlatformIdFromName(AZStd::string_view platformName)
|
||||
{
|
||||
return aznumeric_caster(GetPlatformIndexFromName(platformName));
|
||||
}
|
||||
|
||||
AssetPlatformCombinedString PlatformHelper::GetCommaSeparatedPlatformList(PlatformFlags platformFlags)
|
||||
{
|
||||
AZStd::fixed_vector<AZStd::string_view, PlatformId::NumPlatformIds> platformNames = GetPlatforms(platformFlags);
|
||||
AssetPlatformCombinedString platformsString;
|
||||
AZ::StringFunc::Join(platformsString, platformNames.begin(), platformNames.end(), ", ");
|
||||
return platformsString;
|
||||
}
|
||||
|
||||
PlatformFlags PlatformHelper::GetPlatformFlagsInterpreted(PlatformFlags platformFlags)
|
||||
{
|
||||
PlatformFlags returnFlags = PlatformFlags::Platform_NONE;
|
||||
|
||||
if ((platformFlags & PlatformFlags::Platform_ALL) != PlatformFlags::Platform_NONE)
|
||||
{
|
||||
for (int i = 0; i < NumPlatforms; ++i)
|
||||
{
|
||||
auto platformId = static_cast<PlatformId>(i);
|
||||
|
||||
if (platformId != PlatformId::ALL && platformId != PlatformId::ALL_CLIENT)
|
||||
{
|
||||
returnFlags |= GetPlatformFlagFromPlatformIndex(platformId);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((platformFlags & PlatformFlags::Platform_ALL_CLIENT) != PlatformFlags::Platform_NONE)
|
||||
{
|
||||
for (int i = 0; i < NumPlatforms; ++i)
|
||||
{
|
||||
auto platformId = static_cast<PlatformId>(i);
|
||||
|
||||
if (platformId != PlatformId::ALL && platformId != PlatformId::ALL_CLIENT && platformId != PlatformId::SERVER)
|
||||
{
|
||||
returnFlags |= GetPlatformFlagFromPlatformIndex(platformId);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
returnFlags = platformFlags;
|
||||
}
|
||||
|
||||
return returnFlags;
|
||||
}
|
||||
|
||||
bool PlatformHelper::IsSpecialPlatform(PlatformFlags platformFlags)
|
||||
{
|
||||
return (platformFlags & PlatformFlags::Platform_ALL) != PlatformFlags::Platform_NONE
|
||||
|| (platformFlags & PlatformFlags::Platform_ALL_CLIENT) != PlatformFlags::Platform_NONE;
|
||||
}
|
||||
|
||||
bool HasFlagHelper(PlatformFlags flags, PlatformFlags checkPlatform)
|
||||
{
|
||||
return (flags & checkPlatform) == checkPlatform;
|
||||
}
|
||||
|
||||
|
||||
bool PlatformHelper::HasPlatformFlag(PlatformFlags flags, PlatformId checkPlatform)
|
||||
{
|
||||
// If checkPlatform contains any kind of invalid id, just exit out here
|
||||
if (checkPlatform == PlatformId::Invalid || checkPlatform == NumPlatforms)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// ALL_CLIENT + SERVER = ALL
|
||||
if (HasFlagHelper(flags, PlatformFlags::Platform_ALL_CLIENT | PlatformFlags::Platform_SERVER))
|
||||
{
|
||||
flags = PlatformFlags::Platform_ALL;
|
||||
}
|
||||
|
||||
if (HasFlagHelper(flags, PlatformFlags::Platform_ALL))
|
||||
{
|
||||
// It doesn't matter what checkPlatform is set to in this case, just return true
|
||||
return true;
|
||||
}
|
||||
|
||||
if (HasFlagHelper(flags, PlatformFlags::Platform_ALL_CLIENT))
|
||||
{
|
||||
return checkPlatform != PlatformId::SERVER;
|
||||
}
|
||||
|
||||
return HasFlagHelper(flags, GetPlatformFlagFromPlatformIndex(checkPlatform));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Preprocessor/Enum.h>
|
||||
#include <AzCore/std/containers/fixed_vector.h>
|
||||
#include <AzCore/std/containers/unordered_map.h>
|
||||
#include <AzCore/std/string/fixed_string.h>
|
||||
#include <AzCore/std/string/string_view.h>
|
||||
|
||||
// On IOS builds IOS will be defined and interfere with the below enums
|
||||
#pragma push_macro("IOS")
|
||||
#undef IOS
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
inline namespace PlatformDefaults
|
||||
{
|
||||
constexpr char PlatformPC[] = "pc";
|
||||
constexpr char PlatformES3[] = "es3";
|
||||
constexpr char PlatformIOS[] = "ios";
|
||||
constexpr char PlatformOSX[] = "osx_gl";
|
||||
constexpr char PlatformProvo[] = "provo";
|
||||
constexpr char PlatformSalem[] = "salem";
|
||||
constexpr char PlatformJasper[] = "jasper";
|
||||
constexpr char PlatformServer[] = "server";
|
||||
|
||||
constexpr char PlatformCodeNameWindows[] = "Windows";
|
||||
constexpr char PlatformCodeNameLinux[] = "Linux";
|
||||
constexpr char PlatformCodeNameAndroid[] = "Android";
|
||||
constexpr char PlatformCodeNameiOS[] = "iOS";
|
||||
constexpr char PlatformCodeNameMac[] = "Mac";
|
||||
constexpr char PlatformCodeNameProvo[] = "Provo";
|
||||
constexpr char PlatformCodeNameSalem[] = "Salem";
|
||||
constexpr char PlatformCodeNameJasper[] = "Jasper";
|
||||
constexpr char PlatformAll[] = "all";
|
||||
constexpr char PlatformAllClient[] = "all_client";
|
||||
|
||||
// Used for the capacity of a fixed vector to store the code names of platforms
|
||||
// The value needs to be higher than the number of unique OS platforms that are supported(at this time 8)
|
||||
constexpr size_t MaxPlatformCodeNames = 16;
|
||||
|
||||
//! This platform enum have platform values in sequence and can also be used to get the platform count.
|
||||
AZ_ENUM_WITH_UNDERLYING_TYPE(PlatformId, int,
|
||||
(Invalid, -1),
|
||||
PC,
|
||||
ES3,
|
||||
IOS,
|
||||
OSX,
|
||||
PROVO,
|
||||
SALEM,
|
||||
JASPER,
|
||||
SERVER, // Corresponds to the customer's flavor of "server" which could be windows, ubuntu, etc
|
||||
ALL,
|
||||
ALL_CLIENT,
|
||||
|
||||
// Add new platforms above this
|
||||
NumPlatformIds
|
||||
);
|
||||
constexpr int NumClientPlatforms = 7;
|
||||
constexpr int NumPlatforms = NumClientPlatforms + 1; // 1 "Server" platform currently
|
||||
enum class PlatformFlags : AZ::u32
|
||||
{
|
||||
Platform_NONE = 0x00,
|
||||
Platform_PC = 1 << PlatformId::PC,
|
||||
Platform_ES3 = 1 << PlatformId::ES3,
|
||||
Platform_IOS = 1 << PlatformId::IOS,
|
||||
Platform_OSX = 1 << PlatformId::OSX,
|
||||
Platform_PROVO = 1 << PlatformId::PROVO,
|
||||
Platform_SALEM = 1 << PlatformId::SALEM,
|
||||
Platform_JASPER = 1 << PlatformId::JASPER,
|
||||
Platform_SERVER = 1 << PlatformId::SERVER,
|
||||
|
||||
// A special platform that will always correspond to all platforms, even if new ones are added
|
||||
Platform_ALL = 1ULL << 30,
|
||||
|
||||
// A special platform that will always correspond to all non-server platforms, even if new ones are added
|
||||
Platform_ALL_CLIENT = 1ULL << 31,
|
||||
|
||||
AllNamedPlatforms = Platform_PC | Platform_ES3 | Platform_IOS | Platform_OSX | Platform_PROVO | Platform_SALEM | Platform_JASPER | Platform_SERVER,
|
||||
};
|
||||
|
||||
AZ_DEFINE_ENUM_BITWISE_OPERATORS(PlatformFlags);
|
||||
|
||||
// 32 characters should be more than enough to store a platform name
|
||||
using AssetPlatformFixedString = AZStd::fixed_string<32>;
|
||||
// Fixed string which can store a comma separated list of platforms names
|
||||
// Additional byte is added to take into account the comma
|
||||
using AssetPlatformCombinedString = AZStd::fixed_string < (AssetPlatformFixedString{}.max_size() + 1)* PlatformId::NumPlatformIds > ;
|
||||
|
||||
const char* PlatformIdToPalFolder(PlatformId platform);
|
||||
|
||||
const char* OSPlatformToDefaultAssetPlatform(AZStd::string_view osPlatform);
|
||||
|
||||
//! Platform Helper is an utility class that can be used to retrieve platform related information
|
||||
class PlatformHelper
|
||||
{
|
||||
public:
|
||||
|
||||
//! Given a platformIndex returns the platform name
|
||||
static const char* GetPlatformName(PlatformId platform);
|
||||
|
||||
//! Converts the platform name to the platform code names as defined in AZ_TRAIT_OS_PLATFORM_CODENAME.
|
||||
static void AppendPlatformCodeNames(AZStd::fixed_vector<AZStd::string_view, MaxPlatformCodeNames>& platformCodes, AZStd::string_view platformName);
|
||||
|
||||
//! Converts the platform name to the platform code names as defined in AZ_TRAIT_OS_PLATFORM_CODENAME.
|
||||
static void AppendPlatformCodeNames(AZStd::fixed_vector<AZStd::string_view, MaxPlatformCodeNames>& platformCodes, PlatformId platformId);
|
||||
|
||||
//! Given a platform name returns a platform index.
|
||||
//! If the platform is not found, the method returns -1.
|
||||
static int GetPlatformIndexFromName(AZStd::string_view platformName);
|
||||
|
||||
//! Given a platform name returns a platform id.
|
||||
//! If the platform is not found, the method returns -1.
|
||||
static PlatformId GetPlatformIdFromName(AZStd::string_view platformName);
|
||||
|
||||
//! Given a platformIndex returns the platformFlags
|
||||
static PlatformFlags GetPlatformFlagFromPlatformIndex(PlatformId platform);
|
||||
|
||||
//! Given a platformFlags returns all the platform identifiers that are set.
|
||||
static AZStd::fixed_vector<AZStd::string_view, PlatformId::NumPlatformIds> GetPlatforms(PlatformFlags platformFlags);
|
||||
//! Given a platformFlags returns all the platform identifiers that are set, with special flags interpreted. Do not use the result for saving
|
||||
static AZStd::fixed_vector<AZStd::string_view, PlatformId::NumPlatformIds> GetPlatformsInterpreted(PlatformFlags platformFlags);
|
||||
|
||||
//! Given a platformFlags return a list of PlatformId indices
|
||||
static AZStd::fixed_vector<PlatformId, PlatformId::NumPlatformIds> GetPlatformIndices(PlatformFlags platformFlags);
|
||||
//! Given a platformFlags return a list of PlatformId indices, with special flags interpreted. Do not use the result for saving
|
||||
static AZStd::fixed_vector<PlatformId, PlatformId::NumPlatformIds> GetPlatformIndicesInterpreted(PlatformFlags platformFlags);
|
||||
|
||||
//! Given a platform identifier returns its corresponding platform flag.
|
||||
static PlatformFlags GetPlatformFlag(AZStd::string_view platform);
|
||||
|
||||
//! Given any platformFlags returns a string listing the input platforms
|
||||
static AssetPlatformCombinedString GetCommaSeparatedPlatformList(PlatformFlags platformFlags);
|
||||
|
||||
//! If platformFlags contains any special flags, they are removed and replaced with the normal flags they represent
|
||||
static PlatformFlags GetPlatformFlagsInterpreted(PlatformFlags platformFlags);
|
||||
|
||||
//! Returns true if platformFlags contains any special flags
|
||||
static bool IsSpecialPlatform(PlatformFlags platformFlags);
|
||||
|
||||
//! Returns true if platformFlags has checkPlatform flag set.
|
||||
static bool HasPlatformFlag(PlatformFlags platformFlags, PlatformId checkPlatform);
|
||||
};
|
||||
}
|
||||
}
|
||||
#pragma pop_macro("IOS")
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <AzCore/JSON/pointer.h>
|
||||
#include <AzCore/JSON/prettywriter.h>
|
||||
#include <AzCore/JSON/writer.h>
|
||||
#include <AzCore/PlatformId/PlatformDefaults.h>
|
||||
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
|
||||
#include <AzCore/Settings/CommandLine.h>
|
||||
#include <AzCore/std/string/conversions.h>
|
||||
@@ -132,23 +133,14 @@ namespace AZ::Internal
|
||||
|
||||
AZ::IO::FixedMaxPath ScanUpRootLocator(AZStd::string_view rootFileToLocate)
|
||||
{
|
||||
|
||||
AZStd::fixed_string<AZ::IO::MaxPathLength> executableDir;
|
||||
if (AZ::Utils::GetExecutableDirectory(executableDir.data(), executableDir.capacity()) == Utils::ExecutablePathResult::Success)
|
||||
{
|
||||
// Update the size value of the executable directory fixed string to correctly be the length of the null-terminated string
|
||||
// stored within it
|
||||
executableDir.resize_no_construct(AZStd::char_traits<char>::length(executableDir.data()));
|
||||
}
|
||||
|
||||
AZ::IO::FixedMaxPath engineRootCandidate{ executableDir };
|
||||
AZ::IO::FixedMaxPath rootCandidate{ AZ::Utils::GetExecutableDirectory() };
|
||||
|
||||
bool rootPathVisited = false;
|
||||
do
|
||||
{
|
||||
if (AZ::IO::SystemFile::Exists((engineRootCandidate / rootFileToLocate).c_str()))
|
||||
if (AZ::IO::SystemFile::Exists((rootCandidate / rootFileToLocate).c_str()))
|
||||
{
|
||||
return engineRootCandidate;
|
||||
return rootCandidate;
|
||||
}
|
||||
|
||||
// Note for posix filesystems the parent directory of '/' is '/' and for windows
|
||||
@@ -156,38 +148,69 @@ namespace AZ::Internal
|
||||
|
||||
// Validate that the parent directory isn't itself, that would imply
|
||||
// that it is the filesystem root path
|
||||
AZ::IO::PathView parentPath = engineRootCandidate.ParentPath();
|
||||
rootPathVisited = (engineRootCandidate == parentPath);
|
||||
AZ::IO::PathView parentPath = rootCandidate.ParentPath();
|
||||
rootPathVisited = (rootCandidate == parentPath);
|
||||
// Recurse upwards one directory
|
||||
engineRootCandidate = AZStd::move(parentPath);
|
||||
rootCandidate = AZStd::move(parentPath);
|
||||
|
||||
} while (!rootPathVisited);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
void InjectSettingToCommandLineFront(AZ::SettingsRegistryInterface& settingsRegistry,
|
||||
AZStd::string_view path, AZStd::string_view value)
|
||||
{
|
||||
AZ::CommandLine commandLine;
|
||||
AZ::SettingsRegistryMergeUtils::GetCommandLineFromRegistry(settingsRegistry, commandLine);
|
||||
AZ::CommandLine::ParamContainer paramContainer;
|
||||
commandLine.Dump(paramContainer);
|
||||
|
||||
auto projectPathOverride = AZStd::string::format(R"(--regset="%.*s=%.*s")",
|
||||
aznumeric_cast<int>(path.size()), path.data(), aznumeric_cast<int>(value.size()), value.data());
|
||||
paramContainer.emplace(paramContainer.begin(), AZStd::move(projectPathOverride));
|
||||
commandLine.Parse(paramContainer);
|
||||
AZ::SettingsRegistryMergeUtils::StoreCommandLineToRegistry(settingsRegistry, commandLine);
|
||||
}
|
||||
} // namespace AZ::Internal
|
||||
|
||||
namespace AZ::SettingsRegistryMergeUtils
|
||||
{
|
||||
constexpr AZStd::string_view InternalScanUpEngineRootKey{ "/O3DE/Settings/Internal/engine_root_scan_up_path" };
|
||||
constexpr AZStd::string_view InternalScanUpProjectRootKey{ "/O3DE/Settings/Internal/project_root_scan_up_path" };
|
||||
|
||||
AZ::IO::FixedMaxPath FindEngineRoot(SettingsRegistryInterface& settingsRegistry)
|
||||
{
|
||||
AZ::IO::FixedMaxPath engineRoot;
|
||||
|
||||
// This is the 'external' engine root key, as in passed from command-line or .setreg files.
|
||||
auto engineRootKey = SettingsRegistryInterface::FixedValueString::format("%s/engine_path", BootstrapSettingsRootKey);
|
||||
|
||||
// Step 1 Run the scan upwards logic once to find the location of the engine.json if it exist
|
||||
// Once this step is run the {InternalScanUpEngineRootKey} is set in the Settings Registry
|
||||
// to have this scan logic only run once InternalScanUpEngineRootKey the supplied registry
|
||||
if (settingsRegistry.GetType(InternalScanUpEngineRootKey) == SettingsRegistryInterface::Type::NoType)
|
||||
{
|
||||
// We can scan up from exe directory to find engine.json, use that for engine root if it exists.
|
||||
engineRoot = Internal::ScanUpRootLocator("engine.json");
|
||||
// Set the {InternalScanUpEngineRootKey} to make sure this code path isn't called again for this settings registry
|
||||
settingsRegistry.Set(InternalScanUpEngineRootKey, engineRoot.Native());
|
||||
if (!engineRoot.empty())
|
||||
{
|
||||
settingsRegistry.Set(engineRootKey, engineRoot.Native());
|
||||
// Inject the engine root into the front of the command line settings
|
||||
Internal::InjectSettingToCommandLineFront(settingsRegistry, engineRootKey, engineRoot.Native());
|
||||
return engineRoot;
|
||||
}
|
||||
}
|
||||
|
||||
// Step 2 check if the engine_path key has been supplied
|
||||
if (settingsRegistry.Get(engineRoot.Native(), engineRootKey); !engineRoot.empty())
|
||||
{
|
||||
return engineRoot;
|
||||
}
|
||||
|
||||
// We can scan up from exe directory to find engine.json, use that for engine root if it exists.
|
||||
if (engineRoot = Internal::ScanUpRootLocator("engine.json"); !engineRoot.empty())
|
||||
{
|
||||
settingsRegistry.Set(engineRootKey, engineRoot.c_str());
|
||||
return engineRoot;
|
||||
}
|
||||
|
||||
// Step 3 locate the project root and attempt to find the engine root using the registered engine
|
||||
// for the project in the project.json file
|
||||
AZ::IO::FixedMaxPath projectRoot = FindProjectRoot(settingsRegistry);
|
||||
if (projectRoot.empty())
|
||||
{
|
||||
@@ -207,16 +230,30 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
AZ::IO::FixedMaxPath FindProjectRoot(SettingsRegistryInterface& settingsRegistry)
|
||||
{
|
||||
AZ::IO::FixedMaxPath projectRoot;
|
||||
// This is the 'external' project root key, as in passed from command-line or .setreg files.
|
||||
auto projectRootKey = SettingsRegistryInterface::FixedValueString::format("%s/project_path", BootstrapSettingsRootKey);
|
||||
if (settingsRegistry.Get(projectRoot.Native(), projectRootKey))
|
||||
const auto projectRootKey = SettingsRegistryInterface::FixedValueString::format("%s/project_path", BootstrapSettingsRootKey);
|
||||
|
||||
// Step 1 Run the scan upwards logic once to find the location of the project.json if it exist
|
||||
// Once this step is run the {InternalScanUpProjectRootKey} is set in the Settings Registry
|
||||
// to have this scan logic only run once for the supplied registry
|
||||
// SettingsRegistryInterface::GetType is used to check if a key is set
|
||||
if (settingsRegistry.GetType(InternalScanUpProjectRootKey) == SettingsRegistryInterface::Type::NoType)
|
||||
{
|
||||
return projectRoot;
|
||||
projectRoot = Internal::ScanUpRootLocator("project.json");
|
||||
// Set the {InternalScanUpProjectRootKey} to make sure this code path isn't called again for this settings registry
|
||||
settingsRegistry.Set(InternalScanUpProjectRootKey, projectRoot.Native());
|
||||
if (!projectRoot.empty())
|
||||
{
|
||||
settingsRegistry.Set(projectRootKey, projectRoot.c_str());
|
||||
// Inject the project root into the front of the command line settings
|
||||
Internal::InjectSettingToCommandLineFront(settingsRegistry, projectRootKey, projectRoot.Native());
|
||||
return projectRoot;
|
||||
}
|
||||
}
|
||||
|
||||
if (projectRoot = Internal::ScanUpRootLocator("project.json"); !projectRoot.empty())
|
||||
// Step 2 Check the project-path key
|
||||
// This is the project path root key, as in passed from command-line or .setreg files.
|
||||
if (settingsRegistry.Get(projectRoot.Native(), projectRootKey))
|
||||
{
|
||||
settingsRegistry.Set(projectRootKey, projectRoot.c_str());
|
||||
return projectRoot;
|
||||
}
|
||||
|
||||
@@ -463,24 +500,13 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
void MergeSettingsToRegistry_Bootstrap(SettingsRegistryInterface& registry)
|
||||
{
|
||||
ConfigParserSettings parserSettings;
|
||||
parserSettings.m_commentPrefixFunc = [](AZStd::string_view line) -> AZStd::string_view
|
||||
{
|
||||
constexpr AZStd::string_view commentPrefixes[]{ "--", ";","#" };
|
||||
for (AZStd::string_view commentPrefix : commentPrefixes)
|
||||
{
|
||||
if (size_t commentOffset = line.find(commentPrefix); commentOffset != AZStd::string_view::npos)
|
||||
{
|
||||
return line.substr(0, commentOffset);
|
||||
}
|
||||
}
|
||||
return line;
|
||||
};
|
||||
parserSettings.m_registryRootPointerPath = BootstrapSettingsRootKey;
|
||||
MergeSettingsToRegistry_ConfigFile(registry, "bootstrap.cfg", parserSettings);
|
||||
}
|
||||
|
||||
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());
|
||||
@@ -489,27 +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;
|
||||
|
||||
SettingsRegistryInterface::FixedValueString assetPlatform;
|
||||
buffer = AZStd::fixed_string<bufferSize>::format("%s/%s_assets", BootstrapSettingsRootKey, platformName);
|
||||
AZStd::string_view assetPlatformKey(buffer);
|
||||
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.
|
||||
@@ -549,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))
|
||||
@@ -807,6 +830,11 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
++argumentIndex;
|
||||
commandLinePath.resize(commandLineRootSize);
|
||||
}
|
||||
|
||||
// This key is used allow Notification Handlers to know when the command line has been updated within the
|
||||
// registry. The value itself is meaningless. The JSON path of {CommandLineValueChangedKey}
|
||||
// being passed to the Notification Event Handler indicates that the command line has be updated
|
||||
registry.Set(CommandLineValueChangedKey, true);
|
||||
}
|
||||
|
||||
bool GetCommandLineFromRegistry(SettingsRegistryInterface& registry, AZ::CommandLine& commandLine)
|
||||
@@ -823,10 +851,16 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
}
|
||||
else if (valueName == "Value" && !value.empty())
|
||||
{
|
||||
m_arguments.push_back(value);
|
||||
// Make sure value types are in quotes in case they start with a command option prefix
|
||||
m_arguments.push_back(QuoteArgument(value));
|
||||
}
|
||||
}
|
||||
|
||||
AZStd::string QuoteArgument(AZStd::string_view arg)
|
||||
{
|
||||
return !arg.empty() ? AZStd::string::format(R"("%.*s")", aznumeric_cast<int>(arg.size()), arg.data()) : AZStd::string{ arg };
|
||||
}
|
||||
|
||||
// The first parameter is skipped by the ComamndLine::Parse function so initialize
|
||||
// the container with one empty element
|
||||
AZ::CommandLine::ParamContainer m_arguments{ 1 };
|
||||
|
||||
@@ -57,6 +57,9 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
|
||||
//! Root key for where command line are stored at within the settings registry
|
||||
inline static constexpr char CommandLineRootKey[] = "/Amazon/AzCore/Runtime/CommandLine";
|
||||
//! Key set to trigger a notification that the CommandLine has been stored within the settings registry
|
||||
//! The value of the key has no meaning. Notification Handlers only need to check if the key was supplied
|
||||
inline static constexpr char CommandLineValueChangedKey[] = "/Amazon/AzCore/Runtime/CommandLineChanged";
|
||||
|
||||
//! Root key where raw project settings (project.json) file is merged to settings registry
|
||||
inline static constexpr char ProjectSettingsRootKey[] = "/Amazon/Project/Settings";
|
||||
@@ -74,6 +77,20 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
//! If it's still not found, attempt to find the project (by similar means) then reconcile the
|
||||
//! engine root by inspecting project.json and the engine manifest file.
|
||||
AZ::IO::FixedMaxPath FindEngineRoot(SettingsRegistryInterface& settingsRegistry);
|
||||
|
||||
//! The algorithm that is used to find the project root is as follows
|
||||
//! 1. The first time this function is it performs a upward scan for a project.json file from
|
||||
//! the executable directory and if found stores that path to an internal key.
|
||||
//! In the same step it injects the path into the front of list of command line parameters
|
||||
//! using the --regset="{BootstrapSettingsRootKey}/project_path=<path>" value
|
||||
//! 2. Next the "{BootstrapSettingsRootKey}/project_path" is checked to see if it has a project path set
|
||||
//!
|
||||
//! The order in which the project path settings are overridden proceeds in the following order
|
||||
//! 1. project_path set in the <engine-root>/bootstrap.cfg file
|
||||
//! 2. project_path set in a *.setreg/*.setregpatch file
|
||||
//! 3. project_path found by scanning upwards from the executable directory to the project.json path
|
||||
//! 4. project_path set on the Command line via either --regset="{BootstrapSettingsRootKey}/project_path=<path>"
|
||||
//! or --project_path=<path>
|
||||
AZ::IO::FixedMaxPath FindProjectRoot(SettingsRegistryInterface& settingsRegistry);
|
||||
|
||||
//! Query the specializations that will be used when loading the Settings Registry.
|
||||
|
||||
@@ -607,6 +607,8 @@ set(FILES
|
||||
Utils/Utils.h
|
||||
Script/lua/lua.h
|
||||
Memory/HeapSchema.cpp
|
||||
PlatformId/PlatformDefaults.h
|
||||
PlatformId/PlatformDefaults.cpp
|
||||
PlatformId/PlatformId.h
|
||||
PlatformId/PlatformId.cpp
|
||||
Socket/AzSocket_fwd.h
|
||||
|
||||
@@ -1,338 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Casting/numeric_cast.h>
|
||||
#include <AzFramework/Platform/PlatformDefaults.h>
|
||||
|
||||
#include <AzCore/StringFunc/StringFunc.h>
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
static const char* PlatformNames[PlatformId::NumPlatformIds] = { PlatformPC, PlatformES3, PlatformIOS, PlatformOSX, PlatformProvo, PlatformSalem, PlatformJasper, PlatformServer, PlatformAll, PlatformAllClient };
|
||||
|
||||
const char* PlatformIdToPalFolder(AzFramework::PlatformId platform)
|
||||
{
|
||||
#ifdef IOS
|
||||
#define AZ_REDEFINE_IOS_AT_END IOS
|
||||
#undef IOS
|
||||
#endif
|
||||
switch (platform)
|
||||
{
|
||||
case AzFramework::PC:
|
||||
return "PC";
|
||||
case AzFramework::ES3:
|
||||
return "Android";
|
||||
case AzFramework::IOS:
|
||||
return "iOS";
|
||||
case AzFramework::OSX:
|
||||
return "Mac";
|
||||
case AzFramework::PROVO:
|
||||
return "Provo";
|
||||
case AzFramework::SALEM:
|
||||
return "Salem";
|
||||
case AzFramework::JASPER:
|
||||
return "Jasper";
|
||||
case AzFramework::SERVER:
|
||||
return "Server";
|
||||
case AzFramework::ALL:
|
||||
case AzFramework::ALL_CLIENT:
|
||||
case AzFramework::NumPlatformIds:
|
||||
case AzFramework::Invalid:
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
|
||||
#ifdef AZ_REDEFINE_IOS_AT_END
|
||||
#define IOS AZ_REDEFINE_IOS_AT_END
|
||||
#endif
|
||||
}
|
||||
|
||||
const char* OSPlatformToDefaultAssetPlatform(AZStd::string_view osPlatform)
|
||||
{
|
||||
if (osPlatform == PlatformCodeNameWindows || osPlatform == PlatformCodeNameLinux)
|
||||
{
|
||||
return PlatformPC;
|
||||
}
|
||||
else if (osPlatform == PlatformCodeNameMac)
|
||||
{
|
||||
return PlatformOSX;
|
||||
}
|
||||
else if (osPlatform == PlatformCodeNameAndroid)
|
||||
{
|
||||
return PlatformES3;
|
||||
}
|
||||
else if (osPlatform == PlatformCodeNameiOS)
|
||||
{
|
||||
return PlatformIOS;
|
||||
}
|
||||
else if (osPlatform == PlatformCodeNameProvo)
|
||||
{
|
||||
return PlatformProvo;
|
||||
}
|
||||
else if (osPlatform == PlatformCodeNameSalem)
|
||||
{
|
||||
return PlatformSalem;
|
||||
}
|
||||
else if (osPlatform == PlatformCodeNameJasper)
|
||||
{
|
||||
return PlatformJasper;
|
||||
}
|
||||
|
||||
AZ_Error("PlatformDefault", false, R"(Supplied OS platform "%.*s" does not have a corresponding default asset platform)",
|
||||
aznumeric_cast<int>(osPlatform.size()), osPlatform.data());
|
||||
return "";
|
||||
}
|
||||
|
||||
PlatformFlags PlatformHelper::GetPlatformFlagFromPlatformIndex(PlatformId platformIndex)
|
||||
{
|
||||
if (platformIndex < 0 || platformIndex > PlatformId::NumPlatformIds)
|
||||
{
|
||||
return PlatformFlags::Platform_NONE;
|
||||
}
|
||||
if (platformIndex == PlatformId::ALL)
|
||||
{
|
||||
return PlatformFlags::Platform_ALL;
|
||||
}
|
||||
if (platformIndex == PlatformId::ALL_CLIENT)
|
||||
{
|
||||
return PlatformFlags::Platform_ALL_CLIENT;
|
||||
}
|
||||
return static_cast<PlatformFlags>(1 << platformIndex);
|
||||
}
|
||||
|
||||
AZStd::fixed_vector<AZStd::string_view, PlatformId::NumPlatformIds> PlatformHelper::GetPlatforms(PlatformFlags platformFlags)
|
||||
{
|
||||
AZStd::fixed_vector<AZStd::string_view, PlatformId::NumPlatformIds> platforms;
|
||||
for (int platformNum = 0; platformNum < PlatformId::NumPlatformIds; ++platformNum)
|
||||
{
|
||||
const bool isAllPlatforms = PlatformId::ALL == static_cast<PlatformId>(platformNum)
|
||||
&& ((platformFlags & PlatformFlags::Platform_ALL) != PlatformFlags::Platform_NONE);
|
||||
|
||||
const bool isAllClientPlatforms = PlatformId::ALL_CLIENT == static_cast<PlatformId>(platformNum)
|
||||
&& ((platformFlags & PlatformFlags::Platform_ALL_CLIENT) != PlatformFlags::Platform_NONE);
|
||||
|
||||
if (isAllPlatforms || isAllClientPlatforms
|
||||
|| (platformFlags & static_cast<PlatformFlags>(1 << platformNum)) != PlatformFlags::Platform_NONE)
|
||||
{
|
||||
platforms.push_back(PlatformNames[platformNum]);
|
||||
}
|
||||
}
|
||||
|
||||
return platforms;
|
||||
}
|
||||
|
||||
AZStd::fixed_vector<AZStd::string_view, PlatformId::NumPlatformIds> PlatformHelper::GetPlatformsInterpreted(PlatformFlags platformFlags)
|
||||
{
|
||||
return GetPlatforms(GetPlatformFlagsInterpreted(platformFlags));
|
||||
}
|
||||
|
||||
AZStd::fixed_vector<PlatformId, PlatformId::NumPlatformIds> PlatformHelper::GetPlatformIndices(PlatformFlags platformFlags)
|
||||
{
|
||||
AZStd::fixed_vector<PlatformId, PlatformId::NumPlatformIds> platformIndices;
|
||||
for (int i = 0; i < PlatformId::NumPlatformIds; i++)
|
||||
{
|
||||
PlatformId index = static_cast<PlatformId>(i);
|
||||
if ((GetPlatformFlagFromPlatformIndex(index) & platformFlags) != PlatformFlags::Platform_NONE)
|
||||
{
|
||||
platformIndices.emplace_back(index);
|
||||
}
|
||||
}
|
||||
return platformIndices;
|
||||
}
|
||||
|
||||
AZStd::fixed_vector<PlatformId, PlatformId::NumPlatformIds> PlatformHelper::GetPlatformIndicesInterpreted(PlatformFlags platformFlags)
|
||||
{
|
||||
return GetPlatformIndices(GetPlatformFlagsInterpreted(platformFlags));
|
||||
}
|
||||
|
||||
PlatformFlags PlatformHelper::GetPlatformFlag(AZStd::string_view platform)
|
||||
{
|
||||
int platformIndex = GetPlatformIndexFromName(platform);
|
||||
if (platformIndex == PlatformId::Invalid)
|
||||
{
|
||||
AZ_Error("PlatformDefault", false, "Invalid Platform ( %.*s ).\n", static_cast<int>(platform.length()), platform.data());
|
||||
return PlatformFlags::Platform_NONE;
|
||||
}
|
||||
|
||||
if(platformIndex == PlatformId::ALL)
|
||||
{
|
||||
return PlatformFlags::Platform_ALL;
|
||||
}
|
||||
|
||||
if (platformIndex == PlatformId::ALL_CLIENT)
|
||||
{
|
||||
return PlatformFlags::Platform_ALL_CLIENT;
|
||||
}
|
||||
|
||||
return static_cast<PlatformFlags>(1 << platformIndex);
|
||||
}
|
||||
|
||||
const char* PlatformHelper::GetPlatformName(PlatformId platform)
|
||||
{
|
||||
if (platform < 0 || platform > PlatformId::NumPlatformIds)
|
||||
{
|
||||
return "invalid";
|
||||
}
|
||||
return PlatformNames[platform];
|
||||
}
|
||||
|
||||
void PlatformHelper::AppendPlatformCodeNames(AZStd::fixed_vector<AZStd::string_view, MaxPlatformCodeNames>& platformCodes, AZStd::string_view platformId)
|
||||
{
|
||||
PlatformId platform = GetPlatformIdFromName(platformId);
|
||||
AZ_Assert(platform != PlatformId::Invalid, "Unsupported Platform ID: %.*s", static_cast<int>(platformId.length()), platformId.data());
|
||||
AppendPlatformCodeNames(platformCodes, platform);
|
||||
}
|
||||
|
||||
void PlatformHelper::AppendPlatformCodeNames(AZStd::fixed_vector<AZStd::string_view, MaxPlatformCodeNames>& platformCodes, PlatformId platformId)
|
||||
{
|
||||
// The IOS SDK has a macro that defines IOS as 1 which causes the enum below to be incorrectly converted to "PlatformId::1".
|
||||
#pragma push_macro("IOS")
|
||||
#undef IOS
|
||||
// To reduce work the Asset Processor groups assets that can be shared between hardware platforms together. For this
|
||||
// reason "PC" can for instance cover both the Windows and Linux platforms and "IOS" can cover AppleTV and iOS.
|
||||
switch (platformId)
|
||||
{
|
||||
case PlatformId::PC:
|
||||
platformCodes.emplace_back(PlatformCodeNameWindows);
|
||||
platformCodes.emplace_back(PlatformCodeNameLinux);
|
||||
break;
|
||||
case PlatformId::ES3:
|
||||
platformCodes.emplace_back(PlatformCodeNameAndroid);
|
||||
break;
|
||||
case PlatformId::IOS:
|
||||
platformCodes.emplace_back(PlatformCodeNameiOS);
|
||||
break;
|
||||
case PlatformId::OSX:
|
||||
platformCodes.emplace_back(PlatformCodeNameMac);
|
||||
break;
|
||||
case PlatformId::PROVO:
|
||||
platformCodes.emplace_back(PlatformCodeNameProvo);
|
||||
break;
|
||||
case PlatformId::SALEM:
|
||||
platformCodes.emplace_back(PlatformCodeNameSalem);
|
||||
break;
|
||||
case PlatformId::JASPER:
|
||||
platformCodes.emplace_back(PlatformCodeNameJasper);
|
||||
break;
|
||||
case PlatformId::SERVER:
|
||||
// Server is not a hardware platform
|
||||
break;
|
||||
default:
|
||||
AZ_Assert(false, "Unsupported Platform ID: %i", platformId);
|
||||
break;
|
||||
}
|
||||
#pragma pop_macro("IOS")
|
||||
}
|
||||
|
||||
int PlatformHelper::GetPlatformIndexFromName(AZStd::string_view platformName)
|
||||
{
|
||||
for (int idx = 0; idx < PlatformId::NumPlatformIds; idx++)
|
||||
{
|
||||
if (platformName == PlatformNames[idx])
|
||||
{
|
||||
return idx;
|
||||
}
|
||||
}
|
||||
|
||||
return PlatformId::Invalid;
|
||||
}
|
||||
|
||||
PlatformId PlatformHelper::GetPlatformIdFromName(AZStd::string_view platformName)
|
||||
{
|
||||
return aznumeric_caster(GetPlatformIndexFromName(platformName));
|
||||
}
|
||||
|
||||
AssetPlatformCombinedString PlatformHelper::GetCommaSeparatedPlatformList(PlatformFlags platformFlags)
|
||||
{
|
||||
AZStd::fixed_vector<AZStd::string_view, PlatformId::NumPlatformIds> platformNames = GetPlatforms(platformFlags);
|
||||
AssetPlatformCombinedString platformsString;
|
||||
AZ::StringFunc::Join(platformsString, platformNames.begin(), platformNames.end(), ", ");
|
||||
return platformsString;
|
||||
}
|
||||
|
||||
PlatformFlags PlatformHelper::GetPlatformFlagsInterpreted(PlatformFlags platformFlags)
|
||||
{
|
||||
PlatformFlags returnFlags = PlatformFlags::Platform_NONE;
|
||||
|
||||
if((platformFlags & PlatformFlags::Platform_ALL) != PlatformFlags::Platform_NONE)
|
||||
{
|
||||
for (int i = 0; i < NumPlatforms; ++i)
|
||||
{
|
||||
auto platformId = static_cast<PlatformId>(i);
|
||||
|
||||
if (platformId != PlatformId::ALL && platformId != PlatformId::ALL_CLIENT)
|
||||
{
|
||||
returnFlags |= GetPlatformFlagFromPlatformIndex(platformId);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if((platformFlags & PlatformFlags::Platform_ALL_CLIENT) != PlatformFlags::Platform_NONE)
|
||||
{
|
||||
for (int i = 0; i < NumPlatforms; ++i)
|
||||
{
|
||||
auto platformId = static_cast<PlatformId>(i);
|
||||
|
||||
if (platformId != PlatformId::ALL && platformId != PlatformId::ALL_CLIENT && platformId != PlatformId::SERVER)
|
||||
{
|
||||
returnFlags |= GetPlatformFlagFromPlatformIndex(platformId);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
returnFlags = platformFlags;
|
||||
}
|
||||
|
||||
return returnFlags;
|
||||
}
|
||||
|
||||
bool PlatformHelper::IsSpecialPlatform(PlatformFlags platformFlags)
|
||||
{
|
||||
return (platformFlags & PlatformFlags::Platform_ALL) != PlatformFlags::Platform_NONE
|
||||
|| (platformFlags & PlatformFlags::Platform_ALL_CLIENT) != PlatformFlags::Platform_NONE;
|
||||
}
|
||||
|
||||
bool HasFlagHelper(PlatformFlags flags, PlatformFlags checkPlatform)
|
||||
{
|
||||
return (flags & checkPlatform) == checkPlatform;
|
||||
}
|
||||
|
||||
|
||||
bool PlatformHelper::HasPlatformFlag(PlatformFlags flags, PlatformId checkPlatform)
|
||||
{
|
||||
// If checkPlatform contains any kind of invalid id, just exit out here
|
||||
if(checkPlatform == PlatformId::Invalid || checkPlatform == NumPlatforms)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// ALL_CLIENT + SERVER = ALL
|
||||
if(HasFlagHelper(flags, PlatformFlags::Platform_ALL_CLIENT | PlatformFlags::Platform_SERVER))
|
||||
{
|
||||
flags = PlatformFlags::Platform_ALL;
|
||||
}
|
||||
|
||||
if(HasFlagHelper(flags, PlatformFlags::Platform_ALL))
|
||||
{
|
||||
// It doesn't matter what checkPlatform is set to in this case, just return true
|
||||
return true;
|
||||
}
|
||||
|
||||
if(HasFlagHelper(flags, PlatformFlags::Platform_ALL_CLIENT))
|
||||
{
|
||||
return checkPlatform != PlatformId::SERVER;
|
||||
}
|
||||
|
||||
return HasFlagHelper(flags, GetPlatformFlagFromPlatformIndex(checkPlatform));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -12,144 +12,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Preprocessor/Enum.h>
|
||||
#include <AzCore/std/containers/fixed_vector.h>
|
||||
#include <AzCore/std/containers/unordered_map.h>
|
||||
#include <AzCore/std/string/fixed_string.h>
|
||||
#include <AzCore/std/string/string_view.h>
|
||||
|
||||
// On IOS builds IOS will be defined and interfere with the below enums
|
||||
#pragma push_macro("IOS")
|
||||
#undef IOS
|
||||
#include <AzCore/PlatformId/PlatformDefaults.h>
|
||||
|
||||
// As the Platform defaults is needed within AzCore,
|
||||
// those structures have been moved to AzCore and brought into
|
||||
// The AzFramework namespace for backwards compatibility
|
||||
namespace AzFramework
|
||||
{
|
||||
constexpr char PlatformPC[] = "pc";
|
||||
constexpr char PlatformES3[] = "es3";
|
||||
constexpr char PlatformIOS[] = "ios";
|
||||
constexpr char PlatformOSX[] = "osx_gl";
|
||||
constexpr char PlatformProvo[] = "provo";
|
||||
constexpr char PlatformSalem[] = "salem";
|
||||
constexpr char PlatformJasper[] = "jasper";
|
||||
constexpr char PlatformServer[] = "server";
|
||||
|
||||
constexpr char PlatformCodeNameWindows[] = "Windows";
|
||||
constexpr char PlatformCodeNameLinux[] = "Linux";
|
||||
constexpr char PlatformCodeNameAndroid[] = "Android";
|
||||
constexpr char PlatformCodeNameiOS[] = "iOS";
|
||||
constexpr char PlatformCodeNameMac[] = "Mac";
|
||||
constexpr char PlatformCodeNameProvo[] = "Provo";
|
||||
constexpr char PlatformCodeNameSalem[] = "Salem";
|
||||
constexpr char PlatformCodeNameJasper[] = "Jasper";
|
||||
constexpr char PlatformAll[] = "all";
|
||||
constexpr char PlatformAllClient[] = "all_client";
|
||||
|
||||
// Used for the capacity of a fixed vector to store the code names of platforms
|
||||
// The value needs to be higher than the number of unique OS platforms that are supported(at this time 8)
|
||||
constexpr size_t MaxPlatformCodeNames = 16;
|
||||
|
||||
//! This platform enum have platform values in sequence and can also be used to get the platform count.
|
||||
AZ_ENUM_WITH_UNDERLYING_TYPE(PlatformId, int,
|
||||
(Invalid, -1),
|
||||
PC,
|
||||
ES3,
|
||||
IOS,
|
||||
OSX,
|
||||
PROVO,
|
||||
SALEM,
|
||||
JASPER,
|
||||
SERVER, // Corresponds to the customer's flavor of "server" which could be windows, ubuntu, etc
|
||||
ALL,
|
||||
ALL_CLIENT,
|
||||
|
||||
// Add new platforms above this
|
||||
NumPlatformIds
|
||||
);
|
||||
constexpr int NumClientPlatforms = 7;
|
||||
constexpr int NumPlatforms = NumClientPlatforms + 1; // 1 "Server" platform currently
|
||||
enum class PlatformFlags : AZ::u32
|
||||
{
|
||||
Platform_NONE = 0x00,
|
||||
Platform_PC = 1 << PlatformId::PC,
|
||||
Platform_ES3 = 1 << PlatformId::ES3,
|
||||
Platform_IOS = 1 << PlatformId::IOS,
|
||||
Platform_OSX = 1 << PlatformId::OSX,
|
||||
Platform_PROVO = 1 << PlatformId::PROVO,
|
||||
Platform_SALEM = 1 << PlatformId::SALEM,
|
||||
Platform_JASPER = 1 << PlatformId::JASPER,
|
||||
Platform_SERVER = 1 << PlatformId::SERVER,
|
||||
|
||||
// A special platform that will always correspond to all platforms, even if new ones are added
|
||||
Platform_ALL = 1ULL << 30,
|
||||
|
||||
// A special platform that will always correspond to all non-server platforms, even if new ones are added
|
||||
Platform_ALL_CLIENT = 1ULL << 31,
|
||||
|
||||
AllNamedPlatforms = Platform_PC | Platform_ES3 | Platform_IOS | Platform_OSX | Platform_PROVO | Platform_SALEM | Platform_JASPER | Platform_SERVER,
|
||||
};
|
||||
|
||||
AZ_DEFINE_ENUM_BITWISE_OPERATORS(PlatformFlags);
|
||||
|
||||
// 32 characters should be more than enough to store a platform name
|
||||
using AssetPlatformFixedString = AZStd::fixed_string<32>;
|
||||
// Fixed string which can store a comma separated list of platforms names
|
||||
// Additional byte is added to take into account the comma
|
||||
using AssetPlatformCombinedString = AZStd::fixed_string<(AssetPlatformFixedString{}.max_size() + 1) * PlatformId::NumPlatformIds>;
|
||||
|
||||
const char* PlatformIdToPalFolder(AzFramework::PlatformId platform);
|
||||
|
||||
const char* OSPlatformToDefaultAssetPlatform(AZStd::string_view osPlatform);
|
||||
|
||||
//! Platform Helper is an utility class that can be used to retrieve platform related information
|
||||
class PlatformHelper
|
||||
{
|
||||
public:
|
||||
|
||||
//! Given a platformIndex returns the platform name
|
||||
static const char* GetPlatformName(PlatformId platform);
|
||||
|
||||
//! Converts the platform name to the platform code names as defined in AZ_TRAIT_OS_PLATFORM_CODENAME.
|
||||
static void AppendPlatformCodeNames(AZStd::fixed_vector<AZStd::string_view, MaxPlatformCodeNames>& platformCodes, AZStd::string_view platformName);
|
||||
|
||||
//! Converts the platform name to the platform code names as defined in AZ_TRAIT_OS_PLATFORM_CODENAME.
|
||||
static void AppendPlatformCodeNames(AZStd::fixed_vector<AZStd::string_view, MaxPlatformCodeNames>& platformCodes, PlatformId platformId);
|
||||
|
||||
//! Given a platform name returns a platform index.
|
||||
//! If the platform is not found, the method returns -1.
|
||||
static int GetPlatformIndexFromName(AZStd::string_view platformName);
|
||||
|
||||
//! Given a platform name returns a platform id.
|
||||
//! If the platform is not found, the method returns -1.
|
||||
static PlatformId GetPlatformIdFromName(AZStd::string_view platformName);
|
||||
|
||||
//! Given a platformIndex returns the platformFlags
|
||||
static PlatformFlags GetPlatformFlagFromPlatformIndex(PlatformId platform);
|
||||
|
||||
//! Given a platformFlags returns all the platform identifiers that are set.
|
||||
static AZStd::fixed_vector<AZStd::string_view, PlatformId::NumPlatformIds> GetPlatforms(PlatformFlags platformFlags);
|
||||
//! Given a platformFlags returns all the platform identifiers that are set, with special flags interpreted. Do not use the result for saving
|
||||
static AZStd::fixed_vector<AZStd::string_view, PlatformId::NumPlatformIds> GetPlatformsInterpreted(PlatformFlags platformFlags);
|
||||
|
||||
//! Given a platformFlags return a list of PlatformId indices
|
||||
static AZStd::fixed_vector<PlatformId, PlatformId::NumPlatformIds> GetPlatformIndices(PlatformFlags platformFlags);
|
||||
//! Given a platformFlags return a list of PlatformId indices, with special flags interpreted. Do not use the result for saving
|
||||
static AZStd::fixed_vector<PlatformId, PlatformId::NumPlatformIds> GetPlatformIndicesInterpreted(PlatformFlags platformFlags);
|
||||
|
||||
//! Given a platform identifier returns its corresponding platform flag.
|
||||
static PlatformFlags GetPlatformFlag(AZStd::string_view platform);
|
||||
|
||||
//! Given any platformFlags returns a string listing the input platforms
|
||||
static AssetPlatformCombinedString GetCommaSeparatedPlatformList(PlatformFlags platformFlags);
|
||||
|
||||
//! If platformFlags contains any special flags, they are removed and replaced with the normal flags they represent
|
||||
static PlatformFlags GetPlatformFlagsInterpreted(PlatformFlags platformFlags);
|
||||
|
||||
//! Returns true if platformFlags contains any special flags
|
||||
static bool IsSpecialPlatform(PlatformFlags platformFlags);
|
||||
|
||||
//! Returns true if platformFlags has checkPlatform flag set.
|
||||
static bool HasPlatformFlag(PlatformFlags platformFlags, PlatformId checkPlatform);
|
||||
};
|
||||
using namespace AZ::PlatformDefaults;
|
||||
}
|
||||
|
||||
#pragma pop_macro("IOS")
|
||||
|
||||
@@ -42,8 +42,14 @@ namespace AzFramework::ProjectManager
|
||||
AZ::CommandLine commandLine;
|
||||
commandLine.Parse(argc, argv);
|
||||
AZ::SettingsRegistryImpl settingsRegistry;
|
||||
// Store the Command line to the Setting Registry
|
||||
|
||||
AZ::SettingsRegistryMergeUtils::StoreCommandLineToRegistry(settingsRegistry, commandLine);
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_Bootstrap(settingsRegistry);
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_O3deUserRegistry(settingsRegistry, AZ_TRAIT_OS_PLATFORM_CODENAME, {});
|
||||
// Retrieve Command Line from Settings Registry, it may have been updated by the call to FindEngineRoot()
|
||||
// in MergeSettingstoRegistry_ConfigFile
|
||||
AZ::SettingsRegistryMergeUtils::GetCommandLineFromRegistry(settingsRegistry, commandLine);
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(settingsRegistry, commandLine, false);
|
||||
engineRootPath = AZ::SettingsRegistryMergeUtils::FindEngineRoot(settingsRegistry);
|
||||
projectRootPath = AZ::SettingsRegistryMergeUtils::FindProjectRoot(settingsRegistry);
|
||||
|
||||
@@ -317,7 +317,6 @@ set(FILES
|
||||
Terrain/TerrainDataRequestBus.h
|
||||
Terrain/TerrainDataRequestBus.cpp
|
||||
Platform/PlatformDefaults.h
|
||||
Platform/PlatformDefaults.cpp
|
||||
Windowing/WindowBus.h
|
||||
Windowing/NativeWindow.cpp
|
||||
Windowing/NativeWindow.h
|
||||
|
||||
@@ -80,6 +80,8 @@ namespace AzGameFramework
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_ProjectUserRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer);
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, m_commandLine, true);
|
||||
#endif
|
||||
// Update the Runtime file paths in case the "{BootstrapSettingsRootKey}/assets" key was overriden by a setting registry
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(registry);
|
||||
}
|
||||
|
||||
AZ::ComponentTypeList GameApplication::GetRequiredSystemComponents() const
|
||||
|
||||
@@ -578,16 +578,6 @@ namespace AzToolsFramework
|
||||
*/
|
||||
virtual bool IsEditorInIsolationMode() = 0;
|
||||
|
||||
/*!
|
||||
* Get the engine root path that the current tool is running under.
|
||||
*/
|
||||
virtual const char* GetEngineRootPath() const = 0;
|
||||
|
||||
/**
|
||||
* Get the version of the engine the current tools application is running under
|
||||
*/
|
||||
virtual const char* GetEngineVersion() const = 0;
|
||||
|
||||
/**
|
||||
* Creates and adds a new entity to the tools application from components which match at least one of the requiredTags
|
||||
* The tag matching occurs on AZ::Edit::SystemComponentTags attribute from the reflected class data in the serialization context
|
||||
|
||||
@@ -224,112 +224,6 @@ namespace AzToolsFramework
|
||||
|
||||
} // Internal
|
||||
|
||||
#define AZ_MAX_ENGINE_VERSION_LEN 64
|
||||
// Private Implementation class to manage the engine root and version
|
||||
// Note: We are not using any AzCore classes because the ToolsApplication
|
||||
// initialization happens early on, before the Allocators get instantiated,
|
||||
// so we are using Qt privately instead
|
||||
class ToolsApplication::EngineConfigImpl
|
||||
{
|
||||
private:
|
||||
friend class ToolsApplication;
|
||||
|
||||
typedef QMap<QString, QString> EngineJsonMap;
|
||||
|
||||
EngineConfigImpl(const char* logWindow, const char* fileName)
|
||||
: m_logWindow(logWindow)
|
||||
, m_fileName(fileName)
|
||||
{
|
||||
m_engineRoot[0] = '\0';
|
||||
m_engineVersion[0] = '\0';
|
||||
}
|
||||
|
||||
char m_engineRoot[AZ_MAX_PATH_LEN];
|
||||
char m_engineVersion[AZ_MAX_ENGINE_VERSION_LEN];
|
||||
EngineJsonMap m_engineConfigMap;
|
||||
const char* m_logWindow;
|
||||
const char* m_fileName;
|
||||
|
||||
|
||||
// Read an engine configuration into a map of key/value pairs
|
||||
bool ReadEngineConfigIntoMap(QString engineJsonPath, EngineJsonMap& engineJsonMap)
|
||||
{
|
||||
QFile engineJsonFile(engineJsonPath);
|
||||
if (!engineJsonFile.open(QIODevice::ReadOnly | QIODevice::Text))
|
||||
{
|
||||
AZ_Warning(m_logWindow, false, "Unable to open file '%s' in the current root directory", engineJsonPath.toUtf8().data());
|
||||
return false;
|
||||
}
|
||||
|
||||
QByteArray engineJsonData = engineJsonFile.readAll();
|
||||
engineJsonFile.close();
|
||||
QJsonDocument engineJsonDoc(QJsonDocument::fromJson(engineJsonData));
|
||||
if (engineJsonDoc.isNull())
|
||||
{
|
||||
AZ_Warning(m_logWindow, false, "Unable to read file '%s' in the current root directory", engineJsonPath.toUtf8().data());
|
||||
return false;
|
||||
}
|
||||
|
||||
QJsonObject engineJsonRoot = engineJsonDoc.object();
|
||||
for (const QString& configKey : engineJsonRoot.keys())
|
||||
{
|
||||
QJsonValue configValue = engineJsonRoot[configKey];
|
||||
if (configValue.isString() || configValue.isDouble())
|
||||
{
|
||||
// Only map strings and numbers, ignore every other type
|
||||
engineJsonMap[configKey] = configValue.toString();
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Warning(m_logWindow, false, "Ignoring key '%s' from '%s', unsupported type.", configKey.toUtf8().data(), engineJsonPath.toUtf8().data());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Initialize the engine config object based on the current
|
||||
bool Initialize(const char* currentEngineRoot)
|
||||
{
|
||||
// Start with the app root as the engine root (legacy), but check to see if the engine root
|
||||
// is external to the app root
|
||||
azstrncpy(m_engineRoot, AZ_ARRAY_SIZE(m_engineRoot), currentEngineRoot, strlen(currentEngineRoot) + 1);
|
||||
|
||||
// From the appRoot, check and see if we can read any external engine reference in engine.json
|
||||
QString engineJsonFileName = QString(m_fileName);
|
||||
QString engineJsonFilePath = QDir(currentEngineRoot).absoluteFilePath(engineJsonFileName);
|
||||
|
||||
// From the appRoot, check and see if we can read any external engine reference in engine.json
|
||||
if (!QFile::exists(engineJsonFilePath))
|
||||
{
|
||||
AZ_Warning(m_logWindow, false, "Unable to find '%s' in the current app root directory.", m_fileName);
|
||||
return false;
|
||||
}
|
||||
if (!ReadEngineConfigIntoMap(engineJsonFilePath, m_engineConfigMap))
|
||||
{
|
||||
AZ_Warning(m_logWindow, false, "Defaulting root engine path to '%s'", currentEngineRoot);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Read in the local engine version value
|
||||
auto localEngineVersionValue = m_engineConfigMap.find(QString(AzToolsFramework::Internal::s_engineConfigEngineVersionKey));
|
||||
QString localEngineVersion(localEngineVersionValue.value());
|
||||
azstrncpy(m_engineVersion, AZ_ARRAY_SIZE(m_engineVersion), localEngineVersion.toUtf8().data(), localEngineVersion.length() + 1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const char* GetEngineRoot() const
|
||||
{
|
||||
return m_engineRoot;
|
||||
}
|
||||
|
||||
const char* GetEngineVersion() const
|
||||
{
|
||||
return m_engineVersion;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
ToolsApplication::ToolsApplication(int* argc, char*** argv)
|
||||
: AzFramework::Application(argc, argv)
|
||||
, m_selectionBounds(AZ::Aabb())
|
||||
@@ -339,7 +233,6 @@ namespace AzToolsFramework
|
||||
, m_isInIsolationMode(false)
|
||||
{
|
||||
ToolsApplicationRequests::Bus::Handler::BusConnect();
|
||||
m_engineConfigImpl.reset(new ToolsApplication::EngineConfigImpl(AzToolsFramework::Internal::s_startupLogWindow, AzToolsFramework::Internal::s_engineConfigFileName));
|
||||
|
||||
m_undoCache.RegisterToUndoCacheInterface();
|
||||
}
|
||||
@@ -391,7 +284,6 @@ namespace AzToolsFramework
|
||||
void ToolsApplication::Start(const Descriptor& descriptor, const StartupParameters& startupParameters/* = StartupParameters()*/)
|
||||
{
|
||||
Application::Start(descriptor, startupParameters);
|
||||
InitializeEngineConfig();
|
||||
|
||||
m_editorEntityManager.Start();
|
||||
|
||||
@@ -399,14 +291,6 @@ namespace AzToolsFramework
|
||||
AZ_Assert(m_editorEntityAPI, "ToolsApplication - Could not retrieve instance of EditorEntityAPI");
|
||||
}
|
||||
|
||||
void ToolsApplication::InitializeEngineConfig()
|
||||
{
|
||||
if (!m_engineConfigImpl->Initialize(GetEngineRoot()))
|
||||
{
|
||||
AZ_Warning(AzToolsFramework::Internal::s_startupLogWindow, false, "Defaulting engine root path to '%s'", GetEngineRoot());
|
||||
}
|
||||
}
|
||||
|
||||
void ToolsApplication::StartCommon(AZ::Entity* systemEntity)
|
||||
{
|
||||
Application::StartCommon(systemEntity);
|
||||
@@ -1832,16 +1716,6 @@ namespace AzToolsFramework
|
||||
return m_isInIsolationMode;
|
||||
}
|
||||
|
||||
const char* ToolsApplication::GetEngineRootPath() const
|
||||
{
|
||||
return m_engineConfigImpl->GetEngineRoot();
|
||||
}
|
||||
|
||||
const char* ToolsApplication::GetEngineVersion() const
|
||||
{
|
||||
return m_engineConfigImpl->GetEngineVersion();
|
||||
}
|
||||
|
||||
void ToolsApplication::CreateAndAddEntityFromComponentTags(const AZStd::vector<AZ::Crc32>& requiredTags, const char* entityName)
|
||||
{
|
||||
if (!entityName || !entityName[0])
|
||||
|
||||
@@ -150,8 +150,6 @@ namespace AzToolsFramework
|
||||
void EnterEditorIsolationMode() override;
|
||||
void ExitEditorIsolationMode() override;
|
||||
bool IsEditorInIsolationMode() override;
|
||||
const char* GetEngineRootPath() const override;
|
||||
const char* GetEngineVersion() const override;
|
||||
|
||||
void CreateAndAddEntityFromComponentTags(const AZStd::vector<AZ::Crc32>& requiredTags, const char* entityName) override;
|
||||
|
||||
@@ -174,7 +172,6 @@ namespace AzToolsFramework
|
||||
|
||||
void CreateUndosForDirtyEntities();
|
||||
void ConsistencyCheckUndoCache();
|
||||
void InitializeEngineConfig();
|
||||
AZ::Aabb m_selectionBounds;
|
||||
EntityIdList m_selectedEntities;
|
||||
EntityIdList m_highlightedEntities;
|
||||
@@ -186,9 +183,6 @@ namespace AzToolsFramework
|
||||
bool m_isInIsolationMode;
|
||||
EntityIdSet m_isolatedEntityIdSet;
|
||||
|
||||
class EngineConfigImpl;
|
||||
AZStd::unique_ptr<EngineConfigImpl> m_engineConfigImpl;
|
||||
|
||||
EditorEntityAPI* m_editorEntityAPI = nullptr;
|
||||
|
||||
EditorEntityManager m_editorEntityManager;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -153,7 +153,7 @@ namespace AzToolsFramework
|
||||
AZ::EntityId& commonRootEntityId, InstanceOptionalReference& commonRootEntityOwningInstance)
|
||||
{
|
||||
// Retrieve entityList from entityIds
|
||||
EntityIdListToEntityList(entityIds, inputEntityList);
|
||||
inputEntityList = EntityIdListToEntityList(entityIds);
|
||||
|
||||
// Find common root and top level entities
|
||||
bool entitiesHaveCommonRoot = false;
|
||||
@@ -485,8 +485,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);
|
||||
|
||||
@@ -833,18 +832,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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,7 +99,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;
|
||||
|
||||
+3
-3
@@ -38,6 +38,7 @@ AZ_POP_DISABLE_WARNING
|
||||
#include <AzCore/Asset/AssetManager.h>
|
||||
#include <AzCore/Component/ComponentApplicationBus.h>
|
||||
#include <AzCore/Asset/AssetTypeInfoBus.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
#include <AzFramework/StringFunc/StringFunc.h>
|
||||
#include <AzFramework/Asset/SimpleAsset.h>
|
||||
#include <AzFramework/Asset/AssetCatalogBus.h>
|
||||
@@ -1212,9 +1213,8 @@ namespace AzToolsFramework
|
||||
|
||||
if (!QFile::exists(path))
|
||||
{
|
||||
const char* engineRoot = nullptr;
|
||||
AzToolsFramework::ToolsApplicationRequestBus::BroadcastResult(engineRoot, &AzToolsFramework::ToolsApplicationRequests::GetEngineRootPath);
|
||||
QDir engineDir = engineRoot ? QDir(engineRoot) : QDir::current();
|
||||
AZ::IO::FixedMaxPathString engineRoot = AZ::Utils::GetEnginePath();
|
||||
QDir engineDir = !engineRoot.empty() ? QDir(QString(engineRoot.c_str())) : QDir::current();
|
||||
|
||||
path = engineDir.absoluteFilePath(iconPath.c_str());
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ namespace UnitTest
|
||||
{
|
||||
assets[idx] = AssetId(AZ::Uuid::CreateRandom(), 0);
|
||||
AZ::Data::AssetInfo info;
|
||||
info.m_relativePath = AZStd::string::format("Asset%d.txt", idx);
|
||||
info.m_relativePath = AZStd::string::format("asset%d.txt", idx);
|
||||
m_assetsPath[idx] = info.m_relativePath;
|
||||
info.m_assetId = assets[idx];
|
||||
m_assetRegistry->RegisterAsset(assets[idx], info);
|
||||
@@ -623,7 +623,7 @@ namespace UnitTest
|
||||
EXPECT_TRUE(Search(assetList1, assets[fileIndex]));
|
||||
if (m_fileStreams[0][fileIndex].Open(m_assetsPathFull[0][fileIndex].c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeBinary | AZ::IO::OpenMode::ModeCreatePath))
|
||||
{
|
||||
AZStd::string fileContent = AZStd::string::format("Asset%d.txt", fileIndex);
|
||||
AZStd::string fileContent = AZStd::string::format("asset%d.txt", fileIndex);
|
||||
m_fileStreams[0][fileIndex].Write(fileContent.size(), fileContent.c_str());
|
||||
m_fileStreams[0][fileIndex].Close();
|
||||
}
|
||||
@@ -654,7 +654,7 @@ namespace UnitTest
|
||||
EXPECT_TRUE(Search(assetList1, assets[fileIndex]));
|
||||
if (m_fileStreams[0][fileIndex].Open(m_assetsPathFull[0][fileIndex].c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeBinary | AZ::IO::OpenMode::ModeCreatePath))
|
||||
{
|
||||
AZStd::string fileContent = AZStd::string::format("Asset%d.txt", fileIndex + 1);// changing file content
|
||||
AZStd::string fileContent = AZStd::string::format("asset%d.txt", fileIndex + 1);// changing file content
|
||||
m_fileStreams[0][fileIndex].Write(fileContent.size(), fileContent.c_str());
|
||||
m_fileStreams[0][fileIndex].Close();
|
||||
}
|
||||
@@ -987,7 +987,7 @@ namespace UnitTest
|
||||
|
||||
m_assetSeedManager->AddSeedAsset(assets[0], AzFramework::PlatformFlags::Platform_PC | AzFramework::PlatformFlags::Platform_OSX);
|
||||
|
||||
m_assetSeedManager->RemoveSeedAsset("Asset0.txt", AzFramework::PlatformFlags::Platform_PC | AzFramework::PlatformFlags::Platform_OSX);
|
||||
m_assetSeedManager->RemoveSeedAsset("asset0.txt", AzFramework::PlatformFlags::Platform_PC | AzFramework::PlatformFlags::Platform_OSX);
|
||||
const AzFramework::AssetSeedList& secondSeedList = m_assetSeedManager->GetAssetSeedList();
|
||||
EXPECT_EQ(secondSeedList.size(), 0);
|
||||
}
|
||||
@@ -1003,7 +1003,7 @@ namespace UnitTest
|
||||
|
||||
m_assetSeedManager->AddSeedAsset(assets[0], AzFramework::PlatformFlags::Platform_PC | AzFramework::PlatformFlags::Platform_OSX);
|
||||
|
||||
m_assetSeedManager->RemoveSeedAsset("Asset0.txt", AzFramework::PlatformFlags::Platform_PC);
|
||||
m_assetSeedManager->RemoveSeedAsset("asset0.txt", AzFramework::PlatformFlags::Platform_PC);
|
||||
const AzFramework::AssetSeedList& secondSeedList = m_assetSeedManager->GetAssetSeedList();
|
||||
EXPECT_EQ(secondSeedList.size(), 1);
|
||||
}
|
||||
@@ -1017,7 +1017,7 @@ namespace UnitTest
|
||||
|
||||
EXPECT_EQ(seedList.size(), 1);
|
||||
|
||||
m_assetSeedManager->RemoveSeedAsset("Asset1.txt", AzFramework::PlatformFlags::Platform_PC | AzFramework::PlatformFlags::Platform_OSX);
|
||||
m_assetSeedManager->RemoveSeedAsset("asset1.txt", AzFramework::PlatformFlags::Platform_PC | AzFramework::PlatformFlags::Platform_OSX);
|
||||
const AzFramework::AssetSeedList& secondSeedList = m_assetSeedManager->GetAssetSeedList();
|
||||
EXPECT_EQ(secondSeedList.size(), 1);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
// AzCore
|
||||
#include <AzCore/Asset/AssetManager.h>
|
||||
#include <AzCore/UserSettings/UserSettingsComponent.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
|
||||
// AzToolsFramework
|
||||
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
||||
@@ -104,13 +105,9 @@ void AssetEditorWindow::SaveAssetAs(const AZStd::string_view assetPath)
|
||||
return;
|
||||
}
|
||||
|
||||
const char* engineRoot;
|
||||
AzToolsFramework::ToolsApplicationRequestBus::BroadcastResult(engineRoot, &AzToolsFramework::ToolsApplicationRequests::GetEngineRootPath);
|
||||
auto absoluteAssetPath = AZ::IO::FixedMaxPath(AZ::Utils::GetEnginePath()) / assetPath;
|
||||
|
||||
AZStd::string absoluteAssetPath;
|
||||
AzFramework::StringFunc::Path::Join(engineRoot, assetPath.data(), absoluteAssetPath);
|
||||
|
||||
if (!m_ui->m_assetEditorWidget->SaveAssetToPath(absoluteAssetPath))
|
||||
if (!m_ui->m_assetEditorWidget->SaveAssetToPath(absoluteAssetPath.Native()))
|
||||
{
|
||||
AZ_Warning("Asset Editor", false, "File was not saved correctly via SaveAssetAs.");
|
||||
}
|
||||
|
||||
@@ -1617,11 +1617,6 @@ void EditorViewportWidget::keyPressEvent(QKeyEvent* event)
|
||||
// because we want the movement to be butter smooth.
|
||||
if (!event->isAutoRepeat())
|
||||
{
|
||||
if (m_keyDown.isEmpty())
|
||||
{
|
||||
grabKeyboard();
|
||||
}
|
||||
|
||||
m_keyDown.insert(event->key());
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
#include <QMessageBox>
|
||||
#include <QFileDialog>
|
||||
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
|
||||
// AzToolsFramework
|
||||
#include <AzToolsFramework/API/EditorPythonRunnerRequestsBus.h>
|
||||
#include <AzToolsFramework/UI/UICore/WidgetHelpers.h>
|
||||
@@ -293,9 +295,8 @@ namespace
|
||||
// If not found try editor folder
|
||||
if (!CFileUtil::FileExists(path))
|
||||
{
|
||||
const char* engineRoot = nullptr;
|
||||
AzToolsFramework::ToolsApplicationRequestBus::BroadcastResult(engineRoot, &AzToolsFramework::ToolsApplicationRequests::GetEngineRootPath);
|
||||
QDir engineDir = engineRoot ? QDir(engineRoot) : QDir::current();
|
||||
AZ::IO::FixedMaxPathString engineRoot = AZ::Utils::GetEnginePath();
|
||||
QDir engineDir = !engineRoot.empty() ? QDir(QString(engineRoot.c_str())) : QDir::current();
|
||||
|
||||
QString scriptFolder = engineDir.absoluteFilePath("Editor/Scripts/");
|
||||
Path::ConvertBackSlashToSlash(scriptFolder);
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
#include "ToolBox.h"
|
||||
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
|
||||
// AzToolsFramework
|
||||
#include <AzToolsFramework/API/EditorPythonRunnerRequestsBus.h>
|
||||
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
||||
@@ -419,9 +421,8 @@ void CToolBoxManager::Load(QString xmlpath, AmazonToolbar* pToolbar, bool bToolb
|
||||
}
|
||||
}
|
||||
|
||||
const char* engineRoot = nullptr;
|
||||
AzToolsFramework::ToolsApplicationRequestBus::BroadcastResult(engineRoot, &AzToolsFramework::ToolsApplicationRequests::GetEngineRootPath);
|
||||
QDir engineDir = engineRoot ? QDir(engineRoot) : QDir::current();
|
||||
AZ::IO::FixedMaxPathString engineRoot = AZ::Utils::GetEnginePath();
|
||||
QDir engineDir = !engineRoot.empty() ? QDir(QString(engineRoot.c_str())) : QDir::current();
|
||||
|
||||
string enginePath = PathUtil::AddSlash(engineDir.absolutePath().toUtf8().data());
|
||||
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -49,11 +49,6 @@
|
||||
"IsArray": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"Name": "DepthStencilInputOutput",
|
||||
"SlotType": "InputOutput",
|
||||
"ScopeAttachmentUsage": "DepthStencil"
|
||||
},
|
||||
{
|
||||
"Name": "TileLightData",
|
||||
"SlotType": "Input",
|
||||
@@ -66,6 +61,13 @@
|
||||
"ShaderInputName": "m_lightListRemapped",
|
||||
"ScopeAttachmentUsage": "Shader"
|
||||
},
|
||||
// Input/Outputs...
|
||||
{
|
||||
"Name": "DepthStencilInputOutput",
|
||||
"SlotType": "InputOutput",
|
||||
"ScopeAttachmentUsage": "DepthStencil"
|
||||
},
|
||||
// Outputs...
|
||||
{
|
||||
"Name": "DiffuseOutput",
|
||||
"SlotType": "Output",
|
||||
@@ -222,11 +224,12 @@
|
||||
"Attachment": "Output"
|
||||
}
|
||||
},
|
||||
"MultisampleSource": {
|
||||
"Pass": "This",
|
||||
"Attachment": "DepthStencilInputOutput"
|
||||
},
|
||||
"ImageDescriptor": {
|
||||
"Format": "R8G8B8A8_UNORM",
|
||||
"MultisampleState": {
|
||||
"samples": 4
|
||||
},
|
||||
"SharedQueueMask": "Graphics"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
"Slots": [
|
||||
{
|
||||
"Name": "Output",
|
||||
"SlotType": 2
|
||||
"SlotType": "InputOutput",
|
||||
"ScopeAttachmentUsage": "RenderTarget"
|
||||
}
|
||||
],
|
||||
"PassRequests": [
|
||||
@@ -101,13 +102,8 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"Name": "DepthMSAAPass",
|
||||
"TemplateName": "EnvironmentCubeMapDepthMSAAPassTemplate",
|
||||
"PassData": {
|
||||
"$type": "RasterPassData",
|
||||
"DrawListTag": "depth",
|
||||
"PipelineViewTag": "MainCamera"
|
||||
},
|
||||
"Name": "DepthPrePass",
|
||||
"TemplateName": "DepthMSAAParentTemplate",
|
||||
"Connections": [
|
||||
{
|
||||
"LocalSlot": "SkinnedMeshes",
|
||||
@@ -115,70 +111,11 @@
|
||||
"Pass": "SkinningPass",
|
||||
"Attachment": "SkinnedMeshOutputStream"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
// The light culling system can do highly accurate culling of transparent objects but it needs
|
||||
// more depth information than the opaque geometry pass can provide
|
||||
// Specifically the minimum and maximum depth of transparent objects
|
||||
{
|
||||
"Name": "DepthTransparentMinPass",
|
||||
"TemplateName": "DepthPassTemplate",
|
||||
"PassData": {
|
||||
"$type": "RasterPassData",
|
||||
"DrawListTag": "depthTransparentMin",
|
||||
"PipelineViewTag": "MainCamera"
|
||||
},
|
||||
"Connections": [
|
||||
{
|
||||
"LocalSlot": "SkinnedMeshes",
|
||||
"AttachmentRef": {
|
||||
"Pass": "SkinningPass",
|
||||
"Attachment": "SkinnedMeshOutputStream"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Name": "DepthTransparentMaxPass",
|
||||
"TemplateName": "DepthMaxPassTemplate",
|
||||
"PassData": {
|
||||
"$type": "RasterPassData",
|
||||
"DrawListTag": "depthTransparentMax",
|
||||
"PipelineViewTag": "MainCamera"
|
||||
},
|
||||
"Connections": [
|
||||
{
|
||||
"LocalSlot": "SkinnedMeshes",
|
||||
"AttachmentRef": {
|
||||
"Pass": "SkinningPass",
|
||||
"Attachment": "SkinnedMeshOutputStream"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Name": "LightCullingTilePreparePass",
|
||||
"TemplateName": "LightCullingTilePrepareMSAATemplate",
|
||||
"Connections": [
|
||||
{
|
||||
"LocalSlot": "Depth",
|
||||
"AttachmentRef": {
|
||||
"Pass": "DepthMSAAPass",
|
||||
"Attachment": "Output"
|
||||
}
|
||||
},
|
||||
{
|
||||
"LocalSlot": "DepthTransparentMin",
|
||||
"LocalSlot": "SwapChainOutput",
|
||||
"AttachmentRef": {
|
||||
"Pass": "DepthTransparentMinPass",
|
||||
"Attachment": "Output"
|
||||
}
|
||||
},
|
||||
{
|
||||
"LocalSlot": "DepthTransparentMax",
|
||||
"AttachmentRef": {
|
||||
"Pass": "DepthTransparentMaxPass",
|
||||
"Pass": "Parent",
|
||||
"Attachment": "Output"
|
||||
}
|
||||
}
|
||||
@@ -186,40 +123,27 @@
|
||||
},
|
||||
{
|
||||
"Name": "LightCullingPass",
|
||||
"TemplateName": "LightCullingTemplate",
|
||||
"TemplateName": "LightCullingParentTemplate",
|
||||
"Connections": [
|
||||
{
|
||||
"LocalSlot": "TileLightData",
|
||||
"LocalSlot": "SkinnedMeshes",
|
||||
"AttachmentRef": {
|
||||
"Pass": "LightCullingTilePreparePass",
|
||||
"Attachment": "TileLightData"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Name": "LightCullingRemapPass",
|
||||
"TemplateName": "LightCullingRemapTemplate",
|
||||
"Connections": [
|
||||
{
|
||||
"LocalSlot": "TileLightData",
|
||||
"AttachmentRef": {
|
||||
"Pass": "LightCullingTilePreparePass",
|
||||
"Attachment": "TileLightData"
|
||||
"Pass": "SkinningPass",
|
||||
"Attachment": "SkinnedMeshOutputStream"
|
||||
}
|
||||
},
|
||||
{
|
||||
"LocalSlot": "LightCount",
|
||||
"LocalSlot": "DepthMSAA",
|
||||
"AttachmentRef": {
|
||||
"Pass": "LightCullingPass",
|
||||
"Attachment": "LightCount"
|
||||
"Pass": "DepthPrePass",
|
||||
"Attachment": "DepthMSAA"
|
||||
}
|
||||
},
|
||||
{
|
||||
"LocalSlot": "LightList",
|
||||
"LocalSlot": "SwapChainOutput",
|
||||
"AttachmentRef": {
|
||||
"Pass": "LightCullingPass",
|
||||
"Attachment": "LightList"
|
||||
"Pass": "Parent",
|
||||
"Attachment": "Output"
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -259,21 +183,21 @@
|
||||
{
|
||||
"LocalSlot": "DepthStencilInputOutput",
|
||||
"AttachmentRef": {
|
||||
"Pass": "DepthMSAAPass",
|
||||
"Attachment": "Output"
|
||||
"Pass": "DepthPrePass",
|
||||
"Attachment": "DepthMSAA"
|
||||
}
|
||||
},
|
||||
{
|
||||
"LocalSlot": "TileLightData",
|
||||
"AttachmentRef": {
|
||||
"Pass": "LightCullingRemapPass",
|
||||
"Pass": "LightCullingPass",
|
||||
"Attachment": "TileLightData"
|
||||
}
|
||||
},
|
||||
{
|
||||
"LocalSlot": "LightListRemapped",
|
||||
"AttachmentRef": {
|
||||
"Pass": "LightCullingRemapPass",
|
||||
"Pass": "LightCullingPass",
|
||||
"Attachment": "LightListRemapped"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,11 +32,12 @@
|
||||
"Attachment": "SpecularInputOutput"
|
||||
}
|
||||
},
|
||||
"MultisampleSource": {
|
||||
"Pass": "This",
|
||||
"Attachment": "SpecularInputOutput"
|
||||
},
|
||||
"ImageDescriptor": {
|
||||
"Format": "R16G16B16A16_FLOAT",
|
||||
"MultisampleState": {
|
||||
"samples": 4
|
||||
},
|
||||
"SharedQueueMask": "Graphics"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -131,8 +131,13 @@ namespace AZ
|
||||
AZ_Assert(m_blendedLut.m_lutImage != nullptr, "BlendColorGradingLutsPass unable to acquire LUT image");
|
||||
|
||||
AZ::RHI::AttachmentId imageAttachmentId = AZ::RHI::AttachmentId("BlendColorGradingLutImageAttachmentId");
|
||||
[[maybe_unused]] RHI::ResultCode result = frameGraph.GetAttachmentDatabase().ImportImage(imageAttachmentId, m_blendedLut.m_lutImage);
|
||||
AZ_Error("BlendColorGradingLutsPass", result == RHI::ResultCode::Success, "Failed to import compute buffer with error %d", result);
|
||||
|
||||
// import this attachment if it wasn't imported
|
||||
if (!frameGraph.GetAttachmentDatabase().IsAttachmentValid(imageAttachmentId))
|
||||
{
|
||||
[[maybe_unused]] RHI::ResultCode result = frameGraph.GetAttachmentDatabase().ImportImage(imageAttachmentId, m_blendedLut.m_lutImage);
|
||||
AZ_Error("BlendColorGradingLutsPass", result == RHI::ResultCode::Success, "Failed to import BlendColorGradingLutImageAttachmentId with error %d", result);
|
||||
}
|
||||
|
||||
RHI::ImageScopeAttachmentDescriptor desc;
|
||||
desc.m_attachmentId = imageAttachmentId;
|
||||
|
||||
@@ -248,6 +248,9 @@ namespace AZ
|
||||
|
||||
AZ::RPI::RenderPipelineDescriptor environmentCubeMapPipelineDesc;
|
||||
environmentCubeMapPipelineDesc.m_mainViewTagName = "MainCamera";
|
||||
environmentCubeMapPipelineDesc.m_renderSettings.m_multisampleState.m_samples = 4;
|
||||
environmentCubeMapPipelineDesc.m_renderSettings.m_size.m_width = RPI::EnvironmentCubeMapPass::CubeMapFaceSize;
|
||||
environmentCubeMapPipelineDesc.m_renderSettings.m_size.m_height = RPI::EnvironmentCubeMapPass::CubeMapFaceSize;
|
||||
|
||||
// create a unique name for the pipeline
|
||||
AZ::Uuid uuid = AZ::Uuid::CreateRandom();
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -16,6 +16,6 @@ namespace AZ
|
||||
{
|
||||
namespace RHI
|
||||
{
|
||||
bool Validation::s_isEnabled = BuildOptions::IsDebugBuild;
|
||||
bool Validation::s_isEnabled = BuildOptions::IsDebugBuild || BuildOptions::IsProfileBuild;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -404,6 +404,12 @@ namespace AZ
|
||||
Buffer& buffer = static_cast<Buffer&>(*bufferFrameAttachment.GetBuffer());
|
||||
RHI::BufferScopeAttachment* scopeAttachment = bufferFrameAttachment.GetFirstScopeAttachment();
|
||||
|
||||
if (scopeAttachment == nullptr)
|
||||
{
|
||||
AZ_WarningOnce("RHI", false, "Imported BufferFrameAttachment isn't used in any Scope");
|
||||
return;
|
||||
}
|
||||
|
||||
D3D12_RESOURCE_TRANSITION_BARRIER transition;
|
||||
transition.pResource = buffer.GetMemoryView().GetMemory();
|
||||
transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
|
||||
@@ -471,6 +477,12 @@ namespace AZ
|
||||
Image& image = static_cast<Image&>(*imageFrameAttachment.GetImage());
|
||||
RHI::ImageScopeAttachment* scopeAttachment = imageFrameAttachment.GetFirstScopeAttachment();
|
||||
|
||||
if (scopeAttachment == nullptr)
|
||||
{
|
||||
AZ_WarningOnce("RHI", false, "Imported ImageFrameAttachment isn't used in any Scope");
|
||||
return;
|
||||
}
|
||||
|
||||
D3D12_RESOURCE_TRANSITION_BARRIER transition;
|
||||
transition.pResource = image.GetMemoryView().GetMemory();
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ namespace AZ
|
||||
PassConnection childInputConnection;
|
||||
childInputConnection.m_localSlot = "Output";
|
||||
childInputConnection.m_attachmentRef.m_pass = "Parent";
|
||||
childInputConnection.m_attachmentRef.m_attachment = "CubeMapOutput";
|
||||
childInputConnection.m_attachmentRef.m_attachment = "Output";
|
||||
childRequest.m_connections.emplace_back(childInputConnection);
|
||||
|
||||
PassSystemInterface* passSystem = PassSystemInterface::Get();
|
||||
@@ -120,15 +120,16 @@ namespace AZ
|
||||
|
||||
// create output PassAttachment
|
||||
m_passAttachment = aznew PassAttachment();
|
||||
m_passAttachment->m_name = "CubeMapOutput";
|
||||
m_passAttachment->m_path = "CubeMapOutput";
|
||||
m_passAttachment->m_name = "Output";
|
||||
AZ::Name attachmentPath(AZStd::string::format("%s.%s", GetPathName().GetCStr(), m_passAttachment->m_name.GetCStr()));
|
||||
m_passAttachment->m_path = attachmentPath;
|
||||
m_passAttachment->m_lifetime = RHI::AttachmentLifetimeType::Transient;
|
||||
m_passAttachment->m_descriptor = m_outputImageDesc;
|
||||
|
||||
// create pass attachment binding
|
||||
PassAttachmentBinding outputAttachment;
|
||||
outputAttachment.m_name = "CubeMapOutput";
|
||||
outputAttachment.m_slotType = PassSlotType::Output;
|
||||
outputAttachment.m_name = "Output";
|
||||
outputAttachment.m_slotType = PassSlotType::InputOutput;
|
||||
outputAttachment.m_attachment = m_passAttachment;
|
||||
outputAttachment.m_scopeAttachmentUsage = RHI::ScopeAttachmentUsage::RenderTarget;
|
||||
|
||||
|
||||
@@ -16,6 +16,6 @@ namespace AZ
|
||||
{
|
||||
namespace RPI
|
||||
{
|
||||
bool Validation::s_isEnabled = RHI::BuildOptions::IsDebugBuild;
|
||||
bool Validation::s_isEnabled = RHI::BuildOptions::IsDebugBuild || RHI::BuildOptions::IsProfileBuild;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
"Version": 1,
|
||||
"ClassName": "AZ::Render::LightingPreset",
|
||||
"ClassData": {
|
||||
"autoSelect": false,
|
||||
"displayName": "Urban Street 02",
|
||||
"skyboxImageAsset": {
|
||||
"assetId": {
|
||||
|
||||
-2
@@ -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",
|
||||
|
||||
-1
@@ -3,7 +3,6 @@
|
||||
"Version": 1,
|
||||
"ClassName": "AZ::Render::LightingPreset",
|
||||
"ClassData": {
|
||||
"autoSelect": true,
|
||||
"displayName": "Neutral Urban",
|
||||
"iblDiffuseImageAsset": {
|
||||
"assetId": {
|
||||
|
||||
-1
@@ -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");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
+21
-8
@@ -60,13 +60,17 @@ namespace MaterialEditor
|
||||
AZ::Data::AssetCatalogRequestBus::Broadcast(&AZ::Data::AssetCatalogRequestBus::Events::EnumerateAssets, nullptr, enumerateCB, nullptr);
|
||||
|
||||
//Update the material type file info whenever the combo box selection changes
|
||||
QObject::connect(m_ui->m_materialTypeComboBox, static_cast<void(QComboBox::*)(const int)>(&QComboBox::currentIndexChanged), m_ui->m_materialTypeComboBox, [this](int index) {
|
||||
QVariant data = m_ui->m_materialTypeComboBox->itemData(index);
|
||||
m_materialTypeFileInfo = QFileInfo(data.toString());
|
||||
});
|
||||
QObject::connect(m_ui->m_materialTypeComboBox, static_cast<void (QComboBox::*)(const int)>(&QComboBox::currentIndexChanged), this, [this]() { UpdateMaterialTypeSelection(); });
|
||||
QObject::connect(m_ui->m_materialTypeComboBox, &QComboBox::currentTextChanged, this, [this]() { UpdateMaterialTypeSelection(); });
|
||||
|
||||
//Select StandardPBR by default but we will later data drive this with editor settings
|
||||
m_ui->m_materialTypeComboBox->setCurrentText("StandardPBR");
|
||||
// Select StandardPBR by default but we will later data drive this with editor settings
|
||||
const int index = m_ui->m_materialTypeComboBox->findText("StandardPBR");
|
||||
if (index >= 0)
|
||||
{
|
||||
m_ui->m_materialTypeComboBox->setCurrentIndex(index);
|
||||
}
|
||||
|
||||
UpdateMaterialTypeSelection();
|
||||
}
|
||||
|
||||
void CreateMaterialDialog::InitMaterialFileSelection()
|
||||
@@ -88,15 +92,24 @@ namespace MaterialEditor
|
||||
m_materialFileInfo.absoluteFilePath(),
|
||||
QString("Material (*.material)"));
|
||||
|
||||
//Reject empty or invalid filenames which indicate user cancellation
|
||||
// Reject empty or invalid filenames which indicate user cancellation
|
||||
if (!fileInfo.absoluteFilePath().isEmpty())
|
||||
{
|
||||
m_materialFileInfo = fileInfo;
|
||||
m_ui->m_materialFilePicker->setText(m_materialFileInfo.fileName());
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void CreateMaterialDialog::UpdateMaterialTypeSelection()
|
||||
{
|
||||
const int index = m_ui->m_materialTypeComboBox->currentIndex();
|
||||
if (index >= 0)
|
||||
{
|
||||
const QVariant itemData = m_ui->m_materialTypeComboBox->itemData(index);
|
||||
m_materialTypeFileInfo = QFileInfo(itemData.toString());
|
||||
}
|
||||
}
|
||||
} // namespace MaterialEditor
|
||||
|
||||
#include <Window/CreateMaterialDialog/moc_CreateMaterialDialog.cpp>
|
||||
|
||||
+1
@@ -36,5 +36,6 @@ namespace MaterialEditor
|
||||
QScopedPointer<Ui::CreateMaterialDialog> m_ui;
|
||||
void InitMaterialTypeSelection();
|
||||
void InitMaterialFileSelection();
|
||||
void UpdateMaterialTypeSelection();
|
||||
};
|
||||
} // namespace MaterialEditor
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -249,7 +249,7 @@ namespace AZ
|
||||
bool m_showTimeline = false;
|
||||
|
||||
// Controls how often the timestamp data is refreshed
|
||||
RefreshType m_refreshType = RefreshType::OncePerSecond;
|
||||
RefreshType m_refreshType = RefreshType::Realtime;
|
||||
AZStd::sys_time_t m_lastUpdateTimeMicroSecond;
|
||||
|
||||
};
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
#include <Atom/RPI.Public/RPISystemInterface.h>
|
||||
#include <Atom/RPI.Public/Scene.h>
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
@@ -725,7 +727,7 @@ namespace AZ
|
||||
ImGui::BeginTooltip();
|
||||
ImGui::Text("Name: %s", passEntry->m_name.GetCStr());
|
||||
ImGui::Text("Path: %s", passEntry->m_path.GetCStr());
|
||||
ImGui::Text("Duration in ticks: %lu", passEntry->m_timestampResult.GetDurationInTicks());
|
||||
ImGui::Text("Duration in ticks: %" PRIu64, passEntry->m_timestampResult.GetDurationInTicks());
|
||||
ImGui::Text("Duration in microsecond: %.3f us", passEntry->m_timestampResult.GetDurationInNanoseconds()/1000.f);
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
|
||||
-2
@@ -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": {
|
||||
|
||||
+1
-1
@@ -36,7 +36,7 @@ namespace AZ
|
||||
struct ThumbnailRendererData final
|
||||
{
|
||||
static constexpr const char* LightingPresetPath = "lightingpresets/thumbnail.lightingpreset.azasset";
|
||||
static constexpr const char* DefaultModelPath = "materialeditor/viewportmodels/quadsphere.azmodel";
|
||||
static constexpr const char* DefaultModelPath = "models/sphere.azmodel";
|
||||
static constexpr const char* DefaultMaterialPath = "materials/basic_grey.azmaterial";
|
||||
|
||||
RPI::ScenePtr m_scene;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -68,12 +68,6 @@ ly_add_target(
|
||||
)
|
||||
|
||||
if (PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
|
||||
find_package(OpenGL QUIET REQUIRED)
|
||||
# Imported targets (like OpenGL::GL) are scoped to a directory. Add a
|
||||
# a global scope
|
||||
add_library(3rdParty::OpenGLInterface INTERFACE IMPORTED GLOBAL)
|
||||
target_link_libraries(3rdParty::OpenGLInterface INTERFACE OpenGL::GL)
|
||||
|
||||
ly_add_target(
|
||||
NAME EMotionFX.Editor.Static STATIC
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -13,10 +13,4 @@
|
||||
# based on the active platform
|
||||
# NOTE: functions in cmake are global, therefore adding functions to this file
|
||||
# is being avoided to prevent overriding functions declared in other targets platfrom
|
||||
# specific cmake files
|
||||
|
||||
target_compile_definitions(3rdParty::OpenGLInterface
|
||||
INTERFACE
|
||||
# MacOS 10.14 deprecates OpenGL. This silences the warnings for now.
|
||||
GL_SILENCE_DEPRECATION
|
||||
)
|
||||
# specific cmake files
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -823,20 +823,37 @@ void CAnimSequence::SetId(uint32 newId)
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAnimSequence::Reflect(AZ::SerializeContext* serializeContext)
|
||||
static bool AnimSequenceVersionConverter(
|
||||
AZ::SerializeContext& serializeContext,
|
||||
AZ::SerializeContext::DataElementNode& rootElement)
|
||||
{
|
||||
serializeContext->Class<CAnimSequence>()
|
||||
->Version(4)
|
||||
->Field("Name", &CAnimSequence::m_name)
|
||||
->Field("SequenceEntityId", &CAnimSequence::m_sequenceEntityId)
|
||||
->Field("Flags", &CAnimSequence::m_flags)
|
||||
->Field("TimeRange", &CAnimSequence::m_timeRange)
|
||||
->Field("ID", &CAnimSequence::m_id)
|
||||
->Field("Nodes", &CAnimSequence::m_nodes)
|
||||
->Field("SequenceType", &CAnimSequence::m_sequenceType)
|
||||
->Field("Events", &CAnimSequence::m_events)
|
||||
->Field("Expanded", &CAnimSequence::m_expanded)
|
||||
->Field("ActiveDirectorNodeId", &CAnimSequence::m_activeDirectorNodeId);
|
||||
if (rootElement.GetVersion() < 5)
|
||||
{
|
||||
rootElement.AddElement(serializeContext, "BaseClass1", azrtti_typeid<IAnimSequence>());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CAnimSequence::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
IAnimSequence::Reflect(context);
|
||||
|
||||
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context); serializeContext != nullptr)
|
||||
{
|
||||
serializeContext->Class<CAnimSequence, IAnimSequence>()
|
||||
->Version(IAnimSequence::kSequenceVersion, &AnimSequenceVersionConverter)
|
||||
->Field("Name", &CAnimSequence::m_name)
|
||||
->Field("SequenceEntityId", &CAnimSequence::m_sequenceEntityId)
|
||||
->Field("Flags", &CAnimSequence::m_flags)
|
||||
->Field("TimeRange", &CAnimSequence::m_timeRange)
|
||||
->Field("ID", &CAnimSequence::m_id)
|
||||
->Field("Nodes", &CAnimSequence::m_nodes)
|
||||
->Field("SequenceType", &CAnimSequence::m_sequenceType)
|
||||
->Field("Events", &CAnimSequence::m_events)
|
||||
->Field("Expanded", &CAnimSequence::m_expanded)
|
||||
->Field("ActiveDirectorNodeId", &CAnimSequence::m_activeDirectorNodeId);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -154,7 +154,7 @@ public:
|
||||
return m_nextTrackId++;
|
||||
}
|
||||
|
||||
static void Reflect(AZ::SerializeContext* serializeContext);
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
private:
|
||||
void ComputeTimeRange();
|
||||
|
||||
@@ -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))
|
||||
|
||||
+1
-1
@@ -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())
|
||||
{
|
||||
|
||||
+28
-1
@@ -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:
|
||||
|
||||
|
||||
+6
-2
@@ -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)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user