Line data Source code
1 : //////////////////////////////////////////////////////////////////
2 : // Description : Functions for displaying models and storing //
3 : // their transformation data //
4 : //////////////////////////////////////////////////////////////////
5 : #include <cstdlib>
6 :
7 : #include "Object.h"
8 : #include "api.h"
9 : #include "Snow.h"
10 : #include "StarField.h"
11 :
12 : GLint numObjects;
13 : Object* object;
14 :
15 : unsigned int Object::textureIds[MAX_TEXTURES];
16 1 : std::map <std::string, unsigned int> Object::textureHash;
17 :
18 : //------------------------------------------------------------------------------
19 276 : Object::Object() : ObjectNode() {
20 69 : scriptName_ = "";
21 69 : particleSystem_ = NULL;
22 69 : L_ = NULL;
23 :
24 69 : init();
25 69 : }
26 :
27 : //------------------------------------------------------------------------------
28 69 : Object::~Object() {
29 69 : cleanup();
30 69 : }
31 :
32 : //------------------------------------------------------------------------------
33 138 : void Object::cleanup() {
34 138 : if (L_)
35 0 : lua_close(L_);
36 :
37 138 : if (particleSystem_)
38 0 : delete particleSystem_;
39 :
40 138 : L_ = NULL;
41 138 : particleSystem_ = NULL;
42 :
43 138 : scriptIndex_ = -1;
44 138 : gameLevelId_ = -1;
45 138 : }
46 :
47 : //------------------------------------------------------------------------------
48 69 : void Object::init() {
49 69 : cleanup();
50 69 : initSettings();
51 69 : }
52 :
53 : //------------------------------------------------------------------------------
54 69 : void Object::initSettings() {
55 69 : velocity_.setVector(0.0f, 0.0f, 0.0f);
56 69 : speed_.setVector(0.0f, 0.0f, 0.0f);
57 69 : scaleRate_.setVector(0.0f, 0.0f, 0.0f);
58 69 : rotationVelocity_.setVector(0.0f, 0.0f, 0.0f);
59 :
60 69 : setRotationEuler(0.0f, 0.0f, 0.0f);
61 69 : position_.setVector(0.0f, 0.0f, 0.0f);
62 69 : scale_.setVector(1.0f, 1.0f, 1.0f);
63 :
64 : //rotation_.loadMultIdentity();
65 69 : baseDirection_.setVector(0.0f, 0.0f, 1.0f);
66 69 : direction_.setVector(0.0f, 0.0f, 1.0f);
67 69 : up_.setVector(0.0f, 1.0f, 0.0f);
68 69 : orth_.setVector(1.0f, 0.0f, 0.0f);
69 :
70 : // set default orientation and disable interpolation
71 69 : rInterpStart_.loadMultIdentity();
72 69 : rInterpEnd_.loadMultIdentity();
73 :
74 69 : valInterpBegin_ = valInterpCurrent_ = valInterpEnd_ = 0.0f;
75 69 : isInterpolationEnabled_ = false;
76 :
77 : // setup default collision detection
78 69 : boundingSphere_.setSphere(0.0f, 0.0f, 0.0f, 0.0f);
79 69 : collisionBox_[0].setVector(0.0f, 0.0f, 0.0f);
80 69 : collisionBox_[1].setVector(0.0f, 0.0f, 0.0f);
81 69 : isCollisionDetectionEnabled_ = true;
82 :
83 69 : state_ = NORMAL;
84 69 : active_ = true;
85 69 : suspendTime_ = 0.0f;
86 69 : typeId_ = -1;
87 :
88 69 : isInView_ = true;
89 69 : isDrawEnabled_ = true;
90 :
91 69 : lastLight_.setVector(0.0f, 0.0f, 0.0f);
92 69 : scaleChanged_ = true;
93 69 : rotationChanged_ = true;
94 :
95 69 : isAlwaysLit_ = false;
96 :
97 69 : enableSphereTest_ = true;
98 69 : }
99 :
100 : //------------------------------------------------------------------------------
101 0 : void Object::setScript(const std::string &name) {
102 0 : scriptName_ = name;
103 :
104 : // If the lua state has not been initialized for this object, attempt to
105 : // initialize it.
106 0 : if (scriptName_ == "" || L_)
107 0 : return;
108 :
109 0 : L_ = lua_open();
110 :
111 : // If the lua state still could not be initialized, then exit the game.
112 : // ... we can do something smarter with this in the finished product.
113 0 : if (!L_) {
114 0 : PRINT_ERROR("Could not create Lua state.\n");
115 0 : exit(-1);
116 : }
117 :
118 : // Load the base lua libraries
119 0 : luaL_openlibs(L_);
120 :
121 : // Load our library
122 0 : luaopen_krigApi(L_);
123 :
124 0 : luaL_loadfile(L_, name.c_str());
125 0 : scriptIndex_ = luaL_ref( L_, LUA_REGISTRYINDEX );
126 0 : }
127 :
128 : //------------------------------------------------------------------------------
129 0 : void Object::loadScript(const std::string &name, lua_State* luaState) {
130 0 : if (scriptIndex_ == -1)
131 0 : return;
132 :
133 0 : lua_rawgeti(L_, LUA_REGISTRYINDEX, scriptIndex_);
134 0 : lua_call(L_, 0, 0);
135 :
136 : // Find the update function and call it
137 0 : lua_getglobal(L_, SCRIPT_CALLBACK_ON_LOAD);
138 :
139 : // Push a pointer to the current object for use within the lua function
140 0 : if (lua_isfunction (L_, -1)) {
141 0 : returnObject(L_, this);
142 0 : lua_newtable(L_);
143 :
144 0 : if (lua_istable(luaState, -1)) {
145 0 : traverseAndCopyLuaTable(luaState, L_, -2);
146 0 : }
147 :
148 : // Call the function with two arguments and no return values
149 0 : lua_call(L_, 2, 0);
150 0 : }
151 : else {
152 : PRINT_DEBUG_LVL(4, "'%s' function not defined.\n", SCRIPT_CALLBACK_ON_LOAD);
153 0 : lua_pop(L_, 1);
154 : }
155 0 : }
156 :
157 : //------------------------------------------------------------------------------
158 0 : void Object::unloadScript() {
159 : // Attempt to execute the on_unload function only if the lua state has
160 : // already been initialized with a script
161 0 : if (!L_)
162 0 : return;
163 :
164 : // Find the update function and call it
165 0 : lua_getglobal(L_, SCRIPT_CALLBACK_ON_UNLOAD);
166 :
167 : // Push a pointer to the current object for use within the lua function
168 0 : if (lua_isfunction(L_, -1)) {
169 0 : returnObject(L_, this);
170 0 : lua_call(L_, 1, 0);
171 0 : }
172 : else {
173 : PRINT_DEBUG_LVL(4, "'%s' function not defined.\n", SCRIPT_CALLBACK_ON_UNLOAD);
174 0 : lua_pop(L_, 1);
175 : }
176 :
177 0 : lua_close(L_);
178 0 : L_ = NULL;
179 0 : }
180 :
181 : //------------------------------------------------------------------------------
182 8 : void Object::animateScript(const float &elapsedTime) {
183 : // Attempt to execute the script only if the lua state has already been
184 : // initialized with a script
185 8 : if (!L_)
186 8 : return;
187 :
188 : // If the script is suspended, do not run until time has elapsed
189 0 : if (suspendTime_ > 0.0f) {
190 0 : suspendTime_ -= elapsedTime;
191 0 : if (suspendTime_ > 0.0f)
192 0 : return;
193 0 : suspendTime_ = 0.0f;
194 0 : }
195 :
196 : // Find the update function and call it
197 0 : lua_getglobal(L_, SCRIPT_CALLBACK_ON_UPDATE);
198 :
199 0 : if (lua_isfunction(L_, -1)) {
200 : // Push a pointer to the current object for use within the lua function
201 0 : returnObject(L_, this);
202 :
203 : // Push the time passed since the last iteration of the game loop
204 0 : lua_pushnumber(L_, elapsedTime);
205 :
206 0 : lua_call(L_, 2, 0);
207 0 : }
208 : else {
209 : PRINT_DEBUG_LVL(4, "'%s' function not defined.\n", SCRIPT_CALLBACK_ON_UPDATE);
210 0 : lua_pop(L_, 1);
211 : }
212 8 : }
213 :
214 : //------------------------------------------------------------------------------
215 0 : void Object::processCollisions(Object* temp) {
216 0 : if (this != temp && active_ && temp->active_ && state_ == NORMAL &&
217 0 : temp->state_ == NORMAL && isCollisionDetectionEnabled_ &&
218 0 : temp->isCollisionDetectionEnabled_ && temp != NULL) {
219 :
220 : // First perform a sphere-based collision
221 0 : float radius1 = boundingSphere_.getRadius();
222 0 : float radius2 = boundingSphere_.getRadius();
223 0 : float radius_sum = radius1 + radius2;
224 0 : radius_sum = radius_sum * radius_sum;
225 :
226 0 : float distance =
227 0 : (position_.x - temp->position_.x) * ( position_.x - temp->position_.x) +
228 0 : (position_.y - temp->position_.y) * ( position_.y - temp->position_.y) +
229 0 : (position_.z - temp->position_.z) * ( position_.z - temp->position_.z);
230 :
231 0 : if (!enableSphereTest_ || !temp->getEnableSphereTest() || radius_sum >= distance) {
232 0 : Vector boxA[2];
233 0 : Vector boxB[2];
234 :
235 0 : boxA[0].setVector(collisionBox_[0].x + position_.x, collisionBox_[0].y + position_.y, collisionBox_[0].z + position_.z);
236 0 : boxA[1].setVector(collisionBox_[1].x + position_.x, collisionBox_[1].y + position_.y, collisionBox_[1].z + position_.z);
237 0 : boxB[0].setVector(temp->collisionBox_[0].x + temp->position_.x, temp->collisionBox_[0].y + temp->position_.y, temp->collisionBox_[0].z + temp->position_.z);
238 0 : boxB[1].setVector(temp->collisionBox_[1].x + temp->position_.x, temp->collisionBox_[1].y + temp->position_.y, temp->collisionBox_[1].z + temp->position_.z);
239 :
240 0 : if(((boxA[0].x >= boxB[0].x && boxA[0].x <= boxB[1].x) ||
241 0 : (boxA[1].x >= boxB[0].x && boxA[1].x <= boxB[1].x) ||
242 0 : (boxB[0].x >= boxA[0].x && boxB[0].x <= boxA[1].x) ||
243 0 : (boxB[1].x >= boxA[0].x && boxB[1].x <= boxA[1].x)) &&
244 0 : ((boxA[0].y >= boxB[0].y && boxA[0].y <= boxB[1].y) ||
245 0 : (boxA[1].y >= boxB[0].y && boxA[1].y <= boxB[1].y) ||
246 0 : (boxB[0].y >= boxA[0].y && boxB[0].y <= boxA[1].y) ||
247 0 : (boxB[1].y >= boxA[0].y && boxB[1].y <= boxA[1].y)) &&
248 0 : ((boxA[0].z >= boxB[0].z && boxA[0].z <= boxB[1].z) ||
249 0 : (boxA[1].z >= boxB[0].z && boxA[1].z <= boxB[1].z) ||
250 0 : (boxB[0].z >= boxA[0].z && boxB[0].z <= boxA[1].z) ||
251 0 : (boxB[1].z >= boxA[0].z && boxB[1].z <= boxA[1].z)) ) {
252 :
253 : PRINT_DEBUG_LVL(3, "Collision! object 1=(%d), object 2=(%d).\n", this->typeId_, temp->typeId_);
254 0 : handleCollision(temp);
255 0 : temp->handleCollision(this);
256 0 : }
257 0 : }
258 0 : }
259 :
260 0 : if (temp->next != NULL)
261 0 : processCollisions(((Object*)temp->next));
262 0 : }
263 :
264 : //------------------------------------------------------------------------------
265 1 : float Object::calcTriangleCenter(const float &p1, const float &p2, const float &p3) {
266 1 : float th1 = (.5) * p1 + (.5 * p2);
267 1 : float finalHeight = (.5) * th1 + (.5 * p3);
268 :
269 1 : return (finalHeight);
270 : }
271 :
272 : //------------------------------------------------------------------------------
273 0 : void Object::showCollisionBox() {
274 0 : glDisable(GL_CULL_FACE);
275 0 : glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
276 :
277 0 : glPushMatrix();
278 0 : glTranslatef(position_.x, position_.y, position_.z);
279 :
280 0 : glColor3f(1.0f, 0.0f, 0.0f);
281 :
282 0 : float radius = boundingSphere_.getRadius();
283 :
284 0 : float rad = 6.28f / 16.0f;
285 :
286 0 : glBegin(GL_LINE_LOOP);
287 0 : for (int i = 0; i < 16; ++i) {
288 0 : glVertex3f((cos(rad * i) * radius), (sin(rad * i) * radius), 0.0f);
289 0 : }
290 0 : glEnd();
291 :
292 0 : glBegin(GL_QUADS);
293 :
294 0 : glVertex3f(collisionBox_[0].x, collisionBox_[1].y, collisionBox_[1].z);
295 0 : glVertex3f(collisionBox_[0].x, collisionBox_[0].y, collisionBox_[1].z);
296 0 : glVertex3f(collisionBox_[1].x, collisionBox_[0].y, collisionBox_[1].z);
297 0 : glVertex3f(collisionBox_[1].x, collisionBox_[1].y, collisionBox_[1].z);
298 :
299 0 : glVertex3f(collisionBox_[0].x, collisionBox_[1].y, collisionBox_[1].z);
300 0 : glVertex3f(collisionBox_[0].x, collisionBox_[1].y, collisionBox_[0].z);
301 0 : glVertex3f(collisionBox_[0].x, collisionBox_[0].y, collisionBox_[0].z);
302 0 : glVertex3f(collisionBox_[0].x, collisionBox_[0].y, collisionBox_[1].z);
303 :
304 0 : glVertex3f(collisionBox_[1].x, collisionBox_[1].y, collisionBox_[1].z);
305 0 : glVertex3f(collisionBox_[1].x, collisionBox_[0].y, collisionBox_[1].z);
306 0 : glVertex3f(collisionBox_[1].x, collisionBox_[0].y, collisionBox_[0].z);
307 0 : glVertex3f(collisionBox_[1].x, collisionBox_[1].y, collisionBox_[0].z);
308 :
309 0 : glVertex3f(collisionBox_[1].x, collisionBox_[1].y, collisionBox_[0].z);
310 0 : glVertex3f(collisionBox_[1].x, collisionBox_[0].y, collisionBox_[0].z);
311 0 : glVertex3f(collisionBox_[0].x, collisionBox_[0].y, collisionBox_[0].z);
312 0 : glVertex3f(collisionBox_[0].x, collisionBox_[1].y, collisionBox_[0].z);
313 :
314 0 : glVertex3f(collisionBox_[0].x, collisionBox_[1].y, collisionBox_[0].z);
315 0 : glVertex3f(collisionBox_[0].x, collisionBox_[1].y, collisionBox_[1].z);
316 0 : glVertex3f(collisionBox_[1].x, collisionBox_[1].y, collisionBox_[1].z);
317 0 : glVertex3f(collisionBox_[1].x, collisionBox_[1].y, collisionBox_[0].z);
318 :
319 0 : glVertex3f(collisionBox_[0].x, collisionBox_[0].y, collisionBox_[0].z);
320 0 : glVertex3f(collisionBox_[1].x, collisionBox_[0].y, collisionBox_[0].z);
321 0 : glVertex3f(collisionBox_[1].x, collisionBox_[0].y, collisionBox_[1].z);
322 0 : glVertex3f(collisionBox_[0].x, collisionBox_[0].y, collisionBox_[1].z);
323 :
324 0 : glEnd();
325 :
326 0 : glPopMatrix();
327 0 : glEnable(GL_CULL_FACE);
328 0 : glPolygonMode(GL_FRONT, GL_FILL);
329 :
330 0 : if (next)
331 0 : ((Object*)next)->showCollisionBox();
332 0 : }
333 :
334 : //------------------------------------------------------------------------------
335 0 : void Object::showControlTriangle() {
336 0 : glDisable(GL_CULL_FACE);
337 0 : glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
338 :
339 0 : glPushMatrix();
340 0 : glTranslatef(position_.x, position_.y, position_.z);
341 0 : glColor3f(1.0f, 0.0f, 0.0f);
342 0 : glBegin(GL_TRIANGLES);
343 :
344 0 : glVertex3f(controlPoints_[0].x, controlPoints_[0].y, controlPoints_[0].z);
345 0 : glVertex3f(controlPoints_[1].x, controlPoints_[1].y, controlPoints_[1].z);
346 0 : glVertex3f(controlPoints_[2].x, controlPoints_[2].y, controlPoints_[2].z);
347 0 : glEnd();
348 :
349 0 : glPopMatrix();
350 0 : glEnable(GL_CULL_FACE);
351 0 : glPolygonMode(GL_FRONT, GL_FILL);
352 :
353 0 : if (next)
354 0 : ((Object*)next)->showControlTriangle();
355 0 : }
356 :
357 : //------------------------------------------------------------------------------
358 2 : void Object::setPosition(const GLfloat &x, const GLfloat &y, const GLfloat &z)
359 2 : { position_.setVector(x, y, z); }
360 :
361 : //------------------------------------------------------------------------------
362 1 : void Object::setPosition(const Vector &t)
363 1 : { position_ = t; }
364 :
365 : //------------------------------------------------------------------------------
366 0 : void Object::setRotationAxis(const GLfloat &vx, const GLfloat &vy, const GLfloat &vz, const GLfloat &vw)
367 0 : { rotation_.buildFromAxis(Vector(vx, vy, vz), vw); }
368 :
369 : //------------------------------------------------------------------------------
370 0 : void Object::setRotationAxis(const Vector &v, const GLfloat &a)
371 0 : { rotation_.buildFromAxis(v, a); }
372 :
373 : //------------------------------------------------------------------------------
374 70 : void Object::setRotationEuler(const GLfloat &x, const GLfloat &y, const GLfloat &z)
375 70 : { rotation_.buildFromEuler(x, y, z); }
376 :
377 : //------------------------------------------------------------------------------
378 0 : void Object::setRotationEuler(const Vector &v)
379 0 : { rotation_.buildFromEuler(v); }
380 :
381 : //------------------------------------------------------------------------------
382 2 : void Object::setRotationQuaternion(const Quaternion &q)
383 2 : { rotation_ = q; }
384 :
385 : //------------------------------------------------------------------------------
386 3 : void Object::setRotationVelocity(
387 : const GLfloat &xAngle, const GLfloat &yAngle, const GLfloat &zAngle
388 3 : ) { rotationVelocity_.setVector(xAngle, yAngle, zAngle); }
389 :
390 : //------------------------------------------------------------------------------
391 0 : void Object::setRotationVelocity(const Vector &v)
392 0 : { rotationVelocity_ = v; }
393 :
394 : //------------------------------------------------------------------------------
395 2 : void Object::setVelocity(const GLfloat &x, const GLfloat &y, const GLfloat &z)
396 2 : { velocity_.setVector(x, y, z); }
397 :
398 : //------------------------------------------------------------------------------
399 1 : void Object::setVelocity(const Vector &v)
400 1 : { velocity_ = v; }
401 :
402 : //------------------------------------------------------------------------------
403 1 : void Object::setSpeed(const GLfloat &x, const GLfloat &y, const GLfloat &z)
404 1 : { speed_.setVector(x, y, z); }
405 :
406 : //------------------------------------------------------------------------------
407 0 : void Object::setSpeed(const Vector &v)
408 0 : { speed_ = v; }
409 :
410 : //------------------------------------------------------------------------------
411 0 : void Object::setParticleSystem(const int &particleSystemNumber) {
412 0 : if (particleSystem_) {
413 : // We won't allow updating a particle system for now
414 0 : return;
415 : }
416 :
417 : PRINT_DEBUG_LVL(1, "Attempting to load particle system %d\n", particleSystemNumber);
418 :
419 0 : switch (particleSystemNumber) {
420 : case 1:
421 0 : particleSystem_ = new StarField(this);
422 0 : break;
423 : case 2:
424 0 : particleSystem_ = new Snow(this);
425 0 : break;
426 : default:
427 : PRINT_DEBUG_LVL(1, "Specified particle system was not defined!\n");
428 0 : break;
429 : }
430 0 : }
431 :
432 : //------------------------------------------------------------------------------
433 1 : void Object::setScale(const GLfloat &x, const GLfloat &y, const GLfloat &z)
434 1 : { scale_.setVector(x, y, z); }
435 :
436 : //------------------------------------------------------------------------------
437 0 : void Object::setScale(const Vector &v)
438 0 : { scale_ = v; }
439 :
440 : //------------------------------------------------------------------------------
441 0 : void Object::setState(const unsigned char &tState)
442 0 : { state_ = tState; }
443 :
444 : //------------------------------------------------------------------------------
445 1 : void Object::setScaleRate(const GLfloat &x, const GLfloat &y, const GLfloat &z)
446 1 : { scaleRate_.setVector(x, y, z); }
447 :
448 : //------------------------------------------------------------------------------
449 0 : void Object::setScaleRate(const Vector &v)
450 0 : { scaleRate_ = v; }
451 :
452 : //------------------------------------------------------------------------------
453 0 : void Object::traverseAndCopyLuaTable(lua_State* srcState, lua_State* destState, const int &index) {
454 0 : lua_pushnil(srcState);
455 :
456 0 : while (lua_next(srcState, index) != 0) {
457 0 : switch(lua_type(srcState, -1)) {
458 : case LUA_TTABLE:
459 0 : copyLuaTableKey(srcState, destState);
460 0 : lua_newtable(destState);
461 0 : traverseAndCopyLuaTable(srcState, destState, -2);
462 0 : lua_rawset(destState, -3);
463 0 : break;
464 : case LUA_TNUMBER:
465 0 : copyLuaTableKey(srcState, destState);
466 0 : lua_pushnumber(destState, lua_tonumber(srcState, -1));
467 0 : lua_rawset(destState, -3);
468 0 : break;
469 : case LUA_TSTRING:
470 0 : copyLuaTableKey(srcState, destState);
471 0 : lua_pushstring(destState, lua_tostring(srcState, -1));
472 0 : lua_rawset(destState, -3);
473 0 : break;
474 : default:
475 : PRINT_DEBUG_LVL(
476 : 1,
477 : "Ignoring unsupported type (%s) found on Lua stack while traversing table.\n",
478 : lua_typename(srcState, lua_type(srcState, -1))
479 : );
480 0 : }
481 :
482 0 : lua_pop(srcState, 1);
483 : }
484 0 : }
485 :
486 0 : void Object::copyLuaTableKey(lua_State* srcState, lua_State* destState) {
487 0 : switch (lua_type(srcState, -2)) {
488 : case LUA_TNUMBER:
489 0 : lua_pushnumber(destState, lua_tonumber(srcState, -2));
490 0 : break;
491 : case LUA_TSTRING:
492 0 : lua_pushstring(destState, lua_tostring(srcState, -2));
493 0 : break;
494 : }
495 0 : }
496 :
497 0 : void Object::buildLuaObjectTable(lua_State *L) {
498 0 : lua_pushstring(L, "position");
499 0 : returnVector(L, getPosition());
500 0 : lua_rawset(L, -3);
501 :
502 0 : lua_pushstring(L, "velocity");
503 0 : returnVector(L, getVelocity());
504 0 : lua_rawset(L, -3);
505 :
506 0 : lua_pushstring(L, "rotation");
507 0 : returnQuaternion(L, getRotation());
508 0 : lua_rawset(L, -3);
509 :
510 0 : lua_pushstring(L, "rotation_velocity");
511 0 : returnVector(L, getRotationVelocity());
512 0 : lua_rawset(L, -3);
513 :
514 0 : lua_pushstring(L, "speed");
515 0 : returnVector(L, getSpeed());
516 0 : lua_rawset(L, -3);
517 :
518 0 : lua_pushstring(L, "scale");
519 0 : returnVector(L, getScale());
520 0 : lua_rawset(L, -3);
521 :
522 0 : lua_pushstring(L, "scale_rate");
523 0 : returnVector(L, getScaleRate());
524 0 : lua_rawset(L, -3);
525 :
526 0 : lua_pushstring(L, "up");
527 0 : returnVector(L, getUp());
528 0 : lua_rawset(L, -3);
529 :
530 0 : lua_pushstring(L, "direction");
531 0 : returnVector(L, getDirection());
532 0 : lua_rawset(L, -3);
533 :
534 0 : lua_pushstring(L, "orthogonal");
535 0 : returnVector(L, getOrth());
536 0 : lua_rawset(L, -3);
537 :
538 0 : lua_pushstring(L, "type_id");
539 0 : lua_pushnumber(L, getTypeId());
540 0 : lua_rawset(L, -3);
541 :
542 0 : lua_pushstring(L, "bounding_sphere_radius");
543 0 : lua_pushnumber(L, getBoundingSphere().getRadius());
544 0 : lua_rawset(L, -3);
545 :
546 0 : lua_pushstring(L, "in_view");
547 0 : lua_pushboolean(L, getInView());
548 0 : lua_rawset(L, -3);
549 :
550 0 : lua_pushstring(L, "collision_detection_enabled");
551 0 : lua_pushboolean(L, getCollisionDetectionEnabled());
552 0 : lua_rawset(L, -3);
553 :
554 0 : lua_pushstring(L, "active");
555 0 : lua_pushboolean(L, getActive());
556 0 : lua_rawset(L, -3);
557 :
558 0 : lua_pushstring(L, "draw_enabled");
559 0 : lua_pushboolean(L, getDrawEnabled());
560 0 : lua_rawset(L, -3);
561 :
562 0 : lua_pushstring(L, "always_lit");
563 0 : lua_pushboolean(L, getIsAlwaysLit());
564 0 : lua_rawset(L, -3);
565 :
566 0 : lua_pushstring(L, "interpolation_enabled");
567 0 : lua_pushboolean(L, isInterpolationEnabled());
568 0 : lua_rawset(L, -3);
569 0 : }
570 :
571 0 : void Object::transferLuaObjectTable(lua_State *L) {
572 0 : Vector tv;
573 0 : Quaternion tq;
574 0 : int index = -2;
575 :
576 0 : lua_pushstring(L, "scale");
577 0 : lua_gettable(L, 1);
578 0 : if (lua_istable(L, -1)) {
579 0 : tv = loadVector(L, index);
580 0 : setScale(tv);
581 0 : }
582 0 : lua_pop(L, 1);
583 :
584 0 : index = -2;
585 0 : lua_pushstring(L, "scale_rate");
586 0 : lua_gettable(L, 1);
587 0 : if (lua_istable(L, -1)) {
588 0 : tv = loadVector(L, index);
589 0 : setScaleRate(tv);
590 0 : }
591 0 : lua_pop(L, 1);
592 :
593 0 : index = -2;
594 0 : lua_pushstring(L, "velocity");
595 0 : lua_gettable(L, 1);
596 0 : if (lua_istable(L, -1)) {
597 0 : tv = loadVector(L, index);
598 0 : setVelocity(tv);
599 0 : }
600 0 : lua_pop(L, 1);
601 :
602 0 : index = -2;
603 0 : lua_pushstring(L, "rotation_velocity");
604 0 : lua_gettable(L, 1);
605 0 : if (lua_istable(L, -1)) {
606 0 : tv = loadVector(L, index);
607 0 : setRotationVelocity(tv);
608 0 : }
609 0 : lua_pop(L, 1);
610 :
611 0 : index = -2;
612 0 : lua_pushstring(L, "rotation");
613 0 : lua_gettable(L, 1);
614 0 : if (lua_istable(L, -1)) {
615 0 : tq = loadQuaternion(L, index);
616 0 : setRotation(tq);
617 0 : }
618 0 : lua_pop(L, 1);
619 :
620 0 : index = -2;
621 0 : lua_pushstring(L, "position");
622 0 : lua_gettable(L, 1);
623 0 : if (lua_istable(L, -1)) {
624 0 : tv = loadVector(L, index);
625 0 : setPosition(tv);
626 0 : }
627 0 : lua_pop(L, 1);
628 :
629 0 : index = -2;
630 0 : lua_pushstring(L, "speed");
631 0 : lua_gettable(L, 1);
632 0 : if (lua_istable(L, -1)) {
633 0 : tv = loadVector(L, index);
634 0 : setSpeed(tv);
635 0 : }
636 0 : lua_pop(L, 1);
637 :
638 0 : index = -1;
639 0 : lua_pushstring(L, "type_id");
640 0 : lua_gettable(L, 1);
641 0 : if (lua_isnumber(L, index)) {
642 0 : setTypeId((int)lua_tonumber(L, -1));
643 0 : }
644 0 : lua_pop(L, 1);
645 :
646 0 : index = -1;
647 0 : lua_pushstring(L, "collision_detection_enabled");
648 0 : lua_gettable(L, 1);
649 0 : if (lua_isboolean(L, index)) {
650 0 : setCollisionDetectionEnabled(lua_toboolean(L, -1));
651 0 : }
652 0 : lua_pop(L, 1);
653 :
654 0 : index = -1;
655 0 : lua_pushstring(L, "active");
656 0 : lua_gettable(L, 1);
657 0 : if (lua_isboolean(L, index)) {
658 0 : setActive(lua_toboolean(L, -1));
659 0 : }
660 0 : lua_pop(L, 1);
661 :
662 0 : index = -1;
663 0 : lua_pushstring(L, "draw_enabled");
664 0 : lua_gettable(L, 1);
665 0 : if (lua_isboolean(L, index)) {
666 0 : setDrawEnabled(lua_toboolean(L, -1));
667 0 : }
668 0 : lua_pop(L, 1);
669 :
670 0 : index = -1;
671 0 : lua_pushstring(L, "always_lit");
672 0 : lua_gettable(L, 1);
673 0 : if (lua_isboolean(L, index)) {
674 0 : setIsAlwaysLit(lua_toboolean(L, -1));
675 0 : }
676 0 : lua_pop(L, 1);
677 :
678 0 : index = -1;
679 0 : lua_pushstring(L, "interpolation_enabled");
680 0 : lua_gettable(L, 1);
681 0 : if (lua_isboolean(L, index)) {
682 0 : setIsInterpolationEnabled(lua_toboolean(L, -1));
683 0 : }
684 0 : lua_pop(L, 1);
685 0 : }
686 :
687 : //-----------------------------------------------------------------------------
688 3 : void Object::animate(const float &timeElapsed, Object* camera) {
689 : // exectue the current object's update function
690 3 : animateScript(timeElapsed);
691 :
692 : // calculate new position using speed
693 3 : if (speed_.x != 0.0f) {
694 0 : direction_.scale(speed_.x * timeElapsed);
695 0 : position_.x += direction_.x;
696 0 : position_.y += direction_.y;
697 0 : position_.z += direction_.z;
698 0 : direction_.normalize();
699 0 : }
700 :
701 3 : if (speed_.y != 0.0f) {
702 0 : up_.scale(speed_.y * timeElapsed);
703 0 : position_.x += up_.x;
704 0 : position_.y += up_.y;
705 0 : position_.z += up_.z;
706 0 : direction_.normalize();
707 0 : }
708 :
709 3 : if (speed_.z != 0.0f) {
710 0 : Vector rotationAxis;
711 :
712 0 : rotationAxis.crossProduct(up_, direction_);
713 0 : rotationAxis.normalize();
714 :
715 0 : rotationAxis.scale(speed_.z * timeElapsed);
716 0 : position_.x += rotationAxis.x;
717 0 : position_.y += rotationAxis.y;
718 0 : position_.z += rotationAxis.z;
719 0 : }
720 :
721 : // update position using velocity
722 3 : if (velocity_.x != 0.0f)
723 1 : position_.x += velocity_.x * timeElapsed;
724 :
725 3 : if (velocity_.y != 0.0f)
726 0 : position_.y += velocity_.y * timeElapsed;
727 :
728 3 : if (velocity_.z != 0.0f)
729 1 : position_.z += velocity_.z * timeElapsed;
730 :
731 : // update scale
732 3 : if (scaleRate_.x != 0.0f) {
733 0 : scale_.x += scaleRate_.x * timeElapsed;
734 0 : scaleChanged_ = true;
735 0 : }
736 :
737 3 : if (scaleRate_.y != 0.0f) {
738 0 : scale_.y += scaleRate_.y * timeElapsed;
739 0 : scaleChanged_ = true;
740 0 : }
741 :
742 3 : if (scaleRate_.z != 0.0f) {
743 0 : scale_.z += scaleRate_.z * timeElapsed;
744 0 : scaleChanged_ = true;
745 0 : }
746 :
747 3 : if (!isInterpolationEnabled_) {
748 4 : if (rotationVelocity_.x != 0.0f ||
749 3 : rotationVelocity_.y != 0.0f ||
750 1 : rotationVelocity_.z != 0.0f) {
751 2 : rotationChanged_ = true;
752 :
753 2 : Vector tempV;
754 2 : Quaternion tempQ;
755 :
756 2 : tempV.x = rotationVelocity_.x * timeElapsed;
757 2 : tempV.y = rotationVelocity_.y * timeElapsed;
758 2 : tempV.z = rotationVelocity_.z * timeElapsed;
759 :
760 2 : tempQ.buildFromEuler(tempV);
761 2 : rotation_ = rotation_ * tempQ;
762 2 : }
763 3 : }
764 : else {
765 0 : rotationChanged_ = true;
766 :
767 0 : float endVal = valInterpEnd_ - valInterpBegin_;
768 0 : float curVal = valInterpCurrent_ - valInterpBegin_;
769 :
770 0 : float t = 0.0f;
771 :
772 0 : if (endVal > 0) {
773 0 : if (curVal > endVal)
774 0 : t = 1.0f;
775 0 : else if (curVal < 0.0f)
776 0 : t = 0.0f;
777 : else
778 0 : t = curVal / endVal;
779 0 : }
780 0 : else if (endVal < 0) {
781 0 : if (curVal < endVal)
782 0 : t = 1.0f;
783 0 : else if (curVal > 0.0f)
784 0 : t = 0.0f;
785 : else
786 0 : t = curVal / endVal;
787 0 : }
788 :
789 0 : rotation_.slerp(rInterpStart_, t, rInterpEnd_);
790 : }
791 3 : }
|