From e8c084ebd8255741bfb1eba6fb7fe4153f77aa05 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Th=C3=A9au?= <theau.baton@etu.univ-amu.fr>
Date: Fri, 31 May 2024 16:01:24 +0200
Subject: [PATCH] Rename all scene

---
 ParticleGenerator/res/config/imgui.ini        |   9 +-
 ParticleGenerator/src/Interface/Manager.cpp   |   2 +
 .../src/Interface/Scene/MeshGenerator.cpp     |   2 +
 ParticleGenerator/src/Mesh/Model.cpp          |  18 ++-
 ParticleGenerator/src/Scene/Manager.hpp       |   1 +
 ParticleGenerator/src/Scene/Renderer.cpp      |   8 +-
 ParticleGenerator/src/Scene/Renderer.hpp      |   4 +
 .../src/Scene/Scenes/BillboardTest.cpp        |   3 +-
 .../src/Scene/Scenes/BillboardTest.hpp        |   2 +-
 .../src/Scene/Scenes/MeshGenerator.cpp        |  50 ++++---
 .../src/Scene/Scenes/MeshGenerator.hpp        |   4 +-
 .../src/Scene/Scenes/MeshGeneratorModel.cpp   |  10 +-
 .../src/Scene/Scenes/MeshGeneratorModel.hpp   |   2 +-
 .../src/Scene/Scenes/MultyPath.hpp            |   2 +-
 ParticleGenerator/src/Scene/Scenes/Path.hpp   |   2 +-
 .../src/Scene/Scenes/PathAnimated.cpp         |   3 +-
 .../src/Scene/Scenes/PathAnimated.hpp         |   2 +-
 .../src/Scene/Scenes/PathPregenerated.hpp     |   3 +-
 ParticleGenerator/src/Scene/Scenes/Physic.hpp |   2 +-
 .../src/Scene/Scenes/PhysicModel.cpp          | 141 ++++++++++++++++++
 .../src/Scene/Scenes/PhysicModel.hpp          |  49 ++++++
 .../src/Scene/Scenes/PhysicSprite.hpp         |   2 +-
 ParticleGenerator/src/main.cpp                |  16 +-
 23 files changed, 277 insertions(+), 60 deletions(-)
 create mode 100644 ParticleGenerator/src/Scene/Scenes/PhysicModel.cpp
 create mode 100644 ParticleGenerator/src/Scene/Scenes/PhysicModel.hpp

diff --git a/ParticleGenerator/res/config/imgui.ini b/ParticleGenerator/res/config/imgui.ini
index bc92e89..cff0c39 100644
--- a/ParticleGenerator/res/config/imgui.ini
+++ b/ParticleGenerator/res/config/imgui.ini
@@ -3,11 +3,6 @@ Pos=60,60
 Size=400,400
 
 [Window][Particle Generator]
-<<<<<<< HEAD
-Pos=13,14
-Size=505,662
+Pos=5,11
+Size=447,690
 
