Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/collision_detection/src/lib/collision_detection/obb_tree_node.cc @ 5927

Last change on this file since 5927 was 5927, checked in by patrick, 18 years ago

collision_deteciton: works again! but much more massivesvn diff now realy looks good

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