Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/cr/src/lib/collision_detection/obb_tree_node.cc @ 7944

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

cr: collision registration work

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