Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

moved some of the importer sources, probably will need to rebuild the project

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