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

Add animated scene

parent 133335a8
No related branches found
No related tags found
No related merge requests found
Showing
with 384 additions and 20 deletions
......@@ -86,3 +86,6 @@ target_link_libraries(${CURRENT_TARGET} PRIVATE assimp::assimp)
find_package(tinyfiledialogs CONFIG REQUIRED)
target_link_libraries(${CURRENT_TARGET} PRIVATE tinyfiledialogs::tinyfiledialogs)
find_package(implot CONFIG REQUIRED)
target_link_libraries(${CURRENT_TARGET} PRIVATE implot::implot)
\ No newline at end of file
......@@ -4,10 +4,5 @@ Size=400,400
[Window][Particle Generator]
Pos=60,60
Size=704,561
[Window][Dear ImGui Demo]
Pos=971,50
Size=550,680
Collapsed=1
Size=848,714
......@@ -7,24 +7,24 @@ in vec2 zTexture;
uniform vec3 uLightPosition;
uniform vec3 uViewPosition;
uniform vec3 uColor;
uniform vec4 uColor;
uniform sampler2D uSlot;
void main() {
float ambientStrength = 0.1;
vec3 ambient = ambientStrength * uColor;
float ambientStrength = 0.25;
vec4 ambient = ambientStrength * uColor;
vec3 norm = normalize(zNormal);
vec3 lightDir = normalize(uLightPosition - zFramPosition);
vec3 diffuse = max(dot(norm, lightDir), 0.0) * uColor;
vec4 diffuse = max(dot(norm, lightDir), 0.0) * uColor;
float specularStrength = 0.5;
float specularStrength = 0.85;
vec3 viewDir = normalize(uViewPosition - zFramPosition);
vec3 reflectDir = reflect(-lightDir, norm);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32);
vec3 specular = specularStrength * spec * uColor;
float spec = pow(max(dot(viewDir, reflectDir), 0.0), 128);
vec4 specular = specularStrength * spec * uColor;
vec3 result = (ambient + diffuse + specular);
FragColor = vec4(result, 1.0) * texture(uSlot, zTexture);
vec4 result = (ambient + diffuse + specular);
FragColor = result * texture(uSlot, zTexture);
}
\ No newline at end of file
ParticleGenerator/res/textures/cyan.png

138 B

ParticleGenerator/res/textures/orange.png

138 B

ParticleGenerator/res/textures/red.png

138 B

