Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: merged the proxy back

merged with commandsvn merge -r9346:HEAD https://svn.orxonox.net/orxonox/branches/proxy .

no conflicts

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