Merge main

This commit is contained in:
mnaumov
2021-04-27 17:07:42 -07:00
467 changed files with 5291 additions and 32992 deletions
@@ -9,211 +9,14 @@ remove or modify any license notices. This file is distributed on an "AS IS" BAS
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
import logging
import os
import pytest
import editor_python_test_tools.hydra_test_utils as hydra
logger = logging.getLogger(__name__)
EDITOR_TIMEOUT = 120
TEST_DIRECTORY = os.path.join(os.path.dirname(__file__), "atom_hydra_scripts")
@pytest.mark.parametrize("project", ["AutomatedTesting"])
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
@pytest.mark.parametrize("level", ["auto_test"])
class TestAtomEditorComponents(object):
@pytest.mark.test_case_id(
"C32078117", # Area Light
"C32078130", # Display Mapper
"C32078129", # Light
"C32078131", # Radius Weight Modifier
"C32078127", # PostFX Layer
"C32078126", # Point Light
"C32078125", # Physical Sky
"C32078115", # Global Skylight (IBL)
"C32078121", # Exposure Control
"C32078120", # Directional Light
"C32078119", # DepthOfField
"C32078118") # Decal
def test_AtomEditorComponents_AddedToEntity(self, request, editor, level, workspace, project, launcher_platform):
cfg_args = [level]
expected_lines = [
# Area Light Component
"Area Light Entity successfully created",
"Area Light_test: Component added to the entity: True",
"Area Light_test: Component removed after UNDO: True",
"Area Light_test: Component added after REDO: True",
"Area Light_test: Entered game mode: True",
"Area Light_test: Entity enabled after adding required components: True",
"Area Light_test: Entity is hidden: True",
"Area Light_test: Entity is shown: True",
"Area Light_test: Entity deleted: True",
"Area Light_test: UNDO entity deletion works: True",
"Area Light_test: REDO entity deletion works: True",
# Decal Component
"Decal Entity successfully created",
"Decal_test: Component added to the entity: True",
"Decal_test: Component removed after UNDO: True",
"Decal_test: Component added after REDO: True",
"Decal_test: Entered game mode: True",
"Decal_test: Exit game mode: True",
"Decal Settings|Decal Settings|Material: SUCCESS",
"Decal_test: Entity is hidden: True",
"Decal_test: Entity is shown: True",
"Decal_test: Entity deleted: True",
"Decal_test: UNDO entity deletion works: True",
"Decal_test: REDO entity deletion works: True",
# DepthOfField Component
"DepthOfField Entity successfully created",
"DepthOfField_test: Component added to the entity: True",
"DepthOfField_test: Component removed after UNDO: True",
"DepthOfField_test: Component added after REDO: True",
"DepthOfField_test: Entered game mode: True",
"DepthOfField_test: Exit game mode: True",
"DepthOfField_test: Entity disabled initially: True",
"DepthOfField_test: Entity enabled after adding required components: True",
"DepthOfField Controller|Configuration|Camera Entity: SUCCESS",
"DepthOfField_test: Entity is hidden: True",
"DepthOfField_test: Entity is shown: True",
"DepthOfField_test: Entity deleted: True",
"DepthOfField_test: UNDO entity deletion works: True",
"DepthOfField_test: REDO entity deletion works: True",
# Directional Light Component
"Directional Light Entity successfully created",
"Directional Light_test: Component added to the entity: True",
"Directional Light_test: Component removed after UNDO: True",
"Directional Light_test: Component added after REDO: True",
"Directional Light_test: Entered game mode: True",
"Directional Light_test: Exit game mode: True",
"Directional Light Controller|Configuration|Shadow|Camera: SUCCESS",
"Directional Light_test: Entity is hidden: True",
"Directional Light_test: Entity is shown: True",
"Directional Light_test: Entity deleted: True",
"Directional Light_test: UNDO entity deletion works: True",
"Directional Light_test: REDO entity deletion works: True",
# Exposure Control Component
"Exposure Control Entity successfully created",
"Exposure Control_test: Component added to the entity: True",
"Exposure Control_test: Component removed after UNDO: True",
"Exposure Control_test: Component added after REDO: True",
"Exposure Control_test: Entered game mode: True",
"Exposure Control_test: Exit game mode: True",
"Exposure Control_test: Entity disabled initially: True",
"Exposure Control_test: Entity enabled after adding required components: True",
"Exposure Control_test: Entity is hidden: True",
"Exposure Control_test: Entity is shown: True",
"Exposure Control_test: Entity deleted: True",
"Exposure Control_test: UNDO entity deletion works: True",
"Exposure Control_test: REDO entity deletion works: True",
# Global Skylight (IBL) Component
"Global Skylight (IBL) Entity successfully created",
"Global Skylight (IBL)_test: Component added to the entity: True",
"Global Skylight (IBL)_test: Component removed after UNDO: True",
"Global Skylight (IBL)_test: Component added after REDO: True",
"Global Skylight (IBL)_test: Entered game mode: True",
"Global Skylight (IBL)_test: Exit game mode: True",
"Global Skylight (IBL) Controller|Configuration|Diffuse Image: SUCCESS",
"Global Skylight (IBL) Controller|Configuration|Specular Image: SUCCESS",
"Global Skylight (IBL)_test: Entity is hidden: True",
"Global Skylight (IBL)_test: Entity is shown: True",
"Global Skylight (IBL)_test: Entity deleted: True",
"Global Skylight (IBL)_test: UNDO entity deletion works: True",
"Global Skylight (IBL)_test: REDO entity deletion works: True",
# Physical Sky Component
"Physical Sky Entity successfully created",
"Physical Sky component was added to entity",
"Entity has a Physical Sky component",
"Physical Sky_test: Component added to the entity: True",
"Physical Sky_test: Component removed after UNDO: True",
"Physical Sky_test: Component added after REDO: True",
"Physical Sky_test: Entered game mode: True",
"Physical Sky_test: Exit game mode: True",
"Physical Sky_test: Entity is hidden: True",
"Physical Sky_test: Entity is shown: True",
"Physical Sky_test: Entity deleted: True",
"Physical Sky_test: UNDO entity deletion works: True",
"Physical Sky_test: REDO entity deletion works: True",
# Point Light Component
"Point Light Entity successfully created",
"Point Light_test: Component added to the entity: True",
"Point Light_test: Component removed after UNDO: True",
"Point Light_test: Component added after REDO: True",
"Point Light_test: Entered game mode: True",
"Point Light_test: Exit game mode: True",
"Point Light_test: Entity is hidden: True",
"Point Light_test: Entity is shown: True",
"Point Light_test: Entity deleted: True",
"Point Light_test: UNDO entity deletion works: True",
"Point Light_test: REDO entity deletion works: True",
# PostFX Layer Component
"PostFX Layer Entity successfully created",
"PostFX Layer_test: Component added to the entity: True",
"PostFX Layer_test: Component removed after UNDO: True",
"PostFX Layer_test: Component added after REDO: True",
"PostFX Layer_test: Entered game mode: True",
"PostFX Layer_test: Exit game mode: True",
"PostFX Layer_test: Entity is hidden: True",
"PostFX Layer_test: Entity is shown: True",
"PostFX Layer_test: Entity deleted: True",
"PostFX Layer_test: UNDO entity deletion works: True",
"PostFX Layer_test: REDO entity deletion works: True",
# Radius Weight Modifier Component
"Radius Weight Modifier Entity successfully created",
"Radius Weight Modifier_test: Component added to the entity: True",
"Radius Weight Modifier_test: Component removed after UNDO: True",
"Radius Weight Modifier_test: Component added after REDO: True",
"Radius Weight Modifier_test: Entered game mode: True",
"Radius Weight Modifier_test: Exit game mode: True",
"Radius Weight Modifier_test: Entity is hidden: True",
"Radius Weight Modifier_test: Entity is shown: True",
"Radius Weight Modifier_test: Entity deleted: True",
"Radius Weight Modifier_test: UNDO entity deletion works: True",
"Radius Weight Modifier_test: REDO entity deletion works: True",
# Light Component
"Light Entity successfully created",
"Light_test: Component added to the entity: True",
"Light_test: Component removed after UNDO: True",
"Light_test: Component added after REDO: True",
"Light_test: Entered game mode: True",
"Light_test: Exit game mode: True",
"Light_test: Entity is hidden: True",
"Light_test: Entity is shown: True",
"Light_test: Entity deleted: True",
"Light_test: UNDO entity deletion works: True",
"Light_test: REDO entity deletion works: True",
# Display Mapper Component
"Display Mapper Entity successfully created",
"Display Mapper_test: Component added to the entity: True",
"Display Mapper_test: Component removed after UNDO: True",
"Display Mapper_test: Component added after REDO: True",
"Display Mapper_test: Entered game mode: True",
"Display Mapper_test: Exit game mode: True",
"Display Mapper_test: Entity is hidden: True",
"Display Mapper_test: Entity is shown: True",
"Display Mapper_test: Entity deleted: True",
"Display Mapper_test: UNDO entity deletion works: True",
"Display Mapper_test: REDO entity deletion works: True",
]
unexpected_lines = [
"failed to open",
"Traceback (most recent call last):",
]
hydra.launch_and_validate_results(
request,
TEST_DIRECTORY,
editor,
"hydra_AtomEditorComponents_AddedToEntity.py",
timeout=EDITOR_TIMEOUT,
expected_lines=expected_lines,
unexpected_lines=unexpected_lines,
halt_on_unexpected=True,
null_renderer=True,
cfg_args=cfg_args,
)
# It requires at least one test
def test_Dummy(self, request, editor, level, workspace, project, launcher_platform):
pass
@@ -9,14 +9,211 @@ remove or modify any license notices. This file is distributed on an "AS IS" BAS
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
import logging
import os
import pytest
import editor_python_test_tools.hydra_test_utils as hydra
logger = logging.getLogger(__name__)
EDITOR_TIMEOUT = 120
TEST_DIRECTORY = os.path.join(os.path.dirname(__file__), "atom_hydra_scripts")
@pytest.mark.parametrize("project", ["AutomatedTesting"])
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
@pytest.mark.parametrize("level", ["auto_test"])
class TestAtomEditorComponents(object):
# It requires at least one test
def test_Dummy(self, request, editor, level, workspace, project, launcher_platform):
pass
@pytest.mark.test_case_id(
"C32078117", # Area Light
"C32078130", # Display Mapper
"C32078129", # Light
"C32078131", # Radius Weight Modifier
"C32078127", # PostFX Layer
"C32078126", # Point Light
"C32078125", # Physical Sky
"C32078115", # Global Skylight (IBL)
"C32078121", # Exposure Control
"C32078120", # Directional Light
"C32078119", # DepthOfField
"C32078118") # Decal
def test_AtomEditorComponents_AddedToEntity(self, request, editor, level, workspace, project, launcher_platform):
cfg_args = [level]
expected_lines = [
# Area Light Component
"Area Light Entity successfully created",
"Area Light_test: Component added to the entity: True",
"Area Light_test: Component removed after UNDO: True",
"Area Light_test: Component added after REDO: True",
"Area Light_test: Entered game mode: True",
"Area Light_test: Entity enabled after adding required components: True",
"Area Light_test: Entity is hidden: True",
"Area Light_test: Entity is shown: True",
"Area Light_test: Entity deleted: True",
"Area Light_test: UNDO entity deletion works: True",
"Area Light_test: REDO entity deletion works: True",
# Decal Component
"Decal Entity successfully created",
"Decal_test: Component added to the entity: True",
"Decal_test: Component removed after UNDO: True",
"Decal_test: Component added after REDO: True",
"Decal_test: Entered game mode: True",
"Decal_test: Exit game mode: True",
"Decal Settings|Decal Settings|Material: SUCCESS",
"Decal_test: Entity is hidden: True",
"Decal_test: Entity is shown: True",
"Decal_test: Entity deleted: True",
"Decal_test: UNDO entity deletion works: True",
"Decal_test: REDO entity deletion works: True",
# DepthOfField Component
"DepthOfField Entity successfully created",
"DepthOfField_test: Component added to the entity: True",
"DepthOfField_test: Component removed after UNDO: True",
"DepthOfField_test: Component added after REDO: True",
"DepthOfField_test: Entered game mode: True",
"DepthOfField_test: Exit game mode: True",
"DepthOfField_test: Entity disabled initially: True",
"DepthOfField_test: Entity enabled after adding required components: True",
"DepthOfField Controller|Configuration|Camera Entity: SUCCESS",
"DepthOfField_test: Entity is hidden: True",
"DepthOfField_test: Entity is shown: True",
"DepthOfField_test: Entity deleted: True",
"DepthOfField_test: UNDO entity deletion works: True",
"DepthOfField_test: REDO entity deletion works: True",
# Directional Light Component
"Directional Light Entity successfully created",
"Directional Light_test: Component added to the entity: True",
"Directional Light_test: Component removed after UNDO: True",
"Directional Light_test: Component added after REDO: True",
"Directional Light_test: Entered game mode: True",
"Directional Light_test: Exit game mode: True",
"Directional Light Controller|Configuration|Shadow|Camera: SUCCESS",
"Directional Light_test: Entity is hidden: True",
"Directional Light_test: Entity is shown: True",
"Directional Light_test: Entity deleted: True",
"Directional Light_test: UNDO entity deletion works: True",
"Directional Light_test: REDO entity deletion works: True",
# Exposure Control Component
"Exposure Control Entity successfully created",
"Exposure Control_test: Component added to the entity: True",
"Exposure Control_test: Component removed after UNDO: True",
"Exposure Control_test: Component added after REDO: True",
"Exposure Control_test: Entered game mode: True",
"Exposure Control_test: Exit game mode: True",
"Exposure Control_test: Entity disabled initially: True",
"Exposure Control_test: Entity enabled after adding required components: True",
"Exposure Control_test: Entity is hidden: True",
"Exposure Control_test: Entity is shown: True",
"Exposure Control_test: Entity deleted: True",
"Exposure Control_test: UNDO entity deletion works: True",
"Exposure Control_test: REDO entity deletion works: True",
# Global Skylight (IBL) Component
"Global Skylight (IBL) Entity successfully created",
"Global Skylight (IBL)_test: Component added to the entity: True",
"Global Skylight (IBL)_test: Component removed after UNDO: True",
"Global Skylight (IBL)_test: Component added after REDO: True",
"Global Skylight (IBL)_test: Entered game mode: True",
"Global Skylight (IBL)_test: Exit game mode: True",
"Global Skylight (IBL) Controller|Configuration|Diffuse Image: SUCCESS",
"Global Skylight (IBL) Controller|Configuration|Specular Image: SUCCESS",
"Global Skylight (IBL)_test: Entity is hidden: True",
"Global Skylight (IBL)_test: Entity is shown: True",
"Global Skylight (IBL)_test: Entity deleted: True",
"Global Skylight (IBL)_test: UNDO entity deletion works: True",
"Global Skylight (IBL)_test: REDO entity deletion works: True",
# Physical Sky Component
"Physical Sky Entity successfully created",
"Physical Sky component was added to entity",
"Entity has a Physical Sky component",
"Physical Sky_test: Component added to the entity: True",
"Physical Sky_test: Component removed after UNDO: True",
"Physical Sky_test: Component added after REDO: True",
"Physical Sky_test: Entered game mode: True",
"Physical Sky_test: Exit game mode: True",
"Physical Sky_test: Entity is hidden: True",
"Physical Sky_test: Entity is shown: True",
"Physical Sky_test: Entity deleted: True",
"Physical Sky_test: UNDO entity deletion works: True",
"Physical Sky_test: REDO entity deletion works: True",
# Point Light Component
"Point Light Entity successfully created",
"Point Light_test: Component added to the entity: True",
"Point Light_test: Component removed after UNDO: True",
"Point Light_test: Component added after REDO: True",
"Point Light_test: Entered game mode: True",
"Point Light_test: Exit game mode: True",
"Point Light_test: Entity is hidden: True",
"Point Light_test: Entity is shown: True",
"Point Light_test: Entity deleted: True",
"Point Light_test: UNDO entity deletion works: True",
"Point Light_test: REDO entity deletion works: True",
# PostFX Layer Component
"PostFX Layer Entity successfully created",
"PostFX Layer_test: Component added to the entity: True",
"PostFX Layer_test: Component removed after UNDO: True",
"PostFX Layer_test: Component added after REDO: True",
"PostFX Layer_test: Entered game mode: True",
"PostFX Layer_test: Exit game mode: True",
"PostFX Layer_test: Entity is hidden: True",
"PostFX Layer_test: Entity is shown: True",
"PostFX Layer_test: Entity deleted: True",
"PostFX Layer_test: UNDO entity deletion works: True",
"PostFX Layer_test: REDO entity deletion works: True",
# Radius Weight Modifier Component
"Radius Weight Modifier Entity successfully created",
"Radius Weight Modifier_test: Component added to the entity: True",
"Radius Weight Modifier_test: Component removed after UNDO: True",
"Radius Weight Modifier_test: Component added after REDO: True",
"Radius Weight Modifier_test: Entered game mode: True",
"Radius Weight Modifier_test: Exit game mode: True",
"Radius Weight Modifier_test: Entity is hidden: True",
"Radius Weight Modifier_test: Entity is shown: True",
"Radius Weight Modifier_test: Entity deleted: True",
"Radius Weight Modifier_test: UNDO entity deletion works: True",
"Radius Weight Modifier_test: REDO entity deletion works: True",
# Light Component
"Light Entity successfully created",
"Light_test: Component added to the entity: True",
"Light_test: Component removed after UNDO: True",
"Light_test: Component added after REDO: True",
"Light_test: Entered game mode: True",
"Light_test: Exit game mode: True",
"Light_test: Entity is hidden: True",
"Light_test: Entity is shown: True",
"Light_test: Entity deleted: True",
"Light_test: UNDO entity deletion works: True",
"Light_test: REDO entity deletion works: True",
# Display Mapper Component
"Display Mapper Entity successfully created",
"Display Mapper_test: Component added to the entity: True",
"Display Mapper_test: Component removed after UNDO: True",
"Display Mapper_test: Component added after REDO: True",
"Display Mapper_test: Entered game mode: True",
"Display Mapper_test: Exit game mode: True",
"Display Mapper_test: Entity is hidden: True",
"Display Mapper_test: Entity is shown: True",
"Display Mapper_test: Entity deleted: True",
"Display Mapper_test: UNDO entity deletion works: True",
"Display Mapper_test: REDO entity deletion works: True",
]
unexpected_lines = [
"failed to open",
"Traceback (most recent call last):",
]
hydra.launch_and_validate_results(
request,
TEST_DIRECTORY,
editor,
"hydra_AtomEditorComponents_AddedToEntity.py",
timeout=EDITOR_TIMEOUT,
expected_lines=expected_lines,
unexpected_lines=unexpected_lines,
halt_on_unexpected=True,
null_renderer=True,
cfg_args=cfg_args,
)
@@ -16,7 +16,6 @@
#include <AzCore/Serialization/EditContext.h>
#include <AzToolsFramework/Prefab/PrefabPublicInterface.h>
#include <AzToolsFramework/UI/EditorEntityUi/EditorEntityUiInterface.h>
#include <AzToolsFramework/UI/Outliner/EntityOutlinerWidgetInterface.h>
#include <AzToolsFramework/UI/Prefab/PrefabIntegrationBus.h>
namespace AzToolsFramework
@@ -21,9 +21,9 @@
#include <AzToolsFramework/Prefab/Instance/TemplateInstanceMapperInterface.h>
#include <AzToolsFramework/Prefab/PrefabDomUtils.h>
#include <AzToolsFramework/Prefab/PrefabPublicInterface.h>
#include <AzToolsFramework/Prefab/PrefabPublicNotificationBus.h>
#include <AzToolsFramework/Prefab/PrefabSystemComponentInterface.h>
#include <AzToolsFramework/Prefab/Template/Template.h>
#include <AzToolsFramework/UI/Outliner/EntityOutlinerWidgetInterface.h>
namespace AzToolsFramework
{
@@ -90,17 +90,13 @@ namespace AzToolsFramework
if (instanceCountToUpdateInBatch > 0)
{
// Notify Propagation has begun
PrefabPublicNotificationBus::Broadcast(&PrefabPublicNotifications::OnPrefabInstancePropagationBegin);
EntityIdList selectedEntityIds;
ToolsApplicationRequestBus::BroadcastResult(selectedEntityIds, &ToolsApplicationRequests::GetSelectedEntities);
ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequests::SetSelectedEntities, EntityIdList());
// Disable the Outliner to avoid showing the propagation steps
EntityOutlinerWidgetInterface* entityOutlinerWidgetInterface = AZ::Interface<EntityOutlinerWidgetInterface>::Get();
if (entityOutlinerWidgetInterface)
{
entityOutlinerWidgetInterface->SetUpdatesEnabled(false);
}
for (int i = 0; i < instanceCountToUpdateInBatch; ++i)
{
Instance* instanceToUpdate = m_instancesUpdateQueue.front();
@@ -168,18 +164,8 @@ namespace AzToolsFramework
}
ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequests::SetSelectedEntities, selectedEntityIds);
// Enable the Outliner
if (entityOutlinerWidgetInterface)
{
entityOutlinerWidgetInterface->SetUpdatesEnabled(true);
auto prefabPublicInterface = AZ::Interface<PrefabPublicInterface>::Get();
if (prefabPublicInterface)
{
AZ::EntityId rootEntityId = prefabPublicInterface->GetLevelInstanceContainerEntityId();
entityOutlinerWidgetInterface->ExpandEntityChildren(rootEntityId);
}
}
// Notify Propagation has ended
PrefabPublicNotificationBus::Broadcast(&PrefabPublicNotifications::OnPrefabInstancePropagationEnd);
}
m_updatingTemplateInstancesInQueue = false;
@@ -0,0 +1,34 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/EBus/EBus.h>
namespace AzToolsFramework
{
namespace Prefab
{
class PrefabPublicNotifications
: public AZ::EBusTraits
{
public:
virtual ~PrefabPublicNotifications() = default;
virtual void OnPrefabInstancePropagationBegin() {}
virtual void OnPrefabInstancePropagationEnd() {}
};
using PrefabPublicNotificationBus = AZ::EBus<PrefabPublicNotifications>;
} // namespace Prefab
} // namespace AzToolsFramework
@@ -286,12 +286,12 @@ namespace AzToolsFramework
ComponentModeFramework::EditorComponentModeNotificationBus::Handler::BusConnect(
GetEntityContextId());
EditorEntityInfoNotificationBus::Handler::BusConnect();
AZ::Interface<EntityOutlinerWidgetInterface>::Register(this);
Prefab::PrefabPublicNotificationBus::Handler::BusConnect();
}
EntityOutlinerWidget::~EntityOutlinerWidget()
{
AZ::Interface<EntityOutlinerWidgetInterface>::Unregister(this);
Prefab::PrefabPublicNotificationBus::Handler::BusDisconnect();
ComponentModeFramework::EditorComponentModeNotificationBus::Handler::BusDisconnect();
EditorEntityInfoNotificationBus::Handler::BusDisconnect();
EditorPickModeNotificationBus::Handler::BusDisconnect();
@@ -1109,25 +1109,18 @@ namespace AzToolsFramework
setEnabled(true);
SetEntityOutlinerState(m_gui, true);
}
void EntityOutlinerWidget::SetUpdatesEnabled(bool enable)
void EntityOutlinerWidget::OnPrefabInstancePropagationBegin()
{
if (enable)
{
QTimer::singleShot(1, this, [this]() {
m_gui->m_objectTree->setUpdatesEnabled(true);
});
}
else
{
m_gui->m_objectTree->setUpdatesEnabled(false);
}
m_gui->m_objectTree->setUpdatesEnabled(false);
}
void EntityOutlinerWidget::ExpandEntityChildren(AZ::EntityId entityId)
void EntityOutlinerWidget::OnPrefabInstancePropagationEnd()
{
QModelIndex index = GetIndexFromEntityId(entityId);
m_gui->m_objectTree->expand(index);
QTimer::singleShot(1, this, [this]() {
m_gui->m_objectTree->setUpdatesEnabled(true);
m_gui->m_objectTree->expand(m_proxyModel->index(0,0));
});
}
void EntityOutlinerWidget::OnEntityInfoUpdatedAddChildEnd(AZ::EntityId /*parentId*/, AZ::EntityId childId)
@@ -20,10 +20,10 @@
#include <AzToolsFramework/ComponentMode/EditorComponentModeBus.h>
#include <AzToolsFramework/Entity/EditorEntityInfoBus.h>
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
#include <AzToolsFramework/Prefab/PrefabPublicNotificationBus.h>
#include <AzToolsFramework/ToolsMessaging/EntityHighlightBus.h>
#include <AzToolsFramework/UI/Outliner/EntityOutlinerCacheBus.h>
#include <AzToolsFramework/UI/Outliner/EntityOutlinerSearchWidget.h>
#include <AzToolsFramework/UI/Outliner/EntityOutlinerWidgetInterface.h>
#include <AzToolsFramework/UI/SearchWidget/SearchWidgetTypes.hxx>
#include <QIcon>
@@ -62,7 +62,7 @@ namespace AzToolsFramework
, private EditorEntityContextNotificationBus::Handler
, private EditorEntityInfoNotificationBus::Handler
, private ComponentModeFramework::EditorComponentModeNotificationBus::Handler
, private EntityOutlinerWidgetInterface
, private Prefab::PrefabPublicNotificationBus::Handler
{
Q_OBJECT;
public:
@@ -106,9 +106,9 @@ namespace AzToolsFramework
void EnteredComponentMode(const AZStd::vector<AZ::Uuid>& componentModeTypes) override;
void LeftComponentMode(const AZStd::vector<AZ::Uuid>& componentModeTypes) override;
// EntityOutlinerWidgetInterface
void SetUpdatesEnabled(bool enable) override;
void ExpandEntityChildren(AZ::EntityId entityId) override;
// PrefabPublicNotificationBus
void OnPrefabInstancePropagationBegin() override;
void OnPrefabInstancePropagationEnd() override;
// Build a selection object from the given entities. Entities already in the Widget's selection buffers are ignored.
template <class EntityIdCollection>
@@ -652,6 +652,7 @@ set(FILES
Prefab/PrefabPublicHandler.h
Prefab/PrefabPublicHandler.cpp
Prefab/PrefabPublicInterface.h
Prefab/PrefabPublicNotificationBus.h
Prefab/PrefabUndo.h
Prefab/PrefabUndo.cpp
Prefab/PrefabUndoCache.cpp
@@ -687,7 +688,6 @@ set(FILES
UI/Outliner/EntityOutlinerDisplayOptionsMenu.cpp
UI/Outliner/EntityOutlinerTreeView.hxx
UI/Outliner/EntityOutlinerTreeView.cpp
UI/Outliner/EntityOutlinerWidgetInterface.h
UI/Outliner/EntityOutlinerWidget.hxx
UI/Outliner/EntityOutlinerWidget.cpp
UI/Outliner/EntityOutlinerCacheBus.h
-11
View File
@@ -33,7 +33,6 @@
#include "Util/CryMemFile.h"
#include "Objects/ObjectManager.h"
#include "Objects/ObjectPhysicsManager.h"
#include "Objects/EntityObject.h"
#include "LensFlareEditor/LensFlareManager.h"
#include "LensFlareEditor/LensFlareLibrary.h"
@@ -192,14 +191,6 @@ bool CGameExporter::Export(unsigned int flags, [[maybe_unused]] EEndian eExportE
}
}
////////////////////////////////////////////////////////////////////////
// Inform all objects that an export is about to begin
////////////////////////////////////////////////////////////////////////
if (exportSuccessful)
{
GetIEditor()->GetObjectManager()->GetPhysicsManager()->PrepareForExport();
}
////////////////////////////////////////////////////////////////////////
// Export all data to the game
////////////////////////////////////////////////////////////////////////
@@ -519,8 +510,6 @@ void CGameExporter::ExportMapInfo(XmlNodeRef& node)
CXmlArchive xmlAr;
xmlAr.bLoading = false;
xmlAr.root = node;
GetIEditor()->GetObjectManager()->GetPhysicsManager()->SerializeCollisionClasses(xmlAr);
}
//////////////////////////////////////////////////////////////////////////
@@ -24,7 +24,6 @@ class CUsedResources;
class CSelectionGroup;
class CObjectClassDesc;
class CObjectArchive;
class CObjectPhysicsManager;
class CViewport;
struct HitContext;
enum class ImageRotationDegrees;
@@ -247,10 +246,6 @@ public:
virtual IGizmoManager* GetGizmoManager() = 0;
//////////////////////////////////////////////////////////////////////////
//! Get acess to object physics manager
virtual CObjectPhysicsManager* GetPhysicsManager() = 0;
//////////////////////////////////////////////////////////////////////////
//! Invalidate visibily settings of objects.
virtual void InvalidateVisibleList() = 0;
@@ -25,7 +25,6 @@
#include "Viewport.h"
#include "GizmoManager.h"
#include "AxisGizmo.h"
#include "ObjectPhysicsManager.h"
#include "GameEngine.h"
#include "WaitProgress.h"
#include "Util/Image.h"
@@ -109,7 +108,6 @@ CObjectManager::CObjectManager()
, m_pLoadProgress(nullptr)
, m_loadedObjects(0)
, m_totalObjectsToLoad(0)
, m_pPhysicsManager(new CObjectPhysicsManager())
, m_bExiting(false)
, m_isUpdateVisibilityList(false)
, m_currentHideCount(CBaseObject::s_invalidHiddenID)
@@ -138,7 +136,6 @@ CObjectManager::~CObjectManager()
DeleteAllObjects();
delete m_gizmoManager;
delete m_pPhysicsManager;
}
//////////////////////////////////////////////////////////////////////////
@@ -841,8 +838,6 @@ void CObjectManager::Update()
{
prevActiveWindow->setFocus();
}
m_pPhysicsManager->Update();
}
//////////////////////////////////////////////////////////////////////////
@@ -334,9 +334,6 @@ public:
virtual void FindAndRenameProperty2(const char* property2Name, const QString& oldValue, const QString& newValue);
virtual void FindAndRenameProperty2If(const char* property2Name, const QString& oldValue, const QString& newValue, const char* otherProperty2Name, const QString& otherValue);
class CObjectPhysicsManager* GetPhysicsManager()
{ return m_pPhysicsManager; }
bool IsReloading() const { return m_bInReloading; }
void SetSkipUpdate(bool bSkipUpdate) override { m_bSkipObjectUpdate = bSkipUpdate; }
@@ -433,8 +430,6 @@ private:
int m_totalObjectsToLoad;
//////////////////////////////////////////////////////////////////////////
class CObjectPhysicsManager* m_pPhysicsManager;
//////////////////////////////////////////////////////////////////////////
// Numbering for names.
//////////////////////////////////////////////////////////////////////////
@@ -1,191 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#include "EditorDefs.h"
#include "ObjectPhysicsManager.h"
// Editor
#include "GameEngine.h"
#include "Commands/CommandManager.h"
#include "Objects/SelectionGroup.h"
#include "Include/IObjectManager.h"
#include "CryPhysicsDeprecation.h"
#define MAX_OBJECTS_PHYS_SIMULATION_TIME (5)
//////////////////////////////////////////////////////////////////////////
CObjectPhysicsManager::CObjectPhysicsManager()
{
CommandManagerHelper::RegisterCommand(GetIEditor()->GetCommandManager(),
"physics", "simulate_objects", "", "",
AZStd::bind(&CObjectPhysicsManager::Command_SimulateObjects, this));
CommandManagerHelper::RegisterCommand(GetIEditor()->GetCommandManager(),
"physics", "reset_objects_state", "", "",
AZStd::bind(&CObjectPhysicsManager::Command_ResetPhysicsState, this));
CommandManagerHelper::RegisterCommand(GetIEditor()->GetCommandManager(),
"physics", "get_objects_state", "", "",
AZStd::bind(&CObjectPhysicsManager::Command_GetPhysicsState, this));
m_fStartObjectSimulationTime = 0;
m_bSimulatingObjects = false;
m_wasSimObjects = 0;
}
//////////////////////////////////////////////////////////////////////////
CObjectPhysicsManager::~CObjectPhysicsManager()
{
}
//////////////////////////////////////////////////////////////////////////
void CObjectPhysicsManager::Command_SimulateObjects()
{
SimulateSelectedObjectsPositions();
}
/////////////////////////////////////////////////////////////////////////
void CObjectPhysicsManager::Command_ResetPhysicsState()
{
CSelectionGroup* pSelection = GetIEditor()->GetSelection();
for (int i = 0; i < pSelection->GetCount(); i++)
{
pSelection->GetObject(i)->OnEvent(EVENT_PHYSICS_RESETSTATE);
}
}
/////////////////////////////////////////////////////////////////////////
void CObjectPhysicsManager::Command_GetPhysicsState()
{
CSelectionGroup* pSelection = GetIEditor()->GetSelection();
for (int i = 0; i < pSelection->GetCount(); i++)
{
pSelection->GetObject(i)->OnEvent(EVENT_PHYSICS_GETSTATE);
}
}
//////////////////////////////////////////////////////////////////////////
void CObjectPhysicsManager::Update()
{
if (m_bSimulatingObjects)
{
UpdateSimulatingObjects();
}
}
//////////////////////////////////////////////////////////////////////////
void CObjectPhysicsManager::SimulateSelectedObjectsPositions()
{
CSelectionGroup* pSel = GetIEditor()->GetObjectManager()->GetSelection();
if (pSel->IsEmpty())
{
return;
}
if (GetIEditor()->GetGameEngine()->GetSimulationMode())
{
return;
}
GetIEditor()->GetGameEngine()->SetSimulationMode(true, true);
m_simObjects.clear();
CRY_PHYSICS_REPLACEMENT_ASSERT();
m_wasSimObjects = m_simObjects.size();
m_fStartObjectSimulationTime = GetISystem()->GetITimer()->GetAsyncCurTime();
m_bSimulatingObjects = true;
}
//////////////////////////////////////////////////////////////////////////
void CObjectPhysicsManager::UpdateSimulatingObjects()
{
{
CUndo undo("Simulate");
CRY_PHYSICS_REPLACEMENT_ASSERT();
}
float curTime = GetISystem()->GetITimer()->GetAsyncCurTime();
float runningTime = (curTime - m_fStartObjectSimulationTime);
if (m_simObjects.empty() || (runningTime > MAX_OBJECTS_PHYS_SIMULATION_TIME))
{
m_fStartObjectSimulationTime = 0;
m_bSimulatingObjects = false;
GetIEditor()->GetGameEngine()->SetSimulationMode(false, true);
}
}
//////////////////////////////////////////////////////////////////////////
void CObjectPhysicsManager::PrepareForExport()
{
// Clear the collision class set, ready for objects to register
// their collision classes
m_collisionClasses.clear();
m_collisionClassExportId = 0;
// First collision-class IS always the default one
RegisterCollisionClass(SCollisionClass(0, 0));
}
//////////////////////////////////////////////////////////////////////////
bool operator == (const SCollisionClass& lhs, const SCollisionClass& rhs)
{
return lhs.type == rhs.type && lhs.ignore == rhs.ignore;
}
//////////////////////////////////////////////////////////////////////////
int CObjectPhysicsManager::RegisterCollisionClass(const SCollisionClass& collclass)
{
TCollisionClassVector::iterator it = std::find(m_collisionClasses.begin(), m_collisionClasses.end(), collclass);
if (it == m_collisionClasses.end())
{
m_collisionClasses.push_back(collclass);
return m_collisionClasses.size() - 1;
}
return it - m_collisionClasses.begin();
}
//////////////////////////////////////////////////////////////////////////
int CObjectPhysicsManager::GetCollisionClassId(const SCollisionClass& collclass)
{
TCollisionClassVector::iterator it = std::find(m_collisionClasses.begin(), m_collisionClasses.end(), collclass);
if (it == m_collisionClasses.end())
{
return 0;
}
return it - m_collisionClasses.begin();
}
//////////////////////////////////////////////////////////////////////////
void CObjectPhysicsManager::SerializeCollisionClasses(CXmlArchive& xmlAr)
{
if (!xmlAr.bLoading)
{
// Storing
CLogFile::WriteLine("Storing Collision Classes ...");
XmlNodeRef root = xmlAr.root->newChild("CollisionClasses");
int count = m_collisionClasses.size();
for (int i = 0; i < count; i++)
{
SCollisionClass& cc = m_collisionClasses[i];
XmlNodeRef xmlCC = root->newChild("CollisionClass");
xmlCC->setAttr("type", cc.type);
xmlCC->setAttr("ignore", cc.ignore);
}
}
}
@@ -1,56 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#ifndef CRYINCLUDE_EDITOR_OBJECTS_OBJECTPHYSICSMANAGER_H
#define CRYINCLUDE_EDITOR_OBJECTS_OBJECTPHYSICSMANAGER_H
#pragma once
//////////////////////////////////////////////////////////////////////////
class CObjectPhysicsManager
{
public:
CObjectPhysicsManager();
~CObjectPhysicsManager();
void SimulateSelectedObjectsPositions();
void Update();
//////////////////////////////////////////////////////////////////////////
/// Collision Classes
//////////////////////////////////////////////////////////////////////////
int RegisterCollisionClass(const SCollisionClass& collclass);
int GetCollisionClassId(const SCollisionClass& collclass);
void SerializeCollisionClasses(CXmlArchive& xmlAr);
void PrepareForExport();
private:
void Command_SimulateObjects();
void Command_GetPhysicsState();
void Command_ResetPhysicsState();
void UpdateSimulatingObjects();
bool m_bSimulatingObjects;
float m_fStartObjectSimulationTime;
int m_wasSimObjects;
std::vector<_smart_ptr<CBaseObject> > m_simObjects;
typedef std::vector<SCollisionClass> TCollisionClassVector;
int m_collisionClassExportId;
TCollisionClassVector m_collisionClasses;
};
#endif // CRYINCLUDE_EDITOR_OBJECTS_OBJECTPHYSICSMANAGER_H
@@ -638,8 +638,6 @@ set(FILES
Objects/ObjectManager.h
Objects/ObjectManagerLegacyUndo.cpp
Objects/ObjectManagerLegacyUndo.h
Objects/ObjectPhysicsManager.cpp
Objects/ObjectPhysicsManager.h
Objects/DisplayContext.cpp
Objects/DisplayContext.h
Objects/EntityObject.cpp
+1 -1
View File
@@ -13,6 +13,7 @@ add_subdirectory(SceneAPI) # Needs to go before AssetProcessor since it provides
add_subdirectory(AssetProcessor)
add_subdirectory(AWSNativeSDKInit)
add_subdirectory(AzTestRunner)
add_subdirectory(CrashHandler)
add_subdirectory(CryCommonTools)
add_subdirectory(CryXML)
add_subdirectory(HLSLCrossCompiler)
@@ -21,7 +22,6 @@ add_subdirectory(News)
add_subdirectory(PythonBindingsExample)
add_subdirectory(RC)
add_subdirectory(RemoteConsole)
add_subdirectory(CrashHandler)
add_subdirectory(ShaderCacheGen)
add_subdirectory(DeltaCataloger)
add_subdirectory(SerializeContextTools)
+3 -5
View File
@@ -32,11 +32,11 @@ ly_add_target(
PRIVATE
${pal_dir}
BUILD_DEPENDENCIES
PUBLIC
AZ::CrashSupport
PRIVATE
3rdParty::Crashpad
AZ::AzCore
AZ::AzFramework
AZ::CrashSupport
)
string(REPLACE "." ";" version_list "${LY_VERSION_STRING}")
@@ -67,11 +67,9 @@ ly_add_target(
PRIVATE
Uploader/include/Uploader
BUILD_DEPENDENCIES
PRIVATE
AZ::AzCore
AZ::CrashSupport
PUBLIC
3rdParty::Crashpad::Handler
AZ::CrashSupport
)
add_subdirectory(Tools)
@@ -19,6 +19,6 @@ ly_add_target(
PUBLIC
include
BUILD_DEPENDENCIES
PRIVATE
PUBLIC
AZ::AzCore
)
+3 -7
View File
@@ -21,13 +21,13 @@ ly_add_target(
tools_crash_handler_files.cmake
Platform/${PAL_PLATFORM_NAME}/tools_crash_handler_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake
INCLUDE_DIRECTORIES
PRIVATE
PUBLIC
.
BUILD_DEPENDENCIES
PUBLIC
AZ::CrashHandler
PRIVATE
3rdParty::Qt::Core
AZ::CrashHandler
AZ::CrashSupport
AZ::AzToolsFramework
)
@@ -41,18 +41,14 @@ ly_add_target(
Platform/${PAL_PLATFORM_NAME}/tools_crash_uploader_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake
INCLUDE_DIRECTORIES
PRIVATE
.
Uploader
BUILD_DEPENDENCIES
PRIVATE
3rdParty::Qt::Core
3rdParty::Qt::Gui
3rdParty::Qt::Widgets
3rdParty::Crashpad
3rdParty::Crashpad::Handler
AZ::CrashUploaderSupport
AZ::AzQtComponents
AZ::CrashSupport
TARGET_PROPERTIES
Qt5_NO_LINK_QTMAIN TRUE
)
@@ -138,7 +138,7 @@ namespace O3de
if (!logFileReader->Open(thisFile))
{
#if defined(AZ_PLATFORM_WINDOWS)
LOG(ERROR) << "Failed to open " << base::UTF16ToUTF8(thisFile.BaseName().value());
LOG(ERROR) << "Failed to open " << base::WideToUTF8(thisFile.BaseName().value());
#else
LOG(ERROR) << "Failed to open " << thisFile.BaseName().value();
#endif
@@ -149,7 +149,7 @@ namespace O3de
if (start_offset < 0)
{
#if defined(AZ_PLATFORM_WINDOWS)
LOG(ERROR) << "Failed to get offset for " << base::UTF16ToUTF8(thisFile.BaseName().value());
LOG(ERROR) << "Failed to get offset for " << base::WideToUTF8(thisFile.BaseName().value());
#else
LOG(ERROR) << "Failed to get offset for " << thisFile.BaseName().value();
#endif
@@ -162,7 +162,7 @@ namespace O3de
std::string fileNameKey{ "attachment_" };
#if defined(AZ_PLATFORM_WINDOWS)
fileNameKey += base::UTF16ToUTF8(thisFile.BaseName().value());
fileNameKey += base::WideToUTF8(thisFile.BaseName().value());
#else
fileNameKey += thisFile.BaseName().value();
#endif
@@ -34,6 +34,7 @@ namespace AZ
constexpr uint32_t StreamCountMax = 12;
constexpr uint32_t StreamChannelCountMax = 16;
constexpr uint32_t DrawListTagCountMax = 64;
constexpr uint32_t DrawFilterTagCountMax = 32;
constexpr uint32_t MultiSampleCustomLocationsCountMax = 16;
constexpr uint32_t MultiSampleCustomLocationGridSize = 16;
constexpr uint32_t SubpassCountMax = 10;
@@ -9,22 +9,15 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/Interface/Interface.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <Atom/RHI/DrawItem.h>
#include <Atom/RHI/TagRegistry.h>
namespace AzToolsFramework
namespace AZ
{
class EntityOutlinerWidgetInterface
namespace RHI
{
public:
AZ_RTTI(EntityOutlinerWidgetInterface, "{30C0F252-EC84-4196-BF59-EB9E73B8ADCB}");
virtual void SetUpdatesEnabled(bool enable) = 0;
virtual void ExpandEntityChildren(AZ::EntityId entityId) = 0;
};
} // namespace AzToolsFramework
using DrawFilterTagRegistry = TagRegistry<DrawFilterTag, Limits::Pipeline::DrawFilterTagCountMax>;
}
}
+27 -9
View File
@@ -11,6 +11,7 @@
*/
#pragma once
#include <Atom/RHI.Reflect/Handle.h>
#include <Atom/RHI.Reflect/Limits.h>
#include <Atom/RHI/StreamBufferView.h>
#include <Atom/RHI/IndexBufferView.h>
@@ -152,36 +153,53 @@ namespace AZ
};
using DrawItemSortKey = int64_t;
struct DrawItemKeyPair
// A filter associate to a DrawItem which can be used to filter the DrawItem when submitting to command list
using DrawFilterTag = Handle<uint8_t>;
using DrawFilterMask = uint32_t; // AZStd::bitset's impelmentation is too expensive.
constexpr uint32_t DrawFilterMaskDefaultValue = uint32_t(-1); // Default all bit to 1.
static_assert(sizeof(DrawFilterMask) * 8 >= Limits::Pipeline::DrawFilterTagCountMax, "DrawFilterMask doesn't have enough bits for maximum tag count");
struct DrawItemProperties
{
DrawItemKeyPair() = default;
DrawItemProperties() = default;
DrawItemKeyPair(const DrawItem* item, DrawItemSortKey sortKey)
DrawItemProperties(const DrawItem* item, DrawItemSortKey sortKey = 0, DrawFilterMask filterMask = DrawFilterMaskDefaultValue)
: m_item{item}
, m_sortKey{sortKey}
{}
, m_drawFilterMask{filterMask}
{
}
bool operator == (const DrawItemKeyPair& rhs) const
bool operator==(const DrawItemProperties& rhs) const
{
return m_item == rhs.m_item &&
m_sortKey == rhs.m_sortKey &&
m_depth == rhs.m_depth;
m_depth == rhs.m_depth &&
m_drawFilterMask == rhs.m_drawFilterMask
;
}
bool operator != (const DrawItemKeyPair& rhs) const
bool operator!=(const DrawItemProperties& rhs) const
{
return !(*this == rhs);
}
bool operator < (const DrawItemKeyPair& rhs) const
bool operator<(const DrawItemProperties& rhs) const
{
return m_sortKey < rhs.m_sortKey;
}
//! A pointer to the draw item
const DrawItem* m_item = nullptr;
//! A sorting key of this draw item which is used for sorting draw items in DrawList
// Check RHI::SortDrawList() function for detail
DrawItemSortKey m_sortKey = 0;
//! A depth value this draw item which is used for sorting draw items in DrawList
//! Check RHI::SortDrawList() function for detail
float m_depth = 0.0f;
//! A filter mask which helps decide whether to submit this draw item to a Scope's command list or not
DrawFilterMask m_drawFilterMask = DrawFilterMaskDefaultValue;
};
}
@@ -39,8 +39,8 @@ namespace AZ
using DrawListTag = Handle<uint8_t>;
using DrawListMask = AZStd::bitset<RHI::Limits::Pipeline::DrawListTagCountMax>;
using DrawList = AZStd::vector<RHI::DrawItemKeyPair>;
using DrawListView = AZStd::array_view<RHI::DrawItemKeyPair>;
using DrawList = AZStd::vector<RHI::DrawItemProperties>;
using DrawListView = AZStd::array_view<RHI::DrawItemProperties>;
/// Contains a table of draw lists, indexed by the tag.
using DrawListsByTag = AZStd::array<DrawList, RHI::Limits::Pipeline::DrawListTagCountMax>;
@@ -53,7 +53,7 @@ namespace AZ
/// Adds an individual draw item to the draw list associated with the provided tag. This will
/// no-op if the tag is not present in the internal draw list mask.
void AddDrawItem(DrawListTag drawListTag, DrawItemKeyPair drawItemKeyPair);
void AddDrawItem(DrawListTag drawListTag, DrawItemProperties drawItemProperties);
/// Coalesces the draw lists in preparation for access via GetList. This should
/// be called from a single thread as a sync point between the append / consume phases.
@@ -12,83 +12,12 @@
#pragma once
#include <Atom/RHI/DrawList.h>
#include <AzCore/Name/Name.h>
#include <AzCore/std/smart_ptr/intrusive_base.h>
#include <AzCore/std/parallel/shared_mutex.h>
#include <Atom/RHI/TagRegistry.h>
namespace AZ
{
namespace RHI
{
/**
* Allocates and registers draw list tags by name, allowing the user to acquire and find tags from names.
* The class is designed to map user-friendly tag names defined through content or higher level code to
* low-level tags, which are simple handles.
*
* Some notes about usage and design:
* - DrawListTag values represent indexes into a bitmask, which allows for fast comparison when filtering
* draw items into draw lists (see View::HasDrawListTag()).
* - Tags are reference counted, which means multiple calls to 'Acquire' with the same name will increment
* the internal reference count on the tag. This allows shared ownership between systems, if necessary.
* - FindTag is provided to search for a tag reference without taking ownership.
* - Names are case sensitive.
*/
class DrawListTagRegistry final
: public AZStd::intrusive_base
{
public:
AZ_CLASS_ALLOCATOR(DrawListTagRegistry, AZ::SystemAllocator, 0);
AZ_DISABLE_COPY_MOVE(DrawListTagRegistry);
static Ptr<DrawListTagRegistry> Create();
/**
* Resets the registry back to an empty state. All references are released.
*/
void Reset();
/**
* Acquires a draw list tag from the provided name (case sensitive). If the tag already existed, it is ref-counted.
* Returns a valid tag on success; returns a null tag if the registry is at full capacity. You must
* call ReleaseTag() if successful.
*/
DrawListTag AcquireTag(const Name& drawListName);
/**
* Releases a reference to a tag. Tags are ref-counted, so it's necessary to maintain ownership of the
* tag and release when its no longer needed.
*/
void ReleaseTag(DrawListTag drawListTag);
/**
* Finds the tag associated with the provided name (case sensitive). If a tag exists with that name, the tag
* is returned. The reference count is NOT incremented on success; ownership is not passed to the user. If
* the tag does not exist, a null tag is returned.
*/
DrawListTag FindTag(const Name& drawListName) const;
/**
* Returns the name of the given DrawListTag, or empty string if the tag is not registered.
*/
Name GetName(DrawListTag tag) const;
/**
* Returns the number of allocated tags in the registry.
*/
size_t GetAllocatedTagCount() const;
private:
DrawListTagRegistry() = default;
struct Entry
{
Name m_name;
size_t m_refCount = 0;
};
mutable AZStd::shared_mutex m_mutex;
AZStd::array<Entry, Limits::Pipeline::DrawListTagCountMax> m_entriesByTag;
size_t m_allocatedTagCount = 0;
};
using DrawListTagRegistry = TagRegistry<DrawListTag, Limits::Pipeline::DrawListTagCountMax>;
}
}
@@ -21,45 +21,48 @@ namespace AZ
namespace RHI
{
/**
* DrawPacket is a packed data structure (one contiguous allocation) containing a collection of
* DrawItems and their associated array data. Each draw item in the packet is associated
* with a DrawListTag. All draw items in the packet share the same set of shader resource
* groups, index buffer, and draw arguments.
*
* Some notes about design and usage:
* - Draw packets should be used to 'broadcast' variations of the same 'object' to multiple passes.
* For example: 'Shadow', 'Depth', 'Forward'.
*
* - Draw packets can be re-used between different views, scenes, or passes. The embedded shader resource groups
* should represent only the local data necessary to describe the 'object', not the full context including
* scene / view / pass specific state. They serve as a 'template'.
*
* - The packet is self-contained and does not reference external memory. Use DrawPacketBuilder to construct
* an instance and either store in an RHI::Ptr or call 'delete' to release.
*/
//!
//! DrawPacket is a packed data structure (one contiguous allocation) containing a collection of
//! DrawItems and their associated array data. Each draw item in the packet is associated
//! with a DrawListTag. All draw items in the packet share the same set of shader resource
//! groups, index buffer, one DrawFilterMask, and draw arguments.
//!
//! Some notes about design and usage:
//! - Draw packets should be used to 'broadcast' variations of the same 'object' to multiple passes.
//! For example: 'Shadow', 'Depth', 'Forward'.
//!
//! - Draw packets can be re-used between different views, scenes, or passes. The embedded shader resource groups
//! should represent only the local data necessary to describe the 'object', not the full context including
//! scene / view / pass specific state. They serve as a 'template'.
//!
//! - The packet is self-contained and does not reference external memory. Use DrawPacketBuilder to construct
//! an instance and either store in an RHI::Ptr or call 'delete' to release.
//!
class DrawPacket final : public AZStd::intrusive_base
{
friend class DrawPacketBuilder;
public:
using DrawItemVisitor = AZStd::function<void(DrawListTag, DrawItemKeyPair)>;
using DrawItemVisitor = AZStd::function<void(DrawListTag, DrawItemProperties)>;
/// Draw packets cannot be move constructed or copied, as they contain an additional memory payload.
//! Draw packets cannot be move constructed or copied, as they contain an additional memory payload.
AZ_DISABLE_COPY_MOVE(DrawPacket);
/// Returns the mask representing all the draw lists affected by the packet.
//! Returns the mask representing all the draw lists affected by the packet.
DrawListMask GetDrawListMask() const;
/// Returns the number of draw items stored in the packet.
//! Returns the number of draw items stored in the packet.
size_t GetDrawItemCount() const;
/// Returns the draw item / sort key associated with the provided index.
DrawItemKeyPair GetDrawItem(size_t index) const;
//! Returns the draw item and its properties associated with the provided index.
DrawItemProperties GetDrawItem(size_t index) const;
/// Returns the draw list tag associated with the provided index.
//! Returns the draw list tag associated with the provided index.
DrawListTag GetDrawListTag(size_t index) const;
/// Overloaded operator delete for freeing a draw packet.
//! Returns the draw filter mask which applied to all the draw items.
DrawFilterMask GetDrawFilterMask() const;
//! Overloaded operator delete for freeing a draw packet.
void operator delete(void* p, size_t size);
private:
@@ -72,6 +75,9 @@ namespace AZ
// The bit-mask of all active filter tags.
DrawListMask m_drawListMask = 0;
// The draw filter applies to each draw item
DrawFilterMask m_drawFilterMask = DrawFilterMaskDefaultValue;
// The index buffer view used when the draw call is indexed.
IndexBufferView m_indexBufferView;
@@ -29,23 +29,26 @@ namespace AZ
{
DrawRequest() = default;
/// The filter tag used to direct the draw item.
//! The filter tag used to direct the draw item.
DrawListTag m_listTag;
/// The stencil ref value used for this draw item.
//! The stencil ref value used for this draw item.
uint8_t m_stencilRef = 0;
/// The array of stream buffers to bind for this draw item.
//! The array of stream buffers to bind for this draw item.
AZStd::array_view<StreamBufferView> m_streamBufferViews;
/// Shader resource group unique for this draw request
//! Shader resource group unique for this draw request
const ShaderResourceGroup* m_uniqueShaderResourceGroup = nullptr;
/// The pipeline state assigned to this draw item.
//! The pipeline state assigned to this draw item.
const PipelineState* m_pipelineState = nullptr;
/// The sort key assigned to this draw item.
//! The sort key assigned to this draw item.
DrawItemSortKey m_sortKey = 0;
//! The filter associated to this draw item.
DrawFilterMask m_drawFilterMask = DrawFilterMaskDefaultValue;
};
// NOTE: This is configurable; just used to control the amount of memory held by the builder.
@@ -69,6 +72,8 @@ namespace AZ
void AddShaderResourceGroup(const ShaderResourceGroup* shaderResourceGroup);
void SetDrawFilterMask(DrawFilterMask filterMask);
void AddDrawItem(const DrawRequest& request);
const DrawPacket* End();
@@ -79,6 +84,7 @@ namespace AZ
IAllocatorAllocate* m_allocator = nullptr;
DrawArguments m_drawArguments;
DrawListMask m_drawListMask = 0;
DrawFilterMask m_drawFilterMask = DrawFilterMaskDefaultValue;
size_t m_streamBufferViewCount = 0;
IndexBufferView m_indexBufferView;
AZStd::fixed_vector<DrawRequest, DrawItemCountMax> m_drawRequests;
@@ -15,13 +15,13 @@
#include <AzCore/Name/Name.h>
#include <AzCore/EBus/EBus.h>
#include <Atom/RHI.Reflect/FrameSchedulerEnums.h>
#include <Atom/RHI/DrawListTagRegistry.h>
namespace AZ
{
namespace RHI
{
class Device;
class DrawListTagRegistry;
class FrameGraphBuilder;
class PipelineState;
class PipelineStateCache;
@@ -0,0 +1,188 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/Name/Name.h>
#include <AzCore/std/smart_ptr/intrusive_base.h>
#include <AzCore/std/parallel/shared_mutex.h>
namespace AZ
{
namespace RHI
{
//!
//! Allocates and registers tags by name, allowing the user to acquire and find tags from names.
//! The class is designed to map user-friendly tag names defined through content or higher level code to
//! low-level tags, which are simple handles.
//!
//! Some notes about usage and design:
//! - TagType need to be a Handle<Integer> type.
//! - Tags are reference counted, which means multiple calls to 'Acquire' with the same name will increment
//! the internal reference count on the tag. This allows shared ownership between systems, if necessary.
//! - FindTag is provided to search for a tag reference without taking ownership.
//! - Names are case sensitive.
//!
template<typename TagType, size_t MaxTagCount>
class TagRegistry final
: public AZStd::intrusive_base
{
public:
AZ_CLASS_ALLOCATOR(TagRegistry, AZ::SystemAllocator, 0);
AZ_DISABLE_COPY_MOVE(TagRegistry);
static Ptr<TagRegistry> Create();
//! Resets the registry back to an empty state. All references are released.
void Reset();
//! Acquires a tag from the provided name (case sensitive). If the tag already existed, it is ref-counted.
//! Returns a valid tag on success; returns a null tag if the registry is at full capacity. You must
//! call ReleaseTag() if successful.
TagType AcquireTag(const Name& tagName);
//! Releases a reference to a tag. Tags are ref-counted, so it's necessary to maintain ownership of the
//! tag and release when its no longer needed.
void ReleaseTag(TagType tagName);
//! Finds the tag associated with the provided name (case sensitive). If a tag exists with that name, the tag
//! is returned. The reference count is NOT incremented on success; ownership is not passed to the user. If
//! the tag does not exist, a null tag is returned.
TagType FindTag(const Name& tagName) const;
//! Returns the name of the given tag, or empty string if the tag is not registered.
Name GetName(TagType tag) const;
//! Returns the number of allocated tags in the registry.
size_t GetAllocatedTagCount() const;
private:
TagRegistry() = default;
struct Entry
{
Name m_name;
size_t m_refCount = 0;
};
mutable AZStd::shared_mutex m_mutex;
AZStd::array<Entry, MaxTagCount> m_entriesByTag;
size_t m_allocatedTagCount = 0;
};
template<typename TagType, size_t MaxTagCount>
Ptr<TagRegistry<TagType, MaxTagCount>> TagRegistry<TagType, MaxTagCount>::Create()
{
return aznew TagRegistry<TagType, MaxTagCount>();
}
template<typename TagType, size_t MaxTagCount>
void TagRegistry<TagType, MaxTagCount>::Reset()
{
AZStd::unique_lock<AZStd::shared_mutex> lock(m_mutex);
m_entriesByTag.fill({});
m_allocatedTagCount = 0;
}
template<typename TagType, size_t MaxTagCount>
TagType TagRegistry<TagType, MaxTagCount>::AcquireTag(const Name& tagName)
{
if (tagName.IsEmpty())
{
return {};
}
TagType tag;
Entry* foundEmptyEntry = nullptr;
AZStd::unique_lock<AZStd::shared_mutex> lock(m_mutex);
for (size_t i = 0; i < m_entriesByTag.size(); ++i)
{
Entry& entry = m_entriesByTag[i];
// Found an empty entry. Cache off the tag and pointer, but keep searching to find if
// another entry holds the same name.
if (entry.m_refCount == 0 && !foundEmptyEntry)
{
foundEmptyEntry = &entry;
tag = TagType(i);
}
else if (entry.m_name == tagName)
{
entry.m_refCount++;
return TagType(i);
}
}
// No other entry holds the name, so allocate the empty entry.
if (foundEmptyEntry)
{
foundEmptyEntry->m_refCount = 1;
foundEmptyEntry->m_name = tagName;
++m_allocatedTagCount;
}
return tag;
}
template<typename TagType, size_t MaxTagCount>
void TagRegistry<TagType, MaxTagCount>::ReleaseTag(TagType tag)
{
if (tag.IsValid())
{
AZStd::unique_lock<AZStd::shared_mutex> lock(m_mutex);
Entry& entry = m_entriesByTag[tag.GetIndex()];
const size_t refCount = --entry.m_refCount;
AZ_Assert(
refCount != static_cast<size_t>(-1), "Attempted to forfeit a tag that is not valid. Tag{%d},Name{'%s'}", tag,
entry.m_name.GetCStr());
if (refCount == 0)
{
entry.m_name = Name();
--m_allocatedTagCount;
}
}
}
template<typename TagType, size_t MaxTagCount>
TagType TagRegistry<TagType, MaxTagCount>::FindTag(const Name& tagName) const
{
AZStd::shared_lock<AZStd::shared_mutex> lock(m_mutex);
for (size_t i = 0; i < m_entriesByTag.size(); ++i)
{
if (m_entriesByTag[i].m_name == tagName)
{
return TagType(i);
}
}
return {};
}
template<typename TagType, size_t MaxTagCount>
Name TagRegistry<TagType, MaxTagCount>::GetName(TagType tag) const
{
if (tag.GetIndex() < m_entriesByTag.size())
{
return m_entriesByTag[tag.GetIndex()].m_name;
}
else
{
return Name();
}
}
template<typename TagType, size_t MaxTagCount>
size_t TagRegistry<TagType, MaxTagCount>::GetAllocatedTagCount() const
{
return m_allocatedTagCount;
}
}
}
+4 -8
View File
@@ -35,8 +35,7 @@ namespace AZ
switch (sortType)
{
case DrawListSortType::KeyThenDepth:
AZStd::sort(drawList.begin(), drawList.end(),
[](const DrawItemKeyPair& a, const DrawItemKeyPair& b)
AZStd::sort(drawList.begin(), drawList.end(), [](const DrawItemProperties& a, const DrawItemProperties& b)
{
if (a.m_sortKey != b.m_sortKey)
{
@@ -48,8 +47,7 @@ namespace AZ
break;
case DrawListSortType::KeyThenReverseDepth:
AZStd::sort(drawList.begin(), drawList.end(),
[](const DrawItemKeyPair& a, const DrawItemKeyPair& b)
AZStd::sort(drawList.begin(), drawList.end(), [](const DrawItemProperties& a, const DrawItemProperties& b)
{
if (a.m_sortKey != b.m_sortKey)
{
@@ -61,8 +59,7 @@ namespace AZ
break;
case DrawListSortType::DepthThenKey:
AZStd::sort(drawList.begin(), drawList.end(),
[](const DrawItemKeyPair& a, const DrawItemKeyPair& b)
AZStd::sort(drawList.begin(), drawList.end(), [](const DrawItemProperties& a, const DrawItemProperties& b)
{
if (a.m_depth != b.m_depth)
{
@@ -74,8 +71,7 @@ namespace AZ
break;
case DrawListSortType::ReverseDepthThenKey:
AZStd::sort(drawList.begin(), drawList.end(),
[](const DrawItemKeyPair& a, const DrawItemKeyPair& b)
AZStd::sort(drawList.begin(), drawList.end(), [](const DrawItemProperties& a, const DrawItemProperties& b)
{
if (a.m_depth != b.m_depth)
{
@@ -63,14 +63,14 @@ namespace AZ
if (m_drawListMask[drawListTag.GetIndex()])
{
DrawItemKeyPair drawItem = drawPacket->GetDrawItem(i);
DrawItemProperties drawItem = drawPacket->GetDrawItem(i);
drawItem.m_depth = depth;
threadListsByTag[drawListTag.GetIndex()].push_back(drawItem);
}
}
}
void DrawListContext::AddDrawItem(DrawListTag drawListTag, DrawItemKeyPair drawItemKeyPair)
void DrawListContext::AddDrawItem(DrawListTag drawListTag, DrawItemProperties drawItemProperties)
{
if (Validation::IsEnabled())
{
@@ -84,7 +84,7 @@ namespace AZ
if (m_drawListMask[drawListTag.GetIndex()])
{
DrawListsByTag& drawListsByTag = m_threadListsByTag.GetStorage();
drawListsByTag[drawListTag.GetIndex()].push_back(drawItemKeyPair);
drawListsByTag[drawListTag.GetIndex()].push_back(drawItemProperties);
}
}
@@ -1,117 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <Atom/RHI/DrawListTagRegistry.h>
namespace AZ
{
namespace RHI
{
Ptr<DrawListTagRegistry> DrawListTagRegistry::Create()
{
return aznew DrawListTagRegistry;
}
void DrawListTagRegistry::Reset()
{
AZStd::unique_lock<AZStd::shared_mutex> lock(m_mutex);
m_entriesByTag.fill({});
m_allocatedTagCount = 0;
}
DrawListTag DrawListTagRegistry::AcquireTag(const Name& drawListName)
{
if (drawListName.IsEmpty())
{
return {};
}
DrawListTag drawListTag;
Entry* foundEmptyEntry = nullptr;
AZStd::unique_lock<AZStd::shared_mutex> lock(m_mutex);
for (size_t i = 0; i < m_entriesByTag.size(); ++i)
{
Entry& entry = m_entriesByTag[i];
// Found an empty entry. Cache off the tag and pointer, but keep searching to find if
// another entry holds the same name.
if (entry.m_refCount == 0 && !foundEmptyEntry)
{
foundEmptyEntry = &entry;
drawListTag = DrawListTag(i);
}
else if (entry.m_name == drawListName)
{
entry.m_refCount++;
return DrawListTag(i);
}
}
// No other entry holds the name, so allocate the empty entry.
if (foundEmptyEntry)
{
foundEmptyEntry->m_refCount = 1;
foundEmptyEntry->m_name = drawListName;
++m_allocatedTagCount;
}
return drawListTag;
}
void DrawListTagRegistry::ReleaseTag(DrawListTag drawListTag)
{
if (drawListTag.IsValid())
{
AZStd::unique_lock<AZStd::shared_mutex> lock(m_mutex);
Entry& entry = m_entriesByTag[drawListTag.GetIndex()];
const size_t refCount = --entry.m_refCount;
AZ_Assert(refCount != static_cast<size_t>(-1), "Attempted to forfeit a tag that is not valid. Tag{%d},Name{'%s'}", drawListTag, entry.m_name.GetCStr());
if (refCount == 0)
{
entry.m_name = Name();
--m_allocatedTagCount;
}
}
}
DrawListTag DrawListTagRegistry::FindTag(const Name& drawListName) const
{
AZStd::shared_lock<AZStd::shared_mutex> lock(m_mutex);
for (size_t i = 0; i < m_entriesByTag.size(); ++i)
{
if (m_entriesByTag[i].m_name == drawListName)
{
return DrawListTag(i);
}
}
return {};
}
Name DrawListTagRegistry::GetName(DrawListTag tag) const
{
if (tag.GetIndex() < m_entriesByTag.size())
{
return m_entriesByTag[tag.GetIndex()].m_name;
}
else
{
return Name();
}
}
size_t DrawListTagRegistry::GetAllocatedTagCount() const
{
return m_allocatedTagCount;
}
}
}
+7 -2
View File
@@ -24,10 +24,10 @@ namespace AZ
return m_drawItemCount;
}
DrawItemKeyPair DrawPacket::GetDrawItem(size_t index) const
DrawItemProperties DrawPacket::GetDrawItem(size_t index) const
{
AZ_Assert(index < GetDrawItemCount(), "Out of bounds array access!");
return DrawItemKeyPair(&m_drawItems[index], m_drawItemSortKeys[index]);
return DrawItemProperties(&m_drawItems[index], m_drawItemSortKeys[index], m_drawFilterMask);
}
DrawListTag DrawPacket::GetDrawListTag(size_t index) const
@@ -36,6 +36,11 @@ namespace AZ
return m_drawListTags[index];
}
DrawFilterMask DrawPacket::GetDrawFilterMask() const
{
return m_drawFilterMask;
}
DrawListMask DrawPacket::GetDrawListMask() const
{
return m_drawListMask;
@@ -82,6 +82,11 @@ namespace AZ
}
}
void DrawPacketBuilder::SetDrawFilterMask(DrawFilterMask filterMask)
{
m_drawFilterMask = filterMask;
}
void DrawPacketBuilder::AddDrawItem(const DrawRequest& request)
{
if (request.m_listTag.IsValid())
@@ -165,6 +170,7 @@ namespace AZ
drawPacket->m_allocator = m_allocator;
drawPacket->m_indexBufferView = m_indexBufferView;
drawPacket->m_drawListMask = m_drawListMask;
drawPacket->m_drawFilterMask = m_drawFilterMask;
if (shaderResourceGroupsOffset.IsValid())
{
@@ -288,6 +294,7 @@ namespace AZ
m_rootConstants = {};
m_scissors.clear();
m_viewports.clear();
m_drawFilterMask = DrawFilterMaskDefaultValue;
}
}
}
+1 -2
View File
@@ -60,7 +60,7 @@ namespace AZ
AZ_Assert(false, "RHISystem", "Unable to initialize RHI! \n");
return;
}
m_drawListTagRegistry = RHI::DrawListTagRegistry::Create();
m_pipelineStateCache = RHI::PipelineStateCache::Create(*m_device);
@@ -199,7 +199,6 @@ namespace AZ
m_frameScheduler.Shutdown();
m_platformLimitsDescriptor = nullptr;
m_drawListTagRegistry = nullptr;
m_pipelineStateCache = nullptr;
m_device->PreShutdown();
AZ_Assert(m_device->use_count()==1, "The ref count for Device is %i but it should be 1 here to ensure all the resources are released", m_device->use_count());
+3 -3
View File
@@ -80,11 +80,11 @@ namespace UnitTest
m_indexBufferView = RHI::IndexBufferView(*m_bufferEmpty, random.GetRandom(), random.GetRandom(), RHI::IndexFormat::Uint16);
}
void ValidateDrawItem(const DrawItemData& drawItemData, RHI::DrawItemKeyPair itemKeyPair) const
void ValidateDrawItem(const DrawItemData& drawItemData, RHI::DrawItemProperties itemProperties) const
{
const RHI::DrawItem* drawItem = itemKeyPair.m_item;
const RHI::DrawItem* drawItem = itemProperties.m_item;
EXPECT_EQ(itemKeyPair.m_sortKey, drawItemData.m_sortKey);
EXPECT_EQ(itemProperties.m_sortKey, drawItemData.m_sortKey);
EXPECT_EQ(drawItem->m_stencilRef, drawItemData.m_stencilRef);
EXPECT_EQ(drawItem->m_pipelineState, drawItemData.m_pipelineState);
@@ -36,6 +36,7 @@ set(FILES
Include/Atom/RHI/CopyItem.h
Include/Atom/RHI/ConstantsData.h
Include/Atom/RHI/DispatchItem.h
Include/Atom/RHI/DrawFilterTagRegistry.h
Include/Atom/RHI/DrawItem.h
Include/Atom/RHI/DrawList.h
Include/Atom/RHI/DrawListTagRegistry.h
@@ -48,7 +49,6 @@ set(FILES
Source/RHI/ConstantsData.cpp
Source/RHI/DrawList.cpp
Source/RHI/DrawListContext.cpp
Source/RHI/DrawListTagRegistry.cpp
Source/RHI/DrawPacket.cpp
Source/RHI/DrawPacketBuilder.cpp
Include/Atom/RHI/Device.h
@@ -201,4 +201,5 @@ set(FILES
Include/Atom/RHI/CpuProfiler.h
Include/Atom/RHI/CpuProfilerImpl.h
Source/RHI/CpuProfilerImpl.cpp
Include/Atom/RHI/TagRegistry.h
)
@@ -214,6 +214,10 @@ namespace AZ
Scene* m_scene = nullptr;
RHI::DrawListTag m_drawListTag;
// All draw items use this filter when submit them to views
// It's set to RenderPipeline's draw filter mask if the DynamicDrawContext was created for a render pipeline.
RHI::DrawFilterMask m_drawFilter = RHI::DrawFilterMaskDefaultValue;
// Cached draw data
AZStd::vector<RHI::StreamBufferView> m_cachedStreamBufferViews;
AZStd::vector<RHI::IndexBufferView> m_cachedIndexBufferViews;
@@ -56,9 +56,11 @@ namespace AZ
//! Draw calls which are made to this DynamicDrawContext will only be submitted for this scene.
//! The created DynamicDrawContext is managed by dynamic draw system.
virtual RHI::Ptr<DynamicDrawContext> CreateDynamicDrawContext(Scene* scene) = 0;
//! Create a DynamicDrawContext for specified pass
virtual RHI::Ptr<DynamicDrawContext> CreateDynamicDrawContext(Pass* pass = nullptr) = 0;
//! Create a DynamicDrawContext for specified render pipeline
//! Draw calls submitted through the context created by this function are only submitted
//! to the supplied render pipeline (viewport)
virtual RHI::Ptr<DynamicDrawContext> CreateDynamicDrawContext(RenderPipeline* pipeline) = 0;
//! Get a DynamicBuffer from DynamicDrawSystem.
//! The returned buffer will be invalidated every time the RPISystem's RenderTick is called
@@ -36,7 +36,7 @@ namespace AZ
// DynamicDrawInterface overrides...
RHI::Ptr<DynamicDrawContext> CreateDynamicDrawContext(Scene* scene) override;
RHI::Ptr<DynamicDrawContext> CreateDynamicDrawContext(Pass* pass) override;
RHI::Ptr<DynamicDrawContext> CreateDynamicDrawContext(RenderPipeline* pipeline) override;
RHI::Ptr<DynamicBuffer> GetDynamicBuffer(uint32_t size, uint32_t alignment = 1) override;
void DrawGeometry(Data::Instance<Material> material, const GeometryData& geometry, ScenePtr scene) override;
void AddDrawPacket(Scene* scene, AZStd::unique_ptr<const RHI::DrawPacket> drawPacket) override;
@@ -184,6 +184,12 @@ namespace AZ
//! Get current render mode
RenderMode GetRenderMode() const;
//! Get draw filter tag
RHI::DrawFilterTag GetDrawFilterTag() const;
//! Get draw filter mask
RHI::DrawFilterMask GetDrawFilterMask() const;
private:
RenderPipeline() = default;
@@ -211,6 +217,8 @@ namespace AZ
// if the view already exists in map, its DrawListMask will be combined to the existing one's
void CollectPersistentViews(AZStd::map<ViewPtr, RHI::DrawListMask>& outViewMasks) const;
void SetDrawFilterTag(RHI::DrawFilterTag);
// End of functions accessed by Scene class
//////////////////////////////////////////////////
@@ -250,6 +258,13 @@ namespace AZ
// Original settings from RenderPipelineDescriptor, used to revert active render settings to original settings from RenderPipelineDescriptor
PipelineRenderSettings m_originalRenderSettings;
// A tag to filter draw items submitted by passes of this render pipeline.
// This tag is allocated when it's added to a scene. It's set to invalid when it's removed to the scene.
RHI::DrawFilterTag m_drawFilterTag;
// A mask to filter draw items submitted by passes of this render pipeline.
// This mask is created from the value of m_drawFilterTag.
RHI::DrawFilterMask m_drawFilterMask = 0;
};
} // namespace RPI
@@ -14,6 +14,7 @@
#include <Atom/RHI/DrawList.h>
#include <Atom/RHI/PipelineStateDescriptor.h>
#include <Atom/RHI/DrawFilterTagRegistry.h>
#include <Atom/RHI.Reflect/FrameSchedulerEnums.h>
#include <Atom/RHI.Reflect/ShaderResourceGroupLayoutDescriptor.h>
#include <Atom/RPI.Reflect/System/SceneDescriptor.h>
@@ -234,6 +235,9 @@ namespace AZ
// reference of dynamic draw system (from RPISystem)
DynamicDrawSystem* m_dynamicDrawSystem = nullptr;
// Registry which allocates draw filter tag for RenderPipeline
RHI::Ptr<RHI::DrawFilterTagRegistry> m_drawFilterTagRegistry;
};
// --- Template functions ---
@@ -75,7 +75,7 @@ namespace AZ
void AddDrawPacket(const RHI::DrawPacket* drawPacket, Vector3 worldPosition);
//! Add a draw item to this view with its associated draw list tag
void AddDrawItem(RHI::DrawListTag drawListTag, const RHI::DrawItemKeyPair& drawItemKeyPair);
void AddDrawItem(RHI::DrawListTag drawListTag, const RHI::DrawItemProperties& drawItemProperties);
//! Sets the worldToView matrix and recalculates the other matrices.
void SetWorldToViewMatrix(const AZ::Matrix4x4& worldToView);
@@ -17,6 +17,7 @@
#include <Atom/RPI.Public/DynamicDraw/DynamicBuffer.h>
#include <Atom/RPI.Public/DynamicDraw/DynamicDrawContext.h>
#include <Atom/RPI.Public/DynamicDraw/DynamicDrawInterface.h>
#include <Atom/RPI.Public/RenderPipeline.h>
#include <Atom/RPI.Public/View.h>
@@ -601,10 +602,11 @@ namespace AZ
drawItemInfo.m_drawItem.m_streamBufferViews = &m_cachedStreamBufferViews[drawItemInfo.m_vertexBufferViewIndex];
}
RHI::DrawItemKeyPair drawItemKeyPair;
drawItemKeyPair.m_sortKey = sortKey;
drawItemKeyPair.m_item = &drawItemInfo.m_drawItem;
view->AddDrawItem(m_drawListTag, drawItemKeyPair);
RHI::DrawItemProperties drawItemProperties;
drawItemProperties.m_sortKey = sortKey;
drawItemProperties.m_item = &drawItemInfo.m_drawItem;
drawItemProperties.m_drawFilterMask = m_drawFilter;
view->AddDrawItem(m_drawListTag, drawItemProperties);
sortKey++;
}
}
@@ -59,6 +59,11 @@ namespace AZ
RHI::Ptr<DynamicDrawContext> DynamicDrawSystem::CreateDynamicDrawContext(Scene* scene)
{
if (!scene)
{
AZ_Error("RPI", false, "Failed to create a DynamicDrawContext: the input scene is invalid");
return nullptr;
}
RHI::Ptr<DynamicDrawContext> drawContext = aznew DynamicDrawContext();
drawContext->m_scene = scene;
@@ -67,11 +72,17 @@ namespace AZ
return drawContext;
}
// [GFX TODO][ATOM-13185] Add support for creating DynamicDrawContext for Pass
RHI::Ptr<DynamicDrawContext> DynamicDrawSystem::CreateDynamicDrawContext([[maybe_unused]] Pass* pass)
RHI::Ptr<DynamicDrawContext> DynamicDrawSystem::CreateDynamicDrawContext(RenderPipeline* pipeline)
{
AZ_Error("RPI", false, "Unimplemented function");
return nullptr;
if (!pipeline || !pipeline->GetScene())
{
AZ_Error("RPI", false, "Failed to create a DynamicDrawContext: the input RenderPipeline is invalid or wasn't added to a Scene");
return nullptr;
}
auto context = CreateDynamicDrawContext(pipeline->GetScene());
context->m_drawFilter = pipeline->GetDrawFilterMask();
return context;
}
// [GFX TODO][ATOM-13184] Add support of draw geometry with material for DynamicDrawSystemInterface
@@ -195,9 +195,12 @@ namespace AZ
SetSrgsForDraw(commandList);
}
for (const RHI::DrawItemKeyPair& drawItemKeyPair : drawListViewPartition)
for (const RHI::DrawItemProperties& drawItemProperties : drawListViewPartition)
{
commandList->Submit(*drawItemKeyPair.m_item);
if (drawItemProperties.m_drawFilterMask & m_pipeline->GetDrawFilterMask())
{
commandList->Submit(*drawItemProperties.m_item);
}
}
}
@@ -300,6 +300,9 @@ namespace AZ
m_scene = nullptr;
m_rootPass->SetEnabled(false);
m_rootPass->QueueForRemoval();
m_drawFilterTag.Reset();
m_drawFilterMask = 0;
}
void RenderPipeline::OnPassModified()
@@ -506,5 +509,28 @@ namespace AZ
{
return m_renderMode != RenderMode::NoRender;
}
RHI::DrawFilterTag RenderPipeline::GetDrawFilterTag() const
{
return m_drawFilterTag;
}
RHI::DrawFilterMask RenderPipeline::GetDrawFilterMask() const
{
return m_drawFilterMask;
}
void RenderPipeline::SetDrawFilterTag(RHI::DrawFilterTag tag)
{
m_drawFilterTag = tag;
if (m_drawFilterTag.IsValid())
{
m_drawFilterMask = 1 << tag.GetIndex();
}
else
{
m_drawFilterMask = 0;
}
}
}
}
@@ -87,6 +87,7 @@ namespace AZ
m_id = Uuid::CreateRandom();
m_cullingScene = aznew CullingScene();
SceneRequestBus::Handler::BusConnect(m_id);
m_drawFilterTagRegistry = RHI::DrawFilterTagRegistry::Create();
}
Scene::~Scene()
@@ -269,6 +270,8 @@ namespace AZ
return;
}
pipeline->SetDrawFilterTag(m_drawFilterTagRegistry->AcquireTag(pipelineId));
m_pipelines.push_back(pipeline);
// Set this pipeline as default if the default pipeline was empty. This pipeline should be the first pipeline be added to the scene
@@ -303,6 +306,8 @@ namespace AZ
m_defaultPipeline = nullptr;
}
m_drawFilterTagRegistry->ReleaseTag(pipelineToRemove->GetDrawFilterTag());
pipelineToRemove->OnRemovedFromScene(this);
m_pipelines.erase(it);
@@ -90,9 +90,9 @@ namespace AZ
AddDrawPacket(drawPacket, depth);
}
void View::AddDrawItem(RHI::DrawListTag drawListTag, const RHI::DrawItemKeyPair& drawItemKeyPair)
void View::AddDrawItem(RHI::DrawListTag drawListTag, const RHI::DrawItemProperties& drawItemProperties)
{
m_drawListContext.AddDrawItem(drawListTag, drawItemKeyPair);
m_drawListContext.AddDrawItem(drawListTag, drawItemProperties);
}
void View::SetWorldToViewMatrix(const AZ::Matrix4x4& worldToView)
@@ -41,7 +41,6 @@ namespace AZ
BuilderComponent::~BuilderComponent()
{
AZ::Component::~Component();
AZ::Interface<AzFramework::AtomActiveInterface>::Unregister(this);
}
@@ -57,7 +57,6 @@ namespace AZ
void OnRenderTick() override;
void OnViewportSizeChanged(AzFramework::WindowSize size) override;
DebugConsole m_debugConsole;
bool m_initialized = false;
};
} // namespace LYIntegration
-7
View File
@@ -30,9 +30,7 @@ ly_add_target(
Include
BUILD_DEPENDENCIES
PRIVATE
AZ::AzCore
AZ::CrashHandler
AZ::CrashSupport
)
ly_add_target(
@@ -46,10 +44,5 @@ ly_add_target(
Include
BUILD_DEPENDENCIES
PRIVATE
#3rdParty::Crashpad
#3rdParty::Crashpad::Handler
AZ::AzCore
AZ::CrashUploaderSupport
#AZ::CrashHandler
AZ::CrashSupport
)
@@ -510,7 +510,7 @@ namespace ScriptCanvas
AZ_Assert(lua_isuserdata(lua, 1), "CallExecutionOut: Error in compiled lua file, 1st argument to SetExecutionOut is not userdata (Nodeable)");
AZ_Assert(lua_isnumber(lua, 2), "CallExecutionOut: Error in compiled lua file, 2nd argument to SetExecutionOut is not a number");
Nodeable* nodeable = AZ::ScriptValue<Nodeable*>::StackRead(lua, 1);
size_t index = aznumeric_caster(lua_tointeger(lua, -2));
size_t index = aznumeric_caster(lua_tointeger(lua, 2));
nodeable->CallOut(index, nullptr, nullptr, argsCount - 2);
// Lua: results...
return lua_gettop(lua);
@@ -697,7 +697,7 @@ namespace ScriptCanvas
AZ_Assert(lua_islightuserdata(lua, 2), "Error in compiled lua file, 2nd argument to UnpackDependencyArgs is not userdata (AZStd::vector<AZ::Data::Asset<RuntimeAsset>>*), but a :%s", lua_typename(lua, 2));
auto dependentAssets = reinterpret_cast<AZStd::vector<AZ::Data::Asset<RuntimeAsset>>*>(lua_touserdata(lua, 2));
AZ_Assert(lua_isinteger(lua, 3), "Error in compiled Lua file, 3rd argument to UnpackDependencyArgs is not a number");
const size_t dependentAssetsIndex = lua_tointeger(lua, 3);
const size_t dependentAssetsIndex = aznumeric_caster(lua_tointeger(lua, 3));
return DependencyConstructionPack{ executionState, dependentAssets, dependentAssetsIndex, (*dependentAssets)[dependentAssetsIndex].Get()->m_runtimeData };
}
@@ -3257,13 +3257,12 @@ namespace ScriptCanvas
return;
}
execution->SetNodeable(iter->second->m_nodeable);
child->SetNodeable(iter->second->m_nodeable);
for (auto& childOutSlot : childOutSlots)
{
AZ_Assert(childOutSlot, "null slot in child out slot list");
ExecutionTreePtr internalOut = OpenScope(child, node, childOutSlot);
internalOut->SetNodeable(execution->GetNodeable());
const size_t outIndex = node->GetOutIndex(*childOutSlot);
if (outIndex == std::numeric_limits<size_t>::max())
@@ -262,9 +262,6 @@ namespace ScriptCanvas
void SetSymbol(Symbol val);
protected:
VariableConstPtr m_nodeable;
private:
// the (possible) slot(s) through which execution exited, along with associated output
AZStd::vector<ExecutionChild> m_children;
@@ -316,6 +313,8 @@ namespace ScriptCanvas
Symbol m_symbol = Symbol::FunctionCall;
VariableConstPtr m_nodeable;
size_t FindIndexOfChild(ExecutionTreeConstPtr child) const;
};
@@ -276,7 +276,7 @@ namespace ScriptCanvas
if (IsMethodOverloaded() && BehaviorContextUtils::FindExplicitOverload(method, bcClass, className, methodName, &prettyClassName))
{
MethodConfiguration config(*method, method->IsMember() ? MethodType::Member : MethodType::Free);
MethodConfiguration config(*method, MethodType::Member);
config.m_class = bcClass;
config.m_namespaces = &m_namespaces;
config.m_className = &className;
@@ -582,7 +582,7 @@ namespace ScriptCanvas
void GraphToLua::TranslateExecutionTreeFunctionCall(Grammar::ExecutionTreeConstPtr execution)
{
TranslateNodeableOuts(execution);
TranslateNodeableOuts(execution->GetNodeable(), execution);
WriteDebugInfoIn(execution, "TranslateExecutionTreeFunctionCall begin");
m_dotLua.WriteIndent();
WriteLocalOutputInitialization(execution);
@@ -955,7 +955,7 @@ namespace ScriptCanvas
for (auto& out : nodeAndParse->m_latents)
{
m_dotLua.WriteNewLine();
TranslateNodeableOut(out.second);
TranslateNodeableOut(nodeAndParse->m_nodeable, out.second);
}
if (!nodeAndParse->m_latents.empty())
@@ -1017,7 +1017,7 @@ namespace ScriptCanvas
m_dotLua.WriteNewLine();
}
void GraphToLua::TranslateNodeableOut(Grammar::ExecutionTreeConstPtr execution)
void GraphToLua::TranslateNodeableOut(Grammar::VariableConstPtr host, Grammar::ExecutionTreeConstPtr execution)
{
auto outCallIndexOptional = execution->GetOutCallIndex();
if (!outCallIndexOptional)
@@ -1037,7 +1037,7 @@ namespace ScriptCanvas
m_dotLua.WriteLineIndented("%s(self.%s, %zu, -- %s"
, setExecutionOutName
, execution->GetNodeable()->m_name.data()
, host->m_name.data()
, outIndex
, execution->GetName().data());
@@ -1048,14 +1048,14 @@ namespace ScriptCanvas
m_dotLua.Outdent();
}
void GraphToLua::TranslateNodeableOuts(Grammar::ExecutionTreeConstPtr execution)
void GraphToLua::TranslateNodeableOuts(Grammar::VariableConstPtr host, Grammar::ExecutionTreeConstPtr execution)
{
const auto outs = execution->GetInternalOuts();
for (const auto& out : outs)
{
m_dotLua.WriteNewLine();
TranslateNodeableOut(out);
TranslateNodeableOut(host, out);
}
if (!outs.empty())
@@ -111,8 +111,8 @@ namespace ScriptCanvas
void TranslateFunctionBlock(Grammar::ExecutionTreeConstPtr execution, FunctionBlockConfig functionBlockConfig, IsNamed lex);
void TranslateFunctionDefinition(Grammar::ExecutionTreeConstPtr execution, IsNamed lex);
void TranslateInheritance();
void TranslateNodeableOut(Grammar::ExecutionTreeConstPtr execution);
void TranslateNodeableOuts(Grammar::ExecutionTreeConstPtr execution);
void TranslateNodeableOut(Grammar::VariableConstPtr host, Grammar::ExecutionTreeConstPtr execution);
void TranslateNodeableOuts(Grammar::VariableConstPtr host, Grammar::ExecutionTreeConstPtr execution);
void TranslateNodeableParse();
void TranslateStaticInitialization();
void TranslateVariableInitialization(AZStd::string_view leftValue);
@@ -100,6 +100,11 @@ TEST_F(ScriptCanvasTestFixture, InterpretedReadEnumConstant)
RunUnitTestGraph("LY_SC_UnitTest_ReadEnumConstant");
}
TEST_F(ScriptCanvasTestFixture, UserBranchSanityCheck)
{
RunUnitTestGraph("LY_SC_UnitTest_UserBranchSanityCheck");
}
TEST_F(ScriptCanvasTestFixture, InterpretedEventHandlerNoDisconnect)
{
GlobalHandler handler;
-202
View File
@@ -1,202 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:bb76d30a6782e42737778d75d67192eff8770745a327c7f0bcb172478bbee693
size 3334464
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:60ae111931f84ebfd0fb477f894c16193f2b661448610ef28dadb6e25669f6b6
size 2307704
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:b77a7b85064278b9550fb4926ede40486401023fa0aa3791e26c5b54c89ed065
size 3076056
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:5d84217997c2c29c46e2df33883a9e869ba3a65f22dd014b858dee25cc75f199
size 11129296
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:b43625a00c5e82b21ffbd3f76b15a02b556497a11dea64a70bae065dc6db383a
size 9991040
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:36d6797b5180e458a04f39ebc7ccc4e9a077f94161aa6a1aa500a6dd2532f677
size 76256
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6a976d5ae4e58c41b1203c37c0538ce9b690bfd2c7bd41602c29bb628a4bed12
size 10371432
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:9d7a99dd8cf3b1cadb7e638ede71bf143e787189352800cebe18b6148748497d
size 2312800
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:7721d60e9c15dc07c63b0c457047f359dcd21de08ca1a1c858cb20799be83d6d
size 1802480
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:307a8ac4a2bfc08ff98e10063b503ce7f7dbc8c45bfa3eeb1459f28fced0a69a
size 2532480
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:5f8e32c3fabea8c59f5afc7df2643ad70539aa3db10c2dae97cf3e9281507bf8
size 8205936
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:36ed8253faf1600d136923bf86ef52a812490e43c9caadee61ae28f2ecf1995b
size 7803856
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:3123a5553a578b8494cc9453ab039a3198cfa564f3b8b9ccef4a8a593caffa1c
size 77256
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:f7fd642b088929e74140930107ce9a4f06099eaa8e78dc9c024b98db3201f9fe
size 7588096
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6507de8507e07f3a3a3c216392951dd04cb8303d3c851cee3b6f8ef2615ccbb0
size 536576
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:faf9b73e55eb744a6a672444affcf29338552623bd24400fb858b17242b3ab90
size 2987702
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:0877dd0586810f9f376a712ad9240ee73a35358fa32c7eb74e16f020772f9b51
size 790528
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:ad8c021cd42687428b312cac1ad233f6101708e49437ef817959c303f5e69f37
size 3481946
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:631d2c813cd5f3b258555013db4dc90d57a692df60d3dad5398fce14fd2e69a7
size 1265664
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:1b1e018c8571ab9e1b06c9e3a5750038a9589c2442563678815ae37a47512c80
size 10799690
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:49e77aeba8ff229ed1df999af9ef55fd3beaffe57b3f498036be4445809f5c6f
size 512000
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:d58e0c4a46398a0feaf922c2325b57650f7b80947075ed024f5317c0101e0ebf
size 2604980
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:bb5c38028547b3834b92fcd5f5381b893bd9e5e9f7b3946ae3616f8d5209fbbd
size 733184
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e2157bd0d5f2408074879ba68027bf78ad4585b97eac469281a8c2159f10c0fa
size 3024914
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e477cfcc3433eb2311e4b4349ad9690f61a658298d0a82acb68f53bec086b56c
size 1191936
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:7e7f0c899275be00dc64474d0880f9bbd67989f2df9cd69bd1fc6b6ef36f194b
size 9327612
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:b5eeba748c1c424bf1d354a51b1e804aa37874bb6113a28a80138e1a88df9eef
size 610304
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c5a31ccb663c6becbcc2d479a659f51891465c8664a5d70cf6ebf9a881eaabb0
size 2279968
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:76458fdb9688fd8ec6d01cd127e480c0807a599df4442d83e3d0d5700203b169
size 995328
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:4e5b56aa6a11ecb0f0bf20ed52600c2783bb51192609e058942f6ecddb6f29a7
size 3872018
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:158bec9dec5eb5b9e0bda8a3c6eb20413726ec5e2c32254acc1b7e5d63e884fb
size 77824
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:5f749466487567392cb530d5b6adf104f607f3c665781fe5d28ad402366da453
size 10570
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:811d32c5432a78abe224ebbfa8f05c3cd970264147fde83d31af286bc0bd7ad1
size 1478656
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:997162e154b9cb76cbad70f8e6ce40060309ba6b481d146405fd41bc4ef433a2
size 3713948
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:1f8e52266f2bf35d924559f5b84cbef8f5418ea393edd4a538b3c515c2f5b5f0
size 2068480
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6d998572e0831aba01ab666f2db70ad728f6fc3ee681ccb5b843d4b5d5c42b46
size 17842252

Some files were not shown because too many files have changed in this diff Show More