mirror of
https://github.com/love2d/love.git
synced 2026-08-15 07:41:11 +02:00
Add love.math.perlinNoise and love.math.simplexNoise.
This commit is contained in:
@@ -83,10 +83,14 @@ float linearToGamma(float c);
|
||||
*
|
||||
* @return Noise value in the range of [0, 1].
|
||||
**/
|
||||
static float noise1(double x);
|
||||
static float noise2(double x, double y);
|
||||
static float noise3(double x, double y, double z);
|
||||
static float noise4(double x, double y, double z, double w);
|
||||
static float simplexNoise1(double x);
|
||||
static float simplexNoise2(double x, double y);
|
||||
static float simplexNoise3(double x, double y, double z);
|
||||
static float simplexNoise4(double x, double y, double z, double w);
|
||||
static float perlinNoise1(double x);
|
||||
static float perlinNoise2(double x, double y);
|
||||
static float perlinNoise3(double x, double y, double z);
|
||||
static float perlinNoise4(double x, double y, double z, double w);
|
||||
|
||||
|
||||
class Math : public Module
|
||||
@@ -132,25 +136,42 @@ private:
|
||||
}; // Math
|
||||
|
||||
|
||||
static inline float noise1(double x)
|
||||
static inline float simplexNoise1(double x)
|
||||
{
|
||||
return SimplexNoise1234::noise(x) * 0.5f + 0.5f;
|
||||
}
|
||||
|
||||
static inline float noise2(double x, double y)
|
||||
static inline float simplexNoise2(double x, double y)
|
||||
{
|
||||
return SimplexNoise1234::noise(x, y) * 0.5f + 0.5f;
|
||||
}
|
||||
|
||||
// Perlin noise is used instead of Simplex noise in the 3D and 4D cases to avoid
|
||||
// patent issues.
|
||||
static inline float simplexNoise3(double x, double y, double z)
|
||||
{
|
||||
return SimplexNoise1234::noise(x, y, z) * 0.5f + 0.5f;
|
||||
}
|
||||
|
||||
static inline float noise3(double x, double y, double z)
|
||||
static inline float simplexNoise4(double x, double y, double z, double w)
|
||||
{
|
||||
return SimplexNoise1234::noise(x, y, z, w) * 0.5f + 0.5f;
|
||||
}
|
||||
|
||||
static inline float perlinNoise1(double x)
|
||||
{
|
||||
return Noise1234::noise(x) * 0.5f + 0.5f;
|
||||
}
|
||||
|
||||
static inline float perlinNoise2(double x, double y)
|
||||
{
|
||||
return Noise1234::noise(x, y) * 0.5f + 0.5f;
|
||||
}
|
||||
|
||||
static inline float perlinNoise3(double x, double y, double z)
|
||||
{
|
||||
return Noise1234::noise(x, y, z) * 0.5f + 0.5f;
|
||||
}
|
||||
|
||||
static inline float noise4(double x, double y, double z, double w)
|
||||
static inline float perlinNoise4(double x, double y, double z, double w)
|
||||
{
|
||||
return Noise1234::noise(x, y, z, w) * 0.5f + 0.5f;
|
||||
}
|
||||
|
||||
@@ -329,16 +329,76 @@ int w_noise(lua_State *L)
|
||||
switch (nargs)
|
||||
{
|
||||
case 1:
|
||||
val = noise1(args[0]);
|
||||
val = simplexNoise1(args[0]);
|
||||
break;
|
||||
case 2:
|
||||
val = noise2(args[0], args[1]);
|
||||
val = simplexNoise2(args[0], args[1]);
|
||||
break;
|
||||
case 3:
|
||||
val = noise3(args[0], args[1], args[2]);
|
||||
val = perlinNoise3(args[0], args[1], args[2]);
|
||||
break;
|
||||
case 4:
|
||||
val = noise4(args[0], args[1], args[2], args[3]);
|
||||
val = perlinNoise4(args[0], args[1], args[2], args[3]);
|
||||
break;
|
||||
}
|
||||
|
||||
lua_pushnumber(L, (lua_Number) val);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int w_perlinNoise(lua_State* L)
|
||||
{
|
||||
int nargs = std::min(std::max(lua_gettop(L), 1), 4);
|
||||
double args[4];
|
||||
|
||||
for (int i = 0; i < nargs; i++)
|
||||
args[i] = luaL_checknumber(L, i + 1);
|
||||
|
||||
float val = 0.0f;
|
||||
|
||||
switch (nargs)
|
||||
{
|
||||
case 1:
|
||||
val = perlinNoise1(args[0]);
|
||||
break;
|
||||
case 2:
|
||||
val = perlinNoise2(args[0], args[1]);
|
||||
break;
|
||||
case 3:
|
||||
val = perlinNoise3(args[0], args[1], args[2]);
|
||||
break;
|
||||
case 4:
|
||||
val = perlinNoise4(args[0], args[1], args[2], args[3]);
|
||||
break;
|
||||
}
|
||||
|
||||
lua_pushnumber(L, (lua_Number) val);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int w_simplexNoise(lua_State* L)
|
||||
{
|
||||
int nargs = std::min(std::max(lua_gettop(L), 1), 4);
|
||||
double args[4];
|
||||
|
||||
for (int i = 0; i < nargs; i++)
|
||||
args[i] = luaL_checknumber(L, i + 1);
|
||||
|
||||
float val = 0.0f;
|
||||
|
||||
switch (nargs)
|
||||
{
|
||||
case 1:
|
||||
val = simplexNoise1(args[0]);
|
||||
break;
|
||||
case 2:
|
||||
val = simplexNoise2(args[0], args[1]);
|
||||
break;
|
||||
case 3:
|
||||
val = simplexNoise3(args[0], args[1], args[2]);
|
||||
break;
|
||||
case 4:
|
||||
val = simplexNoise4(args[0], args[1], args[2], args[3]);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -349,10 +409,14 @@ int w_noise(lua_State *L)
|
||||
// C functions in a struct, necessary for the FFI versions of math functions.
|
||||
struct FFI_Math
|
||||
{
|
||||
float (*noise1)(double x);
|
||||
float (*noise2)(double x, double y);
|
||||
float (*noise3)(double x, double y, double z);
|
||||
float (*noise4)(double x, double y, double z, double w);
|
||||
float (*snoise1)(double x);
|
||||
float (*snoise2)(double x, double y);
|
||||
float (*snoise3)(double x, double y, double z);
|
||||
float (*snoise4)(double x, double y, double z, double w);
|
||||
float (*pnoise1)(double x);
|
||||
float (*pnoise2)(double x, double y);
|
||||
float (*pnoise3)(double x, double y, double z);
|
||||
float (*pnoise4)(double x, double y, double z, double w);
|
||||
|
||||
float (*gammaToLinear)(float c);
|
||||
float (*linearToGamma)(float c);
|
||||
@@ -360,10 +424,15 @@ struct FFI_Math
|
||||
|
||||
static FFI_Math ffifuncs =
|
||||
{
|
||||
noise1,
|
||||
noise2,
|
||||
noise3,
|
||||
noise4,
|
||||
simplexNoise1,
|
||||
simplexNoise2,
|
||||
simplexNoise3,
|
||||
simplexNoise4,
|
||||
|
||||
perlinNoise1,
|
||||
perlinNoise2,
|
||||
perlinNoise3,
|
||||
perlinNoise4,
|
||||
|
||||
gammaToLinear,
|
||||
linearToGamma,
|
||||
@@ -383,6 +452,8 @@ static const luaL_Reg functions[] =
|
||||
{ "gammaToLinear", w_gammaToLinear },
|
||||
{ "linearToGamma", w_linearToGamma },
|
||||
{ "noise", w_noise },
|
||||
{ "perlinNoise", w_perlinNoise },
|
||||
{ "simplexNoise", w_simplexNoise },
|
||||
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
@@ -93,10 +93,14 @@ if not status then return end
|
||||
pcall(ffi.cdef, [[
|
||||
typedef struct FFI_Math
|
||||
{
|
||||
float (*noise1)(double x);
|
||||
float (*noise2)(double x, double y);
|
||||
float (*noise3)(double x, double y, double z);
|
||||
float (*noise4)(double x, double y, double z, double w);
|
||||
float (*snoise1)(double x);
|
||||
float (*snoise2)(double x, double y);
|
||||
float (*snoise3)(double x, double y, double z);
|
||||
float (*snoise4)(double x, double y, double z, double w);
|
||||
float (*pnoise1)(double x);
|
||||
float (*pnoise2)(double x, double y);
|
||||
float (*pnoise3)(double x, double y, double z);
|
||||
float (*pnoise4)(double x, double y, double z, double w);
|
||||
|
||||
float (*gammaToLinear)(float c);
|
||||
float (*linearToGamma)(float c);
|
||||
@@ -110,13 +114,37 @@ local ffifuncs = ffi.cast("FFI_Math **", ffifuncspointer_str)[0]
|
||||
|
||||
function love_math.noise(x, y, z, w)
|
||||
if w ~= nil then
|
||||
return tonumber(ffifuncs.noise4(x, y, z, w))
|
||||
return tonumber(ffifuncs.pnoise4(x, y, z, w))
|
||||
elseif z ~= nil then
|
||||
return tonumber(ffifuncs.noise3(x, y, z))
|
||||
return tonumber(ffifuncs.pnoise3(x, y, z))
|
||||
elseif y ~= nil then
|
||||
return tonumber(ffifuncs.noise2(x, y))
|
||||
return tonumber(ffifuncs.snoise2(x, y))
|
||||
else
|
||||
return tonumber(ffifuncs.noise1(x))
|
||||
return tonumber(ffifuncs.snoise1(x))
|
||||
end
|
||||
end
|
||||
|
||||
function love_math.perlinNoise(x, y, z, w)
|
||||
if w ~= nil then
|
||||
return tonumber(ffifuncs.pnoise4(x, y, z, w))
|
||||
elseif z ~= nil then
|
||||
return tonumber(ffifuncs.pnoise3(x, y, z))
|
||||
elseif y ~= nil then
|
||||
return tonumber(ffifuncs.pnoise2(x, y))
|
||||
else
|
||||
return tonumber(ffifuncs.pnoise1(x))
|
||||
end
|
||||
end
|
||||
|
||||
function love_math.simplexNoise(x, y, z, w)
|
||||
if w ~= nil then
|
||||
return tonumber(ffifuncs.snoise4(x, y, z, w))
|
||||
elseif z ~= nil then
|
||||
return tonumber(ffifuncs.snoise3(x, y, z))
|
||||
elseif y ~= nil then
|
||||
return tonumber(ffifuncs.snoise2(x, y))
|
||||
else
|
||||
return tonumber(ffifuncs.snoise1(x))
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user