Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 10766 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
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
[9406]26
[5218]27#define QUADTREE_MATERIAL_COUNT       4
[4790]28
[9869]29ObjectListDefinition(Quadtree);
[4790]30/**
[4836]31 *  standard constructor
[4924]32 */
[5430]33Quadtree::Quadtree (const modelInfo* pModelInfo, const int treeDepth)
[4790]34{
[9869]35  this->registerObject(this, Quadtree::_objectList);
[4924]36  this->pModelInfo = pModelInfo;
37  this->treeDepth = treeDepth;
[4845]38
[4924]39  /* initialize the materials for debug draw */
[5218]40  this->materials = new Material*[QUADTREE_MATERIAL_COUNT];
41  for(int i = 0; i < QUADTREE_MATERIAL_COUNT; ++i)
[4924]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);
[4901]50
[4924]51  /* build the tree */
52  this->rootNode = new QuadtreeNode(this->pModelInfo, this, this->treeDepth);
[4901]53
[4924]54  /* make an array with access to the leafs of the Quad-Tree */
[9110]55  this->nodes = new QuadtreeNode*[(int)pow(4.0, treeDepth)];
[5215]56  int index = 0; //new int; *index = 0; // !!changed by bensch!!
[9110]57  for(int i = 0; i < (int)pow(2.0, treeDepth); ++i)
[4924]58  {
[5215]59    this->rootNode->buildHashTable(this->nodes, &index);
[4924]60  }
61  /* sort and revert the hash table to fit the right position */
62  this->sortHashTable(this->nodes);
63  this->revertHashTable(this->nodes);
[4920]64
[4924]65  /* define some important and often used variables */
66  this->quadLength = this->nodes[0]->getDimension()->getAxis() * 2.0f;
67  Rectangle* r = this->rootNode->getDimension();
[5215]68  float xOff = r->getCenter().x - r->getAxis();
69  float yOff = r->getCenter().z - r->getAxis();
[4925]70  this->offset = new Vector();
[4924]71  this->offset->x = xOff;
72  this->offset->z = yOff;
[9110]73  this->maxIndex = (int)pow(2.0, this->treeDepth);
[4790]74}
75
76
77/**
[4836]78 *  standard deconstructor
[4924]79 */
[4790]80Quadtree::~Quadtree ()
81{
82  // delete what has to be deleted here
[5218]83  if (this->materials != NULL)
84  {
85    for (unsigned int i = 0; i < QUADTREE_MATERIAL_COUNT; i++)
86      delete this->materials[i];
[5219]87    delete[] this->materials;
[5218]88  }
89
[5233]90  delete this->offset;
91
[4907]92  delete this->rootNode;
[5234]93  delete [] this->nodes;
[4790]94}
[4812]95
96
97/**
[4924]98 *  this function rotates the array and mirrors it in the middle
99 * @param nodes: the nodes to translate
[4915]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{
[9110]106  int                  len         = (int)pow(2.0, this->treeDepth);          //!< the length of a quadtree side
[4915]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
[4924]128
[4922]129/**
[4924]130 *  sorts the hash table using their positions
131 * @param nodes the nodes to use
[4922]132 */
[4920]133void Quadtree::sortHashTable(QuadtreeNode** nodes)
134{
[9110]135  int                  len         = (int)pow(2.0, this->treeDepth);          //!< the length of a quadtree side
[4922]136  float                a;                                                   //!< temp place for float a
137  float                b;                                                   //!< temp place for float b
138  QuadtreeNode*        tmpNode;                                             //!< tmp place for a QuadtreeNode
[4920]139
[4922]140  for( int i = 0; i < len; ++i)
[4920]141  {
[4922]142    for( int j = 0; j < len; ++j)
[4920]143    {
[4922]144      for( int k = j + 1; k < len; ++k)
[4920]145      {
[5215]146        a = this->nodes[i * len + j]->getDimension()->getCenter().z;
147        b = this->nodes[i * len + k]->getDimension()->getCenter().z;
[4920]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    }
[4922]157  }
[4920]158
159}
160
161
[4922]162/**
[4924]163 *  maps a position to a quadtree
164 * @param position the position so look for
165 * @return the quadtree
[4920]166
[4922]167  this function will return the quadtree that contains the position
168 */
[4956]169QuadtreeNode* Quadtree::getQuadtreeFromPosition(const Vector& position) const
[4917]170{
[4920]171  /* shift into model space */
[4922]172  Vector v = position - *this->offset;
[4920]173  /* map */
[4922]174  int i = (int)(v.x / quadLength);
175  int j = (int)(v.z / quadLength);
[4917]176
[4929]177  /* check if object is still inside the terrain - this check is not complete @todo check all 4 bounds */
[4968]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;
[4917]184}
185
186
[4915]187/**
[4929]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 */
[4956]194sTriangleExt* Quadtree::getTriangleFromPosition(const Vector& position) const
[4929]195{
196  QuadtreeNode* q = this->getQuadtreeFromPosition(position);
[4968]197
198  if( likely(q != NULL))
199    return q->getTriangle(position - *this->offset);
200  return NULL;
[4929]201}
202
203
204/**
[4836]205 *  draws the debug quadtree boxes around the model
[4812]206 */
[4922]207void Quadtree::drawTree() const
[4889]208{
[4925]209  //this->rootNode->drawTree();
[9110]210  for(int i = 0; i < (int)pow(4.0, this->treeDepth); ++i)
[4925]211  {
212    this->nodes[i]->draw();
213  }
[4889]214}
Note: See TracBrowser for help on using the repository browser.