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"
29 int LuaPerlinNoise::gc_object(lua_State *L)
31 LuaPerlinNoise *o = *(LuaPerlinNoise **)(lua_touserdata(L, 1));
36 int LuaPerlinNoise::l_get2d(lua_State *L)
38 LuaPerlinNoise *o = checkobject(L, 1);
39 v2f pos2d = read_v2f(L,2);
40 lua_Number val = noise2d_perlin(pos2d.X/o->scale, pos2d.Y/o->scale, o->seed, o->octaves, o->persistence);
41 lua_pushnumber(L, val);
44 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)
71 int seed = luaL_checkint(L, 1);
72 int octaves = luaL_checkint(L, 2);
73 float persistence = luaL_checknumber(L, 3);
74 float scale = luaL_checknumber(L, 4);
75 LuaPerlinNoise *o = new LuaPerlinNoise(seed, octaves, persistence, scale);
76 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
77 luaL_getmetatable(L, className);
78 lua_setmetatable(L, -2);
82 LuaPerlinNoise* LuaPerlinNoise::checkobject(lua_State *L, int narg)
84 luaL_checktype(L, narg, LUA_TUSERDATA);
85 void *ud = luaL_checkudata(L, narg, className);
86 if(!ud) luaL_typerror(L, narg, className);
87 return *(LuaPerlinNoise**)ud; // unbox pointer
90 void LuaPerlinNoise::Register(lua_State *L)
93 int methodtable = lua_gettop(L);
94 luaL_newmetatable(L, className);
95 int metatable = lua_gettop(L);
97 lua_pushliteral(L, "__metatable");
98 lua_pushvalue(L, methodtable);
99 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
101 lua_pushliteral(L, "__index");
102 lua_pushvalue(L, methodtable);
103 lua_settable(L, metatable);
105 lua_pushliteral(L, "__gc");
106 lua_pushcfunction(L, gc_object);
107 lua_settable(L, metatable);
109 lua_pop(L, 1); // drop metatable
111 luaL_openlib(L, 0, methods, 0); // fill methodtable
112 lua_pop(L, 1); // drop methodtable
114 // Can be created from Lua (PerlinNoise(seed, octaves, persistence)
115 lua_register(L, className, create_object);
118 const char LuaPerlinNoise::className[] = "PerlinNoise";
119 const luaL_reg LuaPerlinNoise::methods[] = {
120 luamethod(LuaPerlinNoise, get2d),
121 luamethod(LuaPerlinNoise, get3d),
130 int LuaPerlinNoiseMap::gc_object(lua_State *L)
132 LuaPerlinNoiseMap *o = *(LuaPerlinNoiseMap **)(lua_touserdata(L, 1));
137 int LuaPerlinNoiseMap::l_get2dMap(lua_State *L)
141 LuaPerlinNoiseMap *o = checkobject(L, 1);
142 v2f p = read_v2f(L, 2);
145 n->perlinMap2D(p.X, p.Y);
148 for (int y = 0; y != n->sy; y++) {
150 for (int x = 0; x != n->sx; x++) {
151 float noiseval = n->np->offset + n->np->scale * n->result[i++];
152 lua_pushnumber(L, noiseval);
153 lua_rawseti(L, -2, x + 1);
155 lua_rawseti(L, -2, y + 1);
160 int LuaPerlinNoiseMap::l_get3dMap(lua_State *L)
164 LuaPerlinNoiseMap *o = checkobject(L, 1);
165 v3f p = read_v3f(L, 2);
168 n->perlinMap3D(p.X, p.Y, p.Z);
171 for (int z = 0; z != n->sz; z++) {
173 for (int y = 0; y != n->sy; y++) {
175 for (int x = 0; x != n->sx; x++) {
176 lua_pushnumber(L, n->np->offset + n->np->scale * n->result[i++]);
177 lua_rawseti(L, -2, x + 1);
179 lua_rawseti(L, -2, y + 1);
181 lua_rawseti(L, -2, z + 1);
186 LuaPerlinNoiseMap::LuaPerlinNoiseMap(NoiseParams *np, int seed, v3s16 size) {
187 noise = new Noise(np, seed, size.X, size.Y, size.Z);
190 LuaPerlinNoiseMap::~LuaPerlinNoiseMap()
196 // LuaPerlinNoiseMap(np, size)
197 // Creates an LuaPerlinNoiseMap and leaves it on top of stack
198 int LuaPerlinNoiseMap::create_object(lua_State *L)
200 NoiseParams *np = read_noiseparams(L, 1);
203 v3s16 size = read_v3s16(L, 2);
205 LuaPerlinNoiseMap *o = new LuaPerlinNoiseMap(np, 0, size);
206 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
207 luaL_getmetatable(L, className);
208 lua_setmetatable(L, -2);
212 LuaPerlinNoiseMap* LuaPerlinNoiseMap::checkobject(lua_State *L, int narg)
214 luaL_checktype(L, narg, LUA_TUSERDATA);
216 void *ud = luaL_checkudata(L, narg, className);
218 luaL_typerror(L, narg, className);
220 return *(LuaPerlinNoiseMap **)ud; // unbox pointer
223 void LuaPerlinNoiseMap::Register(lua_State *L)
226 int methodtable = lua_gettop(L);
227 luaL_newmetatable(L, className);
228 int metatable = lua_gettop(L);
230 lua_pushliteral(L, "__metatable");
231 lua_pushvalue(L, methodtable);
232 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
234 lua_pushliteral(L, "__index");
235 lua_pushvalue(L, methodtable);
236 lua_settable(L, metatable);
238 lua_pushliteral(L, "__gc");
239 lua_pushcfunction(L, gc_object);
240 lua_settable(L, metatable);
242 lua_pop(L, 1); // drop metatable
244 luaL_openlib(L, 0, methods, 0); // fill methodtable
245 lua_pop(L, 1); // drop methodtable
247 // Can be created from Lua (PerlinNoiseMap(np, size)
248 lua_register(L, className, create_object);
251 const char LuaPerlinNoiseMap::className[] = "PerlinNoiseMap";
252 const luaL_reg LuaPerlinNoiseMap::methods[] = {
253 luamethod(LuaPerlinNoiseMap, get2dMap),
254 luamethod(LuaPerlinNoiseMap, get3dMap),
261 NoiseParams *read_noiseparams(lua_State *L, int index)
264 index = lua_gettop(L) + 1 + index;
266 if (!lua_istable(L, index))
269 NoiseParams *np = new NoiseParams;
271 np->offset = getfloatfield_default(L, index, "offset", 0.0);
272 np->scale = getfloatfield_default(L, index, "scale", 0.0);
273 lua_getfield(L, index, "spread");
274 np->spread = read_v3f(L, -1);
275 np->seed = getintfield_default(L, index, "seed", 0);
276 np->octaves = getintfield_default(L, index, "octaves", 0);
277 np->persist = getfloatfield_default(L, index, "persist", 0.0);
287 int LuaPseudoRandom::gc_object(lua_State *L)
289 LuaPseudoRandom *o = *(LuaPseudoRandom **)(lua_touserdata(L, 1));
294 // next(self, min=0, max=32767) -> get next value
295 int LuaPseudoRandom::l_next(lua_State *L)
297 LuaPseudoRandom *o = checkobject(L, 1);
300 lua_settop(L, 3); // Fill 2 and 3 with nil if they don't exist
302 min = luaL_checkinteger(L, 2);
304 max = luaL_checkinteger(L, 3);
306 errorstream<<"PseudoRandom.next(): max="<<max<<" min="<<min<<std::endl;
307 throw LuaError(L, "PseudoRandom.next(): max < min");
309 if(max - min != 32767 && max - min > 32767/5)
310 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.");
311 PseudoRandom &pseudo = o->m_pseudo;
312 int val = pseudo.next();
313 val = (val % (max-min+1)) + min;
314 lua_pushinteger(L, val);
319 LuaPseudoRandom::LuaPseudoRandom(int seed):
324 LuaPseudoRandom::~LuaPseudoRandom()
328 const PseudoRandom& LuaPseudoRandom::getItem() const
332 PseudoRandom& LuaPseudoRandom::getItem()
337 // LuaPseudoRandom(seed)
338 // Creates an LuaPseudoRandom and leaves it on top of stack
339 int LuaPseudoRandom::create_object(lua_State *L)
341 int seed = luaL_checknumber(L, 1);
342 LuaPseudoRandom *o = new LuaPseudoRandom(seed);
343 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
344 luaL_getmetatable(L, className);
345 lua_setmetatable(L, -2);
349 LuaPseudoRandom* LuaPseudoRandom::checkobject(lua_State *L, int narg)
351 luaL_checktype(L, narg, LUA_TUSERDATA);
352 void *ud = luaL_checkudata(L, narg, className);
353 if(!ud) luaL_typerror(L, narg, className);
354 return *(LuaPseudoRandom**)ud; // unbox pointer
357 void LuaPseudoRandom::Register(lua_State *L)
360 int methodtable = lua_gettop(L);
361 luaL_newmetatable(L, className);
362 int metatable = lua_gettop(L);
364 lua_pushliteral(L, "__metatable");
365 lua_pushvalue(L, methodtable);
366 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
368 lua_pushliteral(L, "__index");
369 lua_pushvalue(L, methodtable);
370 lua_settable(L, metatable);
372 lua_pushliteral(L, "__gc");
373 lua_pushcfunction(L, gc_object);
374 lua_settable(L, metatable);
376 lua_pop(L, 1); // drop metatable
378 luaL_openlib(L, 0, methods, 0); // fill methodtable
379 lua_pop(L, 1); // drop methodtable
381 // Can be created from Lua (LuaPseudoRandom(seed))
382 lua_register(L, className, create_object);
385 const char LuaPseudoRandom::className[] = "PseudoRandom";
386 const luaL_reg LuaPseudoRandom::methods[] = {
387 luamethod(LuaPseudoRandom, next),