Merge branch 'rot-colliders' of https://github.com/Tryibion/FlaxEngine into Tryibion-rot-colliders
# Conflicts: # Source/Engine/Physics/Colliders/CapsuleCollider.cpp # Source/Engine/Physics/Colliders/Collider.cpp
This commit is contained in:
@@ -6,7 +6,9 @@ CapsuleCollider::CapsuleCollider(const SpawnParams& params)
|
||||
: Collider(params)
|
||||
, _radius(20.0f)
|
||||
, _height(100.0f)
|
||||
, _direction(ColliderOrientationDirection::YAxis)
|
||||
{
|
||||
SetColliderDirection(_direction);
|
||||
}
|
||||
|
||||
void CapsuleCollider::SetRadius(const float value)
|
||||
@@ -31,6 +33,24 @@ void CapsuleCollider::SetHeight(const float value)
|
||||
UpdateBounds();
|
||||
}
|
||||
|
||||
void CapsuleCollider::SetColliderDirection(ColliderOrientationDirection value)
|
||||
{
|
||||
_direction = value;
|
||||
switch (value)
|
||||
{
|
||||
case ColliderOrientationDirection::XAxis:
|
||||
SetColliderOrientation(Quaternion::Identity);
|
||||
break;
|
||||
case ColliderOrientationDirection::YAxis:
|
||||
SetColliderOrientation(Quaternion::Euler(0, 0, 90));
|
||||
break;
|
||||
case ColliderOrientationDirection::ZAxis:
|
||||
SetColliderOrientation(Quaternion::Euler(0, 90, 0));
|
||||
break;
|
||||
default: ;
|
||||
}
|
||||
}
|
||||
|
||||
#if USE_EDITOR
|
||||
|
||||
#include "Engine/Debug/DebugDraw.h"
|
||||
@@ -41,8 +61,10 @@ void CapsuleCollider::DrawPhysicsDebug(RenderView& view)
|
||||
const BoundingSphere sphere(_sphere.Center - view.Origin, _sphere.Radius);
|
||||
if (!view.CullingFrustum.Intersects(sphere))
|
||||
return;
|
||||
Quaternion collRot;
|
||||
Quaternion::Multiply( _colliderOrientation, Quaternion::Euler(0, 90, 0), collRot);
|
||||
Quaternion rotation;
|
||||
Quaternion::Multiply(_transform.Orientation, Quaternion::Euler(0, 90, 0), rotation);
|
||||
Quaternion::Multiply(_transform.Orientation, collRot, rotation);
|
||||
const float scaling = _cachedScale.GetAbsolute().MaxValue();
|
||||
const float minSize = 0.001f;
|
||||
const float radius = Math::Max(Math::Abs(_radius) * scaling, minSize);
|
||||
@@ -55,8 +77,10 @@ void CapsuleCollider::DrawPhysicsDebug(RenderView& view)
|
||||
|
||||
void CapsuleCollider::OnDebugDrawSelected()
|
||||
{
|
||||
Quaternion collRot;
|
||||
Quaternion::Multiply( _colliderOrientation, Quaternion::Euler(0, 90, 0), collRot);
|
||||
Quaternion rotation;
|
||||
Quaternion::Multiply(_transform.Orientation, Quaternion::Euler(0, 90, 0), rotation);
|
||||
Quaternion::Multiply(_transform.Orientation, collRot, rotation);
|
||||
const float scaling = _cachedScale.GetAbsolute().MaxValue();
|
||||
const float minSize = 0.001f;
|
||||
const float radius = Math::Max(Math::Abs(_radius) * scaling, minSize);
|
||||
@@ -85,7 +109,11 @@ void CapsuleCollider::UpdateBounds()
|
||||
// Cache bounds
|
||||
const float radiusTwice = _radius * 2.0f;
|
||||
OrientedBoundingBox::CreateCentered(_center, Vector3(_height + radiusTwice, radiusTwice, radiusTwice), _orientedBox);
|
||||
_orientedBox.Transform(_transform);
|
||||
Transform transform = _transform;
|
||||
Quaternion rot;
|
||||
Quaternion::Multiply(transform.Orientation, _colliderOrientation, rot);
|
||||
transform.Orientation = rot;
|
||||
_orientedBox.Transform(transform);
|
||||
_orientedBox.GetBoundingBox(_box);
|
||||
BoundingSphere::FromBox(_box, _sphere);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,27 @@
|
||||
#include "Collider.h"
|
||||
#include "Engine/Core/Math/OrientedBoundingBox.h"
|
||||
|
||||
/// <summary>
|
||||
/// The collider orientation direction.
|
||||
/// </summary>
|
||||
API_ENUM() enum class ColliderOrientationDirection
|
||||
{
|
||||
/// <summary>
|
||||
/// Orient to the X-Axis.
|
||||
/// </summary>
|
||||
XAxis,
|
||||
|
||||
/// <summary>
|
||||
/// Orient to the Y-Axis.
|
||||
/// </summary>
|
||||
YAxis,
|
||||
|
||||
/// <summary>
|
||||
/// Orient to the Z-Axis.
|
||||
/// </summary>
|
||||
ZAxis
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// A capsule-shaped primitive collider.
|
||||
/// </summary>
|
||||
@@ -19,6 +40,7 @@ private:
|
||||
float _radius;
|
||||
float _height;
|
||||
OrientedBoundingBox _orientedBox;
|
||||
ColliderOrientationDirection _direction;
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
@@ -53,6 +75,20 @@ public:
|
||||
/// <remarks>The capsule height will be scaled by the actor's world scale.</remarks>
|
||||
API_PROPERTY() void SetHeight(float value);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the orientation direction of the capsule collider.
|
||||
/// </summary>
|
||||
API_PROPERTY(Attributes="EditorOrder(111), DefaultValue(typeof(ColliderOrientationDirection), \"YAxis\"), EditorDisplay(\"Collider\")")
|
||||
FORCE_INLINE ColliderOrientationDirection GetColliderDirection() const
|
||||
{
|
||||
return _direction;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the orientation direction of the capsule collider.
|
||||
/// </summary>
|
||||
API_PROPERTY() void SetColliderDirection(ColliderOrientationDirection value);
|
||||
|
||||
public:
|
||||
// [Collider]
|
||||
#if USE_EDITOR
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
Collider::Collider(const SpawnParams& params)
|
||||
: PhysicsColliderActor(params)
|
||||
, _center(Float3::Zero)
|
||||
, _colliderOrientation(Quaternion::Identity)
|
||||
, _isTrigger(false)
|
||||
, _shape(nullptr)
|
||||
, _staticActor(nullptr)
|
||||
@@ -44,11 +45,36 @@ void Collider::SetCenter(const Vector3& value)
|
||||
_center = value;
|
||||
if (_staticActor)
|
||||
{
|
||||
PhysicsBackend::SetShapeLocalPose(_shape, _center, Quaternion::Identity);
|
||||
Quaternion result;
|
||||
Quaternion::Multiply(Quaternion::Identity, _colliderOrientation, result);
|
||||
PhysicsBackend::SetShapeLocalPose(_shape, _center, result);
|
||||
}
|
||||
else if (const RigidBody* rigidBody = GetAttachedRigidBody())
|
||||
{
|
||||
PhysicsBackend::SetShapeLocalPose(_shape, (_localTransform.Translation + _localTransform.Orientation * _center) * rigidBody->GetScale(), _localTransform.Orientation);
|
||||
Quaternion result;
|
||||
Quaternion::Multiply(_localTransform.Orientation, _colliderOrientation, result);
|
||||
PhysicsBackend::SetShapeLocalPose(_shape, (_localTransform.Translation + result * _center) * rigidBody->GetScale(), result);
|
||||
}
|
||||
UpdateBounds();
|
||||
}
|
||||
|
||||
void Collider::SetColliderOrientation(const Quaternion& value)
|
||||
{
|
||||
|
||||
if (Quaternion::NearEqual(value, _colliderOrientation))
|
||||
return;
|
||||
_colliderOrientation = value;
|
||||
if (_staticActor)
|
||||
{
|
||||
Quaternion result;
|
||||
Quaternion::Multiply(Quaternion::Identity, _colliderOrientation, result);
|
||||
PhysicsBackend::SetShapeLocalPose(_shape, _center, result);
|
||||
}
|
||||
else if (const RigidBody* rigidBody = GetAttachedRigidBody())
|
||||
{
|
||||
Quaternion result;
|
||||
Quaternion::Multiply(_localTransform.Orientation, _colliderOrientation, result);
|
||||
PhysicsBackend::SetShapeLocalPose(_shape, (_localTransform.Translation + result * _center) * rigidBody->GetScale(), result);
|
||||
}
|
||||
UpdateBounds();
|
||||
}
|
||||
@@ -168,8 +194,10 @@ void Collider::Attach(RigidBody* rigidBody)
|
||||
|
||||
// Attach
|
||||
PhysicsBackend::AttachShape(_shape, rigidBody->GetPhysicsActor());
|
||||
_cachedLocalPosePos = (_localTransform.Translation + _localTransform.Orientation * _center) * rigidBody->GetScale();
|
||||
_cachedLocalPoseRot = _localTransform.Orientation;
|
||||
Quaternion result;
|
||||
Quaternion::Multiply(_localTransform.Orientation, _colliderOrientation, result);
|
||||
_cachedLocalPosePos = (_localTransform.Translation + result * _center) * rigidBody->GetScale();
|
||||
_cachedLocalPoseRot = result;
|
||||
PhysicsBackend::SetShapeLocalPose(_shape, _cachedLocalPosePos, _cachedLocalPoseRot);
|
||||
if (rigidBody->IsDuringPlay())
|
||||
{
|
||||
@@ -261,7 +289,9 @@ void Collider::CreateStaticActor()
|
||||
_staticActor = PhysicsBackend::CreateRigidStaticActor(nullptr, _transform.Translation, _transform.Orientation, scene);
|
||||
|
||||
// Reset local pos of the shape and link it to the actor
|
||||
PhysicsBackend::SetShapeLocalPose(_shape, _center, Quaternion::Identity);
|
||||
Quaternion result;
|
||||
Quaternion::Multiply(Quaternion::Identity, _colliderOrientation, result);
|
||||
PhysicsBackend::SetShapeLocalPose(_shape, _center, result);
|
||||
PhysicsBackend::AttachShape(_shape, _staticActor);
|
||||
|
||||
PhysicsBackend::AddSceneActor(scene, _staticActor);
|
||||
@@ -404,15 +434,19 @@ void Collider::OnTransformChanged()
|
||||
|
||||
if (_staticActor)
|
||||
{
|
||||
PhysicsBackend::SetRigidActorPose(_staticActor, _transform.Translation, _transform.Orientation);
|
||||
Quaternion result;
|
||||
Quaternion::Multiply(_localTransform.Orientation, _colliderOrientation, result);
|
||||
PhysicsBackend::SetRigidActorPose(_staticActor, _transform.Translation, result);
|
||||
}
|
||||
else if (const RigidBody* rigidBody = GetAttachedRigidBody())
|
||||
{
|
||||
const Vector3 localPosePos = (_localTransform.Translation + _localTransform.Orientation * _center) * rigidBody->GetScale();
|
||||
if (_cachedLocalPosePos != localPosePos || _cachedLocalPoseRot != _localTransform.Orientation)
|
||||
Quaternion result;
|
||||
Quaternion::Multiply(_localTransform.Orientation, _colliderOrientation, result);
|
||||
const Vector3 localPosePos = (_localTransform.Translation + result * _center) * rigidBody->GetScale();
|
||||
if (_cachedLocalPosePos != localPosePos || _cachedLocalPoseRot != result)
|
||||
{
|
||||
_cachedLocalPosePos = localPosePos;
|
||||
_cachedLocalPoseRot = _localTransform.Orientation;
|
||||
_cachedLocalPoseRot = result;
|
||||
PhysicsBackend::SetShapeLocalPose(_shape, localPosePos, _cachedLocalPoseRot);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ API_CLASS(Abstract) class FLAXENGINE_API Collider : public PhysicsColliderActor
|
||||
DECLARE_SCENE_OBJECT_ABSTRACT(Collider);
|
||||
protected:
|
||||
Vector3 _center;
|
||||
Quaternion _colliderOrientation;
|
||||
bool _isTrigger;
|
||||
void* _shape;
|
||||
void* _staticActor;
|
||||
@@ -77,6 +78,19 @@ public:
|
||||
/// </summary>
|
||||
API_PROPERTY() void SetContactOffset(float value);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the collider's orientation, measured in the object's local space.
|
||||
/// </summary>
|
||||
FORCE_INLINE Quaternion GetColliderOrientation() const
|
||||
{
|
||||
return _colliderOrientation;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the orientation of the collider, measured in the object's local space.
|
||||
/// </summary>
|
||||
void SetColliderOrientation(const Quaternion& value);
|
||||
|
||||
/// <summary>
|
||||
/// The physical material used to define the collider physical properties.
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user