Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: to show, that the algorithm works also with more than 3 vertices:), code renicer

File size: 9.4 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
96
97  /* fist compute all the convex hull face/facelets and centroids */
98  for(int i = 0; i < length; i+=3)          /* FIX-ME-QUICK: hops of 3, array indiscontinuity*/
99    {
100      p = verticesList[i];
101      q = verticesList[i +1];
102      r = verticesList[i + 2];
103     
104      t1 = p - q; t2 = p - r;
105     
106      /* finding the facelet surface via cross-product */
107      facelet[i] = 0.5f * fabs( t1.cross(t2).len() );
108      /* update the entire convex hull surface */
109      face += facelet[i];
110
111      /* calculate the cetroid of the hull triangles */
112      centroid[i] = (p + q + r) * 1/3;
113      /* now calculate the centroid of the entire convex hull, weighted average of triangle centroids */
114      center += centroid[i] * facelet[i];
115    }
116  /* take the average of the centroid sum */
117  center /= face;
118
119
120 
121  /* now calculate the covariance matrix - if not written in three for-loops, it would compute faster: minor */
122  for(int j = 0; j < 3; ++j)
123    {
124      for(int k = 0; k < 3; ++k)
125        {
126          for(int i = 0; i < length; i+=3)
127            {
128              p = verticesList[i];
129              q = verticesList[i +1];
130              r = verticesList[i + 2];
131
132              covariance[j][k] = facelet[i] / (12.0f * face) * (9.0f * centroid[i][j] * centroid[i][k] + p[j]* p[k] +
133                                                                q[j] * q[k] + r[j]*r[k]) - center[j] * center[k];
134            }
135        }
136    }
137
138    printf("\nVertex Data:\n");
139    for(int i = 0; i < length; i++)
140    {
141      printf("vertex %i: %f, %f, %f\n", i, verticesList[i][0], verticesList[i][1], verticesList[i][2]);
142    }
143 
144  printf("\nCovariance Matrix:\n");
145  for(int j = 0; j < 3; ++j)
146    {
147      printf(" |");
148      for(int k = 0; k < 3; ++k)
149        {
150          printf(" \b%f ", covariance[j][k]);
151        }
152      printf(" |\n");
153    }
154  printf("center: %f, %f, %f\n\n", center.x, center.y, center.z);
155
156   
157  for(int i = 0; i < 3; ++i)
158    {
159   
160      box->covarianceMatrix[i][0] = covariance[i][0];
161      box->covarianceMatrix[i][1] = covariance[i][1];
162      box->covarianceMatrix[i][3] = covariance[i][2];
163    }
164  *box->center = center;
165
166
167  /* now getting spanning vectors of the sub-space:
168     the eigenvectors of a symmertric matrix, such as the
169     covarience matrix are mutually orthogonal.
170     after normalizing them, they can be used as a the basis
171     vectors
172  */
173  Matrix                V(3,3);                               //!< for eigenvectors
174  DiagonalMatrix        D(3);                                 //!< for eigenvalues   
175  SymmetricMatrix       C(3);                                 //!< for the covariance symmetrical matrix
176  Vector**              axis = new Vector*[3];                //!< the references to the obb axis
177 
178  C(1,1) = covariance[0][0];
179  C(1,2) = covariance[0][1];
180  C(1,3) = covariance[0][2];
181  C(2,1) = covariance[1][0];   
182  C(2,2) = covariance[1][1];
183  C(2,3) = covariance[1][2]; 
184  C(3,1) = covariance[2][0];
185  C(3,2) = covariance[2][1];
186  C(3,3) = covariance[2][2];
187
188  Jacobi(C, D, V);                                            /* do the jacobi decomposition */
189
190  printf("we got a result! YES: \n");
191
192  for(int j = 1; j < 4; ++j)
193  {
194    printf(" |");
195    for(int k = 1; k < 4; ++k)
196    {
197      printf(" \b%f ", V(j, k));
198    }
199    printf(" |\n");
200  }
201
202  axis[0] = new Vector(V(1, 1), V(2, 1), V(3, 1));
203  axis[1] = new Vector(V(1, 2), V(2, 2), V(3, 2));
204  axis[2] = new Vector(V(1, 3), V(2, 3), V(3, 3));
205  box->axis = axis;
206 
207  printf("eigenvector: %f, %f, %f\n", box->axis[0]->x, box->axis[0]->y, box->axis[0]->z);
208  printf("eigenvector: %f, %f, %f\n", box->axis[1]->x, box->axis[1]->y, box->axis[1]->z);
209  printf("eigenvector: %f, %f, %f\n", box->axis[2]->x, box->axis[2]->y, box->axis[2]->z);
210
211 
212  /* now get the axis length */
213  Line                ax[3];                                 //!< the axis
214  float*              halfLength = new float[3];             //!< half length of the axis
215  float               tmpLength;                             //!< tmp save point for the length
216 
217  ax[0].r = *box->center; ax[0].a = *box->axis[0];
218  ax[1].r = *box->center; ax[1].a = *box->axis[1];
219  ax[2].r = *box->center; ax[2].a = *box->axis[2];
220
221  Plane p0(*box->axis[0], *box->center);
222  Plane p1(*box->axis[1], *box->center);
223  Plane p2(*box->axis[2], *box->center);
224 
225
226
227  halfLength[0] = 0.0f;
228  for(int j = 0; j < length; ++j)
229  {
230    tmpLength = p0.distancePoint(vertices[j]);
231    if( tmpLength > halfLength[0])
232      halfLength[0] = tmpLength;
233  }
234
235
236  halfLength[1] = 0.0f;
237  for(int j = 0; j < length; ++j)
238  {
239    tmpLength = p1.distancePoint(vertices[j]);
240    if( tmpLength > halfLength[1])
241      halfLength[1] = tmpLength;
242  }
243
244  halfLength[2] = 0.0f;
245  for(int j = 0; j < length; ++j)
246  {
247    tmpLength = p2.distancePoint(vertices[j]);
248    if( tmpLength > halfLength[2])
249      halfLength[2] = tmpLength;
250  }
251
252  box->halfLength = halfLength;
253
254 
255 
256  printf("we got length: \n");
257  for(int i = 0; i < 3; ++i)
258    printf("length[%i] = %f\n", i, box->halfLength[i]);
259}
260
261
262void OBBTreeNode::forkBox(OBB* box)
263{
264  /* get the longest axis of the box */
265  float aLength = -1.0f;
266  int axisNr = 0;
267  for(int i = 0; i < 3; ++i)
268    {
269      if( aLength < box->axis[i]->len())
270        {
271          aLength = box->axis[i]->len();
272          axisNr = i;
273        }
274    }
275 
276  /* get the closest vertex near the center */
277 
278}
279
280
281void OBBTreeNode::collideWith(const BVTree &tree)
282{}
283
284
285void OBBTreeNode::drawBV(int currentDepth, const int depth) const
286{
287  glBegin(GL_LINE_LOOP);
288  glColor3f(1.0, 1.0, 1.0);
289  for(int i = 0; i < this->numOfVertices; ++i)
290    {
291      glVertex3f(this->vertices[i][0], this->vertices[i][1], this->vertices[i][2]);
292      //printf("v(%f, %f, %f)\n", this->vertices[i][0], this->vertices[i][1], this->vertices[i][2]);
293    }
294  glEnd();
295}
296
297
298void OBBTreeNode::drawBVPolygon(int currentDepth, const int depth) const
299{
300  glBegin(GL_LINES);
301  glColor3f(0.0, 0.4, 0.3);
302  glVertex3f(this->bvElement->center->x, this->bvElement->center->y, this->bvElement->center->z);
303  glVertex3f(this->bvElement->center->x + this->bvElement->axis[0]->x * this->bvElement->halfLength[0],
304             this->bvElement->center->y + this->bvElement->axis[0]->y * this->bvElement->halfLength[0],
305             this->bvElement->center->z + this->bvElement->axis[0]->z * this->bvElement->halfLength[0]);
306 
307  glVertex3f(this->bvElement->center->x, this->bvElement->center->y, this->bvElement->center->z);
308  glVertex3f(this->bvElement->center->x + this->bvElement->axis[1]->x * this->bvElement->halfLength[1],
309             this->bvElement->center->y + this->bvElement->axis[1]->y * this->bvElement->halfLength[1],
310             this->bvElement->center->z + this->bvElement->axis[1]->z * this->bvElement->halfLength[1]);
311
312  glVertex3f(this->bvElement->center->x, this->bvElement->center->y, this->bvElement->center->z);
313  glVertex3f(this->bvElement->center->x + this->bvElement->axis[2]->x * this->bvElement->halfLength[2],
314             this->bvElement->center->y + this->bvElement->axis[2]->y * this->bvElement->halfLength[2],
315             this->bvElement->center->z + this->bvElement->axis[2]->z * this->bvElement->halfLength[2]);
316  glEnd();
317}
318
319
320void OBBTreeNode::drawBVBlended(int currentDepth, const int depth) const
321{}
322
323
324void OBBTreeNode::debug()
325{
326
327  /*
328  for(int i = 0; i < length; i++)
329    {
330      printf("vertex %i: %f, %f, %f\n", i, verticesList[i][0], verticesList[i][1], verticesList[i][2]);
331    }
332  */
333}
Note: See TracBrowser for help on using the repository browser.