-=======
-Pos=60,60
-Size=733,329
->>>>>>> 5e77bdb39edb229deb0a1553d2ba4f5719d591a6
diff --git a/ParticleGenerator/src/Interface/Manager.cpp b/ParticleGenerator/src/Interface/Manager.cpp
index 700aac3..565c62c 100644
--- a/ParticleGenerator/src/Interface/Manager.cpp
+++ b/ParticleGenerator/src/Interface/Manager.cpp
@@ -37,6 +37,8 @@ namespace pg::interface {
         this->_historical.count(current_time);
 
         if(ImGui::Begin(this->_title.c_str())) {
+            ImGui::ColorEdit3("Background Color", &this->_manager.getSceneRenderer().getClearColor()[0]);
+
             if(ImGui::CollapsingHeader("Performaces")) {
                 this->_historical.draw(current_time);
             }
diff --git a/ParticleGenerator/src/Interface/Scene/MeshGenerator.cpp b/ParticleGenerator/src/Interface/Scene/MeshGenerator.cpp
index e35b3f4..416853a 100644
--- a/ParticleGenerator/src/Interface/Scene/MeshGenerator.cpp
+++ b/ParticleGenerator/src/Interface/Scene/MeshGenerator.cpp
@@ -11,6 +11,8 @@ namespace pg::interface {
     void MeshGenerator::draw(double current_time) {
         SceneParticle::draw(current_time);
         ImGui::SeparatorText("Model");
+        ImGui::Checkbox("Skybox Render", &this->parent()->_skyboxEnable);
+        ImGui::Checkbox("Mesh Render", &this->parent()->_meshEnable); 
         if(ImGui::Button("Change Model")) {
             char const * imagePatterns[1] = {"*.obj"};
             std::string path = tinyfd_openFileDialog("Model Browser", "", 1, imagePatterns, "Model File", false);
diff --git a/ParticleGenerator/src/Mesh/Model.cpp b/ParticleGenerator/src/Mesh/Model.cpp
index 04ee898..55ef831 100644
--- a/ParticleGenerator/src/Mesh/Model.cpp
+++ b/ParticleGenerator/src/Mesh/Model.cpp
@@ -17,9 +17,16 @@ namespace pg
 			vertex.position.y = aiMesh->mVertices[i].y;
 			vertex.position.z = aiMesh->mVertices[i].z;
 
-			vertex.normal.x = aiMesh->mNormals[i].x;
-			vertex.normal.y = aiMesh->mNormals[i].y;
-			vertex.normal.z = aiMesh->mNormals[i].z;
+			if(aiMesh->HasNormals()) {
+				vertex.normal.x = aiMesh->mNormals[i].x;
+				vertex.normal.y = aiMesh->mNormals[i].y;
+				vertex.normal.z = aiMesh->mNormals[i].z;
+			}
+			else {
+				vertex.normal.x = 0;
+				vertex.normal.y = 0;
+				vertex.normal.z = 0;
+			}
 
 			if (aiMesh->mTextureCoords[0])
 			{
@@ -50,6 +57,7 @@ namespace pg
 		for (unsigned int i = 0; i < node->mNumMeshes; i++)
 			m_meshesGeometry.push_back(loadMesh(scene->mMeshes[node->mMeshes[i]], scene));
 
+
 		for (unsigned int i = 0; i < node->mNumChildren; i++)
 			loadNode(node->mChildren[i], scene);
 	}
@@ -58,7 +66,7 @@ namespace pg
 		m_meshesGeometry()
 	{
 		Assimp::Importer importer;
-		const aiScene* scene = importer.ReadFile(path, aiProcess_Triangulate | aiProcess_FlipUVs);
+		const aiScene* scene = importer.ReadFile(path, aiProcess_Triangulate | aiProcess_FlipUVs | aiProcess_GenNormals);
 
 		if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode)
 		{
@@ -66,7 +74,7 @@ namespace pg
 			return;
 		}
 
-		loadNode(scene->mRootNode, scene);
+		loadNode(scene->mRootNode, scene);		
 	}
 
 	unsigned int Model::getMeshCount() const
diff --git a/ParticleGenerator/src/Scene/Manager.hpp b/ParticleGenerator/src/Scene/Manager.hpp
index 1b836b4..cd0b827 100644
--- a/ParticleGenerator/src/Scene/Manager.hpp
+++ b/ParticleGenerator/src/Scene/Manager.hpp
@@ -25,6 +25,7 @@ namespace pg {
             
             inline const SceneContainer & getScenes() const {return this->_scenes;}
             inline const scene::Renderer & getSceneRenderer() const {return this->_sceneRenderer;}
+            inline scene::Renderer & getSceneRenderer() {return this->_sceneRenderer;}
 
             inline void add(scene::Scene * scene) {this->_scenes.insert(scene);}
 
diff --git a/ParticleGenerator/src/Scene/Renderer.cpp b/ParticleGenerator/src/Scene/Renderer.cpp
index 6cb112b..7f76676 100644
--- a/ParticleGenerator/src/Scene/Renderer.cpp
+++ b/ParticleGenerator/src/Scene/Renderer.cpp
@@ -11,7 +11,8 @@ namespace pg::scene {
         _grid(),
         _chronometer(),
         _accumulator(0.f),
-        _timestep(1.f / 60.f) {
+        _timestep(1.f / 60.f),
+        _clearColor(0.f) {
             this->_grid.initialize();
         }
 
@@ -31,14 +32,13 @@ namespace pg::scene {
     }
 
     void Renderer::render(std::optional<Scene *> scene, const Camera & camera, double current_time) {
-        //glClearColor(0.f, 0.f, 0.f, 1.f);
-        glClearColor(1.f, 1.f, 1.f, 1.0f);
+        glClearColor(this->_clearColor.x, this->_clearColor.y, this->_clearColor.z, 1.0f);
         glEnable(GL_BLEND);
         glEnable(GL_MULTISAMPLE);
         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-        this->_grid.render(camera, current_time);
 
+        this->_grid.render(camera, current_time);
         if(scene.has_value()) {
             (*scene)->update(current_time);
             (*scene)->render(camera, current_time);
diff --git a/ParticleGenerator/src/Scene/Renderer.hpp b/ParticleGenerator/src/Scene/Renderer.hpp
index a834d51..ab5408b 100644
--- a/ParticleGenerator/src/Scene/Renderer.hpp
+++ b/ParticleGenerator/src/Scene/Renderer.hpp
@@ -21,12 +21,16 @@ namespace pg::scene {
 
             Chronometer _chronometer;
             float _accumulator, _timestep;
+            glm::vec3 _clearColor;
 
         public:
             Renderer(const Window &, Manager &);
            ~Renderer();
 
             inline const Window & getWindow() const {return this->_window;}
+            inline const glm::vec3 & getClearColor() const {return this->_clearColor;}
+            inline glm::vec3 & getClearColor() {return this->_clearColor;}
+
             
             void update(Scene &, double);
             void render(std::optional<Scene *>, const Camera &, double);
diff --git a/ParticleGenerator/src/Scene/Scenes/BillboardTest.cpp b/ParticleGenerator/src/Scene/Scenes/BillboardTest.cpp
index 47c4bff..6130db5 100644
--- a/ParticleGenerator/src/Scene/Scenes/BillboardTest.cpp
+++ b/ParticleGenerator/src/Scene/Scenes/BillboardTest.cpp
@@ -40,8 +40,7 @@ namespace pg::scene {
     }
 
     void BillboardTest::render(const Camera & camera, double current_time) {
-        glClearColor(1.f, 1.f, 1.f, 1.0f);
-        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+        glEnable(GL_DEPTH_TEST);
         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
         const glm::mat4 VIEW_MATRIX = camera.getViewMatrix();
         const glm::mat4 PROJECTION_MATRIX = camera.getViewFrustum().getProjectionMatrix();
diff --git a/ParticleGenerator/src/Scene/Scenes/BillboardTest.hpp b/ParticleGenerator/src/Scene/Scenes/BillboardTest.hpp
index 1cad17b..a1875a6 100644
--- a/ParticleGenerator/src/Scene/Scenes/BillboardTest.hpp
+++ b/ParticleGenerator/src/Scene/Scenes/BillboardTest.hpp
@@ -21,6 +21,6 @@ namespace pg::scene {
             virtual void destroy();
 
             virtual void spawn(int, double);
-            virtual std::string name() const {return "Billboard Test Scene";}
+            virtual std::string name() const {return "Billboard Test";}
     };
 }
\ No newline at end of file
diff --git a/ParticleGenerator/src/Scene/Scenes/MeshGenerator.cpp b/ParticleGenerator/src/Scene/Scenes/MeshGenerator.cpp
index 11d2fa9..aa81cf1 100644
--- a/ParticleGenerator/src/Scene/Scenes/MeshGenerator.cpp
+++ b/ParticleGenerator/src/Scene/Scenes/MeshGenerator.cpp
@@ -20,6 +20,8 @@ namespace pg::scene {
       _billboardProgram(),
       _ubo(0),
       _color(1.f),
+      _meshEnable(true),
+      _skyboxEnable(true),
       _interface(this) {}
 
     void MeshGenerator::initialize() {
@@ -108,30 +110,40 @@ namespace pg::scene {
 
         // --------
 
-        this->_skybox.draw(camera);
+        if(this->_skyboxEnable) {
+            this->_skybox.draw(camera);
+        }
 
-        this->_meshProgram.use();
+        if(this->_meshEnable) {
+            glEnable(GL_DEPTH_TEST);
+            this->_meshProgram.use();
 
-        glm::mat4 model = glm::mat4(1.f);
-        model = glm::rotate(model, glm::radians(this->_meshRotation.z), {0.f, 0.f, 1.f});
-        model = glm::rotate(model, glm::radians(this->_meshRotation.y), {0.f, 1.f, 0.f});
-        model = glm::rotate(model, glm::radians(this->_meshRotation.x), {1.f, 0.f, 0.f});
-        model = glm::translate(model, this->_meshPosition);
+            glm::mat4 model = glm::mat4(1.f);
+            model = glm::rotate(model, glm::radians(this->_meshRotation.z), {0.f, 0.f, 1.f});
+            model = glm::rotate(model, glm::radians(this->_meshRotation.y), {0.f, 1.f, 0.f});
+            model = glm::rotate(model, glm::radians(this->_meshRotation.x), {1.f, 0.f, 0.f});
+            model = glm::translate(model, this->_meshPosition);
+            model = glm::scale(model, {2.f, 2.f, 2.f});
 
-        this->_meshProgram.setUniform("uModel", model);
-        this->_meshProgram.setUniform("uView", VIEW_MATRIX);
-        this->_meshProgram.setUniform("uProj", PROJECTION_MATRIX);
+            pg::error::OpenGLError::check();
 
-        this->_meshProgram.setUniform("uColor", glm::vec4(0.6f, 0.2f, 0.4f, 1.f));
+            this->_meshProgram.setUniform("uModel", model);
+            this->_meshProgram.setUniform("uView", VIEW_MATRIX);
+            this->_meshProgram.setUniform("uProj", PROJECTION_MATRIX);
 
-        pg::error::OpenGLError::check();
-        
-        this->_mesh.draw();
+            this->_meshProgram.setUniform("uColor", glm::vec4(0.6f, 0.2f, 0.4f, 1.f));
 
-        pg::error::OpenGLError::check();
+            pg::error::OpenGLError::check();
+            
+            this->_mesh.draw();
+            pg::error::OpenGLError::check();
+            glDisable(GL_DEPTH_TEST);
+        }
 
         // --------
 
+        
+
         size_t particle_accumulator = 0;
         while(particle_accumulator < this->_particles.size()) {
             std::vector<glm::mat4> models;
@@ -161,6 +173,7 @@ namespace pg::scene {
                 this->_billboard.draw(this->_particles.size());
             }
             glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+           
 
             pg::error::OpenGLError::check();
 
@@ -177,20 +190,15 @@ namespace pg::scene {
     void MeshGenerator::changeMesh(const std::string & path) {
         this->_particles.clear();
         this->_generators.clear();
-        std::cout << "mark_-1" << std::endl; 
 
 		Model model(path);
 
-        std::cout << "mark_0" << std::endl;
-
         MeshGeometry geometry = model.getMeshGeometry();
         this->_mesh.generate(geometry.vertices, geometry.indices);
 
         auto & vertices = geometry.vertices;
         auto & indices = geometry.indices;
 
-        std::cout << "mark_1" << std::endl;
-
         for(size_t i = 0; i < geometry.indices.size(); i+= 3) {
             particle::PhysicsGenerator generator;
             glm::vec3 & p1 = vertices[indices[i]].position, p2 = vertices[indices[i+1]].position, p3 =  vertices[indices[i+2]].position;
@@ -204,8 +212,6 @@ namespace pg::scene {
             generator.setPositionVariation(0.5f);
             this->_generators.push_back(generator);
         }
-
-        std::cout << "mark_2" << std::endl;
 	}
 
     void MeshGenerator::spawn(int count, double current_time) {
diff --git a/ParticleGenerator/src/Scene/Scenes/MeshGenerator.hpp b/ParticleGenerator/src/Scene/Scenes/MeshGenerator.hpp
index aab0596..e504d53 100644
--- a/ParticleGenerator/src/Scene/Scenes/MeshGenerator.hpp
+++ b/ParticleGenerator/src/Scene/Scenes/MeshGenerator.hpp
@@ -28,6 +28,8 @@ namespace pg::scene {
             GLuint _ubo;
 
             glm::vec4 _color;
+            bool _meshEnable;
+            bool _skyboxEnable;
 
             interface::MeshGenerator _interface;
 
@@ -41,7 +43,7 @@ namespace pg::scene {
             virtual void render(const Camera &, double);
             virtual void destroy();
 
-            virtual std::string name() const {return "Mesh Generator Scene";};
+            virtual std::string name() const {return "Mesh Generate Billboard Generator";};
             virtual std::optional<interface::Interface *> interface() {return std::optional<interface::Interface *>(&this->_interface);}
 
             void changeMesh(const std::string &);
diff --git a/ParticleGenerator/src/Scene/Scenes/MeshGeneratorModel.cpp b/ParticleGenerator/src/Scene/Scenes/MeshGeneratorModel.cpp
index 978742c..94bb139 100644
--- a/ParticleGenerator/src/Scene/Scenes/MeshGeneratorModel.cpp
+++ b/ParticleGenerator/src/Scene/Scenes/MeshGeneratorModel.cpp
@@ -55,8 +55,8 @@ namespace pg::scene {
         this->_meshParticleTexture.load("res/textures/gray.png");
 
         if(!this->_meshParticleProgram.usable()) {
-            Source vert("res/shaders/scene/Texture-Fat.vert", Source::Categorie::VERTEX);
-            Source frag("res/shaders/scene/Texture.frag", Source::Categorie::FRAGMENT);
+            Source vert("res/shaders/scene/Phong-Fat.vert", Source::Categorie::VERTEX);
+            Source frag("res/shaders/scene/Phong.frag", Source::Categorie::FRAGMENT);
 
             this->_meshParticleProgram << vert;
             this->_meshParticleProgram << frag;
@@ -105,12 +105,11 @@ namespace pg::scene {
     }
 
     void MeshGeneratorModel::render(const Camera & camera, double current_time) {
-        glEnable(GL_DEPTH_TEST);
         const glm::mat4 VIEW_MATRIX = camera.getViewMatrix();
         const glm::mat4 PROJECTION_MATRIX = camera.getViewFrustum().getProjectionMatrix();
 
         // --------
-
+        glEnable(GL_DEPTH_TEST);
         this->_meshProgram.use();
 
         this->_meshProgram.setUniform("uModel", glm::mat4(1.f));
@@ -146,6 +145,8 @@ namespace pg::scene {
             this->_meshParticleProgram.setUniform("uProj", PROJECTION_MATRIX);   
             this->_meshParticleProgram.setUniform("uSlot", 0);
             this->_meshParticleProgram.setUniform("uColor", this->_color);
+            this->_meshParticleProgram.setUniform("uViewPosition", camera.getPosition());
+            this->_meshParticleProgram.setUniform("uLightPosition", camera.getPosition());
 
             pg::error::OpenGLError::check();
 
@@ -159,7 +160,6 @@ namespace pg::scene {
 
             particle_accumulator += 1024;
         }
-
         glDisable(GL_DEPTH_TEST);
     }
 
diff --git a/ParticleGenerator/src/Scene/Scenes/MeshGeneratorModel.hpp b/ParticleGenerator/src/Scene/Scenes/MeshGeneratorModel.hpp
index 4fd1a63..0274587 100644
--- a/ParticleGenerator/src/Scene/Scenes/MeshGeneratorModel.hpp
+++ b/ParticleGenerator/src/Scene/Scenes/MeshGeneratorModel.hpp
@@ -44,7 +44,7 @@ namespace pg::scene {
             virtual void render(const Camera &, double);
             virtual void destroy();
 
-            virtual std::string name() const {return "Mesh Generator Model Scene";}
+            virtual std::string name() const {return "Mesh Generate Model Generator";}
             virtual std::optional<interface::Interface *> interface() {return std::optional<interface::Interface *>(&this->_interface);}
 
             void changeMesh(const std::string &);
diff --git a/ParticleGenerator/src/Scene/Scenes/MultyPath.hpp b/ParticleGenerator/src/Scene/Scenes/MultyPath.hpp
index 0611464..c6a3dad 100644
--- a/ParticleGenerator/src/Scene/Scenes/MultyPath.hpp
+++ b/ParticleGenerator/src/Scene/Scenes/MultyPath.hpp
@@ -39,7 +39,7 @@ namespace pg::scene {
 
             void changeParticletexture(const std::string &);
 
-            virtual std::string name() const {return "Multy Path Scene";}
+            virtual std::string name() const {return "MultiPath Billboard Generator";}
             virtual std::optional<interface::Interface *> interface() {return std::optional<interface::Interface *>(&this->_interface);}
 
             virtual void spawn(int, double);
diff --git a/ParticleGenerator/src/Scene/Scenes/Path.hpp b/ParticleGenerator/src/Scene/Scenes/Path.hpp
index 1c39cb4..e62a566 100644
--- a/ParticleGenerator/src/Scene/Scenes/Path.hpp
+++ b/ParticleGenerator/src/Scene/Scenes/Path.hpp
@@ -38,7 +38,7 @@ namespace pg::scene {
 
             void changeParticletexture(const std::string &);
 
-            virtual std::string name() const {return "Path Scene";}
+            virtual std::string name() const {return "Path Billboard Generator";}
             virtual std::optional<interface::Interface *> interface() {return std::optional<interface::Interface *>(&this->_interface);}
 
             virtual void spawn(int, double);
diff --git a/ParticleGenerator/src/Scene/Scenes/PathAnimated.cpp b/ParticleGenerator/src/Scene/Scenes/PathAnimated.cpp
index 0f659ca..b9137f2 100644
--- a/ParticleGenerator/src/Scene/Scenes/PathAnimated.cpp
+++ b/ParticleGenerator/src/Scene/Scenes/PathAnimated.cpp
@@ -87,10 +87,11 @@ namespace pg::scene {
     }
 
     void PathAnimated::render(const Camera & camera, double current_time) {
-        glEnable(GL_DEPTH_TEST);
         const glm::mat4 VIEW_MATRIX = camera.getViewMatrix();
         const glm::mat4 PROJECTION_MATRIX = camera.getViewFrustum().getProjectionMatrix();
 
+        glEnable(GL_DEPTH_TEST);
+
         this->_trajectory.render(camera, current_time);
 
         std::vector<glm::mat4> models;
diff --git a/ParticleGenerator/src/Scene/Scenes/PathAnimated.hpp b/ParticleGenerator/src/Scene/Scenes/PathAnimated.hpp
index cbbb82a..2afda14 100644
--- a/ParticleGenerator/src/Scene/Scenes/PathAnimated.hpp
+++ b/ParticleGenerator/src/Scene/Scenes/PathAnimated.hpp
@@ -43,7 +43,7 @@ namespace pg::scene {
 
             void changeParticletexture(const std::string &);
 
-            virtual std::string name() const {return "Path Animated Scene";}
+            virtual std::string name() const {return "Path Model Animated Generator";}
             virtual std::optional<interface::Interface *> interface() {return std::optional<interface::Interface *>(&this->_interface);}
 
             virtual void spawn(int, double);
diff --git a/ParticleGenerator/src/Scene/Scenes/PathPregenerated.hpp b/ParticleGenerator/src/Scene/Scenes/PathPregenerated.hpp
index 85f3eb7..bc073ad 100644
--- a/ParticleGenerator/src/Scene/Scenes/PathPregenerated.hpp
+++ b/ParticleGenerator/src/Scene/Scenes/PathPregenerated.hpp
@@ -36,8 +36,7 @@ namespace pg::scene {
 
             void changeParticletexture(const std::string &);
 
-            virtual std::string name() const {return "Path Pregenerated Scene";}
-            //virtual std::optional<interface::Interface *> interface() {return std::optional<interface::Interface *>(&this->_interface);}
+            virtual std::string name() const {return "Path Pregenerated Billboard Generator";}
 
             virtual void spawn(int, double);
 
diff --git a/ParticleGenerator/src/Scene/Scenes/Physic.hpp b/ParticleGenerator/src/Scene/Scenes/Physic.hpp
index 8b36ea2..227f48d 100644
--- a/ParticleGenerator/src/Scene/Scenes/Physic.hpp
+++ b/ParticleGenerator/src/Scene/Scenes/Physic.hpp
@@ -31,7 +31,7 @@ namespace pg::scene {
 
             void changeParticletexture(const std::string &);
 
-            virtual std::string name() const {return "Physic Scene";}
+            virtual std::string name() const {return "Physic Billboard Generator";}
             virtual std::optional<interface::Interface *> interface() {return std::optional<interface::Interface *>(&this->_interface);}
 
             virtual void initialize();
diff --git a/ParticleGenerator/src/Scene/Scenes/PhysicModel.cpp b/ParticleGenerator/src/Scene/Scenes/PhysicModel.cpp
new file mode 100644
index 0000000..c84d657
--- /dev/null
+++ b/ParticleGenerator/src/Scene/Scenes/PhysicModel.cpp
@@ -0,0 +1,141 @@
+#include "PhysicModel.hpp"
+
+#include <chrono>
+#include <glm/gtc/matrix_transform.hpp>
+
+#include "../../Mesh/Model.hpp"
+
+namespace pg::scene {
+    PhysicModel::PhysicModel()
+    :   SceneParticle(1024),
+        _ubo(0),
+        _program(),
+        _texture(),
+        _generator(),
+        _color(1.f)
+        /*_interface(this, &this->_generator)*/ {}
+
+    void PhysicModel::initialize() {
+        this->changeModel("res/models/cube.obj");
+        if(!this->_program.usable()) {
+            pg::Source vertices("res/shaders/scene/Phong-Fat.vert", pg::Source::Categorie::VERTEX);
+            pg::Source fragment("res/shaders/scene/Phong.frag", pg::Source::Categorie::FRAGMENT);
+
+            this->_program << vertices;
+            this->_program << fragment;
+
+            this->_program.link();
+
+            vertices.release();
+            fragment.release();
+        }
+        
+        pg::error::OpenGLError::check();
+
+        glCreateBuffers(1, &this->_ubo);
+        glBindBuffer(GL_UNIFORM_BUFFER, this->_ubo);
+        glBufferData(GL_UNIFORM_BUFFER, 1024 * sizeof(glm::mat4), nullptr, GL_DYNAMIC_DRAW);
+
+        GLuint uniforme_index = glGetUniformBlockIndex(this->_program.id(), "uModels_t");
+        glBindBufferBase(GL_UNIFORM_BUFFER, uniforme_index, this->_ubo);
+
+        pg::error::OpenGLError::check();
+
+        this->_texture.load("res/textures/red.png");  
+
+        pg::error::OpenGLError::check();
+
+        this->_generator.setPosition({0.f, 0.f, 0.f});
+        this->_generator.setPositionVariation(0.5);
+        this->_generator.setVelocity({0, 0.01, 0});
+        this->_generator.setAcceleration({0.0, 0.0001, 0});
+       
+        glClearColor(0.25f, 0.f, 0.15f, 1.0f);
+    }
+
+    void PhysicModel::update(double current_time) {
+        static auto start = std::chrono::high_resolution_clock::now();
+        auto end = std::chrono::high_resolution_clock::now();
+
+        if(!this->isFreezeEnable()) {
+            particle::Particle::purge(this->_particles, static_cast<size_t>(current_time), this->getLifetime());
+            if(duration_cast<std::chrono::milliseconds>(end - start).count() >= this->getSpawnFrequence()) {
+                start = std::chrono::high_resolution_clock::now();
+                if(this->isSpawnEnable()) {
+                    this->spawn(this->getSpawnCount(), current_time);
+                }
+            }
+
+            if(duration_cast<std::chrono::milliseconds>(end - start).count() >= 10) {
+                for(auto& particle : this->_particles) {
+                    particle->update(0.0);
+                }
+            }
+        }
+    }
+
+    void PhysicModel::render(const Camera & camera, double current_time) {
+        const glm::mat4 VIEW_MATRIX = camera.getViewMatrix();
+        const glm::mat4 PROJECTION_MATRIX = camera.getViewFrustum().getProjectionMatrix();
+
+        std::vector<glm::mat4> models;
+
+        glEnable(GL_DEPTH_TEST);
+
+        for(auto & particle : this->_particles) {
+            models.push_back(particle->getModel());
+        }
+
+        pg::error::OpenGLError::check();
+
+        glBindBuffer(GL_UNIFORM_BUFFER, this->_ubo);
+        glBufferSubData(GL_UNIFORM_BUFFER, 0, models.size() * sizeof(glm::mat4), models.data());
+
+        pg::error::OpenGLError::check();
+
+        this->_texture.bind(0);
+        this->_program.use();
+                
+        this->_program.setUniform("uView", VIEW_MATRIX);
+        this->_program.setUniform("uProj", PROJECTION_MATRIX);   
+        this->_program.setUniform("uSlot", 0);
+        this->_program.setUniform("uColor", this->_color);
+        this->_program.setUniform("uViewPosition", camera.getPosition());
+        this->_program.setUniform("uLightPosition", glm::vec3(1.f, 1.f, 1.f));
+        this->_program.setUniform("uColor", this->_color);
+
+        pg::error::OpenGLError::check();
+        glPolygonMode(GL_FRONT_AND_BACK, this->isWireframeEnable() ? GL_LINE : GL_FILL);
+        if(this->isRenderEnable()) {
+            this->_mesh.draw(this->_particles.size());
+        }
+        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+
+        pg::error::OpenGLError::check();
+        glDisable(GL_DEPTH_TEST);
+    }
+
+    void PhysicModel::destroy() {
+        glDeleteBuffers(1, &this->_ubo);
+        this->_particles.clear();
+
+        pg::error::OpenGLError::check();
+    }
+
+    void PhysicModel::changeModel(const std::string & path) {
+        Model model(path);
+        MeshGeometry geometry = model.getMeshGeometry();
+        this->_mesh.generate(geometry.vertices, geometry.indices);
+    }
+
+    void PhysicModel::changeTexture(const std::string & path) {
+        this->_texture.load(path);
+    }
+
+    void PhysicModel::spawn(int count, double current_time) {
+        if((count + this->_particles.size()) <= this->getMaxParticles()) {
+            std::vector<std::unique_ptr<pg::particle::Physics>> newParticles = this->_generator.generate(count, static_cast<size_t>(current_time));
+            this->_particles.insert(this->_particles.begin(), std::make_move_iterator(newParticles.begin()), std::make_move_iterator(newParticles.end()));
+        }
+    }
+}
\ No newline at end of file
diff --git a/ParticleGenerator/src/Scene/Scenes/PhysicModel.hpp b/ParticleGenerator/src/Scene/Scenes/PhysicModel.hpp
new file mode 100644
index 0000000..9870694
--- /dev/null
+++ b/ParticleGenerator/src/Scene/Scenes/PhysicModel.hpp
@@ -0,0 +1,49 @@
+#pragma once
+
+#include "../Scene.hpp"
+
+#include "../../Renderer/Renderer.hpp"
+#include "../../Particle/generator/PhysicsGenerator.hpp"
+#include "../../Interface/Scene/Physic.hpp"
+#include "../../Mesh/Mesh.hpp"
+
+#include "../../System/Window.hpp"
+
+namespace pg::scene {
+    class PhysicModel : public SceneParticle {
+        private:
+            GLuint _ubo;
+            Program _program;
+            Material _texture;
+            Mesh _mesh;
+            particle::PhysicsGenerator _generator;
+            glm::vec4 _color;
+
+            //interface::PhysicModel _interface;
+
+        public:
+            PhysicModel();
+   virtual ~PhysicModel() = default;
+
+            inline const Program & getProgram() const {return this->_program;}
+            inline const Material & getTexture() const {return this->_texture;}
+            inline const particle::PhysicsGenerator & getGenerator() const {return this->_generator;}
+
+            void changeParticletexture(const std::string &);
+
+            virtual std::string name() const {return "Physic Model Generator";}
+            //virtual std::optional<interface::Interface *> interface() {return std::optional<interface::Interface *>(&this->_interface);}
+
+            virtual void initialize();
+            virtual void render(const Camera &, double);
+            virtual void update(double);
+            virtual void destroy();
+
+            void changeModel(const std::string &);
+            void changeTexture(const std::string &);
+
+            virtual void spawn(int, double);
+
+            //friend class pg::interface::PhysicModel;
+    };
+}
\ No newline at end of file
diff --git a/ParticleGenerator/src/Scene/Scenes/PhysicSprite.hpp b/ParticleGenerator/src/Scene/Scenes/PhysicSprite.hpp
index 59e489e..59cbf50 100644
--- a/ParticleGenerator/src/Scene/Scenes/PhysicSprite.hpp
+++ b/ParticleGenerator/src/Scene/Scenes/PhysicSprite.hpp
@@ -30,7 +30,7 @@ namespace pg::scene {
 
             void changeParticletexture(const std::string &);
 
-            virtual std::string name() const {return "Physic Sprite Scene";}
+            virtual std::string name() const {return "Physic Sprite Billboard Generator";}
             virtual std::optional<interface::Interface *> interface() {return std::optional<interface::Interface *>();}
 
             virtual void initialize();
diff --git a/ParticleGenerator/src/main.cpp b/ParticleGenerator/src/main.cpp
index 0158653..dfa666a 100644
--- a/ParticleGenerator/src/main.cpp
+++ b/ParticleGenerator/src/main.cpp
@@ -17,6 +17,7 @@
 #include "Scene/Scenes/PathPregenerated.hpp"
 #include "Scene/Scenes/PathAnimated.hpp"
 #include "Scene/Scenes/BillboardTest.hpp"
+#include "Scene/Scenes/PhysicModel.hpp"
 
 #include "Interface/Manager.hpp"
 
@@ -37,6 +38,7 @@ int main(int argc, const char * argv[]) {
         pg::error::OpenGLError::check();
 
         pg::OrbitCamera camera({0, 0, 3});
+        camera.getViewFrustum().setDistance(glm::vec2(0.1f, 1000.f));
 
         {
             glfwSetWindowUserPointer(window.address(), (void *)&camera);
@@ -90,18 +92,24 @@ int main(int argc, const char * argv[]) {
         pg::scene::PathPregenerated pathPregenerated(&bezier, ctrlPoints);
         pg::scene::PathAnimated pathAnimated(&bezier);
         pg::scene::BillboardTest billboardTest;
+        pg::scene::PhysicModel physicModel;
         
         pg::Manager manager(window);
         pg::interface::Manager imanager(window, manager);
         
-        manager.add(&path);
+
         manager.add(&physic);
         manager.add(&physicSprite);
-        manager.add(&meshGenerator);
-        manager.add(&multyPath);
-        manager.add(&meshGeneratorModel);
+        manager.add(&physicModel);
+
+        manager.add(&path);
         manager.add(&pathPregenerated);
+        manager.add(&multyPath);
         manager.add(&pathAnimated);
+        
+        manager.add(&meshGenerator);
+        manager.add(&meshGeneratorModel);
+       
         manager.add(&billboardTest);
 
         while(window.isOpen()) {
-- 
GitLab