Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/presentation/src/lib/collision_detection/obb_tree_node.cc @ 9182

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

work flush

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