Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: merged the new_class_id branche back to the trunk.
merged with command:
svn merge https://svn.orxonox.net/orxonox/branches/new_class_id trunk -r9683:HEAD
no conflicts… puh..

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