Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/network/src/world_entities/world_entity.cc @ 6291

Last change on this file since 6291 was 6291, checked in by rennerc, 18 years ago

commit code which crashes my system so bensch can test it

File size: 9.8 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  this->objectListNumber = OM_INIT;
57  this->objectListIterator = NULL;
58
59  this->toList(OM_NULL);
60
61  modelFileName = NULL;
62}
63
64/**
65 *  standard destructor
66*/
67WorldEntity::~WorldEntity ()
68{
69  // Delete the obbTree
70  if( this->obbTree != NULL)
71    delete this->obbTree;
72
73  // Delete the model (unregister it with the ResourceManager)
74  for (unsigned int i = 0; i < this->models.size(); i++)
75    this->setModel(NULL, i);
76
77  State::getObjectManager()->toList(this, OM_INIT);
78
79  if ( modelFileName )
80  delete modelFileName;
81}
82
83/**
84 * loads the WorldEntity Specific Parameters.
85 * @param root: the XML-Element to load the Data From
86 */
87void WorldEntity::loadParams(const TiXmlElement* root)
88{
89  // Do the PNode loading stuff
90  static_cast<PNode*>(this)->loadParams(root);
91
92  // Model Loading
93  LoadParam(root, "model", this, WorldEntity, loadModel)
94      .describe("the fileName of the model, that should be loaded onto this world-entity. (must be relative to the data-dir)")
95      .defaultValues(3, NULL, 1.0f, 0);
96
97}
98
99/**
100 * loads a Model onto a WorldEntity
101 * @param fileName the name of the model to load
102 * @param scaling the Scaling of the model
103 *
104 * @todo fix this, so it only has one loadModel-Function.
105*/
106void WorldEntity::loadModel(const char* fileName, float scaling, unsigned int modelNumber)
107{
108  this->modelNumber = modelNumber;
109  this->modelScaling = scaling;
110
111  if ( fileName != NULL && strcmp(fileName, "") )
112  {
113    if ( modelFileName )
114    delete modelFileName;
115    modelFileName = new char[strlen(fileName)+1];
116    strcpy( modelFileName, fileName );
117    // search for the special character # in the LoadParam
118    if (strchr(fileName, '#') != NULL)
119      {
120        PRINTF(4)("Found # in %s... searching for LOD's\n", fileName);
121        char* lodFile = new char[strlen(fileName)+1];
122        strcpy(lodFile, fileName);
123        char* depth = strchr(lodFile, '#');
124        for (unsigned int i = 0; i < 5; i++)
125          {
126            *depth = 48+(int)i;
127            printf("-------%s\n", lodFile);
128            if (ResourceManager::isInDataDir(lodFile))
129              this->loadModel(lodFile, scaling, i);
130          }
131        return;
132      }
133
134    PRINTF(4)("fetching %s\n", fileName);
135    if (scaling == 1.0)
136      this->setModel((Model*)ResourceManager::getInstance()->load(fileName, OBJ, RP_CAMPAIGN), modelNumber);
137    else
138      this->setModel((Model*)ResourceManager::getInstance()->load(fileName, OBJ, RP_CAMPAIGN, &scaling), modelNumber);
139    if (modelNumber == 0)
140    this->buildObbTree(4);
141  }
142  else
143  {
144    if ( modelFileName )
145    delete modelFileName;
146    modelFileName = new char[1];
147    strcpy( modelFileName, "" );
148    this->setModel(NULL);
149  }
150}
151
152/**
153 * sets a specific Model for the Object.
154 * @param model The Model to set
155 * @param modelNumber the n'th model in the List to get.
156 */
157void WorldEntity::setModel(Model* model, unsigned int modelNumber)
158{
159  if (this->models.size() <= modelNumber)
160    this->models.resize(modelNumber+1, NULL);
161
162  if (this->models[modelNumber] != NULL)
163  {
164    Resource* resource = ResourceManager::getInstance()->locateResourceByPointer(this->models[modelNumber]);
165    if (resource != NULL)
166      ResourceManager::getInstance()->unload(resource, RP_LEVEL);
167    else
168      delete this->models[modelNumber];
169  }
170  this->models[modelNumber] = model;
171
172//   if (this->model != NULL)
173//     this->buildObbTree(4);
174}
175
176
177/**
178 * builds the obb-tree
179 * @param depth the depth to calculate
180 */
181bool WorldEntity::buildObbTree(unsigned int depth)
182{
183  if (this->obbTree)
184    delete this->obbTree;
185
186  if (this->models[0] != NULL)
187  {
188    PRINTF(4)("creating obb tree\n");
189
190
191    this->obbTree = new OBBTree(depth, (sVec3D*)this->models[0]->getVertexArray(), this->models[0]->getVertexCount());
192    return true;
193  }
194  else
195  {
196    PRINTF(2)("could not create obb-tree, because no model was loaded yet\n");
197    this->obbTree = NULL;
198    return false;
199  }
200}
201
202/**
203 * @brief moves this entity to the List OM_List
204 * @param list the list to set this Entity to.
205 *
206 * this is the same as a call to State::getObjectManager()->toList(entity , list);
207 * directly, but with an easier interface.
208 *
209 * @todo inline this (peut etre)
210 */
211void WorldEntity::toList(OM_LIST list)
212{
213  State::getObjectManager()->toList(this, list);
214}
215
216
217
218/**
219 * sets the character attributes of a worldentity
220 * @param character attributes
221 *
222 * these attributes don't have to be set, only use them, if you need them
223*/
224//void WorldEntity::setCharacterAttributes(CharacterAttributes* charAttr)
225//{}
226
227
228/**
229 *  this function is called, when two entities collide
230 * @param entity: the world entity with whom it collides
231 *
232 * Implement behaviour like damage application or other miscellaneous collision stuff in this function
233 */
234void WorldEntity::collidesWith(WorldEntity* entity, const Vector& location)
235{
236  /**
237   * THIS IS A DEFAULT COLLISION-Effect.
238   * IF YOU WANT TO CREATE A SPECIFIC COLLISION ON EACH OBJECT
239   * USE::
240   * if (entity->isA(CL_WHAT_YOU_ARE_LOOKING_FOR)) { printf "dothings"; };
241   *
242   * You can always define a default Action.... don't be affraid just test it :)
243   */
244//  PRINTF(3)("collision %s vs %s @ (%f,%f,%f)\n", this->getClassName(), entity->getClassName(), location.x, location.y, location.z);
245}
246
247
248/**
249 *  this is called immediately after the Entity has been constructed, initialized and then Spawned into the World
250 *
251 */
252void WorldEntity::postSpawn ()
253{
254}
255
256
257/**
258 *  this method is called by the world if the WorldEntity leaves valid gamespace
259 *
260 * For free entities this means it left the Track boundaries. With bound entities it means its Location adresses a
261 * place that is not in the world anymore. In both cases you might have to take extreme measures (a.k.a. call destroy).
262 *
263 * NOT YET IMPLEMENTED
264 */
265void WorldEntity::leftWorld ()
266{
267}
268
269
270/**
271 *  this method is called every frame
272 * @param time: the time in seconds that has passed since the last tick
273 *
274 * Handle all stuff that should update with time inside this method (movement, animation, etc.)
275*/
276void WorldEntity::tick(float time)
277{
278}
279
280
281/**
282 *  the entity is drawn onto the screen with this function
283 *
284 * This is a central function of an entity: call it to let the entity painted to the screen.
285 * Just override this function with whatever you want to be drawn.
286*/
287void WorldEntity::draw() const
288{
289  this->drawLODsafe();
290}
291
292void WorldEntity::drawLODsafe() const
293{
294  if (!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}
346
347/**
348 * Writes data from network containing information about the state
349 * @param data pointer to data
350 * @param length length of data
351 * @param sender hostID of sender
352 */
353void WorldEntity::writeState( const byte * data, int length, int sender )
354{
355  SYNCHELP_READ_BEGIN();
356  SYNCHELP_READ_STRINGM( modelFileName );
357  SYNCHELP_READ_FLOAT( modelScaling );
358  SYNCHELP_READ_INT( modelNumber );
359  loadModel( modelFileName );
360}
361
362/**
363 * data copied in data will bee sent to another host
364 * @param data pointer to data
365 * @param maxLength max length of data
366 * @return the number of bytes writen
367 */
368int WorldEntity::readState( byte * data, int maxLength )
369{
370  SYNCHELP_WRITE_BEGIN();
371  SYNCHELP_WRITE_STRING( modelFileName );
372  SYNCHELP_WRITE_FLOAT( modelScaling );
373  SYNCHELP_WRITE_INT( modelNumber );
374  return SYNCHELP_WRITE_N;
375}
Note: See TracBrowser for help on using the repository browser.