1 /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2013 Robert Osfield
2 *
3 * This library is open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version. The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * OpenSceneGraph Public License for more details.
12 */
13
14 #include "LuaScriptEngine.h"
15
16 #include <osg/io_utils>
17 #include <osg/observer_ptr>
18 #include <osgDB/ReadFile>
19 #include <osgDB/WriteFile>
20
21 using namespace lua;
22
23
24
25
26 class LuaCallbackObject : public osg::CallbackObject
27 {
28 public:
LuaCallbackObject(const std::string & methodName,const LuaScriptEngine * lse,int ref)29 LuaCallbackObject(const std::string& methodName, const LuaScriptEngine* lse, int ref):_lse(lse),_ref(ref)
30 {
31 setName(methodName);
32 }
33
run(osg::Object * object,osg::Parameters & inputParameters,osg::Parameters & outputParameters) const34 virtual bool run(osg::Object* object, osg::Parameters& inputParameters, osg::Parameters& outputParameters) const
35 {
36 if (!_lse)
37 {
38 OSG_NOTICE << "Warning: Ignoring call to Lua by an expired callback" << std::endl;
39 return false;
40 }
41
42 // a strong reference is necessary as the lua call might trigger deletion of the LuaScriptEngine object
43 // avoid overhead by observer_ptr<>::lock as a race on run/destruction never is valid
44 osg::ref_ptr<const LuaScriptEngine> lse(_lse.get());
45
46 int topBeforeCall = lua_gettop(lse->getLuaState());
47
48 lua_rawgeti(lse->getLuaState(), LUA_REGISTRYINDEX, _ref);
49
50 int numInputs = 1;
51 lse->pushParameter(object);
52
53 for(osg::Parameters::iterator itr = inputParameters.begin();
54 itr != inputParameters.end();
55 ++itr)
56 {
57 lse->pushParameter(itr->get());
58 ++numInputs;
59 }
60
61 if (lua_pcall(lse->getLuaState(), numInputs, LUA_MULTRET,0)!=0)
62 {
63 OSG_NOTICE<<"Lua error : "<<lua_tostring(lse->getLuaState(), -1)<<std::endl;
64 return false;
65 }
66
67 int topAfterCall = lua_gettop(lse->getLuaState());
68 int numReturns = topAfterCall-topBeforeCall;
69 for(int i=1; i<=numReturns; ++i)
70 {
71 outputParameters.insert(outputParameters.begin(), lse->popParameterObject());
72 }
73 return true;
74 }
75
getRef() const76 int getRef() const { return _ref; }
77
78 protected:
79
80 osg::observer_ptr<const LuaScriptEngine> _lse;
81 int _ref;
82 };
83
84
getProperty(lua_State * _lua)85 static int getProperty(lua_State * _lua)
86 {
87 const LuaScriptEngine* lse = reinterpret_cast<const LuaScriptEngine*>(lua_topointer(_lua, lua_upvalueindex(1)));
88
89 int n = lua_gettop(_lua); /* number of arguments */
90 if (n==2 && lua_type(_lua, 1)==LUA_TTABLE)
91 {
92 if (lua_type(_lua, 2)==LUA_TSTRING)
93 {
94 std::string propertyName = lua_tostring(_lua, 2);
95 osg::Object* object = lse->getObjectFromTable<osg::Object>(1);
96
97 return lse->pushPropertyToStack(object, propertyName);
98 }
99 }
100
101 OSG_NOTICE<<"Warning: Lua getProperty() not matched"<<std::endl;
102 return 0;
103 }
104
105
setProperty(lua_State * _lua)106 static int setProperty(lua_State* _lua)
107 {
108 const LuaScriptEngine* lse = reinterpret_cast<const LuaScriptEngine*>(lua_topointer(_lua, lua_upvalueindex(1)));
109
110 int n = lua_gettop(_lua); /* number of arguments */
111 if (n==3 && lua_type(_lua, 1)==LUA_TTABLE)
112 {
113 if (lua_type(_lua, 2)==LUA_TSTRING)
114 {
115 std::string propertyName = lua_tostring(_lua, 2);
116 osg::Object* object = lse->getObjectFromTable<osg::Object>(1);
117
118 return lse->setPropertyFromStack(object, propertyName);
119 }
120 }
121
122 OSG_NOTICE<<"Warning: Lua setProperty() not matched"<<std::endl;
123 return 0;
124 }
125
126 //////////////////////////////////////////////////////////////////////////////////////
127 //
128 // Vector container support
129 //
getContainerProperty(lua_State * _lua)130 static int getContainerProperty(lua_State * _lua)
131 {
132 const LuaScriptEngine* lse = reinterpret_cast<const LuaScriptEngine*>(lua_topointer(_lua, lua_upvalueindex(1)));
133
134 int n = lua_gettop(_lua); /* number of arguments */
135 if (n==2 && lua_type(_lua, 1)==LUA_TTABLE)
136 {
137 if (lua_type(_lua, 2)==LUA_TSTRING)
138 {
139 std::string propertyName = lua_tostring(_lua, 2);
140 osg::Object* object = lse->getObjectFromTable<osg::Object>(1);
141 std::string containerPropertyName = lse->getStringFromTable(1,"containerPropertyName");
142
143 return lse->pushPropertyToStack(object, propertyName);
144 }
145 else if (lua_type(_lua, 2)==LUA_TNUMBER)
146 {
147 double index = lua_tonumber(_lua, 2);
148 const osg::Object* object = lse->getObjectFromTable<osg::Object>(1);
149 std::string containerPropertyName = lse->getStringFromTable(1,"containerPropertyName");
150
151 // check to see if Object "is a" vector
152 osgDB::BaseSerializer::Type type;
153 osgDB::BaseSerializer* bs = lse->getClassInterface().getSerializer(object, containerPropertyName, type);
154 osgDB::VectorBaseSerializer* vs = dynamic_cast<osgDB::VectorBaseSerializer*>(bs);
155 if (vs)
156 {
157 const void* dataPtr = vs->getElement(*object, (unsigned int) index);
158 if (dataPtr)
159 {
160 SerializerScratchPad valuesp(vs->getElementType(), dataPtr, vs->getElementSize());
161 return lse->pushDataToStack(&valuesp);
162 }
163 else
164 {
165 lua_pushnil(_lua);
166 return 1;
167 }
168 }
169 }
170 }
171
172 OSG_NOTICE<<"Warning: Lua getContainerProperty() not matched"<<std::endl;
173 return 0;
174 }
175
176
setContainerProperty(lua_State * _lua)177 static int setContainerProperty(lua_State* _lua)
178 {
179 const LuaScriptEngine* lse = reinterpret_cast<const LuaScriptEngine*>(lua_topointer(_lua, lua_upvalueindex(1)));
180
181 int n = lua_gettop(_lua); /* number of arguments */
182 if (n==3 && lua_type(_lua, 1)==LUA_TTABLE)
183 {
184 if (lua_type(_lua, 2)==LUA_TSTRING)
185 {
186 std::string propertyName = lua_tostring(_lua, 2);
187 osg::Object* object = lse->getObjectFromTable<osg::Object>(1);
188 std::string containerPropertyName = lse->getStringFromTable(1,"containerPropertyName");
189
190 return lse->setPropertyFromStack(object, propertyName);
191 }
192 else if (lua_type(_lua, 2)==LUA_TNUMBER)
193 {
194 double index = lua_tonumber(_lua, 2);
195
196 osg::Object* object = lse->getObjectFromTable<osg::Object>(1);
197 std::string containerPropertyName = lse->getStringFromTable(1,"containerPropertyName");
198
199 // check to see if Object "is a" vector
200 osgDB::BaseSerializer::Type type;
201 osgDB::BaseSerializer* bs = lse->getClassInterface().getSerializer(object, containerPropertyName, type);
202 osgDB::VectorBaseSerializer* vs = dynamic_cast<osgDB::VectorBaseSerializer*>(bs);
203 if (vs)
204 {
205 SerializerScratchPad ssp;
206 lse->getDataFromStack(&ssp, vs->getElementType(), 3);
207 {
208 vs->setElement(*object, (unsigned int) index, ssp.data);
209 }
210 }
211 return 0;
212 }
213 }
214
215 OSG_NOTICE<<"Warning: Lua setContainerProperty() not matched"<<std::endl;
216 return 0;
217 }
218
getContainerSize(lua_State * _lua)219 static int getContainerSize(lua_State* _lua)
220 {
221 const LuaScriptEngine* lse = reinterpret_cast<const LuaScriptEngine*>(lua_topointer(_lua, lua_upvalueindex(1)));
222 int n = lua_gettop(_lua); /* number of arguments */
223 if (n<1 || lua_type(_lua, 1)!=LUA_TTABLE) return 0;
224
225 osg::Object* object = lse->getObjectFromTable<osg::Object>(1);
226 std::string containerPropertyName = lse->getStringFromTable(1,"containerPropertyName");
227
228 // check to see if Object "is a" vector
229 osgDB::BaseSerializer::Type type;
230 osgDB::BaseSerializer* bs = lse->getClassInterface().getSerializer(object, containerPropertyName, type);
231 osgDB::VectorBaseSerializer* vs = dynamic_cast<osgDB::VectorBaseSerializer*>(bs);
232 if (vs)
233 {
234 lua_pushinteger(lse->getLuaState(), vs->size(*object));
235 return 1;
236 }
237
238 return 0;
239 }
240
callVectorClear(lua_State * _lua)241 static int callVectorClear(lua_State* _lua)
242 {
243 const LuaScriptEngine* lse = reinterpret_cast<const LuaScriptEngine*>(lua_topointer(_lua, lua_upvalueindex(1)));
244 int n = lua_gettop(_lua); /* number of arguments */
245 if (n<1 || lua_type(_lua, 1)!=LUA_TTABLE) return 0;
246
247 osg::Object* object = lse->getObjectFromTable<osg::Object>(1);
248 std::string containerPropertyName = lse->getStringFromTable(1,"containerPropertyName");
249
250 // check to see if Object "is a" vector
251 osgDB::BaseSerializer::Type type;
252 osgDB::BaseSerializer* bs = lse->getClassInterface().getSerializer(object, containerPropertyName, type);
253 osgDB::VectorBaseSerializer* vs = dynamic_cast<osgDB::VectorBaseSerializer*>(bs);
254 if (vs)
255 {
256 vs->clear(*object);
257 return 0;
258 }
259
260 return 0;
261 }
262
callVectorResize(lua_State * _lua)263 static int callVectorResize(lua_State* _lua)
264 {
265 const LuaScriptEngine* lse = reinterpret_cast<const LuaScriptEngine*>(lua_topointer(_lua, lua_upvalueindex(1)));
266 int n = lua_gettop(_lua); /* number of arguments */
267 if (n<2 || lua_type(_lua, 1)!=LUA_TTABLE || lua_type(_lua, 2)!=LUA_TNUMBER) return 0;
268
269 double numElements = lua_tonumber(lse->getLuaState(),2);
270 osg::Object* object = lse->getObjectFromTable<osg::Object>(1);
271 std::string containerPropertyName = lse->getStringFromTable(1,"containerPropertyName");
272
273 // check to see if Object "is a" vector
274 osgDB::BaseSerializer::Type type;
275 osgDB::BaseSerializer* bs = lse->getClassInterface().getSerializer(object, containerPropertyName, type);
276 osgDB::VectorBaseSerializer* vs = dynamic_cast<osgDB::VectorBaseSerializer*>(bs);
277 if (vs)
278 {
279 vs->resize(*object, static_cast<unsigned int>(numElements));
280 }
281
282 return 0;
283 }
284
callVectorReserve(lua_State * _lua)285 static int callVectorReserve(lua_State* _lua)
286 {
287 const LuaScriptEngine* lse = reinterpret_cast<const LuaScriptEngine*>(lua_topointer(_lua, lua_upvalueindex(1)));
288 int n = lua_gettop(_lua); /* number of arguments */
289 if (n<2 || lua_type(_lua, 1)!=LUA_TTABLE || lua_type(_lua, 2)!=LUA_TNUMBER) return 0;
290
291 double numElements = lua_tonumber(lse->getLuaState(),2);
292 osg::Object* object = lse->getObjectFromTable<osg::Object>(1);
293 std::string containerPropertyName = lse->getStringFromTable(1,"containerPropertyName");
294
295 // check to see if Object "is a" vector
296 osgDB::BaseSerializer::Type type;
297 osgDB::BaseSerializer* bs = lse->getClassInterface().getSerializer(object, containerPropertyName, type);
298 osgDB::VectorBaseSerializer* vs = dynamic_cast<osgDB::VectorBaseSerializer*>(bs);
299 if (vs)
300 {
301 vs->reserve(*object, static_cast<unsigned int>(numElements));
302 }
303
304 return 0;
305 }
306
307
callVectorAdd(lua_State * _lua)308 static int callVectorAdd(lua_State* _lua)
309 {
310 const LuaScriptEngine* lse = reinterpret_cast<const LuaScriptEngine*>(lua_topointer(_lua, lua_upvalueindex(1)));
311 int n = lua_gettop(_lua); /* number of arguments */
312 if (n<2 || lua_type(_lua, 1)!=LUA_TTABLE) return 0;
313
314 osg::Object* object = lse->getObjectFromTable<osg::Object>(1);
315 std::string containerPropertyName = lse->getStringFromTable(1,"containerPropertyName");
316
317 // check to see if Object "is a" vector
318 osgDB::BaseSerializer::Type type;
319 osgDB::BaseSerializer* bs = lse->getClassInterface().getSerializer(object, containerPropertyName, type);
320 osgDB::VectorBaseSerializer* vs = dynamic_cast<osgDB::VectorBaseSerializer*>(bs);
321 if (vs)
322 {
323 SerializerScratchPad ssp;
324 lse->getDataFromStack(&ssp, vs->getElementType(), 2);
325
326 if (ssp.dataType==vs->getElementType())
327 {
328 vs->addElement(*object, ssp.data);
329 }
330 else
331 {
332 OSG_NOTICE<<"Failed to match table type"<<std::endl;
333 }
334
335 }
336
337 return 0;
338 }
339
340 //////////////////////////////////////////////////////////////////////////////////////
341 //
342 // Map container support
343 //
getMapProperty(lua_State * _lua)344 static int getMapProperty(lua_State * _lua)
345 {
346 const LuaScriptEngine* lse = reinterpret_cast<const LuaScriptEngine*>(lua_topointer(_lua, lua_upvalueindex(1)));
347
348 int n = lua_gettop(_lua); /* number of arguments */
349 if (n==2 && lua_type(_lua, 1)==LUA_TTABLE)
350 {
351 if (lua_type(_lua, 2)==LUA_TSTRING)
352 {
353 std::string propertyName = lua_tostring(_lua, 2);
354 osg::Object* object = lse->getObjectFromTable<osg::Object>(1);
355 std::string containerPropertyName = lse->getStringFromTable(1,"containerPropertyName");
356
357 return lse->pushPropertyToStack(object, propertyName);
358 }
359 else
360 {
361 const osg::Object* object = lse->getObjectFromTable<osg::Object>(1);
362 std::string containerPropertyName = lse->getStringFromTable(1,"containerPropertyName");
363
364 // check to see if Object "is a" vector
365 osgDB::BaseSerializer::Type type;
366 osgDB::BaseSerializer* bs = lse->getClassInterface().getSerializer(object, containerPropertyName, type);
367 osgDB::MapBaseSerializer* ms = dynamic_cast<osgDB::MapBaseSerializer*>(bs);
368
369 if (ms)
370 {
371 SerializerScratchPad keysp;
372 lse->getDataFromStack(&keysp, ms->getKeyType(),2);
373 if (keysp.dataType==ms->getKeyType())
374 {
375 const void* dataPtr = ms->getElement(*object, keysp.data);
376 if (dataPtr)
377 {
378 SerializerScratchPad valuesp(ms->getElementType(), dataPtr, ms->getElementSize());
379 return lse->pushDataToStack(&valuesp);
380 }
381 else
382 {
383 lua_pushnil(_lua);
384 return 1;
385 }
386
387 return 0;
388 }
389 }
390 }
391 }
392
393 OSG_NOTICE<<"Warning: Lua getMapProperty() not matched"<<std::endl;
394 return 0;
395 }
396
397
setMapProperty(lua_State * _lua)398 static int setMapProperty(lua_State* _lua)
399 {
400 const LuaScriptEngine* lse = reinterpret_cast<const LuaScriptEngine*>(lua_topointer(_lua, lua_upvalueindex(1)));
401
402 int n = lua_gettop(_lua); /* number of arguments */
403
404 if (n==3 && lua_type(_lua, 1)==LUA_TTABLE)
405 {
406 if (lua_type(_lua, 2)==LUA_TSTRING)
407 {
408 std::string propertyName = lua_tostring(_lua, 2);
409 osg::Object* object = lse->getObjectFromTable<osg::Object>(1);
410 std::string containerPropertyName = lse->getStringFromTable(1,"containerPropertyName");
411
412 return lse->setPropertyFromStack(object, propertyName);
413 }
414 else
415 {
416 osg::Object* object = lse->getObjectFromTable<osg::Object>(1);
417 std::string containerPropertyName = lse->getStringFromTable(1,"containerPropertyName");
418
419 // check to see if Object "is a" vector
420 osgDB::BaseSerializer::Type type;
421 osgDB::BaseSerializer* bs = lse->getClassInterface().getSerializer(object, containerPropertyName, type);
422 osgDB::MapBaseSerializer* ms = dynamic_cast<osgDB::MapBaseSerializer*>(bs);
423
424 if (ms)
425 {
426 SerializerScratchPad keysp, valuesp;
427 lse->getDataFromStack(&keysp, ms->getKeyType(),2);
428 lse->getDataFromStack(&valuesp, ms->getElementType(),3);
429 if (keysp.dataType==ms->getKeyType() && ms->getElementType()==valuesp.dataType)
430 {
431 ms->setElement(*object, keysp.data, valuesp.data);
432 return 0;
433 }
434 else
435 {
436 OSG_NOTICE<<"Warning: Lua setMapProperty() : Failed to matched map element "<<std::endl;
437 OSG_NOTICE<<" keysp.dataType="<<keysp.dataType<<std::endl;
438 OSG_NOTICE<<" valuesp.dataType="<<valuesp.dataType<<std::endl;
439 return 0;
440 }
441
442 }
443 }
444 }
445
446 OSG_NOTICE<<"Warning: Lua setMapProperty() not matched"<<std::endl;
447 return 0;
448 }
449
callMapClear(lua_State * _lua)450 static int callMapClear(lua_State* _lua)
451 {
452 const LuaScriptEngine* lse = reinterpret_cast<const LuaScriptEngine*>(lua_topointer(_lua, lua_upvalueindex(1)));
453 int n = lua_gettop(_lua); /* number of arguments */
454 if (n<1 || lua_type(_lua, 1)!=LUA_TTABLE) return 0;
455
456 osg::Object* object = lse->getObjectFromTable<osg::Object>(1);
457 std::string containerPropertyName = lse->getStringFromTable(1,"containerPropertyName");
458
459 // check to see if Object "is a" vector
460 osgDB::BaseSerializer::Type type;
461 osgDB::BaseSerializer* bs = lse->getClassInterface().getSerializer(object, containerPropertyName, type);
462 osgDB::MapBaseSerializer* ms = dynamic_cast<osgDB::MapBaseSerializer*>(bs);
463 if (ms)
464 {
465 ms->clear(*object);
466 return 0;
467 }
468
469 return 0;
470 }
471
getMapSize(lua_State * _lua)472 static int getMapSize(lua_State* _lua)
473 {
474 const LuaScriptEngine* lse = reinterpret_cast<const LuaScriptEngine*>(lua_topointer(_lua, lua_upvalueindex(1)));
475 int n = lua_gettop(_lua); /* number of arguments */
476 if (n<1 || lua_type(_lua, 1)!=LUA_TTABLE) return 0;
477
478 osg::Object* object = lse->getObjectFromTable<osg::Object>(1);
479 std::string containerPropertyName = lse->getStringFromTable(1,"containerPropertyName");
480
481 // check to see if Object "is a" vector
482 osgDB::BaseSerializer::Type type;
483 osgDB::BaseSerializer* bs = lse->getClassInterface().getSerializer(object, containerPropertyName, type);
484 osgDB::MapBaseSerializer* ms = dynamic_cast<osgDB::MapBaseSerializer*>(bs);
485 if (ms)
486 {
487 lua_pushinteger(lse->getLuaState(), ms->size(*object));
488 return 1;
489 }
490
491 return 0;
492 }
493
494
createMapIterator(lua_State * _lua)495 static int createMapIterator(lua_State* _lua)
496 {
497 const LuaScriptEngine* lse = reinterpret_cast<const LuaScriptEngine*>(lua_topointer(_lua, lua_upvalueindex(1)));
498 int n = lua_gettop(_lua); /* number of arguments */
499 if (n<1 || lua_type(_lua, 1)!=LUA_TTABLE) return 0;
500
501 osg::Object* object = lse->getObjectFromTable<osg::Object>(1);
502 std::string containerPropertyName = lse->getStringFromTable(1,"containerPropertyName");
503
504 // check to see if Object "is a" vector
505 osgDB::BaseSerializer::Type type;
506 osgDB::BaseSerializer* bs = lse->getClassInterface().getSerializer(object, containerPropertyName, type);
507 osgDB::MapBaseSerializer* ms = dynamic_cast<osgDB::MapBaseSerializer*>(bs);
508 if (ms)
509 {
510 lse->pushObject(ms->createIterator(*object));
511 return 1;
512 }
513
514 return 0;
515 }
516
createMapReverseIterator(lua_State * _lua)517 static int createMapReverseIterator(lua_State* _lua)
518 {
519 const LuaScriptEngine* lse = reinterpret_cast<const LuaScriptEngine*>(lua_topointer(_lua, lua_upvalueindex(1)));
520 int n = lua_gettop(_lua); /* number of arguments */
521 if (n<1 || lua_type(_lua, 1)!=LUA_TTABLE) return 0;
522
523 osg::Object* object = lse->getObjectFromTable<osg::Object>(1);
524 std::string containerPropertyName = lse->getStringFromTable(1,"containerPropertyName");
525
526 // check to see if Object "is a" vector
527 osgDB::BaseSerializer::Type type;
528 osgDB::BaseSerializer* bs = lse->getClassInterface().getSerializer(object, containerPropertyName, type);
529 osgDB::MapBaseSerializer* ms = dynamic_cast<osgDB::MapBaseSerializer*>(bs);
530 if (ms)
531 {
532 lse->pushObject(ms->createReverseIterator(*object));
533 return 1;
534 }
535
536 return 0;
537 }
538
539 //////////////////////////////////////////////////////////////////////////////////////
540 //
541 // MapIteratorObject support
542 //
callMapIteratorAdvance(lua_State * _lua)543 static int callMapIteratorAdvance(lua_State* _lua)
544 {
545 const LuaScriptEngine* lse = reinterpret_cast<const LuaScriptEngine*>(lua_topointer(_lua, lua_upvalueindex(1)));
546 if (lua_gettop(_lua)<1 || lua_type(_lua, 1)!=LUA_TTABLE) return 0;
547 osgDB::MapIteratorObject* mio = lse->getObjectFromTable<osgDB::MapIteratorObject>(1);
548 if (mio)
549 {
550 lua_pushboolean(lse->getLuaState(), mio->advance());
551 return 1;
552 }
553
554 return 0;
555 }
556
callMapIteratorValid(lua_State * _lua)557 static int callMapIteratorValid(lua_State* _lua)
558 {
559 const LuaScriptEngine* lse = reinterpret_cast<const LuaScriptEngine*>(lua_topointer(_lua, lua_upvalueindex(1)));
560 if (lua_gettop(_lua)<1 || lua_type(_lua, 1)!=LUA_TTABLE) return 0;
561 osgDB::MapIteratorObject* mio = lse->getObjectFromTable<osgDB::MapIteratorObject>(1);
562 if (mio)
563 {
564 lua_pushboolean(lse->getLuaState(), mio->valid());
565 return 1;
566 }
567
568 return 0;
569 }
570
getMapIteratorKey(lua_State * _lua)571 static int getMapIteratorKey(lua_State* _lua)
572 {
573 const LuaScriptEngine* lse = reinterpret_cast<const LuaScriptEngine*>(lua_topointer(_lua, lua_upvalueindex(1)));
574 if (lua_gettop(_lua)<1 || lua_type(_lua, 1)!=LUA_TTABLE) return 0;
575 osgDB::MapIteratorObject* mio = lse->getObjectFromTable<osgDB::MapIteratorObject>(1);
576 if (mio)
577 {
578 const void* dataPtr = mio->getKey();
579 if (dataPtr)
580 {
581 SerializerScratchPad valuesp(mio->getKeyType(), dataPtr, mio->getKeySize());
582 return lse->pushDataToStack(&valuesp);
583 }
584 else
585 {
586 lua_pushnil(_lua);
587 return 1;
588 }
589 }
590
591 return 0;
592 }
593
getMapIteratorElement(lua_State * _lua)594 static int getMapIteratorElement(lua_State* _lua)
595 {
596 const LuaScriptEngine* lse = reinterpret_cast<const LuaScriptEngine*>(lua_topointer(_lua, lua_upvalueindex(1)));
597 if (lua_gettop(_lua)<1 || lua_type(_lua, 1)!=LUA_TTABLE) return 0;
598 osgDB::MapIteratorObject* mio = lse->getObjectFromTable<osgDB::MapIteratorObject>(1);
599 if (mio)
600 {
601 const void* dataPtr = mio->getElement();
602 if (dataPtr)
603 {
604 SerializerScratchPad valuesp(mio->getElementType(), dataPtr, mio->getElementSize());
605 return lse->pushDataToStack(&valuesp);
606 }
607 else
608 {
609 lua_pushnil(_lua);
610 return 1;
611 }
612 }
613 OSG_NOTICE<<"getMapIteratorElement failed. "<<std::endl;
614 return 0;
615 }
616
617
setMapIteratorElement(lua_State * _lua)618 static int setMapIteratorElement(lua_State* _lua)
619 {
620 const LuaScriptEngine* lse = reinterpret_cast<const LuaScriptEngine*>(lua_topointer(_lua, lua_upvalueindex(1)));
621 if (lua_gettop(_lua)<2 || lua_type(_lua, 1)!=LUA_TTABLE) return 0;
622 osgDB::MapIteratorObject* mio = lse->getObjectFromTable<osgDB::MapIteratorObject>(1);
623 if (mio)
624 {
625 SerializerScratchPad valuesp;
626 lse->getDataFromStack(&valuesp, mio->getElementType(), 2);
627
628 if (mio->getElementType()==valuesp.dataType)
629 {
630 mio->setElement(valuesp.data);
631 return 0;
632 }
633 else
634 {
635 OSG_NOTICE<<"Warning: Lua setMapIteratorElement() : Failed to matched map element type, valuesp.dataType="<<valuesp.dataType<<std::endl;
636 return 0;
637 }
638 }
639
640 return 0;
641 }
642
643
644 //////////////////////////////////////////////////////////////////////////////////////
645 //
646 // StateSet support
647 //
convertStringToStateAttributeValue(const std::string & valueString,osg::StateAttribute::OverrideValue defaultValue,bool & setOnOff)648 static int convertStringToStateAttributeValue(const std::string& valueString, osg::StateAttribute::OverrideValue defaultValue, bool& setOnOff)
649 {
650 osg::StateAttribute::OverrideValue value=defaultValue;
651
652 if (valueString.find("ON")!=std::string::npos) { value = osg::StateAttribute::ON; setOnOff = true; }
653 if (valueString.find("OFF")!=std::string::npos) { value = osg::StateAttribute::OFF; setOnOff = true; }
654
655 if (valueString.find("OVERRIDE")!=std::string::npos) value = value | osg::StateAttribute::OVERRIDE;
656 if (valueString.find("PROTECTED")!=std::string::npos) value = value | osg::StateAttribute::PROTECTED;
657 if (valueString.find("INHERIT")!=std::string::npos) value = value | osg::StateAttribute::INHERIT;
658 return value;
659 }
660
convertStateAttributeValueToString(unsigned int value,bool withOnOffCheck)661 static std::string convertStateAttributeValueToString(unsigned int value, bool withOnOffCheck)
662 {
663 std::string valueString;
664 if (withOnOffCheck)
665 {
666 if ((value&osg::StateAttribute::ON)!=0) { if (!valueString.empty()) valueString.append(", "); valueString.append("ON"); }
667 else { if (!valueString.empty()) valueString.append(", "); valueString.append("OFF"); }
668 }
669 if ((value&osg::StateAttribute::OVERRIDE)!=0) { if (!valueString.empty()) valueString.append(", "); valueString.append("OVERRIDE"); }
670 if ((value&osg::StateAttribute::PROTECTED)!=0) { if (!valueString.empty()) valueString.append(", "); valueString.append("PROTECTED"); }
671 if ((value&osg::StateAttribute::INHERIT)!=0) { if (!valueString.empty()) valueString.append(", "); valueString.append("INHERIT"); }
672 return valueString;
673 }
674
callStateSetSet(lua_State * _lua)675 static int callStateSetSet(lua_State* _lua)
676 {
677 const LuaScriptEngine* lse = reinterpret_cast<const LuaScriptEngine*>(lua_topointer(_lua, lua_upvalueindex(1)));
678 int n = lua_gettop(_lua); /* number of arguments */
679 if (n<2 || lua_type(_lua, 1)!=LUA_TTABLE) return 0;
680
681 osg::StateSet* stateset = lse->getObjectFromTable<osg::StateSet>(1);
682 if (!stateset)
683 {
684 OSG_NOTICE<<"Warning: StateSet:add() can only be called on a StateSet"<<std::endl;
685 return 0;
686 }
687
688 if (lua_type(_lua,2)==LUA_TTABLE)
689 {
690 osg::Object* po = lse->getObjectFromTable<osg::Object>(2);
691 osg::StateAttribute* sa = dynamic_cast<osg::StateAttribute*>(po);
692 osg::Uniform* uniform = dynamic_cast<osg::Uniform*>(po);
693
694 osg::StateAttribute::OverrideValue value=osg::StateAttribute::ON;
695 bool setOnOff = false;
696 if (n>=3 && lua_type(_lua,3)==LUA_TSTRING)
697 {
698 value = convertStringToStateAttributeValue(lua_tostring(_lua, 3), value, setOnOff);
699 }
700
701 if (sa)
702 {
703 if (setOnOff)
704 {
705 if (sa->isTextureAttribute()) stateset->setTextureAttributeAndModes(0, sa, value);
706 else stateset->setAttributeAndModes(sa, value);
707 }
708 else
709 {
710 if (sa->isTextureAttribute()) stateset->setTextureAttribute(0, sa, value);
711 else stateset->setAttribute(sa, value);
712 }
713 return 0;
714 }
715 else if (uniform)
716 {
717 stateset->addUniform(uniform, value);
718 return 0;
719 }
720 }
721 else if (lua_type(_lua,2)==LUA_TNUMBER)
722 {
723 double index = lua_tonumber(_lua, 2);
724 if (n>=3)
725 {
726 if (lua_type(_lua,3)==LUA_TTABLE)
727 {
728 osg::Object* po = lse->getObjectFromTable<osg::Object>(3);
729 osg::StateAttribute* sa = dynamic_cast<osg::StateAttribute*>(po);
730
731 osg::StateAttribute::OverrideValue value=osg::StateAttribute::ON;
732 bool setOnOff = false;
733 if (n>=4 && lua_type(_lua,4)==LUA_TSTRING)
734 {
735 value = convertStringToStateAttributeValue(lua_tostring(_lua, 4), value, setOnOff);
736 }
737
738 if (sa)
739 {
740 if (setOnOff)
741 {
742 stateset->setTextureAttributeAndModes(static_cast<unsigned int>(index), sa, value);
743 }
744 else
745 {
746 stateset->setTextureAttribute(static_cast<unsigned int>(index), sa, value);
747 }
748 return 0;
749 }
750 }
751 else if (lua_type(_lua,3)==LUA_TSTRING)
752 {
753 std::string modeString = lua_tostring(_lua, 3);
754 GLenum mode = lse->lookUpGLenumValue(modeString);
755
756 osg::StateAttribute::OverrideValue value=osg::StateAttribute::ON;
757 bool setOnOff = false;
758 if (n>=4 && lua_type(_lua,4)==LUA_TSTRING)
759 {
760 value = convertStringToStateAttributeValue(lua_tostring(_lua, 4), value, setOnOff);
761 }
762 stateset->setTextureMode(static_cast<unsigned int>(index), mode, value);
763 return 0;
764 }
765 }
766 }
767 else if (lua_type(_lua,2)==LUA_TSTRING)
768 {
769 std::string key = lua_tostring(_lua, 2);
770 GLenum mode = lse->lookUpGLenumValue(key);
771 if (n>=3)
772 {
773 if (mode)
774 {
775 osg::StateAttribute::OverrideValue value=osg::StateAttribute::ON;
776 bool setOnOff = false;
777 if (lua_type(_lua,3)==LUA_TSTRING)
778 {
779 value = convertStringToStateAttributeValue(lua_tostring(_lua, 3), value, setOnOff);
780 }
781
782 stateset->setMode(mode, value);
783 return 0;
784 }
785 else
786 {
787 std::string value;
788 if (lua_type(_lua,3)==LUA_TSTRING)
789 {
790 value = lua_tostring(_lua, 3);
791 }
792 stateset->setDefine(key, value);
793 }
794 }
795 else
796 {
797 if (mode)
798 {
799 osg::StateAttribute::OverrideValue value=osg::StateAttribute::ON;
800 stateset->setMode(mode, value);
801 return 0;
802 }
803 else
804 {
805 stateset->setDefine(key);
806 }
807 }
808 }
809
810 OSG_NOTICE<<"Warning: StateSet:set() inappropriate parameters, use form:"<<std::endl;
811 OSG_NOTICE<<" StateSet:set(modestring [,value=\"ON,OFF,OVERRIDE,PROTECTED\"]); "<<std::endl;
812 OSG_NOTICE<<" StateSet:set(uniform [,value=\"ON,OFF,OVERRIDE,PROTECTED\"]); "<<std::endl;
813 OSG_NOTICE<<" StateSet:set(attribute [,value=\"ON,OFF,OVERRIDE,PROTECTED\"]); "<<std::endl;
814 OSG_NOTICE<<" StateSet:set(textureUnit, textureAttribute [,value=\"ON,OFF,OVERRIDE,PROTECTED\"]); "<<std::endl;
815 return 0;
816 }
817
callStateSetGet(lua_State * _lua)818 static int callStateSetGet(lua_State* _lua)
819 {
820 const LuaScriptEngine* lse = reinterpret_cast<const LuaScriptEngine*>(lua_topointer(_lua, lua_upvalueindex(1)));
821 int n = lua_gettop(_lua); /* number of arguments */
822 if (n<2 || lua_type(_lua, 1)!=LUA_TTABLE) return 0;
823
824 osg::StateSet* stateset = lse->getObjectFromTable<osg::StateSet>(1);
825 if (!stateset)
826 {
827 OSG_NOTICE<<"Warning: StateSet:get() can only be called on a StateSet"<<std::endl;
828 return 0;
829 }
830
831 if (lua_type(_lua,2)==LUA_TNUMBER)
832 {
833 if (n<3)
834 {
835 OSG_NOTICE<<"Warning: StateSet:get() must be in form get(textureUnit, ClassName|ModeName|ObjectName)"<<std::endl;
836 return 0;
837 }
838
839 unsigned int index = static_cast<unsigned int>(lua_tonumber(_lua, 2));
840 if (lua_type(_lua,3)==LUA_TTABLE)
841 {
842 osg::Object* po = lse->getObjectFromTable<osg::Object>(3);
843 osg::StateAttribute* sa = dynamic_cast<osg::StateAttribute*>(po);
844 if (sa && sa->isTextureAttribute())
845 {
846 if (stateset->getTextureAttributeList().size()>index)
847 {
848 const osg::StateSet::AttributeList& al = stateset->getTextureAttributeList()[index];
849 for(osg::StateSet::AttributeList::const_iterator itr = al.begin();
850 itr != al.end();
851 ++itr)
852 {
853 if (itr->second.first==sa)
854 {
855 lua_newtable(_lua);
856 lua_pushstring(_lua, "attribute"); lse->pushObject(itr->second.first.get()); lua_settable(_lua, -3);
857 lua_pushstring(_lua, "value"); lua_pushstring(_lua, convertStateAttributeValueToString(itr->second.second, false).c_str()); lua_settable(_lua, -3);
858 return 1;
859 }
860 }
861 }
862 OSG_NOTICE<<"Warning: StateSet:get() Could not find attribute : "<<sa->className()<<std::endl;
863 lua_pushnil(_lua);
864 return 1;
865 }
866 lua_pushnil(_lua);
867 return 1;
868 }
869 else if (lua_type(_lua,3)==LUA_TSTRING)
870 {
871 std::string value = lua_tostring(_lua, 3);
872 // need to look for attribute of mode with specified value
873 if (stateset->getTextureAttributeList().size()>index)
874 {
875 const osg::StateSet::AttributeList& al = stateset->getTextureAttributeList()[index];
876 for(osg::StateSet::AttributeList::const_iterator itr = al.begin();
877 itr != al.end();
878 ++itr)
879 {
880 if (value == itr->second.first->className() ||
881 value == itr->second.first->getName())
882 {
883 lua_newtable(_lua);
884 lua_pushstring(_lua, "attribute"); lse->pushObject(itr->second.first.get()); lua_settable(_lua, -3);
885 lua_pushstring(_lua, "value"); lua_pushstring(_lua, convertStateAttributeValueToString(itr->second.second, false).c_str()); lua_settable(_lua, -3);
886 return 1;
887 }
888 }
889 }
890 if (stateset->getTextureModeList().size()>index)
891 {
892 osg::StateAttribute::GLMode mode = lse->lookUpGLenumValue(value);
893 const osg::StateSet::ModeList& ml = stateset->getTextureModeList()[index];
894 for(osg::StateSet::ModeList::const_iterator itr = ml.begin();
895 itr != ml.end();
896 ++itr)
897 {
898 if (mode == itr->first)
899 {
900 lua_pushstring(_lua, convertStateAttributeValueToString(itr->second, true).c_str());
901 return 1;
902 }
903 }
904 }
905
906 OSG_NOTICE<<"Warning: StateSet:get() Could not find attribute : "<<value<<std::endl;
907 lua_pushnil(_lua);
908 return 1;
909 }
910 }
911 else if (lua_type(_lua,2)==LUA_TTABLE)
912 {
913 osg::Object* po = lse->getObjectFromTable<osg::Object>(2);
914 osg::StateAttribute* sa = dynamic_cast<osg::StateAttribute*>(po);
915 osg::Uniform* uniform = dynamic_cast<osg::Uniform*>(po);
916
917 if (sa && sa->isTextureAttribute() && stateset->getTextureAttributeList().size()>0)
918 {
919 const osg::StateSet::AttributeList& al = stateset->getTextureAttributeList()[0];
920 for(osg::StateSet::AttributeList::const_iterator itr = al.begin();
921 itr != al.end();
922 ++itr)
923 {
924 if (itr->second.first==sa)
925 {
926 lua_newtable(_lua);
927 lua_pushstring(_lua, "attribute"); lse->pushObject(itr->second.first.get()); lua_settable(_lua, -3);
928 lua_pushstring(_lua, "value"); lua_pushstring(_lua, convertStateAttributeValueToString(itr->second.second, false).c_str()); lua_settable(_lua, -3);
929 return 1;
930 }
931 }
932 OSG_NOTICE<<"Warning: StateSet:get("<<sa->className()<<") Could not find attribute"<<std::endl;
933 lua_pushnil(_lua);
934 return 1;
935 }
936 else if (sa)
937 {
938 const osg::StateSet::AttributeList& al = stateset->getAttributeList();
939 for(osg::StateSet::AttributeList::const_iterator itr = al.begin();
940 itr != al.end();
941 ++itr)
942 {
943 if (itr->second.first==sa)
944 {
945 lua_newtable(_lua);
946 lua_pushstring(_lua, "attribute"); lse->pushObject(itr->second.first.get()); lua_settable(_lua, -3);
947 lua_pushstring(_lua, "value"); lua_pushstring(_lua, convertStateAttributeValueToString(itr->second.second, false).c_str()); lua_settable(_lua, -3);
948 return 1;
949 }
950 }
951 OSG_NOTICE<<"Warning: StateSet:get("<<sa->className()<<") Could not find attribute"<<std::endl;
952 lua_pushnil(_lua);
953 return 1;
954 }
955 else if (uniform)
956 {
957 const osg::StateSet::UniformList& ul = stateset->getUniformList();
958 for(osg::StateSet::UniformList::const_iterator itr = ul.begin();
959 itr != ul.end();
960 ++itr)
961 {
962 if (itr->second.first==uniform)
963 {
964 lua_newtable(_lua);
965 lua_pushstring(_lua, "attribute"); lse->pushObject(itr->second.first.get()); lua_settable(_lua, -3);
966 lua_pushstring(_lua, "value"); lua_pushstring(_lua, convertStateAttributeValueToString(itr->second.second, false).c_str()); lua_settable(_lua, -3);
967 return 1;
968 }
969 }
970 OSG_NOTICE<<"Warning: StateSet:get("<<sa->className()<<") Could not find uniform"<<std::endl;
971 lua_pushnil(_lua);
972 return 1;
973 }
974 }
975 else if (lua_type(_lua,2)==LUA_TSTRING)
976 {
977 std::string value = lua_tostring(_lua, 2);
978 const osg::StateSet::AttributeList& al = stateset->getAttributeList();
979 for(osg::StateSet::AttributeList::const_iterator itr = al.begin();
980 itr != al.end();
981 ++itr)
982 {
983 if (value == itr->second.first->className() ||
984 value == itr->second.first->getName())
985 {
986 lua_newtable(_lua);
987 lua_pushstring(_lua, "attribute"); lse->pushObject(itr->second.first.get()); lua_settable(_lua, -3);
988 lua_pushstring(_lua, "value"); lua_pushstring(_lua, convertStateAttributeValueToString(itr->second.second, false).c_str()); lua_settable(_lua, -3);
989 return 1;
990 }
991 }
992
993 const osg::StateSet::UniformList& ul = stateset->getUniformList();
994 for(osg::StateSet::UniformList::const_iterator itr = ul.begin();
995 itr != ul.end();
996 ++itr)
997 {
998 if (value == itr->second.first->className() ||
999 value == itr->second.first->getName())
1000 {
1001 lua_newtable(_lua);
1002 lua_pushstring(_lua, "attribute"); lse->pushObject(itr->second.first.get()); lua_settable(_lua, -3);
1003 lua_pushstring(_lua, "value"); lua_pushstring(_lua, convertStateAttributeValueToString(itr->second.second, false).c_str()); lua_settable(_lua, -3);
1004 return 1;
1005 }
1006 }
1007
1008 osg::StateAttribute::GLMode mode = lse->lookUpGLenumValue(value);
1009 const osg::StateSet::ModeList& ml = stateset->getModeList();
1010 for(osg::StateSet::ModeList::const_iterator itr = ml.begin();
1011 itr != ml.end();
1012 ++itr)
1013 {
1014 if (mode == itr->first)
1015 {
1016 lua_pushstring(_lua, convertStateAttributeValueToString(itr->second, true).c_str());
1017 return 1;
1018 }
1019 }
1020
1021
1022 const osg::StateSet::DefineList& dl = stateset->getDefineList();
1023 for(osg::StateSet::DefineList::const_iterator itr = dl.begin();
1024 itr != dl.end();
1025 ++itr)
1026 {
1027 if (value == itr->first)
1028 {
1029 lua_pushstring(_lua, itr->second.first.c_str());
1030 return 1;
1031 }
1032 }
1033
1034 OSG_NOTICE<<"Warning: StateSet:get("<<value<<") Could not find matching mode or attribute"<<std::endl;
1035 lua_pushnil(_lua);
1036 return 1;
1037 }
1038
1039 OSG_NOTICE<<"Warning: StateSet:get() inappropriate parameters, use form:"<<std::endl;
1040 OSG_NOTICE<<" StateSet:get(modestring); "<<std::endl;
1041 OSG_NOTICE<<" StateSet:get(uniformName); "<<std::endl;
1042 OSG_NOTICE<<" StateSet:get(attributeNameOrClassType); "<<std::endl;
1043 OSG_NOTICE<<" StateSet:get(textureUnit, textureNameOrClassType); "<<std::endl;
1044
1045 lua_pushnil(_lua);
1046 return 1;
1047 }
1048
callStateSetRemove(lua_State * _lua)1049 static int callStateSetRemove(lua_State* _lua)
1050 {
1051 const LuaScriptEngine* lse = reinterpret_cast<const LuaScriptEngine*>(lua_topointer(_lua, lua_upvalueindex(1)));
1052 int n = lua_gettop(_lua); /* number of arguments */
1053 if (n<2 || lua_type(_lua, 1)!=LUA_TTABLE) return 0;
1054
1055 osg::StateSet* stateset = lse->getObjectFromTable<osg::StateSet>(1);
1056 if (!stateset)
1057 {
1058 OSG_NOTICE<<"Warning: StateSet:remove() can only be called on a StateSet"<<std::endl;
1059 return 0;
1060 }
1061
1062 if (lua_type(_lua,2)==LUA_TNUMBER)
1063 {
1064 if (n<3)
1065 {
1066 OSG_NOTICE<<"Warning: StateSet:remove() must be in form remove(textureUnit, textureAttribute)"<<std::endl;
1067 return 0;
1068 }
1069
1070 unsigned int index = static_cast<unsigned int>(lua_tonumber(_lua, 2));
1071 if (lua_type(_lua,3)==LUA_TTABLE)
1072 {
1073 osg::Object* po = lse->getObjectFromTable<osg::Object>(3);
1074 osg::StateAttribute* sa = dynamic_cast<osg::StateAttribute*>(po);
1075 stateset->removeTextureAttribute(static_cast<unsigned int>(index), sa);
1076 return 0;
1077 }
1078 else if (lua_type(_lua,3)==LUA_TSTRING)
1079 {
1080 std::string value = lua_tostring(_lua, 3);
1081 if (stateset->getTextureAttributeList().size()>index)
1082 {
1083 const osg::StateSet::AttributeList& al = stateset->getTextureAttributeList()[index];
1084 for(osg::StateSet::AttributeList::const_iterator itr = al.begin();
1085 itr != al.end();
1086 ++itr)
1087 {
1088 if (value == itr->second.first->className() ||
1089 value == itr->second.first->getName())
1090 {
1091 stateset->removeTextureAttribute(index, itr->second.first.get());
1092 return 0;
1093 }
1094 }
1095 }
1096
1097 if (stateset->getTextureModeList().size()>index)
1098 {
1099 osg::StateAttribute::GLMode mode = lse->lookUpGLenumValue(value);
1100 const osg::StateSet::ModeList& ml = stateset->getTextureModeList()[static_cast<unsigned int>(index)];
1101 for(osg::StateSet::ModeList::const_iterator itr = ml.begin();
1102 itr != ml.end();
1103 ++itr)
1104 {
1105 if (mode == itr->first)
1106 {
1107 stateset->removeTextureMode(static_cast<unsigned int>(index), mode);
1108 return 1;
1109 }
1110 }
1111 }
1112
1113 OSG_NOTICE<<"Warning: StateSet:remove("<<index<<", "<<value<<") could not find entry to remove."<<std::endl;
1114 return 0;
1115 }
1116 }
1117 else if (lua_type(_lua,2)==LUA_TTABLE)
1118 {
1119 osg::Object* po = lse->getObjectFromTable<osg::Object>(2);
1120 osg::StateAttribute* sa = dynamic_cast<osg::StateAttribute*>(po);
1121 osg::Uniform* uniform = dynamic_cast<osg::Uniform*>(po);
1122
1123 if (sa && sa->isTextureAttribute())
1124 {
1125 stateset->removeTextureAttribute(0, sa);
1126 return 0;
1127 }
1128 else if (sa)
1129 {
1130 stateset->removeAttribute(sa);
1131 return 0;
1132 }
1133 else if (uniform)
1134 {
1135 stateset->removeUniform(uniform);
1136 return 0;
1137 }
1138 }
1139 else if (lua_type(_lua,2)==LUA_TSTRING)
1140 {
1141 std::string value = lua_tostring(_lua, 2);
1142 const osg::StateSet::AttributeList& al = stateset->getAttributeList();
1143 for(osg::StateSet::AttributeList::const_iterator itr = al.begin();
1144 itr != al.end();
1145 ++itr)
1146 {
1147 if (value == itr->second.first->className() ||
1148 value == itr->second.first->getName())
1149 {
1150 stateset->removeAttribute(itr->second.first.get());
1151 return 0;
1152 }
1153 }
1154
1155 const osg::StateSet::UniformList& ul = stateset->getUniformList();
1156 for(osg::StateSet::UniformList::const_iterator itr = ul.begin();
1157 itr != ul.end();
1158 ++itr)
1159 {
1160 if (value == itr->second.first->className() ||
1161 value == itr->second.first->getName())
1162 {
1163 stateset->removeUniform(itr->second.first.get());
1164 return 0;
1165 }
1166 }
1167
1168 const osg::StateSet::DefineList& dl = stateset->getDefineList();
1169 for(osg::StateSet::DefineList::const_iterator itr = dl.begin();
1170 itr != dl.end();
1171 ++itr)
1172 {
1173 if (value == itr->first)
1174 {
1175 stateset->removeDefine(value);
1176 return 0;
1177 }
1178 }
1179
1180 osg::StateAttribute::GLMode mode = lse->lookUpGLenumValue(value);
1181 const osg::StateSet::ModeList& ml = stateset->getModeList();
1182 for(osg::StateSet::ModeList::const_iterator itr = ml.begin();
1183 itr != ml.end();
1184 ++itr)
1185 {
1186 if (mode == itr->first)
1187 {
1188 stateset->removeMode(mode);
1189 return 1;
1190 }
1191 }
1192
1193
1194 OSG_NOTICE<<"Warning: StateSet:remove("<<value<<") could not find entry to remove."<<std::endl;
1195 return 0;
1196 }
1197
1198 OSG_NOTICE<<"Warning: StateSet:remove() inappropriate parameters, use form:"<<std::endl;
1199 OSG_NOTICE<<" StateSet:remove(uniform); "<<std::endl;
1200 OSG_NOTICE<<" StateSet:remove(attribute); "<<std::endl;
1201 OSG_NOTICE<<" StateSet:remove(textureUnit, textureAttribute); "<<std::endl;
1202 return 0;
1203 }
1204
1205 //////////////////////////////////////////////////////////////////////////////////////
1206 //
1207 // Image calling support
1208 //
callImageAllocate(lua_State * _lua)1209 static int callImageAllocate(lua_State* _lua)
1210 {
1211 const LuaScriptEngine* lse = reinterpret_cast<const LuaScriptEngine*>(lua_topointer(_lua, lua_upvalueindex(1)));
1212 int n = lua_gettop(_lua); /* number of arguments */
1213 if (n<1 || lua_type(_lua, 1)!=LUA_TTABLE) return 0;
1214
1215 osg::Image* image = lse->getObjectFromTable<osg::Image>(1);
1216 if (!image)
1217 {
1218 OSG_NOTICE<<"Warning: Image:allocate() can only be called on a Image"<<std::endl;
1219 return 0;
1220 }
1221
1222 int s=0, t=0, r=0;
1223 GLenum pixelFormat=0;
1224 GLenum dataType = 0;
1225 int packing = 1;
1226
1227 if (n>=2 && lua_isnumber(_lua, 2)) s = static_cast<int>(lua_tonumber(_lua, 2));
1228 if (n>=3 && lua_isnumber(_lua, 3)) t = static_cast<int>(lua_tonumber(_lua, 3));
1229 if (n>=4 && lua_isnumber(_lua, 4)) r = static_cast<int>(lua_tonumber(_lua, 4));
1230
1231 if (n>=5)
1232 {
1233 if (lua_isnumber(_lua, 5)) pixelFormat = static_cast<int>(lua_tonumber(_lua, 5));
1234 else if (lua_isstring(_lua, 5))
1235 {
1236 pixelFormat = lse->lookUpGLenumValue(lua_tostring(_lua,5));
1237 }
1238 }
1239
1240 if (n>=6)
1241 {
1242 if (lua_isnumber(_lua, 6)) dataType = static_cast<int>(lua_tonumber(_lua, 6));
1243 else if (lua_isstring(_lua, 6))
1244 {
1245 dataType = lse->lookUpGLenumValue(lua_tostring(_lua,6));
1246 }
1247 }
1248
1249 if (n>=7)
1250 {
1251 if (lua_isnumber(_lua, 7)) packing = static_cast<int>(lua_tonumber(_lua, 7));
1252 }
1253
1254
1255 if (s<=0 || t<=0 || r<=0 || pixelFormat==0 || dataType==0)
1256 {
1257 OSG_NOTICE<<"Warning: Cannot not image:allocator("<<s<<", "<<t<<", "<<r<<", "<<pixelFormat<<", "<<dataType<<") a zero sized image, use non zero, positive values for s,t,r, pixelFormat and dataType."<<std::endl;
1258 return 0;
1259 }
1260
1261 image->allocateImage(s,t,r,pixelFormat,dataType,packing);
1262
1263 return 0;
1264 }
1265
callImageS(lua_State * _lua)1266 static int callImageS(lua_State* _lua)
1267 {
1268 const LuaScriptEngine* lse = reinterpret_cast<const LuaScriptEngine*>(lua_topointer(_lua, lua_upvalueindex(1)));
1269 int n = lua_gettop(_lua); /* number of arguments */
1270 if (n<1 || lua_type(_lua, 1)!=LUA_TTABLE) return 0;
1271
1272 osg::Image* image = lse->getObjectFromTable<osg::Image>(1);
1273 if (!image)
1274 {
1275 OSG_NOTICE<<"Warning: Image:s() can only be called on a Image"<<std::endl;
1276 return 0;
1277 }
1278
1279 lua_pushinteger(_lua, image->s());
1280
1281 return 1;
1282 }
1283
callImageT(lua_State * _lua)1284 static int callImageT(lua_State* _lua)
1285 {
1286 const LuaScriptEngine* lse = reinterpret_cast<const LuaScriptEngine*>(lua_topointer(_lua, lua_upvalueindex(1)));
1287 int n = lua_gettop(_lua); /* number of arguments */
1288 if (n<1 || lua_type(_lua, 1)!=LUA_TTABLE) return 0;
1289
1290 osg::Image* image = lse->getObjectFromTable<osg::Image>(1);
1291 if (!image)
1292 {
1293 OSG_NOTICE<<"Warning: Image:t() can only be called on a Image"<<std::endl;
1294 return 0;
1295 }
1296
1297 lua_pushinteger(_lua, image->t());
1298
1299 return 1;
1300 }
1301
callImageR(lua_State * _lua)1302 static int callImageR(lua_State* _lua)
1303 {
1304 const LuaScriptEngine* lse = reinterpret_cast<const LuaScriptEngine*>(lua_topointer(_lua, lua_upvalueindex(1)));
1305 int n = lua_gettop(_lua); /* number of arguments */
1306 if (n<1 || lua_type(_lua, 1)!=LUA_TTABLE) return 0;
1307
1308 osg::Image* image = lse->getObjectFromTable<osg::Image>(1);
1309 if (!image)
1310 {
1311 OSG_NOTICE<<"Warning: Image:r() can only be called on a Image"<<std::endl;
1312 return 0;
1313 }
1314
1315 lua_pushinteger(_lua, image->r());
1316
1317 return 1;
1318 }
1319
1320 // conversion of a lua value/table to a std::string, supports recursion when tables contain tables
cpp_tostring(lua_State * _lua,int index)1321 static std::string cpp_tostring(lua_State* _lua, int index)
1322 {
1323 if (!lua_istable(_lua, index))
1324 {
1325 const char* str = lua_tostring(_lua, index);
1326 if (str)
1327 {
1328 return str;
1329 }
1330 else
1331 {
1332 return "value-cannot-be-converted-to-string";
1333 }
1334 }
1335
1336 // Push another reference to the table on top of the stack (so we know
1337 // where it is, and this function can work for negative, positive and
1338 // pseudo indices
1339 lua_pushvalue(_lua, index);
1340 // stack now contains: -1 => table
1341 lua_pushnil(_lua);
1342 // stack now contains: -1 => nil; -2 => table
1343 bool first = true;
1344 std::string str("{");
1345 while (lua_next(_lua, -2))
1346 {
1347 if (!first) str.append(", ");
1348 else first = false;
1349
1350 // stack now contains: -1 => value; -2 => key; -3 => table
1351 // copy the key so that lua_tostring does not modify the original
1352 lua_pushvalue(_lua, -2);
1353 // stack now contains: -1 => key; -2 => value; -3 => key; -4 => table
1354
1355 // handle key
1356 if (lua_isstring(_lua, -1))
1357 {
1358 const char *key = lua_tostring(_lua, -1);
1359 if (key)
1360 {
1361 str.append(key);
1362 str.append("=");
1363 }
1364 }
1365
1366 // handle value
1367 if (lua_istable(_lua, -2))
1368 {
1369 str.append(cpp_tostring(_lua,-2));
1370 }
1371 else if (lua_isfunction(_lua, -2))
1372 {
1373 str.append("function");
1374 }
1375 else if (lua_isnil(_lua, -2))
1376 {
1377 str.append("nil");
1378 }
1379 else if (lua_isstring(_lua,-2))
1380 {
1381 const char *value = lua_tostring(_lua, -2);
1382 str.append("\"");
1383 if (value)
1384 {
1385 str.append(value);
1386 }
1387 str.append("\"");
1388 }
1389 else
1390 {
1391 const char *value = lua_tostring(_lua, -2);
1392 if (value)
1393 {
1394 str.append(value);
1395 }
1396 }
1397
1398 // pop value + copy of key, leaving original key
1399 lua_pop(_lua, 2);
1400 // stack now contains: -1 => key; -2 => table
1401 }
1402 str.append("}");
1403
1404 // stack now contains: -1 => table (when lua_next returns 0 it pops the key
1405 // but does not push anything.)
1406 // Pop table
1407 lua_pop(_lua, 1);
1408 // Stack is now the same as it was on entry to this function
1409
1410 return str;
1411 }
1412
tostring(lua_State * _lua)1413 static int tostring(lua_State* _lua)
1414 {
1415 lua_pushstring(_lua, cpp_tostring(_lua,-1) .c_str());
1416 return 1;
1417 }
1418
callImageGet(lua_State * _lua)1419 static int callImageGet(lua_State* _lua)
1420 {
1421 const LuaScriptEngine* lse = reinterpret_cast<const LuaScriptEngine*>(lua_topointer(_lua, lua_upvalueindex(1)));
1422 int n = lua_gettop(_lua); /* number of arguments */
1423 if (n<2 || lua_type(_lua, 1)!=LUA_TTABLE) return 0;
1424
1425 osg::Image* image = lse->getObjectFromTable<osg::Image>(1);
1426 if (!image)
1427 {
1428 OSG_NOTICE<<"Warning: Image:get() can only be called on a Image"<<std::endl;
1429 return 0;
1430 }
1431
1432 int image_i = 0;
1433 int image_j = 0;
1434 int image_k = 0;
1435 if (n>=2 && lua_isnumber(_lua, 2)) image_i = static_cast<int>(lua_tonumber(_lua, 2));
1436 if (n>=3 && lua_isnumber(_lua, 3)) image_j = static_cast<int>(lua_tonumber(_lua, 3));
1437 if (n>=4 && lua_isnumber(_lua, 4)) image_k = static_cast<int>(lua_tonumber(_lua, 4));
1438
1439 const unsigned char* ptr = image->data(image_i,image_j,image_k);
1440 unsigned int numComponents = osg::Image::computeNumComponents(image->getPixelFormat());
1441
1442 // OSG_NOTICE<<"Need to implement Image::get("<<i<<", "<<j<<", "<<k<<") ptr="<<(void*)ptr<<", numComponents="<<numComponents<<std::endl;
1443
1444 osg::Vec4d colour;
1445 switch(image->getDataType())
1446 {
1447 case(GL_BYTE): for(unsigned int i=0; i<numComponents; ++i) { colour[i] = static_cast<double>(*(reinterpret_cast<const char*>(ptr)+i)); } break;
1448 case(GL_UNSIGNED_BYTE): for(unsigned int i=0; i<numComponents; ++i) { colour[i] = static_cast<double>(*(ptr+i)); } break;
1449 case(GL_SHORT): for(unsigned int i=0; i<numComponents; ++i) { colour[i] = static_cast<double>(*(reinterpret_cast<const short*>(ptr)+i)); } break;
1450 case(GL_UNSIGNED_SHORT): for(unsigned int i=0; i<numComponents; ++i) { colour[i] = static_cast<double>(*(reinterpret_cast<const unsigned short*>(ptr)+i)); } break;
1451 case(GL_INT): for(unsigned int i=0; i<numComponents; ++i) { colour[i] = static_cast<double>(*(reinterpret_cast<const int*>(ptr)+i)); } break;
1452 case(GL_UNSIGNED_INT): for(unsigned int i=0; i<numComponents; ++i) { colour[i] = static_cast<double>(*(reinterpret_cast<const unsigned int*>(ptr)+i)); } break;
1453 case(GL_FLOAT): for(unsigned int i=0; i<numComponents; ++i) { colour[i] = static_cast<double>(*(reinterpret_cast<const float*>(ptr)+i)); } break;
1454 case(GL_DOUBLE): for(unsigned int i=0; i<numComponents; ++i) { colour[i] = static_cast<double>(*(reinterpret_cast<const double*>(ptr)+i)); } break;
1455 default:
1456 OSG_NOTICE<<"Warning: Unsupported DataType in Image::get()"<<std::endl;
1457 return 0;
1458 }
1459
1460 switch(image->getPixelFormat())
1461 {
1462 case(GL_INTENSITY): lua_pushnumber(_lua, colour[0]); return 1;
1463 case(GL_LUMINANCE): lua_pushnumber(_lua, colour[0]); return 1;
1464 case(GL_ALPHA): lua_pushnumber(_lua, colour[0]); return 1;
1465 case(GL_LUMINANCE_ALPHA):
1466 {
1467 lua_newtable(_lua); luaL_getmetatable(_lua, "LuaScriptEngine.Table"); lua_setmetatable(_lua, -2);
1468 lua_pushstring(_lua, "luminance"); lua_pushnumber(_lua, colour[0]); lua_settable(_lua, -3);
1469 lua_pushstring(_lua, "alpha"); lua_pushnumber(_lua, colour[1]); lua_settable(_lua, -3);
1470 return 1;
1471 }
1472 case(GL_RGB):
1473 {
1474 lua_newtable(_lua); luaL_getmetatable(_lua, "LuaScriptEngine.Table"); lua_setmetatable(_lua, -2);
1475 lua_pushstring(_lua, "red"); lua_pushnumber(_lua, colour[0]); lua_settable(_lua, -3);
1476 lua_pushstring(_lua, "green"); lua_pushnumber(_lua, colour[1]); lua_settable(_lua, -3);
1477 lua_pushstring(_lua, "blue"); lua_pushnumber(_lua, colour[2]); lua_settable(_lua, -3);
1478 return 1;
1479 }
1480 case(GL_RGBA):
1481 {
1482 lua_newtable(_lua); luaL_getmetatable(_lua, "LuaScriptEngine.Table"); lua_setmetatable(_lua, -2);
1483 lua_pushstring(_lua, "red"); lua_pushnumber(_lua, colour[0]); lua_settable(_lua, -3);
1484 lua_pushstring(_lua, "green"); lua_pushnumber(_lua, colour[1]); lua_settable(_lua, -3);
1485 lua_pushstring(_lua, "blue"); lua_pushnumber(_lua, colour[2]); lua_settable(_lua, -3);
1486 lua_pushstring(_lua, "alpha"); lua_pushnumber(_lua, colour[3]); lua_settable(_lua, -3);
1487 return 1;
1488 }
1489 case(GL_BGR):
1490 {
1491 lua_newtable(_lua); luaL_getmetatable(_lua, "LuaScriptEngine.Table"); lua_setmetatable(_lua, -2);
1492 lua_pushstring(_lua, "red"); lua_pushnumber(_lua, colour[2]); lua_settable(_lua, -3);
1493 lua_pushstring(_lua, "green"); lua_pushnumber(_lua, colour[1]); lua_settable(_lua, -3);
1494 lua_pushstring(_lua, "blue"); lua_pushnumber(_lua, colour[0]); lua_settable(_lua, -3);
1495 return 1;
1496 }
1497 case(GL_BGRA):
1498 {
1499 lua_newtable(_lua); luaL_getmetatable(_lua, "LuaScriptEngine.Table"); lua_setmetatable(_lua, -2);
1500 lua_pushstring(_lua, "red"); lua_pushnumber(_lua, colour[2]); lua_settable(_lua, -3);
1501 lua_pushstring(_lua, "green"); lua_pushnumber(_lua, colour[1]); lua_settable(_lua, -3);
1502 lua_pushstring(_lua, "blue"); lua_pushnumber(_lua, colour[0]); lua_settable(_lua, -3);
1503 lua_pushstring(_lua, "alpha"); lua_pushnumber(_lua, colour[3]); lua_settable(_lua, -3);
1504 return 1;
1505 }
1506 }
1507
1508 OSG_NOTICE<<"Warning: Image:get() unsupported PixelFormat"<<std::endl;
1509 return 0;
1510 }
1511
setImageColour(osg::Image * image,int image_i,int image_j,int image_k,const osg::Vec4d & colourToWrite)1512 static void setImageColour(osg::Image* image, int image_i, int image_j, int image_k, const osg::Vec4d& colourToWrite)
1513 {
1514 if (image_i>=image->s() || image_j>=image->t() || image_k>=image->r())
1515 {
1516 OSG_NOTICE<<"Warning: Image::set("<<image_i<<", "<<image_j<<", "<<image_k<<") out of range"<<std::endl;
1517 return;
1518 }
1519
1520 unsigned char* ptr = image->data(image_i,image_j,image_k);
1521 unsigned int numComponents = osg::Image::computeNumComponents(image->getPixelFormat());
1522
1523 switch(image->getDataType())
1524 {
1525 case(GL_BYTE): for(unsigned int i=0; i<numComponents; ++i) { *(reinterpret_cast<char*>(ptr)+i) = static_cast<char>(colourToWrite[i]); } break;
1526 case(GL_UNSIGNED_BYTE): for(unsigned int i=0; i<numComponents; ++i) { *(reinterpret_cast<unsigned char*>(ptr)+i) = static_cast<unsigned char>(colourToWrite[i]); } break;
1527 case(GL_SHORT): for(unsigned int i=0; i<numComponents; ++i) { *(reinterpret_cast<short*>(ptr)+i) = static_cast<short>(colourToWrite[i]); } break;
1528 case(GL_UNSIGNED_SHORT): for(unsigned int i=0; i<numComponents; ++i) { *(reinterpret_cast<unsigned short*>(ptr)+i) = static_cast<unsigned short>(colourToWrite[i]); } break;
1529 case(GL_INT): for(unsigned int i=0; i<numComponents; ++i) { *(reinterpret_cast<int*>(ptr)+i) = static_cast<int>(colourToWrite[i]); } break;
1530 case(GL_UNSIGNED_INT): for(unsigned int i=0; i<numComponents; ++i) { *(reinterpret_cast<unsigned int*>(ptr)+i) = static_cast<unsigned int>(colourToWrite[i]); } break;
1531 case(GL_FLOAT): for(unsigned int i=0; i<numComponents; ++i) { *(reinterpret_cast<float*>(ptr)+i) = static_cast<float>(colourToWrite[i]); } break;
1532 case(GL_DOUBLE): for(unsigned int i=0; i<numComponents; ++i) { *(reinterpret_cast<double*>(ptr)+i) = static_cast<double>(colourToWrite[i]); } break;
1533 default:
1534 OSG_NOTICE<<"Warning: Unsupported DataType in Image::set()"<<std::endl;
1535 return;
1536 }
1537 }
1538
callImageSet(lua_State * _lua)1539 static int callImageSet(lua_State* _lua)
1540 {
1541 const LuaScriptEngine* lse = reinterpret_cast<const LuaScriptEngine*>(lua_topointer(_lua, lua_upvalueindex(1)));
1542 int n = lua_gettop(_lua); /* number of arguments */
1543 if (n<2 || lua_type(_lua, 1)!=LUA_TTABLE) return 0;
1544
1545 osg::Image* image = lse->getObjectFromTable<osg::Image>(1);
1546 if (!image)
1547 {
1548 OSG_NOTICE<<"Warning: Image:set() can only be called on a Image"<<std::endl;
1549 return 0;
1550 }
1551
1552 bool positionSet = false;
1553 int image_i = 0;
1554 int image_j = 0;
1555 int image_k = 0;
1556 if (n>=3 && lua_isnumber(_lua, 2)) { image_i = static_cast<int>(lua_tonumber(_lua, 2)); positionSet = true; }
1557 if (n>=4 && lua_isnumber(_lua, 3)) { image_j = static_cast<int>(lua_tonumber(_lua, 3)); positionSet = true; }
1558 if (n>=5 && lua_isnumber(_lua, 4)) { image_k = static_cast<int>(lua_tonumber(_lua, 4)); positionSet = true; }
1559
1560 osg::Vec4d colour(1.0,1.0,1.0,1.0);
1561 if (lua_isnumber(_lua, n))
1562 {
1563 colour[0] = colour[1] = colour[2] = colour[3] = lua_tonumber(_lua, n);
1564 }
1565 else if (lua_istable(_lua, n))
1566 {
1567 lua_getfield(_lua, n, "intensity");
1568 if (lua_isnumber(_lua, -1)) { double i = lua_tonumber(_lua, -1); colour[0] = i; colour[1] = i; colour[2] = i; colour[3] = i; }
1569 lua_pop(_lua, 1);
1570
1571 lua_getfield(_lua, n, "i");
1572 if (lua_isnumber(_lua, -1)) { double i = lua_tonumber(_lua, -1); colour[0] = i; colour[1] = i; colour[2] = i; colour[3] = i; }
1573 lua_pop(_lua, 1);
1574
1575
1576 lua_getfield(_lua, n, "luminance");
1577 if (lua_isnumber(_lua, -1)) { double l = lua_tonumber(_lua, -1); colour[0] = l; colour[1] = l; colour[2] = l; }
1578 lua_pop(_lua, 1);
1579
1580 lua_getfield(_lua, n, "l");
1581 if (lua_isnumber(_lua, -1)) { double l = lua_tonumber(_lua, -1); colour[0] = l; colour[1] = l; colour[2] = l; }
1582 lua_pop(_lua, 1);
1583
1584
1585 lua_getfield(_lua, n, "alpha");
1586 if (lua_isnumber(_lua, -1)) { double a = lua_tonumber(_lua, -1); colour[3] = a; }
1587 lua_pop(_lua, 1);
1588
1589 lua_getfield(_lua, n, "a");
1590 if (lua_isnumber(_lua, -1)) { double a = lua_tonumber(_lua, -1); colour[3] = a; }
1591 lua_pop(_lua, 1);
1592
1593
1594 lua_getfield(_lua, n, "red");
1595 if (lua_isnumber(_lua, -1)) { double r = lua_tonumber(_lua, -1); colour[0] = r; }
1596 lua_pop(_lua, 1);
1597
1598 lua_getfield(_lua, n, "r");
1599 if (lua_isnumber(_lua, -1)) { double r = lua_tonumber(_lua, -1); colour[0] = r; }
1600 lua_pop(_lua, 1);
1601
1602
1603 lua_getfield(_lua, n, "green");
1604 if (lua_isnumber(_lua, -1)) { double g = lua_tonumber(_lua, -1); colour[1] = g; }
1605 lua_pop(_lua, 1);
1606
1607 lua_getfield(_lua, n, "g");
1608 if (lua_isnumber(_lua, -1)) { double g = lua_tonumber(_lua, -1); colour[1] = g; }
1609 lua_pop(_lua, 1);
1610
1611
1612 lua_getfield(_lua, n, "blue");
1613 if (lua_isnumber(_lua, -1)) { double b = lua_tonumber(_lua, -1); colour[2] = b; }
1614 lua_pop(_lua, 1);
1615
1616 lua_getfield(_lua, n, "b");
1617 if (lua_isnumber(_lua, -1)) { double b = lua_tonumber(_lua, -1); colour[2] = b; }
1618 lua_pop(_lua, 1);
1619
1620 }
1621
1622 // repack the colour data to the final destination form
1623 osg::Vec4d colourToWrite = colour;
1624 switch(image->getPixelFormat())
1625 {
1626 case(GL_INTENSITY): colourToWrite[0] = colour[0]; break;
1627 case(GL_LUMINANCE): colourToWrite[0] = colour[0]; break;
1628 case(GL_ALPHA): colourToWrite[0] = colour[3]; break;
1629 case(GL_LUMINANCE_ALPHA):
1630 {
1631 colourToWrite[0] = colour[0];
1632 colourToWrite[1] = colour[3];
1633 break;
1634 }
1635 case(GL_RGB):
1636 case(GL_RGBA):
1637 {
1638 // nothing to do as data is already in the correct form
1639 break;
1640 }
1641 case(GL_BGR):
1642 case(GL_BGRA):
1643 {
1644 colourToWrite[0] = colour[2];
1645 colourToWrite[1] = colour[1];
1646 colourToWrite[2] = colour[0];
1647 colourToWrite[3] = colour[3];
1648 return 1;
1649 }
1650 }
1651
1652 if (positionSet)
1653 {
1654 setImageColour(image, image_i,image_j,image_k, colourToWrite);
1655 }
1656 else
1657 {
1658 for(int k=0; k<image->r(); ++k)
1659 {
1660 for(int j=0; j<image->t(); ++j)
1661 {
1662 for(int i=0; i<image->s(); ++i)
1663 {
1664 setImageColour(image, i,j,k, colourToWrite);
1665 }
1666 }
1667 }
1668 }
1669
1670 return 0;
1671 }
1672
1673 //////////////////////////////////////////////////////////////////////////////////////
1674 //
1675 // Node Parent
1676 //
callGetParent(lua_State * _lua)1677 static int callGetParent(lua_State* _lua)
1678 {
1679 const LuaScriptEngine* lse = reinterpret_cast<const LuaScriptEngine*>(lua_topointer(_lua, lua_upvalueindex(1)));
1680 int n = lua_gettop(_lua); /* number of arguments */
1681 if (n<1 || lua_type(_lua, 1)!=LUA_TTABLE) return 0;
1682
1683 osg::Node* node = lse->getObjectFromTable<osg::Node>(1);
1684 if (!node)
1685 {
1686 OSG_NOTICE<<"Warning: Node::getParent() can only be called on a Node"<<std::endl;
1687 return 0;
1688 }
1689
1690 int index = 0;
1691 if (n>=2 && lua_isnumber(_lua, 2))
1692 {
1693 index = static_cast<int>(lua_tonumber(_lua, 2));
1694 if (index>=0 && index<static_cast<int>(node->getNumParents()))
1695 {
1696 lse->pushObject(node->getParent(0));
1697 return 1;
1698 }
1699 else
1700 {
1701 OSG_NOTICE<<"Warning: Call to node:getParent(index) has an out of range index."<<std::endl;
1702 return 0;
1703 }
1704 }
1705 else
1706 {
1707 OSG_NOTICE<<"Warning: node:getParent() requires a integer parameter."<<std::endl;
1708 return 0;
1709 }
1710 }
1711
callGetNumParents(lua_State * _lua)1712 static int callGetNumParents(lua_State* _lua)
1713 {
1714 const LuaScriptEngine* lse = reinterpret_cast<const LuaScriptEngine*>(lua_topointer(_lua, lua_upvalueindex(1)));
1715 int n = lua_gettop(_lua); /* number of arguments */
1716 if (n<1 || lua_type(_lua, 1)!=LUA_TTABLE) return 0;
1717
1718 osg::Node* node = lse->getObjectFromTable<osg::Node>(1);
1719 if (!node)
1720 {
1721 OSG_NOTICE<<"Warning: Node::getNumParents() can only be called on a Node"<<std::endl;
1722 return 0;
1723 }
1724
1725 lua_pushnumber(_lua, node->getNumParents());
1726 return 1;
1727 }
1728
1729 //////////////////////////////////////////////////////////////////////////////////////
1730 //
1731 // Method calling support
1732 //
callClassMethod(lua_State * _lua)1733 static int callClassMethod(lua_State* _lua)
1734 {
1735 const LuaScriptEngine* lse = reinterpret_cast<const LuaScriptEngine*>(lua_topointer(_lua, lua_upvalueindex(1)));
1736 std::string methodName = lua_tostring(_lua, lua_upvalueindex(2));
1737 int n = lua_gettop(_lua); /* number of arguments */
1738
1739 if (n>=1 && lua_type(_lua, 1)==LUA_TTABLE)
1740 {
1741 osg::Object* object = lse->getObjectFromTable<osg::Object>(1);
1742 const std::string compoundClassName = lse->getObjectCompoundClassName(1); // object->getCompoundClassName();
1743 // OSG_NOTICE<<"callClassMethod() on "<<object->className()<<" method name "<<methodName<<", stored compoundClassName "<<compoundClassName<<std::endl;
1744
1745 // need to put within a c function
1746 osg::Parameters inputParameters, outputParameters;
1747 for(int i=2; i<=n; ++i)
1748 {
1749 // OSG_NOTICE<<" need to push parameter "<<lua_typename(_lua, lua_type(_lua, n))<<std::endl;
1750 inputParameters.insert(inputParameters.begin(), lse->popParameterObject());
1751 }
1752
1753 if (lse->getClassInterface().run(object, compoundClassName, methodName, inputParameters, outputParameters))
1754 {
1755 for(osg::Parameters::iterator itr = outputParameters.begin();
1756 itr != outputParameters.end();
1757 ++itr)
1758 {
1759 // OSG_NOTICE<<" pushing return "<<(*itr)->className()<<std::endl;
1760 lse->pushParameter(itr->get());
1761 }
1762 return outputParameters.size();
1763 }
1764 }
1765 else
1766 {
1767 OSG_NOTICE<<"Warning: lua method called without passing object, use object::method() convention."<<std::endl;
1768 }
1769
1770 return 0;
1771 }
1772
garabageCollectObject(lua_State * _lua)1773 static int garabageCollectObject(lua_State* _lua)
1774 {
1775 int n = lua_gettop(_lua); /* number of arguments */
1776 if (n==1)
1777 {
1778 if (lua_type(_lua, 1)==LUA_TUSERDATA)
1779 {
1780 osg::Object* object = *const_cast<osg::Object**>(reinterpret_cast<const osg::Object**>(lua_touserdata(_lua, 1)));
1781 object->unref();
1782 }
1783 }
1784
1785 return 0;
1786 }
1787
newObject(lua_State * _lua)1788 static int newObject(lua_State * _lua)
1789 {
1790 const LuaScriptEngine* lse = reinterpret_cast<const LuaScriptEngine*>(lua_topointer(_lua, lua_upvalueindex(1)));
1791
1792 int n = lua_gettop(_lua); /* number of arguments */
1793 if (n==1)
1794 {
1795 if (lua_type(_lua, 1)==LUA_TSTRING)
1796 {
1797 std::string compoundName = lua_tostring(_lua, 1);
1798
1799 lse->createAndPushObject(compoundName);
1800 return 1;
1801 }
1802 }
1803 return 0;
1804 }
1805
castObject(lua_State * _lua)1806 static int castObject(lua_State * _lua)
1807 {
1808 const LuaScriptEngine* lse = reinterpret_cast<const LuaScriptEngine*>(lua_topointer(_lua, lua_upvalueindex(1)));
1809
1810 int n = lua_gettop(_lua); /* number of arguments */
1811 if (n==2)
1812 {
1813 if (lua_type(_lua, 1)==LUA_TSTRING && lua_type(_lua, 2)==LUA_TTABLE)
1814 {
1815 std::string new_compoundClassName = lua_tostring(_lua, 1);
1816 osg::Object* object = lse->getObjectFromTable<osg::Object>(2);
1817
1818 lse->pushAndCastObject(new_compoundClassName, object);
1819
1820 return 1;
1821 }
1822 }
1823 return 0;
1824 }
1825
readObjectFile(lua_State * _lua)1826 static int readObjectFile(lua_State * _lua)
1827 {
1828 const LuaScriptEngine* lse = reinterpret_cast<const LuaScriptEngine*>(lua_topointer(_lua, lua_upvalueindex(1)));
1829
1830 int n = lua_gettop(_lua); /* number of arguments */
1831 if (n==1 && lua_type(_lua, 1)==LUA_TSTRING)
1832 {
1833 std::string filename = lua_tostring(_lua, 1);
1834 osg::ref_ptr<osg::Object> object = osgDB::readRefObjectFile(filename);
1835 if (object.valid())
1836 {
1837 lse->pushObject(object.get());
1838 return 1;
1839 }
1840 }
1841 return 0;
1842 }
1843
readImageFile(lua_State * _lua)1844 static int readImageFile(lua_State * _lua)
1845 {
1846 const LuaScriptEngine* lse = reinterpret_cast<const LuaScriptEngine*>(lua_topointer(_lua, lua_upvalueindex(1)));
1847
1848 int n = lua_gettop(_lua); /* number of arguments */
1849 if (n==1 && lua_type(_lua, 1)==LUA_TSTRING)
1850 {
1851 std::string filename = lua_tostring(_lua, 1);
1852 osg::ref_ptr<osg::Image> image = osgDB::readRefImageFile(filename);
1853 if (image.valid())
1854 {
1855 lse->pushObject(image.get());
1856 return 1;
1857 }
1858 }
1859 return 0;
1860 }
1861
readShaderFile(lua_State * _lua)1862 static int readShaderFile(lua_State * _lua)
1863 {
1864 const LuaScriptEngine* lse = reinterpret_cast<const LuaScriptEngine*>(lua_topointer(_lua, lua_upvalueindex(1)));
1865
1866 int n = lua_gettop(_lua); /* number of arguments */
1867 if (n==1 && lua_type(_lua, 1)==LUA_TSTRING)
1868 {
1869 std::string filename = lua_tostring(_lua, 1);
1870 osg::ref_ptr<osg::Shader> shader = osgDB::readRefShaderFile(filename);
1871 if (shader.valid())
1872 {
1873 lse->pushObject(shader.get());
1874 return 1;
1875 }
1876 }
1877 return 0;
1878 }
1879
readNodeFile(lua_State * _lua)1880 static int readNodeFile(lua_State * _lua)
1881 {
1882 const LuaScriptEngine* lse = reinterpret_cast<const LuaScriptEngine*>(lua_topointer(_lua, lua_upvalueindex(1)));
1883
1884 int n = lua_gettop(_lua); /* number of arguments */
1885 if (n==1 && lua_type(_lua, 1)==LUA_TSTRING)
1886 {
1887 std::string filename = lua_tostring(_lua, 1);
1888 osg::ref_ptr<osg::Node> node = osgDB::readRefNodeFile(filename);
1889 if (node.valid())
1890 {
1891 lse->pushObject(node.get());
1892 return 1;
1893 }
1894 }
1895 return 0;
1896 }
1897
1898
writeFile(lua_State * _lua)1899 static int writeFile(lua_State * _lua)
1900 {
1901 const LuaScriptEngine* lse = reinterpret_cast<const LuaScriptEngine*>(lua_topointer(_lua, lua_upvalueindex(1)));
1902
1903 int n = lua_gettop(_lua); /* number of arguments */
1904 if (n>=2 && lua_type(_lua, 1)==LUA_TTABLE && lua_type(_lua, 2)==LUA_TSTRING)
1905 {
1906 osg::Object* object = lse->getObjectFromTable<osg::Object>(1);
1907 std::string filename = lua_tostring(_lua, 2);
1908 if (object)
1909 {
1910 osgDB::writeObjectFile(*object, filename);
1911 return 1;
1912 }
1913 }
1914 return 0;
1915 }
1916
1917
1918
1919
LuaScriptEngine()1920 LuaScriptEngine::LuaScriptEngine():
1921 osg::ScriptEngine("lua"),
1922 _lua(0),
1923 _scriptCount(0)
1924 {
1925 initialize();
1926 }
1927
LuaScriptEngine(const LuaScriptEngine &,const osg::CopyOp &)1928 LuaScriptEngine::LuaScriptEngine(const LuaScriptEngine&, const osg::CopyOp&):
1929 osg::ScriptEngine("lua"),
1930 _lua(0),
1931 _scriptCount(0)
1932 {
1933 initialize();
1934 }
1935
~LuaScriptEngine()1936 LuaScriptEngine::~LuaScriptEngine()
1937 {
1938 lua_close(_lua);
1939 }
1940
createUniquieScriptName()1941 std::string LuaScriptEngine::createUniquieScriptName()
1942 {
1943 std::stringstream sstr;
1944 sstr<<"script_"<<_scriptCount;
1945 ++_scriptCount;
1946
1947 return sstr.str();
1948 }
1949
initialize()1950 void LuaScriptEngine::initialize()
1951 {
1952 _lua = luaL_newstate();
1953
1954 luaL_openlibs(_lua);
1955
1956 // provide global new method for creating osg::Object's.
1957 {
1958 lua_pushlightuserdata(_lua, this);
1959 lua_pushcclosure(_lua, newObject, 1);
1960 lua_setglobal(_lua, "new");
1961 }
1962
1963 // provide global new method for casting osg::Object's.
1964 {
1965 lua_pushlightuserdata(_lua, this);
1966 lua_pushcclosure(_lua, castObject, 1);
1967 lua_setglobal(_lua, "cast");
1968 }
1969
1970 // provide global new method for reading Objects
1971 {
1972 lua_pushlightuserdata(_lua, this);
1973 lua_pushcclosure(_lua, readObjectFile, 1);
1974 lua_setglobal(_lua, "readFile");
1975 }
1976
1977 // provide global new method for reading Objects
1978 {
1979 lua_pushlightuserdata(_lua, this);
1980 lua_pushcclosure(_lua, readObjectFile, 1);
1981 lua_setglobal(_lua, "readObjectFile");
1982 }
1983
1984 // provide global new method for reading Nodes
1985 {
1986 lua_pushlightuserdata(_lua, this);
1987 lua_pushcclosure(_lua, readNodeFile, 1);
1988 lua_setglobal(_lua, "readNodeFile");
1989 }
1990
1991 // provide global new method for read Images
1992 {
1993 lua_pushlightuserdata(_lua, this);
1994 lua_pushcclosure(_lua, readImageFile, 1);
1995 lua_setglobal(_lua, "readImageFile");
1996 }
1997
1998 // provide global new method for read Images
1999 {
2000 lua_pushlightuserdata(_lua, this);
2001 lua_pushcclosure(_lua, readShaderFile, 1);
2002 lua_setglobal(_lua, "readShaderFile");
2003 }
2004
2005 // provide global new method for read Images
2006 {
2007 lua_pushlightuserdata(_lua, this);
2008 lua_pushcclosure(_lua, writeFile, 1);
2009 lua_setglobal(_lua, "writeFile");
2010 }
2011
2012 // Set up the __newindex and __index methods for looking up implementations of Object properties
2013 {
2014 luaL_newmetatable(_lua, "LuaScriptEngine.Object");
2015
2016 lua_pushstring(_lua, "__index");
2017 lua_pushlightuserdata(_lua, this);
2018 lua_pushcclosure(_lua, getProperty, 1);
2019 lua_settable(_lua, -3);
2020
2021 lua_pushstring(_lua, "__newindex");
2022 lua_pushlightuserdata(_lua, this);
2023 lua_pushcclosure(_lua, setProperty, 1);
2024 lua_settable(_lua, -3);
2025
2026 lua_pushstring(_lua, "__tostring");
2027 lua_pushlightuserdata(_lua, this);
2028 lua_pushcclosure(_lua, tostring, 1);
2029 lua_settable(_lua, -3);
2030
2031 lua_pop(_lua,1);
2032 }
2033
2034 // Set up the __tostring methods to be able to convert tables into strings so they can be output for debugging purposes.
2035 {
2036 luaL_newmetatable(_lua, "LuaScriptEngine.Table");
2037
2038 lua_pushstring(_lua, "__tostring");
2039 lua_pushlightuserdata(_lua, this);
2040 lua_pushcclosure(_lua, tostring, 1);
2041 lua_settable(_lua, -3);
2042
2043 lua_pop(_lua,1);
2044 }
2045
2046 // Set up the __newindex and __index methods for looking up implementations of Object properties
2047 {
2048 luaL_newmetatable(_lua, "LuaScriptEngine.Container");
2049
2050 lua_pushstring(_lua, "__index");
2051 lua_pushlightuserdata(_lua, this);
2052 lua_pushcclosure(_lua, getContainerProperty, 1);
2053 lua_settable(_lua, -3);
2054
2055 lua_pushstring(_lua, "__newindex");
2056 lua_pushlightuserdata(_lua, this);
2057 lua_pushcclosure(_lua, setContainerProperty, 1);
2058 lua_settable(_lua, -3);
2059
2060 lua_pop(_lua,1);
2061 }
2062
2063 // Set up the __newindex and __index methods for looking up implementations of Object properties
2064 {
2065 luaL_newmetatable(_lua, "LuaScriptEngine.Map");
2066
2067 lua_pushstring(_lua, "__index");
2068 lua_pushlightuserdata(_lua, this);
2069 lua_pushcclosure(_lua, getMapProperty, 1);
2070 lua_settable(_lua, -3);
2071
2072 lua_pushstring(_lua, "__newindex");
2073 lua_pushlightuserdata(_lua, this);
2074 lua_pushcclosure(_lua, setMapProperty, 1);
2075 lua_settable(_lua, -3);
2076
2077 lua_pop(_lua,1);
2078 }
2079
2080 // Set up the __gc methods for looking up implementations of Object pointer to do the unref when the associated Lua object is destroyed.
2081 {
2082 luaL_newmetatable(_lua, "LuaScriptEngine.UnrefObject");
2083 lua_pushstring(_lua, "__gc");
2084 lua_pushlightuserdata(_lua, this);
2085 lua_pushcclosure(_lua, garabageCollectObject, 1);
2086 lua_settable(_lua, -3);
2087
2088 lua_pop(_lua,1);
2089 }
2090 }
2091
loadScript(osg::Script * script)2092 bool LuaScriptEngine::loadScript(osg::Script* script)
2093 {
2094 if (_loadedScripts.count(script)!=0) return true;
2095
2096 int loadResult = luaL_loadstring(_lua, script->getScript().c_str());
2097 if (loadResult==0)
2098 {
2099 std::string scriptID = createUniquieScriptName();
2100
2101 lua_pushvalue(_lua, -1);
2102 lua_setglobal(_lua, scriptID.c_str());
2103
2104 _loadedScripts[script] = scriptID;
2105
2106 return true;
2107 }
2108 else
2109 {
2110 OSG_NOTICE << "LuaScriptEngine::luaL_loadstring(Script*) error: " << lua_tostring(_lua, -1) << std::endl;
2111 return false;
2112 }
2113 }
2114
2115
run(osg::Script * script,const std::string & entryPoint,osg::Parameters & inputParameters,osg::Parameters & outputParameters)2116 bool LuaScriptEngine::run(osg::Script* script, const std::string& entryPoint, osg::Parameters& inputParameters, osg::Parameters& outputParameters)
2117 {
2118 if (!script || !_lua) return false;
2119
2120
2121 if (_loadedScripts.count(script)==0)
2122 {
2123 if (!loadScript(script)) return false;
2124
2125 if (!entryPoint.empty())
2126 {
2127 if (lua_pcall(_lua, 0, 0, 0)!=0)
2128 {
2129 OSG_NOTICE<< "error initialize script "<< lua_tostring(_lua, -1)<<std::endl;
2130 return false;
2131 }
2132 }
2133 }
2134
2135 int topBeforeCall = lua_gettop(_lua);
2136
2137 if (entryPoint.empty())
2138 {
2139 ScriptMap::iterator itr = _loadedScripts.find(script);
2140 if (itr == _loadedScripts.end()) return false;
2141
2142 std::string scriptID = itr->second;
2143
2144 lua_getglobal(_lua, scriptID.c_str());
2145 }
2146 else
2147 {
2148 lua_getglobal(_lua, entryPoint.c_str()); /* function to be called */
2149 }
2150
2151 for(osg::Parameters::const_iterator itr = inputParameters.begin();
2152 itr != inputParameters.end();
2153 ++itr)
2154 {
2155 pushParameter(itr->get());
2156 }
2157
2158
2159 if (lua_pcall(_lua, inputParameters.size(), LUA_MULTRET,0)!=0)
2160 {
2161 OSG_NOTICE<<"Lua error : "<<lua_tostring(_lua, -1)<<std::endl;
2162 return false;
2163 }
2164
2165 int topAfterCall = lua_gettop(_lua);
2166 int numReturns = topAfterCall-topBeforeCall;
2167
2168 outputParameters.clear();
2169
2170 for(int i=0; i<numReturns; ++i)
2171 {
2172 osg::ref_ptr<osg::Object> obj = popParameterObject();
2173 if (obj.valid()) outputParameters.push_back(obj);
2174 }
2175
2176 return true;
2177 }
2178
2179
2180 class PushStackValueVisitor : public osg::ValueObject::GetValueVisitor
2181 {
2182 public:
2183
2184 const LuaScriptEngine* _lse;
2185 lua_State* _lua;
2186
PushStackValueVisitor(const LuaScriptEngine * lse)2187 PushStackValueVisitor(const LuaScriptEngine* lse) : _lse(lse) { _lua = const_cast<LuaScriptEngine*>(lse)->getLuaState(); }
2188
apply(bool value)2189 virtual void apply(bool value) { lua_pushboolean(_lua, value ? 1 : 0); }
apply(char value)2190 virtual void apply(char value) { lua_pushnumber(_lua, value); }
apply(unsigned char value)2191 virtual void apply(unsigned char value) { lua_pushnumber(_lua, value); }
apply(short value)2192 virtual void apply(short value) { lua_pushnumber(_lua, value); }
apply(unsigned short value)2193 virtual void apply(unsigned short value) { lua_pushnumber(_lua, value); }
apply(int value)2194 virtual void apply(int value) { lua_pushnumber(_lua, value); }
apply(unsigned int value)2195 virtual void apply(unsigned int value) { lua_pushnumber(_lua, value); }
apply(float value)2196 virtual void apply(float value) { lua_pushnumber(_lua, value); }
apply(double value)2197 virtual void apply(double value) { lua_pushnumber(_lua, value); }
apply(const std::string & value)2198 virtual void apply(const std::string& value) { lua_pushlstring(_lua, &value[0], value.size()); }
2199
apply(const osg::Vec2b & value)2200 virtual void apply(const osg::Vec2b& value) { _lse->pushValue(value); }
apply(const osg::Vec3b & value)2201 virtual void apply(const osg::Vec3b& value) { _lse->pushValue(value); }
apply(const osg::Vec4b & value)2202 virtual void apply(const osg::Vec4b& value) { _lse->pushValue(value); }
2203
apply(const osg::Vec2ub & value)2204 virtual void apply(const osg::Vec2ub& value) { _lse->pushValue(value); }
apply(const osg::Vec3ub & value)2205 virtual void apply(const osg::Vec3ub& value) { _lse->pushValue(value); }
apply(const osg::Vec4ub & value)2206 virtual void apply(const osg::Vec4ub& value) { _lse->pushValue(value); }
2207
apply(const osg::Vec2s & value)2208 virtual void apply(const osg::Vec2s& value) { _lse->pushValue(value); }
apply(const osg::Vec3s & value)2209 virtual void apply(const osg::Vec3s& value) { _lse->pushValue(value); }
apply(const osg::Vec4s & value)2210 virtual void apply(const osg::Vec4s& value) { _lse->pushValue(value); }
2211
apply(const osg::Vec2us & value)2212 virtual void apply(const osg::Vec2us& value) { _lse->pushValue(value); }
apply(const osg::Vec3us & value)2213 virtual void apply(const osg::Vec3us& value) { _lse->pushValue(value); }
apply(const osg::Vec4us & value)2214 virtual void apply(const osg::Vec4us& value) { _lse->pushValue(value); }
2215
apply(const osg::Vec2i & value)2216 virtual void apply(const osg::Vec2i& value) { _lse->pushValue(value); }
apply(const osg::Vec3i & value)2217 virtual void apply(const osg::Vec3i& value) { _lse->pushValue(value); }
apply(const osg::Vec4i & value)2218 virtual void apply(const osg::Vec4i& value) { _lse->pushValue(value); }
2219
apply(const osg::Vec2ui & value)2220 virtual void apply(const osg::Vec2ui& value) { _lse->pushValue(value); }
apply(const osg::Vec3ui & value)2221 virtual void apply(const osg::Vec3ui& value) { _lse->pushValue(value); }
apply(const osg::Vec4ui & value)2222 virtual void apply(const osg::Vec4ui& value) { _lse->pushValue(value); }
2223
apply(const osg::Vec2f & value)2224 virtual void apply(const osg::Vec2f& value) { _lse->pushValue(value); }
apply(const osg::Vec3f & value)2225 virtual void apply(const osg::Vec3f& value) { _lse->pushValue(value); }
apply(const osg::Vec4f & value)2226 virtual void apply(const osg::Vec4f& value) { _lse->pushValue(value); }
2227
apply(const osg::Vec2d & value)2228 virtual void apply(const osg::Vec2d& value) { _lse->pushValue(value); }
apply(const osg::Vec3d & value)2229 virtual void apply(const osg::Vec3d& value) { _lse->pushValue(value); }
apply(const osg::Vec4d & value)2230 virtual void apply(const osg::Vec4d& value) { _lse->pushValue(value); }
2231
apply(const osg::Quat & value)2232 virtual void apply(const osg::Quat& value) { _lse->pushValue(value); }
apply(const osg::Plane & value)2233 virtual void apply(const osg::Plane& value) { _lse->pushValue(value); }
apply(const osg::Matrixf & value)2234 virtual void apply(const osg::Matrixf& value) { _lse->pushValue(value); }
apply(const osg::Matrixd & value)2235 virtual void apply(const osg::Matrixd& value) { _lse->pushValue(value); }
2236 };
2237
2238 #if LUA_VERSION_NUM<=501
2239 #define lua_rawlen lua_strlen
2240 #endif
2241
2242 class GetStackValueVisitor : public osg::ValueObject::SetValueVisitor
2243 {
2244 public:
2245
2246 const LuaScriptEngine* _lse;
2247 lua_State* _lua;
2248 int _index;
2249 int _numberToPop;
2250 bool _success;
2251
GetStackValueVisitor(const LuaScriptEngine * lse,int index)2252 GetStackValueVisitor(const LuaScriptEngine* lse, int index) : _lse(lse), _lua(0), _index(index), _numberToPop(0), _success(false) { _lua = const_cast<LuaScriptEngine*>(lse )->getLuaState(); }
2253
2254
apply(bool & value)2255 virtual void apply(bool& value) { if (lua_isboolean(_lua, _index)) { value = (lua_toboolean(_lua, _index)!=0); _success=true; _numberToPop = 1; } }
apply(char & value)2256 virtual void apply(char& value) { if (lua_isnumber(_lua, _index)) { value = lua_tonumber(_lua, _index)!=0; _success=true; _numberToPop = 1; } }
apply(unsigned char & value)2257 virtual void apply(unsigned char& value) { if (lua_isnumber(_lua, _index)) { value = lua_tonumber(_lua, _index)!=0; _success=true; _numberToPop = 1; } }
apply(short & value)2258 virtual void apply(short& value) { if (lua_isnumber(_lua, _index)) { value = lua_tonumber(_lua, _index)!=0; _success=true; _numberToPop = 1; } }
apply(unsigned short & value)2259 virtual void apply(unsigned short& value) { if (lua_isnumber(_lua, _index)) { value = lua_tonumber(_lua, _index)!=0; _success=true; _numberToPop = 1; } }
apply(int & value)2260 virtual void apply(int& value) { if (lua_isnumber(_lua, _index)) { value = lua_tonumber(_lua, _index)!=0; _success=true; _numberToPop = 1; } }
apply(unsigned int & value)2261 virtual void apply(unsigned int& value) { if (lua_isnumber(_lua, _index)) { value = lua_tonumber(_lua, _index)!=0; _success=true; _numberToPop = 1; } }
apply(float & value)2262 virtual void apply(float& value) { if (lua_isnumber(_lua, _index)) { value = lua_tonumber(_lua, _index)!=0; _success=true; _numberToPop = 1; } }
apply(double & value)2263 virtual void apply(double& value) { if (lua_isnumber(_lua, _index)) { value = lua_tonumber(_lua, _index)!=0; _success=true; _numberToPop = 1; } }
apply(std::string & value)2264 virtual void apply(std::string& value) { if (lua_isstring(_lua, _index)) { value = std::string(lua_tostring(_lua, _index), lua_rawlen(_lua, _index)); _numberToPop = 1; } }
apply(osg::Vec2f & value)2265 virtual void apply(osg::Vec2f& value) { if (_lse->getValue(_index, value)) { _success=true; _numberToPop = 2;} }
apply(osg::Vec3f & value)2266 virtual void apply(osg::Vec3f& value) { if (_lse->getValue(_index, value)) { _success=true; _numberToPop = 2; } }
apply(osg::Vec4f & value)2267 virtual void apply(osg::Vec4f& value) { if (_lse->getValue(_index, value)) { _success=true; _numberToPop = 4; } }
apply(osg::Vec2d & value)2268 virtual void apply(osg::Vec2d& value) { if (_lse->getValue(_index, value)) { _success=true; _numberToPop = 2; } }
apply(osg::Vec3d & value)2269 virtual void apply(osg::Vec3d& value) { if (_lse->getValue(_index, value)) { _success=true; _numberToPop = 3; } }
apply(osg::Vec4d & value)2270 virtual void apply(osg::Vec4d& value) { if (_lse->getValue(_index, value)) { _success=true; _numberToPop = 4; } }
apply(osg::Quat & value)2271 virtual void apply(osg::Quat& value) { if (_lse->getValue(_index, value)) { _success=true; _numberToPop = 4; } }
apply(osg::Plane & value)2272 virtual void apply(osg::Plane& value) { if (_lse->getValue(_index, value)) { _success=true; _numberToPop = 4; } }
apply(osg::Matrixf & value)2273 virtual void apply(osg::Matrixf& value) { if (_lse->getValue(_index, value)) { _success = true; _numberToPop = 16; } }
apply(osg::Matrixd & value)2274 virtual void apply(osg::Matrixd& value) { if (_lse->getValue(_index, value)) { _success = true; _numberToPop = 16; } }
apply(osg::BoundingBoxf & value)2275 virtual void apply(osg::BoundingBoxf& value) { if (_lse->getValue(_index, value)) { _success=true; } }
apply(osg::BoundingBoxd & value)2276 virtual void apply(osg::BoundingBoxd& value) { if (_lse->getValue(_index, value)) { _success=true; } }
apply(osg::BoundingSpheref & value)2277 virtual void apply(osg::BoundingSpheref& value) { if (_lse->getValue(_index, value)) { _success=true; } }
apply(osg::BoundingSphered & value)2278 virtual void apply(osg::BoundingSphered& value) { if (_lse->getValue(_index, value)) { _success=true; } }
2279 };
2280
pushPropertyToStack(osg::Object * object,const std::string & propertyName) const2281 int LuaScriptEngine::pushPropertyToStack(osg::Object* object, const std::string& propertyName) const
2282 {
2283 osgDB::BaseSerializer::Type type;
2284 if (!_ci.getPropertyType(object, propertyName, type))
2285 {
2286 if (_ci.hasMethod(object, propertyName))
2287 {
2288 lua_pushlightuserdata(_lua, const_cast<LuaScriptEngine*>(this));
2289 lua_pushstring(_lua, propertyName.c_str());
2290 lua_pushcclosure(_lua, callClassMethod, 2);
2291
2292 return 1;
2293 }
2294
2295 osg::Object* uo = osg::getUserObject(object, propertyName);
2296 LuaCallbackObject* lco = dynamic_cast<LuaCallbackObject*>(uo);
2297 if (lco)
2298 {
2299 lua_rawgeti(_lua, LUA_REGISTRYINDEX, lco->getRef());
2300 return 1;
2301 }
2302 else if (uo)
2303 {
2304 pushObject(uo);
2305 return 1;
2306 }
2307
2308 OSG_INFO<<"LuaScriptEngine::pushPropertyToStack("<<object<<", "<<propertyName<<") no property found."<<std::endl;
2309 return 0;
2310 }
2311
2312 switch(type)
2313 {
2314 case(osgDB::BaseSerializer::RW_BOOL):
2315 {
2316 bool value;
2317 if (_ci.getProperty(object, propertyName, value))
2318 {
2319 lua_pushboolean(_lua, value ? 1 : 0);
2320 return 1;
2321 }
2322 break;
2323 }
2324 case(osgDB::BaseSerializer::RW_STRING):
2325 {
2326 std::string value;
2327 if (_ci.getProperty(object, propertyName, value))
2328 {
2329 lua_pushstring(_lua, value.c_str());
2330 return 1;
2331 }
2332 break;
2333 }
2334 case(osgDB::BaseSerializer::RW_GLENUM):
2335 {
2336 GLenum value;
2337 if (_ci.getProperty(object, propertyName, value))
2338 {
2339 std::string enumString = lookUpGLenumString(value);
2340 lua_pushstring(_lua, enumString.c_str());
2341 return 1;
2342 }
2343 break;
2344 }
2345 case(osgDB::BaseSerializer::RW_ENUM):
2346 {
2347 int value;
2348 if (_ci.getProperty(object, propertyName, value))
2349 {
2350 osgDB::BaseSerializer* serializer = _ci.getSerializer(object, propertyName, type);
2351 osgDB::IntLookup* lookup = serializer ? serializer->getIntLookup() : 0;
2352 if (lookup)
2353 {
2354 std::string enumString = lookup->getString(value);
2355 lua_pushstring(_lua, enumString.c_str());
2356 }
2357 else
2358 {
2359 lua_pushinteger(_lua, value);
2360 }
2361 return 1;
2362 }
2363 break;
2364 }
2365 case(osgDB::BaseSerializer::RW_SHORT):
2366 {
2367 short value;
2368 if (_ci.getProperty(object, propertyName, value))
2369 {
2370 lua_pushinteger(_lua, value);
2371 return 1;
2372 }
2373 break;
2374 }
2375 case(osgDB::BaseSerializer::RW_USHORT):
2376 {
2377 unsigned short value;
2378 if (_ci.getProperty(object, propertyName, value))
2379 {
2380 lua_pushinteger(_lua, value);
2381 return 1;
2382 }
2383 break;
2384 }
2385 case(osgDB::BaseSerializer::RW_INT):
2386 {
2387 int value;
2388 if (_ci.getProperty(object, propertyName, value))
2389 {
2390 lua_pushinteger(_lua, value);
2391 return 1;
2392 }
2393 break;
2394 }
2395 case(osgDB::BaseSerializer::RW_UINT):
2396 {
2397 unsigned int value;
2398 if (_ci.getProperty(object, propertyName, value))
2399 {
2400 lua_pushinteger(_lua, value);
2401 return 1;
2402 }
2403 break;
2404 }
2405 case(osgDB::BaseSerializer::RW_FLOAT):
2406 {
2407 float value;
2408 if (_ci.getProperty(object, propertyName, value))
2409 {
2410 lua_pushnumber(_lua, value);
2411 return 1;
2412 }
2413 break;
2414 }
2415 case(osgDB::BaseSerializer::RW_DOUBLE):
2416 {
2417 double value;
2418 if (_ci.getProperty(object, propertyName, value))
2419 {
2420 lua_pushnumber(_lua, value);
2421 return 1;
2422 }
2423 break;
2424 }
2425
2426 case(osgDB::BaseSerializer::RW_VEC2B): if (getPropertyAndPushValue<osg::Vec2b>(object, propertyName)) return 1; break;
2427 case(osgDB::BaseSerializer::RW_VEC3B): if (getPropertyAndPushValue<osg::Vec3b>(object, propertyName)) return 1; break;
2428 case(osgDB::BaseSerializer::RW_VEC4B): if (getPropertyAndPushValue<osg::Vec4b>(object, propertyName)) return 1; break;
2429
2430 case(osgDB::BaseSerializer::RW_VEC2UB): if (getPropertyAndPushValue<osg::Vec2ub>(object, propertyName)) return 1; break;
2431 case(osgDB::BaseSerializer::RW_VEC3UB): if (getPropertyAndPushValue<osg::Vec3ub>(object, propertyName)) return 1; break;
2432 case(osgDB::BaseSerializer::RW_VEC4UB): if (getPropertyAndPushValue<osg::Vec4ub>(object, propertyName)) return 1; break;
2433
2434 case(osgDB::BaseSerializer::RW_VEC2S): if (getPropertyAndPushValue<osg::Vec2s>(object, propertyName)) return 1; break;
2435 case(osgDB::BaseSerializer::RW_VEC3S): if (getPropertyAndPushValue<osg::Vec3s>(object, propertyName)) return 1; break;
2436 case(osgDB::BaseSerializer::RW_VEC4S): if (getPropertyAndPushValue<osg::Vec4s>(object, propertyName)) return 1; break;
2437
2438 case(osgDB::BaseSerializer::RW_VEC2US): if (getPropertyAndPushValue<osg::Vec2us>(object, propertyName)) return 1; break;
2439 case(osgDB::BaseSerializer::RW_VEC3US): if (getPropertyAndPushValue<osg::Vec3us>(object, propertyName)) return 1; break;
2440 case(osgDB::BaseSerializer::RW_VEC4US): if (getPropertyAndPushValue<osg::Vec4us>(object, propertyName)) return 1; break;
2441
2442 case(osgDB::BaseSerializer::RW_VEC2I): if (getPropertyAndPushValue<osg::Vec2i>(object, propertyName)) return 1; break;
2443 case(osgDB::BaseSerializer::RW_VEC3I): if (getPropertyAndPushValue<osg::Vec3i>(object, propertyName)) return 1; break;
2444 case(osgDB::BaseSerializer::RW_VEC4I): if (getPropertyAndPushValue<osg::Vec4i>(object, propertyName)) return 1; break;
2445
2446 case(osgDB::BaseSerializer::RW_VEC2UI): if (getPropertyAndPushValue<osg::Vec2ui>(object, propertyName)) return 1; break;
2447 case(osgDB::BaseSerializer::RW_VEC3UI): if (getPropertyAndPushValue<osg::Vec3ui>(object, propertyName)) return 1; break;
2448 case(osgDB::BaseSerializer::RW_VEC4UI): if (getPropertyAndPushValue<osg::Vec4ui>(object, propertyName)) return 1; break;
2449
2450 case(osgDB::BaseSerializer::RW_VEC2F): if (getPropertyAndPushValue<osg::Vec2f>(object, propertyName)) return 1; break;
2451 case(osgDB::BaseSerializer::RW_VEC3F): if (getPropertyAndPushValue<osg::Vec3f>(object, propertyName)) return 1; break;
2452 case(osgDB::BaseSerializer::RW_VEC4F): if (getPropertyAndPushValue<osg::Vec4f>(object, propertyName)) return 1; break;
2453
2454 case(osgDB::BaseSerializer::RW_VEC2D): if (getPropertyAndPushValue<osg::Vec2d>(object, propertyName)) return 1; break;
2455 case(osgDB::BaseSerializer::RW_VEC3D): if (getPropertyAndPushValue<osg::Vec3d>(object, propertyName)) return 1; break;
2456 case(osgDB::BaseSerializer::RW_VEC4D): if (getPropertyAndPushValue<osg::Vec4d>(object, propertyName)) return 1; break;
2457
2458 case(osgDB::BaseSerializer::RW_QUAT): if (getPropertyAndPushValue<osg::Quat>(object, propertyName)) return 1; break;
2459 case(osgDB::BaseSerializer::RW_PLANE): if (getPropertyAndPushValue<osg::Plane>(object, propertyName)) return 1; break;
2460
2461 #ifdef OSG_USE_FLOAT_MATRIX
2462 case(osgDB::BaseSerializer::RW_MATRIX):
2463 #endif
2464 case(osgDB::BaseSerializer::RW_MATRIXF):
2465 {
2466 osg::Matrixf value;
2467 if (_ci.getProperty(object, propertyName, value))
2468 {
2469 pushValue(value);
2470 return 1;
2471 }
2472 break;
2473 }
2474 #ifndef OSG_USE_FLOAT_MATRIX
2475 case(osgDB::BaseSerializer::RW_MATRIX):
2476 #endif
2477 case(osgDB::BaseSerializer::RW_MATRIXD):
2478 {
2479 osg::Matrixd value;
2480 if (_ci.getProperty(object, propertyName, value))
2481 {
2482 pushValue(value);
2483 return 1;
2484 }
2485 break;
2486 }
2487 case(osgDB::BaseSerializer::RW_BOUNDINGBOXF):
2488 {
2489 osg::BoundingBoxf value;
2490 if (_ci.getProperty(object, propertyName, value))
2491 {
2492 pushValue(value);
2493 return 1;
2494 }
2495 break;
2496 }
2497 case(osgDB::BaseSerializer::RW_BOUNDINGBOXD):
2498 {
2499 osg::BoundingBoxd value;
2500 if (_ci.getProperty(object, propertyName, value))
2501 {
2502 pushValue(value);
2503 return 1;
2504 }
2505 break;
2506 }
2507 case(osgDB::BaseSerializer::RW_BOUNDINGSPHEREF):
2508 {
2509 osg::BoundingSpheref value;
2510 if (_ci.getProperty(object, propertyName, value))
2511 {
2512 pushValue(value);
2513 return 1;
2514 }
2515 break;
2516 }
2517 case(osgDB::BaseSerializer::RW_BOUNDINGSPHERED):
2518 {
2519 osg::BoundingSphered value;
2520 if (_ci.getProperty(object, propertyName, value))
2521 {
2522 pushValue(value);
2523 return 1;
2524 }
2525 break;
2526 }
2527 case(osgDB::BaseSerializer::RW_LIST):
2528 {
2529 OSG_NOTICE<<"Need to implement RW_LIST support"<<std::endl;
2530 break;
2531 }
2532 case(osgDB::BaseSerializer::RW_IMAGE):
2533 case(osgDB::BaseSerializer::RW_OBJECT):
2534 {
2535 osg::Object* value = 0;
2536 if (_ci.getProperty(object, propertyName, value))
2537 {
2538 pushObject(value);
2539 return 1;
2540 }
2541 break;
2542 }
2543 case(osgDB::BaseSerializer::RW_VECTOR):
2544 case(osgDB::BaseSerializer::RW_MAP):
2545 {
2546 pushContainer(object, propertyName);
2547 return 1;
2548 }
2549 default:
2550 break;
2551 }
2552
2553 OSG_NOTICE<<"LuaScriptEngine::pushPropertyToStack("<<object<<", "<<propertyName<<") property of type = "<<_ci.getTypeName(type)<<" error, not supported."<<std::endl;
2554 return 0;
2555 }
2556
lookUpGLenumString(GLenum value) const2557 std::string LuaScriptEngine::lookUpGLenumString(GLenum value) const
2558 {
2559 osgDB::ObjectWrapperManager* ow = osgDB::Registry::instance()->getObjectWrapperManager();
2560
2561 {
2562 const osgDB::IntLookup& lookup = ow->getLookupMap()["GL"];
2563 const osgDB::IntLookup::ValueToString& vts = lookup.getValueToString();
2564 osgDB::IntLookup::ValueToString::const_iterator itr = vts.find(value);
2565 if (itr!=vts.end()) return itr->second;
2566 }
2567
2568 {
2569 const osgDB::IntLookup& lookup = ow->getLookupMap()["PrimitiveType"];
2570 const osgDB::IntLookup::ValueToString& vts = lookup.getValueToString();
2571 osgDB::IntLookup::ValueToString::const_iterator itr = vts.find(value);
2572 if (itr!=vts.end()) return itr->second;
2573 }
2574
2575 OSG_NOTICE<<"Warning: LuaScriptEngine did not find valid GL enum value for GLenum value: "<<value<<std::endl;
2576
2577 return std::string();
2578 }
2579
lookUpGLenumValue(const std::string & str) const2580 GLenum LuaScriptEngine::lookUpGLenumValue(const std::string& str) const
2581 {
2582 osgDB::ObjectWrapperManager* ow = osgDB::Registry::instance()->getObjectWrapperManager();
2583
2584 {
2585 const osgDB::IntLookup& lookup = ow->getLookupMap()["GL"];
2586 const osgDB::IntLookup::StringToValue& stv = lookup.getStringToValue();
2587 osgDB::IntLookup::StringToValue::const_iterator itr = stv.find(str);
2588 if (itr!=stv.end()) return itr->second;
2589 }
2590
2591 {
2592 const osgDB::IntLookup& lookup = ow->getLookupMap()["PrimitiveType"];
2593 const osgDB::IntLookup::StringToValue& stv = lookup.getStringToValue();
2594 osgDB::IntLookup::StringToValue::const_iterator itr = stv.find(str);
2595 if (itr!=stv.end()) return itr->second;
2596 }
2597
2598 OSG_NOTICE<<"Warning: LuaScriptEngine did not find valid GL enum value for string value: "<<str<<std::endl;
2599
2600 return GL_NONE;
2601 }
2602
2603
pushDataToStack(SerializerScratchPad * ssp) const2604 int LuaScriptEngine::pushDataToStack(SerializerScratchPad* ssp) const
2605 {
2606 switch(ssp->dataType)
2607 {
2608 case(osgDB::BaseSerializer::RW_BOOL):
2609 {
2610 bool value;
2611 if (ssp->get(value))
2612 {
2613 lua_pushboolean(_lua, value ? 1 : 0);
2614 return 1;
2615 }
2616 break;
2617 }
2618 case(osgDB::BaseSerializer::RW_STRING):
2619 {
2620 std::string value;
2621 if (ssp->get(value))
2622 {
2623 lua_pushstring(_lua, value.c_str());
2624 return 1;
2625 }
2626 break;
2627 }
2628 case(osgDB::BaseSerializer::RW_GLENUM):
2629 {
2630 GLenum value;
2631 if (ssp->get(value))
2632 {
2633 std::string enumString = lookUpGLenumString(value);
2634 lua_pushstring(_lua, enumString.c_str());
2635 return 1;
2636 }
2637 break;
2638 }
2639 case(osgDB::BaseSerializer::RW_ENUM):
2640 {
2641 int value;
2642 if (ssp->get(value))
2643 {
2644 lua_pushinteger(_lua, value);
2645 return 1;
2646 }
2647 break;
2648 }
2649 case(osgDB::BaseSerializer::RW_INT):
2650 {
2651 int value;
2652 if (ssp->get(value))
2653 {
2654 lua_pushinteger(_lua, value);
2655 return 1;
2656 }
2657 break;
2658 }
2659 case(osgDB::BaseSerializer::RW_UINT):
2660 {
2661 unsigned int value;
2662 if (ssp->get(value))
2663 {
2664 lua_pushinteger(_lua, value);
2665 return 1;
2666 }
2667 break;
2668 }
2669 case(osgDB::BaseSerializer::RW_SHORT):
2670 {
2671 short value;
2672 if (ssp->get(value))
2673 {
2674 lua_pushinteger(_lua, value);
2675 return 1;
2676 }
2677 break;
2678 }
2679 case(osgDB::BaseSerializer::RW_USHORT):
2680 {
2681 unsigned short value;
2682 if (ssp->get(value))
2683 {
2684 lua_pushinteger(_lua, value);
2685 return 1;
2686 }
2687 break;
2688 }
2689 case(osgDB::BaseSerializer::RW_FLOAT):
2690 {
2691 float value;
2692 if (ssp->get(value))
2693 {
2694 lua_pushnumber(_lua, value);
2695 return 1;
2696 }
2697 break;
2698 }
2699 case(osgDB::BaseSerializer::RW_DOUBLE):
2700 {
2701 double value;
2702 if (ssp->get(value))
2703 {
2704 lua_pushnumber(_lua, value);
2705 return 1;
2706 }
2707 break;
2708 }
2709
2710 case(osgDB::BaseSerializer::RW_VEC2B): if (pushValueToStack<osg::Vec2b>(ssp)) return 1; break;
2711 case(osgDB::BaseSerializer::RW_VEC3B): if (pushValueToStack<osg::Vec3b>(ssp)) return 1; break;
2712 case(osgDB::BaseSerializer::RW_VEC4B): if (pushValueToStack<osg::Vec4b>(ssp)) return 1; break;
2713
2714 case(osgDB::BaseSerializer::RW_VEC2UB): if (pushValueToStack<osg::Vec2ub>(ssp)) return 1; break;
2715 case(osgDB::BaseSerializer::RW_VEC3UB): if (pushValueToStack<osg::Vec3ub>(ssp)) return 1; break;
2716 case(osgDB::BaseSerializer::RW_VEC4UB): if (pushValueToStack<osg::Vec4ub>(ssp)) return 1; break;
2717
2718 case(osgDB::BaseSerializer::RW_VEC2S): if (pushValueToStack<osg::Vec2s>(ssp)) return 1; break;
2719 case(osgDB::BaseSerializer::RW_VEC3S): if (pushValueToStack<osg::Vec3s>(ssp)) return 1; break;
2720 case(osgDB::BaseSerializer::RW_VEC4S): if (pushValueToStack<osg::Vec4s>(ssp)) return 1; break;
2721
2722 case(osgDB::BaseSerializer::RW_VEC2US): if (pushValueToStack<osg::Vec2us>(ssp)) return 1; break;
2723 case(osgDB::BaseSerializer::RW_VEC3US): if (pushValueToStack<osg::Vec3us>(ssp)) return 1; break;
2724 case(osgDB::BaseSerializer::RW_VEC4US): if (pushValueToStack<osg::Vec4us>(ssp)) return 1; break;
2725
2726 case(osgDB::BaseSerializer::RW_VEC2I): if (pushValueToStack<osg::Vec2i>(ssp)) return 1; break;
2727 case(osgDB::BaseSerializer::RW_VEC3I): if (pushValueToStack<osg::Vec3i>(ssp)) return 1; break;
2728 case(osgDB::BaseSerializer::RW_VEC4I): if (pushValueToStack<osg::Vec4i>(ssp)) return 1; break;
2729
2730 case(osgDB::BaseSerializer::RW_VEC2UI): if (pushValueToStack<osg::Vec2ui>(ssp)) return 1; break;
2731 case(osgDB::BaseSerializer::RW_VEC3UI): if (pushValueToStack<osg::Vec3ui>(ssp)) return 1; break;
2732 case(osgDB::BaseSerializer::RW_VEC4UI): if (pushValueToStack<osg::Vec4ui>(ssp)) return 1; break;
2733
2734 case(osgDB::BaseSerializer::RW_VEC2F): if (pushValueToStack<osg::Vec2f>(ssp)) return 1; break;
2735 case(osgDB::BaseSerializer::RW_VEC3F): if (pushValueToStack<osg::Vec3f>(ssp)) return 1; break;
2736 case(osgDB::BaseSerializer::RW_VEC4F): if (pushValueToStack<osg::Vec4f>(ssp)) return 1; break;
2737
2738 case(osgDB::BaseSerializer::RW_VEC2D): if (pushValueToStack<osg::Vec2d>(ssp)) return 1; break;
2739 case(osgDB::BaseSerializer::RW_VEC3D): if (pushValueToStack<osg::Vec3d>(ssp)) return 1; break;
2740 case(osgDB::BaseSerializer::RW_VEC4D): if (pushValueToStack<osg::Vec4d>(ssp)) return 1; break;
2741
2742 case(osgDB::BaseSerializer::RW_QUAT): if (pushValueToStack<osg::Quat>(ssp)) return 1; break;
2743 case(osgDB::BaseSerializer::RW_PLANE): if (pushValueToStack<osg::Plane>(ssp)) return 1; break;
2744
2745 #ifdef OSG_USE_FLOAT_MATRIX
2746 case(osgDB::BaseSerializer::RW_MATRIX):
2747 #endif
2748 case(osgDB::BaseSerializer::RW_MATRIXF):
2749 {
2750 osg::Matrixf value;
2751 if (ssp->get(value))
2752 {
2753 pushValue(value);
2754 return 1;
2755 }
2756 break;
2757 }
2758 #ifndef OSG_USE_FLOAT_MATRIX
2759 case(osgDB::BaseSerializer::RW_MATRIX):
2760 #endif
2761 case(osgDB::BaseSerializer::RW_MATRIXD):
2762 {
2763 osg::Matrixd value;
2764 if (ssp->get(value))
2765 {
2766 pushValue(value);
2767 return 1;
2768 }
2769 break;
2770 }
2771 case(osgDB::BaseSerializer::RW_BOUNDINGBOXF):
2772 {
2773 osg::BoundingBoxf value;
2774 if (ssp->get(value))
2775 {
2776 pushValue(value);
2777 return 1;
2778 }
2779 break;
2780 }
2781 case(osgDB::BaseSerializer::RW_BOUNDINGBOXD):
2782 {
2783 osg::BoundingBoxd value;
2784 if (ssp->get(value))
2785 {
2786 pushValue(value);
2787 return 1;
2788 }
2789 break;
2790 }
2791 case(osgDB::BaseSerializer::RW_BOUNDINGSPHEREF):
2792 {
2793 osg::BoundingSpheref value;
2794 if (ssp->get(value))
2795 {
2796 pushValue(value);
2797 return 1;
2798 }
2799 break;
2800 }
2801 case(osgDB::BaseSerializer::RW_BOUNDINGSPHERED):
2802 {
2803 osg::BoundingSphered value;
2804 if (ssp->get(value))
2805 {
2806 pushValue(value);
2807 return 1;
2808 }
2809 break;
2810 }
2811 case(osgDB::BaseSerializer::RW_IMAGE):
2812 case(osgDB::BaseSerializer::RW_OBJECT):
2813 {
2814 osg::Object* value = 0;
2815 if (ssp->get(value))
2816 {
2817 pushObject(value);
2818 return 1;
2819 }
2820 break;
2821 }
2822 case(osgDB::BaseSerializer::RW_LIST):
2823 {
2824 break;
2825 }
2826 case(osgDB::BaseSerializer::RW_VECTOR):
2827 {
2828 break;
2829 }
2830 default:
2831 break;
2832 }
2833
2834 OSG_NOTICE<<"LuaScriptEngine::pushDataToStack() property of type = "<<_ci.getTypeName(ssp->dataType)<<" error, not supported."<<std::endl;
2835 return 0;
2836 }
2837
getDataFromStack(SerializerScratchPad * ssp,osgDB::BaseSerializer::Type type,int pos) const2838 int LuaScriptEngine::getDataFromStack(SerializerScratchPad* ssp, osgDB::BaseSerializer::Type type, int pos) const
2839 {
2840 pos = getAbsolutePos(pos);
2841
2842 if (type==osgDB::BaseSerializer::RW_UNDEFINED) type = LuaScriptEngine::getType(pos);
2843
2844 switch(type)
2845 {
2846 case(osgDB::BaseSerializer::RW_BOOL):
2847 {
2848 if (lua_isboolean(_lua, pos))
2849 {
2850 ssp->set(static_cast<bool>(lua_toboolean(_lua, pos)!=0));
2851 return 0;
2852 }
2853 else if (lua_isnumber(_lua, pos))
2854 {
2855 ssp->set(static_cast<bool>(lua_tonumber(_lua, pos)!=0));
2856 return 0;
2857 }
2858 break;
2859 }
2860 case(osgDB::BaseSerializer::RW_STRING):
2861 {
2862 if (lua_isstring(_lua, pos))
2863 {
2864 ssp->set(std::string(lua_tostring(_lua, pos)));
2865 return 0;
2866 }
2867 break;
2868 }
2869 case(osgDB::BaseSerializer::RW_GLENUM):
2870 {
2871 if (lua_isnumber(_lua, pos))
2872 {
2873 ssp->set(static_cast<GLenum>(lua_tonumber(_lua, pos)));
2874 return 0;
2875 }
2876 else if (lua_isstring(_lua, pos))
2877 {
2878 const char* enumString = lua_tostring(_lua, pos);
2879 GLenum value = lookUpGLenumValue(enumString); //getValue("GL",enumString);
2880
2881 ssp->set(value);
2882 return 0;
2883 }
2884 OSG_NOTICE<<"LuaScriptEngine::getDataFromStack() osgDB::BaseSerializer::RW_GLENUM Failed"<<std::endl;
2885 break;
2886 }
2887 case(osgDB::BaseSerializer::RW_ENUM):
2888 {
2889 if (lua_isnumber(_lua, pos))
2890 {
2891 ssp->set(static_cast<int>(lua_tonumber(_lua, pos)));
2892 return 0;
2893 }
2894 else if (lua_isstring(_lua, pos))
2895 {
2896 OSG_NOTICE<<"LuaScriptEngine::getDataFromStack() osgDB::BaseSerializer::RW_ENUM Failed to convert string"<<std::endl;
2897 return 0;
2898 }
2899 break;
2900 }
2901 case(osgDB::BaseSerializer::RW_SHORT):
2902 {
2903 if (lua_isnumber(_lua, pos))
2904 {
2905 ssp->set(static_cast<short>(lua_tonumber(_lua, pos)));
2906 return 0;
2907 }
2908 break;
2909 }
2910 case(osgDB::BaseSerializer::RW_USHORT):
2911 {
2912 if (lua_isnumber(_lua, pos))
2913 {
2914 ssp->set(static_cast<unsigned short>(lua_tonumber(_lua, pos)));
2915 return 0;
2916 }
2917 break;
2918 }
2919 case(osgDB::BaseSerializer::RW_INT):
2920 {
2921 if (lua_isnumber(_lua, pos))
2922 {
2923 ssp->set(static_cast<int>(lua_tonumber(_lua, pos)));
2924 return 0;
2925 }
2926 break;
2927 }
2928 case(osgDB::BaseSerializer::RW_UINT):
2929 {
2930 if (lua_isnumber(_lua, pos))
2931 {
2932 ssp->set(static_cast<unsigned int>(lua_tonumber(_lua, pos)));
2933 return 0;
2934 }
2935 break;
2936 }
2937 case(osgDB::BaseSerializer::RW_FLOAT):
2938 {
2939 if (lua_isnumber(_lua, pos))
2940 {
2941 ssp->set(static_cast<float>(lua_tonumber(_lua, pos)));
2942 return 0;
2943 }
2944 break;
2945 }
2946 case(osgDB::BaseSerializer::RW_DOUBLE):
2947 {
2948 if (lua_isnumber(_lua, pos))
2949 {
2950 ssp->set(static_cast<double>(lua_tonumber(_lua, pos)));
2951 return 0;
2952 }
2953 break;
2954 }
2955
2956 case(osgDB::BaseSerializer::RW_VEC2B): if (getDataFromStack<osg::Vec2b>(ssp, pos)) return 0; break;
2957 case(osgDB::BaseSerializer::RW_VEC3B): if (getDataFromStack<osg::Vec3b>(ssp, pos)) return 0; break;
2958 case(osgDB::BaseSerializer::RW_VEC4B): if (getDataFromStack<osg::Vec4b>(ssp, pos)) return 0; break;
2959
2960 case(osgDB::BaseSerializer::RW_VEC2UB): if (getDataFromStack<osg::Vec2ub>(ssp, pos)) return 0; break;
2961 case(osgDB::BaseSerializer::RW_VEC3UB): if (getDataFromStack<osg::Vec3ub>(ssp, pos)) return 0; break;
2962 case(osgDB::BaseSerializer::RW_VEC4UB): if (getDataFromStack<osg::Vec4ub>(ssp, pos)) return 0; break;
2963
2964 case(osgDB::BaseSerializer::RW_VEC2S): if (getDataFromStack<osg::Vec2s>(ssp, pos)) return 0; break;
2965 case(osgDB::BaseSerializer::RW_VEC3S): if (getDataFromStack<osg::Vec3s>(ssp, pos)) return 0; break;
2966 case(osgDB::BaseSerializer::RW_VEC4S): if (getDataFromStack<osg::Vec4s>(ssp, pos)) return 0; break;
2967
2968 case(osgDB::BaseSerializer::RW_VEC2US): if (getDataFromStack<osg::Vec2us>(ssp, pos)) return 0; break;
2969 case(osgDB::BaseSerializer::RW_VEC3US): if (getDataFromStack<osg::Vec3us>(ssp, pos)) return 0; break;
2970 case(osgDB::BaseSerializer::RW_VEC4US): if (getDataFromStack<osg::Vec4us>(ssp, pos)) return 0; break;
2971
2972 case(osgDB::BaseSerializer::RW_VEC2I): if (getDataFromStack<osg::Vec2i>(ssp, pos)) return 0; break;
2973 case(osgDB::BaseSerializer::RW_VEC3I): if (getDataFromStack<osg::Vec3i>(ssp, pos)) return 0; break;
2974 case(osgDB::BaseSerializer::RW_VEC4I): if (getDataFromStack<osg::Vec4i>(ssp, pos)) return 0; break;
2975
2976 case(osgDB::BaseSerializer::RW_VEC2UI): if (getDataFromStack<osg::Vec2ui>(ssp, pos)) return 0; break;
2977 case(osgDB::BaseSerializer::RW_VEC3UI): if (getDataFromStack<osg::Vec3ui>(ssp, pos)) return 0; break;
2978 case(osgDB::BaseSerializer::RW_VEC4UI): if (getDataFromStack<osg::Vec4ui>(ssp, pos)) return 0; break;
2979
2980 case(osgDB::BaseSerializer::RW_VEC2F): if (getDataFromStack<osg::Vec2f>(ssp, pos)) return 0; break;
2981 case(osgDB::BaseSerializer::RW_VEC3F): if (getDataFromStack<osg::Vec3f>(ssp, pos)) return 0; break;
2982 case(osgDB::BaseSerializer::RW_VEC4F): if (getDataFromStack<osg::Vec4f>(ssp, pos)) return 0; break;
2983
2984 case(osgDB::BaseSerializer::RW_VEC2D): if (getDataFromStack<osg::Vec2d>(ssp, pos)) return 0; break;
2985 case(osgDB::BaseSerializer::RW_VEC3D): if (getDataFromStack<osg::Vec3d>(ssp, pos)) return 0; break;
2986 case(osgDB::BaseSerializer::RW_VEC4D): if (getDataFromStack<osg::Vec4d>(ssp, pos)) return 0; break;
2987
2988 case(osgDB::BaseSerializer::RW_QUAT): if (getDataFromStack<osg::Quat>(ssp, pos)) return 0; break;
2989 case(osgDB::BaseSerializer::RW_PLANE): if (getDataFromStack<osg::Plane>(ssp, pos)) return 0; break;
2990
2991 #ifdef OSG_USE_FLOAT_MATRIX
2992 case(osgDB::BaseSerializer::RW_MATRIX):
2993 #endif
2994 case(osgDB::BaseSerializer::RW_MATRIXF):
2995 {
2996 osg::Matrixd value;
2997 if (getValue(pos, value))
2998 {
2999 ssp->set(value);
3000 return 0;
3001 }
3002 break;
3003 }
3004 #ifndef OSG_USE_FLOAT_MATRIX
3005 case(osgDB::BaseSerializer::RW_MATRIX):
3006 #endif
3007 case(osgDB::BaseSerializer::RW_MATRIXD):
3008 {
3009 osg::Matrixd value;
3010 if (getValue(pos, value))
3011 {
3012 ssp->set(value);
3013 return 0;
3014 }
3015 break;
3016 }
3017 case(osgDB::BaseSerializer::RW_BOUNDINGBOXF):
3018 {
3019 osg::BoundingBoxf value;
3020 if (getValue(pos, value))
3021 {
3022 ssp->set(value);
3023 return 0;
3024 }
3025 break;
3026 }
3027 case(osgDB::BaseSerializer::RW_BOUNDINGBOXD):
3028 {
3029 osg::BoundingBoxd value;
3030 if (getValue(pos, value))
3031 {
3032 ssp->set(value);
3033 return 0;
3034 }
3035 break;
3036 }
3037 case(osgDB::BaseSerializer::RW_BOUNDINGSPHEREF):
3038 {
3039 osg::BoundingSpheref value;
3040 if (getValue(pos, value))
3041 {
3042 ssp->set(value);
3043 return 0;
3044 }
3045 break;
3046 }
3047 case(osgDB::BaseSerializer::RW_BOUNDINGSPHERED):
3048 {
3049 osg::BoundingSphered value;
3050 if (getValue(pos, value))
3051 {
3052 ssp->set(value);
3053 return 0;
3054 }
3055 break;
3056 }
3057 case(osgDB::BaseSerializer::RW_LIST):
3058 {
3059 OSG_NOTICE<<"Need to implement RW_LIST support"<<std::endl;
3060 break;
3061 }
3062 case(osgDB::BaseSerializer::RW_IMAGE):
3063 case(osgDB::BaseSerializer::RW_OBJECT):
3064 {
3065 if (lua_istable(_lua, pos))
3066 {
3067 osg::Object* value = 0;
3068 lua_pushstring(_lua, "object_ptr");
3069 lua_rawget(_lua, pos);
3070 if (lua_type(_lua, -1)==LUA_TUSERDATA) value = *const_cast<osg::Object**>(reinterpret_cast<const osg::Object**>(lua_touserdata(_lua,-1)));
3071 lua_pop(_lua, 1);
3072
3073 if (value)
3074 {
3075 ssp->set(value);
3076 return 0;
3077 }
3078 else
3079 {
3080 OSG_NOTICE<<"Error: lua type '"<<lua_typename(_lua,lua_type(_lua, pos))<<"' cannot be assigned." <<std::endl;
3081 }
3082 }
3083 else if (lua_isnil(_lua, pos))
3084 {
3085 OSG_NOTICE<<"Assigning property object (nil) to to object"<<std::endl;
3086 osg::Object* value = 0;
3087 ssp->set(value);
3088 return 0;
3089 }
3090 else
3091 {
3092 OSG_NOTICE<<"Error: lua type '"<<lua_typename(_lua,lua_type(_lua, pos))<<"' cannot be assigned."<<std::endl;
3093 return 0;
3094 }
3095 break;
3096 }
3097 default:
3098 break;
3099 }
3100 OSG_NOTICE<<"LuaScriptEngine::getDataFromStack() property of type = "<<_ci.getTypeName(type)<<" not matched"<<std::endl;
3101 return 0;
3102
3103 }
3104
3105
setPropertyFromStack(osg::Object * object,const std::string & propertyName) const3106 int LuaScriptEngine::setPropertyFromStack(osg::Object* object, const std::string& propertyName) const
3107 {
3108 osgDB::BaseSerializer::Type type;
3109 if (!_ci.getPropertyType(object, propertyName, type))
3110 {
3111 if (lua_type(_lua,-1)==LUA_TFUNCTION)
3112 {
3113 int ref = luaL_ref(_lua, LUA_REGISTRYINDEX);
3114 osg::ref_ptr<LuaCallbackObject> lco = new LuaCallbackObject(propertyName, this, ref);
3115
3116 osg::UserDataContainer* udc = object->getOrCreateUserDataContainer();
3117 unsigned int objectIndex = udc->getUserObjectIndex(propertyName);
3118 if (objectIndex < udc->getNumUserObjects())
3119 {
3120 udc->setUserObject(objectIndex, lco.get());
3121 }
3122 else
3123 {
3124 udc->addUserObject(lco.get());
3125 }
3126
3127 return 0;
3128 }
3129
3130 type = LuaScriptEngine::getType(-1);
3131 }
3132
3133 return setPropertyFromStack(object, propertyName, type);
3134 }
3135
setPropertyFromStack(osg::Object * object,const std::string & propertyName,osgDB::BaseSerializer::Type type) const3136 int LuaScriptEngine::setPropertyFromStack(osg::Object* object, const std::string& propertyName, osgDB::BaseSerializer::Type type) const
3137 {
3138 switch(type)
3139 {
3140 case(osgDB::BaseSerializer::RW_BOOL):
3141 {
3142 if (lua_isboolean(_lua, -1))
3143 {
3144 _ci.setProperty(object, propertyName, static_cast<bool>(lua_toboolean(_lua, -1)!=0));
3145 return 0;
3146 }
3147 else if (lua_isnumber(_lua, -1))
3148 {
3149 _ci.setProperty(object, propertyName, static_cast<bool>(lua_tonumber(_lua, -1)!=0));
3150 return 0;
3151 }
3152 break;
3153 }
3154 case(osgDB::BaseSerializer::RW_STRING):
3155 {
3156 if (lua_isstring(_lua, -1))
3157 {
3158 _ci.setProperty(object, propertyName, std::string(lua_tostring(_lua, -1)));
3159 return 0;
3160 }
3161 break;
3162 }
3163 case(osgDB::BaseSerializer::RW_GLENUM):
3164 {
3165 if (lua_isnumber(_lua, -1))
3166 {
3167 _ci.setProperty(object, propertyName, static_cast<GLenum>(lua_tonumber(_lua, -1)));
3168 return 0;
3169 }
3170 else if (lua_isstring(_lua, -1))
3171 {
3172 const char* enumString = lua_tostring(_lua, -1);
3173 GLenum value = lookUpGLenumValue(enumString); //getValue("GL",enumString);
3174
3175 _ci.setProperty(object, propertyName, value);
3176 return 0;
3177 }
3178 OSG_NOTICE<<"LuaScriptEngine::setPropertyFromStack("<<propertyName<<") osgDB::BaseSerializer::RW_GLENUM Failed"<<std::endl;
3179 break;
3180 }
3181 case(osgDB::BaseSerializer::RW_ENUM):
3182 {
3183 if (lua_isnumber(_lua, -1))
3184 {
3185 _ci.setProperty(object, propertyName, static_cast<int>(lua_tonumber(_lua, -1)));
3186 return 0;
3187 }
3188 else if (lua_isstring(_lua, -1))
3189 {
3190 const char* enumString = lua_tostring(_lua, -1);
3191 osgDB::BaseSerializer* serializer = _ci.getSerializer(object, propertyName, type);
3192 osgDB::IntLookup* lookup = serializer ? serializer->getIntLookup() : 0;
3193 if (lookup)
3194 {
3195 int value = lookup->getValue(enumString);
3196 _ci.setProperty(object, propertyName, value);
3197 }
3198 return 0;
3199 }
3200 break;
3201 }
3202 case(osgDB::BaseSerializer::RW_SHORT):
3203 {
3204 if (lua_isnumber(_lua, -1))
3205 {
3206 _ci.setProperty(object, propertyName, static_cast<short>(lua_tonumber(_lua, -1)));
3207 return 0;
3208 }
3209 break;
3210 }
3211 case(osgDB::BaseSerializer::RW_USHORT):
3212 {
3213 if (lua_isnumber(_lua, -1))
3214 {
3215 _ci.setProperty(object, propertyName, static_cast<unsigned short>(lua_tonumber(_lua, -1)));
3216 return 0;
3217 }
3218 break;
3219 }
3220 case(osgDB::BaseSerializer::RW_INT):
3221 {
3222 if (lua_isnumber(_lua, -1))
3223 {
3224 _ci.setProperty(object, propertyName, static_cast<int>(lua_tonumber(_lua, -1)));
3225 return 0;
3226 }
3227 break;
3228 }
3229 case(osgDB::BaseSerializer::RW_UINT):
3230 {
3231 if (lua_isnumber(_lua, -1))
3232 {
3233 _ci.setProperty(object, propertyName, static_cast<unsigned int>(lua_tonumber(_lua, -1)));
3234 return 0;
3235 }
3236 break;
3237 }
3238 case(osgDB::BaseSerializer::RW_FLOAT):
3239 {
3240 if (lua_isnumber(_lua, -1))
3241 {
3242 _ci.setProperty(object, propertyName, static_cast<float>(lua_tonumber(_lua, -1)));
3243 return 0;
3244 }
3245 break;
3246 }
3247 case(osgDB::BaseSerializer::RW_DOUBLE):
3248 {
3249 if (lua_isnumber(_lua, -1))
3250 {
3251 _ci.setProperty(object, propertyName, static_cast<double>(lua_tonumber(_lua, -1)));
3252 return 0;
3253 }
3254 break;
3255 }
3256
3257 case(osgDB::BaseSerializer::RW_VEC2B): if (getValueAndSetProperty<osg::Vec2b>(object, propertyName)) return 0; break;
3258 case(osgDB::BaseSerializer::RW_VEC3B): if (getValueAndSetProperty<osg::Vec3b>(object, propertyName)) return 0; break;
3259 case(osgDB::BaseSerializer::RW_VEC4B): if (getValueAndSetProperty<osg::Vec4b>(object, propertyName)) return 0; break;
3260
3261 case(osgDB::BaseSerializer::RW_VEC2UB): if (getValueAndSetProperty<osg::Vec2ub>(object, propertyName)) return 0; break;
3262 case(osgDB::BaseSerializer::RW_VEC3UB): if (getValueAndSetProperty<osg::Vec3ub>(object, propertyName)) return 0; break;
3263 case(osgDB::BaseSerializer::RW_VEC4UB): if (getValueAndSetProperty<osg::Vec4ub>(object, propertyName)) return 0; break;
3264
3265 case(osgDB::BaseSerializer::RW_VEC2F): if (getValueAndSetProperty<osg::Vec2f>(object, propertyName)) return 0; break;
3266 case(osgDB::BaseSerializer::RW_VEC3F): if (getValueAndSetProperty<osg::Vec3f>(object, propertyName)) return 0; break;
3267 case(osgDB::BaseSerializer::RW_VEC4F): if (getValueAndSetProperty<osg::Vec4f>(object, propertyName)) return 0; break;
3268
3269 case(osgDB::BaseSerializer::RW_VEC2D): if (getValueAndSetProperty<osg::Vec2d>(object, propertyName)) return 0; break;
3270 case(osgDB::BaseSerializer::RW_VEC3D): if (getValueAndSetProperty<osg::Vec3d>(object, propertyName)) return 0; break;
3271 case(osgDB::BaseSerializer::RW_VEC4D): if (getValueAndSetProperty<osg::Vec4d>(object, propertyName)) return 0; break;
3272
3273 case(osgDB::BaseSerializer::RW_QUAT): if (getValueAndSetProperty<osg::Quat>(object, propertyName)) return 0; break;
3274 case(osgDB::BaseSerializer::RW_PLANE): if (getValueAndSetProperty<osg::Plane>(object, propertyName)) return 0; break;
3275
3276 #ifdef OSG_USE_FLOAT_MATRIX
3277 case(osgDB::BaseSerializer::RW_MATRIX):
3278 #endif
3279 case(osgDB::BaseSerializer::RW_MATRIXF):
3280 {
3281 osg::Matrixd value;
3282 if (getValue(-1, value))
3283 {
3284 _ci.setProperty(object, propertyName, value);
3285 return 0;
3286 }
3287 break;
3288 }
3289 #ifndef OSG_USE_FLOAT_MATRIX
3290 case(osgDB::BaseSerializer::RW_MATRIX):
3291 #endif
3292 case(osgDB::BaseSerializer::RW_MATRIXD):
3293 {
3294 osg::Matrixd value;
3295 if (getValue(-1, value))
3296 {
3297 _ci.setProperty(object, propertyName, value);
3298 return 0;
3299 }
3300 break;
3301 }
3302 case(osgDB::BaseSerializer::RW_BOUNDINGBOXF):
3303 {
3304 osg::BoundingBoxf value;
3305 if (getValue(-1, value))
3306 {
3307 _ci.setProperty(object, propertyName, value);
3308 return 0;
3309 }
3310 break;
3311 }
3312 case(osgDB::BaseSerializer::RW_BOUNDINGBOXD):
3313 {
3314 osg::BoundingBoxd value;
3315 if (getValue(-1, value))
3316 {
3317 _ci.setProperty(object, propertyName, value);
3318 return 0;
3319 }
3320 break;
3321 }
3322 case(osgDB::BaseSerializer::RW_BOUNDINGSPHEREF):
3323 {
3324 osg::BoundingSpheref value;
3325 if (getValue(-1, value))
3326 {
3327 _ci.setProperty(object, propertyName, value);
3328 return 0;
3329 }
3330 break;
3331 }
3332 case(osgDB::BaseSerializer::RW_BOUNDINGSPHERED):
3333 {
3334 osg::BoundingSphered value;
3335 if (getValue(-1, value))
3336 {
3337 _ci.setProperty(object, propertyName, value);
3338 return 0;
3339 }
3340 break;
3341 }
3342 case(osgDB::BaseSerializer::RW_IMAGE):
3343 case(osgDB::BaseSerializer::RW_OBJECT):
3344 {
3345 if (lua_istable(_lua, -1))
3346 {
3347 osg::Object* value = 0;
3348 lua_pushstring(_lua, "object_ptr");
3349 lua_rawget(_lua, -2);
3350 if (lua_type(_lua, -1)==LUA_TUSERDATA) value = *const_cast<osg::Object**>(reinterpret_cast<const osg::Object**>(lua_touserdata(_lua,-1)));
3351 lua_pop(_lua, 1);
3352
3353 if (value)
3354 {
3355 _ci.setProperty(object, propertyName, value);
3356 return 0;
3357 }
3358 else
3359 {
3360 OSG_NOTICE<<"Error: lua type '"<<lua_typename(_lua,lua_type(_lua, -1))<<"' cannot be assigned to "<<object->className()<<"::"<<propertyName<<std::endl;
3361 }
3362 }
3363 else if (lua_type(_lua,-1)==LUA_TFUNCTION)
3364 {
3365 int ref = luaL_ref(_lua, LUA_REGISTRYINDEX);
3366 osg::ref_ptr<LuaCallbackObject> lco = new LuaCallbackObject(propertyName, this, ref);
3367 osg::Object* value = lco.get();
3368 _ci.setProperty(object, propertyName, value);
3369
3370 return 0;
3371 }
3372 else if (lua_isnil(_lua, -1))
3373 {
3374 OSG_NOTICE<<"Assigning property object (nil) to to object "<<object->className()<<"::"<<propertyName<<std::endl;
3375 osg::Object* value = 0;
3376 _ci.setProperty(object, propertyName, value);
3377 return 0;
3378 }
3379 else
3380 {
3381 OSG_NOTICE<<"Error: lua type '"<<lua_typename(_lua,lua_type(_lua, -1))<<"' cannot be assigned to "<<object->className()<<"::"<<propertyName<<std::endl;
3382 return 0;
3383 }
3384 break;
3385 }
3386 case(osgDB::BaseSerializer::RW_LIST):
3387 default:
3388 break;
3389 }
3390 OSG_NOTICE<<"LuaScriptEngine::setPropertyFromStack("<<object<<", "<<propertyName<<") property of type = "<<_ci.getTypeName(type)<<" not implemented"<<std::endl;
3391 return 0;
3392 }
3393
3394
3395
getfields(int pos,const char * f1,const char * f2,int type) const3396 bool LuaScriptEngine::getfields(int pos, const char* f1, const char* f2, int type) const
3397 {
3398 int abs_pos = getAbsolutePos(pos);
3399 lua_getfield(_lua, abs_pos, f1);
3400 lua_getfield(_lua, abs_pos, f2);
3401 if (lua_type(_lua, -2)!=type || lua_type(_lua, -1)!=type) { lua_pop(_lua, 2); return false; }
3402
3403 return true;
3404 }
3405
getfields(int pos,const char * f1,const char * f2,const char * f3,int type) const3406 bool LuaScriptEngine::getfields(int pos, const char* f1, const char* f2, const char* f3, int type) const
3407 {
3408 int abs_pos = getAbsolutePos(pos);
3409 lua_getfield(_lua, abs_pos, f1);
3410 lua_getfield(_lua, abs_pos, f2);
3411 lua_getfield(_lua, abs_pos, f3);
3412 if (lua_type(_lua, -3)!=type || lua_type(_lua, -2)!=type ||
3413 lua_type(_lua, -1)!=type) { lua_pop(_lua, 3); return false; }
3414
3415 return true;
3416 }
3417
getfields(int pos,const char * f1,const char * f2,const char * f3,const char * f4,int type) const3418 bool LuaScriptEngine::getfields(int pos, const char* f1, const char* f2, const char* f3, const char* f4, int type) const
3419 {
3420 int abs_pos = getAbsolutePos(pos);
3421 lua_getfield(_lua, abs_pos, f1);
3422 lua_getfield(_lua, abs_pos, f2);
3423 lua_getfield(_lua, abs_pos, f3);
3424 lua_getfield(_lua, abs_pos, f4);
3425 if (lua_type(_lua, -4)!=type || lua_type(_lua, -3)!=type ||
3426 lua_type(_lua, -2)!=type || lua_type(_lua, -1)!=type) { lua_pop(_lua, 4); return false; }
3427
3428 return true;
3429 }
3430
getfields(int pos,const char * f1,const char * f2,const char * f3,const char * f4,const char * f5,const char * f6,int type) const3431 bool LuaScriptEngine::getfields(int pos, const char* f1, const char* f2, const char* f3, const char* f4, const char* f5, const char* f6, int type) const
3432 {
3433 int abs_pos = getAbsolutePos(pos);
3434 lua_getfield(_lua, abs_pos, f1);
3435 lua_getfield(_lua, abs_pos, f2);
3436 lua_getfield(_lua, abs_pos, f3);
3437 lua_getfield(_lua, abs_pos, f4);
3438 lua_getfield(_lua, abs_pos, f5);
3439 lua_getfield(_lua, abs_pos, f6);
3440 if (lua_type(_lua, -6)!=type || lua_type(_lua, -5)!=type ||
3441 lua_type(_lua, -4)!=type || lua_type(_lua, -3)!=type ||
3442 lua_type(_lua, -2)!=type || lua_type(_lua, -1)!=type) { lua_pop(_lua, 6); return false; }
3443
3444 return true;
3445 }
3446
getelements(int pos,int numElements,int type) const3447 bool LuaScriptEngine::getelements(int pos, int numElements, int type) const
3448 {
3449 int abs_pos = getAbsolutePos(pos);
3450 for(int i=0; i<numElements; ++i)
3451 {
3452 lua_pushinteger(_lua, i);
3453 lua_gettable(_lua, abs_pos);
3454 if (lua_type(_lua, -1)!=type) { lua_pop(_lua, i+1); return false; }
3455 }
3456 return true;
3457 }
3458
3459
getType(int pos) const3460 osgDB::BaseSerializer::Type LuaScriptEngine::getType(int pos) const
3461 {
3462 int abs_pos = getAbsolutePos(pos);
3463 switch(lua_type(_lua, abs_pos))
3464 {
3465 case(LUA_TNIL): return osgDB::BaseSerializer::RW_UNDEFINED;
3466 case(LUA_TNUMBER): return osgDB::BaseSerializer::RW_DOUBLE;
3467 case(LUA_TBOOLEAN): return osgDB::BaseSerializer::RW_BOOL;
3468 case(LUA_TSTRING): return osgDB::BaseSerializer::RW_STRING;
3469 case(LUA_TTABLE):
3470 {
3471 lua_pushstring(_lua, "object_ptr");
3472 lua_rawget(_lua, abs_pos);
3473 bool isObject = (lua_type(_lua, -1)==LUA_TUSERDATA);
3474 lua_pop(_lua, 1);
3475
3476 if (isObject)
3477 {
3478 return osgDB::BaseSerializer::RW_OBJECT;
3479 }
3480
3481
3482 int n = lua_gettop(_lua); /* number of arguments */
3483 lua_pushnil(_lua);
3484
3485 int numStringKeys = 0;
3486 int numNumberKeys = 0;
3487 int numNumberFields = 0;
3488
3489 while (lua_next(_lua, n) != 0)
3490 {
3491 if (lua_type(_lua, -2)==LUA_TSTRING) ++numStringKeys;
3492 else if (lua_type(_lua, -2)==LUA_TNUMBER) ++numNumberKeys;
3493
3494 if (lua_type(_lua, -1)==LUA_TNUMBER) ++numNumberFields;
3495
3496 lua_pop(_lua, 1); // remove value, leave key for next iteration
3497 }
3498
3499 if ((numStringKeys==2 || numNumberKeys==2) && (numNumberFields==2))
3500 {
3501 return osgDB::BaseSerializer::RW_VEC2D;
3502 }
3503 else if ((numStringKeys==3 || numNumberKeys==3) && (numNumberFields==3))
3504 {
3505 return osgDB::BaseSerializer::RW_VEC3D;
3506 }
3507 else if ((numStringKeys==4 || numNumberKeys==4) && (numNumberFields==4))
3508 {
3509 return osgDB::BaseSerializer::RW_VEC4D;
3510 }
3511 else if ((numNumberKeys==16) && (numNumberFields==16))
3512 {
3513 return osgDB::BaseSerializer::RW_MATRIXD;
3514 }
3515 else if ((numNumberKeys==6) && (numNumberFields==6))
3516 {
3517 return osgDB::BaseSerializer::RW_BOUNDINGBOXD;
3518 }
3519 // not supported
3520 OSG_NOTICE<<"Warning: LuaScriptEngine::getType() Lua table configuration not supported."<<std::endl;
3521 break;
3522 }
3523 default:
3524 OSG_NOTICE<<"Warning: LuaScriptEngine::getType() Lua type "<<lua_typename(_lua, lua_type(_lua, abs_pos))<<" not supported."<<std::endl;
3525 break;
3526
3527 }
3528 return osgDB::BaseSerializer::RW_UNDEFINED;
3529 }
3530
getvec2(int pos) const3531 bool LuaScriptEngine::getvec2(int pos) const
3532 {
3533 int abs_pos = getAbsolutePos(pos);
3534 if (lua_istable(_lua, abs_pos))
3535 {
3536 if (getfields(abs_pos, "x", "y", LUA_TNUMBER) ||
3537 getfields(abs_pos, "s", "t", LUA_TNUMBER) ||
3538 getfields(abs_pos, "luminance", "alpha", LUA_TNUMBER) ||
3539 getelements(abs_pos, 2, LUA_TNUMBER))
3540 {
3541 return true;
3542 }
3543 }
3544 return false;
3545 }
3546
getvec3(int pos) const3547 bool LuaScriptEngine::getvec3(int pos) const
3548 {
3549 int abs_pos = getAbsolutePos(pos);
3550 if (lua_istable(_lua, abs_pos))
3551 {
3552 if (getfields(abs_pos, "x", "y", "z", LUA_TNUMBER) ||
3553 getfields(abs_pos, "r", "g", "b", LUA_TNUMBER) ||
3554 getfields(abs_pos, "red", "green", "blue", LUA_TNUMBER) ||
3555 getfields(abs_pos, "s", "t", "r", LUA_TNUMBER) ||
3556 getelements(abs_pos, 3, LUA_TNUMBER))
3557 {
3558 return true;
3559 }
3560 }
3561 return false;
3562 }
getvec4(int pos) const3563 bool LuaScriptEngine::getvec4(int pos) const
3564 {
3565 int abs_pos = getAbsolutePos(pos);
3566 if (lua_istable(_lua, abs_pos))
3567 {
3568 if (getfields(abs_pos, "x", "y", "z", "w", LUA_TNUMBER) ||
3569 getfields(abs_pos, "r", "g", "b", "a", LUA_TNUMBER) ||
3570 getfields(abs_pos, "red", "green", "blue", "alpha", LUA_TNUMBER) ||
3571 getfields(abs_pos, "s", "t", "r", "q", LUA_TNUMBER) ||
3572 getelements(abs_pos, 4, LUA_TNUMBER))
3573 {
3574 return true;
3575 }
3576 }
3577 return false;
3578 }
3579
getmatrix(int pos) const3580 bool LuaScriptEngine::getmatrix(int pos) const
3581 {
3582 int abs_pos = getAbsolutePos(pos);
3583 if (lua_istable(_lua, abs_pos))
3584 {
3585 if (getelements(abs_pos, 16,LUA_TNUMBER))
3586 {
3587 return true;
3588 }
3589 }
3590 return false;
3591 }
3592
getboundingbox(int pos) const3593 bool LuaScriptEngine::getboundingbox(int pos) const
3594 {
3595 int abs_pos = getAbsolutePos(pos);
3596 if (lua_istable(_lua, abs_pos))
3597 {
3598 if (getfields(abs_pos, "xMin", "yMin", "zMin", "xMax", "yMax", "zMax", LUA_TNUMBER) ||
3599 getelements(abs_pos, 6, LUA_TNUMBER))
3600 {
3601 return true;
3602 }
3603 }
3604 return false;
3605 }
3606
getboundingsphere(int pos) const3607 bool LuaScriptEngine::getboundingsphere(int pos) const
3608 {
3609 int abs_pos = getAbsolutePos(pos);
3610 if (lua_istable(_lua, abs_pos))
3611 {
3612 if (getfields(abs_pos, "x", "y", "z", "radius", LUA_TNUMBER) ||
3613 getelements(abs_pos, 4, LUA_TNUMBER))
3614 {
3615 return true;
3616 }
3617 }
3618 return false;
3619 }
3620
getValue(int pos,osg::Matrixf & value) const3621 bool LuaScriptEngine::getValue(int pos, osg::Matrixf& value) const
3622 {
3623 if (!getmatrix(pos)) return false;
3624
3625 for(int r=0; r<4; ++r)
3626 {
3627 for(int c=0; c<4; ++c)
3628 {
3629 value(r,c) = lua_tonumber(_lua, -16+(r*4+c));
3630 }
3631 }
3632 lua_pop(_lua, 16);
3633 return true;
3634 }
3635
getValue(int pos,osg::Matrixd & value) const3636 bool LuaScriptEngine::getValue(int pos, osg::Matrixd& value) const
3637 {
3638 if (!getmatrix(pos)) return false;
3639
3640 for(int r=0; r<4; ++r)
3641 {
3642 for(int c=0; c<4; ++c)
3643 {
3644 value(r,c) = lua_tonumber(_lua, -16+(r*4+c));
3645 }
3646 }
3647 lua_pop(_lua, 16);
3648 return true;
3649 }
3650
getValue(int pos,osg::BoundingBoxf & value) const3651 bool LuaScriptEngine::getValue(int pos, osg::BoundingBoxf& value) const
3652 {
3653 if (!getboundingbox(pos)) return false;
3654 value.set(lua_tonumber(_lua, -6), lua_tonumber(_lua, -5), lua_tonumber(_lua, -4), lua_tonumber(_lua, -3), lua_tonumber(_lua, -2), lua_tonumber(_lua, -1));
3655 lua_pop(_lua, 6);
3656 return true;
3657 }
3658
getValue(int pos,osg::BoundingBoxd & value) const3659 bool LuaScriptEngine::getValue(int pos, osg::BoundingBoxd& value) const
3660 {
3661 if (!getboundingbox(pos)) return false;
3662 value.set(lua_tonumber(_lua, -6), lua_tonumber(_lua, -5), lua_tonumber(_lua, -4), lua_tonumber(_lua, -3), lua_tonumber(_lua, -2), lua_tonumber(_lua, -1));
3663 lua_pop(_lua, 6);
3664 return true;
3665 }
3666
getValue(int pos,osg::BoundingSpheref & value) const3667 bool LuaScriptEngine::getValue(int pos, osg::BoundingSpheref& value) const
3668 {
3669 if (!getboundingsphere(pos)) return false;
3670 value.set(osg::Vec3f(lua_tonumber(_lua, -4), lua_tonumber(_lua, -3), lua_tonumber(_lua, -2)), lua_tonumber(_lua, -1));
3671 lua_pop(_lua, 4);
3672 return true;
3673 }
3674
getValue(int pos,osg::BoundingSphered & value) const3675 bool LuaScriptEngine::getValue(int pos, osg::BoundingSphered& value) const
3676 {
3677 if (!getboundingsphere(pos)) return false;
3678 value.set(osg::Vec3d(lua_tonumber(_lua, -4), lua_tonumber(_lua, -3), lua_tonumber(_lua, -2)), lua_tonumber(_lua, -1));
3679 lua_pop(_lua, 4);
3680 return true;
3681 }
3682
pushValue(const osg::Matrixf & value) const3683 void LuaScriptEngine::pushValue(const osg::Matrixf& value) const
3684 {
3685 lua_newtable(_lua);
3686 lua_newtable(_lua); luaL_getmetatable(_lua, "LuaScriptEngine.Table"); lua_setmetatable(_lua, -2);
3687
3688 for(unsigned int r=0; r<4; ++r)
3689 {
3690 for(unsigned int c=0; c<4; ++c)
3691 {
3692 lua_pushinteger(_lua, r*4+c); lua_pushnumber(_lua, (lua_Integer) value(r,c)); lua_settable(_lua, -3);
3693 }
3694 }
3695 }
3696
pushValue(const osg::Matrixd & value) const3697 void LuaScriptEngine::pushValue(const osg::Matrixd& value) const
3698 {
3699 lua_newtable(_lua);
3700 lua_newtable(_lua); luaL_getmetatable(_lua, "LuaScriptEngine.Table"); lua_setmetatable(_lua, -2);
3701
3702 for(unsigned int r=0; r<4; ++r)
3703 {
3704 for(unsigned int c=0; c<4; ++c)
3705 {
3706 lua_pushinteger(_lua, r*4+c); lua_pushnumber(_lua, value(r,c)); lua_settable(_lua, -3);
3707 }
3708 }
3709 }
3710
pushValue(const osg::BoundingBoxf & value) const3711 void LuaScriptEngine::pushValue(const osg::BoundingBoxf& value) const
3712 {
3713 lua_newtable(_lua);
3714 lua_newtable(_lua); luaL_getmetatable(_lua, "LuaScriptEngine.Table"); lua_setmetatable(_lua, -2);
3715 lua_pushstring(_lua, "xMin"); lua_pushnumber(_lua, value.xMin()); lua_settable(_lua, -3);
3716 lua_pushstring(_lua, "yMin"); lua_pushnumber(_lua, value.yMin()); lua_settable(_lua, -3);
3717 lua_pushstring(_lua, "zMin"); lua_pushnumber(_lua, value.zMin()); lua_settable(_lua, -3);
3718 lua_pushstring(_lua, "xMax"); lua_pushnumber(_lua, value.xMax()); lua_settable(_lua, -3);
3719 lua_pushstring(_lua, "yMax"); lua_pushnumber(_lua, value.yMax()); lua_settable(_lua, -3);
3720 lua_pushstring(_lua, "zMax"); lua_pushnumber(_lua, value.zMax()); lua_settable(_lua, -3);
3721 }
3722
pushValue(const osg::BoundingBoxd & value) const3723 void LuaScriptEngine::pushValue(const osg::BoundingBoxd& value) const
3724 {
3725 lua_newtable(_lua);
3726 lua_newtable(_lua); luaL_getmetatable(_lua, "LuaScriptEngine.Table"); lua_setmetatable(_lua, -2);
3727 lua_pushstring(_lua, "xMin"); lua_pushnumber(_lua, value.xMin()); lua_settable(_lua, -3);
3728 lua_pushstring(_lua, "yMin"); lua_pushnumber(_lua, value.yMin()); lua_settable(_lua, -3);
3729 lua_pushstring(_lua, "zMin"); lua_pushnumber(_lua, value.zMin()); lua_settable(_lua, -3);
3730 lua_pushstring(_lua, "xMax"); lua_pushnumber(_lua, value.xMax()); lua_settable(_lua, -3);
3731 lua_pushstring(_lua, "yMax"); lua_pushnumber(_lua, value.yMax()); lua_settable(_lua, -3);
3732 lua_pushstring(_lua, "zMax"); lua_pushnumber(_lua, value.zMax()); lua_settable(_lua, -3);
3733 }
3734
pushValue(const osg::BoundingSpheref & value) const3735 void LuaScriptEngine::pushValue(const osg::BoundingSpheref& value) const
3736 {
3737 lua_newtable(_lua);
3738 lua_newtable(_lua); luaL_getmetatable(_lua, "LuaScriptEngine.Table"); lua_setmetatable(_lua, -2);
3739 lua_pushstring(_lua, "x"); lua_pushnumber(_lua, value.center().x()); lua_settable(_lua, -3);
3740 lua_pushstring(_lua, "y"); lua_pushnumber(_lua, value.center().y()); lua_settable(_lua, -3);
3741 lua_pushstring(_lua, "z"); lua_pushnumber(_lua, value.center().z()); lua_settable(_lua, -3);
3742 lua_pushstring(_lua, "radius"); lua_pushnumber(_lua, value.radius()); lua_settable(_lua, -3);
3743 }
3744
pushValue(const osg::BoundingSphered & value) const3745 void LuaScriptEngine::pushValue(const osg::BoundingSphered& value) const
3746 {
3747 lua_newtable(_lua);
3748 lua_newtable(_lua); luaL_getmetatable(_lua, "LuaScriptEngine.Table"); lua_setmetatable(_lua, -2);
3749 lua_pushstring(_lua, "x"); lua_pushnumber(_lua, value.center().x()); lua_settable(_lua, -3);
3750 lua_pushstring(_lua, "y"); lua_pushnumber(_lua, value.center().y()); lua_settable(_lua, -3);
3751 lua_pushstring(_lua, "z"); lua_pushnumber(_lua, value.center().z()); lua_settable(_lua, -3);
3752 lua_pushstring(_lua, "radius"); lua_pushnumber(_lua, value.radius()); lua_settable(_lua, -3);
3753 }
3754
pushParameter(osg::Object * object) const3755 bool LuaScriptEngine::pushParameter(osg::Object* object) const
3756 {
3757 osg::ValueObject* vo = dynamic_cast<osg::ValueObject*>(object);
3758 if (vo)
3759 {
3760 PushStackValueVisitor pvv(this);
3761 vo->get(pvv);
3762 }
3763 else
3764 {
3765 pushObject( object);
3766 }
3767
3768 return false;
3769 }
3770
popParameter(osg::Object * object) const3771 bool LuaScriptEngine::popParameter(osg::Object* object) const
3772 {
3773 osg::ValueObject* vo = dynamic_cast<osg::ValueObject*>(object);
3774 if (vo)
3775 {
3776 GetStackValueVisitor pvv(this, -1);
3777 vo->set(pvv);
3778 lua_pop(_lua, pvv._numberToPop);
3779 }
3780 else
3781 {
3782 lua_pop(_lua, 1);
3783 }
3784
3785 return false;
3786 }
3787
popParameterObject() const3788 osg::Object* LuaScriptEngine::popParameterObject() const
3789 {
3790 osg::ref_ptr<osg::Object> object = 0;
3791
3792 osgDB::BaseSerializer::Type type = getType(-1);
3793 switch(type)
3794 {
3795 case(osgDB::BaseSerializer::RW_BOOL):
3796 {
3797 if (lua_isboolean(_lua, -1)) object = new osg::BoolValueObject("", lua_toboolean(_lua, -1)!=0);
3798 break;
3799 }
3800 case(osgDB::BaseSerializer::RW_STRING):
3801 {
3802 if (lua_isstring(_lua, -1)) object = new osg::StringValueObject("", lua_tostring(_lua, -1));
3803 break;
3804 }
3805 case(osgDB::BaseSerializer::RW_GLENUM):
3806 case(osgDB::BaseSerializer::RW_ENUM):
3807 if (lua_isstring(_lua, -1))
3808 {
3809 object = new osg::StringValueObject("", lua_tostring(_lua, -1));
3810 }
3811 else if (lua_isnumber(_lua, -1))
3812 {
3813 object = new osg::IntValueObject("", static_cast<int>(lua_tonumber(_lua, -1)));
3814 }
3815 break;
3816 case(osgDB::BaseSerializer::RW_INT):
3817 {
3818 if (lua_isnumber(_lua, -1)) object = new osg::IntValueObject("", static_cast<int>(lua_tonumber(_lua, -1)));
3819 break;
3820 }
3821 case(osgDB::BaseSerializer::RW_UINT):
3822 {
3823 if (lua_isnumber(_lua, -1)) object = new osg::UIntValueObject("", static_cast<unsigned int>(lua_tonumber(_lua, -1)));
3824 break;
3825 }
3826 case(osgDB::BaseSerializer::RW_FLOAT):
3827 {
3828 if (lua_isnumber(_lua, -1)) object = new osg::FloatValueObject("", static_cast<float>(lua_tonumber(_lua, -1)));
3829 break;
3830 }
3831 case(osgDB::BaseSerializer::RW_DOUBLE):
3832 {
3833 if (lua_isnumber(_lua, -1)) object = new osg::DoubleValueObject("", static_cast<double>(lua_tonumber(_lua, -1)));
3834 break;
3835 }
3836
3837 case(osgDB::BaseSerializer::RW_VEC2B): object = getValueObject<osg::Vec2b>(-1); break;
3838 case(osgDB::BaseSerializer::RW_VEC3B): object = getValueObject<osg::Vec3b>(-1); break;
3839 case(osgDB::BaseSerializer::RW_VEC4B): object = getValueObject<osg::Vec4b>(-1); break;
3840
3841 case(osgDB::BaseSerializer::RW_VEC2UB): object = getValueObject<osg::Vec2ub>(-1); break;
3842 case(osgDB::BaseSerializer::RW_VEC3UB): object = getValueObject<osg::Vec3ub>(-1); break;
3843 case(osgDB::BaseSerializer::RW_VEC4UB): object = getValueObject<osg::Vec4ub>(-1); break;
3844
3845 case(osgDB::BaseSerializer::RW_VEC2S): object = getValueObject<osg::Vec2s>(-1); break;
3846 case(osgDB::BaseSerializer::RW_VEC3S): object = getValueObject<osg::Vec3s>(-1); break;
3847 case(osgDB::BaseSerializer::RW_VEC4S): object = getValueObject<osg::Vec4s>(-1); break;
3848
3849 case(osgDB::BaseSerializer::RW_VEC2US): object = getValueObject<osg::Vec2us>(-1); break;
3850 case(osgDB::BaseSerializer::RW_VEC3US): object = getValueObject<osg::Vec3us>(-1); break;
3851 case(osgDB::BaseSerializer::RW_VEC4US): object = getValueObject<osg::Vec4us>(-1); break;
3852
3853 case(osgDB::BaseSerializer::RW_VEC2I): object = getValueObject<osg::Vec2i>(-1); break;
3854 case(osgDB::BaseSerializer::RW_VEC3I): object = getValueObject<osg::Vec3i>(-1); break;
3855 case(osgDB::BaseSerializer::RW_VEC4I): object = getValueObject<osg::Vec4i>(-1); break;
3856
3857 case(osgDB::BaseSerializer::RW_VEC2UI): object = getValueObject<osg::Vec2ui>(-1); break;
3858 case(osgDB::BaseSerializer::RW_VEC3UI): object = getValueObject<osg::Vec3ui>(-1); break;
3859 case(osgDB::BaseSerializer::RW_VEC4UI): object = getValueObject<osg::Vec4ui>(-1); break;
3860
3861 case(osgDB::BaseSerializer::RW_VEC2F): object = getValueObject<osg::Vec2f>(-1); break;
3862 case(osgDB::BaseSerializer::RW_VEC3F): object = getValueObject<osg::Vec3f>(-1); break;
3863 case(osgDB::BaseSerializer::RW_VEC4F): object = getValueObject<osg::Vec4f>(-1); break;
3864
3865 case(osgDB::BaseSerializer::RW_VEC2D): object = getValueObject<osg::Vec2d>(-1); break;
3866 case(osgDB::BaseSerializer::RW_VEC3D): object = getValueObject<osg::Vec3d>(-1); break;
3867 case(osgDB::BaseSerializer::RW_VEC4D): object = getValueObject<osg::Vec4d>(-1); break;
3868
3869 case(osgDB::BaseSerializer::RW_QUAT): object = getValueObject<osg::Quat>(-1); break;
3870 case(osgDB::BaseSerializer::RW_PLANE): object = getValueObject<osg::Plane>(-1); break;
3871
3872 #ifdef OSG_USE_FLOAT_MATRIX
3873 case(osgDB::BaseSerializer::RW_MATRIX):
3874 #endif
3875 case(osgDB::BaseSerializer::RW_MATRIXF):
3876 {
3877 osg::Matrixf value;
3878 if (getValue(-1, value)) object = new osg::MatrixfValueObject("", value);
3879 break;
3880 }
3881
3882 #ifndef OSG_USE_FLOAT_MATRIX
3883 case(osgDB::BaseSerializer::RW_MATRIX):
3884 #endif
3885 case(osgDB::BaseSerializer::RW_MATRIXD):
3886 {
3887 osg::Matrixd value;
3888 if (getValue(-1, value)) object = new osg::MatrixdValueObject("", value);
3889 break;
3890 }
3891 case(osgDB::BaseSerializer::RW_BOUNDINGBOXF):
3892 {
3893 osg::BoundingBoxf value;
3894 if (getValue(-1, value)) object = new osg::BoundingBoxfValueObject("", value);
3895 break;
3896 }
3897 case(osgDB::BaseSerializer::RW_BOUNDINGBOXD):
3898 {
3899 osg::BoundingBoxd value;
3900 if (getValue(-1, value)) object = new osg::BoundingBoxdValueObject("", value);
3901 break;
3902 }
3903 case(osgDB::BaseSerializer::RW_BOUNDINGSPHEREF):
3904 {
3905 osg::BoundingSpheref value;
3906 if (getValue(-1, value)) object = new osg::BoundingSpherefValueObject("", value);
3907 break;
3908 }
3909 case(osgDB::BaseSerializer::RW_BOUNDINGSPHERED):
3910 {
3911 osg::BoundingSphered value;
3912 if (getValue(-1, value)) object = new osg::BoundingSpheredValueObject("", value);
3913 break;
3914 }
3915 case(osgDB::BaseSerializer::RW_LIST):
3916 {
3917 OSG_NOTICE<<"Need to implement RW_LIST support"<<std::endl;
3918 break;
3919 }
3920 case(osgDB::BaseSerializer::RW_IMAGE):
3921 case(osgDB::BaseSerializer::RW_OBJECT):
3922 {
3923 lua_pushstring(_lua, "object_ptr");
3924 lua_rawget(_lua, -2);
3925 if (lua_type(_lua, -1)==LUA_TUSERDATA)
3926 {
3927 object = *const_cast<osg::Object**>(reinterpret_cast<const osg::Object**>(lua_touserdata(_lua,-1)));
3928 }
3929 lua_pop(_lua, 1);
3930 }
3931 default:
3932 break;
3933 }
3934
3935 lua_pop(_lua, 1);
3936
3937 return object.release();
3938 }
3939
pushContainer(osg::Object * object,const std::string & propertyName) const3940 void LuaScriptEngine::pushContainer(osg::Object* object, const std::string& propertyName) const
3941 {
3942 if (object)
3943 {
3944 lua_newtable(_lua);
3945
3946 // set up objbect_ptr to handle ref/unref of the object
3947 {
3948 lua_pushstring(_lua, "object_ptr");
3949
3950 // create user data for pointer
3951 void* userdata = lua_newuserdata( _lua, sizeof(osg::Object*));
3952 (*reinterpret_cast<osg::Object**>(userdata)) = object;
3953
3954 luaL_getmetatable( _lua, "LuaScriptEngine.UnrefObject");
3955 lua_setmetatable( _lua, -2 );
3956
3957 lua_settable(_lua, -3);
3958
3959
3960 // increment the reference count as the lua now will unreference it once it's finished with the userdata for the pointer
3961 object->ref();
3962 }
3963
3964 lua_pushstring(_lua, "containerPropertyName"); lua_pushstring(_lua, propertyName.c_str()); lua_settable(_lua, -3);
3965
3966 osgDB::BaseSerializer::Type type;
3967 osgDB::BaseSerializer* bs = _ci.getSerializer(object, propertyName, type);
3968 osgDB::VectorBaseSerializer* vs = dynamic_cast<osgDB::VectorBaseSerializer*>(bs);
3969 osgDB::MapBaseSerializer* ms = dynamic_cast<osgDB::MapBaseSerializer*>(bs);
3970 if (vs)
3971 {
3972 assignClosure("size", getContainerSize);
3973 assignClosure("clear", callVectorClear);
3974 assignClosure("resize", callVectorResize);
3975 assignClosure("reserve", callVectorReserve);
3976 assignClosure("add", callVectorAdd);
3977
3978 luaL_getmetatable(_lua, "LuaScriptEngine.Container");
3979 lua_setmetatable(_lua, -2);
3980 }
3981 else if (ms)
3982 {
3983 assignClosure("clear", callMapClear);
3984 assignClosure("size", getMapSize);
3985 assignClosure("createIterator", createMapIterator);
3986 assignClosure("createReverseIterator", createMapReverseIterator);
3987
3988 luaL_getmetatable(_lua, "LuaScriptEngine.Map");
3989 lua_setmetatable(_lua, -2);
3990 }
3991 else
3992 {
3993 OSG_NOTICE<<"Container type not supported."<<std::endl;
3994 }
3995 }
3996 else
3997 {
3998 lua_pushnil(_lua);
3999 }
4000 }
4001
4002
createAndPushObject(const std::string & compoundName) const4003 void LuaScriptEngine::createAndPushObject(const std::string& compoundName) const
4004 {
4005 osg::ref_ptr<osg::Object> object = _ci.createObject(compoundName);
4006 if (!object) OSG_NOTICE<<"Failed to create object "<<compoundName<<std::endl;
4007
4008 pushObject(object.get());
4009
4010 object.release();
4011 }
4012
pushObject(osg::Object * object) const4013 void LuaScriptEngine::pushObject(osg::Object* object) const
4014 {
4015 if (object)
4016 {
4017 lua_newtable(_lua);
4018
4019 // set up objbect_ptr to handle ref/unref of the object
4020 {
4021 lua_pushstring(_lua, "object_ptr");
4022
4023 // create user data for pointer
4024 void* userdata = lua_newuserdata( _lua, sizeof(osg::Object*));
4025 (*reinterpret_cast<osg::Object**>(userdata)) = object;
4026
4027 luaL_getmetatable( _lua, "LuaScriptEngine.UnrefObject");
4028 lua_setmetatable( _lua, -2 );
4029
4030 lua_settable(_lua, -3);
4031
4032 // increment the reference count as the lua now will unreference it once it's finished with the userdata for the pointer
4033 object->ref();
4034 }
4035
4036 lua_pushstring(_lua, "libraryName"); lua_pushstring(_lua, object->libraryName()); lua_settable(_lua, -3);
4037 lua_pushstring(_lua, "className"); lua_pushstring(_lua, object->className()); lua_settable(_lua, -3);
4038 lua_pushstring(_lua, "compoundClassName"); lua_pushstring(_lua, object->getCompoundClassName().c_str()); lua_settable(_lua, -3);
4039
4040 // check to see if Object "is a" vector
4041 osgDB::BaseSerializer::Type type;
4042 osgDB::BaseSerializer* vs = _ci.getSerializer(object, "vector", type);
4043 if (vs)
4044 {
4045 lua_pushstring(_lua, "containerPropertyName"); lua_pushstring(_lua, "vector"); lua_settable(_lua, -3);
4046
4047 assignClosure("size", getContainerSize);
4048 assignClosure("clear", callVectorClear);
4049 assignClosure("resize", callVectorResize);
4050 assignClosure("reserve", callVectorReserve);
4051 assignClosure("add", callVectorAdd);
4052
4053 luaL_getmetatable(_lua, "LuaScriptEngine.Container");
4054 lua_setmetatable(_lua, -2);
4055 }
4056 else if (dynamic_cast<osgDB::MapIteratorObject*>(object)!=0)
4057 {
4058 assignClosure("advance", callMapIteratorAdvance);
4059 assignClosure("valid", callMapIteratorValid);
4060 assignClosure("getKey", getMapIteratorKey);
4061 assignClosure("getElement", getMapIteratorElement);
4062 assignClosure("setElement", setMapIteratorElement);
4063 }
4064 else if (dynamic_cast<osg::Image*>(object)!=0)
4065 {
4066 assignClosure("allocate", callImageAllocate);
4067 assignClosure("s", callImageS);
4068 assignClosure("t", callImageT);
4069 assignClosure("r", callImageR);
4070 assignClosure("get", callImageGet);
4071 assignClosure("set", callImageSet);
4072
4073 luaL_getmetatable(_lua, "LuaScriptEngine.Object");
4074 lua_setmetatable(_lua, -2);
4075 }
4076 else if (dynamic_cast<osg::StateSet*>(object)!=0)
4077 {
4078 assignClosure("add", callStateSetSet);
4079 assignClosure("set", callStateSetSet);
4080 assignClosure("get", callStateSetGet);
4081 assignClosure("remove", callStateSetRemove);
4082
4083 luaL_getmetatable(_lua, "LuaScriptEngine.Object");
4084 lua_setmetatable(_lua, -2);
4085 }
4086 else if (dynamic_cast<osg::Node*>(object)!=0)
4087 {
4088 assignClosure("getParent", callGetParent);
4089 assignClosure("getNumParents", callGetNumParents);
4090
4091 luaL_getmetatable(_lua, "LuaScriptEngine.Object");
4092 lua_setmetatable(_lua, -2);
4093 }
4094 else
4095 {
4096 luaL_getmetatable(_lua, "LuaScriptEngine.Object");
4097 lua_setmetatable(_lua, -2);
4098 }
4099 }
4100 else
4101 {
4102 lua_pushnil(_lua);
4103 }
4104 }
4105
pushAndCastObject(const std::string & compoundClassName,osg::Object * object) const4106 void LuaScriptEngine::pushAndCastObject(const std::string& compoundClassName, osg::Object* object) const
4107 {
4108 if (object && _ci.isObjectOfType(object, compoundClassName))
4109 {
4110 lua_newtable(_lua);
4111
4112 // set up objbect_ptr to handle ref/unref of the object
4113 {
4114 lua_pushstring(_lua, "object_ptr");
4115
4116 // create user data for pointer
4117 void* userdata = lua_newuserdata( _lua, sizeof(osg::Object*));
4118 (*reinterpret_cast<osg::Object**>(userdata)) = object;
4119
4120 luaL_getmetatable( _lua, "LuaScriptEngine.UnrefObject");
4121 lua_setmetatable( _lua, -2 );
4122
4123 lua_settable(_lua, -3);
4124
4125 // increment the reference count as the lua now will unreference it once it's finished with the userdata for the pointer
4126 object->ref();
4127 }
4128
4129 std::string::size_type separator = compoundClassName.find("::");
4130 std::string libraryName = (separator==std::string::npos) ? object->libraryName() : compoundClassName.substr(0, separator);
4131 std::string className = (separator==std::string::npos) ? object->className() : compoundClassName.substr(separator+2,std::string::npos);
4132
4133 lua_pushstring(_lua, "libraryName"); lua_pushstring(_lua, libraryName.c_str()); lua_settable(_lua, -3);
4134 lua_pushstring(_lua, "className"); lua_pushstring(_lua, className.c_str()); lua_settable(_lua, -3);
4135
4136 lua_pushstring(_lua, "compoundClassName"); lua_pushstring(_lua, compoundClassName.c_str()); lua_settable(_lua, -3);
4137
4138 luaL_getmetatable(_lua, "LuaScriptEngine.Object");
4139 lua_setmetatable(_lua, -2);
4140 }
4141 else
4142 {
4143 lua_pushnil(_lua);
4144 }
4145 }
4146
assignClosure(const char * name,lua_CFunction fn) const4147 void LuaScriptEngine::assignClosure(const char* name, lua_CFunction fn) const
4148 {
4149 lua_pushstring(_lua, name);
4150 lua_pushlightuserdata(_lua, const_cast<LuaScriptEngine*>(this));
4151 lua_pushcclosure(_lua, fn, 1);
4152 lua_settable(_lua, -3);
4153 }
4154
addPaths(const osgDB::FilePathList & paths)4155 void LuaScriptEngine::addPaths(const osgDB::FilePathList& paths)
4156 {
4157 lua_getglobal( _lua, "package" );
4158
4159 lua_getfield( _lua, -1, "path" );
4160 std::string path = lua_tostring( _lua, -1 );
4161 lua_pop( _lua, 1 );
4162
4163 OSG_INFO<<"LuaScriptEngine::addPaths() original package.path = "<<path<<std::endl;
4164
4165
4166 for(osgDB::FilePathList::const_iterator itr = paths.begin();
4167 itr != paths.end();
4168 ++itr)
4169 {
4170 OSG_INFO<<" Appending path ["<<*itr<<"]"<<std::endl;
4171
4172 path.append( ";" );
4173 path.append( *itr );
4174 path.append( "/?.lua" );
4175 }
4176
4177 OSG_INFO<<" path after = "<<path<<std::endl;
4178
4179 lua_pushstring( _lua, path.c_str() );
4180 lua_setfield( _lua, -2, "path" );
4181
4182 lua_pop( _lua, 1 ); // return stack to original
4183 }
4184
addPaths(const osgDB::Options * options)4185 void LuaScriptEngine::addPaths(const osgDB::Options* options)
4186 {
4187 if (!options) return;
4188 addPaths(options->getDatabasePathList());
4189 }
4190
4191