Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/christmas_branche/src/world_entities/world_entity.cc @ 6180

Last change on this file since 6180 was 6180, checked in by patrick, 18 years ago

christmas: cleaned up the model package

File size: 9.1 KB
RevLine 
[2036]1
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:
14   main-programmer: Patrick Boenzli
[2190]15   co-programmer: Christian Meyer
[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
[5511]22#include "model.h"
[6169]23#include "md2Model.h"
[5143]24#include "resource_manager.h"
25#include "load_param.h"
[3608]26#include "list.h"
[3803]27#include "vector.h"
[4682]28#include "obb_tree.h"
[3608]29
[6002]30#include "state.h"
31
[2036]32using namespace std;
33
[5208]34SHELL_COMMAND(model, WorldEntity, loadModel)
35    ->describe("sets the Model of the WorldEntity")
[5555]36    ->defaultValues(2, "models/ships/fighter.obj", 1.0);
[5208]37
38
[2043]39/**
[4836]40 *  Loads the WordEntity-specific Part of any derived Class
[5498]41 *
42 * @param root: Normally NULL, as the Derived Entities define a loadParams Function themeselves,
43 *              that can calls WorldEntities loadParams for itself.
44 */
[4261]45WorldEntity::WorldEntity(const TiXmlElement* root)
[5996]46  : Synchronizeable()
[2190]47{
[4320]48  this->setClassID(CL_WORLD_ENTITY, "WorldEntity");
[4597]49
[4682]50  this->obbTree = NULL;
[4261]51
[5995]52  if (root != NULL)
[4261]53    this->loadParams(root);
54
[4885]55  this->setVisibiliy(true);
[6142]56
57  this->objectListNumber = OM_INIT;
58  this->objectListIterator = NULL;
59
60  this->toList(OM_NULL);
[2190]61}
[2043]62
63/**
[4836]64 *  standard destructor
[2043]65*/
[2190]66WorldEntity::~WorldEntity ()
[2036]67{
[5498]68  // Delete the obbTree
[5302]69  if( this->obbTree != NULL)
[4814]70    delete this->obbTree;
[5994]71
72  // Delete the model (unregister it with the ResourceManager)
[6005]73  for (unsigned int i = 0; i < this->models.size(); i++)
74    this->setModel(NULL, i);
[6142]75
76  State::getObjectManager()->toList(this, OM_INIT);
[3531]77}
78
[5498]79/**
80 * loads the WorldEntity Specific Parameters.
81 * @param root: the XML-Element to load the Data From
82 */
[4436]83void WorldEntity::loadParams(const TiXmlElement* root)
84{
[5498]85  // Do the PNode loading stuff
[4436]86  static_cast<PNode*>(this)->loadParams(root);
[5498]87
[4436]88  // Model Loading
[5671]89  LoadParam(root, "model", this, WorldEntity, loadModel)
[5652]90      .describe("the fileName of the model, that should be loaded onto this world-entity. (must be relative to the data-dir)")
[5995]91      .defaultValues(3, NULL, 1.0f, 0);
[5465]92
[4436]93}
94
[3531]95/**
[4885]96 * loads a Model onto a WorldEntity
[4836]97 * @param fileName the name of the model to load
[5057]98 * @param scaling the Scaling of the model
[5498]99 *
100 * @todo fix this, so it only has one loadModel-Function.
[4261]101*/
[5995]102void WorldEntity::loadModel(const char* fileName, float scaling, unsigned int modelNumber)
[4261]103{
[4732]104  if (fileName != NULL)
[6142]105  {
[6172]106   // search for the special character # in the LoadParam
[6005]107    if (strchr(fileName, '#') != NULL)
[6172]108    {
109      PRINTF(4)("Found # in %s... searching for LOD's\n", fileName);
110      char* lodFile = new char[strlen(fileName)+1];
111      strcpy(lodFile, fileName);
112      char* depth = strchr(lodFile, '#');
113      for (unsigned int i = 0; i < 5; i++)
[6005]114      {
[6172]115        *depth = 48+(int)i;
116        printf("-------%s\n", lodFile);
117        if (ResourceManager::isInDataDir(lodFile))
118          this->loadModel(lodFile, scaling, i);
[6005]119      }
[6172]120      return;
121    }
[6005]122
[6172]123    if(strstr(fileName, ".obj"))
124    {
125      PRINTF(4)("fetching OBJ file: %s\n", fileName);
126      if (scaling == 1.0)
127        this->setModel((Model*)ResourceManager::getInstance()->load(fileName, OBJ, RP_CAMPAIGN), modelNumber);
128      else
129        this->setModel((Model*)ResourceManager::getInstance()->load(fileName, OBJ, RP_CAMPAIGN, &scaling), modelNumber);
[6167]130
[6172]131      if( modelNumber == 0)
132        this->buildObbTree(4);
133    }
134    else if(strstr(fileName, ".md2"))
135    {
[6175]136      PRINTF(4)("fetching MD2 file: %s\n", fileName);
[6169]137//         MD2Model* m = (MD2Model*)ResourceManager::getInstance()->load(fileName, MD2, RP_CAMPAIGN);
[6180]138      Model* m = new MD2Model(fileName, "md2_fake_texture.bad");
[6169]139        //this->setModel((Model*)ResourceManager::getInstance()->load(fileName, MD2, RP_CAMPAIGN), 0);
[6180]140      this->setModel(m, 0);
[6172]141    }
[4732]142  }
143  else
[5995]144    this->setModel(NULL);
[4261]145}
146
[5061]147/**
[5994]148 * sets a specific Model for the Object.
149 * @param model The Model to set
150 * @param modelNumber the n'th model in the List to get.
151 */
152void WorldEntity::setModel(Model* model, unsigned int modelNumber)
153{
[5995]154  if (this->models.size() <= modelNumber)
155    this->models.resize(modelNumber+1, NULL);
156
157  if (this->models[modelNumber] != NULL)
[6004]158  {
[5995]159    Resource* resource = ResourceManager::getInstance()->locateResourceByPointer(this->models[modelNumber]);
[6169]160//     if (resource != NULL)
161    ResourceManager::getInstance()->unload(resource, RP_LEVEL);
[5994]162  }
[6169]163  else
164    delete this->models[modelNumber];
165
[5995]166  this->models[modelNumber] = model;
[5994]167
[6169]168
[6004]169//   if (this->model != NULL)
[5994]170//     this->buildObbTree(4);
171}
172
173
174/**
[5061]175 * builds the obb-tree
176 * @param depth the depth to calculate
177 */
178bool WorldEntity::buildObbTree(unsigned int depth)
179{
[5428]180  if (this->obbTree)
181    delete this->obbTree;
182
[5995]183  if (this->models[0] != NULL)
[5428]184  {
185    PRINTF(4)("creating obb tree\n");
[5708]186
187
[5995]188    this->obbTree = new OBBTree(depth, (sVec3D*)this->models[0]->getVertexArray(), this->models[0]->getVertexCount());
[5428]189    return true;
190  }
191  else
192  {
193    PRINTF(2)("could not create obb-tree, because no model was loaded yet\n");
194    this->obbTree = NULL;
195    return false;
196  }
[5061]197}
[5057]198
[6142]199/**
200 * @brief moves this entity to the List OM_List
201 * @param list the list to set this Entity to.
202 *
203 * this is the same as a call to State::getObjectManager()->toList(entity , list);
204 * directly, but with an easier interface.
205 *
206 * @todo inline this (peut etre)
207 */
208void WorldEntity::toList(OM_LIST list)
209{
210  State::getObjectManager()->toList(this, list);
211}
[5061]212
[6142]213
214
[4261]215/**
[4885]216 * sets the character attributes of a worldentity
[4836]217 * @param character attributes
[4885]218 *
219 * these attributes don't have to be set, only use them, if you need them
[2043]220*/
[5498]221//void WorldEntity::setCharacterAttributes(CharacterAttributes* charAttr)
222//{}
[2036]223
[3583]224
[2043]225/**
[5029]226 *  this function is called, when two entities collide
227 * @param entity: the world entity with whom it collides
228 *
229 * Implement behaviour like damage application or other miscellaneous collision stuff in this function
230 */
231void WorldEntity::collidesWith(WorldEntity* entity, const Vector& location)
232{
[5498]233  /**
234   * THIS IS A DEFAULT COLLISION-Effect.
235   * IF YOU WANT TO CREATE A SPECIFIC COLLISION ON EACH OBJECT
236   * USE::
237   * if (entity->isA(CL_WHAT_YOU_ARE_LOOKING_FOR)) { printf "dothings"; };
238   *
239   * You can always define a default Action.... don't be affraid just test it :)
240   */
[5257]241//  PRINTF(3)("collision %s vs %s @ (%f,%f,%f)\n", this->getClassName(), entity->getClassName(), location.x, location.y, location.z);
[5029]242}
243
[2043]244
245/**
[5498]246 *  this is called immediately after the Entity has been constructed, initialized and then Spawned into the World
[4885]247 *
[5498]248 */
[3229]249void WorldEntity::postSpawn ()
[2190]250{
251}
[2043]252
[3583]253
[2043]254/**
[4836]255 *  this method is called by the world if the WorldEntity leaves valid gamespace
[4885]256 *
257 * For free entities this means it left the Track boundaries. With bound entities it means its Location adresses a
258 * place that is not in the world anymore. In both cases you might have to take extreme measures (a.k.a. call destroy).
[5498]259 *
260 * NOT YET IMPLEMENTED
261 */
[3583]262void WorldEntity::leftWorld ()
[2190]263{
264}
[2043]265
[3583]266
[2190]267/**
[4836]268 *  this method is called every frame
269 * @param time: the time in seconds that has passed since the last tick
[4885]270 *
271 * Handle all stuff that should update with time inside this method (movement, animation, etc.)
[2043]272*/
[4570]273void WorldEntity::tick(float time)
[2190]274{
275}
[3583]276
[5498]277
[3583]278/**
[4836]279 *  the entity is drawn onto the screen with this function
[4885]280 *
281 * This is a central function of an entity: call it to let the entity painted to the screen.
282 * Just override this function with whatever you want to be drawn.
[3365]283*/
[5500]284void WorldEntity::draw() const
[3803]285{
[6005]286  this->drawLODsafe();
287}
288
[6169]289
290/**
291 *  this functions draws the model automaticaly in multiple LOD
292 */
[6005]293void WorldEntity::drawLODsafe() const
294{
[6169]295  if (!unlikely(this->models.empty()))
[6002]296  {
[6179]297    glMatrixMode(GL_MODELVIEW);
298    glPushMatrix();
[4570]299
[6179]300    /* translate */
301    glTranslatef (this->getAbsCoor ().x,
302                  this->getAbsCoor ().y,
303                  this->getAbsCoor ().z);
304    Vector tmpRot = this->getAbsDir().getSpacialAxis();
305    glRotatef (this->getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
[2043]306
[6004]307
308    // This Draws the LOD's
[6179]309    float cameraDistance = (State::getCamera()->getAbsCoor() - this->getAbsCoor()).len();
310    if (cameraDistance > 30 && this->models.size() >= 3 && this->models[2] != NULL)
311    {
312      this->models[2]->draw();
[6004]313    }
[6179]314    else if (cameraDistance > 10 && this->models.size() >= 2 && this->models[1] != NULL)
[6002]315    {
[6179]316      this->models[1]->draw();
317    }
318    else if (this->models.size() >= 1 && this->models[0] != NULL)
319    {
[6002]320      this->models[0]->draw();
321    }
[6179]322    glPopMatrix();
[6002]323  }
[3803]324}
[3583]325
[5498]326/**
327 * DEBUG-DRAW OF THE BV-Tree.
328 * @param depth What depth to draw
329 * @param drawMode the mode to draw this entity under
330 */
[5501]331void WorldEntity::drawBVTree(unsigned int depth, int drawMode) const
[4684]332{
333  glMatrixMode(GL_MODELVIEW);
334  glPushMatrix();
335  /* translate */
336  glTranslatef (this->getAbsCoor ().x,
337                this->getAbsCoor ().y,
338                this->getAbsCoor ().z);
339  /* rotate */
[4998]340  Vector tmpRot = this->getAbsDir().getSpacialAxis();
341  glRotatef (this->getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
[4684]342
343  if (this->obbTree)
344    this->obbTree->drawBV(depth, drawMode);
345  glPopMatrix();
346}
Note: See TracBrowser for help on using the repository browser.