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

Add PathPregeneratedParticle and Generator

parent e6c5bf44
No related branches found
No related tags found
No related merge requests found
Showing with 488 additions and 3 deletions
......@@ -3,10 +3,12 @@ Pos=60,60
Size=400,400
[Window][Dear ImGui Demo]
Pos=1032,14
Pos=1051,35
Size=550,680
Collapsed=1
[Window][Particle Generator]
Pos=-1,11
Size=823,650
Pos=7,9
Size=476,521
Collapsed=1
#include "PathPregenerated.hpp"
#include <iostream>
#include <cmath>
namespace pg::particle {
PathPregenerated::PathPregenerated(size_t birth, const ct::Curve & curve, double u, double inc, glm::dvec3 posVar, double limitor)
: Particle(birth), _curve(curve), _positionVariation(posVar), _u(u), _increment(inc), _limitor(limitor) {
if(!this->_curve.empty()) {
this->setModel(glm::mat4(1.f));
this->translate(this->_curve.at(0));
}
}
void PathPregenerated::update(double delta) {
this->_u += this->_increment;
size_t curvePosition = static_cast<size_t>(std::lerp(0.0, this->_curve.size()-1, this->_u));
if((this->_u > this->_limitor && this->_limitor > 0.0) || curvePosition >= this->_curve.size()) {
this->setBorn(static_cast<size_t>(0.0));
return;
}
this->setModel(glm::mat4(1.f));
this->translate(this->_curve.at(curvePosition) + this->_positionVariation);
}
}
\ No newline at end of file
#pragma once
#include "Particle.hpp"
namespace pg::particle {
class PathPregenerated : public Particle {
private:
const ct::Curve & _curve;
glm::dvec3 _positionVariation;
double _u, _increment, _limitor;
public:
PathPregenerated(size_t birth, const ct::Curve & curve, double u = 0.0, double inc = 0.01, glm::dvec3 posvar = glm::dvec3(), double limitor = 0.0);
inline const ct::Curve & getCurve() const {return this->_curve;}
inline double getParameterValue() const {return this->_u;}
inline glm::dvec3 getPositionVariation() const {return _positionVariation;}
inline double getParameterIncrement() const {return this->_increment;}
inline double getParameterLifeLimitor() const {return this->_limitor;}
inline void setPositionVariation(const glm::dvec3& positionVariation) {this->_positionVariation = positionVariation;}
inline void setParameterValue(double u) {this->_u = u;}
inline void setParameterIncrement(double inc) {this->_increment = inc;}
inline void setParameterLifeLimitor(double limitor) {this->_limitor = limitor;}
virtual void update(double delta = 0.0) override;
};
}
\ No newline at end of file
#include "PathPregeneratedGenerator.hpp"
#include <random>
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/rotate_vector.hpp>
#include <iostream>
namespace pg::particle {
PathPregeneratedGenerator::PathPregeneratedGenerator(ct::CurveGenerator * generator, const ct::Curve & ctrlPoints, double increment, double max, ct::Point position, float posVar)
: _generator(generator), _controlPoints(ctrlPoints), _path(), _u(0.f), _spacing(0.f), _increment(0.01f), _limitor(0.f) {
this->update(increment, max);
}
void PathPregeneratedGenerator::update(double increment, double max) {
std::vector<double> parameters;
for(double i = 0.0; i <= max; i += increment) {
parameters.push_back(i);
}
this->_path.clear();
this->_path = this->_generator->generate(this->_controlPoints, parameters);
}
std::vector<std::unique_ptr<PathPregenerated>> PathPregeneratedGenerator::generate(size_t count, size_t birth) const {
std::random_device device;
std::mt19937 randomEngine(device());
using ureal_dist = std::uniform_real_distribution<double>;
ureal_dist positionGenerator(-this->getPositionVariation(), this->getPositionVariation());
std::vector<std::unique_ptr<PathPregenerated>> particles;
particles.reserve(count);
std::vector<ct::Point> realCtrlPoint;
for(auto & point : this->_controlPoints) {
glm::dvec3 glmPoint = point;
glmPoint = glm::rotateZ<double>(glmPoint, glm::radians<double>(this->m_rotation.z));
glmPoint = glm::rotateY<double>(glmPoint, glm::radians<double>(this->m_rotation.y));
glmPoint = glm::rotateX<double>(glmPoint, glm::radians<double>(this->m_rotation.x));
realCtrlPoint.push_back(glmPoint + ct::Point(m_position));
}
float u_space = 0.0;
for (unsigned int i = 0; i < count; ++i)
{
glm::dvec3 positionVariation(0.0);
positionVariation.x = positionGenerator(randomEngine);
positionVariation.y = positionGenerator(randomEngine);
positionVariation.z = positionGenerator(randomEngine);
PathPregenerated * particle = new PathPregenerated(birth, this->_path, this->_u + u_space, this->_increment, positionVariation, this->_limitor);
particle->setPositionVariation(positionVariation);
particle->setParameterLifeLimitor(this->getParameterLifeLimitor());
u_space += this->getSpacing();
if(u_space > 1.0) {
u_space = 0.0;
}
particles.push_back(std::unique_ptr<PathPregenerated>(particle));
}
return particles;
}
}
\ No newline at end of file
#pragma once
#include "Generator.hpp"
#include "../PathPregenerated.hpp"
namespace pg::particle {
class PathPregeneratedGenerator : public Generator<PathPregenerated> {
private:
ct::CurveGenerator * _generator;
ct::Curve _controlPoints;
ct::Curve _path;
float _u, _spacing, _increment, _limitor;
public:
PathPregeneratedGenerator(ct::CurveGenerator *, const ct::Curve &, double = 0.01, double = 1.00000001, ct::Point = ct::Point(), float = 0.f);
inline ct::CurveGenerator * getGenerator() const {return this->_generator;}
inline const ct::Curve & getControlPoint() const {return this->_controlPoints;}
inline const ct::Curve & getPath() const {return this->_path;}
inline float getParameter() const {return this->_u;}
inline float getSpacing() const {return this->_spacing;}
inline float getParameterIncrement() const {return this->_increment;}
inline float getParameterLifeLimitor() const {return this->_limitor;}
inline void setGenerator(ct::CurveGenerator * generator) {this->_generator = generator;}
inline void setDefaultParameterValue(float u) {this->_u = u;}
inline void setParameterIncrement(float inc) {this->_increment = inc;}
inline void setParameterLifeLimitor(float limitor) {this->_limitor = limitor;}
virtual void update(double, double);
virtual std::vector<std::unique_ptr<PathPregenerated>> generate(size_t count, size_t birth = 0) const;
};
}
\ No newline at end of file
#include "PathPregenerated.hpp"
#include <chrono>
#include <glm/gtc/matrix_transform.hpp>
namespace pg::scene {
PathPregenerated::PathPregenerated(ct::CurveGenerator * generator, const ct::Curve & ctrlpoint)
: SceneParticle(1024),
_ubo(0),
_program(),
_texture(),
_generator(generator, ctrlpoint),
_trajectory(&this->_generator),
_color(1.f) {}
void PathPregenerated::initialize() {
this->_billboard.initialize();
this->_trajectory.initialize();
if(!this->_program.usable()) {
pg::Source vertices("res/shaders/scene/Billboard.vert", pg::Source::Categorie::VERTEX);
pg::Source fragment("res/shaders/scene/Billboard.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/smoke1.png");
pg::error::OpenGLError::check();
this->_generator.setPosition({0.f, 0.f, 0.f});
this->_generator.setPositionVariation(0.5f);
//this->_generator.setParameterIncrement(0.01f);
//this->_generator.setParameterLifeLimitor(1.0f);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glClearColor(0.25f, 0.f, 0.15f, 1.0f);
}
void PathPregenerated::update(double current_time) {
static auto start = std::chrono::high_resolution_clock::now();
auto end = std::chrono::high_resolution_clock::now();
if(!this->isFreezeEnable()) {
pg::particle::Particle::purge(this->_particles, static_cast<size_t>(current_time), this->getLifetime());
if(duration_cast<std::chrono::milliseconds>(end - start).count() >= 500) {
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 PathPregenerated::render(const Camera & camera, double current_time) {
const glm::mat4 VIEW_MATRIX = camera.getViewMatrix();
const glm::mat4 PROJECTION_MATRIX = camera.getViewFrustum().getProjectionMatrix();
this->_trajectory.render(camera, current_time);
std::vector<glm::mat4> models;
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->_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);
pg::error::OpenGLError::check();
this->_texture.bind();
if(this->isRenderEnable()) {
this->_billboard.draw(this->_particles.size());
}
pg::error::OpenGLError::check();
}
void PathPregenerated::destroy() {
glDeleteBuffers(1, &this->_ubo);
this->_billboard.destroy();
this->_particles.clear();
pg::error::OpenGLError::check();
}
void PathPregenerated::changeParticletexture(const std::string & PathPregenerated) {
this->_texture.load(PathPregenerated);
}
void PathPregenerated::spawn(int count, double current_time) {
//this->_generator._model = glm::mat4(1.f);
//this->_generator._model = glm::rotate(this->_generator._model, glm::radians(this->_generator.getRotation().z), {0.f, 0.f, 1.f});
//this->_generator._model = glm::rotate(this->_generator._model, glm::radians(this->_generator.getRotation().y), {0.f, 1.f, 0.f});
//this->_generator._model = glm::rotate(this->_generator._model, glm::radians(this->_generator.getRotation().x), {1.f, 0.f, 0.f});
//this->_generator._model = glm::translate(this->_generator._model, this->_generator.getPosition());
this->_generator.setModel(glm::mat4(1.f));
this->_generator.rotate(this->_generator.getRotation());
this->_generator.translate(this->_generator.getPosition());
if((count + this->_particles.size()) <= this->getMaxParticles()) {
std::vector<std::unique_ptr<pg::particle::PathPregenerated>> 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
#pragma once
#include "../Scene.hpp"
#include "TrajectoryPregenerated.hpp"
#include "../../Renderer/Renderer.hpp"
#include "../../Particle/generator/PathPregeneratedGenerator.hpp"
#include "../../Interface/Scene/Path.hpp"
#include "../../Mesh/Billboard.hpp"
#include "../../System/Window.hpp"
namespace pg::scene {
class PathPregenerated : public SceneParticle {
private:
GLuint _ubo;
Program _program;
Billboard _billboard;
TrajectoryPregenerated _trajectory;
Material _texture;
particle::PathPregeneratedGenerator _generator;
glm::vec4 _color;
public:
PathPregenerated(ct::CurveGenerator *, const ct::Curve &);
virtual ~PathPregenerated() = default;
virtual void initialize();
virtual void render(const Camera &, double);
virtual void update(double);
virtual void destroy();
inline const Program & getProgram() const {return this->_program;}
inline const Material & getTexture() const {return this->_texture;}
inline const particle::PathPregeneratedGenerator & getGenerator() const {return this->_generator;}
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 void spawn(int, double);
friend class pg::interface::Path;
};
}
\ No newline at end of file
#include "TrajectoryPregenerated.hpp"
#include <glm/gtc/matrix_transform.hpp>
#include <CurveTools/CPU/CurveSampler.hpp>
namespace pg::scene {
TrajectoryPregenerated::TrajectoryPregenerated(particle::PathPregeneratedGenerator * generator, double increment)
: _generator(generator),
_vbo(this->_vao, {layout::POSITION, layout::COLOR}),
_increment(increment),
_color(0.0f, 1.f, 0.f, 1.f),
_pointSize(8.f),
_lineSize(1.f),
_controlLine(false),
_enableControl(true),
_enableLine(true),
_enableRender(true) {}
void TrajectoryPregenerated::initialize() {
this->update(0.0);
if(!this->_program.usable()) {
Source vert("res/shaders/scene/Trajectory.vert", Source::Categorie::VERTEX);
Source frag("res/shaders/scene/Trajectory.frag", Source::Categorie::FRAGMENT);
this->_program << vert;
this->_program << frag;
this->_program.link();
vert.release();
frag.release();
}
}
void TrajectoryPregenerated::update(double) {
std::vector<float> traj;
for(auto & point : this->_generator->getControlPoint()) {
traj.push_back(static_cast<float>(point.x));
traj.push_back(static_cast<float>(point.y));
traj.push_back(static_cast<float>(point.z));
traj.push_back(0.25f);
traj.push_back(0.25f);
traj.push_back(0.25f);
}
for(auto & point : this->_generator->getPath()) {
traj.push_back(static_cast<float>(point.x));
traj.push_back(static_cast<float>(point.y));
traj.push_back(static_cast<float>(point.z));
traj.push_back(1.f);
traj.push_back(1.f);
traj.push_back(1.f);
}
this->_vbo.set(traj);
}
void TrajectoryPregenerated::render(const Camera & camera, double current_time) {
if(this->_enableRender) {
glEnable(GL_LINE_SMOOTH);
glLineWidth(this->_lineSize);
this->_vao.bind();
glEnable(GL_PROGRAM_POINT_SIZE);
this->_program.use();
this->_program.setUniform("uProj", camera.getViewFrustum().getProjectionMatrix());
this->_program.setUniform("uView", camera.getViewMatrix());
this->_program.setUniform("uModel", this->_generator->getModel());
this->_program.setUniform("uColor", this->_color);
this->_program.setUniform("uPointSize", this->_pointSize);
GLsizei raw = static_cast<GLsizei>(this->_generator->getControlPoint().size());
GLsizei total = static_cast<GLsizei>(this->_vbo.vertices());
if(this->_enableLine) {
glDrawArrays(GL_LINE_STRIP, raw, total - raw);
}
if(this->_enableControl) {
glDrawArrays(this->_controlLine ? GL_LINE_STRIP : GL_POINTS, 0, static_cast<GLsizei>(this->_generator->getControlPoint().size()));
}
}
}
void TrajectoryPregenerated::destroy() {
}
}
\ No newline at end of file
#pragma once
#include "../../Renderer/Renderer.hpp"
#include "../../Particle/generator/PathPregeneratedGenerator.hpp"
#include "../../Interface/Scene/Trajectory.hpp"
#include "../Scene.hpp"
namespace pg::scene {
class TrajectoryPregenerated : public Scene {
private:
particle::PathPregeneratedGenerator * _generator;
VertexArray _vao;
VerticeBuffer _vbo;
Program _program;
double _increment;
glm::vec4 _color;
float _pointSize;
float _lineSize;
bool _controlLine;
bool _enableControl;
bool _enableLine;
bool _enableRender;
public:
TrajectoryPregenerated(particle::PathPregeneratedGenerator *, double = 0.1f);
inline particle::PathPregeneratedGenerator * getGenerator() const {return this->_generator;}
inline double getIncrement() const {return this->_increment;}
inline const glm::vec4 & getColor() const {return this->_color;}
inline float getPointSize() const {return this->_pointSize;}
inline bool isConrolLineEnable() const {return this->_controlLine;}
inline bool isRenderingEnable() const {return this->_enableRender;}
void initialize();
void render(const Camera &, double);
void update(double);
void destroy();
friend class interface::Trajectory;
};
}
\ No newline at end of file
......@@ -14,6 +14,7 @@
#include "Scene/Scenes/PhysicSprite.hpp"
#include "Scene/Scenes/MultyPath.hpp"
#include "Scene/Scenes/MeshGeneratorModel.hpp"
#include "Scene/Scenes/PathPregenerated.hpp"
#include "Interface/Manager.hpp"
......@@ -84,6 +85,7 @@ int main(int argc, const char * argv[]) {
pg::scene::Path path(&bezier, ctrlPoints);
pg::scene::MultyPath multyPath(ctrlPoints);
pg::scene::MeshGeneratorModel meshGeneratorModel;
pg::scene::PathPregenerated pathPregenerated(&bezier, ctrlPoints);
pg::Manager manager(window);
pg::interface::Manager imanager(window, manager);
......@@ -94,6 +96,7 @@ int main(int argc, const char * argv[]) {
manager.add(&meshGenerator);
manager.add(&multyPath);
manager.add(&meshGeneratorModel);
manager.add(&pathPregenerated);
while(window.isOpen()) {
double current_time = glfwGetTime();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment