TORCS  1.3.9
The Open Racing Car Simulator
BBoxTree.cpp
Go to the documentation of this file.
1 /*
2  SOLID - Software Library for Interference Detection
3  Copyright (C) 1997-1998 Gino van den Bergen
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Library General Public
7  License as published by the Free Software Foundation; either
8  version 2 of the License, or (at your option) any later version.
9 
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Library General Public License for more details.
14 
15  You should have received a copy of the GNU Library General Public
16  License along with this library; if not, write to the Free
17  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 
19  Please send remarks, questions and bug reports to gino@win.tue.nl,
20  or write to:
21  Gino van den Bergen
22  Department of Mathematics and Computing Science
23  Eindhoven University of Technology
24  P.O. Box 513, 5600 MB Eindhoven, The Netherlands
25 */
26 
27 #ifdef _MSC_VER
28 #pragma warning(disable:4786) // identifier was truncated to '255'
29 #endif // _MSC_VER
30 
31 #include "BBoxTree.h"
32 #include "Transform.h"
33 
34 #include <algorithm>
35 #include <new>
36 
37 class BBoxCompAxis {
38 public:
39  int axis;
40  bool operator()(const BBoxNode& p1, const BBoxNode& p2) const {
41  return p1.bbox.getCenter()[axis] < p2.bbox.getCenter()[axis];
42  }
43  BBoxCompAxis(int a) : axis(a) {}
44 } bboxCompAxis[3] = { X, Y, Z };
45 
46 
47 extern BBoxInternal *free_node;
48 
50  bbox.setEmpty();
51  for (int i = 0; i < poly->numVerts(); ++i) {
52  bbox.include((*poly)[i]);
53  }
54 }
55 
57  tag = INTERNAL;
58  bbox.setEmpty();
59  for (int j = 0; j < n; ++j) {
60  bbox.include(l[j].bbox);
61  }
62 
63  int axis = bbox.longestAxis();
64  int i = 0, mid = n;
65  while (i < mid) {
66  if (l[i].bbox.getCenter()[axis] < bbox.getCenter()[axis]) ++i;
67  else swap(l[i], l[--mid]);
68  }
69  if (mid == 0 || mid == n) mid = n / 2;
70 
71  if (mid >= 2) {
72  rson = free_node;
73  new(free_node++) BBoxInternal(mid, &l[0]);
74  }
75  else rson = &l[0];
76  if (n - mid >= 2) {
77  lson = free_node;
78  new(free_node++) BBoxInternal(n - mid, &l[mid]);
79  }
80  else lson = &l[mid];
81 }
82 
83 #ifdef STATISTICS
84 int num_box_tests = 0;
85 #endif
86 
87 inline bool sep_axes_test(const Vector& a, const Vector& b,
88  const Matrix& abs_b2a, const Vector& pos_b2a,
89  const Matrix& abs_a2b, const Vector& pos_a2b) {
90 #ifdef STATISTICS
91  ++num_box_tests;
92 #endif
93 
94  if (a[X] + dot(abs_b2a[X], b) < fabs(pos_b2a[X])) return false;
95  if (a[Y] + dot(abs_b2a[Y], b) < fabs(pos_b2a[Y])) return false;
96  if (a[Z] + dot(abs_b2a[Z], b) < fabs(pos_b2a[Z])) return false;
97 
98  if (b[X] + dot(abs_a2b[X], a) < fabs(pos_a2b[X])) return false;
99  if (b[Y] + dot(abs_a2b[Y], a) < fabs(pos_a2b[Y])) return false;
100  if (b[Z] + dot(abs_a2b[Z], a) < fabs(pos_a2b[Z])) return false;
101 
102  return true;
103 }
104 
105 inline bool intersect(const BBox& a, const BBox& b,
106  const Transform& b2a, const Matrix& abs_b2a,
107  const Transform& a2b, const Matrix& abs_a2b) {
108  return sep_axes_test(a.getExtent(), b.getExtent(),
109  abs_b2a, b2a(b.getCenter()) - a.getCenter(),
110  abs_a2b, a2b(a.getCenter()) - b.getCenter());
111 }
112 
113 
114 
115 bool intersect(const BBoxNode *tree, const Convex& c, const BBox& bb,
116  const Transform& b2a, Vector& v) {
117  if (!intersect(tree->bbox, bb)) return false;
118 
119  if (tree->tag == BBoxNode::LEAF)
120  return intersect(*((const BBoxLeaf *)tree)->poly, c, b2a, v);
121  else {
122  return intersect(((const BBoxInternal *)tree)->lson, c, bb, b2a, v) ||
123  intersect(((const BBoxInternal *)tree)->rson, c, bb, b2a, v);
124  }
125 }
126 
127 
128 bool intersect(const BBoxNode *a, const BBoxNode *b,
129  const Transform& b2a, const Matrix& abs_b2a,
130  const Transform& a2b, const Matrix& abs_a2b, Vector& v) {
131  if (!intersect(a->bbox, b->bbox, b2a, abs_b2a, a2b, abs_a2b)) return false;
132 
133  if (a->tag == BBoxNode::LEAF && b->tag == BBoxNode::LEAF) {
134  return intersect(*((const BBoxLeaf *)a)->poly,
135  *((const BBoxLeaf *)b)->poly, b2a, v);
136  }
137  else if (a->tag == BBoxNode::LEAF ||
138  (b->tag != BBoxNode::LEAF && a->bbox.size() < b->bbox.size())) {
139  return
140  intersect(a, ((const BBoxInternal *)b)->lson,
141  b2a, abs_b2a, a2b, abs_a2b, v) ||
142  intersect(a, ((const BBoxInternal *)b)->rson,
143  b2a, abs_b2a, a2b, abs_a2b, v);
144  }
145  else {
146  return
147  intersect(((const BBoxInternal *)a)->lson, b, b2a, abs_b2a, a2b, abs_a2b, v) ||
148  intersect(((const BBoxInternal *)a)->rson, b, b2a, abs_b2a, a2b, abs_a2b, v);
149  }
150 }
151 
152 
153 
154 bool find_prim(const BBoxNode *tree, const Convex& c, const BBox& bb,
155  const Transform& b2a, Vector& v, ShapePtr& p) {
156  if (!intersect(tree->bbox, bb)) return false;
157 
158  if (tree->tag == BBoxNode::LEAF) {
159  if (intersect(*((const BBoxLeaf *)tree)->poly, c, b2a, v)) {
160  p = ((const BBoxLeaf *)tree)->poly;
161  return true;
162  }
163  else return false;
164  }
165  else {
166  return find_prim(((const BBoxInternal *)tree)->lson, c, bb, b2a, v, p) ||
167  find_prim(((const BBoxInternal *)tree)->rson, c, bb, b2a, v, p);
168  }
169 }
170 
171 
172 bool find_prim(const BBoxNode *a, const BBoxNode *b,
173  const Transform& b2a, const Matrix& abs_b2a,
174  const Transform& a2b, const Matrix& abs_a2b,
175  Vector& v, ShapePtr& pa, ShapePtr& pb) {
176  if (!intersect(a->bbox, b->bbox, b2a, abs_b2a, a2b, abs_a2b)) return false;
177 
178  if (a->tag == BBoxNode::LEAF && b->tag == BBoxNode::LEAF) {
179  if (intersect(*((const BBoxLeaf *)a)->poly,
180  *((const BBoxLeaf *)b)->poly, b2a, v)) {
181  pa = ((const BBoxLeaf *)a)->poly;
182  pb = ((const BBoxLeaf *)b)->poly;
183  return true;
184  }
185  else return false;
186  }
187  else if (a->tag == BBoxNode::LEAF ||
188  (b->tag != BBoxNode::LEAF && a->bbox.size() < b->bbox.size())) {
189  return
190  find_prim(a, ((const BBoxInternal *)b)->lson,
191  b2a, abs_b2a, a2b, abs_a2b, v, pa, pb) ||
192  find_prim(a, ((const BBoxInternal *)b)->rson,
193  b2a, abs_b2a, a2b, abs_a2b, v, pa, pb);
194  }
195  else {
196  return
197  find_prim(((const BBoxInternal *)a)->lson, b, b2a, abs_b2a, a2b, abs_a2b, v, pa, pb) ||
198  find_prim(((const BBoxInternal *)a)->rson, b, b2a, abs_b2a, a2b, abs_a2b, v, pa, pb);
199  }
200 }
201 
202 
203 
204 bool common_point(const BBoxNode *tree, const Convex& c, const BBox& bb,
205  const Transform& b2a, Vector& v, Point& pa, Point& pb) {
206  if (!intersect(tree->bbox, bb)) return false;
207 
208  if (tree->tag == BBoxNode::LEAF)
209  return common_point(*((const BBoxLeaf *)tree)->poly, c, b2a, v, pa, pb);
210  else {
211  return common_point(((const BBoxInternal *)tree)->lson, c, bb, b2a, v, pa, pb) ||
212  common_point(((const BBoxInternal *)tree)->rson, c, bb, b2a, v, pa, pb);
213  }
214 }
215 
216 
217 bool common_point(const BBoxNode *a, const BBoxNode *b,
218  const Transform& b2a, const Matrix& abs_b2a,
219  const Transform& a2b, const Matrix& abs_a2b,
220  Vector& v, Point& pa, Point& pb) {
221  if (!intersect(a->bbox, b->bbox, b2a, abs_b2a, a2b, abs_a2b)) return false;
222 
223  if (a->tag == BBoxNode::LEAF && b->tag == BBoxNode::LEAF) {
224  return common_point(*((const BBoxLeaf *)a)->poly,
225  *((const BBoxLeaf *)b)->poly, b2a, v, pa, pb);
226  }
227  else if (a->tag == BBoxNode::LEAF ||
228  (b->tag != BBoxNode::LEAF && a->bbox.size() < b->bbox.size())) {
229  return
230  common_point(a, ((const BBoxInternal *)b)->lson,
231  b2a, abs_b2a, a2b, abs_a2b, v, pa, pb) ||
232  common_point(a, ((const BBoxInternal *)b)->rson,
233  b2a, abs_b2a, a2b, abs_a2b, v, pa, pb);
234  }
235  else {
236  return
237  common_point(((const BBoxInternal *)a)->lson, b, b2a, abs_b2a, a2b, abs_a2b, v, pa, pb) ||
238  common_point(((const BBoxInternal *)a)->rson, b, b2a, abs_b2a, a2b, abs_a2b, v, pa ,pb);
239  }
240 }
241 
242 
243 
244 
bool sep_axes_test(const Vector &a, const Vector &b, const Matrix &abs_b2a, const Vector &pos_b2a, const Matrix &abs_a2b, const Vector &pos_a2b)
Definition: BBoxTree.cpp:87
bool intersect(const BBox &a, const BBox &b, const Transform &b2a, const Matrix &abs_b2a, const Transform &a2b, const Matrix &abs_a2b)
Definition: BBoxTree.cpp:105
BBoxNode * rson
Definition: BBoxTree.h:66
const Point & getCenter() const
Definition: BBox.h:41
Definition: Convex.h:39
void fitBBox()
Definition: BBoxTree.cpp:49
Scalar dot(const Quaternion &q1, const Quaternion &q2)
Definition: Quaternion.h:163
Definition: Basic.h:58
bool common_point(const BBoxNode *tree, const Convex &c, const BBox &bb, const Transform &b2a, Vector &v, Point &pa, Point &pb)
Definition: BBoxTree.cpp:204
int longestAxis() const
Definition: BBox.h:83
Definition: Basic.h:58
BBox bbox
Definition: BBoxTree.h:45
BBoxNode * lson
Definition: BBoxTree.h:65
int numVerts() const
Definition: Polytope.h:46
Scalar size() const
Definition: BBox.h:82
void setEmpty()
Definition: BBox.h:62
static Point p[4]
Definition: Convex.cpp:54
Definition: Basic.h:58
bool operator()(const BBoxNode &p1, const BBoxNode &p2) const
Definition: BBoxTree.cpp:40
Definition: Shape.h:44
Definition: BBox.h:36
TagType tag
Definition: BBoxTree.h:47
Definition: Matrix.h:37
void include(const Point &p)
Definition: BBox.h:67
const Polytope * poly
Definition: BBoxTree.h:52
BBoxInternal()
Definition: BBoxTree.h:68
const Vector & getExtent() const
Definition: BBox.h:42
Definition: Vector.h:32
class BBoxCompAxis bboxCompAxis[3]
BBoxInternal * free_node
Definition: Complex.cpp:37
Definition: Point.h:34
BBoxCompAxis(int a)
Definition: BBoxTree.cpp:43
bool find_prim(const BBoxNode *tree, const Convex &c, const BBox &bb, const Transform &b2a, Vector &v, ShapePtr &p)
Definition: BBoxTree.cpp:154