Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/lib/collision_detection/obb_tree_node.cc @ 7732

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

orxonox: removed a memory leak

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