Moved rigidbody creation into physics object

This commit is contained in:
Diren D Bharwani 2022-10-10 21:13:14 +08:00
parent 7c4a9ca004
commit 46a082b62e
13 changed files with 198 additions and 85 deletions

View File

@ -26,13 +26,13 @@ namespace SHADE
, center { c }
, halfExtents { hE }
{
type = Type::BOUNDING_BOX;
type = Type::BOX;
}
SHBoundingBox::SHBoundingBox(const SHVec3* vertices, size_t numVertices) noexcept
: SHShape {}
{
type = Type::BOUNDING_BOX;
type = Type::BOX;
if (vertices == nullptr || numVertices < 2)
{
@ -63,7 +63,7 @@ namespace SHADE
SHBoundingBox::SHBoundingBox(const SHBoundingBox* boxes, size_t numBoxes) noexcept
: SHShape {}
{
type = Type::BOUNDING_BOX;
type = Type::BOX;
if (boxes == nullptr || numBoxes == 0)
{
@ -83,7 +83,7 @@ namespace SHADE
, center { rhs.center }
, halfExtents { rhs.halfExtents }
{
type = Type::BOUNDING_BOX;
type = Type::BOX;
}
SHBoundingBox::SHBoundingBox(SHBoundingBox&& rhs) noexcept
@ -91,12 +91,12 @@ namespace SHADE
, center { rhs.center }
, halfExtents { rhs.halfExtents }
{
type = Type::BOUNDING_BOX;
type = Type::BOX;
}
SHBoundingBox& SHBoundingBox::operator=(const SHBoundingBox& rhs) noexcept
{
if (rhs.type != Type::BOUNDING_BOX)
if (rhs.type != Type::BOX)
{
SHLOG_WARNING("Cannot assign a non-bounding box to a bounding box!")
}
@ -111,7 +111,7 @@ namespace SHADE
SHBoundingBox& SHBoundingBox::operator=(SHBoundingBox&& rhs) noexcept
{
if (rhs.type != Type::BOUNDING_BOX)
if (rhs.type != Type::BOX)
{
SHLOG_WARNING("Cannot assign a non-bounding box to a bounding box!")
}

View File

@ -29,7 +29,7 @@ namespace SHADE
enum class Type
{
BOUNDING_BOX
BOX
, SPHERE
, CAPSULE
, CONVEX_HULL

View File

@ -194,6 +194,11 @@ namespace SHADE
return reactphysics3d::Quaternion{ x, y, z, w };
}
SHQuaternion::operator reactphysics3d::Vector3() const noexcept
{
return reactphysics3d::Vector3{ ToEuler() };
}
SHQuaternion operator*(float lhs, const SHQuaternion& rhs) noexcept
{
return rhs * lhs;

View File

@ -86,6 +86,7 @@ namespace SHADE
// Conversion to other math types used by SHADE
operator reactphysics3d::Quaternion () const noexcept;
operator reactphysics3d::Vector3 () const noexcept;
/*---------------------------------------------------------------------------------*/
/* Getter Functions */

View File

@ -14,6 +14,7 @@
#include "SHVec3.h"
// Project Headers
#include "Math/SHMatrix.h"
#include "Math/SHQuaternion.h"
#include "Tools/SHLogger.h"
using namespace DirectX;
@ -55,6 +56,10 @@ namespace SHADE
: XMFLOAT3( rp3dVec3.x, rp3dVec3.y, rp3dVec3.z )
{}
SHVec3::SHVec3(const reactphysics3d::Quaternion& rp3dVec3) noexcept
: XMFLOAT3( SHQuaternion{rp3dVec3}.ToEuler() )
{}
/*-----------------------------------------------------------------------------------*/
/* Operator Overload Definitions */
/*-----------------------------------------------------------------------------------*/

View File

@ -60,13 +60,14 @@ namespace SHADE
SHVec3 (SHVec3&& rhs) = default;
~SHVec3 () = default;
SHVec3 () noexcept;
SHVec3 (float n) noexcept;
SHVec3 (float x, float y, float z) noexcept;
SHVec3 () noexcept;
SHVec3 (float n) noexcept;
SHVec3 (float x, float y, float z) noexcept;
// Conversion from other math types to SHADE
SHVec3 (const reactphysics3d::Vector3& rp3dVec3) noexcept;
SHVec3 (const reactphysics3d::Vector3& rp3dVec3) noexcept;
SHVec3 (const reactphysics3d::Quaternion& rp3dVec3) noexcept;
/*---------------------------------------------------------------------------------*/
/* Operator Overloads */

View File

@ -16,6 +16,11 @@
#include "ECS_Base/Components/SHComponent.h"
#include "Physics/SHCollider.h"
//namespace SHADE
//{
// class SHPhysicsSystem;
//}
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
@ -30,6 +35,7 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/
friend class SHPhysicsSystem;
friend class SHPhysicsObject;
/*---------------------------------------------------------------------------------*/
/* Type Definitions */

View File

@ -392,9 +392,9 @@ RTTR_REGISTRATION
registration::enumeration<SHRigidBodyComponent::Type>("RigidBody Type")
(
value("Static", SHRigidBodyComponent::Type::STATIC),
value("Dynamic", SHRigidBodyComponent::Type::DYNAMIC),
value("Kinematic", SHRigidBodyComponent::Type::KINEMATIC)
value("Static", SHRigidBodyComponent::Type::STATIC),
value("Kinematic", SHRigidBodyComponent::Type::KINEMATIC),
value("Dynamic", SHRigidBodyComponent::Type::DYNAMIC)
);
registration::class_<SHRigidBodyComponent>("RigidBody Component")

View File

@ -14,7 +14,13 @@
// Project Headers
#include "ECS_Base/Components/SHComponent.h"
#include "Physics/SHPhysicsObject.h"
#include "Math/Vector/SHVec3.h"
#include "Math/SHQuaternion.h"
//namespace SHADE
//{
// class SHPhysicsSystem;
//}
namespace SHADE
{
@ -30,6 +36,7 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/
friend class SHPhysicsSystem;
friend class SHPhysicsObject;
public:
/*---------------------------------------------------------------------------------*/

View File

@ -15,7 +15,8 @@
// Project Headers
#include "ECS_Base/Managers/SHSystemManager.h"
#include "SHPhysicsSystem.h"
#include "ECS_Base/Managers/SHComponentManager.h"
namespace SHADE
{
@ -23,16 +24,20 @@ namespace SHADE
/* Constructors & Destructor Definitions */
/*-----------------------------------------------------------------------------------*/
SHPhysicsObject::SHPhysicsObject() noexcept
: entityID { MAX_EID }
SHPhysicsObject::SHPhysicsObject(EntityID eid, rp3d::PhysicsCommon* physicsFactory, rp3d::PhysicsWorld* physicsWorld) noexcept
: entityID { eid }
, isRigidBody { false }
, hasColliders{ false }
, factory { physicsFactory }
, world { physicsWorld }
, rp3dBody { nullptr }
{}
SHPhysicsObject::~SHPhysicsObject() noexcept
{
rp3dBody = nullptr;
factory = nullptr;
world = nullptr;
rp3dBody = nullptr;
}
/*-----------------------------------------------------------------------------------*/
@ -75,6 +80,12 @@ namespace SHADE
void SHPhysicsObject::SetPosition(const SHVec3& position) noexcept
{
if (!rp3dBody)
{
SHLOG_ERROR("Cannot set position of a non-existent physics body for Entity {}", entityID)
return;
}
rp3d::Transform rp3dTF;
rp3dTF.setPosition(position);
rp3dTF.setOrientation(rp3dBody->getTransform().getOrientation());
@ -85,6 +96,12 @@ namespace SHADE
void SHPhysicsObject::SetOrientation(const SHQuaternion& orientation) noexcept
{
if (!rp3dBody)
{
SHLOG_ERROR("Cannot set orientation of a non-existent physics body for Entity {}", entityID)
return;
}
rp3d::Transform rp3dTF;
rp3dTF.setPosition(rp3dBody->getTransform().getPosition());
rp3dTF.setOrientation(orientation);
@ -95,14 +112,70 @@ namespace SHADE
void SHPhysicsObject::SetRotation(const SHVec3& rotation) noexcept
{
const rp3d::Quaternion RP3D_ORIENTATION = rp3d::Quaternion::fromEulerAngles( rotation.x, rotation.y, rotation.z );
if (!rp3dBody)
{
SHLOG_ERROR("Cannot set rotation of a non-existent physics body for Entity {}", entityID)
return;
}
rp3d::Transform rp3dTF;
rp3dTF.setPosition(rp3dBody->getTransform().getPosition());
rp3dTF.setOrientation(RP3D_ORIENTATION);
rp3dTF.setOrientation(rotation);
rp3dBody->setTransform(rp3dTF);
prevTransform = rp3dTF;
}
/*-----------------------------------------------------------------------------------*/
/* Public Function Member Definitions */
/*-----------------------------------------------------------------------------------*/
void SHPhysicsObject::CreateRigidBody(const SHTransformComponent* tf, SHRigidBodyComponent* rb, SHColliderComponent* c)
{
// If collider already exists
if (hasColliders)
world->destroyCollisionBody(rp3dBody);
rp3dBody = world->createRigidBody(rp3d::Transform{ tf->GetWorldPosition(), tf->GetWorldRotation() });
isRigidBody = true;
rb->position = tf->GetWorldPosition();
rb->orientation = tf->GetWorldRotation();
}
void SHPhysicsObject::DestroyRigidBody() noexcept
{
}
void SHPhysicsObject::CreateCollisionBody(const SHTransformComponent* tf, SHColliderComponent* c)
{
}
void SHPhysicsObject::DestroyCollisionBody() noexcept
{
}
int SHPhysicsObject::AddCollider(SHCollider* collider)
{
return 0;
}
void SHPhysicsObject::RemoveCollider(int index) noexcept
{
}
void SHPhysicsObject::SyncRigidBody() noexcept
{
}
void SHPhysicsObject::SyncColliders() noexcept
{
}
} // namespace SHADE

View File

@ -13,9 +13,9 @@
#include <reactphysics3d/reactphysics3d.h>
// Project Headers
#include "Math/Vector/SHVec3.h"
#include "Math/SHQuaternion.h"
#include "ECS_Base/Entity/SHEntity.h"
#include "Math/Transform/SHTransformComponent.h"
#include "Components/SHRigidBodyComponent.h"
#include "Components/SHColliderComponent.h"
namespace SHADE
{
@ -31,15 +31,13 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/
friend class SHPhysicsSystem;
friend class SHRigidBodyComponent;
friend class SHColliderComponent;
public:
/*---------------------------------------------------------------------------------*/
/* Constructors & Destructor */
/*---------------------------------------------------------------------------------*/
SHPhysicsObject () noexcept;
SHPhysicsObject (EntityID eid, rp3d::PhysicsCommon* physicsFactory, rp3d::PhysicsWorld* physicsWorld) noexcept;
SHPhysicsObject (const SHPhysicsObject& rhs) noexcept = default;
SHPhysicsObject (SHPhysicsObject&& rhs) noexcept = default;
virtual ~SHPhysicsObject () noexcept;
@ -63,9 +61,24 @@ namespace SHADE
/* Setter Functions */
/*---------------------------------------------------------------------------------*/
void SetPosition (const SHVec3& position) noexcept;
void SetOrientation (const SHQuaternion& orientation) noexcept;
void SetRotation (const SHVec3& rotation) noexcept;
void SetPosition (const SHVec3& position) noexcept;
void SetOrientation (const SHQuaternion& orientation) noexcept;
void SetRotation (const SHVec3& rotation) noexcept;
/*---------------------------------------------------------------------------------*/
/* Function Members */
/*---------------------------------------------------------------------------------*/
void CreateRigidBody (const SHTransformComponent* tf, SHRigidBodyComponent* rb, SHColliderComponent* c);
void DestroyRigidBody () noexcept;
void CreateCollisionBody (const SHTransformComponent* tf, SHColliderComponent* c);
int AddCollider (SHCollider* collider);
void RemoveCollider (int index) noexcept;
void DestroyCollisionBody () noexcept;
void SyncRigidBody () noexcept;
void SyncColliders () noexcept;
private:
/*---------------------------------------------------------------------------------*/
@ -76,11 +89,9 @@ namespace SHADE
bool isRigidBody;
bool hasColliders;
rp3d::PhysicsCommon* factory;
rp3d::PhysicsWorld* world;
rp3d::CollisionBody* rp3dBody; // Can be either a collision body or a rigid body
rp3d::Transform prevTransform; // Cached transform for interpolation
/*---------------------------------------------------------------------------------*/
/* Function Members */
/*---------------------------------------------------------------------------------*/
};
} // namespace SHADE

View File

@ -204,32 +204,18 @@ namespace SHADE
// Check if entity is already a physics object
auto* physicsObject = GetPhysicsObject(entityID);
if (!physicsObject)
{
physicsObject = &(map.emplace(entityID, SHPhysicsObject{}).first->second);
physicsObject->entityID = entityID;
}
physicsObject = CreatePhysicsObject(entityID);
// Get entity transform
auto const* SHADE_TF = SHComponentManager::GetComponent_s<SHTransformComponent>(entityID);
// Get components transform
auto* transformComponent = EnsureTransform(entityID);
auto* rigidBodyComponent = SHComponentManager::GetComponent<SHRigidBodyComponent>(entityID);
// Possibly redundant
if (!SHADE_TF)
{
SHComponentManager::AddComponent<SHTransformComponent>(entityID);
SHADE_TF = SHComponentManager::GetComponent<SHTransformComponent>(entityID);
}
const rp3d::Transform RP3D_TF { SHADE_TF->GetWorldPosition(), SHADE_TF->GetWorldRotation() };
// If collider already exists
if (physicsObject->hasColliders)
world->destroyCollisionBody(physicsObject->rp3dBody);
physicsObject->rp3dBody = world->createRigidBody(RP3D_TF);
physicsObject->isRigidBody = true;
physicsObject->CreateRigidBody(transformComponent, rigidBodyComponent, nullptr);
// Recreate colliders
const rp3d::Transform RP3D_TF { transformComponent->GetWorldPosition(), transformComponent->GetWorldRotation() };
if (physicsObject->hasColliders)
{
const auto& COLLIDERS = SHComponentManager::GetComponent<SHColliderComponent>(entityID)->GetColliders();
@ -267,22 +253,11 @@ namespace SHADE
// Check if entity is already a physics object
auto* physicsObject = GetPhysicsObject(entityID);
if (!physicsObject)
{
physicsObject = &(map.emplace(entityID, SHPhysicsObject{}).first->second);
physicsObject->entityID = entityID;
}
physicsObject = CreatePhysicsObject(entityID);
// Get entity transform
auto const* SHADE_TF = SHComponentManager::GetComponent_s<SHTransformComponent>(entityID);
// Possibly redundant
if (!SHADE_TF)
{
SHComponentManager::AddComponent<SHTransformComponent>(entityID);
SHADE_TF = SHComponentManager::GetComponent<SHTransformComponent>(entityID);
}
const rp3d::Transform RP3D_TF { SHADE_TF->GetWorldPosition(), SHADE_TF->GetWorldRotation() };
auto const* TF = EnsureTransform(entityID);
const rp3d::Transform RP3D_TF { TF->GetWorldPosition(), TF->GetWorldRotation() };
// No rb
if (!physicsObject->isRigidBody)
@ -375,7 +350,7 @@ namespace SHADE
switch (shape->GetType())
{
case SHShape::Type::BOUNDING_BOX:
case SHShape::Type::BOX:
{
auto* box = reinterpret_cast<SHBoundingBox*>(shape);
rp3d::BoxShape* newBox = factory.createBoxShape(box->GetHalfExtents());
@ -457,6 +432,12 @@ namespace SHADE
/* Private Function Member Definitions */
/*-----------------------------------------------------------------------------------*/
SHPhysicsObject* SHPhysicsSystem::CreatePhysicsObject(EntityID entityID) noexcept
{
auto* newPhysicsObject = &map.emplace(entityID, SHPhysicsObject{entityID, &factory, world}).first->second;
return newPhysicsObject;
}
SHPhysicsObject* SHPhysicsSystem::GetPhysicsObject(EntityID entityID) noexcept
{
const auto it = map.find(entityID);
@ -469,6 +450,14 @@ namespace SHADE
return &(it->second);
}
void SHPhysicsSystem::SyncActiveStates(SHPhysicsObject* physicsObject, bool componentActive) noexcept
{
const bool RP3D_ACTIVE = physicsObject->rp3dBody->isActive();
if (RP3D_ACTIVE != componentActive)
physicsObject->rp3dBody->setIsActive(componentActive);
}
void SHPhysicsSystem::SyncRigidBodyComponents(std::vector<SHRigidBodyComponent>& denseArray) noexcept
{
if (denseArray.empty())
@ -479,14 +468,11 @@ namespace SHADE
const EntityID ENTITY_ID = comp.GetEID();
// Get physicsObject
auto const* physicsObject = GetPhysicsObject(ENTITY_ID);
auto* physicsObject = GetPhysicsObject(ENTITY_ID);
const bool RP3D_ACTIVE = physicsObject->rp3dBody->isActive();
// TODO(Diren): Check if active in hierarchy
const bool COMPONENT_ACTIVE = comp.isActive;
if (RP3D_ACTIVE != COMPONENT_ACTIVE)
physicsObject->rp3dBody->setIsActive(COMPONENT_ACTIVE);
SyncActiveStates(physicsObject, COMPONENT_ACTIVE);
if (!COMPONENT_ACTIVE)
continue;
@ -509,14 +495,11 @@ namespace SHADE
const EntityID ENTITY_ID = comp.GetEID();
// Get physicsObject
auto const* physicsObject = GetPhysicsObject(ENTITY_ID);
auto* physicsObject = GetPhysicsObject(ENTITY_ID);
const bool RP3D_ACTIVE = physicsObject->rp3dBody->isActive();
// TODO(Diren): Check if active in hierarchy
const bool COMPONENT_ACTIVE = comp.isActive;
if (RP3D_ACTIVE != COMPONENT_ACTIVE)
physicsObject->rp3dBody->setIsActive(COMPONENT_ACTIVE);
SyncActiveStates(physicsObject, COMPONENT_ACTIVE);
if (!COMPONENT_ACTIVE)
continue;
@ -706,4 +689,19 @@ namespace SHADE
}
}
SHTransformComponent* SHPhysicsSystem::EnsureTransform(EntityID entityID)
{
auto* tf = SHComponentManager::GetComponent_s<SHTransformComponent>(entityID);
// Possibly redundant
if (!tf)
{
SHComponentManager::AddComponent<SHTransformComponent>(entityID);
tf = SHComponentManager::GetComponent<SHTransformComponent>(entityID);
}
return tf;
}
} // namespace SHADE

View File

@ -19,6 +19,7 @@
#include "SHPhysicsObject.h"
#include "Components/SHRigidBodyComponent.h"
#include "Components/SHColliderComponent.h"
#include "Math/Transform/SHTransformComponent.h"
#include "Scene/SHSceneGraph.h"
#include "ECS_Base/System/SHSystemRoutine.h"
@ -185,11 +186,13 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/
/* Function Members */
/*---------------------------------------------------------------------------------*/
SHPhysicsObject* GetPhysicsObject (EntityID entityID) noexcept;
SHPhysicsObject* CreatePhysicsObject (EntityID entityID) noexcept;
SHPhysicsObject* GetPhysicsObject (EntityID entityID) noexcept;
void SyncRigidBodyComponents (std::vector<SHRigidBodyComponent>& denseArray) noexcept;
void SyncColliderComponents (std::vector<SHColliderComponent>& denseArray) noexcept;
void SyncTransforms () noexcept;
void SyncActiveStates (SHPhysicsObject* physicsObject, bool componentActive) noexcept;
void SyncRigidBodyComponents (std::vector<SHRigidBodyComponent>& denseArray) noexcept;
void SyncColliderComponents (std::vector<SHColliderComponent>& denseArray) noexcept;
void SyncTransforms () noexcept;
// TODO(Diren): Trigger handling
static void SyncRigidBody (SHPhysicsObject const* physicsObject, const SHRigidBodyComponent* comp) noexcept;
@ -197,6 +200,9 @@ namespace SHADE
static void SetRP3DAngularConstraints (rp3d::RigidBody const* rp3dRigidBody, uint8_t rbFlags) noexcept;
static void SyncCollider (SHPhysicsObject const* physicsObject, SHColliderComponent* comp) noexcept;
// TODO(Diren): Remove when responsibility shifted to editor
SHTransformComponent* EnsureTransform (EntityID entityID);
};