Added support for composite colliders
This commit is contained in:
parent
0460d776b0
commit
b2645fb584
|
@ -45,7 +45,7 @@
|
||||||
NumberOfChildren: 0
|
NumberOfChildren: 0
|
||||||
Components:
|
Components:
|
||||||
Camera Component:
|
Camera Component:
|
||||||
Position: {x: 0, y: 4, z: 5}
|
Position: {x: 0, y: 2, z: 5}
|
||||||
Pitch: 0
|
Pitch: 0
|
||||||
Yaw: 0
|
Yaw: 0
|
||||||
Roll: 0
|
Roll: 0
|
||||||
|
@ -62,14 +62,14 @@
|
||||||
NumberOfChildren: 0
|
NumberOfChildren: 0
|
||||||
Components:
|
Components:
|
||||||
Transform Component:
|
Transform Component:
|
||||||
Translate: {x: -1.45715916, y: 7, z: 0.0329093337}
|
Translate: {x: -1.45715916, y: 7, z: 0.227711335}
|
||||||
Rotate: {x: -0, y: 0, z: -0}
|
Rotate: {x: -0, y: 0, z: -0}
|
||||||
Scale: {x: 1, y: 1, z: 1}
|
Scale: {x: 1, y: 1, z: 1}
|
||||||
IsActive: true
|
IsActive: true
|
||||||
RigidBody Component:
|
RigidBody Component:
|
||||||
Type: Dynamic
|
Type: Dynamic
|
||||||
Auto Mass: false
|
Auto Mass: false
|
||||||
Mass: 1
|
Mass: 0.52359879
|
||||||
Drag: 0.00999999978
|
Drag: 0.00999999978
|
||||||
Angular Drag: 0.00999999978
|
Angular Drag: 0.00999999978
|
||||||
Use Gravity: true
|
Use Gravity: true
|
||||||
|
@ -77,7 +77,7 @@
|
||||||
Interpolate: true
|
Interpolate: true
|
||||||
Sleeping Enabled: true
|
Sleeping Enabled: true
|
||||||
Freeze Position X: false
|
Freeze Position X: false
|
||||||
Freeze Position Y: false
|
Freeze Position Y: true
|
||||||
Freeze Position Z: false
|
Freeze Position Z: false
|
||||||
Freeze Rotation X: false
|
Freeze Rotation X: false
|
||||||
Freeze Rotation Y: false
|
Freeze Rotation Y: false
|
||||||
|
@ -95,6 +95,15 @@
|
||||||
Density: 1
|
Density: 1
|
||||||
Position Offset: {x: 0, y: 0, z: 0}
|
Position Offset: {x: 0, y: 0, z: 0}
|
||||||
Rotation Offset: {x: 0, y: 0, z: 0}
|
Rotation Offset: {x: 0, y: 0, z: 0}
|
||||||
|
- Is Trigger: false
|
||||||
|
Collision Tag: 1
|
||||||
|
Type: Sphere
|
||||||
|
Radius: 0.5
|
||||||
|
Friction: 0.400000006
|
||||||
|
Bounciness: 0
|
||||||
|
Density: 1
|
||||||
|
Position Offset: {x: 0.75, y: 0.5, z: 0}
|
||||||
|
Rotation Offset: {x: 0, y: 0, z: 0}
|
||||||
IsActive: true
|
IsActive: true
|
||||||
Scripts:
|
Scripts:
|
||||||
- Type: PhysicsTestObj
|
- Type: PhysicsTestObj
|
||||||
|
|
|
@ -251,8 +251,15 @@ namespace SHADE
|
||||||
|
|
||||||
if(rbType == SHRigidBodyComponent::Type::DYNAMIC) //Dynamic only fields
|
if(rbType == SHRigidBodyComponent::Type::DYNAMIC) //Dynamic only fields
|
||||||
{
|
{
|
||||||
SHEditorWidgets::CheckBox("Use Gravity", [component]{return component->IsGravityEnabled();}, [component](bool const& value){component->SetIsGravityEnabled(value);}, "Gravity");
|
SHEditorWidgets::CheckBox("Use Gravity", [component]{return component->IsGravityEnabled();}, [component](bool const& value){component->SetIsGravityEnabled(value);}, "Whether Gravity is enabled for this body");
|
||||||
SHEditorWidgets::DragFloat("Gravity Scale", [component] { return component->GetGravityScale(); }, [component](float const& value) { component->SetGravityScale(value); }, "Gravity Scale", 0.1f, 0.0f);
|
SHEditorWidgets::DragFloat("Gravity Scale", [component] { return component->GetGravityScale(); }, [component](float const& value) { component->SetGravityScale(value); }, "Gravity Scale", 0.1f, 0.0f);
|
||||||
|
|
||||||
|
SHEditorWidgets::CheckBox("Auto Mass", [component]{return component->GetAutoMass();}, [component](bool const& value){component->SetAutoMass(value);}, "If mass should be automatically computed");
|
||||||
|
|
||||||
|
const bool autoMass = component->GetAutoMass();
|
||||||
|
if (autoMass)
|
||||||
|
SHEditorWidgets::DragFloat("Mass", [component] {return component->GetMass(); }, [component](float const& value) {}, "Mass", 0.1f, 0.0f, 0.0f, "%.3f", ImGuiSliderFlags_ReadOnly);
|
||||||
|
else
|
||||||
SHEditorWidgets::DragFloat("Mass", [component] {return component->GetMass(); }, [component](float const& value) {component->SetMass(value); }, "Mass");
|
SHEditorWidgets::DragFloat("Mass", [component] {return component->GetMass(); }, [component](float const& value) {component->SetMass(value); }, "Mass");
|
||||||
}
|
}
|
||||||
if (rbType == SHRigidBodyComponent::Type::DYNAMIC || rbType == SHRigidBodyComponent::Type::KINEMATIC) //Dynamic or Kinematic only fields
|
if (rbType == SHRigidBodyComponent::Type::DYNAMIC || rbType == SHRigidBodyComponent::Type::KINEMATIC) //Dynamic or Kinematic only fields
|
||||||
|
|
|
@ -147,11 +147,6 @@ namespace SHADE
|
||||||
return relativeExtents;
|
return relativeExtents;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHQuaternion SHBoxCollisionShape::GetOrientation() const noexcept
|
|
||||||
{
|
|
||||||
return Orientation;
|
|
||||||
}
|
|
||||||
|
|
||||||
SHVec3 SHBoxCollisionShape::GetVertex(int index) const
|
SHVec3 SHBoxCollisionShape::GetVertex(int index) const
|
||||||
{
|
{
|
||||||
static constexpr int NUM_VERTICES = 8;
|
static constexpr int NUM_VERTICES = 8;
|
||||||
|
@ -160,41 +155,6 @@ namespace SHADE
|
||||||
throw std::invalid_argument("Index out-of-range!");
|
throw std::invalid_argument("Index out-of-range!");
|
||||||
|
|
||||||
return GetVertices()[index];
|
return GetVertices()[index];
|
||||||
|
|
||||||
//// Rotate half extents
|
|
||||||
//const SHVec3 ROTATED_EXTENTS = SHVec3::Rotate(Extents, Orientation);
|
|
||||||
//const SHVec3 CENTER { Center };
|
|
||||||
|
|
||||||
///*
|
|
||||||
// * Front: -Z
|
|
||||||
// *
|
|
||||||
// * 3 _____ 2
|
|
||||||
// * | |
|
|
||||||
// * | |
|
|
||||||
// * |_____|
|
|
||||||
// * 0 1
|
|
||||||
// *
|
|
||||||
// * Back: +Z
|
|
||||||
// *
|
|
||||||
// * 7 _____ 6
|
|
||||||
// * | |
|
|
||||||
// * | |
|
|
||||||
// * |_____|
|
|
||||||
// * 4 5
|
|
||||||
// *
|
|
||||||
// */
|
|
||||||
|
|
||||||
//switch (index)
|
|
||||||
//{
|
|
||||||
// case 0: return CENTER + SHVec3 { -ROTATED_EXTENTS.x, -ROTATED_EXTENTS.y, -ROTATED_EXTENTS.z }
|
|
||||||
// case 1: return CENTER + SHVec3 {
|
|
||||||
// case 2: return CENTER + SHVec3 {
|
|
||||||
// case 3: return CENTER + SHVec3 {
|
|
||||||
// case 4: return CENTER + SHVec3 {
|
|
||||||
// case 5: return CENTER + SHVec3 {
|
|
||||||
// case 6: return CENTER + SHVec3 {
|
|
||||||
// case 7: return CENTER + SHVec3 {
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SHVec3 SHBoxCollisionShape::GetNormal(int faceIndex) const
|
SHVec3 SHBoxCollisionShape::GetNormal(int faceIndex) const
|
||||||
|
@ -204,7 +164,26 @@ namespace SHADE
|
||||||
|
|
||||||
// Rotate normal into world space
|
// Rotate normal into world space
|
||||||
return SHVec3::Rotate(LOCAL_NORMAL, Orientation);
|
return SHVec3::Rotate(LOCAL_NORMAL, Orientation);
|
||||||
|
}
|
||||||
|
|
||||||
|
SHVec3 SHBoxCollisionShape::GetPosition() const noexcept
|
||||||
|
{
|
||||||
|
return Center;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHQuaternion SHBoxCollisionShape::GetOrientation() const noexcept
|
||||||
|
{
|
||||||
|
return Orientation;
|
||||||
|
}
|
||||||
|
|
||||||
|
float SHBoxCollisionShape::GetVolume() const noexcept
|
||||||
|
{
|
||||||
|
return Volume();
|
||||||
|
}
|
||||||
|
|
||||||
|
SHVec3 SHBoxCollisionShape::GetLocalCentroid() const noexcept
|
||||||
|
{
|
||||||
|
return SHVec3::Zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -75,11 +75,15 @@ namespace SHADE
|
||||||
[[nodiscard]] SHVec3 GetCenter () const noexcept;
|
[[nodiscard]] SHVec3 GetCenter () const noexcept;
|
||||||
[[nodiscard]] SHVec3 GetWorldExtents () const noexcept;
|
[[nodiscard]] SHVec3 GetWorldExtents () const noexcept;
|
||||||
[[nodiscard]] SHVec3 GetRelativeExtents () const noexcept;
|
[[nodiscard]] SHVec3 GetRelativeExtents () const noexcept;
|
||||||
[[nodiscard]] SHQuaternion GetOrientation () const noexcept;
|
|
||||||
|
|
||||||
[[nodiscard]] SHVec3 GetVertex (int index) const override;
|
[[nodiscard]] SHVec3 GetVertex (int index) const override;
|
||||||
[[nodiscard]] SHVec3 GetNormal (int faceIndex) const override;
|
[[nodiscard]] SHVec3 GetNormal (int faceIndex) const override;
|
||||||
|
|
||||||
|
[[nodiscard]] SHVec3 GetPosition () const noexcept override;
|
||||||
|
[[nodiscard]] SHQuaternion GetOrientation () const noexcept override;
|
||||||
|
[[nodiscard]] float GetVolume () const noexcept override;
|
||||||
|
[[nodiscard]] SHVec3 GetLocalCentroid () const noexcept override;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Setter Functions */
|
/* Setter Functions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include "SHCollisionShape.h"
|
#include "SHCollisionShape.h"
|
||||||
|
|
||||||
// Project Headers
|
// Project Headers
|
||||||
|
#include "Physics/Collision/SHCollider.h"
|
||||||
#include "Physics/Collision/CollisionTags/SHCollisionTagMatrix.h"
|
#include "Physics/Collision/CollisionTags/SHCollisionTagMatrix.h"
|
||||||
#include "Reflection/SHReflectionMetadata.h"
|
#include "Reflection/SHReflectionMetadata.h"
|
||||||
#include "Tools/Utilities/SHUtilities.h"
|
#include "Tools/Utilities/SHUtilities.h"
|
||||||
|
@ -111,6 +112,21 @@ namespace SHADE
|
||||||
return *collisionTag;
|
return *collisionTag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SHVec3 SHCollisionShape::GetPosition() const noexcept
|
||||||
|
{
|
||||||
|
const SHTransform& PARENT_TRANSFORM = collider->GetTransform();
|
||||||
|
|
||||||
|
const SHQuaternion FINAL_ROT = PARENT_TRANSFORM.orientation * transform.orientation;
|
||||||
|
const SHMatrix TRS = SHMatrix::Rotate(FINAL_ROT) * SHMatrix::Translate(PARENT_TRANSFORM.position);
|
||||||
|
|
||||||
|
return SHVec3::Transform(transform.position, TRS);
|
||||||
|
}
|
||||||
|
|
||||||
|
SHQuaternion SHCollisionShape::GetOrientation() const noexcept
|
||||||
|
{
|
||||||
|
return collider->GetOrientation() * transform.orientation;
|
||||||
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* Setter Function Definitions */
|
/* Setter Function Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -94,6 +94,8 @@ namespace SHADE
|
||||||
[[nodiscard]] float GetDensity () const noexcept;
|
[[nodiscard]] float GetDensity () const noexcept;
|
||||||
[[nodiscard]] const SHPhysicsMaterial& GetMaterial () const noexcept;
|
[[nodiscard]] const SHPhysicsMaterial& GetMaterial () const noexcept;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Offsets
|
// Offsets
|
||||||
|
|
||||||
[[nodiscard]] const SHVec3& GetPositionOffset () const noexcept;
|
[[nodiscard]] const SHVec3& GetPositionOffset () const noexcept;
|
||||||
|
@ -107,6 +109,14 @@ namespace SHADE
|
||||||
|
|
||||||
[[nodiscard]] const SHCollisionTag& GetCollisionTag () const noexcept;
|
[[nodiscard]] const SHCollisionTag& GetCollisionTag () const noexcept;
|
||||||
|
|
||||||
|
// Virtual methods
|
||||||
|
|
||||||
|
[[nodiscard]] virtual SHVec3 GetPosition () const noexcept;
|
||||||
|
[[nodiscard]] virtual SHQuaternion GetOrientation () const noexcept;
|
||||||
|
[[nodiscard]] virtual float GetVolume () const noexcept = 0;
|
||||||
|
[[nodiscard]] virtual SHMatrix GetInertiaTensor (float mass) const noexcept = 0;
|
||||||
|
[[nodiscard]] virtual SHVec3 GetLocalCentroid () const noexcept = 0;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Setter Functions */
|
/* Setter Functions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
@ -130,7 +140,6 @@ namespace SHADE
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
virtual void ComputeTransforms () noexcept = 0;
|
virtual void ComputeTransforms () noexcept = 0;
|
||||||
[[nodiscard]] virtual SHMatrix GetInertiaTensor (float mass) const noexcept = 0;
|
|
||||||
[[nodiscard]] virtual SHMatrix ComputeWorldTransform () const noexcept = 0;
|
[[nodiscard]] virtual SHMatrix ComputeWorldTransform () const noexcept = 0;
|
||||||
[[nodiscard]] virtual SHAABB ComputeAABB () const noexcept = 0;
|
[[nodiscard]] virtual SHAABB ComputeAABB () const noexcept = 0;
|
||||||
|
|
||||||
|
|
|
@ -141,6 +141,26 @@ namespace SHADE
|
||||||
return relativeRadius;
|
return relativeRadius;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SHVec3 SHSphereCollisionShape::GetPosition() const noexcept
|
||||||
|
{
|
||||||
|
return Center;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHQuaternion SHSphereCollisionShape::GetOrientation() const noexcept
|
||||||
|
{
|
||||||
|
return collider->GetTransform().orientation * transform.orientation;
|
||||||
|
}
|
||||||
|
|
||||||
|
float SHSphereCollisionShape::GetVolume() const noexcept
|
||||||
|
{
|
||||||
|
return Volume();
|
||||||
|
}
|
||||||
|
|
||||||
|
SHVec3 SHSphereCollisionShape::GetLocalCentroid() const noexcept
|
||||||
|
{
|
||||||
|
return SHVec3::Zero;
|
||||||
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* Setter Function Definitions */
|
/* Setter Function Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -75,6 +75,11 @@ namespace SHADE
|
||||||
[[nodiscard]] float GetWorldRadius () const noexcept;
|
[[nodiscard]] float GetWorldRadius () const noexcept;
|
||||||
[[nodiscard]] float GetRelativeRadius () const noexcept;
|
[[nodiscard]] float GetRelativeRadius () const noexcept;
|
||||||
|
|
||||||
|
[[nodiscard]] SHVec3 GetPosition () const noexcept override;
|
||||||
|
[[nodiscard]] SHQuaternion GetOrientation () const noexcept override;
|
||||||
|
[[nodiscard]] float GetVolume () const noexcept override;
|
||||||
|
[[nodiscard]] SHVec3 GetLocalCentroid () const noexcept override;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Setter Functions */
|
/* Setter Functions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
#include "SHRigidBody.h"
|
#include "SHRigidBody.h"
|
||||||
|
|
||||||
// Project Headers
|
// Project Headers
|
||||||
|
#include <numeric>
|
||||||
|
|
||||||
#include "Physics/Collision/SHCollider.h"
|
#include "Physics/Collision/SHCollider.h"
|
||||||
#include "Tools/Logger/SHLogger.h"
|
#include "Tools/Logger/SHLogger.h"
|
||||||
|
|
||||||
|
@ -242,6 +244,12 @@ namespace SHADE
|
||||||
return flags & (1U << FLAG_POS);
|
return flags & (1U << FLAG_POS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SHRigidBody::IsTriggerInMassData() const noexcept
|
||||||
|
{
|
||||||
|
static constexpr unsigned int FLAG_POS = 6;
|
||||||
|
return flags & (1U << FLAG_POS);
|
||||||
|
}
|
||||||
|
|
||||||
bool SHRigidBody::GetFreezePositionX() const noexcept
|
bool SHRigidBody::GetFreezePositionX() const noexcept
|
||||||
{
|
{
|
||||||
static constexpr unsigned int FLAG_POS = 10;
|
static constexpr unsigned int FLAG_POS = 10;
|
||||||
|
@ -334,6 +342,11 @@ namespace SHADE
|
||||||
|
|
||||||
invMass = 1.0f / newMass;
|
invMass = 1.0f / newMass;
|
||||||
|
|
||||||
|
// Turn off automass
|
||||||
|
static constexpr unsigned int AUTO_MASS_FLAG = 4;
|
||||||
|
static constexpr uint16_t VALUE = 1U << AUTO_MASS_FLAG;
|
||||||
|
|
||||||
|
flags &= ~(VALUE);
|
||||||
ComputeMassData();
|
ComputeMassData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -455,7 +468,6 @@ namespace SHADE
|
||||||
if (enableAutoMass)
|
if (enableAutoMass)
|
||||||
{
|
{
|
||||||
flags |= VALUE;
|
flags |= VALUE;
|
||||||
// TODO: Compute mass based on collider geometry
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -463,6 +475,16 @@ namespace SHADE
|
||||||
// Use default mass of 1
|
// Use default mass of 1
|
||||||
invMass = 1.0f;
|
invMass = 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ComputeMassData();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHRigidBody::SetTriggerInMassData(bool triggerInMassData) noexcept
|
||||||
|
{
|
||||||
|
static constexpr unsigned int FLAG_POS = 6;
|
||||||
|
static constexpr uint16_t VALUE = 1U << FLAG_POS;
|
||||||
|
|
||||||
|
triggerInMassData ? flags |= VALUE : flags &= ~VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHRigidBody::SetFreezePositionX(bool freezePositionX) noexcept
|
void SHRigidBody::SetFreezePositionX(bool freezePositionX) noexcept
|
||||||
|
@ -532,7 +554,7 @@ namespace SHADE
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
flags &= ~VALUE;
|
flags &= ~VALUE;
|
||||||
computeInertiaTensor();
|
ComputeMassData();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -552,7 +574,7 @@ namespace SHADE
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
flags &= ~VALUE;
|
flags &= ~VALUE;
|
||||||
computeInertiaTensor();
|
ComputeMassData();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -572,7 +594,7 @@ namespace SHADE
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
flags &= ~VALUE;
|
flags &= ~VALUE;
|
||||||
computeInertiaTensor();
|
ComputeMassData();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -628,60 +650,110 @@ namespace SHADE
|
||||||
|
|
||||||
void SHRigidBody::ComputeMassData() noexcept
|
void SHRigidBody::ComputeMassData() noexcept
|
||||||
{
|
{
|
||||||
computeCentroid();
|
// Reset centroid
|
||||||
computeMassAndInertiaTensor();
|
localCentroid = SHVec3::Zero;
|
||||||
|
localInvInertia = SHMatrix::Identity;
|
||||||
|
|
||||||
|
// In the instance the body is a particle
|
||||||
|
if (!collider || collider->GetCollisionShapes().empty())
|
||||||
|
{
|
||||||
|
localInvInertia.m[0][0] = localInvInertia.m[1][1] = localInvInertia.m[2][2] = invMass;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const float CUSTOM_MASS = 1.0f / invMass;
|
||||||
|
const bool AUTO_MASS = IsAutoMassEnabled();
|
||||||
|
const bool INCLUDE_TRIGGERS = IsTriggerInMassData();
|
||||||
|
const auto& SHAPES = collider->GetCollisionShapes();
|
||||||
|
|
||||||
|
// Compute Total mass and store individual masses if custom mass is being used.
|
||||||
|
// Compute local centroid at the same time
|
||||||
|
|
||||||
|
// Zero matrix;
|
||||||
|
SHMatrix tmpLocalTensor;
|
||||||
|
tmpLocalTensor -= SHMatrix::Identity;
|
||||||
|
|
||||||
|
float totalMass = 0.0f;
|
||||||
|
std::vector<float> trueMass;
|
||||||
|
|
||||||
|
for (auto* shape : SHAPES)
|
||||||
|
{
|
||||||
|
// We skip triggers by default
|
||||||
|
if (shape->IsTrigger() && !INCLUDE_TRIGGERS)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
shape->ComputeTransforms();
|
||||||
|
|
||||||
|
// p = m/v, therefore m = pv. This is the true mass of the shape.
|
||||||
|
const float MASS = shape->GetDensity() * shape->GetVolume();
|
||||||
|
totalMass += MASS;
|
||||||
|
|
||||||
|
trueMass.emplace_back(MASS);
|
||||||
|
|
||||||
|
// Weighted sum of masses contribute to the centroid's location using the collider's local position.
|
||||||
|
localCentroid += MASS * (shape->GetPosition() - collider->GetPosition());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (totalMass > 0.0f)
|
||||||
|
{
|
||||||
|
localCentroid /= totalMass;
|
||||||
|
|
||||||
|
if (AUTO_MASS)
|
||||||
|
invMass = 1.0f / totalMass;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SHMatrix R = SHMatrix::Rotate(motionState.orientation);
|
||||||
|
const SHMatrix RT = SHMatrix::Transpose(R);
|
||||||
|
|
||||||
|
worldCentroid = (R * localCentroid) + motionState.position;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < SHAPES.size(); ++i)
|
||||||
|
{
|
||||||
|
const auto* SHAPE = SHAPES[i];
|
||||||
|
|
||||||
|
// We skip triggers by default
|
||||||
|
if (SHAPE->IsTrigger() && !INCLUDE_TRIGGERS)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// If using custom mass, take the ratio of the mass
|
||||||
|
float actualMass = trueMass[i];
|
||||||
|
if (!AUTO_MASS)
|
||||||
|
actualMass *= CUSTOM_MASS / totalMass;
|
||||||
|
|
||||||
|
// Convert inertia tensor into local-space of the body
|
||||||
|
SHMatrix I = SHAPE->GetInertiaTensor( actualMass ) * RT;
|
||||||
|
I = R * I;
|
||||||
|
|
||||||
|
// Parallel Axis Theorem
|
||||||
|
const SHVec3 O = SHAPE->GetPosition() - worldCentroid;
|
||||||
|
const float O2 = O.LengthSquared();
|
||||||
|
|
||||||
|
SHMatrix offsetMatrix;
|
||||||
|
offsetMatrix -= SHMatrix::Identity;
|
||||||
|
offsetMatrix.m[0][0] = offsetMatrix.m[1][1] = offsetMatrix.m[2][2] = O2;
|
||||||
|
|
||||||
|
const SHVec3 NOX = O * -O.x;
|
||||||
|
const SHVec3 NOY = O * -O.y;
|
||||||
|
const SHVec3 NOZ = O * -O.z;
|
||||||
|
|
||||||
|
offsetMatrix += SHMatrix{ NOX, NOY, NOZ, SHVec4::Zero };
|
||||||
|
offsetMatrix *= actualMass;
|
||||||
|
|
||||||
|
tmpLocalTensor += I + offsetMatrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set diagonals then invert
|
||||||
|
localInvInertia.m[0][0] = tmpLocalTensor.m[0][0];
|
||||||
|
localInvInertia.m[1][1] = tmpLocalTensor.m[1][1];
|
||||||
|
localInvInertia.m[2][2] = tmpLocalTensor.m[2][2];
|
||||||
|
|
||||||
|
localInvInertia = SHMatrix::Inverse(localInvInertia);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* Private Member Function Definition */
|
/* Private Member Function Definition */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
void SHRigidBody::computeCentroid() noexcept
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
void SHRigidBody::computeMass() noexcept
|
|
||||||
{
|
|
||||||
// TODO: If auto mass in enabled, compute total mass based from each collider.
|
|
||||||
// TODO: If auto mass disabled, compute inertia tensor for each shape using the ratio of its mass / total mass by comparing the volume / total volume.
|
|
||||||
}
|
|
||||||
|
|
||||||
void SHRigidBody::computeInertiaTensor() noexcept
|
|
||||||
{
|
|
||||||
// TODO: Compute total inertia from composited colliders using the Parallel Axis Theorem.
|
|
||||||
|
|
||||||
if (!collider || collider->GetCollisionShapes().empty())
|
|
||||||
{
|
|
||||||
localInvInertia.m[0][0] = localInvInertia.m[1][1] = localInvInertia.m[2][2] = invMass;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// HACK: For now, take only the first shape as we are testing with non-composited colliders. We are using the center as the centroid.
|
|
||||||
const auto* FIRST_SHAPE = collider->GetCollisionShape(0);
|
|
||||||
localInvInertia = SHMatrix::Inverse(FIRST_SHAPE->GetInertiaTensor(1.0f / invMass));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SHRigidBody::computeMassAndInertiaTensor() noexcept
|
|
||||||
{
|
|
||||||
// TODO: If auto mass in enabled, compute total mass based from each collider.
|
|
||||||
// TODO: If auto mass disabled, compute inertia tensor for each shape using the ratio of its mass / total mass by comparing the volume / total volume.
|
|
||||||
|
|
||||||
// TODO: Compute total inertia from composited colliders using the Parallel Axis Theorem.
|
|
||||||
|
|
||||||
if (!collider || collider->GetCollisionShapes().empty())
|
|
||||||
{
|
|
||||||
localInvInertia.m[0][0] = localInvInertia.m[1][1] = localInvInertia.m[2][2] = invMass;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// HACK: For now, take only the first shape as we are testing with non-composited colliders. We are using the center as the centroid.
|
|
||||||
const auto* FIRST_SHAPE = collider->GetCollisionShape(0);
|
|
||||||
localInvInertia = SHMatrix::Inverse(FIRST_SHAPE->GetInertiaTensor(1.0f / invMass));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SHRigidBody::constrainLinearVelocities() noexcept
|
void SHRigidBody::constrainLinearVelocities() noexcept
|
||||||
{
|
{
|
||||||
linearVelocity.x = GetFreezePositionX() ? 0.0f : linearVelocity.x;
|
linearVelocity.x = GetFreezePositionX() ? 0.0f : linearVelocity.x;
|
||||||
|
|
|
@ -99,6 +99,7 @@ namespace SHADE
|
||||||
[[nodiscard]] bool IsSleepingEnabled () const noexcept;
|
[[nodiscard]] bool IsSleepingEnabled () const noexcept;
|
||||||
[[nodiscard]] bool IsGravityEnabled () const noexcept;
|
[[nodiscard]] bool IsGravityEnabled () const noexcept;
|
||||||
[[nodiscard]] bool IsAutoMassEnabled () const noexcept;
|
[[nodiscard]] bool IsAutoMassEnabled () const noexcept;
|
||||||
|
[[nodiscard]] bool IsTriggerInMassData () const noexcept;
|
||||||
[[nodiscard]] bool GetFreezePositionX () const noexcept;
|
[[nodiscard]] bool GetFreezePositionX () const noexcept;
|
||||||
[[nodiscard]] bool GetFreezePositionY () const noexcept;
|
[[nodiscard]] bool GetFreezePositionY () const noexcept;
|
||||||
[[nodiscard]] bool GetFreezePositionZ () const noexcept;
|
[[nodiscard]] bool GetFreezePositionZ () const noexcept;
|
||||||
|
@ -157,6 +158,7 @@ namespace SHADE
|
||||||
void SetSleepingEnabled (bool enableSleeping) noexcept;
|
void SetSleepingEnabled (bool enableSleeping) noexcept;
|
||||||
void SetGravityEnabled (bool enableGravity) noexcept;
|
void SetGravityEnabled (bool enableGravity) noexcept;
|
||||||
void SetAutoMassEnabled (bool enableAutoMass) noexcept;
|
void SetAutoMassEnabled (bool enableAutoMass) noexcept;
|
||||||
|
void SetTriggerInMassData(bool triggerInMassData) noexcept;
|
||||||
void SetFreezePositionX (bool freezePositionX) noexcept;
|
void SetFreezePositionX (bool freezePositionX) noexcept;
|
||||||
void SetFreezePositionY (bool freezePositionY) noexcept;
|
void SetFreezePositionY (bool freezePositionY) noexcept;
|
||||||
void SetFreezePositionZ (bool freezePositionZ) noexcept;
|
void SetFreezePositionZ (bool freezePositionZ) noexcept;
|
||||||
|
@ -249,7 +251,7 @@ namespace SHADE
|
||||||
SHVec3 linearVelocity;
|
SHVec3 linearVelocity;
|
||||||
SHVec3 angularVelocity;
|
SHVec3 angularVelocity;
|
||||||
|
|
||||||
// aZ aY aX rotLockActive pZ pY pX posLockActive 0 0 inIsland autoMass enableGravity enableSleeping sleeping active
|
// aZ aY aX pZ pY pX 0 0 0 addTriggersToMassData inIsland autoMass enableGravity enableSleeping sleeping active
|
||||||
uint16_t flags;
|
uint16_t flags;
|
||||||
|
|
||||||
SHMotionState motionState;
|
SHMotionState motionState;
|
||||||
|
@ -258,11 +260,6 @@ namespace SHADE
|
||||||
/* Member Functions */
|
/* Member Functions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
void computeCentroid () noexcept;
|
|
||||||
void computeMass () noexcept;
|
|
||||||
void computeInertiaTensor () noexcept;
|
|
||||||
void computeMassAndInertiaTensor() noexcept;
|
|
||||||
|
|
||||||
void constrainLinearVelocities () noexcept;
|
void constrainLinearVelocities () noexcept;
|
||||||
void constrainAngularVelocities () noexcept;
|
void constrainAngularVelocities () noexcept;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue