Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/presentation/src/world_entities/world_entity.cc @ 9069

Last change on this file since 9069 was 9068, checked in by rennerc, 18 years ago

removed some bugs and added texture sync

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  // get a collision event
445  CollisionEvent* c = CREngine::getInstance()->popCollisionEventObject();
446  assert(c != NULL); // if this should fail: we got not enough precached CollisionEvents: alter value in cr_defs.h
447  c->collide(type, entity, groundEntity, normal, position, bInWall);
448
449  for( int i = 0; i < CREngine::CR_NUMBER; ++i)
450    if( this->collisionHandles[i] != NULL)
451      this->collisionHandles[i]->registerCollisionEvent(c);
452  return true;
453}
454
455
456/**
457 * @brief moves this entity to the List OM_List
458 * @param list the list to set this Entity to.
459 *
460 * this is the same as a call to State::getObjectManager()->toList(entity , list);
461 * directly, but with an easier interface.
462 *
463 * @todo inline this (peut etre)
464 */
465void WorldEntity::toList(OM_LIST list)
466{
467  State::getObjectManager()->toList(this, list);
468}
469
470void WorldEntity::toReflectionList()
471{
472  State::getObjectManager()->toReflectionList( this );
473}
474
475void removeFromReflectionList()
476{
477/// TODO
478///  State::getObject
479}
480
481/**
482 * sets the character attributes of a worldentity
483 * @param character attributes
484 *
485 * these attributes don't have to be set, only use them, if you need them
486*/
487//void WorldEntity::setCharacterAttributes(CharacterAttributes* charAttr)
488//{}
489
490
491/**
492 *  this function is called, when two entities collide
493 * @param entity: the world entity with whom it collides
494 *
495 * Implement behaviour like damage application or other miscellaneous collision stuff in this function
496 */
497void WorldEntity::collidesWith(WorldEntity* entity, const Vector& location)
498{
499  /**
500   * THIS IS A DEFAULT COLLISION-Effect.
501   * IF YOU WANT TO CREATE A SPECIFIC COLLISION ON EACH OBJECT
502   * USE::
503   * if (entity->isA(CL_WHAT_YOU_ARE_LOOKING_FOR)) { printf "dothings"; };
504   *
505   * You can always define a default Action.... don't be affraid just test it :)
506   */
507  //  PRINTF(3)("collision %s vs %s @ (%f,%f,%f)\n", this->getClassName(), entity->getClassName(), location.x, location.y, location.z);
508}
509
510
511/**
512 *  this function is called, when two entities collide
513 * @param entity: the world entity with whom it collides
514 *
515 * Implement behaviour like damage application or other miscellaneous collision stuff in this function
516 */
517void WorldEntity::collidesWithGround(const Vector& location)
518{
519  PRINTF(0)("BSP_GROUND: %s collides \n", this->getClassName() );
520}
521
522void WorldEntity::collidesWithGround(const Vector& feet, const Vector& ray_1, const Vector& ray_2)
523{
524
525  // PRINTF(0)("BSP_GROUND: Player collides \n", this->getClassName() );
526
527  Vector v = this->getAbsDirX();
528  v.x *= 10.1;
529  v.y *= 10.1;
530  v.z *= 10.1;
531  Vector u = Vector(0.0,-20.0,0.0);
532
533
534  if(!(this->getAbsCoor().x == ray_2.x && this->getAbsCoor().y == ray_2.y && this->getAbsCoor().z == ray_2.z) )
535  {
536
537  this->setAbsCoor(ray_2 - v);
538
539  }
540    else
541  {
542    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)
543    {
544      this->setAbsCoor(feet -u );
545    }
546
547    this->setAbsCoor(ray_2 - v);
548
549  }
550
551
552}
553
554/**
555 *  this is called immediately after the Entity has been constructed, initialized and then Spawned into the World
556 *
557 */
558void WorldEntity::postSpawn ()
559{}
560
561
562/**
563 *  this method is called by the world if the WorldEntity leaves the game
564 */
565void WorldEntity::leaveWorld ()
566{}
567
568
569/**
570 * resets the WorldEntity to its initial values. eg. used for multiplayer games: respawning
571 */
572void WorldEntity::reset()
573{}
574
575/**
576 *  this method is called every frame
577 * @param time: the time in seconds that has passed since the last tick
578 *
579 * Handle all stuff that should update with time inside this method (movement, animation, etc.)
580*/
581void WorldEntity::tick(float time)
582{}
583
584
585/**
586 *  the entity is drawn onto the screen with this function
587 *
588 * This is a central function of an entity: call it to let the entity painted to the screen.
589 * Just override this function with whatever you want to be drawn.
590*/
591void WorldEntity::draw() const
592{
593  //PRINTF(0)("(%s::%s)\n", this->getClassName(), this->getName());
594  //  assert(!unlikely(this->models.empty()));
595  {
596    glMatrixMode(GL_MODELVIEW);
597    glPushMatrix();
598
599    /* translate */
600    glTranslatef (this->getAbsCoor ().x,
601                  this->getAbsCoor ().y,
602                  this->getAbsCoor ().z);
603    Vector tmpRot = this->getAbsDir().getSpacialAxis();
604    glRotatef (this->getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
605
606
607    // This Draws the LOD's
608    float cameraDistance = State::getCamera()->distance(this);
609    if (cameraDistance > 30 && this->models.size() >= 3 && this->models[2] != NULL)
610    {
611      this->models[2]->draw();
612    }
613    else if (cameraDistance > 10 && this->models.size() >= 2 && this->models[1] != NULL)
614    {
615      this->models[1]->draw();
616    }
617    else if (this->models.size() >= 1 && this->models[0] != NULL)
618    {
619      this->models[0]->draw();
620    }
621
622//     if( this->aabbNode != NULL)
623//       this->aabbNode->drawBV(0, DRAW_BV_POLYGON, Vector(1, 0.6, 0.2), true);
624
625    glPopMatrix();
626  }
627}
628
629/**
630 * @param health the Health to add.
631 * @returns the health left (this->healthMax - health+this->health)
632 */
633float WorldEntity::increaseHealth(float health)
634{
635  this->health += health;
636  if (this->health > this->healthMax)
637  {
638    float retHealth = this->healthMax - this->health;
639    this->health = this->healthMax;
640    this->updateHealthWidget();
641    return retHealth;
642  }
643  this->updateHealthWidget();
644  return 0.0;
645}
646
647/**
648 * @param health the Health to be removed
649 * @returns 0.0 or the rest, that was not substracted (bellow 0.0)
650 */
651float WorldEntity::decreaseHealth(float health)
652{
653  this->health -= health;
654
655  if (this->health < 0)
656  {
657    float retHealth = -this->health;
658    this->health = 0.0f;
659    this->updateHealthWidget();
660    return retHealth;
661  }
662  this->updateHealthWidget();
663  return 0.0;
664
665}
666
667/**
668 * @param maxHealth the maximal health that can be loaded onto the entity.
669 */
670void WorldEntity::setHealthMax(float healthMax)
671{
672  this->healthMax = healthMax;
673  if (this->health > this->healthMax)
674  {
675    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());
676    this->health = this->healthMax;
677  }
678  this->updateHealthWidget();
679}
680
681/**
682 * @brief creates the HealthWidget
683 *
684 * since not all entities need an HealthWidget, it is only created on request.
685 */
686void WorldEntity::createHealthWidget()
687{
688  if (this->healthWidget == NULL)
689  {
690    this->healthWidget = new OrxGui::GLGuiEnergyWidget();
691    this->healthWidget->setDisplayedName(std::string(this->getClassName()) + " Energy:");
692    this->healthWidget->setSize2D(30,400);
693    this->healthWidget->setAbsCoor2D(10,100);
694
695    this->updateHealthWidget();
696  }
697  else
698    PRINTF(3)("Allready created the HealthWidget for %s::%s\n", this->getClassName(), this->getName());
699}
700
701void WorldEntity::increaseHealthMax(float increaseHealth)
702{
703  this->healthMax += increaseHealth;
704  this->updateHealthWidget();
705}
706
707
708OrxGui::GLGuiWidget* WorldEntity::getHealthWidget()
709{
710  this->createHealthWidget();
711  return this->healthWidget;
712}
713
714/**
715 * @param visibility shows or hides the health-bar
716 * (creates the widget if needed)
717 */
718void WorldEntity::setHealthWidgetVisibilit(bool visibility)
719{
720  if (visibility)
721  {
722    if (this->healthWidget != NULL)
723      this->healthWidget->show();
724    else
725    {
726      this->createHealthWidget();
727      this->updateHealthWidget();
728      this->healthWidget->show();
729    }
730  }
731  else if (this->healthWidget != NULL)
732    this->healthWidget->hide();
733}
734
735
736/**
737 * hit the world entity with
738 *  @param damage damage to be dealt
739 */
740void WorldEntity::hit(float damage, WorldEntity* killer)
741{
742  this->decreaseHealth(damage);
743
744  PRINTF(0)("Hit me: %s now only %f/%f health\n", this->getClassName(), this->getHealth(), this->getHealthMax());
745
746  if( this->getHealth() > 0)
747  {
748    // any small explosion animaitions
749  }
750  else
751  {
752    this->destroy();
753
754    if( State::getGameRules() != NULL)
755      State::getGameRules()->registerKill(Kill(killer, this));
756  }
757}
758
759
760/**
761 * destoys the world entity
762 */
763void WorldEntity::destroy()
764{
765  this->toList(OM_DEAD);
766}
767
768
769/**
770 * @brief updates the HealthWidget
771 */
772void WorldEntity::updateHealthWidget()
773{
774  if (this->healthWidget != NULL)
775  {
776    this->healthWidget->setMaximum(this->healthMax);
777    this->healthWidget->setValue(this->health);
778  }
779}
780
781
782/**
783 * DEBUG-DRAW OF THE BV-Tree.
784 * @param depth What depth to draw
785 * @param drawMode the mode to draw this entity under
786 */
787void WorldEntity::drawBVTree(int depth, int drawMode) const
788{
789  glMatrixMode(GL_MODELVIEW);
790  glPushMatrix();
791  /* translate */
792  glTranslatef (this->getAbsCoor ().x,
793                this->getAbsCoor ().y,
794                this->getAbsCoor ().z);
795  /* rotate */
796  Vector tmpRot = this->getAbsDir().getSpacialAxis();
797  glRotatef (this->getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
798
799
800  if (this->obbTree)
801    this->obbTree->drawBV(depth, drawMode);
802
803
804  glPopMatrix();
805}
806
807
808/**
809 * Debug the WorldEntity
810 */
811void WorldEntity::debugEntity() const
812{
813  PRINT(0)("WorldEntity %s::%s  (DEBUG)\n", this->getClassName(), this->getName());
814  this->debugNode();
815  PRINT(0)("List: %s ; ModelCount %d - ", ObjectManager::OMListToString(this->objectListNumber) , this->models.size());
816  for (unsigned int i = 0; i < this->models.size(); i++)
817  {
818    if (models[i] != NULL)
819      PRINT(0)(" : %d:%s", i, this->models[i]->getName());
820  }
821  PRINT(0)("\n");
822
823}
824
825
826/**
827 * handler for changes on registred vars
828 * @param id id's which changed
829 */
830void WorldEntity::varChangeHandler( std::list< int > & id )
831{
832  if ( std::find( id.begin(), id.end(), modelFileName_handle ) != id.end() ||
833       std::find( id.begin(), id.end(), scaling_handle ) != id.end()
834     )
835  {
836    loadModel( modelFileName, scaling );
837  }
838
839  if ( std::find( id.begin(), id.end(), list_handle ) != id.end() )
840  {
841    this->toList( (OM_LIST)list_write );
842  }
843 
844  if ( std::find( id.begin(), id.end(), health_handle ) != id.end() )
845  {
846    this->setHealth( health_write );
847  }
848 
849  if ( std::find( id.begin(), id.end(), healthMax_handle ) != id.end() )
850  {
851    this->setHealthMax( healthMax_write );
852  }
853
854  PNode::varChangeHandler( id );
855}
856
Note: See TracBrowser for help on using the repository browser.