Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/lib/graphics/spatial_separation/quadtree.cc @ 9370

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

orxonox/trunk: merged the Presentation back

File size: 6.0 KB
RevLine 
[4790]1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
[4924]11### File Specific:
[4790]12   main-programmer: Patrick Boenzli
13   co-programmer: ...
14*/
15
[4808]16#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_SPATIAL_SEPARATION
[4790]17
18#include "quadtree.h"
[4923]19
[4845]20#include "quadtree_node.h"
[4917]21#include "vector.h"
[4790]22
[4924]23#include "material.h"
[5075]24#include "debug.h"
[4924]25
[4790]26using namespace std;
[5218]27#define QUADTREE_MATERIAL_COUNT       4
[4790]28
29/**
[4836]30 *  standard constructor
[4924]31 */
[5430]32Quadtree::Quadtree (const modelInfo* pModelInfo, const int treeDepth)
[4790]33{
[4924]34  this->setClassID(CL_QUADTREE, "Quadtree");
35  this->pModelInfo = pModelInfo;
36  this->treeDepth = treeDepth;
[4845]37
[4924]38  /* initialize the materials for debug draw */
[5218]39  this->materials = new Material*[QUADTREE_MATERIAL_COUNT];
40  for(int i = 0; i < QUADTREE_MATERIAL_COUNT; ++i)
[4924]41  {
42    materials[i] = new Material();
43    materials[i]->setIllum(3);
44  }
45  materials[0]->setAmbient(0.0, 0.3, 0.0);
46  materials[1]->setAmbient(0.4, 0.0, 0.2);
47  materials[2]->setAmbient(1.0, 0.0, 0.0);
48  materials[3]->setAmbient(5.0, 3.0, 1.0);
[4901]49
[4924]50  /* build the tree */
51  this->rootNode = new QuadtreeNode(this->pModelInfo, this, this->treeDepth);
[4901]52
[4924]53  /* make an array with access to the leafs of the Quad-Tree */
[9110]54  this->nodes = new QuadtreeNode*[(int)pow(4.0, treeDepth)];
[5215]55  int index = 0; //new int; *index = 0; // !!changed by bensch!!
[9110]56  for(int i = 0; i < (int)pow(2.0, treeDepth); ++i)
[4924]57  {
[5215]58    this->rootNode->buildHashTable(this->nodes, &index);
[4924]59  }
60  /* sort and revert the hash table to fit the right position */
61  this->sortHashTable(this->nodes);
62  this->revertHashTable(this->nodes);
[4920]63
[4924]64  /* define some important and often used variables */
65  this->quadLength = this->nodes[0]->getDimension()->getAxis() * 2.0f;
66  Rectangle* r = this->rootNode->getDimension();
[5215]67  float xOff = r->getCenter().x - r->getAxis();
68  float yOff = r->getCenter().z - r->getAxis();
[4925]69  this->offset = new Vector();
[4924]70  this->offset->x = xOff;
71  this->offset->z = yOff;
[9110]72  this->maxIndex = (int)pow(2.0, this->treeDepth);
[4790]73}
74
75
76/**
[4836]77 *  standard deconstructor
[4924]78 */
[4790]79Quadtree::~Quadtree ()
80{
81  // delete what has to be deleted here
[5218]82  if (this->materials != NULL)
83  {
84    for (unsigned int i = 0; i < QUADTREE_MATERIAL_COUNT; i++)
85      delete this->materials[i];
[5219]86    delete[] this->materials;
[5218]87  }
88
[5233]89  delete this->offset;
90
[4907]91  delete this->rootNode;
[5234]92  delete [] this->nodes;
[4790]93}
[4812]94
95
96/**
[4924]97 *  this function rotates the array and mirrors it in the middle
98 * @param nodes: the nodes to translate
[4915]99
100  since the original matrix is counted from the right upper edge to the right lower one, we have to reorganize the elements
101  to be able to easily correlate the hashtable array indexes with the coorindates.
102 */
103void Quadtree::revertHashTable(QuadtreeNode** nodes)
104{
[9110]105  int                  len         = (int)pow(2.0, this->treeDepth);          //!< the length of a quadtree side
[4915]106  int                  iterator    = 0;                                     //!< iterator used for mapping
107  QuadtreeNode*        tmpNode     = NULL;                                  //!< temp saving place
108  int                  offset      = 0;                                     //!< offset used in the calc
109
110  for(int i = len - 1; i >= 0; --i)
111  {
112    for(int j = len - 1; j >= 0; --j)
113    {
114      offset = j * len + i;
115      /* only swap the elements in one direction */
116      if( offset > iterator)
117      {
118        tmpNode = nodes[offset];
119        nodes[offset] = nodes[iterator];
120        nodes[iterator] = tmpNode;
121      }
122      ++iterator;
123    }
124  }
125}
126
[4924]127
[4922]128/**
[4924]129 *  sorts the hash table using their positions
130 * @param nodes the nodes to use
[4922]131 */
[4920]132void Quadtree::sortHashTable(QuadtreeNode** nodes)
133{
[9110]134  int                  len         = (int)pow(2.0, this->treeDepth);          //!< the length of a quadtree side
[4922]135  float                a;                                                   //!< temp place for float a
136  float                b;                                                   //!< temp place for float b
137  QuadtreeNode*        tmpNode;                                             //!< tmp place for a QuadtreeNode
[4920]138
[4922]139  for( int i = 0; i < len; ++i)
[4920]140  {
[4922]141    for( int j = 0; j < len; ++j)
[4920]142    {
[4922]143      for( int k = j + 1; k < len; ++k)
[4920]144      {
[5215]145        a = this->nodes[i * len + j]->getDimension()->getCenter().z;
146        b = this->nodes[i * len + k]->getDimension()->getCenter().z;
[4920]147
148        if( b > a)
149        {
150          tmpNode = this->nodes[i * len + j];
151          this->nodes[i * len + j] = this->nodes[i * len + k];
152          this->nodes[i * len + k] = tmpNode;
153        }
154      }
155    }
[4922]156  }
[4920]157
158}
159
160
[4922]161/**
[4924]162 *  maps a position to a quadtree
163 * @param position the position so look for
164 * @return the quadtree
[4920]165
[4922]166  this function will return the quadtree that contains the position
167 */
[4956]168QuadtreeNode* Quadtree::getQuadtreeFromPosition(const Vector& position) const
[4917]169{
[4920]170  /* shift into model space */
[4922]171  Vector v = position - *this->offset;
[4920]172  /* map */
[4922]173  int i = (int)(v.x / quadLength);
174  int j = (int)(v.z / quadLength);
[4917]175
[4929]176  /* check if object is still inside the terrain - this check is not complete @todo check all 4 bounds */
[4968]177  if( i < this->maxIndex && j < this->maxIndex && i >= 0 && j >= 0)
178    return this->nodes[i + j * this->maxIndex];
179
180
181  PRINTF(4)("Object has left terrain\n");
182  return NULL;
[4917]183}
184
185
[4915]186/**
[4929]187 *  maps a position to a triangle
188 * @param position the position so look for
189 * @return the triangle
190
191  this function will return the quadtree that contains the position
192 */
[4956]193sTriangleExt* Quadtree::getTriangleFromPosition(const Vector& position) const
[4929]194{
195  QuadtreeNode* q = this->getQuadtreeFromPosition(position);
[4968]196
197  if( likely(q != NULL))
198    return q->getTriangle(position - *this->offset);
199  return NULL;
[4929]200}
201
202
203/**
[4836]204 *  draws the debug quadtree boxes around the model
[4812]205 */
[4922]206void Quadtree::drawTree() const
[4889]207{
[4925]208  //this->rootNode->drawTree();
[9110]209  for(int i = 0; i < (int)pow(4.0, this->treeDepth); ++i)
[4925]210  {
211    this->nodes[i]->draw();
212  }
[4889]213}
Note: See TracBrowser for help on using the repository browser.