Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/heathaze/src/lib/graphics/spatial_separation/quadtree.cc @ 10772

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

orxonox/trunk: merged the new_class_id branche back to the trunk.
merged with command:
svn merge https://svn.orxonox.net/orxonox/branches/new_class_id trunk -r9683:HEAD
no conflicts… puh..

File size: 6.0 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#include "debug.h"
25
26
27#define QUADTREE_MATERIAL_COUNT       4
28
29ObjectListDefinition(Quadtree);
30/**
31 *  standard constructor
32 */
33Quadtree::Quadtree (const modelInfo* pModelInfo, const int treeDepth)
34{
35  this->registerObject(this, Quadtree::_objectList);
36  this->pModelInfo = pModelInfo;
37  this->treeDepth = treeDepth;
38
39  /* initialize the materials for debug draw */
40  this->materials = new Material*[QUADTREE_MATERIAL_COUNT];
41  for(int i = 0; i < QUADTREE_MATERIAL_COUNT; ++i)
42  {
43    materials[i] = new Material();
44    materials[i]->setIllum(3);
45  }
46  materials[0]->setAmbient(0.0, 0.3, 0.0);
47  materials[1]->setAmbient(0.4, 0.0, 0.2);
48  materials[2]->setAmbient(1.0, 0.0, 0.0);
49  materials[3]->setAmbient(5.0, 3.0, 1.0);
50
51  /* build the tree */
52  this->rootNode = new QuadtreeNode(this->pModelInfo, this, this->treeDepth);
53
54  /* make an array with access to the leafs of the Quad-Tree */
55  this->nodes = new QuadtreeNode*[(int)pow(4.0, treeDepth)];
56  int index = 0; //new int; *index = 0; // !!changed by bensch!!
57  for(int i = 0; i < (int)pow(2.0, treeDepth); ++i)
58  {
59    this->rootNode->buildHashTable(this->nodes, &index);
60  }
61  /* sort and revert the hash table to fit the right position */
62  this->sortHashTable(this->nodes);
63  this->revertHashTable(this->nodes);
64
65  /* define some important and often used variables */
66  this->quadLength = this->nodes[0]->getDimension()->getAxis() * 2.0f;
67  Rectangle* r = this->rootNode->getDimension();
68  float xOff = r->getCenter().x - r->getAxis();
69  float yOff = r->getCenter().z - r->getAxis();
70  this->offset = new Vector();
71  this->offset->x = xOff;
72  this->offset->z = yOff;
73  this->maxIndex = (int)pow(2.0, this->treeDepth);
74}
75
76
77/**
78 *  standard deconstructor
79 */
80Quadtree::~Quadtree ()
81{
82  // delete what has to be deleted here
83  if (this->materials != NULL)
84  {
85    for (unsigned int i = 0; i < QUADTREE_MATERIAL_COUNT; i++)
86      delete this->materials[i];
87    delete[] this->materials;
88  }
89
90  delete this->offset;
91
92  delete this->rootNode;
93  delete [] this->nodes;
94}
95
96
97/**
98 *  this function rotates the array and mirrors it in the middle
99 * @param nodes: the nodes to translate
100
101  since the original matrix is counted from the right upper edge to the right lower one, we have to reorganize the elements
102  to be able to easily correlate the hashtable array indexes with the coorindates.
103 */
104void Quadtree::revertHashTable(QuadtreeNode** nodes)
105{
106  int                  len         = (int)pow(2.0, this->treeDepth);          //!< the length of a quadtree side
107  int                  iterator    = 0;                                     //!< iterator used for mapping
108  QuadtreeNode*        tmpNode     = NULL;                                  //!< temp saving place
109  int                  offset      = 0;                                     //!< offset used in the calc
110
111  for(int i = len - 1; i >= 0; --i)
112  {
113    for(int j = len - 1; j >= 0; --j)
114    {
115      offset = j * len + i;
116      /* only swap the elements in one direction */
117      if( offset > iterator)
118      {
119        tmpNode = nodes[offset];
120        nodes[offset] = nodes[iterator];
121        nodes[iterator] = tmpNode;
122      }
123      ++iterator;
124    }
125  }
126}
127
128
129/**
130 *  sorts the hash table using their positions
131 * @param nodes the nodes to use
132 */
133void Quadtree::sortHashTable(QuadtreeNode** nodes)
134{
135  int                  len         = (int)pow(2.0, this->treeDepth);          //!< the length of a quadtree side
136  float                a;                                                   //!< temp place for float a
137  float                b;                                                   //!< temp place for float b
138  QuadtreeNode*        tmpNode;                                             //!< tmp place for a QuadtreeNode
139
140  for( int i = 0; i < len; ++i)
141  {
142    for( int j = 0; j < len; ++j)
143    {
144      for( int k = j + 1; k < len; ++k)
145      {
146        a = this->nodes[i * len + j]->getDimension()->getCenter().z;
147        b = this->nodes[i * len + k]->getDimension()->getCenter().z;
148
149        if( b > a)
150        {
151          tmpNode = this->nodes[i * len + j];
152          this->nodes[i * len + j] = this->nodes[i * len + k];
153          this->nodes[i * len + k] = tmpNode;
154        }
155      }
156    }
157  }
158
159}
160
161
162/**
163 *  maps a position to a quadtree
164 * @param position the position so look for
165 * @return the quadtree
166
167  this function will return the quadtree that contains the position
168 */
169QuadtreeNode* Quadtree::getQuadtreeFromPosition(const Vector& position) const
170{
171  /* shift into model space */
172  Vector v = position - *this->offset;
173  /* map */
174  int i = (int)(v.x / quadLength);
175  int j = (int)(v.z / quadLength);
176
177  /* check if object is still inside the terrain - this check is not complete @todo check all 4 bounds */
178  if( i < this->maxIndex && j < this->maxIndex && i >= 0 && j >= 0)
179    return this->nodes[i + j * this->maxIndex];
180
181
182  PRINTF(4)("Object has left terrain\n");
183  return NULL;
184}
185
186
187/**
188 *  maps a position to a triangle
189 * @param position the position so look for
190 * @return the triangle
191
192  this function will return the quadtree that contains the position
193 */
194sTriangleExt* Quadtree::getTriangleFromPosition(const Vector& position) const
195{
196  QuadtreeNode* q = this->getQuadtreeFromPosition(position);
197
198  if( likely(q != NULL))
199    return q->getTriangle(position - *this->offset);
200  return NULL;
201}
202
203
204/**
205 *  draws the debug quadtree boxes around the model
206 */
207void Quadtree::drawTree() const
208{
209  //this->rootNode->drawTree();
210  for(int i = 0; i < (int)pow(4.0, this->treeDepth); ++i)
211  {
212    this->nodes[i]->draw();
213  }
214}
Note: See TracBrowser for help on using the repository browser.