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

Final Commit

parent beaa5853
No related branches found
No related tags found
No related merge requests found
Showing
with 1555 additions and 481 deletions
...@@ -10,7 +10,11 @@ namespace ct ...@@ -10,7 +10,11 @@ namespace ct
CurveGenerator* m_generator; CurveGenerator* m_generator;
public: public:
BSplineGenerator(CurveGenerator* generator); BSplineGenerator(CurveGenerator* generator, unsigned int degree);
virtual inline double getParamterMax() const {return this->getDegree() / this->m_generator->getDegree();}
inline CurveGenerator * getGenerator() const {return this->m_generator;}
Point generate(const Curve& points, double u) const override; Point generate(const Curve& points, double u) const override;
std::vector<Point> generate(const Curve& points, const std::vector<double>& us) const override; std::vector<Point> generate(const Curve& points, const std::vector<double>& us) const override;
......
...@@ -7,7 +7,7 @@ namespace ct ...@@ -7,7 +7,7 @@ namespace ct
class CURVETOOLS_API BezierGenerator : public CurveGenerator class CURVETOOLS_API BezierGenerator : public CurveGenerator
{ {
public: public:
BezierGenerator(unsigned int degree = 1); BezierGenerator(unsigned int degree = 4);
Point generate(const Curve& points, double t) const override; Point generate(const Curve& points, double t) const override;
std::vector<Point> generate(const Curve& points, const std::vector<double>& ts) const override; std::vector<Point> generate(const Curve& points, const std::vector<double>& ts) const override;
......
...@@ -15,6 +15,8 @@ namespace ct ...@@ -15,6 +15,8 @@ namespace ct
public: public:
CurveGenerator(uint16_t degree); CurveGenerator(uint16_t degree);
virtual inline double getParamterMax() const {return 1.0;}
static Point lerp(const Point& a, const Point& b, double t); static Point lerp(const Point& a, const Point& b, double t);
static Point smoothstep(const Point& a, const Point& b, double t); static Point smoothstep(const Point& a, const Point& b, double t);
static Point smootherstep(const Point& a, const Point& b, double t); static Point smootherstep(const Point& a, const Point& b, double t);
......
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
#include "StreamedGenerator.cuh" #include "StreamedGenerator.cuh"
#include <iostream>
namespace ct::gpu { namespace ct::gpu {
class SplineGenerator : public Generator<Point, float> { class SplineGenerator : public Generator<Point, float> {
private: private:
...@@ -18,15 +20,17 @@ namespace ct::gpu { ...@@ -18,15 +20,17 @@ namespace ct::gpu {
__host__ SplineGenerator(StreamedGenerator *, size_t = 4, size_t = 8); __host__ SplineGenerator(StreamedGenerator *, size_t = 4, size_t = 8);
inline StreamedGenerator * generator() const {return this->_generator;} inline StreamedGenerator * generator() const {return this->_generator;}
virtual inline float getParamterMax() const {return static_cast<float>(this->getDegree() / this->_generator->getDegree());}
__host__ Point generate(const thrust::universal_vector<Point> &, float) const; __host__ Point generate(const thrust::universal_vector<Point> &, float) const;
__host__ Curve generate(const thrust::universal_vector<Point> &, const std::vector<float> &) const; __host__ Curve generate(const thrust::universal_vector<Point> &, const std::vector<float> &) const;
virtual Point generate(const std::vector<Point> & pts, float u) const override final { inline Point generate(const Curve& points, float p) const override final {
return this->generate(thrust::universal_vector<Point>(pts), u); return this->generate(thrust::universal_vector<Point>(points), p);
} }
virtual std::vector<Point> generate(const std::vector<Point> & pts, const std::vector<float> & us) const override final {
return this->generate(thrust::universal_vector<Point>(pts), us); inline Curve generate(const Curve& points, const std::vector<float> & ps) const override final {
return this->generate(thrust::universal_vector<Point>(points), ps);
} }
}; };
......
...@@ -14,6 +14,8 @@ namespace ct::gpu { ...@@ -14,6 +14,8 @@ namespace ct::gpu {
__host__ virtual Point generate(const thrust::universal_vector<Point> &, const float) const = 0; __host__ virtual Point generate(const thrust::universal_vector<Point> &, const float) const = 0;
__host__ virtual Curve generate(const thrust::universal_vector<Point> &, const std::vector<float> &, const cudaStream_t & = 0) const = 0; __host__ virtual Curve generate(const thrust::universal_vector<Point> &, const std::vector<float> &, const cudaStream_t & = 0) const = 0;
virtual inline float getParamterMax() const {return 1.f;}
inline Point generate(const Curve& points, float p) const override final { inline Point generate(const Curve& points, float p) const override final {
return this->generate(thrust::universal_vector<Point>(points), p); return this->generate(thrust::universal_vector<Point>(points), p);
} }
......
...@@ -13,6 +13,7 @@ namespace ct { ...@@ -13,6 +13,7 @@ namespace ct {
inline Generator(uint16_t degree = 1) : _degree(degree) {} inline Generator(uint16_t degree = 1) : _degree(degree) {}
inline uint16_t getDegree() const {return this->_degree;} inline uint16_t getDegree() const {return this->_degree;}
virtual inline U getParamterMax() const = 0;
virtual T generate(const std::vector<T> &, U) const = 0; virtual T generate(const std::vector<T> &, U) const = 0;
virtual std::vector<T> generate(const std::vector<T> &, const std::vector<U> &) const = 0; virtual std::vector<T> generate(const std::vector<T> &, const std::vector<U> &) const = 0;
......
#include "CurveTools/CPU/BSplineGenerator.hpp" #include "CurveTools/CPU/BSplineGenerator.hpp"
#include "CurveTools/CPU/CurveSampler.hpp" #include "CurveTools/CPU/CurveSampler.hpp"
#include <cmath>
namespace ct namespace ct
{ {
BSplineGenerator::BSplineGenerator(CurveGenerator* generator) BSplineGenerator::BSplineGenerator(CurveGenerator* generator, unsigned int degree)
: CurveGenerator(0), m_generator(generator) {} : CurveGenerator(degree), m_generator(generator) {}
Point BSplineGenerator::generate(const Curve& points, double u) const Point BSplineGenerator::generate(const Curve& points, double u) const
{ {
unsigned int degree = m_generator->getDegree(); unsigned int degree = m_generator->getDegree();
if (points.size() < degree) if (u > this->getParamterMax()) {
{
return Point(0.0); return Point(0.0);
} }
unsigned int nbCurves = static_cast<unsigned int>(std::ceil((points.size() - degree + 1) / static_cast<double>(degree - 1))); unsigned int nbCurves = static_cast<unsigned int>(std::ceil((points.size() - degree + 1) / static_cast<double>(degree - 1)));
u = glm::clamp(u, 0.0, static_cast<double>(nbCurves)); //u = glm::clamp(u, 0.0, static_cast<double>(nbCurves));
u = std::abs(u);
if(nbCurves != 0) {
if(u > nbCurves) {
do {
u -= nbCurves;
}
while(u > nbCurves);
}
}
double k = 0.0; double k = 0.0;
double t = std::modf(u, &k); double t = std::modf(u, &k);
......
...@@ -38,6 +38,8 @@ namespace ct::gpu { ...@@ -38,6 +38,8 @@ namespace ct::gpu {
unsigned int nbBlock = static_cast<unsigned int>(ceil(ts_size/1024)+1); unsigned int nbBlock = static_cast<unsigned int>(ceil(ts_size/1024)+1);
unsigned int nbThread = static_cast<unsigned int>(ts_size - (floor(ts_size/1024) * 1024)); unsigned int nbThread = static_cast<unsigned int>(ts_size - (floor(ts_size/1024) * 1024));
//std::cout << nbBlock << "/" << nbThread << "/" << stream << std::endl;
kernel::Casteljau<<<nbBlock, nbThread, 0, stream>>>(pt_raw, pt_dev.size(), ts_dev, ts_size, r_dev); kernel::Casteljau<<<nbBlock, nbThread, 0, stream>>>(pt_raw, pt_dev.size(), ts_dev, ts_size, r_dev);
cudaMemcpyAsync(&result[0], r_dev, sizeof(Point) * ts_size, cudaMemcpyDeviceToHost, stream); cudaMemcpyAsync(&result[0], r_dev, sizeof(Point) * ts_size, cudaMemcpyDeviceToHost, stream);
......
...@@ -47,9 +47,10 @@ namespace ct::gpu { ...@@ -47,9 +47,10 @@ namespace ct::gpu {
size_t currentPoint = 0; size_t currentPoint = 0;
for(size_t i = 0; i < subCurveCount; i++) { for(size_t i = 0; i < subCurveCount; i++) {
size_t currentStream = i%subCurveCount; size_t currentStream = i%this->_streamsCount;
thrust::universal_vector<Point> subPoints(degree); thrust::universal_vector<Point> subPoints;
subPoints.reserve(degree);
thrust::copy(points.begin()+currentPoint, points.begin()+currentPoint+degree, subPoints.begin()); thrust::copy(points.begin()+currentPoint, points.begin()+currentPoint+degree, subPoints.begin());
std::vector<float> ts; std::vector<float> ts;
...@@ -66,8 +67,10 @@ namespace ct::gpu { ...@@ -66,8 +67,10 @@ namespace ct::gpu {
} }
} }
if(!subPoints.empty() && !ts.empty()) {
Curve subResult = this->_generator->generate(subPoints, ts, streams[currentStream]); Curve subResult = this->_generator->generate(subPoints, ts, streams[currentStream]);
memmove(&result[usCount == 0 ? 0 : usCount-1], subResult.data(), sizeof(Point) * subResult.size()); memmove(&result[usCount == 0 ? 0 : usCount-1], subResult.data(), sizeof(Point) * subResult.size());
}
currentPoint += degree-1; currentPoint += degree-1;
} }
......
...@@ -2,56 +2,508 @@ ...@@ -2,56 +2,508 @@
#include <vector> #include <vector>
#include <chrono> #include <chrono>
#include <fstream>
#include "CurveTools/GPU/BezierGenerator.cuh" #include "CurveTools/GPU/BezierGenerator.cuh" // x
#include "CurveTools/GPU/LinearGenerator.cuh" #include "CurveTools/CPU/BezierGenerator.hpp" // x
#include "CurveTools/GPU/SplineGenerator.cuh"
#include "CurveTools/GPU/CatmullRomGenerator.cuh"
#include "CurveTools/GPU/BezierGenerator.cuh"
#include "CurveTools/CPU/BezierGenerator.hpp" #include "CurveTools/GPU/LinearGenerator.cuh" // x
#include "CurveTools/CPU/LinearGenerator.hpp" #include "CurveTools/CPU/LinearGenerator.hpp" // x
#include "CurveTools/CPU/BSplineGenerator.hpp"
#include "CurveTools/CPU/CatmullRomGenerator.hpp" #include "CurveTools/GPU/SplineGenerator.cuh" // x
#include "CurveTools/CPU/BezierGenerator.hpp" #include "CurveTools/CPU/BSplineGenerator.hpp" // x
#include "CurveTools/GPU/CatmullRomGenerator.cuh" // x
#include "CurveTools/CPU/CatmullRomGenerator.hpp" // x
#include "CurveTools/CPU/HermiteGenerator.hpp"
#include "CurveTools/GPU/HermiteGenerator.cuh"
#include "CurveTools/GPU/SmoothstepGenerator.cuh"
#include "CurveTools/CPU/SmoothstepGenerator.hpp"
#include "CurveTools/GPU/SmootherstepGenerator.cuh"
#include "CurveTools/CPU/SmootherstepGenerator.hpp"
#include "CurveTools/CPU/CurveSampler.hpp" #include "CurveTools/CPU/CurveSampler.hpp"
int main(int argc, const char * argv[]) { int main(int argc, const char * argv[]) {
std::cout << "CPU : " << std::endl; // --- BSpline
/*{
std::cout << "CPU bSpline: " << std::endl;
{ {
using namespace ct; using namespace ct;
BezierGenerator CRG;
BSplineGenerator bs(&CRG, 7);
std::ofstream file;
file.open("bspline_cpu.csv");
Point p1(0.0, 0.0, 0.0);
Point p2(0.25, 1.0, 0.0);
Point p3(0.75, 1.0, 0.0);
Point p4(1.0, 0.0, 0.0);
Point p5(1.0, -0.25, 0.0);
Point p6(1.25, -0.75, 0.0);
Point p7(1.5, -1.0, 0.0);
std::vector<double> parameter = {};
parameter.reserve(20000);
file << "x,y\n";
for(size_t i = 0; i < 20000; i++) {
parameter.push_back(0.00005);
Point p1(-10.0, 0.0, 0.0); std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
Point p2(10.0, 1.0, 1.0); Curve result = bs.generate({p1, p2, p3, p4, p5, p6, p7}, parameter);
BezierGenerator CRG(2); std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
ct::Point result = CRG.operator()({p1, p2}, 0.01); std::cout << "\r" << i;
file << std::chrono::duration_cast<std::chrono::milliseconds>(end - begin).count() << ",";
file << i << "\n";
}
std::cout << result.x << "/" << result.y << "/" << result.z << std::endl; file.close();
} }
std::cout << "GPU : " << std::endl; std::cout << "GPU bspline : " << std::endl;
{ {
using namespace ct::gpu; using namespace ct::gpu;
BezierGenerator CRG;
SplineGenerator Bs(&CRG, 3);
std::ofstream file;
file.open("bspline_gpu.csv");
Point p1(0.0, 0.0, 0.0); Point p1(0.0, 0.0, 0.0);
Point p2(1.0, 1.0, 1.0); Point p2(0.25, 1.0, 0.0);
Point p3(2.0, 2.0, 2.0); Point p3(0.75, 1.0, 0.0);
Point p4(3.0, 3.0, 3.0); Point p4(1.0, 0.0, 0.0);
BezierGenerator CRG; Point p5(1.0, -0.25, 0.0);
Curve curve = CRG({p1, p2, p3, p4}, {0.25f, 0.5f, 0.75f}); Point p6(1.25, -0.75, 0.0);
Point p7(1.5, -1.0, 0.0);
std::vector<float> parameter = {};
parameter.reserve(20000);
file << "x,y\n";
for(size_t i = 0; i < 20000; i++) {
parameter.push_back(0.00005f);
std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
Curve result = Bs.generate(std::vector<Point>({p1, p2, p3, p4, p5, p6, p7}), parameter);
std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
//std::cout << "\r" << i;
std::cout << i << std::endl;
file << std::chrono::duration_cast<std::chrono::milliseconds>(end - begin).count() << ",";
file << i << "\n";
}
file.close();
}
}
// --- CMR
{
std::cout << "CPU Catmullrom : " << std::endl;
{
using namespace ct;
CatmullRomGenerator CRG;
std::ofstream file;
file.open("catmullrom_cpu.csv");
Point p1(0.0, 0.0, 0.0);
Point p2(0.25, 1.0, 0.0);
Point p3(0.75, 1.0, 0.0);
Point p4(1.0, 0.0, 0.0);
Point p5(1.0, -0.25, 0.0);
Point p6(1.25, -0.75, 0.0);
Point p7(1.5, -1.0, 0.0);
std::vector<double> parameter = {};
parameter.reserve(20000);
file << "x,y\n";
for(size_t i = 0; i < 20000; i++) {
parameter.push_back(0.00005);
for(auto & result : curve) { std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
std::cout << result.x << "/" << result.y << "/" << result.z << std::endl; Curve result = CRG.generate({p1, p2, p3, p4}, parameter);
std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
std::cout << "\r" << i;
file << std::chrono::duration_cast<std::chrono::milliseconds>(end - begin).count() << ",";
file << i << "\n";
} }
file.close();
} }
std::cout << "GPU catmullrom : " << std::endl;
{
using namespace ct::gpu;
CatmullRomGenerator CRG;
std::ofstream file;
file.open("catmullrom_gpu.csv");
Point p1(0.0, 0.0, 0.0);
Point p2(0.25, 1.0, 0.0);
Point p3(0.75, 1.0, 0.0);
Point p4(1.0, 0.0, 0.0);
Point p5(1.0, -0.25, 0.0);
Point p6(1.25, -0.75, 0.0);
Point p7(1.5, -1.0, 0.0);
std::vector<float> parameter = {};
parameter.reserve(20000);
file << "x,y\n";
for(size_t i = 0; i < 20000; i++) {
parameter.push_back(0.00005f);
std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
Curve result = CRG.generate(std::vector<Point>({p1, p2}), parameter);
std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
std::cout << "\r" << i;
file << std::chrono::duration_cast<std::chrono::milliseconds>(end - begin).count() << ",";
file << i << "\n";
}
file.close();
}
}
// --- L
{
std::cout << "CPU Linear : " << std::endl;
{
using namespace ct;
LinearGenerator CRG;
std::ofstream file;
file.open("linear_cpu.csv");
Point p1(0.0, 0.0, 0.0);
Point p2(0.25, 1.0, 0.0);
Point p3(0.75, 1.0, 0.0);
Point p4(1.0, 0.0, 0.0);
Point p5(1.0, -0.25, 0.0);
Point p6(1.25, -0.75, 0.0);
Point p7(1.5, -1.0, 0.0);
std::vector<double> parameter = {};
parameter.reserve(20000);
file << "x,y\n";
for(size_t i = 0; i < 20000; i++) {
parameter.push_back(0.00005);
std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
Curve result = CRG.generate({p1, p2}, parameter);
std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
std::cout << "\r" << i;
file << std::chrono::duration_cast<std::chrono::milliseconds>(end - begin).count() << ",";
file << i << "\n";
}
file.close();
}
std::cout << "GPU Linear : " << std::endl;
{
using namespace ct::gpu;
LinearGenerator CRG;
std::ofstream file;
file.open("linear_gpu.csv");
Point p1(0.0, 0.0, 0.0);
Point p2(0.25, 1.0, 0.0);
Point p3(0.75, 1.0, 0.0);
Point p4(1.0, 0.0, 0.0);
Point p5(1.0, -0.25, 0.0);
Point p6(1.25, -0.75, 0.0);
Point p7(1.5, -1.0, 0.0);
std::vector<float> parameter = {};
parameter.reserve(20000);
file << "x,y\n";
for(size_t i = 0; i < 20000; i++) {
parameter.push_back(0.00005f);
std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
Curve result = CRG.generate(std::vector<Point>({p1, p2}), parameter);
std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
std::cout << "\r" << i;
file << std::chrono::duration_cast<std::chrono::milliseconds>(end - begin).count() << ",";
file << i << "\n";
}
file.close();
}
}
// --- H
{
std::cout << "CPU Hermite : " << std::endl;
{
using namespace ct;
HermiteGenerator CRG;
std::ofstream file;
file.open("hermite_cpu.csv");
Point p1(0.0, 0.0, 0.0);
Point p2(0.25, 1.0, 0.0);
Point p3(0.75, 1.0, 0.0);
Point p4(1.0, 0.0, 0.0);
Point p5(1.0, -0.25, 0.0);
Point p6(1.25, -0.75, 0.0);
Point p7(1.5, -1.0, 0.0);
std::vector<double> parameter = {};
parameter.reserve(20000);
file << "x,y\n";
for(size_t i = 0; i < 20000; i++) {
parameter.push_back(0.00005);
std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
Curve result = CRG.generate({p1, p2, p3, p4}, parameter);
std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
std::cout << "\r" << i;
file << std::chrono::duration_cast<std::chrono::milliseconds>(end - begin).count() << ",";
file << i << "\n";
}
file.close();
}
std::cout << "GPU Hermite : " << std::endl;
{
using namespace ct::gpu;
HermiteGenerator CRG;
std::ofstream file;
file.open("hermite_gpu.csv");
Point p1(0.0, 0.0, 0.0);
Point p2(0.25, 1.0, 0.0);
Point p3(0.75, 1.0, 0.0);
Point p4(1.0, 0.0, 0.0);
Point p5(1.0, -0.25, 0.0);
Point p6(1.25, -0.75, 0.0);
Point p7(1.5, -1.0, 0.0);
std::vector<float> parameter = {};
parameter.reserve(20000);
file << "x,y\n";
for(size_t i = 0; i < 20000; i++) {
parameter.push_back(0.00005f);
std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
Curve result = CRG.generate(std::vector<Point>({p1, p2, p3, p4}), parameter);
std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
std::cout << "\r" << i;
file << std::chrono::duration_cast<std::chrono::milliseconds>(end - begin).count() << ",";
file << i << "\n";
}
file.close();
}
}
// --- S
{
std::cout << "CPU Smoothstep : " << std::endl;
{
using namespace ct;
SmoothstepGenerator CRG;
std::ofstream file;
file.open("smoothstep_cpu.csv");
Point p1(0.0, 0.0, 0.0);
Point p2(0.25, 1.0, 0.0);
Point p3(0.75, 1.0, 0.0);
Point p4(1.0, 0.0, 0.0);
Point p5(1.0, -0.25, 0.0);
Point p6(1.25, -0.75, 0.0);
Point p7(1.5, -1.0, 0.0);
std::vector<double> parameter = {};
parameter.reserve(20000);
file << "x,y\n";
for(size_t i = 0; i < 20000; i++) {
parameter.push_back(0.00005);
std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
Curve result = CRG.generate({p1, p2}, parameter);
std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
std::cout << "\r" << i;
file << std::chrono::duration_cast<std::chrono::milliseconds>(end - begin).count() << ",";
file << i << "\n";
}
file.close();
}
std::cout << "GPU Smoothstep : " << std::endl;
{
using namespace ct::gpu;
SmoothstepGenerator CRG;
std::ofstream file;
file.open("smoothstep_gpu.csv");
Point p1(0.0, 0.0, 0.0);
Point p2(0.25, 1.0, 0.0);
Point p3(0.75, 1.0, 0.0);
Point p4(1.0, 0.0, 0.0);
Point p5(1.0, -0.25, 0.0);
Point p6(1.25, -0.75, 0.0);
Point p7(1.5, -1.0, 0.0);
std::vector<float> parameter = {};
parameter.reserve(20000);
file << "x,y\n";
for(size_t i = 0; i < 20000; i++) {
parameter.push_back(0.00005f);
std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
Curve result = CRG.generate(std::vector<Point>({p1, p2}), parameter);
std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
std::cout << "\r" << i;
file << std::chrono::duration_cast<std::chrono::milliseconds>(end - begin).count() << ",";
file << i << "\n";
}
file.close();
}
}
// --- Ser
{
std::cout << "CPU Smootherstep : " << std::endl;
{
using namespace ct;
SmootherstepGenerator CRG;
std::ofstream file;
file.open("smootherstep_cpu.csv");
Point p1(0.0, 0.0, 0.0);
Point p2(0.25, 1.0, 0.0);
Point p3(0.75, 1.0, 0.0);
Point p4(1.0, 0.0, 0.0);
Point p5(1.0, -0.25, 0.0);
Point p6(1.25, -0.75, 0.0);
Point p7(1.5, -1.0, 0.0);
std::vector<double> parameter = {};
parameter.reserve(20000);
file << "x,y\n";
for(size_t i = 0; i < 20000; i++) {
parameter.push_back(0.00005);
std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
Curve result = CRG.generate({p1, p2}, parameter);
std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
std::cout << "\r" << i;
file << std::chrono::duration_cast<std::chrono::milliseconds>(end - begin).count() << ",";
file << i << "\n";
}
file.close();
}
std::cout << "GPU Smoother : " << std::endl;
{
using namespace ct::gpu;
SmootherstepGenerator CRG;
std::ofstream file;
file.open("smootherstep_gpu.csv");
Point p1(0.0, 0.0, 0.0);
Point p2(0.25, 1.0, 0.0);
Point p3(0.75, 1.0, 0.0);
Point p4(1.0, 0.0, 0.0);
Point p5(1.0, -0.25, 0.0);
Point p6(1.25, -0.75, 0.0);
Point p7(1.5, -1.0, 0.0);
std::vector<float> parameter = {};
parameter.reserve(20000);
file << "x,y\n";
for(size_t i = 0; i < 20000; i++) {
parameter.push_back(0.00005f);
std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
Curve result = CRG.generate(std::vector<Point>({p1, p2}), parameter);
std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
std::cout << "\r" << i;
file << std::chrono::duration_cast<std::chrono::milliseconds>(end - begin).count() << ",";
file << i << "\n";
}
file.close();
}
}*/
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
\ No newline at end of file
#include "Mesh.hpp"
#include <glm/gtc/matrix_transform.hpp>
namespace pg::scene
{
Mesh::Mesh(ct::CurveGenerator * generator, const ct::Curve & ctrlpoint)
: _mesh(),
_material(),
_textureShader(),
_colorShader(),
_color(1.f, 1.f, 1.f, 1.f),
_rotation(0.f, 0.f, 0.f),
_scale(1.f, 1.f, 1.f),
_pathGenerator(generator, ctrlpoint),
_physicGenerator(),
_skybox("res/shaders/system/Skybox.vert", "res/shaders/system/Skybox.frag"),
_interface(this, &this->_pathGenerator, &this->_physicGenerator),
_useTexture(false),
_pathActive(false),
_physicActive(true),
_wireframe(false) {
}
void Mesh::initialize()
{
if (!this->_mesh.isGenerated()) {
Model gridModel("res/models/cube.obj");
this->_mesh.generate(gridModel.getMeshGeometry().vertices, gridModel.getMeshGeometry().indices);
}
if(!this->_textureShader.usable()) {
Source vertexShaderSource("res/shaders/scene/Phong-Fat.vert", Source::Categorie::VERTEX);
Source fragmentShaderSource("res/shaders/scene/Phong.frag", Source::Categorie::FRAGMENT);
this->_textureShader << vertexShaderSource;
this->_textureShader << fragmentShaderSource;
this->_textureShader.link();
vertexShaderSource.release();
fragmentShaderSource.release();
}
if(!this->_colorShader.usable()) {
Source vertexShaderSource("res/shaders/scene/Color-Fat.vert", Source::Categorie::VERTEX);
Source fragmentShaderSource("res/shaders/scene/Color.frag", Source::Categorie::FRAGMENT);
this->_colorShader << vertexShaderSource;
this->_colorShader << fragmentShaderSource;
this->_colorShader.link();
vertexShaderSource.release();
fragmentShaderSource.release();
}
if(this->_skybox.material().isValid()) {
this->_skybox.load(
{
"res/textures/skybox/snow/right.png",
"res/textures/skybox/snow/left.png",
"res/textures/skybox/snow/top.png",
"res/textures/skybox/snow/bottom.png",
"res/textures/skybox/snow/front.png",
"res/textures/skybox/snow/back.png",
},
Texture::RGBA,
false
);
}
{
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->_colorShader.id(), "uModels_t");
glBindBufferBase(GL_UNIFORM_BUFFER, uniforme_index, this->_ubo);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
}
pg::error::OpenGLError::check();
this->_pathGenerator.setPosition({0.f, 0.f, 0.f});
this->_pathGenerator.setPositionVariation(0.5f);
this->_pathGenerator.setParameterIncrement(0.01f);
this->_pathGenerator.setParameterLifeLimitor(1.0f);
this->_physicGenerator.setPosition({0.f, 0.f, 0.f});
this->_physicGenerator.setPositionVariation(0.5);
this->_physicGenerator.setVelocity({0, 0.01, 0});
this->_physicGenerator.setAcceleration({0.0, 0.0001, 0});
}
void Mesh::update(double current_time) {
static auto path_start = std::chrono::high_resolution_clock::now();
static auto physic_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), this->_interface.getLifeTime());
if(duration_cast<std::chrono::milliseconds>(end - path_start).count() >= this->_interface.getPathSpawnFrequence()) {
path_start = std::chrono::high_resolution_clock::now();
if((this->_interface.getPathSpawnCount() + this->_particles.size()) <= this->_interface.getMaxParticle() && this->_pathActive) {
std::vector<std::unique_ptr<pg::Particle>> newParticles = this->_pathGenerator.generate(this->_interface.getPathSpawnCount(), 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(duration_cast<std::chrono::milliseconds>(end - physic_start).count() >= this->_interface.getPhysicSpawnFrequence()) {
physic_start = std::chrono::high_resolution_clock::now();
if(this->_interface.getPhysicSpawnCount() + this->_particles.size() <= this->_interface.getMaxParticle() && this->_physicActive) {
std::vector<std::unique_ptr<pg::Particle>> newParticles = this->_physicGenerator.generate(this->_interface.getPhysicSpawnCount(), 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(duration_cast<std::chrono::milliseconds>(end - path_start).count() >= 10 || duration_cast<std::chrono::milliseconds>(end - physic_start).count() >= 10) {
for(auto& particle : this->_particles) {
particle->update(0.0);
}
}
}
void Mesh::render(const Camera& camera, double) {
this->_skybox.material().bind(0);
this->_skybox.draw(camera);
glEnable(GL_DEPTH_TEST);
this->_material.bind(0);
Program * program = this->_useTexture ? &this->_textureShader : &this->_colorShader;
pg::error::OpenGLError::check();
std::vector<glm::mat4> models;
for(auto & particle : this->_particles) {
glm::mat4 model = glm::mat4(1.0);
model = glm::translate(model, glm::vec3(particle->getPosition()));
model = glm::rotate(model, glm::radians(this->_rotation.z), {0.f, 0.f, 1.f});
model = glm::rotate(model, glm::radians(this->_rotation.y), {0.f, 1.f, 0.f});
model = glm::rotate(model, glm::radians(this->_rotation.x), {1.f, 0.f, 0.f});
model = glm::scale(model, this->_scale);
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();
program->use();
program->setUniform("uView", camera.getViewMatrix());
program->setUniform("uProj", camera.getViewFrustum().getProjectionMatrix());
if(this->_useTexture) {
program->setUniform("uSlot", 0);
program->setUniform("uLightPosition", glm::vec3(0.f , 10.f, 0.f));
program->setUniform("uViewPosition", camera.getPosition());
program->setUniform("uColor", glm::vec3(this->_color));
}
else {
program->setUniform("uColor", this->_color);
}
if(this->_wireframe) {
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
}
if(this->_interface.isRenderEnable()) {
this->_mesh.draw(this->_particles.size());
}
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glDisable(GL_DEPTH_TEST);
}
void Mesh::destroy() {
glDeleteBuffers(1, &this->_ubo);
}
std::string Mesh::name() const {
return "Mesh Scene";
}
void Mesh::setMesh(const std::string & path) {
Model gridModel(path);
this->_mesh.generate(gridModel.getMeshGeometry().vertices, gridModel.getMeshGeometry().indices);
}
void Mesh::setTexture(const std::string & path) {
this->_material.load(path);
}
void Mesh::setTextureUse(bool state) {
this->_useTexture = state;
glDeleteBuffers(1, &this->_ubo);
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->_useTexture ? this->_textureShader.id() : this->_colorShader.id(), "uModels_t");
glBindBufferBase(GL_UNIFORM_BUFFER, uniforme_index, this->_ubo);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
}
}
\ No newline at end of file
#pragma once
#include "Scene.hpp"
#include "../../Renderer/Renderer.hpp"
#include "../../Mesh/Model.hpp"
#include "../../Mesh/Mesh.hpp"
#include "../../Renderer/Texture/Material.hpp"
#include "../../Particle/generator/PathParticleGenerator.hpp"
#include "../../Particle/generator/PhysicsParticleGenerator.hpp"
#include "../../Interface/Scene/MeshScene.hpp"
#include "../../Mesh/Skybox.hpp"
namespace pg::scene
{
class Mesh : public Scene {
private:
pg::Mesh _mesh;
Material _material;
Program _textureShader;
Program _colorShader;
glm::vec4 _color;
glm::vec3 _rotation;
glm::vec3 _scale;
PathParticleGenerator _pathGenerator;
PhysicsParticleGenerator _physicGenerator;
std::vector<std::unique_ptr<Particle>> _particles;
SkyBox _skybox;
interface::MeshScene _interface;
GLuint _ubo;
bool _useTexture;
bool _pathActive;
bool _physicActive;
bool _wireframe;
public:
Mesh(ct::CurveGenerator *, const ct::Curve &);
virtual ~Mesh() = default;
void initialize() override;
void update(double) override;
void render(const Camera&, double) override;
void destroy() override;
std::string name() const override;
virtual std::optional<interface::Interface *> interface() {return std::optional<interface::Interface *>(&this->_interface);}
void setMesh(const std::string &);
void setTexture(const std::string &);
void setTextureUse(bool);
friend class pg::interface::MeshScene;
};
}
\ No newline at end of file
#include "MeshScene.hpp"
#include <imgui.h>
#include "../../Scene/Scenes/Mesh.hpp"
#include "../../tfd/tinyfiledialogs.h"
namespace pg::interface {
MeshScene::MeshScene(scene::Mesh * scene, PathParticleGenerator * path, PhysicsParticleGenerator * physic)
: _scene(scene),
_current(nullptr),
_pathGenerator(path),
_physicGenerator(physic),
_max(1024),
_pathSpawnFrequence(500),
_pathSpawnCount(1),
_physicSpawnFrequence(500),
_physicSpawnCount(5),
_lifetime(5),
_enableRender(true) {
}
void MeshScene::render(double current_time) {
ImGui::Text("Particles Number : %i / %i.", this->_scene->_particles.size(), this->_max);
ImGui::SameLine();
if(ImGui::Button("Clear")) {
this->_scene->_particles.clear();
}
ImGui::Checkbox("Enable Rendering", &this->_enableRender);
ImGui::InputInt("Lifetime (s)", &this->_lifetime, 1, 2);
ImGui::SeparatorText("Model");
ImGui::SliderFloat3("Roation", &this->_scene->_rotation[0], 0.f, 359.f);
ImGui::DragFloat3("Scaling", &this->_scene->_scale[0], 0.01f, 0.1f, 0.0f);
ImGui::ColorEdit4("Global Color", &this->_scene->_color[0]);
ImGui::Image((void*)(intptr_t)this->_scene->_material.identifier(), ImVec2(64, 64), ImVec2(0, 1), ImVec2(1, 0));
ImGui::Text("Texture Path : %s", this->_scene->_material.ressource().string().c_str());
ImGui::PushID(0);
if(ImGui::Button(this->_scene->_useTexture ? "No Texture" : "Texture")) {
this->_scene->setTextureUse(!this->_scene->_useTexture);
}
ImGui::SameLine();
ImGui::PushID(1);
if(ImGui::Button("Change Texture")) {
char const * imagePatterns[1] = {"*.png"};
std::string path = tinyfd_openFileDialog("Image Browser", "", 1, imagePatterns, "Image File", false);
this->_scene->setTexture(path);
}
ImGui::SameLine();
ImGui::PushID(2);
if(ImGui::Button("Change Model")) {
char const * imagePatterns[1] = {"*.obj"};
std::string path = tinyfd_openFileDialog("Model Browser", "", 1, imagePatterns, "Model File", false);
this->_scene->setMesh(path);
}
ImGui::SameLine();
ImGui::Checkbox("Wireframe", &this->_scene->_wireframe);
ImGui::PopID();
ImGui::PopID();
ImGui::PopID();
ImGui::PushID(0);
ImGui::SeparatorText("Physic Generator");
ImGui::Checkbox("Enable Spawning", &this->_scene->_physicActive);
ImGui::SliderInt("Spawning Number", &this->_physicSpawnCount, 1, 1024);
ImGui::InputInt("Spawn Frequence (ms)", &this->_physicSpawnFrequence, 25, 100);
if(ImGui::Button("Spawn")) {
std::vector<std::unique_ptr<pg::Particle>> newParticles = this->_scene->_physicGenerator.generate(1, static_cast<size_t>(current_time));
this->_scene->_particles.insert(this->_scene->_particles.begin(), std::make_move_iterator(newParticles.begin()), std::make_move_iterator(newParticles.end()));
}
ImGui::PushID(1);
ImGui::SeparatorText("Path Generator");
ImGui::Checkbox("Enable Spawning", &this->_scene->_pathActive);
ImGui::SliderInt("Spawning Number", &this->_pathSpawnCount, 1, 1024);
ImGui::InputInt("Spawn Frequence (ms)", &this->_pathSpawnFrequence, 25, 100);
if(ImGui::Button("Spawn")) {
std::vector<std::unique_ptr<pg::Particle>> newParticles = this->_scene->_pathGenerator.generate(1, static_cast<size_t>(current_time));
this->_scene->_particles.insert(this->_scene->_particles.begin(), std::make_move_iterator(newParticles.begin()), std::make_move_iterator(newParticles.end()));
}
ImGui::PopID();
ImGui::PopID();
ImGui::SeparatorText("Generators Settings");
if(ImGui::CollapsingHeader("Physic Generator")) {
this->_physicGenerator.render(current_time);
}
ImGui::Separator();
ImGui::Separator();
if(ImGui::CollapsingHeader("Path Generator")) {
this->_pathGenerator.render(current_time);
}
}
}
\ No newline at end of file
#pragma once
#include "../Interface.hpp"
#include "../Generator/PathGenerator.hpp"
#include "../Generator/PhysicGenerator.hpp"
#include <glm/vec4.hpp>
namespace pg::scene {
class Mesh;
}
namespace pg::interface {
class MeshScene : public {
private:
scene::Mesh * _scene;
Interface * _current;
PathGenerator _pathGenerator;
PhysicGenerator _physicGenerator;
int _max;
int _pathSpawnFrequence;
int _pathSpawnCount;
int _physicSpawnFrequence;
int _physicSpawnCount;
int _lifetime;
bool _enableRender;
public:
MeshScene(scene::Mesh *, PathParticleGenerator *, PhysicsParticleGenerator *);
inline int getMaxParticle() const {return this->_max;}
inline int getPathSpawnFrequence() const {return this->_pathSpawnFrequence;}
inline int getPathSpawnCount() const {return this->_pathSpawnCount;}
inline int getLifeTime() const {return this->_lifetime;}
inline int getPhysicSpawnFrequence() const {return this->_physicSpawnFrequence;}
inline int getPhysicSpawnCount() const {return this->_physicSpawnCount;}
inline bool isRenderEnable() {return this->_enableRender;}
virtual void render(double);
inline std::string title() const {return "Mesh Scene Interface";}
};
}
\ No newline at end of file
...@@ -4,5 +4,5 @@ Size=400,400 ...@@ -4,5 +4,5 @@ Size=400,400
[Window][Particle Generator] [Window][Particle Generator]
Pos=60,60 Pos=60,60
Size=576,611 Size=557,755
newmtl mat1
Ns 10
Ni 1.0
d 1.0
Tf 1 1 1
illum 2
Ka 0.5 0.5 0.5
Kd 0.9 0.9 0.9
Ks 0.0 0.0 0.0
map_Kd ItmApple2.PNG
newmtl mat2
Ns 10
Ni 1.0
d 1.0
Tf 1 1 1
illum 2
Ka 0.5 0.5 0.5
Kd 0.9 0.9 0.9
Ks 0.0 0.0 0.0
map_Kd .PNG
This diff is collapsed.
ParticleGenerator/res/models/apples/ItmApple2.png

2.91 KiB

# Blender 4.1.1 MTL File: 'None'
# www.blender.org
ParticleGenerator/res/textures/color/black.png

133 B

0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment