Get collision shapes from collider components
This commit is contained in:
parent
d75491f6ed
commit
6577c6c45b
|
@ -1,4 +1,5 @@
|
||||||
#include "simpleengine/camera.h"
|
#include "simpleengine/camera.h"
|
||||||
|
#include "simpleengine/ecs/component/box_collision_component.h"
|
||||||
#include "simpleengine/ecs/component/mesh_component.h"
|
#include "simpleengine/ecs/component/mesh_component.h"
|
||||||
#include "simpleengine/ecs/component/rigid_body_component.h"
|
#include "simpleengine/ecs/component/rigid_body_component.h"
|
||||||
#include "simpleengine/ecs/component/transform_component.h"
|
#include "simpleengine/ecs/component/transform_component.h"
|
||||||
|
@ -11,6 +12,7 @@
|
||||||
#include "simpleengine/gfx/renderer.h"
|
#include "simpleengine/gfx/renderer.h"
|
||||||
#include "simpleengine/gfx/texture.h"
|
#include "simpleengine/gfx/texture.h"
|
||||||
#include "simpleengine/vector.h"
|
#include "simpleengine/vector.h"
|
||||||
|
#include <semaphore.h>
|
||||||
#include <simpleengine/ecs/component/model_component.h>
|
#include <simpleengine/ecs/component/model_component.h>
|
||||||
#include <simpleengine/ecs/component/rotating_component.h>
|
#include <simpleengine/ecs/component/rotating_component.h>
|
||||||
#include <simpleengine/event/event.h>
|
#include <simpleengine/event/event.h>
|
||||||
|
@ -152,25 +154,17 @@ int main(int argc, char *argv[]) {
|
||||||
auto &transform_comp = entity.add_component<se::TransformComponent>();
|
auto &transform_comp = entity.add_component<se::TransformComponent>();
|
||||||
transform_comp.translate(4.f, 0.f, 0.f); */
|
transform_comp.translate(4.f, 0.f, 0.f); */
|
||||||
|
|
||||||
//brick_e.add_component<se::RotatingComponent>();
|
|
||||||
|
|
||||||
se::ecs::Entity brick_e = scene->create_entity();
|
se::ecs::Entity brick_e = scene->create_entity();
|
||||||
brick_e.add_component<se::ecs::ModelComponent>("examples/dev_testing/resources/bricks/bricks.fbx");
|
brick_e.add_component<se::ecs::ModelComponent>("examples/dev_testing/resources/bricks/bricks.fbx");
|
||||||
auto& brick_transf = brick_e.add_component<se::ecs::TransformComponent>(glm::vec3(6.f, 6.f, 0.f));
|
brick_e.add_component<se::ecs::TransformComponent>(glm::vec3(6.f, 6.f, 0.f));
|
||||||
|
brick_e.add_component<se::ecs::BoxColliderComponent>(1.f, 1.f, 1.f);
|
||||||
btCollisionShape* brick_shape = new btBoxShape(btVector3(btScalar(1.f), btScalar(1.f), btScalar(1.f)));
|
brick_e.add_component<se::ecs::RigidBodyComponent>(1.f, se::Vectorf(6.f, 6.f, 0.1f));
|
||||||
auto& brick_rigid = brick_e.add_component<simpleengine::ecs::RigidBodyComponent>(1.f, se::Vectorf(6.f, 6.f, 0.1f), brick_shape);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
se::ecs::Entity floor = scene->create_entity();
|
se::ecs::Entity floor = scene->create_entity();
|
||||||
floor.add_component<se::ecs::ModelComponent>("examples/dev_testing/resources/ground/ground.fbx");
|
floor.add_component<se::ecs::ModelComponent>("examples/dev_testing/resources/ground/ground.fbx");
|
||||||
auto& floor_transf = floor.add_component<se::ecs::TransformComponent>(glm::vec3(6.f, -6.f, 0.f), glm::vec3(0.f), glm::vec3(1.f, 1.f, 1.f));
|
floor.add_component<se::ecs::TransformComponent>(glm::vec3(6.f, -6.f, 0.f), glm::vec3(0.f), glm::vec3(1.f, 1.f, 1.f));
|
||||||
|
floor.add_component<se::ecs::BoxColliderComponent>(1.f, 1.f, 1.f);
|
||||||
btCollisionShape* floor_shape = new btBoxShape(btVector3(btScalar(1.f), btScalar(1.f), btScalar(1.f)));
|
floor.add_component<se::ecs::RigidBodyComponent>(0.f, se::Vectorf(6.f, -6.f, 0.f));
|
||||||
auto& floor_rigid = floor.add_component<simpleengine::ecs::RigidBodyComponent>(0.f, se::Vectorf(6.f, -6.f, 0.f), floor_shape);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
auto light = std::make_shared<se::gfx::Light>(core_shader, glm::vec3(0.f, 0.f, 0.f), glm::vec3(1.f, 1.f, 1.f));
|
auto light = std::make_shared<se::gfx::Light>(core_shader, glm::vec3(0.f, 0.f, 0.f), glm::vec3(1.f, 1.f, 1.f));
|
||||||
game.add_event(light);
|
game.add_event(light);
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../../physics/collision/box_shape.h"
|
||||||
|
|
||||||
|
namespace simpleengine::ecs {
|
||||||
|
/**
|
||||||
|
* @brief A component that contains a Box collision shape.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class BoxColliderComponent {
|
||||||
|
public:
|
||||||
|
physics::collision::BoxShape box_shape;
|
||||||
|
|
||||||
|
BoxColliderComponent(physics::collision::BoxShape box) : box_shape(box) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Create a BoxShape with the extent of the box.
|
||||||
|
*
|
||||||
|
* @note These extents are in half-extents since that's what the underlying Physics engine uses (Bullet).
|
||||||
|
*
|
||||||
|
* @param x_extent The extent of the box in the x direction.
|
||||||
|
* @param y_extent The extent of the box in the y direction.
|
||||||
|
* @param z_extent The extent of the box in the z direction.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
BoxColliderComponent(const float& x_extent, const float& y_extent, const float& z_extent) : box_shape(x_extent, y_extent, z_extent) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Create a BoxShape with the extent of the box.
|
||||||
|
*
|
||||||
|
* @note These extents are in half-extents since that's what the underlying Physics engine uses (Bullet).
|
||||||
|
*
|
||||||
|
* @param extent The extent of the box.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
BoxColliderComponent(const simpleengine::Vectorf& extent) : box_shape(extent) {
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../../physics/collision/collision_shape.h"
|
||||||
|
|
||||||
|
namespace simpleengine::ecs {
|
||||||
|
/**
|
||||||
|
* @brief A component that contains a collision shape.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class CollisionShapeComponent {
|
||||||
|
public:
|
||||||
|
physics::collision::CollisionShape* collision_shape;
|
||||||
|
|
||||||
|
CollisionShapeComponent(physics::collision::CollisionShape* shape) : collision_shape(shape) {
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
|
@ -31,11 +31,11 @@ namespace simpleengine::ecs {
|
||||||
btDefaultMotionState* motion_state;
|
btDefaultMotionState* motion_state;
|
||||||
btCollisionShape* col_shape;
|
btCollisionShape* col_shape;
|
||||||
public:
|
public:
|
||||||
bool initialized = false;
|
//bool initialized = false;
|
||||||
btRigidBody* rigid_body;
|
btRigidBody* rigid_body;
|
||||||
|
|
||||||
RigidBodyComponent(float mass, simpleengine::Vectorf start_origin, btCollisionShape* col_shape) : mass(mass), is_dynamic(mass != 0.f),
|
RigidBodyComponent(float mass, simpleengine::Vectorf start_origin) : mass(mass), is_dynamic(mass != 0.f), rigid_body(nullptr) {
|
||||||
col_shape(col_shape) {
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../../physics/collision/sphere_shape.h"
|
||||||
|
|
||||||
|
namespace simpleengine::ecs {
|
||||||
|
/**
|
||||||
|
* @brief A component that contains a Sphere collision shape.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class SphereColliderComponent {
|
||||||
|
public:
|
||||||
|
physics::collision::SphereShape sphere_shape;
|
||||||
|
|
||||||
|
SphereColliderComponent(physics::collision::SphereShape sphere) : sphere_shape(sphere) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
SphereColliderComponent(const float& radius) : sphere_shape(radius) {
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "BulletCollision/CollisionShapes/btBoxShape.h"
|
#include "../../vector.h"
|
||||||
#include "vector.h"
|
#include <BulletCollision/CollisionShapes/btBoxShape.h>
|
||||||
|
|
||||||
namespace simpleengine::physics::collision {
|
namespace simpleengine::physics::collision {
|
||||||
class BoxShape {
|
class BoxShape {
|
||||||
|
|
|
@ -16,10 +16,13 @@ class btBroadphaseInterface;
|
||||||
class btSequentialImpulseConstraintSolver;
|
class btSequentialImpulseConstraintSolver;
|
||||||
class btDiscreteDynamicsWorld;
|
class btDiscreteDynamicsWorld;
|
||||||
class btRigidBody;
|
class btRigidBody;
|
||||||
|
class btCollisionShape;
|
||||||
|
|
||||||
namespace simpleengine {
|
namespace simpleengine {
|
||||||
namespace ecs {
|
namespace ecs {
|
||||||
class Registry;
|
class Registry;
|
||||||
|
class TransformComponent;
|
||||||
|
class RigidBodyComponent;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace physics {
|
namespace physics {
|
||||||
|
@ -56,6 +59,11 @@ namespace simpleengine {
|
||||||
virtual void input_update(const float& delta_time) override {}
|
virtual void input_update(const float& delta_time) override {}
|
||||||
virtual void render(const float& interpolate_alpha, const float& frame_time) override {}
|
virtual void render(const float& interpolate_alpha, const float& frame_time) override {}
|
||||||
virtual void destroy() override {}
|
virtual void destroy() override {}
|
||||||
|
protected:
|
||||||
|
// Try get a collision shape from an entities components.
|
||||||
|
btCollisionShape* try_get_collision_shape(const entt::entity& entity);
|
||||||
|
/// Initialize a rigid body component.
|
||||||
|
inline bool init_rigid_body_component(const entt::entity& entity, simpleengine::ecs::TransformComponent& transform_comp, simpleengine::ecs::RigidBodyComponent& rigid_body_comp);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,5 +1,9 @@
|
||||||
|
#include "BulletCollision/CollisionShapes/btCollisionShape.h"
|
||||||
|
#include "ecs/component/box_collision_component.h"
|
||||||
#include "ecs/component/rigid_body_component.h"
|
#include "ecs/component/rigid_body_component.h"
|
||||||
|
#include "ecs/component/sphere_collision_component.h"
|
||||||
#include "ecs/system/system.h"
|
#include "ecs/system/system.h"
|
||||||
|
#include "entt/entity/fwd.hpp"
|
||||||
#include "physics/physics_system.h"
|
#include "physics/physics_system.h"
|
||||||
#include "ecs/component/transform_component.h"
|
#include "ecs/component/transform_component.h"
|
||||||
#include "ecs/entity.h"
|
#include "ecs/entity.h"
|
||||||
|
@ -45,46 +49,74 @@ namespace simpleengine::physics {
|
||||||
if (should_simulate) {
|
if (should_simulate) {
|
||||||
dynamics_world->stepSimulation(delta_time, 10);
|
dynamics_world->stepSimulation(delta_time, 10);
|
||||||
|
|
||||||
entity_registry->get_inner().view<simpleengine::ecs::TransformComponent, simpleengine::ecs::RigidBodyComponent>().each([this](simpleengine::ecs::TransformComponent& transform_comp, simpleengine::ecs::RigidBodyComponent& rigid_body_comp) {
|
entity_registry->get_inner().view<simpleengine::ecs::TransformComponent, simpleengine::ecs::RigidBodyComponent>()
|
||||||
|
.each([this](const entt::entity& entity, simpleengine::ecs::TransformComponent& transform_comp, simpleengine::ecs::RigidBodyComponent& rigid_body_comp) {
|
||||||
//transform_comp
|
// Initialize the rigid body component if it hasn't already been initialized.
|
||||||
if (!rigid_body_comp.initialized) {
|
init_rigid_body_component(entity, transform_comp, rigid_body_comp);
|
||||||
btTransform start_transform;
|
|
||||||
start_transform.setIdentity();
|
|
||||||
|
|
||||||
glm::vec3 origin = transform_comp.get_pos();
|
btRigidBody* rigid_body = rigid_body_comp.rigid_body;
|
||||||
start_transform.setOrigin(btVector3(origin.x, origin.y, origin.z));
|
btTransform trans;
|
||||||
|
if (rigid_body_comp.rigid_body->getMotionState()) {
|
||||||
glm::quat rot = transform_comp.get_rotation_quat();
|
rigid_body->getMotionState()->getWorldTransform(trans);
|
||||||
start_transform.setRotation(btQuaternion(rot.x, rot.y, rot.z, rot.w));
|
|
||||||
|
trans.getOpenGLMatrix(glm::value_ptr(transform_comp.transform_matrix));
|
||||||
btScalar mass_scalar(rigid_body_comp.mass);
|
|
||||||
|
|
||||||
btVector3 local_inertia;
|
|
||||||
if (rigid_body_comp.is_dynamic) {
|
|
||||||
// update collision shape
|
|
||||||
rigid_body_comp.col_shape->calculateLocalInertia(rigid_body_comp.mass, local_inertia);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rigid_body_comp.motion_state = new btDefaultMotionState(start_transform);
|
|
||||||
btRigidBody::btRigidBodyConstructionInfo rb_info(rigid_body_comp.mass, rigid_body_comp.motion_state, rigid_body_comp.col_shape, local_inertia);
|
|
||||||
rigid_body_comp.rigid_body = new btRigidBody(rb_info);
|
|
||||||
|
|
||||||
this->add_rigid_body(rigid_body_comp.rigid_body);
|
|
||||||
rigid_body_comp.initialized = true;
|
|
||||||
|
|
||||||
logger.debug("Initialized rigid body component");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
btRigidBody* rigid_body = rigid_body_comp.rigid_body;
|
|
||||||
btTransform trans;
|
|
||||||
if (rigid_body_comp.rigid_body->getMotionState()) {
|
|
||||||
rigid_body->getMotionState()->getWorldTransform(trans);
|
|
||||||
|
|
||||||
trans.getOpenGLMatrix(glm::value_ptr(transform_comp.transform_matrix));
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
btCollisionShape* PhysicsSystem::try_get_collision_shape(const entt::entity& entity) {
|
||||||
|
btCollisionShape* collision_shape;
|
||||||
|
if (auto box_col = entity_registry->get_inner().try_get<simpleengine::ecs::BoxColliderComponent>(entity)) {
|
||||||
|
return box_col->box_shape.get_inner_ptr();
|
||||||
|
} else if (auto sphere_col = entity_registry->get_inner().try_get<simpleengine::ecs::SphereColliderComponent>(entity)) {
|
||||||
|
return sphere_col->sphere_shape.get_inner_ptr();
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PhysicsSystem::init_rigid_body_component(const entt::entity& entity, simpleengine::ecs::TransformComponent& transform_comp, simpleengine::ecs::RigidBodyComponent& rigid_body_comp) {
|
||||||
|
if (!rigid_body_comp.rigid_body) {
|
||||||
|
// Try to get the collision shape
|
||||||
|
btCollisionShape* collision_shape = try_get_collision_shape(entity);
|
||||||
|
if (!collision_shape) {
|
||||||
|
logger.warn("Entity with a rigid body component is missing a collider! The entities rigid body component will be removed!");
|
||||||
|
|
||||||
|
if (entity_registry->get_inner().remove<simpleengine::ecs::RigidBodyComponent>(entity) == 0) {
|
||||||
|
logger.warn("Failed to remove rigid body component from the entity!");
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
btTransform start_transform;
|
||||||
|
start_transform.setIdentity();
|
||||||
|
|
||||||
|
glm::vec3 origin = transform_comp.get_pos();
|
||||||
|
start_transform.setOrigin(btVector3(origin.x, origin.y, origin.z));
|
||||||
|
|
||||||
|
glm::quat rot = transform_comp.get_rotation_quat();
|
||||||
|
start_transform.setRotation(btQuaternion(rot.x, rot.y, rot.z, rot.w));
|
||||||
|
|
||||||
|
rigid_body_comp.col_shape = collision_shape;
|
||||||
|
|
||||||
|
btVector3 local_inertia;
|
||||||
|
if (rigid_body_comp.is_dynamic) {
|
||||||
|
// update collision shape
|
||||||
|
rigid_body_comp.col_shape->calculateLocalInertia(rigid_body_comp.mass, local_inertia);
|
||||||
|
}
|
||||||
|
|
||||||
|
rigid_body_comp.motion_state = new btDefaultMotionState(start_transform);
|
||||||
|
btRigidBody::btRigidBodyConstructionInfo rb_info(rigid_body_comp.mass, rigid_body_comp.motion_state, rigid_body_comp.col_shape, local_inertia);
|
||||||
|
rigid_body_comp.rigid_body = new btRigidBody(rb_info);
|
||||||
|
|
||||||
|
this->add_rigid_body(rigid_body_comp.rigid_body);
|
||||||
|
|
||||||
|
logger.debug("Initialized rigid body component");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue