198 lines
5.1 KiB
C++
198 lines
5.1 KiB
C++
#include "noise.h"
|
|
#include <iostream>
|
|
#include <glm/ext.hpp>
|
|
|
|
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] = process2DIndex(x0,z0);
|
|
idx[1] = process2DIndex(x1,z0);
|
|
idx[2] = process2DIndex(x0,z1);
|
|
idx[3] = process2DIndex(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;
|
|
}
|
|
|
|
// NOT IMPLEMENTED
|
|
float Noise::SimplexNoise(float x, float y, float z){
|
|
// int x0, x1, y0, y1, z0, z1;
|
|
return 1.f;
|
|
}
|
|
|
|
int Noise::process2DIndex(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};
|