TORCS  1.3.10
The Open Racing Car Simulator
Loading...
Searching...
No Matches
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
38public:
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
47extern 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) {
73 new(free_node++) BBoxInternal(mid, &l[0]);
74 }
75 else rson = &l[0];
76 if (n - mid >= 2) {
78 new(free_node++) BBoxInternal(n - mid, &l[mid]);
79 }
80 else lson = &l[mid];
81}
82
83#ifdef STATISTICS
84int num_box_tests = 0;
85#endif
86
87inline 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
105inline 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
115bool 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
128bool 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
154bool 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
172bool 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
204bool 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
217bool 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
class BBoxCompAxis bboxCompAxis[3]
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
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 find_prim(const BBoxNode *tree, const Convex &c, const BBox &bb, const Transform &b2a, Vector &v, ShapePtr &p)
Definition BBoxTree.cpp:154
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
BBoxInternal * free_node
Definition Complex.cpp:37
@ Y
Definition Basic.h:58
@ X
Definition Basic.h:58
@ Z
Definition Basic.h:58
static Point p[4]
Definition Convex.cpp:54
Scalar dot(const Quaternion &q1, const Quaternion &q2)
Definition Quaternion.h:163
const Shape * ShapePtr
Definition Shape.h:51
BBoxCompAxis(int a)
Definition BBoxTree.cpp:43
bool operator()(const BBoxNode &p1, const BBoxNode &p2) const
Definition BBoxTree.cpp:40
Definition BBox.h:36
Scalar size() const
Definition BBox.h:82
const Point & getCenter() const
Definition BBox.h:41
const Vector & getExtent() const
Definition BBox.h:42
BBoxNode * lson
Definition BBoxTree.h:65
BBoxNode * rson
Definition BBoxTree.h:66
const Polytope * poly
Definition BBoxTree.h:52
void fitBBox()
Definition BBoxTree.cpp:49
@ INTERNAL
Definition BBoxTree.h:43
BBox bbox
Definition BBoxTree.h:45
TagType tag
Definition BBoxTree.h:47
Definition Point.h:34