Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/lib/collision_detection/aabb_tree_node.cc @ 9494

Last change on this file since 9494 was 9494, checked in by bensch, 18 years ago

merged the proxy back

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