You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
889 lines
42 KiB
C++
889 lines
42 KiB
C++
/*
|
|
* Copyright (c) Contributors to the Open 3D Engine Project.
|
|
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
*
|
|
*/
|
|
|
|
#include "SystemComponent.h"
|
|
|
|
#include <AzCore/Serialization/SerializeContext.h>
|
|
#include <AzCore/Serialization/EditContext.h>
|
|
#include <AzCore/Component/TransformBus.h>
|
|
#include <AzCore/Console/IConsole.h>
|
|
|
|
#include <PhysX/SystemComponentBus.h>
|
|
#include <PhysX/MathConversion.h>
|
|
#include <PhysX/UserDataTypes.h>
|
|
#include <PhysX/Utils.h>
|
|
#include <PhysX/PhysXLocks.h>
|
|
#include <PhysX/Debug/PhysXDebugConfiguration.h>
|
|
|
|
#include <AzFramework/Physics/PhysicsScene.h>
|
|
#include <AzFramework/Physics/PhysicsSystem.h>
|
|
#include <AzFramework/Physics/Ragdoll.h>
|
|
#include <AzFramework/Physics/SystemBus.h>
|
|
#include <AzFramework/Physics/Utils.h>
|
|
|
|
#include <IRenderAuxGeom.h>
|
|
#include <MathConversion.h>
|
|
|
|
#include <IConsole.h>
|
|
#include <StringUtils.h>
|
|
|
|
#include <PhysX/Debug/PhysXDebugInterface.h>
|
|
|
|
namespace PhysXDebug
|
|
{
|
|
const float SystemComponent::m_maxCullingBoxSize = 150.0f;
|
|
namespace Internal
|
|
{
|
|
const AZ::Crc32 VewportId = AzFramework::g_defaultSceneEntityDebugDisplayId;
|
|
}
|
|
|
|
bool UseEditorPhysicsScene()
|
|
{
|
|
// Runtime components are created when 'simulation' mode is enabled in the Editor,
|
|
// so we shouldn't use Editor physics scene in this case
|
|
return gEnv->IsEditing() && !gEnv->IsEditorSimulationMode();
|
|
}
|
|
|
|
void ReflectPhysXVisulizationSettings(AZ::ReflectContext* context)
|
|
{
|
|
if (auto serialize = azrtti_cast<AZ::SerializeContext*>(context))
|
|
{
|
|
serialize->Class<PhysXVisualizationSettings>()
|
|
->Version(1)
|
|
->Field("VisualizationEnabled", &PhysXVisualizationSettings::m_visualizationEnabled)
|
|
->Field("CollisionShapes", &PhysXVisualizationSettings::m_collisionShapes)
|
|
->Field("CollisionFNormals", &PhysXVisualizationSettings::m_collisionFNormals)
|
|
->Field("CollisionEdges", &PhysXVisualizationSettings::m_collisionEdges)
|
|
->Field("CollisionAabbs", &PhysXVisualizationSettings::m_collisionAabbs)
|
|
->Field("CollisionCompounds", &PhysXVisualizationSettings::m_collisionCompounds)
|
|
->Field("CollisionStatic", &PhysXVisualizationSettings::m_collisionStatic)
|
|
->Field("CollisionDynamic", &PhysXVisualizationSettings::m_collisionDynamic)
|
|
->Field("BodyAxis", &PhysXVisualizationSettings::m_bodyAxes)
|
|
->Field("BodyMassAxis", &PhysXVisualizationSettings::m_bodyMassAxes)
|
|
->Field("BodyLinVelocity", &PhysXVisualizationSettings::m_bodyLinVelocity)
|
|
->Field("BodyAngVelocity", &PhysXVisualizationSettings::m_bodyAngVelocity)
|
|
->Field("ContactPoint", &PhysXVisualizationSettings::m_contactPoint)
|
|
->Field("ContactNormal", &PhysXVisualizationSettings::m_contactNormal)
|
|
->Field("JointLocalFrames", &PhysXVisualizationSettings::m_jointLocalFrames)
|
|
->Field("JointLimits", &PhysXVisualizationSettings::m_jointLimits)
|
|
->Field("MbpRegions", &PhysXVisualizationSettings::m_mbpRegions)
|
|
->Field("ActorAxes", &PhysXVisualizationSettings::m_actorAxes);
|
|
|
|
if (AZ::EditContext* ec = serialize->GetEditContext())
|
|
{
|
|
ec->Class<PhysXVisualizationSettings>("PhysX Debug Draw Settings", "Settings to configure the PhysX Debug Visualization Gem properties.")
|
|
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
|
|
->DataElement(AZ::Edit::UIHandlers::CheckBox, &PhysXVisualizationSettings::m_visualizationEnabled, "Enable PhysX Debug Visualization", "")
|
|
->DataElement(AZ::Edit::UIHandlers::CheckBox, &PhysXVisualizationSettings::m_collisionShapes, "Collision Shapes", "Enable collision shapes")
|
|
->Attribute(AZ::Edit::Attributes::Visibility, &PhysXVisualizationSettings::IsPhysXDebugEnabled)
|
|
->DataElement(AZ::Edit::UIHandlers::CheckBox, &PhysXVisualizationSettings::m_collisionFNormals, "Collision FNormals", "Enable collision face normals")
|
|
->Attribute(AZ::Edit::Attributes::Visibility, &PhysXVisualizationSettings::IsPhysXDebugEnabled)
|
|
->DataElement(AZ::Edit::UIHandlers::CheckBox, &PhysXVisualizationSettings::m_collisionEdges, "Collision Edges", "Enable collision edges")
|
|
->Attribute(AZ::Edit::Attributes::Visibility, &PhysXVisualizationSettings::IsPhysXDebugEnabled)
|
|
->DataElement(AZ::Edit::UIHandlers::CheckBox, &PhysXVisualizationSettings::m_collisionAabbs, "Collision Aabbs", "Enable collision aabbs")
|
|
->Attribute(AZ::Edit::Attributes::Visibility, &PhysXVisualizationSettings::IsPhysXDebugEnabled)
|
|
->DataElement(AZ::Edit::UIHandlers::CheckBox, &PhysXVisualizationSettings::m_collisionCompounds, "Collision Compounds", "Enable collision compounds")
|
|
->Attribute(AZ::Edit::Attributes::Visibility, &PhysXVisualizationSettings::IsPhysXDebugEnabled)
|
|
->DataElement(AZ::Edit::UIHandlers::CheckBox, &PhysXVisualizationSettings::m_collisionStatic, "Collision Static", "Enable collision static")
|
|
->Attribute(AZ::Edit::Attributes::Visibility, &PhysXVisualizationSettings::IsPhysXDebugEnabled)
|
|
->DataElement(AZ::Edit::UIHandlers::CheckBox, &PhysXVisualizationSettings::m_collisionDynamic, "Collision Dynamic", "Enable collision dynamic")
|
|
->Attribute(AZ::Edit::Attributes::Visibility, &PhysXVisualizationSettings::IsPhysXDebugEnabled)
|
|
->DataElement(AZ::Edit::UIHandlers::CheckBox, &PhysXVisualizationSettings::m_bodyAxes, "Body Axis", "Enable body axis")
|
|
->Attribute(AZ::Edit::Attributes::Visibility, &PhysXVisualizationSettings::IsPhysXDebugEnabled)
|
|
->DataElement(AZ::Edit::UIHandlers::CheckBox, &PhysXVisualizationSettings::m_bodyMassAxes, "Body Mass Axis", "Enable body mass axis")
|
|
->Attribute(AZ::Edit::Attributes::Visibility, &PhysXVisualizationSettings::IsPhysXDebugEnabled)
|
|
->DataElement(AZ::Edit::UIHandlers::CheckBox, &PhysXVisualizationSettings::m_bodyLinVelocity, "Body Linear Velocity", "Enable body linear velocity")
|
|
->Attribute(AZ::Edit::Attributes::Visibility, &PhysXVisualizationSettings::IsPhysXDebugEnabled)
|
|
->DataElement(AZ::Edit::UIHandlers::CheckBox, &PhysXVisualizationSettings::m_bodyAngVelocity, "Body Angular Velocity", "Enable body angular velocity")
|
|
->Attribute(AZ::Edit::Attributes::Visibility, &PhysXVisualizationSettings::IsPhysXDebugEnabled)
|
|
->DataElement(AZ::Edit::UIHandlers::CheckBox, &PhysXVisualizationSettings::m_contactPoint, "Contact Point", "Enable contact point")
|
|
->Attribute(AZ::Edit::Attributes::Visibility, &PhysXVisualizationSettings::IsPhysXDebugEnabled)
|
|
->DataElement(AZ::Edit::UIHandlers::CheckBox, &PhysXVisualizationSettings::m_contactNormal, "Contact Normal", "Enable contact normal")
|
|
->Attribute(AZ::Edit::Attributes::Visibility, &PhysXVisualizationSettings::IsPhysXDebugEnabled)
|
|
->DataElement(AZ::Edit::UIHandlers::CheckBox, &PhysXVisualizationSettings::m_jointLocalFrames, "Joint Local Frames", "Enable joint local frames")
|
|
->Attribute(AZ::Edit::Attributes::Visibility, &PhysXVisualizationSettings::IsPhysXDebugEnabled)
|
|
->DataElement(AZ::Edit::UIHandlers::CheckBox, &PhysXVisualizationSettings::m_jointLimits, "Joint Limits", "Enable Joint limits")
|
|
->Attribute(AZ::Edit::Attributes::Visibility, &PhysXVisualizationSettings::IsPhysXDebugEnabled)
|
|
->DataElement(AZ::Edit::UIHandlers::CheckBox, &PhysXVisualizationSettings::m_mbpRegions, "MBP Regions", "Enable multi box pruning (MBP) regions")
|
|
->Attribute(AZ::Edit::Attributes::Visibility, &PhysXVisualizationSettings::IsPhysXDebugEnabled)
|
|
->DataElement(AZ::Edit::UIHandlers::CheckBox, &PhysXVisualizationSettings::m_actorAxes, "Actor Axes", "Enable actor axes")
|
|
->Attribute(AZ::Edit::Attributes::Visibility, &PhysXVisualizationSettings::IsPhysXDebugEnabled)
|
|
;
|
|
}
|
|
}
|
|
}
|
|
|
|
void ReflectPhysXCullingSettings(AZ::ReflectContext* context)
|
|
{
|
|
if (auto serialize = azrtti_cast<AZ::SerializeContext*>(context))
|
|
{
|
|
serialize->Class<Culling>()
|
|
->Version(1)
|
|
->Field("cullingBoxSize", &Culling::m_boxSize)
|
|
->Field("cullBox", &Culling::m_enabled)
|
|
->Field("cullBoxWireFrame", &Culling::m_boxWireframe)
|
|
;
|
|
|
|
if (AZ::EditContext* ec = serialize->GetEditContext())
|
|
{
|
|
ec->Class<Culling>("Culling Settings", "Settings to configure the PhysX Debug Visualization Culling.")
|
|
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
|
|
->DataElement(AZ::Edit::UIHandlers::CheckBox, &Culling::m_enabled, "Enable Box Culling", "Enable box culling")
|
|
->DataElement(AZ::Edit::UIHandlers::CheckBox, &Culling::m_boxWireframe, "Show Culling Box", "Visualize the culling box")
|
|
->DataElement(AZ::Edit::UIHandlers::Slider, &Culling::m_boxSize, "Culling Box Size", "Size of the culling box")
|
|
->Attribute(AZ::Edit::Attributes::Min, 1.0f)
|
|
->Attribute(AZ::Edit::Attributes::Max, 150.0f)
|
|
;
|
|
}
|
|
}
|
|
}
|
|
|
|
SystemComponent::SystemComponent()
|
|
: m_sceneFinishSimHandler([this](
|
|
[[maybe_unused]] AzPhysics::SceneHandle sceneHanle,
|
|
[[maybe_unused]] float fixedDeltatime)
|
|
{
|
|
this->m_editorPhysicsSceneDirty = true;
|
|
})
|
|
{
|
|
|
|
}
|
|
|
|
void SystemComponent::ReflectPhysXDebugSettings(AZ::ReflectContext* context)
|
|
{
|
|
if (auto serialize = azrtti_cast<AZ::SerializeContext*>(context))
|
|
{
|
|
serialize->Class<SystemComponent, AZ::Component>()
|
|
->Version(1)
|
|
->Field("physxDebugSettings", &SystemComponent::m_settings)
|
|
->Field("physxDebugCulling", &SystemComponent::m_culling)
|
|
;
|
|
|
|
if (AZ::EditContext* ec = serialize->GetEditContext())
|
|
{
|
|
ec->Class<SystemComponent>("PhysX Debug Visualization", "A debug visualization system component for PhysX.")
|
|
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
|
|
->Attribute(AZ::Edit::Attributes::Category, "PhysX")
|
|
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("System", 0xc94d118b))
|
|
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
|
|
->DataElement(AZ::Edit::UIHandlers::Default, &SystemComponent::m_settings, "Settings", "PhysX debug visualization settings")
|
|
->DataElement(AZ::Edit::UIHandlers::Default, &SystemComponent::m_culling, "Culling", "PhysX culling options")
|
|
;
|
|
}
|
|
}
|
|
}
|
|
|
|
void SystemComponent::OnCrySystemInitialized([[maybe_unused]] ISystem& system, const SSystemInitParams&)
|
|
{
|
|
InitPhysXColorMappings();
|
|
ConfigurePhysXVisualizationParameters();
|
|
}
|
|
|
|
void SystemComponent::Reflect(AZ::ReflectContext* context)
|
|
{
|
|
ReflectPhysXVisulizationSettings(context);
|
|
ReflectPhysXCullingSettings(context);
|
|
ReflectPhysXDebugSettings(context);
|
|
}
|
|
|
|
void SystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
|
|
{
|
|
provided.push_back(AZ_CRC("PhysXDebugService"));
|
|
}
|
|
|
|
void SystemComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
|
|
{
|
|
incompatible.push_back(AZ_CRC("PhysXDebugService"));
|
|
}
|
|
|
|
void SystemComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
|
|
{
|
|
required.push_back(AZ_CRC("PhysXService"));
|
|
#ifdef PHYSXDEBUG_GEM_EDITOR
|
|
required.push_back(AZ_CRC("PhysXEditorService"));
|
|
#endif // PHYSXDEBUG_GEM_EDITOR
|
|
}
|
|
|
|
void SystemComponent::GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent)
|
|
{
|
|
(void)dependent;
|
|
}
|
|
|
|
void SystemComponent::Activate()
|
|
{
|
|
PhysXDebugRequestBus::Handler::BusConnect();
|
|
AZ::TickBus::Handler::BusConnect();
|
|
CrySystemEventBus::Handler::BusConnect();
|
|
#ifdef IMGUI_ENABLED
|
|
ImGui::ImGuiUpdateListenerBus::Handler::BusConnect();
|
|
#endif // IMGUI_ENABLED
|
|
#ifdef PHYSXDEBUG_GEM_EDITOR
|
|
if (auto* sceneInterface = AZ::Interface<AzPhysics::SceneInterface>::Get())
|
|
{
|
|
AzPhysics::SceneHandle sceneHandle = sceneInterface->GetSceneHandle(AzPhysics::EditorPhysicsSceneName);
|
|
sceneInterface->RegisterSceneSimulationFinishHandler(sceneHandle, m_sceneFinishSimHandler);
|
|
}
|
|
#endif // PHYSXDEBUG_GEM_EDITOR
|
|
}
|
|
|
|
void SystemComponent::Deactivate()
|
|
{
|
|
#ifdef PHYSXDEBUG_GEM_EDITOR
|
|
m_sceneFinishSimHandler.Disconnect();
|
|
#endif // PHYSXDEBUG_GEM_EDITOR
|
|
#ifdef IMGUI_ENABLED
|
|
ImGui::ImGuiUpdateListenerBus::Handler::BusDisconnect();
|
|
#endif // IMGUI_ENABLED
|
|
CrySystemEventBus::Handler::BusDisconnect();
|
|
AZ::TickBus::Handler::BusDisconnect();
|
|
PhysXDebugRequestBus::Handler::BusDisconnect();
|
|
}
|
|
|
|
#ifdef IMGUI_ENABLED
|
|
void SystemComponent::OnImGuiMainMenuUpdate()
|
|
{
|
|
if (ImGui::BeginMenu("PhysX Debug"))
|
|
{
|
|
ImGui::Checkbox("Debug visualization", &m_settings.m_visualizationEnabled);
|
|
ImGui::Checkbox("Visualize Colliders", &m_settings.m_visualizeCollidersByProximity);
|
|
|
|
if (ImGui::BeginMenu("Culling"))
|
|
{
|
|
ImGui::Checkbox("Wireframe", &m_culling.m_boxWireframe);
|
|
ImGui::SliderFloat("Size", &m_culling.m_boxSize, 0, m_maxCullingBoxSize);
|
|
ImGui::EndMenu();
|
|
}
|
|
|
|
if (ImGui::BeginMenu("Collisions"))
|
|
{
|
|
ImGui::Checkbox("Shapes", &m_settings.m_collisionShapes);
|
|
ImGui::Checkbox("Edges", &m_settings.m_collisionEdges);
|
|
ImGui::Checkbox("F Normals", &m_settings.m_collisionFNormals);
|
|
ImGui::Checkbox("Aabbs", &m_settings.m_collisionAabbs);
|
|
ImGui::Checkbox("Axis", &m_settings.m_collisionAxes);
|
|
ImGui::Checkbox("Compounds", &m_settings.m_collisionCompounds);
|
|
ImGui::Checkbox("Static", &m_settings.m_collisionStatic);
|
|
ImGui::Checkbox("Dynamic", &m_settings.m_collisionDynamic);
|
|
ImGui::EndMenu();
|
|
}
|
|
|
|
if (ImGui::BeginMenu("Body"))
|
|
{
|
|
ImGui::Checkbox("Axes", &m_settings.m_bodyAxes);
|
|
ImGui::Checkbox("Mass Axes", &m_settings.m_bodyMassAxes);
|
|
ImGui::Checkbox("Linear Velocity", &m_settings.m_bodyLinVelocity);
|
|
ImGui::Checkbox("Angular Velocity", &m_settings.m_bodyAngVelocity);
|
|
ImGui::EndMenu();
|
|
}
|
|
|
|
if (ImGui::BeginMenu("Contact"))
|
|
{
|
|
ImGui::Checkbox("Point", &m_settings.m_contactPoint);
|
|
ImGui::Checkbox("Normal", &m_settings.m_contactNormal);
|
|
ImGui::EndMenu();
|
|
}
|
|
|
|
if (ImGui::BeginMenu("Character"))
|
|
{
|
|
ImGui::Checkbox("Joint Limits", &m_settings.m_jointLimits);
|
|
ImGui::Checkbox("Mbp Regions", &m_settings.m_mbpRegions);
|
|
ImGui::Checkbox("Actor Axes", &m_settings.m_actorAxes);
|
|
ImGui::EndMenu();
|
|
}
|
|
|
|
if (ImGui::BeginMenu("PhysX Color Mappings"))
|
|
{
|
|
BuildColorPickingMenuItem("Black", m_colorMappings.m_black);
|
|
BuildColorPickingMenuItem("Red", m_colorMappings.m_red);
|
|
BuildColorPickingMenuItem("Green", m_colorMappings.m_green);
|
|
BuildColorPickingMenuItem("Blue", m_colorMappings.m_blue);
|
|
BuildColorPickingMenuItem("Yellow", m_colorMappings.m_yellow);
|
|
BuildColorPickingMenuItem("Magenta", m_colorMappings.m_magenta);
|
|
BuildColorPickingMenuItem("Cyan", m_colorMappings.m_cyan);
|
|
BuildColorPickingMenuItem("White", m_colorMappings.m_white);
|
|
BuildColorPickingMenuItem("Grey", m_colorMappings.m_grey);
|
|
BuildColorPickingMenuItem("Dark Red", m_colorMappings.m_darkRed);
|
|
BuildColorPickingMenuItem("Dark Green", m_colorMappings.m_darkGreen);
|
|
BuildColorPickingMenuItem("Dark Blue", m_colorMappings.m_darkBlue);
|
|
|
|
if (ImGui::Button("Reset Color Mappings"))
|
|
{
|
|
InitPhysXColorMappings();
|
|
}
|
|
|
|
ImGui::EndMenu();
|
|
}
|
|
|
|
if (ImGui::Button("Enable/Disable all settings"))
|
|
{
|
|
ToggleVisualizationConfiguration();
|
|
}
|
|
|
|
ImGui::SliderFloat("PhysX Scale", &m_settings.m_scale, 1.0f, 10.0f);
|
|
ImGui::EndMenu();
|
|
}
|
|
}
|
|
|
|
void SystemComponent::BuildColorPickingMenuItem(const AZStd::string& label, AZ::Color& color)
|
|
{
|
|
float col[3] = {color.GetR(), color.GetG(), color.GetB()};
|
|
if (ImGui::ColorEdit3(label.c_str(), col, ImGuiColorEditFlags_NoAlpha))
|
|
{
|
|
const float r = AZ::GetClamp(col[0], 0.0f, 1.0f);
|
|
const float g = AZ::GetClamp(col[1], 0.0f, 1.0f);
|
|
const float b = AZ::GetClamp(col[2], 0.0f, 1.0f);
|
|
|
|
color.SetR(r);
|
|
color.SetG(g);
|
|
color.SetB(b);
|
|
}
|
|
}
|
|
#endif // IMGUI_ENABLED
|
|
|
|
static const physx::PxRenderBuffer& GetRenderBuffer(physx::PxScene* physxScene)
|
|
{
|
|
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Physics);
|
|
PHYSX_SCENE_READ_LOCK(physxScene);
|
|
return physxScene->getRenderBuffer();
|
|
}
|
|
|
|
void SystemComponent::ToggleCullingWireFrame()
|
|
{
|
|
m_culling.m_boxWireframe = !m_culling.m_boxWireframe;
|
|
}
|
|
|
|
void SystemComponent::ToggleVisualizationConfiguration()
|
|
{
|
|
const bool updatedValue = !m_settings.m_collisionFNormals;
|
|
|
|
m_settings.m_visualizeCollidersByProximity = updatedValue;
|
|
m_settings.m_collisionFNormals = updatedValue;
|
|
m_settings.m_collisionAabbs = updatedValue;
|
|
m_settings.m_collisionAxes = updatedValue;
|
|
m_settings.m_collisionCompounds = updatedValue;
|
|
m_settings.m_collisionStatic = updatedValue;
|
|
m_settings.m_collisionDynamic = updatedValue;
|
|
m_settings.m_bodyAxes = updatedValue;
|
|
m_settings.m_bodyMassAxes = updatedValue;
|
|
m_settings.m_bodyLinVelocity = updatedValue;
|
|
m_settings.m_bodyAngVelocity = updatedValue;
|
|
m_settings.m_contactPoint = updatedValue;
|
|
m_settings.m_contactNormal = updatedValue;
|
|
m_settings.m_jointLocalFrames = updatedValue;
|
|
m_settings.m_jointLimits = updatedValue;
|
|
m_settings.m_mbpRegions = updatedValue;
|
|
m_settings.m_actorAxes = updatedValue;
|
|
|
|
ConfigurePhysXVisualizationParameters();
|
|
}
|
|
|
|
void SystemComponent::SetVisualization(bool enabled)
|
|
{
|
|
m_settings.m_visualizationEnabled = enabled;
|
|
|
|
ConfigurePhysXVisualizationParameters();
|
|
}
|
|
|
|
void SystemComponent::ToggleColliderProximityDebugVisualization()
|
|
{
|
|
m_settings.m_visualizeCollidersByProximity = !m_settings.m_visualizeCollidersByProximity;
|
|
}
|
|
|
|
void SystemComponent::SetCullingBoxSize(float cullingBoxSize)
|
|
{
|
|
if (cullingBoxSize <= m_maxCullingBoxSize)
|
|
{
|
|
m_culling.m_enabled = true;
|
|
m_culling.m_boxSize = cullingBoxSize;
|
|
|
|
ConfigurePhysXVisualizationParameters();
|
|
ConfigureCullingBox();
|
|
}
|
|
}
|
|
|
|
physx::PxScene* SystemComponent::GetCurrentPxScene()
|
|
{
|
|
AzPhysics::SceneHandle sceneHandle;
|
|
|
|
if (UseEditorPhysicsScene())
|
|
{
|
|
// Editor scene needs to be ticked for debug rendering to work (taking place in EditorSystemComponent)
|
|
Physics::EditorWorldBus::BroadcastResult(sceneHandle, &Physics::EditorWorldRequests::GetEditorSceneHandle);
|
|
}
|
|
else
|
|
{
|
|
Physics::DefaultWorldBus::BroadcastResult(sceneHandle, &Physics::DefaultWorldRequests::GetDefaultSceneHandle);
|
|
}
|
|
|
|
if (auto* physicsSystem = AZ::Interface<AzPhysics::SystemInterface>::Get())
|
|
{
|
|
if (auto* scene = physicsSystem->GetScene(sceneHandle))
|
|
{
|
|
return static_cast<physx::PxScene*>(scene->GetNativePointer());
|
|
}
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
// TickBus::Handler
|
|
void SystemComponent::OnTick([[maybe_unused]] float deltaTime, AZ::ScriptTimePoint time)
|
|
{
|
|
if (!m_settings.IsPhysXDebugEnabled())
|
|
{
|
|
return;
|
|
}
|
|
|
|
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Physics);
|
|
m_currentTime = time;
|
|
bool dirty = true;
|
|
|
|
if (UseEditorPhysicsScene())
|
|
{
|
|
dirty = m_editorPhysicsSceneDirty;
|
|
}
|
|
|
|
UpdateColliderVisualizationByProximity();
|
|
|
|
if (dirty)
|
|
{
|
|
// The physics scene is dirty and contains changes to be gathered.
|
|
if (auto* scene = GetCurrentPxScene())
|
|
{
|
|
ConfigurePhysXVisualizationParameters();
|
|
ConfigureCullingBox();
|
|
|
|
ClearBuffers();
|
|
GatherBuffers();
|
|
|
|
m_editorPhysicsSceneDirty = false;
|
|
}
|
|
}
|
|
|
|
RenderBuffers();
|
|
}
|
|
|
|
void SystemComponent::UpdateColliderVisualizationByProximity()
|
|
{
|
|
if (auto* debug = AZ::Interface<PhysX::Debug::PhysXDebugInterface>::Get();
|
|
UseEditorPhysicsScene() && m_settings.m_visualizeCollidersByProximity
|
|
&& debug != nullptr)
|
|
{
|
|
const CCamera& camera = gEnv->pSystem->GetViewCamera();
|
|
const PhysX::Debug::ColliderProximityVisualization data(
|
|
m_settings.m_visualizeCollidersByProximity,
|
|
LYVec3ToAZVec3(camera.GetPosition()),
|
|
m_culling.m_boxSize * 0.5f);
|
|
debug->UpdateColliderProximityVisualization(data);
|
|
}
|
|
}
|
|
|
|
void SystemComponent::ClearBuffers()
|
|
{
|
|
m_linePoints.clear();
|
|
m_lineColors.clear();
|
|
m_trianglePoints.clear();
|
|
m_triangleColors.clear();
|
|
}
|
|
|
|
void SystemComponent::GatherBuffers()
|
|
{
|
|
physx::PxScene* physxScene = GetCurrentPxScene();
|
|
const physx::PxRenderBuffer& rb = GetRenderBuffer(physxScene);
|
|
GatherLines(rb);
|
|
GatherTriangles(rb);
|
|
GatherJointLimits();
|
|
}
|
|
|
|
void SystemComponent::RenderBuffers()
|
|
{
|
|
if (!m_linePoints.empty() || !m_trianglePoints.empty())
|
|
{
|
|
AzFramework::DebugDisplayRequestBus::BusPtr debugDisplayBus;
|
|
AzFramework::DebugDisplayRequestBus::Bind(debugDisplayBus, Internal::VewportId);
|
|
AZ_Assert(debugDisplayBus, "Invalid DebugDisplayRequestBus.");
|
|
AzFramework::DebugDisplayRequests* debugDisplay = AzFramework::DebugDisplayRequestBus::FindFirstHandler(debugDisplayBus);
|
|
if (debugDisplay)
|
|
{
|
|
if (!m_linePoints.empty())
|
|
{
|
|
AZ_Assert(m_linePoints.size() == m_lineColors.size(), "Lines: Expected an equal number of points to colors.");
|
|
const size_t minLen = AZ::GetMin(m_linePoints.size(), m_lineColors.size());
|
|
for (size_t i = 0; i < minLen; i += 2)
|
|
{
|
|
debugDisplay->DrawLine(m_linePoints[i], m_linePoints[i + 1], m_lineColors[i].GetAsVector4(), m_lineColors[i + 1].GetAsVector4());
|
|
}
|
|
}
|
|
if (!m_trianglePoints.empty())
|
|
{
|
|
AZ_Assert(m_trianglePoints.size() == m_triangleColors.size(), "Triangles: Expected an equal number of points to colors.");
|
|
const size_t minLen = AZ::GetMin(m_trianglePoints.size(), m_triangleColors.size());
|
|
for (size_t i = 0; i < minLen; i += 3)
|
|
{
|
|
debugDisplay->SetColor(m_triangleColors[i]);
|
|
debugDisplay->DrawTri(m_trianglePoints[i], m_trianglePoints[i + 1], m_trianglePoints[i + 2]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void physx_CullingBox([[maybe_unused]] const AZ::ConsoleCommandContainer& arguments)
|
|
{
|
|
PhysXDebug::PhysXDebugRequestBus::Broadcast(&PhysXDebug::PhysXDebugRequestBus::Events::ToggleCullingWireFrame);
|
|
}
|
|
AZ_CONSOLEFREEFUNC(physx_CullingBox, AZ::ConsoleFunctorFlags::DontReplicate, "Enables physx wireframe view");
|
|
|
|
static void physx_PvdConnect([[maybe_unused]] const AZ::ConsoleCommandContainer& arguments)
|
|
{
|
|
auto* debug = AZ::Interface<PhysX::Debug::PhysXDebugInterface>::Get();
|
|
if (debug)
|
|
{
|
|
debug->ConnectToPvd();
|
|
}
|
|
}
|
|
AZ_CONSOLEFREEFUNC(physx_PvdConnect, AZ::ConsoleFunctorFlags::DontReplicate, "Connects to the physx visual debugger");
|
|
|
|
static void physx_PvdDisconnect([[maybe_unused]] const AZ::ConsoleCommandContainer& arguments)
|
|
{
|
|
auto* debug = AZ::Interface<PhysX::Debug::PhysXDebugInterface>::Get();
|
|
if (debug)
|
|
{
|
|
debug->DisconnectFromPvd();
|
|
}
|
|
}
|
|
AZ_CONSOLEFREEFUNC(physx_PvdDisconnect, AZ::ConsoleFunctorFlags::DontReplicate, "Disconnects from the physx visual debugger");
|
|
|
|
static void physx_CullingBoxSize([[maybe_unused]] const AZ::ConsoleCommandContainer& arguments)
|
|
{
|
|
const int argumentCount = arguments.size();
|
|
if (argumentCount == 1)
|
|
{
|
|
float newCullingBoxSize = (float)strtol(AZ::CVarFixedString(arguments[0]).c_str(), nullptr, 10);
|
|
PhysXDebug::PhysXDebugRequestBus::Broadcast(&PhysXDebug::PhysXDebugRequestBus::Events::SetCullingBoxSize, newCullingBoxSize);
|
|
}
|
|
else
|
|
{
|
|
AZ_Warning("PhysXDebug", false, "Invalid physx_SetDebugCullingBoxSize Arguments. "
|
|
"Please use physx_SetDebugCullingBoxSize <boxSize> e.g. physx_SetDebugCullingBoxSize 100.");
|
|
}
|
|
}
|
|
AZ_CONSOLEFREEFUNC(physx_CullingBoxSize, AZ::ConsoleFunctorFlags::DontReplicate, "Sets physx debug culling box size");
|
|
|
|
static void physx_Debug([[maybe_unused]] const AZ::ConsoleCommandContainer& arguments)
|
|
{
|
|
const int argumentCount = arguments.size();
|
|
|
|
if (argumentCount == 1)
|
|
{
|
|
const auto userPreference = static_cast<DebugCVarValues>(strtol(AZ::CVarFixedString(arguments[0]).c_str(), nullptr, 10));
|
|
|
|
switch (userPreference)
|
|
{
|
|
case DebugCVarValues::Enable:
|
|
PhysXDebug::PhysXDebugRequestBus::Broadcast(&PhysXDebug::PhysXDebugRequestBus::Events::SetVisualization, true);
|
|
break;
|
|
case DebugCVarValues::Disable:
|
|
PhysXDebug::PhysXDebugRequestBus::Broadcast(&PhysXDebug::PhysXDebugRequestBus::Events::SetVisualization, false);
|
|
break;
|
|
case DebugCVarValues::SwitchConfigurationPreference:
|
|
PhysXDebug::PhysXDebugRequestBus::Broadcast(&PhysXDebug::PhysXDebugRequestBus::Events::ToggleVisualizationConfiguration);
|
|
break;
|
|
case DebugCVarValues::ColliderProximityDebug:
|
|
PhysXDebug::PhysXDebugRequestBus::Broadcast(&PhysXDebug::PhysXDebugRequestBus::Events::ToggleColliderProximityDebugVisualization);
|
|
break;
|
|
default:
|
|
AZ_Warning("PhysXDebug", false, "Unknown user preference used.");
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
AZ_Warning("PhysXDebug", false, "Invalid physx_Debug Arguments. Please use physx_Debug 1 to enable, physx_Debug 0 to disable or physx_Debug 2 to enable all configuration settings.");
|
|
}
|
|
}
|
|
AZ_CONSOLEFREEFUNC(physx_Debug, AZ::ConsoleFunctorFlags::DontReplicate, "Toggles physx debug visualization");
|
|
|
|
void SystemComponent::ConfigurePhysXVisualizationParameters()
|
|
{
|
|
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Physics);
|
|
|
|
if (physx::PxScene* physxScene = GetCurrentPxScene())
|
|
{
|
|
PHYSX_SCENE_WRITE_LOCK(physxScene);
|
|
|
|
// Warning: if "mScale" is enabled, then debug visualization data will be available and requested from PhysX
|
|
// this however creates a "significant performance impact" !
|
|
// we do however provide culling (as default), however this will only cull eCOLLISION_SHAPES, eCOLLISION_FNORMALS and eCOLLISION_EDGES.
|
|
// if you enabled more settings, we will culling them but the data will still be made available in physX but simply will not be rendered in the viewport.
|
|
// https://docs.nvidia.com/gameworks/content/gameworkslibrary/physx/guide/Manual/DebugVisualization.html
|
|
|
|
if (!m_settings.m_visualizationEnabled)
|
|
{
|
|
physxScene->setVisualizationParameter(physx::PxVisualizationParameter::eSCALE, 0.0f);
|
|
}
|
|
else
|
|
{
|
|
physxScene->setVisualizationParameter(physx::PxVisualizationParameter::eSCALE, m_settings.m_scale);
|
|
}
|
|
|
|
physxScene->setVisualizationParameter(physx::PxVisualizationParameter::eCOLLISION_SHAPES, m_settings.m_collisionShapes ? 1.0f : 0.0f);
|
|
physxScene->setVisualizationParameter(physx::PxVisualizationParameter::eCOLLISION_FNORMALS, m_settings.m_collisionFNormals ? 1.0f : 0.0f);
|
|
physxScene->setVisualizationParameter(physx::PxVisualizationParameter::eCOLLISION_EDGES, m_settings.m_collisionEdges ? 1.0f : 0.0f);
|
|
|
|
physxScene->setVisualizationParameter(physx::PxVisualizationParameter::eCOLLISION_AABBS, m_settings.m_collisionAabbs ? 1.0f : 0.0f);
|
|
physxScene->setVisualizationParameter(physx::PxVisualizationParameter::eBODY_AXES, m_settings.m_bodyAxes ? 1.0f : 0.0f);
|
|
physxScene->setVisualizationParameter(physx::PxVisualizationParameter::eBODY_MASS_AXES, m_settings.m_bodyMassAxes ? 1.0f : 0.0f);
|
|
physxScene->setVisualizationParameter(physx::PxVisualizationParameter::eBODY_LIN_VELOCITY, m_settings.m_bodyLinVelocity ? 1.0f : 0.0f);
|
|
physxScene->setVisualizationParameter(physx::PxVisualizationParameter::eBODY_ANG_VELOCITY, m_settings.m_bodyAngVelocity ? 1.0f : 0.0f);
|
|
physxScene->setVisualizationParameter(physx::PxVisualizationParameter::eCONTACT_POINT, m_settings.m_contactPoint ? 1.0f : 0.0f);
|
|
physxScene->setVisualizationParameter(physx::PxVisualizationParameter::eCONTACT_NORMAL, m_settings.m_contactNormal ? 1.0f : 0.0f);
|
|
physxScene->setVisualizationParameter(physx::PxVisualizationParameter::eCOLLISION_AXES, m_settings.m_collisionAxes ? 1.0f : 0.0f);
|
|
physxScene->setVisualizationParameter(physx::PxVisualizationParameter::eCOLLISION_COMPOUNDS, m_settings.m_collisionCompounds ? 1.0f : 0.0f);
|
|
physxScene->setVisualizationParameter(physx::PxVisualizationParameter::eCOLLISION_STATIC, m_settings.m_collisionStatic ? 1.0f : 0.0f);
|
|
physxScene->setVisualizationParameter(physx::PxVisualizationParameter::eCOLLISION_DYNAMIC, m_settings.m_collisionDynamic ? 1.0f : 0.0f);
|
|
physxScene->setVisualizationParameter(physx::PxVisualizationParameter::eJOINT_LOCAL_FRAMES, m_settings.m_jointLocalFrames ? 1.0f : 0.0f);
|
|
physxScene->setVisualizationParameter(physx::PxVisualizationParameter::eJOINT_LIMITS, m_settings.m_jointLimits ? 1.0f : 0.0f);
|
|
physxScene->setVisualizationParameter(physx::PxVisualizationParameter::eMBP_REGIONS, m_settings.m_mbpRegions ? 1.0f : 0.0f);
|
|
physxScene->setVisualizationParameter(physx::PxVisualizationParameter::eACTOR_AXES, m_settings.m_actorAxes ? 1.0f : 0.0f);
|
|
|
|
physxScene->setVisualizationParameter(physx::PxVisualizationParameter::eCULL_BOX, m_culling.m_enabled ? 1.0f : 0.0f);
|
|
}
|
|
}
|
|
|
|
void SystemComponent::ConfigureCullingBox()
|
|
{
|
|
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Physics);
|
|
|
|
// Currently using the Cry view camera to support Editor, Game and Launcher modes. This will be updated in due course.
|
|
const CCamera& camera = gEnv->pSystem->GetViewCamera();
|
|
AZ::Vector3 cameraTranslation = LYVec3ToAZVec3(camera.GetPosition());
|
|
|
|
if (!cameraTranslation.IsClose(AZ::Vector3::CreateZero()))
|
|
{
|
|
const physx::PxVec3 min = PxMathConvert(cameraTranslation - AZ::Vector3(m_culling.m_boxSize));
|
|
const physx::PxVec3 max = PxMathConvert(cameraTranslation + AZ::Vector3(m_culling.m_boxSize));
|
|
m_cullingBox = physx::PxBounds3(min, max);
|
|
|
|
if (m_culling.m_boxWireframe)
|
|
{
|
|
const AZ::Aabb cullingBoxAabb = AZ::Aabb::CreateFromMinMax(PxMathConvert(min), PxMathConvert(max));
|
|
DrawDebugCullingBox(cullingBoxAabb);
|
|
}
|
|
|
|
if (physx::PxScene* physxScene = GetCurrentPxScene())
|
|
{
|
|
PHYSX_SCENE_WRITE_LOCK(physxScene);
|
|
physxScene->setVisualizationCullingBox(m_cullingBox);
|
|
}
|
|
}
|
|
}
|
|
|
|
void SystemComponent::GatherTriangles(const physx::PxRenderBuffer& rb)
|
|
{
|
|
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Physics);
|
|
if (!m_settings.m_visualizationEnabled)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (GetCurrentPxScene())
|
|
{
|
|
// Reserve vector capacity
|
|
const int numTriangles = rb.getNbTriangles();
|
|
m_trianglePoints.reserve(numTriangles * 3);
|
|
m_triangleColors.reserve(numTriangles * 3);
|
|
|
|
for (physx::PxU32 triangleIndex = 0; triangleIndex < numTriangles; ++triangleIndex)
|
|
{
|
|
const physx::PxDebugTriangle& triangle = rb.getTriangles()[triangleIndex];
|
|
|
|
if (!m_culling.m_enabled ||
|
|
(m_cullingBox.contains(triangle.pos0) && m_cullingBox.contains(triangle.pos1) && m_cullingBox.contains(triangle.pos2)))
|
|
{
|
|
m_trianglePoints.emplace_back(PxMathConvert(triangle.pos0));
|
|
m_trianglePoints.emplace_back(PxMathConvert(triangle.pos1));
|
|
m_trianglePoints.emplace_back(PxMathConvert(triangle.pos2));
|
|
|
|
m_triangleColors.emplace_back(MapOriginalPhysXColorToUserDefinedValues(triangle.color0));
|
|
m_triangleColors.emplace_back(MapOriginalPhysXColorToUserDefinedValues(triangle.color1));
|
|
m_triangleColors.emplace_back(MapOriginalPhysXColorToUserDefinedValues(triangle.color2));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void SystemComponent::GatherLines(const physx::PxRenderBuffer& rb)
|
|
{
|
|
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Physics);
|
|
|
|
if (!m_settings.m_visualizationEnabled)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (GetCurrentPxScene())
|
|
{
|
|
const int numLines = rb.getNbLines();
|
|
|
|
// Reserve vector capacity
|
|
m_linePoints.reserve(numLines * 2);
|
|
m_lineColors.reserve(numLines * 2);
|
|
|
|
for (physx::PxU32 lineIndex = 0; lineIndex < numLines; ++lineIndex)
|
|
{
|
|
const physx::PxDebugLine& line = rb.getLines()[lineIndex];
|
|
|
|
// Bespoke culling of lines on top of the provided PhysX 3.4 box culling.
|
|
// if culling is enabled we will perform additional culling as required.
|
|
if (!m_culling.m_enabled || (m_cullingBox.contains(line.pos0) && m_cullingBox.contains(line.pos1)))
|
|
{
|
|
m_linePoints.emplace_back(PxMathConvert(line.pos0));
|
|
m_linePoints.emplace_back(PxMathConvert(line.pos1));
|
|
|
|
m_lineColors.emplace_back(MapOriginalPhysXColorToUserDefinedValues(line.color0));
|
|
m_lineColors.emplace_back(MapOriginalPhysXColorToUserDefinedValues(line.color0));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void SystemComponent::GatherJointLimits()
|
|
{
|
|
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Physics);
|
|
|
|
physx::PxScene* scene = GetCurrentPxScene();
|
|
|
|
// The PhysX debug render buffer does not seem to include joint limits, even when
|
|
// PxVisualizationParameter::eJOINT_LIMITS is set, so they are separately added to the line buffer here.
|
|
if (m_settings.m_jointLimits && scene)
|
|
{
|
|
const physx::PxU32 numConstraints = scene->getNbConstraints();
|
|
for (physx::PxU32 constraintIndex = 0; constraintIndex < numConstraints; constraintIndex++)
|
|
{
|
|
physx::PxConstraint* constraint;
|
|
scene->getConstraints(&constraint, 1, constraintIndex);
|
|
physx::PxRigidActor* actor0;
|
|
physx::PxRigidActor* actor1;
|
|
constraint->getActors(actor0, actor1);
|
|
|
|
PhysX::ActorData* actorData = PhysX::Utils::GetUserData(actor1);
|
|
if (actorData)
|
|
{
|
|
Physics::RagdollNode* ragdollNode = actorData->GetRagdollNode();
|
|
if (ragdollNode)
|
|
{
|
|
AzPhysics::Joint* joint = ragdollNode->GetJoint();
|
|
physx::PxJoint* pxJoint = static_cast<physx::PxJoint*>(joint->GetNativePointer());
|
|
physx::PxTransform jointPose = actor1->getGlobalPose() * pxJoint->getLocalPose(physx::PxJointActorIndex::eACTOR1);
|
|
if (!m_culling.m_enabled || m_cullingBox.contains(jointPose.p))
|
|
{
|
|
m_jointVertexBuffer.clear();
|
|
m_jointIndexBuffer.clear();
|
|
m_jointLineBuffer.clear();
|
|
m_jointLineValidityBuffer.clear();
|
|
|
|
joint->GenerateJointLimitVisualizationData(0.1f, 32, 2, m_jointVertexBuffer,
|
|
m_jointIndexBuffer, m_jointLineBuffer, m_jointLineValidityBuffer);
|
|
|
|
physx::PxTransform jointWorldTransformPx = actor0->getGlobalPose();
|
|
jointWorldTransformPx.p = jointPose.p;
|
|
AZ::Transform jointWorldTransform = PxMathConvert(jointWorldTransformPx);
|
|
|
|
const size_t jointLineBufferSize = m_jointLineBuffer.size();
|
|
|
|
m_linePoints.reserve((m_linePoints.size() + jointLineBufferSize));
|
|
m_lineColors.reserve((m_lineColors.size() + jointLineBufferSize));
|
|
|
|
for (size_t lineIndex = 0; lineIndex < jointLineBufferSize / 2; lineIndex++)
|
|
{
|
|
m_linePoints.emplace_back(jointWorldTransform.TransformPoint(m_jointLineBuffer[2 * lineIndex]));
|
|
m_linePoints.emplace_back(jointWorldTransform.TransformPoint(m_jointLineBuffer[2 * lineIndex + 1]));
|
|
m_lineColors.emplace_back(m_colorMappings.m_green);
|
|
m_lineColors.emplace_back(m_colorMappings.m_green);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void SystemComponent::DrawDebugCullingBox(const AZ::Aabb& cullingBoxAabb)
|
|
{
|
|
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Physics);
|
|
|
|
if (m_settings.m_visualizationEnabled && m_culling.m_boxWireframe)
|
|
{
|
|
AzFramework::DebugDisplayRequestBus::BusPtr debugDisplayBus;
|
|
AzFramework::DebugDisplayRequestBus::Bind(debugDisplayBus, Internal::VewportId);
|
|
AZ_Assert(debugDisplayBus, "Invalid DebugDisplayRequestBus.");
|
|
if (AzFramework::DebugDisplayRequests* debugDisplay = AzFramework::DebugDisplayRequestBus::FindFirstHandler(debugDisplayBus))
|
|
{
|
|
const AZ::Color wireframeColor = MapOriginalPhysXColorToUserDefinedValues(1);
|
|
debugDisplay->SetColor(wireframeColor.GetAsVector4());
|
|
debugDisplay->DrawWireBox(cullingBoxAabb.GetMin(), cullingBoxAabb.GetMax());
|
|
}
|
|
}
|
|
}
|
|
|
|
AZ::Color SystemComponent::MapOriginalPhysXColorToUserDefinedValues(const physx::PxU32& originalColor)
|
|
{
|
|
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Physics);
|
|
|
|
// color mapping from PhysX to LY user preference: \PhysX_3.4\Include\common\PxRenderBuffer.h
|
|
switch (static_cast<physx::PxDebugColor::Enum>(originalColor))
|
|
{
|
|
case physx::PxDebugColor::eARGB_BLACK:
|
|
return m_colorMappings.m_black;
|
|
case physx::PxDebugColor::eARGB_RED:
|
|
return m_colorMappings.m_red;
|
|
case physx::PxDebugColor::eARGB_GREEN:
|
|
return m_colorMappings.m_green;
|
|
case physx::PxDebugColor::eARGB_BLUE:
|
|
return m_colorMappings.m_blue;
|
|
case physx::PxDebugColor::eARGB_YELLOW:
|
|
return m_colorMappings.m_yellow;
|
|
case physx::PxDebugColor::eARGB_MAGENTA:
|
|
return m_colorMappings.m_magenta;
|
|
case physx::PxDebugColor::eARGB_CYAN:
|
|
return m_colorMappings.m_cyan;
|
|
case physx::PxDebugColor::eARGB_WHITE:
|
|
return m_colorMappings.m_white;
|
|
case physx::PxDebugColor::eARGB_GREY:
|
|
return m_colorMappings.m_grey;
|
|
case physx::PxDebugColor::eARGB_DARKRED:
|
|
return m_colorMappings.m_darkRed;
|
|
case physx::PxDebugColor::eARGB_DARKGREEN:
|
|
return m_colorMappings.m_darkGreen;
|
|
case physx::PxDebugColor::eARGB_DARKBLUE:
|
|
return m_colorMappings.m_darkBlue;
|
|
default:
|
|
return m_colorMappings.m_defaultColor;
|
|
}
|
|
}
|
|
|
|
void SystemComponent::InitPhysXColorMappings()
|
|
{
|
|
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Physics);
|
|
m_colorMappings.m_defaultColor.FromU32(physx::PxDebugColor::eARGB_GREEN);
|
|
m_colorMappings.m_black.FromU32(physx::PxDebugColor::eARGB_BLACK);
|
|
m_colorMappings.m_red.FromU32(physx::PxDebugColor::eARGB_RED);
|
|
m_colorMappings.m_green.FromU32(physx::PxDebugColor::eARGB_GREEN);
|
|
m_colorMappings.m_blue.FromU32(physx::PxDebugColor::eARGB_BLUE);
|
|
m_colorMappings.m_yellow.FromU32(physx::PxDebugColor::eARGB_YELLOW);
|
|
m_colorMappings.m_magenta.FromU32(physx::PxDebugColor::eARGB_MAGENTA);
|
|
m_colorMappings.m_cyan.FromU32(physx::PxDebugColor::eARGB_CYAN);
|
|
m_colorMappings.m_white.FromU32(physx::PxDebugColor::eARGB_WHITE);
|
|
m_colorMappings.m_grey.FromU32(physx::PxDebugColor::eARGB_GREY);
|
|
m_colorMappings.m_darkRed.FromU32(physx::PxDebugColor::eARGB_DARKRED);
|
|
m_colorMappings.m_darkGreen.FromU32(physx::PxDebugColor::eARGB_DARKGREEN);
|
|
m_colorMappings.m_darkBlue.FromU32(physx::PxDebugColor::eARGB_DARKBLUE);
|
|
}
|
|
}
|