Add improvements for joints editing with debug shapes

This commit is contained in:
Wojtek Figat
2021-09-29 10:02:38 +02:00
parent 5c60281814
commit 3d1213d669
14 changed files with 252 additions and 13 deletions

View File

@@ -196,6 +196,73 @@ float D6Joint::GetCurrentSwingZAngle() const
return _joint ? static_cast<PxD6Joint*>(_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

View File

@@ -161,7 +161,7 @@ public:
/// <summary>
/// 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.
/// </summary>
@@ -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;

View File

@@ -88,6 +88,39 @@ float DistanceJoint::GetCurrentDistance() const
return _joint ? static_cast<PxDistanceJoint*>(_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

View File

@@ -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;

View File

@@ -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));

View File

@@ -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]

View File

@@ -73,6 +73,40 @@ float HingeJoint::GetCurrentVelocity() const
return _joint ? static_cast<PxRevoluteJoint*>(_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

View File

@@ -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;

View File

@@ -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();

View File

@@ -137,8 +137,6 @@ public:
/// <param name="angular">The result angular force.</param>
API_FUNCTION() void GetCurrentForce(API_PARAM(Out) Vector3& linear, API_PARAM(Out) Vector3& angular) const;
public:
/// <summary>
/// Creates native join object.
/// </summary>
@@ -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:

View File

@@ -56,6 +56,30 @@ float SliderJoint::GetCurrentVelocity() const
return _joint ? static_cast<PxPrismaticJoint*>(_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

View File

@@ -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;

View File

@@ -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

View File

@@ -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;