diff --git a/Source/Engine/Physics/Joints/D6Joint.cpp b/Source/Engine/Physics/Joints/D6Joint.cpp index 5a2e2bff1..c19eb719d 100644 --- a/Source/Engine/Physics/Joints/D6Joint.cpp +++ b/Source/Engine/Physics/Joints/D6Joint.cpp @@ -196,6 +196,73 @@ float D6Joint::GetCurrentSwingZAngle() const return _joint ? static_cast(_joint)->getSwingZAngle() : 0.0f; } +#if USE_EDITOR + +#include "Engine/Debug/DebugDraw.h" + +float GetAngle(float angle, D6JointMotion motion) +{ + switch (motion) + { + case D6JointMotion::Limited: + return angle * DegreesToRadians; + case D6JointMotion::Free: + return PI; + default: + return 0.0f; + } +} + +void D6Joint::OnDebugDrawSelected() +{ + const Vector3 source = GetPosition(); + const Vector3 target = GetTargetPosition(); + const Quaternion sourceRotation = GetOrientation(); + const Quaternion targetRotation = GetTargetOrientation(); + const float swingSize = 15.0f; + const float twistSize = 9.0f; + const Color swingColor = Color::Green.AlphaMultiplied(0.6f); + const Color twistColor = Color::Yellow.AlphaMultiplied(0.5f); + DebugDraw::DrawWireArrow(source, sourceRotation, swingSize / 100.0f * 0.5f, Color::Red, 0, false); + if (_motion[(int32)D6JointAxis::SwingY] == D6JointMotion::Locked && _motion[(int32)D6JointAxis::SwingZ] == D6JointMotion::Locked) + { + // Swing is locked + } + else if (_motion[(int32)D6JointAxis::SwingY] == D6JointMotion::Free && _motion[(int32)D6JointAxis::SwingZ] == D6JointMotion::Free) + { + // Swing is free + DEBUG_DRAW_SPHERE(BoundingSphere(source, swingSize), swingColor, 0, false); + } + else + { + // Swing is limited + const float angleY = GetAngle(_limitSwing.YLimitAngle, _motion[(int32)D6JointAxis::SwingY]); + const float angleZ = GetAngle(_limitSwing.ZLimitAngle, _motion[(int32)D6JointAxis::SwingZ]); + DEBUG_DRAW_CONE(source, sourceRotation, swingSize, angleY, angleZ, swingColor, 0, false); + } + if (_motion[(int32)D6JointAxis::Twist] == D6JointMotion::Locked) + { + // Twist is locked + } + else if (_motion[(int32)D6JointAxis::Twist] == D6JointMotion::Free) + { + // Twist is free + DEBUG_DRAW_ARC(source, sourceRotation, twistSize, TWO_PI, twistColor, 0, false); + } + else + { + // Twist is limited + const float lower = _limitTwist.Lower * DegreesToRadians; + const float upper = Math::Max(lower, _limitTwist.Upper * DegreesToRadians); + DEBUG_DRAW_ARC(source, sourceRotation * Quaternion::Euler(0, 0, lower), twistSize, upper - lower, twistColor, 0, false); + } + + // Base + Joint::OnDebugDrawSelected(); +} + +#endif + void D6Joint::Serialize(SerializeStream& stream, const void* otherObj) { // Base diff --git a/Source/Engine/Physics/Joints/D6Joint.h b/Source/Engine/Physics/Joints/D6Joint.h index 111caccba..7274ae503 100644 --- a/Source/Engine/Physics/Joints/D6Joint.h +++ b/Source/Engine/Physics/Joints/D6Joint.h @@ -161,7 +161,7 @@ public: /// /// Physics joint that is the most customizable type of joint. This joint type can be used to create all other built-in joint -/// types, and to design your own custom ones, but is less intuitive to use.Allows a specification of a linear +/// types, and to design your own custom ones, but is less intuitive to use. Allows a specification of a linear /// constraint (for example for a slider), twist constraint (rotating around X) and swing constraint (rotating around Y and Z). /// It also allows you to constrain limits to only specific axes or completely lock specific axes. /// @@ -325,6 +325,9 @@ public: public: // [Joint] +#if USE_EDITOR + void OnDebugDrawSelected() override; +#endif void Serialize(SerializeStream& stream, const void* otherObj) override; void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override; diff --git a/Source/Engine/Physics/Joints/DistanceJoint.cpp b/Source/Engine/Physics/Joints/DistanceJoint.cpp index 770bbdc18..5df279801 100644 --- a/Source/Engine/Physics/Joints/DistanceJoint.cpp +++ b/Source/Engine/Physics/Joints/DistanceJoint.cpp @@ -88,6 +88,39 @@ float DistanceJoint::GetCurrentDistance() const return _joint ? static_cast(_joint)->getDistance() : 0.0f; } +#if USE_EDITOR + +#include "Engine/Debug/DebugDraw.h" + +void DistanceJoint::OnDebugDrawSelected() +{ + const Vector3 source = GetPosition(); + const Vector3 target = GetTargetPosition(); + Vector3 dir = target - source; + const float len = dir.Length(); + dir *= 1.0f / len; + Vector3 start = source, end = target; + float max = 0, min = 0; + if (_flags & DistanceJointFlag::MinDistance) + { + min = Math::Min(_minDistance, len); + start += dir * min; + DEBUG_DRAW_LINE(source, start, Color::Red * 0.6f, 0, false); + } + if (_flags & DistanceJointFlag::MaxDistance) + { + max = Math::Min(_maxDistance, len - min); + end -= dir * max; + DEBUG_DRAW_LINE(end, target, Color::Red * 0.6f, 0, false); + } + DEBUG_DRAW_LINE(start, end, Color::Green * 0.6f, 0, false); + + // Base + Joint::OnDebugDrawSelected(); +} + +#endif + void DistanceJoint::Serialize(SerializeStream& stream, const void* otherObj) { // Base diff --git a/Source/Engine/Physics/Joints/DistanceJoint.h b/Source/Engine/Physics/Joints/DistanceJoint.h index 245bc7bea..05dad5d0c 100644 --- a/Source/Engine/Physics/Joints/DistanceJoint.h +++ b/Source/Engine/Physics/Joints/DistanceJoint.h @@ -148,6 +148,9 @@ public: public: // [Joint] +#if USE_EDITOR + void OnDebugDrawSelected() override; +#endif void Serialize(SerializeStream& stream, const void* otherObj) override; void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override; diff --git a/Source/Engine/Physics/Joints/FixedJoint.cpp b/Source/Engine/Physics/Joints/FixedJoint.cpp index b163a78f2..7c01e3e3c 100644 --- a/Source/Engine/Physics/Joints/FixedJoint.cpp +++ b/Source/Engine/Physics/Joints/FixedJoint.cpp @@ -9,6 +9,20 @@ FixedJoint::FixedJoint(const SpawnParams& params) { } +#if USE_EDITOR + +#include "Engine/Debug/DebugDraw.h" + +void FixedJoint::OnDebugDrawSelected() +{ + DEBUG_DRAW_LINE(GetPosition(), GetTargetPosition(), Color::BlueViolet * 0.6f, 0, false); + + // Base + Joint::OnDebugDrawSelected(); +} + +#endif + PxJoint* FixedJoint::CreateJoint(JointData& data) { const PxTransform trans0(C2P(data.Pos0), C2P(data.Rot0)); diff --git a/Source/Engine/Physics/Joints/FixedJoint.h b/Source/Engine/Physics/Joints/FixedJoint.h index 35fa74016..d2ee0f583 100644 --- a/Source/Engine/Physics/Joints/FixedJoint.h +++ b/Source/Engine/Physics/Joints/FixedJoint.h @@ -11,6 +11,13 @@ API_CLASS() class FLAXENGINE_API FixedJoint : public Joint { DECLARE_SCENE_OBJECT(FixedJoint); +public: + + // [Joint] +#if USE_EDITOR + void OnDebugDrawSelected() override; +#endif + protected: // [Joint] diff --git a/Source/Engine/Physics/Joints/HingeJoint.cpp b/Source/Engine/Physics/Joints/HingeJoint.cpp index 4f30e5319..1d100d4ae 100644 --- a/Source/Engine/Physics/Joints/HingeJoint.cpp +++ b/Source/Engine/Physics/Joints/HingeJoint.cpp @@ -73,6 +73,40 @@ float HingeJoint::GetCurrentVelocity() const return _joint ? static_cast(_joint)->getVelocity() : 0.0f; } +#if USE_EDITOR + +#include "Engine/Debug/DebugDraw.h" + +void HingeJoint::OnDebugDrawSelected() +{ + const Vector3 source = GetPosition(); + const Vector3 target = GetTargetPosition(); + const Quaternion xRotation = Quaternion::LookRotation(Vector3::UnitX, Vector3::UnitY); + const Quaternion sourceRotation = GetOrientation() * xRotation; + const Quaternion targetRotation = GetTargetOrientation() * xRotation; + const float size = 15.0f; + const Color color = Color::Green.AlphaMultiplied(0.6f); + DebugDraw::DrawWireArrow(source, sourceRotation, size / 100.0f * 0.5f, Color::Red, 0, false); + DebugDraw::DrawWireArrow(target, targetRotation, size / 100.0f * 0.5f, Color::Blue, 0, false); + if (_flags & HingeJointFlag::Limit) + { + const float upper = Math::Max(_limit.Upper, _limit.Lower); + const float range = Math::Abs(upper - _limit.Lower); + DEBUG_DRAW_ARC(source, sourceRotation * Quaternion::Euler(0, 0, _limit.Lower - 90.0f), size, range * DegreesToRadians, color, 0, false); + DEBUG_DRAW_WIRE_ARC(source, sourceRotation * Quaternion::Euler(0, 0, upper - 90.0f), size, (360.0f - range) * DegreesToRadians, Color::Red.AlphaMultiplied(0.6f), 0, false); + } + else + { + DEBUG_DRAW_ARC(source, sourceRotation, size, TWO_PI, color, 0, false); + } + DEBUG_DRAW_LINE(source, target, Color::Green * 0.6f, 0, false); + + // Base + Joint::OnDebugDrawSelected(); +} + +#endif + void HingeJoint::Serialize(SerializeStream& stream, const void* otherObj) { // Base diff --git a/Source/Engine/Physics/Joints/HingeJoint.h b/Source/Engine/Physics/Joints/HingeJoint.h index 92ce9e3a2..cea8a30ff 100644 --- a/Source/Engine/Physics/Joints/HingeJoint.h +++ b/Source/Engine/Physics/Joints/HingeJoint.h @@ -156,6 +156,9 @@ public: public: // [Joint] +#if USE_EDITOR + void OnDebugDrawSelected() override; +#endif void Serialize(SerializeStream& stream, const void* otherObj) override; void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override; diff --git a/Source/Engine/Physics/Joints/Joint.cpp b/Source/Engine/Physics/Joints/Joint.cpp index 984d90ba1..d688041ff 100644 --- a/Source/Engine/Physics/Joints/Joint.cpp +++ b/Source/Engine/Physics/Joints/Joint.cpp @@ -168,26 +168,44 @@ void Joint::OnTargetChanged() } } +Vector3 Joint::GetTargetPosition() const +{ + Vector3 position = _targetAnchor; + if (Target) + { + position = Target->GetOrientation() * position + Target->GetPosition(); + } + return position; +} + +Quaternion Joint::GetTargetOrientation() const +{ + Quaternion rotation = _targetAnchorRotation; + if (Target) + { + rotation = Target->GetOrientation() * rotation; + } + return rotation; +} + #if USE_EDITOR #include "Engine/Debug/DebugDraw.h" +#include "Engine/Graphics/RenderView.h" void Joint::DrawPhysicsDebug(RenderView& view) { - DEBUG_DRAW_WIRE_SPHERE(BoundingSphere(GetPosition(), 3.0f), Color::BlueViolet * 0.8f, 0, true); - if (Target) + if (view.Mode == ViewMode::PhysicsColliders) { - DEBUG_DRAW_WIRE_SPHERE(BoundingSphere(Target->GetPosition() + _targetAnchor, 4.0f), Color::AliceBlue * 0.8f, 0, true); + DEBUG_DRAW_WIRE_SPHERE(BoundingSphere(GetPosition(), 3.0f), Color::BlueViolet * 0.8f, 0, true); + DEBUG_DRAW_WIRE_SPHERE(BoundingSphere(GetTargetPosition(), 4.0f), Color::AliceBlue * 0.8f, 0, true); } } void Joint::OnDebugDrawSelected() { DEBUG_DRAW_WIRE_SPHERE(BoundingSphere(GetPosition(), 3.0f), Color::BlueViolet * 0.8f, 0, false); - if (Target) - { - DEBUG_DRAW_WIRE_SPHERE(BoundingSphere(Target->GetPosition() + _targetAnchor, 4.0f), Color::AliceBlue * 0.8f, 0, false); - } + DEBUG_DRAW_WIRE_SPHERE(BoundingSphere(GetTargetPosition(), 4.0f), Color::AliceBlue * 0.8f, 0, false); // Base Actor::OnDebugDrawSelected(); diff --git a/Source/Engine/Physics/Joints/Joint.h b/Source/Engine/Physics/Joints/Joint.h index e8da71c91..f2950874f 100644 --- a/Source/Engine/Physics/Joints/Joint.h +++ b/Source/Engine/Physics/Joints/Joint.h @@ -137,8 +137,6 @@ public: /// The result angular force. API_FUNCTION() void GetCurrentForce(API_PARAM(Out) Vector3& linear, API_PARAM(Out) Vector3& angular) const; -public: - /// /// Creates native join object. /// @@ -169,16 +167,18 @@ protected: Vector3 Pos1; }; + Vector3 GetTargetPosition() const; + Quaternion GetTargetOrientation() const; virtual PxJoint* CreateJoint(JointData& data) = 0; +#if USE_EDITOR + virtual void DrawPhysicsDebug(RenderView& view); +#endif private: void Delete(); void SetActors(); void OnTargetChanged(); -#if USE_EDITOR - void DrawPhysicsDebug(RenderView& view); -#endif public: diff --git a/Source/Engine/Physics/Joints/SliderJoint.cpp b/Source/Engine/Physics/Joints/SliderJoint.cpp index 46318bd2d..8b04dae68 100644 --- a/Source/Engine/Physics/Joints/SliderJoint.cpp +++ b/Source/Engine/Physics/Joints/SliderJoint.cpp @@ -56,6 +56,30 @@ float SliderJoint::GetCurrentVelocity() const return _joint ? static_cast(_joint)->getVelocity() : 0.0f; } +#if USE_EDITOR + +#include "Engine/Debug/DebugDraw.h" + +void SliderJoint::OnDebugDrawSelected() +{ + const Vector3 source = GetPosition(); + const Vector3 normal = GetOrientation() * Vector3::Right; + float min = -100.0f, max = 100.0f; + if (_flags & SliderJointFlag::Limit) + { + min = _limit.Lower; + max = _limit.Upper; + if (max < min) + Swap(min, max); + } + DEBUG_DRAW_LINE(source + normal * min, source + normal * max, Color::Green * 0.6f, 0, false); + + // Base + Joint::OnDebugDrawSelected(); +} + +#endif + void SliderJoint::Serialize(SerializeStream& stream, const void* otherObj) { // Base diff --git a/Source/Engine/Physics/Joints/SliderJoint.h b/Source/Engine/Physics/Joints/SliderJoint.h index 432e61c35..b9a11c0a0 100644 --- a/Source/Engine/Physics/Joints/SliderJoint.h +++ b/Source/Engine/Physics/Joints/SliderJoint.h @@ -86,6 +86,9 @@ public: public: // [Joint] +#if USE_EDITOR + void OnDebugDrawSelected() override; +#endif void Serialize(SerializeStream& stream, const void* otherObj) override; void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override; diff --git a/Source/Engine/Physics/Joints/SphericalJoint.cpp b/Source/Engine/Physics/Joints/SphericalJoint.cpp index c1874c3fc..83a959e51 100644 --- a/Source/Engine/Physics/Joints/SphericalJoint.cpp +++ b/Source/Engine/Physics/Joints/SphericalJoint.cpp @@ -43,6 +43,33 @@ void SphericalJoint::SetLimit(const LimitConeRange& value) } } +#if USE_EDITOR + +#include "Engine/Debug/DebugDraw.h" + +void SphericalJoint::OnDebugDrawSelected() +{ + const Vector3 source = GetPosition(); + const Vector3 target = GetTargetPosition(); + const float size = 15.0f; + const Color color = Color::Green.AlphaMultiplied(0.6f); + DebugDraw::DrawWireArrow(source, GetOrientation(), size / 100.0f * 0.5f, Color::Red, 0, false); + if (_flags & SphericalJointFlag::Limit) + { + DEBUG_DRAW_CONE(source, GetOrientation(), size, _limit.YLimitAngle * DegreesToRadians, _limit.ZLimitAngle * DegreesToRadians, color, 0, false); + } + else + { + DEBUG_DRAW_SPHERE(BoundingSphere(source, size), color, 0, false); + } + DEBUG_DRAW_LINE(source, target, Color::Green * 0.6f, 0, false); + + // Base + Joint::OnDebugDrawSelected(); +} + +#endif + void SphericalJoint::Serialize(SerializeStream& stream, const void* otherObj) { // Base diff --git a/Source/Engine/Physics/Joints/SphericalJoint.h b/Source/Engine/Physics/Joints/SphericalJoint.h index c2df39808..67d7e8e07 100644 --- a/Source/Engine/Physics/Joints/SphericalJoint.h +++ b/Source/Engine/Physics/Joints/SphericalJoint.h @@ -76,6 +76,9 @@ public: public: // [Joint] +#if USE_EDITOR + void OnDebugDrawSelected() override; +#endif void Serialize(SerializeStream& stream, const void* otherObj) override; void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override;