diff --git a/src/tools/loader.cpp b/src/tools/loader.cpp new file mode 100644 index 0000000..102bf4e --- /dev/null +++ b/src/tools/loader.cpp @@ -0,0 +1,41 @@ +#include "loader.h" +#include +#include +#include +#include + +std::string* Loader::loadTextFile(const std::string &filename) +{ + std::ifstream t(filename); + std::string *str = new std::string(); + + t.seekg(0, std::ios::end); + str->reserve(t.tellg()); + t.seekg(0, std::ios::beg); + + str->assign((std::istreambuf_iterator(t)), + std::istreambuf_iterator()); + return str; +} + +Image* Loader::loadImage(const std::string &filename, bool hasAlpha) +{ + sf::Image sfImg; + sfImg.loadFromFile(filename); + Image* img = new Image(); + img->depth = hasAlpha ? 32 : 24; + img->width = sfImg.getSize().x; + img->height = sfImg.getSize().y; + int size = img->width*img->height*(img->depth/8); + img->allocate(size); + const sf::Uint8 *pixels = sfImg.getPixelsPtr(); + if(hasAlpha) + memcpy(img->pixels, pixels, size); + else + { + sf::Uint8 *ptr = (sf::Uint8*)img->pixels; + for(int i=0; iwidth*img->height; ++i) + memcpy(ptr + i*3, pixels + i*4, 3); + } + return img; +} diff --git a/src/tools/loader.h b/src/tools/loader.h new file mode 100644 index 0000000..3afef05 --- /dev/null +++ b/src/tools/loader.h @@ -0,0 +1,15 @@ +#ifndef LOADER_H +#define LOADER_H + +#include + +class Image; + +class Loader +{ +public: + static std::string* loadTextFile(const std::string &filename); + static Image* loadImage(const std::string &filename, bool hasAlpha = true); +}; + +#endif // LOADER_H diff --git a/src/tools/noise.cpp b/src/tools/noise.cpp new file mode 100644 index 0000000..77ea584 --- /dev/null +++ b/src/tools/noise.cpp @@ -0,0 +1,197 @@ +#include "noise.h" +#include +#include + +Noise::Noise() +{ + +} + +Noise::~Noise() +{ + +} + +void Noise::initPerlinNoise(int seed) +{ + int i,j,k; + srand(seed); + //INFO: permutation array + for (i = 0 ; i < ARBITRARY_VALUE ; i++) permut[i] = i; + for (i = ARBITRARY_VALUE ; i > 0 ; i -= 2) + { + k = permut[i]; + permut[i] = permut[j = std::rand() % ARBITRARY_VALUE]; + permut[j] = k; + }; +} + +float Noise::PerlinNoise2D(float x, float z) +{ + int x0,x1,z0,z1; + x0 = fastfloor(x); + x1 = x0 + 1; + z0 = fastfloor(z); + z1 = z0 + 1; + + float dx,dz; + dx = x - x0; + dz = z - z0; + + glm::vec2 grad[4]; + int idx[4]; + + idx[0] = calculIdx2D(x0,z0); + idx[1] = calculIdx2D(x1,z0); + idx[2] = calculIdx2D(x0,z1); + idx[3] = calculIdx2D(x1,z1); + + for(int i=0; i < 4; i++) + grad[i] = gradient2[idx[i]]; + + glm::vec2 vect[4]; + vect[0] = glm::vec2(dx+1, dz+1); + vect[1] = glm::vec2(dx-1, dz+1); + vect[2] = glm::vec2(dx+1, dz-1); + vect[3] = glm::vec2(dx-1, dz-1); + + float val[4]; + for(int i=0; i < 4; i++) + val[i] = glm::dot(grad[i], vect[i]); + + float sx, sz; + sx = (3.f * dx * dx) - (2.f * dx * dx * dx); + sz = (3.f * dz * dz) - (2.f * dz * dz * dz); + + // interpolation on axis x + float u[2]; + for (int i = 0;i <2; i++) + u[i]= lerp(val[i*2],val[(i*2)+1], sx); + + // interpolation on axis z + return lerp(u[0],u[1],sz); +} + + +float Noise::PerlinNoise3D(float x, float y, float z) +{ + int x0, x1, y0, y1, z0, z1; + + x0 = fastfloor(x); + x1 = x0 + 1; + + y0 = fastfloor(y); + y1 = y0 + 1; + + z0 = fastfloor(z); + z1 = z0 + 1; + + float dx,dy,dz; + dx = x - x0; + dy = y - y0; + dz = z - z0; + + glm::vec3 grad[8]; + grad[0] = gradient3[(permut[(permut[x0%ARBITRARY_VALUE] + y0)%ARBITRARY_VALUE] + z0)]; + grad[1] = gradient3[(permut[(permut[x1%ARBITRARY_VALUE] + y0)%ARBITRARY_VALUE] + z0)]; + grad[2] = gradient3[(permut[(permut[x0%ARBITRARY_VALUE] + y1)%ARBITRARY_VALUE] + z0)]; + grad[3] = gradient3[(permut[(permut[x1%ARBITRARY_VALUE] + y1)%ARBITRARY_VALUE] + z0)]; + grad[4] = gradient3[(permut[(permut[x0%ARBITRARY_VALUE] + y0)%ARBITRARY_VALUE] + z1)]; + grad[5] = gradient3[(permut[(permut[x1%ARBITRARY_VALUE] + y0)%ARBITRARY_VALUE] + z1)]; + grad[6] = gradient3[(permut[(permut[x0%ARBITRARY_VALUE] + y1)%ARBITRARY_VALUE] + z1)]; + grad[7] = gradient3[(permut[(permut[x1%ARBITRARY_VALUE] + y1)%ARBITRARY_VALUE] + z1)]; + + glm::vec3 vect[8]; + vect[0] = glm::vec3(dx, dy, dz); + vect[1] = glm::vec3(dx-1, dy, dz); + vect[2] = glm::vec3(dx, dy-1, dz); + vect[3] = glm::vec3(dx-1, dy-1, dz); + vect[4] = glm::vec3(dx, dy, dz-1); + vect[5] = glm::vec3(dx-1, dy, dz-1); + vect[6] = glm::vec3(dx, dy-1, dz-1); + vect[7] = glm::vec3(dx-1, dy-1, dz-1); + + float val[8]; + for(int i=0; i < 8; i++) + val[i] = glm::dot(grad[i], vect[i]); + + // process weight for interpolation + float sx, sy, sz; + sx = (3.f * dx * dx) - (2.f * dx * dx * dx); + sy = (3.f * dy * dy) - (2.f * dy * dy * dy); + sz = (3.f * dz * dz) - (2.f * dz * dz * dz); + + // interpolation on axis x + float u[4]; + for (int i = 0;i <4; i++){ + u[i]= lerp(val[i*2],val[(i*2)+1], sx); + } + + // interpolation on axis y + float v[2]; + for (int i = 0;i <2; i++) + v[i]= lerp(u[i*2],u[(i*2)+1],sy); + + // interpolation on axis z + return lerp(v[0],v[1],sz); +} + +//shitty function +float Noise::OctavePerlinNoise(float nb_octave, float persistence, float x, float y, float z) +{ + float total = 0; + float frequency = 1; + float amplitude = 100; + + float maxAmplitude = 0; + + for(int i=0; i < nb_octave; i++){ + total += PerlinNoise3D(x/frequency, y/frequency, z/frequency)*amplitude; + + frequency *= 2; + maxAmplitude += amplitude; + amplitude *= persistence; + } + + return total/maxAmplitude; +} + +float Noise::SimplexNoise(float x, float y, float z){ + int x0, x1, y0, y1, z0, z1; + + return 1.f; +} + +int Noise::calculIdx2D(int x, int z) +{ + int u = x%ARBITRARY_VALUE; + u = u < 0 ? u + ARBITRARY_VALUE : u; + int v = (permut[u] + z) % ARBITRARY_VALUE; + v = v < 0 ? v + ARBITRARY_VALUE : v; + return permut[v]; +} + +int Noise::fastfloor(float v) +{ + int res = (int) v; + return res > v ? res -1 : res; +} + +//linear interpolation +float Noise::lerp(float a, float b, float w){ + return (1-w)*a + w*b; +} + +glm::vec2 Noise::gradient2[] = { + glm::vec2(1,0), glm::vec2(-1,0), glm::vec2(0,1), glm::vec2(0,-1), + glm::vec2(1,1), glm::vec2(-1,1), glm::vec2(1,-1), glm::vec2(-1,-1), + glm::vec2(0,1), glm::vec2(0,-1), glm::vec2(1,0), glm::vec2(-1,0) +}; + +glm::vec3 Noise::gradient3[] = { +// irr::core::vector3df(1,1,0), irr::core::vector3df(-1,1,0), irr::core::vector3df(1,-1,0), irr::core::vector3df(-1,-1,0), +// irr::core::vector3df(1,0,1), irr::core::vector3df(-1,0,1), irr::core::vector3df(1,0,-1), irr::core::vector3df(-1,0,-1), +// irr::core::vector3df(0,1,1), irr::core::vector3df(0,-1,1), irr::core::vector3df(0,1,-1), irr::core::vector3df(0,-1,-1) +}; + +int Noise::permut[] = {0}; diff --git a/src/tools/noise.h b/src/tools/noise.h new file mode 100644 index 0000000..90e64c8 --- /dev/null +++ b/src/tools/noise.h @@ -0,0 +1,30 @@ +#ifndef NOISE_H +#define NOISE_H + +#include +#include + +#define ARBITRARY_VALUE 12 // TODO : find an appropriate name + +class Noise +{ +private: + static glm::vec2 gradient2[ARBITRARY_VALUE]; + static glm::vec3 gradient3[ARBITRARY_VALUE]; + static int permut[ARBITRARY_VALUE]; + //private function + static int calculIdx2D(int x, int z); // TODO : remove french namings + static int fastfloor(float v); + static float lerp(float a, float b, float w); + +public: + Noise(); + ~Noise(); + static void initPerlinNoise(int seed); + static float PerlinNoise2D(float x, float z); + static float PerlinNoise3D(float x, float y, float z); + static float OctavePerlinNoise(float nb_octave, float persistence, float x, float y, float z); + static float SimplexNoise(float x, float y, float z); +}; + +#endif // NOISE_H