Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

collision: some more debug work on the collision detection framework

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