00001 #ifdef USE_LUGRE_LIB_PAGED_GEOMETRY
00002
00003 #include "lugre_prefix.h"
00004 #include "lugre_gfx3D.h"
00005 #include "lugre_scripting.h"
00006 #include "lugre_ogrewrapper.h"
00007 #include "lugre_input.h"
00008 #include "lugre_robstring.h"
00009 #include "lugre_luabind.h"
00010 #include "lugre_camera.h"
00011
00012 #include <Ogre.h>
00013
00014 #include "PagedGeometry.h"
00015 #include "BatchPage.h"
00016 #include "ImpostorPage.h"
00017 #include "GrassLoader.h"
00018 #include "TreeLoader3D.h"
00019
00020 extern "C" {
00021 #include "lua.h"
00022 #include "lauxlib.h"
00023 #include "lualib.h"
00024 }
00025
00026 using namespace Ogre;
00027
00028 namespace Lugre {
00029 class cGrassLayer_L : public cLuaBind<Forests::GrassLayer> { public:
00030
00031 virtual void RegisterMethods (lua_State *L) { PROFILE
00032 #define REGISTER_METHOD(methodname) mlMethod.push_back(make_luaL_reg(#methodname,&cGrassLayer_L::methodname));
00033
00034 REGISTER_METHOD(SetMaterialName);
00035 REGISTER_METHOD(SetMinimumSize);
00036 REGISTER_METHOD(SetMaximumSize);
00037 REGISTER_METHOD(SetDensity);
00038 REGISTER_METHOD(SetHeightRange);
00039 REGISTER_METHOD(SetDensityMapFileColor);
00040 REGISTER_METHOD(SetDensityMapFileAlpha);
00041 REGISTER_METHOD(SetDensityMapTextureColor);
00042 REGISTER_METHOD(SetDensityMapTextureAlpha);
00043 REGISTER_METHOD(SetDensityMapFilterBilinear);
00044 REGISTER_METHOD(SetColorMapFileColor);
00045 REGISTER_METHOD(SetColorMapTextureColor);
00046 REGISTER_METHOD(SetColorMapFilterBilinear);
00047 REGISTER_METHOD(SetMapBounds);
00048 REGISTER_METHOD(SetRenderTechniqueCrossquads);
00049 REGISTER_METHOD(SetFadeTechnique);
00050 REGISTER_METHOD(SetAnimationEnabled);
00051 REGISTER_METHOD(SetSwayLength);
00052 REGISTER_METHOD(SetSwaySpeed);
00053 REGISTER_METHOD(SetSwayDistribution);
00054
00055 #undef REGISTER_METHOD
00056 }
00057
00059 static int SetSwayLength (lua_State *L) { PROFILE
00060 checkudata_alive(L)->setSwayLength(luaL_checknumber(L,2));
00061 return 0;
00062 }
00063
00065 static int SetSwaySpeed (lua_State *L) { PROFILE
00066 checkudata_alive(L)->setSwaySpeed(luaL_checknumber(L,2));
00067 return 0;
00068 }
00069
00071 static int SetSwayDistribution (lua_State *L) { PROFILE
00072 checkudata_alive(L)->setSwayDistribution(luaL_checknumber(L,2));
00073 return 0;
00074 }
00075
00077 static int SetAnimationEnabled (lua_State *L) { PROFILE
00078 checkudata_alive(L)->setAnimationEnabled(luaL_checkbool(L,2));
00079 return 0;
00080 }
00081
00083 static int SetRenderTechniqueCrossquads (lua_State *L) { PROFILE
00084 bool bb = (lua_gettop(L) >= 3 && !lua_isnil(L,3)) ? luaL_checkbool(L,3) : false;
00085 checkudata_alive(L)->setRenderTechnique(luaL_checkbool(L,2) ? Forests::GRASSTECH_CROSSQUADS : Forests::GRASSTECH_QUAD, bb);
00086 return 0;
00087 }
00088
00090 static int SetFadeTechnique (lua_State *L) { PROFILE
00091 bool a = luaL_checkbool(L,2);
00092 bool b = luaL_checkbool(L,3);
00093
00094 if(a && b) checkudata_alive(L)->setFadeTechnique(Forests::FADETECH_ALPHAGROW);
00095 else if(a) checkudata_alive(L)->setFadeTechnique(Forests::FADETECH_ALPHA);
00096 else checkudata_alive(L)->setFadeTechnique(Forests::FADETECH_GROW);
00097
00098 return 0;
00099 }
00100
00102 static int SetMapBounds (lua_State *L) { PROFILE
00103 checkudata_alive(L)->setMapBounds( Ogre::TRect<Ogre::Real>(luaL_checknumber(L,2),luaL_checknumber(L,3),luaL_checknumber(L,4),luaL_checknumber(L,5)) );
00104 return 0;
00105 }
00106
00108 static int SetColorMapFileColor (lua_State *L) { PROFILE
00109 checkudata_alive(L)->setColorMap(std::string(luaL_checkstring(L,2)),Forests::CHANNEL_COLOR);
00110 return 0;
00111 }
00112
00114 static int SetColorMapTextureColor (lua_State *L) { PROFILE
00115 checkudata_alive(L)->setColorMap(Ogre::TextureManager::getSingleton().load(luaL_checkstring(L,2),Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME),Forests::CHANNEL_COLOR);
00116 return 0;
00117 }
00118
00120 static int SetDensityMapFilterBilinear (lua_State *L) { PROFILE
00121 checkudata_alive(L)->setDensityMapFilter(luaL_checkbool(L,2) ? Forests::MAPFILTER_BILINEAR : Forests::MAPFILTER_NONE);
00122 return 0;
00123 }
00124
00126 static int SetColorMapFilterBilinear (lua_State *L) { PROFILE
00127 checkudata_alive(L)->setColorMapFilter(luaL_checkbool(L,2) ? Forests::MAPFILTER_BILINEAR : Forests::MAPFILTER_NONE);
00128 return 0;
00129 }
00130
00132 static int SetDensityMapTextureColor (lua_State *L) { PROFILE
00133 checkudata_alive(L)->setDensityMap(Ogre::TextureManager::getSingleton().load(luaL_checkstring(L,2),Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME),Forests::CHANNEL_COLOR);
00134 return 0;
00135 }
00136
00138 static int SetDensityMapTextureAlpha (lua_State *L) { PROFILE
00139 checkudata_alive(L)->setDensityMap(Ogre::TextureManager::getSingleton().load(luaL_checkstring(L,2),Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME),Forests::CHANNEL_ALPHA);
00140 return 0;
00141 }
00142
00144 static int SetDensityMapFileColor (lua_State *L) { PROFILE
00145 checkudata_alive(L)->setDensityMap(std::string(luaL_checkstring(L,2)),Forests::CHANNEL_COLOR);
00146 return 0;
00147 }
00148
00150 static int SetDensityMapFileAlpha (lua_State *L) { PROFILE
00151 checkudata_alive(L)->setDensityMap(std::string(luaL_checkstring(L,2)),Forests::CHANNEL_ALPHA);
00152 return 0;
00153 }
00154
00156 static int SetMaterialName (lua_State *L) { PROFILE
00157 checkudata_alive(L)->setMaterialName(luaL_checkstring(L,2));
00158 return 0;
00159 }
00160
00162 static int SetMaximumSize (lua_State *L) { PROFILE
00163 checkudata_alive(L)->setMaximumSize(luaL_checknumber(L,2),luaL_checknumber(L,3));
00164 return 0;
00165 }
00166
00168 static int SetHeightRange (lua_State *L) { PROFILE
00169 checkudata_alive(L)->setHeightRange(luaL_checknumber(L,2),luaL_checknumber(L,3));
00170 return 0;
00171 }
00172
00174 static int SetMinimumSize (lua_State *L) { PROFILE
00175 checkudata_alive(L)->setMinimumSize(luaL_checknumber(L,2),luaL_checknumber(L,3));
00176 return 0;
00177 }
00178
00180 static int SetDensity (lua_State *L) { PROFILE
00181 checkudata_alive(L)->setDensity(luaL_checknumber(L,2));
00182 return 0;
00183 }
00184
00185 virtual const char* GetLuaTypeName () { return "lugre.paged_geometry.grasslayer"; }
00186 };
00187
00188
00189 class cTreeLoader3D_L : public cLuaBind<Forests::TreeLoader3D> { public:
00190
00191 virtual void RegisterMethods (lua_State *L) { PROFILE
00192 lua_register(L,"CreateTreeLoader3D", &cTreeLoader3D_L::CreateTreeLoader3D);
00193
00194 #define REGISTER_METHOD(methodname) mlMethod.push_back(make_luaL_reg(#methodname,&cTreeLoader3D_L::methodname));
00195
00196 REGISTER_METHOD(AddTree);
00197 REGISTER_METHOD(DeleteTrees);
00198 REGISTER_METHOD(AssignToPagedGeometry);
00199 REGISTER_METHOD(Destroy);
00200
00201 #undef REGISTER_METHOD
00202 }
00203 virtual const char* GetLuaTypeName () { return "lugre.paged_geometry.treeloader3d"; }
00204
00207 static int AddTree (lua_State *L) { PROFILE
00208 Ogre::Vector3 pos(luaL_checknumber(L,2),luaL_checknumber(L,3),luaL_checknumber(L,4));
00209 Ogre::Degree yaw(luaL_checknumber(L,5));
00210 Ogre::Real s(luaL_checknumber(L,6));
00211 cGfx3D *p = cLuaBind<cGfx3D>::checkudata_alive(L,7);
00212 if(p)checkudata_alive(L)->addTree(p->mpEntity,pos,yaw,s);
00213 return 0;
00214 }
00215
00217 static int DeleteTrees (lua_State *L) { PROFILE
00218 Ogre::Vector3 pos(luaL_checknumber(L,2),luaL_checknumber(L,3),luaL_checknumber(L,4));
00219 Ogre::Real radius(luaL_checknumber(L,5));
00220 checkudata_alive(L)->deleteTrees(pos,radius);
00221 return 0;
00222 }
00223
00225 static int AssignToPagedGeometry (lua_State *L) { PROFILE
00226 Forests::TreeLoader3D *l = checkudata_alive(L,1);
00227 Forests::PagedGeometry *p = cLuaBind<Forests::PagedGeometry>::checkudata_alive(L,2);
00228 p->setPageLoader(l);
00229 return 0;
00230 }
00231
00233 static int Destroy (lua_State *L) { PROFILE
00234 Forests::TreeLoader3D *p = checkudata_alive(L);
00235 delete p;
00236 return 0;
00237 }
00238
00241 static int CreateTreeLoader3D (lua_State *L) { PROFILE
00242 Forests::TBounds bounds(
00243 luaL_checknumber(L,2),luaL_checknumber(L,3),
00244 luaL_checknumber(L,4),luaL_checknumber(L,5)
00245 );
00246 Forests::TreeLoader3D *p = new Forests::TreeLoader3D(cLuaBind<Forests::PagedGeometry>::checkudata_alive(L), bounds);
00247 return CreateUData(L,p);
00248 }
00249 };
00250
00251
00252 class cGrassLoader_L : public cLuaBind<Forests::GrassLoader> { public:
00253
00254 virtual void RegisterMethods (lua_State *L) { PROFILE
00255 lua_register(L,"CreateGrassLoader", &cGrassLoader_L::CreateGrassLoader);
00256
00257 #define REGISTER_METHOD(methodname) mlMethod.push_back(make_luaL_reg(#methodname,&cGrassLoader_L::methodname));
00258
00259
00260 REGISTER_METHOD(AddLayer);
00261 REGISTER_METHOD(GetLayer);
00262 REGISTER_METHOD(SetWindDirection);
00263 REGISTER_METHOD(GetWindDirection);
00264 REGISTER_METHOD(SetDensityFactor);
00265 REGISTER_METHOD(GetDensityFactor);
00266 REGISTER_METHOD(SetHeightFunction);
00267 REGISTER_METHOD(AssignToPagedGeometry);
00268 REGISTER_METHOD(Destroy);
00269
00270 #undef REGISTER_METHOD
00271 }
00272
00273 class CallbackEnv { public:
00274 lua_State *L;
00275 int fun;
00276 };
00277
00278 static Ogre::Real HeightFunctionCallback (Ogre::Real x, Ogre::Real z, void *userData) {
00279 CallbackEnv *e = (CallbackEnv *)userData;
00280
00281 lua_rawgeti(e->L, LUA_REGISTRYINDEX, e->fun);
00282 lua_pushnumber(e->L, x);
00283 lua_pushnumber(e->L, z);
00284 lua_call(e->L, 2, 1);
00285 float r = luaL_checknumber(e->L,lua_gettop(e->L));
00286 lua_pop(e->L, 1);
00287 return r;
00288 }
00289
00291 static int SetHeightFunction (lua_State *L) { PROFILE
00292 Forests::GrassLoader *p = checkudata_alive(L);
00293 CallbackEnv *e = (CallbackEnv *)p->heightFunctionUserData;
00294
00295 if(e){
00296
00297 luaL_unref(e->L, LUA_REGISTRYINDEX, e->fun);
00298 } else {
00299 e = new CallbackEnv();
00300 p->heightFunctionUserData = e;
00301 }
00302
00303
00304 e->fun = luaL_ref(L, LUA_REGISTRYINDEX);
00305 e->L = L;
00306 lua_pop(L,1);
00307
00308 p->setHeightFunction(&HeightFunctionCallback,e);
00309
00310 return 0;
00311 }
00312
00313
00315
00316
00317
00318
00319
00320
00322 static int SetWindDirection (lua_State *L) { PROFILE
00323 Ogre::Vector3 dir = Ogre::Vector3( luaL_checknumber(L,2),luaL_checknumber(L,3),luaL_checknumber(L,4) );
00324 checkudata_alive(L)->setWindDirection( dir );
00325 return 0;
00326 }
00327
00329 static int AssignToPagedGeometry (lua_State *L) { PROFILE
00330 Forests::GrassLoader *l = checkudata_alive(L,1);
00331 Forests::PagedGeometry *p = cLuaBind<Forests::PagedGeometry>::checkudata_alive(L,2);
00332 p->setPageLoader(l);
00333 return 0;
00334 }
00335
00337 static int GetWindDirection (lua_State *L) { PROFILE
00338 Ogre::Vector3 dir = checkudata_alive(L)->getWindDirection();
00339
00340 lua_pushnumber(L,dir.x);
00341 lua_pushnumber(L,dir.y);
00342 lua_pushnumber(L,dir.z);
00343
00344 return 3;
00345 }
00346
00348 static int SetDensityFactor (lua_State *L) { PROFILE
00349 checkudata_alive(L)->setDensityFactor(luaL_checknumber(L,2));
00350 return 0;
00351 }
00352
00354 static int GetDensityFactor (lua_State *L) { PROFILE
00355 lua_pushnumber(L,checkudata_alive(L)->getDensityFactor());
00356 return 1;
00357 }
00358
00360 static int AddLayer (lua_State *L) { PROFILE
00361 return cLuaBind<Forests::GrassLayer>::CreateUData(L,checkudata_alive(L)->addLayer(std::string(luaL_checkstring(L,2))));
00362 }
00363
00365 static int GetLayer (lua_State *L) { PROFILE
00366 std::list<Forests::GrassLayer*> l = checkudata_alive(L)->getLayerList();
00367 int count = l.size();
00368 int index = luaL_checkint(L,2);
00369
00370 int pos = 0;
00371 for(std::list<Forests::GrassLayer*>::iterator it = l.begin(); it!=l.end(); ++it, ++pos)if(pos == index)return cLuaBind<Forests::GrassLayer>::CreateUData(L,*it);
00372
00373 return 0;
00374 }
00375
00376 virtual const char* GetLuaTypeName () { return "lugre.paged_geometry.grassloader"; }
00377
00378
00380 static int Destroy (lua_State *L) { PROFILE
00381 Forests::GrassLoader *p = checkudata_alive(L);
00382 CallbackEnv *e = (CallbackEnv *)p->heightFunctionUserData;
00383
00384 if(e){
00385
00386 luaL_unref(L, LUA_REGISTRYINDEX, e->fun);
00387 delete e;
00388 e = 0;
00389 }
00390
00391 delete p;
00392 return 0;
00393 }
00394
00396 static int CreateGrassLoader (lua_State *L) { PROFILE
00397 Forests::GrassLoader *p = new Forests::GrassLoader(cLuaBind<Forests::PagedGeometry>::checkudata_alive(L));
00398 p->setHeightFunction(0,0);
00399 return CreateUData(L,p);
00400 }
00401 };
00402
00403 class cPagedGeometry_L : public cLuaBind<Forests::PagedGeometry> { public:
00404
00405 virtual void RegisterMethods (lua_State *L) { PROFILE
00406 lua_register(L,"CreatePagedGeometry", &cPagedGeometry_L::CreatePagedGeometry);
00407
00408 #define REGISTER_METHOD(methodname) mlMethod.push_back(make_luaL_reg(#methodname,&cPagedGeometry_L::methodname));
00409
00410 REGISTER_METHOD(SetCamera);
00411 REGISTER_METHOD(SetPageSize);
00412 REGISTER_METHOD(GetPageSize);
00413 REGISTER_METHOD(AddDetailLevel);
00414 REGISTER_METHOD(RemoveDetailLevels);
00415
00416 REGISTER_METHOD(Update);
00417 REGISTER_METHOD(ReloadGeometry);
00418 REGISTER_METHOD(ReloadGeometryPage);
00419 REGISTER_METHOD(Destroy);
00420
00421 #undef REGISTER_METHOD
00422 }
00423
00424 virtual const char* GetLuaTypeName () { return "lugre.paged_geometry.paged_geometry"; }
00425
00427 static int CreatePagedGeometry (lua_State *L) { PROFILE
00428 if(lua_gettop(L) == 0)return CreateUData(L,new Forests::PagedGeometry());
00429 else {
00430 Ogre::Camera *cam = (lua_gettop(L) >= 1 && !lua_isnil(L,1)) ? cLuaBind<cCamera>::checkudata_alive(L,1)->mpCam : 0;
00431 Ogre::Real pageSize = (lua_gettop(L) >= 2 && !lua_isnil(L,2)) ? luaL_checknumber(L,2) : 100;
00432 return CreateUData(L,new Forests::PagedGeometry(cam,pageSize));
00433 }
00434
00435 }
00436
00438 static int SetCamera (lua_State *L) { PROFILE
00439 checkudata_alive(L)->setCamera(cLuaBind<cCamera>::checkudata_alive(L,2)->mpCam);
00440 return 0;
00441 }
00442
00444 static int RemoveDetailLevels (lua_State *L) { PROFILE
00445 checkudata_alive(L)->removeDetailLevels();
00446 return 0;
00447 }
00448
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00463 static int Update (lua_State *L) { PROFILE
00464 checkudata_alive(L)->update();
00465 return 0;
00466 }
00467
00469 static int AddDetailLevel (lua_State *L) { PROFILE
00470 const char* sPageTypeName = luaL_checkstring(L,2);
00471 Forests::PagedGeometry *p = checkudata_alive(L);
00472 Ogre::Real fMaxRange = luaL_checknumber(L,3);
00473 Ogre::Real fTransitionLength = (lua_gettop(L) >= 4 && !lua_isnil(L,4)) ? luaL_checknumber(L,4) : 0.0f;
00474
00475 if(strcmp(sPageTypeName,"batch") == 0) p->addDetailLevel<Forests::BatchPage>(fMaxRange,fTransitionLength);
00476 else p->addDetailLevel<Forests::ImpostorPage>(fMaxRange,fTransitionLength);
00477
00478 return 0;
00479 }
00480
00482 static int ReloadGeometry (lua_State *L) { PROFILE
00483 checkudata_alive(L)->reloadGeometry();
00484 return 0;
00485 }
00486
00488 static int ReloadGeometryPage (lua_State *L) { PROFILE
00489 checkudata_alive(L)->reloadGeometryPage(Ogre::Vector3(luaL_checknumber(L,2),luaL_checknumber(L,3),luaL_checknumber(L,4)));
00490 return 0;
00491 }
00492
00494 static int SetPageSize (lua_State *L) { PROFILE
00495 checkudata_alive(L)->setPageSize(luaL_checknumber(L,2));
00496 return 0;
00497 }
00498
00500 static int GetPageSize (lua_State *L) { PROFILE
00501 lua_pushnumber(L,checkudata_alive(L)->getPageSize());
00502 return 1;
00503 }
00504
00506 static int Destroy (lua_State *L) { PROFILE
00507 delete checkudata_alive(L);
00508 return 0;
00509 }
00510
00511 };
00512
00513
00514
00515
00516
00517
00518
00520 void LuaRegisterPagedGeometry (lua_State *L) { PROFILE
00521 cLuaBind<Forests::PagedGeometry>::GetSingletonPtr(new cPagedGeometry_L())->LuaRegister(L);
00522 cLuaBind<Forests::GrassLoader>::GetSingletonPtr(new cGrassLoader_L())->LuaRegister(L);
00523 cLuaBind<Forests::TreeLoader3D>::GetSingletonPtr(new cTreeLoader3D_L())->LuaRegister(L);
00524 cLuaBind<Forests::GrassLayer>::GetSingletonPtr(new cGrassLayer_L())->LuaRegister(L);
00525 }
00526 }
00527
00528
00529 #endif