Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

collision_detection: speed up in some function, more checks and more flexible output

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