Changes to ECS, create simple Bullet physics system

This commit is contained in:
SeanOMik 2022-11-10 19:07:05 -05:00
parent e634a4dfce
commit d75491f6ed
Signed by: SeanOMik
GPG Key ID: 568F326C7EB33ACB
27 changed files with 669 additions and 94 deletions

View File

@ -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)

View File

@ -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);

View File

@ -6,7 +6,7 @@
#include <iostream>
#include <vector>
namespace simpleengine {
namespace simpleengine::ecs {
/**
* @brief A component that contains a Mesh that will be rendered.
*

View File

@ -5,7 +5,7 @@
#include <iostream>
#include <vector>
namespace simpleengine {
namespace simpleengine::ecs {
/**
* @brief A component that contains a Model that will be rendered.
*

View File

@ -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) {
}
};
}

View File

@ -2,7 +2,7 @@
#include <glm/glm.hpp>
namespace simpleengine {
namespace simpleengine::ecs {
/**
* @brief A component that will rotate the transform every frame.
*

View File

@ -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);

View File

@ -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;
}; */
}

View File

@ -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;
};
}
}
}

View File

@ -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;
};
}
}

View File

@ -7,9 +7,6 @@
namespace simpleengine {
class Event : public simpleengine::Destructable {
public:
Event() = default;
virtual ~Event() = default;
/**
* @brief The update function with fixed-timestep.
*

View File

@ -1,4 +1,4 @@
//#define SPDLOG_FMT_EXTERNAL
#pragma once
#include <memory>
#include <string>

View File

@ -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;
}
};
}

View File

@ -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;
}
};
}

View File

@ -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;
}
};
}

View File

@ -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;
}
};
}

View File

@ -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;
}
};
}

View File

@ -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;
}
};
}

View File

@ -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 {}
};
}
}

View File

@ -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;
};
}

View File

@ -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;
}

View File

@ -13,5 +13,6 @@ pkgs.mkShell {
glm
assimp
spdlog
bullet
];
}

16
src/ecs/registry.cpp Normal file
View File

@ -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());
}
}

View File

@ -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();
});
}

13
src/ecs/system/system.cpp Normal file
View File

@ -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();
}
}

View File

@ -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"

View File

@ -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));
}
});
}
}
}