Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/world_entities/world_entity.cc @ 6002

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

orxonox/trunk: implemented the helicopter

File size: 7.6 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 "resource_manager.h"
24#include "load_param.h"
25#include "list.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
57/**
58 *  standard destructor
59*/
60WorldEntity::~WorldEntity ()
61{
62  // Delete the obbTree
63  if( this->obbTree != NULL)
64    delete this->obbTree;
65
66  // Delete the model (unregister it with the ResourceManager)
67  this->setModel(NULL);
68}
69
70/**
71 * loads the WorldEntity Specific Parameters.
72 * @param root: the XML-Element to load the Data From
73 */
74void WorldEntity::loadParams(const TiXmlElement* root)
75{
76  // Do the PNode loading stuff
77  static_cast<PNode*>(this)->loadParams(root);
78
79  // Model Loading
80  LoadParam(root, "model", this, WorldEntity, loadModel)
81      .describe("the fileName of the model, that should be loaded onto this world-entity. (must be relative to the data-dir)")
82      .defaultValues(3, NULL, 1.0f, 0);
83
84}
85
86/**
87 * loads a Model onto a WorldEntity
88 * @param fileName the name of the model to load
89 * @param scaling the Scaling of the model
90 *
91 * @todo fix this, so it only has one loadModel-Function.
92*/
93void WorldEntity::loadModel(const char* fileName, float scaling, unsigned int modelNumber)
94{
95  if (fileName != NULL)
96  {
97    PRINTF(4)("fetching %s\n", fileName);
98    if (scaling == 1.0)
99      this->setModel((Model*)ResourceManager::getInstance()->load(fileName, OBJ, RP_CAMPAIGN), modelNumber);
100    else
101      this->setModel((Model*)ResourceManager::getInstance()->load(fileName, OBJ, RP_CAMPAIGN, &scaling), modelNumber);
102    if (modelNumber == 0)
103    this->buildObbTree(4);
104  }
105  else
106    this->setModel(NULL);
107}
108
109/**
110 * sets a specific Model for the Object.
111 * @param model The Model to set
112 * @param modelNumber the n'th model in the List to get.
113 */
114void WorldEntity::setModel(Model* model, unsigned int modelNumber)
115{
116  if (this->models.size() <= modelNumber)
117    this->models.resize(modelNumber+1, NULL);
118
119  if (this->models[modelNumber] != NULL)
120  { 
121    Resource* resource = ResourceManager::getInstance()->locateResourceByPointer(this->models[modelNumber]);
122    if (resource != NULL)
123      ResourceManager::getInstance()->unload(resource, RP_LEVEL);
124    else
125      delete this->models[modelNumber];
126  }
127  this->models[modelNumber] = model;
128
129//   if (this->model != NULL) 
130//     this->buildObbTree(4);
131}
132
133
134/**
135 * builds the obb-tree
136 * @param depth the depth to calculate
137 */
138bool WorldEntity::buildObbTree(unsigned int depth)
139{
140  if (this->obbTree)
141    delete this->obbTree;
142
143  if (this->models[0] != NULL)
144  {
145    PRINTF(4)("creating obb tree\n");
146
147
148    this->obbTree = new OBBTree(depth, (sVec3D*)this->models[0]->getVertexArray(), this->models[0]->getVertexCount());
149    return true;
150  }
151  else
152  {
153    PRINTF(2)("could not create obb-tree, because no model was loaded yet\n");
154    this->obbTree = NULL;
155    return false;
156  }
157}
158
159
160/**
161 * sets the character attributes of a worldentity
162 * @param character attributes
163 *
164 * these attributes don't have to be set, only use them, if you need them
165*/
166//void WorldEntity::setCharacterAttributes(CharacterAttributes* charAttr)
167//{}
168
169
170/**
171 *  this function is called, when two entities collide
172 * @param entity: the world entity with whom it collides
173 *
174 * Implement behaviour like damage application or other miscellaneous collision stuff in this function
175 */
176void WorldEntity::collidesWith(WorldEntity* entity, const Vector& location)
177{
178  /**
179   * THIS IS A DEFAULT COLLISION-Effect.
180   * IF YOU WANT TO CREATE A SPECIFIC COLLISION ON EACH OBJECT
181   * USE::
182   * if (entity->isA(CL_WHAT_YOU_ARE_LOOKING_FOR)) { printf "dothings"; };
183   *
184   * You can always define a default Action.... don't be affraid just test it :)
185   */
186//  PRINTF(3)("collision %s vs %s @ (%f,%f,%f)\n", this->getClassName(), entity->getClassName(), location.x, location.y, location.z);
187}
188
189
190/**
191 *  this is called immediately after the Entity has been constructed, initialized and then Spawned into the World
192 *
193 */
194void WorldEntity::postSpawn ()
195{
196}
197
198
199/**
200 *  this method is called by the world if the WorldEntity leaves valid gamespace
201 *
202 * For free entities this means it left the Track boundaries. With bound entities it means its Location adresses a
203 * place that is not in the world anymore. In both cases you might have to take extreme measures (a.k.a. call destroy).
204 *
205 * NOT YET IMPLEMENTED
206 */
207void WorldEntity::leftWorld ()
208{
209}
210
211
212/**
213 *  this method is called every frame
214 * @param time: the time in seconds that has passed since the last tick
215 *
216 * Handle all stuff that should update with time inside this method (movement, animation, etc.)
217*/
218void WorldEntity::tick(float time)
219{
220}
221
222
223/**
224 *  the entity is drawn onto the screen with this function
225 *
226 * This is a central function of an entity: call it to let the entity painted to the screen.
227 * Just override this function with whatever you want to be drawn.
228*/
229void WorldEntity::draw() const
230{
231  if (!this->models.empty())
232  {
233    glMatrixMode(GL_MODELVIEW);
234    glPushMatrix();
235    float matrix[4][4];
236
237    /* translate */
238    glTranslatef (this->getAbsCoor ().x,
239                  this->getAbsCoor ().y,
240                  this->getAbsCoor ().z);
241   /* rotate */ // FIXME: devise a new Way to rotate this
242    this->getAbsDir ().matrix (matrix);
243    glMultMatrixf((float*)matrix);
244
245    float cameraDistance = (State::getCamera()->getAbsCoor() - this->getAbsCoor()).len();
246    if (this->isA(CL_HELICOPTER))
247        printf("Test %f %d\n", cameraDistance, this->models.size());
248    if (cameraDistance > 100 && this->models.size() >= 3 && this->models[2] != NULL)
249    {
250      if (this->isA(CL_HELICOPTER))printf("====== 2 ===\n");
251       this->models[2]->draw();
252    } 
253    else if (cameraDistance > 50 && this->models.size() >= 2 && this->models[1] != NULL)
254    {
255      if (this->isA(CL_HELICOPTER))printf("====== 1 ===\n");
256      this->models[1]->draw();
257    } 
258    else if (this->models.size() >= 1 && this->models[0] != NULL) 
259    {
260      if (this->isA(CL_HELICOPTER))printf("====== 0 ===\n");
261      this->models[0]->draw();
262    }
263    glPopMatrix();
264  }
265}
266
267/**
268 * DEBUG-DRAW OF THE BV-Tree.
269 * @param depth What depth to draw
270 * @param drawMode the mode to draw this entity under
271 */
272void WorldEntity::drawBVTree(unsigned int depth, int drawMode) const
273{
274  glMatrixMode(GL_MODELVIEW);
275  glPushMatrix();
276  /* translate */
277  glTranslatef (this->getAbsCoor ().x,
278                this->getAbsCoor ().y,
279                this->getAbsCoor ().z);
280  /* rotate */
281  Vector tmpRot = this->getAbsDir().getSpacialAxis();
282  glRotatef (this->getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
283
284  if (this->obbTree)
285    this->obbTree->drawBV(depth, drawMode);
286  glPopMatrix();
287}
Note: See TracBrowser for help on using the repository browser.