diff --git a/ParticleGenerator/res/config/imgui.ini b/ParticleGenerator/res/config/imgui.ini
index 66570e980fd9b91b81d11036729f9fe88dd0631c..95c0d993f74668de113b95e11920c341a443c429 100644
--- a/ParticleGenerator/res/config/imgui.ini
+++ b/ParticleGenerator/res/config/imgui.ini
@@ -3,11 +3,10 @@ Pos=60,60
 Size=400,400
 
 [Window][Dear ImGui Demo]
-Pos=926,43
+Pos=1131,67
 Size=550,680
-Collapsed=1
 
 [Window][Particle Generator]
-Pos=60,60
-Size=141,81
+Pos=65,78
+Size=455,596
 
diff --git a/ParticleGenerator/src/Interface/Scene/MeshGenerator.cpp b/ParticleGenerator/src/Interface/Scene/MeshGenerator.cpp
index aeff43f665a9d239e1c23aad0b9a35799436866e..e35b3f4c72cd89b86ba02d6a92a57aa5c40e5e0a 100644
--- a/ParticleGenerator/src/Interface/Scene/MeshGenerator.cpp
+++ b/ParticleGenerator/src/Interface/Scene/MeshGenerator.cpp
@@ -28,6 +28,10 @@ namespace pg::interface {
         ImGui::SameLine();
         ImGui::ColorEdit4("Color : ", &this->parent()->_color[0]);
 
+        ImGui::SeparatorText("Position");
+        ImGui::DragFloat3("Position", &this->parent()->_meshPosition[0]);
+        ImGui::DragFloat3("Rotation", &this->parent()->_meshRotation[0]);
+
         ImGui::SeparatorText("Generators");
 
         if(!this->parent()->_generators.empty()) {
diff --git a/ParticleGenerator/src/Particle/Particle.hpp b/ParticleGenerator/src/Particle/Particle.hpp
index 0d0ef5529442f86b1be98bcc1a82684ae9dedfef..54dce2f121c1941d12732d756f79599802325453 100644
--- a/ParticleGenerator/src/Particle/Particle.hpp
+++ b/ParticleGenerator/src/Particle/Particle.hpp
@@ -5,6 +5,8 @@
 
 #include <CurveTools/CPU/CurveGenerator.hpp>
 
+#include <glm/mat4x4.hpp>
+
 namespace pg::particle
 {
 	class Particle
@@ -14,6 +16,8 @@ namespace pg::particle
 		ct::Point m_position;
 
 	public:
+		glm::mat4 _model = glm::mat4(1.f);
+
 		Particle(const ct::Point& position = ct::Point());
 		Particle(size_t born, const ct::Point& position = ct::Point());
    		virtual ~Particle() = default;
diff --git a/ParticleGenerator/src/Particle/Physics.cpp b/ParticleGenerator/src/Particle/Physics.cpp
index f2fff0f0676df019d44e1fc1464e428435f2cd52..dd67108cdbdbcf411defaeccfc3c6e19100e034c 100644
--- a/ParticleGenerator/src/Particle/Physics.cpp
+++ b/ParticleGenerator/src/Particle/Physics.cpp
@@ -1,5 +1,7 @@
 #include "Physics.hpp"
 
+#include <glm/gtc/matrix_transform.hpp>
+
 namespace pg::particle  {
 	Physics::Physics(size_t birth, const ct::Point& position, const glm::dvec3& velocity) 
 	: Particle(birth, position), m_velocity(velocity), m_acceleration(ct::Point()), m_friction(ct::Point()) {}
@@ -11,6 +13,7 @@ namespace pg::particle  {
 		m_acceleration -= static_cast<glm::dvec3>(m_friction) * m_velocity;
 		m_velocity += m_acceleration;
 
-		this->translate(this->m_velocity);
+		//this->translate(this->m_velocity);
+		this->_model = glm::translate(this->_model, glm::vec3(this->m_velocity));
 	}
 }
\ No newline at end of file
diff --git a/ParticleGenerator/src/Particle/generator/Generator.hpp b/ParticleGenerator/src/Particle/generator/Generator.hpp
index ae234afe8f41e00aa4375b72831a4506d762fcb8..8f290d40bec1490098cfa81d50ce5a7ba2dcf9b9 100644
--- a/ParticleGenerator/src/Particle/generator/Generator.hpp
+++ b/ParticleGenerator/src/Particle/generator/Generator.hpp
@@ -3,6 +3,9 @@
 #include <memory>
 #include "../Particle.hpp"
 
+#define GLM_ENABLE_EXPERIMENTAL
+#include <glm/gtx/rotate_vector.hpp>
+
 namespace pg::particle {
 
 	template <typename T>
@@ -13,6 +16,8 @@ namespace pg::particle {
 			glm::vec3 m_rotation;
 			
 		public:
+			glm::mat4 _model = glm::mat4(1.f);
+
 			Generator(const glm::vec3& position = glm::vec3(0.f), float positionVariation = 0.0)
 			: m_position(position), m_positionVariation(positionVariation), m_rotation(0.0) {}
 			
diff --git a/ParticleGenerator/src/Particle/generator/PhysicsGenerator.cpp b/ParticleGenerator/src/Particle/generator/PhysicsGenerator.cpp
index ed0665858ff87e38e3a51bad7375d8a1dccddf29..6c39ba54c226faabbcb3ba1251c0bf4579222b3a 100644
--- a/ParticleGenerator/src/Particle/generator/PhysicsGenerator.cpp
+++ b/ParticleGenerator/src/Particle/generator/PhysicsGenerator.cpp
@@ -45,7 +45,7 @@ namespace pg::particle
 		for (size_t i = 0; i < count; ++i) {
 			Physics * particle = new Physics(birth, this->getPosition());
 
-			particle->translate({p(randomEngine), p(randomEngine), p(randomEngine)});
+			//particle->translate({p(randomEngine), p(randomEngine), p(randomEngine)});
 
 			glm::vec3 velocityVariation = {vx(randomEngine), vy(randomEngine), vz(randomEngine)};
 			glm::vec3 accelerationVariation = {ax(randomEngine), ay(randomEngine), az(randomEngine)};
@@ -71,6 +71,9 @@ namespace pg::particle
 			particle->setAcceleration(realAcceleration);
 			particle->setFriction(realFriction);
 
+			particle->_model = this->_model;
+			particle->_model = glm::translate(particle->_model, {p(randomEngine), p(randomEngine), p(randomEngine)});
+
 			particles.push_back(std::unique_ptr<Physics>(particle));
 		}
 
diff --git a/ParticleGenerator/src/Scene/Scenes/MeshGenerator.cpp b/ParticleGenerator/src/Scene/Scenes/MeshGenerator.cpp
index 2c8daad45a60a8010caa6527b33328770b600c88..a01bf0597c9f6cc61b6b46bc6be34f25fc93e39e 100644
--- a/ParticleGenerator/src/Scene/Scenes/MeshGenerator.cpp
+++ b/ParticleGenerator/src/Scene/Scenes/MeshGenerator.cpp
@@ -100,7 +100,13 @@ namespace pg::scene {
 
         this->_meshProgram.use();
 
-        this->_meshProgram.setUniform("uModel", glm::mat4(1.f));
+        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);
+
+        this->_meshProgram.setUniform("uModel", model);
         this->_meshProgram.setUniform("uView", VIEW_MATRIX);
         this->_meshProgram.setUniform("uProj", PROJECTION_MATRIX);
 
@@ -118,10 +124,10 @@ namespace pg::scene {
         while(particle_accumulator < this->_particles.size()) {
             std::vector<glm::mat4> models;
             for(size_t i = 0; i < this->_particles.size() && i < 1024; i++) {
-                glm::mat4 model = glm::mat4(1.0);
+                //glm::mat4 model = glm::mat4(1.0);
                 if(i + particle_accumulator < this->_particles.size()) {
-                    model = glm::translate(model, glm::vec3(this->_particles[particle_accumulator + i]->getPosition()));
-                    models.push_back(model);
+                   //model = glm::translate(model, glm::vec3(this->_particles[particle_accumulator + i]->getPosition()));
+                    models.push_back(this->_particles[particle_accumulator + i]->_model);
                 }
             }
 
@@ -186,10 +192,22 @@ namespace pg::scene {
 
     void MeshGenerator::spawn(int count, double current_time) {
         for(auto & generator : this->_generators) {
+            //? #####
+            generator._model = glm::mat4(1.f);
+
+            generator._model = glm::rotate(generator._model, glm::radians(this->_meshRotation.z), {0.f, 0.f, 1.f});
+            generator._model = glm::rotate(generator._model, glm::radians(this->_meshRotation.y), {0.f, 1.f, 0.f});
+            generator._model = glm::rotate(generator._model, glm::radians(this->_meshRotation.x), {1.f, 0.f, 0.f});
+
+            generator._model = glm::translate(generator._model, generator.getPosition() + this->_meshPosition);
+            //? #####
+            
+            
             if((count + this->_particles.size()) <= this->getMaxParticles()) {
                 std::vector<std::unique_ptr<particle::Physics>> newParticles = 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()));
             }
+            
         }
     }
 
diff --git a/ParticleGenerator/src/Scene/Scenes/MeshGenerator.hpp b/ParticleGenerator/src/Scene/Scenes/MeshGenerator.hpp
index 82ef60d06dfe518ed6979e435de9018020298e5c..d5382bcae02c6ee70b73af9ba1f42ddac79e2898 100644
--- a/ParticleGenerator/src/Scene/Scenes/MeshGenerator.hpp
+++ b/ParticleGenerator/src/Scene/Scenes/MeshGenerator.hpp
@@ -29,7 +29,8 @@ namespace pg::scene {
 
             interface::MeshGenerator _interface;
 
-        public:
+        public:        
+
             MeshGenerator();
    virtual ~MeshGenerator() = default;
 
diff --git a/ParticleGenerator/src/Scene/Scenes/MeshGeneratorModel.cpp b/ParticleGenerator/src/Scene/Scenes/MeshGeneratorModel.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a3ed710cd0c442293dbe0c89075b498b477dcf09
--- /dev/null
+++ b/ParticleGenerator/src/Scene/Scenes/MeshGeneratorModel.cpp
@@ -0,0 +1,206 @@
+#include "MeshGeneratorModel.hpp"
+
+#include "../../Mesh/Model.hpp"
+
+#define GLM_ENABLE_EXPERIMENTAL
+#include <glm/gtx/normal.hpp>
+#include <glm/gtc/matrix_transform.hpp>
+
+namespace pg::scene {
+    MeshGeneratorModel::MeshGeneratorModel()
+    : SceneParticle(16384),
+      _mesh(),
+      _meshProgram(),
+      _meshPosition(0.f),
+      _meshRotation(0.f),
+      _generators(),
+      _meshParticle(),
+      _meshParticleTexture(),
+      _meshParticleProgram(),
+      _ubo(0),
+      _color(1.f) {}
+
+    void MeshGeneratorModel::initialize() {
+        if(!this->_mesh.isGenerated()) {
+            this->changeMesh("res/models/sphere.obj");
+        }
+
+        if(!this->_meshParticle.isGenerated()) {
+            this->changeMeshParticle("res/models/sphere.obj");
+        }
+
+        if(!this->_meshProgram.usable()) {
+            Source vert("res/shaders/scene/Color.vert", Source::Categorie::VERTEX);
+            Source frag("res/shaders/scene/Color.frag", Source::Categorie::FRAGMENT);
+
+            this->_meshProgram << vert;
+            this->_meshProgram << frag;
+
+            this->_meshProgram.link();
+
+            vert.release();
+            frag.release();
+        }
+
+        this->_meshParticleTexture.load("res/textures/smoke1.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);
+
+            this->_meshParticleProgram << vert;
+            this->_meshParticleProgram << frag;
+
+            this->_meshParticleProgram.link();
+
+            vert.release();
+            frag.release();
+        }
+
+        {
+			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->_meshParticleProgram.id(), "uModels_t");
+			glBindBufferBase(GL_UNIFORM_BUFFER, uniforme_index, this->_ubo);
+			glBindBuffer(GL_UNIFORM_BUFFER, 0);
+		}
+
+        this->_particles.reserve(16384);
+        this->setSpawnCount(1);
+        this->setSpawnFrequence(3000);
+        this->setLifetime(3);
+    }
+
+    void MeshGeneratorModel::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 MeshGeneratorModel::render(const Camera & camera, double current_time) {
+        const glm::mat4 VIEW_MATRIX = camera.getViewMatrix();
+        const glm::mat4 PROJECTION_MATRIX = camera.getViewFrustum().getProjectionMatrix();
+
+        // --------
+
+        this->_meshProgram.use();
+
+        this->_meshProgram.setUniform("uModel", glm::mat4(1.f));
+        this->_meshProgram.setUniform("uView", VIEW_MATRIX);
+        this->_meshProgram.setUniform("uProj", PROJECTION_MATRIX);
+
+        this->_meshProgram.setUniform("uColor", glm::vec4(0.6f, 0.2f, 0.4f, 1.f));
+
+        pg::error::OpenGLError::check();
+        
+        this->_mesh.draw();
+
+        pg::error::OpenGLError::check();
+
+        // --------
+
+        size_t particle_accumulator = 0;
+        while(particle_accumulator < this->_particles.size()) {
+            std::vector<glm::mat4> models;
+            for(size_t i = 0; i < this->_particles.size() && i < 1024; i++) {
+                glm::mat4 model = glm::mat4(1.0);
+                if(i + particle_accumulator < this->_particles.size()) {
+                    model = glm::translate(model, glm::vec3(this->_particles[particle_accumulator + i]->getPosition()));
+                    models.push_back(model);
+                }
+            }
+
+            glBindBuffer(GL_UNIFORM_BUFFER, this->_ubo);
+            glBufferSubData(GL_UNIFORM_BUFFER, 0, models.size() * sizeof(glm::mat4), models.data());
+
+            pg::error::OpenGLError::check();
+
+            this->_meshParticleTexture.bind(0);
+            this->_meshParticleProgram.use();
+
+            this->_meshParticleProgram.setUniform("uView", VIEW_MATRIX);
+            this->_meshParticleProgram.setUniform("uProj", PROJECTION_MATRIX);   
+            this->_meshParticleProgram.setUniform("uSlot", 0);
+            this->_meshParticleProgram.setUniform("uColor", this->_color);
+
+            pg::error::OpenGLError::check();
+
+            if(this->isRenderEnable()) {
+                this->_meshParticle.draw(this->_particles.size());
+            }
+
+            pg::error::OpenGLError::check();
+
+            particle_accumulator += 1024;
+        }
+
+        // --------
+    }
+
+    void MeshGeneratorModel::destroy() {
+        glDeleteBuffers(1, &this->_ubo);
+        this->_particles.clear();
+    }
+
+    void MeshGeneratorModel::changeMesh(const std::string & path) {
+        this->_particles.clear();
+        this->_generators.clear();
+		Model model(path);
+
+        MeshGeometry geometry = model.getMeshGeometry();
+        this->_mesh.generate(geometry.vertices, geometry.indices);
+
+        auto & vertices = geometry.vertices;
+        auto & indices = geometry.indices;
+
+        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;
+
+            glm::vec3 baricenter = (p1 + p2 + p3) / 3.f;
+            generator.setPosition(baricenter);
+
+            glm::vec3 normal = glm::triangleNormal(p1, p2, p3);
+            generator.setVelocity(glm::normalize(normal) / 50.f);
+
+            generator.setPositionVariation(0.5f);
+            this->_generators.push_back(generator);
+        }
+	}
+
+    void MeshGeneratorModel::changeMeshParticle(const std::string & path) {
+        Model model(path);
+        MeshGeometry geometry = model.getMeshGeometry();
+        this->_meshParticle.generate(geometry.vertices, geometry.indices);
+    }
+
+    void MeshGeneratorModel::spawn(int count, double current_time) {
+        for(auto & generator : this->_generators) {
+            if((count + this->_particles.size()) <= this->getMaxParticles()) {
+                std::vector<std::unique_ptr<particle::Physics>> newParticles = 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()));
+            }
+        }
+    }
+
+	void MeshGeneratorModel::changeTexture(const std::string & path) {
+		this->_meshParticleTexture.load(path);
+	}
+}
\ No newline at end of file
diff --git a/ParticleGenerator/src/Scene/Scenes/MeshGeneratorModel.hpp b/ParticleGenerator/src/Scene/Scenes/MeshGeneratorModel.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..811943c3b15cb455ee9e21549c835dbb125c5e0f
--- /dev/null
+++ b/ParticleGenerator/src/Scene/Scenes/MeshGeneratorModel.hpp
@@ -0,0 +1,45 @@
+#pragma once
+
+#include "../Scene.hpp"
+
+#include <vector>
+#include <memory>
+
+#include "../../Mesh/Mesh.hpp"
+#include "../../Mesh/Billboard.hpp"
+#include "../../Renderer/Renderer.hpp"
+#include "../../Particle/generator/PhysicsGenerator.hpp"
+
+namespace pg::scene {
+    class MeshGeneratorModel : public SceneParticle {
+        private:
+            Mesh _mesh;
+            Program _meshProgram;
+            glm::vec3 _meshPosition;
+            glm::vec3 _meshRotation;
+
+            std::vector<particle::PhysicsGenerator> _generators;
+            Mesh _meshParticle;
+            Material _meshParticleTexture;
+            Program _meshParticleProgram;
+            GLuint _ubo;
+            glm::vec4 _color;
+
+        public:
+            MeshGeneratorModel();
+   virtual ~MeshGeneratorModel() = default;
+
+            virtual void initialize();
+            virtual void update(double);
+            virtual void render(const Camera &, double);
+            virtual void destroy();
+
+            virtual std::string name() const {return "Mesh Generator Model Scene";};
+
+            void changeMesh(const std::string &);
+            void changeMeshParticle(const std::string &);
+			void changeTexture(const std::string &);
+
+            void spawn(int count, double current_time);
+    };
+}
\ No newline at end of file
diff --git a/ParticleGenerator/src/main.cpp b/ParticleGenerator/src/main.cpp
index 87505251309600816c7e06ffa943522cf4460279..ecdda9055ff7de0682746b77d2ebae38f339ee25 100644
--- a/ParticleGenerator/src/main.cpp
+++ b/ParticleGenerator/src/main.cpp
@@ -13,6 +13,7 @@
 #include "Scene/Scenes/Grid.hpp"
 #include "Scene/Scenes/PhysicSprite.hpp"
 #include "Scene/Scenes/MultyPath.hpp"
+#include "Scene/Scenes/MeshGeneratorModel.hpp"
 
 #include "Interface/Manager.hpp"
 
@@ -82,6 +83,7 @@ int main(int argc, const char * argv[]) {
         pg::scene::MeshGenerator meshGenerator;
         pg::scene::Path path(&bezier, ctrlPoints);
         pg::scene::MultyPath multyPath(ctrlPoints);
+        pg::scene::MeshGeneratorModel meshGeneratorModel;
         
         pg::Manager manager(window);
         pg::interface::Manager imanager(window, manager);
@@ -91,6 +93,7 @@ int main(int argc, const char * argv[]) {
         manager.add(&physicSprite);
         manager.add(&meshGenerator);
         manager.add(&multyPath);
+        manager.add(&meshGeneratorModel);
 
         while(window.isOpen()) {
             double current_time = glfwGetTime();