Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/terrain.old/src/world_entities/world_entity.cc @ 9442

Last change on this file since 9442 was 9140, checked in by bensch, 18 years ago

merged back

File size: 22.5 KB
Line 
1
2
3/*
4   orxonox - the future of 3D-vertical-scrollers
5
6   Copyright (C) 2004 orx
7
8   This program is free software; you can redistribute it and/or modify
9   it under the terms of the GNU General Public License as published by
10   the Free Software Foundation; either version 2, or (at your option)
11   any later version.
12
13   ### File Specific:
14   main-programmer: Patrick Boenzli
15   co-programmer: Christian Meyer
16*/
17#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
18
19#include "world_entity.h"
20#include "shell_command.h"
21
22#include "model.h"
23#include "md2/md2Model.h"
24#include "md3/md3_model.h"
25
26#include "aabb_tree_node.h"
27
28#include "util/loading/resource_manager.h"
29#include "util/loading/load_param.h"
30#include "vector.h"
31#include "obb_tree.h"
32
33#include "elements/glgui_energywidget.h"
34
35#include "state.h"
36#include "camera.h"
37
38#include "collision_handle.h"
39#include "collision_event.h"
40#include "game_rules.h"
41#include "kill.h"
42
43
44SHELL_COMMAND(model, WorldEntity, loadModel)
45->describe("sets the Model of the WorldEntity")
46->defaultValues("models/ships/fighter.obj", 1.0f);
47
48SHELL_COMMAND(debugEntity, WorldEntity, debugWE);
49
50/**
51 *  Loads the WordEntity-specific Part of any derived Class
52 *
53 * @param root: Normally NULL, as the Derived Entities define a loadParams Function themeselves,
54 *              that can calls WorldEntities loadParams for itself.
55 */
56WorldEntity::WorldEntity()
57    : Synchronizeable()
58{
59  this->setClassID(CL_WORLD_ENTITY, "WorldEntity");
60
61  this->obbTree = NULL;
62  this->aabbNode = NULL;
63  this->healthWidget = NULL;
64  this->healthMax = 1.0f;
65  this->health = 1.0f;
66  this->damage = 0.0f; // no damage dealt by a default entity
67  this->scaling = 1.0f;
68
69  /* OSOLETE */
70  this->bVisible = true;
71  this->bCollide = true;
72
73  this->objectListNumber = OM_INIT;
74  this->lastObjectListNumber = OM_INIT;
75  this->objectListIterator = NULL;
76
77  // reset all collision handles to NULL == unsubscribed state
78  for(int i = 0; i < CREngine::CR_NUMBER; ++i)
79    this->collisionHandles[i] = NULL;
80  this->bReactive = false;
81  this->bOnGround = false;
82
83  // registering default reactions:
84  this->subscribeReaction(CREngine::CR_OBJECT_DAMAGE, /*CL_WORLD_ENTITY*/ CL_PROJECTILE);
85
86  this->toList(OM_NULL);
87 
88  registerVar( new SynchronizeableString( &this->md2TextureFileName, &this->md2TextureFileName, "md2TextureFileName" ) );
89  modelFileName_handle = registerVarId( new SynchronizeableString( &modelFileName, &modelFileName, "modelFileName" ) );
90  scaling_handle = registerVarId( new SynchronizeableFloat( &scaling, &scaling, "scaling" ) );
91  list_handle = registerVarId( new SynchronizeableInt( (int*)&objectListNumber, &list_write, "list" ) );
92 
93  health_handle = registerVarId( new SynchronizeableFloat( &this->health, &this->health_write, "health" ) );
94  healthMax_handle = registerVarId( new SynchronizeableFloat( &this->healthMax, &this->healthMax_write, "maxHealth" ) );
95}
96
97/**
98 *  standard destructor
99*/
100WorldEntity::~WorldEntity ()
101{
102  State::getObjectManager()->toList(this, OM_INIT);
103
104  // Delete the model (unregister it with the ResourceManager)
105  for (unsigned int i = 0; i < this->models.size(); i++)
106    this->setModel(NULL, i);
107
108  // Delete the obbTree
109  if( this->obbTree != NULL)
110    delete this->obbTree;
111
112  if (this->healthWidget != NULL)
113    delete this->healthWidget;
114
115  this->unsubscribeReaction();
116}
117
118/**
119 * loads the WorldEntity Specific Parameters.
120 * @param root: the XML-Element to load the Data From
121 */
122void WorldEntity::loadParams(const TiXmlElement* root)
123{
124  // Do the PNode loading stuff
125  PNode::loadParams(root);
126
127  LoadParam(root, "md2texture", this, WorldEntity, loadMD2Texture)
128  .describe("the fileName of the texture, that should be loaded onto this world-entity. (must be relative to the data-dir)")
129  .defaultValues("");
130
131  // Model Loading
132  LoadParam(root, "model", this, WorldEntity, loadModel)
133  .describe("the fileName of the model, that should be loaded onto this world-entity. (must be relative to the data-dir)")
134  .defaultValues("", 1.0f, 0);
135
136  LoadParam(root, "maxHealth", this, WorldEntity, setHealthMax)
137  .describe("The Maximum health that can be loaded onto this entity")
138  .defaultValues(1.0f);
139
140  LoadParam(root, "health", this, WorldEntity, setHealth)
141  .describe("The Health the WorldEntity has at this moment")
142  .defaultValues(1.0f);
143}
144
145
146/**
147 * loads a Model onto a WorldEntity
148 * @param fileName the name of the model to load
149 * @param scaling the Scaling of the model
150 *
151 * FIXME
152 * @todo: separate the obb tree generation from the model
153 */
154void WorldEntity::loadModel(const std::string& fileName, float scaling, unsigned int modelNumber, unsigned int obbTreeDepth)
155{
156  this->modelLODName = fileName;
157  this->scaling = scaling;
158
159  std::string name = fileName;
160
161  if (  name.find( ResourceManager::getInstance()->getDataDir() ) == 0 )
162  {
163    name.erase(ResourceManager::getInstance()->getDataDir().size());
164  }
165
166  this->modelFileName = name;
167
168  if (!fileName.empty())
169  {
170    // search for the special character # in the LoadParam
171    if (fileName.find('#') != std::string::npos)
172    {
173      PRINTF(4)("Found # in %s... searching for LOD's\n", fileName.c_str());
174      std::string lodFile = fileName;
175      unsigned int offset = lodFile.find('#');
176      for (unsigned int i = 0; i < 3; i++)
177      {
178        lodFile[offset] = 48+(int)i;
179        if (ResourceManager::isInDataDir(lodFile))
180          this->loadModel(lodFile, scaling, i);
181      }
182      return;
183    }
184    if (this->scaling <= 0.0)
185    {
186      PRINTF(1)("YOU GAVE ME A CRAPY SCALE resetting to 1.0\n");
187      this->scaling = 1.0;
188    }
189    if(fileName.find(".obj") != std::string::npos)
190    {
191      PRINTF(4)("fetching OBJ file: %s\n", fileName.c_str());
192      BaseObject* loadedModel = ResourceManager::getInstance()->load(fileName, OBJ, RP_CAMPAIGN, this->scaling);
193      if (loadedModel != NULL)
194        this->setModel(dynamic_cast<Model*>(loadedModel), modelNumber);
195      else
196        PRINTF(1)("OBJ-File %s not found.\n", fileName.c_str());
197
198      if( modelNumber == 0 && !this->isA(CL_WEAPON))
199        this->buildObbTree(obbTreeDepth);
200    }
201    else if(fileName.find(".md2") != std::string::npos)
202    {
203      PRINTF(4)("fetching MD2 file: %s\n", fileName.c_str());
204      Model* m = new MD2Model(fileName, this->md2TextureFileName, this->scaling);
205      //this->setModel((Model*)ResourceManager::getInstance()->load(fileName, MD2, RP_CAMPAIGN), 0);
206      this->setModel(m, 0);
207
208      if( m != NULL)
209        this->buildObbTree(obbTreeDepth);
210    }
211    else /*if(fileName.find(".md3") != std::string::npos)*/
212    {
213      PRINTF(4)("fetching MD3 file: %s\n", fileName.c_str());
214      Model* m = new md3::MD3Model(fileName, this->scaling);
215      this->setModel(m, 0);
216
217//       if( m != NULL)
218//         this->buildObbTree(obbTreeDepth);
219    }
220  }
221  else
222  {
223    this->setModel(NULL);
224  }
225}
226
227/**
228 * sets a specific Model for the Object.
229 * @param model The Model to set
230 * @param modelNumber the n'th model in the List to get.
231 */
232void WorldEntity::setModel(Model* model, unsigned int modelNumber)
233{
234  if (this->models.size() <= modelNumber)
235    this->models.resize(modelNumber+1, NULL);
236
237  if (this->models[modelNumber] != NULL)
238  {
239    Resource* resource = ResourceManager::getInstance()->locateResourceByPointer(dynamic_cast<BaseObject*>(this->models[modelNumber]));
240    if (resource != NULL)
241      ResourceManager::getInstance()->unload(resource, RP_LEVEL);
242    else
243    {
244      PRINTF(4)("Forcing model deletion\n");
245      delete this->models[modelNumber];
246    }
247  }
248
249  this->models[modelNumber] = model;
250}
251
252
253/**
254 * builds the obb-tree
255 * @param depth the depth to calculate
256 */
257bool WorldEntity::buildObbTree(int depth)
258{
259  if (this->obbTree)
260    delete this->obbTree;
261
262  if (this->models[0] != NULL)
263    this->obbTree = new OBBTree(depth, models[0]->getModelInfo(), this);
264  else
265  {
266    PRINTF(1)("could not create obb-tree, because no model was loaded yet\n");
267    this->obbTree = NULL;
268    return false;
269  }
270
271
272  // create the axis aligned bounding box
273  if( this->aabbNode != NULL)
274  {
275    delete this->aabbNode;
276    this->aabbNode = NULL;
277  }
278
279  if( this->models[0] != NULL) {
280    this->aabbNode = new AABBTreeNode();
281    this->aabbNode->spawnBVTree(this->models[0]);
282  }
283  return true;
284}
285
286
287/**
288 * subscribes this world entity to a collision reaction
289 *  @param type the type of reaction to subscribe to
290 *  @param target1 a filter target (classID)
291 */
292void WorldEntity::subscribeReaction(CREngine::CRType type, long target1)
293{
294  this->subscribeReaction(type);
295
296  // add the target filter
297  this->collisionHandles[type]->addTarget(target1);
298}
299
300
301/**
302 * subscribes this world entity to a collision reaction
303 *  @param type the type of reaction to subscribe to
304 *  @param target1 a filter target (classID)
305 */
306void WorldEntity::subscribeReaction(CREngine::CRType type, long target1, long target2)
307{
308  this->subscribeReaction(type);
309
310  // add the target filter
311  this->collisionHandles[type]->addTarget(target1);
312  this->collisionHandles[type]->addTarget(target2);
313}
314
315
316/**
317 * subscribes this world entity to a collision reaction
318 *  @param type the type of reaction to subscribe to
319 *  @param target1 a filter target (classID)
320 */
321void WorldEntity::subscribeReaction(CREngine::CRType type, long target1, long target2, long target3)
322{
323  this->subscribeReaction(type);
324
325  // add the target filter
326  this->collisionHandles[type]->addTarget(target1);
327  this->collisionHandles[type]->addTarget(target2);
328  this->collisionHandles[type]->addTarget(target3);
329}
330
331
332/**
333 * subscribes this world entity to a collision reaction
334 *  @param type the type of reaction to subscribe to
335 *  @param target1 a filter target (classID)
336 */
337void WorldEntity::subscribeReaction(CREngine::CRType type, long target1, long target2, long target3, long target4)
338{
339  this->subscribeReaction(type);
340
341  // add the target filter
342  this->collisionHandles[type]->addTarget(target1);
343  this->collisionHandles[type]->addTarget(target2);
344  this->collisionHandles[type]->addTarget(target3);
345  this->collisionHandles[type]->addTarget(target4);
346}
347
348
349/**
350 * subscribes this world entity to a collision reaction
351 *  @param type the type of reaction to subscribe to
352 *  @param nrOfTargets number of target filters
353 *  @param ... the targets as classIDs
354 */
355void WorldEntity::subscribeReaction(CREngine::CRType type)
356{
357  if( this->collisionHandles[type] != NULL)  {
358    PRINTF(2)("Registering for a CollisionReaction already subscribed to! Skipping\n");
359    return;
360  }
361
362  this->collisionHandles[type] = CREngine::getInstance()->subscribeReaction(this, type);
363
364  // now there is at least one collision reaction subscribed
365  this->bReactive = true;
366}
367
368
369/**
370 * unsubscribes a specific reaction from the worldentity
371 *  @param type the reaction to unsubscribe
372 */
373void WorldEntity::unsubscribeReaction(CREngine::CRType type)
374{
375  if( this->collisionHandles[type] == NULL)
376    return;
377
378  CREngine::getInstance()->unsubscribeReaction(this->collisionHandles[type]);
379  this->collisionHandles[type] = NULL;
380
381  // check if there is still any handler registered
382  for(int i = 0; i < CREngine::CR_NUMBER; ++i)
383  {
384    if( this->collisionHandles[i] != NULL)
385    {
386      this->bReactive = true;
387      return;
388    }
389  }
390  this->bReactive = false;
391}
392
393
394/**
395 * unsubscribes all collision reactions
396 */
397void WorldEntity::unsubscribeReaction()
398{
399  for( int i = 0; i < CREngine::CR_NUMBER; i++)
400    this->unsubscribeReaction((CREngine::CRType)i);
401
402  // there are no reactions subscribed from now on
403  this->bReactive = false;
404}
405
406
407/**
408 * registers a new collision event to this world entity
409 *  @param entityA entity of the collision
410 *  @param entityB entity of the collision
411 *  @param bvA colliding bounding volume of entityA
412 *  @param bvB colliding bounding volume of entityA
413 */
414bool WorldEntity::registerCollision(WorldEntity* entityA, WorldEntity* entityB, BoundingVolume* bvA, BoundingVolume* bvB)
415{
416  // is there any handler listening?
417  if( !this->bReactive)
418    return false;
419
420  // get a collision event
421  CollisionEvent* c = CREngine::getInstance()->popCollisionEventObject();
422  assert(c != NULL); // if this should fail: we got not enough precached CollisionEvents: alter value in cr_defs.h
423  c->collide(COLLISION_TYPE_OBB, entityA, entityB, bvA, bvB);
424
425  for( int i = 0; i < CREngine::CR_NUMBER; ++i)
426    if( this->collisionHandles[i] != NULL)
427      this->collisionHandles[i]->registerCollisionEvent(c);
428  return true;
429}
430
431
432/**
433 * registers a new collision event to this woeld entity
434 *  @param entity the entity that collides
435 *  @param plane it stands on
436 *  @param position it collides on the plane
437 */
438bool WorldEntity::registerCollision(int type, WorldEntity* entity, WorldEntity* groundEntity, Vector normal, Vector position, bool bInWall)
439{
440  // is there any handler listening?
441  if( !this->bReactive)
442    return false;
443
444
445  // get a collision event
446  CollisionEvent* c = CREngine::getInstance()->popCollisionEventObject();
447  assert(c != NULL); // if this should fail: we got not enough precached CollisionEvents: alter value in cr_defs.h
448  c->collide(type, entity, groundEntity, normal, position, bInWall);
449
450  for( int i = 0; i < CREngine::CR_NUMBER; ++i)
451    if( this->collisionHandles[i] != NULL)
452      this->collisionHandles[i]->registerCollisionEvent(c);
453  return true;
454}
455
456
457/**
458 * @brief moves this entity to the List OM_List
459 * @param list the list to set this Entity to.
460 *
461 * this is the same as a call to State::getObjectManager()->toList(entity , list);
462 * directly, but with an easier interface.
463 *
464 * @todo inline this (peut etre)
465 */
466void WorldEntity::toList(OM_LIST list)
467{
468  State::getObjectManager()->toList(this, list);
469}
470
471void WorldEntity::toReflectionList()
472{
473  State::getObjectManager()->toReflectionList( this );
474}
475
476void removeFromReflectionList()
477{
478/// TODO
479///  State::getObject
480}
481
482/**
483 * sets the character attributes of a worldentity
484 * @param character attributes
485 *
486 * these attributes don't have to be set, only use them, if you need them
487*/
488//void WorldEntity::setCharacterAttributes(CharacterAttributes* charAttr)
489//{}
490
491
492/**
493 *  this function is called, when two entities collide
494 * @param entity: the world entity with whom it collides
495 *
496 * Implement behaviour like damage application or other miscellaneous collision stuff in this function
497 */
498void WorldEntity::collidesWith(WorldEntity* entity, const Vector& location)
499{
500  /**
501   * THIS IS A DEFAULT COLLISION-Effect.
502   * IF YOU WANT TO CREATE A SPECIFIC COLLISION ON EACH OBJECT
503   * USE::
504   * if (entity->isA(CL_WHAT_YOU_ARE_LOOKING_FOR)) { printf "dothings"; };
505   *
506   * You can always define a default Action.... don't be affraid just test it :)
507   */
508  //  PRINTF(3)("collision %s vs %s @ (%f,%f,%f)\n", this->getClassName(), entity->getClassName(), location.x, location.y, location.z);
509}
510
511
512/**
513 *  this function is called, when two entities collide
514 * @param entity: the world entity with whom it collides
515 *
516 * Implement behaviour like damage application or other miscellaneous collision stuff in this function
517 */
518void WorldEntity::collidesWithGround(const Vector& location)
519{
520  PRINTF(0)("BSP_GROUND: %s collides \n", this->getClassName() );
521}
522
523void WorldEntity::collidesWithGround(const Vector& feet, const Vector& ray_1, const Vector& ray_2)
524{
525
526  // PRINTF(0)("BSP_GROUND: Player collides \n", this->getClassName() );
527
528  Vector v = this->getAbsDirX();
529  v.x *= 10.1;
530  v.y *= 10.1;
531  v.z *= 10.1;
532  Vector u = Vector(0.0,-20.0,0.0);
533
534
535  if(!(this->getAbsCoor().x == ray_2.x && this->getAbsCoor().y == ray_2.y && this->getAbsCoor().z == ray_2.z) )
536  {
537
538  this->setAbsCoor(ray_2 - v);
539
540  }
541    else
542  {
543    if(ray_1.x == this->getAbsCoor().x + v.x && ray_1.y == this->getAbsCoor().y + v.y + 0.1 && ray_1.z ==this->getAbsCoor().z + v.z)
544    {
545      this->setAbsCoor(feet -u );
546    }
547
548    this->setAbsCoor(ray_2 - v);
549
550  }
551
552
553}
554
555/**
556 *  this is called immediately after the Entity has been constructed, initialized and then Spawned into the World
557 *
558 */
559void WorldEntity::postSpawn ()
560{}
561
562
563/**
564 *  this method is called by the world if the WorldEntity leaves the game
565 */
566void WorldEntity::leaveWorld ()
567{}
568
569
570/**
571 * resets the WorldEntity to its initial values. eg. used for multiplayer games: respawning
572 */
573void WorldEntity::reset()
574{}
575
576/**
577 *  this method is called every frame
578 * @param time: the time in seconds that has passed since the last tick
579 *
580 * Handle all stuff that should update with time inside this method (movement, animation, etc.)
581*/
582void WorldEntity::tick(float time)
583{}
584
585
586/**
587 *  the entity is drawn onto the screen with this function
588 *
589 * This is a central function of an entity: call it to let the entity painted to the screen.
590 * Just override this function with whatever you want to be drawn.
591*/
592void WorldEntity::draw() const
593{
594  //PRINTF(0)("(%s::%s)\n", this->getClassName(), this->getName());
595  //  assert(!unlikely(this->models.empty()));
596  {
597    glMatrixMode(GL_MODELVIEW);
598    glPushMatrix();
599
600    /* translate */
601    glTranslatef (this->getAbsCoor ().x,
602                  this->getAbsCoor ().y,
603                  this->getAbsCoor ().z);
604    Vector tmpRot = this->getAbsDir().getSpacialAxis();
605    glRotatef (this->getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
606
607
608    // This Draws the LOD's
609    float cameraDistance = State::getCamera()->distance(this);
610    if (cameraDistance > 30 && this->models.size() >= 3 && this->models[2] != NULL)
611    {
612      this->models[2]->draw();
613    }
614    else if (cameraDistance > 10 && this->models.size() >= 2 && this->models[1] != NULL)
615    {
616      this->models[1]->draw();
617    }
618    else if (this->models.size() >= 1 && this->models[0] != NULL)
619    {
620      this->models[0]->draw();
621    }
622
623//     if( this->aabbNode != NULL)
624//       this->aabbNode->drawBV(0, DRAW_BV_POLYGON, Vector(1, 0.6, 0.2), true);
625
626    glPopMatrix();
627  }
628}
629
630/**
631 * @param health the Health to add.
632 * @returns the health left (this->healthMax - health+this->health)
633 */
634float WorldEntity::increaseHealth(float health)
635{
636  this->health += health;
637  if (this->health > this->healthMax)
638  {
639    float retHealth = this->healthMax - this->health;
640    this->health = this->healthMax;
641    this->updateHealthWidget();
642    return retHealth;
643  }
644  this->updateHealthWidget();
645  return 0.0;
646}
647
648/**
649 * @param health the Health to be removed
650 * @returns 0.0 or the rest, that was not substracted (bellow 0.0)
651 */
652float WorldEntity::decreaseHealth(float health)
653{
654  this->health -= health;
655
656  if (this->health < 0)
657  {
658    float retHealth = -this->health;
659    this->health = 0.0f;
660    this->updateHealthWidget();
661    return retHealth;
662  }
663  this->updateHealthWidget();
664  return 0.0;
665
666}
667
668/**
669 * @param maxHealth the maximal health that can be loaded onto the entity.
670 */
671void WorldEntity::setHealthMax(float healthMax)
672{
673  this->healthMax = healthMax;
674  if (this->health > this->healthMax)
675  {
676    PRINTF(3)("new maxHealth is bigger as the old health. Did you really intend to do this for (%s::%s)\n", this->getClassName(), this->getName());
677    this->health = this->healthMax;
678  }
679  this->updateHealthWidget();
680}
681
682/**
683 * @brief creates the HealthWidget
684 *
685 * since not all entities need an HealthWidget, it is only created on request.
686 */
687void WorldEntity::createHealthWidget()
688{
689  if (this->healthWidget == NULL)
690  {
691    this->healthWidget = new OrxGui::GLGuiEnergyWidget();
692    this->healthWidget->setDisplayedName(std::string(this->getClassName()) + " Energy:");
693    this->healthWidget->setSize2D(30,400);
694    this->healthWidget->setAbsCoor2D(10,100);
695
696    this->updateHealthWidget();
697  }
698  else
699    PRINTF(3)("Allready created the HealthWidget for %s::%s\n", this->getClassName(), this->getName());
700}
701
702void WorldEntity::increaseHealthMax(float increaseHealth)
703{
704  this->healthMax += increaseHealth;
705  this->updateHealthWidget();
706}
707
708
709OrxGui::GLGuiWidget* WorldEntity::getHealthWidget()
710{
711  this->createHealthWidget();
712  return this->healthWidget;
713}
714
715/**
716 * @param visibility shows or hides the health-bar
717 * (creates the widget if needed)
718 */
719void WorldEntity::setHealthWidgetVisibilit(bool visibility)
720{
721  if (visibility)
722  {
723    if (this->healthWidget != NULL)
724      this->healthWidget->show();
725    else
726    {
727      this->createHealthWidget();
728      this->updateHealthWidget();
729      this->healthWidget->show();
730    }
731  }
732  else if (this->healthWidget != NULL)
733    this->healthWidget->hide();
734}
735
736
737/**
738 * hit the world entity with
739 *  @param damage damage to be dealt
740 */
741void WorldEntity::hit(float damage, WorldEntity* killer)
742{
743  this->decreaseHealth(damage);
744
745  PRINTF(0)("Hit me: %s now only %f/%f health\n", this->getClassName(), this->getHealth(), this->getHealthMax());
746
747  if( this->getHealth() > 0)
748  {
749    // any small explosion animaitions
750  }
751  else
752  {
753    this->destroy();
754
755    if( State::getGameRules() != NULL)
756      State::getGameRules()->registerKill(Kill(killer, this));
757  }
758}
759
760
761/**
762 * destoys the world entity
763 */
764void WorldEntity::destroy()
765{
766  this->toList(OM_DEAD);
767}
768
769
770/**
771 * @brief updates the HealthWidget
772 */
773void WorldEntity::updateHealthWidget()
774{
775  if (this->healthWidget != NULL)
776  {
777    this->healthWidget->setMaximum(this->healthMax);
778    this->healthWidget->setValue(this->health);
779  }
780}
781
782
783/**
784 * DEBUG-DRAW OF THE BV-Tree.
785 * @param depth What depth to draw
786 * @param drawMode the mode to draw this entity under
787 */
788void WorldEntity::drawBVTree(int depth, int drawMode) const
789{
790  glMatrixMode(GL_MODELVIEW);
791  glPushMatrix();
792  /* translate */
793  glTranslatef (this->getAbsCoor ().x,
794                this->getAbsCoor ().y,
795                this->getAbsCoor ().z);
796  /* rotate */
797  Vector tmpRot = this->getAbsDir().getSpacialAxis();
798  glRotatef (this->getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
799
800
801  if (this->obbTree)
802    this->obbTree->drawBV(depth, drawMode);
803
804
805  glPopMatrix();
806}
807
808
809/**
810 * Debug the WorldEntity
811 */
812void WorldEntity::debugEntity() const
813{
814  PRINT(0)("WorldEntity %s::%s  (DEBUG)\n", this->getClassName(), this->getName());
815  this->debugNode();
816  PRINT(0)("List: %s ; ModelCount %d - ", ObjectManager::OMListToString(this->objectListNumber) , this->models.size());
817  for (unsigned int i = 0; i < this->models.size(); i++)
818  {
819    if (models[i] != NULL)
820      PRINT(0)(" : %d:%s", i, this->models[i]->getName());
821  }
822  PRINT(0)("\n");
823
824}
825
826
827/**
828 * handler for changes on registred vars
829 * @param id id's which changed
830 */
831void WorldEntity::varChangeHandler( std::list< int > & id )
832{
833  if ( std::find( id.begin(), id.end(), modelFileName_handle ) != id.end() ||
834       std::find( id.begin(), id.end(), scaling_handle ) != id.end()
835     )
836  {
837    loadModel( modelFileName, scaling );
838  }
839
840  if ( std::find( id.begin(), id.end(), list_handle ) != id.end() )
841  {
842    this->toList( (OM_LIST)list_write );
843  }
844 
845  if ( std::find( id.begin(), id.end(), health_handle ) != id.end() )
846  {
847    this->setHealth( health_write );
848  }
849 
850  if ( std::find( id.begin(), id.end(), healthMax_handle ) != id.end() )
851  {
852    this->setHealthMax( healthMax_write );
853  }
854
855  PNode::varChangeHandler( id );
856}
857
Note: See TracBrowser for help on using the repository browser.