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 "scriptapi.h"
21 #include "scriptapi_noise.h"
22 #include "scriptapi_types.h"
26 int LuaPerlinNoise::gc_object(lua_State *L)
28 LuaPerlinNoise *o = *(LuaPerlinNoise **)(lua_touserdata(L, 1));
33 int LuaPerlinNoise::l_get2d(lua_State *L)
35 LuaPerlinNoise *o = checkobject(L, 1);
36 v2f pos2d = read_v2f(L,2);
37 lua_Number val = noise2d_perlin(pos2d.X/o->scale, pos2d.Y/o->scale, o->seed, o->octaves, o->persistence);
38 lua_pushnumber(L, val);
41 int LuaPerlinNoise::l_get3d(lua_State *L)
43 LuaPerlinNoise *o = checkobject(L, 1);
44 v3f pos3d = read_v3f(L,2);
45 lua_Number val = noise3d_perlin(pos3d.X/o->scale, pos3d.Y/o->scale, pos3d.Z/o->scale, o->seed, o->octaves, o->persistence);
46 lua_pushnumber(L, val);
51 LuaPerlinNoise::LuaPerlinNoise(int a_seed, int a_octaves, float a_persistence,
55 persistence(a_persistence),
60 LuaPerlinNoise::~LuaPerlinNoise()
64 // LuaPerlinNoise(seed, octaves, persistence, scale)
65 // Creates an LuaPerlinNoise and leaves it on top of stack
66 int LuaPerlinNoise::create_object(lua_State *L)
68 int seed = luaL_checkint(L, 1);
69 int octaves = luaL_checkint(L, 2);
70 float persistence = luaL_checknumber(L, 3);
71 float scale = luaL_checknumber(L, 4);
72 LuaPerlinNoise *o = new LuaPerlinNoise(seed, octaves, persistence, scale);
73 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
74 luaL_getmetatable(L, className);
75 lua_setmetatable(L, -2);
79 LuaPerlinNoise* LuaPerlinNoise::checkobject(lua_State *L, int narg)
81 luaL_checktype(L, narg, LUA_TUSERDATA);
82 void *ud = luaL_checkudata(L, narg, className);
83 if(!ud) luaL_typerror(L, narg, className);
84 return *(LuaPerlinNoise**)ud; // unbox pointer
87 void LuaPerlinNoise::Register(lua_State *L)
90 int methodtable = lua_gettop(L);
91 luaL_newmetatable(L, className);
92 int metatable = lua_gettop(L);
94 lua_pushliteral(L, "__metatable");
95 lua_pushvalue(L, methodtable);
96 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
98 lua_pushliteral(L, "__index");
99 lua_pushvalue(L, methodtable);
100 lua_settable(L, metatable);
102 lua_pushliteral(L, "__gc");
103 lua_pushcfunction(L, gc_object);
104 lua_settable(L, metatable);
106 lua_pop(L, 1); // drop metatable
108 luaL_openlib(L, 0, methods, 0); // fill methodtable
109 lua_pop(L, 1); // drop methodtable
111 // Can be created from Lua (PerlinNoise(seed, octaves, persistence)
112 lua_register(L, className, create_object);
115 const char LuaPerlinNoise::className[] = "PerlinNoise";
116 const luaL_reg LuaPerlinNoise::methods[] = {
117 luamethod(LuaPerlinNoise, get2d),
118 luamethod(LuaPerlinNoise, get3d),
127 int LuaPerlinNoiseMap::gc_object(lua_State *L)
129 LuaPerlinNoiseMap *o = *(LuaPerlinNoiseMap **)(lua_touserdata(L, 1));
134 int LuaPerlinNoiseMap::l_get2dMap(lua_State *L)
138 LuaPerlinNoiseMap *o = checkobject(L, 1);
139 v2f p = read_v2f(L, 2);
142 n->perlinMap2D(p.X, p.Y);
145 for (int y = 0; y != n->sy; y++) {
147 for (int x = 0; x != n->sx; x++) {
148 float noiseval = n->np->offset + n->np->scale * n->result[i++];
149 lua_pushnumber(L, noiseval);
150 lua_rawseti(L, -2, x + 1);
152 lua_rawseti(L, -2, y + 1);
157 int LuaPerlinNoiseMap::l_get3dMap(lua_State *L)
161 LuaPerlinNoiseMap *o = checkobject(L, 1);
162 v3f p = read_v3f(L, 2);
165 n->perlinMap3D(p.X, p.Y, p.Z);
168 for (int z = 0; z != n->sz; z++) {
170 for (int y = 0; y != n->sy; y++) {
172 for (int x = 0; x != n->sx; x++) {
173 lua_pushnumber(L, n->np->offset + n->np->scale * n->result[i++]);
174 lua_rawseti(L, -2, x + 1);
176 lua_rawseti(L, -2, y + 1);
178 lua_rawseti(L, -2, z + 1);
183 LuaPerlinNoiseMap::LuaPerlinNoiseMap(NoiseParams *np, int seed, v3s16 size) {
184 noise = new Noise(np, seed, size.X, size.Y, size.Z);
187 LuaPerlinNoiseMap::~LuaPerlinNoiseMap()
193 // LuaPerlinNoiseMap(np, size)
194 // Creates an LuaPerlinNoiseMap and leaves it on top of stack
195 int LuaPerlinNoiseMap::create_object(lua_State *L)
197 NoiseParams *np = read_noiseparams(L, 1);
200 v3s16 size = read_v3s16(L, 2);
202 LuaPerlinNoiseMap *o = new LuaPerlinNoiseMap(np, 0, size);
203 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
204 luaL_getmetatable(L, className);
205 lua_setmetatable(L, -2);
209 LuaPerlinNoiseMap* LuaPerlinNoiseMap::checkobject(lua_State *L, int narg)
211 luaL_checktype(L, narg, LUA_TUSERDATA);
213 void *ud = luaL_checkudata(L, narg, className);
215 luaL_typerror(L, narg, className);
217 return *(LuaPerlinNoiseMap **)ud; // unbox pointer
220 void LuaPerlinNoiseMap::Register(lua_State *L)
223 int methodtable = lua_gettop(L);
224 luaL_newmetatable(L, className);
225 int metatable = lua_gettop(L);
227 lua_pushliteral(L, "__metatable");
228 lua_pushvalue(L, methodtable);
229 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
231 lua_pushliteral(L, "__index");
232 lua_pushvalue(L, methodtable);
233 lua_settable(L, metatable);
235 lua_pushliteral(L, "__gc");
236 lua_pushcfunction(L, gc_object);
237 lua_settable(L, metatable);
239 lua_pop(L, 1); // drop metatable
241 luaL_openlib(L, 0, methods, 0); // fill methodtable
242 lua_pop(L, 1); // drop methodtable
244 // Can be created from Lua (PerlinNoiseMap(np, size)
245 lua_register(L, className, create_object);
248 const char LuaPerlinNoiseMap::className[] = "PerlinNoiseMap";
249 const luaL_reg LuaPerlinNoiseMap::methods[] = {
250 luamethod(LuaPerlinNoiseMap, get2dMap),
251 luamethod(LuaPerlinNoiseMap, get3dMap),
258 NoiseParams *read_noiseparams(lua_State *L, int index)
261 index = lua_gettop(L) + 1 + index;
263 if (!lua_istable(L, index))
266 NoiseParams *np = new NoiseParams;
268 np->offset = getfloatfield_default(L, index, "offset", 0.0);
269 np->scale = getfloatfield_default(L, index, "scale", 0.0);
270 lua_getfield(L, index, "spread");
271 np->spread = read_v3f(L, -1);
273 np->seed = getintfield_default(L, index, "seed", 0);
274 np->octaves = getintfield_default(L, index, "octaves", 0);
275 np->persist = getfloatfield_default(L, index, "persist", 0.0);
286 int LuaPseudoRandom::gc_object(lua_State *L)
288 LuaPseudoRandom *o = *(LuaPseudoRandom **)(lua_touserdata(L, 1));
293 // next(self, min=0, max=32767) -> get next value
294 int LuaPseudoRandom::l_next(lua_State *L)
296 LuaPseudoRandom *o = checkobject(L, 1);
299 lua_settop(L, 3); // Fill 2 and 3 with nil if they don't exist
301 min = luaL_checkinteger(L, 2);
303 max = luaL_checkinteger(L, 3);
305 errorstream<<"PseudoRandom.next(): max="<<max<<" min="<<min<<std::endl;
306 throw LuaError(L, "PseudoRandom.next(): max < min");
308 if(max - min != 32767 && max - min > 32767/5)
309 throw LuaError(L, "PseudoRandom.next() max-min is not 32767 and is > 32768/5. This is disallowed due to the bad random distribution the implementation would otherwise make.");
310 PseudoRandom &pseudo = o->m_pseudo;
311 int val = pseudo.next();
312 val = (val % (max-min+1)) + min;
313 lua_pushinteger(L, val);
318 LuaPseudoRandom::LuaPseudoRandom(int seed):
323 LuaPseudoRandom::~LuaPseudoRandom()
327 const PseudoRandom& LuaPseudoRandom::getItem() const
331 PseudoRandom& LuaPseudoRandom::getItem()
336 // LuaPseudoRandom(seed)
337 // Creates an LuaPseudoRandom and leaves it on top of stack
338 int LuaPseudoRandom::create_object(lua_State *L)
340 int seed = luaL_checknumber(L, 1);
341 LuaPseudoRandom *o = new LuaPseudoRandom(seed);
342 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
343 luaL_getmetatable(L, className);
344 lua_setmetatable(L, -2);
348 LuaPseudoRandom* LuaPseudoRandom::checkobject(lua_State *L, int narg)
350 luaL_checktype(L, narg, LUA_TUSERDATA);
351 void *ud = luaL_checkudata(L, narg, className);
352 if(!ud) luaL_typerror(L, narg, className);
353 return *(LuaPseudoRandom**)ud; // unbox pointer
356 void LuaPseudoRandom::Register(lua_State *L)
359 int methodtable = lua_gettop(L);
360 luaL_newmetatable(L, className);
361 int metatable = lua_gettop(L);
363 lua_pushliteral(L, "__metatable");
364 lua_pushvalue(L, methodtable);
365 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
367 lua_pushliteral(L, "__index");
368 lua_pushvalue(L, methodtable);
369 lua_settable(L, metatable);
371 lua_pushliteral(L, "__gc");
372 lua_pushcfunction(L, gc_object);
373 lua_settable(L, metatable);
375 lua_pop(L, 1); // drop metatable
377 luaL_openlib(L, 0, methods, 0); // fill methodtable
378 lua_pop(L, 1); // drop methodtable
380 // Can be created from Lua (LuaPseudoRandom(seed))
381 lua_register(L, className, create_object);
384 const char LuaPseudoRandom::className[] = "PseudoRandom";
385 const luaL_reg LuaPseudoRandom::methods[] = {
386 luamethod(LuaPseudoRandom, next),