Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/mount_points/src/world_entities/world_entity.cc @ 10228

Last change on this file since 10228 was 10228, checked in by patrick, 17 years ago

some more work on the mounting points. should soon be finished

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