3 Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include "lua_api/l_noise.h"
21 #include "lua_api/l_internal.h"
22 #include "common/c_converter.h"
23 #include "common/c_content.h"
27 int LuaPerlinNoise::gc_object(lua_State *L)
29 LuaPerlinNoise *o = *(LuaPerlinNoise **)(lua_touserdata(L, 1));
34 int LuaPerlinNoise::l_get2d(lua_State *L)
37 LuaPerlinNoise *o = checkobject(L, 1);
38 v2f pos2d = read_v2f(L,2);
39 lua_Number val = noise2d_perlin(pos2d.X/o->scale, pos2d.Y/o->scale, o->seed, o->octaves, o->persistence);
40 lua_pushnumber(L, val);
43 int LuaPerlinNoise::l_get3d(lua_State *L)
46 LuaPerlinNoise *o = checkobject(L, 1);
47 v3f pos3d = read_v3f(L,2);
48 lua_Number val = noise3d_perlin(pos3d.X/o->scale, pos3d.Y/o->scale, pos3d.Z/o->scale, o->seed, o->octaves, o->persistence);
49 lua_pushnumber(L, val);
54 LuaPerlinNoise::LuaPerlinNoise(int a_seed, int a_octaves, float a_persistence,
58 persistence(a_persistence),
63 LuaPerlinNoise::~LuaPerlinNoise()
67 // LuaPerlinNoise(seed, octaves, persistence, scale)
68 // Creates an LuaPerlinNoise and leaves it on top of stack
69 int LuaPerlinNoise::create_object(lua_State *L)
72 int seed = luaL_checkint(L, 1);
73 int octaves = luaL_checkint(L, 2);
74 float persistence = luaL_checknumber(L, 3);
75 float scale = luaL_checknumber(L, 4);
76 LuaPerlinNoise *o = new LuaPerlinNoise(seed, octaves, persistence, scale);
77 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
78 luaL_getmetatable(L, className);
79 lua_setmetatable(L, -2);
83 LuaPerlinNoise* LuaPerlinNoise::checkobject(lua_State *L, int narg)
86 luaL_checktype(L, narg, LUA_TUSERDATA);
87 void *ud = luaL_checkudata(L, narg, className);
88 if(!ud) luaL_typerror(L, narg, className);
89 return *(LuaPerlinNoise**)ud; // unbox pointer
92 void LuaPerlinNoise::Register(lua_State *L)
95 int methodtable = lua_gettop(L);
96 luaL_newmetatable(L, className);
97 int metatable = lua_gettop(L);
99 lua_pushliteral(L, "__metatable");
100 lua_pushvalue(L, methodtable);
101 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
103 lua_pushliteral(L, "__index");
104 lua_pushvalue(L, methodtable);
105 lua_settable(L, metatable);
107 lua_pushliteral(L, "__gc");
108 lua_pushcfunction(L, gc_object);
109 lua_settable(L, metatable);
111 lua_pop(L, 1); // drop metatable
113 luaL_openlib(L, 0, methods, 0); // fill methodtable
114 lua_pop(L, 1); // drop methodtable
116 // Can be created from Lua (PerlinNoise(seed, octaves, persistence)
117 lua_register(L, className, create_object);
120 const char LuaPerlinNoise::className[] = "PerlinNoise";
121 const luaL_reg LuaPerlinNoise::methods[] = {
122 luamethod(LuaPerlinNoise, get2d),
123 luamethod(LuaPerlinNoise, get3d),
132 int LuaPerlinNoiseMap::gc_object(lua_State *L)
134 LuaPerlinNoiseMap *o = *(LuaPerlinNoiseMap **)(lua_touserdata(L, 1));
139 int LuaPerlinNoiseMap::l_get2dMap(lua_State *L)
141 NO_MAP_LOCK_REQUIRED;
144 LuaPerlinNoiseMap *o = checkobject(L, 1);
145 v2f p = read_v2f(L, 2);
148 n->perlinMap2D(p.X, p.Y);
151 for (int y = 0; y != n->sy; y++) {
153 for (int x = 0; x != n->sx; x++) {
154 float noiseval = n->np->offset + n->np->scale * n->result[i++];
155 lua_pushnumber(L, noiseval);
156 lua_rawseti(L, -2, x + 1);
158 lua_rawseti(L, -2, y + 1);
163 int LuaPerlinNoiseMap::l_get2dMap_flat(lua_State *L)
165 NO_MAP_LOCK_REQUIRED;
167 LuaPerlinNoiseMap *o = checkobject(L, 1);
168 v2f p = read_v2f(L, 2);
171 n->perlinMap2D(p.X, p.Y);
173 int maplen = n->sx * n->sy;
176 for (int i = 0; i != maplen; i++) {
177 float noiseval = n->np->offset + n->np->scale * n->result[i];
178 lua_pushnumber(L, noiseval);
179 lua_rawseti(L, -2, i + 1);
184 int LuaPerlinNoiseMap::l_get3dMap(lua_State *L)
186 NO_MAP_LOCK_REQUIRED;
189 LuaPerlinNoiseMap *o = checkobject(L, 1);
190 v3f p = read_v3f(L, 2);
193 n->perlinMap3D(p.X, p.Y, p.Z, n->np->eased);
196 for (int z = 0; z != n->sz; z++) {
198 for (int y = 0; y != n->sy; y++) {
200 for (int x = 0; x != n->sx; x++) {
201 lua_pushnumber(L, n->np->offset + n->np->scale * n->result[i++]);
202 lua_rawseti(L, -2, x + 1);
204 lua_rawseti(L, -2, y + 1);
206 lua_rawseti(L, -2, z + 1);
211 int LuaPerlinNoiseMap::l_get3dMap_flat(lua_State *L)
213 NO_MAP_LOCK_REQUIRED;
215 LuaPerlinNoiseMap *o = checkobject(L, 1);
216 v3f p = read_v3f(L, 2);
219 n->perlinMap3D(p.X, p.Y, p.Z, n->np->eased);
222 int maplen = n->sx * n->sy * n->sz;
225 for (int i = 0; i != maplen; i++) {
226 float noiseval = n->np->offset + n->np->scale * n->result[i];
227 lua_pushnumber(L, noiseval);
228 lua_rawseti(L, -2, i + 1);
233 LuaPerlinNoiseMap::LuaPerlinNoiseMap(NoiseParams *np, int seed, v3s16 size) {
235 noise = new Noise(np, seed, size.X, size.Y, size.Z);
236 } catch (InvalidNoiseParamsException &e) {
237 throw LuaError(e.what());
241 LuaPerlinNoiseMap::~LuaPerlinNoiseMap()
247 // LuaPerlinNoiseMap(np, size)
248 // Creates an LuaPerlinNoiseMap and leaves it on top of stack
249 int LuaPerlinNoiseMap::create_object(lua_State *L)
251 NoiseParams *np = read_noiseparams(L, 1);
254 v3s16 size = read_v3s16(L, 2);
256 LuaPerlinNoiseMap *o = new LuaPerlinNoiseMap(np, 0, size);
257 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
258 luaL_getmetatable(L, className);
259 lua_setmetatable(L, -2);
263 LuaPerlinNoiseMap* LuaPerlinNoiseMap::checkobject(lua_State *L, int narg)
265 luaL_checktype(L, narg, LUA_TUSERDATA);
267 void *ud = luaL_checkudata(L, narg, className);
269 luaL_typerror(L, narg, className);
271 return *(LuaPerlinNoiseMap **)ud; // unbox pointer
274 void LuaPerlinNoiseMap::Register(lua_State *L)
277 int methodtable = lua_gettop(L);
278 luaL_newmetatable(L, className);
279 int metatable = lua_gettop(L);
281 lua_pushliteral(L, "__metatable");
282 lua_pushvalue(L, methodtable);
283 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
285 lua_pushliteral(L, "__index");
286 lua_pushvalue(L, methodtable);
287 lua_settable(L, metatable);
289 lua_pushliteral(L, "__gc");
290 lua_pushcfunction(L, gc_object);
291 lua_settable(L, metatable);
293 lua_pop(L, 1); // drop metatable
295 luaL_openlib(L, 0, methods, 0); // fill methodtable
296 lua_pop(L, 1); // drop methodtable
298 // Can be created from Lua (PerlinNoiseMap(np, size)
299 lua_register(L, className, create_object);
302 const char LuaPerlinNoiseMap::className[] = "PerlinNoiseMap";
303 const luaL_reg LuaPerlinNoiseMap::methods[] = {
304 luamethod(LuaPerlinNoiseMap, get2dMap),
305 luamethod(LuaPerlinNoiseMap, get2dMap_flat),
306 luamethod(LuaPerlinNoiseMap, get3dMap),
307 luamethod(LuaPerlinNoiseMap, get3dMap_flat),
316 int LuaPseudoRandom::gc_object(lua_State *L)
318 LuaPseudoRandom *o = *(LuaPseudoRandom **)(lua_touserdata(L, 1));
323 // next(self, min=0, max=32767) -> get next value
324 int LuaPseudoRandom::l_next(lua_State *L)
326 NO_MAP_LOCK_REQUIRED;
327 LuaPseudoRandom *o = checkobject(L, 1);
330 lua_settop(L, 3); // Fill 2 and 3 with nil if they don't exist
332 min = luaL_checkinteger(L, 2);
334 max = luaL_checkinteger(L, 3);
336 errorstream<<"PseudoRandom.next(): max="<<max<<" min="<<min<<std::endl;
337 throw LuaError("PseudoRandom.next(): max < min");
339 if(max - min != 32767 && max - min > 32767/5)
340 throw LuaError("PseudoRandom.next() max-min is not 32767"
341 " and is > 32768/5. This is disallowed due to"
342 " the bad random distribution the"
343 " implementation would otherwise make.");
344 PseudoRandom &pseudo = o->m_pseudo;
345 int val = pseudo.next();
346 val = (val % (max-min+1)) + min;
347 lua_pushinteger(L, val);
352 LuaPseudoRandom::LuaPseudoRandom(int seed):
357 LuaPseudoRandom::~LuaPseudoRandom()
361 const PseudoRandom& LuaPseudoRandom::getItem() const
365 PseudoRandom& LuaPseudoRandom::getItem()
370 // LuaPseudoRandom(seed)
371 // Creates an LuaPseudoRandom and leaves it on top of stack
372 int LuaPseudoRandom::create_object(lua_State *L)
374 int seed = luaL_checknumber(L, 1);
375 LuaPseudoRandom *o = new LuaPseudoRandom(seed);
376 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
377 luaL_getmetatable(L, className);
378 lua_setmetatable(L, -2);
382 LuaPseudoRandom* LuaPseudoRandom::checkobject(lua_State *L, int narg)
384 luaL_checktype(L, narg, LUA_TUSERDATA);
385 void *ud = luaL_checkudata(L, narg, className);
386 if(!ud) luaL_typerror(L, narg, className);
387 return *(LuaPseudoRandom**)ud; // unbox pointer
390 void LuaPseudoRandom::Register(lua_State *L)
393 int methodtable = lua_gettop(L);
394 luaL_newmetatable(L, className);
395 int metatable = lua_gettop(L);
397 lua_pushliteral(L, "__metatable");
398 lua_pushvalue(L, methodtable);
399 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
401 lua_pushliteral(L, "__index");
402 lua_pushvalue(L, methodtable);
403 lua_settable(L, metatable);
405 lua_pushliteral(L, "__gc");
406 lua_pushcfunction(L, gc_object);
407 lua_settable(L, metatable);
409 lua_pop(L, 1); // drop metatable
411 luaL_openlib(L, 0, methods, 0); // fill methodtable
412 lua_pop(L, 1); // drop methodtable
414 // Can be created from Lua (LuaPseudoRandom(seed))
415 lua_register(L, className, create_object);
418 const char LuaPseudoRandom::className[] = "PseudoRandom";
419 const luaL_reg LuaPseudoRandom::methods[] = {
420 luamethod(LuaPseudoRandom, next),