Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 7701 was 7668, checked in by patrick, 19 years ago

cd: most bugs found. but there is still at least one left: the axis are corrected in a wrong way. some more testing necessary

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