From d75491f6ed8b498a92100a368fd7e231fd1bc804 Mon Sep 17 00:00:00 2001 From: SeanOMik Date: Thu, 10 Nov 2022 19:07:05 -0500 Subject: [PATCH 1/5] Changes to ECS, create simple Bullet physics system --- CMakeLists.txt | 3 + examples/dev_testing/src/main.cpp | 51 ++++++++--- .../ecs/component/mesh_component.h | 2 +- .../ecs/component/model_component.h | 2 +- .../ecs/component/rigid_body_component.h | 41 +++++++++ .../ecs/component/rotating_component.h | 2 +- .../ecs/component/transform_component.h | 62 +++++++++++-- include/simpleengine/ecs/registry.h | 22 +++++ .../simpleengine/ecs/system/scene_system.h | 33 +++++++ include/simpleengine/ecs/system/system.h | 24 +++++ include/simpleengine/event/event.h | 3 - include/simpleengine/log/logger.h | 2 +- .../physics/collision/box_shape.h | 60 +++++++++++++ .../physics/collision/capsule_shape.h | 37 ++++++++ .../physics/collision/collision_shape.h | 19 ++++ .../physics/collision/cone_shape.h | 25 ++++++ .../physics/collision/cylinder_shape.h | 60 +++++++++++++ .../physics/collision/sphere_shape.h | 37 ++++++++ include/simpleengine/physics/physics_system.h | 61 +++++++++++++ include/simpleengine/scene.h | 44 --------- include/simpleengine/vector.h | 6 +- shell.nix | 1 + src/ecs/registry.cpp | 16 ++++ .../system/scene_system.cpp} | 46 ++++++---- src/ecs/system/system.cpp | 13 +++ src/gfx/renderer.cpp | 1 + src/physics/physics_system.cpp | 90 +++++++++++++++++++ 27 files changed, 669 insertions(+), 94 deletions(-) create mode 100644 include/simpleengine/ecs/component/rigid_body_component.h create mode 100644 include/simpleengine/ecs/registry.h create mode 100644 include/simpleengine/ecs/system/scene_system.h create mode 100644 include/simpleengine/ecs/system/system.h create mode 100644 include/simpleengine/physics/collision/box_shape.h create mode 100644 include/simpleengine/physics/collision/capsule_shape.h create mode 100644 include/simpleengine/physics/collision/collision_shape.h create mode 100644 include/simpleengine/physics/collision/cone_shape.h create mode 100644 include/simpleengine/physics/collision/cylinder_shape.h create mode 100644 include/simpleengine/physics/collision/sphere_shape.h create mode 100644 include/simpleengine/physics/physics_system.h delete mode 100644 include/simpleengine/scene.h create mode 100644 src/ecs/registry.cpp rename src/{scene.cpp => ecs/system/scene_system.cpp} (53%) create mode 100644 src/ecs/system/system.cpp create mode 100644 src/physics/physics_system.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index ea9d78e..92ccadd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,6 +24,7 @@ find_package(OpenGL REQUIRED) find_package(fmt REQUIRED) find_package(spdlog REQUIRED) find_package(assimp CONFIG REQUIRED) +find_package(Bullet REQUIRED) # Link sources file(GLOB_RECURSE source_list src/*.cpp) @@ -51,6 +52,7 @@ target_link_libraries(simpleengine PUBLIC fmt) target_link_libraries(simpleengine PUBLIC spdlog) target_link_libraries(simpleengine PUBLIC ${GLM_LIBRARIES}) target_link_libraries(simpleengine PUBLIC ${OPENGL_LIBRARIES}) +target_link_libraries(simpleengine PUBLIC ${BULLET_LIBRARIES}) if(WIN32) target_link_libraries(simpleengine PUBLIC assimp::assimp) else() @@ -66,6 +68,7 @@ target_include_directories(simpleengine PUBLIC ${OPENGL_INCLUDE_DIR}) target_include_directories(simpleengine PUBLIC ${GLM_INCLUDE_DIRS}) target_include_directories(simpleengine PUBLIC ${STB_INCLUDE_DIR}) target_include_directories(simpleengine PUBLIC ${ENTT_INCLUDE_DIR}) +target_include_directories(simpleengine PUBLIC ${BULLET_INCLUDE_DIRS}) # Add examples as a target if the user has them enabled if (SIMPLE_ENGINE_BUILD_EXAMPLES) diff --git a/examples/dev_testing/src/main.cpp b/examples/dev_testing/src/main.cpp index e3a1f39..aecae85 100644 --- a/examples/dev_testing/src/main.cpp +++ b/examples/dev_testing/src/main.cpp @@ -1,7 +1,9 @@ #include "simpleengine/camera.h" #include "simpleengine/ecs/component/mesh_component.h" +#include "simpleengine/ecs/component/rigid_body_component.h" #include "simpleengine/ecs/component/transform_component.h" #include "simpleengine/ecs/entity.h" +#include "simpleengine/ecs/registry.h" #include "simpleengine/gfx/light.h" #include "simpleengine/gfx/material.h" #include "simpleengine/gfx/mesh.h" @@ -9,7 +11,6 @@ #include "simpleengine/gfx/renderer.h" #include "simpleengine/gfx/texture.h" #include "simpleengine/vector.h" -#include #include #include #include @@ -18,15 +19,20 @@ #include #include #include -#include #include +#include #include #include +#include + +#include "entt/entity/fwd.hpp" #include #include #include +#include + #include #include #include @@ -34,6 +40,8 @@ #include #include +#include + namespace se = simpleengine; class FPSCounterEvent : public se::Renderable { @@ -107,26 +115,28 @@ int main(int argc, char *argv[]) { se::log::LoggerManager::set_level(spdlog::level::trace); se::log::LoggerPtr logger = se::log::LoggerManager::get_core_logger(); - logger->info("Hmmmm very cool"); // Load core shaders from SimpleEngine resources se::gfx::shaders::Core3dShader core_shader; - auto camera = std::make_shared(game.get_window(), core_shader, 70, glm::vec3(0, 0, 0)); + // Create an entity registry + auto registry = std::make_shared(); + + auto camera = std::make_shared(game.get_window(), core_shader, 70, glm::vec3(-6, 0, 0)); //game.add_event(camera); // Create a renderer auto renderer = std::make_shared(game.get_window(), core_shader, camera); renderer->initialize(); - //game.add_renderable(renderer); - - logger->error("AHHHHH SOMETHING BAD!"); // Create a Scene and give it the renderer - auto scene = std::make_shared(renderer, camera); - //game.add_event(scene); + auto scene = std::make_shared(registry, renderer, camera); game.add_renderable(scene); + // Create a Physics System for handling the physics + auto physics_sys = std::make_shared(registry); + game.add_event(physics_sys); + /* se::ecs::Entity other_e = scene->create_entity(); other_e.add_component("examples/dev_testing/resources/transparent_window.fbx", se::gfx::ModelProcessingFlags::MdlProcFlag_TRANSPARENT); @@ -142,12 +152,25 @@ int main(int argc, char *argv[]) { auto &transform_comp = entity.add_component(); transform_comp.translate(4.f, 0.f, 0.f); */ + //brick_e.add_component(); + se::ecs::Entity brick_e = scene->create_entity(); - brick_e.add_component("examples/dev_testing/resources/bricks/bricks.fbx"); - brick_e.add_component(); - auto &brick_transf = brick_e.add_component(); - brick_transf.translate(6.f, 0.f, 0.f); - //brick_transf.translate(6.f, -0.5f, 1.f); + brick_e.add_component("examples/dev_testing/resources/bricks/bricks.fbx"); + auto& brick_transf = brick_e.add_component(glm::vec3(6.f, 6.f, 0.f)); + + btCollisionShape* brick_shape = new btBoxShape(btVector3(btScalar(1.f), btScalar(1.f), btScalar(1.f))); + auto& brick_rigid = brick_e.add_component(1.f, se::Vectorf(6.f, 6.f, 0.1f), brick_shape); + + + + se::ecs::Entity floor = scene->create_entity(); + floor.add_component("examples/dev_testing/resources/ground/ground.fbx"); + auto& floor_transf = floor.add_component(glm::vec3(6.f, -6.f, 0.f), glm::vec3(0.f), glm::vec3(1.f, 1.f, 1.f)); + + btCollisionShape* floor_shape = new btBoxShape(btVector3(btScalar(1.f), btScalar(1.f), btScalar(1.f))); + auto& floor_rigid = floor.add_component(0.f, se::Vectorf(6.f, -6.f, 0.f), floor_shape); + + auto light = std::make_shared(core_shader, glm::vec3(0.f, 0.f, 0.f), glm::vec3(1.f, 1.f, 1.f)); game.add_event(light); diff --git a/include/simpleengine/ecs/component/mesh_component.h b/include/simpleengine/ecs/component/mesh_component.h index 6e2bf15..e14633c 100644 --- a/include/simpleengine/ecs/component/mesh_component.h +++ b/include/simpleengine/ecs/component/mesh_component.h @@ -6,7 +6,7 @@ #include #include -namespace simpleengine { +namespace simpleengine::ecs { /** * @brief A component that contains a Mesh that will be rendered. * diff --git a/include/simpleengine/ecs/component/model_component.h b/include/simpleengine/ecs/component/model_component.h index cac09de..e792290 100644 --- a/include/simpleengine/ecs/component/model_component.h +++ b/include/simpleengine/ecs/component/model_component.h @@ -5,7 +5,7 @@ #include #include -namespace simpleengine { +namespace simpleengine::ecs { /** * @brief A component that contains a Model that will be rendered. * diff --git a/include/simpleengine/ecs/component/rigid_body_component.h b/include/simpleengine/ecs/component/rigid_body_component.h new file mode 100644 index 0000000..ff8ae70 --- /dev/null +++ b/include/simpleengine/ecs/component/rigid_body_component.h @@ -0,0 +1,41 @@ +#pragma once + +#include "../../gfx/model.h" +#include "simpleengine/vector.h" + +#include +#include +#include +#include +#include +#include + +#include + +namespace simpleengine::physics { + class PhysicsSystem; +} + +namespace simpleengine::ecs { + /** + * @brief A component that contains a Model that will be rendered. + * + */ + class RigidBodyComponent { + friend simpleengine::physics::PhysicsSystem; + private: + float mass; + bool is_dynamic; + + // TODO: Free + btDefaultMotionState* motion_state; + btCollisionShape* col_shape; + public: + bool initialized = false; + btRigidBody* rigid_body; + + RigidBodyComponent(float mass, simpleengine::Vectorf start_origin, btCollisionShape* col_shape) : mass(mass), is_dynamic(mass != 0.f), + col_shape(col_shape) { + } + }; +} \ No newline at end of file diff --git a/include/simpleengine/ecs/component/rotating_component.h b/include/simpleengine/ecs/component/rotating_component.h index ab33827..7dee920 100644 --- a/include/simpleengine/ecs/component/rotating_component.h +++ b/include/simpleengine/ecs/component/rotating_component.h @@ -2,7 +2,7 @@ #include -namespace simpleengine { +namespace simpleengine::ecs { /** * @brief A component that will rotate the transform every frame. * diff --git a/include/simpleengine/ecs/component/transform_component.h b/include/simpleengine/ecs/component/transform_component.h index 9a15519..5f5f00f 100644 --- a/include/simpleengine/ecs/component/transform_component.h +++ b/include/simpleengine/ecs/component/transform_component.h @@ -1,26 +1,42 @@ #pragma once -//#include "simpleengine/scene.h" +#include #include +#include #include -namespace simpleengine { +namespace simpleengine::ecs { + namespace system { + class SceneSystem; + } + /** * @brief A component that contains a Mesh that will be rendered. * */ class TransformComponent { - friend class Scene; - private: + friend simpleengine::ecs::system::SceneSystem; + public: // This is the transform from the last render loop. The renderer uses this for frame interprelation glm::mat4 last_transform_matrix; - public: glm::mat4 transform_matrix; TransformComponent() : transform_matrix(1.f), last_transform_matrix(1.f) { } + TransformComponent(glm::vec3 initial_position, glm::vec3 initial_rotation = glm::vec3(0.f), glm::vec3 initial_scale = glm::vec3(1.f)) + : transform_matrix(1.f), last_transform_matrix(1.f) { + + translate(initial_position); + + rotate_x(initial_rotation.x); + rotate_y(initial_rotation.y); + rotate_z(initial_rotation.z); + + scale(initial_scale); + } + TransformComponent(glm::mat4 transform_matrix) : transform_matrix(transform_matrix), last_transform_matrix(1.f) { } @@ -45,6 +61,38 @@ namespace simpleengine { return lhs; } + virtual void decompose_matrix(glm::vec3& pos, glm::quat& rot, glm::vec3& scale) const { + pos = transform_matrix[3]; + for(int i = 0; i < 3; i++) { + scale[i] = glm::length(glm::vec3(transform_matrix[i])); + } + + const glm::mat3 rotMtx(glm::vec3(transform_matrix[0]) / scale[0], + glm::vec3(transform_matrix[1]) / scale[1], glm::vec3(transform_matrix[2]) / scale[2]); + rot = glm::quat_cast(rotMtx); + } + + virtual glm::vec3 get_pos() const { + return transform_matrix[3]; + } + + virtual glm::vec3 get_scale() const { + glm::vec3 scale; + for(int i = 0; i < 3; i++) { + scale[i] = glm::length(glm::vec3(transform_matrix[i])); + } + + return scale; + } + + virtual glm::quat get_rotation_quat() const { + glm::vec3 scale = get_scale(); + + const glm::mat3 rot_mtx(glm::vec3(transform_matrix[0]) / scale[0], + glm::vec3(transform_matrix[1]) / scale[1], glm::vec3(transform_matrix[2]) / scale[2]); + return glm::quat_cast(rot_mtx); + } + virtual void combine_transform(const glm::mat4& transform_matrix) { this->transform_matrix *= transform_matrix; } @@ -57,9 +105,9 @@ namespace simpleengine { transform_matrix = glm::translate(transform_matrix, glm::vec3(x, y, z)); } - /* virtual void translate(const glm::vec3& vec) { + virtual void translate(const glm::vec3& vec) { transform_matrix = glm::translate(transform_matrix, vec); - } */ + } virtual glm::mat4 rotation_matrix(float degrees, glm::vec3 rotation_axis) const { return glm::rotate(transform_matrix, glm::radians(degrees), rotation_axis); diff --git a/include/simpleengine/ecs/registry.h b/include/simpleengine/ecs/registry.h new file mode 100644 index 0000000..0399d63 --- /dev/null +++ b/include/simpleengine/ecs/registry.h @@ -0,0 +1,22 @@ +#pragma once + +#include "entt/signal/fwd.hpp" +#include + +namespace simpleengine::ecs { + class Entity; + + class Registry { + entt::registry inner; + //entt::dispatcher dispatcher; + public: + Registry(); + + entt::registry& get_inner(); + Entity create_entity(); + }; + + /* struct NewEntityEvent { + Entity& entity; + }; */ +} \ No newline at end of file diff --git a/include/simpleengine/ecs/system/scene_system.h b/include/simpleengine/ecs/system/scene_system.h new file mode 100644 index 0000000..a49279f --- /dev/null +++ b/include/simpleengine/ecs/system/scene_system.h @@ -0,0 +1,33 @@ +#pragma once + +#include "system.h" + +namespace simpleengine { + // fwd decl + class Camera; + namespace gfx { + class Renderer; + } + + namespace ecs { + class Entity; + class Registry; + + namespace system { + class SceneSystem : public System { + protected: + std::shared_ptr renderer; + std::shared_ptr camera; + public: + SceneSystem(std::shared_ptr entity_registry, std::shared_ptr renderer, std::shared_ptr camera); + + ecs::Entity create_entity(); + + virtual void 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 destroy() override; + }; + } + } +} \ No newline at end of file diff --git a/include/simpleengine/ecs/system/system.h b/include/simpleengine/ecs/system/system.h new file mode 100644 index 0000000..5f0e392 --- /dev/null +++ b/include/simpleengine/ecs/system/system.h @@ -0,0 +1,24 @@ +#pragma once + +#include "../../renderable.h" + +namespace simpleengine::ecs { + class Entity; + class Registry; + + namespace system { + class System : public simpleengine::Renderable { + protected: + std::shared_ptr entity_registry; + public: + System(std::shared_ptr entity_registry); + + ecs::Entity create_entity(); + + virtual void update(const float& delta_time) = 0; + virtual void input_update(const float& delta_time) = 0; + virtual void render(const float& interpolate_alpha, const float& frame_time) = 0; + virtual void destroy() = 0; + }; + } +} \ No newline at end of file diff --git a/include/simpleengine/event/event.h b/include/simpleengine/event/event.h index 35d09b7..edeeabc 100644 --- a/include/simpleengine/event/event.h +++ b/include/simpleengine/event/event.h @@ -7,9 +7,6 @@ namespace simpleengine { class Event : public simpleengine::Destructable { public: - Event() = default; - virtual ~Event() = default; - /** * @brief The update function with fixed-timestep. * diff --git a/include/simpleengine/log/logger.h b/include/simpleengine/log/logger.h index 0febd5b..42ea67b 100644 --- a/include/simpleengine/log/logger.h +++ b/include/simpleengine/log/logger.h @@ -1,4 +1,4 @@ -//#define SPDLOG_FMT_EXTERNAL +#pragma once #include #include diff --git a/include/simpleengine/physics/collision/box_shape.h b/include/simpleengine/physics/collision/box_shape.h new file mode 100644 index 0000000..e592149 --- /dev/null +++ b/include/simpleengine/physics/collision/box_shape.h @@ -0,0 +1,60 @@ +#pragma once + +#include "BulletCollision/CollisionShapes/btBoxShape.h" +#include "vector.h" + +namespace simpleengine::physics::collision { + class BoxShape { + btBoxShape inner; + public: + BoxShape() = default; + + BoxShape(btBoxShape inner) : inner(inner) { + + } + + /** + * @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. + * + */ + BoxShape(const float& x_extent, const float& y_extent, const float& z_extent) : inner(btVector3(btScalar(x_extent), btScalar(y_extent), btScalar(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. + * + */ + BoxShape(const simpleengine::Vectorf& extent) : BoxShape(extent.x(), extent.y(), extent.z()) { + + } + + /** + * @brief Get the inner bullet box shape object as a pointer. + * + * @return btBoxShape* + */ + btBoxShape* get_inner_ptr() { + return &inner; + } + + /** + * @brief Get the inner bullet box shape object as a reference. + * + * @return btBoxShape& + */ + btBoxShape& get_inner() { + return inner; + } + }; +} \ No newline at end of file diff --git a/include/simpleengine/physics/collision/capsule_shape.h b/include/simpleengine/physics/collision/capsule_shape.h new file mode 100644 index 0000000..cfe9ca0 --- /dev/null +++ b/include/simpleengine/physics/collision/capsule_shape.h @@ -0,0 +1,37 @@ +#pragma once + +#include "BulletCollision/CollisionShapes/btCapsuleShape.h" + +namespace simpleengine::physics::collision { + class CapsuleShape { + btCapsuleShape inner; + public: + CapsuleShape() = default; + + CapsuleShape(btCapsuleShape inner) : inner(inner) { + + } + + CapsuleShape(const float& radius, const float& height) : inner(radius, height) { + + } + + /** + * @brief Get the inner bullet capsule shape object as a pointer. + * + * @return btCapsuleShape* + */ + btCapsuleShape* get_inner_ptr() { + return &inner; + } + + /** + * @brief Get the inner bullet capsule shape object as a reference. + * + * @return btCapsuleShape& + */ + btCapsuleShape& get_inner() { + return inner; + } + }; +} \ No newline at end of file diff --git a/include/simpleengine/physics/collision/collision_shape.h b/include/simpleengine/physics/collision/collision_shape.h new file mode 100644 index 0000000..17ccf1d --- /dev/null +++ b/include/simpleengine/physics/collision/collision_shape.h @@ -0,0 +1,19 @@ +#pragma once + +#include "BulletCollision/CollisionShapes/btCollisionShape.h" + +namespace simpleengine::physics::collision { + class CollisionShape { + btCollisionShape* inner; + public: + CollisionShape() = default; + + CollisionShape(btCollisionShape* inner) : inner(inner) { + + } + + btCollisionShape* get_inner() { + return inner; + } + }; +} \ No newline at end of file diff --git a/include/simpleengine/physics/collision/cone_shape.h b/include/simpleengine/physics/collision/cone_shape.h new file mode 100644 index 0000000..3e6884c --- /dev/null +++ b/include/simpleengine/physics/collision/cone_shape.h @@ -0,0 +1,25 @@ +#pragma once + +#include + +#include "BulletCollision/CollisionShapes/btConeShape.h" + +namespace simpleengine::physics::collision { + class ConeShape { + btConeShape inner; + public: + ConeShape() = default; + + ConeShape(btConeShape inner) : inner(std::move(inner)) { + + } + + ConeShape(float radius, float height) : inner(radius, height) { + + } + + btConeShape* get_inner() { + return &inner; + } + }; +} \ No newline at end of file diff --git a/include/simpleengine/physics/collision/cylinder_shape.h b/include/simpleengine/physics/collision/cylinder_shape.h new file mode 100644 index 0000000..774fc0a --- /dev/null +++ b/include/simpleengine/physics/collision/cylinder_shape.h @@ -0,0 +1,60 @@ +#pragma once + +#include "BulletCollision/CollisionShapes/btCylinderShape.h" +#include "vector.h" + +namespace simpleengine::physics::collision { + class CylinderShape { + btCylinderShape inner; + public: + CylinderShape() = default; + + CylinderShape(btCylinderShape inner) : inner(inner) { + + } + + /** + * @brief Create a CylinderShape 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. + * + */ + CylinderShape(const float& x_extent, const float& y_extent, const float& z_extent) : inner(btVector3(btScalar(x_extent), btScalar(y_extent), btScalar(z_extent))) { + + } + + /** + * @brief Create a CylinderShape 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 cylinder. + * + */ + CylinderShape(const simpleengine::Vectorf& extent) : CylinderShape(extent.x(), extent.y(), extent.z()) { + + } + + /** + * @brief Get the inner bullet cylinder shape object as a pointer. + * + * @return btCylinderShape* + */ + btCylinderShape* get_inner_ptr() { + return &inner; + } + + /** + * @brief Get the inner bullet cylinder shape object as a reference. + * + * @return btCylinderShape& + */ + btCylinderShape& get_inner() { + return inner; + } + }; +} \ No newline at end of file diff --git a/include/simpleengine/physics/collision/sphere_shape.h b/include/simpleengine/physics/collision/sphere_shape.h new file mode 100644 index 0000000..4d0f89e --- /dev/null +++ b/include/simpleengine/physics/collision/sphere_shape.h @@ -0,0 +1,37 @@ +#pragma once + +#include "BulletCollision/CollisionShapes/btSphereShape.h" + +namespace simpleengine::physics::collision { + class SphereShape { + btSphereShape inner; + public: + SphereShape() = default; + + SphereShape(btSphereShape inner) : inner(inner) { + + } + + SphereShape(const float& radius) : inner(btScalar(radius)) { + + } + + /** + * @brief Get the inner bullet sphere shape object as a pointer. + * + * @return btSphereShape* + */ + btSphereShape* get_inner_ptr() { + return &inner; + } + + /** + * @brief Get the inner bullet sphere shape object as a reference. + * + * @return btSphereShape& + */ + btSphereShape& get_inner() { + return inner; + } + }; +} \ No newline at end of file diff --git a/include/simpleengine/physics/physics_system.h b/include/simpleengine/physics/physics_system.h new file mode 100644 index 0000000..738bfc9 --- /dev/null +++ b/include/simpleengine/physics/physics_system.h @@ -0,0 +1,61 @@ +#pragma once + +#include "../vector.h" +#include "../ecs/entity.h" +#include "../log/logger.h" +#include "../ecs/system/system.h" + +#include + +#include +#include + +class btDefaultCollisionConfiguration; +class btCollisionDispatcher; +class btBroadphaseInterface; +class btSequentialImpulseConstraintSolver; +class btDiscreteDynamicsWorld; +class btRigidBody; + +namespace simpleengine { + namespace ecs { + class Registry; + } + + namespace physics { + class PhysicsSystem : public simpleengine::ecs::system::System { + protected: + std::unique_ptr collision_configuration; + std::unique_ptr col_dispatcher; + std::unique_ptr overlapping_pair_cache; + std::unique_ptr solver; + std::unique_ptr dynamics_world; + + simpleengine::log::Logger logger; + public: + simpleengine::Vectorf gravity_vector; + bool should_simulate; + + PhysicsSystem(std::shared_ptr entity_registry); + ~PhysicsSystem(); + + void set_y_gravity(const float& gravity); + + /** + * @brief Add a *manually* constructed rigid body to the Physics System. + * + * @note Do not add a rigid body from a rigid body component. This will be added automatically by the Physics System. + * + * @param rigid_body The rigid body that *manually* created. + */ + void add_rigid_body(btRigidBody* rigid_body); + + virtual void update(const float& delta_time) override; + + // Empty implementations + virtual void input_update(const float& delta_time) override {} + virtual void render(const float& interpolate_alpha, const float& frame_time) override {} + virtual void destroy() override {} + }; + } +} \ No newline at end of file diff --git a/include/simpleengine/scene.h b/include/simpleengine/scene.h deleted file mode 100644 index 56820dd..0000000 --- a/include/simpleengine/scene.h +++ /dev/null @@ -1,44 +0,0 @@ -#pragma once - -#include "camera.h" -#include "entt/entity/fwd.hpp" -#include "gfx/mesh.h" -#include "event/event.h" -#include "renderable.h" -#include "simpleengine/gfx/renderer.h" - -#include - -#include -#include -#include - -#include - -namespace simpleengine { - namespace ecs { - class Entity; - } - - //class Scene : public simpleengine::Event { - class Scene : public simpleengine::Renderable { - protected: - entt::registry registry; - std::shared_ptr renderer; - - // Last transform matrixes for all entities. - std::unordered_map last_transforms; - - std::shared_ptr camera; - public: - Scene(std::shared_ptr renderer, std::shared_ptr camera); - - ecs::Entity create_entity(); - - virtual void 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 destroy() override; - }; -} \ No newline at end of file diff --git a/include/simpleengine/vector.h b/include/simpleengine/vector.h index 53bc814..d0a21dc 100644 --- a/include/simpleengine/vector.h +++ b/include/simpleengine/vector.h @@ -29,15 +29,15 @@ namespace simpleengine { return inner_vec; } - VectorType& x() { + const VectorType& x() const { return inner_vec.x; } - VectorType& y() { + const VectorType& y() const { return inner_vec.y; } - VectorType& z() { + const VectorType& z() const { return inner_vec.z; } diff --git a/shell.nix b/shell.nix index 0412ece..0246176 100644 --- a/shell.nix +++ b/shell.nix @@ -13,5 +13,6 @@ pkgs.mkShell { glm assimp spdlog + bullet ]; } \ No newline at end of file diff --git a/src/ecs/registry.cpp b/src/ecs/registry.cpp new file mode 100644 index 0000000..7a1dd70 --- /dev/null +++ b/src/ecs/registry.cpp @@ -0,0 +1,16 @@ +#include "ecs/registry.h" +#include "ecs/entity.h" + +namespace simpleengine::ecs { + Registry::Registry() { + + } + + entt::registry& Registry::get_inner() { + return inner; + } + + Entity Registry::create_entity() { + return ecs::Entity(inner, inner.create()); + } +} \ No newline at end of file diff --git a/src/scene.cpp b/src/ecs/system/scene_system.cpp similarity index 53% rename from src/scene.cpp rename to src/ecs/system/scene_system.cpp index 2ecb694..29e9f85 100644 --- a/src/scene.cpp +++ b/src/ecs/system/scene_system.cpp @@ -1,42 +1,50 @@ -#include "scene.h" -#include "ecs/component/mesh_component.h" -#include "ecs/component/model_component.h" +#include "gfx/renderer.h" +#include "ecs/system/scene_system.h" #include "ecs/component/transform_component.h" #include "ecs/component/rotating_component.h" #include "ecs/entity.h" -#include "gfx/renderer.h" +#include "ecs/registry.h" +#include "ecs/component/model_component.h" +#include "ecs/component/mesh_component.h" #include #include -namespace simpleengine { - Scene::Scene(std::shared_ptr renderer, std::shared_ptr camera) : renderer(renderer), camera(camera) { +#include +#include + +using namespace simpleengine::ecs; + +namespace simpleengine::ecs::system { + + SceneSystem::SceneSystem(std::shared_ptr entity_registry, std::shared_ptr renderer, std::shared_ptr camera) + : System(entity_registry), renderer(renderer), camera(camera) { } - ecs::Entity Scene::create_entity() { - return ecs::Entity(registry, registry.create()); + ecs::Entity SceneSystem::create_entity() { + return entity_registry->create_entity(); } - void Scene::input_update(const float& delta_time) { + void SceneSystem::input_update(const float& delta_time) { camera->input_update(delta_time); // Update camera input } - void Scene::update(const float& delta_time) { + void SceneSystem::update(const float& delta_time) { // Update the last transform matrix - registry.view().each([this, &delta_time](TransformComponent& transform) { + entity_registry->get_inner().view().each([this, &delta_time](TransformComponent& transform) { transform.last_transform_matrix = transform.transform_matrix; }); // Rotate the model - registry.view().each([this, &delta_time](TransformComponent& transform, RotatingComponent& rotating) { + /* registry->view().each([this, &delta_time](TransformComponent& transform, RotatingComponent& rotating) { transform.rotate(rotating.rate * delta_time, rotating.rotation_axis); - }); + }); */ } - void Scene::render(const float& interpolate_alpha, const float& frame_time) { + void SceneSystem::render(const float& interpolate_alpha, const float& frame_time) { // Is there a way these can be grouped? - registry.view().each([this](TransformComponent& transform, ModelComponent& model_component) { + entity_registry->get_inner().view().each([this](TransformComponent& transform, ModelComponent& model_component) { for (auto& mesh : model_component.model.meshes) { auto rendering_type = gfx::RenderingType::RendType_OPAQUE; if (mesh.material) { @@ -47,7 +55,7 @@ namespace simpleengine { } }); - registry.view().each([this](TransformComponent& transform, MeshComponent& mesh_component) { + entity_registry->get_inner().view().each([this](TransformComponent& transform, MeshComponent& mesh_component) { auto rendering_type = gfx::RenderingType::RendType_OPAQUE; if (mesh_component.mesh.material) { rendering_type = mesh_component.mesh.material->rendering_type; @@ -59,15 +67,15 @@ namespace simpleengine { renderer->render(interpolate_alpha, frame_time); } - void Scene::destroy() { + void SceneSystem::destroy() { std::cout << "Destroying Scene..." << std::endl; - registry.view().each([this](ModelComponent& model_component) { + entity_registry->get_inner().view().each([this](ModelComponent& model_component) { for (auto& mesh : model_component.model.meshes) { mesh.destroy(); } }); - registry.view().each([this](MeshComponent& mesh_component) { + entity_registry->get_inner().view().each([this](MeshComponent& mesh_component) { mesh_component.mesh.destroy(); }); } diff --git a/src/ecs/system/system.cpp b/src/ecs/system/system.cpp new file mode 100644 index 0000000..7c19633 --- /dev/null +++ b/src/ecs/system/system.cpp @@ -0,0 +1,13 @@ +#include "ecs/system/system.h" +#include "ecs/entity.h" +#include "ecs/registry.h" + +namespace simpleengine::ecs::system { + System::System(std::shared_ptr entity_registry) : entity_registry(entity_registry) { + + } + + ecs::Entity System::create_entity() { + return entity_registry->create_entity(); + } +} \ No newline at end of file diff --git a/src/gfx/renderer.cpp b/src/gfx/renderer.cpp index eb3ad47..3a81765 100644 --- a/src/gfx/renderer.cpp +++ b/src/gfx/renderer.cpp @@ -2,6 +2,7 @@ #include "gfx/mesh.h" #include "gfx/vao.h" #include "renderable.h" +#include "gfx/shader.h" #include "ecs/component/mesh_component.h" #include "ecs/component/model_component.h" diff --git a/src/physics/physics_system.cpp b/src/physics/physics_system.cpp new file mode 100644 index 0000000..b72d4bf --- /dev/null +++ b/src/physics/physics_system.cpp @@ -0,0 +1,90 @@ +#include "ecs/component/rigid_body_component.h" +#include "ecs/system/system.h" +#include "physics/physics_system.h" +#include "ecs/component/transform_component.h" +#include "ecs/entity.h" +#include "ecs/registry.h" +#include "game.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace simpleengine::physics { + PhysicsSystem::PhysicsSystem(std::shared_ptr entity_registry) : simpleengine::ecs::system::System(entity_registry), + logger(log::LoggerManager::create_logger("physics")), should_simulate(true), gravity_vector(0, -8, 0) { + collision_configuration = std::make_unique(); + col_dispatcher = std::make_unique(collision_configuration.get()); + overlapping_pair_cache = std::make_unique(); + solver = std::make_unique(); + + dynamics_world = std::make_unique(col_dispatcher.get(), overlapping_pair_cache.get(), solver.get(), collision_configuration.get()); + dynamics_world->setGravity(btVector3(gravity_vector.x(), gravity_vector.y(), gravity_vector.z())); + } + + PhysicsSystem::~PhysicsSystem() { + + } + + void PhysicsSystem::set_y_gravity(const float& gravity) { + this->gravity_vector.set_y(gravity); + } + + void PhysicsSystem::add_rigid_body(btRigidBody* rigid_body) { + dynamics_world->addRigidBody(rigid_body); + } + + void PhysicsSystem::update(const float& delta_time) { + if (should_simulate) { + dynamics_world->stepSimulation(delta_time, 10); + + entity_registry->get_inner().view().each([this](simpleengine::ecs::TransformComponent& transform_comp, simpleengine::ecs::RigidBodyComponent& rigid_body_comp) { + + //transform_comp + if (!rigid_body_comp.initialized) { + 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)); + + 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)); + } + }); + } + } +} \ No newline at end of file From 6577c6c45b3e53222f8d8c58f90fd6789957e287 Mon Sep 17 00:00:00 2001 From: SeanOMik Date: Thu, 10 Nov 2022 23:34:38 -0500 Subject: [PATCH 2/5] Get collision shapes from collider components --- examples/dev_testing/src/main.cpp | 22 ++-- .../ecs/component/box_collision_component.h | 44 ++++++++ .../ecs/component/collision_shape_component.h | 18 +++ .../ecs/component/rigid_body_component.h | 6 +- .../component/sphere_collision_component.h | 22 ++++ .../physics/collision/box_shape.h | 4 +- include/simpleengine/physics/physics_system.h | 8 ++ src/physics/physics_system.cpp | 106 ++++++++++++------ 8 files changed, 174 insertions(+), 56 deletions(-) create mode 100644 include/simpleengine/ecs/component/box_collision_component.h create mode 100644 include/simpleengine/ecs/component/collision_shape_component.h create mode 100644 include/simpleengine/ecs/component/sphere_collision_component.h diff --git a/examples/dev_testing/src/main.cpp b/examples/dev_testing/src/main.cpp index aecae85..104b274 100644 --- a/examples/dev_testing/src/main.cpp +++ b/examples/dev_testing/src/main.cpp @@ -1,4 +1,5 @@ #include "simpleengine/camera.h" +#include "simpleengine/ecs/component/box_collision_component.h" #include "simpleengine/ecs/component/mesh_component.h" #include "simpleengine/ecs/component/rigid_body_component.h" #include "simpleengine/ecs/component/transform_component.h" @@ -11,6 +12,7 @@ #include "simpleengine/gfx/renderer.h" #include "simpleengine/gfx/texture.h" #include "simpleengine/vector.h" +#include #include #include #include @@ -152,25 +154,17 @@ int main(int argc, char *argv[]) { auto &transform_comp = entity.add_component(); transform_comp.translate(4.f, 0.f, 0.f); */ - //brick_e.add_component(); - se::ecs::Entity brick_e = scene->create_entity(); brick_e.add_component("examples/dev_testing/resources/bricks/bricks.fbx"); - auto& brick_transf = brick_e.add_component(glm::vec3(6.f, 6.f, 0.f)); - - btCollisionShape* brick_shape = new btBoxShape(btVector3(btScalar(1.f), btScalar(1.f), btScalar(1.f))); - auto& brick_rigid = brick_e.add_component(1.f, se::Vectorf(6.f, 6.f, 0.1f), brick_shape); - - + brick_e.add_component(glm::vec3(6.f, 6.f, 0.f)); + brick_e.add_component(1.f, 1.f, 1.f); + brick_e.add_component(1.f, se::Vectorf(6.f, 6.f, 0.1f)); se::ecs::Entity floor = scene->create_entity(); floor.add_component("examples/dev_testing/resources/ground/ground.fbx"); - auto& floor_transf = floor.add_component(glm::vec3(6.f, -6.f, 0.f), glm::vec3(0.f), glm::vec3(1.f, 1.f, 1.f)); - - btCollisionShape* floor_shape = new btBoxShape(btVector3(btScalar(1.f), btScalar(1.f), btScalar(1.f))); - auto& floor_rigid = floor.add_component(0.f, se::Vectorf(6.f, -6.f, 0.f), floor_shape); - - + floor.add_component(glm::vec3(6.f, -6.f, 0.f), glm::vec3(0.f), glm::vec3(1.f, 1.f, 1.f)); + floor.add_component(1.f, 1.f, 1.f); + floor.add_component(0.f, se::Vectorf(6.f, -6.f, 0.f)); auto light = std::make_shared(core_shader, glm::vec3(0.f, 0.f, 0.f), glm::vec3(1.f, 1.f, 1.f)); game.add_event(light); diff --git a/include/simpleengine/ecs/component/box_collision_component.h b/include/simpleengine/ecs/component/box_collision_component.h new file mode 100644 index 0000000..be29d75 --- /dev/null +++ b/include/simpleengine/ecs/component/box_collision_component.h @@ -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) { + + } + }; +} \ No newline at end of file diff --git a/include/simpleengine/ecs/component/collision_shape_component.h b/include/simpleengine/ecs/component/collision_shape_component.h new file mode 100644 index 0000000..837c549 --- /dev/null +++ b/include/simpleengine/ecs/component/collision_shape_component.h @@ -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) { + + } + }; +} \ No newline at end of file diff --git a/include/simpleengine/ecs/component/rigid_body_component.h b/include/simpleengine/ecs/component/rigid_body_component.h index ff8ae70..daa60e4 100644 --- a/include/simpleengine/ecs/component/rigid_body_component.h +++ b/include/simpleengine/ecs/component/rigid_body_component.h @@ -31,11 +31,11 @@ namespace simpleengine::ecs { btDefaultMotionState* motion_state; btCollisionShape* col_shape; public: - bool initialized = false; + //bool initialized = false; btRigidBody* rigid_body; - RigidBodyComponent(float mass, simpleengine::Vectorf start_origin, btCollisionShape* col_shape) : mass(mass), is_dynamic(mass != 0.f), - col_shape(col_shape) { + RigidBodyComponent(float mass, simpleengine::Vectorf start_origin) : mass(mass), is_dynamic(mass != 0.f), rigid_body(nullptr) { + } }; } \ No newline at end of file diff --git a/include/simpleengine/ecs/component/sphere_collision_component.h b/include/simpleengine/ecs/component/sphere_collision_component.h new file mode 100644 index 0000000..c16da4f --- /dev/null +++ b/include/simpleengine/ecs/component/sphere_collision_component.h @@ -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) { + + } + }; +} \ No newline at end of file diff --git a/include/simpleengine/physics/collision/box_shape.h b/include/simpleengine/physics/collision/box_shape.h index e592149..3497c33 100644 --- a/include/simpleengine/physics/collision/box_shape.h +++ b/include/simpleengine/physics/collision/box_shape.h @@ -1,7 +1,7 @@ #pragma once -#include "BulletCollision/CollisionShapes/btBoxShape.h" -#include "vector.h" +#include "../../vector.h" +#include namespace simpleengine::physics::collision { class BoxShape { diff --git a/include/simpleengine/physics/physics_system.h b/include/simpleengine/physics/physics_system.h index 738bfc9..a9f05f2 100644 --- a/include/simpleengine/physics/physics_system.h +++ b/include/simpleengine/physics/physics_system.h @@ -16,10 +16,13 @@ class btBroadphaseInterface; class btSequentialImpulseConstraintSolver; class btDiscreteDynamicsWorld; class btRigidBody; +class btCollisionShape; namespace simpleengine { namespace ecs { class Registry; + class TransformComponent; + class RigidBodyComponent; } namespace physics { @@ -56,6 +59,11 @@ namespace simpleengine { virtual void input_update(const float& delta_time) override {} virtual void render(const float& interpolate_alpha, const float& frame_time) 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); }; } } \ No newline at end of file diff --git a/src/physics/physics_system.cpp b/src/physics/physics_system.cpp index b72d4bf..680266d 100644 --- a/src/physics/physics_system.cpp +++ b/src/physics/physics_system.cpp @@ -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/sphere_collision_component.h" #include "ecs/system/system.h" +#include "entt/entity/fwd.hpp" #include "physics/physics_system.h" #include "ecs/component/transform_component.h" #include "ecs/entity.h" @@ -45,46 +49,74 @@ namespace simpleengine::physics { if (should_simulate) { dynamics_world->stepSimulation(delta_time, 10); - entity_registry->get_inner().view().each([this](simpleengine::ecs::TransformComponent& transform_comp, simpleengine::ecs::RigidBodyComponent& rigid_body_comp) { - - //transform_comp - if (!rigid_body_comp.initialized) { - btTransform start_transform; - start_transform.setIdentity(); + entity_registry->get_inner().view() + .each([this](const entt::entity& entity, simpleengine::ecs::TransformComponent& transform_comp, simpleengine::ecs::RigidBodyComponent& rigid_body_comp) { + // Initialize the rigid body component if it hasn't already been initialized. + init_rigid_body_component(entity, transform_comp, rigid_body_comp); - 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)); - - 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); + 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)); } - - 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(entity)) { + return box_col->box_shape.get_inner_ptr(); + } else if (auto sphere_col = entity_registry->get_inner().try_get(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(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; + } } \ No newline at end of file From bac1ff4a00145957e98e35038f5fb20681b3fbb8 Mon Sep 17 00:00:00 2001 From: SeanOMik Date: Thu, 10 Nov 2022 23:53:03 -0500 Subject: [PATCH 3/5] Add more collider components --- examples/dev_testing/src/main.cpp | 2 +- ...n_component.h => box_collider_component.h} | 0 .../component/capsule_collider_component.h | 23 ++++++++++ .../ecs/component/cone_collider_component.h | 23 ++++++++++ .../component/cylinder_collider_component.h | 45 +++++++++++++++++++ ...omponent.h => sphere_collider_component.h} | 0 .../physics/collision/cone_shape.h | 16 ++++++- .../physics/collision/cylinder_shape.h | 10 ++--- src/physics/physics_system.cpp | 14 ++++-- 9 files changed, 123 insertions(+), 10 deletions(-) rename include/simpleengine/ecs/component/{box_collision_component.h => box_collider_component.h} (100%) create mode 100644 include/simpleengine/ecs/component/capsule_collider_component.h create mode 100644 include/simpleengine/ecs/component/cone_collider_component.h create mode 100644 include/simpleengine/ecs/component/cylinder_collider_component.h rename include/simpleengine/ecs/component/{sphere_collision_component.h => sphere_collider_component.h} (100%) diff --git a/examples/dev_testing/src/main.cpp b/examples/dev_testing/src/main.cpp index 104b274..f423fa4 100644 --- a/examples/dev_testing/src/main.cpp +++ b/examples/dev_testing/src/main.cpp @@ -1,5 +1,5 @@ #include "simpleengine/camera.h" -#include "simpleengine/ecs/component/box_collision_component.h" +#include "simpleengine/ecs/component/box_collider_component.h" #include "simpleengine/ecs/component/mesh_component.h" #include "simpleengine/ecs/component/rigid_body_component.h" #include "simpleengine/ecs/component/transform_component.h" diff --git a/include/simpleengine/ecs/component/box_collision_component.h b/include/simpleengine/ecs/component/box_collider_component.h similarity index 100% rename from include/simpleengine/ecs/component/box_collision_component.h rename to include/simpleengine/ecs/component/box_collider_component.h diff --git a/include/simpleengine/ecs/component/capsule_collider_component.h b/include/simpleengine/ecs/component/capsule_collider_component.h new file mode 100644 index 0000000..6e49ff4 --- /dev/null +++ b/include/simpleengine/ecs/component/capsule_collider_component.h @@ -0,0 +1,23 @@ +#pragma once + +#include "../../physics/collision/capsule_shape.h" +#include "../../vector.h" + +namespace simpleengine::ecs { + /** + * @brief A component that contains a capsule collision shape. + * + */ + class CapsuleColliderComponent { + public: + physics::collision::CapsuleShape capsule_shape; + + CapsuleColliderComponent(physics::collision::CapsuleShape capsule) : capsule_shape(capsule) { + + } + + CapsuleColliderComponent(const float& radius, const float& height) : capsule_shape(radius, height) { + + } + }; +} \ No newline at end of file diff --git a/include/simpleengine/ecs/component/cone_collider_component.h b/include/simpleengine/ecs/component/cone_collider_component.h new file mode 100644 index 0000000..f41068a --- /dev/null +++ b/include/simpleengine/ecs/component/cone_collider_component.h @@ -0,0 +1,23 @@ +#pragma once + +#include "../../physics/collision/cone_shape.h" +#include "../../vector.h" + +namespace simpleengine::ecs { + /** + * @brief A component that contains a cone collision shape. + * + */ + class ConeColliderComponent { + public: + physics::collision::ConeShape cone_shape; + + ConeColliderComponent(physics::collision::ConeShape cone) : cone_shape(cone) { + + } + + ConeColliderComponent(float radius, float height) : cone_shape(radius, height) { + + } + }; +} \ No newline at end of file diff --git a/include/simpleengine/ecs/component/cylinder_collider_component.h b/include/simpleengine/ecs/component/cylinder_collider_component.h new file mode 100644 index 0000000..423f3ec --- /dev/null +++ b/include/simpleengine/ecs/component/cylinder_collider_component.h @@ -0,0 +1,45 @@ +#pragma once + +#include "../../physics/collision/cylinder_shape.h" +#include "../../vector.h" + +namespace simpleengine::ecs { + /** + * @brief A component that contains a cylinder collision shape. + * + */ + class CylinderColliderComponent { + public: + physics::collision::CylinderShape cylinder_shape; + + CylinderColliderComponent(physics::collision::CylinderShape cylinder) : cylinder_shape(cylinder) { + + } + + /** + * @brief Create a cylinder collider with the extent of the cylinder shape. + * + * @note These extents are in half-extents since that's what the underlying Physics engine uses (Bullet). + * + * @param x_extent The extent of the cylinder shape in the x direction. + * @param y_extent The extent of the cylinder shape in the y direction. + * @param z_extent The extent of the cylinder shape in the z direction. + * + */ + CylinderColliderComponent(const float& x_extent, const float& y_extent, const float& z_extent) : cylinder_shape(x_extent, y_extent, z_extent) { + + } + + /** + * @brief Create a CylinderShape with the extent of the cylinder shape. + * + * @note These extents are in half-extents since that's what the underlying Physics engine uses (Bullet). + * + * @param extent The extent of the cylinder. + * + */ + CylinderColliderComponent(const simpleengine::Vectorf& extent) : cylinder_shape(extent) { + + } + }; +} \ No newline at end of file diff --git a/include/simpleengine/ecs/component/sphere_collision_component.h b/include/simpleengine/ecs/component/sphere_collider_component.h similarity index 100% rename from include/simpleengine/ecs/component/sphere_collision_component.h rename to include/simpleengine/ecs/component/sphere_collider_component.h diff --git a/include/simpleengine/physics/collision/cone_shape.h b/include/simpleengine/physics/collision/cone_shape.h index 3e6884c..062d06a 100644 --- a/include/simpleengine/physics/collision/cone_shape.h +++ b/include/simpleengine/physics/collision/cone_shape.h @@ -18,8 +18,22 @@ namespace simpleengine::physics::collision { } - btConeShape* get_inner() { + /** + * @brief Get the inner bullet cone shape object as a pointer. + * + * @return btConeShape* + */ + btConeShape* get_inner_ptr() { return &inner; } + + /** + * @brief Get the inner bullet cone shape object as a reference. + * + * @return btConeShape& + */ + btConeShape& get_inner() { + return inner; + } }; } \ No newline at end of file diff --git a/include/simpleengine/physics/collision/cylinder_shape.h b/include/simpleengine/physics/collision/cylinder_shape.h index 774fc0a..c369a6b 100644 --- a/include/simpleengine/physics/collision/cylinder_shape.h +++ b/include/simpleengine/physics/collision/cylinder_shape.h @@ -14,13 +14,13 @@ namespace simpleengine::physics::collision { } /** - * @brief Create a CylinderShape with the extent of the box. + * @brief Create a CylinderShape with the extent of the cylinder shape. * * @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. + * @param x_extent The extent of the cylinder shape in the x direction. + * @param y_extent The extent of the cylinder shape in the y direction. + * @param z_extent The extent of the cylinder shape in the z direction. * */ CylinderShape(const float& x_extent, const float& y_extent, const float& z_extent) : inner(btVector3(btScalar(x_extent), btScalar(y_extent), btScalar(z_extent))) { @@ -28,7 +28,7 @@ namespace simpleengine::physics::collision { } /** - * @brief Create a CylinderShape with the extent of the box. + * @brief Create a CylinderShape with the extent of the cylinder shape. * * @note These extents are in half-extents since that's what the underlying Physics engine uses (Bullet). * diff --git a/src/physics/physics_system.cpp b/src/physics/physics_system.cpp index 680266d..9d16b07 100644 --- a/src/physics/physics_system.cpp +++ b/src/physics/physics_system.cpp @@ -1,7 +1,10 @@ #include "BulletCollision/CollisionShapes/btCollisionShape.h" -#include "ecs/component/box_collision_component.h" +#include "ecs/component/box_collider_component.h" +#include "ecs/component/sphere_collider_component.h" +#include "ecs/component/cylinder_collider_component.h" +#include "ecs/component/cone_collider_component.h" +#include "ecs/component/capsule_collider_component.h" #include "ecs/component/rigid_body_component.h" -#include "ecs/component/sphere_collision_component.h" #include "ecs/system/system.h" #include "entt/entity/fwd.hpp" #include "physics/physics_system.h" @@ -66,11 +69,16 @@ namespace simpleengine::physics { } btCollisionShape* PhysicsSystem::try_get_collision_shape(const entt::entity& entity) { - btCollisionShape* collision_shape; if (auto box_col = entity_registry->get_inner().try_get(entity)) { return box_col->box_shape.get_inner_ptr(); } else if (auto sphere_col = entity_registry->get_inner().try_get(entity)) { return sphere_col->sphere_shape.get_inner_ptr(); + } else if (auto cylinder_col = entity_registry->get_inner().try_get(entity)) { + return cylinder_col->cylinder_shape.get_inner_ptr(); + } else if (auto cone_col = entity_registry->get_inner().try_get(entity)) { + return cone_col->cone_shape.get_inner_ptr(); + } else if (auto capsule_col = entity_registry->get_inner().try_get(entity)) { + return capsule_col->capsule_shape.get_inner_ptr(); } return nullptr; From 9134d0af233e30a681d75f2e4676bc231f8d621b Mon Sep 17 00:00:00 2001 From: SeanOMik Date: Fri, 11 Nov 2022 00:01:17 -0500 Subject: [PATCH 4/5] Code cleanup a tiny bit --- include/simpleengine/physics/collision/box_shape.h | 4 +--- include/simpleengine/physics/collision/capsule_shape.h | 4 +--- include/simpleengine/physics/collision/collision_shape.h | 2 +- include/simpleengine/physics/collision/cone_shape.h | 4 +--- include/simpleengine/physics/collision/cylinder_shape.h | 4 +--- include/simpleengine/physics/collision/sphere_shape.h | 4 +--- src/physics/physics_system.cpp | 8 ++++---- 7 files changed, 10 insertions(+), 20 deletions(-) diff --git a/include/simpleengine/physics/collision/box_shape.h b/include/simpleengine/physics/collision/box_shape.h index 3497c33..a8e94b9 100644 --- a/include/simpleengine/physics/collision/box_shape.h +++ b/include/simpleengine/physics/collision/box_shape.h @@ -1,14 +1,12 @@ #pragma once #include "../../vector.h" -#include +#include namespace simpleengine::physics::collision { class BoxShape { btBoxShape inner; public: - BoxShape() = default; - BoxShape(btBoxShape inner) : inner(inner) { } diff --git a/include/simpleengine/physics/collision/capsule_shape.h b/include/simpleengine/physics/collision/capsule_shape.h index cfe9ca0..1a50d68 100644 --- a/include/simpleengine/physics/collision/capsule_shape.h +++ b/include/simpleengine/physics/collision/capsule_shape.h @@ -1,13 +1,11 @@ #pragma once -#include "BulletCollision/CollisionShapes/btCapsuleShape.h" +#include namespace simpleengine::physics::collision { class CapsuleShape { btCapsuleShape inner; public: - CapsuleShape() = default; - CapsuleShape(btCapsuleShape inner) : inner(inner) { } diff --git a/include/simpleengine/physics/collision/collision_shape.h b/include/simpleengine/physics/collision/collision_shape.h index 17ccf1d..558b671 100644 --- a/include/simpleengine/physics/collision/collision_shape.h +++ b/include/simpleengine/physics/collision/collision_shape.h @@ -1,6 +1,6 @@ #pragma once -#include "BulletCollision/CollisionShapes/btCollisionShape.h" +#include namespace simpleengine::physics::collision { class CollisionShape { diff --git a/include/simpleengine/physics/collision/cone_shape.h b/include/simpleengine/physics/collision/cone_shape.h index 062d06a..28d3e00 100644 --- a/include/simpleengine/physics/collision/cone_shape.h +++ b/include/simpleengine/physics/collision/cone_shape.h @@ -2,14 +2,12 @@ #include -#include "BulletCollision/CollisionShapes/btConeShape.h" +#include namespace simpleengine::physics::collision { class ConeShape { btConeShape inner; public: - ConeShape() = default; - ConeShape(btConeShape inner) : inner(std::move(inner)) { } diff --git a/include/simpleengine/physics/collision/cylinder_shape.h b/include/simpleengine/physics/collision/cylinder_shape.h index c369a6b..1f35eba 100644 --- a/include/simpleengine/physics/collision/cylinder_shape.h +++ b/include/simpleengine/physics/collision/cylinder_shape.h @@ -1,14 +1,12 @@ #pragma once -#include "BulletCollision/CollisionShapes/btCylinderShape.h" +#include #include "vector.h" namespace simpleengine::physics::collision { class CylinderShape { btCylinderShape inner; public: - CylinderShape() = default; - CylinderShape(btCylinderShape inner) : inner(inner) { } diff --git a/include/simpleengine/physics/collision/sphere_shape.h b/include/simpleengine/physics/collision/sphere_shape.h index 4d0f89e..d265642 100644 --- a/include/simpleengine/physics/collision/sphere_shape.h +++ b/include/simpleengine/physics/collision/sphere_shape.h @@ -1,13 +1,11 @@ #pragma once -#include "BulletCollision/CollisionShapes/btSphereShape.h" +#include namespace simpleengine::physics::collision { class SphereShape { btSphereShape inner; public: - SphereShape() = default; - SphereShape(btSphereShape inner) : inner(inner) { } diff --git a/src/physics/physics_system.cpp b/src/physics/physics_system.cpp index 9d16b07..defe8fe 100644 --- a/src/physics/physics_system.cpp +++ b/src/physics/physics_system.cpp @@ -1,4 +1,3 @@ -#include "BulletCollision/CollisionShapes/btCollisionShape.h" #include "ecs/component/box_collider_component.h" #include "ecs/component/sphere_collider_component.h" #include "ecs/component/cylinder_collider_component.h" @@ -14,13 +13,14 @@ #include "game.h" #include -#include -#include +#include +#include #include #include #include #include -#include +#include +#include #include From 9202c10795f1acefddd1b825f7a062af2135e68b Mon Sep 17 00:00:00 2001 From: SeanOMik Date: Sun, 20 Nov 2022 13:08:12 -0500 Subject: [PATCH 5/5] Fix compiler errors --- examples/dev_testing/src/main.cpp | 2 +- .../ecs/component/rigid_body_component.h | 14 +++++++------- .../simpleengine/physics/collision/box_shape.h | 2 +- .../physics/collision/capsule_shape.h | 2 +- .../physics/collision/collision_shape.h | 2 +- .../physics/collision/cone_shape.h | 2 +- .../physics/collision/cylinder_shape.h | 2 +- .../physics/collision/sphere_shape.h | 2 +- src/physics/physics_system.cpp | 18 +++++++++--------- 9 files changed, 23 insertions(+), 23 deletions(-) diff --git a/examples/dev_testing/src/main.cpp b/examples/dev_testing/src/main.cpp index f423fa4..6d34315 100644 --- a/examples/dev_testing/src/main.cpp +++ b/examples/dev_testing/src/main.cpp @@ -42,7 +42,7 @@ #include #include -#include +#include namespace se = simpleengine; diff --git a/include/simpleengine/ecs/component/rigid_body_component.h b/include/simpleengine/ecs/component/rigid_body_component.h index daa60e4..7b613de 100644 --- a/include/simpleengine/ecs/component/rigid_body_component.h +++ b/include/simpleengine/ecs/component/rigid_body_component.h @@ -3,14 +3,14 @@ #include "../../gfx/model.h" #include "simpleengine/vector.h" -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include -#include +#include namespace simpleengine::physics { class PhysicsSystem; diff --git a/include/simpleengine/physics/collision/box_shape.h b/include/simpleengine/physics/collision/box_shape.h index a8e94b9..4885df0 100644 --- a/include/simpleengine/physics/collision/box_shape.h +++ b/include/simpleengine/physics/collision/box_shape.h @@ -1,7 +1,7 @@ #pragma once #include "../../vector.h" -#include +#include namespace simpleengine::physics::collision { class BoxShape { diff --git a/include/simpleengine/physics/collision/capsule_shape.h b/include/simpleengine/physics/collision/capsule_shape.h index 1a50d68..78ce2d5 100644 --- a/include/simpleengine/physics/collision/capsule_shape.h +++ b/include/simpleengine/physics/collision/capsule_shape.h @@ -1,6 +1,6 @@ #pragma once -#include +#include namespace simpleengine::physics::collision { class CapsuleShape { diff --git a/include/simpleengine/physics/collision/collision_shape.h b/include/simpleengine/physics/collision/collision_shape.h index 558b671..6f9fb57 100644 --- a/include/simpleengine/physics/collision/collision_shape.h +++ b/include/simpleengine/physics/collision/collision_shape.h @@ -1,6 +1,6 @@ #pragma once -#include +#include namespace simpleengine::physics::collision { class CollisionShape { diff --git a/include/simpleengine/physics/collision/cone_shape.h b/include/simpleengine/physics/collision/cone_shape.h index 28d3e00..f86622c 100644 --- a/include/simpleengine/physics/collision/cone_shape.h +++ b/include/simpleengine/physics/collision/cone_shape.h @@ -2,7 +2,7 @@ #include -#include +#include namespace simpleengine::physics::collision { class ConeShape { diff --git a/include/simpleengine/physics/collision/cylinder_shape.h b/include/simpleengine/physics/collision/cylinder_shape.h index 1f35eba..31a8d6e 100644 --- a/include/simpleengine/physics/collision/cylinder_shape.h +++ b/include/simpleengine/physics/collision/cylinder_shape.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include "vector.h" namespace simpleengine::physics::collision { diff --git a/include/simpleengine/physics/collision/sphere_shape.h b/include/simpleengine/physics/collision/sphere_shape.h index d265642..ecc349e 100644 --- a/include/simpleengine/physics/collision/sphere_shape.h +++ b/include/simpleengine/physics/collision/sphere_shape.h @@ -1,6 +1,6 @@ #pragma once -#include +#include namespace simpleengine::physics::collision { class SphereShape { diff --git a/src/physics/physics_system.cpp b/src/physics/physics_system.cpp index defe8fe..60f71a6 100644 --- a/src/physics/physics_system.cpp +++ b/src/physics/physics_system.cpp @@ -12,15 +12,15 @@ #include "ecs/registry.h" #include "game.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include