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"
26 ///////////////////////////////////////
31 LuaPerlinNoise::LuaPerlinNoise(NoiseParams *params) :
37 LuaPerlinNoise::~LuaPerlinNoise()
42 int LuaPerlinNoise::l_get2d(lua_State *L)
45 LuaPerlinNoise *o = checkobject(L, 1);
46 v2f p = check_v2f(L, 2);
47 lua_Number val = NoisePerlin2D(&o->np, p.X, p.Y, 0);
48 lua_pushnumber(L, val);
53 int LuaPerlinNoise::l_get3d(lua_State *L)
56 LuaPerlinNoise *o = checkobject(L, 1);
57 v3f p = check_v3f(L, 2);
58 lua_Number val = NoisePerlin3D(&o->np, p.X, p.Y, p.Z, 0);
59 lua_pushnumber(L, val);
64 int LuaPerlinNoise::create_object(lua_State *L)
70 if (lua_istable(L, 1)) {
71 read_noiseparams(L, 1, ¶ms);
73 params.seed = luaL_checkint(L, 1);
74 params.octaves = luaL_checkint(L, 2);
75 params.persist = luaL_checknumber(L, 3);
76 params.spread = v3f(1, 1, 1) * luaL_checknumber(L, 4);
79 LuaPerlinNoise *o = new LuaPerlinNoise(¶ms);
81 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
82 luaL_getmetatable(L, className);
83 lua_setmetatable(L, -2);
88 int LuaPerlinNoise::gc_object(lua_State *L)
90 LuaPerlinNoise *o = *(LuaPerlinNoise **)(lua_touserdata(L, 1));
96 LuaPerlinNoise *LuaPerlinNoise::checkobject(lua_State *L, int narg)
99 luaL_checktype(L, narg, LUA_TUSERDATA);
100 void *ud = luaL_checkudata(L, narg, className);
102 luaL_typerror(L, narg, className);
103 return *(LuaPerlinNoise **)ud;
107 void LuaPerlinNoise::Register(lua_State *L)
110 int methodtable = lua_gettop(L);
111 luaL_newmetatable(L, className);
112 int metatable = lua_gettop(L);
114 lua_pushliteral(L, "__metatable");
115 lua_pushvalue(L, methodtable);
116 lua_settable(L, metatable);
118 lua_pushliteral(L, "__index");
119 lua_pushvalue(L, methodtable);
120 lua_settable(L, metatable);
122 lua_pushliteral(L, "__gc");
123 lua_pushcfunction(L, gc_object);
124 lua_settable(L, metatable);
128 luaL_openlib(L, 0, methods, 0);
131 lua_register(L, className, create_object);
135 const char LuaPerlinNoise::className[] = "PerlinNoise";
136 const luaL_reg LuaPerlinNoise::methods[] = {
137 luamethod(LuaPerlinNoise, get2d),
138 luamethod(LuaPerlinNoise, get3d),
142 ///////////////////////////////////////
147 LuaPerlinNoiseMap::LuaPerlinNoiseMap(NoiseParams *params, int seed, v3s16 size)
152 noise = new Noise(&np, seed, size.X, size.Y, size.Z);
153 } catch (InvalidNoiseParamsException &e) {
154 throw LuaError(e.what());
159 LuaPerlinNoiseMap::~LuaPerlinNoiseMap()
165 int LuaPerlinNoiseMap::l_get2dMap(lua_State *L)
167 NO_MAP_LOCK_REQUIRED;
170 LuaPerlinNoiseMap *o = checkobject(L, 1);
171 v2f p = check_v2f(L, 2);
174 n->perlinMap2D(p.X, p.Y);
177 for (u32 y = 0; y != n->sy; y++) {
179 for (u32 x = 0; x != n->sx; x++) {
180 lua_pushnumber(L, n->result[i++]);
181 lua_rawseti(L, -2, x + 1);
183 lua_rawseti(L, -2, y + 1);
189 int LuaPerlinNoiseMap::l_get2dMap_flat(lua_State *L)
191 NO_MAP_LOCK_REQUIRED;
193 LuaPerlinNoiseMap *o = checkobject(L, 1);
194 v2f p = check_v2f(L, 2);
195 bool use_buffer = lua_istable(L, 3);
198 n->perlinMap2D(p.X, p.Y);
200 size_t maplen = n->sx * n->sy;
207 for (size_t i = 0; i != maplen; i++) {
208 lua_pushnumber(L, n->result[i]);
209 lua_rawseti(L, -2, i + 1);
215 int LuaPerlinNoiseMap::l_get3dMap(lua_State *L)
217 NO_MAP_LOCK_REQUIRED;
220 LuaPerlinNoiseMap *o = checkobject(L, 1);
221 v3f p = check_v3f(L, 2);
227 n->perlinMap3D(p.X, p.Y, p.Z);
230 for (u32 z = 0; z != n->sz; z++) {
232 for (u32 y = 0; y != n->sy; y++) {
234 for (u32 x = 0; x != n->sx; x++) {
235 lua_pushnumber(L, n->result[i++]);
236 lua_rawseti(L, -2, x + 1);
238 lua_rawseti(L, -2, y + 1);
240 lua_rawseti(L, -2, z + 1);
246 int LuaPerlinNoiseMap::l_get3dMap_flat(lua_State *L)
248 NO_MAP_LOCK_REQUIRED;
250 LuaPerlinNoiseMap *o = checkobject(L, 1);
251 v3f p = check_v3f(L, 2);
252 bool use_buffer = lua_istable(L, 3);
258 n->perlinMap3D(p.X, p.Y, p.Z);
260 size_t maplen = n->sx * n->sy * n->sz;
267 for (size_t i = 0; i != maplen; i++) {
268 lua_pushnumber(L, n->result[i]);
269 lua_rawseti(L, -2, i + 1);
275 int LuaPerlinNoiseMap::l_calc2dMap(lua_State *L)
277 NO_MAP_LOCK_REQUIRED;
279 LuaPerlinNoiseMap *o = checkobject(L, 1);
280 v2f p = check_v2f(L, 2);
283 n->perlinMap2D(p.X, p.Y);
288 int LuaPerlinNoiseMap::l_calc3dMap(lua_State *L)
290 NO_MAP_LOCK_REQUIRED;
292 LuaPerlinNoiseMap *o = checkobject(L, 1);
293 v3f p = check_v3f(L, 2);
299 n->perlinMap3D(p.X, p.Y, p.Z);
305 int LuaPerlinNoiseMap::l_getMapSlice(lua_State *L)
307 NO_MAP_LOCK_REQUIRED;
309 LuaPerlinNoiseMap *o = checkobject(L, 1);
310 v3s16 slice_offset = read_v3s16(L, 2);
311 v3s16 slice_size = read_v3s16(L, 3);
312 bool use_buffer = lua_istable(L, 4);
321 write_array_slice_float(L, lua_gettop(L), n->result,
322 v3u16(n->sx, n->sy, n->sz),
323 v3u16(slice_offset.X, slice_offset.Y, slice_offset.Z),
324 v3u16(slice_size.X, slice_size.Y, slice_size.Z));
330 int LuaPerlinNoiseMap::create_object(lua_State *L)
333 if (!read_noiseparams(L, 1, &np))
335 v3s16 size = read_v3s16(L, 2);
337 LuaPerlinNoiseMap *o = new LuaPerlinNoiseMap(&np, 0, size);
338 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
339 luaL_getmetatable(L, className);
340 lua_setmetatable(L, -2);
345 int LuaPerlinNoiseMap::gc_object(lua_State *L)
347 LuaPerlinNoiseMap *o = *(LuaPerlinNoiseMap **)(lua_touserdata(L, 1));
353 LuaPerlinNoiseMap *LuaPerlinNoiseMap::checkobject(lua_State *L, int narg)
355 luaL_checktype(L, narg, LUA_TUSERDATA);
357 void *ud = luaL_checkudata(L, narg, className);
359 luaL_typerror(L, narg, className);
361 return *(LuaPerlinNoiseMap **)ud;
365 void LuaPerlinNoiseMap::Register(lua_State *L)
368 int methodtable = lua_gettop(L);
369 luaL_newmetatable(L, className);
370 int metatable = lua_gettop(L);
372 lua_pushliteral(L, "__metatable");
373 lua_pushvalue(L, methodtable);
374 lua_settable(L, metatable);
376 lua_pushliteral(L, "__index");
377 lua_pushvalue(L, methodtable);
378 lua_settable(L, metatable);
380 lua_pushliteral(L, "__gc");
381 lua_pushcfunction(L, gc_object);
382 lua_settable(L, metatable);
386 luaL_openlib(L, 0, methods, 0);
389 lua_register(L, className, create_object);
393 const char LuaPerlinNoiseMap::className[] = "PerlinNoiseMap";
394 const luaL_reg LuaPerlinNoiseMap::methods[] = {
395 luamethod(LuaPerlinNoiseMap, get2dMap),
396 luamethod(LuaPerlinNoiseMap, get2dMap_flat),
397 luamethod(LuaPerlinNoiseMap, calc2dMap),
398 luamethod(LuaPerlinNoiseMap, get3dMap),
399 luamethod(LuaPerlinNoiseMap, get3dMap_flat),
400 luamethod(LuaPerlinNoiseMap, calc3dMap),
401 luamethod(LuaPerlinNoiseMap, getMapSlice),
405 ///////////////////////////////////////
410 int LuaPseudoRandom::l_next(lua_State *L)
412 NO_MAP_LOCK_REQUIRED;
413 LuaPseudoRandom *o = checkobject(L, 1);
417 if (lua_isnumber(L, 2))
418 min = luaL_checkinteger(L, 2);
419 if (lua_isnumber(L, 3))
420 max = luaL_checkinteger(L, 3);
422 errorstream<<"PseudoRandom.next(): max="<<max<<" min="<<min<<std::endl;
423 throw LuaError("PseudoRandom.next(): max < min");
425 if(max - min != 32767 && max - min > 32767/5)
426 throw LuaError("PseudoRandom.next() max-min is not 32767"
427 " and is > 32768/5. This is disallowed due to"
428 " the bad random distribution the"
429 " implementation would otherwise make.");
430 PseudoRandom &pseudo = o->m_pseudo;
431 int val = pseudo.next();
432 val = (val % (max-min+1)) + min;
433 lua_pushinteger(L, val);
438 int LuaPseudoRandom::create_object(lua_State *L)
440 int seed = luaL_checknumber(L, 1);
441 LuaPseudoRandom *o = new LuaPseudoRandom(seed);
442 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
443 luaL_getmetatable(L, className);
444 lua_setmetatable(L, -2);
449 int LuaPseudoRandom::gc_object(lua_State *L)
451 LuaPseudoRandom *o = *(LuaPseudoRandom **)(lua_touserdata(L, 1));
457 LuaPseudoRandom *LuaPseudoRandom::checkobject(lua_State *L, int narg)
459 luaL_checktype(L, narg, LUA_TUSERDATA);
460 void *ud = luaL_checkudata(L, narg, className);
462 luaL_typerror(L, narg, className);
463 return *(LuaPseudoRandom **)ud;
467 void LuaPseudoRandom::Register(lua_State *L)
470 int methodtable = lua_gettop(L);
471 luaL_newmetatable(L, className);
472 int metatable = lua_gettop(L);
474 lua_pushliteral(L, "__metatable");
475 lua_pushvalue(L, methodtable);
476 lua_settable(L, metatable);
478 lua_pushliteral(L, "__index");
479 lua_pushvalue(L, methodtable);
480 lua_settable(L, metatable);
482 lua_pushliteral(L, "__gc");
483 lua_pushcfunction(L, gc_object);
484 lua_settable(L, metatable);
488 luaL_openlib(L, 0, methods, 0);
491 lua_register(L, className, create_object);
495 const char LuaPseudoRandom::className[] = "PseudoRandom";
496 const luaL_reg LuaPseudoRandom::methods[] = {
497 luamethod(LuaPseudoRandom, next),
501 ///////////////////////////////////////
506 int LuaPcgRandom::l_next(lua_State *L)
508 NO_MAP_LOCK_REQUIRED;
510 LuaPcgRandom *o = checkobject(L, 1);
511 u32 min = lua_isnumber(L, 2) ? lua_tointeger(L, 2) : o->m_rnd.RANDOM_MIN;
512 u32 max = lua_isnumber(L, 3) ? lua_tointeger(L, 3) : o->m_rnd.RANDOM_MAX;
514 lua_pushinteger(L, o->m_rnd.range(min, max));
519 int LuaPcgRandom::l_rand_normal_dist(lua_State *L)
521 NO_MAP_LOCK_REQUIRED;
523 LuaPcgRandom *o = checkobject(L, 1);
524 u32 min = lua_isnumber(L, 2) ? lua_tointeger(L, 2) : o->m_rnd.RANDOM_MIN;
525 u32 max = lua_isnumber(L, 3) ? lua_tointeger(L, 3) : o->m_rnd.RANDOM_MAX;
526 int num_trials = lua_isnumber(L, 4) ? lua_tointeger(L, 4) : 6;
528 lua_pushinteger(L, o->m_rnd.randNormalDist(min, max, num_trials));
533 int LuaPcgRandom::create_object(lua_State *L)
535 lua_Integer seed = luaL_checknumber(L, 1);
536 LuaPcgRandom *o = lua_isnumber(L, 2) ?
537 new LuaPcgRandom(seed, lua_tointeger(L, 2)) :
538 new LuaPcgRandom(seed);
539 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
540 luaL_getmetatable(L, className);
541 lua_setmetatable(L, -2);
546 int LuaPcgRandom::gc_object(lua_State *L)
548 LuaPcgRandom *o = *(LuaPcgRandom **)(lua_touserdata(L, 1));
554 LuaPcgRandom *LuaPcgRandom::checkobject(lua_State *L, int narg)
556 luaL_checktype(L, narg, LUA_TUSERDATA);
557 void *ud = luaL_checkudata(L, narg, className);
559 luaL_typerror(L, narg, className);
560 return *(LuaPcgRandom **)ud;
564 void LuaPcgRandom::Register(lua_State *L)
567 int methodtable = lua_gettop(L);
568 luaL_newmetatable(L, className);
569 int metatable = lua_gettop(L);
571 lua_pushliteral(L, "__metatable");
572 lua_pushvalue(L, methodtable);
573 lua_settable(L, metatable);
575 lua_pushliteral(L, "__index");
576 lua_pushvalue(L, methodtable);
577 lua_settable(L, metatable);
579 lua_pushliteral(L, "__gc");
580 lua_pushcfunction(L, gc_object);
581 lua_settable(L, metatable);
585 luaL_openlib(L, 0, methods, 0);
588 lua_register(L, className, create_object);
592 const char LuaPcgRandom::className[] = "PcgRandom";
593 const luaL_reg LuaPcgRandom::methods[] = {
594 luamethod(LuaPcgRandom, next),
595 luamethod(LuaPcgRandom, rand_normal_dist),