Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/old.we/src/lib/collision_detection/obb_tree_node.cc @ 5828

Last change on this file since 5828 was 5511, checked in by bensch, 19 years ago

orxonox/trunk: more cleanup of the WorldEntity (includes rearanged)

File size: 37.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_COLLISION
17
18#include "obb_tree_node.h"
19#include "list.h"
20#include "obb.h"
21#include "obb_tree.h"
22#include "vector.h"
23#include "abstract_model.h"
24#include "world_entity.h"
25
26#include <math.h>
27#include "color.h"
28
29#include "debug.h"
30#include "stdincl.h"
31#include "lin_alg.h"
32#include "glincl.h"
33
34
35
36using namespace std;
37
38OBBTree*  OBBTreeNode::obbTree = NULL;
39
40float**  OBBTreeNode::coMat = NULL;
41float**  OBBTreeNode::eigvMat = NULL;
42float*   OBBTreeNode::eigvlMat = NULL;
43int*     OBBTreeNode::rotCount = NULL;
44GLUquadricObj* OBBTreeNode_sphereObj = NULL;
45
46/**
47 *  standard constructor
48 */
49OBBTreeNode::OBBTreeNode ()
50{
51  this->setClassID(CL_OBB_TREE_NODE, "OBBTreeNode");
52  this->nodeLeft = NULL;
53  this->nodeRight = NULL;
54  this->bvElement = NULL;
55
56  if(OBBTreeNode::coMat == NULL)
57  {
58    OBBTreeNode::coMat = new float*[4];
59    for(int i = 0; i < 4; i++)
60      OBBTreeNode::coMat[i] = new float[4];
61  }
62  if(OBBTreeNode::eigvMat == NULL)
63  {
64    OBBTreeNode::eigvMat = new float*[4];
65    for(int i = 0; i < 4; i++)
66      OBBTreeNode::eigvMat[i] = new float[4];
67  }
68  if( OBBTreeNode::eigvlMat == NULL)
69  {
70    OBBTreeNode::eigvlMat = new float[4];
71  }
72  if( OBBTreeNode::rotCount == NULL)
73    OBBTreeNode::rotCount = new int;
74
75  if (OBBTreeNode_sphereObj == NULL)
76    OBBTreeNode_sphereObj = gluNewQuadric();
77}
78
79
80/**
81 *  standard deconstructor
82 */
83OBBTreeNode::~OBBTreeNode ()
84{
85  if( this->nodeLeft)
86  {
87    delete this->nodeLeft;
88    this->nodeLeft = NULL;
89  }
90  if( this->nodeRight)
91  {
92    delete this->nodeRight;
93    this->nodeRight = NULL;
94  }
95  if( this->bvElement)
96    delete this->bvElement;
97  this->bvElement = NULL;
98}
99
100
101
102/**
103 *  creates a new BVTree or BVTree partition
104 * @param depth: how much more depth-steps to go: if == 1 don't go any deeper!
105 * @param verticesList: the list of vertices of the object - each vertices triple is interpreted as a triangle
106 */
107void OBBTreeNode::spawnBVTree(const int depth, sVec3D *verticesList, const int length)
108{
109  PRINT(3)("\n");
110  this->treeIndex = this->obbTree->getID();
111  PRINTF(3)("OBB Depth: %i, tree index: %i, numVertices: %i\n", depth, treeIndex, length);
112  this->depth = depth;
113
114
115  this->bvElement = new OBB();
116  this->bvElement->vertices = verticesList;
117  this->bvElement->numOfVertices = length;
118  PRINTF(3)("Created OBBox\n");
119  this->calculateBoxCovariance(this->bvElement, verticesList, length);
120  PRINTF(3)("Calculated attributes1\n");
121  this->calculateBoxEigenvectors(this->bvElement, verticesList, length);
122  PRINTF(3)("Calculated attributes2\n");
123  this->calculateBoxAxis(this->bvElement, verticesList, length);
124  PRINTF(3)("Calculated attributes3\n");
125
126  /* if this is the first node, the vertices data are the original ones of the model itself, so dont delete them in cleanup */
127  if( this->treeIndex == 1)
128    this->bvElement->bOrigVertices = true;
129
130  if( likely( this->depth > 0))
131  {
132    this->forkBox(this->bvElement);
133
134
135    if(this->tmpLen1 > 2)
136    {
137      OBBTreeNode* node1 = new OBBTreeNode();
138      this->nodeLeft = node1;
139      this->nodeLeft->spawnBVTree(depth - 1, this->tmpVert1, this->tmpLen1);
140    }
141    else
142    {
143      PRINTF(3)("Aboarding tree walk: less than 3 vertices left\n");
144    }
145
146    if( this->tmpLen2 > 2)
147    {
148      OBBTreeNode* node2 = new OBBTreeNode();
149      this->nodeRight = node2;
150      this->nodeRight->spawnBVTree(depth - 1, this->tmpVert2, this->tmpLen2);
151    }
152    else
153    {
154      PRINTF(3)("Abording tree walk: less than 3 vertices left\n");
155    }
156
157  }
158}
159
160
161
162void OBBTreeNode::calculateBoxCovariance(OBB* box, sVec3D* verticesList, int length)
163{
164  float     facelet[length];                         //!< surface area of the i'th triangle of the convex hull
165  float     face = 0.0f;                             //!< surface area of the entire convex hull
166  Vector    centroid[length];                        //!< centroid of the i'th convex hull
167  Vector    center;                                  //!< the center of the entire hull
168  Vector    p, q, r;                                 //!< holder of the polygon data, much more conveniant to work with Vector than sVec3d
169  Vector    t1, t2;                                  //!< temporary values
170  float     covariance[3][3];                        //!< the covariance matrix
171  int       mode = 0;                                //!< mode = 0: vertex soup, no connections, mode = 1: 3 following verteces build a triangle
172
173  this->numOfVertices = length;
174  this->vertices = verticesList;
175
176
177  if( likely(mode == 0))
178  {
179    /* fist compute all the convex hull face/facelets and centroids */
180    for( int i = 0; i+3 < length ; i+=3)          /* FIX-ME-QUICK: hops of 3, array indiscontinuity*/
181    {
182      p = verticesList[i];
183      q = verticesList[i + 1];
184      r = verticesList[i + 2];
185
186      t1 = p - q; t2 = p - r;
187
188      /* finding the facelet surface via cross-product */
189      facelet[i] = 0.5f * fabs( t1.cross(t2).len() );
190      /* update the entire convex hull surface */
191      face += facelet[i];
192
193      /* calculate the cetroid of the hull triangles */
194      centroid[i] = (p + q + r) * 1/3;
195      /* now calculate the centroid of the entire convex hull, weighted average of triangle centroids */
196      center += centroid[i] * facelet[i];
197    }
198    /* take the average of the centroid sum */
199    center /= face;
200    PRINTF(3)("-- Calculated Center\n");
201
202
203    /* now calculate the covariance matrix - if not written in three for-loops, it would compute faster: minor */
204    for( int j = 0; j < 3; ++j)
205    {
206      for( int k = 0; k < 3; ++k)
207      {
208        for( int i = 0; i + 3 < length; i+=3)
209        {
210          p = verticesList[i];
211          q = verticesList[i + 1];
212          r = verticesList[i + 2];
213
214          covariance[j][k] = facelet[i] / (12.0f * face) * (9.0f * centroid[i][j] * centroid[i][k] + p[j] * p[k] +
215              q[j] * q[k] + r[j] * r[k]) - center[j] * center[k];
216        }
217      }
218    }
219    PRINTF(3)("-- Calculated Covariance\n");
220  }
221  else if( mode == 1)
222  {
223    for( int i = 0; i + 3 < length; i+=3)          /* FIX-ME-QUICK: hops of 3, array indiscontinuity*/
224    {
225      p = verticesList[i];
226      q = verticesList[i + 1];
227      r = verticesList[i + 2];
228
229      centroid[i] = (p + q + r) / 3.0f;
230      center += centroid[i];
231    }
232    center /= length;
233
234    for( int j = 0; j < 3; ++j)
235    {
236      for( int k = 0; k < 3; ++k)
237      {
238        for( int i = 0; i + 3 < length; i+=3)
239        {
240          p = verticesList[i];
241          q = verticesList[i +1];
242          r = verticesList[i + 2];
243
244          covariance[j][k] = p[j] * p[k] + q[j] * q[k] + r[j] + r[k];
245        }
246        covariance[j][k] /= (3.0f * length);
247      }
248    }
249    PRINTF(3)("-- Calculated Covariance\n");
250  }
251  else if( mode == 2)
252  {
253    /* fist compute all the convex hull face/facelets and centroids */
254    for(int i = 0; i + 3 < length; i+=3)          /* FIX-ME-QUICK: hops of 3, array indiscontinuity*/
255    {
256      p = verticesList[i];
257      q = verticesList[i + 1];
258      r = verticesList[i + 2];
259
260      t1 = p - q; t2 = p - r;
261
262      /* finding the facelet surface via cross-product */
263      facelet[i] = 0.5f * fabs( t1.cross(t2).len() );
264      /* update the entire convex hull surface */
265      face += facelet[i];
266
267      /* calculate the cetroid of the hull triangles */
268      centroid[i] = (p + q + r) * 1/3;
269      /* now calculate the centroid of the entire convex hull, weighted average of triangle centroids */
270      center += centroid[i] * facelet[i];
271    }
272    /* take the average of the centroid sum */
273    center /= face;
274    PRINTF(3)("-- Calculated Center\n");
275
276    for( int j = 0; j < 3; ++j)
277    {
278      for( int k = 0; k < 3; ++k)
279      {
280        for( int i = 0; i + 3 < length; i+=3)
281        {
282          p = verticesList[i];
283          q = verticesList[i +1];
284          r = verticesList[i + 2];
285
286          covariance[j][k] = p[j] * p[k] + q[j] * q[k] + r[j] + r[k];
287        }
288        covariance[j][k] /= (3.0f * length);
289      }
290    }
291    PRINTF(3)("-- Calculated Covariance\n");
292  }
293  else
294  {
295    for( int i = 0; i < length; ++i)          /* FIX-ME-QUICK: hops of 3, array indiscontinuity*/
296    {
297      center += verticesList[i];
298    }
299    center /= length;
300
301    for( int j = 0; j < 3; ++j)
302    {
303      for( int k = 0; k < 3; ++k)
304      {
305        for( int i = 0; i + 3 < length; i+=3)
306        {
307          p = verticesList[i];
308          q = verticesList[i +1];
309          r = verticesList[i + 2];
310
311          covariance[j][k] = p[j] * p[k] + q[j] * q[k] + r[j] + r[k];
312        }
313        covariance[j][k] /= (3.0f * length);
314      }
315    }
316    PRINTF(3)("-- Calculated Covariance\n");
317  }
318
319  PRINTF(3)("\nVertex Data:\n");
320  for(int i = 0; i < length; i++)
321  {
322    PRINTF(3)("vertex %i: %f, %f, %f\n", i, box->vertices[i][0], box->vertices[i][1], box->vertices[i][2]);
323  }
324
325
326  PRINTF(3)("\nCovariance Matrix:\n");
327  for(int j = 0; j < 3; ++j)
328  {
329    PRINT(3)(" |");
330    for(int k = 0; k < 3; ++k)
331    {
332      PRINT(3)(" \b%f ", covariance[j][k]);
333    }
334    PRINT(3)(" |\n");
335  }
336
337  PRINTF(3)("center: %f, %f, %f\n", center.x, center.y, center.z);
338
339
340  for(int i = 0; i < 3; ++i)
341  {
342    box->covarianceMatrix[i][0] = covariance[i][0];
343    box->covarianceMatrix[i][1] = covariance[i][1];
344    box->covarianceMatrix[i][2] = covariance[i][2];
345  }
346  *box->center = center;
347  PRINTF(3)("-- Written Result to obb\n");
348}
349
350
351
352void OBBTreeNode::calculateBoxEigenvectors(OBB* box, sVec3D* verticesList, int length)
353{
354
355  /* now getting spanning vectors of the sub-space:
356  the eigenvectors of a symmertric matrix, such as the
357  covarience matrix are mutually orthogonal.
358  after normalizing them, they can be used as a the basis
359  vectors
360  */
361  Vector*              axis = new Vector[3];                //!< the references to the obb axis
362
363  OBBTreeNode::coMat[0][0] = box->covarianceMatrix[0][0];
364  OBBTreeNode::coMat[0][1] = box->covarianceMatrix[0][1];
365  OBBTreeNode::coMat[0][2] = box->covarianceMatrix[0][2];
366
367  OBBTreeNode::coMat[1][0] = box->covarianceMatrix[1][0];
368  OBBTreeNode::coMat[1][1] = box->covarianceMatrix[1][1];
369  OBBTreeNode::coMat[1][2] = box->covarianceMatrix[1][2];
370
371  OBBTreeNode::coMat[2][0] = box->covarianceMatrix[2][0];
372  OBBTreeNode::coMat[2][1] = box->covarianceMatrix[2][1];
373  OBBTreeNode::coMat[2][2] = box->covarianceMatrix[2][2];
374
375
376//   OBBTreeNode::coMat[0][0] = 1;
377//   OBBTreeNode::coMat[0][1] = 2;
378//   OBBTreeNode::coMat[0][2] = 7;
379//
380//   OBBTreeNode::coMat[1][0] = 2;
381//   OBBTreeNode::coMat[1][1] = 5;
382//   OBBTreeNode::coMat[1][2] = 5;
383//
384//   OBBTreeNode::coMat[2][0] = 7;
385//   OBBTreeNode::coMat[2][1] = 5;
386//   OBBTreeNode::coMat[2][2] = 8;
387
388//   OBBTreeNode::coMat[1][1] = box->covarianceMatrix[0][0];
389//   OBBTreeNode::coMat[1][2] = box->covarianceMatrix[0][1];
390//   OBBTreeNode::coMat[1][3] = box->covarianceMatrix[0][2];
391//
392//   OBBTreeNode::coMat[2][1] = box->covarianceMatrix[1][0];
393//   OBBTreeNode::coMat[2][2] = box->covarianceMatrix[1][1];
394//   OBBTreeNode::coMat[2][3] = box->covarianceMatrix[1][2];
395//
396//   OBBTreeNode::coMat[3][1] = box->covarianceMatrix[2][0];
397//   OBBTreeNode::coMat[3][2] = box->covarianceMatrix[2][1];
398//   OBBTreeNode::coMat[3][3] = box->covarianceMatrix[2][2];
399
400
401  /* new jacobi tests */
402  JacobI(OBBTreeNode::coMat, OBBTreeNode::eigvlMat, OBBTreeNode::eigvMat, OBBTreeNode::rotCount);
403  PRINTF(3)("-- Done Jacobi Decomposition\n");
404
405
406//   PRINTF(0)("Jacobi\n");
407//   for(int j = 0; j < 3; ++j)
408//   {
409//     printf(" |");
410//     for(int k = 0; k < 3; ++k)
411//     {
412//       printf(" \t%f ", OBBTreeNode::OBBTreeNode::eigvMat[j][k]);
413//     }
414//     printf(" |\n");
415//   }
416
417  axis[0].x = OBBTreeNode::eigvMat[0][0]; axis[0].y = OBBTreeNode::eigvMat[1][0]; axis[0].z = OBBTreeNode::eigvMat[2][0];
418  axis[1].x = OBBTreeNode::eigvMat[0][1]; axis[1].y = OBBTreeNode::eigvMat[1][1]; axis[1].z = OBBTreeNode::eigvMat[2][1];
419  axis[2].x = OBBTreeNode::eigvMat[0][2]; axis[2].y = OBBTreeNode::eigvMat[1][2]; axis[2].z = OBBTreeNode::eigvMat[2][2];
420  axis[0].normalize();
421  axis[1].normalize();
422  axis[2].normalize();
423  box->axis = axis;
424
425//   PRINTF(0)("-- Got Axis\n");
426//
427//   PRINTF(0)("eigenvector: %f, %f, %f\n", box->axis[0].x, box->axis[0].y, box->axis[0].z);
428//   PRINTF(0)("eigenvector: %f, %f, %f\n", box->axis[1].x, box->axis[1].y, box->axis[1].z);
429//   PRINTF(0)("eigenvector: %f, %f, %f\n", box->axis[2].x, box->axis[2].y, box->axis[2].z);
430}
431
432
433void OBBTreeNode::calculateBoxAxis(OBB* box, sVec3D* verticesList, int length)
434{
435
436  /* now get the axis length */
437  Line                ax[3];                                 //!< the axis
438  float*              halfLength = new float[3];             //!< half length of the axis
439  float               tmpLength;                             //!< tmp save point for the length
440  Plane               p0(box->axis[0], *box->center);       //!< the axis planes
441  Plane               p1(box->axis[1], *box->center);
442  Plane               p2(box->axis[2], *box->center);
443  float               maxLength[3];
444  float               minLength[3];
445
446
447  /* get a bad bounding box */
448  halfLength[0] = -1.0f;
449  for(int j = 0; j < length; ++j)
450    {
451      tmpLength = fabs(p0.distancePoint(vertices[j]));
452      if( tmpLength > halfLength[0])
453        halfLength[0] = tmpLength;
454    }
455
456  halfLength[1] = -1.0f;
457  for(int j = 0; j < length; ++j)
458    {
459      tmpLength = fabs(p1.distancePoint(vertices[j]));
460      if( tmpLength > halfLength[1])
461        halfLength[1] = tmpLength;
462    }
463
464  halfLength[2] = -1.0f;
465  for(int j = 0; j < length; ++j)
466    {
467      tmpLength = fabs(p2.distancePoint(vertices[j]));
468      if( tmpLength > halfLength[2])
469        halfLength[2] = tmpLength;
470    }
471
472
473
474  /* get the maximal dimensions of the body in all directions */
475    maxLength[0] = p0.distancePoint(vertices[0]);
476    minLength[0] = p0.distancePoint(vertices[0]);
477   for(int j = 0; j < length; ++j)
478   {
479     tmpLength = p0.distancePoint(vertices[j]);
480     if( tmpLength > maxLength[0])
481       maxLength[0] = tmpLength;
482     else if( tmpLength < minLength[0])
483       minLength[0] = tmpLength;
484   }
485
486   maxLength[1] = p1.distancePoint(vertices[0]);
487   minLength[1] = p1.distancePoint(vertices[0]);
488   for(int j = 0; j < length; ++j)
489   {
490     tmpLength = p1.distancePoint(vertices[j]);
491     if( tmpLength > maxLength[1])
492       maxLength[1] = tmpLength;
493     else if( tmpLength < minLength[1])
494       minLength[1] = tmpLength;
495   }
496
497   maxLength[2] = p2.distancePoint(vertices[0]);
498   minLength[2] = p2.distancePoint(vertices[0]);
499   for(int j = 0; j < length; ++j)
500   {
501     tmpLength = p2.distancePoint(vertices[j]);
502     if( tmpLength > maxLength[2])
503       maxLength[2] = tmpLength;
504     else if( tmpLength < minLength[2])
505       minLength[2] = tmpLength;
506   }
507
508
509   /* calculate the real centre of the body by using the axis length */
510   float centerOffset[3];
511   float newHalfLength[3];
512   for(int i = 0; i < 3; ++i)
513     {
514       PRINTF(3)("max: %f, min: %f \n", maxLength[i], minLength[i]);
515       centerOffset[i] = (maxLength[i] + minLength[i]) / 2.0f;       // min length is negatie
516       newHalfLength[i] = (maxLength[i] - minLength[i]) / 2.0f;      // min length is negative
517       *box->center +=  (box->axis[i] * centerOffset[i]);            // update the new center vector
518       halfLength[i] = newHalfLength[i];
519     }
520
521
522
523  box->halfLength = halfLength;
524  PRINTF(3)("-- Written Axis to obb\n");
525  PRINTF(3)("-- Finished Calculating Attributes\n");
526
527}
528
529
530
531/**
532  \brief this separates an ob-box in the middle
533* @param box: the box to separate
534
535  this will separate the box into to smaller boxes. the separation is done along the middle of the longest axis
536 */
537void OBBTreeNode::forkBox(OBB* box)
538{
539  /* get the longest axis of the box */
540  float               aLength = -1.0f;                     //!< the length of the longest axis
541  int                 axisIndex = 0;                       //!< this is the nr of the longest axis
542
543  for(int i = 0; i < 3; ++i)
544  {
545    if( aLength < box->halfLength[i])
546    {
547      aLength = box->halfLength[i];
548      axisIndex = i;
549    }
550  }
551
552   PRINTF(3)("longest axis is: nr %i with a half-length of: %f\n", axisIndex, aLength);
553
554
555  /* get the closest vertex near the center */
556  float               dist = 999999.0f;                    //!< the smallest distance to each vertex
557  float               tmpDist;                             //!< temporary distance
558  int                 vertexIndex;
559  Plane               middlePlane(box->axis[axisIndex], *box->center); //!< the middle plane
560
561  vertexIndex = 0;
562  for(int i = 0; i < box->numOfVertices; ++i)
563  {
564    tmpDist = fabs(middlePlane.distancePoint(box->vertices[i]));
565    if( tmpDist < dist)
566    {
567      dist = tmpDist;
568      vertexIndex = i;
569    }
570  }
571
572  PRINTF(3)("\nthe clostest vertex is nr: %i, with a dist of: %f\n", vertexIndex ,dist);
573
574
575  /* now definin the separation plane through this specified nearest point and partition
576  the points depending on which side they are located
577  */
578  tList<sVec3D>      partition1;                           //!< the vertex partition 1
579  tList<sVec3D>      partition2;                           //!< the vertex partition 2
580
581
582  PRINTF(3)("vertex index: %i, of %i\n", vertexIndex, box->numOfVertices);
583  this->separationPlane = new Plane(box->axis[axisIndex], box->vertices[vertexIndex]);  //!< separation plane
584  this->sepPlaneCenter = &box->vertices[vertexIndex];
585  this->longestAxisIndex = axisIndex;
586
587  for(int i = 0; i < box->numOfVertices; ++i)
588  {
589    if( i == vertexIndex) continue;
590    tmpDist = this->separationPlane->distancePoint(box->vertices[i]);
591    if( tmpDist > 0.0)
592      partition1.add(&box->vertices[i]); /* positive numbers plus zero */
593    else
594      partition2.add(&box->vertices[i]); /* negatice numbers */
595  }
596  partition1.add(&box->vertices[vertexIndex]);
597  partition2.add(&box->vertices[vertexIndex]);
598
599  PRINTF(3)("\npartition1: got %i vertices/ partition 2: got %i vertices\n", partition1.getSize(), partition2.getSize());
600
601
602  /* now comes the separation into two different sVec3D arrays */
603  tIterator<sVec3D>* iterator;                             //!< the iterator to go through the lists
604  sVec3D*            element;                              //!< the elements
605  int                index;                                //!< index storage place
606  sVec3D*            vertList1;                            //!< the vertex list 1
607  sVec3D*            vertList2;                            //!< the vertex list 2
608
609  vertList1 = new sVec3D[partition1.getSize()];
610  vertList2 = new sVec3D[partition2.getSize()];
611
612  iterator = partition1.getIterator();
613  element = iterator->firstElement();
614  index = 0;
615  while( element != NULL)
616  {
617    vertList1[index][0] = element[0][0];
618    vertList1[index][1] = element[0][1];
619    vertList1[index][2] = element[0][2];
620    ++index;
621    element = iterator->nextElement();
622  }
623
624//   PRINTF(0)("\npartition 1:\n");
625//   for(int i = 0; i < partition1.getSize(); ++i)
626//   {
627//     PRINTF(0)("v[%i][0] = %f,\tv[%i][1] = %f,\tv[%i][1] = %f\n", i, vertList1[i][0], i, vertList1[i][1], i, vertList1[i][2]);
628//   }
629
630  iterator = partition2.getIterator();
631  element = iterator->firstElement();
632  index = 0;
633  while( element != NULL)
634  {
635    vertList2[index][0] = element[0][0];
636    vertList2[index][1] = element[0][1];
637    vertList2[index][2] = element[0][2];
638    ++index;
639    element = iterator->nextElement();
640  }
641
642  this->tmpVert1 = vertList1;
643  this->tmpVert2 = vertList2;
644  this->tmpLen1 = partition1.getSize();
645  this->tmpLen2 = partition2.getSize();
646
647  delete iterator;
648
649//   PRINTF(0)("\npartition 2:\n");
650//   for(int i = 0; i < partition2.getSize(); ++i)
651//   {
652//     PRINTF(0)("v[%i][0] = %f,\tv[%i][1] = %f,\tv[%i][1] = %f\n", i, vertList2[i][0], i,  vertList2[i][1], i, vertList2[i][2]);
653//   }
654}
655
656
657
658
659void OBBTreeNode::collideWith(BVTreeNode* treeNode, WorldEntity* nodeA, WorldEntity* nodeB)
660{
661  PRINTF(3)("collideWith\n");
662  /* if the obb overlap, make subtests: check which node is realy overlaping  */
663  PRINT(3)("Checking OBB %i vs %i: ", this->getIndex(), treeNode->getIndex());
664  if( unlikely(treeNode == NULL)) return;
665
666  if( this->overlapTest(this->bvElement, ((OBBTreeNode*)treeNode)->bvElement, nodeA, nodeB))
667  {
668    PRINTF(3)("collision @ lvl %i, object %s vs. %s, (%p, %p)\n", this->depth, nodeA->getClassName(), nodeB->getClassName(), this->nodeLeft, this->nodeRight);
669
670    /* check if left node overlaps */
671    if( likely( this->nodeLeft != NULL))
672    {
673      PRINT(3)("Checking OBB %i vs %i: ", this->nodeLeft->getIndex(), treeNode->getIndex());
674      if( this->overlapTest(this->nodeLeft->bvElement, ((OBBTreeNode*)treeNode)->bvElement, nodeA, nodeB))
675      {
676        this->nodeLeft->collideWith(((OBBTreeNode*)treeNode)->nodeLeft, nodeA, nodeB);
677        this->nodeLeft->collideWith(((OBBTreeNode*)treeNode)->nodeRight, nodeA, nodeB);
678      }
679    }
680    /* check if right node overlaps */
681    if( likely( this->nodeRight != NULL))
682    {
683      PRINT(3)("Checking OBB %i vs %i: ", this->nodeRight->getIndex(), treeNode->getIndex());
684      if(this->overlapTest(this->nodeRight->bvElement, ((OBBTreeNode*)treeNode)->bvElement, nodeA, nodeB))
685      {
686       this->nodeRight->collideWith(((OBBTreeNode*)treeNode)->nodeLeft, nodeA, nodeB);
687       this->nodeRight->collideWith(((OBBTreeNode*)treeNode)->nodeRight, nodeA, nodeB);
688      }
689    }
690
691    /* so there is a collision and this is the last box in the tree (i.e. leaf) */
692    if( unlikely(this->nodeRight == NULL && this->nodeLeft == NULL))
693    {
694      nodeA->collidesWith(nodeB, *((OBBTreeNode*)treeNode)->bvElement->center);
695
696      nodeB->collidesWith(nodeA, *this->bvElement->center);
697    }
698
699  }
700}
701
702
703
704bool OBBTreeNode::overlapTest(OBB* boxA, OBB* boxB, WorldEntity* nodeA, WorldEntity* nodeB)
705{
706  /* first check all axis */
707  Vector t;
708  float rA = 0.0f;
709  float rB = 0.0f;
710  Vector l;
711  Vector rotAxisA[3];
712  Vector rotAxisB[3];
713
714  rotAxisA[0] =  nodeA->getAbsDir().apply(boxA->axis[0]);
715  rotAxisA[1] =  nodeA->getAbsDir().apply(boxA->axis[1]);
716  rotAxisA[2] =  nodeA->getAbsDir().apply(boxA->axis[2]);
717
718  rotAxisB[0] =  nodeB->getAbsDir().apply(boxB->axis[0]);
719  rotAxisB[1] =  nodeB->getAbsDir().apply(boxB->axis[1]);
720  rotAxisB[2] =  nodeB->getAbsDir().apply(boxB->axis[2]);
721
722  t = nodeA->getAbsCoor() + nodeA->getAbsDir().apply(*boxA->center) - ( nodeB->getAbsCoor() + nodeB->getAbsDir().apply(*boxB->center));
723
724//   printf("\n");
725//   printf("(%f, %f, %f) -> (%f, %f, %f)\n", boxA->axis[0].x, boxA->axis[0].y, boxA->axis[0].z, rotAxisA[0].x, rotAxisA[0].y, rotAxisA[0].z);
726//   printf("(%f, %f, %f) -> (%f, %f, %f)\n", boxA->axis[1].x, boxA->axis[1].y, boxA->axis[1].z, rotAxisA[1].x, rotAxisA[1].y, rotAxisA[1].z);
727//   printf("(%f, %f, %f) -> (%f, %f, %f)\n", boxA->axis[2].x, boxA->axis[2].y, boxA->axis[2].z, rotAxisA[2].x, rotAxisA[2].y, rotAxisA[2].z);
728//
729//   printf("(%f, %f, %f) -> (%f, %f, %f)\n", boxB->axis[0].x, boxB->axis[0].y, boxB->axis[0].z, rotAxisB[0].x, rotAxisB[0].y, rotAxisB[0].z);
730//   printf("(%f, %f, %f) -> (%f, %f, %f)\n", boxB->axis[1].x, boxB->axis[1].y, boxB->axis[1].z, rotAxisB[1].x, rotAxisB[1].y, rotAxisB[1].z);
731//   printf("(%f, %f, %f) -> (%f, %f, %f)\n", boxB->axis[2].x, boxB->axis[2].y, boxB->axis[2].z, rotAxisB[2].x, rotAxisB[2].y, rotAxisB[2].z);
732
733
734  /* All 3 axis of the object A */
735  for( int j = 0; j < 3; ++j)
736  {
737    rA = 0.0f;
738    rB = 0.0f;
739    l = rotAxisA[j];
740
741    rA += fabs(boxA->halfLength[0] * rotAxisA[0].dot(l));
742    rA += fabs(boxA->halfLength[1] * rotAxisA[1].dot(l));
743    rA += fabs(boxA->halfLength[2] * rotAxisA[2].dot(l));
744
745    rB += fabs(boxB->halfLength[0] * rotAxisB[0].dot(l));
746    rB += fabs(boxB->halfLength[1] * rotAxisB[1].dot(l));
747    rB += fabs(boxB->halfLength[2] * rotAxisB[2].dot(l));
748
749    PRINTF(3)("s = %f, rA+rB = %f\n", fabs(t.dot(l)), rA+rB);
750
751    if( (rA + rB) < fabs(t.dot(l)))
752    {
753      PRINT(3)("keine Kollision\n");
754      return false;
755    }
756  }
757
758  /* All 3 axis of the object B */
759  for( int j = 0; j < 3; ++j)
760  {
761    rA = 0.0f;
762    rB = 0.0f;
763    l = rotAxisB[j];
764
765    rA += fabs(boxA->halfLength[0] * rotAxisA[0].dot(l));
766    rA += fabs(boxA->halfLength[1] * rotAxisA[1].dot(l));
767    rA += fabs(boxA->halfLength[2] * rotAxisA[2].dot(l));
768
769    rB += fabs(boxB->halfLength[0] * rotAxisB[0].dot(l));
770    rB += fabs(boxB->halfLength[1] * rotAxisB[1].dot(l));
771    rB += fabs(boxB->halfLength[2] * rotAxisB[2].dot(l));
772
773    PRINTF(3)("s = %f, rA+rB = %f\n", fabs(t.dot(l)), rA+rB);
774
775    if( (rA + rB) < fabs(t.dot(l)))
776    {
777      PRINT(3)("keine Kollision\n");
778      return false;
779    }
780  }
781
782
783  /* Now check for all face cross products */
784
785  for( int j = 0; j < 3; ++j)
786  {
787    for(int k = 0; k < 3; ++k )
788    {
789      rA = 0.0f;
790      rB = 0.0f;
791      l = rotAxisA[j].cross(rotAxisB[k]);
792
793      rA += fabs(boxA->halfLength[0] * rotAxisA[0].dot(l));
794      rA += fabs(boxA->halfLength[1] * rotAxisA[1].dot(l));
795      rA += fabs(boxA->halfLength[2] * rotAxisA[2].dot(l));
796
797      rB += fabs(boxB->halfLength[0] * rotAxisB[0].dot(l));
798      rB += fabs(boxB->halfLength[1] * rotAxisB[1].dot(l));
799      rB += fabs(boxB->halfLength[2] * rotAxisB[2].dot(l));
800
801      PRINTF(3)("s = %f, rA+rB = %f\n", fabs(t.dot(l)), rA+rB);
802
803      if( (rA + rB) < fabs(t.dot(l)))
804      {
805        PRINT(3)("keine Kollision\n");
806        return false;
807      }
808    }
809  }
810
811
812  boxA->bCollided = true; /* use this ONLY(!!!!) for drawing operations */
813  boxB->bCollided = true;
814  PRINT(3)("Kollision!\n");
815  return true;
816}
817
818
819
820
821
822void OBBTreeNode::drawBV(int depth, int drawMode, const Vector& color,  bool top) const
823{
824
825  /* draw the model itself, there is some problem concerning this: the vertices are drawn multiple times */
826  if( drawMode & DRAW_MODEL || drawMode & DRAW_ALL)
827  {
828    if( !(drawMode & DRAW_SINGLE && depth != 0))
829    {
830      if( drawMode & DRAW_POINTS)
831        glBegin(GL_POINTS);
832      for(int i = 0; i < this->bvElement->numOfVertices; ++i)
833      {
834        if( drawMode & DRAW_POINTS)
835          glVertex3f(this->bvElement->vertices[i][0], this->bvElement->vertices[i][1], this->bvElement->vertices[i][2]);
836        else
837        {
838          glPushMatrix();
839          glTranslatef(this->bvElement->vertices[i][0], this->bvElement->vertices[i][1], this->bvElement->vertices[i][2]);
840          gluSphere(OBBTreeNode_sphereObj, 0.1, 10, 10);
841          glPopMatrix();
842        }
843      }
844      if( drawMode & DRAW_POINTS)
845        glEnd();
846    }
847  }
848
849  if (top)
850  {
851    glPushAttrib(GL_ENABLE_BIT);
852    glDisable(GL_LIGHTING);
853    glDisable(GL_TEXTURE_2D);
854  }
855  glColor3f(color.x, color.y, color.z);
856
857
858  /* draw world axes */
859  if( drawMode & DRAW_BV_AXIS)
860  {
861    glBegin(GL_LINES);
862    glColor3f(1.0, 0.0, 0.0);
863    glVertex3f(0.0, 0.0, 0.0);
864    glVertex3f(3.0, 0.0, 0.0);
865
866    glColor3f(0.0, 1.0, 0.0);
867    glVertex3f(0.0, 0.0, 0.0);
868    glVertex3f(0.0, 3.0, 0.0);
869
870    glColor3f(0.0, 0.0, 1.0);
871    glVertex3f(0.0, 0.0, 0.0);
872    glVertex3f(0.0, 0.0, 3.0);
873    glEnd();
874  }
875
876
877  if( drawMode & DRAW_BV_AXIS || drawMode & DRAW_ALL)
878  {
879    if( !(drawMode & DRAW_SINGLE && depth != 0))
880    {
881      /* draw the obb axes */
882      glBegin(GL_LINES);
883      glColor3f(0.0, 0.4, 0.3);
884      glVertex3f(this->bvElement->center->x, this->bvElement->center->y, this->bvElement->center->z);
885      glVertex3f(this->bvElement->center->x + this->bvElement->axis[0].x * this->bvElement->halfLength[0],
886                 this->bvElement->center->y + this->bvElement->axis[0].y * this->bvElement->halfLength[0],
887                 this->bvElement->center->z + this->bvElement->axis[0].z * this->bvElement->halfLength[0]);
888
889      glVertex3f(this->bvElement->center->x, this->bvElement->center->y, this->bvElement->center->z);
890      glVertex3f(this->bvElement->center->x + this->bvElement->axis[1].x * this->bvElement->halfLength[1],
891                 this->bvElement->center->y + this->bvElement->axis[1].y * this->bvElement->halfLength[1],
892                 this->bvElement->center->z + this->bvElement->axis[1].z * this->bvElement->halfLength[1]);
893
894      glVertex3f(this->bvElement->center->x, this->bvElement->center->y, this->bvElement->center->z);
895      glVertex3f(this->bvElement->center->x + this->bvElement->axis[2].x * this->bvElement->halfLength[2],
896                 this->bvElement->center->y + this->bvElement->axis[2].y * this->bvElement->halfLength[2],
897                 this->bvElement->center->z + this->bvElement->axis[2].z * this->bvElement->halfLength[2]);
898      glEnd();
899    }
900  }
901
902
903  /* DRAW POLYGONS */
904  if( drawMode & DRAW_BV_POLYGON || drawMode & DRAW_ALL || drawMode & DRAW_BV_BLENDED)
905  {
906    if (top)
907    {
908      glEnable(GL_BLEND);
909      glBlendFunc(GL_SRC_ALPHA, GL_ONE);
910    }
911
912    if(this->nodeLeft == NULL || this->nodeRight == NULL)
913      depth = 0;
914    if( !(drawMode & DRAW_SINGLE && depth != 0))
915    {
916    Vector cen = *this->bvElement->center;
917    Vector* axis = this->bvElement->axis;
918    float* len = this->bvElement->halfLength;
919
920    if( this->bvElement->bCollided)
921    {
922      glColor4f(1.0, 1.0, 1.0, .5); // COLLISION COLOR
923    }
924    else if( drawMode & DRAW_BV_BLENDED)
925    {
926      glColor4f(color.x, color.y, color.z, .5);
927    }
928
929    /* draw bounding box */
930    if( drawMode & DRAW_BV_BLENDED)
931      glBegin(GL_QUADS);
932    else
933      glBegin(GL_LINE_LOOP);
934    glVertex3f(cen.x + axis[0].x * len[0] + axis[1].x * len[1] + axis[2].x * len[2],
935               cen.y + axis[0].y * len[0] + axis[1].y * len[1] + axis[2].y * len[2],
936               cen.z + axis[0].z * len[0] + axis[1].z * len[1] + axis[2].z * len[2]);
937    glVertex3f(cen.x + axis[0].x * len[0] + axis[1].x * len[1] - axis[2].x * len[2],
938               cen.y + axis[0].y * len[0] + axis[1].y * len[1] - axis[2].y * len[2],
939               cen.z + axis[0].z * len[0] + axis[1].z * len[1] - axis[2].z * len[2]);
940    glVertex3f(cen.x + axis[0].x * len[0] - axis[1].x * len[1] - axis[2].x * len[2],
941               cen.y + axis[0].y * len[0] - axis[1].y * len[1] - axis[2].y * len[2],
942               cen.z + axis[0].z * len[0] - axis[1].z * len[1] - axis[2].z * len[2]);
943    glVertex3f(cen.x + axis[0].x * len[0] - axis[1].x * len[1] + axis[2].x * len[2],
944               cen.y + axis[0].y * len[0] - axis[1].y * len[1] + axis[2].y * len[2],
945               cen.z + axis[0].z * len[0] - axis[1].z * len[1] + axis[2].z * len[2]);
946    glEnd();
947
948    if( drawMode & DRAW_BV_BLENDED)
949      glBegin(GL_QUADS);
950    else
951      glBegin(GL_LINE_LOOP);
952    glVertex3f(cen.x + axis[0].x * len[0] - axis[1].x * len[1] + axis[2].x * len[2],
953               cen.y + axis[0].y * len[0] - axis[1].y * len[1] + axis[2].y * len[2],
954               cen.z + axis[0].z * len[0] - axis[1].z * len[1] + axis[2].z * len[2]);
955    glVertex3f(cen.x + axis[0].x * len[0] - axis[1].x * len[1] - axis[2].x * len[2],
956               cen.y + axis[0].y * len[0] - axis[1].y * len[1] - axis[2].y * len[2],
957               cen.z + axis[0].z * len[0] - axis[1].z * len[1] - axis[2].z * len[2]);
958    glVertex3f(cen.x - axis[0].x * len[0] - axis[1].x * len[1] - axis[2].x * len[2],
959               cen.y - axis[0].y * len[0] - axis[1].y * len[1] - axis[2].y * len[2],
960               cen.z - axis[0].z * len[0] - axis[1].z * len[1] - axis[2].z * len[2]);
961    glVertex3f(cen.x - axis[0].x * len[0] - axis[1].x * len[1] + axis[2].x * len[2],
962               cen.y - axis[0].y * len[0] - axis[1].y * len[1] + axis[2].y * len[2],
963               cen.z - axis[0].z * len[0] - axis[1].z * len[1] + axis[2].z * len[2]);
964    glEnd();
965
966    if( drawMode & DRAW_BV_BLENDED)
967      glBegin(GL_QUADS);
968    else
969      glBegin(GL_LINE_LOOP);
970    glVertex3f(cen.x - axis[0].x * len[0] - axis[1].x * len[1] + axis[2].x * len[2],
971               cen.y - axis[0].y * len[0] - axis[1].y * len[1] + axis[2].y * len[2],
972               cen.z - axis[0].z * len[0] - axis[1].z * len[1] + axis[2].z * len[2]);
973    glVertex3f(cen.x - axis[0].x * len[0] - axis[1].x * len[1] - axis[2].x * len[2],
974               cen.y - axis[0].y * len[0] - axis[1].y * len[1] - axis[2].y * len[2],
975               cen.z - axis[0].z * len[0] - axis[1].z * len[1] - axis[2].z * len[2]);
976    glVertex3f(cen.x - axis[0].x * len[0] + axis[1].x * len[1] - axis[2].x * len[2],
977               cen.y - axis[0].y * len[0] + axis[1].y * len[1] - axis[2].y * len[2],
978               cen.z - axis[0].z * len[0] + axis[1].z * len[1] - axis[2].z * len[2]);
979    glVertex3f(cen.x - axis[0].x * len[0] + axis[1].x * len[1] + axis[2].x * len[2],
980               cen.y - axis[0].y * len[0] + axis[1].y * len[1] + axis[2].y * len[2],
981               cen.z - axis[0].z * len[0] + axis[1].z * len[1] + axis[2].z * len[2]);
982    glEnd();
983
984    if( drawMode & DRAW_BV_BLENDED)
985      glBegin(GL_QUADS);
986    else
987      glBegin(GL_LINE_LOOP);
988    glVertex3f(cen.x - axis[0].x * len[0] + axis[1].x * len[1] - axis[2].x * len[2],
989               cen.y - axis[0].y * len[0] + axis[1].y * len[1] - axis[2].y * len[2],
990               cen.z - axis[0].z * len[0] + axis[1].z * len[1] - axis[2].z * len[2]);
991    glVertex3f(cen.x - axis[0].x * len[0] + axis[1].x * len[1] + axis[2].x * len[2],
992               cen.y - axis[0].y * len[0] + axis[1].y * len[1] + axis[2].y * len[2],
993               cen.z - axis[0].z * len[0] + axis[1].z * len[1] + axis[2].z * len[2]);
994    glVertex3f(cen.x + axis[0].x * len[0] + axis[1].x * len[1] + axis[2].x * len[2],
995               cen.y + axis[0].y * len[0] + axis[1].y * len[1] + axis[2].y * len[2],
996               cen.z + axis[0].z * len[0] + axis[1].z * len[1] + axis[2].z * len[2]);
997    glVertex3f(cen.x + axis[0].x * len[0] + axis[1].x * len[1] - axis[2].x * len[2],
998               cen.y + axis[0].y * len[0] + axis[1].y * len[1] - axis[2].y * len[2],
999               cen.z + axis[0].z * len[0] + axis[1].z * len[1] - axis[2].z * len[2]);
1000    glEnd();
1001
1002
1003    if( drawMode & DRAW_BV_BLENDED)
1004    {
1005      glBegin(GL_QUADS);
1006      glVertex3f(cen.x - axis[0].x * len[0] + axis[1].x * len[1] - axis[2].x * len[2],
1007                 cen.y - axis[0].y * len[0] + axis[1].y * len[1] - axis[2].y * len[2],
1008                 cen.z - axis[0].z * len[0] + axis[1].z * len[1] - axis[2].z * len[2]);
1009      glVertex3f(cen.x + axis[0].x * len[0] + axis[1].x * len[1] - axis[2].x * len[2],
1010                 cen.y + axis[0].y * len[0] + axis[1].y * len[1] - axis[2].y * len[2],
1011                 cen.z + axis[0].z * len[0] + axis[1].z * len[1] - axis[2].z * len[2]);
1012      glVertex3f(cen.x + axis[0].x * len[0] - axis[1].x * len[1] - axis[2].x * len[2],
1013                 cen.y + axis[0].y * len[0] - axis[1].y * len[1] - axis[2].y * len[2],
1014                 cen.z + axis[0].z * len[0] - axis[1].z * len[1] - axis[2].z * len[2]);
1015      glVertex3f(cen.x - axis[0].x * len[0] - axis[1].x * len[1] - axis[2].x * len[2],
1016                 cen.y - axis[0].y * len[0] - axis[1].y * len[1] - axis[2].y * len[2],
1017                 cen.z - axis[0].z * len[0] - axis[1].z * len[1] - axis[2].z * len[2]);
1018      glEnd();
1019
1020      glBegin(GL_QUADS);
1021      glVertex3f(cen.x - axis[0].x * len[0] + axis[1].x * len[1] + axis[2].x * len[2],
1022                 cen.y - axis[0].y * len[0] + axis[1].y * len[1] + axis[2].y * len[2],
1023                 cen.z - axis[0].z * len[0] + axis[1].z * len[1] + axis[2].z * len[2]);
1024      glVertex3f(cen.x + axis[0].x * len[0] + axis[1].x * len[1] + axis[2].x * len[2],
1025                 cen.y + axis[0].y * len[0] + axis[1].y * len[1] + axis[2].y * len[2],
1026                 cen.z + axis[0].z * len[0] + axis[1].z * len[1] + axis[2].z * len[2]);
1027      glVertex3f(cen.x + axis[0].x * len[0] - axis[1].x * len[1] + axis[2].x * len[2],
1028                 cen.y + axis[0].y * len[0] - axis[1].y * len[1] + axis[2].y * len[2],
1029                 cen.z + axis[0].z * len[0] - axis[1].z * len[1] + axis[2].z * len[2]);
1030      glVertex3f(cen.x - axis[0].x * len[0] - axis[1].x * len[1] + axis[2].x * len[2],
1031                 cen.y - axis[0].y * len[0] - axis[1].y * len[1] + axis[2].y * len[2],
1032                 cen.z - axis[0].z * len[0] - axis[1].z * len[1] + axis[2].z * len[2]);
1033      glEnd();
1034    }
1035
1036
1037    if( drawMode & DRAW_BV_BLENDED)
1038      glColor3f(color.x, color.y, color.z);
1039    }
1040
1041  }
1042
1043  /* DRAW SEPARATING PLANE */
1044  if( drawMode & DRAW_SEPARATING_PLANE || drawMode & DRAW_ALL)
1045  {
1046    if( !(drawMode & DRAW_SINGLE && depth != 0))
1047    {
1048      if( drawMode & DRAW_BV_BLENDED)
1049        glColor4f(color.x, color.y, color.z, .6);
1050
1051    /* now draw the separation plane */
1052    Vector a1 = this->bvElement->axis[(this->longestAxisIndex + 1)%3];
1053    Vector a2 = this->bvElement->axis[(this->longestAxisIndex + 2)%3];
1054    Vector c = *this->bvElement->center;
1055    float l1 = this->bvElement->halfLength[(this->longestAxisIndex + 1)%3];
1056    float l2 = this->bvElement->halfLength[(this->longestAxisIndex + 2)%3];
1057    glBegin(GL_QUADS);
1058    glVertex3f(c.x + a1.x * l1 + a2.x * l2, c.y + a1.y * l1+ a2.y * l2, c.z + a1.z * l1 + a2.z * l2);
1059    glVertex3f(c.x - a1.x * l1 + a2.x * l2, c.y - a1.y * l1+ a2.y * l2, c.z - a1.z * l1 + a2.z * l2);
1060    glVertex3f(c.x - a1.x * l1 - a2.x * l2, c.y - a1.y * l1- a2.y * l2, c.z - a1.z * l1 - a2.z * l2);
1061    glVertex3f(c.x + a1.x * l1 - a2.x * l2, c.y + a1.y * l1- a2.y * l2, c.z + a1.z * l1 - a2.z * l2);
1062    glEnd();
1063
1064    if( drawMode & DRAW_BV_BLENDED)
1065      glColor4f(color.x, color.y, color.z, 1.0);
1066
1067    }
1068  }
1069
1070
1071
1072  if (depth > 0)
1073  {
1074    if( this->nodeLeft != NULL)
1075      this->nodeLeft->drawBV(depth - 1, drawMode, Color::HSVtoRGB(Color::RGBtoHSV(color)+Vector(15.0,0.0,0.0)), false);
1076    if( this->nodeRight != NULL)
1077      this->nodeRight->drawBV(depth - 1, drawMode, Color::HSVtoRGB(Color::RGBtoHSV(color)+Vector(30.0,0.0,0.0)), false);
1078  }
1079  this->bvElement->bCollided = false;
1080
1081  if (top)
1082    glPopAttrib();
1083}
1084
1085
1086
1087void OBBTreeNode::debug() const
1088{
1089
1090  /*
1091  for(int i = 0; i < length; i++)
1092  {
1093  PRINTF(3)("vertex %i: %f, %f, %f\n", i, verticesList[i][0], verticesList[i][1], verticesList[i][2]);
1094}
1095  */
1096}
Note: See TracBrowser for help on using the repository browser.