From c79bf7a0c187459c94a4acf5bd0a6d41fe76ca3b Mon Sep 17 00:00:00 2001 From: rhhong Date: Sat, 30 Oct 2021 22:37:05 -0700 Subject: [PATCH] load render option in atom render plugin and use render actor settings in atom debug draw Signed-off-by: rhhong --- .../Code/Source/AtomActorDebugDraw.cpp | 83 ++++++++++--------- .../Code/Source/AtomActorDebugDraw.h | 7 +- .../Tools/EMStudio/AnimViewportRenderer.cpp | 19 ++--- .../Tools/EMStudio/AnimViewportRenderer.h | 5 +- .../Tools/EMStudio/AnimViewportWidget.cpp | 12 ++- .../Code/Tools/EMStudio/AnimViewportWidget.h | 6 +- .../Code/Tools/EMStudio/AtomRenderPlugin.cpp | 27 +++++- .../Code/Tools/EMStudio/AtomRenderPlugin.h | 12 ++- .../EMotionFX/Source/EMotionFXManager.cpp | 10 +++ .../Code/EMotionFX/Source/EMotionFXManager.h | 22 +++++ .../Source/RenderPlugin/RenderOptions.cpp | 24 +++++- .../Source/RenderPlugin/RenderOptions.h | 8 ++ .../Rendering/RenderActorSettings.h | 34 ++++++++ .../Code/emotionfx_shared_files.cmake | 1 + 14 files changed, 203 insertions(+), 67 deletions(-) create mode 100644 Gems/EMotionFX/Code/Source/Integration/Rendering/RenderActorSettings.h diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorDebugDraw.cpp b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorDebugDraw.cpp index 1325455cd9..4b06fc5753 100644 --- a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorDebugDraw.cpp +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorDebugDraw.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -70,6 +71,7 @@ namespace AZ::Render const EMotionFX::Pose* pose = instance->GetTransformData()->GetCurrentPose(); const size_t geomLODLevel = instance->GetLODLevel(); const size_t numEnabled = instance->GetNumEnabledNodes(); + const float scaleMultiplier = CalculateScaleMultiplier(instance); for (size_t i = 0; i < numEnabled; ++i) { EMotionFX::Node* node = instance->GetActor()->GetSkeleton()->GetNode(instance->GetEnabledNode(i)); @@ -83,19 +85,27 @@ namespace AZ::Render continue; } - RenderNormals(mesh, globalTM, renderVertexNormals, renderFaceNormals); + RenderNormals(mesh, globalTM, renderVertexNormals, renderFaceNormals, scaleMultiplier); if (renderTangents) { - RenderTangents(mesh, globalTM); + RenderTangents(mesh, globalTM, scaleMultiplier); } if (renderWireframe) { - RenderWireframe(mesh, globalTM); + RenderWireframe(mesh, globalTM, scaleMultiplier); } } } } + float AtomActorDebugDraw::CalculateScaleMultiplier(EMotionFX::ActorInstance* instance) const + { + const AZ::Aabb aabb = instance->GetAabb(); + const float aabbRadius = AZ::Vector3(aabb.GetMax() - aabb.GetMin()).GetLength() * 0.5f; + // Scale the multiplier down to 1% of the character size, that looks pretty nice on all models + return aabbRadius * 0.01f; + } + void AtomActorDebugDraw::PrepareForMesh(EMotionFX::Mesh* mesh, const AZ::Transform& worldTM) { // Check if we have already prepared for the given mesh @@ -128,7 +138,8 @@ namespace AZ::Render { RPI::AuxGeomDrawPtr auxGeom = m_auxGeomFeatureProcessor->GetDrawQueue(); const AZ::Aabb& aabb = instance->GetAabb(); - auxGeom->DrawAabb(aabb, AZ::Color(0.0f, 1.0f, 1.0f, 1.0f), RPI::AuxGeomDraw::DrawStyle::Line); + const AZ::Render::RenderActorSettings& renderActorSettings = EMotionFX::GetRenderActorSettings(); + auxGeom->DrawAabb(aabb, renderActorSettings.m_staticAABBColor, RPI::AuxGeomDraw::DrawStyle::Line); } void AtomActorDebugDraw::RenderSkeleton(EMotionFX::ActorInstance* instance) @@ -166,11 +177,11 @@ namespace AZ::Render m_auxVertices.emplace_back(bonePos); } - const AZ::Color skeletonColor(0.604f, 0.804f, 0.196f, 1.0f); + const AZ::Render::RenderActorSettings& renderActorSettings = EMotionFX::GetRenderActorSettings(); RPI::AuxGeomDraw::AuxGeomDynamicDrawArguments lineArgs; lineArgs.m_verts = m_auxVertices.data(); lineArgs.m_vertCount = static_cast(m_auxVertices.size()); - lineArgs.m_colors = &skeletonColor; + lineArgs.m_colors = &renderActorSettings.m_lineSkeletonColor; lineArgs.m_colorCount = 1; lineArgs.m_depthTest = RPI::AuxGeomDraw::DepthTest::Off; auxGeom->DrawLines(lineArgs); @@ -218,7 +229,7 @@ namespace AZ::Render auxGeom->DrawLines(lineArgs); } - void AtomActorDebugDraw::RenderNormals(EMotionFX::Mesh* mesh, const AZ::Transform& worldTM, bool vertexNormals, bool faceNormals) + void AtomActorDebugDraw::RenderNormals(EMotionFX::Mesh* mesh, const AZ::Transform& worldTM, bool vertexNormals, bool faceNormals, float scaleMultiplier) { if (!mesh) { @@ -236,11 +247,7 @@ namespace AZ::Render return; } - // TODO: Move line color to a render setting. - const float faceNormalsScale = 0.01f; - const AZ::Color colorFaceNormals = AZ::Colors::Lime; - const float vertexNormalsScale = 0.01f; - const AZ::Color colorVertexNormals = AZ::Colors::Orange; + const AZ::Render::RenderActorSettings& renderActorSettings = EMotionFX::GetRenderActorSettings(); PrepareForMesh(mesh, worldTM); @@ -277,14 +284,14 @@ namespace AZ::Render const AZ::Vector3 normalPos = (posA + posB + posC) * (1.0f / 3.0f); m_auxVertices.emplace_back(normalPos); - m_auxVertices.emplace_back(normalPos + (normalDir * faceNormalsScale)); + m_auxVertices.emplace_back(normalPos + (normalDir * renderActorSettings.m_faceNormalsScale * scaleMultiplier)); } } RPI::AuxGeomDraw::AuxGeomDynamicDrawArguments lineArgs; lineArgs.m_verts = m_auxVertices.data(); lineArgs.m_vertCount = static_cast(m_auxVertices.size()); - lineArgs.m_colors = &colorFaceNormals; + lineArgs.m_colors = &renderActorSettings.m_faceNormalsColor; lineArgs.m_colorCount = 1; lineArgs.m_depthTest = RPI::AuxGeomDraw::DepthTest::Off; auxGeom->DrawLines(lineArgs); @@ -307,7 +314,8 @@ namespace AZ::Render { const uint32 vertexIndex = j + startVertex; const AZ::Vector3& position = m_worldSpacePositions[vertexIndex]; - const AZ::Vector3 normal = worldTM.TransformVector(normals[vertexIndex]).GetNormalizedSafe() * vertexNormalsScale; + const AZ::Vector3 normal = worldTM.TransformVector(normals[vertexIndex]).GetNormalizedSafe() * + renderActorSettings.m_vertexNormalsScale * scaleMultiplier; m_auxVertices.emplace_back(position); m_auxVertices.emplace_back(position + normal); @@ -317,14 +325,14 @@ namespace AZ::Render RPI::AuxGeomDraw::AuxGeomDynamicDrawArguments lineArgs; lineArgs.m_verts = m_auxVertices.data(); lineArgs.m_vertCount = static_cast(m_auxVertices.size()); - lineArgs.m_colors = &colorVertexNormals; + lineArgs.m_colors = &renderActorSettings.m_vertexNormalsColor; lineArgs.m_colorCount = 1; lineArgs.m_depthTest = RPI::AuxGeomDraw::DepthTest::Off; auxGeom->DrawLines(lineArgs); } } - void AtomActorDebugDraw::RenderTangents(EMotionFX::Mesh* mesh, const AZ::Transform& worldTM) + void AtomActorDebugDraw::RenderTangents(EMotionFX::Mesh* mesh, const AZ::Transform& worldTM, float scaleMultiplier) { if (!mesh) { @@ -337,11 +345,7 @@ namespace AZ::Render return; } - // TODO: Move line color to a render setting. - const AZ::Color colorTangents = AZ::Colors::Red; - const AZ::Color mirroredBitangentColor = AZ::Colors::Yellow; - const AZ::Color colorBitangents = AZ::Colors::White; - const float scale = 0.01f; + const AZ::Render::RenderActorSettings& renderActorSettings = EMotionFX::GetRenderActorSettings(); // Get the tangents and check if this mesh actually has tangents AZ::Vector4* tangents = static_cast(mesh->FindVertexData(EMotionFX::Mesh::ATTRIB_TANGENTS)); @@ -380,23 +384,23 @@ namespace AZ::Render bitangent = (worldTM.TransformVector(bitangent)).GetNormalizedSafe(); m_auxVertices.emplace_back(m_worldSpacePositions[i]); - m_auxColors.emplace_back(colorTangents); - m_auxVertices.emplace_back(m_worldSpacePositions[i] + (tangent * scale)); - m_auxColors.emplace_back(colorTangents); + m_auxColors.emplace_back(renderActorSettings.m_tangentsColor); + m_auxVertices.emplace_back(m_worldSpacePositions[i] + (tangent * renderActorSettings.m_tangentsScale * scaleMultiplier)); + m_auxColors.emplace_back(renderActorSettings.m_tangentsColor); if (tangents[i].GetW() < 0.0f) { m_auxVertices.emplace_back(m_worldSpacePositions[i]); - m_auxColors.emplace_back(mirroredBitangentColor); - m_auxVertices.emplace_back(m_worldSpacePositions[i] + (bitangent * scale)); - m_auxColors.emplace_back(mirroredBitangentColor); + m_auxColors.emplace_back(renderActorSettings.m_mirroredBitangentsColor); + m_auxVertices.emplace_back(m_worldSpacePositions[i] + (bitangent * renderActorSettings.m_tangentsScale * scaleMultiplier)); + m_auxColors.emplace_back(renderActorSettings.m_mirroredBitangentsColor); } else { m_auxVertices.emplace_back(m_worldSpacePositions[i]); - m_auxColors.emplace_back(colorBitangents); - m_auxVertices.emplace_back(m_worldSpacePositions[i] + (bitangent * scale)); - m_auxColors.emplace_back(colorBitangents); + m_auxColors.emplace_back(renderActorSettings.m_bitangentsColor); + m_auxVertices.emplace_back(m_worldSpacePositions[i] + (bitangent * renderActorSettings.m_tangentsScale * scaleMultiplier)); + m_auxColors.emplace_back(renderActorSettings.m_bitangentsColor); } } @@ -409,7 +413,7 @@ namespace AZ::Render auxGeom->DrawLines(lineArgs); } - void AtomActorDebugDraw::RenderWireframe(EMotionFX::Mesh* mesh, const AZ::Transform& worldTM) + void AtomActorDebugDraw::RenderWireframe(EMotionFX::Mesh* mesh, const AZ::Transform& worldTM, float scaleMultiplier) { // Check if the mesh is valid and skip the node in case it's not if (!mesh) @@ -423,12 +427,10 @@ namespace AZ::Render return; } + const AZ::Render::RenderActorSettings& renderActorSettings = EMotionFX::GetRenderActorSettings(); PrepareForMesh(mesh, worldTM); - const float scale = 0.01f; - const AZ::Vector3* normals = (AZ::Vector3*)mesh->FindVertexData(EMotionFX::Mesh::ATTRIB_NORMALS); - const AZ::Color vertexColor = AZ::Color(0.8f, 0.24f, 0.88f, 1.0f); const size_t numSubMeshes = mesh->GetNumSubMeshes(); for (uint32 subMeshIndex = 0; subMeshIndex < numSubMeshes; ++subMeshIndex) @@ -448,9 +450,12 @@ namespace AZ::Render const uint32 indexB = indices[triangleStartIndex + 1] + startVertex; const uint32 indexC = indices[triangleStartIndex + 2] + startVertex; - const AZ::Vector3 posA = m_worldSpacePositions[indexA] + normals[indexA] * scale; - const AZ::Vector3 posB = m_worldSpacePositions[indexB] + normals[indexB] * scale; - const AZ::Vector3 posC = m_worldSpacePositions[indexC] + normals[indexC] * scale; + const AZ::Vector3 posA = + m_worldSpacePositions[indexA] + normals[indexA] * renderActorSettings.m_wireframeScale * scaleMultiplier; + const AZ::Vector3 posB = + m_worldSpacePositions[indexB] + normals[indexB] * renderActorSettings.m_wireframeScale * scaleMultiplier; + const AZ::Vector3 posC = + m_worldSpacePositions[indexC] + normals[indexC] * renderActorSettings.m_wireframeScale * scaleMultiplier; m_auxVertices.emplace_back(posA); m_auxVertices.emplace_back(posB); @@ -465,7 +470,7 @@ namespace AZ::Render RPI::AuxGeomDraw::AuxGeomDynamicDrawArguments lineArgs; lineArgs.m_verts = m_auxVertices.data(); lineArgs.m_vertCount = static_cast(m_auxVertices.size()); - lineArgs.m_colors = &vertexColor; + lineArgs.m_colors = &renderActorSettings.m_wireframeColor; lineArgs.m_colorCount = 1; lineArgs.m_depthTest = RPI::AuxGeomDraw::DepthTest::Off; auxGeom->DrawLines(lineArgs); diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorDebugDraw.h b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorDebugDraw.h index 797de16351..f674ffbb96 100644 --- a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorDebugDraw.h +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorDebugDraw.h @@ -37,13 +37,14 @@ namespace AZ::Render private: + float CalculateScaleMultiplier(EMotionFX::ActorInstance* instance) const; void PrepareForMesh(EMotionFX::Mesh* mesh, const AZ::Transform& worldTM); void RenderAABB(EMotionFX::ActorInstance* instance); void RenderSkeleton(EMotionFX::ActorInstance* instance); void RenderEMFXDebugDraw(EMotionFX::ActorInstance* instance); - void RenderNormals(EMotionFX::Mesh* mesh, const AZ::Transform& worldTM, bool vertexNormals, bool faceNormals); - void RenderTangents(EMotionFX::Mesh* mesh, const AZ::Transform& worldTM); - void RenderWireframe(EMotionFX::Mesh* mesh, const AZ::Transform& worldTM); + void RenderNormals(EMotionFX::Mesh* mesh, const AZ::Transform& worldTM, bool vertexNormals, bool faceNormals, float scaleMultiplier); + void RenderTangents(EMotionFX::Mesh* mesh, const AZ::Transform& worldTM, float scaleMultiplier); + void RenderWireframe(EMotionFX::Mesh* mesh, const AZ::Transform& worldTM, float scaleMultiplier); EMotionFX::Mesh* m_currentMesh = nullptr; /**< A pointer to the mesh whose world space positions are in the pre-calculated positions buffer. NULL in case we haven't pre-calculated any positions yet. */ diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportRenderer.cpp b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportRenderer.cpp index facf7a7b12..1afae0e17b 100644 --- a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportRenderer.cpp +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportRenderer.cpp @@ -37,14 +37,13 @@ #include #include #include - +#include namespace EMStudio { - static constexpr float DepthNear = 0.01f; - - AnimViewportRenderer::AnimViewportRenderer(AZ::RPI::ViewportContextPtr viewportContext) + AnimViewportRenderer::AnimViewportRenderer(AZ::RPI::ViewportContextPtr viewportContext, const RenderOptions* renderOptions) : m_windowContext(viewportContext->GetWindowContext()) + , m_renderOptions(renderOptions) { // Create a new entity context m_entityContext = AZStd::make_unique(); @@ -128,10 +127,10 @@ namespace EMStudio AZ_Assert(m_gridEntity != nullptr, "Failed to create grid entity."); AZ::Render::GridComponentConfig gridConfig; - gridConfig.m_gridSize = 20.0f; - gridConfig.m_axisColor = AZ::Color(0.5f, 0.5f, 0.5f, 1.0f); - gridConfig.m_primaryColor = AZ::Color(0.3f, 0.3f, 0.3f, 1.0f); - gridConfig.m_secondaryColor = AZ::Color(0.5f, 0.5f, 0.5f, 1.0f); + gridConfig.m_secondarySpacing = m_renderOptions->GetGridUnitSize(); + gridConfig.m_axisColor = m_renderOptions->GetMainAxisColor(); + gridConfig.m_primaryColor = m_renderOptions->GetGridColor(); + gridConfig.m_secondaryColor = m_renderOptions->GetSubStepColor(); auto gridComponent = m_gridEntity->CreateComponent(AZ::Render::GridComponentTypeId); gridComponent->SetConfiguration(gridConfig); @@ -326,8 +325,8 @@ namespace EMStudio ->GetOrCreateExposureControlSettingsInterface(); Camera::Configuration cameraConfig; - cameraConfig.m_fovRadians = AZ::Constants::HalfPi; - cameraConfig.m_nearClipDistance = DepthNear; + cameraConfig.m_fovRadians = AZ::DegToRad(m_renderOptions->GetFOV()); + cameraConfig.m_nearClipDistance = m_renderOptions->GetNearClipPlaneDistance(); preset->ApplyLightingPreset( iblFeatureProcessor, m_skyboxFeatureProcessor, exposureControlSettingInterface, m_directionalLightFeatureProcessor, diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportRenderer.h b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportRenderer.h index a4f67ddfd1..df69856355 100644 --- a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportRenderer.h +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportRenderer.h @@ -39,12 +39,14 @@ namespace AZ namespace EMStudio { + class RenderOptions; + class AnimViewportRenderer { public: AZ_CLASS_ALLOCATOR(AnimViewportRenderer, AZ::SystemAllocator, 0); - AnimViewportRenderer(AZ::RPI::ViewportContextPtr viewportContext); + AnimViewportRenderer(AZ::RPI::ViewportContextPtr viewportContext, const RenderOptions* renderOptions); ~AnimViewportRenderer(); void Reinit(); @@ -83,6 +85,7 @@ namespace EMStudio AZ::Entity* m_iblEntity = nullptr; AZ::Entity* m_gridEntity = nullptr; AZStd::vector m_actorEntities; + const RenderOptions* m_renderOptions; AZStd::vector m_lightHandles; }; diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportWidget.cpp b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportWidget.cpp index c6e349236f..cf7341e9ab 100644 --- a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportWidget.cpp +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportWidget.cpp @@ -17,11 +17,13 @@ #include #include #include +#include namespace EMStudio { - AnimViewportWidget::AnimViewportWidget(QWidget* parent) - : AtomToolsFramework::RenderViewportWidget(parent) + AnimViewportWidget::AnimViewportWidget(AtomRenderPlugin* parentPlugin) + : AtomToolsFramework::RenderViewportWidget(parentPlugin->GetInnerWidget()) + , m_plugin(parentPlugin) { setObjectName(QString::fromUtf8("AtomViewportWidget")); QSizePolicy qSize(QSizePolicy::Preferred, QSizePolicy::Preferred); @@ -32,7 +34,7 @@ namespace EMStudio setAutoFillBackground(false); setStyleSheet(QString::fromUtf8("")); - m_renderer = AZStd::make_unique(GetViewportContext()); + m_renderer = AZStd::make_unique(GetViewportContext(), m_plugin->GetRenderOptions()); LoadRenderFlags(); SetupCameras(); @@ -181,8 +183,10 @@ namespace EMStudio const float height = AZStd::max(aznumeric_cast(windowSize.m_height), 1.0f); const float aspectRatio = aznumeric_cast(windowSize.m_width) / height; + const RenderOptions* renderOptions = m_plugin->GetRenderOptions(); AZ::Matrix4x4 viewToClipMatrix; - AZ::MakePerspectiveFovMatrixRH(viewToClipMatrix, AZ::Constants::HalfPi, aspectRatio, DepthNear, DepthFar, true); + AZ::MakePerspectiveFovMatrixRH(viewToClipMatrix, AZ::DegToRad(renderOptions->GetFOV()), aspectRatio, + renderOptions->GetNearClipPlaneDistance(), renderOptions->GetFarClipPlaneDistance(), true); viewportContext->GetDefaultView()->SetViewToClipMatrix(viewToClipMatrix); } diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportWidget.h b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportWidget.h index e2099ea2ab..7a8ae2cf52 100644 --- a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportWidget.h +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportWidget.h @@ -15,6 +15,7 @@ namespace EMStudio { + class AtomRenderPlugin; class AnimViewportRenderer; class AnimViewportWidget @@ -22,7 +23,7 @@ namespace EMStudio , private AnimViewportRequestBus::Handler { public: - AnimViewportWidget(QWidget* parent = nullptr); + AnimViewportWidget(AtomRenderPlugin* parentPlugin); ~AnimViewportWidget() override; AnimViewportRenderer* GetAnimViewportRenderer() { return m_renderer.get(); } @@ -45,9 +46,8 @@ namespace EMStudio void ToggleRenderFlag(EMotionFX::ActorRenderFlag flag); static constexpr float CameraDistance = 2.0f; - static constexpr float DepthNear = 0.01f; - static constexpr float DepthFar = 100.0f; + AtomRenderPlugin* m_plugin; AZStd::unique_ptr m_renderer; AZStd::shared_ptr m_rotateCamera; AZStd::shared_ptr m_translateCamera; diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AtomRenderPlugin.cpp b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AtomRenderPlugin.cpp index ce2e76a6c7..297bfea760 100644 --- a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AtomRenderPlugin.cpp +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AtomRenderPlugin.cpp @@ -27,7 +27,10 @@ namespace EMStudio AtomRenderPlugin::~AtomRenderPlugin() { - + GetCommandManager()->RemoveCommandCallback(m_importActorCallback, false); + GetCommandManager()->RemoveCommandCallback(m_removeActorCallback, false); + delete m_importActorCallback; + delete m_removeActorCallback; } const char* AtomRenderPlugin::GetName() const @@ -75,6 +78,11 @@ namespace EMStudio return EMStudioPlugin::PLUGINTYPE_RENDERING; } + QWidget* AtomRenderPlugin::GetInnerWidget() + { + return m_innerWidget; + } + void AtomRenderPlugin::ReinitRenderer() { m_animViewportWidget->Reinit(); @@ -82,6 +90,8 @@ namespace EMStudio bool AtomRenderPlugin::Init() { + LoadRenderOptions(); + m_innerWidget = new QWidget(); m_dock->setWidget(m_innerWidget); @@ -91,7 +101,7 @@ namespace EMStudio verticalLayout->setMargin(0); // Add the viewport widget - m_animViewportWidget = new AnimViewportWidget(m_innerWidget); + m_animViewportWidget = new AnimViewportWidget(this); // Add the tool bar AnimViewportToolBar* toolBar = new AnimViewportToolBar(m_innerWidget); @@ -109,6 +119,19 @@ namespace EMStudio return true; } + void AtomRenderPlugin::LoadRenderOptions() + { + AZStd::string renderOptionsFilename(GetManager()->GetAppDataFolder()); + renderOptionsFilename += "EMStudioRenderOptions.cfg"; + QSettings settings(renderOptionsFilename.c_str(), QSettings::IniFormat, this); + m_renderOptions = RenderOptions::Load(&settings); + } + + const RenderOptions* AtomRenderPlugin::GetRenderOptions() const + { + return &m_renderOptions; + } + // Command callbacks bool ReinitAtomRenderPlugin() { diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AtomRenderPlugin.h b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AtomRenderPlugin.h index 1516b45e77..d87e039487 100644 --- a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AtomRenderPlugin.h +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AtomRenderPlugin.h @@ -11,6 +11,7 @@ #if !defined(Q_MOC_RUN) #include #include +#include #include #include @@ -47,15 +48,22 @@ namespace EMStudio bool Init() override; EMStudioPlugin* Clone(); EMStudioPlugin::EPluginType GetPluginType() const override; + QWidget* GetInnerWidget(); void ReinitRenderer(); + void LoadRenderOptions(); + const RenderOptions* GetRenderOptions() const; + private: + + QWidget* m_innerWidget = nullptr; + AnimViewportWidget* m_animViewportWidget = nullptr; + RenderOptions m_renderOptions; + MCORE_DEFINECOMMANDCALLBACK(ImportActorCallback); MCORE_DEFINECOMMANDCALLBACK(RemoveActorCallback); ImportActorCallback* m_importActorCallback = nullptr; RemoveActorCallback* m_removeActorCallback = nullptr; - QWidget* m_innerWidget = nullptr; - AnimViewportWidget* m_animViewportWidget = nullptr; }; }// namespace EMStudio diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/EMotionFXManager.cpp b/Gems/EMotionFX/Code/EMotionFX/Source/EMotionFXManager.cpp index d5fa3867e0..af041fd316 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/EMotionFXManager.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Source/EMotionFXManager.cpp @@ -29,6 +29,7 @@ #include #include #include +#include namespace EMotionFX { @@ -75,6 +76,7 @@ namespace EMotionFX gEMFX.Get()->SetRecorder (Recorder::Create()); gEMFX.Get()->SetMotionInstancePool (MotionInstancePool::Create()); gEMFX.Get()->SetDebugDraw (aznew DebugDraw()); + gEMFX.Get()->SetRenderActorSettings (new AZ::Render::RenderActorSettings()); gEMFX.Get()->SetGlobalSimulationSpeed (1.0f); // set the number of threads @@ -123,6 +125,7 @@ namespace EMotionFX m_recorder = nullptr; m_motionInstancePool = nullptr; m_debugDraw = nullptr; + m_renderActorSettings = nullptr; m_unitType = MCore::Distance::UNITTYPE_METERS; m_globalSimulationSpeed = 1.0f; m_isInEditorMode = false; @@ -167,6 +170,8 @@ namespace EMotionFX delete m_debugDraw; m_debugDraw = nullptr; + delete m_renderActorSettings; + m_renderActorSettings = nullptr; m_eventManager->Destroy(); m_eventManager = nullptr; @@ -311,6 +316,11 @@ namespace EMotionFX m_debugDraw = draw; } + void EMotionFXManager::SetRenderActorSettings(AZ::Render::RenderActorSettings* settings) + { + m_renderActorSettings = settings; + } + // set the motion instance pool void EMotionFXManager::SetMotionInstancePool(MotionInstancePool* pool) { diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/EMotionFXManager.h b/Gems/EMotionFX/Code/EMotionFX/Source/EMotionFXManager.h index d5c5247de6..41b57cb2d8 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/EMotionFXManager.h +++ b/Gems/EMotionFX/Code/EMotionFX/Source/EMotionFXManager.h @@ -19,6 +19,10 @@ MCORE_FORWARD_DECLARE(MemoryTracker); +namespace AZ::Render +{ + class RenderActorSettings; +} namespace EMotionFX { @@ -184,6 +188,15 @@ namespace EMotionFX */ MCORE_INLINE DebugDraw* GetDebugDraw() const { return m_debugDraw; } + /** + * Get the render actor settings + * @result A pointer to global render actor settings. + */ + MCORE_INLINE AZ::Render::RenderActorSettings* GetRenderActorSettings() const + { + return m_renderActorSettings; + } + /** * Set the path of the media root directory. * @param path The path of the media root folder. @@ -347,6 +360,8 @@ namespace EMotionFX Recorder* m_recorder; /**< The recorder. */ MotionInstancePool* m_motionInstancePool; /**< The motion instance pool. */ DebugDraw* m_debugDraw; /**< The debug drawing system. */ + AZ::Render::RenderActorSettings* m_renderActorSettings; /**< The global render actor settings. */ + AZStd::vector m_threadDatas; /**< The per thread data. */ MCore::Distance::EUnitType m_unitType; /**< The unit type, on default it is MCore::Distance::UNITTYPE_METERS. */ float m_globalSimulationSpeed; /**< The global simulation speed, default is 1.0. */ @@ -412,6 +427,12 @@ namespace EMotionFX */ void SetDebugDraw(DebugDraw* draw); + /** + * Set the render actor settings. + * @param settings The render actor settings. + */ + void SetRenderActorSettings(AZ::Render::RenderActorSettings* settings); + /** * Set the motion instance pool. * @param pool The motion instance pool. @@ -505,4 +526,5 @@ namespace EMotionFX MCORE_INLINE Recorder& GetRecorder() { return *GetEMotionFX().GetRecorder(); } /**< Get the recorder. */ MCORE_INLINE MotionInstancePool& GetMotionInstancePool() { return *GetEMotionFX().GetMotionInstancePool(); } /**< Get the motion instance pool. */ MCORE_INLINE DebugDraw& GetDebugDraw() { return *GetEMotionFX().GetDebugDraw(); } /**< Get the debug drawing. */ + MCORE_INLINE AZ::Render::RenderActorSettings& GetRenderActorSettings() { return *GetEMotionFX().GetRenderActorSettings(); }/**< Get the render actor settings. */ } // namespace EMotionFX diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderOptions.cpp b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderOptions.cpp index af2cb2c8e8..46c3703949 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderOptions.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderOptions.cpp @@ -12,9 +12,7 @@ #include #include #include -#include -#include -#include +#include #include #include @@ -318,6 +316,9 @@ namespace EMStudio options.m_manipulatorMode = static_cast(settings->value("manipulatorMode", options.m_manipulatorMode).toInt()); + AZ::Render::RenderActorSettings& renderActorSettings = EMotionFX::GetRenderActorSettings(); + options.CopyToRenderActorSettings(renderActorSettings); + return options; } @@ -1057,6 +1058,23 @@ namespace EMStudio return m_manipulatorMode; } + void RenderOptions::CopyToRenderActorSettings(AZ::Render::RenderActorSettings& settings) const + { + settings.m_vertexNormalsScale = m_vertexNormalsScale; + settings.m_faceNormalsScale = m_faceNormalsScale; + settings.m_tangentsScale = m_tangentsScale; + + settings.m_vertexNormalsColor = m_vertexNormalsColor; + settings.m_faceNormalsColor = m_faceNormalsColor; + settings.m_tangentsColor = m_tangentsColor; + settings.m_mirroredBitangentsColor = m_mirroredBitangentsColor; + settings.m_bitangentsColor = m_bitangentsColor; + settings.m_wireframeColor = m_wireframeColor; + settings.m_staticAABBColor = m_staticAABBColor; + settings.m_skeletonColor = m_skeletonColor; + settings.m_lineSkeletonColor = m_lineSkeletonColor; + } + void RenderOptions::OnGridUnitSizeChangedCallback() const { PluginOptionsNotificationsBus::Event(s_gridUnitSizeOptionName, &PluginOptionsNotificationsBus::Events::OnOptionChanged, s_gridUnitSizeOptionName); diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderOptions.h b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderOptions.h index f146f62215..20d521813d 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderOptions.h +++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderOptions.h @@ -18,6 +18,11 @@ QT_FORWARD_DECLARE_CLASS(QSettings); +namespace AZ::Render +{ + class RenderActorSettings; +} + namespace EMStudio { class EMSTUDIO_API RenderOptions @@ -314,6 +319,9 @@ namespace EMStudio void OnLastUsedLayoutChangedCallback() const; void OnRenderSelectionBoxChangedCallback() const; + // Copy render actor related settings to the global settings in emfx. + void CopyToRenderActorSettings(AZ::Render::RenderActorSettings& settings) const; + // Maintain the order between here and the reflect method. // The order in the SerializeContext defines the order it is shown in the UI float m_gridUnitSize; diff --git a/Gems/EMotionFX/Code/Source/Integration/Rendering/RenderActorSettings.h b/Gems/EMotionFX/Code/Source/Integration/Rendering/RenderActorSettings.h new file mode 100644 index 0000000000..a23860bcb8 --- /dev/null +++ b/Gems/EMotionFX/Code/Source/Integration/Rendering/RenderActorSettings.h @@ -0,0 +1,34 @@ +/* + * 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 + * + */ +#pragma once + +#include + +namespace AZ::Render +{ + // RenderActorSettings is a subset of RenderOptions. The goal is eventually move those actor render related settings out of render options since + // it will be shared between main editor and animation editor. + class RenderActorSettings + { + public: + float m_vertexNormalsScale = 1.0f; + float m_faceNormalsScale = 1.0f; + float m_tangentsScale = 1.0f; + float m_wireframeScale = 1.0f; + + AZ::Color m_vertexNormalsColor{ 0.0f, 1.0f, 0.0f, 1.0f }; + AZ::Color m_faceNormalsColor{ 0.5f, 0.5f, 1.0f, 1.0f }; + AZ::Color m_tangentsColor{ 1.0f, 0.0f, 0.0f, 1.0f }; + AZ::Color m_mirroredBitangentsColor{ 1.0f, 1.0f, 0.0f, 1.0f }; + AZ::Color m_bitangentsColor{ 1.0f, 1.0f, 1.0f, 1.0f }; + AZ::Color m_wireframeColor{ 0.0f, 0.0f, 0.0f, 1.0f }; + AZ::Color m_staticAABBColor{ 0.0f, 0.7f, 0.7f, 1.0f }; + AZ::Color m_lineSkeletonColor{ 0.33333f, 1.0f, 0.0f, 1.0f }; + AZ::Color m_skeletonColor{ 0.19f, 0.58f, 0.19f, 1.0f }; + }; +} // namespace AZ::Render diff --git a/Gems/EMotionFX/Code/emotionfx_shared_files.cmake b/Gems/EMotionFX/Code/emotionfx_shared_files.cmake index b45f15a5be..26b51f280b 100644 --- a/Gems/EMotionFX/Code/emotionfx_shared_files.cmake +++ b/Gems/EMotionFX/Code/emotionfx_shared_files.cmake @@ -42,4 +42,5 @@ set(FILES Source/Integration/Rendering/RenderActorInstance.cpp Source/Integration/Rendering/RenderBackendManager.h Source/Integration/Rendering/RenderBackendManager.cpp + Source/Integration/Rendering/RenderActorSettings.h )