Merge branch 'development' of https://github.com/o3de/o3de into GroupToggleSwitch
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
|
||||
#include "SequenceBatchRenderDialog.h"
|
||||
|
||||
#include <AzCore/Component/ComponentApplication.h>
|
||||
#include <AzFramework/Windowing/WindowBus.h>
|
||||
|
||||
// Qt
|
||||
@@ -1215,6 +1216,18 @@ void CSequenceBatchRenderDialog::OnKickIdleTimout()
|
||||
// All done with our custom OnKickIdle, restore editor idle.
|
||||
SetEnableEditorIdleProcessing(true);
|
||||
}
|
||||
|
||||
//When we disable the editor idle processing. system tick is no longer invoked.
|
||||
//so we call it here to ensure rendering + other systems are updated.
|
||||
if (!m_editorIdleProcessingEnabled)
|
||||
{
|
||||
AZ::ComponentApplication* componentApplication = nullptr;
|
||||
AZ::ComponentApplicationBus::BroadcastResult(componentApplication, &AZ::ComponentApplicationRequests::GetApplication);
|
||||
if (componentApplication)
|
||||
{
|
||||
componentApplication->TickSystem();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSequenceBatchRenderDialog::OnKickIdle()
|
||||
|
||||
@@ -28,27 +28,27 @@ namespace AZ
|
||||
}
|
||||
namespace SceneData
|
||||
{
|
||||
class SCENE_DATA_CLASS MeshGroup
|
||||
class MeshGroup
|
||||
: public DataTypes::IMeshGroup
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(MeshGroup, "{07B356B7-3635-40B5-878A-FAC4EFD5AD86}", DataTypes::IMeshGroup);
|
||||
AZ_CLASS_ALLOCATOR(MeshGroup, SystemAllocator, 0)
|
||||
|
||||
SCENE_DATA_API MeshGroup();
|
||||
SCENE_DATA_API ~MeshGroup() override = default;
|
||||
MeshGroup();
|
||||
~MeshGroup() override = default;
|
||||
|
||||
SCENE_DATA_API const AZStd::string& GetName() const override;
|
||||
SCENE_DATA_API void SetName(const AZStd::string& name);
|
||||
SCENE_DATA_API void SetName(AZStd::string&& name) override;
|
||||
SCENE_DATA_API const Uuid& GetId() const override;
|
||||
SCENE_DATA_API void OverrideId(const Uuid& id) override;
|
||||
const AZStd::string& GetName() const override;
|
||||
void SetName(const AZStd::string& name);
|
||||
void SetName(AZStd::string&& name) override;
|
||||
const Uuid& GetId() const override;
|
||||
void OverrideId(const Uuid& id) override;
|
||||
|
||||
SCENE_DATA_API Containers::RuleContainer& GetRuleContainer() override;
|
||||
SCENE_DATA_API const Containers::RuleContainer& GetRuleContainerConst() const override;
|
||||
Containers::RuleContainer& GetRuleContainer() override;
|
||||
const Containers::RuleContainer& GetRuleContainerConst() const override;
|
||||
|
||||
SCENE_DATA_API DataTypes::ISceneNodeSelectionList& GetSceneNodeSelectionList() override;
|
||||
SCENE_DATA_API const DataTypes::ISceneNodeSelectionList& GetSceneNodeSelectionList() const override;
|
||||
DataTypes::ISceneNodeSelectionList& GetSceneNodeSelectionList() override;
|
||||
const DataTypes::ISceneNodeSelectionList& GetSceneNodeSelectionList() const override;
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
static bool VersionConverter(SerializeContext& context, SerializeContext::DataElementNode& classElement);
|
||||
|
||||
@@ -950,7 +950,7 @@ namespace Multiplayer
|
||||
|
||||
NetworkEntityHandle MultiplayerSystemComponent::SpawnDefaultPlayerPrefab()
|
||||
{
|
||||
PrefabEntityId playerPrefabEntityId(AZ::Name(static_cast<AZ::CVarFixedString>(sv_defaultPlayerSpawnAsset).c_str()), 1);
|
||||
PrefabEntityId playerPrefabEntityId(AZ::Name(static_cast<AZ::CVarFixedString>(sv_defaultPlayerSpawnAsset).c_str()));
|
||||
INetworkEntityManager::EntityList entityList = m_networkEntityManager.CreateEntitiesImmediate(playerPrefabEntityId, NetEntityRole::Authority, AZ::Transform::CreateIdentity());
|
||||
|
||||
NetworkEntityHandle controlledEntity;
|
||||
|
||||
@@ -111,7 +111,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
|
||||
PRIVATE
|
||||
Gem::SceneProcessing.Editor.Static
|
||||
AZ::AzTest
|
||||
AZ::SceneData
|
||||
)
|
||||
ly_add_googletest(
|
||||
NAME Gem::SceneProcessing.Editor.Tests
|
||||
|
||||
+12
-44
@@ -106,7 +106,7 @@ namespace AZ::SceneGenerationComponents
|
||||
auto* serializeContext = azrtti_cast<AZ::SerializeContext*>(context);
|
||||
if (serializeContext)
|
||||
{
|
||||
serializeContext->Class<MeshOptimizerComponent, GenerationComponent>()->Version(3);
|
||||
serializeContext->Class<MeshOptimizerComponent, GenerationComponent>()->Version(2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -192,12 +192,17 @@ namespace AZ::SceneGenerationComponents
|
||||
const AZStd::vector<AZStd::pair<const IMeshData*, NodeIndex>> meshes = [](const SceneGraph& graph)
|
||||
{
|
||||
AZStd::vector<AZStd::pair<const IMeshData*, NodeIndex>> meshes;
|
||||
const auto meshNodes = Containers::MakeDerivedFilterView<IMeshData>(graph.GetContentStorage());
|
||||
for (auto it = meshNodes.cbegin(); it != meshNodes.cend(); ++it)
|
||||
for (auto it = graph.GetContentStorage().cbegin(); it != graph.GetContentStorage().cend(); ++it)
|
||||
{
|
||||
// Skip anything that isn't a mesh.
|
||||
const auto* mesh = azdynamic_cast<const AZ::SceneAPI::DataTypes::IMeshData*>(it->get());
|
||||
if (!mesh)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get the mesh data and node index and store them in the vector as a pair, so we can iterate over them later.
|
||||
// The sequential calls to GetBaseIterator unwrap the layers of FilterIterators from the MakeDerivedFilterView
|
||||
meshes.emplace_back(&(*it), graph.ConvertToNodeIndex(it.GetBaseIterator().GetBaseIterator().GetBaseIterator()));
|
||||
meshes.emplace_back(mesh, graph.ConvertToNodeIndex(it));
|
||||
}
|
||||
return meshes;
|
||||
}(graph);
|
||||
@@ -282,12 +287,6 @@ namespace AZ::SceneGenerationComponents
|
||||
|
||||
auto [optimizedMesh, optimizedUVs, optimizedTangents, optimizedBitangents, optimizedVertexColors, optimizedSkinWeights] = OptimizeMesh(mesh, mesh, uvDatas, tangentDatas, bitangentDatas, colorDatas, skinWeightDatas, meshGroup, hasBlendShapes);
|
||||
|
||||
AZ_TracePrintf(AZ::SceneAPI::Utilities::LogWindow, "Base mesh: %zu vertices, optimized mesh: %zu vertices, %0.02f%% of the original",
|
||||
mesh->GetUsedControlPointCount(),
|
||||
optimizedMesh->GetUsedControlPointCount(),
|
||||
((float)optimizedMesh->GetUsedControlPointCount() / (float)mesh->GetUsedControlPointCount()) * 100.0f
|
||||
);
|
||||
|
||||
const NodeIndex optimizedMeshNodeIndex = graph.AddChild(graph.GetNodeParent(nodeIndex), name.c_str(), AZStd::move(optimizedMesh));
|
||||
|
||||
auto addOptimizedNodes = [&graph, &optimizedMeshNodeIndex](const auto& originalNodeIndexes, auto& optimizedNodes)
|
||||
@@ -434,12 +433,6 @@ namespace AZ::SceneGenerationComponents
|
||||
const float weightThreshold = skinRule ? skinRule->GetWeightThreshold() : 0.001f;
|
||||
meshBuilder.SetSkinningInfo(ExtractSkinningInfo(meshData, skinWeights, maxWeightsPerVertex, weightThreshold));
|
||||
|
||||
constexpr float positionTolerance = 0.0001f;
|
||||
constexpr float positionToleranceReciprocal = 1.0f / positionTolerance;
|
||||
AZStd::unordered_map<AZ::Vector3, AZ::u32> positionMap{};
|
||||
|
||||
AZ::u32 currentOriginalVertexIndex = 0;
|
||||
|
||||
// Add the vertex data to all the layers
|
||||
const AZ::u32 faceCount = meshData->GetFaceCount();
|
||||
for (AZ::u32 faceIndex = 0; faceIndex < faceCount; ++faceIndex)
|
||||
@@ -447,33 +440,8 @@ namespace AZ::SceneGenerationComponents
|
||||
meshBuilder.BeginPolygon(baseMesh->GetFaceMaterialId(faceIndex));
|
||||
for (const AZ::u32 vertexIndex : meshData->GetFaceInfo(faceIndex).vertexIndex)
|
||||
{
|
||||
const AZ::u32 orgVertexNumber = [&meshData, &hasBlendShapes, &vertexIndex, &positionMap, ¤tOriginalVertexIndex, positionTolerance, positionToleranceReciprocal]() -> AZ::u32
|
||||
{
|
||||
if (hasBlendShapes)
|
||||
{
|
||||
// Don't attempt to weld similar vertices if there's blendshapes
|
||||
// Welding the vertices here based on position could cause the vertices of a base shape to be
|
||||
// welded, and the vertices of the blendshape to not be welded, resulting in a vertex count
|
||||
// mismatch between the two
|
||||
return meshData->GetUsedPointIndexForControlPoint(meshData->GetControlPointIndex(vertexIndex));
|
||||
}
|
||||
|
||||
// Round the vertex position so that a float comparison can be made with entires in the positionMap
|
||||
// pos = floor( x * 10 + 0.5) * 0.1
|
||||
const AZ::Vector3 position = AZ::Vector3(
|
||||
AZ::Simd::Vec3::Floor(
|
||||
(meshData->GetPosition(vertexIndex) * positionToleranceReciprocal + AZ::Vector3(0.5f)).GetSimdValue()
|
||||
)
|
||||
) * positionTolerance;
|
||||
|
||||
const auto& [iter, didInsert] = positionMap.try_emplace(position, currentOriginalVertexIndex);
|
||||
if (didInsert)
|
||||
{
|
||||
++currentOriginalVertexIndex;
|
||||
}
|
||||
return iter->second;
|
||||
}();
|
||||
|
||||
const int orgVertexNumber = meshData->GetUsedPointIndexForControlPoint(meshData->GetControlPointIndex(vertexIndex));
|
||||
AZ_Assert(orgVertexNumber >= 0, "Invalid vertex number");
|
||||
orgVtxLayer->SetCurrentVertexValue(orgVertexNumber);
|
||||
|
||||
posLayer->SetCurrentVertexValue(meshData->GetPosition(vertexIndex));
|
||||
|
||||
@@ -1,100 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <AzCore/Component/ComponentApplication.h>
|
||||
#include <AzCore/Component/Entity.h>
|
||||
#include <AzCore/Jobs/JobManagerComponent.h>
|
||||
#include <AzCore/Memory/MemoryComponent.h>
|
||||
#include <AzCore/UnitTest/TestTypes.h>
|
||||
#include <AzCore/std/smart_ptr/shared_ptr.h>
|
||||
#include <AzCore/std/smart_ptr/unique_ptr.h>
|
||||
#include <SceneAPI/SceneCore/Containers/Scene.h>
|
||||
#include <SceneAPI/SceneCore/Containers/SceneGraph.h>
|
||||
#include <SceneAPI/SceneCore/Events/GenerateEventContext.h>
|
||||
#include <SceneAPI/SceneCore/Utilities/SceneGraphSelector.h>
|
||||
#include <SceneAPI/SceneData/GraphData/MeshData.h>
|
||||
#include <SceneAPI/SceneData/Groups/MeshGroup.h>
|
||||
#include <Generation/Components/MeshOptimizer/MeshOptimizerComponent.h>
|
||||
|
||||
#include <InitSceneAPIFixture.h>
|
||||
|
||||
namespace SceneProcessing
|
||||
{
|
||||
using VertexDeduplicationFixture = SceneProcessing::InitSceneAPIFixture;
|
||||
|
||||
TEST_F(VertexDeduplicationFixture, CanDeduplicateVertices)
|
||||
{
|
||||
AZ::ComponentApplication app;
|
||||
AZ::Entity* systemEntity = app.Create({}, {});
|
||||
systemEntity->AddComponent(aznew AZ::MemoryComponent());
|
||||
systemEntity->AddComponent(aznew AZ::JobManagerComponent());
|
||||
systemEntity->Init();
|
||||
systemEntity->Activate();
|
||||
|
||||
AZ::SceneAPI::Containers::Scene scene("testScene");
|
||||
AZ::SceneAPI::Containers::SceneGraph& graph = scene.GetGraph();
|
||||
|
||||
// Create a simple plane with 2 triangles, 6 total vertices, 2 shared vertices
|
||||
// 0 --- 1
|
||||
// | / |
|
||||
// | / |
|
||||
// | / |
|
||||
// 2 --- 3
|
||||
const AZStd::array planeVertexPositions = {
|
||||
AZ::Vector3{0.0f, 0.0f, 0.0f},
|
||||
AZ::Vector3{0.0f, 0.0f, 1.0f},
|
||||
AZ::Vector3{1.0f, 0.0f, 1.0f},
|
||||
AZ::Vector3{1.0f, 0.0f, 1.0f},
|
||||
AZ::Vector3{1.0f, 0.0f, 0.0f},
|
||||
AZ::Vector3{0.0f, 0.0f, 0.0f},
|
||||
};
|
||||
{
|
||||
auto mesh = AZStd::make_unique<AZ::SceneData::GraphData::MeshData>();
|
||||
{
|
||||
int i = 0;
|
||||
for (const AZ::Vector3& position : planeVertexPositions)
|
||||
{
|
||||
mesh->AddPosition(position);
|
||||
mesh->AddNormal(AZ::Vector3::CreateAxisY());
|
||||
|
||||
// This assumes that the data coming from the import process gives a unique control point
|
||||
// index to every vertex. This follows the behavior of the AssImp library.
|
||||
mesh->SetVertexIndexToControlPointIndexMap(i, i);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
mesh->AddFace({0, 1, 2}, 0);
|
||||
mesh->AddFace({3, 4, 5}, 0);
|
||||
|
||||
// The original source mesh should have 6 vertices
|
||||
EXPECT_EQ(mesh->GetVertexCount(), planeVertexPositions.size());
|
||||
|
||||
graph.AddChild(graph.GetRoot(), "testMesh", AZStd::move(mesh));
|
||||
}
|
||||
|
||||
auto meshGroup = AZStd::make_unique<AZ::SceneAPI::SceneData::MeshGroup>();
|
||||
meshGroup->GetSceneNodeSelectionList().AddSelectedNode("testMesh");
|
||||
scene.GetManifest().AddEntry(AZStd::move(meshGroup));
|
||||
|
||||
AZ::SceneGenerationComponents::MeshOptimizerComponent component;
|
||||
AZ::SceneAPI::Events::GenerateSimplificationEventContext context(scene, "pc");
|
||||
component.OptimizeMeshes(context);
|
||||
|
||||
AZ::SceneAPI::Containers::SceneGraph::NodeIndex optimizedNodeIndex = graph.Find(AZStd::string("testMesh").append(AZ::SceneAPI::Utilities::OptimizedMeshSuffix));
|
||||
ASSERT_TRUE(optimizedNodeIndex.IsValid()) << "Mesh optimizer did not add an optimized version of the mesh";
|
||||
|
||||
const auto& optimizedMesh = AZStd::rtti_pointer_cast<AZ::SceneAPI::DataTypes::IMeshData>(graph.GetNodeContent(optimizedNodeIndex));
|
||||
ASSERT_TRUE(optimizedMesh);
|
||||
|
||||
// The optimized mesh should have 4 vertices, the 2 shared vertices are welded together
|
||||
EXPECT_EQ(optimizedMesh->GetVertexCount(), 4);
|
||||
|
||||
systemEntity->Deactivate();
|
||||
}
|
||||
} // namespace SceneProcessing
|
||||
@@ -7,7 +7,6 @@
|
||||
|
||||
set(FILES
|
||||
Tests/InitSceneAPIFixture.h
|
||||
Tests/MeshBuilder/MeshOptimizerComponentTests.cpp
|
||||
Tests/MeshBuilder/MeshBuilderTests.cpp
|
||||
Tests/MeshBuilder/MeshVerticesTests.cpp
|
||||
Tests/MeshBuilder/SkinInfluencesTests.cpp
|
||||
|
||||
@@ -60,7 +60,7 @@ namespace ScriptCanvas
|
||||
|
||||
void RuntimeComponent::Execute()
|
||||
{
|
||||
AZ_PROFILE_SCOPE_DYNAMIC(AZ::Debug::ProfileCategory::ScriptCanvas, "RuntimeComponent::Execute (%s)", m_runtimeAsset.GetId().ToString<AZStd::string>().c_str());
|
||||
AZ_PROFILE_SCOPE_DYNAMIC(AZ::Debug::ProfileCategory::ScriptCanvas, "RuntimeComponent::Execute (%s)", m_runtimeOverrides.m_runtimeAsset.GetId().ToString<AZStd::string>().c_str());
|
||||
AZ_Assert(m_executionState, "RuntimeComponent::Execute called without an execution state");
|
||||
SC_EXECUTION_TRACE_GRAPH_ACTIVATED(CreateActivationInfo());
|
||||
SCRIPT_CANVAS_PERFORMANCE_SCOPE_EXECUTION(m_executionState->GetScriptCanvasId(), m_runtimeOverrides.m_runtimeAsset.GetId());
|
||||
@@ -116,7 +116,7 @@ namespace ScriptCanvas
|
||||
AZ_Assert(m_runtimeAsset.Get(), "RuntimeComponent::m_runtimeAsset AssetId: %s was valid, but the data was not pre-loaded, so this script will not run", m_runtimeOverrides.m_runtimeAsset.GetId().ToString<AZStd::string>().data());
|
||||
#endif
|
||||
|
||||
AZ_PROFILE_SCOPE_DYNAMIC(AZ::Debug::ProfileCategory::ScriptCanvas, "RuntimeComponent::InitializeExecution (%s)", m_runtimeAsset.GetId().ToString<AZStd::string>().c_str());
|
||||
AZ_PROFILE_SCOPE_DYNAMIC(AZ::Debug::ProfileCategory::ScriptCanvas, "RuntimeComponent::InitializeExecution (%s)", m_runtimeOverrides.m_runtimeAsset.GetId().ToString<AZStd::string>().c_str());
|
||||
SCRIPT_CANVAS_PERFORMANCE_SCOPE_INITIALIZATION(m_scriptCanvasId, m_runtimeOverrides.m_runtimeAsset.GetId());
|
||||
m_executionState = ExecutionState::Create(ExecutionStateConfig(m_runtimeOverrides.m_runtimeAsset, *this));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user