Ajout de Jolt Physics + 1ere version des factory entitecomposants - camera, transform, rigidbody, collider, renderer
This commit is contained in:
@@ -4,7 +4,8 @@
|
||||
namespace CosmicCore {
|
||||
class CAbstractCollider: public CAbstractComponent
|
||||
{
|
||||
|
||||
public:
|
||||
CAbstractCollider(CEntity& entity): CAbstractComponent(entity){};
|
||||
};
|
||||
}
|
||||
#endif
|
||||
78
src/Engine/Core/Component/Collider/CCollider.cpp
Normal file
78
src/Engine/Core/Component/Collider/CCollider.cpp
Normal file
@@ -0,0 +1,78 @@
|
||||
#include "CCollider.hpp"
|
||||
#include "CAbstractCollider.hpp"
|
||||
#include <Jolt/Physics/Collision/Shape/BoxShape.h>
|
||||
#include <Jolt/Physics/Collision/Shape/SphereShape.h>
|
||||
#include <Jolt/Physics/Collision/Shape/MeshShape.h>
|
||||
#include <Jolt/Physics/Collision/Shape/ConvexHullShape.h>
|
||||
#include <Jolt/Physics/Collision/Shape/CapsuleShape.h>
|
||||
namespace CosmicCore {
|
||||
CCollider::CCollider(CEntity& e, EColliderType type): CAbstractCollider(e), m_type(type)
|
||||
{
|
||||
buildDefaultShape();
|
||||
}
|
||||
|
||||
void CCollider::buildFromMesh(CMesh* mesh) {
|
||||
if (m_type == EColliderType::ConvexHull) {
|
||||
JPH::ConvexHullShapeSettings settings;
|
||||
for (auto& v : mesh->getVertices())
|
||||
settings.mPoints.push_back({v.m_position.x,
|
||||
v.m_position.y,
|
||||
v.m_position.z});
|
||||
m_shape = settings.Create().Get();
|
||||
}
|
||||
/*else if (m_type == EColliderType::Mesh) {
|
||||
// pour les statiques
|
||||
JPH::MeshShapeSettings settings;
|
||||
// remplir triangles depuis vertices + indices
|
||||
m_shape = settings.Create().Get();
|
||||
}*/
|
||||
}
|
||||
|
||||
void CCollider::buildDefaultShape()
|
||||
{
|
||||
switch (m_type) {
|
||||
case CosmicCore::EColliderType::Box:
|
||||
setBoxSize({1.0f,1.0f,1.0f});
|
||||
break;
|
||||
case EColliderType::Sphere:
|
||||
setSphereRadius(1.0f);
|
||||
break;
|
||||
case EColliderType::Capsule:
|
||||
setCapsule(2.0f, 1.0f);
|
||||
break;
|
||||
case EColliderType::ConvexHull:
|
||||
break;
|
||||
case EColliderType::Mesh:
|
||||
break;
|
||||
case EColliderType::Compound:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// override manuel de la taille
|
||||
void CCollider::setBoxSize(glm::vec3 size) {
|
||||
m_type = EColliderType::Box;
|
||||
m_shape = new JPH::BoxShape(JPH::Vec3(size.x, size.y, size.z));
|
||||
}
|
||||
|
||||
void CCollider::setSphereRadius(float radius) {
|
||||
m_type = EColliderType::Sphere;
|
||||
m_shape = new JPH::SphereShape(radius);
|
||||
}
|
||||
|
||||
void CCollider::setCapsule(float halfHeight, float radius) {
|
||||
m_type = EColliderType::Capsule;
|
||||
m_shape = new JPH::CapsuleShape(halfHeight, radius);
|
||||
}
|
||||
|
||||
// build depuis le mesh du renderer si présent
|
||||
void CCollider::buildFromRenderer() {
|
||||
/*auto& registry = getEntity().getRegistry();
|
||||
if (!registry.all_of<CRenderer>(getEntity().getHandle())) return;
|
||||
|
||||
auto* model = registry.get<CRenderer>(getEntity().getHandle()).getModel();
|
||||
if (model->getMeshes().empty()) return;
|
||||
|
||||
buildFromMesh(model->getMeshes()[0]);*/
|
||||
}
|
||||
}
|
||||
42
src/Engine/Core/Component/Collider/CCollider.hpp
Normal file
42
src/Engine/Core/Component/Collider/CCollider.hpp
Normal file
@@ -0,0 +1,42 @@
|
||||
#ifndef CCOLLIDER_HPP
|
||||
#define CCOLLIDER_HPP
|
||||
#include "CAbstractCollider.hpp"
|
||||
#include <Jolt/Jolt.h>
|
||||
#include <Jolt/Physics/Collision/Shape/Shape.h>
|
||||
#include "../../Graphics/Data/Mesh/CMesh.hpp"
|
||||
#include "nlohmann/json_fwd.hpp"
|
||||
|
||||
namespace CosmicCore {
|
||||
|
||||
enum class EColliderType {
|
||||
Box,
|
||||
Sphere,
|
||||
Capsule,
|
||||
ConvexHull,
|
||||
Mesh,
|
||||
Compound
|
||||
};
|
||||
|
||||
class CCollider : public CAbstractCollider{
|
||||
private:
|
||||
EColliderType m_type;
|
||||
JPH::ShapeRefC m_shape = nullptr;
|
||||
public:
|
||||
CCollider(CEntity& e, EColliderType type);
|
||||
|
||||
void buildFromMesh(CMesh* mesh);
|
||||
void buildDefaultShape();
|
||||
|
||||
JPH::ShapeRefC getShape() const { return m_shape; }
|
||||
EColliderType getType() const { return m_type; }
|
||||
|
||||
void setCapsule(float halfHeight, float radius);
|
||||
void setSphereRadius(float radius);
|
||||
void setBoxSize(glm::vec3 size);
|
||||
void buildFromRenderer();
|
||||
|
||||
nlohmann::json to_json(){return nlohmann::json();};
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
122
src/Engine/Core/Component/Rigidbody/CRigidBody.cpp
Normal file
122
src/Engine/Core/Component/Rigidbody/CRigidBody.cpp
Normal file
@@ -0,0 +1,122 @@
|
||||
#include "CRigidBody.hpp"
|
||||
#include "../../Physics/PhysicsLayers.hpp"
|
||||
#include "../../Scene/CScene.hpp"
|
||||
#include "../Geometry/CTransform.hpp"
|
||||
#include "../Collider/CCollider.hpp"
|
||||
#include "Jolt/Physics/EActivation.h"
|
||||
#include <iostream>
|
||||
|
||||
namespace CosmicCore {
|
||||
CRigidBody::CRigidBody(CEntity& entity, EBodyType type): CAbstractRigidBody(entity), m_bodyType(type)
|
||||
{
|
||||
}
|
||||
|
||||
// initialise le body dans le monde physique
|
||||
// doit être appelé après CCollider et CTransform
|
||||
void CRigidBody::init() {
|
||||
|
||||
|
||||
auto& registry = getEntity().getRegistry();
|
||||
|
||||
// récupère le transform
|
||||
auto& transform = registry.registry.get<CTransform>(*getEntity());
|
||||
auto& collider = registry.registry.get<CCollider>(*getEntity());
|
||||
glm::vec3 pos = transform.getCenter();
|
||||
glm::quat ori = transform.getOrientation();
|
||||
|
||||
// motion type
|
||||
JPH::EMotionType motionType;
|
||||
JPH::ObjectLayer layer;
|
||||
switch (m_bodyType) {
|
||||
case EBodyType::Static:
|
||||
motionType = JPH::EMotionType::Static;
|
||||
layer = Layers::NON_MOVING;
|
||||
break;
|
||||
case EBodyType::Kinematic:
|
||||
motionType = JPH::EMotionType::Kinematic;
|
||||
layer = Layers::MOVING;
|
||||
break;
|
||||
case EBodyType::Dynamic:
|
||||
default:
|
||||
motionType = JPH::EMotionType::Dynamic;
|
||||
layer = Layers::MOVING;
|
||||
break;
|
||||
}
|
||||
|
||||
// création du body
|
||||
JPH::BodyCreationSettings settings(
|
||||
collider.getShape(),
|
||||
JPH::RVec3(pos.x, pos.y, pos.z),
|
||||
JPH::Quat(ori.x, ori.y, ori.z, ori.w),
|
||||
motionType,
|
||||
layer
|
||||
);
|
||||
settings.mFriction = m_friction;
|
||||
settings.mRestitution = m_restitution;
|
||||
if (m_bodyType == EBodyType::Static)
|
||||
{
|
||||
settings.mMotionType = JPH::EMotionType::Static;
|
||||
}
|
||||
else
|
||||
{
|
||||
settings.mOverrideMassProperties = JPH::EOverrideMassProperties::CalculateInertia;
|
||||
settings.mMassPropertiesOverride.mMass = m_mass;
|
||||
}
|
||||
|
||||
auto& bodyInterface = getEntity().getScene()->getTangibleWorld().getBodyInterface();
|
||||
m_bodyID = bodyInterface.CreateAndAddBody(
|
||||
settings,
|
||||
m_bodyType != EBodyType::Static ? JPH::EActivation::Activate : JPH::EActivation::DontActivate
|
||||
);
|
||||
m_initialized = true;
|
||||
}
|
||||
|
||||
void CRigidBody::destroy() {
|
||||
if (!m_initialized) return;
|
||||
// récupère le world via le kernel
|
||||
auto* scene = getEntity().getScene();
|
||||
if (!scene) return;
|
||||
auto& bodyInterface = scene->getTangibleWorld()
|
||||
.getPhysicsSystem()
|
||||
.GetBodyInterface();
|
||||
if (bodyInterface.IsAdded(m_bodyID))
|
||||
bodyInterface.RemoveBody(m_bodyID);
|
||||
bodyInterface.DestroyBody(m_bodyID);
|
||||
m_initialized = false;
|
||||
}
|
||||
|
||||
// sync CTransform depuis la physique
|
||||
void CRigidBody::syncTransform() {
|
||||
if (!m_initialized) return;
|
||||
auto& registry = getEntity().getRegistry();
|
||||
auto& transform = registry.registry.get<CTransform>(*getEntity());
|
||||
auto& bodyInterface = getEntity().getScene()
|
||||
->getTangibleWorld()
|
||||
.getBodyInterface();
|
||||
|
||||
JPH::RVec3 pos = bodyInterface.GetCenterOfMassPosition(m_bodyID);
|
||||
JPH::Quat ori = bodyInterface.GetRotation(m_bodyID);
|
||||
|
||||
transform.setCenter({pos.GetX(), pos.GetY(), pos.GetZ()});
|
||||
transform.setQuaternion({ori.GetW(), ori.GetX(), ori.GetY(), ori.GetZ()});
|
||||
}
|
||||
|
||||
// forces
|
||||
void CRigidBody::addForce(glm::vec3 force) {
|
||||
if (!m_initialized) return;
|
||||
auto& bi = getEntity().getScene()->getTangibleWorld().getBodyInterface();
|
||||
bi.AddForce(m_bodyID, JPH::Vec3(force.x, force.y, force.z));
|
||||
}
|
||||
|
||||
void CRigidBody::addImpulse(glm::vec3 impulse) {
|
||||
if (!m_initialized) return;
|
||||
auto& bi = getEntity().getScene()->getTangibleWorld().getBodyInterface();
|
||||
bi.AddImpulse(m_bodyID, JPH::Vec3(impulse.x, impulse.y, impulse.z));
|
||||
}
|
||||
|
||||
void CRigidBody::setLinearVelocity(glm::vec3 velocity) {
|
||||
if (!m_initialized) return;
|
||||
auto& bi = getEntity().getScene()->getTangibleWorld().getBodyInterface();
|
||||
bi.SetLinearVelocity(m_bodyID, JPH::Vec3(velocity.x, velocity.y, velocity.z));
|
||||
}
|
||||
}
|
||||
62
src/Engine/Core/Component/Rigidbody/CRigidBody.hpp
Normal file
62
src/Engine/Core/Component/Rigidbody/CRigidBody.hpp
Normal file
@@ -0,0 +1,62 @@
|
||||
#ifndef CRIGIDBODY_HPP
|
||||
#define CRIGIDBODY_HPP
|
||||
|
||||
#include "CAbstractRigidbody.hpp"
|
||||
#include "glm/fwd.hpp"
|
||||
#include <Jolt/Jolt.h>
|
||||
#include <Jolt/Physics/Body/Body.h>
|
||||
#include <Jolt/Physics/Body/BodyCreationSettings.h>
|
||||
#include <Jolt/Physics/Body/MotionType.h>
|
||||
|
||||
namespace CosmicCore {
|
||||
|
||||
enum class EBodyType {
|
||||
Static, // ne bouge pas (décors, terrain)
|
||||
Kinematic, // bouge mais pas affecté par la physique (plateformes)
|
||||
Dynamic // affecté par la physique (objets normaux)
|
||||
};
|
||||
|
||||
class CRigidBody : public CAbstractRigidBody {
|
||||
private:
|
||||
JPH::BodyID m_bodyID;
|
||||
EBodyType m_bodyType = EBodyType::Dynamic;
|
||||
float m_mass = 1.0f;
|
||||
float m_friction = 0.5f;
|
||||
float m_restitution = 0.0f; // rebond
|
||||
bool m_initialized = false;
|
||||
|
||||
public:
|
||||
CRigidBody(CEntity& entity, EBodyType type = EBodyType::Dynamic);
|
||||
|
||||
~CRigidBody() {
|
||||
destroy();
|
||||
}
|
||||
|
||||
CRigidBody(const CRigidBody&) = delete;
|
||||
CRigidBody& operator=(const CRigidBody&) = delete;
|
||||
|
||||
void setLinearVelocity(glm::vec3 velocity);
|
||||
void addImpulse(glm::vec3 impulse);
|
||||
void addForce(glm::vec3 force);
|
||||
void syncTransform();
|
||||
void destroy();
|
||||
void init();
|
||||
|
||||
|
||||
// setters
|
||||
void setMass(float mass) { m_mass = mass; }
|
||||
void setFriction(float friction) { m_friction = friction; }
|
||||
void setRestitution(float restitution){ m_restitution = restitution; }
|
||||
void setBodyType(EBodyType type) { m_bodyType = type; }
|
||||
|
||||
// getters
|
||||
JPH::BodyID getBodyID() const { return m_bodyID; }
|
||||
EBodyType getBodyType() const { return m_bodyType; }
|
||||
float getMass() const { return m_mass; }
|
||||
bool isInitialized() const { return m_initialized; }
|
||||
|
||||
nlohmann::json to_json() { return {}; }
|
||||
};
|
||||
|
||||
} // namespace CosmicCore
|
||||
#endif
|
||||
@@ -5,7 +5,8 @@
|
||||
CModel* CModelLoader::loadModel(std::string fileName, CResourceManager& rm)
|
||||
{
|
||||
Assimp::Importer importer;
|
||||
const aiScene* scene = importer.ReadFile(fileName,
|
||||
|
||||
const aiScene* scene = importer.ReadFile(fileName.c_str(),
|
||||
aiProcess_Triangulate |
|
||||
aiProcess_FlipUVs |
|
||||
aiProcess_CalcTangentSpace |
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
/**
|
||||
* @brief Class allowing to load models from obj files.
|
||||
*/
|
||||
#include <filesystem>
|
||||
class CModelLoader {
|
||||
private:
|
||||
/**
|
||||
|
||||
@@ -126,7 +126,6 @@ CMaterial::~CMaterial()
|
||||
void CMaterial::destroy()
|
||||
{
|
||||
VulkanImpl* api = dynamic_cast<VulkanImpl*>(GraphicsAPI::getAPI().get());
|
||||
uint32_t currentFrame = api->getCurrentFrameIndex();
|
||||
|
||||
api->destroyPipeline(pipeline, pipelineLayout);
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
#include "../../Shader/Implementations/CShaderImplVulkan.hpp"
|
||||
#include "../../API/ManagedDescriptorSet.hpp"
|
||||
#include "SColor.hpp"
|
||||
#include "../Texture/CTexture.hpp"
|
||||
|
||||
class CMaterial {
|
||||
@@ -12,7 +11,6 @@ class CMaterial {
|
||||
~CMaterial();
|
||||
void destroy();
|
||||
bool isInit = false;
|
||||
SColor m_color;
|
||||
CTexture* textureAlbedo = nullptr;
|
||||
CTexture* textureNormal = nullptr;
|
||||
CShaderImplVulkan* shader;
|
||||
|
||||
0
src/Engine/Core/Graphics/Data/Tint/CTint.hpp
Normal file
0
src/Engine/Core/Graphics/Data/Tint/CTint.hpp
Normal file
@@ -11,9 +11,15 @@
|
||||
|
||||
#include "../Graphics/CContext.hpp"
|
||||
#include "../Graphics/API/GraphicsAPI.hpp"
|
||||
#include "../Physics/CPhysicsAPI.hpp"
|
||||
#include "../Scene/CScene.hpp"
|
||||
#include "../Entity/CEntity.hpp"
|
||||
#include "../Component/Camera/CCamera.hpp"
|
||||
#include "../../Utils/Factory/CEntityFactory.hpp"
|
||||
#include "../../Utils/Factory/ComponentFactory.hpp"
|
||||
|
||||
#include "../Component/Graphics/CRenderer.hpp"
|
||||
#include "glm/ext/vector_float3.hpp"
|
||||
//CShader* CKernel::m_mainShader;
|
||||
|
||||
// #define NAME "Cosmic Engine"
|
||||
@@ -62,82 +68,38 @@ namespace CosmicCore {
|
||||
}*/
|
||||
|
||||
void CKernel::start(bool isPreview) {
|
||||
|
||||
//DEBUG_LOG(trace, "Kernel", "Context", "Starting " + m_gameName + "...")
|
||||
//CosmicConfig::CConfiguration::init();
|
||||
//CComponentFactory::registerStandardProvidedAbstractComponents();
|
||||
//std::cout << CModuleLoader::loadAll() << std::endl;
|
||||
if(!isPreview)
|
||||
{
|
||||
m_window.initialization();
|
||||
|
||||
m_sceneMap["TestScene"] = std::make_unique<CScene>("Scene1");
|
||||
m_activeScene = m_sceneMap["TestScene"].get();
|
||||
m_activeScene->addEntity("TestEntity", "Description");
|
||||
// Open the splash window.
|
||||
//DEBUG_LOG(trace, "Kernel", "Context", "Loading splash window...")
|
||||
//m_loadingWindow.setVisible(true);
|
||||
//m_loadingWindow.initialization();
|
||||
|
||||
// Load the config file.
|
||||
//m_engineConfig.load();
|
||||
//m_config.load();
|
||||
CEntityFactory::EntityConfig configCamera;
|
||||
CEntityFactory::EntityConfig configSol;
|
||||
CEntityFactory::EntityConfig configCube;
|
||||
|
||||
// Load the main window.
|
||||
/*DEBUG_LOG(trace, "Kernel", "Context", "Loading main window...")
|
||||
m_window.setAntiAliasing(m_config.getMsaa());
|
||||
m_window.initialization();
|
||||
m_window.setCursorGrabbed(m_config.getFullscreen());
|
||||
m_GLcontext = m_window.getOpenGLContext();
|
||||
SDL_GL_SetSwapInterval(1);
|
||||
m_window.setFullscreen(m_config.getFullscreen());
|
||||
if (m_config.getFullscreen()) {
|
||||
m_window.setSize(m_config.getFullScreenSize());
|
||||
glViewport(0, 0, m_config.getFullScreenSize().first, m_config.getFullScreenSize().second);
|
||||
configCamera = {"camera", "une caméra", {0.0f,0.0f,6.0f}, {1.0f,1.0f,1.0f}, glm::vec3(), "", "triangle", EColliderType::Box, EBodyType::Static, false};
|
||||
configSol = {"sol", "le sol, ne bouge pas", {0.0f,-2.0f,0.0f}, {100.0f,1.0f,100.0f}, glm::vec3(), "assets/models/cube.glb", "triangle", EColliderType::Box, EBodyType::Static, true};
|
||||
configCube = {"cube", "le cube, shrek", {0.0f,2.0f,0.0f}, {1.0f,1.0f,1.0f}, glm::vec3(), "assets/models/cube.glb", "triangle", EColliderType::Box, EBodyType::Dynamic, true};
|
||||
|
||||
auto cam = CEntityFactory::create(m_activeScene, configCamera);
|
||||
ComponentFactory::addCamera(cam);
|
||||
|
||||
auto e = CEntityFactory::create(m_activeScene, configCube);
|
||||
auto& renderer = m_activeScene->getECManager().registry.get<CRenderer>(*e);
|
||||
|
||||
VulkanImpl* api = dynamic_cast<VulkanImpl*>(GraphicsAPI::getAPI().get());
|
||||
api->getResourceManager().getTextureManager().loadedTextures.push_back(std::make_unique<CTexture>("assets/shrekt.png"));
|
||||
auto texture = api->getResourceManager().getTextureManager().loadedTextures.back().get();
|
||||
texture->init();
|
||||
|
||||
for(auto& mesh : renderer.getModel()->getMeshes())
|
||||
{
|
||||
mesh->getMaterial()->textureAlbedo = texture;
|
||||
mesh->getMaterial()->build();
|
||||
}
|
||||
else {
|
||||
m_window.setSize(m_config.getWindowSize());
|
||||
glViewport(0, 0, m_config.getWindowSize().first, m_config.getWindowSize().second);
|
||||
}*/
|
||||
}
|
||||
|
||||
// On initialise GLEW.
|
||||
/*DEBUG_LOG(trace, "Kernel", "Context", "GLEW initialization...")
|
||||
GLenum initialisationGLEW(glewInit());
|
||||
|
||||
if (initialisationGLEW != GLEW_OK) {
|
||||
// On affiche l'erreur grace a la fonction : glewGetErrorString(GLenum code)
|
||||
HandleException(CLibException(std::string("Erreur d'initialisation de GLEW : ") + (char*)glewGetErrorString(initialisationGLEW)), true);
|
||||
}
|
||||
DEBUG_LOG(trace, "Kernel", "Context", "GLEW initialized!")
|
||||
|
||||
try {
|
||||
m_shaderManager.create();
|
||||
m_shaderManager.compile();
|
||||
}
|
||||
catch (const CException& exception) {
|
||||
HandleException(exception, true);
|
||||
}
|
||||
|
||||
m_mainShader = m_shaderManager.get("basicColor");
|
||||
|
||||
//double ratio;
|
||||
//if (isFullscreen()) {
|
||||
// ratio = ((double)m_fullscreenSize.first) / ((double)m_fullscreenSize.second);
|
||||
//}
|
||||
//else {
|
||||
// ratio = ((double)m_windowSize.first) / ((double)m_windowSize.second);
|
||||
//}
|
||||
// m_projection = glm::perspective(m_fov, ratio, 1.0, 100.0);
|
||||
// m_modelView = glm::mat4(1.0);
|
||||
|
||||
if(!isPreview)
|
||||
{
|
||||
m_loadingWindow.setVisible(false);
|
||||
m_window.setVisible(true);
|
||||
}
|
||||
|
||||
DEBUG_LOG(trace, "Kernel", "Context", m_gameName + " Started !")*/
|
||||
}
|
||||
|
||||
void CKernel::loop() {
|
||||
@@ -187,10 +149,10 @@ namespace CosmicCore {
|
||||
case SDLK_D:
|
||||
ent.forward({0.05f, 0.0f, 0.0f});
|
||||
break;
|
||||
case SDLK_LCTRL:
|
||||
case SDLK_E:
|
||||
ent.forward({0.0f, -0.05f, 0.0f});
|
||||
break;
|
||||
case SDLK_LSHIFT:
|
||||
case SDLK_A:
|
||||
ent.forward({0.0f, 0.05f, 0.0f});
|
||||
break;
|
||||
default:
|
||||
@@ -213,7 +175,11 @@ namespace CosmicCore {
|
||||
}
|
||||
|
||||
if(m_activeScene)
|
||||
{
|
||||
m_activeScene->getTangibleWorld().updateWorld(1.0f/60.0f);
|
||||
GraphicsAPI::getAPI()->drawFrame();
|
||||
}
|
||||
|
||||
// ####### end render #######
|
||||
|
||||
// Compute the end and spended time .
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
#include "CAbstractTangibleWorld.hpp"
|
||||
|
||||
namespace CosmicCore {
|
||||
|
||||
CAbstractTangibleWorld::CAbstractTangibleWorld()
|
||||
{
|
||||
}
|
||||
|
||||
CAbstractTangibleWorld::~CAbstractTangibleWorld()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
#ifndef CABSTRACTTANGIBLEWORLD_HPP
|
||||
#define CABSTRACTTANGIBLEWORLD_HPP
|
||||
|
||||
namespace CosmicCore {
|
||||
/**
|
||||
* @brief Class representing any physical world - abstract.
|
||||
*/
|
||||
class CAbstractTangibleWorld {
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* @brief The ODE world ID.
|
||||
*/
|
||||
//dWorldID m_world;
|
||||
|
||||
/**
|
||||
* @brief The ODE collision space.
|
||||
*/
|
||||
//dSpaceID m_space;
|
||||
|
||||
/**
|
||||
* @brief The ODE joint Group for the collisions.
|
||||
*/
|
||||
//dJointGroupID m_jointGroup;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* @brief CTangibleWorld's default constructor. Does nothing.
|
||||
*/
|
||||
CAbstractTangibleWorld();
|
||||
|
||||
/**
|
||||
* @brief CTangibleWorld's destructor.
|
||||
*/
|
||||
~CAbstractTangibleWorld();
|
||||
|
||||
/**
|
||||
* @brief Update the physical world, move the bodies.
|
||||
* @param[in] seconds The time to spend in the current step of simulation.
|
||||
* If an object falls and seconds equals to 1, the object's position will correspond to 1 second of falling after the call of the function.
|
||||
*/
|
||||
virtual void updateWorld(float seconds) = 0;
|
||||
|
||||
/**
|
||||
* @brief Getter to the ODE world ID.
|
||||
* @return The ODE world ID, actually return m_world.
|
||||
*/
|
||||
//dWorldID getWorld();
|
||||
|
||||
/**
|
||||
* @brief Getter to the ODE space ID.
|
||||
* @return The ODE space ID, actually return m_space.
|
||||
*/
|
||||
//dSpaceID getSpace(void);
|
||||
|
||||
virtual void initWorld() = 0;
|
||||
|
||||
/**
|
||||
* @brief Getter to the ODE joint group.
|
||||
* @return The ODE joint group , actually return m_jointGroup.
|
||||
*/
|
||||
//dJointGroupID getJointGroup(void);
|
||||
|
||||
/**
|
||||
* @brief The collision callback of the ODE space.
|
||||
* Is called each time a collision occurs when the ODE world is updated.
|
||||
*/
|
||||
//static dNearCallback callback;
|
||||
|
||||
};
|
||||
}
|
||||
#endif
|
||||
7
src/Engine/Core/Physics/CPhysicsAPI.cpp
Normal file
7
src/Engine/Core/Physics/CPhysicsAPI.cpp
Normal file
@@ -0,0 +1,7 @@
|
||||
#include "CPhysicsAPI.hpp"
|
||||
namespace CosmicCore {
|
||||
CPhysicsAPI::~CPhysicsAPI()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
25
src/Engine/Core/Physics/CPhysicsAPI.hpp
Normal file
25
src/Engine/Core/Physics/CPhysicsAPI.hpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#ifndef CPHYSICSAPI_HPP
|
||||
#define CPHYSICSAPI_HPP
|
||||
namespace CosmicCore {
|
||||
|
||||
class CScene;
|
||||
/**
|
||||
* @brief Class representing any physical world - abstract.
|
||||
*/
|
||||
class CPhysicsAPI {
|
||||
|
||||
private:
|
||||
CScene* m_scene;
|
||||
public:
|
||||
CPhysicsAPI(CScene* scene): m_scene(scene){};
|
||||
virtual ~CPhysicsAPI();
|
||||
|
||||
virtual void updateWorld(float delta) = 0;
|
||||
|
||||
virtual void initWorld() = 0;
|
||||
virtual void destroy() = 0;
|
||||
|
||||
CScene* getScene(){return m_scene;};
|
||||
};
|
||||
}
|
||||
#endif
|
||||
50
src/Engine/Core/Physics/CTangibleWorld.cpp
Normal file
50
src/Engine/Core/Physics/CTangibleWorld.cpp
Normal file
@@ -0,0 +1,50 @@
|
||||
#include "CTangibleWorld.hpp"
|
||||
#include "Jolt/Core/Memory.h"
|
||||
#include "Jolt/RegisterTypes.h"
|
||||
#include <memory>
|
||||
#include "../Scene/CScene.hpp"
|
||||
#include "../Component/Rigidbody/CRigidBody.hpp"
|
||||
namespace CosmicCore {
|
||||
|
||||
CTangibleWorld::~CTangibleWorld()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CTangibleWorld::initWorld()
|
||||
{
|
||||
JPH::RegisterDefaultAllocator();
|
||||
JPH::Factory::sInstance = new JPH::Factory();
|
||||
JPH::RegisterTypes();
|
||||
m_tempAllocator = std::make_unique<JPH::TempAllocatorImpl>(10 * 1024 * 1024);
|
||||
m_jobSystem = std::make_unique<JPH::JobSystemThreadPool>(JPH::cMaxPhysicsJobs, JPH::cMaxPhysicsBarriers, JPH::thread::hardware_concurrency() - 1);
|
||||
m_physicsSystem.Init(cMaxBodies, cNumBodyMutexes, cMaxBodyPairs, cMaxContactConstraints, m_broadPhaseLayer, m_objectVsBroadPhase, m_objectLayerPairFilter);
|
||||
}
|
||||
|
||||
void CTangibleWorld::updateWorld(float deltaTime){
|
||||
m_physicsSystem.Update(deltaTime, 1, m_tempAllocator.get(), m_jobSystem.get());
|
||||
auto& registry = getScene()->getECManager(); // accès via scene
|
||||
auto view = registry.registry.view<CRigidBody>();
|
||||
for (auto entity : view) {
|
||||
auto& rb = registry.registry.get<CRigidBody>(entity);
|
||||
|
||||
// ne sync que les bodies dynamiques et kinématiques
|
||||
if (rb.getBodyType() == EBodyType::Static) continue;
|
||||
|
||||
registry.registry.get<CRigidBody>(entity).syncTransform();
|
||||
}
|
||||
}
|
||||
|
||||
void CTangibleWorld::destroy(){
|
||||
|
||||
getScene()->getECManager().registry.view<CRigidBody>().each([](CRigidBody& rb) {
|
||||
rb.destroy();
|
||||
});
|
||||
|
||||
JPH::UnregisterTypes();
|
||||
// Destroy the factory
|
||||
delete JPH::Factory::sInstance;
|
||||
JPH::Factory::sInstance = nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
116
src/Engine/Core/Physics/CTangibleWorld.hpp
Normal file
116
src/Engine/Core/Physics/CTangibleWorld.hpp
Normal file
@@ -0,0 +1,116 @@
|
||||
#ifndef CTANGIBLEWORLD_HPP
|
||||
#define CTANGIBLEWORLD_HPP
|
||||
#include "CPhysicsAPI.hpp"
|
||||
#include "PhysicsLayers.hpp"
|
||||
#include <Jolt/RegisterTypes.h>
|
||||
#include <Jolt/Core/Factory.h>
|
||||
#include <Jolt/Core/TempAllocator.h>
|
||||
#include <Jolt/Core/JobSystemThreadPool.h>
|
||||
#include <Jolt/Physics/PhysicsSettings.h>
|
||||
#include <Jolt/Physics/PhysicsSystem.h>
|
||||
#include <Jolt/Physics/Collision/Shape/BoxShape.h>
|
||||
#include <Jolt/Physics/Collision/Shape/SphereShape.h>
|
||||
#include <Jolt/Physics/Body/BodyCreationSettings.h>
|
||||
#include <Jolt/Physics/Body/BodyActivationListener.h>
|
||||
|
||||
|
||||
namespace CosmicCore {
|
||||
|
||||
// BroadPhaseLayerInterface implementation
|
||||
// This defines a mapping between object and broadphase layers.
|
||||
class BPLayerInterfaceImpl final : public JPH::BroadPhaseLayerInterface
|
||||
{
|
||||
public:
|
||||
BPLayerInterfaceImpl()
|
||||
{
|
||||
// Create a mapping table from object to broad phase layer
|
||||
mObjectToBroadPhase[Layers::NON_MOVING] = BroadPhaseLayers::NON_MOVING;
|
||||
mObjectToBroadPhase[Layers::MOVING] = BroadPhaseLayers::MOVING;
|
||||
}
|
||||
|
||||
virtual uint GetNumBroadPhaseLayers() const override
|
||||
{
|
||||
return BroadPhaseLayers::NUM_LAYERS;
|
||||
}
|
||||
|
||||
virtual JPH::BroadPhaseLayer GetBroadPhaseLayer(JPH::ObjectLayer inLayer) const override
|
||||
{
|
||||
JPH_ASSERT(inLayer < Layers::NUM_LAYERS);
|
||||
return mObjectToBroadPhase[inLayer];
|
||||
}
|
||||
|
||||
virtual const char *GetBroadPhaseLayerName(JPH::BroadPhaseLayer inLayer) const {return nullptr;};
|
||||
private:
|
||||
JPH::BroadPhaseLayer mObjectToBroadPhase[Layers::NUM_LAYERS];
|
||||
};
|
||||
|
||||
/// Class that determines if an object layer can collide with a broadphase layer
|
||||
class ObjectVsBroadPhaseLayerFilterImpl : public JPH::ObjectVsBroadPhaseLayerFilter
|
||||
{
|
||||
public:
|
||||
virtual bool ShouldCollide(JPH::ObjectLayer inLayer1, JPH::BroadPhaseLayer inLayer2) const override
|
||||
{
|
||||
switch (inLayer1)
|
||||
{
|
||||
case Layers::NON_MOVING:
|
||||
return inLayer2 == BroadPhaseLayers::MOVING;
|
||||
case Layers::MOVING:
|
||||
return true;
|
||||
default:
|
||||
JPH_ASSERT(false);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// Class that determines if two object layers can collide
|
||||
class ObjectLayerPairFilterImpl : public JPH::ObjectLayerPairFilter
|
||||
{
|
||||
public:
|
||||
virtual bool ShouldCollide(JPH::ObjectLayer inObject1, JPH::ObjectLayer inObject2) const override
|
||||
{
|
||||
switch (inObject1)
|
||||
{
|
||||
case Layers::NON_MOVING:
|
||||
return inObject2 == Layers::MOVING; // Non moving only collides with moving
|
||||
case Layers::MOVING:
|
||||
return true; // Moving collides with everything
|
||||
default:
|
||||
JPH_ASSERT(false);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class CTangibleWorld : public CPhysicsAPI{
|
||||
|
||||
JPH::PhysicsSystem m_physicsSystem;
|
||||
std::unique_ptr<JPH::TempAllocatorImpl> m_tempAllocator;
|
||||
std::unique_ptr<JPH::JobSystemThreadPool> m_jobSystem;
|
||||
|
||||
const uint cMaxBodies = 65536;
|
||||
const uint cNumBodyMutexes = 0;
|
||||
const uint cMaxBodyPairs = 65536;
|
||||
const uint cMaxContactConstraints = 10240;
|
||||
|
||||
BPLayerInterfaceImpl m_broadPhaseLayer;
|
||||
ObjectVsBroadPhaseLayerFilterImpl m_objectVsBroadPhase;
|
||||
ObjectLayerPairFilterImpl m_objectLayerPairFilter;
|
||||
|
||||
public:
|
||||
CTangibleWorld(CScene* scene): CPhysicsAPI(scene){};
|
||||
~CTangibleWorld();
|
||||
void initWorld();
|
||||
void updateWorld(float deltaTime);
|
||||
void destroy();
|
||||
|
||||
|
||||
JPH::PhysicsSystem& getPhysicsSystem() { return m_physicsSystem; }
|
||||
JPH::BodyInterface& getBodyInterface() {
|
||||
return m_physicsSystem.GetBodyInterface();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
29
src/Engine/Core/Physics/PhysicsLayers.hpp
Normal file
29
src/Engine/Core/Physics/PhysicsLayers.hpp
Normal file
@@ -0,0 +1,29 @@
|
||||
#ifndef PHYSICSLAYERS_HPP
|
||||
#define PHYSICSLAYERS_HPP
|
||||
|
||||
#include <Jolt/Jolt.h>
|
||||
#include <Jolt/Physics/Collision/BroadPhase/BroadPhaseLayer.h>
|
||||
#include <Jolt/Physics/Collision/ObjectLayer.h>
|
||||
namespace CosmicCore {
|
||||
|
||||
// Layer that objects can be in, determines which other objects it can collide with
|
||||
// Typically you at least want to have 1 layer for moving bodies and 1 layer for static bodies, but you can have more
|
||||
// layers if you want. E.g. you could have a layer for high detail collision (which is not used by the physics simulation
|
||||
// but only if you do collision testing).
|
||||
namespace Layers
|
||||
{
|
||||
static constexpr JPH::ObjectLayer NON_MOVING = 0;
|
||||
static constexpr JPH::ObjectLayer MOVING = 1;
|
||||
static constexpr JPH::ObjectLayer NUM_LAYERS = 2;
|
||||
};
|
||||
|
||||
namespace BroadPhaseLayers
|
||||
{
|
||||
static constexpr JPH::BroadPhaseLayer NON_MOVING(0);
|
||||
static constexpr JPH::BroadPhaseLayer MOVING(1);
|
||||
static constexpr unsigned int NUM_LAYERS(2);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -13,7 +13,9 @@
|
||||
namespace CosmicCore {
|
||||
|
||||
CScene::CScene(std::string name) : CSerializable(),
|
||||
m_name(std::move(name)) {
|
||||
m_name(std::move(name)), m_tangibleWorld(this)
|
||||
{
|
||||
m_tangibleWorld.initWorld();
|
||||
}
|
||||
|
||||
|
||||
@@ -21,47 +23,14 @@ namespace CosmicCore {
|
||||
return m_name;
|
||||
}
|
||||
|
||||
CEntity CScene::addEntity(std::string name, std::string description){
|
||||
VulkanImpl* api = dynamic_cast<VulkanImpl*>(GraphicsAPI::getAPI().get());
|
||||
CScene::~CScene()
|
||||
{
|
||||
m_tangibleWorld.destroy();
|
||||
}
|
||||
|
||||
CEntity CScene::createEntity(){
|
||||
auto handle = m_ecManager.registry.create();
|
||||
CEntity handler(m_ecManager, handle, this);
|
||||
m_ecManager().emplace<CTransform>(handle, handler);
|
||||
m_ecManager().emplace<CMetaData>(handle, handler, std::move(name), std::move(description));
|
||||
|
||||
auto& rM = GraphicsAPI::getAPI()->getResourceManager();
|
||||
|
||||
auto model = CModelLoader::loadModel("assets/models/cube.glb", rM);
|
||||
|
||||
rM.getTextureManager().loadedTextures.push_back(std::make_unique<CTexture>("assets/shrekt.png"));
|
||||
auto texture = rM.getTextureManager().loadedTextures.back().get();
|
||||
texture->init();
|
||||
for(auto& mesh : model->getMeshes())
|
||||
{
|
||||
mesh->getMaterial()->textureAlbedo = texture;
|
||||
mesh->getMaterial()->build();
|
||||
}
|
||||
|
||||
m_ecManager().emplace<CRenderer>(handle, handler, model);
|
||||
auto& tr = m_ecManager.registry.get<CTransform>(handle);
|
||||
tr.initUniformBuffer(dynamic_cast<VulkanImpl*>(GraphicsAPI::getAPI().get())->getAllocator());
|
||||
tr.updateUniformBuffer(0);
|
||||
tr.updateUniformBuffer(1);
|
||||
|
||||
auto camHandle = m_ecManager.registry.create();
|
||||
CEntity handlerCam(m_ecManager, camHandle, this);
|
||||
|
||||
auto& transform = m_ecManager().emplace<CTransform>(camHandle, handlerCam);
|
||||
auto& cam = m_ecManager.registry.emplace<CCamera>(camHandle, handlerCam);
|
||||
|
||||
m_ecManager.registry.emplace<CRelationship>(camHandle, handlerCam, std::vector<EntityId>{handle});
|
||||
m_ecManager.registry.emplace<CRelationship>(handle, handler, camHandle);
|
||||
|
||||
transform.setCenter({0.0f, 0.9f, 3.0f});
|
||||
cam.setAspect((float)api->getSwapChainExtent().width / api->getSwapChainExtent().height);
|
||||
cam.initUniformBuffer(api->getAllocator());
|
||||
cam.updateUniformBuffer(0, transform);
|
||||
cam.updateUniformBuffer(1, transform);
|
||||
return handler;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "../Utils/CSerializable.hpp"
|
||||
#include <string>
|
||||
#include <vulkan/vulkan_raii.hpp>
|
||||
|
||||
#include "../Physics/CTangibleWorld.hpp"
|
||||
namespace CosmicCore {
|
||||
class CEntity;
|
||||
class CScene : public CSerializable {
|
||||
@@ -13,15 +13,16 @@ namespace CosmicCore {
|
||||
// The name of the scene.
|
||||
std::string m_name;
|
||||
EntityComponentManager m_ecManager;
|
||||
|
||||
CTangibleWorld m_tangibleWorld;
|
||||
|
||||
public:
|
||||
CScene() = delete;
|
||||
CScene(std::string name);
|
||||
virtual ~CScene() = default;
|
||||
virtual ~CScene();
|
||||
|
||||
unsigned int getNumEntity() const;
|
||||
|
||||
CEntity addEntity(std::string name, std::string description);
|
||||
CEntity createEntity();
|
||||
|
||||
std::string getName() const;
|
||||
|
||||
@@ -29,6 +30,7 @@ namespace CosmicCore {
|
||||
|
||||
void removeEntity(unsigned int index, bool destroy = true);
|
||||
|
||||
CTangibleWorld& getTangibleWorld() {return m_tangibleWorld;};
|
||||
//CEntity* getActiveCamera();
|
||||
//void setActiveCamera(CEntity* newCamera);
|
||||
|
||||
|
||||
@@ -1,27 +1,37 @@
|
||||
/*#include "CEntityFactory.hpp"
|
||||
#include "CEntity.hpp"
|
||||
#include "Components/Graphic/Renderers/CMeshRenderer.hpp"
|
||||
#include "Components/Physic/CRigidBody.hpp"
|
||||
#include "Components/Physic/CCollider.hpp"
|
||||
#include "../Graphic/Material/SMaterial.hpp"
|
||||
#include "../Graphic/Material/SColor.hpp"
|
||||
#include "CEntityFactory.hpp"
|
||||
#include "ComponentFactory.hpp"
|
||||
|
||||
CEntity* CEntityFactory::createCube(CScene* e) {
|
||||
std::string name = "Cube" + std::to_string(CEntity::entityNumber);
|
||||
CEntity* cube = new CEntity(name, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f), glm::vec3(0.0f, 0.0f, 0.0f));
|
||||
cube->setScene(e);
|
||||
CRigidBody* body = new CRigidBody(cube);
|
||||
CCollider* geom = new CCollider(cube, GEOM_BOX, body->getMass());
|
||||
CMeshRenderer* renderer = new CMeshRenderer(cube);
|
||||
renderer->createPremadeMesh(4, MODEL_CUBE);
|
||||
cube->attachComponent(body);
|
||||
cube->attachComponent(geom);
|
||||
cube->attachComponent(renderer);
|
||||
e->addEntity(cube);
|
||||
return cube;
|
||||
namespace CEntityFactory{
|
||||
|
||||
CEntity CEntityFactory::create(CScene* scene, const EntityConfig& config) {
|
||||
auto entity = scene->createEntity();
|
||||
ComponentFactory::addTransform(entity, config.position, config.scale, config.rotation);
|
||||
if(!config.modelPath.empty())
|
||||
ComponentFactory::addRenderer(entity, config.modelPath);
|
||||
if(config.hasPhysics)
|
||||
{
|
||||
ComponentFactory::addCollider(entity, config.colliderType);
|
||||
ComponentFactory::addRigidBody(entity, config.bodyType);
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
|
||||
CEntity* CEntityFactory::createSphere(CScene* e) {
|
||||
/*CEntity* CEntityFactory::createCylinder(CScene* e, const EntityConfig& config) {
|
||||
/*std::string name = "Cylindre" + std::to_string(CEntity::entityNumber);
|
||||
CEntity* cylindre = new CEntity(name, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f), glm::vec3(0.0f, 0.0f, 0.0f));
|
||||
cylindre->setScene(e);
|
||||
CRigidBody* body = new CRigidBody(cylindre);
|
||||
CCollider* geom = new CCollider(cylindre, GEOM_CYLINDRE, body->getMass());
|
||||
CMeshRenderer* renderer = new CMeshRenderer(cylindre);
|
||||
renderer->createPremadeMesh(4, MODEL_CYLINDRE);
|
||||
cylindre->attachComponent(body);
|
||||
cylindre->attachComponent(geom);
|
||||
cylindre->attachComponent(renderer);
|
||||
e->addEntity(cylindre);
|
||||
return cylindre;
|
||||
}*/
|
||||
|
||||
/*CEntity* CEntityFactory::createSphere(CScene* e) {
|
||||
std::string name = "Sphere" + std::to_string(CEntity::entityNumber);
|
||||
CEntity* sphere = new CEntity(name, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f), glm::vec3(0.0f, 0.0f, 0.0f));
|
||||
sphere->setScene(e);
|
||||
@@ -36,20 +46,6 @@ CEntity* CEntityFactory::createSphere(CScene* e) {
|
||||
return sphere;
|
||||
}
|
||||
|
||||
CEntity* CEntityFactory::createCylinder(CScene* e) {
|
||||
std::string name = "Cylindre" + std::to_string(CEntity::entityNumber);
|
||||
CEntity* cylindre = new CEntity(name, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f), glm::vec3(0.0f, 0.0f, 0.0f));
|
||||
cylindre->setScene(e);
|
||||
CRigidBody* body = new CRigidBody(cylindre);
|
||||
CCollider* geom = new CCollider(cylindre, GEOM_CYLINDRE, body->getMass());
|
||||
CMeshRenderer* renderer = new CMeshRenderer(cylindre);
|
||||
renderer->createPremadeMesh(4, MODEL_CYLINDRE);
|
||||
cylindre->attachComponent(body);
|
||||
cylindre->attachComponent(geom);
|
||||
cylindre->attachComponent(renderer);
|
||||
e->addEntity(cylindre);
|
||||
return cylindre;
|
||||
}
|
||||
|
||||
CEntity* CEntityFactory::createPlane(CScene* e) {
|
||||
std::string name = "Ground";
|
||||
@@ -120,5 +116,5 @@ CEntity* CEntityFactory::createReferenceAxis(CScene* e) {
|
||||
e->addEntity(r0);
|
||||
|
||||
return r0;
|
||||
}
|
||||
*/
|
||||
}*/
|
||||
}
|
||||
@@ -1,17 +1,31 @@
|
||||
//#include "CEntity.fwd.hpp"
|
||||
//#include "CScene.fwd.hpp"
|
||||
|
||||
/*
|
||||
#include <string>
|
||||
#include "../../Core/Scene/CScene.hpp"
|
||||
#include "../../Core/Entity/CEntity.hpp"
|
||||
#include "../../Core/Component/Collider/CCollider.hpp"
|
||||
#include "../../Core/Component/Rigidbody/CRigidBody.hpp"
|
||||
|
||||
namespace CEntityFactory {
|
||||
CEntity* createCube(CScene* e);
|
||||
using namespace CosmicCore;
|
||||
|
||||
CEntity* createSphere(CScene* e);
|
||||
struct EntityConfig {
|
||||
std::string name = "Entity";
|
||||
std::string description = "";
|
||||
glm::vec3 position = {0.0f, 0.0f, 0.0f};
|
||||
glm::vec3 scale = {1.0f, 1.0f, 1.0f};
|
||||
glm::vec3 rotation = {0.0f, 0.0f, 0.0f};
|
||||
std::string modelPath = "";
|
||||
std::string shaderName = "triangle";
|
||||
EColliderType colliderType = EColliderType::Box;
|
||||
EBodyType bodyType = EBodyType::Dynamic;
|
||||
bool hasPhysics = true;
|
||||
};
|
||||
|
||||
CEntity* createCylinder(CScene* e);
|
||||
CEntity create(CScene* e, const EntityConfig& config);
|
||||
|
||||
CEntity* createPlane(CScene* e);
|
||||
/*CEntity createSphere(CScene* e, const EntityConfig& config);
|
||||
|
||||
CEntity* createReferenceAxis(CScene* e);
|
||||
}*/
|
||||
CEntity createCylinder(CScene* e, const EntityConfig& config);
|
||||
|
||||
CEntity createPlane(CScene* e, const EntityConfig& config);
|
||||
|
||||
CEntity createReferenceAxis(CScene* e, const EntityConfig& config);*/
|
||||
}
|
||||
@@ -1,11 +1,96 @@
|
||||
#include "ComponentFactory.hpp"
|
||||
#include "../../Core/Graphics/Data/CModelLoader.hpp"
|
||||
namespace ComponentFactory {
|
||||
using namespace CosmicCore;
|
||||
|
||||
/*namespace CosmicCore {
|
||||
CComponentFactory& globalComponentFactory = CComponentFactory::instance();
|
||||
|
||||
CComponentFactory& CComponentFactory::instance() {
|
||||
static CComponentFactory factory;
|
||||
return factory;
|
||||
CTransform& addTransform(CEntity& entity, glm::vec3 position, glm::vec3 scale, glm::vec3 rotation)
|
||||
{
|
||||
VulkanImpl* api = dynamic_cast<VulkanImpl*>(GraphicsAPI::getAPI().get());
|
||||
auto& reg = entity.getRegistry();
|
||||
auto& tr = reg.registry.emplace<CTransform>(*entity, entity);
|
||||
tr.setCenter(position);
|
||||
tr.setScale(scale);
|
||||
tr.setEulerAngle(rotation);
|
||||
tr.initUniformBuffer(api->getAllocator());
|
||||
tr.updateUniformBuffer(0);
|
||||
tr.updateUniformBuffer(1);
|
||||
return tr;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
CCamera& addCamera(CEntity& entity, float fov, float near, float far)
|
||||
{
|
||||
VulkanImpl* api = dynamic_cast<VulkanImpl*>(GraphicsAPI::getAPI().get());
|
||||
auto& reg = entity.getRegistry();
|
||||
|
||||
// CTransform obligatoire pour la caméra
|
||||
if (!reg.registry.all_of<CTransform>(*entity))
|
||||
throw std::runtime_error("addCamera requires a CTransform on the entity");
|
||||
|
||||
auto& transform = reg.registry.get<CTransform>(*entity);
|
||||
auto& cam = reg.registry.emplace<CCamera>(*entity, entity);
|
||||
|
||||
cam.setFov(fov);
|
||||
cam.setNearFar(near, far);
|
||||
cam.setAspect((float)api->getSwapChainExtent().width /
|
||||
(float)api->getSwapChainExtent().height);
|
||||
cam.initUniformBuffer(api->getAllocator());
|
||||
cam.updateUniformBuffer(0, transform);
|
||||
cam.updateUniformBuffer(1, transform);
|
||||
return cam;
|
||||
}
|
||||
|
||||
CRenderer& addRenderer(CEntity& entity, const std::string& modelPath)
|
||||
{
|
||||
auto& rm = GraphicsAPI::getAPI()->getResourceManager();
|
||||
auto& reg = entity.getRegistry();
|
||||
|
||||
CModel* model = CModelLoader::loadModel(modelPath, rm);
|
||||
return reg.registry.emplace<CRenderer>(*entity, entity, model);
|
||||
}
|
||||
|
||||
CCollider& addCollider(CEntity& entity, EColliderType type)
|
||||
{
|
||||
auto& reg = entity.getRegistry();
|
||||
auto& col = reg.registry.emplace<CCollider>(*entity, entity, type);
|
||||
|
||||
// taille par défaut depuis le transform si disponible
|
||||
if (reg.registry.all_of<CTransform>(*entity)) {
|
||||
auto& tr = reg.registry.get<CTransform>(*entity);
|
||||
switch (type) {
|
||||
case EColliderType::Box:
|
||||
col.setBoxSize(tr.getScale());
|
||||
break;
|
||||
case EColliderType::Sphere:
|
||||
col.setSphereRadius(glm::compMax(tr.getScale()) * 0.5f);
|
||||
break;
|
||||
case EColliderType::Capsule:
|
||||
col.setCapsule(tr.getScale().y * 0.5f,
|
||||
glm::max(tr.getScale().x, tr.getScale().z) * 0.5f);
|
||||
break;
|
||||
case EColliderType::ConvexHull:
|
||||
case EColliderType::Mesh:
|
||||
// build depuis le renderer si disponible
|
||||
if (reg.registry.all_of<CRenderer>(*entity))
|
||||
col.buildFromRenderer();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return col;
|
||||
}
|
||||
|
||||
CRigidBody& addRigidBody(CEntity& entity, EBodyType type)
|
||||
{
|
||||
auto& reg = entity.getRegistry();
|
||||
|
||||
if (!reg.registry.all_of<CTransform>(*entity))
|
||||
throw std::runtime_error("addRigidBody requires a CTransform on the entity");
|
||||
if (!reg.registry.all_of<CCollider>(*entity))
|
||||
throw std::runtime_error("addRigidBody requires a CCollider on the entity");
|
||||
|
||||
auto& rb = reg.registry.emplace<CRigidBody>(*entity, entity, type);
|
||||
rb.init();
|
||||
return rb;
|
||||
}
|
||||
};
|
||||
@@ -1,95 +1,36 @@
|
||||
#ifndef CCOMPONENTFACTORY_HPP
|
||||
#define CCOMPONENTFACTORY_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
#include <typeindex>
|
||||
#include <utility>
|
||||
//#include "../Component/CAbstractComponent.hpp"
|
||||
#include "../../Core/Entity/CEntity.hpp"
|
||||
#include "../../Core/Component/Collider/CCollider.hpp"
|
||||
#include "../../Core/Component/Geometry/CTransform.hpp"
|
||||
#include "../../Core/Component/Rigidbody/CRigidBody.hpp"
|
||||
#include "../../Core/Component/Graphics/CRenderer.hpp"
|
||||
#include "../../Core/Component/Camera/CCamera.hpp"
|
||||
|
||||
//TODO modifier pour la scène soit obligatoire, sans scène pas d'entité, sans entité pas de composants
|
||||
/*namespace CosmicCore
|
||||
{
|
||||
class CEntity;
|
||||
class CComponentFactory {
|
||||
public:
|
||||
using ComponentCreator = std::function<std::shared_ptr<CAbstractComponent>(std::weak_ptr<CEntity>&, const std::vector<std::any>&)>;
|
||||
using ResourceComponentCreator = std::function<std::shared_ptr<CAbstractComponent>(const std::vector<std::any>&)>;
|
||||
namespace ComponentFactory {
|
||||
using namespace CosmicCore;
|
||||
|
||||
static CComponentFactory& instance();
|
||||
|
||||
static void registerStandardProvidedAbstractComponents()
|
||||
{
|
||||
//auto& ins = instance();
|
||||
//ins.registerComponent<CAbstractComponent>();//todo
|
||||
}
|
||||
// crée et initialise un CTransform sur une entité existante
|
||||
CTransform& addTransform(CEntity& entity,
|
||||
glm::vec3 position = {0,0,0},
|
||||
glm::vec3 scale = {1,1,1},
|
||||
glm::vec3 rotation = {0,0,0});
|
||||
|
||||
template <typename T, typename... Args>
|
||||
void registerComponent() {
|
||||
creators[typeid(T)] = [](std::weak_ptr<CEntity> entity, const std::vector<std::any>& args) {
|
||||
return createComponent<T, Args...>(entity, args, std::index_sequence_for<Args...>{});
|
||||
};
|
||||
}
|
||||
// crée et initialise une CCamera sur une entité existante
|
||||
CCamera& addCamera(CEntity& entity,
|
||||
float fov = 45.0f,
|
||||
float near = 0.1f,
|
||||
float far = 1000.0f);
|
||||
|
||||
template <typename T, typename... Args>
|
||||
void registerResourceComponent() {
|
||||
resourceCreators[typeid(T)] = [](const std::vector<std::any>& args) {
|
||||
return createComponent<T, Args...>(args, std::index_sequence_for<Args...>{});
|
||||
};
|
||||
}
|
||||
// crée et initialise un CRenderer depuis un fichier
|
||||
CRenderer& addRenderer(CEntity& entity, const std::string& modelPath);
|
||||
|
||||
template <typename T>
|
||||
std::shared_ptr<T> create(std::weak_ptr<CEntity> entity, const std::vector<std::any>& params) {
|
||||
auto it = creators.find(typeid(T));
|
||||
if (it != creators.end()) {
|
||||
return std::dynamic_pointer_cast<T>(it->second(entity, params));
|
||||
}
|
||||
throw std::runtime_error("Component not registered");
|
||||
}
|
||||
// crée un CCollider
|
||||
CCollider& addCollider(CEntity& entity, EColliderType type = EColliderType::Box);
|
||||
|
||||
template <typename T>
|
||||
std::shared_ptr<T> createResource(const std::vector<std::any>& params) {
|
||||
//ajouter au cache des resources pour réutilisation
|
||||
auto it = resourceCreators.find(typeid(T));
|
||||
if (it != resourceCreators.end()) {
|
||||
return std::dynamic_pointer_cast<T>(it->second(params));
|
||||
}
|
||||
throw std::runtime_error("Resource Component not registered: " + std::string(typeid(T).name()));
|
||||
}
|
||||
// crée et initialise un CRigidBody
|
||||
CRigidBody& addRigidBody(CEntity& entity, EBodyType type = EBodyType::Dynamic);
|
||||
};
|
||||
|
||||
std::unordered_map<std::type_index, ComponentCreator>& getRegisteredComponents(){return creators;};
|
||||
|
||||
std::unordered_map<std::type_index, ResourceComponentCreator>& getRegisteredResourceComponents(){return resourceCreators;};
|
||||
|
||||
private:
|
||||
std::unordered_map<std::type_index, ComponentCreator> creators;
|
||||
std::unordered_map<std::type_index, ResourceComponentCreator> resourceCreators;
|
||||
|
||||
|
||||
template <typename T, typename... Args, std::size_t... Is>
|
||||
static std::shared_ptr<T> createComponent(std::weak_ptr<CEntity>& entity, const std::vector<std::any>& args,
|
||||
std::index_sequence<Is...>) {
|
||||
try {
|
||||
return std::make_shared<T>(entity, std::any_cast<Args>(args[Is])...);
|
||||
} catch (const std::bad_any_cast& e) {
|
||||
throw std::runtime_error("Type mismatch in component arguments: " + std::string(e.what()));
|
||||
}
|
||||
}
|
||||
template <typename T, typename... Args, std::size_t... Is>
|
||||
static std::shared_ptr<T> createComponent(const std::vector<std::any>& args,
|
||||
std::index_sequence<Is...>) {
|
||||
try {
|
||||
return std::make_shared<T>(std::any_cast<Args>(args[Is])...);
|
||||
} catch (const std::bad_any_cast& e) {
|
||||
throw std::runtime_error("Type mismatch in component arguments: " + std::string(e.what()));
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
extern CComponentFactory& globalComponentFactory;
|
||||
}
|
||||
|
||||
*/
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user