......@@ -28,7 +28,7 @@ namespace pg::interface {
if(ImGui::CollapsingHeader("Parameter")) {
ImGui::InputFloat("Parameter Default Value", &this->parent()->m_u, 0.1f, 0.5f);
ImGui::DragFloat("Parameter Increment Value", &this->parent()->m_increment, 0.01f);
ImGui::DragFloat("Parameter Increment Value", &this->parent()->m_increment, 0.01f, 0.0f, 0.0f, "%.5f");
ImGui::DragFloat("Spacing", &this->parent()->m_spacing, 0.001f);
ImGui::InputFloat("Life Limitor", &this->parent()->m_limitor, 1.0f, 2.0f);
}
......
......@@ -6,11 +6,13 @@
#include <imgui.h>
#include <imgui_impl_glfw.h>
#include <imgui_impl_opengl3.h>
#include <implot.h>
namespace pg::interface {
Manager::Manager(const Window & window, pg::Manager & manager)
: _window(window), _manager(manager), _title(window.title()) {
ImGui::CreateContext();
ImPlot::CreateContext();
ImGui::GetIO().IniFilename = "config/imgui.ini";
ImGui_ImplGlfw_InitForOpenGL(window.address(), true);
......@@ -26,6 +28,7 @@ namespace pg::interface {
ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImPlot::DestroyContext();
ImGui::DestroyContext();
}
......@@ -34,8 +37,6 @@ namespace pg::interface {
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
ImGui::ShowDemoWindow();
this->_historical.count(current_time);
if(ImGui::Begin(this->_title.c_str())) {
......
#include "PathAnimated.hpp"
#include <imgui.h>
#include <implot.h>
#include "../../Scene/Scenes/Path.hpp"
#include "../../tfd/tinyfiledialogs.h"
#include "../../Scene/Scenes/PathAnimated.hpp"
namespace pg::interface {
PathAnimated::PathAnimated(scene::PathAnimated * parent, particle::PathGenerator * generator, scene::Trajectory * trajectory)
: Scene(parent), SceneParticle(parent), _interface(generator, trajectory), _next(1.f), _index(0) {
this->_animeCurvePreset = {{0.0, 1.0, 0.0}, {2.0, 1.0, 0.0}, {3.0, -1.0, 0.0}, {0.0, 1.0, 0.0}, {1.0, 1.5, 0.0}};
}
void PathAnimated::draw(double current_time) {
SceneParticle::draw(current_time);
ImGui::SeparatorText("Mesh");
ImGui::Image((void*)(intptr_t)this->parent()->getTexture().identifier(), ImVec2(128, 128), ImVec2(0, 1), ImVec2(1, 0));
if(ImGui::Button("Change Texture", ImVec2(128, 25))) {
char const * imagePatterns[1] = {"*.png"};
std::string path = tinyfd_openFileDialog("Image Browser", "", 1, imagePatterns, "Image File", false);
this->parent()->changeTexture(path);
}
ImGui::SameLine();
if(ImGui::Button("Change Model", ImVec2(128, 25))) {
char const * imagePatterns[1] = {"*.obj"};
std::string path = tinyfd_openFileDialog("Model Browser", "", 1, imagePatterns, "Model File", false);
this->parent()->changeMesh(path);
}
ImGui::SameLine();
ImGui::ColorEdit4("Color", &this->parent()->_color[0]);
ImGui::SeparatorText("Generator");
this->_interface.draw(current_time);
ImGui::SeparatorText("Trajectory");
auto tinterface = this->parent()->_trajectory.interface();
if(tinterface.has_value()) {
(*tinterface)->draw(current_time);
}
ImGui::SeparatorText("Animation Curve");
ImGui::PushID(1);
if(ImGui::CollapsingHeader("Control Points")) {
for(size_t i = 0; i < this->_animeCurvePreset.size(); ++i) {
glm::vec3 current = static_cast<glm::vec3>(this->_animeCurvePreset[i]);
ImGui::Text("%i : %f / %f / %f.", i, current.x, current.y, current.z);
}
ImGui::InputFloat3("", &this->_next[0]);
ImGui::InputInt("Index", &this->_index, 1, 2);
if(this->_index < 0) {
ImGui::TextColored(ImVec4(0.75f, 0.f, 0.f, 1.f), "Negative index !");
}
else {
if(this->_index > this->_animeCurvePreset.size()) {
ImGui::TextColored(ImVec4(1.f, 1.f, 0.f, 1.f), "Index out of range, new point will be at the back !");
}
if(ImGui::Button("Push Point")) {
if(this->_index > this->_animeCurvePreset.size()) {
this->_animeCurvePreset.push_back(static_cast<ct::Point>(this->_next));
}
else {
this->_animeCurvePreset.insert(this->_animeCurvePreset.begin() + this->_index, static_cast<ct::Point>(this->_next));
}
this->parent()->changeAnimeCurve(this->_animeCurvePreset, 0.01, 1.f);
}
ImGui::SameLine();
if(ImGui::Button("Pop Point")) {
if(this->_index > this->_animeCurvePreset.size()) {
this->_animeCurvePreset.pop_back();
}
else {
this->_animeCurvePreset.erase(this->_animeCurvePreset.begin() + this->_index);
}
this->parent()->changeAnimeCurve(this->_animeCurvePreset, 0.01, 1.f);
}
}
}
ImGui::PopID();
}
}
\ No newline at end of file
#pragma once
#include "../Interface.hpp"
#include "SceneParticle.hpp"
#include "../Generator/PathGenerator.hpp"
#include "../../Scene/Scenes/Trajectory.hpp"
#include <glm/vec4.hpp>
namespace pg::scene {
class PathAnimated;
}
namespace pg::interface {
class PathAnimated : public Scene<scene::PathAnimated>, public SceneParticle {
private:
PathGenerator _interface;
ct::Curve _animeCurvePreset;
glm::vec3 _next;
int _index;
public:
PathAnimated(scene::PathAnimated *, particle::PathGenerator *, pg::scene::Trajectory * = nullptr);
virtual ~PathAnimated() = default;
virtual void draw(double);
inline std::string title() const override final {return "Path Scene Interface";}
};
}
\ No newline at end of file
......@@ -198,7 +198,6 @@ namespace pg::scene {
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()));
}
}
}
......
#include "PathAnimated.hpp"
#include "../../Mesh/Model.hpp"
#include <chrono>
#include <glm/gtc/matrix_transform.hpp>
namespace pg::scene {
PathAnimated::PathAnimated(ct::CurveGenerator * generator)
: SceneParticle(1024),
_ubo(0),
_program(),
_texture(),
_generator(generator, {{-10.0, 15.0, -5.0}, {2.5, 20.0, -2.5}, {1.0, -10.0, 0.0}, {-1.0, -10.0, 0.0}, {-2.5, 15.0, 2.5}, {5.0, 10.0, 5.0}}),
_trajectory(&this->_generator, 0.01),
_color(1.f),
_interface(this, &this->_generator, &this->_trajectory) {
}
void PathAnimated::initialize() {
if(!this->_mesh.isGenerated()) {
this->changeMesh("res/models/sphere.obj");
}
this->_trajectory.initialize();
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();
}
//this->changeAnimeCurve({{0.0, 1.0, 0.0}, {2.0, 1.0, 0.0}, {0.25, -1.0, 0.0}, {0.0, 1.5, 0.0}, {1.0, 1.5, 0.0}}, 0.01);
this->changeAnimeCurve({{0.0, 1.0, 0.0}, {2.0, 1.0, 0.0}, {3.0, -1.0, 0.0}, {0.0, 1.0, 0.0}, {1.0, 1.5, 0.0}}, 0.01);
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/cyan.png");
pg::error::OpenGLError::check();
this->_generator.setPosition({0.f, 0.f, 0.f});
this->_generator.setPositionVariation(0.5f);
this->_generator.setParameterIncrement(0.005f);
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 PathAnimated::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 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();
this->_trajectory.render(camera, current_time);
std::vector<glm::mat4> models;
for(size_t i = 0; i < this->_particles.size(); i++) {
particle::Path * particle = dynamic_cast<particle::Path *>(this->_particles.at(i).get());
glm::mat4 model = particle->getModel();
double p = particle->getParameterValue();
size_t animePos = static_cast<size_t>(std::lerp(0.0, this->_animate_Y.size()-1, p));
if(animePos >= this->_animate_Y.size()) {
animePos = this->_animate_Y.size()-1;
}
float scale_y = static_cast<float>(this->_animate_Y.at(animePos).y);
model = glm::scale(model, {1.f, scale_y, 1.f});
models.push_back(model);
}
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);
this->_program.setUniform("uViewPos", camera.getPosition());
this->_program.setUniform("uLightPosition", glm::vec3(0.f, 10.f, 0.f));
pg::error::OpenGLError::check();
this->_texture.bind();
if(this->isRenderEnable()) {
this->_mesh.draw(this->_particles.size());
}
pg::error::OpenGLError::check();
glDisable(GL_DEPTH_TEST);
}
void PathAnimated::destroy() {
glDeleteBuffers(1, &this->_ubo);
this->_particles.clear();
pg::error::OpenGLError::check();
}
void PathAnimated::changeParticletexture(const std::string & path) {
this->_texture.load(path);
}
void PathAnimated::spawn(int count, double current_time) {
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::Path>> 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()));
}
}
void PathAnimated::changeMesh(const std::string & path) {
Model model(path);
MeshGeometry geometry = model.getMeshGeometry();
this->_mesh.generate(geometry.vertices, geometry.indices);
}
void PathAnimated::changeTexture(const std::string & path) {
this->_texture.load(path);
}
void PathAnimated::changeAnimeCurve(const ct::Curve & curve, double precision, double max) {
for(double i = 0; i < max; i+= precision) {
this->_animate_Y.push_back(this->_generator.getGenerator()->generate(curve, i));
}
}
}
\ No newline at end of file
#pragma once
#include "../Scene.hpp"
#include "Trajectory.hpp"
#include "../../Renderer/Renderer.hpp"
#include "../../Particle/generator/PathUniqueGenerator.hpp"
#include "../../Interface/Scene/Path.hpp"
#include "../../Mesh/Mesh.hpp"
#include "../../System/Window.hpp"
#include "../../Interface/Scene/PathAnimated.hpp"
namespace pg::interface {
class PathAnimated;
}
namespace pg::scene {
class PathAnimated : public SceneParticle {
private:
GLuint _ubo;
Program _program;
Mesh _mesh;
Trajectory _trajectory;
Material _texture;
particle::PathUniqueGenerator _generator;
glm::vec4 _color;
ct::Curve _animate_Y;
interface::PathAnimated _interface;
public:
PathAnimated(ct::CurveGenerator *);
virtual ~PathAnimated() = 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::PathUniqueGenerator & getGenerator() const {return this->_generator;}
void changeParticletexture(const std::string &);
virtual std::string name() const {return "Path Animated Scene";}
virtual std::optional<interface::Interface *> interface() {return std::optional<interface::Interface *>(&this->_interface);}
virtual void spawn(int, double);
void changeMesh(const std::string &);
void changeTexture(const std::string &);
void changeAnimeCurve(const ct::Curve &, double, double = 1.0);
friend class pg::interface::PathAnimated;
};
}
\ No newline at end of file
......@@ -15,6 +15,7 @@
#include "Scene/Scenes/MultyPath.hpp"
#include "Scene/Scenes/MeshGeneratorModel.hpp"
#include "Scene/Scenes/PathPregenerated.hpp"
#include "Scene/Scenes/PathAnimated.hpp"
#include "Interface/Manager.hpp"
......@@ -86,6 +87,7 @@ int main(int argc, const char * argv[]) {
pg::scene::MultyPath multyPath(ctrlPoints);
pg::scene::MeshGeneratorModel meshGeneratorModel;
pg::scene::PathPregenerated pathPregenerated(&bezier, ctrlPoints);
pg::scene::PathAnimated pathAnimated(&bezier);
pg::Manager manager(window);
pg::interface::Manager imanager(window, manager);
......@@ -97,6 +99,7 @@ int main(int argc, const char * argv[]) {
manager.add(&multyPath);
manager.add(&meshGeneratorModel);
manager.add(&pathPregenerated);
manager.add(&pathAnimated);
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