+8
-8
@@ -13,9 +13,9 @@
|
||||
|
||||
if(PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_BUILD_TESTS_SUPPORTED AND AutomatedTesting IN_LIST LY_PROJECTS)
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::AtomRenderer_HydraTests_Main
|
||||
NAME AutomatedTesting::Atom_TestSuite_Main
|
||||
TEST_SUITE main
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/test_Atom_MainSuite.py
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Main.py
|
||||
TEST_SERIAL
|
||||
TIMEOUT 600
|
||||
RUNTIME_DEPENDENCIES
|
||||
@@ -26,9 +26,9 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_BUILD_TESTS_SUPPORTED AND AutomatedT
|
||||
Atom
|
||||
)
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::AtomRenderer_HydraTests_MainOptimized
|
||||
NAME AutomatedTesting::Atom_TestSuite_Main_Optimized
|
||||
TEST_SUITE main
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/test_Atom_MainSuite_Optimized.py
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Main_Optimized.py
|
||||
TEST_SERIAL
|
||||
TIMEOUT 600
|
||||
RUNTIME_DEPENDENCIES
|
||||
@@ -39,9 +39,9 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_BUILD_TESTS_SUPPORTED AND AutomatedT
|
||||
Atom
|
||||
)
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::AtomRenderer_HydraTests_Sandbox
|
||||
NAME AutomatedTesting::Atom_TestSuite_Sandbox
|
||||
TEST_SUITE sandbox
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/test_Atom_SandboxSuite.py
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Sandbox.py
|
||||
TEST_SERIAL
|
||||
TIMEOUT 400
|
||||
RUNTIME_DEPENDENCIES
|
||||
@@ -52,12 +52,12 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_BUILD_TESTS_SUPPORTED AND AutomatedT
|
||||
Atom
|
||||
)
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::AtomRenderer_HydraTests_GPUTests
|
||||
NAME AutomatedTesting::Atom_TestSuite_Main_GPU
|
||||
TEST_SUITE main
|
||||
TEST_REQUIRES gpu
|
||||
TEST_SERIAL
|
||||
TIMEOUT 1200
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/test_Atom_GPUTests.py
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Main_GPU.py
|
||||
RUNTIME_DEPENDENCIES
|
||||
AssetProcessor
|
||||
AutomatedTesting.Assets
|
||||
+2
-2
@@ -13,10 +13,10 @@ import pytest
|
||||
|
||||
import ly_test_tools.environment.file_system as file_system
|
||||
import editor_python_test_tools.hydra_test_utils as hydra
|
||||
from atom_renderer.atom_utils.atom_constants import LIGHT_TYPES
|
||||
from Atom.atom_utils.atom_constants import LIGHT_TYPES
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
TEST_DIRECTORY = os.path.join(os.path.dirname(__file__), "atom_hydra_scripts")
|
||||
TEST_DIRECTORY = os.path.join(os.path.dirname(__file__), "tests")
|
||||
|
||||
|
||||
@pytest.mark.parametrize("project", ["AutomatedTesting"])
|
||||
+1
-3
@@ -3,8 +3,6 @@ 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
|
||||
|
||||
Tests that require a GPU in order to run.
|
||||
"""
|
||||
|
||||
import datetime
|
||||
@@ -22,7 +20,7 @@ import editor_python_test_tools.hydra_test_utils as hydra
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
DEFAULT_SUBFOLDER_PATH = 'user/PythonTests/Automated/Screenshots'
|
||||
TEST_DIRECTORY = os.path.join(os.path.dirname(__file__), "atom_hydra_scripts")
|
||||
TEST_DIRECTORY = os.path.join(os.path.dirname(__file__), "tests")
|
||||
|
||||
|
||||
def golden_images_directory():
|
||||
+10
-10
@@ -15,32 +15,32 @@ from ly_test_tools.o3de.editor_test import EditorSharedTest, EditorTestSuite
|
||||
class TestAutomation(EditorTestSuite):
|
||||
|
||||
class AtomEditorComponents_DecalAdded(EditorSharedTest):
|
||||
from atom_renderer.atom_hydra_scripts import hydra_AtomEditorComponents_DecalAdded as test_module
|
||||
from Atom.tests import hydra_AtomEditorComponents_DecalAdded as test_module
|
||||
|
||||
class AtomEditorComponents_DepthOfFieldAdded(EditorSharedTest):
|
||||
from atom_renderer.atom_hydra_scripts import hydra_AtomEditorComponents_DepthOfFieldAdded as test_module
|
||||
from Atom.tests import hydra_AtomEditorComponents_DepthOfFieldAdded as test_module
|
||||
|
||||
class AtomEditorComponents_DirectionalLightAdded(EditorSharedTest):
|
||||
from atom_renderer.atom_hydra_scripts import hydra_AtomEditorComponents_DirectionalLightAdded as test_module
|
||||
from Atom.tests import hydra_AtomEditorComponents_DirectionalLightAdded as test_module
|
||||
|
||||
class AtomEditorComponents_ExposureControlAdded(EditorSharedTest):
|
||||
from atom_renderer.atom_hydra_scripts import hydra_AtomEditorComponents_ExposureControlAdded as test_module
|
||||
from Atom.tests import hydra_AtomEditorComponents_ExposureControlAdded as test_module
|
||||
|
||||
class AtomEditorComponents_GlobalSkylightIBLAdded(EditorSharedTest):
|
||||
from atom_renderer.atom_hydra_scripts import hydra_AtomEditorComponents_GlobalSkylightIBLAdded as test_module
|
||||
from Atom.tests import hydra_AtomEditorComponents_GlobalSkylightIBLAdded as test_module
|
||||
|
||||
class AtomEditorComponents_PhysicalSkyAdded(EditorSharedTest):
|
||||
from atom_renderer.atom_hydra_scripts import hydra_AtomEditorComponents_PhysicalSkyAdded as test_module
|
||||
from Atom.tests import hydra_AtomEditorComponents_PhysicalSkyAdded as test_module
|
||||
|
||||
class AtomEditorComponents_PostFXRadiusWeightModifierAdded(EditorSharedTest):
|
||||
from atom_renderer.atom_hydra_scripts import (
|
||||
from Atom.tests import (
|
||||
hydra_AtomEditorComponents_PostFXRadiusWeightModifierAdded as test_module)
|
||||
|
||||
class AtomEditorComponents_LightAdded(EditorSharedTest):
|
||||
from atom_renderer.atom_hydra_scripts import hydra_AtomEditorComponents_LightAdded as test_module
|
||||
from Atom.tests import hydra_AtomEditorComponents_LightAdded as test_module
|
||||
|
||||
class AtomEditorComponents_DisplayMapperAdded(EditorSharedTest):
|
||||
from atom_renderer.atom_hydra_scripts import hydra_AtomEditorComponents_DisplayMapperAdded as test_module
|
||||
from Atom.tests import hydra_AtomEditorComponents_DisplayMapperAdded as test_module
|
||||
|
||||
class ShaderAssetBuilder_RecompilesShaderAsChainOfDependenciesChanges(EditorSharedTest):
|
||||
from .atom_hydra_scripts import hydra_ShaderAssetBuilder_RecompilesShaderAsChainOfDependenciesChanges as test_module
|
||||
from Atom.tests import hydra_ShaderAssetBuilder_RecompilesShaderAsChainOfDependenciesChanges as test_module
|
||||
+2
-2
@@ -2,7 +2,7 @@
|
||||
{
|
||||
"Source" : "DependencyValidation.azsl",
|
||||
|
||||
"DepthStencilState" : {
|
||||
"DepthStencilState" : {
|
||||
"Depth" : { "Enable" : false, "CompareFunc" : "GreaterEqual" }
|
||||
},
|
||||
|
||||
@@ -22,5 +22,5 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+1
-1
@@ -12,5 +12,5 @@
|
||||
|
||||
float4 GetTest2Color(float4 color)
|
||||
{
|
||||
return color * 0.5;
|
||||
return color * 0.5;
|
||||
}
|
||||
+1
-1
@@ -12,5 +12,5 @@
|
||||
|
||||
float4 GetTest3Color(float4 color)
|
||||
{
|
||||
return color * 0.13;
|
||||
return color * 0.13;
|
||||
}
|
||||
+1
-1
@@ -17,7 +17,7 @@ import azlmbr.legacy.general as general
|
||||
sys.path.append(os.path.join(azlmbr.paths.devassets, "Gem", "PythonTests"))
|
||||
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from atom_renderer.atom_utils.atom_constants import LIGHT_TYPES
|
||||
from Atom.atom_utils.atom_constants import LIGHT_TYPES
|
||||
|
||||
LIGHT_TYPE_PROPERTY = 'Controller|Configuration|Light type'
|
||||
SPHERE_AND_SPOT_DISK_LIGHT_PROPERTIES = [
|
||||
+1
-1
@@ -18,7 +18,7 @@ import azlmbr.paths
|
||||
|
||||
sys.path.append(os.path.join(azlmbr.paths.devassets, "Gem", "PythonTests"))
|
||||
|
||||
import atom_renderer.atom_utils.material_editor_utils as material_editor
|
||||
import Atom.atom_utils.material_editor_utils as material_editor
|
||||
|
||||
NEW_MATERIAL = "test_material.material"
|
||||
NEW_MATERIAL_1 = "test_material_1.material"
|
||||
+1
-1
@@ -14,7 +14,7 @@ sys.path.append(os.path.join(azlmbr.paths.devroot, "AutomatedTesting", "Gem", "P
|
||||
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.editor_test_helper import EditorTestHelper
|
||||
from atom_renderer.atom_utils.benchmark_utils import BenchmarkHelper
|
||||
from Atom.atom_utils.benchmark_utils import BenchmarkHelper
|
||||
|
||||
SCREEN_WIDTH = 1280
|
||||
SCREEN_HEIGHT = 720
|
||||
+1
-1
@@ -21,7 +21,7 @@ sys.path.append(os.path.join(azlmbr.paths.devroot, "AutomatedTesting", "Gem", "P
|
||||
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.editor_test_helper import EditorTestHelper
|
||||
from atom_renderer.atom_utils.screenshot_utils import ScreenshotHelper
|
||||
from Atom.atom_utils.screenshot_utils import ScreenshotHelper
|
||||
|
||||
SCREEN_WIDTH = 1280
|
||||
SCREEN_HEIGHT = 720
|
||||
+1
-1
@@ -17,7 +17,7 @@ import azlmbr.legacy.general as general
|
||||
sys.path.append(os.path.join(azlmbr.paths.devroot, "AutomatedTesting", "Gem", "PythonTests"))
|
||||
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from atom_renderer.atom_utils import atom_component_helper, atom_constants, screenshot_utils
|
||||
from Atom.atom_utils import atom_component_helper, atom_constants, screenshot_utils
|
||||
from editor_python_test_tools.editor_test_helper import EditorTestHelper
|
||||
|
||||
helper = EditorTestHelper(log_prefix="Atom_EditorTestHelper")
|
||||
@@ -18,7 +18,7 @@ include(${pal_dir}/PAL_traits_${PAL_PLATFORM_NAME_LOWERCASE}.cmake)
|
||||
add_subdirectory(assetpipeline)
|
||||
|
||||
## Atom Renderer ##
|
||||
add_subdirectory(atom_renderer)
|
||||
add_subdirectory(Atom)
|
||||
|
||||
## Physics ##
|
||||
add_subdirectory(Physics)
|
||||
|
||||
@@ -10,17 +10,12 @@
|
||||
# Only 'xcb' and 'wayland' are recognized
|
||||
if (${PAL_TRAIT_LINUX_WINDOW_MANAGER} STREQUAL "xcb")
|
||||
|
||||
find_library(XCB_LIBRARY xcb)
|
||||
find_library(XCB_XKB_LIBRARY xcb-xkb)
|
||||
find_library(XKBCOMMON_LIBRARY xkbcommon)
|
||||
find_library(XKBCOMMON_X11_LIBRARY xkbcommon-x11)
|
||||
|
||||
set(LY_BUILD_DEPENDENCIES
|
||||
PRIVATE
|
||||
${XCB_LIBRARY}
|
||||
${XKBCOMMON_LIBRARY}
|
||||
${XKBCOMMON_X11_LIBRARY}
|
||||
${XCB_XKB_LIBRARY}
|
||||
3rdParty::X11::xcb
|
||||
3rdParty::X11::xcb_xkb
|
||||
3rdParty::X11::xkbcommon
|
||||
3rdParty::X11::xkbcommon_X11
|
||||
)
|
||||
|
||||
set(LY_COMPILE_DEFINITIONS PUBLIC PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB)
|
||||
|
||||
+1
-1
@@ -46,7 +46,7 @@ namespace AzToolsFramework
|
||||
|
||||
QModelIndex AssetBrowserTableModel::mapToSource(const QModelIndex& proxyIndex) const
|
||||
{
|
||||
Q_ASSERT(!proxyIndex.isValid() || proxyIndex.model() != this);
|
||||
Q_ASSERT(!proxyIndex.isValid() || proxyIndex.model() == this);
|
||||
if (!proxyIndex.isValid() || !m_indexMap.contains(proxyIndex.row()))
|
||||
{
|
||||
return QModelIndex();
|
||||
|
||||
@@ -16,6 +16,11 @@
|
||||
|
||||
static const float4 s_AzslDebugColor = float4(165.0 / 255.0, 30.0 / 255.0, 36.0 / 255.0, 1);
|
||||
|
||||
// Uniform limitation need to be taken into consideration for mobile devices
|
||||
// Uniform limitation need to be taken into consideration for mobile devices. This would help alleviate device lost errors if the constant buffer
|
||||
// size overshoots the device's memory constraints. An example is a large number of constant buffers associated with mesh instances that would result in device lost,
|
||||
// but otherwise OK on PC. We can separate out the number of instances for the different platforms with this define.
|
||||
// [ATOM-14949]
|
||||
#define AZ_TRAIT_CONSTANT_BUFFER_LIMITATIONS 1
|
||||
#define AZ_TRAIT_CONSTANT_BUFFER_LIMITATIONS 1
|
||||
|
||||
// Different constant buffer alignment on platforms
|
||||
#define AZ_TRAIT_CONSTANT_BUFFER_ALIGNMENT 16
|
||||
|
||||
@@ -12,3 +12,7 @@
|
||||
*/
|
||||
|
||||
static const float4 s_AzslDebugColor = float4(165.0 / 255.0, 30.0 / 255.0, 36.0 / 255.0, 1);
|
||||
|
||||
|
||||
// Different constant buffer alignment on platforms
|
||||
#define AZ_TRAIT_CONSTANT_BUFFER_ALIGNMENT 128
|
||||
@@ -104,6 +104,7 @@ option bool o_layer3_enabled;
|
||||
enum class DebugDrawMode { None, BlendMask, Displacement, FinalBlendWeights };
|
||||
option DebugDrawMode o_debugDrawMode;
|
||||
|
||||
// If you modify this enum, you must update the BlendSourceUsesDisplacement function in StandardMultilayerPBR_Displacement.lua
|
||||
enum class LayerBlendSource { BlendMaskTexture, BlendMaskVertexColors, Displacement, Displacement_With_BlendMaskTexture, Displacement_With_BlendMaskVertexColors, Fallback };
|
||||
option LayerBlendSource o_layerBlendSource;
|
||||
|
||||
|
||||
+3
-2
@@ -88,7 +88,7 @@ end
|
||||
-- @return a table with two values {min,max}. Negative values are below the surface and positive values are above the surface.
|
||||
function CalcOverallHeightRange(context)
|
||||
|
||||
local heightMinMax = {nil, nil}
|
||||
local heightMinMax = {}
|
||||
|
||||
local function GetMergedHeightRange(heightMinMax, offset, factor)
|
||||
top = offset
|
||||
@@ -138,7 +138,8 @@ function CalcOverallHeightRange(context)
|
||||
if(enableLayer3) then GetMergedHeightRange(heightMinMax, offsetLayer3, factorLayer3) end
|
||||
|
||||
else
|
||||
heightMinMax = {0,0}
|
||||
heightMinMax[0] = 0
|
||||
heightMinMax[1] = 0
|
||||
end
|
||||
|
||||
return heightMinMax
|
||||
|
||||
+10
@@ -33,6 +33,16 @@ namespace AZ
|
||||
virtual const MaterialAssignmentMap& GetMaterialOverrides() const = 0;
|
||||
//! Clear all material overrides
|
||||
virtual void ClearAllMaterialOverrides() = 0;
|
||||
//! Clear non-lod material overrides
|
||||
virtual void ClearModelMaterialOverrides() = 0;
|
||||
//! Clear lod material overrides
|
||||
virtual void ClearLodMaterialOverrides() = 0;
|
||||
//! Clear residual materials that don't correspond to the associated model
|
||||
virtual void ClearIncompatibleMaterialOverrides() = 0;
|
||||
//! Clear materials that reference missing assets
|
||||
virtual void ClearInvalidMaterialOverrides() = 0;
|
||||
//! Repair materials that reference missing assets by assigning the default asset
|
||||
virtual void RepairInvalidMaterialOverrides() = 0;
|
||||
//! Set default material override
|
||||
virtual void SetDefaultMaterialOverride(const AZ::Data::AssetId& materialAssetId) = 0;
|
||||
//! Get default material override
|
||||
|
||||
+91
-115
@@ -32,9 +32,6 @@ namespace AZ
|
||||
const char* EditorMaterialComponent::GenerateMaterialsButtonText = "Generate/Manage Source Materials...";
|
||||
const char* EditorMaterialComponent::GenerateMaterialsToolTipText = "Generate editable source material files from materials provided by the model.";
|
||||
|
||||
const char* EditorMaterialComponent::ResetMaterialsButtonText = "Reset Materials";
|
||||
const char* EditorMaterialComponent::ResetMaterialsToolTipText = "Clear all settings, materials, and properties then rebuild material slots from the associated model.";
|
||||
|
||||
// Update serialized data to the new format and data types
|
||||
bool EditorMaterialComponent::ConvertVersion(AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& classElement)
|
||||
{
|
||||
@@ -178,43 +175,74 @@ namespace AZ
|
||||
|
||||
menu->addSeparator();
|
||||
|
||||
action = menu->addAction(ResetMaterialsButtonText, [this]() { ResetMaterialSlots(); });
|
||||
action->setToolTip(ResetMaterialsToolTipText);
|
||||
action = menu->addAction("Clear All Materials", [this]() {
|
||||
AzToolsFramework::ScopedUndoBatch undoBatch("Clearing all materials.");
|
||||
SetDirty();
|
||||
|
||||
menu->addSeparator();
|
||||
MaterialComponentRequestBus::Event(GetEntityId(), &MaterialComponentRequestBus::Events::ClearAllMaterialOverrides);
|
||||
|
||||
m_materialSlotsByLodEnabled = false;
|
||||
|
||||
UpdateMaterialSlots();
|
||||
});
|
||||
action->setToolTip("Clear all materials and properties then rebuild material slots from the associated model.");
|
||||
|
||||
action = menu->addAction("Clear Model Materials", [this]() {
|
||||
AzToolsFramework::ScopedUndoBatch undoBatch("Clearing model materials.");
|
||||
SetDirty();
|
||||
|
||||
for (auto& materialSlotPair : GetMaterialSlots())
|
||||
{
|
||||
EditorMaterialComponentSlot* materialSlot = materialSlotPair.second;
|
||||
if (materialSlot->m_id.IsSlotIdOnly())
|
||||
{
|
||||
materialSlot->Clear();
|
||||
}
|
||||
}
|
||||
});
|
||||
MaterialComponentRequestBus::Event(GetEntityId(), &MaterialComponentRequestBus::Events::ClearModelMaterialOverrides);
|
||||
|
||||
UpdateMaterialSlots();
|
||||
});
|
||||
action->setToolTip("Clear model materials and properties then rebuild material slots from the associated model.");
|
||||
|
||||
action = menu->addAction("Clear LOD Materials", [this]() {
|
||||
AzToolsFramework::ScopedUndoBatch undoBatch("Clearing LOD materials.");
|
||||
SetDirty();
|
||||
|
||||
for (auto& materialSlotPair : GetMaterialSlots())
|
||||
{
|
||||
EditorMaterialComponentSlot* materialSlot = materialSlotPair.second;
|
||||
if (materialSlot->m_id.IsLodAndSlotId())
|
||||
{
|
||||
materialSlot->Clear();
|
||||
}
|
||||
}
|
||||
});
|
||||
action->setEnabled(m_materialSlotsByLodEnabled);
|
||||
MaterialComponentRequestBus::Event(GetEntityId(), &MaterialComponentRequestBus::Events::ClearLodMaterialOverrides);
|
||||
|
||||
m_materialSlotsByLodEnabled = false;
|
||||
|
||||
UpdateMaterialSlots();
|
||||
});
|
||||
action->setToolTip("Clear LOD materials and properties then rebuild material slots from the associated model.");
|
||||
|
||||
action = menu->addAction("Clear Incompatible Materials", [this]() {
|
||||
AzToolsFramework::ScopedUndoBatch undoBatch("Clearing incompatible materials.");
|
||||
SetDirty();
|
||||
|
||||
MaterialComponentRequestBus::Event(GetEntityId(), &MaterialComponentRequestBus::Events::ClearIncompatibleMaterialOverrides);
|
||||
|
||||
UpdateMaterialSlots();
|
||||
});
|
||||
action->setToolTip("Clear residual materials that don't correspond to the associated model.");
|
||||
|
||||
action = menu->addAction("Clear Invalid Materials", [this]() {
|
||||
AzToolsFramework::ScopedUndoBatch undoBatch("Clearing invalid materials.");
|
||||
SetDirty();
|
||||
|
||||
MaterialComponentRequestBus::Event(GetEntityId(), &MaterialComponentRequestBus::Events::ClearInvalidMaterialOverrides);
|
||||
|
||||
UpdateMaterialSlots();
|
||||
});
|
||||
action->setToolTip("Clear materials that reference missing assets.");
|
||||
|
||||
action = menu->addAction("Repair Invalid Materials", [this]() {
|
||||
AzToolsFramework::ScopedUndoBatch undoBatch("Repairing invalid materials.");
|
||||
SetDirty();
|
||||
|
||||
MaterialComponentRequestBus::Event(GetEntityId(), &MaterialComponentRequestBus::Events::RepairInvalidMaterialOverrides);
|
||||
|
||||
UpdateMaterialSlots();
|
||||
});
|
||||
action->setToolTip("Repair materials that reference missing assets by assigning the default asset.");
|
||||
}
|
||||
|
||||
void EditorMaterialComponent::SetPrimaryAsset(const AZ::Data::AssetId& assetId)
|
||||
{
|
||||
m_controller.SetDefaultMaterialOverride(assetId);
|
||||
MaterialComponentRequestBus::Event(GetEntityId(), &MaterialComponentRequestBus::Events::SetDefaultMaterialOverride, assetId);
|
||||
|
||||
MaterialComponentNotificationBus::Event(GetEntityId(), &MaterialComponentNotifications::OnMaterialsEdited);
|
||||
|
||||
@@ -249,14 +277,18 @@ namespace AZ
|
||||
m_materialSlots = {};
|
||||
m_materialSlotsByLod = {};
|
||||
|
||||
const MaterialComponentConfig& config = m_controller.GetConfiguration();
|
||||
// Get current material assignments
|
||||
MaterialAssignmentMap currentMaterials;
|
||||
MaterialComponentRequestBus::EventResult(
|
||||
currentMaterials, GetEntityId(), &MaterialComponentRequestBus::Events::GetMaterialOverrides);
|
||||
|
||||
// Get the known material assignment slots from the associated model or other source
|
||||
MaterialAssignmentMap materialsFromSource;
|
||||
MaterialReceiverRequestBus::EventResult(materialsFromSource, GetEntityId(), &MaterialReceiverRequestBus::Events::GetMaterialAssignments);
|
||||
MaterialAssignmentMap originalMaterials;
|
||||
MaterialComponentRequestBus::EventResult(
|
||||
originalMaterials, GetEntityId(), &MaterialComponentRequestBus::Events::GetOriginalMaterialAssignments);
|
||||
|
||||
// Generate the table of editable materials using the source data to define number of groups, elements, and initial values
|
||||
for (const auto& materialPair : materialsFromSource)
|
||||
for (const auto& materialPair : originalMaterials)
|
||||
{
|
||||
// Setup the material slot entry
|
||||
EditorMaterialComponentSlot slot;
|
||||
@@ -264,7 +296,7 @@ namespace AZ
|
||||
slot.m_id = materialPair.first;
|
||||
|
||||
// if material is present in controller configuration, assign its data
|
||||
const MaterialAssignment& materialFromController = GetMaterialAssignmentFromMap(config.m_materials, slot.m_id);
|
||||
const MaterialAssignment& materialFromController = GetMaterialAssignmentFromMap(currentMaterials, slot.m_id);
|
||||
slot.m_materialAsset = materialFromController.m_materialAsset;
|
||||
|
||||
if (slot.m_id.IsDefault())
|
||||
@@ -289,7 +321,7 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
// Sort all of the slots by label to ensure stable index values (materialsFromSource is an unordered map)
|
||||
// Sort all of the slots by label to ensure stable index values (originalMaterials is an unordered map)
|
||||
AZStd::sort(m_materialSlots.begin(), m_materialSlots.end(),
|
||||
[](const auto& a, const auto& b) { return a.GetLabel() < b.GetLabel(); });
|
||||
|
||||
@@ -305,49 +337,36 @@ namespace AZ
|
||||
&AzToolsFramework::ToolsApplicationEvents::InvalidatePropertyDisplay, AzToolsFramework::Refresh_EntireTree);
|
||||
}
|
||||
|
||||
AZ::u32 EditorMaterialComponent::ResetMaterialSlots()
|
||||
{
|
||||
AzToolsFramework::ScopedUndoBatch undoBatch("Resetting materials.");
|
||||
SetDirty();
|
||||
|
||||
m_controller.SetMaterialOverrides(MaterialAssignmentMap());
|
||||
UpdateMaterialSlots();
|
||||
|
||||
m_materialSlotsByLodEnabled = false;
|
||||
|
||||
MaterialComponentNotificationBus::Event(GetEntityId(), &MaterialComponentNotifications::OnMaterialsEdited);
|
||||
|
||||
AzToolsFramework::ToolsApplicationEvents::Bus::Broadcast(
|
||||
&AzToolsFramework::ToolsApplicationEvents::InvalidatePropertyDisplay, AzToolsFramework::Refresh_EntireTree);
|
||||
|
||||
return AZ::Edit::PropertyRefreshLevels::EntireTree;
|
||||
}
|
||||
|
||||
AZ::u32 EditorMaterialComponent::OpenMaterialExporter()
|
||||
{
|
||||
AzToolsFramework::ScopedUndoBatch undoBatch("Generating materials.");
|
||||
SetDirty();
|
||||
|
||||
// First generating a unique set of all material asset IDs that will be used for source data generation
|
||||
AZStd::unordered_map<AZ::Data::AssetId, AZStd::string /*slot name*/> assetIdMap;
|
||||
MaterialAssignmentMap originalMaterials;
|
||||
MaterialComponentRequestBus::EventResult(
|
||||
originalMaterials, GetEntityId(), &MaterialComponentRequestBus::Events::GetOriginalMaterialAssignments);
|
||||
|
||||
auto materialSlots = GetMaterialSlots();
|
||||
for (auto& materialSlotPair : materialSlots)
|
||||
// Generate a unique set of all material asset IDs that will be used for source data generation
|
||||
AZStd::unordered_map<AZ::Data::AssetId, AZStd::string> assetIdToSlotNameMap;
|
||||
for (const auto& materialPair : originalMaterials)
|
||||
{
|
||||
Data::AssetId defaultMaterialAssetId = materialSlotPair.second->GetDefaultAssetId();
|
||||
if (defaultMaterialAssetId.IsValid())
|
||||
const Data::AssetId originalAssetId = materialPair.second.m_materialAsset.GetId();
|
||||
if (originalAssetId.IsValid())
|
||||
{
|
||||
assetIdMap[defaultMaterialAssetId] = materialSlotPair.second->GetLabel();
|
||||
MaterialComponentRequestBus::EventResult(
|
||||
assetIdToSlotNameMap[originalAssetId], GetEntityId(), &MaterialComponentRequestBus::Events::GetMaterialSlotLabel,
|
||||
materialPair.first);
|
||||
}
|
||||
}
|
||||
|
||||
// Convert the unique set of asset IDs into export items that can be configured in the dialog
|
||||
// The order should not matter because the table in the dialog can sort itself for a specific row
|
||||
EditorMaterialComponentExporter::ExportItemsContainer exportItems;
|
||||
for (auto assetIdInfo : assetIdMap)
|
||||
exportItems.reserve(assetIdToSlotNameMap.size());
|
||||
|
||||
for (const auto& [assetId, slotName] : assetIdToSlotNameMap)
|
||||
{
|
||||
EditorMaterialComponentExporter::ExportItem exportItem{ assetIdInfo.first, assetIdInfo.second };
|
||||
exportItems.push_back(exportItem);
|
||||
exportItems.emplace_back(assetId, slotName);
|
||||
}
|
||||
|
||||
// Display the export dialog so that the user can configure how they want different materials to be exported
|
||||
@@ -363,16 +382,17 @@ namespace AZ
|
||||
const auto& assetIdOutcome = AZ::RPI::AssetUtils::MakeAssetId(exportItem.GetExportPath(), 0);
|
||||
if (assetIdOutcome)
|
||||
{
|
||||
for (auto& materialSlotPair : materialSlots)
|
||||
for (const auto& materialPair : originalMaterials)
|
||||
{
|
||||
EditorMaterialComponentSlot* editorMaterialSlot = materialSlotPair.second;
|
||||
|
||||
if (editorMaterialSlot)
|
||||
// We need to check whether replaced material corresponds to this slot's default material.
|
||||
const Data::AssetId originalAssetId = materialPair.second.m_materialAsset.GetId();
|
||||
if (originalAssetId == exportItem.GetOriginalAssetId())
|
||||
{
|
||||
// We need to check whether replaced material corresponds to this slot's default material.
|
||||
if (editorMaterialSlot->GetDefaultAssetId() == exportItem.GetOriginalAssetId())
|
||||
if (m_materialSlotsByLodEnabled || !materialPair.first.IsLodAndSlotId())
|
||||
{
|
||||
editorMaterialSlot->SetAsset(assetIdOutcome.GetValue());
|
||||
MaterialComponentRequestBus::Event(
|
||||
GetEntityId(), &MaterialComponentRequestBus::Events::SetMaterialOverride, materialPair.first,
|
||||
assetIdOutcome.GetValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -380,12 +400,9 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
MaterialComponentNotificationBus::Event(GetEntityId(), &MaterialComponentNotifications::OnMaterialsEdited);
|
||||
UpdateMaterialSlots();
|
||||
|
||||
AzToolsFramework::ToolsApplicationEvents::Bus::Broadcast(
|
||||
&AzToolsFramework::ToolsApplicationEvents::InvalidatePropertyDisplay, AzToolsFramework::Refresh_AttributesAndValues);
|
||||
|
||||
return AZ::Edit::PropertyRefreshLevels::AttributesAndValues;
|
||||
return AZ::Edit::PropertyRefreshLevels::EntireTree;
|
||||
}
|
||||
|
||||
AZ::u32 EditorMaterialComponent::OnLodsToggled()
|
||||
@@ -395,15 +412,10 @@ namespace AZ
|
||||
|
||||
if (!m_materialSlotsByLodEnabled)
|
||||
{
|
||||
MaterialComponentConfig config = m_controller.GetConfiguration();
|
||||
AZStd::erase_if(config.m_materials, [](const auto& item) {
|
||||
const auto& [key, value] = item;
|
||||
return key.m_lodIndex != MaterialAssignmentId::NonLodIndex;
|
||||
});
|
||||
m_controller.SetMaterialOverrides(config.m_materials);
|
||||
MaterialComponentRequestBus::Event(GetEntityId(), &MaterialComponentRequestBus::Events::ClearLodMaterialOverrides);
|
||||
}
|
||||
|
||||
MaterialComponentNotificationBus::Event(GetEntityId(), &MaterialComponentNotifications::OnMaterialsEdited);
|
||||
UpdateMaterialSlots();
|
||||
|
||||
return AZ::Edit::PropertyRefreshLevels::EntireTree;
|
||||
}
|
||||
@@ -440,41 +452,5 @@ namespace AZ
|
||||
{
|
||||
return AZStd::string::format("LOD %d", lodIndex);
|
||||
}
|
||||
|
||||
template<typename ComponentType, typename ContainerType>
|
||||
void EditorMaterialComponent::BuildMaterialSlotMap(ComponentType& component, ContainerType& materialSlots)
|
||||
{
|
||||
materialSlots[DefaultMaterialAssignmentId] = &component.m_defaultMaterialSlot;
|
||||
|
||||
for (auto& slot : component.m_materialSlots)
|
||||
{
|
||||
materialSlots[slot.m_id] = &slot;
|
||||
}
|
||||
|
||||
if (component.m_materialSlotsByLodEnabled)
|
||||
{
|
||||
for (auto& slotsForLod : component.m_materialSlotsByLod)
|
||||
{
|
||||
for (auto& slot : slotsForLod)
|
||||
{
|
||||
materialSlots[slot.m_id] = &slot;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AZStd::unordered_map<MaterialAssignmentId, EditorMaterialComponentSlot*> EditorMaterialComponent::GetMaterialSlots()
|
||||
{
|
||||
AZStd::unordered_map<MaterialAssignmentId, EditorMaterialComponentSlot*> materialSlots;
|
||||
BuildMaterialSlotMap(*this, materialSlots);
|
||||
return AZStd::move(materialSlots);
|
||||
}
|
||||
|
||||
AZStd::unordered_map<MaterialAssignmentId, const EditorMaterialComponentSlot*> EditorMaterialComponent::GetMaterialSlots() const
|
||||
{
|
||||
AZStd::unordered_map<MaterialAssignmentId, const EditorMaterialComponentSlot*> materialSlots;
|
||||
BuildMaterialSlotMap(*this, materialSlots);
|
||||
return AZStd::move(materialSlots);
|
||||
}
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
|
||||
@@ -58,9 +58,6 @@ namespace AZ
|
||||
// controller configuration then those values will be assigned to the editor component slots.
|
||||
void UpdateMaterialSlots();
|
||||
|
||||
// Clears all values related to the material component and regenerates the editor slots
|
||||
AZ::u32 ResetMaterialSlots();
|
||||
|
||||
// Opens the source material export dialog and updates editor material slots based on
|
||||
// selected actions
|
||||
AZ::u32 OpenMaterialExporter();
|
||||
@@ -82,10 +79,6 @@ namespace AZ
|
||||
// Evaluate if materials can be edited
|
||||
bool IsEditingAllowed() const;
|
||||
|
||||
template<typename ComponentType, typename ContainerType>
|
||||
static void BuildMaterialSlotMap(ComponentType& component, ContainerType& materialSlots);
|
||||
AZStd::unordered_map<MaterialAssignmentId, EditorMaterialComponentSlot*> GetMaterialSlots();
|
||||
AZStd::unordered_map<MaterialAssignmentId, const EditorMaterialComponentSlot*> GetMaterialSlots() const;
|
||||
AZStd::string GetLabelForLod(int lodIndex) const;
|
||||
|
||||
AZStd::string m_message;
|
||||
|
||||
+4
@@ -55,6 +55,10 @@ namespace AZ
|
||||
|
||||
bool OpenExportDialog(ExportItemsContainer& exportItems)
|
||||
{
|
||||
// Sort material entries so they are ordered by name in the table
|
||||
AZStd::sort(exportItems.begin(), exportItems.end(),
|
||||
[](const auto& a, const auto& b) { return a.GetMaterialSlotName() < b.GetMaterialSlotName(); });
|
||||
|
||||
QWidget* activeWindow = nullptr;
|
||||
AzToolsFramework::EditorWindowRequestBus::BroadcastResult(activeWindow, &AzToolsFramework::EditorWindowRequests::GetAppMainWindow);
|
||||
|
||||
|
||||
+4
-3
@@ -140,7 +140,7 @@ namespace AZ
|
||||
|
||||
void EditorMaterialComponentSlot::SetAsset(const Data::AssetId& assetId)
|
||||
{
|
||||
m_materialAsset.Create(assetId);
|
||||
m_materialAsset = AZ::Data::Asset<AZ::RPI::MaterialAsset>(assetId, AZ::AzTypeInfo<AZ::RPI::MaterialAsset>::Uuid());
|
||||
MaterialComponentRequestBus::Event(
|
||||
m_entityId, &MaterialComponentRequestBus::Events::SetMaterialOverride, m_id, m_materialAsset.GetId());
|
||||
OnDataChanged();
|
||||
@@ -164,7 +164,7 @@ namespace AZ
|
||||
|
||||
void EditorMaterialComponentSlot::ClearToDefaultAsset()
|
||||
{
|
||||
m_materialAsset.Create(GetDefaultAssetId());
|
||||
m_materialAsset = AZ::Data::Asset<AZ::RPI::MaterialAsset>(GetDefaultAssetId(), AZ::AzTypeInfo<AZ::RPI::MaterialAsset>::Uuid());
|
||||
MaterialComponentRequestBus::Event(
|
||||
m_entityId, &MaterialComponentRequestBus::Events::SetMaterialOverride, m_id, m_materialAsset.GetId());
|
||||
ClearOverrides();
|
||||
@@ -204,7 +204,8 @@ namespace AZ
|
||||
const auto& assetIdOutcome = AZ::RPI::AssetUtils::MakeAssetId(exportItem.GetExportPath(), 0);
|
||||
if (assetIdOutcome)
|
||||
{
|
||||
m_materialAsset.Create(assetIdOutcome.GetValue());
|
||||
m_materialAsset = AZ::Data::Asset<AZ::RPI::MaterialAsset>(
|
||||
assetIdOutcome.GetValue(), AZ::AzTypeInfo<AZ::RPI::MaterialAsset>::Uuid());
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
+73
-11
@@ -43,6 +43,11 @@ namespace AZ
|
||||
->Event("SetDefaultMaterialOverride", &MaterialComponentRequestBus::Events::SetDefaultMaterialOverride)
|
||||
->Event("GetDefaultMaterialOverride", &MaterialComponentRequestBus::Events::GetDefaultMaterialOverride)
|
||||
->Event("ClearDefaultMaterialOverride", &MaterialComponentRequestBus::Events::ClearDefaultMaterialOverride)
|
||||
->Event("ClearModelMaterialOverrides", &MaterialComponentRequestBus::Events::ClearModelMaterialOverrides)
|
||||
->Event("ClearLodMaterialOverrides", &MaterialComponentRequestBus::Events::ClearLodMaterialOverrides)
|
||||
->Event("ClearIncompatibleMaterialOverrides", &MaterialComponentRequestBus::Events::ClearIncompatibleMaterialOverrides)
|
||||
->Event("ClearInvalidMaterialOverrides", &MaterialComponentRequestBus::Events::ClearInvalidMaterialOverrides)
|
||||
->Event("RepairInvalidMaterialOverrides", &MaterialComponentRequestBus::Events::RepairInvalidMaterialOverrides)
|
||||
->Event("SetMaterialOverride", &MaterialComponentRequestBus::Events::SetMaterialOverride)
|
||||
->Event("GetMaterialOverride", &MaterialComponentRequestBus::Events::GetMaterialOverride)
|
||||
->Event("ClearMaterialOverride", &MaterialComponentRequestBus::Events::ClearMaterialOverride)
|
||||
@@ -275,10 +280,10 @@ namespace AZ
|
||||
|
||||
MaterialAssignmentMap MaterialComponentController::GetOriginalMaterialAssignments() const
|
||||
{
|
||||
MaterialAssignmentMap materialAssignmentMap;
|
||||
MaterialAssignmentMap originalMaterials;
|
||||
MaterialReceiverRequestBus::EventResult(
|
||||
materialAssignmentMap, m_entityId, &MaterialReceiverRequestBus::Events::GetMaterialAssignments);
|
||||
return materialAssignmentMap;
|
||||
originalMaterials, m_entityId, &MaterialReceiverRequestBus::Events::GetMaterialAssignments);
|
||||
return originalMaterials;
|
||||
}
|
||||
|
||||
MaterialAssignmentId MaterialComponentController::FindMaterialAssignmentId(
|
||||
@@ -348,6 +353,67 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
void MaterialComponentController::ClearModelMaterialOverrides()
|
||||
{
|
||||
AZStd::erase_if(m_configuration.m_materials, [](const auto& materialPair) {
|
||||
return materialPair.first.IsSlotIdOnly();
|
||||
});
|
||||
QueueMaterialUpdateNotification();
|
||||
}
|
||||
|
||||
void MaterialComponentController::ClearLodMaterialOverrides()
|
||||
{
|
||||
AZStd::erase_if(m_configuration.m_materials, [](const auto& materialPair) {
|
||||
return materialPair.first.IsLodAndSlotId();
|
||||
});
|
||||
QueueMaterialUpdateNotification();
|
||||
}
|
||||
|
||||
void MaterialComponentController::ClearIncompatibleMaterialOverrides()
|
||||
{
|
||||
const MaterialAssignmentMap& originalMaterials = GetOriginalMaterialAssignments();
|
||||
AZStd::erase_if(m_configuration.m_materials, [&originalMaterials](const auto& materialPair) {
|
||||
return originalMaterials.find(materialPair.first) == originalMaterials.end();
|
||||
});
|
||||
QueueMaterialUpdateNotification();
|
||||
}
|
||||
|
||||
void MaterialComponentController::ClearInvalidMaterialOverrides()
|
||||
{
|
||||
AZStd::erase_if(m_configuration.m_materials, [](const auto& materialPair) {
|
||||
if (materialPair.second.m_materialAsset.GetId().IsValid())
|
||||
{
|
||||
AZ::Data::AssetInfo assetInfo;
|
||||
AZ::Data::AssetCatalogRequestBus::BroadcastResult(
|
||||
assetInfo, &AZ::Data::AssetCatalogRequestBus::Events::GetAssetInfoById,
|
||||
materialPair.second.m_materialAsset.GetId());
|
||||
return !assetInfo.m_assetId.IsValid();
|
||||
}
|
||||
return false;
|
||||
});
|
||||
QueueMaterialUpdateNotification();
|
||||
}
|
||||
|
||||
void MaterialComponentController::RepairInvalidMaterialOverrides()
|
||||
{
|
||||
for (auto& materialPair : m_configuration.m_materials)
|
||||
{
|
||||
if (materialPair.second.m_materialAsset.GetId().IsValid())
|
||||
{
|
||||
AZ::Data::AssetInfo assetInfo;
|
||||
AZ::Data::AssetCatalogRequestBus::BroadcastResult(
|
||||
assetInfo, &AZ::Data::AssetCatalogRequestBus::Events::GetAssetInfoById,
|
||||
materialPair.second.m_materialAsset.GetId());
|
||||
if (!assetInfo.m_assetId.IsValid())
|
||||
{
|
||||
materialPair.second.m_materialAsset = AZ::Data::Asset<AZ::RPI::MaterialAsset>(
|
||||
GetDefaultMaterialAssetId(materialPair.first), AZ::AzTypeInfo<AZ::RPI::MaterialAsset>::Uuid());
|
||||
}
|
||||
}
|
||||
}
|
||||
LoadMaterials();
|
||||
}
|
||||
|
||||
void MaterialComponentController::SetDefaultMaterialOverride(const AZ::Data::AssetId& materialAssetId)
|
||||
{
|
||||
SetMaterialOverride(DefaultMaterialAssignmentId, materialAssetId);
|
||||
@@ -363,9 +429,11 @@ namespace AZ
|
||||
ClearMaterialOverride(DefaultMaterialAssignmentId);
|
||||
}
|
||||
|
||||
void MaterialComponentController::SetMaterialOverride(const MaterialAssignmentId& materialAssignmentId, const AZ::Data::AssetId& materialAssetId)
|
||||
void MaterialComponentController::SetMaterialOverride(
|
||||
const MaterialAssignmentId& materialAssignmentId, const AZ::Data::AssetId& materialAssetId)
|
||||
{
|
||||
m_configuration.m_materials[materialAssignmentId].m_materialAsset.Create(materialAssetId);
|
||||
m_configuration.m_materials[materialAssignmentId].m_materialAsset =
|
||||
AZ::Data::Asset<AZ::RPI::MaterialAsset>(materialAssetId, AZ::AzTypeInfo<AZ::RPI::MaterialAsset>::Uuid());
|
||||
LoadMaterials();
|
||||
}
|
||||
|
||||
@@ -616,7 +684,6 @@ namespace AZ
|
||||
|
||||
void MaterialComponentController::ClearAllPropertyOverrides()
|
||||
{
|
||||
bool cleared = false;
|
||||
for (auto& materialPair : m_configuration.m_materials)
|
||||
{
|
||||
if (!materialPair.second.m_propertyOverrides.empty())
|
||||
@@ -625,13 +692,8 @@ namespace AZ
|
||||
materialPair.second.RebuildInstance();
|
||||
MaterialComponentNotificationBus::Event(m_entityId, &MaterialComponentNotifications::OnMaterialInstanceCreated, materialPair.second);
|
||||
QueueMaterialUpdateNotification();
|
||||
cleared = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (cleared)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
void MaterialComponentController::SetPropertyOverrides(
|
||||
|
||||
+5
@@ -52,6 +52,11 @@ namespace AZ
|
||||
void SetMaterialOverrides(const MaterialAssignmentMap& materials) override;
|
||||
const MaterialAssignmentMap& GetMaterialOverrides() const override;
|
||||
void ClearAllMaterialOverrides() override;
|
||||
void ClearModelMaterialOverrides() override;
|
||||
void ClearLodMaterialOverrides() override;
|
||||
void ClearIncompatibleMaterialOverrides() override;
|
||||
void ClearInvalidMaterialOverrides() override;
|
||||
void RepairInvalidMaterialOverrides() override;
|
||||
void SetDefaultMaterialOverride(const AZ::Data::AssetId& materialAssetId) override;
|
||||
const AZ::Data::AssetId GetDefaultMaterialOverride() const override;
|
||||
void ClearDefaultMaterialOverride() override;
|
||||
|
||||
@@ -18,8 +18,8 @@ ly_add_target(
|
||||
PUBLIC
|
||||
Gem::Atom_RPI.Public
|
||||
AZ::AtomCore
|
||||
PRIVATE
|
||||
Legacy::CryCommon
|
||||
AZ::AzCore
|
||||
AZ::AzFramework
|
||||
)
|
||||
|
||||
ly_add_target(
|
||||
@@ -32,7 +32,6 @@ ly_add_target(
|
||||
Source
|
||||
BUILD_DEPENDENCIES
|
||||
PRIVATE
|
||||
Legacy::CryCommon
|
||||
Gem::Camera.Static
|
||||
)
|
||||
|
||||
@@ -56,9 +55,6 @@ if (PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
Source
|
||||
BUILD_DEPENDENCIES
|
||||
PRIVATE
|
||||
Legacy::CryCommon
|
||||
Legacy::Editor.Headers
|
||||
Legacy::EditorCommon
|
||||
AZ::AzToolsFramework
|
||||
Gem::Camera.Static
|
||||
RUNTIME_DEPENDENCIES
|
||||
|
||||
@@ -14,9 +14,7 @@
|
||||
|
||||
#include "CameraComponent.h"
|
||||
|
||||
#include <MathConversion.h>
|
||||
#include <AzCore/Math/MatrixUtils.h>
|
||||
#include <IRenderer.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
|
||||
namespace Camera
|
||||
|
||||
@@ -11,9 +11,6 @@
|
||||
#include <AzFramework/Components/ComponentAdapter.h>
|
||||
|
||||
#include <AzFramework/Components/CameraBus.h>
|
||||
#include <IViewSystem.h>
|
||||
#include <ISystem.h>
|
||||
#include <Cry_Camera.h>
|
||||
#include <CameraComponentController.h>
|
||||
|
||||
#include <Atom/RPI.Public/Base.h>
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include "CameraComponentController.h"
|
||||
#include "CameraViewRegistrationBus.h"
|
||||
|
||||
#include <MathConversion.h>
|
||||
#include <AzCore/Math/MatrixUtils.h>
|
||||
#include <Atom/RPI.Public/View.h>
|
||||
#include <Atom/RPI.Public/ViewportContextManager.h>
|
||||
@@ -53,7 +52,7 @@ namespace Camera
|
||||
->Attribute(AZ::Edit::Attributes::ChangeNotify, AZ::Edit::PropertyRefreshLevels::ValuesOnly)
|
||||
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &CameraComponentConfig::m_fov, "Field of view", "Vertical field of view in degrees")
|
||||
->Attribute(AZ::Edit::Attributes::Min, MIN_FOV)
|
||||
->Attribute(AZ::Edit::Attributes::Min, MinFoV)
|
||||
->Attribute(AZ::Edit::Attributes::Suffix, " degrees")
|
||||
->Attribute(AZ::Edit::Attributes::Step, 1.f)
|
||||
->Attribute(AZ::Edit::Attributes::Max, AZ::RadToDeg(AZ::Constants::Pi) - 0.0001f) //We assert at fovs >= Pi so set the max for this field to be just under that
|
||||
@@ -61,7 +60,7 @@ namespace Camera
|
||||
->Attribute(AZ::Edit::Attributes::Visibility, &CameraComponentConfig::GetPerspectiveParameterVisibility)
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &CameraComponentConfig::m_nearClipDistance, "Near clip distance",
|
||||
"Distance to the near clip plane of the view Frustum")
|
||||
->Attribute(AZ::Edit::Attributes::Min, CAMERA_MIN_NEAR)
|
||||
->Attribute(AZ::Edit::Attributes::Min, MinimumNearPlaneDistance)
|
||||
->Attribute(AZ::Edit::Attributes::Suffix, " m")
|
||||
->Attribute(AZ::Edit::Attributes::Step, 0.1f)
|
||||
->Attribute(AZ::Edit::Attributes::Max, &CameraComponentConfig::GetFarClipDistance)
|
||||
@@ -150,6 +149,11 @@ namespace Camera
|
||||
}
|
||||
}
|
||||
|
||||
void CameraComponentController::SetShouldActivateFunction(AZStd::function<bool()> shouldActivateFunction)
|
||||
{
|
||||
m_shouldActivateFn = shouldActivateFunction;
|
||||
}
|
||||
|
||||
void CameraComponentController::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
CameraComponentConfig::Reflect(context);
|
||||
@@ -202,36 +206,6 @@ namespace Camera
|
||||
{
|
||||
m_entityId = entityId;
|
||||
|
||||
if ((!m_viewSystem)||(!m_system))
|
||||
{
|
||||
// perform first-time init
|
||||
if (gEnv)
|
||||
{
|
||||
m_system = gEnv->pSystem;
|
||||
}
|
||||
if (m_system)
|
||||
{
|
||||
// Initialize local view.
|
||||
m_viewSystem = m_system->GetIViewSystem();
|
||||
if (!m_viewSystem)
|
||||
{
|
||||
AZ_Error("CameraComponent", m_viewSystem != nullptr, "The CameraComponent shouldn't be used without a local view system");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_viewSystem)
|
||||
{
|
||||
if (m_view == nullptr)
|
||||
{
|
||||
m_view = m_viewSystem->CreateView();
|
||||
|
||||
AZ::Entity* entity = nullptr;
|
||||
AZ::ComponentApplicationBus::BroadcastResult(entity, &AZ::ComponentApplicationRequests::FindEntity, m_entityId);
|
||||
m_view->LinkTo(entity);
|
||||
}
|
||||
}
|
||||
|
||||
auto atomViewportRequests = AZ::Interface<AZ::RPI::ViewportContextRequestsInterface>::Get();
|
||||
if (atomViewportRequests)
|
||||
{
|
||||
@@ -270,9 +244,8 @@ namespace Camera
|
||||
CameraBus::Handler::BusConnect();
|
||||
CameraNotificationBus::Broadcast(&CameraNotificationBus::Events::OnCameraAdded, m_entityId);
|
||||
|
||||
// Activate our camera if we're running from the launcher or Editor game mode
|
||||
// Otherwise, let the Editor keep managing the active camera
|
||||
if (m_config.m_makeActiveViewOnActivation && (!gEnv || !gEnv->IsEditor() || gEnv->IsEditorGameMode()))
|
||||
// Only activate if we're configured to do so, and our activation call back indicates that we should
|
||||
if (m_config.m_makeActiveViewOnActivation && (!m_shouldActivateFn || m_shouldActivateFn()))
|
||||
{
|
||||
MakeActiveView();
|
||||
}
|
||||
@@ -284,20 +257,6 @@ namespace Camera
|
||||
CameraBus::Handler::BusDisconnect();
|
||||
AZ::TransformNotificationBus::Handler::BusDisconnect(m_entityId);
|
||||
CameraRequestBus::Handler::BusDisconnect(m_entityId);
|
||||
if (m_viewSystem)
|
||||
{
|
||||
if (m_view != nullptr && m_viewSystem->GetViewId(m_view) != 0)
|
||||
{
|
||||
m_view->Unlink();
|
||||
}
|
||||
if (m_viewSystem->GetActiveView() == m_view)
|
||||
{
|
||||
m_viewSystem->SetActiveView(m_prevViewId);
|
||||
}
|
||||
m_viewSystem->RemoveView(m_view);
|
||||
m_prevViewId = 0;
|
||||
m_view = nullptr;
|
||||
}
|
||||
|
||||
auto atomViewportRequests = AZ::Interface<AZ::RPI::ViewportContextRequestsInterface>::Get();
|
||||
if (atomViewportRequests)
|
||||
@@ -429,13 +388,6 @@ namespace Camera
|
||||
return;
|
||||
}
|
||||
|
||||
// Set Legacy Cry view, if it exists
|
||||
if (m_viewSystem)
|
||||
{
|
||||
m_prevViewId = AZ::u32(m_viewSystem->GetActiveViewId());
|
||||
m_viewSystem->SetActiveView(m_view);
|
||||
}
|
||||
|
||||
// Set Atom camera, if it exists
|
||||
if (m_atomCamera)
|
||||
{
|
||||
@@ -461,12 +413,6 @@ namespace Camera
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_view)
|
||||
{
|
||||
CCamera& camera = m_view->GetCamera();
|
||||
camera.SetMatrix(AZTransformToLYTransform(world.GetOrthogonalized()));
|
||||
}
|
||||
|
||||
if (m_atomCamera)
|
||||
{
|
||||
m_updatingTransformFromEntity = true;
|
||||
@@ -495,25 +441,15 @@ namespace Camera
|
||||
|
||||
void CameraComponentController::UpdateCamera()
|
||||
{
|
||||
if (m_view)
|
||||
{
|
||||
auto viewParams = *m_view->GetCurrentParams();
|
||||
viewParams.fov = AZ::DegToRad(m_config.m_fov);
|
||||
viewParams.nearplane = m_config.m_nearClipDistance;
|
||||
viewParams.farplane = m_config.m_farClipDistance;
|
||||
m_view->SetCurrentParams(viewParams);
|
||||
}
|
||||
|
||||
if (auto viewportContext = GetViewportContext())
|
||||
{
|
||||
AZ::Matrix4x4 viewToClipMatrix;
|
||||
float aspectRatio = m_view ? m_view->GetCamera().GetPixelAspectRatio() : 1.f;
|
||||
if (!m_atomAuxGeom)
|
||||
{
|
||||
SetupAtomAuxGeom(viewportContext);
|
||||
}
|
||||
auto windowSize = viewportContext->GetViewportSize();
|
||||
aspectRatio = aznumeric_cast<float>(windowSize.m_width) / aznumeric_cast<float>(windowSize.m_height);
|
||||
const float aspectRatio = aznumeric_cast<float>(windowSize.m_width) / aznumeric_cast<float>(windowSize.m_height);
|
||||
|
||||
// This assumes a reversed depth buffer, in line with other LY Atom integration
|
||||
if (m_config.m_orthographic)
|
||||
|
||||
@@ -16,15 +16,12 @@
|
||||
#include <Atom/RPI.Public/ViewProviderBus.h>
|
||||
#include <Atom/RPI.Public/AuxGeom/AuxGeomFeatureProcessorInterface.h>
|
||||
|
||||
#include <IViewSystem.h>
|
||||
#include <ISystem.h>
|
||||
#include <Cry_Camera.h>
|
||||
|
||||
namespace Camera
|
||||
{
|
||||
static constexpr float DefaultFoV = 75.0f;
|
||||
static constexpr float MinFoV = std::numeric_limits<float>::epsilon();
|
||||
static constexpr float MaxFoV = AZ::RadToDeg(AZ::Constants::Pi);
|
||||
static constexpr float MinimumNearPlaneDistance = 0.001f;
|
||||
static constexpr float DefaultNearPlaneDistance = 0.2f;
|
||||
static constexpr float DefaultFarClipPlaneDistance = 1024.0f;
|
||||
static constexpr float DefaultFrustumDimension = 256.f;
|
||||
@@ -69,6 +66,10 @@ namespace Camera
|
||||
CameraComponentController() = default;
|
||||
explicit CameraComponentController(const CameraComponentConfig& config);
|
||||
|
||||
//! Defines a callback for determining whether this camera should push itself to the top of the Atom camera stack.
|
||||
//! Used by the Editor to disable undesirable camera changes in edit mode.
|
||||
void SetShouldActivateFunction(AZStd::function<bool()> shouldActivateFunction);
|
||||
|
||||
// Controller interface
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required);
|
||||
@@ -134,10 +135,6 @@ namespace Camera
|
||||
bool m_updatingTransformFromEntity = false;
|
||||
bool m_isActiveView = false;
|
||||
|
||||
// Cry view integration
|
||||
IView* m_view = nullptr;
|
||||
AZ::u32 m_prevViewId = 0;
|
||||
IViewSystem* m_viewSystem = nullptr;
|
||||
ISystem* m_system = nullptr;
|
||||
AZStd::function<bool()> m_shouldActivateFn;
|
||||
};
|
||||
} // namespace Camera
|
||||
|
||||
@@ -21,17 +21,12 @@
|
||||
#include <AzToolsFramework/API/EntityCompositionRequestBus.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityHelpers.h>
|
||||
|
||||
#include <IEditor.h>
|
||||
#include <ViewManager.h>
|
||||
#include <GameEngine.h>
|
||||
#include <Objects/BaseObject.h>
|
||||
#include <Include/IObjectManager.h>
|
||||
|
||||
#include <Cry_Geo.h>
|
||||
#include <MathConversion.h>
|
||||
#include <AzToolsFramework/API/EditorCameraBus.h>
|
||||
#include "ViewportCameraSelectorWindow.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QMenu>
|
||||
|
||||
namespace Camera
|
||||
{
|
||||
void CameraEditorSystemComponent::Reflect(AZ::ReflectContext* context)
|
||||
@@ -72,15 +67,6 @@ namespace Camera
|
||||
|
||||
void CameraEditorSystemComponent::PopulateEditorGlobalContextMenu(QMenu* menu, const AZ::Vector2&, int flags)
|
||||
{
|
||||
IEditor* editor;
|
||||
AzToolsFramework::EditorRequests::Bus::BroadcastResult(editor, &AzToolsFramework::EditorRequests::GetEditor);
|
||||
|
||||
CGameEngine* gameEngine = editor->GetGameEngine();
|
||||
if (!gameEngine || !gameEngine->IsLevelLoaded())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(flags & AzToolsFramework::EditorEvents::eECMF_HIDE_ENTITY_CREATION))
|
||||
{
|
||||
QAction* action = menu->addAction(QObject::tr("Create camera entity from view"));
|
||||
@@ -90,9 +76,6 @@ namespace Camera
|
||||
|
||||
void CameraEditorSystemComponent::CreateCameraEntityFromViewport()
|
||||
{
|
||||
IEditor* editor = nullptr;
|
||||
AzToolsFramework::EditorRequests::Bus::BroadcastResult(editor, &AzToolsFramework::EditorRequests::GetEditor);
|
||||
|
||||
AzFramework::CameraState cameraState{};
|
||||
AZ::EBusReduceResult<bool, AZStd::logical_or<bool>> aggregator;
|
||||
Camera::EditorCameraRequestBus::BroadcastResult(
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
*/
|
||||
|
||||
#include <AzCore/Module/Module.h>
|
||||
#include <IGem.h>
|
||||
|
||||
#include "CameraComponent.h"
|
||||
#include "CameraSystemComponent.h"
|
||||
@@ -22,13 +21,13 @@
|
||||
namespace Camera
|
||||
{
|
||||
class CameraModule
|
||||
: public CryHooksModule
|
||||
: public AZ::Module
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(CameraModule, "{C2E72B0D-BCEF-452A-9BFA-03833015258C}", AZ::Module);
|
||||
|
||||
CameraModule()
|
||||
: CryHooksModule()
|
||||
: AZ::Module()
|
||||
{
|
||||
m_descriptors.insert(m_descriptors.end(), {
|
||||
Camera::CameraComponent::CreateDescriptor(),
|
||||
|
||||
@@ -12,10 +12,9 @@
|
||||
#include "EditorCameraComponent.h"
|
||||
#include "ViewportCameraSelectorWindow.h"
|
||||
|
||||
#include <MathConversion.h>
|
||||
#include <IRenderer.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
|
||||
|
||||
#include <Atom/RPI.Public/ViewportContext.h>
|
||||
#include <Atom/RPI.Public/View.h>
|
||||
@@ -33,6 +32,14 @@ namespace Camera
|
||||
CameraComponentConfig controllerConfig = m_controller.GetConfiguration();
|
||||
controllerConfig.m_editorEntityId = GetEntityId().operator AZ::u64();
|
||||
m_controller.SetConfiguration(controllerConfig);
|
||||
// Only allow our camera to activate with the component if we're currently in game mode.
|
||||
m_controller.SetShouldActivateFunction([]()
|
||||
{
|
||||
bool isInGameMode = true;
|
||||
AzToolsFramework::EditorEntityContextRequestBus::BroadcastResult(
|
||||
isInGameMode, &AzToolsFramework::EditorEntityContextRequestBus::Events::IsEditorRunningGame);
|
||||
return isInGameMode;
|
||||
});
|
||||
|
||||
// Call base class activate, which in turn calls Activate on our controller.
|
||||
EditorCameraComponentBase::Activate();
|
||||
|
||||
@@ -21,8 +21,6 @@
|
||||
#include <AzFramework/Components/EditorEntityEvents.h>
|
||||
#include "CameraComponent.h"
|
||||
#include "CameraComponentController.h"
|
||||
#include <IViewSystem.h>
|
||||
#include <Cry_Camera.h>
|
||||
|
||||
#include <Atom/RPI.Public/Base.h>
|
||||
|
||||
|
||||
@@ -7,17 +7,14 @@
|
||||
*/
|
||||
#include "ViewportCameraSelectorWindow.h"
|
||||
#include "ViewportCameraSelectorWindow_Internals.h"
|
||||
#include <IEditor.h>
|
||||
#include <qmetatype.h>
|
||||
#include <QScopedValueRollback>
|
||||
#include <QListView>
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <QVBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <ViewManager.h>
|
||||
#include <Maestro/Bus/EditorSequenceBus.h>
|
||||
#include <Maestro/Bus/SequenceComponentBus.h>
|
||||
#include <AzToolsFramework/API/EditorCameraBus.h>
|
||||
#include <AzToolsFramework/API/ViewPaneOptions.h>
|
||||
|
||||
namespace Qt
|
||||
{
|
||||
@@ -308,7 +305,7 @@ namespace Camera
|
||||
|
||||
void RegisterViewportCameraSelectorWindow()
|
||||
{
|
||||
QtViewOptions viewOptions;
|
||||
AzToolsFramework::ViewPaneOptions viewOptions;
|
||||
viewOptions.isPreview = true;
|
||||
viewOptions.showInMenu = true;
|
||||
viewOptions.preferedDockingArea = Qt::DockWidgetArea::LeftDockWidgetArea;
|
||||
|
||||
@@ -2512,6 +2512,26 @@ namespace LandscapeCanvasEditor
|
||||
{
|
||||
// See comment above in OnPrefabInstancePropagationBegin
|
||||
m_prefabPropagationInProgress = false;
|
||||
|
||||
// After prefab propagation is complete, the entity tied to one of our open
|
||||
// graphs might have been deleted (e.g. if a prefab was created from that entity).
|
||||
// Any open graphs tied to an entity that no longer exists will need to be closed.
|
||||
// We need to close them in a separate iterator because the CloseEditor API will
|
||||
// end up modifying m_dockWidgetsByEntity.
|
||||
AZStd::vector<GraphCanvas::DockWidgetId> dockWidgetsToDelete;
|
||||
for (auto [entityId, dockWidgetId] : m_dockWidgetsByEntity)
|
||||
{
|
||||
AZ::Entity* entity = nullptr;
|
||||
AZ::ComponentApplicationBus::BroadcastResult(entity, &AZ::ComponentApplicationRequests::FindEntity, entityId);
|
||||
if (!entity)
|
||||
{
|
||||
dockWidgetsToDelete.push_back(dockWidgetId);
|
||||
}
|
||||
}
|
||||
for (auto dockWidgetId : dockWidgetsToDelete)
|
||||
{
|
||||
CloseEditor(dockWidgetId);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::OnCryEditorEndCreate()
|
||||
|
||||
Vendored
+29
@@ -0,0 +1,29 @@
|
||||
#
|
||||
# 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
|
||||
#
|
||||
#
|
||||
|
||||
# Open a new scope so we can make changes to CMAKE_MODULE_PATH, and restore it
|
||||
# when we're done
|
||||
function(FindX11)
|
||||
# O3DE's FindX11.cmake is a wrapper for the one that CMake provides. Remove
|
||||
# our current directory from CMAKE_MODULE_PATH to avoid recursive includes
|
||||
list(REMOVE_ITEM CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
find_package(X11 COMPONENTS ${X11_FIND_COMPONENTS} QUIET)
|
||||
|
||||
foreach(component IN LISTS X11_FIND_COMPONENTS)
|
||||
ly_add_external_target(
|
||||
SYSTEM
|
||||
PACKAGE X11
|
||||
NAME ${component}
|
||||
VERSION ""
|
||||
BUILD_DEPENDENCIES
|
||||
X11::${component}
|
||||
)
|
||||
endforeach()
|
||||
endfunction()
|
||||
FindX11()
|
||||
+13
-1
@@ -477,11 +477,23 @@ function(ly_parse_third_party_dependencies ly_THIRD_PARTY_LIBRARIES)
|
||||
if(${dependency_namespace} STREQUAL "3rdParty")
|
||||
if (NOT TARGET ${dependency})
|
||||
list(GET dependency_list 1 dependency_package)
|
||||
list(LENGTH dependency_list dependency_list_length)
|
||||
ly_download_associated_package(${dependency_package})
|
||||
find_package(${dependency_package} REQUIRED MODULE)
|
||||
if (dependency_list_length GREATER 2)
|
||||
# There's an optional interface specified
|
||||
list(GET dependency_list 2 component)
|
||||
list(APPEND packages_with_components ${dependency_package})
|
||||
list(APPEND ${dependency_package}_components ${component})
|
||||
else()
|
||||
find_package(${dependency_package} REQUIRED MODULE)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
foreach(dependency IN LISTS packages_with_components)
|
||||
find_package(${dependency} REQUIRED MODULE COMPONENTS ${${dependency}_components})
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
#! ly_configure_target_platform_properties: Configures any platform specific properties on target
|
||||
|
||||
Reference in New Issue
Block a user