Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

christmas: the draw funciton now is original again

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      MD2Model* m = new MD2Model(fileName, "");
139      m->debug();
140        //this->setModel((Model*)ResourceManager::getInstance()->load(fileName, MD2, RP_CAMPAIGN), 0);
141      this->setModel((Model*)m, 0);
142    }
143  }
144  else
145    this->setModel(NULL);
146}
147
148/**
149 * sets a specific Model for the Object.
150 * @param model The Model to set
151 * @param modelNumber the n'th model in the List to get.
152 */
153void WorldEntity::setModel(Model* model, unsigned int modelNumber)
154{
155  if (this->models.size() <= modelNumber)
156    this->models.resize(modelNumber+1, NULL);
157
158  if (this->models[modelNumber] != NULL)
159  {
160    Resource* resource = ResourceManager::getInstance()->locateResourceByPointer(this->models[modelNumber]);
161//     if (resource != NULL)
162    ResourceManager::getInstance()->unload(resource, RP_LEVEL);
163  }
164  else
165    delete this->models[modelNumber];
166
167  this->models[modelNumber] = model;
168
169
170//   if (this->model != NULL)
171//     this->buildObbTree(4);
172}
173
174
175/**
176 * builds the obb-tree
177 * @param depth the depth to calculate
178 */
179bool WorldEntity::buildObbTree(unsigned int depth)
180{
181  if (this->obbTree)
182    delete this->obbTree;
183
184  if (this->models[0] != NULL)
185  {
186    PRINTF(4)("creating obb tree\n");
187
188
189    this->obbTree = new OBBTree(depth, (sVec3D*)this->models[0]->getVertexArray(), this->models[0]->getVertexCount());
190    return true;
191  }
192  else
193  {
194    PRINTF(2)("could not create obb-tree, because no model was loaded yet\n");
195    this->obbTree = NULL;
196    return false;
197  }
198}
199
200/**
201 * @brief moves this entity to the List OM_List
202 * @param list the list to set this Entity to.
203 *
204 * this is the same as a call to State::getObjectManager()->toList(entity , list);
205 * directly, but with an easier interface.
206 *
207 * @todo inline this (peut etre)
208 */
209void WorldEntity::toList(OM_LIST list)
210{
211  State::getObjectManager()->toList(this, list);
212}
213
214
215
216/**
217 * sets the character attributes of a worldentity
218 * @param character attributes
219 *
220 * these attributes don't have to be set, only use them, if you need them
221*/
222//void WorldEntity::setCharacterAttributes(CharacterAttributes* charAttr)
223//{}
224
225
226/**
227 *  this function is called, when two entities collide
228 * @param entity: the world entity with whom it collides
229 *
230 * Implement behaviour like damage application or other miscellaneous collision stuff in this function
231 */
232void WorldEntity::collidesWith(WorldEntity* entity, const Vector& location)
233{
234  /**
235   * THIS IS A DEFAULT COLLISION-Effect.
236   * IF YOU WANT TO CREATE A SPECIFIC COLLISION ON EACH OBJECT
237   * USE::
238   * if (entity->isA(CL_WHAT_YOU_ARE_LOOKING_FOR)) { printf "dothings"; };
239   *
240   * You can always define a default Action.... don't be affraid just test it :)
241   */
242//  PRINTF(3)("collision %s vs %s @ (%f,%f,%f)\n", this->getClassName(), entity->getClassName(), location.x, location.y, location.z);
243}
244
245
246/**
247 *  this is called immediately after the Entity has been constructed, initialized and then Spawned into the World
248 *
249 */
250void WorldEntity::postSpawn ()
251{
252}
253
254
255/**
256 *  this method is called by the world if the WorldEntity leaves valid gamespace
257 *
258 * For free entities this means it left the Track boundaries. With bound entities it means its Location adresses a
259 * place that is not in the world anymore. In both cases you might have to take extreme measures (a.k.a. call destroy).
260 *
261 * NOT YET IMPLEMENTED
262 */
263void WorldEntity::leftWorld ()
264{
265}
266
267
268/**
269 *  this method is called every frame
270 * @param time: the time in seconds that has passed since the last tick
271 *
272 * Handle all stuff that should update with time inside this method (movement, animation, etc.)
273*/
274void WorldEntity::tick(float time)
275{
276}
277
278
279/**
280 *  the entity is drawn onto the screen with this function
281 *
282 * This is a central function of an entity: call it to let the entity painted to the screen.
283 * Just override this function with whatever you want to be drawn.
284*/
285void WorldEntity::draw() const
286{
287  this->drawLODsafe();
288}
289
290
291/**
292 *  this functions draws the model automaticaly in multiple LOD
293 */
294void WorldEntity::drawLODsafe() const
295{
296  if (!unlikely(this->models.empty()))
297  {
298    glMatrixMode(GL_MODELVIEW);
299    glPushMatrix();
300
301    /* translate */
302    glTranslatef (this->getAbsCoor ().x,
303                  this->getAbsCoor ().y,
304                  this->getAbsCoor ().z);
305    Vector tmpRot = this->getAbsDir().getSpacialAxis();
306    glRotatef (this->getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
307
308
309    // This Draws the LOD's
310    float cameraDistance = (State::getCamera()->getAbsCoor() - this->getAbsCoor()).len();
311    if (cameraDistance > 30 && this->models.size() >= 3 && this->models[2] != NULL)
312    {
313      this->models[2]->draw();
314    }
315    else if (cameraDistance > 10 && this->models.size() >= 2 && this->models[1] != NULL)
316    {
317      this->models[1]->draw();
318    }
319    else if (this->models.size() >= 1 && this->models[0] != NULL)
320    {
321      this->models[0]->draw();
322    }
323    glPopMatrix();
324  }
325}
326
327/**
328 * DEBUG-DRAW OF THE BV-Tree.
329 * @param depth What depth to draw
330 * @param drawMode the mode to draw this entity under
331 */
332void WorldEntity::drawBVTree(unsigned int depth, int drawMode) const
333{
334  glMatrixMode(GL_MODELVIEW);
335  glPushMatrix();
336  /* translate */
337  glTranslatef (this->getAbsCoor ().x,
338                this->getAbsCoor ().y,
339                this->getAbsCoor ().z);
340  /* rotate */
341  Vector tmpRot = this->getAbsDir().getSpacialAxis();
342  glRotatef (this->getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
343
344  if (this->obbTree)
345    this->obbTree->drawBV(depth, drawMode);
346  glPopMatrix();
347}
Note: See TracBrowser for help on using the repository browser.