Implemented a custom physics engine #316
|
@ -45,7 +45,7 @@
|
|||
NumberOfChildren: 0
|
||||
Components:
|
||||
Camera Component:
|
||||
Position: {x: 0, y: 4, z: 5}
|
||||
Position: {x: 0, y: 2, z: 5}
|
||||
Pitch: 0
|
||||
Yaw: 0
|
||||
Roll: 0
|
||||
|
@ -62,14 +62,14 @@
|
|||
NumberOfChildren: 0
|
||||
Components:
|
||||
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}
|
||||
Scale: {x: 1, y: 1, z: 1}
|
||||
IsActive: true
|
||||
RigidBody Component:
|
||||
Type: Dynamic
|
||||
Auto Mass: false
|
||||
Mass: 1
|
||||
Mass: 0.52359879
|
||||
Drag: 0.00999999978
|
||||
Angular Drag: 0.00999999978
|
||||
Use Gravity: true
|
||||
|
@ -77,7 +77,7 @@
|
|||
Interpolate: true
|
||||
Sleeping Enabled: true
|
||||
Freeze Position X: false
|
||||
Freeze Position Y: false
|
||||
Freeze Position Y: true
|
||||
Freeze Position Z: false
|
||||
Freeze Rotation X: false
|
||||
Freeze Rotation Y: false
|
||||
|
@ -95,6 +95,15 @@
|
|||
Density: 1
|
||||
Position 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
|
||||
Scripts:
|
||||
- Type: PhysicsTestObj
|
||||
|
|
|
@ -251,9 +251,16 @@ namespace SHADE
|
|||
|
||||
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("Mass", [component] {return component->GetMass(); }, [component](float const& value) {component->SetMass(value); }, "Mass");
|
||||
|
||||
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");
|
||||
}
|
||||
if (rbType == SHRigidBodyComponent::Type::DYNAMIC || rbType == SHRigidBodyComponent::Type::KINEMATIC) //Dynamic or Kinematic only fields
|
||||
{
|
||||
|
|
|
@ -147,11 +147,6 @@ namespace SHADE
|
|||
return relativeExtents;
|
||||
}
|
||||
|
||||
SHQuaternion SHBoxCollisionShape::GetOrientation() const noexcept
|
||||
{
|
||||
return Orientation;
|
||||
}
|
||||
|
||||
SHVec3 SHBoxCollisionShape::GetVertex(int index) const
|
||||
{
|
||||
static constexpr int NUM_VERTICES = 8;
|
||||
|
@ -160,41 +155,6 @@ namespace SHADE
|
|||
throw std::invalid_argument("Index out-of-range!");
|
||||
|
||||
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
|
||||
|
@ -204,7 +164,26 @@ namespace SHADE
|
|||
|
||||
// Rotate normal into world space
|
||||
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,10 +75,14 @@ namespace SHADE
|
|||
[[nodiscard]] SHVec3 GetCenter () const noexcept;
|
||||
[[nodiscard]] SHVec3 GetWorldExtents () const noexcept;
|
||||
[[nodiscard]] SHVec3 GetRelativeExtents () const noexcept;
|
||||
[[nodiscard]] SHQuaternion GetOrientation () const noexcept;
|
||||
|
||||
[[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 */
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "SHCollisionShape.h"
|
||||
|
||||
// Project Headers
|
||||
#include "Physics/Collision/SHCollider.h"
|
||||
#include "Physics/Collision/CollisionTags/SHCollisionTagMatrix.h"
|
||||
#include "Reflection/SHReflectionMetadata.h"
|
||||
#include "Tools/Utilities/SHUtilities.h"
|
||||
|
@ -111,6 +112,21 @@ namespace SHADE
|
|||
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 */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
|
|
@ -94,6 +94,8 @@ namespace SHADE
|
|||
[[nodiscard]] float GetDensity () const noexcept;
|
||||
[[nodiscard]] const SHPhysicsMaterial& GetMaterial () const noexcept;
|
||||
|
||||
|
||||
|
||||
// Offsets
|
||||
|
||||
[[nodiscard]] const SHVec3& GetPositionOffset () const noexcept;
|
||||
|
@ -107,6 +109,14 @@ namespace SHADE
|
|||
|
||||
[[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 */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
@ -130,7 +140,6 @@ namespace SHADE
|
|||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
virtual void ComputeTransforms () noexcept = 0;
|
||||
[[nodiscard]] virtual SHMatrix GetInertiaTensor (float mass) const noexcept = 0;
|
||||
[[nodiscard]] virtual SHMatrix ComputeWorldTransform () const noexcept = 0;
|
||||
[[nodiscard]] virtual SHAABB ComputeAABB () const noexcept = 0;
|
||||
|
||||
|
|
|
@ -141,6 +141,26 @@ namespace SHADE
|
|||
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 */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
|
|
@ -71,9 +71,14 @@ namespace SHADE
|
|||
/* Getter Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
[[nodiscard]] SHVec3 GetCenter () const noexcept;
|
||||
[[nodiscard]] float GetWorldRadius () const noexcept;
|
||||
[[nodiscard]] float GetRelativeRadius () const noexcept;
|
||||
[[nodiscard]] SHVec3 GetCenter () const noexcept;
|
||||
[[nodiscard]] float GetWorldRadius () 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 */
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
#include "SHRigidBody.h"
|
||||
|
||||
// Project Headers
|
||||
#include <numeric>
|
||||
|
||||
#include "Physics/Collision/SHCollider.h"
|
||||
#include "Tools/Logger/SHLogger.h"
|
||||
|
||||
|
@ -60,19 +62,19 @@ namespace SHADE
|
|||
}
|
||||
|
||||
SHRigidBody::SHRigidBody(SHRigidBody&& rhs) noexcept
|
||||
: entityID { rhs.entityID }
|
||||
, collider { nullptr }
|
||||
, bodyType { rhs.bodyType }
|
||||
, gravityScale { rhs.gravityScale }
|
||||
, invMass { rhs.invMass }
|
||||
, linearDrag { rhs.linearDrag }
|
||||
, angularDrag { rhs.angularDrag }
|
||||
: entityID { rhs.entityID }
|
||||
, collider { nullptr }
|
||||
, bodyType { rhs.bodyType }
|
||||
, gravityScale { rhs.gravityScale }
|
||||
, invMass { rhs.invMass }
|
||||
, linearDrag { rhs.linearDrag }
|
||||
, angularDrag { rhs.angularDrag }
|
||||
, localInvInertia { rhs.localInvInertia }
|
||||
, worldInvInertia { rhs.worldInvInertia }
|
||||
, localCentroid { rhs.localCentroid }
|
||||
, worldCentroid { rhs.worldCentroid }
|
||||
, flags { rhs.flags }
|
||||
, motionState { std::move(rhs.motionState) }
|
||||
, flags { rhs.flags }
|
||||
, motionState { std::move(rhs.motionState) }
|
||||
{
|
||||
// All other properties are defaulted to 0 to not carry over any potential errors / invalid values.
|
||||
}
|
||||
|
@ -114,21 +116,21 @@ namespace SHADE
|
|||
|
||||
SHRigidBody& SHRigidBody::operator=(SHRigidBody&& rhs) noexcept
|
||||
{
|
||||
entityID = rhs.entityID;
|
||||
entityID = rhs.entityID;
|
||||
|
||||
// Deep copy the collider
|
||||
*collider = *rhs.collider;
|
||||
bodyType = rhs.bodyType;
|
||||
gravityScale = rhs.gravityScale;
|
||||
invMass = rhs.invMass;
|
||||
linearDrag = rhs.linearDrag;
|
||||
angularDrag = rhs.angularDrag;
|
||||
*collider = *rhs.collider;
|
||||
bodyType = rhs.bodyType;
|
||||
gravityScale = rhs.gravityScale;
|
||||
invMass = rhs.invMass;
|
||||
linearDrag = rhs.linearDrag;
|
||||
angularDrag = rhs.angularDrag;
|
||||
localInvInertia = rhs.localInvInertia;
|
||||
worldInvInertia = rhs.worldInvInertia;
|
||||
localCentroid = rhs.localCentroid;
|
||||
worldCentroid = rhs.worldCentroid;
|
||||
flags = rhs.flags;
|
||||
motionState = std::move(rhs.motionState);
|
||||
flags = rhs.flags;
|
||||
motionState = std::move(rhs.motionState);
|
||||
|
||||
// All other properties are defaulted to 0 to not carry over any potential errors / invalid values.
|
||||
accumulatedForce = SHVec3::Zero;
|
||||
|
@ -242,6 +244,12 @@ namespace SHADE
|
|||
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
|
||||
{
|
||||
static constexpr unsigned int FLAG_POS = 10;
|
||||
|
@ -334,6 +342,11 @@ namespace SHADE
|
|||
|
||||
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();
|
||||
}
|
||||
|
||||
|
@ -455,7 +468,6 @@ namespace SHADE
|
|||
if (enableAutoMass)
|
||||
{
|
||||
flags |= VALUE;
|
||||
// TODO: Compute mass based on collider geometry
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -463,6 +475,16 @@ namespace SHADE
|
|||
// Use default mass of 1
|
||||
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
|
||||
|
@ -532,7 +554,7 @@ namespace SHADE
|
|||
else
|
||||
{
|
||||
flags &= ~VALUE;
|
||||
computeInertiaTensor();
|
||||
ComputeMassData();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -552,7 +574,7 @@ namespace SHADE
|
|||
else
|
||||
{
|
||||
flags &= ~VALUE;
|
||||
computeInertiaTensor();
|
||||
ComputeMassData();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -572,7 +594,7 @@ namespace SHADE
|
|||
else
|
||||
{
|
||||
flags &= ~VALUE;
|
||||
computeInertiaTensor();
|
||||
ComputeMassData();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -628,60 +650,110 @@ namespace SHADE
|
|||
|
||||
void SHRigidBody::ComputeMassData() noexcept
|
||||
{
|
||||
computeCentroid();
|
||||
computeMassAndInertiaTensor();
|
||||
// Reset centroid
|
||||
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 */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
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
|
||||
{
|
||||
linearVelocity.x = GetFreezePositionX() ? 0.0f : linearVelocity.x;
|
||||
|
|
|
@ -99,6 +99,7 @@ namespace SHADE
|
|||
[[nodiscard]] bool IsSleepingEnabled () const noexcept;
|
||||
[[nodiscard]] bool IsGravityEnabled () const noexcept;
|
||||
[[nodiscard]] bool IsAutoMassEnabled () const noexcept;
|
||||
[[nodiscard]] bool IsTriggerInMassData () const noexcept;
|
||||
[[nodiscard]] bool GetFreezePositionX () const noexcept;
|
||||
[[nodiscard]] bool GetFreezePositionY () const noexcept;
|
||||
[[nodiscard]] bool GetFreezePositionZ () const noexcept;
|
||||
|
@ -157,6 +158,7 @@ namespace SHADE
|
|||
void SetSleepingEnabled (bool enableSleeping) noexcept;
|
||||
void SetGravityEnabled (bool enableGravity) noexcept;
|
||||
void SetAutoMassEnabled (bool enableAutoMass) noexcept;
|
||||
void SetTriggerInMassData(bool triggerInMassData) noexcept;
|
||||
void SetFreezePositionX (bool freezePositionX) noexcept;
|
||||
void SetFreezePositionY (bool freezePositionY) noexcept;
|
||||
void SetFreezePositionZ (bool freezePositionZ) noexcept;
|
||||
|
@ -249,7 +251,7 @@ namespace SHADE
|
|||
SHVec3 linearVelocity;
|
||||
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;
|
||||
|
||||
SHMotionState motionState;
|
||||
|
@ -258,11 +260,6 @@ namespace SHADE
|
|||
/* Member Functions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
void computeCentroid () noexcept;
|
||||
void computeMass () noexcept;
|
||||
void computeInertiaTensor () noexcept;
|
||||
void computeMassAndInertiaTensor() noexcept;
|
||||
|
||||
void constrainLinearVelocities () noexcept;
|
||||
void constrainAngularVelocities () noexcept;
|
||||
|
||||
|
|
Loading…
Reference in New Issue