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
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 "md2Model.h"
24#include "resource_manager.h"
25#include "load_param.h"
26#include "list.h"
27#include "vector.h"
28#include "obb_tree.h"
29
30#include "state.h"
31
32using namespace std;
33
34SHELL_COMMAND(model, WorldEntity, loadModel)
35    ->describe("sets the Model of the WorldEntity")
36    ->defaultValues(2, "models/ships/fighter.obj", 1.0);
37
38
39/**
40 *  Loads the WordEntity-specific Part of any derived Class
41 *
42 * @param root: Normally NULL, as the Derived Entities define a loadParams Function themeselves,
43 *              that can calls WorldEntities loadParams for itself.
44 */
45WorldEntity::WorldEntity(const TiXmlElement* root)
46  : Synchronizeable()
47{
48  this->setClassID(CL_WORLD_ENTITY, "WorldEntity");
49
50  this->obbTree = NULL;
51
52  if (root != NULL)
53    this->loadParams(root);
54
55  this->setVisibiliy(true);
56
57  this->objectListNumber = OM_INIT;
58  this->objectListIterator = NULL;
59
60  this->toList(OM_NULL);
61}
62
63/**
64 *  standard destructor
65*/
66WorldEntity::~WorldEntity ()
67{
68  // Delete the obbTree
69  if( this->obbTree != NULL)
70    delete this->obbTree;
71
72  // Delete the model (unregister it with the ResourceManager)
73  for (unsigned int i = 0; i < this->models.size(); i++)
74    this->setModel(NULL, i);
75
76  State::getObjectManager()->toList(this, OM_INIT);
77}
78
79/**
80 * loads the WorldEntity Specific Parameters.
81 * @param root: the XML-Element to load the Data From
82 */
83void WorldEntity::loadParams(const TiXmlElement* root)
84{
85  // Do the PNode loading stuff
86  static_cast<PNode*>(this)->loadParams(root);
87
88  // Model Loading
89  LoadParam(root, "model", this, WorldEntity, loadModel)
90      .describe("the fileName of the model, that should be loaded onto this world-entity. (must be relative to the data-dir)")
91      .defaultValues(3, NULL, 1.0f, 0);
92
93}
94
95/**
96 * loads a Model onto a WorldEntity
97 * @param fileName the name of the model to load
98 * @param scaling the Scaling of the model
99 *
100 * @todo fix this, so it only has one loadModel-Function.
101*/
102void WorldEntity::loadModel(const char* fileName, float scaling, unsigned int modelNumber)
103{
104  if (fileName != NULL)
105  {
106   // search for the special character # in the LoadParam
107    if (strchr(fileName, '#') != NULL)
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++)
114      {
115        *depth = 48+(int)i;
116        printf("-------%s\n", lodFile);
117        if (ResourceManager::isInDataDir(lodFile))
118          this->loadModel(lodFile, scaling, i);
119      }
120      return;
121    }
122
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);
130
131      if( modelNumber == 0)
132        this->buildObbTree(4);
133    }
134    else if(strstr(fileName, ".md2"))
135    {
136      PRINTF(4)("fetching MD2 file: %s\n", fileName);
137//         MD2Model* m = (MD2Model*)ResourceManager::getInstance()->load(fileName, MD2, RP_CAMPAIGN);
138      Model* m = new MD2Model(fileName, "md2_fake_texture.bad");
139        //this->setModel((Model*)ResourceManager::getInstance()->load(fileName, MD2, RP_CAMPAIGN), 0);
140      this->setModel(m, 0);
141    }
142  }
143  else
144    this->setModel(NULL);
145}
146
147/**
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{
154  if (this->models.size() <= modelNumber)
155    this->models.resize(modelNumber+1, NULL);
156
157  if (this->models[modelNumber] != NULL)
158  {
159    Resource* resource = ResourceManager::getInstance()->locateResourceByPointer(this->models[modelNumber]);
160//     if (resource != NULL)
161    ResourceManager::getInstance()->unload(resource, RP_LEVEL);
162  }
163  else
164    delete this->models[modelNumber];
165
166  this->models[modelNumber] = model;
167
168
169//   if (this->model != NULL)
170//     this->buildObbTree(4);
171}
172
173
174/**
175 * builds the obb-tree
176 * @param depth the depth to calculate
177 */
178bool WorldEntity::buildObbTree(unsigned int depth)
179{
180  if (this->obbTree)
181    delete this->obbTree;
182
183  if (this->models[0] != NULL)
184  {
185    PRINTF(4)("creating obb tree\n");
186
187
188    this->obbTree = new OBBTree(depth, (sVec3D*)this->models[0]->getVertexArray(), this->models[0]->getVertexCount());
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  }
197}
198
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}
212
213
214
215/**
216 * sets the character attributes of a worldentity
217 * @param character attributes
218 *
219 * these attributes don't have to be set, only use them, if you need them
220*/
221//void WorldEntity::setCharacterAttributes(CharacterAttributes* charAttr)
222//{}
223
224
225/**
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{
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   */
241//  PRINTF(3)("collision %s vs %s @ (%f,%f,%f)\n", this->getClassName(), entity->getClassName(), location.x, location.y, location.z);
242}
243
244
245/**
246 *  this is called immediately after the Entity has been constructed, initialized and then Spawned into the World
247 *
248 */
249void WorldEntity::postSpawn ()
250{
251}
252
253
254/**
255 *  this method is called by the world if the WorldEntity leaves valid gamespace
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).
259 *
260 * NOT YET IMPLEMENTED
261 */
262void WorldEntity::leftWorld ()
263{
264}
265
266
267/**
268 *  this method is called every frame
269 * @param time: the time in seconds that has passed since the last tick
270 *
271 * Handle all stuff that should update with time inside this method (movement, animation, etc.)
272*/
273void WorldEntity::tick(float time)
274{
275}
276
277
278/**
279 *  the entity is drawn onto the screen with this function
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.
283*/
284void WorldEntity::draw() const
285{
286  this->drawLODsafe();
287}
288
289
290/**
291 *  this functions draws the model automaticaly in multiple LOD
292 */
293void WorldEntity::drawLODsafe() const
294{
295  if (!unlikely(this->models.empty()))
296  {
297    glMatrixMode(GL_MODELVIEW);
298    glPushMatrix();
299
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 );
306
307
308    // This Draws the LOD's
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();
313    }
314    else if (cameraDistance > 10 && this->models.size() >= 2 && this->models[1] != NULL)
315    {
316      this->models[1]->draw();
317    }
318    else if (this->models.size() >= 1 && this->models[0] != NULL)
319    {
320      this->models[0]->draw();
321    }
322    glPopMatrix();
323  }
324}
325
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 */
331void WorldEntity::drawBVTree(unsigned int depth, int drawMode) const
332{
333  glMatrixMode(GL_MODELVIEW);
334  glPushMatrix();
335  /* translate */
336  glTranslatef (this->getAbsCoor ().x,
337                this->getAbsCoor ().y,
338                this->getAbsCoor ().z);
339  /* rotate */
340  Vector tmpRot = this->getAbsDir().getSpacialAxis();
341  glRotatef (this->getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
342
343  if (this->obbTree)
344    this->obbTree->drawBV(depth, drawMode);
345  glPopMatrix();
346}
Note: See TracBrowser for help on using the repository browser.