diff --git a/src/api/l_math.c b/src/api/l_math.c index c2de7d22..7b32b22f 100644 --- a/src/api/l_math.c +++ b/src/api/l_math.c @@ -153,12 +153,12 @@ static int l_lovrMathNewRandomGenerator(lua_State* L) { static int l_lovrMathNoise(lua_State* L) { switch (lua_gettop(L)) { case 0: - case 1: lua_pushnumber(L, lovrMathNoise1(luax_checkfloat(L, 1))); return 1; - case 2: lua_pushnumber(L, lovrMathNoise2(luax_checkfloat(L, 1), luax_checkfloat(L, 2))); return 1; - case 3: lua_pushnumber(L, lovrMathNoise3(luax_checkfloat(L, 1), luax_checkfloat(L, 2), luax_checkfloat(L, 3))); return 1; + case 1: lua_pushnumber(L, lovrMathNoise1(luaL_checknumber(L, 1))); return 1; + case 2: lua_pushnumber(L, lovrMathNoise2(luaL_checknumber(L, 1), luaL_checknumber(L, 2))); return 1; + case 3: lua_pushnumber(L, lovrMathNoise3(luaL_checknumber(L, 1), luaL_checknumber(L, 2), luaL_checknumber(L, 3))); return 1; case 4: default: - lua_pushnumber(L, lovrMathNoise4(luax_checkfloat(L, 1), luax_checkfloat(L, 2), luax_checkfloat(L, 3), luax_checkfloat(L, 4))); + lua_pushnumber(L, lovrMathNoise4(luaL_checknumber(L, 1), luaL_checknumber(L, 2), luaL_checknumber(L, 3), luaL_checknumber(L, 4))); return 1; } } diff --git a/src/lib/noise/simplexnoise1234.c b/src/lib/noise/simplexnoise1234.c index 19be3062..bfd6f39b 100644 --- a/src/lib/noise/simplexnoise1234.c +++ b/src/lib/noise/simplexnoise1234.c @@ -95,32 +95,32 @@ unsigned char perm[512] = {151,160,137,91,90,15, * float SLnoise = (noise(x,y,z) + 1.0) * 0.5; */ -float grad1( int hash, float x ) { +double grad1( int hash, double x ) { int h = hash & 15; - float grad = 1.0f + (h & 7); // Gradient value 1.0, 2.0, ..., 8.0 + double grad = 1.0 + (h & 7); // Gradient value 1.0, 2.0, ..., 8.0 if (h&8) grad = -grad; // Set a random sign for the gradient return ( grad * x ); // Multiply the gradient with the distance } -float grad2( int hash, float x, float y ) { +double grad2( int hash, double x, double y ) { int h = hash & 7; // Convert low 3 bits of hash code - float u = h<4 ? x : y; // into 8 simple gradient directions, - float v = h<4 ? y : x; // and compute the dot product with (x,y). - return ((h&1)? -u : u) + ((h&2)? -2.0f*v : 2.0f*v); + double u = h<4 ? x : y; // into 8 simple gradient directions, + double v = h<4 ? y : x; // and compute the dot product with (x,y). + return ((h&1)? -u : u) + ((h&2)? -2.0*v : 2.0*v); } -float grad3( int hash, float x, float y , float z ) { +double grad3( int hash, double x, double y , double z ) { int h = hash & 15; // Convert low 4 bits of hash code into 12 simple - float u = h<8 ? x : y; // gradient directions, and compute dot product. - float v = h<4 ? y : h==12||h==14 ? x : z; // Fix repeats at h = 12 to 15 + double u = h<8 ? x : y; // gradient directions, and compute dot product. + double v = h<4 ? y : h==12||h==14 ? x : z; // Fix repeats at h = 12 to 15 return ((h&1)? -u : u) + ((h&2)? -v : v); } -float grad4( int hash, float x, float y, float z, float t ) { +double grad4( int hash, double x, double y, double z, double t ) { int h = hash & 31; // Convert low 5 bits of hash code into 32 simple - float u = h<24 ? x : y; // gradient directions, and compute dot product. - float v = h<16 ? y : z; - float w = h<8 ? z : t; + double u = h<24 ? x : y; // gradient directions, and compute dot product. + double v = h<16 ? y : z; + double w = h<8 ? z : t; return ((h&1)? -u : u) + ((h&2)? -v : v) + ((h&4)? -w : w); } @@ -138,22 +138,22 @@ float grad4( int hash, float x, float y, float z, float t ) { {2,1,0,3},{0,0,0,0},{0,0,0,0},{0,0,0,0},{3,1,0,2},{0,0,0,0},{3,2,0,1},{3,2,1,0}}; // 1D simplex noise -float snoise1(float x) { +double snoise1(double x) { int i0 = FASTFLOOR(x); int i1 = i0 + 1; - float x0 = x - i0; - float x1 = x0 - 1.0f; + double x0 = x - i0; + double x1 = x0 - 1.0; - float n0, n1; + double n0, n1; - float t0 = 1.0f - x0*x0; -// if(t0 < 0.0f) t0 = 0.0f; // this never happens for the 1D case + double t0 = 1.0 - x0*x0; +// if(t0 < 0.0) t0 = 0.0; // this never happens for the 1D case t0 *= t0; n0 = t0 * t0 * grad1(perm[i0 & 0xff], x0); - float t1 = 1.0f - x1*x1; -// if(t1 < 0.0f) t1 = 0.0f; // this never happens for the 1D case + double t1 = 1.0 - x1*x1; +// if(t1 < 0.0) t1 = 0.0; // this never happens for the 1D case t1 *= t1; n1 = t1 * t1 * grad1(perm[i1 & 0xff], x1); // The maximum value of this noise is 8*(3/4)^4 = 2.53125 @@ -164,25 +164,25 @@ float snoise1(float x) { } // 2D simplex noise -float snoise2(float x, float y) { +double snoise2(double x, double y) { #define F2 0.366025403 // F2 = 0.5*(sqrt(3.0)-1.0) #define G2 0.211324865 // G2 = (3.0-Math.sqrt(3.0))/6.0 - float n0, n1, n2; // Noise contributions from the three corners + double n0, n1, n2; // Noise contributions from the three corners // Skew the input space to determine which simplex cell we're in - float s = (x+y)*F2; // Hairy factor for 2D - float xs = x + s; - float ys = y + s; + double s = (x+y)*F2; // Hairy factor for 2D + double xs = x + s; + double ys = y + s; int i = FASTFLOOR(xs); int j = FASTFLOOR(ys); - float t = (float)(i+j)*G2; - float X0 = i-t; // Unskew the cell origin back to (x,y) space - float Y0 = j-t; - float x0 = x-X0; // The x,y distances from the cell origin - float y0 = y-Y0; + double t = (double)(i+j)*G2; + double X0 = i-t; // Unskew the cell origin back to (x,y) space + double Y0 = j-t; + double x0 = x-X0; // The x,y distances from the cell origin + double y0 = y-Y0; // For the 2D case, the simplex shape is an equilateral triangle. // Determine which simplex we are in. @@ -194,32 +194,32 @@ float snoise2(float x, float y) { // a step of (0,1) in (i,j) means a step of (-c,1-c) in (x,y), where // c = (3-sqrt(3))/6 - float x1 = x0 - i1 + G2; // Offsets for middle corner in (x,y) unskewed coords - float y1 = y0 - j1 + G2; - float x2 = x0 - 1.0f + 2.0f * G2; // Offsets for last corner in (x,y) unskewed coords - float y2 = y0 - 1.0f + 2.0f * G2; + double x1 = x0 - i1 + G2; // Offsets for middle corner in (x,y) unskewed coords + double y1 = y0 - j1 + G2; + double x2 = x0 - 1.0 + 2.0 * G2; // Offsets for last corner in (x,y) unskewed coords + double y2 = y0 - 1.0 + 2.0 * G2; // Wrap the integer indices at 256, to avoid indexing perm[] out of bounds int ii = i & 0xff; int jj = j & 0xff; // Calculate the contribution from the three corners - float t0 = 0.5f - x0*x0-y0*y0; - if(t0 < 0.0f) n0 = 0.0f; + double t0 = 0.5f - x0*x0-y0*y0; + if(t0 < 0.0) n0 = 0.0; else { t0 *= t0; n0 = t0 * t0 * grad2(perm[ii+perm[jj]], x0, y0); } - float t1 = 0.5f - x1*x1-y1*y1; - if(t1 < 0.0f) n1 = 0.0f; + double t1 = 0.5f - x1*x1-y1*y1; + if(t1 < 0.0) n1 = 0.0; else { t1 *= t1; n1 = t1 * t1 * grad2(perm[ii+i1+perm[jj+j1]], x1, y1); } - float t2 = 0.5f - x2*x2-y2*y2; - if(t2 < 0.0f) n2 = 0.0f; + double t2 = 0.5f - x2*x2-y2*y2; + if(t2 < 0.0) n2 = 0.0; else { t2 *= t2; n2 = t2 * t2 * grad2(perm[ii+1+perm[jj+1]], x2, y2); @@ -227,34 +227,34 @@ float snoise2(float x, float y) { // Add contributions from each corner to get the final noise value. // The result is scaled to return values in the interval [-1,1]. - return 40.0f * (n0 + n1 + n2); // TODO: The scale factor is preliminary! + return 40.0 * (n0 + n1 + n2); // TODO: The scale factor is preliminary! } // 3D simplex noise -float snoise3(float x, float y, float z) { +double snoise3(double x, double y, double z) { // Simple skewing factors for the 3D case #define F3 0.333333333 #define G3 0.166666667 - float n0, n1, n2, n3; // Noise contributions from the four corners + double n0, n1, n2, n3; // Noise contributions from the four corners // Skew the input space to determine which simplex cell we're in - float s = (x+y+z)*F3; // Very nice and simple skew factor for 3D - float xs = x+s; - float ys = y+s; - float zs = z+s; + double s = (x+y+z)*F3; // Very nice and simple skew factor for 3D + double xs = x+s; + double ys = y+s; + double zs = z+s; int i = FASTFLOOR(xs); int j = FASTFLOOR(ys); int k = FASTFLOOR(zs); - float t = (float)(i+j+k)*G3; - float X0 = i-t; // Unskew the cell origin back to (x,y,z) space - float Y0 = j-t; - float Z0 = k-t; - float x0 = x-X0; // The x,y,z distances from the cell origin - float y0 = y-Y0; - float z0 = z-Z0; + double t = (double)(i+j+k)*G3; + double X0 = i-t; // Unskew the cell origin back to (x,y,z) space + double Y0 = j-t; + double Z0 = k-t; + double x0 = x-X0; // The x,y,z distances from the cell origin + double y0 = y-Y0; + double z0 = z-Z0; // For the 3D case, the simplex shape is a slightly irregular tetrahedron. // Determine which simplex we are in. @@ -279,15 +279,15 @@ float snoise3(float x, float y, float z) { // a step of (0,0,1) in (i,j,k) means a step of (-c,-c,1-c) in (x,y,z), where // c = 1/6. - float x1 = x0 - i1 + G3; // Offsets for second corner in (x,y,z) coords - float y1 = y0 - j1 + G3; - float z1 = z0 - k1 + G3; - float x2 = x0 - i2 + 2.0f*G3; // Offsets for third corner in (x,y,z) coords - float y2 = y0 - j2 + 2.0f*G3; - float z2 = z0 - k2 + 2.0f*G3; - float x3 = x0 - 1.0f + 3.0f*G3; // Offsets for last corner in (x,y,z) coords - float y3 = y0 - 1.0f + 3.0f*G3; - float z3 = z0 - 1.0f + 3.0f*G3; + double x1 = x0 - i1 + G3; // Offsets for second corner in (x,y,z) coords + double y1 = y0 - j1 + G3; + double z1 = z0 - k1 + G3; + double x2 = x0 - i2 + 2.0*G3; // Offsets for third corner in (x,y,z) coords + double y2 = y0 - j2 + 2.0*G3; + double z2 = z0 - k2 + 2.0*G3; + double x3 = x0 - 1.0 + 3.0*G3; // Offsets for last corner in (x,y,z) coords + double y3 = y0 - 1.0 + 3.0*G3; + double z3 = z0 - 1.0 + 3.0*G3; // Wrap the integer indices at 256, to avoid indexing perm[] out of bounds int ii = i & 0xff; @@ -295,29 +295,29 @@ float snoise3(float x, float y, float z) { int kk = k & 0xff; // Calculate the contribution from the four corners - float t0 = 0.5f - x0*x0 - y0*y0 - z0*z0; - if(t0 < 0.0f) n0 = 0.0f; + double t0 = 0.5f - x0*x0 - y0*y0 - z0*z0; + if(t0 < 0.0) n0 = 0.0; else { t0 *= t0; n0 = t0 * t0 * grad3(perm[ii+perm[jj+perm[kk]]], x0, y0, z0); } - float t1 = 0.5f - x1*x1 - y1*y1 - z1*z1; - if(t1 < 0.0f) n1 = 0.0f; + double t1 = 0.5f - x1*x1 - y1*y1 - z1*z1; + if(t1 < 0.0) n1 = 0.0; else { t1 *= t1; n1 = t1 * t1 * grad3(perm[ii+i1+perm[jj+j1+perm[kk+k1]]], x1, y1, z1); } - float t2 = 0.5f - x2*x2 - y2*y2 - z2*z2; - if(t2 < 0.0f) n2 = 0.0f; + double t2 = 0.5f - x2*x2 - y2*y2 - z2*z2; + if(t2 < 0.0) n2 = 0.0; else { t2 *= t2; n2 = t2 * t2 * grad3(perm[ii+i2+perm[jj+j2+perm[kk+k2]]], x2, y2, z2); } - float t3 = 0.5f - x3*x3 - y3*y3 - z3*z3; - if(t3<0.0f) n3 = 0.0f; + double t3 = 0.5f - x3*x3 - y3*y3 - z3*z3; + if(t3<0.0) n3 = 0.0; else { t3 *= t3; n3 = t3 * t3 * grad3(perm[ii+1+perm[jj+1+perm[kk+1]]], x3, y3, z3); @@ -325,40 +325,40 @@ float snoise3(float x, float y, float z) { // Add contributions from each corner to get the final noise value. // The result is scaled to stay just inside [-1,1] - return 72.0f * (n0 + n1 + n2 + n3); + return 72.0 * (n0 + n1 + n2 + n3); } // 4D simplex noise -float snoise4(float x, float y, float z, float w) { +double snoise4(double x, double y, double z, double w) { // The skewing and unskewing factors are hairy again for the 4D case #define F4 0.309016994 // F4 = (Math.sqrt(5.0)-1.0)/4.0 #define G4 0.138196601 // G4 = (5.0-Math.sqrt(5.0))/20.0 - float n0, n1, n2, n3, n4; // Noise contributions from the five corners + double n0, n1, n2, n3, n4; // Noise contributions from the five corners // Skew the (x,y,z,w) space to determine which cell of 24 simplices we're in - float s = (x + y + z + w) * F4; // Factor for 4D skewing - float xs = x + s; - float ys = y + s; - float zs = z + s; - float ws = w + s; + double s = (x + y + z + w) * F4; // Factor for 4D skewing + double xs = x + s; + double ys = y + s; + double zs = z + s; + double ws = w + s; int i = FASTFLOOR(xs); int j = FASTFLOOR(ys); int k = FASTFLOOR(zs); int l = FASTFLOOR(ws); - float t = (i + j + k + l) * G4; // Factor for 4D unskewing - float X0 = i - t; // Unskew the cell origin back to (x,y,z,w) space - float Y0 = j - t; - float Z0 = k - t; - float W0 = l - t; + double t = (i + j + k + l) * G4; // Factor for 4D unskewing + double X0 = i - t; // Unskew the cell origin back to (x,y,z,w) space + double Y0 = j - t; + double Z0 = k - t; + double W0 = l - t; - float x0 = x - X0; // The x,y,z,w distances from the cell origin - float y0 = y - Y0; - float z0 = z - Z0; - float w0 = w - W0; + double x0 = x - X0; // The x,y,z,w distances from the cell origin + double y0 = y - Y0; + double z0 = z - Z0; + double w0 = w - W0; // For the 4D case, the simplex is a 4D shape I won't even try to describe. // To find out which of the 24 possible simplices we're in, we need to @@ -401,22 +401,22 @@ float snoise4(float x, float y, float z, float w) { l3 = simplex[c][3]>=1 ? 1 : 0; // The fifth corner has all coordinate offsets = 1, so no need to look that up. - float x1 = x0 - i1 + G4; // Offsets for second corner in (x,y,z,w) coords - float y1 = y0 - j1 + G4; - float z1 = z0 - k1 + G4; - float w1 = w0 - l1 + G4; - float x2 = x0 - i2 + 2.0f*G4; // Offsets for third corner in (x,y,z,w) coords - float y2 = y0 - j2 + 2.0f*G4; - float z2 = z0 - k2 + 2.0f*G4; - float w2 = w0 - l2 + 2.0f*G4; - float x3 = x0 - i3 + 3.0f*G4; // Offsets for fourth corner in (x,y,z,w) coords - float y3 = y0 - j3 + 3.0f*G4; - float z3 = z0 - k3 + 3.0f*G4; - float w3 = w0 - l3 + 3.0f*G4; - float x4 = x0 - 1.0f + 4.0f*G4; // Offsets for last corner in (x,y,z,w) coords - float y4 = y0 - 1.0f + 4.0f*G4; - float z4 = z0 - 1.0f + 4.0f*G4; - float w4 = w0 - 1.0f + 4.0f*G4; + double x1 = x0 - i1 + G4; // Offsets for second corner in (x,y,z,w) coords + double y1 = y0 - j1 + G4; + double z1 = z0 - k1 + G4; + double w1 = w0 - l1 + G4; + double x2 = x0 - i2 + 2.0*G4; // Offsets for third corner in (x,y,z,w) coords + double y2 = y0 - j2 + 2.0*G4; + double z2 = z0 - k2 + 2.0*G4; + double w2 = w0 - l2 + 2.0*G4; + double x3 = x0 - i3 + 3.0*G4; // Offsets for fourth corner in (x,y,z,w) coords + double y3 = y0 - j3 + 3.0*G4; + double z3 = z0 - k3 + 3.0*G4; + double w3 = w0 - l3 + 3.0*G4; + double x4 = x0 - 1.0 + 4.0*G4; // Offsets for last corner in (x,y,z,w) coords + double y4 = y0 - 1.0 + 4.0*G4; + double z4 = z0 - 1.0 + 4.0*G4; + double w4 = w0 - 1.0 + 4.0*G4; // Wrap the integer indices at 256, to avoid indexing perm[] out of bounds int ii = i & 0xff; @@ -425,42 +425,42 @@ float snoise4(float x, float y, float z, float w) { int ll = l & 0xff; // Calculate the contribution from the five corners - float t0 = 0.5f - x0*x0 - y0*y0 - z0*z0 - w0*w0; - if(t0 < 0.0f) n0 = 0.0f; + double t0 = 0.5f - x0*x0 - y0*y0 - z0*z0 - w0*w0; + if(t0 < 0.0) n0 = 0.0; else { t0 *= t0; n0 = t0 * t0 * grad4(perm[ii+perm[jj+perm[kk+perm[ll]]]], x0, y0, z0, w0); } - float t1 = 0.5f - x1*x1 - y1*y1 - z1*z1 - w1*w1; - if(t1 < 0.0f) n1 = 0.0f; + double t1 = 0.5f - x1*x1 - y1*y1 - z1*z1 - w1*w1; + if(t1 < 0.0) n1 = 0.0; else { t1 *= t1; n1 = t1 * t1 * grad4(perm[ii+i1+perm[jj+j1+perm[kk+k1+perm[ll+l1]]]], x1, y1, z1, w1); } - float t2 = 0.5f - x2*x2 - y2*y2 - z2*z2 - w2*w2; - if(t2 < 0.0f) n2 = 0.0f; + double t2 = 0.5f - x2*x2 - y2*y2 - z2*z2 - w2*w2; + if(t2 < 0.0) n2 = 0.0; else { t2 *= t2; n2 = t2 * t2 * grad4(perm[ii+i2+perm[jj+j2+perm[kk+k2+perm[ll+l2]]]], x2, y2, z2, w2); } - float t3 = 0.5f - x3*x3 - y3*y3 - z3*z3 - w3*w3; - if(t3 < 0.0f) n3 = 0.0f; + double t3 = 0.5f - x3*x3 - y3*y3 - z3*z3 - w3*w3; + if(t3 < 0.0) n3 = 0.0; else { t3 *= t3; n3 = t3 * t3 * grad4(perm[ii+i3+perm[jj+j3+perm[kk+k3+perm[ll+l3]]]], x3, y3, z3, w3); } - float t4 = 0.5f - x4*x4 - y4*y4 - z4*z4 - w4*w4; - if(t4 < 0.0f) n4 = 0.0f; + double t4 = 0.5f - x4*x4 - y4*y4 - z4*z4 - w4*w4; + if(t4 < 0.0) n4 = 0.0; else { t4 *= t4; n4 = t4 * t4 * grad4(perm[ii+1+perm[jj+1+perm[kk+1+perm[ll+1]]]], x4, y4, z4, w4); } // Sum up and scale the result to cover the range [-1,1] - return 62.0f * (n0 + n1 + n2 + n3 + n4); + return 62.0 * (n0 + n1 + n2 + n3 + n4); } //--------------------------------------------------------------------- diff --git a/src/lib/noise/simplexnoise1234.h b/src/lib/noise/simplexnoise1234.h index c9502581..536b850a 100644 --- a/src/lib/noise/simplexnoise1234.h +++ b/src/lib/noise/simplexnoise1234.h @@ -25,7 +25,7 @@ /** 1D, 2D, 3D and 4D float Perlin simplex noise */ - float snoise1( float x ); - float snoise2( float x, float y ); - float snoise3( float x, float y, float z ); - float snoise4( float x, float y, float z, float w ); + double snoise1( double x ); + double snoise2( double x, double y ); + double snoise3( double x, double y, double z ); + double snoise4( double x, double y, double z, double w ); diff --git a/src/modules/math/math.c b/src/modules/math/math.c index b4f9676f..3afa1ef4 100644 --- a/src/modules/math/math.c +++ b/src/modules/math/math.c @@ -45,18 +45,18 @@ float lovrMathLinearToGamma(float x) { } } -float lovrMathNoise1(float x) { - return snoise1(x) * .5f + .5f; +double lovrMathNoise1(double x) { + return snoise1(x) * .5 + .5; } -float lovrMathNoise2(float x, float y) { - return snoise2(x, y) * .5f + .5f; +double lovrMathNoise2(double x, double y) { + return snoise2(x, y) * .5 + .5; } -float lovrMathNoise3(float x, float y, float z) { - return snoise3(x, y, z) * .5f + .5f; +double lovrMathNoise3(double x, double y, double z) { + return snoise3(x, y, z) * .5 + .5; } -float lovrMathNoise4(float x, float y, float z, float w) { - return snoise4(x, y, z, w) * .5f + .5f; +double lovrMathNoise4(double x, double y, double z, double w) { + return snoise4(x, y, z, w) * .5 + .5; } diff --git a/src/modules/math/math.h b/src/modules/math/math.h index e5d0d2ce..bfb43634 100644 --- a/src/modules/math/math.h +++ b/src/modules/math/math.h @@ -9,7 +9,7 @@ void lovrMathDestroy(void); struct RandomGenerator* lovrMathGetRandomGenerator(void); float lovrMathGammaToLinear(float x); float lovrMathLinearToGamma(float x); -float lovrMathNoise1(float x); -float lovrMathNoise2(float x, float y); -float lovrMathNoise3(float x, float y, float z); -float lovrMathNoise4(float x, float y, float z, float w); +double lovrMathNoise1(double x); +double lovrMathNoise2(double x, double y); +double lovrMathNoise3(double x, double y, double z); +double lovrMathNoise4(double x, double y, double z, double w);