Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: merge the ObjectManager to the trunk
merged with command:
svn merge -r6082:HEAD objectmanager/ ../trunk/

conflicts resolution was easy this time :)
but specially merged the world to network_world

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