Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/multi_player_map/src/lib/collision_detection/obb_tree_node.cc @ 8849

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

collision detection works now

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