Render Colliders (#5434)
* Render Colliders Signed-off-by: rhhong <rhhong@amazon.com> * CR feedback Signed-off-by: rhhong <rhhong@amazon.com>
This commit is contained in:
@@ -137,6 +137,18 @@ namespace AtomToolsFramework
|
||||
m_viewportContext->SetRenderScene(nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the scene already has an atom scene attached. In this case we don't need to create a new atom scene.
|
||||
if (auto existingScene = scene->FindSubsystem<AZ::RPI::ScenePtr>())
|
||||
{
|
||||
m_viewportContext->SetRenderScene(*existingScene);
|
||||
if (auto auxGeomFP = existingScene->get()->GetFeatureProcessor<AZ::RPI::AuxGeomFeatureProcessorInterface>())
|
||||
{
|
||||
m_auxGeom = auxGeomFP->GetOrCreateDrawQueueForView(m_defaultCamera.get());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
AZ::RPI::ScenePtr atomScene;
|
||||
auto initializeScene = [&](AZ::Render::Bootstrap::Request* bootstrapRequests)
|
||||
{
|
||||
|
||||
@@ -24,8 +24,6 @@
|
||||
|
||||
#include <AtomLyIntegration/CommonFeatures/Material/MaterialComponentConstants.h>
|
||||
#include <AtomLyIntegration/CommonFeatures/Material/MaterialComponentBus.h>
|
||||
#include <AtomLyIntegration/CommonFeatures/Grid/GridComponentConstants.h>
|
||||
#include <AtomLyIntegration/CommonFeatures/Grid/GridComponentConfig.h>
|
||||
#include <AtomLyIntegration/CommonFeatures/Mesh/MeshComponentConstants.h>
|
||||
#include <AtomLyIntegration/CommonFeatures/Mesh/MeshComponentBus.h>
|
||||
#include <AtomLyIntegration/CommonFeatures/PostProcess/PostFxLayerComponentConstants.h>
|
||||
@@ -122,22 +120,15 @@ namespace EMStudio
|
||||
const AZ::Render::LightingPreset* preset = lightingPresetAsset->GetDataAs<AZ::Render::LightingPreset>();
|
||||
SetLightingPreset(preset);
|
||||
|
||||
// Create grid
|
||||
// Create the ground plane
|
||||
AzFramework::EntityContextRequestBus::EventResult(
|
||||
m_gridEntity, entityContextId, &AzFramework::EntityContextRequestBus::Events::CreateEntity, "ViewportGrid");
|
||||
AZ_Assert(m_gridEntity != nullptr, "Failed to create grid entity.");
|
||||
m_groundEntity, entityContextId, &AzFramework::EntityContextRequestBus::Events::CreateEntity, "ViewportModel");
|
||||
AZ_Assert(m_groundEntity != nullptr, "Failed to create model entity.");
|
||||
|
||||
AZ::Render::GridComponentConfig gridConfig;
|
||||
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);
|
||||
|
||||
m_gridEntity->CreateComponent(azrtti_typeid<AzFramework::TransformComponent>());
|
||||
m_gridEntity->Init();
|
||||
m_gridEntity->Activate();
|
||||
m_groundEntity->CreateComponent(AZ::Render::MeshComponentTypeId);
|
||||
m_groundEntity->CreateComponent(AZ::Render::MaterialComponentTypeId);
|
||||
m_groundEntity->CreateComponent(azrtti_typeid<AzFramework::TransformComponent>());
|
||||
m_groundEntity->Activate();
|
||||
|
||||
Reinit();
|
||||
}
|
||||
@@ -147,7 +138,7 @@ namespace EMStudio
|
||||
// Destroy all the entity we created.
|
||||
m_entityContext->DestroyEntity(m_iblEntity);
|
||||
m_entityContext->DestroyEntity(m_postProcessEntity);
|
||||
m_entityContext->DestroyEntity(m_gridEntity);
|
||||
m_entityContext->DestroyEntity(m_groundEntity);
|
||||
for (AZ::Entity* entity : m_actorEntities)
|
||||
{
|
||||
m_entityContext->DestroyEntity(entity);
|
||||
@@ -220,6 +211,11 @@ namespace EMStudio
|
||||
}
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<AzFramework::Scene> AnimViewportRenderer::GetFrameworkScene() const
|
||||
{
|
||||
return m_frameworkScene;
|
||||
}
|
||||
|
||||
void AnimViewportRenderer::ResetEnvironment()
|
||||
{
|
||||
// Reset environment
|
||||
@@ -229,6 +225,15 @@ namespace EMStudio
|
||||
const AZ::Matrix4x4 rotationMatrix = AZ::Matrix4x4::CreateIdentity();
|
||||
auto skyBoxFeatureProcessorInterface = m_scene->GetFeatureProcessor<AZ::Render::SkyBoxFeatureProcessorInterface>();
|
||||
skyBoxFeatureProcessorInterface->SetCubemapRotationMatrix(rotationMatrix);
|
||||
|
||||
// Reset ground entity
|
||||
AZ::Transform groundTransform = AZ::Transform::CreateIdentity();
|
||||
AZ::TransformBus::Event(m_groundEntity->GetId(), &AZ::TransformBus::Events::SetLocalTM, groundTransform);
|
||||
|
||||
auto modelAsset = AZ::RPI::AssetUtils::GetAssetByProductPath<AZ::RPI::ModelAsset>(
|
||||
"objects/groudplane/groundplane_512x512m.azmodel", AZ::RPI::AssetUtils::TraceLevel::Assert);
|
||||
AZ::Render::MeshComponentRequestBus::Event(
|
||||
m_groundEntity->GetId(), &AZ::Render::MeshComponentRequestBus::Events::SetModelAsset, modelAsset);
|
||||
}
|
||||
|
||||
void AnimViewportRenderer::ReinitActorEntities()
|
||||
|
||||
@@ -56,6 +56,8 @@ namespace EMStudio
|
||||
|
||||
void UpdateActorRenderFlag(EMotionFX::ActorRenderFlagBitset renderFlags);
|
||||
|
||||
AZStd::shared_ptr<AzFramework::Scene> GetFrameworkScene() const;
|
||||
|
||||
private:
|
||||
|
||||
// This function resets the light, camera and other environment settings.
|
||||
@@ -83,7 +85,7 @@ namespace EMStudio
|
||||
|
||||
AZ::Entity* m_postProcessEntity = nullptr;
|
||||
AZ::Entity* m_iblEntity = nullptr;
|
||||
AZ::Entity* m_gridEntity = nullptr;
|
||||
AZ::Entity* m_groundEntity = nullptr;
|
||||
AZStd::vector<AZ::Entity*> m_actorEntities;
|
||||
const RenderOptions* m_renderOptions;
|
||||
|
||||
|
||||
@@ -48,6 +48,12 @@ namespace EMStudio
|
||||
CreateViewOptionEntry(contextMenu, "Joint Orientations", EMotionFX::ActorRenderFlag::RENDER_NODEORIENTATION);
|
||||
CreateViewOptionEntry(contextMenu, "Actor Bind Pose", EMotionFX::ActorRenderFlag::RENDER_ACTORBINDPOSE);
|
||||
contextMenu->addSeparator();
|
||||
CreateViewOptionEntry(contextMenu, "Hit Detection Colliders", EMotionFX::ActorRenderFlag::RENDER_HITDETECTION_COLLIDERS);
|
||||
CreateViewOptionEntry(contextMenu, "Ragdoll Colliders", EMotionFX::ActorRenderFlag::RENDER_RAGDOLL_COLLIDERS);
|
||||
CreateViewOptionEntry(contextMenu, "Ragdoll Joint Limits", EMotionFX::ActorRenderFlag::RENDER_RAGDOLL_JOINTLIMITS);
|
||||
CreateViewOptionEntry(contextMenu, "Cloth Colliders", EMotionFX::ActorRenderFlag::RENDER_CLOTH_COLLIDERS);
|
||||
CreateViewOptionEntry(contextMenu, "Simulated Object Colliders", EMotionFX::ActorRenderFlag::RENDER_SIMULATEDOBJECT_COLLIDERS);
|
||||
CreateViewOptionEntry(contextMenu, "Simulated Joints", EMotionFX::ActorRenderFlag::RENDER_SIMULATEJOINTS);
|
||||
}
|
||||
|
||||
// Add the camera button
|
||||
|
||||
@@ -35,6 +35,7 @@ namespace EMStudio
|
||||
setStyleSheet(QString::fromUtf8(""));
|
||||
|
||||
m_renderer = AZStd::make_unique<AnimViewportRenderer>(GetViewportContext(), m_plugin->GetRenderOptions());
|
||||
SetScene(m_renderer->GetFrameworkScene(), false);
|
||||
|
||||
LoadRenderFlags();
|
||||
SetupCameras();
|
||||
@@ -42,11 +43,13 @@ namespace EMStudio
|
||||
Reinit();
|
||||
|
||||
AnimViewportRequestBus::Handler::BusConnect();
|
||||
ViewportPluginRequestBus::Handler::BusConnect();
|
||||
}
|
||||
|
||||
AnimViewportWidget::~AnimViewportWidget()
|
||||
{
|
||||
SaveRenderFlags();
|
||||
ViewportPluginRequestBus::Handler::BusDisconnect();
|
||||
AnimViewportRequestBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
@@ -173,6 +176,7 @@ namespace EMStudio
|
||||
{
|
||||
RenderViewportWidget::OnTick(deltaTime, time);
|
||||
CalculateCameraProjection();
|
||||
RenderCustomPluginData();
|
||||
}
|
||||
|
||||
void AnimViewportWidget::CalculateCameraProjection()
|
||||
@@ -191,6 +195,16 @@ namespace EMStudio
|
||||
viewportContext->GetDefaultView()->SetViewToClipMatrix(viewToClipMatrix);
|
||||
}
|
||||
|
||||
void AnimViewportWidget::RenderCustomPluginData()
|
||||
{
|
||||
const size_t numPlugins = GetPluginManager()->GetNumActivePlugins();
|
||||
for (size_t i = 0; i < numPlugins; ++i)
|
||||
{
|
||||
EMStudioPlugin* plugin = GetPluginManager()->GetActivePlugin(i);
|
||||
plugin->Render(m_renderFlags);
|
||||
}
|
||||
}
|
||||
|
||||
void AnimViewportWidget::ToggleRenderFlag(EMotionFX::ActorRenderFlag flag)
|
||||
{
|
||||
m_renderFlags[flag] = !m_renderFlags[flag];
|
||||
@@ -224,4 +238,9 @@ namespace EMStudio
|
||||
settings.setValue(name, (bool)m_renderFlags[i]);
|
||||
}
|
||||
}
|
||||
|
||||
AZ::s32 AnimViewportWidget::GetViewportId() const
|
||||
{
|
||||
return GetViewportContext()->GetId();
|
||||
}
|
||||
} // namespace EMStudio
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
#include <QSettings>
|
||||
#include <AtomToolsFramework/Viewport/RenderViewportWidget.h>
|
||||
#include <AzFramework/Viewport/CameraInput.h>
|
||||
|
||||
#include <EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/ViewportPluginBus.h>
|
||||
#include <EMStudio/AnimViewportRequestBus.h>
|
||||
#include <Integration/Rendering/RenderFlag.h>
|
||||
|
||||
@@ -21,6 +23,7 @@ namespace EMStudio
|
||||
class AnimViewportWidget
|
||||
: public AtomToolsFramework::RenderViewportWidget
|
||||
, private AnimViewportRequestBus::Handler
|
||||
, private ViewportPluginRequestBus::Handler
|
||||
{
|
||||
public:
|
||||
AnimViewportWidget(AtomRenderPlugin* parentPlugin);
|
||||
@@ -34,6 +37,8 @@ namespace EMStudio
|
||||
void OnTick(float deltaTime, AZ::ScriptTimePoint time) override;
|
||||
|
||||
void CalculateCameraProjection();
|
||||
void RenderCustomPluginData();
|
||||
|
||||
void SetupCameras();
|
||||
void SetupCameraController();
|
||||
|
||||
@@ -45,6 +50,9 @@ namespace EMStudio
|
||||
void SetCameraViewMode(CameraViewMode mode);
|
||||
void ToggleRenderFlag(EMotionFX::ActorRenderFlag flag);
|
||||
|
||||
// ViewportPluginRequestBus::Handler overrides
|
||||
AZ::s32 GetViewportId() const;
|
||||
|
||||
static constexpr float CameraDistance = 2.0f;
|
||||
|
||||
AtomRenderPlugin* m_plugin;
|
||||
|
||||
+10
-1
@@ -15,6 +15,7 @@
|
||||
#include <MCore/Source/MemoryFile.h>
|
||||
#include <EMotionFX/Rendering/Common/RenderUtil.h>
|
||||
#include <EMotionFX/Rendering/Common/Camera.h>
|
||||
#include <Integration/Rendering/RenderFlag.h>
|
||||
#include "EMStudioConfig.h"
|
||||
#include <QString>
|
||||
#include <QObject>
|
||||
@@ -92,7 +93,15 @@ namespace EMStudio
|
||||
uint32 m_screenHeight;
|
||||
};
|
||||
|
||||
virtual void Render(RenderPlugin* renderPlugin, RenderInfo* renderInfo) { MCORE_UNUSED(renderPlugin); MCORE_UNUSED(renderInfo); }
|
||||
//! Deprecated: LegacyRender will call EMotionFX::DebugDraw that tied to OpenGL render.
|
||||
//! It will be removed after OpenGLPlugin and GLWidget is gone.
|
||||
virtual void LegacyRender(RenderPlugin* renderPlugin, RenderInfo* renderInfo) { MCORE_UNUSED(renderPlugin); MCORE_UNUSED(renderInfo); }
|
||||
|
||||
//! Render function will call atom auxGeom internally to render. This is the replacement for LegacyRender function.
|
||||
virtual void Render(EMotionFX::ActorRenderFlagBitset renderFlags)
|
||||
{
|
||||
AZ_UNUSED(renderFlags);
|
||||
};
|
||||
|
||||
virtual PluginOptions* GetOptions() { return nullptr; }
|
||||
|
||||
|
||||
+10
@@ -1072,6 +1072,16 @@ namespace EMStudio
|
||||
settings.m_staticAABBColor = m_staticAABBColor;
|
||||
settings.m_skeletonColor = m_skeletonColor;
|
||||
settings.m_lineSkeletonColor = m_lineSkeletonColor;
|
||||
|
||||
settings.m_hitDetectionColliderColor = m_hitDetectionColliderColor;
|
||||
settings.m_selectedHitDetectionColliderColor = m_selectedHitDetectionColliderColor;
|
||||
settings.m_ragdollColliderColor = m_ragdollColliderColor;
|
||||
settings.m_selectedRagdollColliderColor = m_selectedRagdollColliderColor;
|
||||
settings.m_violatedJointLimitColor = m_violatedJointLimitColor;
|
||||
settings.m_clothColliderColor = m_clothColliderColor;
|
||||
settings.m_selectedClothColliderColor = m_selectedClothColliderColor;
|
||||
settings.m_simulatedObjectColliderColor = m_simulatedObjectColliderColor;
|
||||
settings.m_selectedSimulatedObjectColliderColor = m_selectedSimulatedObjectColliderColor;
|
||||
}
|
||||
|
||||
void RenderOptions::OnGridUnitSizeChangedCallback() const
|
||||
|
||||
+1
-1
@@ -1054,7 +1054,7 @@ namespace EMStudio
|
||||
EMStudioPlugin* plugin = GetPluginManager()->GetActivePlugin(i);
|
||||
EMStudioPlugin::RenderInfo renderInfo(renderUtil, m_camera, m_width, m_height);
|
||||
|
||||
plugin->Render(m_plugin, &renderInfo);
|
||||
plugin->LegacyRender(m_plugin, &renderInfo);
|
||||
}
|
||||
|
||||
RenderDebugDraw();
|
||||
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* 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 <AzCore/EBus/EBus.h>
|
||||
|
||||
namespace EMStudio
|
||||
{
|
||||
class ViewportPluginRequests
|
||||
: public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
virtual AZ::s32 GetViewportId() const = 0;
|
||||
};
|
||||
|
||||
using ViewportPluginRequestBus = AZ::EBus<ViewportPluginRequests>;
|
||||
}
|
||||
+1
-1
@@ -667,7 +667,7 @@ namespace EMStudio
|
||||
}
|
||||
|
||||
|
||||
void MotionWindowPlugin::Render(RenderPlugin* renderPlugin, EMStudioPlugin::RenderInfo* renderInfo)
|
||||
void MotionWindowPlugin::LegacyRender(RenderPlugin* renderPlugin, EMStudioPlugin::RenderInfo* renderInfo)
|
||||
{
|
||||
MCommon::RenderUtil* renderUtil = renderInfo->m_renderUtil;
|
||||
|
||||
|
||||
+1
-1
@@ -61,7 +61,7 @@ namespace EMStudio
|
||||
bool Init() override;
|
||||
EMStudioPlugin* Clone() override;
|
||||
|
||||
void Render(RenderPlugin* renderPlugin, EMStudioPlugin::RenderInfo* renderInfo) override;
|
||||
void LegacyRender(RenderPlugin* renderPlugin, EMStudioPlugin::RenderInfo* renderInfo) override;
|
||||
|
||||
void ReInit();
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/std/smart_ptr/make_shared.h>
|
||||
#include <AzFramework/Physics/ShapeConfiguration.h>
|
||||
#include <AzFramework/Entity/EntityDebugDisplayBus.h>
|
||||
#include <AzQtComponents/Components/Widgets/CardHeader.h>
|
||||
#include <EMotionFX/CommandSystem/Source/ColliderCommands.h>
|
||||
#include <EMotionFX/CommandSystem/Source/SimulatedObjectCommands.h>
|
||||
@@ -19,6 +20,7 @@
|
||||
#include <EMotionFX/Source/Node.h>
|
||||
#include <EMotionFX/Source/TransformData.h>
|
||||
#include <EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/EMStudioManager.h>
|
||||
#include <EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/ViewportPluginBus.h>
|
||||
#include <Editor/ColliderContainerWidget.h>
|
||||
#include <Editor/ColliderHelpers.h>
|
||||
#include <Editor/ObjectEditor.h>
|
||||
@@ -610,7 +612,7 @@ namespace EMotionFX
|
||||
return QWidget::sizeHint() + QSize(0, s_layoutSpacing);
|
||||
}
|
||||
|
||||
void ColliderContainerWidget::RenderColliders(const AzPhysics::ShapeColliderPairList& colliders,
|
||||
void ColliderContainerWidget::LegacyRenderColliders(const AzPhysics::ShapeColliderPairList& colliders,
|
||||
const ActorInstance* actorInstance,
|
||||
const Node* node,
|
||||
EMStudio::EMStudioPlugin::RenderInfo* renderInfo,
|
||||
@@ -630,7 +632,6 @@ namespace EMotionFX
|
||||
const Transform colliderOffsetTransform(collider.first->m_position, collider.first->m_rotation);
|
||||
const Transform& actorInstanceGlobalTransform = actorInstance->GetWorldSpaceTransform();
|
||||
const Transform& emfxNodeGlobalTransform = actorInstance->GetTransformData()->GetCurrentPose()->GetModelSpaceTransform(nodeIndex);
|
||||
|
||||
const Transform emfxColliderGlobalTransformNoScale = colliderOffsetTransform * emfxNodeGlobalTransform * actorInstanceGlobalTransform;
|
||||
|
||||
const AZ::TypeId colliderType = collider.second->RTTI_GetType();
|
||||
@@ -638,7 +639,7 @@ namespace EMotionFX
|
||||
{
|
||||
Physics::SphereShapeConfiguration* sphere = static_cast<Physics::SphereShapeConfiguration*>(collider.second.get());
|
||||
|
||||
// LY Physics scaling rules: The maximum component from the node scale will be multiplied by the radius of the sphere.
|
||||
// O3DE Physics scaling rules: The maximum component from the node scale will be multiplied by the radius of the sphere.
|
||||
const float radius = sphere->m_radius * MCore::Max3<float>(static_cast<float>(worldScale.GetX()), static_cast<float>(worldScale.GetY()), static_cast<float>(worldScale.GetZ()));
|
||||
|
||||
renderUtil->RenderWireframeSphere(radius, emfxColliderGlobalTransformNoScale.ToAZTransform(), colliderColor);
|
||||
@@ -647,7 +648,7 @@ namespace EMotionFX
|
||||
{
|
||||
Physics::CapsuleShapeConfiguration* capsule = static_cast<Physics::CapsuleShapeConfiguration*>(collider.second.get());
|
||||
|
||||
// LY Physics scaling rules: The maximum of the X/Y scale components of the node scale will be multiplied by the radius of the capsule. The Z component of the entity scale will be multiplied by the height of the capsule.
|
||||
// O3DE Physics scaling rules: The maximum of the X/Y scale components of the node scale will be multiplied by the radius of the capsule. The Z component of the entity scale will be multiplied by the height of the capsule.
|
||||
const float radius = capsule->m_radius * MCore::Max<float>(static_cast<float>(worldScale.GetX()), static_cast<float>(worldScale.GetY()));
|
||||
const float height = capsule->m_height * static_cast<float>(worldScale.GetZ());
|
||||
|
||||
@@ -657,7 +658,7 @@ namespace EMotionFX
|
||||
{
|
||||
Physics::BoxShapeConfiguration* box = static_cast<Physics::BoxShapeConfiguration*>(collider.second.get());
|
||||
|
||||
// LY Physics scaling rules: Each component of the box dimensions will be scaled by the node's world scale.
|
||||
// O3DE Physics scaling rules: Each component of the box dimensions will be scaled by the node's world scale.
|
||||
AZ::Vector3 dimensions = box->m_dimensions;
|
||||
dimensions *= worldScale;
|
||||
|
||||
@@ -666,7 +667,8 @@ namespace EMotionFX
|
||||
}
|
||||
}
|
||||
|
||||
void ColliderContainerWidget::RenderColliders(PhysicsSetup::ColliderConfigType colliderConfigType,
|
||||
void ColliderContainerWidget::LegacyRenderColliders(
|
||||
PhysicsSetup::ColliderConfigType colliderConfigType,
|
||||
const MCore::RGBAColor& defaultColor,
|
||||
const MCore::RGBAColor& selectedColor,
|
||||
EMStudio::RenderPlugin* renderPlugin,
|
||||
@@ -701,7 +703,7 @@ namespace EMotionFX
|
||||
{
|
||||
const bool jointSelected = selectedJointIndices.empty() || selectedJointIndices.find(joint->GetNodeIndex()) != selectedJointIndices.end();
|
||||
const AzPhysics::ShapeColliderPairList& colliders = nodeConfig.m_shapes;
|
||||
RenderColliders(colliders, actorInstance, joint, renderInfo, jointSelected ? selectedColor : defaultColor);
|
||||
LegacyRenderColliders(colliders, actorInstance, joint, renderInfo, jointSelected ? selectedColor : defaultColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -711,6 +713,121 @@ namespace EMotionFX
|
||||
renderUtil->EnableLighting(oldLightingEnabled);
|
||||
}
|
||||
|
||||
void ColliderContainerWidget::RenderColliders(
|
||||
const AzPhysics::ShapeColliderPairList& colliders,
|
||||
const ActorInstance* actorInstance,
|
||||
const Node* node,
|
||||
const AZ::Color& colliderColor)
|
||||
{
|
||||
const size_t nodeIndex = node->GetNodeIndex();
|
||||
|
||||
for (const auto& collider : colliders)
|
||||
{
|
||||
#ifndef EMFX_SCALE_DISABLED
|
||||
const AZ::Vector3& worldScale = actorInstance->GetTransformData()->GetCurrentPose()->GetModelSpaceTransform(nodeIndex).m_scale;
|
||||
#else
|
||||
const AZ::Vector3 worldScale = AZ::Vector3::CreateOne();
|
||||
#endif
|
||||
|
||||
const Transform colliderOffsetTransform(collider.first->m_position, collider.first->m_rotation);
|
||||
const Transform& actorInstanceGlobalTransform = actorInstance->GetWorldSpaceTransform();
|
||||
const Transform& emfxNodeGlobalTransform =
|
||||
actorInstance->GetTransformData()->GetCurrentPose()->GetModelSpaceTransform(nodeIndex);
|
||||
const Transform emfxColliderGlobalTransformNoScale =
|
||||
colliderOffsetTransform * emfxNodeGlobalTransform * actorInstanceGlobalTransform;
|
||||
|
||||
AZ::s32 viewportId = -1;
|
||||
EMStudio::ViewportPluginRequestBus::BroadcastResult(viewportId, &EMStudio::ViewportPluginRequestBus::Events::GetViewportId);
|
||||
AzFramework::DebugDisplayRequestBus::BusPtr debugDisplayBus;
|
||||
AzFramework::DebugDisplayRequestBus::Bind(debugDisplayBus, viewportId);
|
||||
AzFramework::DebugDisplayRequests* debugDisplay = nullptr;
|
||||
debugDisplay = AzFramework::DebugDisplayRequestBus::FindFirstHandler(debugDisplayBus);
|
||||
if (!debugDisplay)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const AZ::TypeId colliderType = collider.second->RTTI_GetType();
|
||||
if (colliderType == azrtti_typeid<Physics::SphereShapeConfiguration>())
|
||||
{
|
||||
Physics::SphereShapeConfiguration* sphere = static_cast<Physics::SphereShapeConfiguration*>(collider.second.get());
|
||||
|
||||
// O3DE Physics scaling rules: The maximum component from the node scale will be multiplied by the radius of the sphere.
|
||||
const float radius = sphere->m_radius *
|
||||
MCore::Max3<float>(static_cast<float>(worldScale.GetX()), static_cast<float>(worldScale.GetY()),
|
||||
static_cast<float>(worldScale.GetZ()));
|
||||
|
||||
debugDisplay->DepthTestOff();
|
||||
debugDisplay->SetColor(colliderColor);
|
||||
debugDisplay->DrawWireSphere(emfxColliderGlobalTransformNoScale.m_position, radius);
|
||||
}
|
||||
else if (colliderType == azrtti_typeid<Physics::CapsuleShapeConfiguration>())
|
||||
{
|
||||
Physics::CapsuleShapeConfiguration* capsule = static_cast<Physics::CapsuleShapeConfiguration*>(collider.second.get());
|
||||
|
||||
// O3DE Physics scaling rules: The maximum of the X/Y scale components of the node scale will be multiplied by the radius of
|
||||
// the capsule. The Z component of the entity scale will be multiplied by the height of the capsule.
|
||||
const float radius =
|
||||
capsule->m_radius * MCore::Max<float>(static_cast<float>(worldScale.GetX()), static_cast<float>(worldScale.GetY()));
|
||||
const float height = capsule->m_height * static_cast<float>(worldScale.GetZ());
|
||||
|
||||
debugDisplay->DepthTestOff();
|
||||
debugDisplay->SetColor(colliderColor);
|
||||
debugDisplay->DrawWireCapsule(
|
||||
emfxColliderGlobalTransformNoScale.m_position, emfxColliderGlobalTransformNoScale.ToAZTransform().GetBasisZ(), radius, height);
|
||||
}
|
||||
else if (colliderType == azrtti_typeid<Physics::BoxShapeConfiguration>())
|
||||
{
|
||||
Physics::BoxShapeConfiguration* box = static_cast<Physics::BoxShapeConfiguration*>(collider.second.get());
|
||||
|
||||
// O3DE Physics scaling rules: Each component of the box dimensions will be scaled by the node's world scale.
|
||||
AZ::Vector3 dimensions = box->m_dimensions;
|
||||
dimensions *= worldScale;
|
||||
|
||||
debugDisplay->DepthTestOff();
|
||||
debugDisplay->SetColor(colliderColor);
|
||||
debugDisplay->DrawWireBox(
|
||||
emfxColliderGlobalTransformNoScale.m_position, emfxColliderGlobalTransformNoScale.m_position + dimensions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ColliderContainerWidget::RenderColliders(PhysicsSetup::ColliderConfigType colliderConfigType,
|
||||
const AZ::Color& defaultColor, const AZ::Color& selectedColor)
|
||||
{
|
||||
if (colliderConfigType == PhysicsSetup::Unknown)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const AZStd::unordered_set<size_t>& selectedJointIndices = EMStudio::GetManager()->GetSelectedJointIndices();
|
||||
|
||||
const ActorManager* actorManager = GetEMotionFX().GetActorManager();
|
||||
const size_t actorInstanceCount = actorManager->GetNumActorInstances();
|
||||
for (size_t i = 0; i < actorInstanceCount; ++i)
|
||||
{
|
||||
const ActorInstance* actorInstance = actorManager->GetActorInstance(i);
|
||||
const Actor* actor = actorInstance->GetActor();
|
||||
const AZStd::shared_ptr<PhysicsSetup>& physicsSetup = actor->GetPhysicsSetup();
|
||||
const Physics::CharacterColliderConfiguration* colliderConfig = physicsSetup->GetColliderConfigByType(colliderConfigType);
|
||||
|
||||
if (colliderConfig)
|
||||
{
|
||||
for (const Physics::CharacterColliderNodeConfiguration& nodeConfig : colliderConfig->m_nodes)
|
||||
{
|
||||
const Node* joint = actor->GetSkeleton()->FindNodeByName(nodeConfig.m_name.c_str());
|
||||
if (joint)
|
||||
{
|
||||
const bool jointSelected =
|
||||
selectedJointIndices.empty() || selectedJointIndices.find(joint->GetNodeIndex()) != selectedJointIndices.end();
|
||||
const AzPhysics::ShapeColliderPairList& colliders = nodeConfig.m_shapes;
|
||||
RenderColliders(colliders, actorInstance, joint, jointSelected ? selectedColor : defaultColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ColliderContainerWidget::ColliderEditedCallback::ColliderEditedCallback(ColliderContainerWidget* parent, bool executePreUndo, bool executePreCommand)
|
||||
|
||||
@@ -152,18 +152,32 @@ namespace EMotionFX
|
||||
* @param[in] renderInfo Needed to access the render util.
|
||||
* @param[in] colliderColor The collider color.
|
||||
*/
|
||||
static void RenderColliders(const AzPhysics::ShapeColliderPairList& colliders,
|
||||
//! Deprecated: remove after openglrenderwidget is gone.
|
||||
static void LegacyRenderColliders(const AzPhysics::ShapeColliderPairList& colliders,
|
||||
const ActorInstance* actorInstance,
|
||||
const Node* node,
|
||||
EMStudio::EMStudioPlugin::RenderInfo* renderInfo,
|
||||
const MCore::RGBAColor& colliderColor);
|
||||
|
||||
static void RenderColliders(PhysicsSetup::ColliderConfigType colliderConfigType,
|
||||
//! Deprecated: remove after openglrenderwidget is gone.
|
||||
static void LegacyRenderColliders(
|
||||
PhysicsSetup::ColliderConfigType colliderConfigType,
|
||||
const MCore::RGBAColor& defaultColor,
|
||||
const MCore::RGBAColor& selectedColor,
|
||||
EMStudio::RenderPlugin* renderPlugin,
|
||||
EMStudio::EMStudioPlugin::RenderInfo* renderInfo);
|
||||
|
||||
static void RenderColliders(
|
||||
const AzPhysics::ShapeColliderPairList& colliders,
|
||||
const ActorInstance* actorInstance,
|
||||
const Node* node,
|
||||
const AZ::Color& colliderColor);
|
||||
|
||||
static void RenderColliders(
|
||||
PhysicsSetup::ColliderConfigType colliderConfigType,
|
||||
const AZ::Color& defaultColor,
|
||||
const AZ::Color& selectedColor);
|
||||
|
||||
static int s_layoutSpacing;
|
||||
|
||||
signals:
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <Editor/SkeletonModel.h>
|
||||
#include <Editor/Plugins/Cloth/ClothJointInspectorPlugin.h>
|
||||
#include <Editor/Plugins/Cloth/ClothJointWidget.h>
|
||||
#include <Integration/Rendering/RenderActorSettings.h>
|
||||
#include <QScrollArea>
|
||||
|
||||
|
||||
@@ -172,7 +173,7 @@ namespace EMotionFX
|
||||
ColliderHelpers::ClearColliders(selectedRowIndices, PhysicsSetup::Cloth);
|
||||
}
|
||||
|
||||
void ClothJointInspectorPlugin::Render(EMStudio::RenderPlugin* renderPlugin, RenderInfo* renderInfo)
|
||||
void ClothJointInspectorPlugin::LegacyRender(EMStudio::RenderPlugin* renderPlugin, RenderInfo* renderInfo)
|
||||
{
|
||||
EMStudio::RenderViewWidget* activeViewWidget = renderPlugin->GetActiveViewWidget();
|
||||
if (!activeViewWidget)
|
||||
@@ -188,10 +189,22 @@ namespace EMotionFX
|
||||
|
||||
const EMStudio::RenderOptions* renderOptions = renderPlugin->GetRenderOptions();
|
||||
|
||||
ColliderContainerWidget::RenderColliders(PhysicsSetup::Cloth,
|
||||
ColliderContainerWidget::LegacyRenderColliders(PhysicsSetup::Cloth,
|
||||
renderOptions->GetClothColliderColor(),
|
||||
renderOptions->GetSelectedClothColliderColor(),
|
||||
renderPlugin,
|
||||
renderInfo);
|
||||
}
|
||||
|
||||
void ClothJointInspectorPlugin::Render(EMotionFX::ActorRenderFlagBitset renderFlags)
|
||||
{
|
||||
const bool renderColliders = renderFlags[RENDER_CLOTH_COLLIDERS];
|
||||
if (!renderColliders)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const AZ::Render::RenderActorSettings& settings = EMotionFX::GetRenderActorSettings();
|
||||
ColliderContainerWidget::RenderColliders(PhysicsSetup::Cloth, settings.m_clothColliderColor, settings.m_selectedClothColliderColor);
|
||||
}
|
||||
} // namespace EMotionFX
|
||||
|
||||
@@ -47,7 +47,8 @@ namespace EMotionFX
|
||||
// SkeletonOutlinerNotificationBus overrides
|
||||
void OnContextMenu(QMenu* menu, const QModelIndexList& selectedRowIndices) override;
|
||||
|
||||
void Render(EMStudio::RenderPlugin* renderPlugin, RenderInfo* renderInfo) override;
|
||||
void LegacyRender(EMStudio::RenderPlugin* renderPlugin, RenderInfo* renderInfo) override;
|
||||
void Render(EMotionFX::ActorRenderFlagBitset renderFlags) override;
|
||||
static bool IsJointInCloth(const QModelIndex& index);
|
||||
|
||||
public slots:
|
||||
|
||||
+18
-2
@@ -15,6 +15,7 @@
|
||||
#include <Editor/SkeletonModel.h>
|
||||
#include <Editor/Plugins/HitDetection/HitDetectionJointInspectorPlugin.h>
|
||||
#include <Editor/Plugins/HitDetection/HitDetectionJointWidget.h>
|
||||
#include <Integration/Rendering/RenderActorSettings.h>
|
||||
#include <QScrollArea>
|
||||
#include <MCore/Source/AzCoreConversions.h>
|
||||
|
||||
@@ -157,7 +158,7 @@ namespace EMotionFX
|
||||
ColliderHelpers::ClearColliders(selectedRowIndices, PhysicsSetup::HitDetection);
|
||||
}
|
||||
|
||||
void HitDetectionJointInspectorPlugin::Render(EMStudio::RenderPlugin* renderPlugin, RenderInfo* renderInfo)
|
||||
void HitDetectionJointInspectorPlugin::LegacyRender(EMStudio::RenderPlugin* renderPlugin, RenderInfo* renderInfo)
|
||||
{
|
||||
EMStudio::RenderViewWidget* activeViewWidget = renderPlugin->GetActiveViewWidget();
|
||||
if (!activeViewWidget)
|
||||
@@ -173,10 +174,25 @@ namespace EMotionFX
|
||||
|
||||
const EMStudio::RenderOptions* renderOptions = renderPlugin->GetRenderOptions();
|
||||
|
||||
ColliderContainerWidget::RenderColliders(PhysicsSetup::HitDetection,
|
||||
ColliderContainerWidget::LegacyRenderColliders(PhysicsSetup::HitDetection,
|
||||
renderOptions->GetHitDetectionColliderColor(),
|
||||
renderOptions->GetSelectedHitDetectionColliderColor(),
|
||||
renderPlugin,
|
||||
renderInfo);
|
||||
}
|
||||
|
||||
void HitDetectionJointInspectorPlugin::Render(EMotionFX::ActorRenderFlagBitset renderFlags)
|
||||
{
|
||||
const bool renderColliders = renderFlags[EMotionFX::ActorRenderFlag::RENDER_HITDETECTION_COLLIDERS];
|
||||
if (!renderColliders)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const AZ::Render::RenderActorSettings& settings = EMotionFX::GetRenderActorSettings();
|
||||
|
||||
ColliderContainerWidget::RenderColliders(
|
||||
PhysicsSetup::HitDetection, settings.m_hitDetectionColliderColor,
|
||||
settings.m_selectedHitDetectionColliderColor);
|
||||
}
|
||||
} // namespace EMotionFX
|
||||
|
||||
+2
-1
@@ -43,7 +43,8 @@ namespace EMotionFX
|
||||
// SkeletonOutlinerNotificationBus overrides
|
||||
void OnContextMenu(QMenu* menu, const QModelIndexList& selectedRowIndices) override;
|
||||
|
||||
void Render(EMStudio::RenderPlugin* renderPlugin, RenderInfo* renderInfo) override;
|
||||
void LegacyRender(EMStudio::RenderPlugin* renderPlugin, RenderInfo* renderInfo) override;
|
||||
void Render(EMotionFX::ActorRenderFlagBitset renderFlags) override;
|
||||
|
||||
public slots:
|
||||
void OnAddCollider();
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
#include <AzFramework/Physics/SystemBus.h>
|
||||
#include <AzFramework/Entity/EntityDebugDisplayBus.h>
|
||||
#include <EMotionFX/Source/ActorManager.h>
|
||||
#include <EMotionFX/Source/RagdollInstance.h>
|
||||
#include <EMotionFX/Source/TransformData.h>
|
||||
@@ -17,12 +18,14 @@
|
||||
#include <EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderPlugin.h>
|
||||
#include <EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderViewWidget.h>
|
||||
#include <EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/EMStudioManager.h>
|
||||
#include <EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/ViewportPluginBus.h>
|
||||
#include <Editor/ColliderContainerWidget.h>
|
||||
#include <Editor/ColliderHelpers.h>
|
||||
#include <Editor/SkeletonModel.h>
|
||||
#include <Editor/Plugins/Ragdoll/RagdollJointLimitWidget.h>
|
||||
#include <Editor/Plugins/Ragdoll/RagdollNodeInspectorPlugin.h>
|
||||
#include <Editor/Plugins/Ragdoll/RagdollNodeWidget.h>
|
||||
#include <Integration/Rendering/RenderActorSettings.h>
|
||||
#include <QScrollArea>
|
||||
#include <MCore/Source/AzCoreConversions.h>
|
||||
|
||||
@@ -412,7 +415,7 @@ namespace EMotionFX
|
||||
}
|
||||
}
|
||||
|
||||
void RagdollNodeInspectorPlugin::Render(EMStudio::RenderPlugin* renderPlugin, RenderInfo* renderInfo)
|
||||
void RagdollNodeInspectorPlugin::LegacyRender(EMStudio::RenderPlugin* renderPlugin, RenderInfo* renderInfo)
|
||||
{
|
||||
EMStudio::RenderViewWidget* activeViewWidget = renderPlugin->GetActiveViewWidget();
|
||||
if (!activeViewWidget)
|
||||
@@ -435,14 +438,19 @@ namespace EMotionFX
|
||||
for (size_t i = 0; i < actorInstanceCount; ++i)
|
||||
{
|
||||
ActorInstance* actorInstance = GetActorManager().GetActorInstance(i);
|
||||
RenderRagdoll(actorInstance, renderColliders, renderJointLimits, renderPlugin, renderInfo);
|
||||
LegacyRenderRagdoll(actorInstance, renderColliders, renderJointLimits, renderPlugin, renderInfo);
|
||||
}
|
||||
|
||||
renderUtil->RenderLines();
|
||||
renderUtil->EnableLighting(oldLightingEnabled);
|
||||
}
|
||||
|
||||
void RagdollNodeInspectorPlugin::RenderRagdoll(ActorInstance* actorInstance, bool renderColliders, bool renderJointLimits, EMStudio::RenderPlugin* renderPlugin, RenderInfo* renderInfo)
|
||||
void RagdollNodeInspectorPlugin::LegacyRenderRagdoll(
|
||||
ActorInstance* actorInstance,
|
||||
bool renderColliders,
|
||||
bool renderJointLimits,
|
||||
EMStudio::RenderPlugin* renderPlugin,
|
||||
RenderInfo* renderInfo)
|
||||
{
|
||||
const Actor* actor = actorInstance->GetActor();
|
||||
const Skeleton* skeleton = actor->GetSkeleton();
|
||||
@@ -495,11 +503,12 @@ namespace EMotionFX
|
||||
|
||||
if (renderColliders)
|
||||
{
|
||||
const Physics::CharacterColliderNodeConfiguration* colliderNodeConfig = colliderConfig.FindNodeConfigByName(joint->GetNameString());
|
||||
const Physics::CharacterColliderNodeConfiguration* colliderNodeConfig =
|
||||
colliderConfig.FindNodeConfigByName(joint->GetNameString());
|
||||
if (colliderNodeConfig)
|
||||
{
|
||||
const AzPhysics::ShapeColliderPairList& colliders = colliderNodeConfig->m_shapes;
|
||||
ColliderContainerWidget::RenderColliders(colliders, actorInstance, joint, renderInfo, finalColor);
|
||||
ColliderContainerWidget::LegacyRenderColliders(colliders, actorInstance, joint, renderInfo, finalColor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -511,15 +520,15 @@ namespace EMotionFX
|
||||
const Node* ragdollParentNode = physicsSetup->FindRagdollParentNode(joint);
|
||||
if (ragdollParentNode)
|
||||
{
|
||||
RenderJointLimit(*jointLimitConfig, actorInstance, joint, ragdollParentNode, renderPlugin, renderInfo, finalColor);
|
||||
RenderJointFrame(*jointLimitConfig, actorInstance, joint, ragdollParentNode, renderInfo, finalColor);
|
||||
LegacyRenderJointLimit(*jointLimitConfig, actorInstance, joint, ragdollParentNode, renderPlugin, renderInfo, finalColor);
|
||||
LegacyRenderJointFrame(*jointLimitConfig, actorInstance, joint, ragdollParentNode, renderInfo, finalColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RagdollNodeInspectorPlugin::RenderJointLimit(
|
||||
void RagdollNodeInspectorPlugin::LegacyRenderJointLimit(
|
||||
const AzPhysics::JointConfiguration& configuration,
|
||||
const ActorInstance* actorInstance,
|
||||
const Node* node,
|
||||
@@ -567,7 +576,7 @@ namespace EMotionFX
|
||||
}
|
||||
}
|
||||
|
||||
void RagdollNodeInspectorPlugin::RenderJointFrame(
|
||||
void RagdollNodeInspectorPlugin::LegacyRenderJointFrame(
|
||||
const AzPhysics::JointConfiguration& configuration,
|
||||
const ActorInstance* actorInstance,
|
||||
const Node* node,
|
||||
@@ -585,4 +594,192 @@ namespace EMotionFX
|
||||
|
||||
renderInfo->m_renderUtil->RenderArrow(0.1f, jointChildWorldSpaceTransformNoScale.m_position, MCore::GetRight(jointChildWorldSpaceTransformNoScale.ToAZTransform()), color);
|
||||
}
|
||||
|
||||
void RagdollNodeInspectorPlugin::Render(EMotionFX::ActorRenderFlagBitset renderFlags)
|
||||
{
|
||||
const bool renderColliders = renderFlags[RENDER_RAGDOLL_COLLIDERS];
|
||||
const bool renderJointLimits = renderFlags[RENDER_RAGDOLL_JOINTLIMITS];
|
||||
if (!renderColliders && !renderJointLimits)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const size_t actorInstanceCount = GetActorManager().GetNumActorInstances();
|
||||
for (size_t i = 0; i < actorInstanceCount; ++i)
|
||||
{
|
||||
ActorInstance* actorInstance = GetActorManager().GetActorInstance(i);
|
||||
RenderRagdoll(actorInstance, renderColliders, renderJointLimits);
|
||||
}
|
||||
}
|
||||
|
||||
void RagdollNodeInspectorPlugin::RenderRagdoll(
|
||||
ActorInstance* actorInstance,
|
||||
bool renderColliders,
|
||||
bool renderJointLimits)
|
||||
{
|
||||
const Actor* actor = actorInstance->GetActor();
|
||||
const Skeleton* skeleton = actor->GetSkeleton();
|
||||
const size_t numNodes = skeleton->GetNumNodes();
|
||||
const AZStd::shared_ptr<EMotionFX::PhysicsSetup>& physicsSetup = actor->GetPhysicsSetup();
|
||||
const Physics::RagdollConfiguration& ragdollConfig = physicsSetup->GetRagdollConfig();
|
||||
const AZStd::vector<Physics::RagdollNodeConfiguration>& ragdollNodes = ragdollConfig.m_nodes;
|
||||
const Physics::CharacterColliderConfiguration& colliderConfig = ragdollConfig.m_colliders;
|
||||
const RagdollInstance* ragdollInstance = actorInstance->GetRagdollInstance();
|
||||
|
||||
const AZ::Render::RenderActorSettings& settings = EMotionFX::GetRenderActorSettings();
|
||||
const AZ::Color& violatedColor = settings.m_violatedJointLimitColor;
|
||||
const AZ::Color& defaultColor = settings.m_ragdollColliderColor;
|
||||
const AZ::Color& selectedColor = settings.m_selectedRagdollColliderColor;
|
||||
|
||||
const AZStd::unordered_set<size_t>& selectedJointIndices = EMStudio::GetManager()->GetSelectedJointIndices();
|
||||
|
||||
for (size_t nodeIndex = 0; nodeIndex < numNodes; ++nodeIndex)
|
||||
{
|
||||
const Node* joint = skeleton->GetNode(nodeIndex);
|
||||
const size_t jointIndex = joint->GetNodeIndex();
|
||||
|
||||
AZ::Outcome<size_t> ragdollNodeIndex = AZ::Failure();
|
||||
if (ragdollInstance)
|
||||
{
|
||||
ragdollNodeIndex = ragdollInstance->GetRagdollNodeIndex(jointIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
ragdollNodeIndex = ragdollConfig.FindNodeConfigIndexByName(joint->GetNameString());
|
||||
}
|
||||
|
||||
if (!ragdollNodeIndex.IsSuccess())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const bool jointSelected = selectedJointIndices.empty() || selectedJointIndices.find(jointIndex) != selectedJointIndices.end();
|
||||
|
||||
AZ::Color finalColor;
|
||||
if (jointSelected)
|
||||
{
|
||||
finalColor = selectedColor;
|
||||
}
|
||||
else
|
||||
{
|
||||
finalColor = defaultColor;
|
||||
}
|
||||
|
||||
const Physics::RagdollNodeConfiguration& ragdollNode = ragdollNodes[ragdollNodeIndex.GetValue()];
|
||||
|
||||
if (renderColliders)
|
||||
{
|
||||
const Physics::CharacterColliderNodeConfiguration* colliderNodeConfig =
|
||||
colliderConfig.FindNodeConfigByName(joint->GetNameString());
|
||||
if (colliderNodeConfig)
|
||||
{
|
||||
const AzPhysics::ShapeColliderPairList& colliders = colliderNodeConfig->m_shapes;
|
||||
ColliderContainerWidget::RenderColliders(colliders, actorInstance, joint, finalColor);
|
||||
}
|
||||
}
|
||||
|
||||
if (renderJointLimits && jointSelected)
|
||||
{
|
||||
const AZStd::shared_ptr<AzPhysics::JointConfiguration>& jointLimitConfig = ragdollNode.m_jointConfig;
|
||||
if (jointLimitConfig)
|
||||
{
|
||||
const Node* ragdollParentNode = physicsSetup->FindRagdollParentNode(joint);
|
||||
if (ragdollParentNode)
|
||||
{
|
||||
RenderJointLimit(*jointLimitConfig, actorInstance, joint, ragdollParentNode, finalColor, violatedColor);
|
||||
RenderJointFrame(*jointLimitConfig, actorInstance, joint, ragdollParentNode, finalColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RagdollNodeInspectorPlugin::RenderJointLimit(
|
||||
const AzPhysics::JointConfiguration& configuration,
|
||||
const ActorInstance* actorInstance,
|
||||
const Node* node,
|
||||
const Node* parentNode,
|
||||
const AZ::Color& regularColor,
|
||||
const AZ::Color& violatedColor)
|
||||
{
|
||||
const size_t nodeIndex = node->GetNodeIndex();
|
||||
const size_t parentNodeIndex = parentNode->GetNodeIndex();
|
||||
const Transform& actorInstanceWorldTransform = actorInstance->GetWorldSpaceTransform();
|
||||
const Pose* currentPose = actorInstance->GetTransformData()->GetCurrentPose();
|
||||
const AZ::Quaternion& parentOrientation = currentPose->GetModelSpaceTransform(parentNodeIndex).m_rotation;
|
||||
const AZ::Quaternion& childOrientation = currentPose->GetModelSpaceTransform(nodeIndex).m_rotation;
|
||||
|
||||
m_vertexBuffer.clear();
|
||||
m_indexBuffer.clear();
|
||||
m_lineBuffer.clear();
|
||||
m_lineValidityBuffer.clear();
|
||||
if (auto* jointHelpers = AZ::Interface<AzPhysics::JointHelpersInterface>::Get())
|
||||
{
|
||||
jointHelpers->GenerateJointLimitVisualizationData(
|
||||
configuration, parentOrientation, childOrientation, s_scale, s_angularSubdivisions, s_radialSubdivisions, m_vertexBuffer,
|
||||
m_indexBuffer, m_lineBuffer, m_lineValidityBuffer);
|
||||
}
|
||||
|
||||
Transform jointModelSpaceTransform = currentPose->GetModelSpaceTransform(parentNodeIndex);
|
||||
jointModelSpaceTransform.m_position = currentPose->GetModelSpaceTransform(nodeIndex).m_position;
|
||||
const Transform jointGlobalTransformNoScale = jointModelSpaceTransform * actorInstanceWorldTransform;
|
||||
|
||||
const size_t numLineBufferEntries = m_lineBuffer.size();
|
||||
if (m_lineValidityBuffer.size() * 2 != numLineBufferEntries)
|
||||
{
|
||||
AZ_ErrorOnce("EMotionFX", false, "Unexpected buffer size in joint limit visualization for node %s", node->GetName());
|
||||
return;
|
||||
}
|
||||
|
||||
AZ::s32 viewportId = -1;
|
||||
EMStudio::ViewportPluginRequestBus::BroadcastResult(viewportId, &EMStudio::ViewportPluginRequestBus::Events::GetViewportId);
|
||||
AzFramework::DebugDisplayRequestBus::BusPtr debugDisplayBus;
|
||||
AzFramework::DebugDisplayRequestBus::Bind(debugDisplayBus, viewportId);
|
||||
AzFramework::DebugDisplayRequests* debugDisplay = nullptr;
|
||||
debugDisplay = AzFramework::DebugDisplayRequestBus::FindFirstHandler(debugDisplayBus);
|
||||
if (!debugDisplay)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < numLineBufferEntries; i += 2)
|
||||
{
|
||||
const AZ::Color& lineColor = m_lineValidityBuffer[i / 2] ? regularColor : violatedColor;
|
||||
debugDisplay->DrawLine(
|
||||
jointGlobalTransformNoScale.TransformPoint(m_lineBuffer[i]),
|
||||
jointGlobalTransformNoScale.TransformPoint(m_lineBuffer[i + 1]), lineColor.GetAsVector4(), lineColor.GetAsVector4()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void RagdollNodeInspectorPlugin::RenderJointFrame(
|
||||
const AzPhysics::JointConfiguration& configuration,
|
||||
const ActorInstance* actorInstance,
|
||||
const Node* node,
|
||||
const Node* parentNode,
|
||||
const AZ::Color& color)
|
||||
{
|
||||
AZ_UNUSED(parentNode);
|
||||
|
||||
const Transform& actorInstanceWorldSpaceTransform = actorInstance->GetWorldSpaceTransform();
|
||||
const Pose* currentPose = actorInstance->GetTransformData()->GetCurrentPose();
|
||||
const Transform childJointLocalSpaceTransform(AZ::Vector3::CreateZero(), configuration.m_childLocalRotation);
|
||||
const Transform childModelSpaceTransform =
|
||||
childJointLocalSpaceTransform * currentPose->GetModelSpaceTransform(node->GetNodeIndex());
|
||||
const Transform jointChildWorldSpaceTransformNoScale = (childModelSpaceTransform * actorInstanceWorldSpaceTransform);
|
||||
AZ::Vector3 dir = jointChildWorldSpaceTransformNoScale.ToAZTransform().GetBasisX();
|
||||
|
||||
AZ::s32 viewportId = -1;
|
||||
EMStudio::ViewportPluginRequestBus::BroadcastResult(viewportId, &EMStudio::ViewportPluginRequestBus::Events::GetViewportId);
|
||||
AzFramework::DebugDisplayRequestBus::BusPtr debugDisplayBus;
|
||||
AzFramework::DebugDisplayRequestBus::Bind(debugDisplayBus, viewportId);
|
||||
AzFramework::DebugDisplayRequests* debugDisplay = nullptr;
|
||||
debugDisplay = AzFramework::DebugDisplayRequestBus::FindFirstHandler(debugDisplayBus);
|
||||
if (!debugDisplay)
|
||||
{
|
||||
return;
|
||||
}
|
||||
debugDisplay->SetColor(color);
|
||||
debugDisplay->DrawArrow(jointChildWorldSpaceTransformNoScale.m_position, jointChildWorldSpaceTransformNoScale.m_position + dir, 0.1f);
|
||||
}
|
||||
} // namespace EMotionFX
|
||||
|
||||
@@ -54,9 +54,10 @@ namespace EMotionFX
|
||||
static void AddCollider(const QModelIndexList& modelIndices, const AZ::TypeId& colliderType);
|
||||
static void CopyColliders(const QModelIndexList& modelIndices, PhysicsSetup::ColliderConfigType copyFrom);
|
||||
|
||||
void Render(EMStudio::RenderPlugin* renderPlugin, RenderInfo* renderInfo) override;
|
||||
void RenderRagdoll(ActorInstance* actorInstance, bool renderColliders, bool renderJointLimits, EMStudio::RenderPlugin* renderPlugin, RenderInfo* renderInfo);
|
||||
void RenderJointLimit(
|
||||
//! Deprecated: All legacy render function is tied to openGL. Will be removed after openGLPlugin is completely removed.
|
||||
void LegacyRender(EMStudio::RenderPlugin* renderPlugin, RenderInfo* renderInfo) override;
|
||||
void LegacyRenderRagdoll(ActorInstance* actorInstance, bool renderColliders, bool renderJointLimits, EMStudio::RenderPlugin* renderPlugin, RenderInfo* renderInfo);
|
||||
void LegacyRenderJointLimit(
|
||||
const AzPhysics::JointConfiguration& jointConfiguration,
|
||||
const ActorInstance* actorInstance,
|
||||
const Node* node,
|
||||
@@ -64,7 +65,7 @@ namespace EMotionFX
|
||||
EMStudio::RenderPlugin* renderPlugin,
|
||||
EMStudio::EMStudioPlugin::RenderInfo* renderInfo,
|
||||
const MCore::RGBAColor& color);
|
||||
void RenderJointFrame(
|
||||
void LegacyRenderJointFrame(
|
||||
const AzPhysics::JointConfiguration& jointConfiguration,
|
||||
const ActorInstance* actorInstance,
|
||||
const Node* node,
|
||||
@@ -72,6 +73,26 @@ namespace EMotionFX
|
||||
EMStudio::EMStudioPlugin::RenderInfo* renderInfo,
|
||||
const MCore::RGBAColor& color);
|
||||
|
||||
//! Those function replaces legacyRender function and calls atom auxGeom render internally.
|
||||
void Render(EMotionFX::ActorRenderFlagBitset renderFlags) override;
|
||||
void RenderRagdoll(
|
||||
ActorInstance* actorInstance,
|
||||
bool renderColliders,
|
||||
bool renderJointLimits);
|
||||
void RenderJointLimit(
|
||||
const AzPhysics::JointConfiguration& jointConfiguration,
|
||||
const ActorInstance* actorInstance,
|
||||
const Node* node,
|
||||
const Node* parentNode,
|
||||
const AZ::Color& regularColor,
|
||||
const AZ::Color& violatedColor);
|
||||
void RenderJointFrame(
|
||||
const AzPhysics::JointConfiguration& jointConfiguration,
|
||||
const ActorInstance* actorInstance,
|
||||
const Node* node,
|
||||
const Node* parentNode,
|
||||
const AZ::Color& color);
|
||||
|
||||
public slots:
|
||||
void OnAddToRagdoll();
|
||||
void OnAddCollider();
|
||||
|
||||
+118
-20
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <AzCore/std/algorithm.h>
|
||||
#include <AzToolsFramework/UI/PropertyEditor/PropertyEditorAPI.h>
|
||||
#include <AzFramework/Entity/EntityDebugDisplayBus.h>
|
||||
#include <EMotionFX/CommandSystem/Source/SimulatedObjectCommands.h>
|
||||
#include <EMotionFX/Source/Actor.h>
|
||||
#include <EMotionFX/Source/ActorInstance.h>
|
||||
@@ -18,6 +19,7 @@
|
||||
#include <EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderOptions.h>
|
||||
#include <EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderPlugin.h>
|
||||
#include <EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderViewWidget.h>
|
||||
#include <EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/ViewportPluginBus.h>
|
||||
#include <Editor/ColliderContainerWidget.h>
|
||||
#include <Editor/ColliderHelpers.h>
|
||||
#include <Editor/Plugins/SimulatedObject/SimulatedJointWidget.h>
|
||||
@@ -25,6 +27,7 @@
|
||||
#include <Editor/ReselectingTreeView.h>
|
||||
#include <Editor/SimulatedObjectHelpers.h>
|
||||
#include <Editor/SkeletonModel.h>
|
||||
#include <Integration/Rendering/RenderActorSettings.h>
|
||||
#include <MCore/Source/AzCoreConversions.h>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
@@ -330,6 +333,11 @@ namespace EMotionFX
|
||||
|
||||
const Actor* actor = selectedRowIndices[0].data(SkeletonModel::ROLE_ACTOR_POINTER).value<Actor*>();
|
||||
const SimulatedObjectSetup* simulatedObjectSetup = actor->GetSimulatedObjectSetup().get();
|
||||
if (!simulatedObjectSetup)
|
||||
{
|
||||
AZ_Assert(false, "Expected a simulated object setup on the actor.");
|
||||
return;
|
||||
}
|
||||
|
||||
AZStd::unordered_set<const SimulatedObject*> addToCandidates;
|
||||
for (const QModelIndex& index : selectedRowIndices)
|
||||
@@ -477,7 +485,7 @@ namespace EMotionFX
|
||||
|
||||
// -------------------------------------------------- Rendering -------------------------------------------------------------
|
||||
|
||||
void SimulatedObjectWidget::Render(EMStudio::RenderPlugin* renderPlugin, RenderInfo* renderInfo)
|
||||
void SimulatedObjectWidget::LegacyRender(EMStudio::RenderPlugin* renderPlugin, RenderInfo* renderInfo)
|
||||
{
|
||||
if (!m_actor || !m_actorInstance)
|
||||
{
|
||||
@@ -501,7 +509,92 @@ namespace EMotionFX
|
||||
ActorInstance* actorInstance = GetActorManager().GetActorInstance(actorInstanceIndex);
|
||||
const Actor* actor = actorInstance->GetActor();
|
||||
const SimulatedObjectSetup* setup = actor->GetSimulatedObjectSetup().get();
|
||||
AZ_Assert(setup, "Expected a simulated object setup on the actor instance.");
|
||||
if (!setup)
|
||||
{
|
||||
AZ_Assert(false, "Expected a simulated object setup on the actor instance.");
|
||||
return;
|
||||
}
|
||||
|
||||
const size_t objectCount = setup->GetNumSimulatedObjects();
|
||||
for (size_t objectIndex = 0; objectIndex < objectCount; ++objectIndex)
|
||||
{
|
||||
const SimulatedObject* object = setup->GetSimulatedObject(objectIndex);
|
||||
const size_t simulatedJointCount = object->GetNumSimulatedJoints();
|
||||
for (size_t simulatedJointIndex = 0; simulatedJointIndex < simulatedJointCount; ++simulatedJointIndex)
|
||||
{
|
||||
const SimulatedJoint* simulatedJoint = object->GetSimulatedJoint(simulatedJointIndex);
|
||||
const size_t skeletonJointIndex = simulatedJoint->GetSkeletonJointIndex();
|
||||
if (selectedJointIndices.find(skeletonJointIndex) != selectedJointIndices.end())
|
||||
{
|
||||
LegacyRenderJointRadius(simulatedJoint, actorInstance, AZ::Color(1.0f, 0.0f, 1.0f, 1.0f));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const bool renderColliders = activeViewWidget->GetRenderFlag(EMStudio::RenderViewWidget::RENDER_SIMULATEDOBJECT_COLLIDERS);
|
||||
if (renderColliders)
|
||||
{
|
||||
const EMStudio::RenderOptions* renderOptions = renderPlugin->GetRenderOptions();
|
||||
ColliderContainerWidget::LegacyRenderColliders(PhysicsSetup::SimulatedObjectCollider,
|
||||
renderOptions->GetSimulatedObjectColliderColor(),
|
||||
renderOptions->GetSelectedSimulatedObjectColliderColor(),
|
||||
renderPlugin,
|
||||
renderInfo);
|
||||
}
|
||||
}
|
||||
|
||||
void SimulatedObjectWidget::LegacyRenderJointRadius(const SimulatedJoint* joint, ActorInstance* actorInstance, const AZ::Color& color)
|
||||
{
|
||||
#ifndef EMFX_SCALE_DISABLED
|
||||
const float scale = actorInstance->GetWorldSpaceTransform().m_scale.GetX();
|
||||
#else
|
||||
const float scale = 1.0f;
|
||||
#endif
|
||||
|
||||
const float radius = joint->GetCollisionRadius() * scale;
|
||||
if (radius <= AZ::Constants::FloatEpsilon)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
AZ_Assert(joint->GetSkeletonJointIndex() != InvalidIndex, "Expected skeletal joint index to be valid.");
|
||||
const EMotionFX::Transform jointTransform =
|
||||
actorInstance->GetTransformData()->GetCurrentPose()->GetWorldSpaceTransform(joint->GetSkeletonJointIndex());
|
||||
|
||||
DebugDraw& debugDraw = GetDebugDraw();
|
||||
DebugDraw::ActorInstanceData* drawData = debugDraw.GetActorInstanceData(actorInstance);
|
||||
drawData->Lock();
|
||||
drawData->DrawWireframeSphere(jointTransform.m_position, radius, color, jointTransform.m_rotation, 12, 12);
|
||||
drawData->Unlock();
|
||||
}
|
||||
|
||||
void SimulatedObjectWidget::Render(EMotionFX::ActorRenderFlagBitset renderFlags)
|
||||
{
|
||||
if (!m_actor || !m_actorInstance)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const AZ::Render::RenderActorSettings& settings = EMotionFX::GetRenderActorSettings();
|
||||
const bool renderSimulatedJoints = renderFlags[RENDER_SIMULATEJOINTS];
|
||||
const AZStd::unordered_set<size_t>& selectedJointIndices = EMStudio::GetManager()->GetSelectedJointIndices();
|
||||
if (renderSimulatedJoints && !selectedJointIndices.empty())
|
||||
{
|
||||
// Render the joint radius.
|
||||
const size_t actorInstanceCount = GetActorManager().GetNumActorInstances();
|
||||
for (size_t actorInstanceIndex = 0; actorInstanceIndex < actorInstanceCount; ++actorInstanceIndex)
|
||||
{
|
||||
ActorInstance* actorInstance = GetActorManager().GetActorInstance(actorInstanceIndex);
|
||||
const Actor* actor = actorInstance->GetActor();
|
||||
const SimulatedObjectSetup* setup = actor->GetSimulatedObjectSetup().get();
|
||||
if (!setup)
|
||||
{
|
||||
AZ_Assert(false, "Expected a simulated object setup on the actor instance.");
|
||||
return;
|
||||
}
|
||||
|
||||
const size_t objectCount = setup->GetNumSimulatedObjects();
|
||||
for (size_t objectIndex = 0; objectIndex < objectCount; ++objectIndex)
|
||||
{
|
||||
@@ -520,25 +613,21 @@ namespace EMotionFX
|
||||
}
|
||||
}
|
||||
|
||||
const bool renderColliders = activeViewWidget->GetRenderFlag(EMStudio::RenderViewWidget::RENDER_SIMULATEDOBJECT_COLLIDERS);
|
||||
const bool renderColliders = renderFlags[RENDER_SIMULATEDOBJECT_COLLIDERS];
|
||||
if (renderColliders)
|
||||
{
|
||||
const EMStudio::RenderOptions* renderOptions = renderPlugin->GetRenderOptions();
|
||||
ColliderContainerWidget::RenderColliders(PhysicsSetup::SimulatedObjectCollider,
|
||||
renderOptions->GetSimulatedObjectColliderColor(),
|
||||
renderOptions->GetSelectedSimulatedObjectColliderColor(),
|
||||
renderPlugin,
|
||||
renderInfo);
|
||||
settings.m_simulatedObjectColliderColor, settings.m_selectedSimulatedObjectColliderColor);
|
||||
}
|
||||
}
|
||||
|
||||
void SimulatedObjectWidget::RenderJointRadius(const SimulatedJoint* joint, ActorInstance* actorInstance, const AZ::Color& color)
|
||||
void SimulatedObjectWidget::RenderJointRadius(const SimulatedJoint* joint, ActorInstance* actorInstance, const AZ::Color& color)
|
||||
{
|
||||
#ifndef EMFX_SCALE_DISABLED
|
||||
const float scale = actorInstance->GetWorldSpaceTransform().m_scale.GetX();
|
||||
#else
|
||||
const float scale = 1.0f;
|
||||
#endif
|
||||
#ifndef EMFX_SCALE_DISABLED
|
||||
const float scale = actorInstance->GetWorldSpaceTransform().m_scale.GetX();
|
||||
#else
|
||||
const float scale = 1.0f;
|
||||
#endif
|
||||
|
||||
const float radius = joint->GetCollisionRadius() * scale;
|
||||
if (radius <= AZ::Constants::FloatEpsilon)
|
||||
@@ -547,12 +636,21 @@ namespace EMotionFX
|
||||
}
|
||||
|
||||
AZ_Assert(joint->GetSkeletonJointIndex() != InvalidIndex, "Expected skeletal joint index to be valid.");
|
||||
const EMotionFX::Transform jointTransform = actorInstance->GetTransformData()->GetCurrentPose()->GetWorldSpaceTransform(joint->GetSkeletonJointIndex());
|
||||
const EMotionFX::Transform jointTransform =
|
||||
actorInstance->GetTransformData()->GetCurrentPose()->GetWorldSpaceTransform(joint->GetSkeletonJointIndex());
|
||||
|
||||
DebugDraw& debugDraw = GetDebugDraw();
|
||||
DebugDraw::ActorInstanceData* drawData = debugDraw.GetActorInstanceData(actorInstance);
|
||||
drawData->Lock();
|
||||
drawData->DrawWireframeSphere(jointTransform.m_position, radius, color, jointTransform.m_rotation, 12, 12);
|
||||
drawData->Unlock();
|
||||
AZ::s32 viewportId = -1;
|
||||
EMStudio::ViewportPluginRequestBus::BroadcastResult(viewportId, &EMStudio::ViewportPluginRequestBus::Events::GetViewportId);
|
||||
AzFramework::DebugDisplayRequestBus::BusPtr debugDisplayBus;
|
||||
AzFramework::DebugDisplayRequestBus::Bind(debugDisplayBus, viewportId);
|
||||
AzFramework::DebugDisplayRequests* debugDisplay = nullptr;
|
||||
debugDisplay = AzFramework::DebugDisplayRequestBus::FindFirstHandler(debugDisplayBus);
|
||||
if (!debugDisplay)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
debugDisplay->SetColor(color);
|
||||
debugDisplay->DrawWireSphere(jointTransform.m_position, radius);
|
||||
}
|
||||
} // namespace EMotionFX
|
||||
|
||||
@@ -59,8 +59,9 @@ namespace EMotionFX
|
||||
bool Init() override;
|
||||
void Reinit();
|
||||
|
||||
// Render
|
||||
void Render(EMStudio::RenderPlugin* renderPlugin, RenderInfo* renderInfo) override;
|
||||
void LegacyRender(EMStudio::RenderPlugin* renderPlugin, RenderInfo* renderInfo) override;
|
||||
void LegacyRenderJointRadius(const SimulatedJoint* joint, ActorInstance* actorInstance, const AZ::Color& color);
|
||||
void Render(EMotionFX::ActorRenderFlagBitset renderFlags) override;
|
||||
void RenderJointRadius(const SimulatedJoint* joint, ActorInstance* actorInstance, const AZ::Color& color);
|
||||
|
||||
SimulatedObjectModel* GetSimulatedObjectModel() const;
|
||||
|
||||
@@ -27,6 +27,16 @@ namespace AZ::Render
|
||||
float m_tangentsScale = 1.0f;
|
||||
float m_wireframeScale = 1.0f;
|
||||
|
||||
AZ::Color m_hitDetectionColliderColor{0.44f, 0.44f, 0.44f, 1.0f};
|
||||
AZ::Color m_selectedHitDetectionColliderColor{ 0.3f, 0.56f, 0.88f, 1.0f };
|
||||
AZ::Color m_ragdollColliderColor{ 0.44f, 0.44f, 0.44f, 1.0f };
|
||||
AZ::Color m_selectedRagdollColliderColor{ 0.96f, 0.65f, 0.14f, 1.0f };
|
||||
AZ::Color m_violatedJointLimitColor{ 1.0f, 0.0f, 0.0f, 1.0f };
|
||||
AZ::Color m_clothColliderColor{ 0.44f, 0.44f, 0.44f, 1.0f };
|
||||
AZ::Color m_selectedClothColliderColor{ 0.6f, 0.46f, 1.0f, 1.0f };
|
||||
AZ::Color m_simulatedObjectColliderColor{ 0.44f, 0.44f, 0.44f, 1.0f };
|
||||
AZ::Color m_selectedSimulatedObjectColliderColor{ 1.0, 0.34f, 0.87f, 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 };
|
||||
|
||||
Reference in New Issue
Block a user