Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: partition the vertices into two different lists

File size: 16.5 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   co-programmer: ...
14*/
15
16#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_COLLISION
17
18#include "obb_tree_node.h"
19#include "list.h"
20#include "obb.h"
21#include "vector.h"
22#include "abstract_model.h"
23
24#include <math.h>
25
26
27#define WANT_STREAM
28#define WANT_MATH
29#define WANT_FSTREAM
30
31
32#include "include.h"
33#include "newmat.h"
34#include "newmatap.h"
35#include "newmatio.h"
36
37
38
39
40using namespace std;
41
42
43/**
44   \brief standard constructor
45*/
46OBBTreeNode::OBBTreeNode ()
47{
48   this->setClassID(CL_OBB_TREE_NODE, "OBBTreeNode");
49
50}
51
52
53/**
54   \brief standard deconstructor
55
56*/
57OBBTreeNode::~OBBTreeNode ()
58{
59  // delete what has to be deleted here
60}
61
62
63
64/**
65   \brief creates a new BVTree or BVTree partition
66   \param depth: the depth of the tree
67   \param verticesList: the list of vertices of the object - each vertices triple is interpreted as a triangle
68*/
69void OBBTreeNode::spawnBVTree(const int depth, sVec3D *verticesList, const int length)
70{
71  this->bvElement = this->createBox();
72  this->calculateBoxAttributes(this->bvElement, verticesList, length);
73  this->forkBox(this->bvElement);
74}
75
76
77OBB* OBBTreeNode::createBox()
78{
79  return new OBB();
80}
81
82
83void OBBTreeNode::calculateBoxAttributes(OBB* box, sVec3D* verticesList, int length)
84{
85  float     facelet[length];                         //!< surface area of the i'th triangle of the convex hull
86  float     face;                                    //!< surface area of the entire convex hull
87  Vector    centroid[length];                        //!< centroid of the i'th convex hull
88  Vector    center;                                  //!< the center of the entire hull
89  Vector    p, q, r;                                 //!< holder of the polygon data, much more conveniant to work with Vector than sVec3d
90  Vector    t1, t2;                                  //!< temporary values
91  float     covariance[3][3];                        //!< the covariance matrix
92
93  this->numOfVertices = length;
94  this->vertices = verticesList;
95  box->vertices = verticesList;
96  box->numOfVertices = length;
97
98
99  /* fist compute all the convex hull face/facelets and centroids */
100  for(int i = 0; i < length; i+=3)          /* FIX-ME-QUICK: hops of 3, array indiscontinuity*/
101    {
102      p = verticesList[i];
103      q = verticesList[i +1];
104      r = verticesList[i + 2];
105
106      t1 = p - q; t2 = p - r;
107
108      /* finding the facelet surface via cross-product */
109      facelet[i] = 0.5f * fabs( t1.cross(t2).len() );
110      /* update the entire convex hull surface */
111      face += facelet[i];
112
113      /* calculate the cetroid of the hull triangles */
114      centroid[i] = (p + q + r) * 1/3;
115      /* now calculate the centroid of the entire convex hull, weighted average of triangle centroids */
116      center += centroid[i] * facelet[i];
117    }
118  /* take the average of the centroid sum */
119  center /= face;
120
121
122
123  /* now calculate the covariance matrix - if not written in three for-loops, it would compute faster: minor */
124  for(int j = 0; j < 3; ++j)
125    {
126      for(int k = 0; k < 3; ++k)
127        {
128          for(int i = 0; i < length; i+=3)
129            {
130              p = verticesList[i];
131              q = verticesList[i +1];
132              r = verticesList[i + 2];
133
134              covariance[j][k] = facelet[i] / (12.0f * face) * (9.0f * centroid[i][j] * centroid[i][k] + p[j]* p[k] +
135                                                                q[j] * q[k] + r[j]*r[k]) - center[j] * center[k];
136            }
137        }
138    }
139
140    printf("\nVertex Data:\n");
141    for(int i = 0; i < length; i++)
142    {
143      printf("vertex %i: %f, %f, %f\n", i, verticesList[i][0], verticesList[i][1], verticesList[i][2]);
144    }
145
146  printf("\nCovariance Matrix:\n");
147  for(int j = 0; j < 3; ++j)
148    {
149      printf(" |");
150      for(int k = 0; k < 3; ++k)
151        {
152          printf(" \b%f ", covariance[j][k]);
153        }
154      printf(" |\n");
155    }
156  printf("center: %f, %f, %f\n\n", center.x, center.y, center.z);
157
158
159  for(int i = 0; i < 3; ++i)
160    {
161
162      box->covarianceMatrix[i][0] = covariance[i][0];
163      box->covarianceMatrix[i][1] = covariance[i][1];
164      box->covarianceMatrix[i][3] = covariance[i][2];
165    }
166  *box->center = center;
167
168
169  /* now getting spanning vectors of the sub-space:
170     the eigenvectors of a symmertric matrix, such as the
171     covarience matrix are mutually orthogonal.
172     after normalizing them, they can be used as a the basis
173     vectors
174  */
175  Matrix                V(3,3);                               //!< for eigenvectors
176  DiagonalMatrix        D(3);                                 //!< for eigenvalues
177  SymmetricMatrix       C(3);                                 //!< for the covariance symmetrical matrix
178  Vector**              axis = new Vector*[3];                //!< the references to the obb axis
179
180  C(1,1) = covariance[0][0];
181  C(1,2) = covariance[0][1];
182  C(1,3) = covariance[0][2];
183  C(2,1) = covariance[1][0];
184  C(2,2) = covariance[1][1];
185  C(2,3) = covariance[1][2];
186  C(3,1) = covariance[2][0];
187  C(3,2) = covariance[2][1];
188  C(3,3) = covariance[2][2];
189
190  Jacobi(C, D, V);                                            /* do the jacobi decomposition */
191
192  printf("\nwe got a result! YES: \n");
193
194  for(int j = 1; j < 4; ++j)
195  {
196    printf(" |");
197    for(int k = 1; k < 4; ++k)
198    {
199      printf(" \b%f ", V(j, k));
200    }
201    printf(" |\n");
202  }
203
204  axis[0] = new Vector(V(1, 1), V(2, 1), V(3, 1));
205  axis[1] = new Vector(V(1, 2), V(2, 2), V(3, 2));
206  axis[2] = new Vector(V(1, 3), V(2, 3), V(3, 3));
207  box->axis = axis;
208
209  printf("\neigenvector: %f, %f, %f\n", box->axis[0]->x, box->axis[0]->y, box->axis[0]->z);
210  printf("eigenvector: %f, %f, %f\n", box->axis[1]->x, box->axis[1]->y, box->axis[1]->z);
211  printf("eigenvector: %f, %f, %f\n", box->axis[2]->x, box->axis[2]->y, box->axis[2]->z);
212
213
214  /* now get the axis length */
215  Line                ax[3];                                 //!< the axis
216  float*              halfLength = new float[3];             //!< half length of the axis
217  float               tmpLength;                             //!< tmp save point for the length
218  Plane               p0(*box->axis[0], *box->center);       //!< the axis planes
219  Plane               p1(*box->axis[1], *box->center);
220  Plane               p2(*box->axis[2], *box->center);
221
222  halfLength[0] = -1.0f;
223  for(int j = 0; j < length; ++j)
224  {
225    tmpLength = fabs(p0.distancePoint(vertices[j]));
226    if( tmpLength > halfLength[0])
227      halfLength[0] = tmpLength;
228  }
229
230  halfLength[1] = -1.0f;
231  for(int j = 0; j < length; ++j)
232  {
233    tmpLength = fabs(p1.distancePoint(vertices[j]));
234    if( tmpLength > halfLength[1])
235      halfLength[1] = tmpLength;
236  }
237
238  halfLength[2] = -1.0f;
239  for(int j = 0; j < length; ++j)
240  {
241    tmpLength = fabs(p2.distancePoint(vertices[j]));
242    if( tmpLength > halfLength[2])
243      halfLength[2] = tmpLength;
244  }
245
246  box->halfLength = halfLength;
247
248
249  printf("\nwe got length: \n");
250  for(int i = 0; i < 3; ++i)
251    printf("length[%i] = %f\n", i, box->halfLength[i]);
252}
253
254
255
256/**
257  \brief this separates an ob-box in the middle
258  \param box: the box to separate
259
260  this will separate the box into to smaller boxes. the separation is done along the middle of the longest axis
261 */
262void OBBTreeNode::forkBox(OBB* box)
263{
264  /* get the longest axis of the box */
265  float               aLength = -1.0f;                     //!< the length of the longest axis
266  int                 axisIndex = 0;                       //!< this is the nr of the longest axis
267
268  for(int i = 0; i < 3; ++i)
269  {
270    if( aLength < box->halfLength[i])
271    {
272      aLength = box->halfLength[i];
273      axisIndex = i;
274    }
275  }
276
277  printf("\nlongest axis is: nr %i with a half-length of: %f\n", axisIndex, aLength);
278
279
280  /* get the closest vertex near the center */
281  float               dist = 999999.0f;                    //!< the smallest distance to each vertex
282  float               tmpDist;                             //!< temporary distance
283  int                 vertexIndex;
284  Plane               middlePlane(*box->axis[axisIndex], *box->center); //!< the middle plane
285
286  for(int i = 0; i < box->numOfVertices; ++i)
287  {
288    tmpDist = fabs(middlePlane.distancePoint(box->vertices[i]));
289    if( tmpDist < dist)
290    {
291      dist = tmpDist;
292      vertexIndex = i;
293    }
294  }
295
296  printf("\nthe clostest vertex is nr: %i, with a dist of: %f\n", vertexIndex ,dist);
297
298
299  /* now definin the separation plane through this specified nearest point and partition
300    the points depending on which side they are located
301  */
302  Plane              separationPlane(*box->axis[axisIndex], box->vertices[vertexIndex]);  //!< separation plane
303  tList<sVec3D>      partition1;                           //!< the vertex partition 1
304  tList<sVec3D>      partition2;                           //!< the vertex partition 2
305
306  for(int i = 0; i < box->numOfVertices; ++i)
307  {
308    if( separationPlane.distancePoint(box->vertices[i]) > 0.0f)
309      partition1.add(&box->vertices[i]);
310    else
311      partition2.add(&box->vertices[i]);
312  }
313  partition2.add(&box->vertices[vertexIndex]);
314
315  printf("\npartition1: got %i vertices/ partition 2: got %i vertices\n", partition1.getSize(), partition2.getSize());
316
317}
318
319
320void OBBTreeNode::collideWith(const BVTree &tree)
321{}
322
323
324void OBBTreeNode::drawBV(int currentDepth, const int depth) const
325{
326  glBegin(GL_LINE_LOOP);
327  glColor3f(1.0, 1.0, 1.0);
328  for(int i = 0; i < this->bvElement->numOfVertices; ++i)
329    {
330      glVertex3f(this->bvElement->vertices[i][0], this->bvElement->vertices[i][1], this->bvElement->vertices[i][2]);
331      //printf("v(%f, %f, %f)\n", this->vertices[i][0], this->vertices[i][1], this->vertices[i][2]);
332    }
333  glEnd();
334}
335
336
337void OBBTreeNode::drawBVPolygon(int currentDepth, const int depth) const
338{
339
340  /* draw world axes */
341  glBegin(GL_LINES);
342  glColor3f(0.0, 0.4, 0.3);
343  glVertex3f(0.0, 0.0, 0.0);
344  glVertex3f(3.0, 0.0, 0.0);
345
346  glVertex3f(0.0, 0.0, 0.0);
347  glVertex3f(0.0, 3.0, 0.0);
348
349  glVertex3f(0.0, 0.0, 0.0);
350  glVertex3f(0.0, 0.0, 3.0);
351  glEnd();
352
353
354
355  /* draw the obb axes */
356  glBegin(GL_LINES);
357  glColor3f(0.0, 0.4, 0.3);
358  glVertex3f(this->bvElement->center->x, this->bvElement->center->y, this->bvElement->center->z);
359  glVertex3f(this->bvElement->center->x + this->bvElement->axis[0]->x * this->bvElement->halfLength[0],
360             this->bvElement->center->y + this->bvElement->axis[0]->y * this->bvElement->halfLength[0],
361             this->bvElement->center->z + this->bvElement->axis[0]->z * this->bvElement->halfLength[0]);
362
363  glVertex3f(this->bvElement->center->x, this->bvElement->center->y, this->bvElement->center->z);
364  glVertex3f(this->bvElement->center->x + this->bvElement->axis[1]->x * this->bvElement->halfLength[1],
365             this->bvElement->center->y + this->bvElement->axis[1]->y * this->bvElement->halfLength[1],
366             this->bvElement->center->z + this->bvElement->axis[1]->z * this->bvElement->halfLength[1]);
367
368  glVertex3f(this->bvElement->center->x, this->bvElement->center->y, this->bvElement->center->z);
369  glVertex3f(this->bvElement->center->x + this->bvElement->axis[2]->x * this->bvElement->halfLength[2],
370             this->bvElement->center->y + this->bvElement->axis[2]->y * this->bvElement->halfLength[2],
371             this->bvElement->center->z + this->bvElement->axis[2]->z * this->bvElement->halfLength[2]);
372  glEnd();
373
374
375  Vector cen = *this->bvElement->center;
376  Vector** axis = this->bvElement->axis;
377  float* len = this->bvElement->halfLength;
378
379  /* draw bounding box */
380  glBegin(GL_LINE_LOOP);
381  glColor3f(0.3, 0.4, 0.7);
382  glVertex3f(cen.x + axis[0]->x * len[0] + axis[1]->x * len[1] + axis[2]->x * len[2],
383             cen.y + axis[0]->y * len[0] + axis[1]->y * len[1] + axis[2]->y * len[2],
384             cen.z + axis[0]->z * len[0] + axis[1]->z * len[1] + axis[2]->z * len[2]);
385  glVertex3f(cen.x + axis[0]->x * len[0] + axis[1]->x * len[1] - axis[2]->x * len[2],
386             cen.y + axis[0]->y * len[0] + axis[1]->y * len[1] - axis[2]->y * len[2],
387             cen.z + axis[0]->z * len[0] + axis[1]->z * len[1] - axis[2]->z * len[2]);
388  glVertex3f(cen.x + axis[0]->x * len[0] - axis[1]->x * len[1] - axis[2]->x * len[2],
389             cen.y + axis[0]->y * len[0] - axis[1]->y * len[1] - axis[2]->y * len[2],
390             cen.z + axis[0]->z * len[0] - axis[1]->z * len[1] - axis[2]->z * len[2]);
391  glVertex3f(cen.x + axis[0]->x * len[0] - axis[1]->x * len[1] + axis[2]->x * len[2],
392             cen.y + axis[0]->y * len[0] - axis[1]->y * len[1] + axis[2]->y * len[2],
393             cen.z + axis[0]->z * len[0] - axis[1]->z * len[1] + axis[2]->z * len[2]);
394  glEnd();
395
396  glBegin(GL_LINE_LOOP);
397  glVertex3f(cen.x + axis[0]->x * len[0] - axis[1]->x * len[1] + axis[2]->x * len[2],
398             cen.y + axis[0]->y * len[0] - axis[1]->y * len[1] + axis[2]->y * len[2],
399             cen.z + axis[0]->z * len[0] - axis[1]->z * len[1] + axis[2]->z * len[2]);
400  glVertex3f(cen.x + axis[0]->x * len[0] - axis[1]->x * len[1] - axis[2]->x * len[2],
401             cen.y + axis[0]->y * len[0] - axis[1]->y * len[1] - axis[2]->y * len[2],
402             cen.z + axis[0]->z * len[0] - axis[1]->z * len[1] - axis[2]->z * len[2]);
403  glVertex3f(cen.x - axis[0]->x * len[0] - axis[1]->x * len[1] - axis[2]->x * len[2],
404             cen.y - axis[0]->y * len[0] - axis[1]->y * len[1] - axis[2]->y * len[2],
405             cen.z - axis[0]->z * len[0] - axis[1]->z * len[1] - axis[2]->z * len[2]);
406  glVertex3f(cen.x - axis[0]->x * len[0] - axis[1]->x * len[1] + axis[2]->x * len[2],
407             cen.y - axis[0]->y * len[0] - axis[1]->y * len[1] + axis[2]->y * len[2],
408             cen.z - axis[0]->z * len[0] - axis[1]->z * len[1] + axis[2]->z * len[2]);
409  glEnd();
410
411  glBegin(GL_LINE_LOOP);
412  glVertex3f(cen.x - axis[0]->x * len[0] - axis[1]->x * len[1] + axis[2]->x * len[2],
413             cen.y - axis[0]->y * len[0] - axis[1]->y * len[1] + axis[2]->y * len[2],
414             cen.z - axis[0]->z * len[0] - axis[1]->z * len[1] + axis[2]->z * len[2]);
415  glVertex3f(cen.x - axis[0]->x * len[0] - axis[1]->x * len[1] - axis[2]->x * len[2],
416             cen.y - axis[0]->y * len[0] - axis[1]->y * len[1] - axis[2]->y * len[2],
417             cen.z - axis[0]->z * len[0] - axis[1]->z * len[1] - axis[2]->z * len[2]);
418  glVertex3f(cen.x - axis[0]->x * len[0] + axis[1]->x * len[1] - axis[2]->x * len[2],
419             cen.y - axis[0]->y * len[0] + axis[1]->y * len[1] - axis[2]->y * len[2],
420             cen.z - axis[0]->z * len[0] + axis[1]->z * len[1] - axis[2]->z * len[2]);
421  glVertex3f(cen.x - axis[0]->x * len[0] + axis[1]->x * len[1] + axis[2]->x * len[2],
422             cen.y - axis[0]->y * len[0] + axis[1]->y * len[1] + axis[2]->y * len[2],
423             cen.z - axis[0]->z * len[0] + axis[1]->z * len[1] + axis[2]->z * len[2]);
424  glEnd();
425
426  glBegin(GL_LINE_LOOP);
427  glVertex3f(cen.x - axis[0]->x * len[0] + axis[1]->x * len[1] - axis[2]->x * len[2],
428             cen.y - axis[0]->y * len[0] + axis[1]->y * len[1] - axis[2]->y * len[2],
429             cen.z - axis[0]->z * len[0] + axis[1]->z * len[1] - axis[2]->z * len[2]);
430  glVertex3f(cen.x - axis[0]->x * len[0] + axis[1]->x * len[1] + axis[2]->x * len[2],
431             cen.y - axis[0]->y * len[0] + axis[1]->y * len[1] + axis[2]->y * len[2],
432             cen.z - axis[0]->z * len[0] + axis[1]->z * len[1] + axis[2]->z * len[2]);
433  glVertex3f(cen.x + axis[0]->x * len[0] + axis[1]->x * len[1] + axis[2]->x * len[2],
434             cen.y + axis[0]->y * len[0] + axis[1]->y * len[1] + axis[2]->y * len[2],
435             cen.z + axis[0]->z * len[0] + axis[1]->z * len[1] + axis[2]->z * len[2]);
436  glVertex3f(cen.x + axis[0]->x * len[0] + axis[1]->x * len[1] - axis[2]->x * len[2],
437             cen.y + axis[0]->y * len[0] + axis[1]->y * len[1] - axis[2]->y * len[2],
438             cen.z + axis[0]->z * len[0] + axis[1]->z * len[1] - axis[2]->z * len[2]);
439  glEnd();
440
441/*
442  glVertex3f(cen.x - axis[0]->x * len[0] + axis[1]->x * len[1] - axis[2]->x * len[2],
443             cen.y - axis[0]->y * len[0] + axis[1]->y * len[1] - axis[2]->y * len[2],
444             cen.z - axis[0]->z * len[0] + axis[1]->z * len[1] - axis[2]->z * len[2]);
445  glVertex3f(cen.x - axis[0]->x * len[0] + axis[1]->x * len[1] + axis[2]->x * len[2],
446             cen.y - axis[0]->y * len[0] + axis[1]->y * len[1] + axis[2]->y * len[2],
447             cen.z - axis[0]->z * len[0] + axis[1]->z * len[1] + axis[2]->z * len[2]);*/
448
449
450  glEnd();
451
452
453}
454
455
456void OBBTreeNode::drawBVBlended(int currentDepth, const int depth) const
457{}
458
459
460void OBBTreeNode::debug()
461{
462
463  /*
464  for(int i = 0; i < length; i++)
465    {
466      printf("vertex %i: %f, %f, %f\n", i, verticesList[i][0], verticesList[i][1], verticesList[i][2]);
467    }
468  */
469}
Note: See TracBrowser for help on using the repository browser.