Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/ODE/src/world_entities/world_entity.cc

Last change on this file was 10355, checked in by bottac, 19 years ago

Here comes the updated version.

File size: 37.4 KB
RevLine 
[10355]1       
[2036]2
[4570]3/*
[2036]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:
[10147]14   main-programmer: Patrick Boenzli, Benjamin Grauer
15   co-programmer: Christian Meier
[2036]16*/
[5300]17#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
[2036]18
19#include "world_entity.h"
[5208]20#include "shell_command.h"
[5143]21
[9869]22#include "util/loading/resource_manager.h"
23#include "resource_obj.h"
[8490]24#include "md2/md2Model.h"
25#include "md3/md3_model.h"
26
[10147]27#include "oif/object_information_file.h"
28#include "mount_point.h"
29
[8724]30#include "aabb_tree_node.h"
31
[7193]32#include "util/loading/load_param.h"
[4682]33#include "obb_tree.h"
[3608]34
[8974]35#include "elements/glgui_energywidget.h"
[6430]36
[6002]37#include "state.h"
[7014]38#include "camera.h"
[6002]39
[10013]40#include "collision_filter.h"
[8190]41#include "collision_event.h"
[8777]42#include "game_rules.h"
43#include "kill.h"
[9869]44#include "debug.h"
[7927]45
[9869]46#include "projectiles/projectile.h"
[7927]47
[10355]48
49#include "class_id.h"
50#include "aabb.h"
51#include "cr_defs.h"
52#include "cd_engine.h"
53#include "collision_tube.h"
54
55#include "static_model.h"
56
57
58
59#ifdef WITH_ODE
60#include  <ode/ode.h>
61#endif
62
[5208]63SHELL_COMMAND(model, WorldEntity, loadModel)
[6430]64->describe("sets the Model of the WorldEntity")
[7711]65->defaultValues("models/ships/fighter.obj", 1.0f);
[5208]66
[6424]67SHELL_COMMAND(debugEntity, WorldEntity, debugWE);
[5208]68
[9869]69
70ObjectListDefinition(WorldEntity);
[2043]71/**
[4836]72 *  Loads the WordEntity-specific Part of any derived Class
[5498]73 *
74 * @param root: Normally NULL, as the Derived Entities define a loadParams Function themeselves,
75 *              that can calls WorldEntities loadParams for itself.
76 */
[6430]77WorldEntity::WorldEntity()
[10013]78  : Synchronizeable(), _collisionFilter(this)
[2190]79{
[9869]80  this->registerObject(this, WorldEntity::_objectList);
[4597]81
[4682]82  this->obbTree = NULL;
[8724]83  this->aabbNode = NULL;
[6700]84  this->healthWidget = NULL;
85  this->healthMax = 1.0f;
86  this->health = 1.0f;
[8190]87  this->damage = 0.0f; // no damage dealt by a default entity
[6695]88  this->scaling = 1.0f;
[10147]89  this->oiFile = NULL;
[4261]90
[6695]91  /* OSOLETE */
92  this->bVisible = true;
93  this->bCollide = true;
94
[6142]95  this->objectListNumber = OM_INIT;
[9003]96  this->lastObjectListNumber = OM_INIT;
[6142]97
[10013]98  this->_bOnGround = false;
[8190]99
100  // registering default reactions:
[10013]101  this->subscribeReaction(CoRe::CREngine::CR_OBJECT_DAMAGE, Projectile::staticClassID());
[8190]102
[6142]103  this->toList(OM_NULL);
[9235]104
[10013]105  this->registerVar( new SynchronizeableString( &this->md2TextureFileName, &this->md2TextureFileName, "md2TextureFileName", PERMISSION_MASTER_SERVER ) );
106  this->modelFileName_handle = registerVarId( new SynchronizeableString( &modelFileName, &modelFileName, "modelFileName", PERMISSION_MASTER_SERVER ) );
107  this->scaling_handle = registerVarId( new SynchronizeableFloat( &scaling, &scaling, "scaling", PERMISSION_MASTER_SERVER ) );
108  this->list_handle = registerVarId( new SynchronizeableInt( (int*)&objectListNumber, &list_write, "list", PERMISSION_MASTER_SERVER ) );
[9235]109
[10013]110  this->health_handle = registerVarId( new SynchronizeableFloat( &this->health, &this->health_write, "health", PERMISSION_MASTER_SERVER ) );
111  this->healthMax_handle = registerVarId( new SynchronizeableFloat( &this->healthMax, &this->healthMax_write, "maxHealth", PERMISSION_MASTER_SERVER ) );
[2190]112}
[2043]113
114/**
[4836]115 *  standard destructor
[2043]116*/
[2190]117WorldEntity::~WorldEntity ()
[2036]118{
[7125]119  State::getObjectManager()->toList(this, OM_INIT);
120
121  // Delete the model (unregister it with the ResourceManager)
122  for (unsigned int i = 0; i < this->models.size(); i++)
123    this->setModel(NULL, i);
124
[10147]125  // remove the object information file
126  if( this->oiFile)
127    delete this->oiFile;
128  // and clear all monut points
129  this->mountPoints.clear();
130
[5498]131  // Delete the obbTree
[5302]132  if( this->obbTree != NULL)
[4814]133    delete this->obbTree;
[5994]134
[6700]135  if (this->healthWidget != NULL)
136    delete this->healthWidget;
[8190]137
[10013]138  this->unsubscribeReactions();
[3531]139}
140
[5498]141/**
142 * loads the WorldEntity Specific Parameters.
143 * @param root: the XML-Element to load the Data From
144 */
[4436]145void WorldEntity::loadParams(const TiXmlElement* root)
146{
[5498]147  // Do the PNode loading stuff
[6512]148  PNode::loadParams(root);
[5498]149
[6222]150  LoadParam(root, "md2texture", this, WorldEntity, loadMD2Texture)
[6430]151  .describe("the fileName of the texture, that should be loaded onto this world-entity. (must be relative to the data-dir)")
[7198]152  .defaultValues("");
[6222]153
[4436]154  // Model Loading
[5671]155  LoadParam(root, "model", this, WorldEntity, loadModel)
[6430]156  .describe("the fileName of the model, that should be loaded onto this world-entity. (must be relative to the data-dir)")
[7198]157  .defaultValues("", 1.0f, 0);
[6430]158
[6700]159  LoadParam(root, "maxHealth", this, WorldEntity, setHealthMax)
160  .describe("The Maximum health that can be loaded onto this entity")
[7198]161  .defaultValues(1.0f);
[6430]162
[6700]163  LoadParam(root, "health", this, WorldEntity, setHealth)
164  .describe("The Health the WorldEntity has at this moment")
[7198]165  .defaultValues(1.0f);
[9656]166
167  LoadParam(root, "list", this, WorldEntity, toListS);
[4436]168}
169
[6222]170
[3531]171/**
[4885]172 * loads a Model onto a WorldEntity
[4836]173 * @param fileName the name of the model to load
[5057]174 * @param scaling the Scaling of the model
[7711]175 *
176 * FIXME
177 * @todo: separate the obb tree generation from the model
[7221]178 */
[7711]179void WorldEntity::loadModel(const std::string& fileName, float scaling, unsigned int modelNumber, unsigned int obbTreeDepth)
[4261]180{
[6695]181  this->modelLODName = fileName;
[6424]182  this->scaling = scaling;
[7954]183
184  std::string name = fileName;
185
[9869]186  if (  name.find( Resources::ResourceManager::getInstance()->mainGlobalPath().name() ) == 0 )
[7954]187  {
[9869]188    name.erase(Resources::ResourceManager::getInstance()->mainGlobalPath().name().size());
[7954]189  }
190
191  this->modelFileName = name;
192
[7221]193  if (!fileName.empty())
[6142]194  {
[6430]195    // search for the special character # in the LoadParam
[7221]196    if (fileName.find('#') != std::string::npos)
[6222]197    {
[7221]198      PRINTF(4)("Found # in %s... searching for LOD's\n", fileName.c_str());
199      std::string lodFile = fileName;
200      unsigned int offset = lodFile.find('#');
[6720]201      for (unsigned int i = 0; i < 3; i++)
[6005]202      {
[7221]203        lodFile[offset] = 48+(int)i;
[9869]204        if (Resources::ResourceManager::getInstance()->checkFileInMainPath( lodFile))
[6222]205          this->loadModel(lodFile, scaling, i);
[6005]206      }
[6222]207      return;
208    }
[6720]209    if (this->scaling <= 0.0)
[6424]210    {
[7193]211      PRINTF(1)("YOU GAVE ME A CRAPY SCALE resetting to 1.0\n");
[6720]212      this->scaling = 1.0;
[6424]213    }
[9869]214    /// LOADING AN OBJ FILE
[7221]215    if(fileName.find(".obj") != std::string::npos)
[6222]216    {
[7221]217      PRINTF(4)("fetching OBJ file: %s\n", fileName.c_str());
[10147]218      // creating the model and loading it
[9869]219      StaticModel* model = new StaticModel();
220      *model = ResourceOBJ(fileName, this->scaling);
221      if (model->getVertexCount() > 0)
222      {
223        this->setModel(model, modelNumber);
224        if( modelNumber == 0 /* FIXME && !this->isA(CL_WEAPON) */)
225          this->buildObbTree(obbTreeDepth);
226      }
[7221]227      else
[9869]228        delete model;
[10147]229
230      // now get the object information file for this model, if any
231      std::string oifName = fileName.substr(0, fileName.length() - 4) + ".oif";
232      this->loadObjectInformationFile( oifName);
[6222]233    }
[9869]234    /// LOADING AN MD2-model
[7221]235    else if(fileName.find(".md2") != std::string::npos)
[6222]236    {
[7221]237      PRINTF(4)("fetching MD2 file: %s\n", fileName.c_str());
[7055]238      Model* m = new MD2Model(fileName, this->md2TextureFileName, this->scaling);
[6430]239      //this->setModel((Model*)ResourceManager::getInstance()->load(fileName, MD2, RP_CAMPAIGN), 0);
[6222]240      this->setModel(m, 0);
[7068]241
242      if( m != NULL)
[7711]243        this->buildObbTree(obbTreeDepth);
[6222]244    }
[9869]245    /// LOADING AN MD3-MODEL.
[9235]246    else if(fileName.find(".md3") != std::string::npos)
[8490]247    {
248      PRINTF(4)("fetching MD3 file: %s\n", fileName.c_str());
[9869]249//      Model* m = new md3::MD3Model(fileName, this->scaling);
250//      this->setModel(m, 0);
[8490]251
[9869]252      //       if( m != NULL)
253      //         this->buildObbTree(obbTreeDepth);
[8490]254    }
[4732]255  }
256  else
[6341]257  {
[5995]258    this->setModel(NULL);
[6341]259  }
[4261]260}
261
[5061]262/**
[5994]263 * sets a specific Model for the Object.
264 * @param model The Model to set
265 * @param modelNumber the n'th model in the List to get.
266 */
267void WorldEntity::setModel(Model* model, unsigned int modelNumber)
268{
[5995]269  if (this->models.size() <= modelNumber)
270    this->models.resize(modelNumber+1, NULL);
271
272  if (this->models[modelNumber] != NULL)
[6004]273  {
[9869]274    delete this->models[modelNumber];
[5994]275  }
[6222]276
[5995]277  this->models[modelNumber] = model;
[5994]278}
279
280
[10147]281
[5994]282/**
[10147]283 * loads the object information file for this model
284 * @param fileName the name of the file
285 */
286void WorldEntity::loadObjectInformationFile(const std::string& fileName)
287{
288  PRINTF(4)("loading the oif File: %s\n", fileName.c_str());
289
290  this->oiFile = new ObjectInformationFile(fileName);
291}
292
293
294/**
[5061]295 * builds the obb-tree
296 * @param depth the depth to calculate
297 */
[7711]298bool WorldEntity::buildObbTree(int depth)
[5061]299{
[10355]300
301#ifdef WITH_ODE
302        this->world =  dWorldCreate(); // the World will be Static for mor efficiency
303        this->space = dSimpleSpaceCreate(0); // same for the space
304        contactgroup = dJointGroupCreate (0);
305        dWorldSetGravity (world,0,0,-0.5);
306        dWorldSetCFM (world,1e-5);
307
308 
309if(this->getModel(0)!=0)
310        {
311 if(this->getModel(0)->isA( StaticModel::staticClassID() ) ) 
312        {
313
314
315
316        StaticModelData::Pointer   ModelData = ((StaticModel*)this->getModel())->dataPointer();
317        //ModelData->buildTriangleList();
318
319        PRINTF(0)(" Dieses Model hat %i Vertices \n", ModelData->getVertices().size());
320        PRINTF(0)(" Dieses Model hat %i Dreiecke \n",((ModelData->getTriangles()).size()  ));
321        this->Ind = new unsigned int [(ModelData->getTriangles()).size()*3];
322        for(int i = 0 ; i < (ModelData->getTriangles()).size(); i++)
323                {
324                        Ind[3*i]    = (ModelData->getTrianglesExt())[i].indexToVertices[0] / 3 ;
325                        Ind[3*i +1] = (ModelData->getTrianglesExt())[i].indexToVertices[1] / 3;
326                        Ind[3*i +2] = (ModelData->getTrianglesExt())[i].indexToVertices[2] / 3;
327               
328                }
329       
330        //((StaticModel*)(this->getModel()))->acquireData(ModelData);
331        this->ODE_Geometry = dGeomTriMeshDataCreate();
332        dGeomTriMeshDataBuildSingle(this->ODE_Geometry,&((ModelData->getVertices())[0]), 3*sizeof(float),(ModelData->getVertices().size() /3 )  , &Ind[0] ,((ModelData->getTriangles()).size() *3 ),  3*sizeof(unsigned int) );
333    // Create ODE-Data here!
334       
335
336        //!fixme
337        for (int i=0; i<30; i++) {
338                contact[i].surface.mode = dContactBounce | dContactSoftCFM;
339                contact[i].surface.mu = dInfinity;
340                contact[i].surface.mu2 = 0;
341                contact[i].surface.bounce = 0.1;
342                contact[i].surface.bounce_vel = 0.1;
343                contact[i].surface.soft_cfm = 0.01;
344        }
345
346       
347        this->ODE_Geom_ID = dCreateTriMesh(space,this->ODE_Geometry,0 , 0, 0);
348
349               
350        //CDEngine::getInstance()->setTerrain(this);
351        //this->loaded = true;
352        //this->toList(OM_ENVIRON);
353
354} else
355{
356if(this->getModelAABB() == NULL )
357{
358        this->ODE_Geom_ID  = dCreateBox (space, 20.0f, 40.0f  ,20.0f);
359        //dGeomID BBOX = dCreateBox (space,box->halfLength[0]*2.0f, box->halfLength[1]*2.0f  ,2.0f* box->halfLength[2]);
360        dGeomSetPosition (this->ODE_Geom_ID, this->getAbsCoor().,this->getAbsCoor().y, this->getAbsCoor().z);
361        //dGeomSetPosition (BBOX, worldEntity->getAbsCoor().x + box->center.x ,worldEntity->getAbsCoor().y+box->center.y, worldEntity->getAbsCoor().z+box->center.z);
362}
363}
364
365
366if(this->getModelAABB() != NULL )
367{
368        AABB* box = this->getModelAABB();
369        //this->ODE_Geom_ID  = dCreateBox (space, 2.0f, 4.0f  ,2.0f);
370        this->ODE_Geom_ID = dCreateBox (space,box->halfLength[0]*2.0f, box->halfLength[1]*2.0f  ,2.0f* box->halfLength[2]);
371        dGeomSetPosition (this->ODE_Geom_ID, this->getAbsCoor().,this->getAbsCoor().y, this->getAbsCoor().z);
372        //dGeomSetPosition (BBOX, worldEntity->getAbsCoor().x + box->center.x ,worldEntity->getAbsCoor().y+box->center.y, worldEntity->getAbsCoor().z+box->center.z);
373}
374        }
375
376else
377{
378if(this->getModelAABB() != NULL )
379{
380        AABB* box = this->getModelAABB();
381        //this->ODE_Geom_ID  = dCreateBox (space, 2.0f, 4.0f  ,2.0f);
382        this->ODE_Geom_ID = dCreateBox (space,box->halfLength[0]*2.0f, box->halfLength[1]*2.0f  ,2.0f* box->halfLength[2]);
383        dGeomSetPosition (this->ODE_Geom_ID, this->getAbsCoor().,this->getAbsCoor().y, this->getAbsCoor().z);
384        //dGeomSetPosition (BBOX, worldEntity->getAbsCoor().x + box->center.x ,worldEntity->getAbsCoor().y+box->center.y, worldEntity->getAbsCoor().z+box->center.z);
385}
386
387if(this->getModelAABB() == NULL )
388{
389        this->ODE_Geom_ID  = dCreateBox (space, 20.0f, 40.0f  ,20.0f);
390        //dGeomID BBOX = dCreateBox (space,box->halfLength[0]*2.0f, box->halfLength[1]*2.0f  ,2.0f* box->halfLength[2]);
391        dGeomSetPosition (this->ODE_Geom_ID, this->getAbsCoor().,this->getAbsCoor().y, this->getAbsCoor().z);
392        //dGeomSetPosition (BBOX, worldEntity->getAbsCoor().x + box->center.x ,worldEntity->getAbsCoor().y+box->center.y, worldEntity->getAbsCoor().z+box->center.z);
393}
394}
395
396
397
398#endif
399
400
[9494]401  if( this->obbTree != NULL)
402  {
[5428]403    delete this->obbTree;
[9494]404    this->obbTree = NULL;
405  }
[5428]406
[5995]407  if (this->models[0] != NULL)
[7711]408    this->obbTree = new OBBTree(depth, models[0]->getModelInfo(), this);
[5428]409  else
410  {
[7711]411    PRINTF(1)("could not create obb-tree, because no model was loaded yet\n");
[5428]412    this->obbTree = NULL;
413    return false;
414  }
[8724]415
416
417  // create the axis aligned bounding box
418  if( this->aabbNode != NULL)
419  {
420    delete this->aabbNode;
421    this->aabbNode = NULL;
422  }
423
[9869]424  if( this->models[0] != NULL)
425  {
[8724]426    this->aabbNode = new AABBTreeNode();
427    this->aabbNode->spawnBVTree(this->models[0]);
428  }
[9494]429  else
430  {
431    PRINTF(1)("could not create aabb bounding box, because no model was loaded yet\n");
432    this->aabbNode = NULL;
433    return false;
434  }
[10355]435 
[8724]436  return true;
[5061]437}
[5057]438
[7927]439
[10355]440
441void WorldEntity::checkCollision(WorldEntity* worldEntity) {
442
443#ifndef WITH_ODE
444        return;
445#endif
446#ifdef WITH_ODE
447        //if(!this->loaded) return;
448        //dWorldSetQuickStepNumIterations (this->world, 1);
449        //dWorldQuickStep (this->world, 0.1);
450
451         AABB* box = worldEntity->getModelAABB();
452   dReal  aabbox [6];
453
454if(   (this->getModel(0)!= 0) && (this->getModel(0)->isA( StaticModel::staticClassID())) )  {
455       
456        dGeomSetPosition (this->ODE_Geom_ID, this->getAbsCoor().,this->getAbsCoor().y, this->getAbsCoor().z);
457        if(box != NULL )
458        {
459        //PRINTF(0)("Do have abb-box! :_)\n");
460        dGeomID RayX =    dCreateRay(space,box->halfLength[0] *2.0f);
461        dGeomRaySet (RayX, worldEntity->getAbsCoor().- box->halfLength[0]  ,worldEntity->getAbsCoor().y, worldEntity->getAbsCoor().z,
462                  1.0f, 0.0f, 0.0f); 
463        dGeomID RayY =    dCreateRay(space,box->halfLength[1] * 10000.0f);
464        dGeomRaySet (RayY, worldEntity->getAbsCoor().x    ,worldEntity->getAbsCoor().y - 5000.0f*box->halfLength[1], worldEntity->getAbsCoor().z,
465                  0.0f, 1.0f, 0.0f); 
466        dGeomID RayZ =    dCreateRay(space,box->halfLength[2] *2.0f);
467        dGeomRaySet (RayZ, worldEntity->getAbsCoor().x    ,worldEntity->getAbsCoor().y, worldEntity->getAbsCoor().z - box->halfLength[2],
468                  0.0f, 0.0f, 1.0f); 
469
470        dGeomID RayXPos =    dCreateRay(space,box->halfLength[0]);
471        dGeomRaySet (RayX, worldEntity->getAbsCoor().x    ,worldEntity->getAbsCoor().y, worldEntity->getAbsCoor().z,
472                  1.0f, 0.0f, 0.0f); 
473        dGeomID RayYPos =    dCreateRay(space,box->halfLength[1] * 1100.0 );
474        dGeomRaySet (RayY, worldEntity->getAbsCoor().x    ,worldEntity->getAbsCoor().y, worldEntity->getAbsCoor().z,
475                  0.0f, 1.0f, 0.0f); 
476        dGeomID RayZPos =    dCreateRay(space,box->halfLength[2] );
477        dGeomRaySet (RayZ, worldEntity->getAbsCoor().x    ,worldEntity->getAbsCoor().y, worldEntity->getAbsCoor().z,
478                  0.0f, 0.0f, 1.0f); 
479
480        dGeomID RayXNeg =    dCreateRay(space,box->halfLength[0]  );
481        dGeomRaySet (RayX, worldEntity->getAbsCoor().x    ,worldEntity->getAbsCoor().y, worldEntity->getAbsCoor().z,
482                  -1.0f, 0.0f, 0.0f); 
483        dGeomID RayYNeg =    dCreateRay(space, box->halfLength[1] *  1100.0f );
484        dGeomRaySet (RayY, worldEntity->getAbsCoor().x    ,worldEntity->getAbsCoor().y , worldEntity->getAbsCoor().z,
485                  0.0f, -1.0f, 0.0f);
486        dGeomID RayZNeg =    dCreateRay(space,box->halfLength[2] );
487        dGeomRaySet (RayZ, worldEntity->getAbsCoor().x    ,worldEntity->getAbsCoor().y, worldEntity->getAbsCoor().z ,
488                  0.0f, 0.0f, -1.0f); 
489
490        //dGeomID BBOX = dCreateBox (space, 2.0f, 4.0f  ,2.0f);
491        dGeomID BBOX = dCreateBox (space,box->halfLength[0]*0.003f, box->halfLength[1]*500.0f  ,0.0030f* box->halfLength[2]);
492        dGeomSetPosition (BBOX, worldEntity->getAbsCoor().,worldEntity->getAbsCoor().y, worldEntity->getAbsCoor().z);
493        //dGeomSetPosition (BBOX, worldEntity->getAbsCoor().x + box->center.x ,worldEntity->getAbsCoor().y+box->center.y, worldEntity->getAbsCoor().z+box->center.z);
494
495       
496       
497 
498
499   int g;
500   bool collision = false;
501
502 
503                        // dGeomGetAABB (this->bspFile->ODE_Geom_IDs[i],aabbox );
504                        // BBOX2 = dCreateBox (space, aabbox[1]-aabbox[0], aabbox[3]-aabbox[2], aabbox[5]-aabbox[4]);
505                        //  dGeomSetPosition (BBOX2,(aabbox[1]+ aabbox[0])/2, (aabbox[3]+ aabbox[2])/2, (aabbox[4]+ aabbox[5])/2);
506                        // dGeomDestroy(BBOX2);
507                         g = 0;
508                         if( dCollide(this->ODE_Geom_ID,BBOX, 2, &contact[0].geom, sizeof(dContact)) ) {
509                       
510                                PRINTF(0)("%s :Collision wit %s at %f , %f , %f : height: %f. \n", this->getCName(),worldEntity->getCName(), contact[0].geom.pos[0],contact[0].geom.pos[1]+2.1,contact[0].geom.pos[2], (worldEntity->getAbsCoorY() - contact[0].geom.pos[1]) );
511                                for(int i = 0; i <1 ; i++)
512                                        { 
513                                CoRe::CollisionTube::getInstance()->registerCollisionEvent( CoRe::CREngine::CR_COLLISION_TYPE_AXIS_Y_NEG , worldEntity, this, Vector(0.0f, 1.0f, 0.0f), Vector(contact[0].geom.pos[0],contact[0].geom.pos[1],contact[0].geom.pos[2]),  false);
514                                        }
515                                       
516                                if(dCollide(this->ODE_Geom_ID,RayX, 1, &contact[0].geom, sizeof(dContact)))  {
517                                                if(dCollide(this->ODE_Geom_ID,RayXPos, 1, &contact[0].geom, sizeof(dContact)))  {
518                                                        // worldEntity->registerCollision(COLLISION_TYPE_AXIS_X , this, worldEntity, Vector(1.0f, 0.0f, 0.0f),
519                                                        // Vector((float)contact[0].geom.pos[0],(float)contact[0].geom.pos[1],contact[0].geom.pos[2]), false); 
520                                                       
521                                                }//if           
522                                                if(dCollide(this->ODE_Geom_ID,RayXNeg, 1, &contact[0].geom, sizeof(dContact)))  {
523                                                        //  worldEntity->registerCollision(COLLISION_TYPE_AXIS_X_NEG , this, worldEntity, //Vector(1.0f, 0.0f, 0.0f),
524                                                        // Vector(contact[0].geom.pos[0],contact[0].geom.pos[1],contact[0].geom.pos[2]), false);
525                                                         
526                                                }//if
527                                        }//if
528                               
529                        if(this->isA("Terrain")) //ClassList::StringToID)
530                                        {
531                                       
532
533
534if(this->isA("Terrain"))
535{
536PRINTF(0)("Ich bin ein %s \n",this->getClassCName() );
537}
538
539                                        if( dCollide(this->ODE_Geom_ID,RayY, 1, &contact[0].geom, sizeof(dContact)))  {
540                                               
541                                                /*
542                                                if(false && dCollide(this->ODE_Geom_ID,RayYNeg, 1, &contact[0].geom, sizeof(dContact)))  {
543                                                        // worldEntity->registerCollision(COLLISION_TYPE_AXIS_Y_NEG , this, worldEntity, Vector(0.0f, ,this1.0f, 0.0f),
544                                                       //  Vector(contact[0].geom.pos[0],contact[0].geom.pos[1],contact[0].geom.pos[2]), false);
545                                                        CoRe::CollisionTube::getInstance()->registerCollisionEvent( CoRe::CREngine::CR_COLLISION_TYPE_AXIS_Y_NEG , worldEntity,this,  Vector(0.0f, 1.0f, 0.0f), Vector(contact[0].geom.pos[0],contact[0].geom.pos[1],contact[0].geom.pos[2]), false);
546                                                        PRINTF(0)("Kooomische  ................Collision");
547                                                       
548                                                }//if
549                                         if( false && dCollide(this->ODE_Geom_ID,RayYPos, 1, &contact[0].geom, sizeof(dContact)))  {
550
551                                                                CoRe::CollisionTube::getInstance()->registerCollisionEvent( CoRe::CREngine::CR_COLLISION_TYPE_AXIS_Y_NEG , worldEntity,this,  Vector(0.0f, -1.0f, 0.0f), Vector(contact[0].geom.pos[0],contact[0].geom.pos[1],contact[0].geom.pos[2]), false);
552                                                        PRINTF(0)("Kooomische  ................Collision");
553                                                         // worldEntity->registerCollision(COLLISION_TYPE_AXIS_Y_NEG , this, worldEntity, Vector(0.0f, 1.0f, 0.0f),
554                                                         //Vector(contact[0].geom.pos[0],contact[0].geom.pos[1] ,contact[0].geom.pos[2]), false);
555                                                       
556                                                }//if
557                                                else { */
558
559                                                //CoRe::CollisionTube::getInstance()->registerCollisionEvent( CoRe::CREngine::CR_COLLISION_TYPE_AXIS_Y_NEG , worldEntity,this,  Vector(0.0f, 1.0f, 0.0f), Vector(contact[0].geom.pos[0],contact[0].geom.pos[1],contact[0].geom.pos[2]), false);
560                                                        PRINTF(0)("Kooomische  ................Collision");
561
562                                                //worldEntity->registerCollision(COLLISION_TYPE_AXIS_Y_NEG , this, worldEntity, Vector(0.0f, 1.0f, 0.0f),
563                                                 //       Vector(contact[0].geom.pos[0],contact[0].geom.pos[1],contact[0].geom.pos[2]), false);
564
565                                                //}
566
567                                        }//if
568                               
569                                        if(dCollide(this->ODE_Geom_ID,RayZ, 1, &contact[0].geom, sizeof(dContact)))  {
570                                                if(dCollide(this->ODE_Geom_ID,RayZPos, 1, &contact[0].geom, sizeof(dContact)))  {
571                                                CoRe::CollisionTube::getInstance()->registerCollisionEvent( CoRe::CREngine::CR_COLLISION_TYPE_AXIS_Z , worldEntity,this,  Vector(0.0f, 1.0f, 0.0f), Vector(contact[0].geom.pos[0],contact[0].geom.pos[1],contact[0].geom.pos[2]), false);
572                                                        PRINTF(0)("Kooomische  ................Collision");
573                                                //        worldEntity->registerCollision(COLLISION_TYPE_AXIS_Z , this, worldEntity, Vector(0.0f, 0.0f, 1.0f),
574                                                  //       Vector(contact[0].geom.pos[0],contact[0].geom.pos[1],contact[0].geom.pos[2]), false);
575                                                       
576                                                }//if
577                                                if(dCollide(this->ODE_Geom_ID,RayZNeg, 1, &contact[0].geom, sizeof(dContact)))  {
578                                                CoRe::CollisionTube::getInstance()->registerCollisionEvent( CoRe::CREngine::CR_COLLISION_TYPE_AXIS_Z_NEG , worldEntity,this,  Vector(0.0f, 1.0f, 0.0f), Vector(contact[0].geom.pos[0],contact[0].geom.pos[1],contact[0].geom.pos[2]), false);
579                                                        PRINTF(0)("Kooomische  ................Collision");
580                                                        //  worldEntity->registerCollision(COLLISION_TYPE_AXIS_Z_NEG , this, worldEntity, Vector(0.0f, 0.0f, 1.0f),
581                                                         // Vector(contact[0].geom.pos[0],contact[0].geom.pos[1],contact[0].geom.pos[2]), false);
582                                                       
583                                                }//if
584                       
585                                               
586                                                if(dCollide(this->ODE_Geom_ID,RayXPos, 1, &contact[0].geom, sizeof(dContact)))  {
587                                                CoRe::CollisionTube::getInstance()->registerCollisionEvent( CoRe::CREngine::CR_COLLISION_TYPE_AXIS_X , worldEntity,this,  Vector(0.0f, 1.0f, 0.0f), Vector(contact[0].geom.pos[0],contact[0].geom.pos[1],contact[0].geom.pos[2]), false);
588                                                        PRINTF(0)("Kooomische  ................Collision");
589                                                //        worldEntity->registerCollision(COLLISION_TYPE_AXIS_Z , this, worldEntity, Vector(0.0f, 0.0f, 1.0f),
590                                                  //       Vector(contact[0].geom.pos[0],contact[0].geom.pos[1],contact[0].geom.pos[2]), false);
591                                                       
592                                                }//if
593                                                if(dCollide(this->ODE_Geom_ID,RayXNeg, 1, &contact[0].geom, sizeof(dContact)))  {
594                                                CoRe::CollisionTube::getInstance()->registerCollisionEvent( CoRe::CREngine::CR_COLLISION_TYPE_AXIS_X_NEG , worldEntity,this,  Vector(0.0f, 1.0f, 0.0f), Vector(contact[0].geom.pos[0],contact[0].geom.pos[1],contact[0].geom.pos[2]), false);
595                                                        PRINTF(0)("Kooomische  ................Collision");
596                                                        //  worldEntity->registerCollision(COLLISION_TYPE_AXIS_Z_NEG , this, worldEntity, Vector(0.0f, 0.0f, 1.0f),
597                                                         // Vector(contact[0].geom.pos[0],contact[0].geom.pos[1],contact[0].geom.pos[2]), false);
598                                                       
599                                                }//if
600
601
602                                        }//if
603                                }//if
604                       
605                        } //if
606               
607                       
608      dGeomDestroy(RayX);
609      dGeomDestroy(RayY);
610      dGeomDestroy(RayZ);
611      dGeomDestroy(RayXPos);
612      dGeomDestroy(RayYPos);
613      dGeomDestroy(RayZPos);
614      dGeomDestroy(RayXNeg);
615      dGeomDestroy(RayYNeg);
616      dGeomDestroy(RayZNeg);
617       
618     dGeomDestroy(BBOX);
619} // if(bbox != 0)
620
621if(box == NULL)
622{
623        dGeomID BBOX = dCreateBox (space, 20.0f, 40.0f  ,20.0f);
624        dGeomSetPosition (BBOX, worldEntity->getAbsCoor().,worldEntity->getAbsCoor().y, worldEntity->getAbsCoor().z);
625        //dGeomSetPosition (BBOX, worldEntity->getAbsCoor().x + box->center.x ,worldEntity->getAbsCoor().y+box->center.y, worldEntity->getAbsCoor().z+box->center.z);
626        if(dCollide(this->ODE_Geom_ID,BBOX, 1, &contact[0].geom, sizeof(dContact)))
627                                                {
628                                                       
629                                                PRINTF(0)("Collision wit %s at %f , %f , %f . \n", worldEntity->getCName(), contact[0].geom.pos[0],contact[0].geom.pos[1],contact[0].geom.pos[2] );     
630
631                                                CoRe::CollisionTube::getInstance()->registerCollisionEvent( CoRe::CREngine::CR_COLLISION_TYPE_AXIS_Y_NEG , this, worldEntity, Vector(1.0f, 0.0f, 0.0f), Vector(contact[0].geom.pos[0],contact[0].geom.pos[1],contact[0].geom.pos[2]), false);
632                                                }
633        dGeomDestroy(BBOX);
634}
635}
636else {
637        dGeomSetPosition (this->ODE_Geom_ID, this->getAbsCoor().,this->getAbsCoor().y, this->getAbsCoor().z);
638        //if(box != NULL )
639        dGeomID BBOX = dCreateBox (space, 10.0f, 40.0f  ,10.0f);
640        dGeomSetPosition (BBOX, worldEntity->getAbsCoor().,worldEntity->getAbsCoor().y, worldEntity->getAbsCoor().z);
641        //dGeomSetPosition (BBOX, worldEntity->getAbsCoor().x + box->center.x ,worldEntity->getAbsCoor().y+box->center.y, worldEntity->getAbsCoor().z+box->center.z);
642        if(dCollide(this->ODE_Geom_ID,BBOX, 1, &contact[0].geom, sizeof(dContact)))
643                                                {
644                                                       
645                                                PRINTF(5)("Collision wit %s at %f , %f , %f . \n", worldEntity->getCName(), contact[0].geom.pos[0],contact[0].geom.pos[1],contact[0].geom.pos[2] );
646
647                                                CoRe::CollisionTube::getInstance()->registerCollisionEvent( CoRe::CREngine::CR_COLLISION_TYPE_AXIS_Y_NEG , worldEntity, this, Vector(1.0f, 0.0f, 0.0f), Vector(contact[0].geom.pos[0],contact[0].geom.pos[1],contact[0].geom.pos[2]), false);
648                                                }
649        dGeomDestroy(BBOX);
650
651}
652
653#endif
654 
655}
656
657
658
[6142]659/**
[10147]660 * adds a mount point to the end of the list
661 * @param mountPoint point to be added
662 */
663void WorldEntity::addMountPoint(MountPoint* mountPoint)
664{
665  // add the mount point at the last position
666  this->mountPoints.push_back(mountPoint);
667}
668
669/**
670 * adds a mount point to a world entity
671 * @param mountPoint point to be added
672 */
673void WorldEntity::addMountPoint(int slot, MountPoint* mountPoint)
674{
675  if( this->mountPoints[slot] != NULL)
676  {
677    PRINTF(0)("adding a mount point to a slot, that already exists! ignoring - maybe some object do not get connected well (object: %s)\n", this->getClassCName());
678  }
679
680  // just connect the mount point
681  this->mountPoints[slot] = mountPoint;
682}
683
684
685/**
686 * mounts a world entity on a specified mount point (~socket)
687 * @param entity entity to be connected
688 */
689void WorldEntity::mount(int slot, WorldEntity* entity)
690{
691  if( this->mountPoints[slot] == NULL)
692  {
693    PRINTF(0)("you tried to add an entity to a mount point that doesn't exist (slot %i)\n", slot);
694    return;
695  }
696
697  // mount the entity
698  this->mountPoints[slot]->mount(entity);
699}
700
701
702/**
703 * removes a mount point from a specified mount point
704 * @param mountPoint entity to be unconnected
705 */
706void WorldEntity::unmount(int slot)
707{
708    if( this->mountPoints[slot] == NULL)
709  {
710    PRINTF(0)("you tried to remove an entity from a mount point that doesn't exist (slot %i)\n", slot);
711    return;
712  }
713
714  // unmount the entity
715  this->mountPoints[slot]->unmount();
716}
717
718
719/**
[7927]720 * subscribes this world entity to a collision reaction
721 *  @param type the type of reaction to subscribe to
[8190]722 *  @param target1 a filter target (classID)
723 */
[10013]724void WorldEntity::subscribeReaction(CoRe::CREngine::ReactionType type, const ClassID& target1)
[8190]725{
[10013]726  this->_collisionFilter.subscribeReaction(type, target1);
[8190]727}
728
729
730/**
731 * subscribes this world entity to a collision reaction
732 *  @param type the type of reaction to subscribe to
733 *  @param target1 a filter target (classID)
734 */
[10013]735void WorldEntity::subscribeReaction(CoRe::CREngine::ReactionType type, const ClassID& target1, const ClassID& target2)
[8190]736{
[10013]737  this->_collisionFilter.subscribeReaction(type, target1, target2);
[8190]738}
739
740
741/**
742 * subscribes this world entity to a collision reaction
743 *  @param type the type of reaction to subscribe to
744 *  @param target1 a filter target (classID)
745 */
[10013]746void WorldEntity::subscribeReaction(CoRe::CREngine::ReactionType type, const ClassID& target1, const ClassID& target2, const ClassID& target3)
[8190]747{
[10013]748  this->_collisionFilter.subscribeReaction(type, target1, target2, target3);
[8190]749}
750
751
752/**
753 * unsubscribes a specific reaction from the worldentity
754 *  @param type the reaction to unsubscribe
755 */
[10013]756void WorldEntity::unsubscribeReaction(CoRe::CREngine::ReactionType type)
[8190]757{
[10013]758  this->_collisionFilter.unsubscribeReaction(type);
[8190]759}
760
761
762/**
763 * unsubscribes all collision reactions
764 */
[10013]765void WorldEntity::unsubscribeReactions()
[8190]766{
[10013]767  this->_collisionFilter.unsubscribeReactions();
[8190]768}
769
770
771/**
[6142]772 * @brief moves this entity to the List OM_List
773 * @param list the list to set this Entity to.
774 *
775 * this is the same as a call to State::getObjectManager()->toList(entity , list);
776 * directly, but with an easier interface.
777 *
778 * @todo inline this (peut etre)
779 */
780void WorldEntity::toList(OM_LIST list)
781{
782  State::getObjectManager()->toList(this, list);
783}
[5061]784
[9656]785void WorldEntity::toListS(const std::string& listName)
786{
787  OM_LIST id = ObjectManager::StringToOMList(listName);
788  if (id != OM_NULL)
789    this->toList(id);
790  else
791    PRINTF(2)("List %s not found\n", listName.c_str());
792}
793
794
[8037]795void WorldEntity::toReflectionList()
796{
797  State::getObjectManager()->toReflectionList( this );
798}
[6142]799
[8037]800void removeFromReflectionList()
801{
[9869]802  /// TODO
803  ///  State::getObject
[8037]804}
[6142]805
[4261]806/**
[4885]807 * sets the character attributes of a worldentity
[4836]808 * @param character attributes
[4885]809 *
810 * these attributes don't have to be set, only use them, if you need them
[2043]811*/
[5498]812//void WorldEntity::setCharacterAttributes(CharacterAttributes* charAttr)
813//{}
[2036]814
[3583]815
[2043]816/**
[5029]817 *  this function is called, when two entities collide
818 * @param entity: the world entity with whom it collides
819 *
820 * Implement behaviour like damage application or other miscellaneous collision stuff in this function
821 */
822void WorldEntity::collidesWith(WorldEntity* entity, const Vector& location)
823{
[5498]824  /**
825   * THIS IS A DEFAULT COLLISION-Effect.
826   * IF YOU WANT TO CREATE A SPECIFIC COLLISION ON EACH OBJECT
827   * USE::
828   * if (entity->isA(CL_WHAT_YOU_ARE_LOOKING_FOR)) { printf "dothings"; };
829   *
830   * You can always define a default Action.... don't be affraid just test it :)
831   */
[9406]832  //  PRINTF(3)("collision %s vs %s @ (%f,%f,%f)\n", this->getClassCName(), entity->getClassCName(), location.x, location.y, location.z);
[5029]833}
834
[2043]835
836/**
[8186]837 *  this function is called, when two entities collide
838 * @param entity: the world entity with whom it collides
839 *
840 * Implement behaviour like damage application or other miscellaneous collision stuff in this function
841 */
842void WorldEntity::collidesWithGround(const Vector& location)
843{
[9406]844  PRINTF(0)("BSP_GROUND: %s collides \n", this->getClassCName() );
[8186]845}
846
847void WorldEntity::collidesWithGround(const Vector& feet, const Vector& ray_1, const Vector& ray_2)
848{
[8190]849
[9406]850  // PRINTF(0)("BSP_GROUND: Player collides \n", this->getClassCName() );
[8190]851
[8186]852  Vector v = this->getAbsDirX();
[8490]853  v.x *= 10.1;
854  v.y *= 10.1;
855  v.z *= 10.1;
856  Vector u = Vector(0.0,-20.0,0.0);
[8190]857
[8490]858
859  if(!(this->getAbsCoor().x == ray_2.x && this->getAbsCoor().y == ray_2.y && this->getAbsCoor().z == ray_2.z) )
[8186]860  {
[8190]861
[9869]862    this->setAbsCoor(ray_2 - v);
[8490]863
[8186]864  }
[9869]865  else
[8186]866  {
867    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)
868    {
[8190]869      this->setAbsCoor(feet -u );
[8186]870    }
[8190]871
872    this->setAbsCoor(ray_2 - v);
873
[8186]874  }
[8490]875
876
[8186]877}
878
879/**
[5498]880 *  this is called immediately after the Entity has been constructed, initialized and then Spawned into the World
[4885]881 *
[5498]882 */
[3229]883void WorldEntity::postSpawn ()
[6430]884{}
[2043]885
[3583]886
[2043]887/**
[6959]888 *  this method is called by the world if the WorldEntity leaves the game
[5498]889 */
[6959]890void WorldEntity::leaveWorld ()
[6430]891{}
[2043]892
[3583]893
[2190]894/**
[7085]895 * resets the WorldEntity to its initial values. eg. used for multiplayer games: respawning
896 */
897void WorldEntity::reset()
[9235]898{
899  this->setHealth( this->getHealthMax() );
900}
[7085]901
902/**
[4836]903 *  this method is called every frame
904 * @param time: the time in seconds that has passed since the last tick
[4885]905 *
906 * Handle all stuff that should update with time inside this method (movement, animation, etc.)
[2043]907*/
[4570]908void WorldEntity::tick(float time)
[6430]909{}
[3583]910
[5498]911
[3583]912/**
[4836]913 *  the entity is drawn onto the screen with this function
[4885]914 *
915 * This is a central function of an entity: call it to let the entity painted to the screen.
916 * Just override this function with whatever you want to be drawn.
[3365]917*/
[5500]918void WorldEntity::draw() const
[3803]919{
[9406]920  //PRINTF(0)("(%s::%s)\n", this->getClassCName(), this->getName());
[6281]921  //  assert(!unlikely(this->models.empty()));
[6002]922  {
923    glMatrixMode(GL_MODELVIEW);
924    glPushMatrix();
[4570]925
[6002]926    /* translate */
927    glTranslatef (this->getAbsCoor ().x,
928                  this->getAbsCoor ().y,
929                  this->getAbsCoor ().z);
[6004]930    Vector tmpRot = this->getAbsDir().getSpacialAxis();
931    glRotatef (this->getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
[2043]932
[6004]933
934    // This Draws the LOD's
[7014]935    float cameraDistance = State::getCamera()->distance(this);
[6004]936    if (cameraDistance > 30 && this->models.size() >= 3 && this->models[2] != NULL)
[6002]937    {
[6222]938      this->models[2]->draw();
[6004]939    }
940    else if (cameraDistance > 10 && this->models.size() >= 2 && this->models[1] != NULL)
[6002]941    {
942      this->models[1]->draw();
[6004]943    }
944    else if (this->models.size() >= 1 && this->models[0] != NULL)
[6002]945    {
946      this->models[0]->draw();
947    }
[8724]948
[9869]949    //     if( this->aabbNode != NULL)
950    //       this->aabbNode->drawBV(0, DRAW_BV_POLYGON, Vector(1, 0.6, 0.2), true);
[8724]951
[6002]952    glPopMatrix();
953  }
[3803]954}
[3583]955
[6430]956/**
[6700]957 * @param health the Health to add.
958 * @returns the health left (this->healthMax - health+this->health)
[6430]959 */
[6700]960float WorldEntity::increaseHealth(float health)
[6430]961{
[6700]962  this->health += health;
963  if (this->health > this->healthMax)
[6430]964  {
[6700]965    float retHealth = this->healthMax - this->health;
966    this->health = this->healthMax;
967    this->updateHealthWidget();
968    return retHealth;
[6430]969  }
[6700]970  this->updateHealthWidget();
[6430]971  return 0.0;
972}
[6281]973
[5498]974/**
[6700]975 * @param health the Health to be removed
[6430]976 * @returns 0.0 or the rest, that was not substracted (bellow 0.0)
977 */
[6700]978float WorldEntity::decreaseHealth(float health)
[6430]979{
[6700]980  this->health -= health;
[6430]981
[6700]982  if (this->health < 0)
[6430]983  {
[6700]984    float retHealth = -this->health;
985    this->health = 0.0f;
986    this->updateHealthWidget();
987    return retHealth;
[6430]988  }
[6700]989  this->updateHealthWidget();
[6430]990  return 0.0;
991
992}
993
994/**
[6700]995 * @param maxHealth the maximal health that can be loaded onto the entity.
[6430]996 */
[6700]997void WorldEntity::setHealthMax(float healthMax)
[6430]998{
[6700]999  this->healthMax = healthMax;
1000  if (this->health > this->healthMax)
[6430]1001  {
[9406]1002    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());
[6700]1003    this->health = this->healthMax;
[6430]1004  }
[6700]1005  this->updateHealthWidget();
[6430]1006}
1007
[6431]1008/**
[6700]1009 * @brief creates the HealthWidget
[6431]1010 *
[6700]1011 * since not all entities need an HealthWidget, it is only created on request.
[6431]1012 */
[6700]1013void WorldEntity::createHealthWidget()
[6430]1014{
[6700]1015  if (this->healthWidget == NULL)
[6430]1016  {
[8974]1017    this->healthWidget = new OrxGui::GLGuiEnergyWidget();
[8977]1018    this->healthWidget->setDisplayedName(std::string(this->getClassName()) + " Energy:");
[6700]1019    this->healthWidget->setSize2D(30,400);
1020    this->healthWidget->setAbsCoor2D(10,100);
[6430]1021
[6700]1022    this->updateHealthWidget();
[6430]1023  }
1024  else
[9406]1025    PRINTF(3)("Allready created the HealthWidget for %s::%s\n", this->getClassCName(), this->getCName());
[6430]1026}
1027
[6700]1028void WorldEntity::increaseHealthMax(float increaseHealth)
[6440]1029{
[6700]1030  this->healthMax += increaseHealth;
1031  this->updateHealthWidget();
[6440]1032}
1033
[6700]1034
[7779]1035OrxGui::GLGuiWidget* WorldEntity::getHealthWidget()
[6700]1036{
1037  this->createHealthWidget();
1038  return this->healthWidget;
1039}
1040
[6431]1041/**
[6700]1042 * @param visibility shows or hides the health-bar
[6431]1043 * (creates the widget if needed)
1044 */
[6700]1045void WorldEntity::setHealthWidgetVisibilit(bool visibility)
[6430]1046{
[7198]1047  if (visibility)
1048  {
1049    if (this->healthWidget != NULL)
1050      this->healthWidget->show();
1051    else
[6430]1052    {
[7198]1053      this->createHealthWidget();
1054      this->updateHealthWidget();
1055      this->healthWidget->show();
[6430]1056    }
[7198]1057  }
1058  else if (this->healthWidget != NULL)
1059    this->healthWidget->hide();
[6430]1060}
1061
[8724]1062
[6431]1063/**
[8724]1064 * hit the world entity with
1065 *  @param damage damage to be dealt
1066 */
[9008]1067void WorldEntity::hit(float damage, WorldEntity* killer)
[8724]1068{
1069  this->decreaseHealth(damage);
1070
[9406]1071  PRINTF(5)("Hit me: %s::%s now only %f/%f health\n", this->getClassCName(), this->getCName(), this->getHealth(), this->getHealthMax());
[8777]1072
[8724]1073  if( this->getHealth() > 0)
1074  {
1075    // any small explosion animaitions
1076  }
1077  else
1078  {
[9235]1079    this->destroy( killer );
[8724]1080  }
1081}
1082
1083
1084/**
[8777]1085 * destoys the world entity
1086 */
[9235]1087void WorldEntity::destroy(WorldEntity* killer)
[8777]1088{
1089  this->toList(OM_DEAD);
1090}
1091
1092
1093/**
[6700]1094 * @brief updates the HealthWidget
[6431]1095 */
[6700]1096void WorldEntity::updateHealthWidget()
[6430]1097{
[6700]1098  if (this->healthWidget != NULL)
[6430]1099  {
[6700]1100    this->healthWidget->setMaximum(this->healthMax);
1101    this->healthWidget->setValue(this->health);
[6430]1102  }
1103}
1104
1105
1106/**
[5498]1107 * DEBUG-DRAW OF THE BV-Tree.
1108 * @param depth What depth to draw
1109 * @param drawMode the mode to draw this entity under
1110 */
[7711]1111void WorldEntity::drawBVTree(int depth, int drawMode) const
[4684]1112{
1113  glMatrixMode(GL_MODELVIEW);
1114  glPushMatrix();
1115  /* translate */
1116  glTranslatef (this->getAbsCoor ().x,
1117                this->getAbsCoor ().y,
1118                this->getAbsCoor ().z);
1119  /* rotate */
[4998]1120  Vector tmpRot = this->getAbsDir().getSpacialAxis();
1121  glRotatef (this->getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
[4684]1122
[7711]1123
[4684]1124  if (this->obbTree)
1125    this->obbTree->drawBV(depth, drawMode);
[7711]1126
1127
[4684]1128  glPopMatrix();
1129}
[6341]1130
[6424]1131
[6341]1132/**
[6424]1133 * Debug the WorldEntity
1134 */
1135void WorldEntity::debugEntity() const
1136{
[9406]1137  PRINT(0)("WorldEntity %s::%s  (DEBUG)\n", this->getClassCName(), this->getCName());
[6424]1138  this->debugNode();
[9656]1139  PRINT(0)("List: %s ; ModelCount %d - ", ObjectManager::OMListToString(this->objectListNumber).c_str(), this->models.size());
[6424]1140  for (unsigned int i = 0; i < this->models.size(); i++)
1141  {
1142    if (models[i] != NULL)
[9406]1143      PRINT(0)(" : %d:%s", i, this->models[i]->getCName());
[6424]1144  }
1145  PRINT(0)("\n");
1146
1147}
1148
1149
1150/**
[7954]1151 * handler for changes on registred vars
1152 * @param id id's which changed
[6341]1153 */
[7954]1154void WorldEntity::varChangeHandler( std::list< int > & id )
[6341]1155{
[7954]1156  if ( std::find( id.begin(), id.end(), modelFileName_handle ) != id.end() ||
1157       std::find( id.begin(), id.end(), scaling_handle ) != id.end()
1158     )
[6341]1159  {
[7954]1160    loadModel( modelFileName, scaling );
[6341]1161  }
1162
[9008]1163  if ( std::find( id.begin(), id.end(), list_handle ) != id.end() )
1164  {
1165    this->toList( (OM_LIST)list_write );
1166  }
[9235]1167
[9110]1168  if ( std::find( id.begin(), id.end(), health_handle ) != id.end() )
1169  {
1170    this->setHealth( health_write );
1171  }
[9235]1172
[9110]1173  if ( std::find( id.begin(), id.end(), healthMax_handle ) != id.end() )
1174  {
1175    this->setHealthMax( healthMax_write );
1176  }
[9008]1177
[7954]1178  PNode::varChangeHandler( id );
[6341]1179}
1180
Note: See TracBrowser for help on using the repository browser.