/*
* =====================================================================================
*
* Filename: noise.cpp
*
* Description: Various noise functions
*
* Version: 1.0
* Created: 11/08/2011 20:51:00
* Revision: none
* Compiler: gcc
*
* Author: John Ryland (jryland), jryland@xiaofrog.com
* Company: InvertedLogic
*
* =====================================================================================
*/
#include <noise.h>
#include <math.h>
//
// ideas
//
// fractal mountains - tessalation
// procedural cities
// procedural textures
// procedural grass, trees / growth
// procedrual waves
// clouds
// particles
//
// the maskable angle/normal table
// using the normal table to project spherical rays to make a sphere map for environment mapping
//
// voxelizer using OpenGL to render Z-buffer at different angles and a put-voxel routine that
// blends in the values as the view is changed. Perhaps use the normal table to add views.
//
vec3 Add(vec3 v1, vec3 v2)
{
return vec3(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z);
}
float DotProduct(vec3 v1, vec3 v2)
{
return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
}
float Length(vec3 v)
{
return sqrt(DotProduct(v, v));
}
vec3& Normalize(vec3 v)
{
float len = Length(v);
if ( len )
{
float one_over_len = 1.0f / len;
v.x *= one_over_len;
v.y *= one_over_len;
v.z *= one_over_len;
}
return v;
}
vec3 normalTable[1 << 16];
void initNormalTable()
{
for (int i = 0; i < (1<<16); i++)
{
normalTable[i].x = 0;
normalTable[i].y = 0;
normalTable[i].z = 0;
}
}
// I think the vectors shouldn't be expanded fully out to being normalized at first
// as the opposing vectors need to pass through the center and it doesn't work as
// well if they don't but could still kinda work
void recursiveBuildNormalTable(int i, int a, int b, int c, int depth)
{
if ( depth >= 12 )
return;
depth += 3;
int i1 = i + (1 << depth);
int i2 = i + (2 << depth);
int i3 = i + (3 << depth);
int i4 = i + (0 << depth);
normalTable[i1] = Normalize(Add(normalTable[a], normalTable[b]));
normalTable[i2] = Normalize(Add(normalTable[a], normalTable[c]));
normalTable[i3] = Normalize(Add(normalTable[b], normalTable[c]));
recursiveBuildNormalTable(i4, a, i1, i2, depth);
recursiveBuildNormalTable(i1, i1, i3, b, depth);
recursiveBuildNormalTable(i2, i2, c, i3, depth);
recursiveBuildNormalTable(i3, i3, i1, i2, depth);
}
void buildNormalTable()
{
normalTable[0] = vec3( 0, 1, 0 );
normalTable[1] = vec3( 0, -1, 0 );
normalTable[2] = vec3( 0, 0, 1 );
normalTable[3] = vec3( 0, 0, -1 );
normalTable[4] = vec3( 1, 0, 0 );
normalTable[5] = vec3( -1, 0, 0 );
recursiveBuildNormalTable(0, 0, 2, 4, 0 );
recursiveBuildNormalTable(1, 2, 5, 0, 0 );
recursiveBuildNormalTable(2, 3, 4, 0, 0 );
recursiveBuildNormalTable(3, 5, 0, 3, 0 );
recursiveBuildNormalTable(4, 1, 2, 4, 0 );
recursiveBuildNormalTable(5, 1, 2, 5, 0 );
recursiveBuildNormalTable(6, 4, 1, 3, 0 );
recursiveBuildNormalTable(7, 1, 3, 5, 0 );
}
float perlinNoise(float x, float y, float z)
{
float a = 0.13f;
float b = 0.23f;
float c = 0.33f;
float d = 0.43f;
return x * a + y * b + z * c + d;
}
vec3 perlinNoise3(float x, float y, float z)
{
float dNoise = perlinNoise(x, y, z);
float dx = 0.213f;
float dy = 0.123f;
float dz = 0.133f;
return vec3( dNoise / dx, dNoise / dy, dNoise / dz );
}
float noiseA(float x, float y, float z);
float noiseB(float x, float y, float z);
float noiseC(float x, float y, float z);