Bullet Collision Detection & Physics Library
btGImpactQuantizedBvh.h
Go to the documentation of this file.
1 #ifndef GIM_QUANTIZED_SET_H_INCLUDED
2 #define GIM_QUANTIZED_SET_H_INCLUDED
3 
7 /*
8 This source file is part of GIMPACT Library.
9 
10 For the latest info, see http://gimpact.sourceforge.net/
11 
12 Copyright (c) 2007 Francisco Leon Najera. C.C. 80087371.
13 email: projectileman@yahoo.com
14 
15 
16 This software is provided 'as-is', without any express or implied warranty.
17 In no event will the authors be held liable for any damages arising from the use of this software.
18 Permission is granted to anyone to use this software for any purpose,
19 including commercial applications, and to alter it and redistribute it freely,
20 subject to the following restrictions:
21 
22 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
23 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
24 3. This notice may not be removed or altered from any source distribution.
25 */
26 
27 #include "btGImpactBvh.h"
28 #include "btQuantization.h"
29 
30 
31 
32 
33 
37 {
38  //12 bytes
39  unsigned short int m_quantizedAabbMin[3];
40  unsigned short int m_quantizedAabbMax[3];
41  //4 bytes
43 
45  {
46  m_escapeIndexOrDataIndex = 0;
47  }
48 
50  {
51  //skipindex is negative (internal node), triangleindex >=0 (leafnode)
52  return (m_escapeIndexOrDataIndex>=0);
53  }
54 
56  {
57  //btAssert(m_escapeIndexOrDataIndex < 0);
58  return -m_escapeIndexOrDataIndex;
59  }
60 
62  {
63  m_escapeIndexOrDataIndex = -index;
64  }
65 
67  {
68  //btAssert(m_escapeIndexOrDataIndex >= 0);
69 
70  return m_escapeIndexOrDataIndex;
71  }
72 
74  {
75  m_escapeIndexOrDataIndex = index;
76  }
77 
79  unsigned short * quantizedMin,unsigned short * quantizedMax) const
80  {
81  if(m_quantizedAabbMin[0] > quantizedMax[0] ||
82  m_quantizedAabbMax[0] < quantizedMin[0] ||
83  m_quantizedAabbMin[1] > quantizedMax[1] ||
84  m_quantizedAabbMax[1] < quantizedMin[1] ||
85  m_quantizedAabbMin[2] > quantizedMax[2] ||
86  m_quantizedAabbMax[2] < quantizedMin[2])
87  {
88  return false;
89  }
90  return true;
91  }
92 
93 };
94 
95 
96 
97 class GIM_QUANTIZED_BVH_NODE_ARRAY:public btAlignedObjectArray<BT_QUANTIZED_BVH_NODE>
98 {
99 };
100 
101 
102 
103 
106 {
107 protected:
112 protected:
113  void calc_quantization(GIM_BVH_DATA_ARRAY & primitive_boxes, btScalar boundMargin = btScalar(1.0) );
114 
116  GIM_BVH_DATA_ARRAY & primitive_boxes,
117  int startIndex, int endIndex, int splitAxis);
118 
119  int _calc_splitting_axis(GIM_BVH_DATA_ARRAY & primitive_boxes, int startIndex, int endIndex);
120 
121  void _build_sub_tree(GIM_BVH_DATA_ARRAY & primitive_boxes, int startIndex, int endIndex);
122 public:
124  {
125  m_num_nodes = 0;
126  }
127 
130  void build_tree(GIM_BVH_DATA_ARRAY & primitive_boxes);
131 
133  unsigned short * quantizedpoint, const btVector3 & point) const
134  {
136  }
137 
138 
140  int node_index,
141  unsigned short * quantizedMin,unsigned short * quantizedMax) const
142  {
143  return m_node_array[node_index].testQuantizedBoxOverlapp(quantizedMin,quantizedMax);
144  }
145 
147  {
149  m_num_nodes = 0;
150  }
151 
154  {
155  return m_num_nodes;
156  }
157 
159  SIMD_FORCE_INLINE bool isLeafNode(int nodeindex) const
160  {
161  return m_node_array[nodeindex].isLeafNode();
162  }
163 
164  SIMD_FORCE_INLINE int getNodeData(int nodeindex) const
165  {
166  return m_node_array[nodeindex].getDataIndex();
167  }
168 
169  SIMD_FORCE_INLINE void getNodeBound(int nodeindex, btAABB & bound) const
170  {
171  bound.m_min = bt_unquantize(
172  m_node_array[nodeindex].m_quantizedAabbMin,
174 
175  bound.m_max = bt_unquantize(
176  m_node_array[nodeindex].m_quantizedAabbMax,
178  }
179 
180  SIMD_FORCE_INLINE void setNodeBound(int nodeindex, const btAABB & bound)
181  {
182  bt_quantize_clamp( m_node_array[nodeindex].m_quantizedAabbMin,
183  bound.m_min,
187 
188  bt_quantize_clamp( m_node_array[nodeindex].m_quantizedAabbMax,
189  bound.m_max,
193  }
194 
195  SIMD_FORCE_INLINE int getLeftNode(int nodeindex) const
196  {
197  return nodeindex+1;
198  }
199 
200  SIMD_FORCE_INLINE int getRightNode(int nodeindex) const
201  {
202  if(m_node_array[nodeindex+1].isLeafNode()) return nodeindex+2;
203  return nodeindex+1 + m_node_array[nodeindex+1].getEscapeIndex();
204  }
205 
206  SIMD_FORCE_INLINE int getEscapeNodeIndex(int nodeindex) const
207  {
208  return m_node_array[nodeindex].getEscapeIndex();
209  }
210 
212  {
213  return &m_node_array[index];
214  }
215 
217 };
218 
219 
220 
222 
227 {
228 protected:
231 
232 protected:
233  //stackless refit
234  void refit();
235 public:
236 
239  {
240  m_primitive_manager = NULL;
241  }
242 
245  {
246  m_primitive_manager = primitive_manager;
247  }
248 
250  {
251  btAABB totalbox;
252  getNodeBound(0, totalbox);
253  return totalbox;
254  }
255 
257  {
258  m_primitive_manager = primitive_manager;
259  }
260 
262  {
263  return m_primitive_manager;
264  }
265 
266 
269 
272  {
273  refit();
274  }
275 
277  void buildSet();
278 
280  bool boxQuery(const btAABB & box, btAlignedObjectArray<int> & collided_results) const;
281 
284  const btTransform & transform, btAlignedObjectArray<int> & collided_results) const
285  {
286  btAABB transbox=box;
287  transbox.appy_transform(transform);
288  return boxQuery(transbox,collided_results);
289  }
290 
292  bool rayQuery(
293  const btVector3 & ray_dir,const btVector3 & ray_origin ,
294  btAlignedObjectArray<int> & collided_results) const;
295 
298  {
299  return true;
300  }
301 
304  {
306  }
307 
310  {
311  return m_box_tree.getNodeCount();
312  }
313 
315  SIMD_FORCE_INLINE bool isLeafNode(int nodeindex) const
316  {
317  return m_box_tree.isLeafNode(nodeindex);
318  }
319 
320  SIMD_FORCE_INLINE int getNodeData(int nodeindex) const
321  {
322  return m_box_tree.getNodeData(nodeindex);
323  }
324 
325  SIMD_FORCE_INLINE void getNodeBound(int nodeindex, btAABB & bound) const
326  {
327  m_box_tree.getNodeBound(nodeindex, bound);
328  }
329 
330  SIMD_FORCE_INLINE void setNodeBound(int nodeindex, const btAABB & bound)
331  {
332  m_box_tree.setNodeBound(nodeindex, bound);
333  }
334 
335 
336  SIMD_FORCE_INLINE int getLeftNode(int nodeindex) const
337  {
338  return m_box_tree.getLeftNode(nodeindex);
339  }
340 
341  SIMD_FORCE_INLINE int getRightNode(int nodeindex) const
342  {
343  return m_box_tree.getRightNode(nodeindex);
344  }
345 
346  SIMD_FORCE_INLINE int getEscapeNodeIndex(int nodeindex) const
347  {
348  return m_box_tree.getEscapeNodeIndex(nodeindex);
349  }
350 
351  SIMD_FORCE_INLINE void getNodeTriangle(int nodeindex,btPrimitiveTriangle & triangle) const
352  {
354  }
355 
356 
358  {
359  return m_box_tree.get_node_pointer(index);
360  }
361 
362 #ifdef TRI_COLLISION_PROFILING
363  static float getAverageTreeCollisionTime();
364 #endif //TRI_COLLISION_PROFILING
365 
366  static void find_collision(const btGImpactQuantizedBvh * boxset1, const btTransform & trans1,
367  const btGImpactQuantizedBvh * boxset2, const btTransform & trans2,
368  btPairSet & collision_pairs);
369 };
370 
371 
372 #endif // GIM_BOXPRUNING_H_INCLUDED
int getRightNode(int nodeindex) const
bool testQuantizedBoxOverlapp(unsigned short *quantizedMin, unsigned short *quantizedMax) const
void build_tree(GIM_BVH_DATA_ARRAY &primitive_boxes)
prototype functions for box tree management
void calc_quantization(GIM_BVH_DATA_ARRAY &primitive_boxes, btScalar boundMargin=btScalar(1.0))
int _calc_splitting_axis(GIM_BVH_DATA_ARRAY &primitive_boxes, int startIndex, int endIndex)
btGImpactQuantizedBvh()
this constructor doesn't build the tree. you must call buildSet
bool testQuantizedBoxOverlapp(int node_index, unsigned short *quantizedMin, unsigned short *quantizedMax) const
The btAlignedObjectArray template class uses a subset of the stl::vector interface for its methods It...
int getRightNode(int nodeindex) const
btVector3 m_max
int getNodeData(int nodeindex) const
#define SIMD_FORCE_INLINE
Definition: btScalar.h:58
btVector3 bt_unquantize(const unsigned short *vecIn, const btVector3 &offset, const btVector3 &bvhQuantization)
bool rayQuery(const btVector3 &ray_dir, const btVector3 &ray_origin, btAlignedObjectArray< int > &collided_results) const
returns the indices of the primitives in the m_primitive_manager
int getNodeData(int nodeindex) const
btVector3 m_min
bool isTrimesh() const
tells if this set is a trimesh
void setEscapeIndex(int index)
btQuantizedBvhTree m_box_tree
Prototype Base class for primitive classification.
Definition: btGImpactBvh.h:230
bool isLeafNode(int nodeindex) const
tells if the node is a leaf
A pairset array.
Definition: btGImpactBvh.h:59
void clear()
clear the array, deallocated memory. Generally it is better to use array.resize(0), to reduce performance overhead of run-time memory (de)allocations.
void bt_quantize_clamp(unsigned short *out, const btVector3 &point, const btVector3 &min_bound, const btVector3 &max_bound, const btVector3 &bvhQuantization)
bool boxQueryTrans(const btAABB &box, const btTransform &transform, btAlignedObjectArray< int > &collided_results) const
returns the indices of the primitives in the m_primitive_manager
void setNodeBound(int nodeindex, const btAABB &bound)
int getLeftNode(int nodeindex) const
void update()
node manager prototype functions
int getNodeCount() const
node count
void setPrimitiveManager(btPrimitiveManagerBase *primitive_manager)
Axis aligned box.
void appy_transform(const btTransform &trans)
Apply a transform to an AABB.
virtual bool is_trimesh() const =0
determines if this manager consist on only triangles, which special case will be optimized ...
GIM_QUANTIZED_BVH_NODE_ARRAY m_node_array
btPrimitiveManagerBase * getPrimitiveManager() const
btVector3 can be used to represent 3D points and vectors.
Definition: btVector3.h:83
#define ATTRIBUTE_ALIGNED16(a)
Definition: btScalar.h:59
virtual void get_primitive_triangle(int prim_index, btPrimitiveTriangle &triangle) const =0
retrieves only the points of the triangle, and the collision margin
The btTransform class supports rigid transforms with only translation and rotation and no scaling/she...
Definition: btTransform.h:34
Basic Box tree structure.
void getNodeBound(int nodeindex, btAABB &bound) const
int getLeftNode(int nodeindex) const
void getNodeTriangle(int nodeindex, btPrimitiveTriangle &triangle) const
btPrimitiveManagerBase * m_primitive_manager
bool hasHierarchy() const
tells if this set has hierarcht
btGImpactQuantizedBvh(btPrimitiveManagerBase *primitive_manager)
this constructor doesn't build the tree. you must call buildSet
int getNodeCount() const
node count
bool boxQuery(const btAABB &box, btAlignedObjectArray< int > &collided_results) const
returns the indices of the primitives in the m_primitive_manager
bool isLeafNode(int nodeindex) const
tells if the node is a leaf
int getEscapeNodeIndex(int nodeindex) const
int _sort_and_calc_splitting_index(GIM_BVH_DATA_ARRAY &primitive_boxes, int startIndex, int endIndex, int splitAxis)
btQuantizedBvhNode is a compressed aabb node, 16 bytes.
void quantizePoint(unsigned short *quantizedpoint, const btVector3 &point) const
static void find_collision(const btGImpactQuantizedBvh *boxset1, const btTransform &trans1, const btGImpactQuantizedBvh *boxset2, const btTransform &trans2, btPairSet &collision_pairs)
void getNodeBound(int nodeindex, btAABB &bound) const
const BT_QUANTIZED_BVH_NODE * get_node_pointer(int index=0) const
Structure for containing Boxes.
void setNodeBound(int nodeindex, const btAABB &bound)
int getEscapeNodeIndex(int nodeindex) const
const BT_QUANTIZED_BVH_NODE * get_node_pointer(int index=0) const
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:266
void buildSet()
this rebuild the entire set
void _build_sub_tree(GIM_BVH_DATA_ARRAY &primitive_boxes, int startIndex, int endIndex)