Changes to ECS, create simple Bullet physics system
This commit is contained in:
parent
e634a4dfce
commit
d75491f6ed
|
@ -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)
|
||||
|
|
|
@ -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 <GLFW/glfw3.h>
|
||||
#include <simpleengine/ecs/component/model_component.h>
|
||||
#include <simpleengine/ecs/component/rotating_component.h>
|
||||
#include <simpleengine/event/event.h>
|
||||
|
@ -18,15 +19,20 @@
|
|||
#include <simpleengine/gfx/shader.h>
|
||||
#include <simpleengine/gfx/shaders/core_3d_shader.h>
|
||||
#include <simpleengine/renderable.h>
|
||||
#include <simpleengine/scene.h>
|
||||
#include <simpleengine/shader_program.h>
|
||||
#include <simpleengine/ecs/system/scene_system.h>
|
||||
#include <simpleengine/vertex.h>
|
||||
#include <simpleengine/log/logger.h>
|
||||
#include <simpleengine/physics/physics_system.h>
|
||||
|
||||
#include "entt/entity/fwd.hpp"
|
||||
|
||||
#include <assimp/material.h>
|
||||
#include <glm/ext/matrix_clip_space.hpp>
|
||||
#include <glm/fwd.hpp>
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
|
@ -34,6 +40,8 @@
|
|||
#include <sstream>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <bullet/BulletCollision/CollisionShapes/btStaticPlaneShape.h>
|
||||
|
||||
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<se::Camera>(game.get_window(), core_shader, 70, glm::vec3(0, 0, 0));
|
||||
// Create an entity registry
|
||||
auto registry = std::make_shared<se::ecs::Registry>();
|
||||
|
||||
auto camera = std::make_shared<se::Camera>(game.get_window(), core_shader, 70, glm::vec3(-6, 0, 0));
|
||||
//game.add_event(camera);
|
||||
|
||||
// Create a renderer
|
||||
auto renderer = std::make_shared<se::gfx::Renderer>(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<se::Scene>(renderer, camera);
|
||||
//game.add_event(scene);
|
||||
auto scene = std::make_shared<se::ecs::system::SceneSystem>(registry, renderer, camera);
|
||||
game.add_renderable(scene);
|
||||
|
||||
// Create a Physics System for handling the physics
|
||||
auto physics_sys = std::make_shared<se::physics::PhysicsSystem>(registry);
|
||||
game.add_event(physics_sys);
|
||||
|
||||
/* se::ecs::Entity other_e = scene->create_entity();
|
||||
other_e.add_component<se::ModelComponent>("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<se::TransformComponent>();
|
||||
transform_comp.translate(4.f, 0.f, 0.f); */
|
||||
|
||||
//brick_e.add_component<se::RotatingComponent>();
|
||||
|
||||
se::ecs::Entity brick_e = scene->create_entity();
|
||||
brick_e.add_component<se::ModelComponent>("examples/dev_testing/resources/bricks/bricks.fbx");
|
||||
brick_e.add_component<se::RotatingComponent>();
|
||||
auto &brick_transf = brick_e.add_component<se::TransformComponent>();
|
||||
brick_transf.translate(6.f, 0.f, 0.f);
|
||||
//brick_transf.translate(6.f, -0.5f, 1.f);
|
||||
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));
|
||||
|
||||
btCollisionShape* brick_shape = new btBoxShape(btVector3(btScalar(1.f), btScalar(1.f), btScalar(1.f)));
|
||||
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();
|
||||
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));
|
||||
|
||||
btCollisionShape* floor_shape = new btBoxShape(btVector3(btScalar(1.f), btScalar(1.f), btScalar(1.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));
|
||||
game.add_event(light);
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
namespace simpleengine {
|
||||
namespace simpleengine::ecs {
|
||||
/**
|
||||
* @brief A component that contains a Mesh that will be rendered.
|
||||
*
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
namespace simpleengine {
|
||||
namespace simpleengine::ecs {
|
||||
/**
|
||||
* @brief A component that contains a Model that will be rendered.
|
||||
*
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../gfx/model.h"
|
||||
#include "simpleengine/vector.h"
|
||||
|
||||
#include <bullet/BulletCollision/CollisionDispatch/btCollisionWorld.h>
|
||||
#include <bullet/BulletDynamics/Dynamics/btRigidBody.h>
|
||||
#include <bullet/LinearMath/btDefaultMotionState.h>
|
||||
#include <bullet/LinearMath/btScalar.h>
|
||||
#include <bullet/LinearMath/btTransform.h>
|
||||
#include <bullet/LinearMath/btVector3.h>
|
||||
|
||||
#include <bullet/btBulletDynamicsCommon.h>
|
||||
|
||||
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) {
|
||||
}
|
||||
};
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
namespace simpleengine {
|
||||
namespace simpleengine::ecs {
|
||||
/**
|
||||
* @brief A component that will rotate the transform every frame.
|
||||
*
|
||||
|
|
|
@ -1,26 +1,42 @@
|
|||
#pragma once
|
||||
|
||||
//#include "simpleengine/scene.h"
|
||||
#include <glm/gtx/euler_angles.hpp>
|
||||
#include <glm/ext/matrix_transform.hpp>
|
||||
#include <glm/fwd.hpp>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
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);
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
#pragma once
|
||||
|
||||
#include "entt/signal/fwd.hpp"
|
||||
#include <entt/entt.hpp>
|
||||
|
||||
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;
|
||||
}; */
|
||||
}
|
|
@ -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<gfx::Renderer> renderer;
|
||||
std::shared_ptr<Camera> camera;
|
||||
public:
|
||||
SceneSystem(std::shared_ptr<Registry> entity_registry, std::shared_ptr<gfx::Renderer> renderer, std::shared_ptr<Camera> 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;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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<Registry> entity_registry;
|
||||
public:
|
||||
System(std::shared_ptr<Registry> 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;
|
||||
};
|
||||
}
|
||||
}
|
|
@ -7,9 +7,6 @@
|
|||
namespace simpleengine {
|
||||
class Event : public simpleengine::Destructable {
|
||||
public:
|
||||
Event() = default;
|
||||
virtual ~Event() = default;
|
||||
|
||||
/**
|
||||
* @brief The update function with fixed-timestep.
|
||||
*
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//#define SPDLOG_FMT_EXTERNAL
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
#pragma once
|
||||
|
||||
#include <utility>
|
||||
|
||||
#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;
|
||||
}
|
||||
};
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
#pragma once
|
||||
|
||||
#include "../vector.h"
|
||||
#include "../ecs/entity.h"
|
||||
#include "../log/logger.h"
|
||||
#include "../ecs/system/system.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <entt/entity/fwd.hpp>
|
||||
#include <entt/entt.hpp>
|
||||
|
||||
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<btDefaultCollisionConfiguration> collision_configuration;
|
||||
std::unique_ptr<btCollisionDispatcher> col_dispatcher;
|
||||
std::unique_ptr<btBroadphaseInterface> overlapping_pair_cache;
|
||||
std::unique_ptr<btSequentialImpulseConstraintSolver> solver;
|
||||
std::unique_ptr<btDiscreteDynamicsWorld> dynamics_world;
|
||||
|
||||
simpleengine::log::Logger logger;
|
||||
public:
|
||||
simpleengine::Vectorf gravity_vector;
|
||||
bool should_simulate;
|
||||
|
||||
PhysicsSystem(std::shared_ptr<ecs::Registry> 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 {}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -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 <memory>
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include <entt/entt.hpp>
|
||||
|
||||
namespace simpleengine {
|
||||
namespace ecs {
|
||||
class Entity;
|
||||
}
|
||||
|
||||
//class Scene : public simpleengine::Event {
|
||||
class Scene : public simpleengine::Renderable {
|
||||
protected:
|
||||
entt::registry registry;
|
||||
std::shared_ptr<gfx::Renderer> renderer;
|
||||
|
||||
// Last transform matrixes for all entities.
|
||||
std::unordered_map<uint32_t, glm::mat4> last_transforms;
|
||||
|
||||
std::shared_ptr<Camera> camera;
|
||||
public:
|
||||
Scene(std::shared_ptr<gfx::Renderer> renderer, std::shared_ptr<Camera> 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;
|
||||
};
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -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 <glm/gtx/string_cast.hpp>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace simpleengine {
|
||||
Scene::Scene(std::shared_ptr<gfx::Renderer> renderer, std::shared_ptr<Camera> camera) : renderer(renderer), camera(camera) {
|
||||
#include <entt/entity/fwd.hpp>
|
||||
#include <entt/entt.hpp>
|
||||
|
||||
using namespace simpleengine::ecs;
|
||||
|
||||
namespace simpleengine::ecs::system {
|
||||
|
||||
SceneSystem::SceneSystem(std::shared_ptr<Registry> entity_registry, std::shared_ptr<gfx::Renderer> renderer, std::shared_ptr<Camera> 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<TransformComponent>().each([this, &delta_time](TransformComponent& transform) {
|
||||
entity_registry->get_inner().view<TransformComponent>().each([this, &delta_time](TransformComponent& transform) {
|
||||
transform.last_transform_matrix = transform.transform_matrix;
|
||||
});
|
||||
|
||||
// Rotate the model
|
||||
registry.view<TransformComponent, RotatingComponent>().each([this, &delta_time](TransformComponent& transform, RotatingComponent& rotating) {
|
||||
/* registry->view<TransformComponent, RotatingComponent>().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<TransformComponent, ModelComponent>().each([this](TransformComponent& transform, ModelComponent& model_component) {
|
||||
entity_registry->get_inner().view<TransformComponent, ModelComponent>().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<TransformComponent, MeshComponent>().each([this](TransformComponent& transform, MeshComponent& mesh_component) {
|
||||
entity_registry->get_inner().view<TransformComponent, MeshComponent>().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<ModelComponent>().each([this](ModelComponent& model_component) {
|
||||
entity_registry->get_inner().view<ModelComponent>().each([this](ModelComponent& model_component) {
|
||||
for (auto& mesh : model_component.model.meshes) {
|
||||
mesh.destroy();
|
||||
}
|
||||
});
|
||||
|
||||
registry.view<MeshComponent>().each([this](MeshComponent& mesh_component) {
|
||||
entity_registry->get_inner().view<MeshComponent>().each([this](MeshComponent& mesh_component) {
|
||||
mesh_component.mesh.destroy();
|
||||
});
|
||||
}
|
|
@ -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<Registry> entity_registry) : entity_registry(entity_registry) {
|
||||
|
||||
}
|
||||
|
||||
ecs::Entity System::create_entity() {
|
||||
return entity_registry->create_entity();
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
|
|
|
@ -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 <bullet/btBulletDynamicsCommon.h>
|
||||
#include <BulletCollision/CollisionDispatch/btCollisionDispatcher.h>
|
||||
#include <BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h>
|
||||
#include <bullet/BulletCollision/BroadphaseCollision/btBroadphaseInterface.h>
|
||||
#include <bullet/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h>
|
||||
#include <bullet/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h>
|
||||
#include <bullet/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h>
|
||||
#include <BulletDynamics/Dynamics/btRigidBody.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace simpleengine::physics {
|
||||
PhysicsSystem::PhysicsSystem(std::shared_ptr<ecs::Registry> 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<btDefaultCollisionConfiguration>();
|
||||
col_dispatcher = std::make_unique<btCollisionDispatcher>(collision_configuration.get());
|
||||
overlapping_pair_cache = std::make_unique<btDbvtBroadphase>();
|
||||
solver = std::make_unique<btSequentialImpulseConstraintSolver>();
|
||||
|
||||
dynamics_world = std::make_unique<btDiscreteDynamicsWorld>(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<simpleengine::ecs::TransformComponent, simpleengine::ecs::RigidBodyComponent>().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));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue