Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 6187 was 6187, checked in by bensch, 18 years ago

branches/christmas removed many include 'list.h'

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