Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

cd: some more debug infos

File size: 36.5 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
124  /* do we need to descent further in the obb tree?*/
125  if( likely( this->depth > 0))
126  {
127    this->forkBox(*this->bvElement);
128
129    if( this->triangleIndexLength1 >= 3)
130    {
131      this->nodeLeft = new OBBTreeNode(*this->obbTree, this, depth - 1);
132      this->nodeLeft->spawnBVTree(modelInf, this->triangleIndexList1, this->triangleIndexLength1);
133    }
134    if( this->triangleIndexLength2 >= 3)
135    {
136      this->nodeRight = new OBBTreeNode(*this->obbTree, this, depth - 1);
137      this->nodeRight->spawnBVTree(modelInf, this->triangleIndexList2, this->triangleIndexLength2);
138    }
139  }
140}
141
142
143
144/**
145 *  calculate the box covariance matrix
146 * @param box: reference to the box
147 * @param modelInf: the model info structure of the model
148 * @param tirangleIndexes: an array with the indexes of the triangles inside this
149 * @param length: the length of the indexes array
150 */
151void OBBTreeNode::calculateBoxCovariance(OBB& box, const modelInfo& modelInf, const int* triangleIndexes, int length)
152{
153  float     facelet[length];                         //!< surface area of the i'th triangle of the convex hull
154  float     face = 0.0f;                             //!< surface area of the entire convex hull
155  Vector    centroid[length];                        //!< centroid of the i'th convex hull
156  Vector    center;                                  //!< the center of the entire hull
157  Vector    p, q, r;                                 //!< holder of the polygon data, much more conveniant to work with Vector than sVec3d
158  Vector    t1, t2;                                  //!< temporary values
159  float     covariance[3][3] = {0,0,0, 0,0,0, 0,0,0};//!< the covariance matrix
160  sVec3D*   tmpVec = NULL;                           //!< a temp saving place for sVec3Ds
161
162  /* fist compute all the convex hull face/facelets and centroids */
163  for( int i = 0; i < length ; ++i)
164  {
165    tmpVec = (sVec3D*)(&modelInf.pVertices[modelInf.pTriangles[triangleIndexes[i]].indexToVertices[0]]);
166    p = *tmpVec;
167    tmpVec = (sVec3D*)(&modelInf.pVertices[modelInf.pTriangles[triangleIndexes[i]].indexToVertices[1]]);
168    q = *tmpVec;
169    tmpVec = (sVec3D*)(&modelInf.pVertices[modelInf.pTriangles[triangleIndexes[i]].indexToVertices[2]]);
170    r = *tmpVec;
171
172    /* finding the facelet surface via cross-product */
173    t1 = p - q;
174    t2 = p - r;
175    facelet[i] = 0.5f * /*fabs*/( t1.cross(t2).len() );
176    /* update the entire convex hull surface */
177    face += facelet[i];
178
179    /* calculate the cetroid of the hull triangles */
180    centroid[i] = (p + q + r) / 3.0f;
181    /* now calculate the centroid of the entire convex hull, weighted average of triangle centroids */
182    center += centroid[i] * facelet[i];
183    /* the arithmetical center */
184  }
185  /* take the average of the centroid sum */
186  center /= face;
187
188
189  /* now calculate the covariance matrix - if not written in three for-loops,
190     it would compute faster: minor */
191  for( int j = 0; j < 3; ++j)
192  {
193    for( int k = 0; k < 3; ++k)
194    {
195      for( int i = 0; i < length; ++i)
196      {
197        tmpVec = (sVec3D*)(&modelInf.pVertices[modelInf.pTriangles[triangleIndexes[i]].indexToVertices[0]]);
198        p = *tmpVec;
199        tmpVec = (sVec3D*)(&modelInf.pVertices[modelInf.pTriangles[triangleIndexes[i]].indexToVertices[1]]);
200        q = *tmpVec;
201        tmpVec = (sVec3D*)(&modelInf.pVertices[modelInf.pTriangles[triangleIndexes[i]].indexToVertices[2]]);
202        r = *tmpVec;
203
204        covariance[j][k] = facelet[i] * (9.0f * centroid[i][j] * centroid[i][k] + p[j] * p[k] +
205                           q[j] * q[k] + r[j] * r[k]);
206      }
207      covariance[j][k] = covariance[j][k] / (12.0f * face) - center[j] * center[k];
208    }
209  }
210  for( int i = 0; i < 3; ++i)
211  {
212    box.covarianceMatrix[i][0] = covariance[i][0];
213    box.covarianceMatrix[i][1] = covariance[i][1];
214    box.covarianceMatrix[i][2] = covariance[i][2];
215  }
216  box.center = center;
217
218
219  std::vector<int>           vertIndexVector;                           //!< vertex indexes list
220  int                        vertIndex;                                 //!< index to vertex
221  bool                       vertexFound;                               //!< vertex found flag
222  Vector                     arithCenter;                               //!< aritmetical center
223
224
225  /* debug output section*/
226  PRINTF(3)("\nOBB Covariance Matrix:\n");
227  for(int j = 0; j < 3; ++j)
228  {
229    PRINT(3)("\t\t");
230    for(int k = 0; k < 3; ++k)
231    {
232      PRINT(3)("%11.4f\t", covariance[j][k]);
233    }
234    PRINT(3)("\n");
235  }
236  PRINTF(3)("\nWeighteed OBB Center:\n\t\t%11.4f\t %11.4f\t %11.4f\n", center.x, center.y, center.z);
237//   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);
238
239  /* write back the covariance matrix data to the object oriented bouning box */
240}
241
242
243
244/**
245 *  calculate the eigenvectors for the object oriented box
246 * @param box: reference to the box
247 * @param modelInf: the model info structure of the model
248 * @param tirangleIndexes: an array with the indexes of the triangles inside this
249 * @param length: the length of the indexes array
250 */
251void OBBTreeNode::calculateBoxEigenvectors(OBB& box, const modelInfo& modelInf,
252    const int* triangleIndexes, int length)
253{
254
255  Vector         axis[3];                            //!< the references to the obb axis
256  Matrix         covMat(  box.covarianceMatrix  );   //!< covariance matrix (in the matrix dataform)
257
258  /*
259  now getting spanning vectors of the sub-space:
260  the eigenvectors of a symmertric matrix, such as the
261  covarience matrix are mutually orthogonal.
262  after normalizing them, they can be used as a the basis
263  vectors
264  */
265
266  /* calculate the axis */
267  covMat.getEigenVectors(axis[0], axis[1], axis[2] );
268  box.axis[0] = axis[0];
269  box.axis[1] = axis[1];
270  box.axis[2] = axis[2];
271
272  PRINTF(3)("Eigenvectors:\n");
273  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);
274  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);
275  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);
276}
277
278
279
280
281/**
282 *  calculate the eigenvectors for the object oriented box
283 * @param box: reference to the box
284 * @param modelInf: the model info structure of the model
285 * @param tirangleIndexes: an array with the indexes of the triangles inside this
286 * @param length: the length of the indexes array
287 */
288void OBBTreeNode::calculateBoxAxis(OBB& box, const modelInfo& modelInf, const int* triangleIndexes, int length)
289{
290
291  PRINTF(3)("Calculate Box Axis\n");
292  /* now get the axis length */
293  Line                ax[3];                                 //!< the axis
294  float               halfLength[3];                         //!< half length of the axis
295  float               tmpLength;                             //!< tmp save point for the length
296  Plane               p0(box.axis[0], box.center);           //!< the axis planes
297  Plane               p1(box.axis[1], box.center);           //!< the axis planes
298  Plane               p2(box.axis[2], box.center);           //!< the axis planes
299  float               maxLength[3];                          //!< maximal lenth of the axis
300  float               minLength[3];                          //!< minimal length of the axis
301  const sVec3D*       tmpVec;                                //!< variable taking tmp vectors
302
303
304  /* get the maximal dimensions of the body in all directions */
305  /* for the initialisation the value just has to be inside of the polygon soup -> first vertices (rand) */
306  tmpVec = (sVec3D*)(&modelInf.pVertices[modelInf.pTriangles[triangleIndexes[0]].indexToVertices[0]]);
307  maxLength[0] = p0.distancePoint(*tmpVec);
308  minLength[0] = p0.distancePoint(*tmpVec);
309  for( int j = 0; j < length; ++j)
310  {
311    for( int i = 0; i < 3; ++i)
312    {
313      tmpVec = (sVec3D*)(&modelInf.pVertices[modelInf.pTriangles[triangleIndexes[j]].indexToVertices[i]]);
314      tmpLength = p0.distancePoint(*tmpVec);
315      PRINTF(0)("point[%i][%i]: %f, %f, %f with distance to plane: %f\n", j, i, tmpVec[0], tmpVec[1], tmpVec[2], tmpLength);
316      if( tmpLength > maxLength[0])
317        maxLength[0] = tmpLength;
318      else if( tmpLength < minLength[0])
319        minLength[0] = tmpLength;
320    }
321  }
322
323  /* for the initialisation the value just has to be inside of the polygon soup -> first vertices (rand) */
324  tmpVec = (sVec3D*)(&modelInf.pVertices[modelInf.pTriangles[triangleIndexes[0]].indexToVertices[0]]);
325  maxLength[1] = p1.distancePoint(*tmpVec);
326  minLength[1] = p1.distancePoint(*tmpVec);
327  for( int j = 0; j < length; ++j)
328  {
329    for( int i = 0; i < 3; ++i)
330    {
331      tmpVec = (sVec3D*)(&modelInf.pVertices[modelInf.pTriangles[triangleIndexes[j]].indexToVertices[i]]);
332      tmpLength = p1.distancePoint(*tmpVec);
333      if( tmpLength > maxLength[1])
334        maxLength[1] = tmpLength;
335      else if( tmpLength < minLength[1])
336        minLength[1] = tmpLength;
337    }
338  }
339
340  /* for the initialisation the value just has to be inside of the polygon soup -> first vertices (rand) */
341  tmpVec = (sVec3D*)(&modelInf.pVertices[modelInf.pTriangles[triangleIndexes[0]].indexToVertices[0]]);
342  maxLength[2] = p2.distancePoint(*tmpVec);
343  minLength[2] = p2.distancePoint(*tmpVec);
344  for( int j = 0; j < length; ++j)
345  {
346    for( int i = 0; i < 3; ++i)
347    {
348      tmpVec = (sVec3D*)(&modelInf.pVertices[modelInf.pTriangles[triangleIndexes[j]].indexToVertices[i]]);
349      tmpLength = p2.distancePoint(*tmpVec);
350      if( tmpLength > maxLength[2])
351        maxLength[2] = tmpLength;
352      else if( tmpLength < minLength[2])
353        minLength[2] = tmpLength;
354    }
355  }
356
357
358  /* calculate the real centre of the body by using the axis length */
359  float               centerOffset[3];
360
361  for( int i = 0; i < 3; ++i)
362  {
363    centerOffset[i] = (fabs(maxLength[i]) - fabs(minLength[i])) / 2.0f;       // min length is negatie
364    box.halfLength[i] = (maxLength[i] - minLength[i]) / 3.0f;                 // min length is negative
365  }
366  // FIXME: += anstatt -= ????????? verwirr
367  box.center.x -= centerOffset[0];
368  box.center.y -= centerOffset[1];
369  box.center.z -= centerOffset[2];
370
371  PRINTF(3)("\n");
372  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]);
373  PRINT(3)("\tAxis halflength x: %11.2f (max: %11.2f, \tmin: %11.2f), offset: %11.2f\n", box.halfLength[1], maxLength[1], minLength[1], centerOffset[1] );
374  PRINT(3)("\tAxis halflength x: %11.2f (max: %11.2f, \tmin: %11.2f), offset: %11.2f\n", box.halfLength[2], maxLength[2], minLength[2], centerOffset[2]);
375}
376
377
378
379/**
380 *  this separates an ob-box in the middle
381 * @param box: the box to separate
382 *
383 * this will separate the box into to smaller boxes. the separation is done along the middle of the longest axis
384 */
385void OBBTreeNode::forkBox(OBB& box)
386{
387
388  PRINTF(3)("Fork Box\n");
389  PRINTF(4)("Calculating the longest Axis\n");
390  /* get the longest axis of the box */
391  float               longestAxis = -1.0f;                 //!< the length of the longest axis
392  int                 longestAxisIndex = 0;                //!< this is the nr of the longest axis
393
394
395  /* now get the longest axis of the three exiting */
396  for( int i = 0; i < 3; ++i)
397  {
398    if( longestAxis < box.halfLength[i])
399    {
400      longestAxis = box.halfLength[i];
401      longestAxisIndex = i;
402    }
403  }
404  PRINTF(3)("\nLongest Axis is: Nr %i with a half-length of:%11.2f\n", longestAxisIndex, longestAxis);
405
406
407  PRINTF(4)("Separating along the longest axis\n");
408  /* get the closest vertex near the center */
409  float               dist = 999999.0f;                    //!< the smallest distance to each vertex
410  float               tmpDist;                             //!< variable to save diverse distances temporarily
411  int                 vertexIndex;                         //!< index of the vertex near the center
412  Plane               middlePlane(box.axis[longestAxisIndex], box.center); //!< the middle plane
413  const sVec3D*       tmpVec;                              //!< temp simple 3D vector
414
415
416  /* now definin the separation plane through this specified nearest point and partition
417  the points depending on which side they are located
418  */
419  std::list<int>           partition1;                           //!< the vertex partition 1
420  std::list<int>           partition2;                           //!< the vertex partition 2
421  float*                   triangleCenter = new float[3];        //!< the center of the triangle
422  const float*             a;                                    //!< triangle  edge a
423  const float*             b;                                    //!< triangle  edge b
424  const float*             c;                                    //!< triangle  edge c
425
426
427  /* find the center of the box */
428  this->separationPlane = Plane(box.axis[longestAxisIndex], box.center);
429  this->sepPlaneCenter[0] = box.center.x;
430  this->sepPlaneCenter[1] = box.center.y;
431  this->sepPlaneCenter[2] = box.center.z;
432  this->longestAxisIndex = longestAxisIndex;
433
434  for( int i = 0; i < box.triangleIndexesLength; ++i)
435  {
436    /* first calculate the middle of the triangle */
437    a = &box.modelInf->pVertices[box.modelInf->pTriangles[box.triangleIndexes[i]].indexToVertices[0]];
438    b = &box.modelInf->pVertices[box.modelInf->pTriangles[box.triangleIndexes[i]].indexToVertices[1]];
439    c = &box.modelInf->pVertices[box.modelInf->pTriangles[box.triangleIndexes[i]].indexToVertices[2]];
440
441    triangleCenter[0] = (a[0] + b[0] + c[0]) / 3.0f;
442    triangleCenter[1] = (a[1] + b[1] + c[1]) / 3.0f;
443    triangleCenter[2] = (a[2] + b[2] + c[2]) / 3.0f;
444    tmpDist = this->separationPlane.distancePoint(*((sVec3D*)triangleCenter));
445
446    if( tmpDist > 0.0f)
447      partition1.push_back(box.triangleIndexes[i]); /* positive numbers plus zero */
448    else if( tmpDist < 0.0f)
449      partition2.push_back(box.triangleIndexes[i]); /* negatice numbers */
450    else {
451      partition1.push_back(box.triangleIndexes[i]); /* 0.0f? unprobable... */
452      partition2.push_back(box.triangleIndexes[i]);
453    }
454  }
455  PRINTF(3)("\nPartition1: got \t%i Vertices \nPartition2: got \t%i Vertices\n", partition1.size(), partition2.size());
456
457
458  /* now comes the separation into two different sVec3D arrays */
459  int                index;                                //!< index storage place
460  int*               triangleIndexList1;                   //!< the vertex list 1
461  int*               triangleIndexList2;                   //!< the vertex list 2
462  std::list<int>::iterator element;                        //!< the list iterator
463
464  triangleIndexList1 = new int[partition1.size()];
465  triangleIndexList2 = new int[partition2.size()];
466
467  for( element = partition1.begin(), index = 0; element != partition1.end(); element++, index++)
468    triangleIndexList1[index] = (*element);
469
470  for( element = partition2.begin(), index = 0; element != partition2.end(); element++, index++)
471    triangleIndexList2[index] = (*element);
472
473  if( this->triangleIndexList1!= NULL)
474    delete[] this->triangleIndexList1;
475  this->triangleIndexList1 = triangleIndexList1;
476  this->triangleIndexLength1 = partition1.size();
477
478  if( this->triangleIndexList2 != NULL)
479    delete[] this->triangleIndexList2;
480  this->triangleIndexList2 = triangleIndexList2;
481  this->triangleIndexLength2 = partition2.size();
482}
483
484
485
486
487void OBBTreeNode::collideWith(BVTreeNode* treeNode, WorldEntity* nodeA, WorldEntity* nodeB)
488{
489  if( unlikely(treeNode == NULL))
490    return;
491
492  PRINTF(3)("collideWith\n");
493  /* if the obb overlap, make subtests: check which node is realy overlaping  */
494  PRINTF(3)("Checking OBB %i vs %i: ", this->getIndex(), treeNode->getIndex());
495  //   if( unlikely(treeNode == NULL)) return;
496
497
498  if( this->overlapTest(*this->bvElement, *(((const OBBTreeNode*)&treeNode)->bvElement), nodeA, nodeB))
499  {
500    PRINTF(3)("collision @ lvl %i, object %s vs. %s, (%p, %p)\n", this->depth, nodeA->getClassName(), nodeB->getClassName(), this->nodeLeft, this->nodeRight);
501
502    /* check if left node overlaps */
503    if( likely( this->nodeLeft != NULL))
504    {
505      PRINTF(3)("Checking OBB %i vs %i: ", this->nodeLeft->getIndex(), treeNode->getIndex());
506      if( this->overlapTest(*this->nodeLeft->bvElement, *(((const OBBTreeNode*)&treeNode)->bvElement), nodeA, nodeB))
507      {
508        this->nodeLeft->collideWith((((const OBBTreeNode*)treeNode)->nodeLeft), nodeA, nodeB);
509        this->nodeLeft->collideWith((((const OBBTreeNode*)treeNode)->nodeRight), nodeA, nodeB);
510      }
511    }
512    /* check if right node overlaps */
513    if( likely( this->nodeRight != NULL))
514    {
515      PRINTF(3)("Checking OBB %i vs %i: ", this->nodeRight->getIndex(), treeNode->getIndex());
516      if(this->overlapTest(*this->nodeRight->bvElement, *(((const OBBTreeNode*)&treeNode)->bvElement), nodeA, nodeB))
517      {
518        this->nodeRight->collideWith((((const OBBTreeNode*)treeNode)->nodeLeft), nodeA, nodeB);
519        this->nodeRight->collideWith((((const OBBTreeNode*)treeNode)->nodeRight), nodeA, nodeB);
520      }
521    }
522
523    /* so there is a collision and this is the last box in the tree (i.e. leaf) */
524    /* FIXME: If we would choose || insead of && there would also be asymmetrical cases supported */
525    if( unlikely(this->nodeRight == NULL && this->nodeLeft == NULL))
526    {
527      nodeA->collidesWith(nodeB, (((const OBBTreeNode*)&treeNode)->bvElement->center));
528
529      nodeB->collidesWith(nodeA, this->bvElement->center);
530    }
531
532  }
533}
534
535
536
537bool OBBTreeNode::overlapTest(OBB& boxA, OBB& boxB, WorldEntity* nodeA, WorldEntity* nodeB)
538{
539  //HACK remove this again
540  this->owner = nodeA;
541  //   if( boxB == NULL || boxA == NULL)
542  //     return false;
543
544  /* first check all axis */
545  Vector t;
546  float rA = 0.0f;
547  float rB = 0.0f;
548  Vector l;
549  Vector rotAxisA[3];
550  Vector rotAxisB[3];
551
552  rotAxisA[0] =  nodeA->getAbsDir().apply(boxA.axis[0]);
553  rotAxisA[1] =  nodeA->getAbsDir().apply(boxA.axis[1]);
554  rotAxisA[2] =  nodeA->getAbsDir().apply(boxA.axis[2]);
555
556  rotAxisB[0] =  nodeB->getAbsDir().apply(boxB.axis[0]);
557  rotAxisB[1] =  nodeB->getAbsDir().apply(boxB.axis[1]);
558  rotAxisB[2] =  nodeB->getAbsDir().apply(boxB.axis[2]);
559
560
561  t = nodeA->getAbsCoor() + nodeA->getAbsDir().apply(boxA.center) - ( nodeB->getAbsCoor() + nodeB->getAbsDir().apply(boxB.center));
562
563  //   printf("\n");
564  //   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);
565  //   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);
566  //   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);
567  //
568  //   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);
569  //   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);
570  //   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);
571
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(3)("s = %f, rA+rB = %f\n", fabs(t.dot(l)), rA+rB);
589
590    if( (rA + rB) < fabs(t.dot(l)))
591    {
592      PRINTF(3)("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(3)("s = %f, rA+rB = %f\n", fabs(t.dot(l)), rA+rB);
613
614    if( (rA + rB) < fabs(t.dot(l)))
615    {
616      PRINTF(3)("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(3)("s = %f, rA+rB = %f\n", fabs(t.dot(l)), rA+rB);
641
642      if( (rA + rB) < fabs(t.dot(l)))
643      {
644        PRINTF(3)("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(3)("Kollision!\n");
656  return true;
657}
658
659
660
661
662
663
664
665
666
667
668/**
669 *
670 * draw the BV tree - debug mode
671 */
672void OBBTreeNode::drawBV(int depth, int drawMode, const Vector& color,  bool top) const
673{
674  /* this function can be used to draw the triangles and/or the points only  */
675  if( 1 /*drawMode & DRAW_MODEL || drawMode & DRAW_ALL*/)
676  {
677    if( depth == 0/*!(drawMode & DRAW_SINGLE && depth != 0)*/)
678    {
679      if( 1 /*drawMode & DRAW_POINTS*/)
680      {
681        glBegin(GL_POINTS);
682        glColor3f(0.3, 0.8, 0.54);
683        for( int i = 0; i < this->bvElement->modelInf->numVertices*3; i+=3)
684          glVertex3f(this->bvElement->modelInf->pVertices[i],
685                     this->bvElement->modelInf->pVertices[i+1],
686                     this->bvElement->modelInf->pVertices[i+2]);
687        glEnd();
688      }
689    }
690  }
691
692  if (top)
693  {
694    glPushAttrib(GL_ENABLE_BIT);
695    glDisable(GL_LIGHTING);
696    glDisable(GL_TEXTURE_2D);
697  }
698  glColor3f(color.x, color.y, color.z);
699
700
701  /* draw world axes */
702  if( 1 /*drawMode & DRAW_BV_AXIS*/)
703  {
704    glBegin(GL_LINES);
705    glColor3f(1.0, 0.0, 0.0);
706    glVertex3f(0.0, 0.0, 0.0);
707    glVertex3f(3.0, 0.0, 0.0);
708
709    glColor3f(0.0, 1.0, 0.0);
710    glVertex3f(0.0, 0.0, 0.0);
711    glVertex3f(0.0, 3.0, 0.0);
712
713    glColor3f(0.0, 0.0, 1.0);
714    glVertex3f(0.0, 0.0, 0.0);
715    glVertex3f(0.0, 0.0, 3.0);
716    glEnd();
717  }
718
719
720  if( 1/*drawMode & DRAW_BV_AXIS || drawMode & DRAW_ALL*/)
721  {
722    if( 1/*drawMode & DRAW_SINGLE && depth != 0*/)
723    {
724      /* draw the obb axes */
725      glBegin(GL_LINES);
726      glColor3f(1.0, 0.0, 0.0);
727      glVertex3f(this->bvElement->center.x, this->bvElement->center.y, this->bvElement->center.z);
728      glVertex3f(this->bvElement->center.x + this->bvElement->axis[0].x * this->bvElement->halfLength[0],
729                 this->bvElement->center.y + this->bvElement->axis[0].y * this->bvElement->halfLength[0],
730                 this->bvElement->center.z + this->bvElement->axis[0].z * this->bvElement->halfLength[0]);
731
732      glColor3f(0.0, 1.0, 0.0);
733      glVertex3f(this->bvElement->center.x, this->bvElement->center.y, this->bvElement->center.z);
734      glVertex3f(this->bvElement->center.x + this->bvElement->axis[1].x * this->bvElement->halfLength[1],
735                 this->bvElement->center.y + this->bvElement->axis[1].y * this->bvElement->halfLength[1],
736                 this->bvElement->center.z + this->bvElement->axis[1].z * this->bvElement->halfLength[1]);
737
738      glColor3f(0.0, 0.0, 1.0);
739      glVertex3f(this->bvElement->center.x, this->bvElement->center.y, this->bvElement->center.z);
740      glVertex3f(this->bvElement->center.x + this->bvElement->axis[2].x * this->bvElement->halfLength[2],
741                 this->bvElement->center.y + this->bvElement->axis[2].y * this->bvElement->halfLength[2],
742                 this->bvElement->center.z + this->bvElement->axis[2].z * this->bvElement->halfLength[2]);
743      glEnd();
744    }
745  }
746
747
748  /* DRAW POLYGONS */
749  if( drawMode & DRAW_BV_POLYGON || drawMode & DRAW_ALL || drawMode & DRAW_BV_BLENDED)
750  {
751    if (top)
752    {
753      glEnable(GL_BLEND);
754      glBlendFunc(GL_SRC_ALPHA, GL_ONE);
755    }
756
757    if( this->nodeLeft == NULL && this->nodeRight == NULL)
758      depth = 0;
759
760    if( depth == 0 /*!(drawMode & DRAW_SINGLE && depth != 0)*/)
761    {
762
763
764      Vector cen = this->bvElement->center;
765      Vector* axis = this->bvElement->axis;
766      float* len = this->bvElement->halfLength;
767
768      if( this->bvElement->bCollided)
769      {
770        glColor4f(1.0, 1.0, 1.0, .5); // COLLISION COLOR
771      }
772      else if( drawMode & DRAW_BV_BLENDED)
773      {
774        glColor4f(color.x, color.y, color.z, .5);
775      }
776
777      // debug out
778      if( this->obbTree->getOwner() != NULL)
779      {
780        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());
781      }
782      else
783        PRINTF(4)("debug poly draw: depth: %i, mode: %i\n", depth, drawMode);
784
785
786      /* draw bounding box */
787      if( drawMode & DRAW_BV_BLENDED)
788        glBegin(GL_QUADS);
789      else
790        glBegin(GL_LINE_LOOP);
791      glVertex3f(cen.x + axis[0].x * len[0] + axis[1].x * len[1] + axis[2].x * len[2],
792                 cen.y + axis[0].y * len[0] + axis[1].y * len[1] + axis[2].y * len[2],
793                 cen.z + axis[0].z * len[0] + axis[1].z * len[1] + axis[2].z * len[2]);
794      glVertex3f(cen.x + axis[0].x * len[0] + axis[1].x * len[1] - axis[2].x * len[2],
795                 cen.y + axis[0].y * len[0] + axis[1].y * len[1] - axis[2].y * len[2],
796                 cen.z + axis[0].z * len[0] + axis[1].z * len[1] - axis[2].z * len[2]);
797      glVertex3f(cen.x + axis[0].x * len[0] - axis[1].x * len[1] - axis[2].x * len[2],
798                 cen.y + axis[0].y * len[0] - axis[1].y * len[1] - axis[2].y * len[2],
799                 cen.z + axis[0].z * len[0] - axis[1].z * len[1] - axis[2].z * len[2]);
800      glVertex3f(cen.x + axis[0].x * len[0] - axis[1].x * len[1] + axis[2].x * len[2],
801                 cen.y + axis[0].y * len[0] - axis[1].y * len[1] + axis[2].y * len[2],
802                 cen.z + axis[0].z * len[0] - axis[1].z * len[1] + axis[2].z * len[2]);
803      glEnd();
804
805      if( drawMode & DRAW_BV_BLENDED)
806        glBegin(GL_QUADS);
807      else
808        glBegin(GL_LINE_LOOP);
809      glVertex3f(cen.x + axis[0].x * len[0] - axis[1].x * len[1] + axis[2].x * len[2],
810                 cen.y + axis[0].y * len[0] - axis[1].y * len[1] + axis[2].y * len[2],
811                 cen.z + axis[0].z * len[0] - axis[1].z * len[1] + axis[2].z * len[2]);
812      glVertex3f(cen.x + axis[0].x * len[0] - axis[1].x * len[1] - axis[2].x * len[2],
813                 cen.y + axis[0].y * len[0] - axis[1].y * len[1] - axis[2].y * len[2],
814                 cen.z + axis[0].z * len[0] - axis[1].z * len[1] - axis[2].z * len[2]);
815      glVertex3f(cen.x - axis[0].x * len[0] - axis[1].x * len[1] - axis[2].x * len[2],
816                 cen.y - axis[0].y * len[0] - axis[1].y * len[1] - axis[2].y * len[2],
817                 cen.z - axis[0].z * len[0] - axis[1].z * len[1] - axis[2].z * len[2]);
818      glVertex3f(cen.x - axis[0].x * len[0] - axis[1].x * len[1] + axis[2].x * len[2],
819                 cen.y - axis[0].y * len[0] - axis[1].y * len[1] + axis[2].y * len[2],
820                 cen.z - axis[0].z * len[0] - axis[1].z * len[1] + axis[2].z * len[2]);
821      glEnd();
822
823      if( drawMode & DRAW_BV_BLENDED)
824        glBegin(GL_QUADS);
825      else
826        glBegin(GL_LINE_LOOP);
827      glVertex3f(cen.x - axis[0].x * len[0] - axis[1].x * len[1] + axis[2].x * len[2],
828                 cen.y - axis[0].y * len[0] - axis[1].y * len[1] + axis[2].y * len[2],
829                 cen.z - axis[0].z * len[0] - axis[1].z * len[1] + axis[2].z * len[2]);
830      glVertex3f(cen.x - axis[0].x * len[0] - axis[1].x * len[1] - axis[2].x * len[2],
831                 cen.y - axis[0].y * len[0] - axis[1].y * len[1] - axis[2].y * len[2],
832                 cen.z - axis[0].z * len[0] - axis[1].z * len[1] - axis[2].z * len[2]);
833      glVertex3f(cen.x - axis[0].x * len[0] + axis[1].x * len[1] - axis[2].x * len[2],
834                 cen.y - axis[0].y * len[0] + axis[1].y * len[1] - axis[2].y * len[2],
835                 cen.z - axis[0].z * len[0] + axis[1].z * len[1] - axis[2].z * len[2]);
836      glVertex3f(cen.x - axis[0].x * len[0] + axis[1].x * len[1] + axis[2].x * len[2],
837                 cen.y - axis[0].y * len[0] + axis[1].y * len[1] + axis[2].y * len[2],
838                 cen.z - axis[0].z * len[0] + axis[1].z * len[1] + axis[2].z * len[2]);
839      glEnd();
840
841      if( drawMode & DRAW_BV_BLENDED)
842        glBegin(GL_QUADS);
843      else
844        glBegin(GL_LINE_LOOP);
845      glVertex3f(cen.x - axis[0].x * len[0] + axis[1].x * len[1] - axis[2].x * len[2],
846                 cen.y - axis[0].y * len[0] + axis[1].y * len[1] - axis[2].y * len[2],
847                 cen.z - axis[0].z * len[0] + axis[1].z * len[1] - axis[2].z * len[2]);
848      glVertex3f(cen.x - axis[0].x * len[0] + axis[1].x * len[1] + axis[2].x * len[2],
849                 cen.y - axis[0].y * len[0] + axis[1].y * len[1] + axis[2].y * len[2],
850                 cen.z - axis[0].z * len[0] + axis[1].z * len[1] + axis[2].z * len[2]);
851      glVertex3f(cen.x + axis[0].x * len[0] + axis[1].x * len[1] + axis[2].x * len[2],
852                 cen.y + axis[0].y * len[0] + axis[1].y * len[1] + axis[2].y * len[2],
853                 cen.z + axis[0].z * len[0] + axis[1].z * len[1] + axis[2].z * len[2]);
854      glVertex3f(cen.x + axis[0].x * len[0] + axis[1].x * len[1] - axis[2].x * len[2],
855                 cen.y + axis[0].y * len[0] + axis[1].y * len[1] - axis[2].y * len[2],
856                 cen.z + axis[0].z * len[0] + axis[1].z * len[1] - axis[2].z * len[2]);
857      glEnd();
858
859
860      if( drawMode & DRAW_BV_BLENDED)
861      {
862        glBegin(GL_QUADS);
863        glVertex3f(cen.x - axis[0].x * len[0] + axis[1].x * len[1] - axis[2].x * len[2],
864                   cen.y - axis[0].y * len[0] + axis[1].y * len[1] - axis[2].y * len[2],
865                   cen.z - axis[0].z * len[0] + axis[1].z * len[1] - axis[2].z * len[2]);
866        glVertex3f(cen.x + axis[0].x * len[0] + axis[1].x * len[1] - axis[2].x * len[2],
867                   cen.y + axis[0].y * len[0] + axis[1].y * len[1] - axis[2].y * len[2],
868                   cen.z + axis[0].z * len[0] + axis[1].z * len[1] - axis[2].z * len[2]);
869        glVertex3f(cen.x + axis[0].x * len[0] - axis[1].x * len[1] - axis[2].x * len[2],
870                   cen.y + axis[0].y * len[0] - axis[1].y * len[1] - axis[2].y * len[2],
871                   cen.z + axis[0].z * len[0] - axis[1].z * len[1] - axis[2].z * len[2]);
872        glVertex3f(cen.x - axis[0].x * len[0] - axis[1].x * len[1] - axis[2].x * len[2],
873                   cen.y - axis[0].y * len[0] - axis[1].y * len[1] - axis[2].y * len[2],
874                   cen.z - axis[0].z * len[0] - axis[1].z * len[1] - axis[2].z * len[2]);
875        glEnd();
876
877        glBegin(GL_QUADS);
878        glVertex3f(cen.x - axis[0].x * len[0] + axis[1].x * len[1] + axis[2].x * len[2],
879                   cen.y - axis[0].y * len[0] + axis[1].y * len[1] + axis[2].y * len[2],
880                   cen.z - axis[0].z * len[0] + axis[1].z * len[1] + axis[2].z * len[2]);
881        glVertex3f(cen.x + axis[0].x * len[0] + axis[1].x * len[1] + axis[2].x * len[2],
882                   cen.y + axis[0].y * len[0] + axis[1].y * len[1] + axis[2].y * len[2],
883                   cen.z + axis[0].z * len[0] + axis[1].z * len[1] + axis[2].z * len[2]);
884        glVertex3f(cen.x + axis[0].x * len[0] - axis[1].x * len[1] + axis[2].x * len[2],
885                   cen.y + axis[0].y * len[0] - axis[1].y * len[1] + axis[2].y * len[2],
886                   cen.z + axis[0].z * len[0] - axis[1].z * len[1] + axis[2].z * len[2]);
887        glVertex3f(cen.x - axis[0].x * len[0] - axis[1].x * len[1] + axis[2].x * len[2],
888                   cen.y - axis[0].y * len[0] - axis[1].y * len[1] + axis[2].y * len[2],
889                   cen.z - axis[0].z * len[0] - axis[1].z * len[1] + axis[2].z * len[2]);
890        glEnd();
891      }
892
893      if( drawMode & DRAW_BV_BLENDED)
894        glColor3f(color.x, color.y, color.z);
895    }
896  }
897
898  /* DRAW SEPARATING PLANE */
899  if( drawMode & DRAW_SEPARATING_PLANE || drawMode & DRAW_ALL)
900  {
901    if( !(drawMode & DRAW_SINGLE && depth != 0))
902    {
903      if( drawMode & DRAW_BV_BLENDED)
904        glColor4f(color.x, color.y, color.z, .6);
905
906      /* now draw the separation plane */
907      Vector a1 = this->bvElement->axis[(this->longestAxisIndex + 1)%3];
908      Vector a2 = this->bvElement->axis[(this->longestAxisIndex + 2)%3];
909      Vector c = this->bvElement->center;
910      float l1 = this->bvElement->halfLength[(this->longestAxisIndex + 1)%3];
911      float l2 = this->bvElement->halfLength[(this->longestAxisIndex + 2)%3];
912      glBegin(GL_QUADS);
913      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);
914      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);
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      glEnd();
918
919      if( drawMode & DRAW_BV_BLENDED)
920        glColor4f(color.x, color.y, color.z, 1.0);
921
922    }
923  }
924
925
926
927  if (depth > 0)
928  {
929    if( this->nodeLeft != NULL)
930      this->nodeLeft->drawBV(depth - 1, drawMode, Color::HSVtoRGB(Color::RGBtoHSV(color)+Vector(15.0,0.0,0.0)), false);
931    if( this->nodeRight != NULL)
932      this->nodeRight->drawBV(depth - 1, drawMode, Color::HSVtoRGB(Color::RGBtoHSV(color)+Vector(30.0,0.0,0.0)), false);
933  }
934  this->bvElement->bCollided = false;
935
936  if (top)
937    glPopAttrib();
938}
939
940
941
942void OBBTreeNode::debug() const
943{
944  PRINT(0)("========OBBTreeNode::debug()=====\n");
945  PRINT(0)(" Current depth: %i", this->depth);
946  PRINT(0)(" ");
947  PRINT(0)("=================================\n");
948}
Note: See TracBrowser for help on using the repository browser.