Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 9120 was 9119, checked in by rennerc, 18 years ago

added scling for playables

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