1
// ---------------------------------------------------------
6
// Broad phase collision detection culling using three regular, volumetric grids.
8
// ---------------------------------------------------------
10
#ifndef EL_TOPO_BROADPHASEGRID_H
11
#define EL_TOPO_BROADPHASEGRID_H
13
// ---------------------------------------------------------
15
// ---------------------------------------------------------
17
#include <broadphase.h>
18
#include <accelerationgrid.h>
20
// ---------------------------------------------------------
21
// Forwards and typedefs
22
// ---------------------------------------------------------
26
// ---------------------------------------------------------
28
// ---------------------------------------------------------
30
// --------------------------------------------------------
32
/// Broad phase collision detector using three regular grids: one grid each for vertices, edges and triangles.
34
// --------------------------------------------------------
36
class BroadPhaseGrid : public BroadPhase
40
/// Default constructor, just initialize empty grids
43
m_solid_vertex_grid(),
45
m_solid_triangle_grid(),
46
m_dynamic_vertex_grid(),
47
m_dynamic_edge_grid(),
48
m_dynamic_triangle_grid()
52
/// Do-nothing destructor
57
/// Rebuild the broad phase
59
void update_broad_phase( const DynamicSurface& surface, bool continuous );
61
/// Add a vertex with the specified bounding box to the broad phase
63
inline void add_vertex( size_t index,
64
const Vec3d& aabb_low,
65
const Vec3d& aabb_high,
68
/// Add an edge with the specified bounding box to the broad phase
70
inline void add_edge( size_t index,
71
const Vec3d& aabb_low,
72
const Vec3d& aabb_high,
75
/// Add a triangle with the specified bounding box to the broad phase
77
inline void add_triangle( size_t index,
78
const Vec3d& aabb_low,
79
const Vec3d& aabb_high,
82
/// Update a vertex's broad phase entry
84
inline void update_vertex( size_t index,
85
const Vec3d& aabb_low,
86
const Vec3d& aabb_high,
89
/// Update an edge's broad phase entry
91
inline void update_edge( size_t index,
92
const Vec3d& aabb_low,
93
const Vec3d& aabb_high,
96
/// Update a triangle's broad phase entry
98
inline void update_triangle( size_t index,
99
const Vec3d& aabb_low,
100
const Vec3d& aabb_high,
103
/// Remove a vertex from the broad phase
105
inline void remove_vertex( size_t index );
107
/// Remove an edge from the broad phase
109
inline void remove_edge( size_t index );
111
/// Remove a triangle from the broad phase
113
inline void remove_triangle( size_t index );
115
/// Get the stored axis-aligned bounding box of a vertex
117
virtual void get_vertex_aabb( size_t index, bool is_solid, Vec3d& aabb_low, Vec3d& aabb_high );
119
/// Get the stored axis-aligned bounding box of an edge
121
virtual void get_edge_aabb( size_t index, bool is_solid, Vec3d& aabb_low, Vec3d& aabb_high );
123
/// Get the stored axis-aligned bounding box of a triangle
125
virtual void get_triangle_aabb( size_t index, bool is_solid, Vec3d& aabb_low, Vec3d& aabb_high );
127
/// Get the set of vertices whose bounding volumes overlap the specified bounding volume
129
inline void get_potential_vertex_collisions( const Vec3d& aabb_low,
130
const Vec3d& aabb_high,
133
std::vector<size_t>& overlapping_vertices );
135
/// Get the set of edges whose bounding volumes overlap the specified bounding volume
137
inline void get_potential_edge_collisions( const Vec3d& aabb_low,
138
const Vec3d& aabb_high,
141
std::vector<size_t>& overlapping_edges );
143
/// Get the set of triangles whose bounding volumes overlap the specified bounding volume
145
inline void get_potential_triangle_collisions( const Vec3d& aabb_low,
146
const Vec3d& aabb_high,
149
std::vector<size_t>& overlapping_triangles );
151
/// Rebuild one of the grids
153
void build_acceleration_grid( AccelerationGrid& grid,
154
std::vector<Vec3d>& xmins,
155
std::vector<Vec3d>& xmaxs,
156
std::vector<size_t>& indices,
158
double grid_padding );
160
/// Regular grids for solid mesh elements
162
AccelerationGrid m_solid_vertex_grid;
163
AccelerationGrid m_solid_edge_grid;
164
AccelerationGrid m_solid_triangle_grid;
166
/// Regular grids for dynamic mesh elements
168
AccelerationGrid m_dynamic_vertex_grid;
169
AccelerationGrid m_dynamic_edge_grid;
170
AccelerationGrid m_dynamic_triangle_grid;
174
// ---------------------------------------------------------
176
// ---------------------------------------------------------
178
// --------------------------------------------------------
180
/// Add a vertex to the broad phase
182
// --------------------------------------------------------
184
inline void BroadPhaseGrid::add_vertex( size_t index, const Vec3d& aabb_low, const Vec3d& aabb_high, bool is_solid )
188
m_solid_vertex_grid.add_element( index, aabb_low, aabb_high );
192
m_dynamic_vertex_grid.add_element( index, aabb_low, aabb_high );
196
// --------------------------------------------------------
198
/// Add an edge to the broad phase
200
// --------------------------------------------------------
202
inline void BroadPhaseGrid::add_edge( size_t index, const Vec3d& aabb_low, const Vec3d& aabb_high, bool is_solid )
206
m_solid_edge_grid.add_element( index, aabb_low, aabb_high );
210
m_dynamic_edge_grid.add_element( index, aabb_low, aabb_high );
214
// --------------------------------------------------------
216
/// Add a triangle to the broad phase
218
// --------------------------------------------------------
220
inline void BroadPhaseGrid::add_triangle( size_t index, const Vec3d& aabb_low, const Vec3d& aabb_high, bool is_solid )
224
m_solid_triangle_grid.add_element( index, aabb_low, aabb_high );
228
m_dynamic_triangle_grid.add_element( index, aabb_low, aabb_high );
233
// ---------------------------------------------------------
235
/// Update a vertex's broad phase entry
237
// ---------------------------------------------------------
239
inline void BroadPhaseGrid::update_vertex( size_t index, const Vec3d& aabb_low, const Vec3d& aabb_high, bool is_solid )
243
m_solid_vertex_grid.update_element( index, aabb_low, aabb_high );
247
m_dynamic_vertex_grid.update_element( index, aabb_low, aabb_high );
251
// ---------------------------------------------------------
253
/// Update an edge's broad phase entry
255
// ---------------------------------------------------------
257
inline void BroadPhaseGrid::update_edge( size_t index, const Vec3d& aabb_low, const Vec3d& aabb_high, bool is_solid )
261
m_solid_edge_grid.update_element( index, aabb_low, aabb_high );
265
m_dynamic_edge_grid.update_element( index, aabb_low, aabb_high );
269
// ---------------------------------------------------------
271
/// Update a triangle's broad phase entry
273
// ---------------------------------------------------------
275
inline void BroadPhaseGrid::update_triangle( size_t index, const Vec3d& aabb_low, const Vec3d& aabb_high, bool is_solid )
279
m_solid_triangle_grid.update_element( index, aabb_low, aabb_high );
283
m_dynamic_triangle_grid.update_element( index, aabb_low, aabb_high );
288
// --------------------------------------------------------
290
/// Remove a vertex from the broad phase
292
// --------------------------------------------------------
294
inline void BroadPhaseGrid::remove_vertex( size_t index )
296
m_solid_vertex_grid.remove_element( index );
297
m_dynamic_vertex_grid.remove_element( index );
300
// --------------------------------------------------------
302
/// Remove an edge from the broad phase
304
// --------------------------------------------------------
306
inline void BroadPhaseGrid::remove_edge( size_t index )
308
m_solid_edge_grid.remove_element( index );
309
m_dynamic_edge_grid.remove_element( index );
312
// --------------------------------------------------------
314
/// Remove a triangle from the broad phase
316
// --------------------------------------------------------
318
inline void BroadPhaseGrid::remove_triangle( size_t index )
320
m_solid_triangle_grid.remove_element( index );
321
m_dynamic_triangle_grid.remove_element( index );
324
// --------------------------------------------------------
326
/// Query the broad phase to get the set of all vertices overlapping the given AABB
328
// --------------------------------------------------------
330
inline void BroadPhaseGrid::get_potential_vertex_collisions( const Vec3d& aabb_low,
331
const Vec3d& aabb_high,
334
std::vector<size_t>& overlapping_vertices )
338
m_solid_vertex_grid.find_overlapping_elements( aabb_low, aabb_high, overlapping_vertices );
341
if ( return_dynamic )
343
m_dynamic_vertex_grid.find_overlapping_elements( aabb_low, aabb_high, overlapping_vertices );
347
// --------------------------------------------------------
349
/// Query the broad phase to get the set of all edges overlapping the given AABB
351
// --------------------------------------------------------
353
inline void BroadPhaseGrid::get_potential_edge_collisions( const Vec3d& aabb_low,
354
const Vec3d& aabb_high,
357
std::vector<size_t>& overlapping_edges )
361
m_solid_edge_grid.find_overlapping_elements( aabb_low, aabb_high, overlapping_edges );
364
if ( return_dynamic )
366
m_dynamic_edge_grid.find_overlapping_elements( aabb_low, aabb_high, overlapping_edges );
370
// --------------------------------------------------------
372
/// Query the broad phase to get the set of all triangles overlapping the given AABB
374
// --------------------------------------------------------
376
inline void BroadPhaseGrid::get_potential_triangle_collisions( const Vec3d& aabb_low,
377
const Vec3d& aabb_high,
380
std::vector<size_t>& overlapping_triangles )
384
m_solid_triangle_grid.find_overlapping_elements( aabb_low, aabb_high, overlapping_triangles );
387
if ( return_dynamic )
389
m_dynamic_triangle_grid.find_overlapping_elements( aabb_low, aabb_high, overlapping_triangles );
394
// ---------------------------------------------------------
396
/// Get the stored axis-aligned bounding box of a vertex
398
// ---------------------------------------------------------
400
inline void BroadPhaseGrid::get_vertex_aabb( size_t index, bool is_solid, Vec3d& aabb_low, Vec3d& aabb_high )
404
aabb_low = m_solid_vertex_grid.m_elementxmins[index];
405
aabb_high = m_solid_vertex_grid.m_elementxmaxs[index];
409
aabb_low = m_dynamic_vertex_grid.m_elementxmins[index];
410
aabb_high = m_dynamic_vertex_grid.m_elementxmaxs[index];
414
// ---------------------------------------------------------
416
/// Get the stored axis-aligned bounding box of an edge
418
// ---------------------------------------------------------
420
inline void BroadPhaseGrid::get_edge_aabb( size_t index, bool is_solid, Vec3d& aabb_low, Vec3d& aabb_high )
424
aabb_low = m_solid_edge_grid.m_elementxmins[index];
425
aabb_high = m_solid_edge_grid.m_elementxmaxs[index];
429
aabb_low = m_dynamic_edge_grid.m_elementxmins[index];
430
aabb_high = m_dynamic_edge_grid.m_elementxmaxs[index];
434
// ---------------------------------------------------------
436
/// Get the stored axis-aligned bounding box of a triangle
438
// ---------------------------------------------------------
440
inline void BroadPhaseGrid::get_triangle_aabb( size_t index, bool is_solid, Vec3d& aabb_low, Vec3d& aabb_high )
444
aabb_low = m_solid_triangle_grid.m_elementxmins[index];
445
aabb_high = m_solid_triangle_grid.m_elementxmaxs[index];
449
aabb_low = m_dynamic_triangle_grid.m_elementxmins[index];
450
aabb_high = m_dynamic_triangle_grid.m_elementxmaxs[index];