Skip to content
Snippets Groups Projects
Commit f322c5fc authored by BATON Theau's avatar BATON Theau
Browse files

Start interface for MesgGenerator Scene

parent 0d311e68
Branches
No related tags found
No related merge requests found
#include "MeshGeneratorInterface.hpp"
#include <imgui.h>
#include "../../Scene/Scenes/MeshGenerator.hpp"
#include "../../tfd/tinyfiledialogs.h"
namespace pg {
MeshGeneratorInterface::MeshGeneratorInterface(scene::MeshGenerator * scene, size_t max)
: _scene(scene),
_max(max),
_spawnFrequence(2500),
_spawnCount(1),
_lifetime(2),
_enableRender(true),
_enableSpawn(true) {
}
void MeshGeneratorInterface::render(double current_time) {
ImGui::Text("Particles Number : %i / %i.", this->_scene->_particles.size(), this->_max);
ImGui::SameLine();
if(ImGui::Button("Spawn")) {
this->_scene->spawn(1, current_time);
}
ImGui::SameLine();
if(ImGui::Button("Clear")) {
this->_scene->_particles.clear();
}
ImGui::Text("Particles Batchs : %i", static_cast<int>(this->_scene->_particles.size() / 1024) + 1);
ImGui::Separator();
ImGui::Checkbox("Enable Rendering", &this->_enableRender);
ImGui::Checkbox("Enable Spawning", &this->_enableSpawn);
ImGui::Separator();
ImGui::InputInt("Lifetime (s)", &this->_lifetime, 1, 2);
ImGui::InputInt("Spawn Frequence (ms)", &this->_spawnFrequence, 100, 500);
ImGui::SliderInt("Spawning Number", &this->_spawnCount, 1, static_cast<int>(this->_max));
ImGui::SeparatorText("Model");
if(ImGui::Button("Change Model")) {
char const * imagePatterns[1] = {"*.obj"};
std::string path = tinyfd_openFileDialog("Model Browser", "", 1, imagePatterns, "Model File", false);
this->_scene->changeMesh(path);
}
if(ImGui::CollapsingHeader("Global Genrator Parameter")) {
if(ImGui::Button("Apply")) {
}
}
}
}
\ No newline at end of file
#pragma once
#include "../Interface.hpp"
namespace pg {
namespace scene {
class MeshGenerator;
}
class MeshGeneratorInterface : public Interface {
private:
scene::MeshGenerator * _scene;
size_t _max;
int _spawnFrequence;
int _spawnCount;
int _lifetime;
bool _enableRender;
bool _enableSpawn;
public:
MeshGeneratorInterface(scene::MeshGenerator *, size_t max = 1024);
inline size_t getMaxParticle() const {return this->_max;}
inline int getSpawnFrequence() const {return this->_spawnFrequence;}
inline int getSpawnCount() const {return this->_spawnCount;}
inline int getLifeTime() const {return this->_lifetime;}
inline bool isRenderEnable() {return this->_enableRender;}
inline bool isSpawnEnable() {return this->_enableSpawn;}
virtual void render(double);
inline std::string title() const {return "Mesh Generator Scene Interface";}
};
}
\ No newline at end of file
......@@ -17,30 +17,12 @@ namespace pg::scene {
_billboard(),
_billboardTexture(),
_billboardProgram(),
_ubo(0) {}
_ubo(0),
_interface(this, 8192) {}
void MeshGenerator::initialize() {
if(!this->_mesh.isGenerated()) {
Model model("res/models/sphere.obj");
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) {
PhysicsParticleGenerator 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);
this->_generators.push_back(generator);
}
this->changeMesh("res/models/sphere.obj");
}
if(!this->_meshProgram.usable()) {
......@@ -81,20 +63,19 @@ namespace pg::scene {
glBindBufferBase(GL_UNIFORM_BUFFER, uniforme_index, this->_ubo);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
}
this->_particles.reserve(this->_interface.getMaxParticle());
}
void MeshGenerator::update(double current_time) {
static auto start = std::chrono::high_resolution_clock::now();
auto end = std::chrono::high_resolution_clock::now();
pg::Particle::purge(this->_particles, static_cast<size_t>(current_time), 2);
if(duration_cast<std::chrono::milliseconds>(end - start).count() >= 2500) {
pg::Particle::purge(this->_particles, static_cast<size_t>(current_time), this->_interface.getLifeTime());
if(duration_cast<std::chrono::milliseconds>(end - start).count() >= this->_interface.getSpawnFrequence()) {
start = std::chrono::high_resolution_clock::now();
for(auto & generator : this->_generators) {
if((1 + this->_particles.size()) <= 1024) {
std::vector<std::unique_ptr<pg::Particle>> newParticles = generator.generate(1, static_cast<size_t>(current_time));
this->_particles.insert(this->_particles.begin(), std::make_move_iterator(newParticles.begin()), std::make_move_iterator(newParticles.end()));
}
if(this->_interface.isSpawnEnable()) {
this->spawn(this->_interface.getSpawnCount(), current_time);
}
}
......@@ -127,12 +108,16 @@ namespace pg::scene {
// --------
size_t particle_accumulator = 0;
while(particle_accumulator < this->_particles.size()) {
std::vector<glm::mat4> models;
for(auto & particle : this->_particles) {
for(size_t i = 0; i < this->_particles.size() && i < 1024; i++) {
glm::mat4 model = glm::mat4(1.0);
model = glm::translate(model, glm::vec3(particle->getPosition()));
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());
......@@ -149,10 +134,15 @@ namespace pg::scene {
pg::error::OpenGLError::check();
if(this->_interface.isRenderEnable()) {
this->_billboard.draw(this->_particles.size());
}
pg::error::OpenGLError::check();
particle_accumulator += 1024;
}
// --------
}
......@@ -161,4 +151,43 @@ namespace pg::scene {
this->_billboard.destroy();
this->_particles.clear();
}
void MeshGenerator::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) {
PhysicsParticleGenerator 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 MeshGenerator::spawn(size_t count, double current_time) {
for(auto & generator : this->_generators) {
if((count + this->_particles.size()) <= this->_interface.getMaxParticle()) {
std::vector<std::unique_ptr<pg::Particle>> 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 MeshGenerator::changeTexture(const std::string & path) {
this->_billboardTexture.load(path);
}
}
\ No newline at end of file
......@@ -9,6 +9,7 @@
#include "../../Mesh/Billboard.hpp"
#include "../../Renderer/Renderer.hpp"
#include "../../Particle/generator/PhysicsParticleGenerator.hpp"
#include "../../Interface/Scene/MeshGeneratorInterface.hpp"
namespace pg::scene {
class MeshGenerator : public Scene {
......@@ -25,6 +26,8 @@ namespace pg::scene {
Program _billboardProgram;
GLuint _ubo;
MeshGeneratorInterface _interface;
public:
MeshGenerator();
......@@ -34,7 +37,14 @@ namespace pg::scene {
virtual void destroy();
virtual std::string name() const {return "Mesh Generator Scene";};
virtual Interface * interface() {return nullptr;};
virtual Interface * interface() {return &this->_interface;}
void changeMesh(const std::string &);
void changeTexture(const std::string &);
void spawn(size_t count, double current_time);
friend class pg::MeshGeneratorInterface;
};
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment