diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/EditorMeshComponent.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/EditorMeshComponent.cpp index e1c9026c74..2315c38095 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/EditorMeshComponent.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/EditorMeshComponent.cpp @@ -25,12 +25,16 @@ namespace AZ void EditorMeshComponent::Reflect(AZ::ReflectContext* context) { BaseClass::Reflect(context); + EditorMeshStats::Reflect(context); if (AZ::SerializeContext* serializeContext = azrtti_cast(context)) { + serializeContext->RegisterGenericType(); + serializeContext->Class() ->Version(2, ConvertToEditorRenderComponentAdapter<1>) ->Field("addMaterialComponentFlag", &EditorMeshComponent::m_addMaterialComponentFlag) + ->Field("meshStats", &EditorMeshComponent::m_stats) ; // This shouldn't be registered here, but is required to make a vector from EditorMeshComponentTypeId. This can be removed when one of the following happens: @@ -55,6 +59,8 @@ namespace AZ ->Attribute(AZ::Edit::Attributes::ButtonText, "Add Material Component") ->Attribute(AZ::Edit::Attributes::ChangeNotify, &EditorMeshComponent::AddEditorMaterialComponent) ->Attribute(AZ::Edit::Attributes::Visibility, &EditorMeshComponent::GetEditorMaterialComponentVisibility) + ->DataElement(AZ::Edit::UIHandlers::Default, &EditorMeshComponent::m_stats, "Mesh Stats", "Mesh statistics.") + ->Attribute(AZ::Edit::Attributes::AutoExpand, false) ; editContext->Class( @@ -204,6 +210,25 @@ namespace AZ void EditorMeshComponent::OnModelReady(const Data::Asset& /*modelAsset*/, const Data::Instance& /*model*/) { + m_stats.m_meshStatsForLod.clear(); + if (m_controller.GetConfiguration().IsAssetSet()) + { + auto lods = m_controller.GetConfiguration().m_modelAsset->GetLodAssets(); + for (auto& lod : lods) + { + EditorMeshStatsForLod stats; + auto meshes = lod->GetMeshes(); + stats.m_meshCount = lod->GetMeshes().size(); + for (auto& mesh : meshes) + { + stats.m_vertCount += mesh.GetVertexCount(); + stats.m_triCount += mesh.GetIndexCount() / 3; + } + m_stats.m_meshStatsForLod.push_back(stats); + } + } + m_stats.UpdateStringRepresentation(); + // Refresh the tree when the model loads to update UI based on the model. AzToolsFramework::ToolsApplicationEvents::Bus::Broadcast( &AzToolsFramework::ToolsApplicationEvents::InvalidatePropertyDisplay, @@ -216,6 +241,11 @@ namespace AZ // places it in a bad state, which happens in OnConfigurationChanged base function. // This is a bug with AssetManager [LYN-2249] auto temp = m_controller.m_configuration.m_modelAsset; + + m_stats.m_meshStatsForLod.clear(); + m_stats.UpdateStringRepresentation(); + SetDirty(); + return BaseClass::OnConfigurationChanged(); } } // namespace Render diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/EditorMeshComponent.h b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/EditorMeshComponent.h index 41ea80f8d1..93966bfc74 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/EditorMeshComponent.h +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/EditorMeshComponent.h @@ -18,6 +18,7 @@ #include #include #include +#include namespace AZ { @@ -33,6 +34,7 @@ namespace AZ , private AzToolsFramework::EditorComponentSelectionRequestsBus::Handler , private AzFramework::EntityDebugDisplayEventBus::Handler , private MeshComponentNotificationBus::Handler + , private Data::AssetBus::Handler { public: using BaseClass = EditorRenderComponentAdapter; @@ -71,6 +73,8 @@ namespace AZ // Flag used for button placement bool m_addMaterialComponentFlag = false; + + EditorMeshStats m_stats; }; } // namespace Render } // namespace AZ diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/EditorMeshStats.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/EditorMeshStats.cpp new file mode 100644 index 0000000000..4fa4364569 --- /dev/null +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/EditorMeshStats.cpp @@ -0,0 +1,58 @@ +/* +* 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 +#include +#include +#include + +namespace AZ +{ + namespace Render + { + void EditorMeshStats::Reflect(ReflectContext* context) + { + if (AZ::SerializeContext* serializeContext = azrtti_cast(context)) + { + serializeContext->Class() + ->Field("stringRepresentation", &EditorMeshStats::m_stringRepresentation) + ; + + if (AZ::EditContext* editContext = serializeContext->GetEditContext()) + { + editContext->Class( + "EditorMeshStats", "") + ->ClassElement(AZ::Edit::ClassElements::EditorData, "") + ->Attribute(AZ::Edit::Attributes::AutoExpand, false) + ->DataElement(AZ::Edit::UIHandlers::MultiLineEdit, &EditorMeshStats::m_stringRepresentation, "Mesh Stats", "") + ->Attribute(AZ::Edit::Attributes::NameLabelOverride, "") + ->Attribute(AZ::Edit::Attributes::ReadOnly, true) + ; + } + } + } + + void EditorMeshStats::UpdateStringRepresentation() + { + m_stringRepresentation = ""; + int lodIndex = 0; + for (auto& meshStatsForLod : m_meshStatsForLod) + { + m_stringRepresentation += AZStd::string::format("LOD: %d:\n", lodIndex++); + m_stringRepresentation += AZStd::string::format("\tMesh Count: %d\n", meshStatsForLod.m_meshCount); + m_stringRepresentation += AZStd::string::format("\tVert Count: %d\n", meshStatsForLod.m_vertCount); + m_stringRepresentation += AZStd::string::format("\tTriangle Count: %d\n", meshStatsForLod.m_triCount); + } + AZ::StringFunc::TrimWhiteSpace(m_stringRepresentation, true, true); + }; + } // namespace Render +} // namespace AZ diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/EditorMeshStats.h b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/EditorMeshStats.h new file mode 100644 index 0000000000..baf422d984 --- /dev/null +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/EditorMeshStats.h @@ -0,0 +1,49 @@ +/* +* 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 +#include +#include +#include + +namespace AZ +{ + namespace Render + { + struct EditorMeshStatsForLod final + { + AZ_RTTI(EditorMeshStatsForLod, "{626E3AEB-0F7A-4777-BAF1-2BBA8C1857ED}"); + AZ_CLASS_ALLOCATOR(EditorMeshStatsForLod, SystemAllocator, 0); + + + int m_meshCount = 0; + int m_vertCount = 0; + int m_triCount = 0; + }; + + struct EditorMeshStats final + { + AZ_RTTI(EditorMeshStats, "{68D0D3EF-17BB-46EA-B98F-51355402CCD6}"); + AZ_CLASS_ALLOCATOR(EditorMeshStats, SystemAllocator, 0); + + static void Reflect(ReflectContext* context); + + AZStd::vector m_meshStatsForLod; + + void UpdateStringRepresentation(); + + AZStd::string m_stringRepresentation = {}; + }; + } // namespace Render +} // namespace AZ diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/MeshComponentController.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/MeshComponentController.cpp index e7eecd3c7f..6c9b4e6514 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/MeshComponentController.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/MeshComponentController.cpp @@ -49,7 +49,7 @@ namespace AZ } } - bool MeshComponentConfig::IsAssetSet() + bool MeshComponentConfig::IsAssetSet() const { return m_modelAsset.GetId().IsValid(); } diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/MeshComponentController.h b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/MeshComponentController.h index 4d63e5e88d..e44fad07df 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/MeshComponentController.h +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/MeshComponentController.h @@ -44,7 +44,7 @@ namespace AZ static void Reflect(AZ::ReflectContext* context); // Editor helper functions - bool IsAssetSet(); + bool IsAssetSet() const; AZStd::vector> GetLodOverrideValues(); Data::Asset m_modelAsset = { AZ::Data::AssetLoadBehavior::QueueLoad }; diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/atomlyintegration_commonfeatures_editor_files.cmake b/Gems/AtomLyIntegration/CommonFeatures/Code/atomlyintegration_commonfeatures_editor_files.cmake index 9072cd54f2..6c45015e39 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/atomlyintegration_commonfeatures_editor_files.cmake +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/atomlyintegration_commonfeatures_editor_files.cmake @@ -50,6 +50,8 @@ set(FILES Source/Material/MaterialThumbnail.h Source/Mesh/EditorMeshComponent.h Source/Mesh/EditorMeshComponent.cpp + Source/Mesh/EditorMeshStats.h + Source/Mesh/EditorMeshStats.cpp Source/Mesh/EditorMeshSystemComponent.cpp Source/Mesh/EditorMeshSystemComponent.h Source/Mesh/MeshThumbnail.h