Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 7616 was 7597, checked in by patrick, 19 years ago

cd: plane forumula reformulated since there was a small bug in it.

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