[Change] Hardcoded everything to have three dimensions. [perlin noise.]
This commit is contained in:
parent
02e8b560fa
commit
5ed5cf6b6d
244
src/perlin.c
244
src/perlin.c
@ -2,10 +2,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __SSE__
|
||||
#include <xmmintrin.h>
|
||||
#endif /* __SSE__ */
|
||||
|
||||
#include "lephisto.h"
|
||||
#include "log.h"
|
||||
#include "rng.h"
|
||||
@ -16,7 +12,6 @@
|
||||
#define NEBULAE_Z 32
|
||||
|
||||
#define NOISE_MAX_OCTAVES 128
|
||||
#define NOISE_MAX_DIMENSIONS 4
|
||||
#define NOISE_DEFAULT_HURST 0.5
|
||||
#define NOISE_DEFAULT_LACUNARITY 2.
|
||||
|
||||
@ -27,71 +22,40 @@ typedef void* noise_t;
|
||||
|
||||
/* Used internally. */
|
||||
typedef struct {
|
||||
int ndim;
|
||||
unsigned char map[256]; /* Randomized map of indexes into buffer. */
|
||||
float buffer[256][NOISE_MAX_DIMENSIONS]; // Random 256 x ndim buffer. */
|
||||
unsigned char map[256]; /* Randomized map of indexes into buffer. */
|
||||
float buffer[256][3]; /* Random 256x3 buffer. */
|
||||
/* Fractal stuff. */
|
||||
float H;
|
||||
float lacunarity;
|
||||
float exponent[NOISE_MAX_OCTAVES];
|
||||
} perling_data_t;
|
||||
} perlin_data_t;
|
||||
|
||||
static float* genNebulaeMap(const int w, const int h, const int n, float rug);
|
||||
SDL_Surface* surfaceFromNebulaeMap(float* map, const int w, const int h);
|
||||
static noise_t noise_new(int dimensions, float hurst, float lacunarity);
|
||||
static noise_t noise_new(float hurst, float lacunarity);
|
||||
/* Basic perlin noise. */
|
||||
static float noise_get(noise_t noise, float* f);
|
||||
/* Fractional brownian motion. */
|
||||
/*static float noise_fbm(noise_t noise, float* f, float octaves);*/
|
||||
/* Turbulence. */
|
||||
static float noise_turbulence(noise_t noise, float* f, float octaves);
|
||||
static void noise_delete(noise_t noise);
|
||||
|
||||
static float lattice(perling_data_t* pdata, int ix, float fx, int iy,
|
||||
float fy, int iz, float fz, int iw, float fw) {
|
||||
#ifdef __SSE__
|
||||
(void)iw;
|
||||
(void)fw;
|
||||
static float lattice(perlin_data_t* pdata, int ix, float fx, int iy,
|
||||
float fy, int iz, float fz) {
|
||||
|
||||
int nindex;
|
||||
__m128 a, b, c;
|
||||
float value;
|
||||
|
||||
nindex = 0;
|
||||
nindex = pdata->map[(nindex + ix) & 0xFF];
|
||||
nindex = pdata->map[(nindex + iy) & 0xFF];
|
||||
nindex = pdata->map[(nindex + iz) & 0xFF];
|
||||
|
||||
float inp_sse1[4] __attribute__((aligned(16))) = {
|
||||
pdata->buffer[nindex][0],
|
||||
pdata->buffer[nindex][1],
|
||||
pdata->buffer[nindex][2],
|
||||
0.
|
||||
};
|
||||
float inp_sse2[4] __attribute__ ((aligned(16))) = {
|
||||
fx, fy, fz, 0.
|
||||
};
|
||||
float out_sse[4] __attribute__((aligned(16)));
|
||||
|
||||
a = _mm_load_ps(inp_sse1);
|
||||
b = _mm_load_ps(inp_sse2);
|
||||
c = _mm_mul_ps(a, b);
|
||||
_mm_store_ps(out_sse, c);
|
||||
|
||||
return out_sse[0] + out_sse[1] + out_sse[2];
|
||||
|
||||
#else /* __SSE__ */
|
||||
int n[4] = { ix, iy, iz, iw };
|
||||
float f[4] = { fx, fy, fz, fw };
|
||||
int nindex = 0;
|
||||
int i;
|
||||
float value = 0;
|
||||
|
||||
for(i = 0; i < pdata->ndim; i++)
|
||||
nindex = pdata->map[(nindex + n[i]) & 0xFF];
|
||||
for(i = 0; i < pdata->ndim; i++)
|
||||
value += pdata->buffer[nindex][i] * f[i];
|
||||
value = pdata->buffer[nindex][0] * fx;
|
||||
value += pdata->buffer[nindex][1] * fy;
|
||||
value += pdata->buffer[nindex][2] * fz;
|
||||
|
||||
return value;
|
||||
#endif /* __SSE__ */
|
||||
}
|
||||
|
||||
#define DEFAULT_SEED 0x15687436
|
||||
@ -101,27 +65,26 @@ static float lattice(perling_data_t* pdata, int ix, float fx, int iy,
|
||||
#define FLOOR(a) ((int) a - (a < 0 && a != (int)a))
|
||||
#define CUBIC(a) (a * a * (3 - 2 * a))
|
||||
|
||||
static void normalize(perling_data_t* pdata, float* f) {
|
||||
float magnitude = 0;
|
||||
int i;
|
||||
for(i = 0; i < pdata->ndim; i++)
|
||||
magnitude += f[i] * f[i];
|
||||
magnitude = 1 / sqrtf(magnitude);
|
||||
for(i = 0; i < pdata->ndim; i++)
|
||||
f[i] *= magnitude;
|
||||
static void normalize(float f[3]) {
|
||||
float magnitude;
|
||||
|
||||
magnitude = 1. / sqrtf(f[0]*f[0] + f[1]*f[1] + f[2]*f[2]);
|
||||
f[0] *= magnitude;
|
||||
f[1] *= magnitude;
|
||||
f[2] *= magnitude;
|
||||
}
|
||||
|
||||
static noise_t noise_new(int ndim, float hurst, float lacunarity) {
|
||||
perling_data_t* pdata=(perling_data_t*)calloc(sizeof(perling_data_t), 1);
|
||||
static noise_t noise_new(float hurst, float lacunarity) {
|
||||
perlin_data_t* pdata = (perlin_data_t*)calloc(sizeof(perlin_data_t), 1);
|
||||
int i, j;
|
||||
unsigned char tmp;
|
||||
float f = 1;
|
||||
pdata->ndim = ndim;
|
||||
for(i = 0; i < 256; i++) {
|
||||
pdata->map[i] = (unsigned char) i;
|
||||
for(j = 0; j < pdata->ndim; j++)
|
||||
pdata->buffer[i][j] = RNGF()-0.5;
|
||||
normalize(pdata, pdata->buffer[i]);
|
||||
pdata->map[i] = (unsigned char)i;
|
||||
pdata->buffer[i][0] = RNGF()-0.5;
|
||||
pdata->buffer[i][1] = RNGF()-0.5;
|
||||
pdata->buffer[i][2] = RNGF()-0.5;
|
||||
normalize(pdata->buffer[i]);
|
||||
}
|
||||
|
||||
while(--i) {
|
||||
@ -132,133 +95,68 @@ static noise_t noise_new(int ndim, float hurst, float lacunarity) {
|
||||
pdata->H = hurst;
|
||||
pdata->lacunarity = lacunarity;
|
||||
for(i = 0; i < NOISE_MAX_OCTAVES; i++) {
|
||||
/*exponent[i] = powf(f, -H); */
|
||||
pdata->exponent[i] = 1.0f / f;
|
||||
/*exponent[i] = powf(f, -H);*/
|
||||
pdata->exponent[i] = 1. / f;
|
||||
f *= lacunarity;
|
||||
}
|
||||
return (noise_t)pdata;
|
||||
}
|
||||
|
||||
static float noise_get(noise_t noise, float *f )
|
||||
{
|
||||
perling_data_t* pdata = (perling_data_t*) noise;
|
||||
int n[NOISE_MAX_DIMENSIONS]; /* Indexes to pass to lattice function */
|
||||
int i;
|
||||
float r[NOISE_MAX_DIMENSIONS]; /* Remainders to pass to lattice function */
|
||||
float w[NOISE_MAX_DIMENSIONS]; /* Cubic values to pass to interpolation function */
|
||||
static float noise_get(noise_t noise, float *f ) {
|
||||
perlin_data_t* pdata = (perlin_data_t*)noise;
|
||||
int n[3]; /* Indexes to pass to lattice function. */
|
||||
float r[3]; /* Remainders to pass to lattice function. */
|
||||
float w[3]; /* Cubic values to pass to interpolation function. */
|
||||
float value;
|
||||
|
||||
for(i=0; i<pdata->ndim; i++) {
|
||||
n[i] = FLOOR(f[i]);
|
||||
r[i] = f[i] - n[i];
|
||||
w[i] = CUBIC(r[i]);
|
||||
}
|
||||
n[0] = FLOOR(f[0]);
|
||||
n[1] = FLOOR(f[1]);
|
||||
n[2] = FLOOR(f[2]);
|
||||
|
||||
r[0] = f[0] - n[0];
|
||||
r[1] = f[1] - n[1];
|
||||
r[2] = f[2] - n[2];
|
||||
|
||||
w[0] = CUBIC(r[0]);
|
||||
w[1] = CUBIC(r[1]);
|
||||
w[2] = CUBIC(r[2]);
|
||||
|
||||
value = LERP(LERP(LERP(lattice(pdata,n[0], r[0], n[1], r[1], n[2], r[2]),
|
||||
lattice(pdata,n[0]+1, r[0]-1, n[1], r[1], n[2], r[2]),
|
||||
w[0]),
|
||||
LERP(lattice(pdata,n[0], r[0], n[1]+1, r[1]-1, n[2], r[2]),
|
||||
lattice(pdata,n[0]+1, r[0]-1, n[1]+1, r[1]-1, n[2], r[2]),
|
||||
w[0]),
|
||||
w[1]),
|
||||
LERP(LERP(lattice(pdata,n[0], r[0], n[1], r[1], n[2]+1, r[2]-1),
|
||||
lattice(pdata,n[0]+1, r[0]-1, n[1], r[1], n[2]+1, r[2]-1),
|
||||
w[0]),
|
||||
LERP(lattice(pdata,n[0], r[0], n[1]+1, r[1]-1, n[2]+1, r[2]-1),
|
||||
lattice(pdata,n[0]+1, r[0]-1, n[1]+1, r[1]-1, n[2]+1, r[2]-1),
|
||||
w[0]),
|
||||
w[1]),
|
||||
w[2]);
|
||||
|
||||
switch(pdata->ndim) {
|
||||
case 1:
|
||||
value = LERP(lattice(pdata,n[0], r[0],0,0,0,0,0,0),
|
||||
lattice(pdata,n[0]+1, r[0]-1,0,0,0,0,0,0),
|
||||
w[0]);
|
||||
break;
|
||||
case 2:
|
||||
value = LERP(LERP(lattice(pdata,n[0], r[0], n[1], r[1],0,0,0,0),
|
||||
lattice(pdata,n[0]+1, r[0]-1, n[1], r[1],0,0,0,0),
|
||||
w[0]),
|
||||
LERP(lattice(pdata,n[0], r[0], n[1]+1, r[1]-1,0,0,0,0),
|
||||
lattice(pdata,n[0]+1, r[0]-1, n[1]+1, r[1]-1,0,0,0,0),
|
||||
w[0]),
|
||||
w[1]);
|
||||
break;
|
||||
case 3:
|
||||
value = LERP(LERP(LERP(lattice(pdata,n[0], r[0], n[1], r[1], n[2], r[2],0,0),
|
||||
lattice(pdata,n[0]+1, r[0]-1, n[1], r[1], n[2], r[2],0,0),
|
||||
w[0]),
|
||||
LERP(lattice(pdata,n[0], r[0], n[1]+1, r[1]-1, n[2], r[2],0,0),
|
||||
lattice(pdata,n[0]+1, r[0]-1, n[1]+1, r[1]-1, n[2], r[2],0,0),
|
||||
w[0]),
|
||||
w[1]),
|
||||
LERP(LERP(lattice(pdata,n[0], r[0], n[1], r[1], n[2]+1, r[2]-1,0,0),
|
||||
lattice(pdata,n[0]+1, r[0]-1, n[1], r[1], n[2]+1, r[2]-1,0,0),
|
||||
w[0]),
|
||||
LERP(lattice(pdata,n[0], r[0], n[1]+1, r[1]-1, n[2]+1, r[2]-1,0,0),
|
||||
lattice(pdata,n[0]+1, r[0]-1, n[1]+1, r[1]-1, n[2]+1, r[2]-1,0,0),
|
||||
w[0]),
|
||||
w[1]),
|
||||
w[2]);
|
||||
break;
|
||||
case 4:
|
||||
default:
|
||||
value = LERP(LERP(LERP(LERP(lattice(pdata,n[0], r[0], n[1], r[1], n[2], r[2], n[3], r[3]),
|
||||
lattice(pdata,n[0]+1, r[0]-1, n[1], r[1], n[2], r[2], n[3], r[3]),
|
||||
w[0]),
|
||||
LERP(lattice(pdata,n[0], r[0], n[1]+1, r[1]-1, n[2], r[2], n[3], r[3]),
|
||||
lattice(pdata,n[0]+1, r[0]-1, n[1]+1, r[1]-1, n[2], r[2], n[3], r[3]),
|
||||
w[0]),
|
||||
w[1]),
|
||||
LERP(LERP(lattice(pdata,n[0], r[0], n[1], r[1], n[2]+1, r[2]-1, n[3], r[3]),
|
||||
lattice(pdata,n[0]+1, r[0]-1, n[1], r[1], n[2]+1, r[2]-1, n[3], r[3]),
|
||||
w[0]),
|
||||
LERP(lattice(pdata,n[0], r[0], n[1]+1, r[1]-1, n[2]+1, r[2]-1,0,0),
|
||||
lattice(pdata,n[0]+1, r[0]-1, n[1]+1, r[1]-1, n[2]+1, r[2]-1, n[3], r[3]),
|
||||
w[0]),
|
||||
w[1]),
|
||||
w[2]),
|
||||
LERP(LERP(LERP(lattice(pdata,n[0], r[0], n[1], r[1], n[2], r[2], n[3]+1, r[3]-1),
|
||||
lattice(pdata,n[0]+1, r[0]-1, n[1], r[1], n[2], r[2], n[3]+1, r[3]-1),
|
||||
w[0]),
|
||||
LERP(lattice(pdata,n[0], r[0], n[1]+1, r[1]-1, n[2], r[2], n[3]+1, r[3]-1),
|
||||
lattice(pdata,n[0]+1, r[0]-1, n[1]+1, r[1]-1, n[2], r[2], n[3]+1, r[3]-1),
|
||||
w[0]),
|
||||
w[1]),
|
||||
LERP(LERP(lattice(pdata,n[0], r[0], n[1], r[1], n[2]+1, r[2]-1, n[3]+1, r[3]-1),
|
||||
lattice(pdata,n[0]+1, r[0]-1, n[1], r[1], n[2]+1, r[2]-1, n[3]+1, r[3]-1),
|
||||
w[0]),
|
||||
LERP(lattice(pdata,n[0], r[0], n[1]+1, r[1]-1, n[2]+1, r[2]-1,0,0),
|
||||
lattice(pdata,n[0]+1, r[0]-1, n[1]+1, r[1]-1, n[2]+1, r[2]-1, n[3]+1, r[3]-1),
|
||||
w[0]),
|
||||
w[1]),
|
||||
w[2]),
|
||||
w[3]);
|
||||
break;
|
||||
}
|
||||
return CLAMP(-0.99999f, 0.99999f, value);
|
||||
}
|
||||
|
||||
#if 0
|
||||
float noise_fbm(noise_t noise, float* f, float octaves) {
|
||||
float tf[NOISE_MAX_DIMENSIONS];
|
||||
perling_data_t* pdata = (perling_data_t*) noise;
|
||||
/* Init locals. */
|
||||
float value = 0;
|
||||
int i, j;
|
||||
memcpy(tf, f, sizeof(float) * pdata->ndim);
|
||||
|
||||
/* Inner loop for spectral construction, where the fractal is build. */
|
||||
for(i = 0; i < (int)octaves; i++) {
|
||||
value += noise_get(noise, tf) * pdata->exponent[i];
|
||||
for(j = 0; j < pdata->ndim; j++) tf[j] *= pdata->lacunarity;
|
||||
}
|
||||
|
||||
/* Take care of remainder in octaves. */
|
||||
octaves -= (int)octaves;
|
||||
if(octaves > DELTA)
|
||||
value += octaves * noise_get(noise, tf) * pdata->exponent[i];
|
||||
return CLAMP(-0.99999f, 0.99999f, value);
|
||||
}
|
||||
#endif
|
||||
|
||||
static float noise_turbulence(noise_t noise, float* f, float octaves) {
|
||||
float tf[NOISE_MAX_DIMENSIONS];
|
||||
perling_data_t* pdata = (perling_data_t*) noise;
|
||||
float tf[3];
|
||||
perlin_data_t* pdata = (perlin_data_t*) noise;
|
||||
/* Init locals. */
|
||||
float value = 0;
|
||||
int i, j;
|
||||
memcpy(tf, f, sizeof(float) * pdata->ndim);
|
||||
int i;
|
||||
|
||||
tf[0] = f[0];
|
||||
tf[1] = f[1];
|
||||
tf[2] = f[2];
|
||||
|
||||
/* Inner loop of spectral construction, where the fractal is built. */
|
||||
for(i = 0; i < (int)octaves; i++) {
|
||||
value += ABS(noise_get(noise, tf)) * pdata->exponent[i];
|
||||
for(j = 0; j < pdata->ndim; j++) tf[j] *= pdata->lacunarity;
|
||||
tf[0] *= pdata->lacunarity;
|
||||
tf[1] *= pdata->lacunarity;
|
||||
tf[2] *= pdata->lacunarity;
|
||||
}
|
||||
|
||||
/* Take care of remainders in octaves. */
|
||||
@ -269,7 +167,7 @@ static float noise_turbulence(noise_t noise, float* f, float octaves) {
|
||||
}
|
||||
|
||||
void noise_delete(noise_t noise) {
|
||||
free((perling_data_t*)noise);
|
||||
free((perlin_data_t*)noise);
|
||||
}
|
||||
|
||||
/* Generate a 3d nebulae map of dimensions w,h,n with ruggedness rig. */
|
||||
@ -290,7 +188,7 @@ static float* genNebulaeMap(const int w, const int h, const int n, float rug) {
|
||||
lacunarity = NOISE_DEFAULT_LACUNARITY;
|
||||
|
||||
/* Create noiuse and data. */
|
||||
noise = noise_new(2, hurst, lacunarity);
|
||||
noise = noise_new(hurst, lacunarity);
|
||||
|
||||
nebulae = malloc(sizeof(float)*w*h*n);
|
||||
if(nebulae == NULL) {
|
||||
|
@ -22,7 +22,7 @@ glTexture* pf_genFractal(const int w, const int h, double rug) {
|
||||
|
||||
map = pf_genFractalMap(w, h, rug);
|
||||
|
||||
sur = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, RGBMASK);
|
||||
sur = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, RGBAMASK);
|
||||
pix = sur->pixels;
|
||||
|
||||
/* Convert from mapping to actual colours. */
|
||||
|
Loading…
Reference in New Issue
Block a user