Merge branch 'stabilization/2110' of https://github.com/aws-lumberyard/o3de into Prism/WindowsInstallerName
Signed-off-by: AMZN-Phil <pconroy@amazon.com>
This commit is contained in:
+1
-2
@@ -12,13 +12,12 @@ class Tests():
|
||||
add_terrain_collider = ("Terrain Physics Heightfield Collider component added", "Failed to add a Terrain Physics Heightfield Collider component")
|
||||
box_dimensions_changed = ("Aabb dimensions changed successfully", "Failed change Aabb dimensions")
|
||||
configuration_changed = ("Terrain size changed successfully", "Failed terrain size change")
|
||||
no_errors_and_warnings_found = ("No errors and warnings found", "Found errors and warnings")
|
||||
#fmt: on
|
||||
|
||||
def TerrainPhysicsCollider_ChangesSizeWithAxisAlignedBoxShapeChanges():
|
||||
"""
|
||||
Summary:
|
||||
Test aspects of the TerrainHeightGradientList through the BehaviorContext and the Property Tree.
|
||||
Test aspects of the Terrain Physics Heightfield Collider through the BehaviorContext and the Property Tree.
|
||||
|
||||
Test Steps:
|
||||
Expected Behavior:
|
||||
|
||||
@@ -0,0 +1,164 @@
|
||||
"""
|
||||
Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
#fmt: off
|
||||
class Tests():
|
||||
create_terrain_spawner_entity = ("Terrain_spawner_entity created successfully", "Failed to create terrain_spawner_entity")
|
||||
create_height_provider_entity = ("Height_provider_entity created successfully", "Failed to create height_provider_entity")
|
||||
create_test_ball = ("Ball created successfully", "Failed to create Ball")
|
||||
box_dimensions_changed = ("Aabb dimensions changed successfully", "Failed change Aabb dimensions")
|
||||
shape_changed = ("Shape changed successfully", "Failed Shape change")
|
||||
entity_added = ("Entity added successfully", "Failed Entity add")
|
||||
frequency_changed = ("Frequency changed successfully", "Failed Frequency change")
|
||||
shape_set = ("Shape set to Sphere successfully", "Failed to set Sphere shape")
|
||||
test_collision = ("Ball collided with terrain", "Ball failed to collide with terrain")
|
||||
no_errors_and_warnings_found = ("No errors and warnings found", "Found errors and warnings")
|
||||
#fmt: on
|
||||
|
||||
def Terrain_SupportsPhysics():
|
||||
"""
|
||||
Summary:
|
||||
Test aspects of the TerrainHeightGradientList through the BehaviorContext and the Property Tree.
|
||||
|
||||
Test Steps:
|
||||
Expected Behavior:
|
||||
The Editor is stable there are no warnings or errors.
|
||||
|
||||
Test Steps:
|
||||
1) Load the base level
|
||||
2) Create 2 test entities, one parent at 512.0, 512.0, 50.0 and one child at the default position and add the required components
|
||||
2a) Create a ball at 600.0, 600.0, 46.0 - This position is not too high over the heightfield so will collide in a reasonable time
|
||||
3) Start the Tracer to catch any errors and warnings
|
||||
4) Change the Axis Aligned Box Shape dimensions
|
||||
5) Set the Vegetation Shape reference to TestEntity1
|
||||
6) Set the FastNoise gradient frequency to 0.01
|
||||
7) Set the Gradient List to TestEntity2
|
||||
8) Set the PhysX Collider to Sphere mode
|
||||
9) Disable and Enable the Terrain Gradient List so that it is recognised
|
||||
10) Enter game mode and test if the ball hits the heightfield within 3 seconds
|
||||
11) Verify there are no errors and warnings in the logs
|
||||
|
||||
|
||||
:return: None
|
||||
"""
|
||||
|
||||
from editor_python_test_tools.editor_entity_utils import EditorEntity
|
||||
from editor_python_test_tools.utils import TestHelper as helper, Report
|
||||
from editor_python_test_tools.utils import Report, Tracer
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
import azlmbr.math as azmath
|
||||
import azlmbr.legacy.general as general
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import math
|
||||
|
||||
SET_BOX_X_SIZE = 1024.0
|
||||
SET_BOX_Y_SIZE = 1024.0
|
||||
SET_BOX_Z_SIZE = 100.0
|
||||
|
||||
helper.init_idle()
|
||||
|
||||
# 1) Load the level
|
||||
helper.open_level("", "Base")
|
||||
helper.wait_for_condition(lambda: general.get_current_level_name() == "Base", 2.0)
|
||||
|
||||
#1a) Load the level components
|
||||
hydra.add_level_component("Terrain World")
|
||||
hydra.add_level_component("Terrain World Renderer")
|
||||
|
||||
# 2) Create 2 test entities, one parent at 512.0, 512.0, 50.0 and one child at the default position and add the required components
|
||||
entity1_components_to_add = ["Axis Aligned Box Shape", "Terrain Layer Spawner", "Terrain Height Gradient List", "Terrain Physics Heightfield Collider", "PhysX Heightfield Collider"]
|
||||
entity2_components_to_add = ["Vegetation Reference Shape", "Gradient Transform Modifier", "FastNoise Gradient"]
|
||||
ball_components_to_add = ["Sphere Shape", "PhysX Collider", "PhysX Rigid Body"]
|
||||
terrain_spawner_entity = hydra.Entity("TestEntity1")
|
||||
terrain_spawner_entity.create_entity(azmath.Vector3(512.0, 512.0, 50.0), entity1_components_to_add)
|
||||
Report.result(Tests.create_terrain_spawner_entity, terrain_spawner_entity.id.IsValid())
|
||||
height_provider_entity = hydra.Entity("TestEntity2")
|
||||
height_provider_entity.create_entity(azmath.Vector3(0.0, 0.0, 0.0), entity2_components_to_add,terrain_spawner_entity.id)
|
||||
Report.result(Tests.create_height_provider_entity, height_provider_entity.id.IsValid())
|
||||
# 2a) Create a ball at 600.0, 600.0, 46.0 - This position is not too high over the heightfield so will collide in a reasonable time
|
||||
ball = hydra.Entity("Ball")
|
||||
ball.create_entity(azmath.Vector3(600.0, 600.0, 46.0), ball_components_to_add)
|
||||
Report.result(Tests.create_test_ball, ball.id.IsValid())
|
||||
# Give everything a chance to finish initializing.
|
||||
general.idle_wait_frames(1)
|
||||
|
||||
# 3) Start the Tracer to catch any errors and warnings
|
||||
with Tracer() as section_tracer:
|
||||
# 4) Change the Axis Aligned Box Shape dimensions
|
||||
box_dimensions = azmath.Vector3(SET_BOX_X_SIZE, SET_BOX_Y_SIZE, SET_BOX_Z_SIZE)
|
||||
terrain_spawner_entity.get_set_test(0, "Axis Aligned Box Shape|Box Configuration|Dimensions", box_dimensions)
|
||||
box_shape_dimensions = hydra.get_component_property_value(terrain_spawner_entity.components[0], "Axis Aligned Box Shape|Box Configuration|Dimensions")
|
||||
Report.result(Tests.box_dimensions_changed, box_dimensions == box_shape_dimensions)
|
||||
|
||||
# 5) Set the Vegetaion Shape reference to TestEntity1
|
||||
height_provider_entity.get_set_test(0, "Configuration|Shape Entity Id", terrain_spawner_entity.id)
|
||||
entityId = hydra.get_component_property_value(height_provider_entity.components[0], "Configuration|Shape Entity Id")
|
||||
Report.result(Tests.shape_changed, entityId == terrain_spawner_entity.id)
|
||||
|
||||
# 6) Set the FastNoise Gradient frequency to 0.01
|
||||
Frequency = 0.01
|
||||
height_provider_entity.get_set_test(2, "Configuration|Frequency", Frequency)
|
||||
FrequencyVal = hydra.get_component_property_value(height_provider_entity.components[2], "Configuration|Frequency")
|
||||
Report.result(Tests.frequency_changed, math.isclose(Frequency, FrequencyVal, abs_tol = 0.00001))
|
||||
|
||||
# 7) Set the Gradient List to TestEntity2
|
||||
propertyTree = hydra.get_property_tree(terrain_spawner_entity.components[2])
|
||||
propertyTree.add_container_item("Configuration|Gradient Entities", 0, height_provider_entity.id)
|
||||
checkID = propertyTree.get_container_item("Configuration|Gradient Entities", 0)
|
||||
Report.result(Tests.entity_added, checkID.GetValue() == height_provider_entity.id)
|
||||
|
||||
# 8) Set the PhysX Collider to Sphere mode
|
||||
shape = 0
|
||||
hydra.get_set_test(ball, 1, "Shape Configuration|Shape", shape)
|
||||
setShape = hydra.get_component_property_value(ball.components[1], "Shape Configuration|Shape")
|
||||
Report.result(Tests.shape_set, shape == setShape)
|
||||
|
||||
# 9) Disable and Enable the Terrain Gradient List so that it is recognised
|
||||
editor.EditorComponentAPIBus(bus.Broadcast, 'EnableComponents', [terrain_spawner_entity.components[2]])
|
||||
|
||||
general.enter_game_mode()
|
||||
|
||||
general.idle_wait_frames(1)
|
||||
|
||||
# 10) Enter game mode and test if the ball hits the heightfield within 3 seconds
|
||||
TIMEOUT = 3.0
|
||||
|
||||
class Collider:
|
||||
id = general.find_game_entity("Ball")
|
||||
touched_ground = False
|
||||
|
||||
terrain_id = general.find_game_entity("TestEntity1")
|
||||
|
||||
def on_collision_begin(args):
|
||||
other_id = args[0]
|
||||
if other_id.Equal(terrain_id):
|
||||
Report.info("Touched ground")
|
||||
Collider.touched_ground = True
|
||||
|
||||
handler = azlmbr.physics.CollisionNotificationBusHandler()
|
||||
handler.connect(Collider.id)
|
||||
handler.add_callback("OnCollisionBegin", on_collision_begin)
|
||||
|
||||
helper.wait_for_condition(lambda: Collider.touched_ground, TIMEOUT)
|
||||
Report.result(Tests.test_collision, Collider.touched_ground)
|
||||
|
||||
general.exit_game_mode()
|
||||
|
||||
# 11) Verify there are no errors and warnings in the logs
|
||||
helper.wait_for_condition(lambda: section_tracer.has_errors or section_tracer.has_asserts, 1.0)
|
||||
for error_info in section_tracer.errors:
|
||||
Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}")
|
||||
for assert_info in section_tracer.asserts:
|
||||
Report.info(f"Assert: {assert_info.filename} {assert_info.function} | {assert_info.message}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(Terrain_SupportsPhysics)
|
||||
|
||||
@@ -13,13 +13,15 @@ import os
|
||||
import sys
|
||||
|
||||
from ly_test_tools import LAUNCHERS
|
||||
from ly_test_tools.o3de.editor_test import EditorTestSuite, EditorSingleTest
|
||||
from ly_test_tools.o3de.editor_test import EditorTestSuite, EditorSharedTest
|
||||
|
||||
@pytest.mark.SUITE_main
|
||||
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
|
||||
@pytest.mark.parametrize("project", ["AutomatedTesting"])
|
||||
class TestAutomation(EditorTestSuite):
|
||||
#global_extra_cmdline_args=["--regset=/Amazon/Preferences/EnablePrefabSystem=true"]
|
||||
|
||||
class test_AxisAlignedBoxShape_ConfigurationWorks(EditorSingleTest):
|
||||
class test_AxisAlignedBoxShape_ConfigurationWorks(EditorSharedTest):
|
||||
from .EditorScripts import TerrainPhysicsCollider_ChangesSizeWithAxisAlignedBoxShapeChanges as test_module
|
||||
|
||||
class test_Terrain_SupportsPhysics(EditorSharedTest):
|
||||
from .EditorScripts import Terrain_SupportsPhysics as test_module
|
||||
|
||||
+12
-7
@@ -62,7 +62,7 @@ def AssetBrowser_SearchFiltering():
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
def verify_files_appeared(model, allowed_asset_extentions, parent_index=QtCore.QModelIndex()):
|
||||
def verify_files_appeared(model, allowed_asset_extensions, parent_index=QtCore.QModelIndex()):
|
||||
indexes = [parent_index]
|
||||
while len(indexes) > 0:
|
||||
parent_index = indexes.pop(0)
|
||||
@@ -71,7 +71,7 @@ def AssetBrowser_SearchFiltering():
|
||||
cur_data = cur_index.data(Qt.DisplayRole)
|
||||
if (
|
||||
"." in cur_data
|
||||
and (cur_data.lower().split(".")[-1] not in allowed_asset_extentions)
|
||||
and (cur_data.lower().split(".")[-1] not in allowed_asset_extensions)
|
||||
and not cur_data[-1] == ")"
|
||||
):
|
||||
Report.info(f"Incorrect file found: {cur_data}")
|
||||
@@ -94,16 +94,21 @@ def AssetBrowser_SearchFiltering():
|
||||
Report.info("Asset Browser is already open")
|
||||
editor_window = pyside_utils.get_editor_main_window()
|
||||
app = QtWidgets.QApplication.instance()
|
||||
|
||||
# 3) Type the name of an asset in the search bar and make sure only one asset is filtered in Asset browser
|
||||
|
||||
# 3) Type the name of an asset in the search bar and make sure it is filtered to and selectable
|
||||
asset_browser = editor_window.findChild(QtWidgets.QDockWidget, "Asset Browser")
|
||||
search_bar = asset_browser.findChild(QtWidgets.QLineEdit, "textSearch")
|
||||
search_bar.setText("cedar.fbx")
|
||||
asset_browser_tree = asset_browser.findChild(QtWidgets.QTreeView, "m_assetBrowserTreeViewWidget")
|
||||
model_index = pyside_utils.find_child_by_pattern(asset_browser_tree, "cedar.fbx")
|
||||
pyside_utils.item_view_index_mouse_click(asset_browser_tree, model_index)
|
||||
asset_browser_table = asset_browser.findChild(QtWidgets.QTreeView, "m_assetBrowserTableViewWidget")
|
||||
found = await pyside_utils.wait_for_condition(lambda: pyside_utils.find_child_by_pattern(asset_browser_table, "cedar.fbx"), 5.0)
|
||||
if found:
|
||||
model_index = pyside_utils.find_child_by_pattern(asset_browser_table, "cedar.fbx")
|
||||
else:
|
||||
Report.result(Tests.asset_filtered, found)
|
||||
pyside_utils.item_view_index_mouse_click(asset_browser_table, model_index)
|
||||
is_filtered = await pyside_utils.wait_for_condition(
|
||||
lambda: asset_browser_tree.indexBelow(asset_browser_tree.currentIndex()) == QtCore.QModelIndex(), 5.0)
|
||||
lambda: asset_browser_table.currentIndex() == model_index, 5.0)
|
||||
Report.result(Tests.asset_filtered, is_filtered)
|
||||
|
||||
# 4) Click the "X" in the search bar.
|
||||
|
||||
+2
-2
@@ -84,8 +84,8 @@ def AssetBrowser_TreeNavigation():
|
||||
|
||||
# 3) Collapse all files initially
|
||||
main_window = editor_window.findChild(QtWidgets.QMainWindow)
|
||||
asset_browser = pyside_utils.find_child_by_hierarchy(main_window, ..., "Asset Browser")
|
||||
tree = pyside_utils.find_child_by_hierarchy(asset_browser, ..., "m_assetBrowserTreeViewWidget")
|
||||
asset_browser = pyside_utils.find_child_by_pattern(main_window, text="Asset Browser", type=QtWidgets.QDockWidget)
|
||||
tree = pyside_utils.find_child_by_pattern(asset_browser, "m_assetBrowserTreeViewWidget")
|
||||
scroll_area = tree.findChild(QtWidgets.QWidget, "qt_scrollarea_vcontainer")
|
||||
scroll_bar = scroll_area.findChild(QtWidgets.QScrollBar)
|
||||
tree.collapseAll()
|
||||
|
||||
@@ -43,7 +43,6 @@ class TestAutomationNoAutoTestMode(EditorTestSuite):
|
||||
class test_InputBindings_Add_Remove_Input_Events(EditorSharedTest):
|
||||
from .EditorScripts import InputBindings_Add_Remove_Input_Events as test_module
|
||||
|
||||
@pytest.mark.skip(reason="Crashes Editor: ATOM-15493")
|
||||
class test_AssetPicker_UI_UX(EditorSharedTest):
|
||||
from .EditorScripts import AssetPicker_UI_UX as test_module
|
||||
|
||||
@@ -60,7 +59,6 @@ class TestAutomationAutoTestMode(EditorTestSuite):
|
||||
class test_AssetBrowser_TreeNavigation(EditorSharedTest):
|
||||
from .EditorScripts import AssetBrowser_TreeNavigation as test_module
|
||||
|
||||
@pytest.mark.skip(reason="Crashes Editor: ATOM-15493")
|
||||
class test_AssetBrowser_SearchFiltering(EditorSharedTest):
|
||||
from .EditorScripts import AssetBrowser_SearchFiltering as test_module
|
||||
|
||||
@@ -74,6 +72,5 @@ class TestAutomationAutoTestMode(EditorTestSuite):
|
||||
class test_Menus_FileMenuOptions_Work(EditorSharedTest):
|
||||
from .EditorScripts import Menus_FileMenuOptions as test_module
|
||||
|
||||
|
||||
class test_BasicEditorWorkflows_ExistingLevel_EntityComponentCRUD(EditorSharedTest):
|
||||
from .EditorScripts import BasicEditorWorkflows_ExistingLevel_EntityComponentCRUD as test_module
|
||||
|
||||
@@ -34,12 +34,10 @@ class TestAutomation(TestAutomationBase):
|
||||
from .EditorScripts import AssetBrowser_TreeNavigation as test_module
|
||||
self._run_test(request, workspace, editor, test_module, batch_mode=False)
|
||||
|
||||
@pytest.mark.skip(reason="Crashes Editor: ATOM-15493")
|
||||
def test_AssetBrowser_SearchFiltering(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import AssetBrowser_SearchFiltering as test_module
|
||||
self._run_test(request, workspace, editor, test_module, batch_mode=False)
|
||||
|
||||
@pytest.mark.skip(reason="Crashes Editor: ATOM-15493")
|
||||
def test_AssetPicker_UI_UX(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import AssetPicker_UI_UX as test_module
|
||||
self._run_test(request, workspace, editor, test_module, autotest_mode=False, batch_mode=False)
|
||||
|
||||
@@ -17,7 +17,16 @@
|
||||
},
|
||||
"Component_[14126657869720434043]": {
|
||||
"$type": "EditorEntitySortComponent",
|
||||
"Id": 14126657869720434043
|
||||
"Id": 14126657869720434043,
|
||||
"ChildEntityOrderEntryArray": [
|
||||
{
|
||||
"EntityId": ""
|
||||
},
|
||||
{
|
||||
"EntityId": "",
|
||||
"SortIndex": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
"Component_[15230859088967841193]": {
|
||||
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
|
||||
|
||||
@@ -234,7 +234,7 @@ void Q2DViewport::UpdateContent(int flags)
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void Q2DViewport::OnRButtonDown(Qt::KeyboardModifiers modifiers, const QPoint& point)
|
||||
void Q2DViewport::OnRButtonDown([[maybe_unused]] Qt::KeyboardModifiers modifiers, const QPoint& point)
|
||||
{
|
||||
if (GetIEditor()->IsInGameMode())
|
||||
{
|
||||
@@ -246,9 +246,6 @@ void Q2DViewport::OnRButtonDown(Qt::KeyboardModifiers modifiers, const QPoint& p
|
||||
setFocus();
|
||||
}
|
||||
|
||||
// Check Edit Tool.
|
||||
MouseCallback(eMouseRDown, point, modifiers);
|
||||
|
||||
SetCurrentCursor(STD_CURSOR_MOVE, QString());
|
||||
|
||||
// Save the mouse down position
|
||||
@@ -273,17 +270,8 @@ void Q2DViewport::OnRButtonUp([[maybe_unused]] Qt::KeyboardModifiers modifiers,
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void Q2DViewport::OnMButtonDown(Qt::KeyboardModifiers modifiers, const QPoint& point)
|
||||
void Q2DViewport::OnMButtonDown([[maybe_unused]] Qt::KeyboardModifiers modifiers, const QPoint& point)
|
||||
{
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// User pressed the middle mouse button
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Check Edit Tool.
|
||||
if (MouseCallback(eMouseMDown, point, modifiers))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Save the mouse down position
|
||||
m_RMouseDownPos = point;
|
||||
|
||||
@@ -300,14 +288,8 @@ void Q2DViewport::OnMButtonDown(Qt::KeyboardModifiers modifiers, const QPoint& p
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void Q2DViewport::OnMButtonUp(Qt::KeyboardModifiers modifiers, const QPoint& point)
|
||||
void Q2DViewport::OnMButtonUp([[maybe_unused]] Qt::KeyboardModifiers modifiers, [[maybe_unused]] const QPoint& point)
|
||||
{
|
||||
// Check Edit Tool.
|
||||
if (MouseCallback(eMouseMUp, point, modifiers))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SetViewMode(NothingMode);
|
||||
|
||||
ReleaseMouse();
|
||||
|
||||
@@ -3834,7 +3834,7 @@ void CCryEditApp::SetEditorWindowTitle(QString sTitleStr, QString sPreTitleStr,
|
||||
{
|
||||
if (sTitleStr.isEmpty())
|
||||
{
|
||||
sTitleStr = QObject::tr("O3DE Editor [Developer Preview]");
|
||||
sTitleStr = QObject::tr("O3DE Editor [Stable 21.11]");
|
||||
}
|
||||
|
||||
if (!sPreTitleStr.isEmpty())
|
||||
|
||||
@@ -2307,10 +2307,10 @@ void* EditorViewportWidget::GetSystemCursorConstraintWindow() const
|
||||
return systemCursorConstrained ? renderOverlayHWND() : nullptr;
|
||||
}
|
||||
|
||||
void EditorViewportWidget::BuildDragDropContext(AzQtComponents::ViewportDragContext& context, const QPoint& pt)
|
||||
void EditorViewportWidget::BuildDragDropContext(
|
||||
AzQtComponents::ViewportDragContext& context, const AzFramework::ViewportId viewportId, const QPoint& point)
|
||||
{
|
||||
const auto scaledPoint = WidgetToViewport(pt);
|
||||
QtViewport::BuildDragDropContext(context, scaledPoint);
|
||||
QtViewport::BuildDragDropContext(context, viewportId, point);
|
||||
}
|
||||
|
||||
void EditorViewportWidget::RestoreViewportAfterGameMode()
|
||||
|
||||
@@ -273,7 +273,8 @@ private:
|
||||
|
||||
bool CheckRespondToInput() const;
|
||||
|
||||
void BuildDragDropContext(AzQtComponents::ViewportDragContext& context, const QPoint& pt) override;
|
||||
void BuildDragDropContext(
|
||||
AzQtComponents::ViewportDragContext& context, AzFramework::ViewportId viewportId, const QPoint& point) override;
|
||||
|
||||
void SetAsActiveViewport();
|
||||
void PushDisableRendering();
|
||||
|
||||
@@ -519,7 +519,7 @@ MainWindow* MainWindow::instance()
|
||||
|
||||
void MainWindow::closeEvent(QCloseEvent* event)
|
||||
{
|
||||
gSettings.Save();
|
||||
gSettings.Save(true);
|
||||
|
||||
AzFramework::SystemCursorState currentCursorState;
|
||||
bool isInGameMode = false;
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#include <AzCore/Component/ComponentApplicationBus.h>
|
||||
#include <AzCore/Component/Entity.h>
|
||||
#include <AzCore/Component/TransformBus.h>
|
||||
#include <AzCore/Console/IConsole.h>
|
||||
#include <AzCore/Debug/Profiler.h>
|
||||
#include <AzCore/Math/Transform.h>
|
||||
#include <AzCore/RTTI/AttributeReader.h>
|
||||
@@ -57,6 +56,7 @@
|
||||
#include <AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.hxx>
|
||||
#include <AzToolsFramework/UI/Layer/NameConflictWarning.hxx>
|
||||
#include <AzToolsFramework/ViewportSelection/EditorHelpers.h>
|
||||
#include <AzToolsFramework/ViewportSelection/EditorSelectionUtil.h>
|
||||
#include <MathConversion.h>
|
||||
|
||||
#include <Atom/RPI.Public/ViewportContext.h>
|
||||
@@ -1394,13 +1394,13 @@ void SandboxIntegrationManager::ContextMenu_NewEntity()
|
||||
{
|
||||
AZ::Vector3 worldPosition = AZ::Vector3::CreateZero();
|
||||
|
||||
CViewport* view = GetIEditor()->GetViewManager()->GetGameViewport();
|
||||
// If we don't have a viewport active to aid in placement, the object
|
||||
// will be created at the origin.
|
||||
if (view)
|
||||
if (CViewport* view = GetIEditor()->GetViewManager()->GetGameViewport())
|
||||
{
|
||||
const QPoint viewPoint(static_cast<int>(m_contextMenuViewPoint.GetX()), static_cast<int>(m_contextMenuViewPoint.GetY()));
|
||||
worldPosition = view->GetHitLocation(viewPoint);
|
||||
worldPosition = AzToolsFramework::FindClosestPickIntersection(
|
||||
view->GetViewportId(), AzFramework::ScreenPointFromVector2(m_contextMenuViewPoint), AzToolsFramework::EditorPickRayLength,
|
||||
GetDefaultEntityPlacementDistance());
|
||||
}
|
||||
|
||||
CreateNewEntityAtPosition(worldPosition);
|
||||
|
||||
@@ -473,7 +473,7 @@ void SEditorSettings::LoadValue(const char* sSection, const char* sKey, ESystemC
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void SEditorSettings::Save()
|
||||
void SEditorSettings::Save(bool isEditorClosing)
|
||||
{
|
||||
QString strStringPlaceholder;
|
||||
|
||||
@@ -640,14 +640,16 @@ void SEditorSettings::Save()
|
||||
// --- Settings Registry values
|
||||
|
||||
// Prefab System UI
|
||||
AzFramework::ApplicationRequests::Bus::Broadcast(
|
||||
&AzFramework::ApplicationRequests::SetPrefabSystemEnabled, prefabSystem);
|
||||
AzFramework::ApplicationRequests::Bus::Broadcast(&AzFramework::ApplicationRequests::SetPrefabSystemEnabled, prefabSystem);
|
||||
|
||||
AzToolsFramework::Prefab::PrefabLoaderInterface* prefabLoaderInterface =
|
||||
AZ::Interface<AzToolsFramework::Prefab::PrefabLoaderInterface>::Get();
|
||||
prefabLoaderInterface->SetSaveAllPrefabsPreference(levelSaveSettings.saveAllPrefabsPreference);
|
||||
|
||||
SaveSettingsRegistryFile();
|
||||
if (!isEditorClosing)
|
||||
{
|
||||
SaveSettingsRegistryFile();
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -267,7 +267,7 @@ struct SANDBOX_API SEditorSettings
|
||||
AZ_POP_DISABLE_DLL_EXPORT_BASECLASS_WARNING
|
||||
SEditorSettings();
|
||||
~SEditorSettings() = default;
|
||||
void Save();
|
||||
void Save(bool isEditorClosing = false);
|
||||
void Load();
|
||||
void LoadCloudSettings();
|
||||
|
||||
|
||||
+26
-210
@@ -14,14 +14,19 @@
|
||||
// Qt
|
||||
#include <QPainter>
|
||||
|
||||
// AzCore
|
||||
#include <AzCore/Console/IConsole.h>
|
||||
|
||||
// AzQtComponents
|
||||
#include <AzQtComponents/DragAndDrop/ViewportDragAndDrop.h>
|
||||
|
||||
#include <AzToolsFramework/API/ComponentEntitySelectionBus.h>
|
||||
#include <AzToolsFramework/ViewportSelection/EditorSelectionUtil.h>
|
||||
#include <AzToolsFramework/Viewport/ViewportMessages.h>
|
||||
#include <AzToolsFramework/ViewportSelection/EditorSelectionUtil.h>
|
||||
|
||||
// Editor
|
||||
#include "Editor/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.h"
|
||||
#include "ViewManager.h"
|
||||
#include "Include/ITransformManipulator.h"
|
||||
#include "Include/HitContext.h"
|
||||
@@ -32,22 +37,35 @@
|
||||
#include "GameEngine.h"
|
||||
#include "Settings.h"
|
||||
|
||||
|
||||
#ifdef LoadCursor
|
||||
#undef LoadCursor
|
||||
#endif
|
||||
|
||||
AZ_CVAR(
|
||||
float,
|
||||
ed_defaultEntityPlacementDistance,
|
||||
10.0f,
|
||||
nullptr,
|
||||
AZ::ConsoleFunctorFlags::Null,
|
||||
"The default distance to place an entity from the camera if no intersection is found");
|
||||
|
||||
float GetDefaultEntityPlacementDistance()
|
||||
{
|
||||
return ed_defaultEntityPlacementDistance;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Viewport drag and drop support
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
void QtViewport::BuildDragDropContext(AzQtComponents::ViewportDragContext& context, const QPoint& pt)
|
||||
void QtViewport::BuildDragDropContext(
|
||||
AzQtComponents::ViewportDragContext& context, const AzFramework::ViewportId viewportId, const QPoint& point)
|
||||
{
|
||||
context.m_hitLocation = AZ::Vector3::CreateZero();
|
||||
context.m_hitLocation = GetHitLocation(pt);
|
||||
context.m_hitLocation = AzToolsFramework::FindClosestPickIntersection(
|
||||
viewportId, AzToolsFramework::ViewportInteraction::ScreenPointFromQPoint(point), AzToolsFramework::EditorPickRayLength,
|
||||
GetDefaultEntityPlacementDistance());
|
||||
}
|
||||
|
||||
|
||||
void QtViewport::dragEnterEvent(QDragEnterEvent* event)
|
||||
{
|
||||
if (!GetIEditor()->GetGameEngine()->IsLevelLoaded())
|
||||
@@ -66,7 +84,7 @@ void QtViewport::dragEnterEvent(QDragEnterEvent* event)
|
||||
// new bus-based way of doing it (install a listener!)
|
||||
using namespace AzQtComponents;
|
||||
ViewportDragContext context;
|
||||
BuildDragDropContext(context, event->pos());
|
||||
BuildDragDropContext(context, GetViewportId(), event->pos());
|
||||
DragAndDropEventsBus::Event(DragAndDropContexts::EditorViewport, &DragAndDropEvents::DragEnter, event, context);
|
||||
}
|
||||
}
|
||||
@@ -89,7 +107,7 @@ void QtViewport::dragMoveEvent(QDragMoveEvent* event)
|
||||
// new bus-based way of doing it (install a listener!)
|
||||
using namespace AzQtComponents;
|
||||
ViewportDragContext context;
|
||||
BuildDragDropContext(context, event->pos());
|
||||
BuildDragDropContext(context, GetViewportId(), event->pos());
|
||||
DragAndDropEventsBus::Event(DragAndDropContexts::EditorViewport, &DragAndDropEvents::DragMove, event, context);
|
||||
}
|
||||
}
|
||||
@@ -112,7 +130,7 @@ void QtViewport::dropEvent(QDropEvent* event)
|
||||
{
|
||||
// new bus-based way of doing it (install a listener!)
|
||||
ViewportDragContext context;
|
||||
BuildDragDropContext(context, event->pos());
|
||||
BuildDragDropContext(context, GetViewportId(), event->pos());
|
||||
DragAndDropEventsBus::Event(DragAndDropContexts::EditorViewport, &DragAndDropEvents::Drop, event, context);
|
||||
}
|
||||
}
|
||||
@@ -340,13 +358,6 @@ void QtViewport::resizeEvent(QResizeEvent* event)
|
||||
Update();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void QtViewport::leaveEvent(QEvent* event)
|
||||
{
|
||||
QWidget::leaveEvent(event);
|
||||
MouseCallback(eMouseLeave, QPoint(), Qt::KeyboardModifiers(), Qt::MouseButtons());
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void QtViewport::paintEvent([[maybe_unused]] QPaintEvent* event)
|
||||
{
|
||||
@@ -581,63 +592,7 @@ void QtViewport::keyReleaseEvent(QKeyEvent* event)
|
||||
OnKeyUp(nativeKey, 1, event->nativeModifiers());
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void QtViewport::OnLButtonDown(Qt::KeyboardModifiers modifiers, const QPoint& point)
|
||||
{
|
||||
// Save the mouse down position
|
||||
m_cMouseDownPos = point;
|
||||
|
||||
if (MouseCallback(eMouseLDown, point, modifiers))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void QtViewport::OnLButtonUp(Qt::KeyboardModifiers modifiers, const QPoint& point)
|
||||
{
|
||||
// Check Edit Tool.
|
||||
MouseCallback(eMouseLUp, point, modifiers);
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void QtViewport::OnRButtonDown(Qt::KeyboardModifiers modifiers, const QPoint& point)
|
||||
{
|
||||
MouseCallback(eMouseRDown, point, modifiers);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void QtViewport::OnRButtonUp(Qt::KeyboardModifiers modifiers, const QPoint& point)
|
||||
{
|
||||
MouseCallback(eMouseRUp, point, modifiers);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void QtViewport::OnMButtonDown(Qt::KeyboardModifiers modifiers, const QPoint& point)
|
||||
{
|
||||
// Check Edit Tool.
|
||||
MouseCallback(eMouseMDown, point, modifiers);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void QtViewport::OnMButtonUp(Qt::KeyboardModifiers modifiers, const QPoint& point)
|
||||
{
|
||||
// Move the viewer to the mouse location.
|
||||
// Check Edit Tool.
|
||||
MouseCallback(eMouseMUp, point, modifiers);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void QtViewport::OnMButtonDblClk(Qt::KeyboardModifiers modifiers, const QPoint& point)
|
||||
{
|
||||
MouseCallback(eMouseMDblClick, point, modifiers);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void QtViewport::OnMouseMove(Qt::KeyboardModifiers modifiers, Qt::MouseButtons buttons, const QPoint& point)
|
||||
{
|
||||
MouseCallback(eMouseMove, point, modifiers, buttons);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void QtViewport::OnSetCursor()
|
||||
@@ -696,44 +651,6 @@ void QtViewport::OnDragSelectRectangle(const QRect& rect, bool bNormalizeRect)
|
||||
GetIEditor()->SetStatusText(szNewStatusText);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void QtViewport::OnLButtonDblClk(Qt::KeyboardModifiers modifiers, const QPoint& point)
|
||||
{
|
||||
if (GetIEditor()->IsInGameMode())
|
||||
{
|
||||
// Ignore double clicks while in game.
|
||||
return;
|
||||
}
|
||||
|
||||
MouseCallback(eMouseLDblClick, point, modifiers);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void QtViewport::OnRButtonDblClk(Qt::KeyboardModifiers modifiers, const QPoint& point)
|
||||
{
|
||||
MouseCallback(eMouseRDblClick, point, modifiers);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void QtViewport::OnKeyDown([[maybe_unused]] UINT nChar, [[maybe_unused]] UINT nRepCnt, [[maybe_unused]] UINT nFlags)
|
||||
{
|
||||
if (GetIEditor()->IsInGameMode())
|
||||
{
|
||||
// Ignore key downs while in game.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void QtViewport::OnKeyUp([[maybe_unused]] UINT nChar, [[maybe_unused]] UINT nRepCnt, [[maybe_unused]] UINT nFlags)
|
||||
{
|
||||
if (GetIEditor()->IsInGameMode())
|
||||
{
|
||||
// Ignore key downs while in game.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void QtViewport::SetCurrentCursor(const QCursor& hCursor, const QString& cursorString)
|
||||
{
|
||||
@@ -1119,29 +1036,6 @@ bool QtViewport::HitTest(const QPoint& point, HitContext& hitInfo)
|
||||
return false;
|
||||
}
|
||||
|
||||
AZ::Vector3 QtViewport::GetHitLocation(const QPoint& point)
|
||||
{
|
||||
Vec3 pos = Vec3(ZERO);
|
||||
HitContext hit;
|
||||
if (HitTest(point, hit))
|
||||
{
|
||||
pos = hit.raySrc + hit.rayDir * hit.dist;
|
||||
pos = SnapToGrid(pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
bool hitTerrain;
|
||||
pos = ViewToWorld(point, &hitTerrain);
|
||||
if (hitTerrain)
|
||||
{
|
||||
pos.z = GetIEditor()->GetTerrainElevation(pos.x, pos.y);
|
||||
}
|
||||
pos = SnapToGrid(pos);
|
||||
}
|
||||
|
||||
return AZ::Vector3(pos.x, pos.y, pos.z);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void QtViewport::SetZoomFactor(float fZoomFactor)
|
||||
{
|
||||
@@ -1315,84 +1209,6 @@ bool QtViewport::GetAdvancedSelectModeFlag()
|
||||
return m_bAdvancedSelectMode;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool QtViewport::MouseCallback(EMouseEvent event, const QPoint& point, Qt::KeyboardModifiers modifiers, Qt::MouseButtons buttons)
|
||||
{
|
||||
AZ_PROFILE_FUNCTION(Editor);
|
||||
|
||||
// Ignore any mouse events in game mode.
|
||||
if (GetIEditor()->IsInGameMode())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// We must ignore mouse events when we are in the middle of an assert.
|
||||
// Reason: If we have an assert called from an engine module under the editor, if we call this function,
|
||||
// it may call the engine again and cause a deadlock.
|
||||
// Concrete example: CryPhysics called from Trackview causing an assert, and moving the cursor over the viewport
|
||||
// would cause the editor to freeze as it calls CryPhysics again for a raycast while it didn't release the lock.
|
||||
if (gEnv->pSystem->IsAssertDialogVisible())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Hit test gizmo objects.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool bAltClick = (modifiers & Qt::AltModifier);
|
||||
bool bCtrlClick = (modifiers & Qt::ControlModifier);
|
||||
bool bShiftClick = (modifiers & Qt::ShiftModifier);
|
||||
|
||||
int flags = (bCtrlClick ? MK_CONTROL : 0) |
|
||||
(bShiftClick ? MK_SHIFT : 0) |
|
||||
((buttons& Qt::LeftButton) ? MK_LBUTTON : 0) |
|
||||
((buttons& Qt::MiddleButton) ? MK_MBUTTON : 0) |
|
||||
((buttons& Qt::RightButton) ? MK_RBUTTON : 0);
|
||||
|
||||
switch (event)
|
||||
{
|
||||
case eMouseMove:
|
||||
|
||||
if (m_nLastUpdateFrame == m_nLastMouseMoveFrame)
|
||||
{
|
||||
// If mouse move event generated in the same frame, ignore it.
|
||||
return false;
|
||||
}
|
||||
m_nLastMouseMoveFrame = m_nLastUpdateFrame;
|
||||
|
||||
// Skip the marker position update if anything is selected, since it is only used
|
||||
// by the info bar which doesn't show the marker when there is an active selection.
|
||||
// This helps a performance issue when calling ViewToWorld (which calls RayWorldIntersection)
|
||||
// on every mouse movement becomes very expensive in scenes with large amounts of entities.
|
||||
CSelectionGroup* selection = GetIEditor()->GetSelection();
|
||||
if (!(buttons & Qt::RightButton) /* && m_nLastUpdateFrame != m_nLastMouseMoveFrame*/ && (selection && selection->IsEmpty()))
|
||||
{
|
||||
//m_nLastMouseMoveFrame = m_nLastUpdateFrame;
|
||||
Vec3 pos = ViewToWorld(point);
|
||||
GetIEditor()->SetMarkerPosition(pos);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
QPoint tempPoint(point.x(), point.y());
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Handle viewport manipulators.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
if (!bAltClick)
|
||||
{
|
||||
ITransformManipulator* pManipulator = GetIEditor()->GetTransformManipulator();
|
||||
if (pManipulator)
|
||||
{
|
||||
if (pManipulator->MouseCallback(this, event, tempPoint, flags))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void QtViewport::ProcessRenderLisneters(DisplayContext& rstDisplayContext)
|
||||
{
|
||||
|
||||
+20
-23
@@ -6,13 +6,12 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
// Description : interface for the CViewport class.
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <AzFramework/Viewport/ViewportId.h>
|
||||
#include <AzToolsFramework/Viewport/ViewportTypes.h>
|
||||
#include <AzToolsFramework/ViewportUi/ViewportUiManager.h>
|
||||
#include <Cry_Color.h>
|
||||
@@ -88,6 +87,9 @@ enum EStdCursor
|
||||
STD_CURSOR_LAST,
|
||||
};
|
||||
|
||||
//! The default distance an entity is placed from the camera if there is no intersection
|
||||
SANDBOX_API float GetDefaultEntityPlacementDistance();
|
||||
|
||||
AZ_PUSH_DISABLE_DLL_EXPORT_BASECLASS_WARNING
|
||||
class SANDBOX_API CViewport
|
||||
: public IDisplayViewport
|
||||
@@ -201,7 +203,6 @@ public:
|
||||
|
||||
//! Performs hit testing of 2d point in view to find which object hit.
|
||||
virtual bool HitTest(const QPoint& point, HitContext& hitInfo) = 0;
|
||||
virtual AZ::Vector3 GetHitLocation(const QPoint& point) = 0;
|
||||
|
||||
virtual void MakeConstructionPlane(int axis) = 0;
|
||||
|
||||
@@ -432,7 +433,6 @@ public:
|
||||
|
||||
//! Performs hit testing of 2d point in view to find which object hit.
|
||||
bool HitTest(const QPoint& point, HitContext& hitInfo) override;
|
||||
AZ::Vector3 GetHitLocation(const QPoint& point) override;
|
||||
|
||||
//! Do 2D hit testing of line in world space.
|
||||
// pToCameraDistance is an optional output parameter in which distance from the camera to the line is returned.
|
||||
@@ -522,9 +522,6 @@ protected:
|
||||
void setRenderOverlayVisible(bool);
|
||||
bool isRenderOverlayVisible() const;
|
||||
|
||||
// called to process mouse callback inside the viewport.
|
||||
virtual bool MouseCallback(EMouseEvent event, const QPoint& point, Qt::KeyboardModifiers modifiers, Qt::MouseButtons buttons = Qt::NoButton);
|
||||
|
||||
void ProcessRenderLisneters(DisplayContext& rstDisplayContext);
|
||||
|
||||
void mousePressEvent(QMouseEvent* event) override;
|
||||
@@ -535,29 +532,29 @@ protected:
|
||||
void keyPressEvent(QKeyEvent* event) override;
|
||||
void keyReleaseEvent(QKeyEvent* event) override;
|
||||
void resizeEvent(QResizeEvent* event) override;
|
||||
void leaveEvent(QEvent* event) override;
|
||||
|
||||
void paintEvent(QPaintEvent* event) override;
|
||||
|
||||
virtual void OnMouseMove(Qt::KeyboardModifiers modifiers, Qt::MouseButtons buttons, const QPoint& point);
|
||||
virtual void OnMouseWheel(Qt::KeyboardModifiers modifiers, short zDelta, const QPoint& pt);
|
||||
virtual void OnLButtonDown(Qt::KeyboardModifiers modifiers, const QPoint& point);
|
||||
virtual void OnLButtonUp(Qt::KeyboardModifiers modifiers, const QPoint& point);
|
||||
virtual void OnRButtonDown(Qt::KeyboardModifiers modifiers, const QPoint& point);
|
||||
virtual void OnRButtonUp(Qt::KeyboardModifiers modifiers, const QPoint& point);
|
||||
virtual void OnMButtonDblClk(Qt::KeyboardModifiers modifiers, const QPoint& point);
|
||||
virtual void OnMButtonDown(Qt::KeyboardModifiers modifiers, const QPoint& point);
|
||||
virtual void OnMButtonUp(Qt::KeyboardModifiers modifiers, const QPoint& point);
|
||||
virtual void OnLButtonDblClk(Qt::KeyboardModifiers modifiers, const QPoint& point);
|
||||
virtual void OnRButtonDblClk(Qt::KeyboardModifiers modifiers, const QPoint& point);
|
||||
virtual void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
|
||||
virtual void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags);
|
||||
virtual void OnMouseMove(Qt::KeyboardModifiers, Qt::MouseButtons, const QPoint&) {}
|
||||
virtual void OnMouseWheel(Qt::KeyboardModifiers, short zDelta, const QPoint&);
|
||||
virtual void OnLButtonDown(Qt::KeyboardModifiers, const QPoint&) {}
|
||||
virtual void OnLButtonUp(Qt::KeyboardModifiers, const QPoint&) {}
|
||||
virtual void OnRButtonDown(Qt::KeyboardModifiers, const QPoint&) {}
|
||||
virtual void OnRButtonUp(Qt::KeyboardModifiers, const QPoint&) {}
|
||||
virtual void OnMButtonDblClk(Qt::KeyboardModifiers, const QPoint&) {}
|
||||
virtual void OnMButtonDown(Qt::KeyboardModifiers, const QPoint&) {}
|
||||
virtual void OnMButtonUp(Qt::KeyboardModifiers, const QPoint&) {}
|
||||
virtual void OnLButtonDblClk(Qt::KeyboardModifiers, const QPoint&) {}
|
||||
virtual void OnRButtonDblClk(Qt::KeyboardModifiers, const QPoint&) {}
|
||||
virtual void OnKeyDown([[maybe_unused]] UINT nChar, [[maybe_unused]] UINT nRepCnt, [[maybe_unused]] UINT nFlags) {}
|
||||
virtual void OnKeyUp([[maybe_unused]] UINT nChar, [[maybe_unused]] UINT nRepCnt, [[maybe_unused]] UINT nFlags) {}
|
||||
#if defined(AZ_PLATFORM_WINDOWS)
|
||||
void OnRawInput(UINT wParam, HRAWINPUT lParam);
|
||||
#endif
|
||||
void OnSetCursor();
|
||||
|
||||
virtual void BuildDragDropContext(AzQtComponents::ViewportDragContext& context, const QPoint& pt);
|
||||
virtual void BuildDragDropContext(
|
||||
AzQtComponents::ViewportDragContext& context, AzFramework::ViewportId viewportId, const QPoint& point);
|
||||
|
||||
void dragEnterEvent(QDragEnterEvent* event) override;
|
||||
void dragMoveEvent(QDragMoveEvent* event) override;
|
||||
void dragLeaveEvent(QDragLeaveEvent* event) override;
|
||||
|
||||
@@ -556,16 +556,24 @@ namespace AZ
|
||||
Asset<AssetData> assetData(AssetInternal::GetAssetData(actualId, AZ::Data::AssetLoadBehavior::Default));
|
||||
if (assetData)
|
||||
{
|
||||
auto curStatus = assetData->GetStatus();
|
||||
auto isReady = assetData->GetStatus() == AssetData::AssetStatus::Ready;
|
||||
bool isError = assetData->IsError();
|
||||
connectLock.unlock();
|
||||
if (curStatus == AssetData::AssetStatus::Ready)
|
||||
|
||||
if (isReady || isError)
|
||||
{
|
||||
handler->OnAssetReady(assetData);
|
||||
}
|
||||
else if (isError)
|
||||
{
|
||||
handler->OnAssetError(assetData);
|
||||
connectLock.unlock();
|
||||
|
||||
if (isReady)
|
||||
{
|
||||
handler->OnAssetReady(assetData);
|
||||
}
|
||||
else if (isError)
|
||||
{
|
||||
handler->OnAssetError(assetData);
|
||||
}
|
||||
|
||||
// Lock the mutex again since some destructors will be modifying the context afterwards
|
||||
connectLock.lock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,9 +76,12 @@ namespace AzFramework
|
||||
virtual void DrawSolidCone(const AZ::Vector3& pos, const AZ::Vector3& dir, float radius, float height, bool drawShaded = true) { (void)pos; (void)dir; (void)radius; (void)height; (void)drawShaded; }
|
||||
virtual void DrawWireCylinder(const AZ::Vector3& center, const AZ::Vector3& axis, float radius, float height) { (void)center; (void)axis; (void)radius; (void)height; }
|
||||
virtual void DrawSolidCylinder(const AZ::Vector3& center, const AZ::Vector3& axis, float radius, float height, bool drawShaded = true) { (void)center; (void)axis; (void)radius; (void)height; (void)drawShaded; }
|
||||
virtual void DrawWireCylinderNoEnds(const AZ::Vector3& center, const AZ::Vector3& axis, float radius, float height) { (void)center; (void)axis; (void)radius; (void)height; }
|
||||
virtual void DrawSolidCylinderNoEnds(const AZ::Vector3& center, const AZ::Vector3& axis, float radius, float height, bool drawShaded = true) { (void)center; (void)axis; (void)radius; (void)height; (void)drawShaded; }
|
||||
virtual void DrawWireCapsule(const AZ::Vector3& center, const AZ::Vector3& axis, float radius, float heightStraightSection) { (void)center; (void)axis; (void)radius; (void)heightStraightSection; }
|
||||
virtual void DrawWireSphere(const AZ::Vector3& pos, float radius) { (void)pos; (void)radius; }
|
||||
virtual void DrawWireSphere(const AZ::Vector3& pos, const AZ::Vector3 radius) { (void)pos; (void)radius; }
|
||||
virtual void DrawWireHemisphere(const AZ::Vector3& pos, const AZ::Vector3& axis, float radius) { (void)pos; (void)axis; (void)radius; }
|
||||
virtual void DrawWireDisk(const AZ::Vector3& pos, const AZ::Vector3& dir, float radius) { (void)pos; (void)dir; (void)radius; }
|
||||
virtual void DrawBall(const AZ::Vector3& pos, float radius, bool drawShaded = true) { (void)pos; (void)radius; (void)drawShaded; }
|
||||
virtual void DrawDisk(const AZ::Vector3& pos, const AZ::Vector3& dir, float radius) { (void)pos; (void)dir; (void)radius; }
|
||||
|
||||
+5
-1
@@ -448,7 +448,11 @@ namespace AzToolsFramework
|
||||
|
||||
ViewportUi::ViewportUiRequestBus::Event(
|
||||
ViewportUi::DefaultViewportId, &ViewportUi::ViewportUiRequestBus::Events::CreateViewportBorder,
|
||||
componentMode.m_componentMode->GetComponentModeName().c_str());
|
||||
componentMode.m_componentMode->GetComponentModeName().c_str(),
|
||||
[]
|
||||
{
|
||||
ComponentModeSystemRequestBus::Broadcast(&ComponentModeSystemRequests::EndComponentMode);
|
||||
});
|
||||
}
|
||||
|
||||
RefreshActions();
|
||||
|
||||
+5
-2
@@ -55,8 +55,11 @@ namespace AzToolsFramework
|
||||
GetEntityComponentIdPair(), elementIdsToDisplay);
|
||||
// create the component mode border with the specific name for this component mode
|
||||
ViewportUi::ViewportUiRequestBus::Event(
|
||||
ViewportUi::DefaultViewportId, &ViewportUi::ViewportUiRequestBus::Events::CreateViewportBorder,
|
||||
GetComponentModeName());
|
||||
ViewportUi::DefaultViewportId, &ViewportUi::ViewportUiRequestBus::Events::CreateViewportBorder, GetComponentModeName(),
|
||||
[]
|
||||
{
|
||||
ComponentModeSystemRequestBus::Broadcast(&ComponentModeSystemRequests::EndComponentMode);
|
||||
});
|
||||
// set the EntityComponentId for this ComponentMode to active in the ComponentModeViewportUi system
|
||||
ComponentModeViewportUiRequestBus::Event(
|
||||
GetComponentType(), &ComponentModeViewportUiRequestBus::Events::SetViewportUiActiveEntityComponentId,
|
||||
|
||||
@@ -98,7 +98,7 @@ namespace AzToolsFramework::Prefab
|
||||
}
|
||||
|
||||
// Retrieve parent of currently focused prefab.
|
||||
InstanceOptionalReference parentInstance = m_instanceFocusHierarchy[hierarchySize - 2];
|
||||
InstanceOptionalReference parentInstance = GetReferenceFromContainerEntityId(m_instanceFocusHierarchy[hierarchySize - 2]);
|
||||
|
||||
// Use container entity of parent Instance for focus operations.
|
||||
AZ::EntityId entityId = parentInstance->get().GetContainerEntityId();
|
||||
@@ -132,7 +132,7 @@ namespace AzToolsFramework::Prefab
|
||||
return AZ::Failure(AZStd::string("Prefab Focus Handler: Invalid index on FocusOnPathIndex."));
|
||||
}
|
||||
|
||||
InstanceOptionalReference focusedInstance = m_instanceFocusHierarchy[index];
|
||||
InstanceOptionalReference focusedInstance = GetReferenceFromContainerEntityId(m_instanceFocusHierarchy[index]);
|
||||
|
||||
return FocusOnOwningPrefab(focusedInstance->get().GetContainerEntityId());
|
||||
}
|
||||
@@ -172,7 +172,8 @@ namespace AzToolsFramework::Prefab
|
||||
// Close all container entities in the old path.
|
||||
CloseInstanceContainers(m_instanceFocusHierarchy);
|
||||
|
||||
m_focusedInstance = focusedInstance;
|
||||
// Do not store the container for the root instance, use an invalid EntityId instead.
|
||||
m_focusedInstanceContainerEntityId = focusedInstance->get().GetParentInstance().has_value() ? focusedInstance->get().GetContainerEntityId() : AZ::EntityId();
|
||||
m_focusedTemplateId = focusedInstance->get().GetTemplateId();
|
||||
|
||||
// Focus on the descendants of the container entity in the Editor, if the interface is initialized.
|
||||
@@ -206,56 +207,55 @@ namespace AzToolsFramework::Prefab
|
||||
InstanceOptionalReference PrefabFocusHandler::GetFocusedPrefabInstance(
|
||||
[[maybe_unused]] AzFramework::EntityContextId entityContextId) const
|
||||
{
|
||||
return m_focusedInstance;
|
||||
return GetReferenceFromContainerEntityId(m_focusedInstanceContainerEntityId);
|
||||
}
|
||||
|
||||
AZ::EntityId PrefabFocusHandler::GetFocusedPrefabContainerEntityId([[maybe_unused]] AzFramework::EntityContextId entityContextId) const
|
||||
{
|
||||
if (!m_focusedInstance.has_value())
|
||||
{
|
||||
// PrefabFocusHandler has not been initialized yet.
|
||||
return AZ::EntityId();
|
||||
}
|
||||
|
||||
return m_focusedInstance->get().GetContainerEntityId();
|
||||
return m_focusedInstanceContainerEntityId;
|
||||
}
|
||||
|
||||
bool PrefabFocusHandler::IsOwningPrefabBeingFocused(AZ::EntityId entityId) const
|
||||
{
|
||||
if (!m_focusedInstance.has_value())
|
||||
{
|
||||
// PrefabFocusHandler has not been initialized yet.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!entityId.IsValid())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
InstanceOptionalReference instance = m_instanceEntityMapperInterface->FindOwningInstance(entityId);
|
||||
if (!instance.has_value())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return instance.has_value() && (&instance->get() == &m_focusedInstance->get());
|
||||
// If this is owned by the root instance, that corresponds to an invalid m_focusedInstanceContainerEntityId.
|
||||
if (!instance->get().GetParentInstance().has_value())
|
||||
{
|
||||
return !m_focusedInstanceContainerEntityId.IsValid();
|
||||
}
|
||||
|
||||
return (instance->get().GetContainerEntityId() == m_focusedInstanceContainerEntityId);
|
||||
}
|
||||
|
||||
bool PrefabFocusHandler::IsOwningPrefabInFocusHierarchy(AZ::EntityId entityId) const
|
||||
{
|
||||
if (!m_focusedInstance.has_value())
|
||||
{
|
||||
// PrefabFocusHandler has not been initialized yet.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!entityId.IsValid())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the focus is on the root, m_focusedInstanceContainerEntityId will be the invalid id.
|
||||
// In those case all entities are in the focus hierarchy and should return true.
|
||||
if (!m_focusedInstanceContainerEntityId.IsValid())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
InstanceOptionalReference instance = m_instanceEntityMapperInterface->FindOwningInstance(entityId);
|
||||
|
||||
while (instance.has_value())
|
||||
{
|
||||
if (&instance->get() == &m_focusedInstance->get())
|
||||
if (instance->get().GetContainerEntityId() == m_focusedInstanceContainerEntityId)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -290,8 +290,9 @@ namespace AzToolsFramework::Prefab
|
||||
// Determine if the entityId is the container for any of the instances in the vector.
|
||||
auto result = AZStd::find_if(
|
||||
m_instanceFocusHierarchy.begin(), m_instanceFocusHierarchy.end(),
|
||||
[entityId](const InstanceOptionalReference& instance)
|
||||
[&, entityId](const AZ::EntityId& containerEntityId)
|
||||
{
|
||||
InstanceOptionalReference instance = GetReferenceFromContainerEntityId(containerEntityId);
|
||||
return (instance->get().GetContainerEntityId() == entityId);
|
||||
}
|
||||
);
|
||||
@@ -316,8 +317,9 @@ namespace AzToolsFramework::Prefab
|
||||
// Determine if the templateId matches any of the instances in the vector.
|
||||
auto result = AZStd::find_if(
|
||||
m_instanceFocusHierarchy.begin(), m_instanceFocusHierarchy.end(),
|
||||
[templateId](const InstanceOptionalReference& instance)
|
||||
[&, templateId](const AZ::EntityId& containerEntityId)
|
||||
{
|
||||
InstanceOptionalReference instance = GetReferenceFromContainerEntityId(containerEntityId);
|
||||
return (instance->get().GetTemplateId() == templateId);
|
||||
}
|
||||
);
|
||||
@@ -336,10 +338,17 @@ namespace AzToolsFramework::Prefab
|
||||
|
||||
AZStd::list<InstanceOptionalReference> instanceFocusList;
|
||||
|
||||
InstanceOptionalReference currentInstance = m_focusedInstance;
|
||||
InstanceOptionalReference currentInstance = GetReferenceFromContainerEntityId(m_focusedInstanceContainerEntityId);
|
||||
while (currentInstance.has_value())
|
||||
{
|
||||
m_instanceFocusHierarchy.emplace_back(currentInstance);
|
||||
if (currentInstance->get().GetParentInstance().has_value())
|
||||
{
|
||||
m_instanceFocusHierarchy.emplace_back(currentInstance->get().GetContainerEntityId());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_instanceFocusHierarchy.emplace_back(AZ::EntityId());
|
||||
}
|
||||
|
||||
currentInstance = currentInstance->get().GetParentInstance();
|
||||
}
|
||||
@@ -357,42 +366,48 @@ namespace AzToolsFramework::Prefab
|
||||
size_t index = 0;
|
||||
size_t maxIndex = m_instanceFocusHierarchy.size() - 1;
|
||||
|
||||
for (const InstanceOptionalReference& instance : m_instanceFocusHierarchy)
|
||||
for (const AZ::EntityId containerEntityId : m_instanceFocusHierarchy)
|
||||
{
|
||||
AZStd::string prefabName;
|
||||
|
||||
if (index < maxIndex)
|
||||
InstanceOptionalReference instance = GetReferenceFromContainerEntityId(containerEntityId);
|
||||
if (instance.has_value())
|
||||
{
|
||||
// Get the filename without the extension (stem).
|
||||
prefabName = instance->get().GetTemplateSourcePath().Stem().Native();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get the full filename.
|
||||
prefabName = instance->get().GetTemplateSourcePath().Filename().Native();
|
||||
}
|
||||
AZStd::string prefabName;
|
||||
|
||||
if (prefabSystemComponentInterface->IsTemplateDirty(instance->get().GetTemplateId()))
|
||||
{
|
||||
prefabName += "*";
|
||||
}
|
||||
if (index < maxIndex)
|
||||
{
|
||||
// Get the filename without the extension (stem).
|
||||
prefabName = instance->get().GetTemplateSourcePath().Stem().Native();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get the full filename.
|
||||
prefabName = instance->get().GetTemplateSourcePath().Filename().Native();
|
||||
}
|
||||
|
||||
m_instanceFocusPath.Append(prefabName);
|
||||
if (prefabSystemComponentInterface->IsTemplateDirty(instance->get().GetTemplateId()))
|
||||
{
|
||||
prefabName += "*";
|
||||
}
|
||||
|
||||
m_instanceFocusPath.Append(prefabName);
|
||||
}
|
||||
|
||||
++index;
|
||||
}
|
||||
}
|
||||
|
||||
void PrefabFocusHandler::OpenInstanceContainers(const AZStd::vector<InstanceOptionalReference>& instances) const
|
||||
void PrefabFocusHandler::OpenInstanceContainers(const AZStd::vector<AZ::EntityId>& instances) const
|
||||
{
|
||||
// If this is called outside the Editor, this interface won't be initialized.
|
||||
if (!m_containerEntityInterface)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (const InstanceOptionalReference& instance : instances)
|
||||
|
||||
for (const AZ::EntityId containerEntityId : instances)
|
||||
{
|
||||
InstanceOptionalReference instance = GetReferenceFromContainerEntityId(containerEntityId);
|
||||
|
||||
if (instance.has_value())
|
||||
{
|
||||
m_containerEntityInterface->SetContainerOpen(instance->get().GetContainerEntityId(), true);
|
||||
@@ -400,7 +415,7 @@ namespace AzToolsFramework::Prefab
|
||||
}
|
||||
}
|
||||
|
||||
void PrefabFocusHandler::CloseInstanceContainers(const AZStd::vector<InstanceOptionalReference>& instances) const
|
||||
void PrefabFocusHandler::CloseInstanceContainers(const AZStd::vector<AZ::EntityId>& instances) const
|
||||
{
|
||||
// If this is called outside the Editor, this interface won't be initialized.
|
||||
if (!m_containerEntityInterface)
|
||||
@@ -408,8 +423,10 @@ namespace AzToolsFramework::Prefab
|
||||
return;
|
||||
}
|
||||
|
||||
for (const InstanceOptionalReference& instance : instances)
|
||||
for (const AZ::EntityId containerEntityId : instances)
|
||||
{
|
||||
InstanceOptionalReference instance = GetReferenceFromContainerEntityId(containerEntityId);
|
||||
|
||||
if (instance.has_value())
|
||||
{
|
||||
m_containerEntityInterface->SetContainerOpen(instance->get().GetContainerEntityId(), false);
|
||||
@@ -417,4 +434,22 @@ namespace AzToolsFramework::Prefab
|
||||
}
|
||||
}
|
||||
|
||||
InstanceOptionalReference PrefabFocusHandler::GetReferenceFromContainerEntityId(AZ::EntityId containerEntityId) const
|
||||
{
|
||||
if (!containerEntityId.IsValid())
|
||||
{
|
||||
PrefabEditorEntityOwnershipInterface* prefabEditorEntityOwnershipInterface =
|
||||
AZ::Interface<PrefabEditorEntityOwnershipInterface>::Get();
|
||||
|
||||
if (!prefabEditorEntityOwnershipInterface)
|
||||
{
|
||||
return AZStd::nullopt;
|
||||
}
|
||||
|
||||
return prefabEditorEntityOwnershipInterface->GetRootPrefabInstance();
|
||||
}
|
||||
|
||||
return m_instanceEntityMapperInterface->FindOwningInstance(containerEntityId);
|
||||
}
|
||||
|
||||
} // namespace AzToolsFramework::Prefab
|
||||
|
||||
@@ -73,16 +73,19 @@ namespace AzToolsFramework::Prefab
|
||||
void RefreshInstanceFocusList();
|
||||
void RefreshInstanceFocusPath();
|
||||
|
||||
void OpenInstanceContainers(const AZStd::vector<InstanceOptionalReference>& instances) const;
|
||||
void CloseInstanceContainers(const AZStd::vector<InstanceOptionalReference>& instances) const;
|
||||
void OpenInstanceContainers(const AZStd::vector<AZ::EntityId>& instances) const;
|
||||
void CloseInstanceContainers(const AZStd::vector<AZ::EntityId>& instances) const;
|
||||
|
||||
//! The instance the editor is currently focusing on.
|
||||
InstanceOptionalReference m_focusedInstance;
|
||||
InstanceOptionalReference GetReferenceFromContainerEntityId(AZ::EntityId containerEntityId) const;
|
||||
|
||||
//! The EntityId of the prefab container entity for the instance the editor is currently focusing on.
|
||||
AZ::EntityId m_focusedInstanceContainerEntityId = AZ::EntityId();
|
||||
//! The templateId of the focused instance.
|
||||
TemplateId m_focusedTemplateId;
|
||||
//! The list of instances going from the root (index 0) to the focused instance.
|
||||
AZStd::vector<InstanceOptionalReference> m_instanceFocusHierarchy;
|
||||
//! A path containing the names of the containers in the instance focus hierarchy, separated with a /.
|
||||
//! The list of instances going from the root (index 0) to the focused instance,
|
||||
//! referenced by their prefab container's EntityId.
|
||||
AZStd::vector<AZ::EntityId> m_instanceFocusHierarchy;
|
||||
//! A path containing the filenames of the instances in the focus hierarchy, separated with a /.
|
||||
AZ::IO::Path m_instanceFocusPath;
|
||||
|
||||
ContainerEntityInterface* m_containerEntityInterface = nullptr;
|
||||
|
||||
+28
-5
@@ -527,8 +527,8 @@ namespace AzToolsFramework
|
||||
m_errorButton = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void PropertyAssetCtrl::UpdateErrorButton(const AZStd::string& errorLog)
|
||||
|
||||
void PropertyAssetCtrl::UpdateErrorButton()
|
||||
{
|
||||
if (m_errorButton)
|
||||
{
|
||||
@@ -543,12 +543,17 @@ namespace AzToolsFramework
|
||||
m_errorButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
m_errorButton->setFixedSize(QSize(16, 16));
|
||||
m_errorButton->setMouseTracking(true);
|
||||
m_errorButton->setIcon(QIcon("Icons/PropertyEditor/error_icon.png"));
|
||||
m_errorButton->setIcon(QIcon(":/PropertyEditor/Resources/error_icon.png"));
|
||||
m_errorButton->setToolTip("Show Errors");
|
||||
|
||||
// Insert the error button after the asset label
|
||||
qobject_cast<QHBoxLayout*>(layout())->insertWidget(1, m_errorButton);
|
||||
}
|
||||
}
|
||||
|
||||
void PropertyAssetCtrl::UpdateErrorButtonWithLog(const AZStd::string& errorLog)
|
||||
{
|
||||
UpdateErrorButton();
|
||||
|
||||
// Connect pressed to opening the error dialog
|
||||
// Must capture this for call to QObject::connect
|
||||
@@ -587,6 +592,21 @@ namespace AzToolsFramework
|
||||
logDialog->show();
|
||||
});
|
||||
}
|
||||
|
||||
void PropertyAssetCtrl::UpdateErrorButtonWithMessage(const AZStd::string& message)
|
||||
{
|
||||
UpdateErrorButton();
|
||||
|
||||
connect(m_errorButton, &QPushButton::clicked, this, [this, message]() {
|
||||
QMessageBox::critical(nullptr, "Error", message.c_str());
|
||||
|
||||
// Without this, the error button would maintain focus after clicking, which left the red error icon in a blue-highlighted state
|
||||
if (parentWidget())
|
||||
{
|
||||
parentWidget()->setFocus();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void PropertyAssetCtrl::ClearAssetInternal()
|
||||
{
|
||||
@@ -960,7 +980,6 @@ namespace AzToolsFramework
|
||||
else
|
||||
{
|
||||
const AZ::Data::AssetId assetID = GetCurrentAssetID();
|
||||
m_currentAssetHint = "";
|
||||
|
||||
AZ::Outcome<AssetSystem::JobInfoContainer> jobOutcome = AZ::Failure();
|
||||
AssetSystemJobRequestBus::BroadcastResult(jobOutcome, &AssetSystemJobRequestBus::Events::GetAssetJobsInfoByAssetID, assetID, false, false);
|
||||
@@ -1018,7 +1037,7 @@ namespace AzToolsFramework
|
||||
// In case of failure, render failure icon
|
||||
case AssetSystem::JobStatus::Failed:
|
||||
{
|
||||
UpdateErrorButton(errorLog);
|
||||
UpdateErrorButtonWithLog(errorLog);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1043,6 +1062,10 @@ namespace AzToolsFramework
|
||||
m_currentAssetHint = assetPath;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateErrorButtonWithMessage(AZStd::string::format("Asset is missing.\n\nID: %s\nHint:%s", assetID.ToString<AZStd::string>().c_str(), GetCurrentAssetHint().c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
// Get the asset file name
|
||||
|
||||
+3
-1
@@ -168,7 +168,9 @@ namespace AzToolsFramework
|
||||
|
||||
bool IsCorrectMimeData(const QMimeData* pData, AZ::Data::AssetId* pAssetId = nullptr, AZ::Data::AssetType* pAssetType = nullptr) const;
|
||||
void ClearErrorButton();
|
||||
void UpdateErrorButton(const AZStd::string& errorLog);
|
||||
void UpdateErrorButton();
|
||||
void UpdateErrorButtonWithLog(const AZStd::string& errorLog);
|
||||
void UpdateErrorButtonWithMessage(const AZStd::string& message);
|
||||
virtual const AZStd::string GetFolderSelection() const { return AZStd::string(); }
|
||||
virtual void SetFolderSelection(const AZStd::string& /* folderPath */) {}
|
||||
virtual void ClearAssetInternal();
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzFramework/Render/IntersectorInterface.h>
|
||||
#include <AzToolsFramework/Viewport/ViewportMessages.h>
|
||||
|
||||
namespace AzToolsFramework
|
||||
@@ -62,4 +63,33 @@ namespace AzToolsFramework
|
||||
|
||||
return circleBoundWidth;
|
||||
}
|
||||
|
||||
AZ::Vector3 FindClosestPickIntersection(
|
||||
AzFramework::ViewportId viewportId, const AzFramework::ScreenPoint& screenPoint, const float rayLength, const float defaultDistance)
|
||||
{
|
||||
using AzToolsFramework::ViewportInteraction::ViewportInteractionRequestBus;
|
||||
AzToolsFramework::ViewportInteraction::ProjectedViewportRay viewportRay{};
|
||||
ViewportInteractionRequestBus::EventResult(
|
||||
viewportRay, viewportId, &ViewportInteractionRequestBus::Events::ViewportScreenToWorldRay, screenPoint);
|
||||
|
||||
AzFramework::RenderGeometry::RayRequest ray;
|
||||
ray.m_startWorldPosition = viewportRay.origin;
|
||||
ray.m_endWorldPosition = viewportRay.origin + viewportRay.direction * rayLength;
|
||||
ray.m_onlyVisible = true;
|
||||
|
||||
AzFramework::RenderGeometry::RayResult renderGeometryIntersectionResult;
|
||||
AzFramework::RenderGeometry::IntersectorBus::EventResult(
|
||||
renderGeometryIntersectionResult, AzToolsFramework::GetEntityContextId(),
|
||||
&AzFramework::RenderGeometry::IntersectorBus::Events::RayIntersect, ray);
|
||||
|
||||
// attempt a ray intersection with any visible mesh and return the intersection position if successful
|
||||
if (renderGeometryIntersectionResult)
|
||||
{
|
||||
return renderGeometryIntersectionResult.m_worldPosition;
|
||||
}
|
||||
else
|
||||
{
|
||||
return viewportRay.origin + viewportRay.direction * defaultDistance;
|
||||
}
|
||||
}
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
@@ -334,6 +334,12 @@ namespace AzToolsFramework
|
||||
return entityContextId;
|
||||
}
|
||||
|
||||
//! Performs an intersection test against meshes in the scene, if there is a hit (the ray intersects
|
||||
//! a mesh), that position is returned, otherwise a point projected defaultDistance from the
|
||||
//! origin of the ray will be returned.
|
||||
AZ::Vector3 FindClosestPickIntersection(
|
||||
AzFramework::ViewportId viewportId, const AzFramework::ScreenPoint& screenPoint, float rayLength, float defaultDistance);
|
||||
|
||||
//! Maps a mouse interaction event to a ClickDetector event.
|
||||
//! @note Function only cares about up or down events, all other events are mapped to Nil (ignored).
|
||||
AzFramework::ClickDetector::ClickEvent ClickDetectorEventFromViewportInteraction(
|
||||
|
||||
-3
@@ -18,9 +18,6 @@
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
// default ray length for picking in the viewport
|
||||
static const float EditorPickRayLength = 1000.0f;
|
||||
|
||||
AZ::Vector3 CalculateCenterOffset(const AZ::EntityId entityId, const EditorTransformComponentSelectionRequests::Pivot pivot)
|
||||
{
|
||||
if (Centered(pivot))
|
||||
|
||||
+3
@@ -26,6 +26,9 @@ namespace AzFramework
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
//! Default ray length for picking in the viewport.
|
||||
inline constexpr float EditorPickRayLength = 1000.0f;
|
||||
|
||||
//! Is the pivot at the center of the object (middle of extents) or at the
|
||||
//! exported authored object root position.
|
||||
inline bool Centered(const EditorTransformComponentSelectionRequests::Pivot pivot)
|
||||
|
||||
+15
-2
@@ -27,6 +27,7 @@
|
||||
#include <AzToolsFramework/Manipulators/ScaleManipulators.h>
|
||||
#include <AzToolsFramework/Manipulators/TranslationManipulators.h>
|
||||
#include <AzToolsFramework/Maths/TransformUtils.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabFocusPublicInterface.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabFocusInterface.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabFocusPublicInterface.h>
|
||||
#include <AzToolsFramework/ToolsComponents/EditorLockComponentBus.h>
|
||||
@@ -1014,6 +1015,15 @@ namespace AzToolsFramework
|
||||
ToolsApplicationNotificationBus::Broadcast(&ToolsApplicationNotificationBus::Events::InvalidatePropertyDisplay, Refresh_Values);
|
||||
}
|
||||
|
||||
// leaves focus mode by focusing on the parent of the current perfab in the entity outliner
|
||||
static void LeaveFocusMode()
|
||||
{
|
||||
if (auto prefabFocusPublicInterface = AZ::Interface<Prefab::PrefabFocusPublicInterface>::Get())
|
||||
{
|
||||
prefabFocusPublicInterface->FocusOnParentOfFocusedPrefab(GetEntityContextId());
|
||||
}
|
||||
}
|
||||
|
||||
EditorTransformComponentSelection::EditorTransformComponentSelection(const EditorVisibleEntityDataCache* entityDataCache)
|
||||
: m_entityDataCache(entityDataCache)
|
||||
{
|
||||
@@ -3674,7 +3684,8 @@ namespace AzToolsFramework
|
||||
case ViewportEditorMode::Focus:
|
||||
{
|
||||
ViewportUi::ViewportUiRequestBus::Event(
|
||||
ViewportUi::DefaultViewportId, &ViewportUi::ViewportUiRequestBus::Events::CreateViewportBorder, "Focus Mode");
|
||||
ViewportUi::DefaultViewportId, &ViewportUi::ViewportUiRequestBus::Events::CreateViewportBorder, "Focus Mode",
|
||||
LeaveFocusMode);
|
||||
}
|
||||
break;
|
||||
case ViewportEditorMode::Default:
|
||||
@@ -3703,12 +3714,14 @@ namespace AzToolsFramework
|
||||
if (editorModeState.IsModeActive(ViewportEditorMode::Focus))
|
||||
{
|
||||
ViewportUi::ViewportUiRequestBus::Event(
|
||||
ViewportUi::DefaultViewportId, &ViewportUi::ViewportUiRequestBus::Events::CreateViewportBorder, "Focus Mode");
|
||||
ViewportUi::DefaultViewportId, &ViewportUi::ViewportUiRequestBus::Events::CreateViewportBorder, "Focus Mode",
|
||||
LeaveFocusMode);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ViewportEditorMode::Focus:
|
||||
{
|
||||
|
||||
ViewportUi::ViewportUiRequestBus::Event(
|
||||
ViewportUi::DefaultViewportId, &ViewportUi::ViewportUiRequestBus::Events::RemoveViewportBorder);
|
||||
}
|
||||
|
||||
@@ -21,6 +21,9 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
{
|
||||
const static int HighlightBorderSize = 5;
|
||||
const static char* HighlightBorderColor = "#4A90E2";
|
||||
const static int HighlightBorderBackButtonMargin = 5;
|
||||
const static int HighlightBorderBackButtonIconSize = 20;
|
||||
const static char* HighlightBorderBackButtonIconFile = "X_axis.svg";
|
||||
|
||||
static void UnparentWidgets(ViewportUiElementIdInfoLookup& viewportUiElementIdInfoLookup)
|
||||
{
|
||||
@@ -62,6 +65,7 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
, m_fullScreenLayout(&m_uiOverlay)
|
||||
, m_uiOverlayLayout()
|
||||
, m_viewportBorderText(&m_uiOverlay)
|
||||
, m_viewportBorderBackButton(&m_uiOverlay)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -291,7 +295,8 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
return false;
|
||||
}
|
||||
|
||||
void ViewportUiDisplay::CreateViewportBorder(const AZStd::string& borderTitle)
|
||||
void ViewportUiDisplay::CreateViewportBorder(
|
||||
const AZStd::string& borderTitle, AZStd::optional<ViewportUiBackButtonCallback> backButtonCallback)
|
||||
{
|
||||
const AZStd::string styleSheet = AZStd::string::format(
|
||||
"border: %dpx solid %s; border-top: %dpx solid %s;", HighlightBorderSize, HighlightBorderColor, ViewportUiTopBorderSize,
|
||||
@@ -302,6 +307,10 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
HighlightBorderSize + ViewportUiOverlayMargin, HighlightBorderSize + ViewportUiOverlayMargin);
|
||||
m_viewportBorderText.setVisible(true);
|
||||
m_viewportBorderText.setText(borderTitle.c_str());
|
||||
|
||||
// only display the back button if a callback was provided
|
||||
m_viewportBorderBackButtonCallback = backButtonCallback;
|
||||
m_viewportBorderBackButton.setVisible(m_viewportBorderBackButtonCallback.has_value());
|
||||
}
|
||||
|
||||
void ViewportUiDisplay::RemoveViewportBorder()
|
||||
@@ -311,6 +320,8 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
m_uiOverlayLayout.setContentsMargins(
|
||||
ViewportUiOverlayMargin, ViewportUiOverlayMargin + ViewportUiOverlayTopMarginPadding, ViewportUiOverlayMargin,
|
||||
ViewportUiOverlayMargin);
|
||||
m_viewportBorderBackButtonCallback.reset();
|
||||
m_viewportBorderBackButton.setVisible(false);
|
||||
}
|
||||
|
||||
void ViewportUiDisplay::PositionViewportUiElementFromWorldSpace(ViewportUiElementId elementId, const AZ::Vector3& pos)
|
||||
@@ -347,6 +358,8 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
|
||||
void ViewportUiDisplay::InitializeUiOverlay()
|
||||
{
|
||||
AZStd::string styleSheet;
|
||||
|
||||
m_uiMainWindow.setObjectName(QString("ViewportUiWindow"));
|
||||
ConfigureWindowForViewportUi(&m_uiMainWindow);
|
||||
m_uiMainWindow.setVisible(false);
|
||||
@@ -361,11 +374,37 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
m_fullScreenLayout.addLayout(&m_uiOverlayLayout, 0, 0, 1, 1);
|
||||
|
||||
// format the label which will appear on top of the highlight border
|
||||
AZStd::string styleSheet = AZStd::string::format("background-color: %s; border: none;", HighlightBorderColor);
|
||||
styleSheet = AZStd::string::format("background-color: %s; border: none;", HighlightBorderColor);
|
||||
m_viewportBorderText.setStyleSheet(styleSheet.c_str());
|
||||
m_viewportBorderText.setFixedHeight(ViewportUiTopBorderSize);
|
||||
m_viewportBorderText.setVisible(false);
|
||||
m_fullScreenLayout.addWidget(&m_viewportBorderText, 0, 0, Qt::AlignTop | Qt::AlignHCenter);
|
||||
|
||||
// format the back button which will appear in the top right of the highlight border
|
||||
styleSheet = AZStd::string::format(
|
||||
"border: 0px; padding-left: %dpx; padding-right: %dpx", HighlightBorderBackButtonMargin, HighlightBorderBackButtonMargin);
|
||||
m_viewportBorderBackButton.setStyleSheet(styleSheet.c_str());
|
||||
m_viewportBorderBackButton.setVisible(false);
|
||||
QIcon backButtonIcon(QString(AZStd::string::format(":/stylesheet/img/UI20/toolbar/%s", HighlightBorderBackButtonIconFile).c_str()));
|
||||
m_viewportBorderBackButton.setIcon(backButtonIcon);
|
||||
m_viewportBorderBackButton.setIconSize(QSize(HighlightBorderBackButtonIconSize, HighlightBorderBackButtonIconSize));
|
||||
|
||||
// setup the handler for the back button to call the user provided callback (if any)
|
||||
QObject::connect(
|
||||
&m_viewportBorderBackButton, &QPushButton::clicked,
|
||||
[this]()
|
||||
{
|
||||
if (m_viewportBorderBackButtonCallback.has_value())
|
||||
{
|
||||
// we need to swap out the existing back button callback because it will be reset in RemoveViewportBorder()
|
||||
// so preserve the lifetime with this temporary callback until after the call to RemoveViewportBorder()
|
||||
AZStd::optional<ViewportUiBackButtonCallback> backButtonCallback;
|
||||
m_viewportBorderBackButtonCallback.swap(backButtonCallback);
|
||||
RemoveViewportBorder();
|
||||
(*backButtonCallback)();
|
||||
}
|
||||
});
|
||||
m_fullScreenLayout.addWidget(&m_viewportBorderBackButton, 0, 0, Qt::AlignTop | Qt::AlignRight);
|
||||
}
|
||||
|
||||
void ViewportUiDisplay::PrepareWidgetForViewportUi(QPointer<QWidget> widget)
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <QLabel>
|
||||
#include <QMainWindow>
|
||||
#include <QPointer>
|
||||
#include <QPushButton>
|
||||
|
||||
AZ_PUSH_DISABLE_WARNING(4251, "-Wunknown-warning-option")
|
||||
#include <QGridLayout>
|
||||
@@ -89,7 +90,7 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
AZStd::shared_ptr<QWidget> GetViewportUiElement(ViewportUiElementId elementId);
|
||||
bool IsViewportUiElementVisible(ViewportUiElementId elementId);
|
||||
|
||||
void CreateViewportBorder(const AZStd::string& borderTitle);
|
||||
void CreateViewportBorder(const AZStd::string& borderTitle, AZStd::optional<ViewportUiBackButtonCallback> backButtonCallback);
|
||||
void RemoveViewportBorder();
|
||||
|
||||
private:
|
||||
@@ -113,7 +114,10 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
QWidget m_uiOverlay; //!< The UI Overlay which displays Viewport UI Elements.
|
||||
QGridLayout m_fullScreenLayout; //!< The layout which extends across the full screen.
|
||||
ViewportUiDisplayLayout m_uiOverlayLayout; //!< The layout used for optionally anchoring Viewport UI Elements.
|
||||
QLabel m_viewportBorderText; //!< The text used for the viewport border.
|
||||
QLabel m_viewportBorderText; //!< The text used for the viewport highlight border.
|
||||
QPushButton m_viewportBorderBackButton; //!< The button to return from the viewport highlight border (only displayed if callback provided).
|
||||
AZStd::optional<ViewportUiBackButtonCallback>
|
||||
m_viewportBorderBackButtonCallback; //!< The optional callback for when the viewport highlight border back button is pressed.
|
||||
|
||||
QWidget* m_renderOverlay;
|
||||
QPointer<QWidget> m_fullScreenWidget; //!< Reference to the widget attached to m_fullScreenLayout if any.
|
||||
|
||||
@@ -240,9 +240,10 @@ namespace AzToolsFramework::ViewportUi
|
||||
}
|
||||
}
|
||||
|
||||
void ViewportUiManager::CreateViewportBorder(const AZStd::string& borderTitle)
|
||||
void ViewportUiManager::CreateViewportBorder(
|
||||
const AZStd::string& borderTitle, AZStd::optional<ViewportUiBackButtonCallback> backButtonCallback)
|
||||
{
|
||||
m_viewportUi->CreateViewportBorder(borderTitle);
|
||||
m_viewportUi->CreateViewportBorder(borderTitle, backButtonCallback);
|
||||
}
|
||||
|
||||
void ViewportUiManager::RemoveViewportBorder()
|
||||
|
||||
@@ -50,7 +50,8 @@ namespace AzToolsFramework::ViewportUi
|
||||
void RegisterTextFieldCallback(TextFieldId textFieldId, AZ::Event<AZStd::string>::Handler& handler) override;
|
||||
void RemoveTextField(TextFieldId textFieldId) override;
|
||||
void SetTextFieldVisible(TextFieldId textFieldId, bool visible) override;
|
||||
void CreateViewportBorder(const AZStd::string& borderTitle) override;
|
||||
void CreateViewportBorder(
|
||||
const AZStd::string& borderTitle, AZStd::optional<ViewportUiBackButtonCallback> backButtonCallback) override;
|
||||
void RemoveViewportBorder() override;
|
||||
void PressButton(ClusterId clusterId, ButtonId buttonId) override;
|
||||
void PressButton(SwitcherId switcherId, ButtonId buttonId) override;
|
||||
|
||||
@@ -22,6 +22,9 @@ namespace AzToolsFramework::ViewportUi
|
||||
using SwitcherId = IdType<struct SwitcherIdType>;
|
||||
using TextFieldId = IdType<struct TextFieldIdType>;
|
||||
|
||||
//! Callback function for viewport UI back button.
|
||||
using ViewportUiBackButtonCallback = AZStd::function<void()>;
|
||||
|
||||
inline const ViewportUiElementId InvalidViewportUiElementId = ViewportUiElementId(0);
|
||||
inline const ButtonId InvalidButtonId = ButtonId(0);
|
||||
inline const ClusterId InvalidClusterId = ClusterId(0);
|
||||
@@ -95,9 +98,9 @@ namespace AzToolsFramework::ViewportUi
|
||||
virtual void RemoveTextField(TextFieldId textFieldId) = 0;
|
||||
//! Sets the visibility of the text field.
|
||||
virtual void SetTextFieldVisible(TextFieldId textFieldId, bool visible) = 0;
|
||||
//! Create the highlight border for Component Mode.
|
||||
virtual void CreateViewportBorder(const AZStd::string& borderTitle) = 0;
|
||||
//! Remove the highlight border for Component Mode.
|
||||
//! Create the highlight border with optional back button to exit the given editor mode.
|
||||
virtual void CreateViewportBorder(const AZStd::string& borderTitle, AZStd::optional<ViewportUiBackButtonCallback> backButtonCallback) = 0;
|
||||
//! Remove the highlight border.
|
||||
virtual void RemoveViewportBorder() = 0;
|
||||
//! Invoke a button press on a cluster.
|
||||
virtual void PressButton(ClusterId clusterId, ButtonId buttonId) = 0;
|
||||
|
||||
@@ -106,7 +106,9 @@ namespace UnitTest
|
||||
inline static const char* Passenger2EntityName = "Passenger2";
|
||||
};
|
||||
|
||||
TEST_F(PrefabFocusTests, PrefabFocus_FocusOnOwningPrefab_RootContainer)
|
||||
// Test was disabled because the implementation of GetFocusedPrefabInstance now relies on the Prefab EOS,
|
||||
// which is not used by our test environment. This can be restored once Instance handles are implemented.
|
||||
TEST_F(PrefabFocusTests, DISABLED_PrefabFocus_FocusOnOwningPrefab_RootContainer)
|
||||
{
|
||||
// Verify FocusOnOwningPrefab works when passing the container entity of the root prefab.
|
||||
{
|
||||
@@ -121,7 +123,9 @@ namespace UnitTest
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(PrefabFocusTests, PrefabFocus_FocusOnOwningPrefab_RootEntity)
|
||||
// Test was disabled because the implementation of GetFocusedPrefabInstance now relies on the Prefab EOS,
|
||||
// which is not used by our test environment. This can be restored once Instance handles are implemented.
|
||||
TEST_F(PrefabFocusTests, DISABLED_PrefabFocus_FocusOnOwningPrefab_RootEntity)
|
||||
{
|
||||
// Verify FocusOnOwningPrefab works when passing a nested entity of the root prefab.
|
||||
{
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <GemCatalog/GemCatalogScreen.h>
|
||||
#include <GemRepo/GemRepoScreen.h>
|
||||
#include <ProjectUtils.h>
|
||||
#include <DownloadController.h>
|
||||
|
||||
#include <QDialogButtonBox>
|
||||
#include <QHBoxLayout>
|
||||
|
||||
@@ -73,13 +73,25 @@ namespace O3DE::ProjectManager
|
||||
emit GemDownloadProgress(m_gemNames.front(), bytesDownloaded, totalBytes);
|
||||
}
|
||||
|
||||
void DownloadController::HandleResults(const QString& result)
|
||||
void DownloadController::HandleResults(const QString& result, const QString& detailedError)
|
||||
{
|
||||
bool succeeded = true;
|
||||
|
||||
if (!result.isEmpty())
|
||||
{
|
||||
QMessageBox::critical(nullptr, tr("Gem download"), result);
|
||||
if (!detailedError.isEmpty())
|
||||
{
|
||||
QMessageBox gemDownloadError;
|
||||
gemDownloadError.setIcon(QMessageBox::Critical);
|
||||
gemDownloadError.setWindowTitle(tr("Gem download"));
|
||||
gemDownloadError.setText(result);
|
||||
gemDownloadError.setDetailedText(detailedError);
|
||||
gemDownloadError.exec();
|
||||
}
|
||||
else
|
||||
{
|
||||
QMessageBox::critical(nullptr, tr("Gem download"), result);
|
||||
}
|
||||
succeeded = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ namespace O3DE::ProjectManager
|
||||
}
|
||||
public slots:
|
||||
void UpdateUIProgress(int bytesDownloaded, int totalBytes);
|
||||
void HandleResults(const QString& result);
|
||||
void HandleResults(const QString& result, const QString& detailedError);
|
||||
|
||||
signals:
|
||||
void StartGemDownload(const QString& gemName);
|
||||
|
||||
@@ -24,16 +24,16 @@ namespace O3DE::ProjectManager
|
||||
{
|
||||
emit UpdateProgress(bytesDownloaded, totalBytes);
|
||||
};
|
||||
AZ::Outcome<void, AZStd::string> gemInfoResult =
|
||||
AZ::Outcome<void, AZStd::pair<AZStd::string, AZStd::string>> gemInfoResult =
|
||||
PythonBindingsInterface::Get()->DownloadGem(m_gemName, gemDownloadProgress, /*force*/true);
|
||||
|
||||
if (gemInfoResult.IsSuccess())
|
||||
{
|
||||
emit Done("");
|
||||
emit Done("", "");
|
||||
}
|
||||
else
|
||||
{
|
||||
emit Done(tr("Gem download failed"));
|
||||
emit Done(gemInfoResult.GetError().first.c_str(), gemInfoResult.GetError().second.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace O3DE::ProjectManager
|
||||
|
||||
signals:
|
||||
void UpdateProgress(int bytesDownloaded, int totalBytes);
|
||||
void Done(QString result = "");
|
||||
void Done(QString result = "", QString detailedResult = "");
|
||||
|
||||
private:
|
||||
|
||||
|
||||
@@ -72,12 +72,7 @@ namespace O3DE::ProjectManager
|
||||
|
||||
bool EngineScreenCtrl::ContainsScreen(ProjectManagerScreen screen)
|
||||
{
|
||||
if (screen == m_engineSettingsScreen->GetScreenEnum() || screen == m_gemRepoScreen->GetScreenEnum())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return screen == m_engineSettingsScreen->GetScreenEnum() || screen == m_gemRepoScreen->GetScreenEnum();
|
||||
}
|
||||
|
||||
void EngineScreenCtrl::NotifyCurrentScreen()
|
||||
|
||||
@@ -7,25 +7,32 @@
|
||||
*/
|
||||
|
||||
#include <GemCatalog/GemCatalogHeaderWidget.h>
|
||||
#include <TagWidget.h>
|
||||
|
||||
#include <AzCore/std/functional.h>
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QMouseEvent>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QProgressBar>
|
||||
#include <TagWidget.h>
|
||||
#include <QMenu>
|
||||
#include <QLocale>
|
||||
#include <QMovie>
|
||||
#include <QPainter>
|
||||
#include <QPainterPath>
|
||||
|
||||
namespace O3DE::ProjectManager
|
||||
{
|
||||
CartOverlayWidget::CartOverlayWidget(GemModel* gemModel, DownloadController* downloadController, QWidget* parent)
|
||||
: QWidget(parent)
|
||||
GemCartWidget::GemCartWidget(GemModel* gemModel, DownloadController* downloadController, QWidget* parent)
|
||||
: QScrollArea(parent)
|
||||
, m_gemModel(gemModel)
|
||||
, m_downloadController(downloadController)
|
||||
{
|
||||
setObjectName("GemCatalogCart");
|
||||
setWidgetResizable(true);
|
||||
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
|
||||
|
||||
m_layout = new QVBoxLayout();
|
||||
m_layout->setSpacing(0);
|
||||
@@ -118,17 +125,15 @@ namespace O3DE::ProjectManager
|
||||
}
|
||||
return dependencies;
|
||||
});
|
||||
|
||||
setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog);
|
||||
}
|
||||
|
||||
CartOverlayWidget::~CartOverlayWidget()
|
||||
GemCartWidget::~GemCartWidget()
|
||||
{
|
||||
// disconnect from all download controller signals
|
||||
disconnect(m_downloadController, nullptr, this, nullptr);
|
||||
}
|
||||
|
||||
void CartOverlayWidget::CreateGemSection(const QString& singularTitle, const QString& pluralTitle, GetTagIndicesCallback getTagIndices)
|
||||
void GemCartWidget::CreateGemSection(const QString& singularTitle, const QString& pluralTitle, GetTagIndicesCallback getTagIndices)
|
||||
{
|
||||
QWidget* widget = new QWidget();
|
||||
widget->setFixedWidth(s_width);
|
||||
@@ -164,12 +169,12 @@ namespace O3DE::ProjectManager
|
||||
update();
|
||||
}
|
||||
|
||||
void CartOverlayWidget::OnCancelDownloadActivated(const QString& gemName)
|
||||
void GemCartWidget::OnCancelDownloadActivated(const QString& gemName)
|
||||
{
|
||||
m_downloadController->CancelGemDownload(gemName);
|
||||
}
|
||||
|
||||
void CartOverlayWidget::CreateDownloadSection()
|
||||
void GemCartWidget::CreateDownloadSection()
|
||||
{
|
||||
m_downloadSectionWidget = new QWidget();
|
||||
m_downloadSectionWidget->setFixedWidth(s_width);
|
||||
@@ -223,12 +228,12 @@ namespace O3DE::ProjectManager
|
||||
}
|
||||
|
||||
// connect to download controller data changed
|
||||
connect(m_downloadController, &DownloadController::GemDownloadAdded, this, &CartOverlayWidget::GemDownloadAdded);
|
||||
connect(m_downloadController, &DownloadController::GemDownloadRemoved, this, &CartOverlayWidget::GemDownloadRemoved);
|
||||
connect(m_downloadController, &DownloadController::GemDownloadProgress, this, &CartOverlayWidget::GemDownloadProgress);
|
||||
connect(m_downloadController, &DownloadController::GemDownloadAdded, this, &GemCartWidget::GemDownloadAdded);
|
||||
connect(m_downloadController, &DownloadController::GemDownloadRemoved, this, &GemCartWidget::GemDownloadRemoved);
|
||||
connect(m_downloadController, &DownloadController::GemDownloadProgress, this, &GemCartWidget::GemDownloadProgress);
|
||||
}
|
||||
|
||||
void CartOverlayWidget::GemDownloadAdded(const QString& gemName)
|
||||
void GemCartWidget::GemDownloadAdded(const QString& gemName)
|
||||
{
|
||||
// Containing widget for the current download item
|
||||
QWidget* newGemDownloadWidget = new QWidget();
|
||||
@@ -246,7 +251,7 @@ namespace O3DE::ProjectManager
|
||||
nameProgressLayout->addStretch();
|
||||
QLabel* cancelText = new QLabel(tr("<a href=\"%1\">Cancel</a>").arg(gemName), newGemDownloadWidget);
|
||||
cancelText->setTextInteractionFlags(Qt::LinksAccessibleByMouse);
|
||||
connect(cancelText, &QLabel::linkActivated, this, &CartOverlayWidget::OnCancelDownloadActivated);
|
||||
connect(cancelText, &QLabel::linkActivated, this, &GemCartWidget::OnCancelDownloadActivated);
|
||||
nameProgressLayout->addWidget(cancelText);
|
||||
downloadingGemLayout->addLayout(nameProgressLayout);
|
||||
|
||||
@@ -267,7 +272,7 @@ namespace O3DE::ProjectManager
|
||||
m_downloadingListWidget->show();
|
||||
}
|
||||
|
||||
void CartOverlayWidget::GemDownloadRemoved(const QString& gemName)
|
||||
void GemCartWidget::GemDownloadRemoved(const QString& gemName)
|
||||
{
|
||||
QWidget* gemToRemove = m_downloadingListWidget->findChild<QWidget*>(gemName);
|
||||
if (gemToRemove)
|
||||
@@ -289,7 +294,7 @@ namespace O3DE::ProjectManager
|
||||
}
|
||||
}
|
||||
|
||||
void CartOverlayWidget::GemDownloadProgress(const QString& gemName, int bytesDownloaded, int totalBytes)
|
||||
void GemCartWidget::GemDownloadProgress(const QString& gemName, int bytesDownloaded, int totalBytes)
|
||||
{
|
||||
QWidget* gemToUpdate = m_downloadingListWidget->findChild<QWidget*>(gemName);
|
||||
if (gemToUpdate)
|
||||
@@ -324,7 +329,7 @@ namespace O3DE::ProjectManager
|
||||
}
|
||||
}
|
||||
|
||||
QVector<Tag> CartOverlayWidget::GetTagsFromModelIndices(const QVector<QModelIndex>& gems) const
|
||||
QVector<Tag> GemCartWidget::GetTagsFromModelIndices(const QVector<QModelIndex>& gems) const
|
||||
{
|
||||
QVector<Tag> tags;
|
||||
tags.reserve(gems.size());
|
||||
@@ -349,7 +354,7 @@ namespace O3DE::ProjectManager
|
||||
iconButton->setFocusPolicy(Qt::NoFocus);
|
||||
iconButton->setIcon(QIcon(":/Summary.svg"));
|
||||
iconButton->setFixedSize(s_iconSize, s_iconSize);
|
||||
connect(iconButton, &QPushButton::clicked, this, &CartButton::ShowOverlay);
|
||||
connect(iconButton, &QPushButton::clicked, this, &CartButton::ShowGemCart);
|
||||
m_layout->addWidget(iconButton);
|
||||
|
||||
m_countLabel = new QLabel();
|
||||
@@ -362,7 +367,7 @@ namespace O3DE::ProjectManager
|
||||
m_dropDownButton->setFocusPolicy(Qt::NoFocus);
|
||||
m_dropDownButton->setIcon(QIcon(":/CarrotArrowDown.svg"));
|
||||
m_dropDownButton->setFixedSize(s_arrowDownIconSize, s_arrowDownIconSize);
|
||||
connect(m_dropDownButton, &QPushButton::clicked, this, &CartButton::ShowOverlay);
|
||||
connect(m_dropDownButton, &QPushButton::clicked, this, &CartButton::ShowGemCart);
|
||||
m_layout->addWidget(m_dropDownButton);
|
||||
|
||||
// Adjust the label text whenever the model gets updated.
|
||||
@@ -377,28 +382,28 @@ namespace O3DE::ProjectManager
|
||||
m_dropDownButton->setVisible(!toBeAdded.isEmpty() || !toBeRemoved.isEmpty());
|
||||
|
||||
// Automatically close the overlay window in case there are no gems to be activated or deactivated anymore.
|
||||
if (m_cartOverlay && toBeAdded.isEmpty() && toBeRemoved.isEmpty())
|
||||
if (m_gemCart && toBeAdded.isEmpty() && toBeRemoved.isEmpty())
|
||||
{
|
||||
m_cartOverlay->deleteLater();
|
||||
m_cartOverlay = nullptr;
|
||||
m_gemCart->deleteLater();
|
||||
m_gemCart = nullptr;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void CartButton::mousePressEvent([[maybe_unused]] QMouseEvent* event)
|
||||
{
|
||||
ShowOverlay();
|
||||
ShowGemCart();
|
||||
}
|
||||
|
||||
void CartButton::hideEvent(QHideEvent*)
|
||||
{
|
||||
if (m_cartOverlay)
|
||||
if (m_gemCart)
|
||||
{
|
||||
m_cartOverlay->hide();
|
||||
m_gemCart->hide();
|
||||
}
|
||||
}
|
||||
|
||||
void CartButton::ShowOverlay()
|
||||
void CartButton::ShowGemCart()
|
||||
{
|
||||
const QVector<QModelIndex> toBeAdded = m_gemModel->GatherGemsToBeAdded(/*includeDependencies=*/true);
|
||||
const QVector<QModelIndex> toBeRemoved = m_gemModel->GatherGemsToBeRemoved(/*includeDependencies=*/true);
|
||||
@@ -407,37 +412,33 @@ namespace O3DE::ProjectManager
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_cartOverlay)
|
||||
if (m_gemCart)
|
||||
{
|
||||
// Directly delete the former overlay before creating the new one.
|
||||
// Don't use deleteLater() here. This might overwrite the new overlay pointer
|
||||
// depending on the event queue.
|
||||
delete m_cartOverlay;
|
||||
delete m_gemCart;
|
||||
}
|
||||
|
||||
m_cartOverlay = new CartOverlayWidget(m_gemModel, m_downloadController, this);
|
||||
connect(m_cartOverlay, &QWidget::destroyed, this, [=]
|
||||
m_gemCart = new GemCartWidget(m_gemModel, m_downloadController, this);
|
||||
connect(m_gemCart, &QWidget::destroyed, this, [=]
|
||||
{
|
||||
// Reset the overlay pointer on destruction to prevent dangling pointers.
|
||||
m_cartOverlay = nullptr;
|
||||
m_gemCart = nullptr;
|
||||
// Tell header gem cart is no longer open
|
||||
UpdateGemCart(nullptr);
|
||||
});
|
||||
m_cartOverlay->show();
|
||||
m_gemCart->show();
|
||||
|
||||
const QPoint parentPos = m_dropDownButton->mapToParent(m_dropDownButton->pos());
|
||||
const QPoint globalPos = m_dropDownButton->mapToGlobal(m_dropDownButton->pos());
|
||||
const QPoint offset(-4, 10);
|
||||
m_cartOverlay->setGeometry(globalPos.x() - parentPos.x() - m_cartOverlay->width() + width() + offset.x(),
|
||||
globalPos.y() + offset.y(),
|
||||
m_cartOverlay->width(),
|
||||
m_cartOverlay->height());
|
||||
emit UpdateGemCart(m_gemCart);
|
||||
}
|
||||
|
||||
CartButton::~CartButton()
|
||||
{
|
||||
// Make sure the overlay window is automatically closed in case the gem catalog is destroyed.
|
||||
if (m_cartOverlay)
|
||||
if (m_gemCart)
|
||||
{
|
||||
m_cartOverlay->deleteLater();
|
||||
m_gemCart->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -514,6 +515,17 @@ namespace O3DE::ProjectManager
|
||||
|
||||
connect(m_downloadController, &DownloadController::GemDownloadAdded, this, &GemCatalogHeaderWidget::GemDownloadAdded);
|
||||
connect(m_downloadController, &DownloadController::GemDownloadRemoved, this, &GemCatalogHeaderWidget::GemDownloadRemoved);
|
||||
|
||||
connect(
|
||||
m_cartButton, &CartButton::UpdateGemCart, this,
|
||||
[this](QWidget* gemCart)
|
||||
{
|
||||
GemCartShown(gemCart);
|
||||
if (gemCart)
|
||||
{
|
||||
emit UpdateGemCart(gemCart);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void GemCatalogHeaderWidget::GemDownloadAdded(const QString& /*gemName*/)
|
||||
@@ -521,7 +533,7 @@ namespace O3DE::ProjectManager
|
||||
m_downloadSpinner->show();
|
||||
m_downloadLabel->show();
|
||||
m_downloadSpinnerMovie->start();
|
||||
m_cartButton->ShowOverlay();
|
||||
m_cartButton->ShowGemCart();
|
||||
}
|
||||
|
||||
void GemCatalogHeaderWidget::GemDownloadRemoved(const QString& /*gemName*/)
|
||||
@@ -534,8 +546,44 @@ namespace O3DE::ProjectManager
|
||||
}
|
||||
}
|
||||
|
||||
void GemCatalogHeaderWidget::GemCartShown(bool state)
|
||||
{
|
||||
m_showGemCart = state;
|
||||
repaint();
|
||||
}
|
||||
|
||||
void GemCatalogHeaderWidget::ReinitForProject()
|
||||
{
|
||||
m_filterLineEdit->setText({});
|
||||
}
|
||||
|
||||
void GemCatalogHeaderWidget::paintEvent([[maybe_unused]] QPaintEvent* event)
|
||||
{
|
||||
// Only show triangle when cart is shown
|
||||
if (!m_showGemCart)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const QPoint buttonPos = m_cartButton->pos();
|
||||
const QSize buttonSize = m_cartButton->size();
|
||||
|
||||
// Draw isosceles triangle with top point touching bottom of cartButton
|
||||
// Bottom aligned with header bottom and top of right panel
|
||||
const QPoint topPoint(buttonPos.x() + buttonSize.width() / 2, buttonPos.y() + buttonSize.height());
|
||||
const QPoint bottomLeftPoint(topPoint.x() - 20, height());
|
||||
const QPoint bottomRightPoint(topPoint.x() + 20, height());
|
||||
|
||||
QPainterPath trianglePath;
|
||||
trianglePath.moveTo(topPoint);
|
||||
trianglePath.lineTo(bottomLeftPoint);
|
||||
trianglePath.lineTo(bottomRightPoint);
|
||||
trianglePath.lineTo(topPoint);
|
||||
|
||||
QPainter painter(this);
|
||||
painter.setRenderHint(QPainter::Antialiasing, true);
|
||||
painter.setPen(Qt::NoPen);
|
||||
painter.fillPath(trianglePath, QBrush(QColor("#555555")));
|
||||
}
|
||||
|
||||
} // namespace O3DE::ProjectManager
|
||||
|
||||
@@ -14,8 +14,10 @@
|
||||
#include <GemCatalog/GemModel.h>
|
||||
#include <GemCatalog/GemSortFilterProxyModel.h>
|
||||
#include <TagWidget.h>
|
||||
#include <QFrame>
|
||||
#include <DownloadController.h>
|
||||
|
||||
#include <QFrame>
|
||||
#include <QScrollArea>
|
||||
#endif
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QPushButton)
|
||||
@@ -28,14 +30,14 @@ QT_FORWARD_DECLARE_CLASS(QMovie)
|
||||
|
||||
namespace O3DE::ProjectManager
|
||||
{
|
||||
class CartOverlayWidget
|
||||
: public QWidget
|
||||
class GemCartWidget
|
||||
: public QScrollArea
|
||||
{
|
||||
Q_OBJECT // AUTOMOC
|
||||
|
||||
public:
|
||||
CartOverlayWidget(GemModel* gemModel, DownloadController* downloadController, QWidget* parent = nullptr);
|
||||
~CartOverlayWidget();
|
||||
GemCartWidget(GemModel* gemModel, DownloadController* downloadController, QWidget* parent = nullptr);
|
||||
~GemCartWidget();
|
||||
|
||||
public slots:
|
||||
void GemDownloadAdded(const QString& gemName);
|
||||
@@ -68,7 +70,10 @@ namespace O3DE::ProjectManager
|
||||
public:
|
||||
CartButton(GemModel* gemModel, DownloadController* downloadController, QWidget* parent = nullptr);
|
||||
~CartButton();
|
||||
void ShowOverlay();
|
||||
void ShowGemCart();
|
||||
|
||||
signals:
|
||||
void UpdateGemCart(QWidget* gemCart);
|
||||
|
||||
private:
|
||||
void mousePressEvent(QMouseEvent* event) override;
|
||||
@@ -78,7 +83,7 @@ namespace O3DE::ProjectManager
|
||||
QHBoxLayout* m_layout = nullptr;
|
||||
QLabel* m_countLabel = nullptr;
|
||||
QPushButton* m_dropDownButton = nullptr;
|
||||
CartOverlayWidget* m_cartOverlay = nullptr;
|
||||
GemCartWidget* m_gemCart = nullptr;
|
||||
DownloadController* m_downloadController = nullptr;
|
||||
|
||||
inline constexpr static int s_iconSize = 24;
|
||||
@@ -99,11 +104,16 @@ namespace O3DE::ProjectManager
|
||||
public slots:
|
||||
void GemDownloadAdded(const QString& gemName);
|
||||
void GemDownloadRemoved(const QString& gemName);
|
||||
void GemCartShown(bool state = false);
|
||||
|
||||
signals:
|
||||
void AddGem();
|
||||
void OpenGemsRepo();
|
||||
void RefreshGems();
|
||||
void UpdateGemCart(QWidget* gemCart);
|
||||
|
||||
protected slots:
|
||||
void paintEvent(QPaintEvent* event) override;
|
||||
|
||||
private:
|
||||
AzQtComponents::SearchLineEdit* m_filterLineEdit = nullptr;
|
||||
@@ -113,5 +123,6 @@ namespace O3DE::ProjectManager
|
||||
QLabel* m_downloadLabel = nullptr;
|
||||
QMovie* m_downloadSpinnerMovie = nullptr;
|
||||
CartButton* m_cartButton = nullptr;
|
||||
bool m_showGemCart = false;
|
||||
};
|
||||
} // namespace O3DE::ProjectManager
|
||||
|
||||
@@ -8,6 +8,11 @@
|
||||
|
||||
#include <GemCatalog/GemCatalogScreen.h>
|
||||
#include <PythonBindingsInterface.h>
|
||||
#include <GemCatalog/GemCatalogHeaderWidget.h>
|
||||
#include <GemCatalog/GemFilterWidget.h>
|
||||
#include <GemCatalog/GemListView.h>
|
||||
#include <GemCatalog/GemInspector.h>
|
||||
#include <GemCatalog/GemModel.h>
|
||||
#include <GemCatalog/GemListHeaderWidget.h>
|
||||
#include <GemCatalog/GemSortFilterProxyModel.h>
|
||||
#include <GemCatalog/GemRequirementDialog.h>
|
||||
@@ -28,6 +33,7 @@
|
||||
#include <QFileDialog>
|
||||
#include <QMessageBox>
|
||||
#include <QHash>
|
||||
#include <QStackedWidget>
|
||||
|
||||
namespace O3DE::ProjectManager
|
||||
{
|
||||
@@ -51,9 +57,11 @@ namespace O3DE::ProjectManager
|
||||
vLayout->addWidget(m_headerWidget);
|
||||
|
||||
connect(m_gemModel, &GemModel::gemStatusChanged, this, &GemCatalogScreen::OnGemStatusChanged);
|
||||
connect(m_gemModel->GetSelectionModel(), &QItemSelectionModel::selectionChanged, this, [this]{ ShowInspector(); });
|
||||
connect(m_headerWidget, &GemCatalogHeaderWidget::RefreshGems, this, &GemCatalogScreen::Refresh);
|
||||
connect(m_headerWidget, &GemCatalogHeaderWidget::OpenGemsRepo, this, &GemCatalogScreen::HandleOpenGemRepo);
|
||||
connect(m_headerWidget, &GemCatalogHeaderWidget::AddGem, this, &GemCatalogScreen::OnAddGemClicked);
|
||||
connect(m_headerWidget, &GemCatalogHeaderWidget::UpdateGemCart, this, &GemCatalogScreen::UpdateAndShowGemCart);
|
||||
connect(m_downloadController, &DownloadController::Done, this, &GemCatalogScreen::OnGemDownloadResult);
|
||||
|
||||
QHBoxLayout* hLayout = new QHBoxLayout();
|
||||
@@ -61,8 +69,11 @@ namespace O3DE::ProjectManager
|
||||
vLayout->addLayout(hLayout);
|
||||
|
||||
m_gemListView = new GemListView(m_proxyModel, m_proxyModel->GetSelectionModel(), this);
|
||||
|
||||
m_rightPanelStack = new QStackedWidget(this);
|
||||
m_rightPanelStack->setFixedWidth(240);
|
||||
|
||||
m_gemInspector = new GemInspector(m_gemModel, this);
|
||||
m_gemInspector->setFixedWidth(240);
|
||||
|
||||
connect(m_gemInspector, &GemInspector::TagClicked, [=](const Tag& tag) { SelectGem(tag.id); });
|
||||
connect(m_gemInspector, &GemInspector::UpdateGem, this, &GemCatalogScreen::UpdateGem);
|
||||
@@ -85,7 +96,9 @@ namespace O3DE::ProjectManager
|
||||
|
||||
hLayout->addWidget(filterWidget);
|
||||
hLayout->addLayout(middleVLayout);
|
||||
hLayout->addWidget(m_gemInspector);
|
||||
|
||||
hLayout->addWidget(m_rightPanelStack);
|
||||
m_rightPanelStack->addWidget(m_gemInspector);
|
||||
|
||||
m_notificationsView = AZStd::make_unique<AzToolsFramework::ToastNotificationsView>(this, AZ_CRC("GemCatalogNotificationsView"));
|
||||
m_notificationsView->SetOffset(QPoint(10, 70));
|
||||
@@ -188,7 +201,7 @@ namespace O3DE::ProjectManager
|
||||
}
|
||||
|
||||
// add all the gem repos into the hash
|
||||
const AZ::Outcome<QVector<GemInfo>, AZStd::string>& allRepoGemInfosResult = PythonBindingsInterface::Get()->GetAllGemReposGemInfos();
|
||||
const AZ::Outcome<QVector<GemInfo>, AZStd::string>& allRepoGemInfosResult = PythonBindingsInterface::Get()->GetGemInfosForAllRepos();
|
||||
if (allRepoGemInfosResult.IsSuccess())
|
||||
{
|
||||
const QVector<GemInfo>& allRepoGemInfos = allRepoGemInfosResult.GetValue();
|
||||
@@ -303,6 +316,8 @@ namespace O3DE::ProjectManager
|
||||
QModelIndex proxyIndex = m_proxyModel->mapFromSource(modelIndex);
|
||||
m_proxyModel->GetSelectionModel()->setCurrentIndex(proxyIndex, QItemSelectionModel::ClearAndSelect);
|
||||
m_gemListView->scrollTo(proxyIndex);
|
||||
|
||||
ShowInspector();
|
||||
}
|
||||
|
||||
void GemCatalogScreen::UpdateGem(const QModelIndex& modelIndex)
|
||||
@@ -440,7 +455,7 @@ namespace O3DE::ProjectManager
|
||||
m_gemModel->AddGem(gemInfo);
|
||||
}
|
||||
|
||||
const AZ::Outcome<QVector<GemInfo>, AZStd::string>& allRepoGemInfosResult = PythonBindingsInterface::Get()->GetAllGemReposGemInfos();
|
||||
const AZ::Outcome<QVector<GemInfo>, AZStd::string>& allRepoGemInfosResult = PythonBindingsInterface::Get()->GetGemInfosForAllRepos();
|
||||
if (allRepoGemInfosResult.IsSuccess())
|
||||
{
|
||||
const QVector<GemInfo>& allRepoGemInfos = allRepoGemInfosResult.GetValue();
|
||||
@@ -496,6 +511,12 @@ namespace O3DE::ProjectManager
|
||||
}
|
||||
}
|
||||
|
||||
void GemCatalogScreen::ShowInspector()
|
||||
{
|
||||
m_rightPanelStack->setCurrentIndex(RightPanelWidgetOrder::Inspector);
|
||||
m_headerWidget->GemCartShown();
|
||||
}
|
||||
|
||||
GemCatalogScreen::EnableDisableGemsResult GemCatalogScreen::EnableDisableGemsForProject(const QString& projectPath)
|
||||
{
|
||||
IPythonBindings* pythonBindings = PythonBindingsInterface::Get();
|
||||
@@ -577,6 +598,18 @@ namespace O3DE::ProjectManager
|
||||
emit ChangeScreenRequest(ProjectManagerScreen::GemRepos);
|
||||
}
|
||||
|
||||
void GemCatalogScreen::UpdateAndShowGemCart(QWidget* cartWidget)
|
||||
{
|
||||
QWidget* previousCart = m_rightPanelStack->widget(RightPanelWidgetOrder::Cart);
|
||||
if (previousCart)
|
||||
{
|
||||
m_rightPanelStack->removeWidget(previousCart);
|
||||
}
|
||||
|
||||
m_rightPanelStack->insertWidget(RightPanelWidgetOrder::Cart, cartWidget);
|
||||
m_rightPanelStack->setCurrentIndex(RightPanelWidgetOrder::Cart);
|
||||
}
|
||||
|
||||
void GemCatalogScreen::OnGemDownloadResult(const QString& gemName, bool succeeded)
|
||||
{
|
||||
if (succeeded)
|
||||
|
||||
@@ -12,18 +12,24 @@
|
||||
#include <ScreenWidget.h>
|
||||
#include <AzCore/std/smart_ptr/unique_ptr.h>
|
||||
#include <AzToolsFramework/UI/Notifications/ToastNotificationsView.h>
|
||||
#include <GemCatalog/GemCatalogHeaderWidget.h>
|
||||
#include <GemCatalog/GemFilterWidget.h>
|
||||
#include <GemCatalog/GemListView.h>
|
||||
#include <GemCatalog/GemInspector.h>
|
||||
#include <GemCatalog/GemModel.h>
|
||||
#include <GemCatalog/GemSortFilterProxyModel.h>
|
||||
|
||||
#include <QSet>
|
||||
#include <QString>
|
||||
#endif
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QVBoxLayout)
|
||||
QT_FORWARD_DECLARE_CLASS(QStackedWidget)
|
||||
|
||||
namespace O3DE::ProjectManager
|
||||
{
|
||||
QT_FORWARD_DECLARE_CLASS(GemCatalogHeaderWidget)
|
||||
QT_FORWARD_DECLARE_CLASS(GemFilterWidget)
|
||||
QT_FORWARD_DECLARE_CLASS(GemListView)
|
||||
QT_FORWARD_DECLARE_CLASS(GemInspector)
|
||||
QT_FORWARD_DECLARE_CLASS(GemModel)
|
||||
QT_FORWARD_DECLARE_CLASS(GemSortFilterProxyModel)
|
||||
QT_FORWARD_DECLARE_CLASS(DownloadController)
|
||||
|
||||
class GemCatalogScreen
|
||||
: public ScreenWidget
|
||||
{
|
||||
@@ -62,14 +68,22 @@ namespace O3DE::ProjectManager
|
||||
|
||||
private slots:
|
||||
void HandleOpenGemRepo();
|
||||
|
||||
void UpdateAndShowGemCart(QWidget* cartWidget);
|
||||
void ShowInspector();
|
||||
|
||||
private:
|
||||
enum RightPanelWidgetOrder
|
||||
{
|
||||
Inspector = 0,
|
||||
Cart
|
||||
};
|
||||
|
||||
void FillModel(const QString& projectPath);
|
||||
|
||||
AZStd::unique_ptr<AzToolsFramework::ToastNotificationsView> m_notificationsView;
|
||||
|
||||
GemListView* m_gemListView = nullptr;
|
||||
QStackedWidget* m_rightPanelStack = nullptr;
|
||||
GemInspector* m_gemInspector = nullptr;
|
||||
GemModel* m_gemModel = nullptr;
|
||||
GemCatalogHeaderWidget* m_headerWidget = nullptr;
|
||||
|
||||
@@ -53,10 +53,13 @@ namespace O3DE::ProjectManager
|
||||
Update(selectedIndices[0]);
|
||||
}
|
||||
|
||||
void SetLabelElidedText(QLabel* label, QString text)
|
||||
void SetLabelElidedText(QLabel* label, QString text, int labelWidth = 0)
|
||||
{
|
||||
QFontMetrics nameFontMetrics(label->font());
|
||||
int labelWidth = label->width();
|
||||
if (!labelWidth)
|
||||
{
|
||||
labelWidth = label->width();
|
||||
}
|
||||
|
||||
// Don't elide if the widgets are sized too small (sometimes occurs when loading gem catalog)
|
||||
if (labelWidth > 100)
|
||||
@@ -84,7 +87,8 @@ namespace O3DE::ProjectManager
|
||||
m_summaryLabel->setText(m_model->GetSummary(modelIndex));
|
||||
m_summaryLabel->adjustSize();
|
||||
|
||||
m_licenseLinkLabel->setText(m_model->GetLicenseText(modelIndex));
|
||||
// Manually define remaining space to elide text because spacer would like to take all of the space
|
||||
SetLabelElidedText(m_licenseLinkLabel, m_model->GetLicenseText(modelIndex), width() - m_licenseLabel->width() - 35);
|
||||
m_licenseLinkLabel->SetUrl(m_model->GetLicenseLink(modelIndex));
|
||||
|
||||
m_directoryLinkLabel->SetUrl(m_model->GetDirectoryLink(modelIndex));
|
||||
@@ -175,8 +179,8 @@ namespace O3DE::ProjectManager
|
||||
licenseHLayout->setAlignment(Qt::AlignLeft);
|
||||
m_mainLayout->addLayout(licenseHLayout);
|
||||
|
||||
QLabel* licenseLabel = CreateStyledLabel(licenseHLayout, s_baseFontSize, s_headerColor);
|
||||
licenseLabel->setText(tr("License: "));
|
||||
m_licenseLabel = CreateStyledLabel(licenseHLayout, s_baseFontSize, s_headerColor);
|
||||
m_licenseLabel->setText(tr("License: "));
|
||||
|
||||
m_licenseLinkLabel = new LinkLabel("", QUrl(), s_baseFontSize);
|
||||
licenseHLayout->addWidget(m_licenseLinkLabel);
|
||||
|
||||
@@ -64,6 +64,7 @@ namespace O3DE::ProjectManager
|
||||
QLabel* m_nameLabel = nullptr;
|
||||
QLabel* m_creatorLabel = nullptr;
|
||||
QLabel* m_summaryLabel = nullptr;
|
||||
QLabel* m_licenseLabel = nullptr;
|
||||
LinkLabel* m_licenseLinkLabel = nullptr;
|
||||
LinkLabel* m_directoryLinkLabel = nullptr;
|
||||
LinkLabel* m_documentationLinkLabel = nullptr;
|
||||
|
||||
@@ -120,7 +120,7 @@ namespace O3DE::ProjectManager
|
||||
{
|
||||
QString repoUri = GetRepoUri(modelIndex);
|
||||
|
||||
const AZ::Outcome<QVector<GemInfo>, AZStd::string>& gemInfosResult = PythonBindingsInterface::Get()->GetGemRepoGemInfos(repoUri);
|
||||
const AZ::Outcome<QVector<GemInfo>, AZStd::string>& gemInfosResult = PythonBindingsInterface::Get()->GetGemInfosForRepo(repoUri);
|
||||
if (gemInfosResult.IsSuccess())
|
||||
{
|
||||
return gemInfosResult.GetValue();
|
||||
|
||||
@@ -92,8 +92,9 @@ namespace O3DE::ProjectManager
|
||||
return;
|
||||
}
|
||||
|
||||
bool addGemRepoResult = PythonBindingsInterface::Get()->AddGemRepo(repoUri);
|
||||
if (addGemRepoResult)
|
||||
AZ::Outcome < void,
|
||||
AZStd::pair<AZStd::string, AZStd::string>> addGemRepoResult = PythonBindingsInterface::Get()->AddGemRepo(repoUri);
|
||||
if (addGemRepoResult.IsSuccess())
|
||||
{
|
||||
Reinit();
|
||||
emit OnRefresh();
|
||||
@@ -101,8 +102,21 @@ namespace O3DE::ProjectManager
|
||||
else
|
||||
{
|
||||
QString failureMessage = tr("Failed to add gem repo: %1.").arg(repoUri);
|
||||
QMessageBox::critical(this, tr("Operation failed"), failureMessage);
|
||||
AZ_Error("Project Manger", false, failureMessage.toUtf8());
|
||||
if (!addGemRepoResult.GetError().second.empty())
|
||||
{
|
||||
QMessageBox addRepoError;
|
||||
addRepoError.setIcon(QMessageBox::Critical);
|
||||
addRepoError.setWindowTitle(failureMessage);
|
||||
addRepoError.setText(addGemRepoResult.GetError().first.c_str());
|
||||
addRepoError.setDetailedText(addGemRepoResult.GetError().second.c_str());
|
||||
addRepoError.exec();
|
||||
}
|
||||
else
|
||||
{
|
||||
QMessageBox::critical(this, failureMessage, addGemRepoResult.GetError().first.c_str());
|
||||
}
|
||||
|
||||
AZ_Error("Project Manager", false, failureMessage.toUtf8());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -203,6 +203,7 @@ namespace O3DE::ProjectManager
|
||||
|
||||
QMenu* menu = new QMenu(this);
|
||||
menu->addAction(tr("Edit Project Settings..."), this, [this]() { emit EditProject(m_projectInfo.m_path); });
|
||||
menu->addAction(tr("Configure Gems..."), this, [this]() { emit EditProjectGems(m_projectInfo.m_path); });
|
||||
menu->addAction(tr("Build"), this, [this]() { emit BuildProject(m_projectInfo); });
|
||||
menu->addAction(tr("Open CMake GUI..."), this, [this]() { emit OpenCMakeGUI(m_projectInfo); });
|
||||
menu->addSeparator();
|
||||
|
||||
@@ -95,6 +95,7 @@ namespace O3DE::ProjectManager
|
||||
signals:
|
||||
void OpenProject(const QString& projectName);
|
||||
void EditProject(const QString& projectName);
|
||||
void EditProjectGems(const QString& projectName);
|
||||
void CopyProject(const ProjectInfo& projectInfo);
|
||||
void RemoveProject(const QString& projectName);
|
||||
void DeleteProject(const QString& projectName);
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QStandardPaths>
|
||||
#include <QScrollArea>
|
||||
|
||||
namespace O3DE::ProjectManager
|
||||
{
|
||||
@@ -33,11 +34,23 @@ namespace O3DE::ProjectManager
|
||||
// if we don't set this in a frame (just use a sub-layout) all the content will align incorrectly horizontally
|
||||
QFrame* projectSettingsFrame = new QFrame(this);
|
||||
projectSettingsFrame->setObjectName("projectSettings");
|
||||
m_verticalLayout = new QVBoxLayout();
|
||||
|
||||
// you cannot remove content margins in qss
|
||||
m_verticalLayout->setContentsMargins(0, 0, 0, 0);
|
||||
QVBoxLayout* vLayout = new QVBoxLayout();
|
||||
vLayout->setMargin(0);
|
||||
vLayout->setAlignment(Qt::AlignTop);
|
||||
projectSettingsFrame->setLayout(vLayout);
|
||||
|
||||
QScrollArea* scrollArea = new QScrollArea(this);
|
||||
scrollArea->setWidgetResizable(true);
|
||||
vLayout->addWidget(scrollArea);
|
||||
|
||||
QWidget* scrollWidget = new QWidget(this);
|
||||
scrollArea->setWidget(scrollWidget);
|
||||
|
||||
m_verticalLayout = new QVBoxLayout();
|
||||
m_verticalLayout->setMargin(0);
|
||||
m_verticalLayout->setAlignment(Qt::AlignTop);
|
||||
scrollWidget->setLayout(m_verticalLayout);
|
||||
|
||||
m_projectName = new FormLineEditWidget(tr("Project name"), "", this);
|
||||
connect(m_projectName->lineEdit(), &QLineEdit::textChanged, this, &ProjectSettingsScreen::OnProjectNameUpdated);
|
||||
|
||||
@@ -183,6 +183,7 @@ namespace O3DE::ProjectManager
|
||||
|
||||
connect(projectButton, &ProjectButton::OpenProject, this, &ProjectsScreen::HandleOpenProject);
|
||||
connect(projectButton, &ProjectButton::EditProject, this, &ProjectsScreen::HandleEditProject);
|
||||
connect(projectButton, &ProjectButton::EditProjectGems, this, &ProjectsScreen::HandleEditProjectGems);
|
||||
connect(projectButton, &ProjectButton::CopyProject, this, &ProjectsScreen::HandleCopyProject);
|
||||
connect(projectButton, &ProjectButton::RemoveProject, this, &ProjectsScreen::HandleRemoveProject);
|
||||
connect(projectButton, &ProjectButton::DeleteProject, this, &ProjectsScreen::HandleDeleteProject);
|
||||
@@ -469,6 +470,14 @@ namespace O3DE::ProjectManager
|
||||
emit ChangeScreenRequest(ProjectManagerScreen::UpdateProject);
|
||||
}
|
||||
}
|
||||
void ProjectsScreen::HandleEditProjectGems(const QString& projectPath)
|
||||
{
|
||||
if (!WarnIfInBuildQueue(projectPath))
|
||||
{
|
||||
emit NotifyCurrentProject(projectPath);
|
||||
emit ChangeScreenRequest(ProjectManagerScreen::GemCatalog);
|
||||
}
|
||||
}
|
||||
void ProjectsScreen::HandleCopyProject(const ProjectInfo& projectInfo)
|
||||
{
|
||||
if (!WarnIfInBuildQueue(projectInfo.m_path))
|
||||
|
||||
@@ -46,6 +46,7 @@ namespace O3DE::ProjectManager
|
||||
void HandleAddProjectButton();
|
||||
void HandleOpenProject(const QString& projectPath);
|
||||
void HandleEditProject(const QString& projectPath);
|
||||
void HandleEditProjectGems(const QString& projectPath);
|
||||
void HandleCopyProject(const ProjectInfo& projectInfo);
|
||||
void HandleRemoveProject(const QString& projectPath);
|
||||
void HandleDeleteProject(const QString& projectPath);
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <AzCore/IO/SystemFile.h>
|
||||
#include <AzCore/std/containers/unordered_set.h>
|
||||
#include <AzCore/std/string/conversions.h>
|
||||
#include <AzCore/std/numeric.h>
|
||||
#include <AzCore/StringFunc/StringFunc.h>
|
||||
|
||||
#include <QDir>
|
||||
@@ -210,6 +211,16 @@ namespace RedirectOutput
|
||||
});
|
||||
|
||||
SetRedirection("stderr", g_redirect_stderr_saved, g_redirect_stderr, []([[maybe_unused]] const char* msg) {
|
||||
AZStd::string lastPythonError = msg;
|
||||
constexpr const char* pythonErrorPrefix = "ERROR:root:";
|
||||
constexpr size_t lengthOfErrorPrefix = AZStd::char_traits<char>::length(pythonErrorPrefix);
|
||||
auto errorPrefix = lastPythonError.find(pythonErrorPrefix);
|
||||
if (errorPrefix != AZStd::string::npos)
|
||||
{
|
||||
lastPythonError.erase(errorPrefix, lengthOfErrorPrefix);
|
||||
}
|
||||
O3DE::ProjectManager::PythonBindingsInterface::Get()->AddErrorString(lastPythonError);
|
||||
|
||||
AZ_TracePrintf("Python", msg);
|
||||
});
|
||||
|
||||
@@ -376,6 +387,8 @@ namespace O3DE::ProjectManager
|
||||
pybind11::gil_scoped_release release;
|
||||
pybind11::gil_scoped_acquire acquire;
|
||||
|
||||
ClearErrorStrings();
|
||||
|
||||
try
|
||||
{
|
||||
executionCallback();
|
||||
@@ -1051,7 +1064,7 @@ namespace O3DE::ProjectManager
|
||||
return result && refreshResult;
|
||||
}
|
||||
|
||||
bool PythonBindings::AddGemRepo(const QString& repoUri)
|
||||
AZ::Outcome<void, AZStd::pair<AZStd::string, AZStd::string>> PythonBindings::AddGemRepo(const QString& repoUri)
|
||||
{
|
||||
bool registrationResult = false;
|
||||
bool result = ExecuteWithLock(
|
||||
@@ -1065,7 +1078,12 @@ namespace O3DE::ProjectManager
|
||||
registrationResult = !pythonRegistrationResult.cast<bool>();
|
||||
});
|
||||
|
||||
return result && registrationResult;
|
||||
if (!result || !registrationResult)
|
||||
{
|
||||
return AZ::Failure<AZStd::pair<AZStd::string, AZStd::string>>(GetSimpleDetailedErrorPair());
|
||||
}
|
||||
|
||||
return AZ::Success();
|
||||
}
|
||||
|
||||
bool PythonBindings::RemoveGemRepo(const QString& repoUri)
|
||||
@@ -1188,7 +1206,7 @@ namespace O3DE::ProjectManager
|
||||
return AZ::Success(AZStd::move(gemRepos));
|
||||
}
|
||||
|
||||
AZ::Outcome<QVector<GemInfo>, AZStd::string> PythonBindings::GetGemRepoGemInfos(const QString& repoUri)
|
||||
AZ::Outcome<QVector<GemInfo>, AZStd::string> PythonBindings::GetGemInfosForRepo(const QString& repoUri)
|
||||
{
|
||||
QVector<GemInfo> gemInfos;
|
||||
AZ::Outcome<void, AZStd::string> result = ExecuteWithLockErrorHandling(
|
||||
@@ -1216,7 +1234,7 @@ namespace O3DE::ProjectManager
|
||||
return AZ::Success(AZStd::move(gemInfos));
|
||||
}
|
||||
|
||||
AZ::Outcome<QVector<GemInfo>, AZStd::string> PythonBindings::GetAllGemReposGemInfos()
|
||||
AZ::Outcome<QVector<GemInfo>, AZStd::string> PythonBindings::GetGemInfosForAllRepos()
|
||||
{
|
||||
QVector<GemInfo> gemInfos;
|
||||
AZ::Outcome<void, AZStd::string> result = ExecuteWithLockErrorHandling(
|
||||
@@ -1243,7 +1261,7 @@ namespace O3DE::ProjectManager
|
||||
return AZ::Success(AZStd::move(gemInfos));
|
||||
}
|
||||
|
||||
AZ::Outcome<void, AZStd::string> PythonBindings::DownloadGem(
|
||||
AZ::Outcome<void, AZStd::pair<AZStd::string, AZStd::string>> PythonBindings::DownloadGem(
|
||||
const QString& gemName, std::function<void(int, int)> gemProgressCallback, bool force)
|
||||
{
|
||||
// This process is currently limited to download a single gem at a time.
|
||||
@@ -1272,11 +1290,12 @@ namespace O3DE::ProjectManager
|
||||
|
||||
if (!result.IsSuccess())
|
||||
{
|
||||
return result;
|
||||
AZStd::pair<AZStd::string, AZStd::string> pythonRunError(result.GetError(), result.GetError());
|
||||
return AZ::Failure<AZStd::pair<AZStd::string, AZStd::string>>(AZStd::move(pythonRunError));
|
||||
}
|
||||
else if (!downloadSucceeded)
|
||||
{
|
||||
return AZ::Failure<AZStd::string>("Failed to download gem.");
|
||||
return AZ::Failure<AZStd::pair<AZStd::string, AZStd::string>>(GetSimpleDetailedErrorPair());
|
||||
}
|
||||
|
||||
return AZ::Success();
|
||||
@@ -1302,4 +1321,23 @@ namespace O3DE::ProjectManager
|
||||
|
||||
return result && updateAvaliableResult;
|
||||
}
|
||||
|
||||
AZStd::pair<AZStd::string, AZStd::string> PythonBindings::GetSimpleDetailedErrorPair()
|
||||
{
|
||||
AZStd::string detailedString = m_pythonErrorStrings.size() == 1
|
||||
? ""
|
||||
: AZStd::accumulate(m_pythonErrorStrings.begin(), m_pythonErrorStrings.end(), AZStd::string(""));
|
||||
|
||||
return AZStd::pair<AZStd::string, AZStd::string>(m_pythonErrorStrings.front(), detailedString);
|
||||
}
|
||||
|
||||
void PythonBindings::AddErrorString(AZStd::string errorString)
|
||||
{
|
||||
m_pythonErrorStrings.push_back(errorString);
|
||||
}
|
||||
|
||||
void PythonBindings::ClearErrorStrings()
|
||||
{
|
||||
m_pythonErrorStrings.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,15 +62,19 @@ namespace O3DE::ProjectManager
|
||||
// Gem Repos
|
||||
AZ::Outcome<void, AZStd::string> RefreshGemRepo(const QString& repoUri) override;
|
||||
bool RefreshAllGemRepos() override;
|
||||
bool AddGemRepo(const QString& repoUri) override;
|
||||
AZ::Outcome<void, AZStd::pair<AZStd::string, AZStd::string>> AddGemRepo(const QString& repoUri) override;
|
||||
bool RemoveGemRepo(const QString& repoUri) override;
|
||||
AZ::Outcome<QVector<GemRepoInfo>, AZStd::string> GetAllGemRepoInfos() override;
|
||||
AZ::Outcome<QVector<GemInfo>, AZStd::string> GetGemRepoGemInfos(const QString& repoUri) override;
|
||||
AZ::Outcome<QVector<GemInfo>, AZStd::string> GetAllGemReposGemInfos() override;
|
||||
AZ::Outcome<void, AZStd::string> DownloadGem(const QString& gemName, std::function<void(int, int)> gemProgressCallback, bool force = false) override;
|
||||
AZ::Outcome<QVector<GemInfo>, AZStd::string> GetGemInfosForRepo(const QString& repoUri) override;
|
||||
AZ::Outcome<QVector<GemInfo>, AZStd::string> GetGemInfosForAllRepos() override;
|
||||
AZ::Outcome<void, AZStd::pair<AZStd::string, AZStd::string>> DownloadGem(
|
||||
const QString& gemName, std::function<void(int, int)> gemProgressCallback, bool force = false) override;
|
||||
void CancelDownload() override;
|
||||
bool IsGemUpdateAvaliable(const QString& gemName, const QString& lastUpdated) override;
|
||||
|
||||
void AddErrorString(AZStd::string errorString) override;
|
||||
void ClearErrorStrings() override;
|
||||
|
||||
private:
|
||||
AZ_DISABLE_COPY_MOVE(PythonBindings);
|
||||
|
||||
@@ -83,6 +87,7 @@ namespace O3DE::ProjectManager
|
||||
AZ::Outcome<void, AZStd::string> GemRegistration(const QString& gemPath, const QString& projectPath, bool remove = false);
|
||||
bool RegisterThisEngine();
|
||||
bool StopPython();
|
||||
AZStd::pair<AZStd::string, AZStd::string> GetSimpleDetailedErrorPair();
|
||||
|
||||
|
||||
bool m_pythonStarted = false;
|
||||
@@ -102,5 +107,6 @@ namespace O3DE::ProjectManager
|
||||
pybind11::handle m_pathlib;
|
||||
|
||||
bool m_requestCancelDownload = false;
|
||||
AZStd::vector<AZStd::string> m_pythonErrorStrings;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -200,9 +200,9 @@ namespace O3DE::ProjectManager
|
||||
/**
|
||||
* Registers this gem repo with the current engine.
|
||||
* @param repoUri the absolute filesystem path or url to the gem repo.
|
||||
* @return true on success, false on failure.
|
||||
* @return an outcome with a pair of string error and detailed messages on failure.
|
||||
*/
|
||||
virtual bool AddGemRepo(const QString& repoUri) = 0;
|
||||
virtual AZ::Outcome<void, AZStd::pair<AZStd::string, AZStd::string>> AddGemRepo(const QString& repoUri) = 0;
|
||||
|
||||
/**
|
||||
* Unregisters this gem repo with the current engine.
|
||||
@@ -218,26 +218,26 @@ namespace O3DE::ProjectManager
|
||||
virtual AZ::Outcome<QVector<GemRepoInfo>, AZStd::string> GetAllGemRepoInfos() = 0;
|
||||
|
||||
/**
|
||||
* Gathers all gem infos for repos
|
||||
* Gathers all gem infos from the provided repo
|
||||
* @param repoUri the absolute filesystem path or url to the gem repo.
|
||||
* @return A list of gem infos.
|
||||
*/
|
||||
virtual AZ::Outcome<QVector<GemInfo>, AZStd::string> GetGemRepoGemInfos(const QString& repoUri) = 0;
|
||||
virtual AZ::Outcome<QVector<GemInfo>, AZStd::string> GetGemInfosForRepo(const QString& repoUri) = 0;
|
||||
|
||||
/**
|
||||
* Gathers all gem infos for all gems registered from repos.
|
||||
* @return A list of gem infos.
|
||||
*/
|
||||
virtual AZ::Outcome<QVector<GemInfo>, AZStd::string> GetAllGemReposGemInfos() = 0;
|
||||
virtual AZ::Outcome<QVector<GemInfo>, AZStd::string> GetGemInfosForAllRepos() = 0;
|
||||
|
||||
/**
|
||||
* Downloads and registers a Gem.
|
||||
* @param gemName the name of the Gem to download.
|
||||
* @param gemProgressCallback a callback function that is called with an int percentage download value.
|
||||
* @param force should we forcibly overwrite the old version of the gem.
|
||||
* @return an outcome with a string error message on failure.
|
||||
* @return an outcome with a pair of string error and detailed messages on failure.
|
||||
*/
|
||||
virtual AZ::Outcome<void, AZStd::string> DownloadGem(
|
||||
virtual AZ::Outcome<void, AZStd::pair<AZStd::string, AZStd::string>> DownloadGem(
|
||||
const QString& gemName, std::function<void(int, int)> gemProgressCallback, bool force = false) = 0;
|
||||
|
||||
/**
|
||||
@@ -252,6 +252,17 @@ namespace O3DE::ProjectManager
|
||||
* @return true if update is avaliable, false if not.
|
||||
*/
|
||||
virtual bool IsGemUpdateAvaliable(const QString& gemName, const QString& lastUpdated) = 0;
|
||||
|
||||
/**
|
||||
* Add an error string to be returned when the current python call is complete.
|
||||
* @param The error string to be displayed.
|
||||
*/
|
||||
virtual void AddErrorString(AZStd::string errorString) = 0;
|
||||
|
||||
/**
|
||||
* Clears the current list of error strings.
|
||||
*/
|
||||
virtual void ClearErrorStrings() = 0;
|
||||
};
|
||||
|
||||
using PythonBindingsInterface = AZ::Interface<IPythonBindings>;
|
||||
|
||||
@@ -47,9 +47,9 @@ namespace O3DE::ProjectManager
|
||||
return tr("Missing");
|
||||
}
|
||||
|
||||
virtual bool ContainsScreen([[maybe_unused]] ProjectManagerScreen screen)
|
||||
virtual bool ContainsScreen(ProjectManagerScreen screen)
|
||||
{
|
||||
return false;
|
||||
return GetScreenEnum() == screen;
|
||||
}
|
||||
virtual void GoToScreen([[maybe_unused]] ProjectManagerScreen screen)
|
||||
{
|
||||
@@ -58,7 +58,6 @@ namespace O3DE::ProjectManager
|
||||
//! Notify this screen it is the current screen
|
||||
virtual void NotifyCurrentScreen()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
signals:
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
#include <UpdateProjectCtrl.h>
|
||||
#include <UpdateProjectSettingsScreen.h>
|
||||
#include <ProjectUtils.h>
|
||||
#include <DownloadController.h>
|
||||
#include <ProjectManagerSettings.h>
|
||||
|
||||
#include <AzCore/Settings/SettingsRegistry.h>
|
||||
|
||||
#include <QDialogButtonBox>
|
||||
@@ -97,6 +97,17 @@ namespace O3DE::ProjectManager
|
||||
return ProjectManagerScreen::UpdateProject;
|
||||
}
|
||||
|
||||
bool UpdateProjectCtrl::ContainsScreen(ProjectManagerScreen screen)
|
||||
{
|
||||
// Do not include GemRepos because we don't want to advertise jumping to it from all other screens here
|
||||
return screen == GetScreenEnum() || screen == ProjectManagerScreen::GemCatalog;
|
||||
}
|
||||
|
||||
void UpdateProjectCtrl::GoToScreen(ProjectManagerScreen screen)
|
||||
{
|
||||
OnChangeScreenRequest(screen);
|
||||
}
|
||||
|
||||
// Called when pressing "Edit Project Settings..."
|
||||
void UpdateProjectCtrl::NotifyCurrentScreen()
|
||||
{
|
||||
@@ -117,6 +128,16 @@ namespace O3DE::ProjectManager
|
||||
m_stack->setCurrentWidget(m_gemRepoScreen);
|
||||
Update();
|
||||
}
|
||||
else if (screen == ProjectManagerScreen::GemCatalog)
|
||||
{
|
||||
m_stack->setCurrentWidget(m_gemCatalogScreen);
|
||||
Update();
|
||||
}
|
||||
else if (screen == ProjectManagerScreen::UpdateProjectSettings)
|
||||
{
|
||||
m_stack->setCurrentWidget(m_updateSettingsScreen);
|
||||
Update();
|
||||
}
|
||||
else
|
||||
{
|
||||
emit ChangeScreenRequest(screen);
|
||||
|
||||
@@ -24,7 +24,8 @@ namespace O3DE::ProjectManager
|
||||
QT_FORWARD_DECLARE_CLASS(GemCatalogScreen)
|
||||
QT_FORWARD_DECLARE_CLASS(GemRepoScreen)
|
||||
|
||||
class UpdateProjectCtrl : public ScreenWidget
|
||||
class UpdateProjectCtrl
|
||||
: public ScreenWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
@@ -32,7 +33,8 @@ namespace O3DE::ProjectManager
|
||||
~UpdateProjectCtrl() = default;
|
||||
ProjectManagerScreen GetScreenEnum() override;
|
||||
|
||||
protected:
|
||||
bool ContainsScreen(ProjectManagerScreen screen) override;
|
||||
void GoToScreen(ProjectManagerScreen screen) override;
|
||||
void NotifyCurrentScreen() override;
|
||||
|
||||
protected slots:
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace O3DE::ProjectManager
|
||||
previewExtrasLayout->setContentsMargins(50, 0, 0, 0);
|
||||
|
||||
QLabel* projectPreviewLabel = new QLabel(tr("Select an image (PNG). Minimum %1 x %2 pixels.")
|
||||
.arg(QString::number(ProjectPreviewImageWidth), QString::number(ProjectPreviewImageHeight)));
|
||||
.arg(QString::number(ProjectPreviewImageWidth), QString::number(ProjectPreviewImageHeight)));
|
||||
projectPreviewLabel->setObjectName("projectPreviewLabel");
|
||||
previewExtrasLayout->addWidget(projectPreviewLabel);
|
||||
|
||||
|
||||
@@ -84,7 +84,7 @@ static constexpr const char TEST_VALID_EMPTY_ACCOUNTID_RESOURCE_MAPPING_CONFIG_F
|
||||
},
|
||||
"AccountId": "",
|
||||
"Region": "us-west-2",
|
||||
"Version": "1.0.0"
|
||||
"Version": "1.1.0"
|
||||
})";
|
||||
|
||||
static constexpr const char TEST_INVALID_RESOURCE_MAPPING_CONFIG_FILE[] =
|
||||
|
||||
@@ -24,7 +24,7 @@ _RESOURCE_MAPPING_TYPE_JSON_KEY_NAME: str = "Type"
|
||||
_RESOURCE_MAPPING_NAMEID_JSON_KEY_NAME: str = "Name/ID"
|
||||
_RESOURCE_MAPPING_REGION_JSON_KEY_NAME: str = "Region"
|
||||
_RESOURCE_MAPPING_VERSION_JSON_KEY_NAME: str = "Version"
|
||||
_RESOURCE_MAPPING_JSON_FORMAT_VERSION: str = "1.0.0"
|
||||
_RESOURCE_MAPPING_JSON_FORMAT_VERSION: str = "1.1.0"
|
||||
|
||||
RESOURCE_MAPPING_ACCOUNTID_JSON_KEY_NAME: str = "AccountId"
|
||||
RESOURCE_MAPPING_ACCOUNTID_TEMPLATE_VALUE: str = "EMPTY"
|
||||
|
||||
@@ -48,6 +48,9 @@ void MainCS(uint3 group_thread_id : SV_GroupThreadID, uint3 group_id : SV_GroupI
|
||||
LDS_MAX_COC[group_thread_id.x] = 0;
|
||||
}
|
||||
|
||||
// Sync LDS
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
|
||||
// We use gather to get 2x2 values at once, so thread samples are spaced 2 pixels apart (+1 so the sample position is in between the four pixels)
|
||||
float2 samplePos = float2(dispatch_id.xy) * 2 + float2(1, 1);
|
||||
float2 sampleUV = samplePos * PassSrg::m_inputDimensions.zw;
|
||||
@@ -74,6 +77,9 @@ void MainCS(uint3 group_thread_id : SV_GroupThreadID, uint3 group_id : SV_GroupI
|
||||
InterlockedMin( LDS_MIN_COC[0], LDS_MIN_COC[group_thread_id.x] );
|
||||
InterlockedMax( LDS_MAX_COC[0], LDS_MAX_COC[group_thread_id.x] );
|
||||
|
||||
// Sync LDS
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
|
||||
// Each group write to just one pixel. If we're the last thread in the group, write out
|
||||
if(group_thread_id.x == 0)
|
||||
{
|
||||
|
||||
@@ -30,7 +30,6 @@ namespace AZ
|
||||
|
||||
AZStd::string m_displayName;
|
||||
AZ::Data::Asset<AZ::RPI::ModelAsset> m_modelAsset;
|
||||
AZ::Data::Asset<AZ::RPI::StreamingImageAsset> m_previewImageAsset;
|
||||
};
|
||||
|
||||
using ModelPresetPtr = AZStd::shared_ptr<ModelPreset>;
|
||||
|
||||
@@ -155,8 +155,10 @@ namespace AZ
|
||||
enum AuxGeomShapeType
|
||||
{
|
||||
ShapeType_Sphere,
|
||||
ShapeType_Hemisphere,
|
||||
ShapeType_Cone,
|
||||
ShapeType_Cylinder,
|
||||
ShapeType_CylinderNoEnds, // Cylinder without disks on either end
|
||||
ShapeType_Disk,
|
||||
ShapeType_Quad,
|
||||
|
||||
|
||||
@@ -314,15 +314,40 @@ namespace AZ
|
||||
AddShape(style, shape);
|
||||
}
|
||||
|
||||
void AuxGeomDrawQueue::DrawSphere(
|
||||
const AZ::Vector3& center,
|
||||
Matrix3x3 CreateMatrix3x3FromDirection(const AZ::Vector3& direction)
|
||||
{
|
||||
Vector3 unitDirection(direction.GetNormalized());
|
||||
Vector3 unitOrthogonal(direction.GetOrthogonalVector().GetNormalized());
|
||||
Vector3 unitCross(unitOrthogonal.Cross(unitDirection));
|
||||
return Matrix3x3::CreateFromColumns(unitOrthogonal, unitDirection, unitCross);
|
||||
}
|
||||
|
||||
void AuxGeomDrawQueue::DrawSphere(const AZ::Vector3& center, const AZ::Vector3& direction, float radius, const AZ::Color& color, DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex)
|
||||
{
|
||||
DrawSphereCommon(center, direction, radius, color, style, depthTest, depthWrite, faceCull, viewProjOverrideIndex, false);
|
||||
}
|
||||
|
||||
void AuxGeomDrawQueue::DrawSphere(const AZ::Vector3& center, float radius, const AZ::Color& color, DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex)
|
||||
{
|
||||
DrawSphereCommon(center, AZ::Vector3::CreateAxisZ(), radius, color, style, depthTest, depthWrite, faceCull, viewProjOverrideIndex, false);
|
||||
}
|
||||
|
||||
void AuxGeomDrawQueue::DrawHemisphere(const AZ::Vector3& center, const AZ::Vector3& direction, float radius, const AZ::Color& color, DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex)
|
||||
{
|
||||
DrawSphereCommon(center, direction, radius, color, style, depthTest, depthWrite, faceCull, viewProjOverrideIndex, true);
|
||||
}
|
||||
|
||||
void AuxGeomDrawQueue::DrawSphereCommon(
|
||||
const AZ::Vector3& center,
|
||||
const AZ::Vector3& direction,
|
||||
float radius,
|
||||
const AZ::Color& color,
|
||||
DrawStyle style,
|
||||
DepthTest depthTest,
|
||||
DepthWrite depthWrite,
|
||||
FaceCullMode faceCull,
|
||||
int32_t viewProjOverrideIndex)
|
||||
int32_t viewProjOverrideIndex,
|
||||
bool isHemisphere)
|
||||
{
|
||||
if (radius <= 0.0f)
|
||||
{
|
||||
@@ -330,12 +355,12 @@ namespace AZ
|
||||
}
|
||||
|
||||
ShapeBufferEntry shape;
|
||||
shape.m_shapeType = ShapeType_Sphere;
|
||||
shape.m_shapeType = isHemisphere ? ShapeType_Hemisphere : ShapeType_Sphere;
|
||||
shape.m_depthRead = ConvertRPIDepthTestFlag(depthTest);
|
||||
shape.m_depthWrite = ConvertRPIDepthWriteFlag(depthWrite);
|
||||
shape.m_faceCullMode = ConvertRPIFaceCullFlag(faceCull);
|
||||
shape.m_color = color;
|
||||
shape.m_rotationMatrix = Matrix3x3::CreateIdentity();
|
||||
shape.m_rotationMatrix = CreateMatrix3x3FromDirection(direction);
|
||||
shape.m_position = center;
|
||||
shape.m_scale = AZ::Vector3(radius, radius, radius);
|
||||
shape.m_pointSize = m_pointSize;
|
||||
@@ -362,13 +387,9 @@ namespace AZ
|
||||
shape.m_faceCullMode = ConvertRPIFaceCullFlag(faceCull);
|
||||
shape.m_color = color;
|
||||
|
||||
Vector3 unitDirection(direction.GetNormalized());
|
||||
Vector3 unitOrthogonal(direction.GetOrthogonalVector().GetNormalized());
|
||||
Vector3 unitCross(unitOrthogonal.Cross(unitDirection));
|
||||
|
||||
// The disk mesh is created with the top of the disk pointing along the positive Y axis. This creates a
|
||||
// rotation so that the top of the disk will point along the given direction vector.
|
||||
shape.m_rotationMatrix = Matrix3x3::CreateFromColumns(unitOrthogonal, unitDirection, unitCross);
|
||||
shape.m_rotationMatrix = CreateMatrix3x3FromDirection(direction);
|
||||
shape.m_position = center;
|
||||
shape.m_scale = AZ::Vector3(radius, 1.0f, radius);
|
||||
shape.m_pointSize = m_pointSize;
|
||||
@@ -401,13 +422,7 @@ namespace AZ
|
||||
shape.m_faceCullMode = ConvertRPIFaceCullFlag(faceCull);
|
||||
shape.m_color = color;
|
||||
|
||||
Vector3 unitDirection(direction.GetNormalized());
|
||||
Vector3 unitOrthogonal(direction.GetOrthogonalVector().GetNormalized());
|
||||
Vector3 unitCross(unitOrthogonal.Cross(unitDirection));
|
||||
|
||||
// The cone mesh is created with the tip of the cone pointing along the positive Y axis. This creates a
|
||||
// rotation so that the tip of the cone will point along the given direction vector.
|
||||
shape.m_rotationMatrix = Matrix3x3::CreateFromColumns(unitOrthogonal, unitDirection, unitCross);
|
||||
shape.m_rotationMatrix = CreateMatrix3x3FromDirection(direction);
|
||||
shape.m_position = center;
|
||||
shape.m_scale = AZ::Vector3(radius, height, radius);
|
||||
shape.m_pointSize = m_pointSize;
|
||||
@@ -416,17 +431,30 @@ namespace AZ
|
||||
AddShape(style, shape);
|
||||
}
|
||||
|
||||
void AuxGeomDrawQueue::DrawCylinder(
|
||||
const AZ::Vector3& center,
|
||||
const AZ::Vector3& direction,
|
||||
float radius,
|
||||
float height,
|
||||
const AZ::Color& color,
|
||||
DrawStyle style,
|
||||
DepthTest depthTest,
|
||||
DepthWrite depthWrite,
|
||||
FaceCullMode faceCull,
|
||||
int32_t viewProjOverrideIndex)
|
||||
void AuxGeomDrawQueue::DrawCylinder(const AZ::Vector3& center, const AZ::Vector3& direction, float radius, float height, const AZ::Color& color,
|
||||
DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex)
|
||||
{
|
||||
DrawCylinderCommon(center, direction, radius, height, color, style, depthTest, depthWrite, faceCull, viewProjOverrideIndex, true);
|
||||
}
|
||||
|
||||
void AuxGeomDrawQueue::DrawCylinderNoEnds(const AZ::Vector3& center, const AZ::Vector3& direction, float radius, float height, const AZ::Color& color,
|
||||
DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex)
|
||||
{
|
||||
DrawCylinderCommon(center, direction, radius, height, color, style, depthTest, depthWrite, faceCull, viewProjOverrideIndex, false);
|
||||
}
|
||||
|
||||
void AuxGeomDrawQueue::DrawCylinderCommon(
|
||||
const AZ::Vector3& center,
|
||||
const AZ::Vector3& direction,
|
||||
float radius,
|
||||
float height,
|
||||
const AZ::Color& color,
|
||||
DrawStyle style,
|
||||
DepthTest depthTest,
|
||||
DepthWrite depthWrite,
|
||||
FaceCullMode faceCull,
|
||||
int32_t viewProjOverrideIndex,
|
||||
bool drawEnds)
|
||||
{
|
||||
if (radius <= 0.0f || height <= 0.0f)
|
||||
{
|
||||
@@ -434,19 +462,15 @@ namespace AZ
|
||||
}
|
||||
|
||||
ShapeBufferEntry shape;
|
||||
shape.m_shapeType = ShapeType_Cylinder;
|
||||
shape.m_depthRead = ConvertRPIDepthTestFlag(depthTest);
|
||||
shape.m_shapeType = drawEnds ? ShapeType_Cylinder : ShapeType_CylinderNoEnds;
|
||||
shape.m_depthRead = ConvertRPIDepthTestFlag(depthTest);
|
||||
shape.m_depthWrite = ConvertRPIDepthWriteFlag(depthWrite);
|
||||
shape.m_faceCullMode = ConvertRPIFaceCullFlag(faceCull);
|
||||
shape.m_color = color;
|
||||
|
||||
Vector3 unitDirection(direction.GetNormalized());
|
||||
Vector3 unitOrthogonal(direction.GetOrthogonalVector().GetNormalized());
|
||||
Vector3 unitCross(unitOrthogonal.Cross(unitDirection));
|
||||
|
||||
// The cylinder mesh is created with the top end cap of the cylinder facing along the positive Y axis. This creates a
|
||||
// rotation so that the top face of the cylinder will face along the given direction vector.
|
||||
shape.m_rotationMatrix = Matrix3x3::CreateFromColumns(unitOrthogonal, unitDirection, unitCross);
|
||||
shape.m_rotationMatrix = CreateMatrix3x3FromDirection(direction);
|
||||
shape.m_position = center;
|
||||
shape.m_scale = AZ::Vector3(radius, height, radius);
|
||||
shape.m_pointSize = m_pointSize;
|
||||
|
||||
@@ -60,9 +60,12 @@ namespace AZ
|
||||
// Fixed shape draws
|
||||
void DrawQuad(float width, float height, const AZ::Matrix3x4& transform, const AZ::Color& color, DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex) override;
|
||||
void DrawSphere(const AZ::Vector3& center, float radius, const AZ::Color& color, DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex) override;
|
||||
void DrawSphere(const AZ::Vector3& center, const AZ::Vector3& direction, float radius, const AZ::Color& color, DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex) override;
|
||||
void DrawHemisphere(const AZ::Vector3& center, const AZ::Vector3& direction, float radius, const AZ::Color& color, DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex) override;
|
||||
void DrawDisk(const AZ::Vector3& center, const AZ::Vector3& direction, float radius, const AZ::Color& color, DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex) override;
|
||||
void DrawCone(const AZ::Vector3& center, const AZ::Vector3& direction, float radius, float height, const AZ::Color& color, DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex) override;
|
||||
void DrawCylinder(const AZ::Vector3& center, const AZ::Vector3& direction, float radius, float height, const AZ::Color& color, DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex) override;
|
||||
void DrawCylinderNoEnds(const AZ::Vector3& center, const AZ::Vector3& direction, float radius, float height, const AZ::Color& color, DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex) override;
|
||||
void DrawAabb(const AZ::Aabb& aabb, const AZ::Color& color, DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex) override;
|
||||
void DrawAabb(const AZ::Aabb& aabb, const AZ::Matrix3x4& transform, const AZ::Color& color, DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex) override;
|
||||
void DrawObb(const AZ::Obb& obb, const AZ::Vector3& position, const AZ::Color& color, DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex) override;
|
||||
@@ -73,6 +76,9 @@ namespace AZ
|
||||
|
||||
private: // functions
|
||||
|
||||
void DrawCylinderCommon(const AZ::Vector3& center, const AZ::Vector3& direction, float radius, float height, const AZ::Color& color, DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex, bool drawEnds);
|
||||
void DrawSphereCommon(const AZ::Vector3& center, const AZ::Vector3& direction, float radius, const AZ::Color& color, DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex, bool isHemisphere);
|
||||
|
||||
//! Clear the current buffers
|
||||
void ClearCurrentBufferData();
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "AuxGeomDrawProcessorShared.h"
|
||||
|
||||
#include <AzCore/Debug/EventTrace.h>
|
||||
#include <AzCore/std/algorithm.h>
|
||||
#include <AzCore/std/containers/array.h>
|
||||
|
||||
#include <Atom/RHI/Factory.h>
|
||||
@@ -69,11 +70,13 @@ namespace AZ
|
||||
SetupInputStreamLayout(m_objectStreamLayout[DrawStyle_Solid], RHI::PrimitiveTopology::TriangleList, false);
|
||||
SetupInputStreamLayout(m_objectStreamLayout[DrawStyle_Shaded], RHI::PrimitiveTopology::TriangleList, true);
|
||||
|
||||
CreateSphereBuffersAndViews();
|
||||
CreateSphereBuffersAndViews(AuxGeomShapeType::ShapeType_Sphere);
|
||||
CreateSphereBuffersAndViews(AuxGeomShapeType::ShapeType_Hemisphere);
|
||||
CreateQuadBuffersAndViews();
|
||||
CreateDiskBuffersAndViews();
|
||||
CreateConeBuffersAndViews();
|
||||
CreateCylinderBuffersAndViews();
|
||||
CreateCylinderBuffersAndViews(AuxGeomShapeType::ShapeType_Cylinder);
|
||||
CreateCylinderBuffersAndViews(AuxGeomShapeType::ShapeType_CylinderNoEnds);
|
||||
CreateBoxBuffersAndViews();
|
||||
|
||||
// cache scene pointer for RHI::PipelineState creation.
|
||||
@@ -293,8 +296,11 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
bool FixedShapeProcessor::CreateSphereBuffersAndViews()
|
||||
bool FixedShapeProcessor::CreateSphereBuffersAndViews(AuxGeomShapeType sphereShapeType)
|
||||
{
|
||||
AZ_Assert(sphereShapeType == ShapeType_Sphere || sphereShapeType == ShapeType_Hemisphere,
|
||||
"Trying to create sphere buffers and views with a non-sphere shape type!");
|
||||
|
||||
const uint32_t numSphereLods = 5;
|
||||
struct LodInfo
|
||||
{
|
||||
@@ -311,13 +317,13 @@ namespace AZ
|
||||
{ 9, 9, 0.0000f}
|
||||
}};
|
||||
|
||||
auto& m_shape = m_shapes[ShapeType_Sphere];
|
||||
auto& m_shape = m_shapes[sphereShapeType];
|
||||
m_shape.m_numLods = numSphereLods;
|
||||
|
||||
for (uint32_t lodIndex = 0; lodIndex < numSphereLods; ++lodIndex)
|
||||
{
|
||||
MeshData meshData;
|
||||
CreateSphereMeshData(meshData, lodInfo[lodIndex].numRings, lodInfo[lodIndex].numSections);
|
||||
CreateSphereMeshData(meshData, lodInfo[lodIndex].numRings, lodInfo[lodIndex].numSections, sphereShapeType);
|
||||
|
||||
ObjectBuffers objectBuffers;
|
||||
|
||||
@@ -334,12 +340,25 @@ namespace AZ
|
||||
return true;
|
||||
}
|
||||
|
||||
void FixedShapeProcessor::CreateSphereMeshData(MeshData& meshData, uint32_t numRings, uint32_t numSections)
|
||||
void FixedShapeProcessor::CreateSphereMeshData(MeshData& meshData, uint32_t numRings, uint32_t numSections, AuxGeomShapeType sphereShapeType)
|
||||
{
|
||||
const float radius = 1.0f;
|
||||
|
||||
// calculate "inner" vertices
|
||||
float sectionAngle(DegToRad(360.0f / static_cast<float>(numSections)));
|
||||
float ringSlice(DegToRad(180.0f / static_cast<float>(numRings)));
|
||||
|
||||
uint32_t numberOfPoles = 2;
|
||||
|
||||
if (sphereShapeType == ShapeType_Hemisphere)
|
||||
{
|
||||
numberOfPoles = 1;
|
||||
numRings = (numRings + 1) / 2;
|
||||
ringSlice = DegToRad(90.0f / static_cast<float>(numRings));
|
||||
}
|
||||
|
||||
// calc required number of vertices/indices/triangles to build a sphere for the given parameters
|
||||
uint32_t numVertices = (numRings - 1) * numSections + 2;
|
||||
uint32_t numVertices = (numRings - 1) * numSections + numberOfPoles;
|
||||
|
||||
// setup buffers
|
||||
auto& positions = meshData.m_positions;
|
||||
@@ -354,30 +373,29 @@ namespace AZ
|
||||
using NormalType = AuxGeomNormal;
|
||||
|
||||
// 1st pole vertex
|
||||
positions.push_back(PosType(0.0f, 0.0f, radius));
|
||||
normals.push_back(NormalType(0.0f, 0.0f, 1.0f));
|
||||
positions.push_back(PosType(0.0f, radius, 0.0f));
|
||||
normals.push_back(NormalType(0.0f, 1.0f, 0.0f));
|
||||
|
||||
// calculate "inner" vertices
|
||||
float sectionAngle(DegToRad(360.0f / static_cast<float>(numSections)));
|
||||
float ringSlice(DegToRad(180.0f / static_cast<float>(numRings)));
|
||||
|
||||
for (uint32_t ring = 1; ring < numRings; ++ring)
|
||||
for (uint32_t ring = 1; ring < numRings - numberOfPoles + 2; ++ring)
|
||||
{
|
||||
float w(sinf(ring * ringSlice));
|
||||
for (uint32_t section = 0; section < numSections; ++section)
|
||||
{
|
||||
float x = radius * cosf(section * sectionAngle) * w;
|
||||
float y = radius * sinf(section * sectionAngle) * w;
|
||||
float z = radius * cosf(ring * ringSlice);
|
||||
float y = radius * cosf(ring * ringSlice);
|
||||
float z = radius * sinf(section * sectionAngle) * w;
|
||||
Vector3 radialVector(x, y, z);
|
||||
positions.push_back(radialVector);
|
||||
normals.push_back(radialVector.GetNormalized());
|
||||
}
|
||||
}
|
||||
|
||||
// 2nd vertex of pole (for end cap)
|
||||
positions.push_back(PosType(0.0f, 0.0f, -radius));
|
||||
normals.push_back(NormalType(0.0f, 0.0f, -1.0f));
|
||||
if (sphereShapeType == ShapeType_Sphere)
|
||||
{
|
||||
// 2nd vertex of pole (for end cap)
|
||||
positions.push_back(PosType(0.0f, -radius, 0.0f));
|
||||
normals.push_back(NormalType(0.0f, -1.0f, 0.0f));
|
||||
}
|
||||
|
||||
// point indices
|
||||
{
|
||||
@@ -393,7 +411,8 @@ namespace AZ
|
||||
|
||||
// line indices
|
||||
{
|
||||
const uint32_t numEdges = (numRings - 2) * numSections * 2 + 2 * numSections * 2;
|
||||
// NumEdges = NumRingEdges + NumSectionEdges = (numRings * numSections) + (numRings * numSections)
|
||||
const uint32_t numEdges = numRings * numSections * 2;
|
||||
const uint32_t numLineIndices = numEdges * 2;
|
||||
|
||||
// build "inner" faces
|
||||
@@ -401,10 +420,9 @@ namespace AZ
|
||||
indices.clear();
|
||||
indices.reserve(numLineIndices);
|
||||
|
||||
for (uint16_t ring = 0; ring < numRings - 2; ++ring)
|
||||
for (uint16_t ring = 0; ring < numRings - numberOfPoles + 1; ++ring)
|
||||
{
|
||||
uint16_t firstVertOfThisRing = static_cast<uint16_t>(1 + ring * numSections);
|
||||
uint16_t firstVertOfNextRing = static_cast<uint16_t>(1 + (ring + 1) * numSections);
|
||||
for (uint16_t section = 0; section < numSections; ++section)
|
||||
{
|
||||
uint32_t nextSection = (section + 1) % numSections;
|
||||
@@ -414,32 +432,33 @@ namespace AZ
|
||||
indices.push_back(static_cast<uint16_t>(firstVertOfThisRing + nextSection));
|
||||
|
||||
// line around section
|
||||
indices.push_back(firstVertOfThisRing + section);
|
||||
indices.push_back(firstVertOfNextRing + section);
|
||||
int currentVertexIndex = firstVertOfThisRing + section;
|
||||
// max 0 will implicitly handle the top pole
|
||||
int previousVertexIndex = AZStd::max(currentVertexIndex - (int)numSections, 0);
|
||||
indices.push_back(static_cast<uint16_t>(currentVertexIndex));
|
||||
indices.push_back(static_cast<uint16_t>(previousVertexIndex));
|
||||
}
|
||||
}
|
||||
|
||||
// build faces for end caps (to connect "inner" vertices with poles)
|
||||
uint16_t firstPoleVert = 0;
|
||||
uint16_t firstVertOfFirstRing = static_cast<uint16_t>(1 + (0) * numSections);
|
||||
for (uint16_t section = 0; section < numSections; ++section)
|
||||
if (sphereShapeType == ShapeType_Sphere)
|
||||
{
|
||||
indices.push_back(firstPoleVert);
|
||||
indices.push_back(firstVertOfFirstRing + section);
|
||||
}
|
||||
|
||||
uint16_t lastPoleVert = static_cast<uint16_t>((numRings - 1) * numSections + 1);
|
||||
uint16_t firstVertOfLastRing = static_cast<uint16_t>(1 + (numRings - 2) * numSections);
|
||||
for (uint16_t section = 0; section < numSections; ++section)
|
||||
{
|
||||
indices.push_back(firstVertOfLastRing + section);
|
||||
indices.push_back(lastPoleVert);
|
||||
// build faces for bottom pole (to connect "inner" vertices with poles)
|
||||
uint16_t lastPoleVert = static_cast<uint16_t>((numRings - 1) * numSections + 1);
|
||||
uint16_t firstVertOfLastRing = static_cast<uint16_t>(1 + (numRings - 2) * numSections);
|
||||
for (uint16_t section = 0; section < numSections; ++section)
|
||||
{
|
||||
indices.push_back(firstVertOfLastRing + section);
|
||||
indices.push_back(lastPoleVert);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// triangle indices
|
||||
{
|
||||
const uint32_t numTriangles = (numRings - 2) * numSections * 2 + 2 * numSections;
|
||||
// NumTriangles = NumTrianglesAtPoles + NumQuads * 2
|
||||
// = (numSections * 2) + ((numRings - 2) * numSections * 2)
|
||||
// = (numSections * 2) * (numRings - 2 + 1)
|
||||
const uint32_t numTriangles = (numRings - 1) * numSections * 2;
|
||||
const uint32_t numTriangleIndices = numTriangles * 3;
|
||||
|
||||
// build "inner" faces
|
||||
@@ -447,10 +466,10 @@ namespace AZ
|
||||
indices.clear();
|
||||
indices.reserve(numTriangleIndices);
|
||||
|
||||
for (uint32_t ring = 0; ring < numRings - 2; ++ring)
|
||||
for (uint32_t ring = 0; ring < numRings - numberOfPoles; ++ring)
|
||||
{
|
||||
uint32_t firstVertOfThisRing = 1 + ring * numSections;
|
||||
uint32_t firstVertOfNextRing = 1 + (ring + 1) * numSections;
|
||||
uint32_t firstVertOfNextRing = firstVertOfThisRing + numSections;
|
||||
|
||||
for (uint32_t section = 0; section < numSections; ++section)
|
||||
{
|
||||
@@ -476,14 +495,17 @@ namespace AZ
|
||||
indices.push_back(static_cast<uint16_t>(firstPoleVert));
|
||||
}
|
||||
|
||||
uint32_t lastPoleVert = (numRings - 1) * numSections + 1;
|
||||
uint32_t firstVertOfLastRing = 1 + (numRings - 2) * numSections;
|
||||
for (uint32_t section = 0; section < numSections; ++section)
|
||||
if (sphereShapeType == ShapeType_Sphere)
|
||||
{
|
||||
uint32_t nextSection = (section + 1) % numSections;
|
||||
indices.push_back(static_cast<uint16_t>(firstVertOfLastRing + nextSection));
|
||||
indices.push_back(static_cast<uint16_t>(firstVertOfLastRing + section));
|
||||
indices.push_back(static_cast<uint16_t>(lastPoleVert));
|
||||
uint32_t lastPoleVert = (numRings - 1) * numSections + 1;
|
||||
uint32_t firstVertOfLastRing = 1 + (numRings - 2) * numSections;
|
||||
for (uint32_t section = 0; section < numSections; ++section)
|
||||
{
|
||||
uint32_t nextSection = (section + 1) % numSections;
|
||||
indices.push_back(static_cast<uint16_t>(firstVertOfLastRing + nextSection));
|
||||
indices.push_back(static_cast<uint16_t>(firstVertOfLastRing + section));
|
||||
indices.push_back(static_cast<uint16_t>(lastPoleVert));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -827,8 +849,11 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
bool FixedShapeProcessor::CreateCylinderBuffersAndViews()
|
||||
bool FixedShapeProcessor::CreateCylinderBuffersAndViews(AuxGeomShapeType cylinderShapeType)
|
||||
{
|
||||
AZ_Assert(cylinderShapeType == ShapeType_Cylinder || cylinderShapeType == ShapeType_CylinderNoEnds,
|
||||
"Trying to create cylinder buffers and views with a non-cylinder shape type!");
|
||||
|
||||
const uint32_t numCylinderLods = 5;
|
||||
struct LodInfo
|
||||
{
|
||||
@@ -836,21 +861,21 @@ namespace AZ
|
||||
float screenPercentage;
|
||||
};
|
||||
const AZStd::array<LodInfo, numCylinderLods> lodInfo =
|
||||
{{
|
||||
{ {
|
||||
{ 38, 0.1000f},
|
||||
{ 22, 0.0100f},
|
||||
{ 14, 0.0010f},
|
||||
{ 10, 0.0001f},
|
||||
{ 8, 0.0000f}
|
||||
}};
|
||||
} };
|
||||
|
||||
auto& m_shape = m_shapes[ShapeType_Cylinder];
|
||||
auto& m_shape = m_shapes[cylinderShapeType];
|
||||
m_shape.m_numLods = numCylinderLods;
|
||||
|
||||
for (uint32_t lodIndex = 0; lodIndex < numCylinderLods; ++lodIndex)
|
||||
{
|
||||
MeshData meshData;
|
||||
CreateCylinderMeshData(meshData, lodInfo[lodIndex].numSections);
|
||||
CreateCylinderMeshData(meshData, lodInfo[lodIndex].numSections, cylinderShapeType);
|
||||
|
||||
ObjectBuffers objectBuffers;
|
||||
|
||||
@@ -867,13 +892,25 @@ namespace AZ
|
||||
return true;
|
||||
}
|
||||
|
||||
void FixedShapeProcessor::CreateCylinderMeshData(MeshData& meshData, uint32_t numSections)
|
||||
void FixedShapeProcessor::CreateCylinderMeshData(MeshData& meshData, uint32_t numSections, AuxGeomShapeType cylinderShapeType)
|
||||
{
|
||||
const float radius = 1.0f;
|
||||
const float height = 1.0f;
|
||||
|
||||
//uint16_t indexOfBottomCenter = 0;
|
||||
//uint16_t indexOfBottomStart = 1;
|
||||
//uint16_t indexOfTopCenter = numSections + 1;
|
||||
//uint16_t indexOfTopStart = numSections + 2;
|
||||
uint16_t indexOfSidesStart = static_cast<uint16_t>(2 * numSections + 2);
|
||||
|
||||
if (cylinderShapeType == ShapeType_CylinderNoEnds)
|
||||
{
|
||||
// We won't draw disks at the ends of the cylinder, so no need to offset side indices
|
||||
indexOfSidesStart = 0;
|
||||
}
|
||||
|
||||
// calc required number of vertices to build a cylinder for the given parameters
|
||||
uint32_t numVertices = 4 * numSections + 2;
|
||||
uint32_t numVertices = indexOfSidesStart + 2 * numSections;
|
||||
|
||||
// setup buffers
|
||||
auto& positions = meshData.m_positions;
|
||||
@@ -888,8 +925,11 @@ namespace AZ
|
||||
float topHeight = height * 0.5f;
|
||||
|
||||
// Create caps
|
||||
CreateDiskMeshData(meshData, numSections, Facing::Down, bottomHeight);
|
||||
CreateDiskMeshData(meshData, numSections, Facing::Up, topHeight);
|
||||
if (cylinderShapeType == ShapeType_Cylinder)
|
||||
{
|
||||
CreateDiskMeshData(meshData, numSections, Facing::Down, bottomHeight);
|
||||
CreateDiskMeshData(meshData, numSections, Facing::Up, topHeight);
|
||||
}
|
||||
|
||||
// create vertices for side (so normal points out correctly)
|
||||
float sectionAngle(DegToRad(360.0f / (float)numSections));
|
||||
@@ -906,12 +946,6 @@ namespace AZ
|
||||
normals.push_back(normal);
|
||||
}
|
||||
|
||||
//uint16_t indexOfBottomCenter = 0;
|
||||
//uint16_t indexOfBottomStart = 1;
|
||||
//uint16_t indexOfTopCenter = numSections + 1;
|
||||
//uint16_t indexOfTopStart = numSections + 2;
|
||||
uint16_t indexOfSidesStart = static_cast<uint16_t>(2 * numSections + 2);
|
||||
|
||||
// build point indices
|
||||
{
|
||||
auto& indices = meshData.m_pointIndices;
|
||||
@@ -930,6 +964,24 @@ namespace AZ
|
||||
indices.push_back(indexOfSidesStart + 2 * section);
|
||||
indices.push_back(indexOfSidesStart + 2 * section + 1);
|
||||
}
|
||||
|
||||
// If we're not drawing the disks at the ends of the cylinder, we still want to
|
||||
// draw a ring around the end to join the tips of lines we created just above
|
||||
if (cylinderShapeType == ShapeType_CylinderNoEnds)
|
||||
{
|
||||
for (uint16_t section = 0; section < numSections; ++section)
|
||||
{
|
||||
uint16_t nextSection = (section + 1) % numSections;
|
||||
|
||||
// line around the bottom cap
|
||||
indices.push_back(section * 2);
|
||||
indices.push_back(nextSection * 2);
|
||||
|
||||
// line around the top cap
|
||||
indices.push_back(section * 2 + 1);
|
||||
indices.push_back(nextSection * 2 + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// indices for triangles
|
||||
|
||||
@@ -138,8 +138,8 @@ namespace AZ
|
||||
Both,
|
||||
};
|
||||
|
||||
bool CreateSphereBuffersAndViews();
|
||||
void CreateSphereMeshData(MeshData& meshData, uint32_t numRings, uint32_t numSections);
|
||||
bool CreateSphereBuffersAndViews(AuxGeomShapeType sphereShapeType);
|
||||
void CreateSphereMeshData(MeshData& meshData, uint32_t numRings, uint32_t numSections, AuxGeomShapeType sphereShapeType);
|
||||
|
||||
bool CreateQuadBuffersAndViews();
|
||||
void CreateQuadMeshDataSide(MeshData& meshData, bool isUp, bool drawLines);
|
||||
@@ -152,8 +152,8 @@ namespace AZ
|
||||
bool CreateConeBuffersAndViews();
|
||||
void CreateConeMeshData(MeshData& meshData, uint32_t numRings, uint32_t numSections);
|
||||
|
||||
bool CreateCylinderBuffersAndViews();
|
||||
void CreateCylinderMeshData(MeshData& meshData, uint32_t numSections);
|
||||
bool CreateCylinderBuffersAndViews(AuxGeomShapeType cylinderShapeType);
|
||||
void CreateCylinderMeshData(MeshData& meshData, uint32_t numSections, AuxGeomShapeType cylinderShapeType);
|
||||
|
||||
bool CreateBoxBuffersAndViews();
|
||||
void CreateBoxMeshData(MeshData& meshData);
|
||||
|
||||
@@ -29,7 +29,6 @@ namespace AZ
|
||||
->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_modelAsset, "Model Asset", "Model asset reference")
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &ModelPreset::m_previewImageAsset, "Preview Image Asset", "Preview image asset reference")
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,10 +24,9 @@ namespace AZ
|
||||
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
{
|
||||
serializeContext->Class<ModelPreset>()
|
||||
->Version(3)
|
||||
->Version(4)
|
||||
->Field("displayName", &ModelPreset::m_displayName)
|
||||
->Field("modelAsset", &ModelPreset::m_modelAsset)
|
||||
->Field("previewImageAsset", &ModelPreset::m_previewImageAsset)
|
||||
;
|
||||
}
|
||||
|
||||
@@ -41,7 +40,6 @@ namespace AZ
|
||||
->Constructor<const ModelPreset&>()
|
||||
->Property("displayName", BehaviorValueProperty(&ModelPreset::m_displayName))
|
||||
->Property("modelAsset", BehaviorValueProperty(&ModelPreset::m_modelAsset))
|
||||
->Property("previewImageAsset", BehaviorValueProperty(&ModelPreset::m_previewImageAsset))
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:28c3cfd8958813b4b539738bfff589731da0aeec5b3376558f377da2ebe973ff
|
||||
size 5455
|
||||
oid sha256:7028c8db4f935f23aa4396668278a67691d92fe345cc9d417a9f47bd9a4af32b
|
||||
size 8130
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
<ObjectStream version="3">
|
||||
<Class name="TextureSettings" version="2" type="{980132FF-C450-425D-8AE0-BD96A8486177}">
|
||||
<Class name="AZ::Uuid" field="PresetID" value="{00000000-0000-0000-0000-000000000000}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
|
||||
<Class name="Name" field="Preset" value="ReferenceImage" type="{3D2B920C-9EFD-40D5-AAE0-DF131C3D4931}"/>
|
||||
<Class name="unsigned int" field="SizeReduceLevel" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="bool" field="EngineReduce" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="bool" field="EnableMipmap" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="bool" field="MaintainAlphaCoverage" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="AZStd::vector" field="MipMapAlphaAdjustments" type="{3349AACD-BE04-50BC-9478-528BF2ACFD55}">
|
||||
<Class name="unsigned int" field="element" value="50" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="unsigned int" field="element" value="50" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="unsigned int" field="element" value="50" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="unsigned int" field="element" value="50" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="unsigned int" field="element" value="50" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="unsigned int" field="element" value="50" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
</Class>
|
||||
<Class name="unsigned int" field="MipMapGenEval" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="ImageProcessingAtom::MipGenType" field="MipMapGenType" value="1" type="{8524F650-1417-44DA-BBB0-C707A7A1A709}"/>
|
||||
<Class name="AZStd::map" field="PlatformSpecificOverrides" type="{74E4843B-0924-583D-8C6E-A37B09BD51FE}">
|
||||
<Class name="AZStd::pair" field="element" type="{CAC4E67F-D626-5452-A057-ACB57D53F549}">
|
||||
<Class name="AZStd::string" field="value1" value="android" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
|
||||
<Class name="DataPatch" field="value2" type="{BFF7A3F5-9014-4000-92C7-9B2BC7913DA9}">
|
||||
<Class name="AZ::Uuid" field="m_targetClassId" value="{980132FF-C450-425D-8AE0-BD96A8486177}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
|
||||
<Class name="unsigned int" field="m_targetClassVersion" value="2" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="AZStd::unordered_map" field="m_patch" type="{CEA836FC-77E0-5E46-BD0F-2E5A39D845E9}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
<Class name="AZStd::pair" field="element" type="{CAC4E67F-D626-5452-A057-ACB57D53F549}">
|
||||
<Class name="AZStd::string" field="value1" value="ios" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
|
||||
<Class name="DataPatch" field="value2" type="{BFF7A3F5-9014-4000-92C7-9B2BC7913DA9}">
|
||||
<Class name="AZ::Uuid" field="m_targetClassId" value="{980132FF-C450-425D-8AE0-BD96A8486177}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
|
||||
<Class name="unsigned int" field="m_targetClassVersion" value="2" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="AZStd::unordered_map" field="m_patch" type="{CEA836FC-77E0-5E46-BD0F-2E5A39D845E9}">
|
||||
<Class name="AZStd::pair" field="element" type="{FED51EB4-F646-51FF-9646-9852CF90F353}">
|
||||
<Class name="AddressType" field="value1" value="AZStd::map({74E4843B-0924-583D-8C6E-A37B09BD51FE})::PlatformSpecificOverrides·0/AZStd::pair({CAC4E67F-D626-5452-A057-ACB57D53F549})#0·0/" version="1" type="{90752F2D-CBD3-4EE9-9CDD-447E797C8408}"/>
|
||||
<Class name="any" field="value2" type="{03924488-C7F4-4D6D-948B-ABC2D1AE2FD3}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
</Class>
|
||||
</Class>
|
||||
<Class name="AZStd::pair" field="element" type="{CAC4E67F-D626-5452-A057-ACB57D53F549}">
|
||||
<Class name="AZStd::string" field="value1" value="linux" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
|
||||
<Class name="DataPatch" field="value2" type="{BFF7A3F5-9014-4000-92C7-9B2BC7913DA9}">
|
||||
<Class name="AZ::Uuid" field="m_targetClassId" value="{980132FF-C450-425D-8AE0-BD96A8486177}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
|
||||
<Class name="unsigned int" field="m_targetClassVersion" value="2" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="AZStd::unordered_map" field="m_patch" type="{CEA836FC-77E0-5E46-BD0F-2E5A39D845E9}">
|
||||
<Class name="AZStd::pair" field="element" type="{FED51EB4-F646-51FF-9646-9852CF90F353}">
|
||||
<Class name="AddressType" field="value1" value="AZStd::map({74E4843B-0924-583D-8C6E-A37B09BD51FE})::PlatformSpecificOverrides·0/AZStd::pair({CAC4E67F-D626-5452-A057-ACB57D53F549})#0·0/" version="1" type="{90752F2D-CBD3-4EE9-9CDD-447E797C8408}"/>
|
||||
<Class name="any" field="value2" type="{03924488-C7F4-4D6D-948B-ABC2D1AE2FD3}"/>
|
||||
</Class>
|
||||
<Class name="AZStd::pair" field="element" type="{FED51EB4-F646-51FF-9646-9852CF90F353}">
|
||||
<Class name="AddressType" field="value1" value="AZStd::map({74E4843B-0924-583D-8C6E-A37B09BD51FE})::PlatformSpecificOverrides·0/AZStd::pair({CAC4E67F-D626-5452-A057-ACB57D53F549})#1·0/" version="1" type="{90752F2D-CBD3-4EE9-9CDD-447E797C8408}"/>
|
||||
<Class name="any" field="value2" type="{03924488-C7F4-4D6D-948B-ABC2D1AE2FD3}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
</Class>
|
||||
</Class>
|
||||
<Class name="AZStd::pair" field="element" type="{CAC4E67F-D626-5452-A057-ACB57D53F549}">
|
||||
<Class name="AZStd::string" field="value1" value="mac" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
|
||||
<Class name="DataPatch" field="value2" type="{BFF7A3F5-9014-4000-92C7-9B2BC7913DA9}">
|
||||
<Class name="AZ::Uuid" field="m_targetClassId" value="{980132FF-C450-425D-8AE0-BD96A8486177}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
|
||||
<Class name="unsigned int" field="m_targetClassVersion" value="2" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="AZStd::unordered_map" field="m_patch" type="{CEA836FC-77E0-5E46-BD0F-2E5A39D845E9}">
|
||||
<Class name="AZStd::pair" field="element" type="{FED51EB4-F646-51FF-9646-9852CF90F353}">
|
||||
<Class name="AddressType" field="value1" value="AZStd::map({74E4843B-0924-583D-8C6E-A37B09BD51FE})::PlatformSpecificOverrides·0/AZStd::pair({CAC4E67F-D626-5452-A057-ACB57D53F549})#2·0/" version="1" type="{90752F2D-CBD3-4EE9-9CDD-447E797C8408}"/>
|
||||
<Class name="any" field="value2" type="{03924488-C7F4-4D6D-948B-ABC2D1AE2FD3}"/>
|
||||
</Class>
|
||||
<Class name="AZStd::pair" field="element" type="{FED51EB4-F646-51FF-9646-9852CF90F353}">
|
||||
<Class name="AddressType" field="value1" value="AZStd::map({74E4843B-0924-583D-8C6E-A37B09BD51FE})::PlatformSpecificOverrides·0/AZStd::pair({CAC4E67F-D626-5452-A057-ACB57D53F549})#1·0/" version="1" type="{90752F2D-CBD3-4EE9-9CDD-447E797C8408}"/>
|
||||
<Class name="any" field="value2" type="{03924488-C7F4-4D6D-948B-ABC2D1AE2FD3}"/>
|
||||
</Class>
|
||||
<Class name="AZStd::pair" field="element" type="{FED51EB4-F646-51FF-9646-9852CF90F353}">
|
||||
<Class name="AddressType" field="value1" value="AZStd::map({74E4843B-0924-583D-8C6E-A37B09BD51FE})::PlatformSpecificOverrides·0/AZStd::pair({CAC4E67F-D626-5452-A057-ACB57D53F549})#0·0/" version="1" type="{90752F2D-CBD3-4EE9-9CDD-447E797C8408}"/>
|
||||
<Class name="any" field="value2" type="{03924488-C7F4-4D6D-948B-ABC2D1AE2FD3}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
</Class>
|
||||
</Class>
|
||||
<Class name="AZStd::pair" field="element" type="{CAC4E67F-D626-5452-A057-ACB57D53F549}">
|
||||
<Class name="AZStd::string" field="value1" value="pc" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
|
||||
<Class name="DataPatch" field="value2" type="{BFF7A3F5-9014-4000-92C7-9B2BC7913DA9}">
|
||||
<Class name="AZ::Uuid" field="m_targetClassId" value="{980132FF-C450-425D-8AE0-BD96A8486177}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
|
||||
<Class name="unsigned int" field="m_targetClassVersion" value="2" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="AZStd::unordered_map" field="m_patch" type="{CEA836FC-77E0-5E46-BD0F-2E5A39D845E9}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
</Class>
|
||||
<Class name="AZStd::string" field="OverridingPlatform" value="" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
|
||||
</Class>
|
||||
</ObjectStream>
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:8a0935be7347d695ed1716d030b5bae68153a88239b0ff15f67f900ac90be442
|
||||
size 5038
|
||||
oid sha256:a7d94b9c0a77741736b93d8ed4d2b22bc9ae4cf649f3d8b3f10cbaf595a3ed31
|
||||
size 8336
|
||||
|
||||
@@ -0,0 +1,148 @@
|
||||
<ObjectStream version="3">
|
||||
<Class name="TextureSettings" version="2" type="{980132FF-C450-425D-8AE0-BD96A8486177}">
|
||||
<Class name="AZ::Uuid" field="PresetID" value="{00000000-0000-0000-0000-000000000000}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
|
||||
<Class name="Name" field="Preset" value="ReferenceImage" type="{3D2B920C-9EFD-40D5-AAE0-DF131C3D4931}"/>
|
||||
<Class name="unsigned int" field="SizeReduceLevel" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="bool" field="EngineReduce" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="bool" field="EnableMipmap" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="bool" field="MaintainAlphaCoverage" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="AZStd::vector" field="MipMapAlphaAdjustments" type="{3349AACD-BE04-50BC-9478-528BF2ACFD55}">
|
||||
<Class name="unsigned int" field="element" value="50" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="unsigned int" field="element" value="50" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="unsigned int" field="element" value="50" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="unsigned int" field="element" value="50" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="unsigned int" field="element" value="50" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="unsigned int" field="element" value="50" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
</Class>
|
||||
<Class name="unsigned int" field="MipMapGenEval" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="ImageProcessingAtom::MipGenType" field="MipMapGenType" value="1" type="{8524F650-1417-44DA-BBB0-C707A7A1A709}"/>
|
||||
<Class name="AZStd::map" field="PlatformSpecificOverrides" type="{74E4843B-0924-583D-8C6E-A37B09BD51FE}">
|
||||
<Class name="AZStd::pair" field="element" type="{CAC4E67F-D626-5452-A057-ACB57D53F549}">
|
||||
<Class name="AZStd::string" field="value1" value="android" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
|
||||
<Class name="DataPatch" field="value2" type="{BFF7A3F5-9014-4000-92C7-9B2BC7913DA9}">
|
||||
<Class name="AZ::Uuid" field="m_targetClassId" value="{980132FF-C450-425D-8AE0-BD96A8486177}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
|
||||
<Class name="unsigned int" field="m_targetClassVersion" value="2" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="AZStd::unordered_map" field="m_patch" type="{CEA836FC-77E0-5E46-BD0F-2E5A39D845E9}">
|
||||
<Class name="AZStd::pair" field="element" type="{FED51EB4-F646-51FF-9646-9852CF90F353}">
|
||||
<Class name="AddressType" field="value1" value="AZStd::map({74E4843B-0924-583D-8C6E-A37B09BD51FE})::PlatformSpecificOverrides·0/AZStd::pair({CAC4E67F-D626-5452-A057-ACB57D53F549})#4·0/" version="1" type="{90752F2D-CBD3-4EE9-9CDD-447E797C8408}"/>
|
||||
<Class name="any" field="value2" type="{03924488-C7F4-4D6D-948B-ABC2D1AE2FD3}"/>
|
||||
</Class>
|
||||
<Class name="AZStd::pair" field="element" type="{FED51EB4-F646-51FF-9646-9852CF90F353}">
|
||||
<Class name="AddressType" field="value1" value="AZStd::map({74E4843B-0924-583D-8C6E-A37B09BD51FE})::PlatformSpecificOverrides·0/AZStd::pair({CAC4E67F-D626-5452-A057-ACB57D53F549})#2·0/" version="1" type="{90752F2D-CBD3-4EE9-9CDD-447E797C8408}"/>
|
||||
<Class name="any" field="value2" type="{03924488-C7F4-4D6D-948B-ABC2D1AE2FD3}"/>
|
||||
</Class>
|
||||
<Class name="AZStd::pair" field="element" type="{FED51EB4-F646-51FF-9646-9852CF90F353}">
|
||||
<Class name="AddressType" field="value1" value="AZStd::map({74E4843B-0924-583D-8C6E-A37B09BD51FE})::PlatformSpecificOverrides·0/AZStd::pair({CAC4E67F-D626-5452-A057-ACB57D53F549})#3·0/" version="1" type="{90752F2D-CBD3-4EE9-9CDD-447E797C8408}"/>
|
||||
<Class name="any" field="value2" type="{03924488-C7F4-4D6D-948B-ABC2D1AE2FD3}"/>
|
||||
</Class>
|
||||
<Class name="AZStd::pair" field="element" type="{FED51EB4-F646-51FF-9646-9852CF90F353}">
|
||||
<Class name="AddressType" field="value1" value="AZStd::map({74E4843B-0924-583D-8C6E-A37B09BD51FE})::PlatformSpecificOverrides·0/AZStd::pair({CAC4E67F-D626-5452-A057-ACB57D53F549})#0·0/" version="1" type="{90752F2D-CBD3-4EE9-9CDD-447E797C8408}"/>
|
||||
<Class name="any" field="value2" type="{03924488-C7F4-4D6D-948B-ABC2D1AE2FD3}"/>
|
||||
</Class>
|
||||
<Class name="AZStd::pair" field="element" type="{FED51EB4-F646-51FF-9646-9852CF90F353}">
|
||||
<Class name="AddressType" field="value1" value="AZStd::map({74E4843B-0924-583D-8C6E-A37B09BD51FE})::PlatformSpecificOverrides·0/AZStd::pair({CAC4E67F-D626-5452-A057-ACB57D53F549})#1·0/" version="1" type="{90752F2D-CBD3-4EE9-9CDD-447E797C8408}"/>
|
||||
<Class name="any" field="value2" type="{03924488-C7F4-4D6D-948B-ABC2D1AE2FD3}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
</Class>
|
||||
</Class>
|
||||
<Class name="AZStd::pair" field="element" type="{CAC4E67F-D626-5452-A057-ACB57D53F549}">
|
||||
<Class name="AZStd::string" field="value1" value="ios" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
|
||||
<Class name="DataPatch" field="value2" type="{BFF7A3F5-9014-4000-92C7-9B2BC7913DA9}">
|
||||
<Class name="AZ::Uuid" field="m_targetClassId" value="{980132FF-C450-425D-8AE0-BD96A8486177}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
|
||||
<Class name="unsigned int" field="m_targetClassVersion" value="2" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="AZStd::unordered_map" field="m_patch" type="{CEA836FC-77E0-5E46-BD0F-2E5A39D845E9}">
|
||||
<Class name="AZStd::pair" field="element" type="{FED51EB4-F646-51FF-9646-9852CF90F353}">
|
||||
<Class name="AddressType" field="value1" value="AZStd::map({74E4843B-0924-583D-8C6E-A37B09BD51FE})::PlatformSpecificOverrides·0/AZStd::pair({CAC4E67F-D626-5452-A057-ACB57D53F549})#4·0/" version="1" type="{90752F2D-CBD3-4EE9-9CDD-447E797C8408}"/>
|
||||
<Class name="any" field="value2" type="{03924488-C7F4-4D6D-948B-ABC2D1AE2FD3}"/>
|
||||
</Class>
|
||||
<Class name="AZStd::pair" field="element" type="{FED51EB4-F646-51FF-9646-9852CF90F353}">
|
||||
<Class name="AddressType" field="value1" value="AZStd::map({74E4843B-0924-583D-8C6E-A37B09BD51FE})::PlatformSpecificOverrides·0/AZStd::pair({CAC4E67F-D626-5452-A057-ACB57D53F549})#2·0/" version="1" type="{90752F2D-CBD3-4EE9-9CDD-447E797C8408}"/>
|
||||
<Class name="any" field="value2" type="{03924488-C7F4-4D6D-948B-ABC2D1AE2FD3}"/>
|
||||
</Class>
|
||||
<Class name="AZStd::pair" field="element" type="{FED51EB4-F646-51FF-9646-9852CF90F353}">
|
||||
<Class name="AddressType" field="value1" value="AZStd::map({74E4843B-0924-583D-8C6E-A37B09BD51FE})::PlatformSpecificOverrides·0/AZStd::pair({CAC4E67F-D626-5452-A057-ACB57D53F549})#3·0/" version="1" type="{90752F2D-CBD3-4EE9-9CDD-447E797C8408}"/>
|
||||
<Class name="any" field="value2" type="{03924488-C7F4-4D6D-948B-ABC2D1AE2FD3}"/>
|
||||
</Class>
|
||||
<Class name="AZStd::pair" field="element" type="{FED51EB4-F646-51FF-9646-9852CF90F353}">
|
||||
<Class name="AddressType" field="value1" value="AZStd::map({74E4843B-0924-583D-8C6E-A37B09BD51FE})::PlatformSpecificOverrides·0/AZStd::pair({CAC4E67F-D626-5452-A057-ACB57D53F549})#0·0/" version="1" type="{90752F2D-CBD3-4EE9-9CDD-447E797C8408}"/>
|
||||
<Class name="any" field="value2" type="{03924488-C7F4-4D6D-948B-ABC2D1AE2FD3}"/>
|
||||
</Class>
|
||||
<Class name="AZStd::pair" field="element" type="{FED51EB4-F646-51FF-9646-9852CF90F353}">
|
||||
<Class name="AddressType" field="value1" value="AZStd::map({74E4843B-0924-583D-8C6E-A37B09BD51FE})::PlatformSpecificOverrides·0/AZStd::pair({CAC4E67F-D626-5452-A057-ACB57D53F549})#1·0/" version="1" type="{90752F2D-CBD3-4EE9-9CDD-447E797C8408}"/>
|
||||
<Class name="any" field="value2" type="{03924488-C7F4-4D6D-948B-ABC2D1AE2FD3}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
</Class>
|
||||
</Class>
|
||||
<Class name="AZStd::pair" field="element" type="{CAC4E67F-D626-5452-A057-ACB57D53F549}">
|
||||
<Class name="AZStd::string" field="value1" value="linux" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
|
||||
<Class name="DataPatch" field="value2" type="{BFF7A3F5-9014-4000-92C7-9B2BC7913DA9}">
|
||||
<Class name="AZ::Uuid" field="m_targetClassId" value="{980132FF-C450-425D-8AE0-BD96A8486177}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
|
||||
<Class name="unsigned int" field="m_targetClassVersion" value="2" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="AZStd::unordered_map" field="m_patch" type="{CEA836FC-77E0-5E46-BD0F-2E5A39D845E9}">
|
||||
<Class name="AZStd::pair" field="element" type="{FED51EB4-F646-51FF-9646-9852CF90F353}">
|
||||
<Class name="AddressType" field="value1" value="AZStd::map({74E4843B-0924-583D-8C6E-A37B09BD51FE})::PlatformSpecificOverrides·0/AZStd::pair({CAC4E67F-D626-5452-A057-ACB57D53F549})#4·0/" version="1" type="{90752F2D-CBD3-4EE9-9CDD-447E797C8408}"/>
|
||||
<Class name="any" field="value2" type="{03924488-C7F4-4D6D-948B-ABC2D1AE2FD3}"/>
|
||||
</Class>
|
||||
<Class name="AZStd::pair" field="element" type="{FED51EB4-F646-51FF-9646-9852CF90F353}">
|
||||
<Class name="AddressType" field="value1" value="AZStd::map({74E4843B-0924-583D-8C6E-A37B09BD51FE})::PlatformSpecificOverrides·0/AZStd::pair({CAC4E67F-D626-5452-A057-ACB57D53F549})#2·0/" version="1" type="{90752F2D-CBD3-4EE9-9CDD-447E797C8408}"/>
|
||||
<Class name="any" field="value2" type="{03924488-C7F4-4D6D-948B-ABC2D1AE2FD3}"/>
|
||||
</Class>
|
||||
<Class name="AZStd::pair" field="element" type="{FED51EB4-F646-51FF-9646-9852CF90F353}">
|
||||
<Class name="AddressType" field="value1" value="AZStd::map({74E4843B-0924-583D-8C6E-A37B09BD51FE})::PlatformSpecificOverrides·0/AZStd::pair({CAC4E67F-D626-5452-A057-ACB57D53F549})#3·0/" version="1" type="{90752F2D-CBD3-4EE9-9CDD-447E797C8408}"/>
|
||||
<Class name="any" field="value2" type="{03924488-C7F4-4D6D-948B-ABC2D1AE2FD3}"/>
|
||||
</Class>
|
||||
<Class name="AZStd::pair" field="element" type="{FED51EB4-F646-51FF-9646-9852CF90F353}">
|
||||
<Class name="AddressType" field="value1" value="AZStd::map({74E4843B-0924-583D-8C6E-A37B09BD51FE})::PlatformSpecificOverrides·0/AZStd::pair({CAC4E67F-D626-5452-A057-ACB57D53F549})#0·0/" version="1" type="{90752F2D-CBD3-4EE9-9CDD-447E797C8408}"/>
|
||||
<Class name="any" field="value2" type="{03924488-C7F4-4D6D-948B-ABC2D1AE2FD3}"/>
|
||||
</Class>
|
||||
<Class name="AZStd::pair" field="element" type="{FED51EB4-F646-51FF-9646-9852CF90F353}">
|
||||
<Class name="AddressType" field="value1" value="AZStd::map({74E4843B-0924-583D-8C6E-A37B09BD51FE})::PlatformSpecificOverrides·0/AZStd::pair({CAC4E67F-D626-5452-A057-ACB57D53F549})#1·0/" version="1" type="{90752F2D-CBD3-4EE9-9CDD-447E797C8408}"/>
|
||||
<Class name="any" field="value2" type="{03924488-C7F4-4D6D-948B-ABC2D1AE2FD3}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
</Class>
|
||||
</Class>
|
||||
<Class name="AZStd::pair" field="element" type="{CAC4E67F-D626-5452-A057-ACB57D53F549}">
|
||||
<Class name="AZStd::string" field="value1" value="mac" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
|
||||
<Class name="DataPatch" field="value2" type="{BFF7A3F5-9014-4000-92C7-9B2BC7913DA9}">
|
||||
<Class name="AZ::Uuid" field="m_targetClassId" value="{980132FF-C450-425D-8AE0-BD96A8486177}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
|
||||
<Class name="unsigned int" field="m_targetClassVersion" value="2" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="AZStd::unordered_map" field="m_patch" type="{CEA836FC-77E0-5E46-BD0F-2E5A39D845E9}">
|
||||
<Class name="AZStd::pair" field="element" type="{FED51EB4-F646-51FF-9646-9852CF90F353}">
|
||||
<Class name="AddressType" field="value1" value="AZStd::map({74E4843B-0924-583D-8C6E-A37B09BD51FE})::PlatformSpecificOverrides·0/AZStd::pair({CAC4E67F-D626-5452-A057-ACB57D53F549})#4·0/" version="1" type="{90752F2D-CBD3-4EE9-9CDD-447E797C8408}"/>
|
||||
<Class name="any" field="value2" type="{03924488-C7F4-4D6D-948B-ABC2D1AE2FD3}"/>
|
||||
</Class>
|
||||
<Class name="AZStd::pair" field="element" type="{FED51EB4-F646-51FF-9646-9852CF90F353}">
|
||||
<Class name="AddressType" field="value1" value="AZStd::map({74E4843B-0924-583D-8C6E-A37B09BD51FE})::PlatformSpecificOverrides·0/AZStd::pair({CAC4E67F-D626-5452-A057-ACB57D53F549})#2·0/" version="1" type="{90752F2D-CBD3-4EE9-9CDD-447E797C8408}"/>
|
||||
<Class name="any" field="value2" type="{03924488-C7F4-4D6D-948B-ABC2D1AE2FD3}"/>
|
||||
</Class>
|
||||
<Class name="AZStd::pair" field="element" type="{FED51EB4-F646-51FF-9646-9852CF90F353}">
|
||||
<Class name="AddressType" field="value1" value="AZStd::map({74E4843B-0924-583D-8C6E-A37B09BD51FE})::PlatformSpecificOverrides·0/AZStd::pair({CAC4E67F-D626-5452-A057-ACB57D53F549})#3·0/" version="1" type="{90752F2D-CBD3-4EE9-9CDD-447E797C8408}"/>
|
||||
<Class name="any" field="value2" type="{03924488-C7F4-4D6D-948B-ABC2D1AE2FD3}"/>
|
||||
</Class>
|
||||
<Class name="AZStd::pair" field="element" type="{FED51EB4-F646-51FF-9646-9852CF90F353}">
|
||||
<Class name="AddressType" field="value1" value="AZStd::map({74E4843B-0924-583D-8C6E-A37B09BD51FE})::PlatformSpecificOverrides·0/AZStd::pair({CAC4E67F-D626-5452-A057-ACB57D53F549})#0·0/" version="1" type="{90752F2D-CBD3-4EE9-9CDD-447E797C8408}"/>
|
||||
<Class name="any" field="value2" type="{03924488-C7F4-4D6D-948B-ABC2D1AE2FD3}"/>
|
||||
</Class>
|
||||
<Class name="AZStd::pair" field="element" type="{FED51EB4-F646-51FF-9646-9852CF90F353}">
|
||||
<Class name="AddressType" field="value1" value="AZStd::map({74E4843B-0924-583D-8C6E-A37B09BD51FE})::PlatformSpecificOverrides·0/AZStd::pair({CAC4E67F-D626-5452-A057-ACB57D53F549})#1·0/" version="1" type="{90752F2D-CBD3-4EE9-9CDD-447E797C8408}"/>
|
||||
<Class name="any" field="value2" type="{03924488-C7F4-4D6D-948B-ABC2D1AE2FD3}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
</Class>
|
||||
</Class>
|
||||
<Class name="AZStd::pair" field="element" type="{CAC4E67F-D626-5452-A057-ACB57D53F549}">
|
||||
<Class name="AZStd::string" field="value1" value="pc" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
|
||||
<Class name="DataPatch" field="value2" type="{BFF7A3F5-9014-4000-92C7-9B2BC7913DA9}">
|
||||
<Class name="AZ::Uuid" field="m_targetClassId" value="{980132FF-C450-425D-8AE0-BD96A8486177}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
|
||||
<Class name="unsigned int" field="m_targetClassVersion" value="2" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="AZStd::unordered_map" field="m_patch" type="{CEA836FC-77E0-5E46-BD0F-2E5A39D845E9}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
</Class>
|
||||
<Class name="AZStd::string" field="OverridingPlatform" value="" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
|
||||
</Class>
|
||||
</ObjectStream>
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:bb243cd6d6414b4e95eab919fa94193b57825902b8d09f40ce3f334d829e74e2
|
||||
size 6286
|
||||
oid sha256:3bbd45e3ef81850da81d1cc01775930a53c424e64e287b00990af3e7e6a682ba
|
||||
size 9701
|
||||
|
||||
@@ -0,0 +1,148 @@
|
||||
<ObjectStream version="3">
|
||||
<Class name="TextureSettings" version="2" type="{980132FF-C450-425D-8AE0-BD96A8486177}">
|
||||
<Class name="AZ::Uuid" field="PresetID" value="{00000000-0000-0000-0000-000000000000}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
|
||||
<Class name="Name" field="Preset" value="ReferenceImage" type="{3D2B920C-9EFD-40D5-AAE0-DF131C3D4931}"/>
|
||||
<Class name="unsigned int" field="SizeReduceLevel" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="bool" field="EngineReduce" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="bool" field="EnableMipmap" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="bool" field="MaintainAlphaCoverage" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="AZStd::vector" field="MipMapAlphaAdjustments" type="{3349AACD-BE04-50BC-9478-528BF2ACFD55}">
|
||||
<Class name="unsigned int" field="element" value="50" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="unsigned int" field="element" value="50" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="unsigned int" field="element" value="50" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="unsigned int" field="element" value="50" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="unsigned int" field="element" value="50" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="unsigned int" field="element" value="50" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
</Class>
|
||||
<Class name="unsigned int" field="MipMapGenEval" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="ImageProcessingAtom::MipGenType" field="MipMapGenType" value="1" type="{8524F650-1417-44DA-BBB0-C707A7A1A709}"/>
|
||||
<Class name="AZStd::map" field="PlatformSpecificOverrides" type="{74E4843B-0924-583D-8C6E-A37B09BD51FE}">
|
||||
<Class name="AZStd::pair" field="element" type="{CAC4E67F-D626-5452-A057-ACB57D53F549}">
|
||||
<Class name="AZStd::string" field="value1" value="android" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
|
||||
<Class name="DataPatch" field="value2" type="{BFF7A3F5-9014-4000-92C7-9B2BC7913DA9}">
|
||||
<Class name="AZ::Uuid" field="m_targetClassId" value="{980132FF-C450-425D-8AE0-BD96A8486177}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
|
||||
<Class name="unsigned int" field="m_targetClassVersion" value="2" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="AZStd::unordered_map" field="m_patch" type="{CEA836FC-77E0-5E46-BD0F-2E5A39D845E9}">
|
||||
<Class name="AZStd::pair" field="element" type="{FED51EB4-F646-51FF-9646-9852CF90F353}">
|
||||
<Class name="AddressType" field="value1" value="AZStd::map({74E4843B-0924-583D-8C6E-A37B09BD51FE})::PlatformSpecificOverrides·0/AZStd::pair({CAC4E67F-D626-5452-A057-ACB57D53F549})#4·0/" version="1" type="{90752F2D-CBD3-4EE9-9CDD-447E797C8408}"/>
|
||||
<Class name="any" field="value2" type="{03924488-C7F4-4D6D-948B-ABC2D1AE2FD3}"/>
|
||||
</Class>
|
||||
<Class name="AZStd::pair" field="element" type="{FED51EB4-F646-51FF-9646-9852CF90F353}">
|
||||
<Class name="AddressType" field="value1" value="AZStd::map({74E4843B-0924-583D-8C6E-A37B09BD51FE})::PlatformSpecificOverrides·0/AZStd::pair({CAC4E67F-D626-5452-A057-ACB57D53F549})#2·0/" version="1" type="{90752F2D-CBD3-4EE9-9CDD-447E797C8408}"/>
|
||||
<Class name="any" field="value2" type="{03924488-C7F4-4D6D-948B-ABC2D1AE2FD3}"/>
|
||||
</Class>
|
||||
<Class name="AZStd::pair" field="element" type="{FED51EB4-F646-51FF-9646-9852CF90F353}">
|
||||
<Class name="AddressType" field="value1" value="AZStd::map({74E4843B-0924-583D-8C6E-A37B09BD51FE})::PlatformSpecificOverrides·0/AZStd::pair({CAC4E67F-D626-5452-A057-ACB57D53F549})#3·0/" version="1" type="{90752F2D-CBD3-4EE9-9CDD-447E797C8408}"/>
|
||||
<Class name="any" field="value2" type="{03924488-C7F4-4D6D-948B-ABC2D1AE2FD3}"/>
|
||||
</Class>
|
||||
<Class name="AZStd::pair" field="element" type="{FED51EB4-F646-51FF-9646-9852CF90F353}">
|
||||
<Class name="AddressType" field="value1" value="AZStd::map({74E4843B-0924-583D-8C6E-A37B09BD51FE})::PlatformSpecificOverrides·0/AZStd::pair({CAC4E67F-D626-5452-A057-ACB57D53F549})#0·0/" version="1" type="{90752F2D-CBD3-4EE9-9CDD-447E797C8408}"/>
|
||||
<Class name="any" field="value2" type="{03924488-C7F4-4D6D-948B-ABC2D1AE2FD3}"/>
|
||||
</Class>
|
||||
<Class name="AZStd::pair" field="element" type="{FED51EB4-F646-51FF-9646-9852CF90F353}">
|
||||
<Class name="AddressType" field="value1" value="AZStd::map({74E4843B-0924-583D-8C6E-A37B09BD51FE})::PlatformSpecificOverrides·0/AZStd::pair({CAC4E67F-D626-5452-A057-ACB57D53F549})#1·0/" version="1" type="{90752F2D-CBD3-4EE9-9CDD-447E797C8408}"/>
|
||||
<Class name="any" field="value2" type="{03924488-C7F4-4D6D-948B-ABC2D1AE2FD3}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
</Class>
|
||||
</Class>
|
||||
<Class name="AZStd::pair" field="element" type="{CAC4E67F-D626-5452-A057-ACB57D53F549}">
|
||||
<Class name="AZStd::string" field="value1" value="ios" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
|
||||
<Class name="DataPatch" field="value2" type="{BFF7A3F5-9014-4000-92C7-9B2BC7913DA9}">
|
||||
<Class name="AZ::Uuid" field="m_targetClassId" value="{980132FF-C450-425D-8AE0-BD96A8486177}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
|
||||
<Class name="unsigned int" field="m_targetClassVersion" value="2" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="AZStd::unordered_map" field="m_patch" type="{CEA836FC-77E0-5E46-BD0F-2E5A39D845E9}">
|
||||
<Class name="AZStd::pair" field="element" type="{FED51EB4-F646-51FF-9646-9852CF90F353}">
|
||||
<Class name="AddressType" field="value1" value="AZStd::map({74E4843B-0924-583D-8C6E-A37B09BD51FE})::PlatformSpecificOverrides·0/AZStd::pair({CAC4E67F-D626-5452-A057-ACB57D53F549})#4·0/" version="1" type="{90752F2D-CBD3-4EE9-9CDD-447E797C8408}"/>
|
||||
<Class name="any" field="value2" type="{03924488-C7F4-4D6D-948B-ABC2D1AE2FD3}"/>
|
||||
</Class>
|
||||
<Class name="AZStd::pair" field="element" type="{FED51EB4-F646-51FF-9646-9852CF90F353}">
|
||||
<Class name="AddressType" field="value1" value="AZStd::map({74E4843B-0924-583D-8C6E-A37B09BD51FE})::PlatformSpecificOverrides·0/AZStd::pair({CAC4E67F-D626-5452-A057-ACB57D53F549})#2·0/" version="1" type="{90752F2D-CBD3-4EE9-9CDD-447E797C8408}"/>
|
||||
<Class name="any" field="value2" type="{03924488-C7F4-4D6D-948B-ABC2D1AE2FD3}"/>
|
||||
</Class>
|
||||
<Class name="AZStd::pair" field="element" type="{FED51EB4-F646-51FF-9646-9852CF90F353}">
|
||||
<Class name="AddressType" field="value1" value="AZStd::map({74E4843B-0924-583D-8C6E-A37B09BD51FE})::PlatformSpecificOverrides·0/AZStd::pair({CAC4E67F-D626-5452-A057-ACB57D53F549})#0·0/" version="1" type="{90752F2D-CBD3-4EE9-9CDD-447E797C8408}"/>
|
||||
<Class name="any" field="value2" type="{03924488-C7F4-4D6D-948B-ABC2D1AE2FD3}"/>
|
||||
</Class>
|
||||
<Class name="AZStd::pair" field="element" type="{FED51EB4-F646-51FF-9646-9852CF90F353}">
|
||||
<Class name="AddressType" field="value1" value="AZStd::map({74E4843B-0924-583D-8C6E-A37B09BD51FE})::PlatformSpecificOverrides·0/AZStd::pair({CAC4E67F-D626-5452-A057-ACB57D53F549})#3·0/" version="1" type="{90752F2D-CBD3-4EE9-9CDD-447E797C8408}"/>
|
||||
<Class name="any" field="value2" type="{03924488-C7F4-4D6D-948B-ABC2D1AE2FD3}"/>
|
||||
</Class>
|
||||
<Class name="AZStd::pair" field="element" type="{FED51EB4-F646-51FF-9646-9852CF90F353}">
|
||||
<Class name="AddressType" field="value1" value="AZStd::map({74E4843B-0924-583D-8C6E-A37B09BD51FE})::PlatformSpecificOverrides·0/AZStd::pair({CAC4E67F-D626-5452-A057-ACB57D53F549})#1·0/" version="1" type="{90752F2D-CBD3-4EE9-9CDD-447E797C8408}"/>
|
||||
<Class name="any" field="value2" type="{03924488-C7F4-4D6D-948B-ABC2D1AE2FD3}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
</Class>
|
||||
</Class>
|
||||
<Class name="AZStd::pair" field="element" type="{CAC4E67F-D626-5452-A057-ACB57D53F549}">
|
||||
<Class name="AZStd::string" field="value1" value="linux" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
|
||||
<Class name="DataPatch" field="value2" type="{BFF7A3F5-9014-4000-92C7-9B2BC7913DA9}">
|
||||
<Class name="AZ::Uuid" field="m_targetClassId" value="{980132FF-C450-425D-8AE0-BD96A8486177}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
|
||||
<Class name="unsigned int" field="m_targetClassVersion" value="2" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="AZStd::unordered_map" field="m_patch" type="{CEA836FC-77E0-5E46-BD0F-2E5A39D845E9}">
|
||||
<Class name="AZStd::pair" field="element" type="{FED51EB4-F646-51FF-9646-9852CF90F353}">
|
||||
<Class name="AddressType" field="value1" value="AZStd::map({74E4843B-0924-583D-8C6E-A37B09BD51FE})::PlatformSpecificOverrides·0/AZStd::pair({CAC4E67F-D626-5452-A057-ACB57D53F549})#4·0/" version="1" type="{90752F2D-CBD3-4EE9-9CDD-447E797C8408}"/>
|
||||
<Class name="any" field="value2" type="{03924488-C7F4-4D6D-948B-ABC2D1AE2FD3}"/>
|
||||
</Class>
|
||||
<Class name="AZStd::pair" field="element" type="{FED51EB4-F646-51FF-9646-9852CF90F353}">
|
||||
<Class name="AddressType" field="value1" value="AZStd::map({74E4843B-0924-583D-8C6E-A37B09BD51FE})::PlatformSpecificOverrides·0/AZStd::pair({CAC4E67F-D626-5452-A057-ACB57D53F549})#2·0/" version="1" type="{90752F2D-CBD3-4EE9-9CDD-447E797C8408}"/>
|
||||
<Class name="any" field="value2" type="{03924488-C7F4-4D6D-948B-ABC2D1AE2FD3}"/>
|
||||
</Class>
|
||||
<Class name="AZStd::pair" field="element" type="{FED51EB4-F646-51FF-9646-9852CF90F353}">
|
||||
<Class name="AddressType" field="value1" value="AZStd::map({74E4843B-0924-583D-8C6E-A37B09BD51FE})::PlatformSpecificOverrides·0/AZStd::pair({CAC4E67F-D626-5452-A057-ACB57D53F549})#3·0/" version="1" type="{90752F2D-CBD3-4EE9-9CDD-447E797C8408}"/>
|
||||
<Class name="any" field="value2" type="{03924488-C7F4-4D6D-948B-ABC2D1AE2FD3}"/>
|
||||
</Class>
|
||||
<Class name="AZStd::pair" field="element" type="{FED51EB4-F646-51FF-9646-9852CF90F353}">
|
||||
<Class name="AddressType" field="value1" value="AZStd::map({74E4843B-0924-583D-8C6E-A37B09BD51FE})::PlatformSpecificOverrides·0/AZStd::pair({CAC4E67F-D626-5452-A057-ACB57D53F549})#0·0/" version="1" type="{90752F2D-CBD3-4EE9-9CDD-447E797C8408}"/>
|
||||
<Class name="any" field="value2" type="{03924488-C7F4-4D6D-948B-ABC2D1AE2FD3}"/>
|
||||
</Class>
|
||||
<Class name="AZStd::pair" field="element" type="{FED51EB4-F646-51FF-9646-9852CF90F353}">
|
||||
<Class name="AddressType" field="value1" value="AZStd::map({74E4843B-0924-583D-8C6E-A37B09BD51FE})::PlatformSpecificOverrides·0/AZStd::pair({CAC4E67F-D626-5452-A057-ACB57D53F549})#1·0/" version="1" type="{90752F2D-CBD3-4EE9-9CDD-447E797C8408}"/>
|
||||
<Class name="any" field="value2" type="{03924488-C7F4-4D6D-948B-ABC2D1AE2FD3}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
</Class>
|
||||
</Class>
|
||||
<Class name="AZStd::pair" field="element" type="{CAC4E67F-D626-5452-A057-ACB57D53F549}">
|
||||
<Class name="AZStd::string" field="value1" value="mac" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
|
||||
<Class name="DataPatch" field="value2" type="{BFF7A3F5-9014-4000-92C7-9B2BC7913DA9}">
|
||||
<Class name="AZ::Uuid" field="m_targetClassId" value="{980132FF-C450-425D-8AE0-BD96A8486177}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
|
||||
<Class name="unsigned int" field="m_targetClassVersion" value="2" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="AZStd::unordered_map" field="m_patch" type="{CEA836FC-77E0-5E46-BD0F-2E5A39D845E9}">
|
||||
<Class name="AZStd::pair" field="element" type="{FED51EB4-F646-51FF-9646-9852CF90F353}">
|
||||
<Class name="AddressType" field="value1" value="AZStd::map({74E4843B-0924-583D-8C6E-A37B09BD51FE})::PlatformSpecificOverrides·0/AZStd::pair({CAC4E67F-D626-5452-A057-ACB57D53F549})#4·0/" version="1" type="{90752F2D-CBD3-4EE9-9CDD-447E797C8408}"/>
|
||||
<Class name="any" field="value2" type="{03924488-C7F4-4D6D-948B-ABC2D1AE2FD3}"/>
|
||||
</Class>
|
||||
<Class name="AZStd::pair" field="element" type="{FED51EB4-F646-51FF-9646-9852CF90F353}">
|
||||
<Class name="AddressType" field="value1" value="AZStd::map({74E4843B-0924-583D-8C6E-A37B09BD51FE})::PlatformSpecificOverrides·0/AZStd::pair({CAC4E67F-D626-5452-A057-ACB57D53F549})#2·0/" version="1" type="{90752F2D-CBD3-4EE9-9CDD-447E797C8408}"/>
|
||||
<Class name="any" field="value2" type="{03924488-C7F4-4D6D-948B-ABC2D1AE2FD3}"/>
|
||||
</Class>
|
||||
<Class name="AZStd::pair" field="element" type="{FED51EB4-F646-51FF-9646-9852CF90F353}">
|
||||
<Class name="AddressType" field="value1" value="AZStd::map({74E4843B-0924-583D-8C6E-A37B09BD51FE})::PlatformSpecificOverrides·0/AZStd::pair({CAC4E67F-D626-5452-A057-ACB57D53F549})#3·0/" version="1" type="{90752F2D-CBD3-4EE9-9CDD-447E797C8408}"/>
|
||||
<Class name="any" field="value2" type="{03924488-C7F4-4D6D-948B-ABC2D1AE2FD3}"/>
|
||||
</Class>
|
||||
<Class name="AZStd::pair" field="element" type="{FED51EB4-F646-51FF-9646-9852CF90F353}">
|
||||
<Class name="AddressType" field="value1" value="AZStd::map({74E4843B-0924-583D-8C6E-A37B09BD51FE})::PlatformSpecificOverrides·0/AZStd::pair({CAC4E67F-D626-5452-A057-ACB57D53F549})#0·0/" version="1" type="{90752F2D-CBD3-4EE9-9CDD-447E797C8408}"/>
|
||||
<Class name="any" field="value2" type="{03924488-C7F4-4D6D-948B-ABC2D1AE2FD3}"/>
|
||||
</Class>
|
||||
<Class name="AZStd::pair" field="element" type="{FED51EB4-F646-51FF-9646-9852CF90F353}">
|
||||
<Class name="AddressType" field="value1" value="AZStd::map({74E4843B-0924-583D-8C6E-A37B09BD51FE})::PlatformSpecificOverrides·0/AZStd::pair({CAC4E67F-D626-5452-A057-ACB57D53F549})#1·0/" version="1" type="{90752F2D-CBD3-4EE9-9CDD-447E797C8408}"/>
|
||||
<Class name="any" field="value2" type="{03924488-C7F4-4D6D-948B-ABC2D1AE2FD3}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
</Class>
|
||||
</Class>
|
||||
<Class name="AZStd::pair" field="element" type="{CAC4E67F-D626-5452-A057-ACB57D53F549}">
|
||||
<Class name="AZStd::string" field="value1" value="pc" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
|
||||
<Class name="DataPatch" field="value2" type="{BFF7A3F5-9014-4000-92C7-9B2BC7913DA9}">
|
||||
<Class name="AZ::Uuid" field="m_targetClassId" value="{980132FF-C450-425D-8AE0-BD96A8486177}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
|
||||
<Class name="unsigned int" field="m_targetClassVersion" value="2" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="AZStd::unordered_map" field="m_patch" type="{CEA836FC-77E0-5E46-BD0F-2E5A39D845E9}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
</Class>
|
||||
<Class name="AZStd::string" field="OverridingPlatform" value="" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
|
||||
</Class>
|
||||
</ObjectStream>
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <AzCore/JSON/document.h>
|
||||
|
||||
#include <Atom/RPI.Reflect/Image/StreamingImageAsset.h>
|
||||
#include <Atom/RPI.Reflect/Asset/AssetUtils.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
@@ -21,21 +22,24 @@ namespace AZ
|
||||
{
|
||||
// Declarations...
|
||||
|
||||
Outcome<Data::AssetId> MakeAssetId(const AZStd::string& sourcePath, uint32_t productSubId);
|
||||
// Note that these functions default to TraceLevel::Error to preserve legacy behavior of these APIs. It would be nice to make the default match
|
||||
// RPI.Reflect/Asset/AssetUtils.h which is TraceLevel::Warning, but we are close to a release so it isn't worth the risk at this time.
|
||||
|
||||
Outcome<Data::AssetId> MakeAssetId(const AZStd::string& originatingSourcePath, const AZStd::string& referencedSourceFilePath, uint32_t productSubId);
|
||||
Outcome<Data::AssetId> MakeAssetId(const AZStd::string& sourcePath, uint32_t productSubId, TraceLevel reporting = TraceLevel::Error);
|
||||
|
||||
Outcome<Data::AssetId> MakeAssetId(const AZStd::string& originatingSourcePath, const AZStd::string& referencedSourceFilePath, uint32_t productSubId, TraceLevel reporting = TraceLevel::Error);
|
||||
|
||||
template<typename AssetDataT>
|
||||
Outcome<AZ::Data::Asset<AssetDataT>> LoadAsset(const AZStd::string& sourcePath, uint32_t productSubId = 0);
|
||||
Outcome<AZ::Data::Asset<AssetDataT>> LoadAsset(const AZStd::string& sourcePath, uint32_t productSubId = 0, TraceLevel reporting = TraceLevel::Error);
|
||||
|
||||
template<typename AssetDataT>
|
||||
Outcome<AZ::Data::Asset<AssetDataT>> LoadAsset(const AZStd::string& originatingSourcePath, const AZStd::string& referencedSourceFilePath, uint32_t productSubId = 0);
|
||||
Outcome<AZ::Data::Asset<AssetDataT>> LoadAsset(const AZStd::string& originatingSourcePath, const AZStd::string& referencedSourceFilePath, uint32_t productSubId = 0, TraceLevel reporting = TraceLevel::Error);
|
||||
|
||||
template<typename AssetDataT>
|
||||
Outcome<AZ::Data::Asset<AssetDataT>> LoadAsset(const AZ::Data::AssetId& assetId, const char* sourcePathForDebug);
|
||||
Outcome<AZ::Data::Asset<AssetDataT>> LoadAsset(const AZ::Data::AssetId& assetId, const char* sourcePathForDebug, TraceLevel reporting = TraceLevel::Error);
|
||||
|
||||
template<typename AssetDataT>
|
||||
Outcome<AZ::Data::Asset<AssetDataT>> LoadAsset(const AZ::Data::AssetId& assetId);
|
||||
Outcome<AZ::Data::Asset<AssetDataT>> LoadAsset(const AZ::Data::AssetId& assetId, TraceLevel reporting = TraceLevel::Error);
|
||||
|
||||
//! Attempts to resolve the full path to a product asset given its ID
|
||||
AZStd::string GetProductPathByAssetId(const AZ::Data::AssetId& assetId);
|
||||
@@ -65,12 +69,12 @@ namespace AZ
|
||||
// Definitions...
|
||||
|
||||
template<typename AssetDataT>
|
||||
Outcome<AZ::Data::Asset<AssetDataT>> LoadAsset(const AZStd::string& sourcePath, uint32_t productSubId)
|
||||
Outcome<AZ::Data::Asset<AssetDataT>> LoadAsset(const AZStd::string& sourcePath, uint32_t productSubId, TraceLevel reporting)
|
||||
{
|
||||
auto assetId = MakeAssetId(sourcePath, productSubId);
|
||||
auto assetId = MakeAssetId(sourcePath, productSubId, reporting);
|
||||
if (assetId.IsSuccess())
|
||||
{
|
||||
return LoadAsset<AssetDataT>(assetId.GetValue(), sourcePath.c_str());
|
||||
return LoadAsset<AssetDataT>(assetId.GetValue(), sourcePath.c_str(), reporting);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -79,20 +83,20 @@ namespace AZ
|
||||
}
|
||||
|
||||
template<typename AssetDataT>
|
||||
Outcome<AZ::Data::Asset<AssetDataT>> LoadAsset(const AZStd::string& originatingSourcePath, const AZStd::string& referencedSourceFilePath, uint32_t productSubId)
|
||||
Outcome<AZ::Data::Asset<AssetDataT>> LoadAsset(const AZStd::string& originatingSourcePath, const AZStd::string& referencedSourceFilePath, uint32_t productSubId, TraceLevel reporting)
|
||||
{
|
||||
AZStd::string resolvedPath = ResolvePathReference(originatingSourcePath, referencedSourceFilePath);
|
||||
return LoadAsset<AssetDataT>(resolvedPath, productSubId);
|
||||
return LoadAsset<AssetDataT>(resolvedPath, productSubId, reporting);
|
||||
}
|
||||
|
||||
template<typename AssetDataT>
|
||||
Outcome<AZ::Data::Asset<AssetDataT>> LoadAsset(const AZ::Data::AssetId& assetId)
|
||||
Outcome<AZ::Data::Asset<AssetDataT>> LoadAsset(const AZ::Data::AssetId& assetId, TraceLevel reporting)
|
||||
{
|
||||
return LoadAsset<AssetDataT>(assetId, nullptr);
|
||||
return LoadAsset<AssetDataT>(assetId, nullptr, reporting);
|
||||
}
|
||||
|
||||
template<typename AssetDataT>
|
||||
Outcome<AZ::Data::Asset<AssetDataT>> LoadAsset(const AZ::Data::AssetId& assetId, [[maybe_unused]] const char* sourcePathForDebug)
|
||||
Outcome<AZ::Data::Asset<AssetDataT>> LoadAsset(const AZ::Data::AssetId& assetId, [[maybe_unused]] const char* sourcePathForDebug, TraceLevel reporting)
|
||||
{
|
||||
if (nullptr == AZ::IO::FileIOBase::GetInstance()->GetAlias("@products@"))
|
||||
{
|
||||
@@ -111,11 +115,11 @@ namespace AZ
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Error("AssetUtils", false, "Could not load %s [Source='%s' Cache='%s' AssetID=%s] ",
|
||||
AssetUtilsInternal::ReportIssue(reporting, AZStd::string::format("Could not load %s [Source='%s' Cache='%s' AssetID=%s] ",
|
||||
AzTypeInfo<AssetDataT>::Name(),
|
||||
sourcePathForDebug ? sourcePathForDebug : "<unknown>",
|
||||
asset.GetHint().empty() ? "<unknown>" : asset.GetHint().c_str(),
|
||||
assetId.ToString<AZStd::string>().c_str());
|
||||
assetId.ToString<AZStd::string>().c_str()).c_str());
|
||||
|
||||
return AZ::Failure();
|
||||
}
|
||||
|
||||
@@ -28,7 +28,18 @@ namespace AZ
|
||||
|
||||
namespace MaterialUtils
|
||||
{
|
||||
Outcome<Data::Asset<ImageAsset>> GetImageAssetReference(AZStd::string_view materialSourceFilePath, const AZStd::string imageFilePath);
|
||||
enum class GetImageAssetResult
|
||||
{
|
||||
Empty, //! No image was actually requested, the path was empty
|
||||
Found, //! The requested asset was found
|
||||
Missing //! The requested asset was not found, and a placeholder asset was used instead
|
||||
};
|
||||
|
||||
//! Finds an ImageAsset referenced by a material file (or a placeholder)
|
||||
//! @param imageAsset the resulting ImageAsset
|
||||
//! @param materialSourceFilePath the full path to a material source file that is referenfing an image file
|
||||
//! @param imageFilePath the path to an image source file, which could be relative to the asset root or relative to the material file
|
||||
GetImageAssetResult GetImageAssetReference(Data::Asset<ImageAsset>& imageAsset, AZStd::string_view materialSourceFilePath, const AZStd::string imageFilePath);
|
||||
|
||||
//! Resolve an enum to a uint32_t given its name and definition array (in MaterialPropertyDescriptor).
|
||||
//! @param propertyDescriptor it contains the definition of all enum names in an array.
|
||||
|
||||
@@ -147,6 +147,30 @@ namespace AZ
|
||||
//! @param viewProjOverrideIndex Which view projection override entry to use, -1 if unused
|
||||
virtual void DrawSphere( const AZ::Vector3& center, float radius, const AZ::Color& color, DrawStyle style = DrawStyle::Shaded, DepthTest depthTest = DepthTest::On, DepthWrite depthWrite = DepthWrite::On, FaceCullMode faceCull = FaceCullMode::Back, int32_t viewProjOverrideIndex = -1) = 0;
|
||||
|
||||
//! Draw a sphere.
|
||||
//! @param center The center of the sphere.
|
||||
//! @param direction The direction vector. The Pole of the hemisphere will point along this vector.
|
||||
//! @param radius The radius.
|
||||
//! @param color The color to draw the sphere.
|
||||
//! @param style The draw style (point, wireframe, solid, shaded etc).
|
||||
//! @param depthTest If depth testing should be enabled
|
||||
//! @param depthWrite If depth writing should be enabled
|
||||
//! @param faceCull Which (if any) facing triangles should be culled
|
||||
//! @param viewProjOverrideIndex Which view projection override entry to use, -1 if unused
|
||||
virtual void DrawSphere(const AZ::Vector3& center, const AZ::Vector3& direction, float radius, const AZ::Color& color, DrawStyle style = DrawStyle::Shaded, DepthTest depthTest = DepthTest::On, DepthWrite depthWrite = DepthWrite::On, FaceCullMode faceCull = FaceCullMode::Back, int32_t viewProjOverrideIndex = -1) = 0;
|
||||
|
||||
//! Draw a hemisphere.
|
||||
//! @param center The center of the sphere.
|
||||
//! @param direction The direction vector. The Pole of the hemisphere will point along this vector.
|
||||
//! @param radius The radius.
|
||||
//! @param color The color to draw the sphere.
|
||||
//! @param style The draw style (point, wireframe, solid, shaded etc).
|
||||
//! @param depthTest If depth testing should be enabled
|
||||
//! @param depthWrite If depth writing should be enabled
|
||||
//! @param faceCull Which (if any) facing triangles should be culled
|
||||
//! @param viewProjOverrideIndex Which view projection override entry to use, -1 if unused
|
||||
virtual void DrawHemisphere( const AZ::Vector3& center, const AZ::Vector3& direction, float radius, const AZ::Color& color, DrawStyle style = DrawStyle::Shaded, DepthTest depthTest = DepthTest::On, DepthWrite depthWrite = DepthWrite::On, FaceCullMode faceCull = FaceCullMode::Back, int32_t viewProjOverrideIndex = -1) = 0;
|
||||
|
||||
//! Draw a disk.
|
||||
//! @param center The center of the disk.
|
||||
//! @param direction The direction vector. The disk will be orthogonal this vector.
|
||||
@@ -172,7 +196,7 @@ namespace AZ
|
||||
//! @param viewProjOverrideIndex Which view projection override entry to use, -1 if unused
|
||||
virtual void DrawCone(const AZ::Vector3& center, const AZ::Vector3& direction, float radius, float height, const AZ::Color& color, DrawStyle style = DrawStyle::Shaded, DepthTest depthTest = DepthTest::On, DepthWrite depthWrite = DepthWrite::On, FaceCullMode faceCull = FaceCullMode::Back, int32_t viewProjOverrideIndex = -1) = 0;
|
||||
|
||||
//! Draw a cylinder.
|
||||
//! Draw a cylinder (with flat disks on the end).
|
||||
//! @param center The center of the base circle.
|
||||
//! @param direction The direction vector. The top end cap of the cylinder will face along this vector.
|
||||
//! @param radius The radius.
|
||||
@@ -185,6 +209,19 @@ namespace AZ
|
||||
//! @param viewProjOverrideIndex Which view projection override entry to use, -1 if unused
|
||||
virtual void DrawCylinder(const AZ::Vector3& center, const AZ::Vector3& direction, float radius, float height, const AZ::Color& color, DrawStyle style = DrawStyle::Shaded, DepthTest depthTest = DepthTest::On, DepthWrite depthWrite = DepthWrite::On, FaceCullMode faceCull = FaceCullMode::Back, int32_t viewProjOverrideIndex = -1) = 0;
|
||||
|
||||
//! Draw a cylinder without flat disk on the end.
|
||||
//! @param center The center of the base circle.
|
||||
//! @param direction The direction vector. The top end cap of the cylinder will face along this vector.
|
||||
//! @param radius The radius.
|
||||
//! @param height The height of the cylinder.
|
||||
//! @param color The color to draw the cylinder.
|
||||
//! @param style The draw style (point, wireframe, solid, shaded etc).
|
||||
//! @param depthTest If depth testing should be enabled
|
||||
//! @param depthWrite If depth writing should be enabled
|
||||
//! @param faceCull Which (if any) facing triangles should be culled
|
||||
//! @param viewProjOverrideIndex Which view projection override entry to use, -1 if unused
|
||||
virtual void DrawCylinderNoEnds(const AZ::Vector3& center, const AZ::Vector3& direction, float radius, float height, const AZ::Color& color, DrawStyle style = DrawStyle::Shaded, DepthTest depthTest = DepthTest::On, DepthWrite depthWrite = DepthWrite::On, FaceCullMode faceCull = FaceCullMode::Back, int32_t viewProjOverrideIndex = -1) = 0;
|
||||
|
||||
//! Draw an axis-aligned bounding box with no transform.
|
||||
//! @param aabb The AABB (typically the bounding box of a set of world space points).
|
||||
//! @param color The color to draw the box.
|
||||
|
||||
@@ -29,6 +29,14 @@ namespace AZ
|
||||
Count
|
||||
};
|
||||
|
||||
namespace DefaultImageAssetPaths
|
||||
{
|
||||
static constexpr char DefaultFallback[] = "textures/defaults/defaultfallback.png.streamingimage";
|
||||
static constexpr char Processing[] = "textures/defaults/processing.png.streamingimage";
|
||||
static constexpr char ProcessingFailed[] = "textures/defaults/processingfailed.png.streamingimage";
|
||||
static constexpr char Missing[] = "textures/defaults/missing.png.streamingimage";
|
||||
}
|
||||
|
||||
class ImageSystemInterface
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -63,11 +63,21 @@ namespace AZ
|
||||
{
|
||||
BusDisconnect();
|
||||
}
|
||||
|
||||
bool MaterialBuilder::ReportMaterialAssetWarningsAsErrors() const
|
||||
{
|
||||
bool warningsAsErrors = false;
|
||||
if (auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry != nullptr)
|
||||
{
|
||||
settingsRegistry->Get(warningsAsErrors, "/O3DE/Atom/RPI/MaterialBuilder/WarningsAsErrors");
|
||||
}
|
||||
return warningsAsErrors;
|
||||
}
|
||||
|
||||
//! Adds all relevant dependencies for a referenced source file, considering that the path might be relative to the original file location or a full asset path.
|
||||
//! This will usually include multiple source dependencies and a single job dependency, but will include only source dependencies if the file is not found.
|
||||
//! Note the AssetBuilderSDK::JobDependency::m_platformIdentifier will not be set by this function. The calling code must set this value before passing back
|
||||
//! to the AssetBuilderSDK::CreateJobsResponse. If isOrderedOnceForMaterialTypes is true and the dependency is a materialtype file, the job dependency type
|
||||
//! to the AssetBuilderSDK::CreateJobsResponse. If isOrderedOnceForMaterialTypes is true and the dependency is a .materialtype file, the job dependency type
|
||||
//! will be set to JobDependencyType::OrderOnce.
|
||||
void AddPossibleDependencies(AZStd::string_view currentFilePath,
|
||||
AZStd::string_view referencedParentPath,
|
||||
@@ -277,8 +287,8 @@ namespace AZ
|
||||
|
||||
return materialTypeAssetOutcome.GetValue();
|
||||
}
|
||||
|
||||
AZ::Data::Asset<MaterialAsset> CreateMaterialAsset(AZStd::string_view materialSourceFilePath, const rapidjson::Value& json)
|
||||
|
||||
AZ::Data::Asset<MaterialAsset> MaterialBuilder::CreateMaterialAsset(AZStd::string_view materialSourceFilePath, const rapidjson::Value& json) const
|
||||
{
|
||||
auto material = LoadSourceData<MaterialSourceData>(json, materialSourceFilePath);
|
||||
|
||||
@@ -292,7 +302,7 @@ namespace AZ
|
||||
return {};
|
||||
}
|
||||
|
||||
auto materialAssetOutcome = material.GetValue().CreateMaterialAsset(Uuid::CreateRandom(), materialSourceFilePath, true);
|
||||
auto materialAssetOutcome = material.GetValue().CreateMaterialAsset(Uuid::CreateRandom(), materialSourceFilePath, ReportMaterialAssetWarningsAsErrors());
|
||||
if (!materialAssetOutcome.IsSuccess())
|
||||
{
|
||||
return {};
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <AssetBuilderSDK/AssetBuilderBusses.h>
|
||||
#include <Atom/RPI.Reflect/Material/MaterialAsset.h>
|
||||
#include <AzCore/JSON/document.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
@@ -37,6 +39,9 @@ namespace AZ
|
||||
|
||||
private:
|
||||
|
||||
AZ::Data::Asset<MaterialAsset> CreateMaterialAsset(AZStd::string_view materialSourceFilePath, const rapidjson::Value& json) const;
|
||||
bool ReportMaterialAssetWarningsAsErrors() const;
|
||||
|
||||
bool m_isShuttingDown = false;
|
||||
};
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <AzFramework/StringFunc/StringFunc.h>
|
||||
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
|
||||
#include <AzCore/IO/IOUtils.h>
|
||||
#include <AzCore/IO/Path/Path.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
@@ -46,6 +47,12 @@ namespace AZ
|
||||
|
||||
AZStd::string ResolvePathReference(const AZStd::string& originatingSourceFilePath, const AZStd::string& referencedSourceFilePath)
|
||||
{
|
||||
// The IsAbsolute part prevents "second join parameter is an absolute path" warnings in StringFunc::Path::Join below
|
||||
if (referencedSourceFilePath.empty() || AZ::IO::PathView{referencedSourceFilePath}.IsAbsolute())
|
||||
{
|
||||
return referencedSourceFilePath;
|
||||
}
|
||||
|
||||
AZStd::string normalizedReferencedPath = referencedSourceFilePath;
|
||||
AzFramework::StringFunc::Path::Normalize(normalizedReferencedPath);
|
||||
|
||||
@@ -113,7 +120,7 @@ namespace AZ
|
||||
return results;
|
||||
}
|
||||
|
||||
Outcome<Data::AssetId> MakeAssetId(const AZStd::string& sourcePath, uint32_t productSubId)
|
||||
Outcome<Data::AssetId> MakeAssetId(const AZStd::string& sourcePath, uint32_t productSubId, TraceLevel reporting)
|
||||
{
|
||||
bool assetFound = false;
|
||||
AZ::Data::AssetInfo sourceInfo;
|
||||
@@ -122,7 +129,7 @@ namespace AZ
|
||||
|
||||
if (!assetFound)
|
||||
{
|
||||
AZ_Error("AssetUtils", false, "Could not find asset [%s]", sourcePath.c_str());
|
||||
AssetUtilsInternal::ReportIssue(reporting, AZStd::string::format("Could not find asset [%s]", sourcePath.c_str()).c_str());
|
||||
return AZ::Failure();
|
||||
}
|
||||
else
|
||||
@@ -131,10 +138,10 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
Outcome<Data::AssetId> MakeAssetId(const AZStd::string& originatingSourcePath, const AZStd::string& referencedSourceFilePath, uint32_t productSubId)
|
||||
Outcome<Data::AssetId> MakeAssetId(const AZStd::string& originatingSourcePath, const AZStd::string& referencedSourceFilePath, uint32_t productSubId, TraceLevel reporting)
|
||||
{
|
||||
AZStd::string resolvedPath = ResolvePathReference(originatingSourcePath, referencedSourceFilePath);
|
||||
return MakeAssetId(resolvedPath, productSubId);
|
||||
return MakeAssetId(resolvedPath, productSubId, reporting);
|
||||
}
|
||||
} // namespace AssetUtils
|
||||
} // namespace RPI
|
||||
|
||||
@@ -303,7 +303,7 @@ namespace AZ
|
||||
MaterialPropertyId propertyId{ group.first, property.first };
|
||||
if (!property.second.m_value.IsValid())
|
||||
{
|
||||
AZ_Warning("Material source data", false, "Source data for material property value is invalid.");
|
||||
materialAssetCreator.ReportWarning("Source data for material property value is invalid.");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -317,22 +317,20 @@ namespace AZ
|
||||
{
|
||||
case MaterialPropertyDataType::Image:
|
||||
{
|
||||
Outcome<Data::Asset<ImageAsset>> imageAssetResult = MaterialUtils::GetImageAssetReference(
|
||||
materialSourceFilePath, property.second.m_value.GetValue<AZStd::string>());
|
||||
Data::Asset<ImageAsset> imageAsset;
|
||||
|
||||
if (imageAssetResult.IsSuccess())
|
||||
MaterialUtils::GetImageAssetResult result = MaterialUtils::GetImageAssetReference(
|
||||
imageAsset, materialSourceFilePath, property.second.m_value.GetValue<AZStd::string>());
|
||||
|
||||
if (result == MaterialUtils::GetImageAssetResult::Missing)
|
||||
{
|
||||
auto& imageAsset = imageAssetResult.GetValue();
|
||||
// Load referenced images when load material
|
||||
imageAsset.SetAutoLoadBehavior(Data::AssetLoadBehavior::PreLoad);
|
||||
materialAssetCreator.SetPropertyValue(propertyId.GetFullName(), imageAsset);
|
||||
}
|
||||
else
|
||||
{
|
||||
materialAssetCreator.ReportError(
|
||||
materialAssetCreator.ReportWarning(
|
||||
"Material property '%s': Could not find the image '%s'", propertyId.GetFullName().GetCStr(),
|
||||
property.second.m_value.GetValue<AZStd::string>().data());
|
||||
}
|
||||
|
||||
imageAsset.SetAutoLoadBehavior(Data::AssetLoadBehavior::PreLoad);
|
||||
materialAssetCreator.SetPropertyValue(propertyId.GetFullName(), imageAsset);
|
||||
}
|
||||
break;
|
||||
case MaterialPropertyDataType::Enum:
|
||||
|
||||
@@ -451,20 +451,21 @@ namespace AZ
|
||||
{
|
||||
case MaterialPropertyDataType::Image:
|
||||
{
|
||||
auto imageAssetResult = MaterialUtils::GetImageAssetReference(
|
||||
materialTypeSourceFilePath, property.m_value.GetValue<AZStd::string>());
|
||||
Data::Asset<ImageAsset> imageAsset;
|
||||
|
||||
if (imageAssetResult)
|
||||
{
|
||||
auto imageAsset = imageAssetResult.GetValue();
|
||||
materialTypeAssetCreator.SetPropertyValue(propertyId.GetFullName(), imageAsset);
|
||||
}
|
||||
else
|
||||
MaterialUtils::GetImageAssetResult result = MaterialUtils::GetImageAssetReference(
|
||||
imageAsset, materialTypeSourceFilePath, property.m_value.GetValue<AZStd::string>());
|
||||
|
||||
if (result == MaterialUtils::GetImageAssetResult::Missing)
|
||||
{
|
||||
materialTypeAssetCreator.ReportError(
|
||||
"Material property '%s': Could not find the image '%s'", propertyId.GetFullName().GetCStr(),
|
||||
property.m_value.GetValue<AZStd::string>().data());
|
||||
}
|
||||
else
|
||||
{
|
||||
materialTypeAssetCreator.SetPropertyValue(propertyId.GetFullName(), imageAsset);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MaterialPropertyDataType::Enum:
|
||||
|
||||
@@ -28,25 +28,36 @@ namespace AZ
|
||||
{
|
||||
namespace MaterialUtils
|
||||
{
|
||||
Outcome<Data::Asset<ImageAsset>> GetImageAssetReference(AZStd::string_view materialSourceFilePath, const AZStd::string imageFilePath)
|
||||
GetImageAssetResult GetImageAssetReference(Data::Asset<ImageAsset>& imageAsset, AZStd::string_view materialSourceFilePath, const AZStd::string imageFilePath)
|
||||
{
|
||||
imageAsset = {};
|
||||
|
||||
if (imageFilePath.empty())
|
||||
{
|
||||
// The image value was present but specified an empty string, meaning the texture asset should be explicitly cleared.
|
||||
return AZ::Success(Data::Asset<ImageAsset>());
|
||||
return GetImageAssetResult::Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
Outcome<Data::AssetId> imageAssetId = AssetUtils::MakeAssetId(materialSourceFilePath, imageFilePath, StreamingImageAsset::GetImageAssetSubId());
|
||||
// We use TraceLevel::None because fallback textures are available and we'll return GetImageAssetResult::Missing below in that case.
|
||||
// Callers of GetImageAssetReference will be responsible for logging warnings or errors as needed.
|
||||
|
||||
Outcome<Data::AssetId> imageAssetId = AssetUtils::MakeAssetId(materialSourceFilePath, imageFilePath, StreamingImageAsset::GetImageAssetSubId(), AssetUtils::TraceLevel::None);
|
||||
|
||||
if (!imageAssetId.IsSuccess())
|
||||
{
|
||||
return AZ::Failure();
|
||||
}
|
||||
else
|
||||
{
|
||||
Data::Asset<ImageAsset> unloadedImageAssetReference(imageAssetId.GetValue(), azrtti_typeid<StreamingImageAsset>(), imageFilePath);
|
||||
return AZ::Success(unloadedImageAssetReference);
|
||||
// When the AssetId cannot be found, we don't want to outright fail, because the runtime has mechanisms for displaying fallback textures which gives the
|
||||
// user a better recovery workflow. On the other hand we can't just provide an empty/invalid Asset<ImageAsset> because that would be interpreted as simply
|
||||
// no value was present and result in using no texture, and this would amount to a silent failure.
|
||||
// So we use a randomly generated (well except for the "BADA55E7" bit ;) UUID which the runtime and tools will interpret as a missing asset and represent
|
||||
// it as such.
|
||||
static const Uuid InvalidAssetPlaceholderId = "{BADA55E7-1A1D-4940-B655-9D08679BD62F}";
|
||||
imageAsset = Data::Asset<ImageAsset>{InvalidAssetPlaceholderId, azrtti_typeid<StreamingImageAsset>(), imageFilePath};
|
||||
return GetImageAssetResult::Missing;
|
||||
}
|
||||
|
||||
imageAsset = Data::Asset<ImageAsset>{imageAssetId.GetValue(), azrtti_typeid<StreamingImageAsset>(), imageFilePath};
|
||||
return GetImageAssetResult::Found;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
#include <Atom/RPI.Reflect/Image/StreamingImageAssetHandler.h>
|
||||
#include <Atom/RPI.Public/Image/ImageSystemInterface.h>
|
||||
#include <AzCore/Settings/SettingsRegistry.h>
|
||||
#include <AzFramework/Asset/AssetSystemBus.h>
|
||||
|
||||
@@ -52,7 +53,7 @@ namespace AZ
|
||||
missingAssetStatus, &AzFramework::AssetSystem::AssetSystemRequests::GetAssetStatusById, asset.GetId().m_guid);
|
||||
|
||||
// Determine which fallback image to use
|
||||
const char* relativePath = "textures/defaults/defaultfallback.png.streamingimage";
|
||||
const char* relativePath = DefaultImageAssetPaths::DefaultFallback;
|
||||
|
||||
bool useDebugFallbackImages = true;
|
||||
if (auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry != nullptr)
|
||||
@@ -66,15 +67,15 @@ namespace AZ
|
||||
{
|
||||
case AzFramework::AssetSystem::AssetStatus::AssetStatus_Queued:
|
||||
case AzFramework::AssetSystem::AssetStatus::AssetStatus_Compiling:
|
||||
relativePath = "textures/defaults/processing.png.streamingimage";
|
||||
relativePath = DefaultImageAssetPaths::Processing;
|
||||
break;
|
||||
case AzFramework::AssetSystem::AssetStatus::AssetStatus_Failed:
|
||||
relativePath = "textures/defaults/processingfailed.png.streamingimage";
|
||||
relativePath = DefaultImageAssetPaths::ProcessingFailed;
|
||||
break;
|
||||
case AzFramework::AssetSystem::AssetStatus::AssetStatus_Missing:
|
||||
case AzFramework::AssetSystem::AssetStatus::AssetStatus_Unknown:
|
||||
case AzFramework::AssetSystem::AssetStatus::AssetStatus_Compiled:
|
||||
relativePath = "textures/defaults/missing.png.streamingimage";
|
||||
relativePath = DefaultImageAssetPaths::Missing;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,12 +118,16 @@ namespace AZ
|
||||
else if (value.is<Data::Asset<Data::AssetData>>())
|
||||
{
|
||||
result.m_value = Data::Asset<RPI::ImageAsset>(
|
||||
AZStd::any_cast<Data::Asset<Data::AssetData>>(value).GetId(), azrtti_typeid<RPI::StreamingImageAsset>());
|
||||
AZStd::any_cast<Data::Asset<Data::AssetData>>(value).GetId(),
|
||||
azrtti_typeid<RPI::StreamingImageAsset>(),
|
||||
AZStd::any_cast<Data::Asset<Data::AssetData>>(value).GetHint());
|
||||
}
|
||||
else if (value.is<Data::Asset<StreamingImageAsset>>())
|
||||
{
|
||||
result.m_value = Data::Asset<RPI::ImageAsset>(
|
||||
AZStd::any_cast<Data::Asset<StreamingImageAsset>>(value).GetId(), azrtti_typeid<RPI::StreamingImageAsset>());
|
||||
AZStd::any_cast<Data::Asset<StreamingImageAsset>>(value).GetId(),
|
||||
azrtti_typeid<RPI::StreamingImageAsset>(),
|
||||
AZStd::any_cast<Data::Asset<StreamingImageAsset>>(value).GetHint());
|
||||
}
|
||||
else if (value.is<Data::Asset<ImageAsset>>())
|
||||
{
|
||||
|
||||
@@ -625,23 +625,6 @@ namespace UnitTest
|
||||
// We use local functions to easily start a new MaterialAssetCreator for each test case because
|
||||
// the AssetCreator would just skip subsequent operations after the first failure is detected.
|
||||
|
||||
auto expectError = [](AZStd::function<void(MaterialSourceData& materialSourceData)> setOneBadInput, [[maybe_unused]] uint32_t expectedAsserts = 2)
|
||||
{
|
||||
MaterialSourceData sourceData;
|
||||
|
||||
sourceData.m_materialType = "@exefolder@/Temp/test.materialtype";
|
||||
|
||||
AddPropertyGroup(sourceData, "general");
|
||||
|
||||
setOneBadInput(sourceData);
|
||||
|
||||
AZ_TEST_START_ASSERTTEST;
|
||||
auto materialAssetOutcome = sourceData.CreateMaterialAsset(Uuid::CreateRandom(), "", false);
|
||||
AZ_TEST_STOP_ASSERTTEST(expectedAsserts); // Usually one for the initial error, and one for when End() is called
|
||||
|
||||
EXPECT_FALSE(materialAssetOutcome.IsSuccess());
|
||||
};
|
||||
|
||||
auto expectWarning = [](AZStd::function<void(MaterialSourceData& materialSourceData)> setOneBadInput, [[maybe_unused]] uint32_t expectedAsserts = 1)
|
||||
{
|
||||
MaterialSourceData sourceData;
|
||||
@@ -692,10 +675,10 @@ namespace UnitTest
|
||||
});
|
||||
|
||||
// Missing image reference
|
||||
expectError([](MaterialSourceData& materialSourceData)
|
||||
expectWarning([](MaterialSourceData& materialSourceData)
|
||||
{
|
||||
AddProperty(materialSourceData, "general", "MyImage", AZStd::string("doesNotExist.streamingimage"));
|
||||
}, 3); // Expect a 3rd error because AssetUtils reports its own assertion failure
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -888,4 +888,43 @@ namespace UnitTest
|
||||
EXPECT_EQ(indexFromOldName, indexFromNewName);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void CheckPropertyValueRoundTrip(const T& value)
|
||||
{
|
||||
AZ::RPI::MaterialPropertyValue materialPropertyValue{value};
|
||||
AZStd::any anyValue{value};
|
||||
AZ::RPI::MaterialPropertyValue materialPropertyValueFromAny = MaterialPropertyValue::FromAny(anyValue);
|
||||
AZ::RPI::MaterialPropertyValue materialPropertyValueFromRoundTrip = MaterialPropertyValue::FromAny(MaterialPropertyValue::ToAny(materialPropertyValue));
|
||||
|
||||
EXPECT_EQ(materialPropertyValue, materialPropertyValueFromAny);
|
||||
EXPECT_EQ(materialPropertyValue, materialPropertyValueFromRoundTrip);
|
||||
|
||||
if (materialPropertyValue.Is<Data::Asset<ImageAsset>>())
|
||||
{
|
||||
EXPECT_EQ(materialPropertyValue.GetValue<Data::Asset<ImageAsset>>().GetHint(), materialPropertyValueFromAny.GetValue<Data::Asset<ImageAsset>>().GetHint());
|
||||
EXPECT_EQ(materialPropertyValue.GetValue<Data::Asset<ImageAsset>>().GetHint(), materialPropertyValueFromRoundTrip.GetValue<Data::Asset<ImageAsset>>().GetHint());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(MaterialTests, TestMaterialPropertyValueAsAny)
|
||||
{
|
||||
CheckPropertyValueRoundTrip(true);
|
||||
CheckPropertyValueRoundTrip(false);
|
||||
CheckPropertyValueRoundTrip(7);
|
||||
CheckPropertyValueRoundTrip(8u);
|
||||
CheckPropertyValueRoundTrip(9.0f);
|
||||
CheckPropertyValueRoundTrip(AZ::Vector2(1.0f, 2.0f));
|
||||
CheckPropertyValueRoundTrip(AZ::Vector3(1.0f, 2.0f, 3.0f));
|
||||
CheckPropertyValueRoundTrip(AZ::Vector4(1.0f, 2.0f, 3.0f, 4.0f));
|
||||
CheckPropertyValueRoundTrip(AZ::Color(1.0f, 2.0f, 3.0f, 4.0f));
|
||||
CheckPropertyValueRoundTrip(Data::Asset<Data::AssetData>{});
|
||||
CheckPropertyValueRoundTrip(Data::Asset<ImageAsset>{});
|
||||
CheckPropertyValueRoundTrip(Data::Asset<StreamingImageAsset>{});
|
||||
CheckPropertyValueRoundTrip(Data::Asset<Data::AssetData>{Uuid::CreateRandom(), azrtti_typeid<AZ::RPI::StreamingImageAsset>(), "TestAssetPath.png"});
|
||||
CheckPropertyValueRoundTrip(Data::Asset<ImageAsset>{Uuid::CreateRandom(), azrtti_typeid<AZ::RPI::StreamingImageAsset>(), "TestAssetPath.png"});
|
||||
CheckPropertyValueRoundTrip(Data::Asset<StreamingImageAsset>{Uuid::CreateRandom(), azrtti_typeid<AZ::RPI::StreamingImageAsset>(), "TestAssetPath.png"});
|
||||
CheckPropertyValueRoundTrip(m_testImageAsset);
|
||||
CheckPropertyValueRoundTrip(Data::Instance<Image>{m_testImage});
|
||||
CheckPropertyValueRoundTrip(AZStd::string{"hello"});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@ ly_add_target(
|
||||
Gem::Atom_RHI.Reflect
|
||||
Gem::Atom_Feature_Common.Static
|
||||
Gem::Atom_Bootstrap.Headers
|
||||
Gem::ImageProcessingAtom.Headers
|
||||
)
|
||||
|
||||
ly_add_target(
|
||||
@@ -60,6 +61,8 @@ ly_add_target(
|
||||
BUILD_DEPENDENCIES
|
||||
PRIVATE
|
||||
Gem::AtomToolsFramework.Static
|
||||
RUNTIME_DEPENDENCIES
|
||||
Gem::ImageProcessingAtom.Editor
|
||||
)
|
||||
|
||||
################################################################################
|
||||
|
||||
+21
@@ -26,6 +26,21 @@ namespace AtomToolsFramework
|
||||
//! Get the combined output of all messages
|
||||
AZStd::string GetDump() const;
|
||||
|
||||
//! Return the number of OnAssert calls
|
||||
size_t GetAssertCount() const;
|
||||
|
||||
//! Return the number of OnException calls
|
||||
size_t GetExceptionCount() const;
|
||||
|
||||
//! Return the number of OnError calls, and includes OnAssert and OnException if @includeHigher is true
|
||||
size_t GetErrorCount(bool includeHigher = false) const;
|
||||
|
||||
//! Return the number of OnWarning calls, and includes higher categories if @includeHigher is true
|
||||
size_t GetWarningCount(bool includeHigher = false) const;
|
||||
|
||||
//! Return the number of OnPrintf calls, and includes higher categories if @includeHigher is true
|
||||
size_t GetPrintfCount(bool includeHigher = false) const;
|
||||
|
||||
private:
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// AZ::Debug::TraceMessageBus::Handler overrides...
|
||||
@@ -38,5 +53,11 @@ namespace AtomToolsFramework
|
||||
|
||||
size_t m_maxMessageCount = std::numeric_limits<size_t>::max();
|
||||
AZStd::list<AZStd::string> m_messages;
|
||||
|
||||
size_t m_assertCount = 0;
|
||||
size_t m_exceptionCount = 0;
|
||||
size_t m_errorCount = 0;
|
||||
size_t m_warningCount = 0;
|
||||
size_t m_printfCount = 0;
|
||||
};
|
||||
} // namespace AtomToolsFramework
|
||||
|
||||
+1
@@ -49,6 +49,7 @@ namespace AtomToolsFramework
|
||||
//! @param propertyValue the value being converted before saving
|
||||
bool ConvertToExportFormat(
|
||||
const AZStd::string& exportPath,
|
||||
[[maybe_unused]] const AZ::Name& propertyId,
|
||||
const AZ::RPI::MaterialTypeSourceData::PropertyDefinition& propertyDefinition,
|
||||
AZ::RPI::MaterialPropertyValue& propertyValue);
|
||||
|
||||
|
||||
@@ -8,8 +8,9 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/PlatformDef.h>
|
||||
#include <AzCore/Asset/AssetManager.h>
|
||||
#include <AzCore/PlatformDef.h>
|
||||
#include <AzCore/Settings/SettingsRegistry.h>
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
|
||||
AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option") // disable warnings spawned by QT
|
||||
@@ -18,11 +19,24 @@ AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option") // disable warnin
|
||||
#include <QStringList>
|
||||
AZ_POP_DISABLE_WARNING
|
||||
|
||||
class QImage;
|
||||
|
||||
namespace AtomToolsFramework
|
||||
{
|
||||
template<typename T>
|
||||
T GetSettingOrDefault(AZStd::string_view path, const T& defaultValue)
|
||||
{
|
||||
T result;
|
||||
auto settingsRegistry = AZ::SettingsRegistry::Get();
|
||||
return (settingsRegistry && settingsRegistry->Get(result, path)) ? result : defaultValue;
|
||||
}
|
||||
|
||||
using LoadImageAsyncCallback = AZStd::function<void(const QImage&)>;
|
||||
void LoadImageAsync(const AZStd::string& path, LoadImageAsyncCallback callback);
|
||||
|
||||
QFileInfo GetSaveFileInfo(const QString& initialPath);
|
||||
QFileInfo GetOpenFileInfo(const AZStd::vector<AZ::Data::AssetType>& assetTypes);
|
||||
QFileInfo GetUniqueFileInfo(const QString& initialPath);
|
||||
QFileInfo GetDuplicationFileInfo(const QString& initialPath);
|
||||
bool LaunchTool(const QString& baseName, const QString& extension, const QStringList& arguments);
|
||||
}
|
||||
} // namespace AtomToolsFramework
|
||||
|
||||
+7
-1
@@ -10,6 +10,7 @@
|
||||
|
||||
#include <Atom/RPI.Public/Base.h>
|
||||
#include <Atom/RPI.Public/View.h>
|
||||
#include <Atom/RPI.Public/ViewportContextBus.h>
|
||||
#include <AzFramework/Viewport/CameraState.h>
|
||||
#include <AzToolsFramework/Viewport/ViewportMessages.h>
|
||||
|
||||
@@ -17,7 +18,9 @@ namespace AtomToolsFramework
|
||||
{
|
||||
//! A concrete implementation of the ViewportInteractionRequestBus.
|
||||
//! Primarily concerned with picking (screen to world and world to screen transformations).
|
||||
class ViewportInteractionImpl : public AzToolsFramework::ViewportInteraction::ViewportInteractionRequestBus::Handler
|
||||
class ViewportInteractionImpl
|
||||
: public AzToolsFramework::ViewportInteraction::ViewportInteractionRequestBus::Handler
|
||||
, private AZ::RPI::ViewportContextIdNotificationBus::Handler
|
||||
{
|
||||
public:
|
||||
explicit ViewportInteractionImpl(AZ::RPI::ViewPtr viewPtr);
|
||||
@@ -37,6 +40,9 @@ namespace AtomToolsFramework
|
||||
AZStd::function<float()> m_deviceScalingFactorFn; //! Callback to determine the device scaling factor.
|
||||
|
||||
private:
|
||||
// ViewportContextIdNotificationBus overrides ...
|
||||
void OnViewportDefaultViewChanged(AZ::RPI::ViewPtr view) override;
|
||||
|
||||
AZ::RPI::ViewPtr m_viewPtr;
|
||||
};
|
||||
} // namespace AtomToolsFramework
|
||||
|
||||
@@ -31,6 +31,7 @@ namespace AtomToolsFramework
|
||||
|
||||
bool TraceRecorder::OnAssert(const char* message)
|
||||
{
|
||||
++m_assertCount;
|
||||
if (m_messages.size() < m_maxMessageCount)
|
||||
{
|
||||
m_messages.push_back(AZStd::string::format("Assert: %s", message));
|
||||
@@ -40,6 +41,7 @@ namespace AtomToolsFramework
|
||||
|
||||
bool TraceRecorder::OnException(const char* message)
|
||||
{
|
||||
++m_exceptionCount;
|
||||
if (m_messages.size() < m_maxMessageCount)
|
||||
{
|
||||
m_messages.push_back(AZStd::string::format("Exception: %s", message));
|
||||
@@ -49,6 +51,7 @@ namespace AtomToolsFramework
|
||||
|
||||
bool TraceRecorder::OnError(const char* /*window*/, const char* message)
|
||||
{
|
||||
++m_errorCount;
|
||||
if (m_messages.size() < m_maxMessageCount)
|
||||
{
|
||||
m_messages.push_back(AZStd::string::format("Error: %s", message));
|
||||
@@ -58,6 +61,7 @@ namespace AtomToolsFramework
|
||||
|
||||
bool TraceRecorder::OnWarning(const char* /*window*/, const char* message)
|
||||
{
|
||||
++m_warningCount;
|
||||
if (m_messages.size() < m_maxMessageCount)
|
||||
{
|
||||
m_messages.push_back(AZStd::string::format("Warning: %s", message));
|
||||
@@ -67,11 +71,58 @@ namespace AtomToolsFramework
|
||||
|
||||
bool TraceRecorder::OnPrintf(const char* /*window*/, const char* message)
|
||||
{
|
||||
++m_printfCount;
|
||||
if (m_messages.size() < m_maxMessageCount)
|
||||
{
|
||||
m_messages.push_back(AZStd::string::format("%s", message));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t TraceRecorder::GetAssertCount() const
|
||||
{
|
||||
return m_assertCount;
|
||||
}
|
||||
|
||||
size_t TraceRecorder::GetExceptionCount() const
|
||||
{
|
||||
return m_exceptionCount;
|
||||
}
|
||||
|
||||
size_t TraceRecorder::GetErrorCount(bool includeHigher) const
|
||||
{
|
||||
if (includeHigher)
|
||||
{
|
||||
return m_errorCount + GetAssertCount() + GetExceptionCount();
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_errorCount;
|
||||
}
|
||||
}
|
||||
|
||||
size_t TraceRecorder::GetWarningCount(bool includeHigher) const
|
||||
{
|
||||
if (includeHigher)
|
||||
{
|
||||
return m_warningCount + GetErrorCount(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_warningCount;
|
||||
}
|
||||
}
|
||||
|
||||
size_t TraceRecorder::GetPrintfCount(bool includeHigher) const
|
||||
{
|
||||
if (includeHigher)
|
||||
{
|
||||
return m_printfCount + GetWarningCount(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_printfCount;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace AtomToolsFramework
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user