Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 4924 was 4924, checked in by patrick, 19 years ago

orxonox/trunk: the last cleanups, now the classes look better

File size: 5.2 KB
Line 
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
11### File Specific:
12   main-programmer: Patrick Boenzli
13   co-programmer: ...
14*/
15
16#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_SPATIAL_SEPARATION
17
18#include "quadtree.h"
19
20#include "quadtree_node.h"
21#include "vector.h"
22
23#include "material.h"
24
25
26using namespace std;
27
28
29/**
30 *  standard constructor
31 */
32Quadtree::Quadtree (modelInfo* pModelInfo, const int treeDepth)
33{
34  this->setClassID(CL_QUADTREE, "Quadtree");
35  this->pModelInfo = pModelInfo;
36  this->treeDepth = treeDepth;
37
38  /* initialize the materials for debug draw */
39  this->materials = new Material*[4];
40  for(int i = 0; i < 4; ++i)
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);
49
50  /* build the tree */
51  this->rootNode = new QuadtreeNode(this->pModelInfo, this, this->treeDepth);
52
53  /* make an array with access to the leafs of the Quad-Tree */
54  this->nodes = new QuadtreeNode*[(int)pow(4, treeDepth)];
55  int* index = new int; *index = 0;
56  for(int i = 0; i < (int)pow(2, treeDepth); ++i)
57  {
58    this->rootNode->buildHashTable(this->nodes, index);
59  }
60  /* sort and revert the hash table to fit the right position */
61  this->sortHashTable(this->nodes);
62  this->revertHashTable(this->nodes);
63
64  /* define some important and often used variables */
65  this->quadLength = this->nodes[0]->getDimension()->getAxis() * 2.0f;
66  Rectangle* r = this->rootNode->getDimension();
67  Vector* offset = new Vector();
68  float xOff = r->getCenter()->x - r->getAxis();
69  float yOff = r->getCenter()->z - r->getAxis();
70  this->offset->x = xOff;
71  this->offset->z = yOff;
72  this->maxIndex = (int)pow(2, this->treeDepth);
73}
74
75
76/**
77 *  standard deconstructor
78 */
79Quadtree::~Quadtree ()
80{
81  // delete what has to be deleted here
82  delete [] this->nodes;
83  delete this->rootNode;
84  delete offset;
85}
86
87
88/**
89 *  this function rotates the array and mirrors it in the middle
90 * @param nodes: the nodes to translate
91
92  since the original matrix is counted from the right upper edge to the right lower one, we have to reorganize the elements
93  to be able to easily correlate the hashtable array indexes with the coorindates.
94 */
95void Quadtree::revertHashTable(QuadtreeNode** nodes)
96{
97  int                  len         = (int)pow(2, this->treeDepth);          //!< the length of a quadtree side
98  int                  iterator    = 0;                                     //!< iterator used for mapping
99  QuadtreeNode*        tmpNode     = NULL;                                  //!< temp saving place
100  int                  offset      = 0;                                     //!< offset used in the calc
101
102  for(int i = len - 1; i >= 0; --i)
103  {
104    for(int j = len - 1; j >= 0; --j)
105    {
106      offset = j * len + i;
107      /* only swap the elements in one direction */
108      if( offset > iterator)
109      {
110        tmpNode = nodes[offset];
111        nodes[offset] = nodes[iterator];
112        nodes[iterator] = tmpNode;
113      }
114      ++iterator;
115    }
116  }
117}
118
119
120/**
121 *  sorts the hash table using their positions
122 * @param nodes the nodes to use
123 */
124void Quadtree::sortHashTable(QuadtreeNode** nodes)
125{
126  int                  len         = (int)pow(2, this->treeDepth);          //!< the length of a quadtree side
127  float                a;                                                   //!< temp place for float a
128  float                b;                                                   //!< temp place for float b
129  QuadtreeNode*        tmpNode;                                             //!< tmp place for a QuadtreeNode
130
131  for( int i = 0; i < len; ++i)
132  {
133    for( int j = 0; j < len; ++j)
134    {
135      for( int k = j + 1; k < len; ++k)
136      {
137        a = this->nodes[i * len + j]->getDimension()->getCenter()->z;
138        b = this->nodes[i * len + k]->getDimension()->getCenter()->z;
139
140        if( b > a)
141        {
142          tmpNode = this->nodes[i * len + j];
143          this->nodes[i * len + j] = this->nodes[i * len + k];
144          this->nodes[i * len + k] = tmpNode;
145        }
146      }
147    }
148  }
149
150}
151
152
153/**
154 *  maps a position to a quadtree
155 * @param position the position so look for
156 * @return the quadtree
157
158  this function will return the quadtree that contains the position
159 */
160QuadtreeNode* Quadtree::getQuadtreeFromPosition(const Vector& position)
161{
162  /* shift into model space */
163  Vector v = position - *this->offset;
164  /* map */
165  int i = (int)(v.x / quadLength);
166  int j = (int)(v.z / quadLength);
167
168  /* check if object is still inside the terrain */
169  if( i < this->maxIndex && j < this->maxIndex)
170    this->nodes[i + j * this->maxIndex]->includesPoint(position);
171  else
172    PRINTF(0)("Object has left terrain\n");
173}
174
175
176/**
177 *  draws the debug quadtree boxes around the model
178 */
179void Quadtree::drawTree() const
180{
181  this->rootNode->drawTree();
182//   for(int i = 0; i < (int)pow(4, this->treeDepth); ++i)
183//   {
184//     this->nodes[i]->draw();
185//   }
186}
Note: See TracBrowser for help on using the repository browser.