1 #ifndef GIM_QUANTIZED_SET_H_INCLUDED
2 #define GIM_QUANTIZED_SET_H_INCLUDED
4 /*! \file btGImpactQuantizedBvh.h
5 \author Francisco Leon Najera
8 This source file is part of GIMPACT Library.
10 For the latest info, see http://gimpact.sourceforge.net/
12 Copyright (c) 2007 Francisco Leon Najera. C.C. 80087371.
13 email: projectileman@yahoo.com
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:
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.
27 #include "btGImpactBvh.h"
28 #include "btQuantization.h"
34 ///btQuantizedBvhNode is a compressed aabb node, 16 bytes.
35 ///Node can be used for leafnode or internal node. Leafnodes can point to 32-bit triangle index (non-negative range).
36 ATTRIBUTE_ALIGNED16 (struct) BT_QUANTIZED_BVH_NODE
39 unsigned short int m_quantizedAabbMin[3];
40 unsigned short int m_quantizedAabbMax[3];
42 int m_escapeIndexOrDataIndex;
44 BT_QUANTIZED_BVH_NODE()
46 m_escapeIndexOrDataIndex = 0;
49 SIMD_FORCE_INLINE bool isLeafNode() const
51 //skipindex is negative (internal node), triangleindex >=0 (leafnode)
52 return (m_escapeIndexOrDataIndex>=0);
55 SIMD_FORCE_INLINE int getEscapeIndex() const
57 //btAssert(m_escapeIndexOrDataIndex < 0);
58 return -m_escapeIndexOrDataIndex;
61 SIMD_FORCE_INLINE void setEscapeIndex(int index)
63 m_escapeIndexOrDataIndex = -index;
66 SIMD_FORCE_INLINE int getDataIndex() const
68 //btAssert(m_escapeIndexOrDataIndex >= 0);
70 return m_escapeIndexOrDataIndex;
73 SIMD_FORCE_INLINE void setDataIndex(int index)
75 m_escapeIndexOrDataIndex = index;
78 SIMD_FORCE_INLINE bool testQuantizedBoxOverlapp(
79 unsigned short * quantizedMin,unsigned short * quantizedMax) const
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])
97 class GIM_QUANTIZED_BVH_NODE_ARRAY:public btAlignedObjectArray<BT_QUANTIZED_BVH_NODE>
104 //! Basic Box tree structure
105 class btQuantizedBvhTree
109 GIM_QUANTIZED_BVH_NODE_ARRAY m_node_array;
110 btAABB m_global_bound;
111 btVector3 m_bvhQuantization;
113 void calc_quantization(GIM_BVH_DATA_ARRAY & primitive_boxes, btScalar boundMargin = btScalar(1.0) );
115 int _sort_and_calc_splitting_index(
116 GIM_BVH_DATA_ARRAY & primitive_boxes,
117 int startIndex, int endIndex, int splitAxis);
119 int _calc_splitting_axis(GIM_BVH_DATA_ARRAY & primitive_boxes, int startIndex, int endIndex);
121 void _build_sub_tree(GIM_BVH_DATA_ARRAY & primitive_boxes, int startIndex, int endIndex);
128 //! prototype functions for box tree management
130 void build_tree(GIM_BVH_DATA_ARRAY & primitive_boxes);
132 SIMD_FORCE_INLINE void quantizePoint(
133 unsigned short * quantizedpoint, const btVector3 & point) const
135 bt_quantize_clamp(quantizedpoint,point,m_global_bound.m_min,m_global_bound.m_max,m_bvhQuantization);
139 SIMD_FORCE_INLINE bool testQuantizedBoxOverlapp(
141 unsigned short * quantizedMin,unsigned short * quantizedMax) const
143 return m_node_array[node_index].testQuantizedBoxOverlapp(quantizedMin,quantizedMax);
146 SIMD_FORCE_INLINE void clearNodes()
148 m_node_array.clear();
153 SIMD_FORCE_INLINE int getNodeCount() const
158 //! tells if the node is a leaf
159 SIMD_FORCE_INLINE bool isLeafNode(int nodeindex) const
161 return m_node_array[nodeindex].isLeafNode();
164 SIMD_FORCE_INLINE int getNodeData(int nodeindex) const
166 return m_node_array[nodeindex].getDataIndex();
169 SIMD_FORCE_INLINE void getNodeBound(int nodeindex, btAABB & bound) const
171 bound.m_min = bt_unquantize(
172 m_node_array[nodeindex].m_quantizedAabbMin,
173 m_global_bound.m_min,m_bvhQuantization);
175 bound.m_max = bt_unquantize(
176 m_node_array[nodeindex].m_quantizedAabbMax,
177 m_global_bound.m_min,m_bvhQuantization);
180 SIMD_FORCE_INLINE void setNodeBound(int nodeindex, const btAABB & bound)
182 bt_quantize_clamp( m_node_array[nodeindex].m_quantizedAabbMin,
184 m_global_bound.m_min,
185 m_global_bound.m_max,
188 bt_quantize_clamp( m_node_array[nodeindex].m_quantizedAabbMax,
190 m_global_bound.m_min,
191 m_global_bound.m_max,
195 SIMD_FORCE_INLINE int getLeftNode(int nodeindex) const
200 SIMD_FORCE_INLINE int getRightNode(int nodeindex) const
202 if(m_node_array[nodeindex+1].isLeafNode()) return nodeindex+2;
203 return nodeindex+1 + m_node_array[nodeindex+1].getEscapeIndex();
206 SIMD_FORCE_INLINE int getEscapeNodeIndex(int nodeindex) const
208 return m_node_array[nodeindex].getEscapeIndex();
211 SIMD_FORCE_INLINE const BT_QUANTIZED_BVH_NODE * get_node_pointer(int index = 0) const
213 return &m_node_array[index];
221 //! Structure for containing Boxes
223 This class offers an structure for managing a box tree of primitives.
224 Requires a Primitive prototype (like btPrimitiveManagerBase )
226 class btGImpactQuantizedBvh
229 btQuantizedBvhTree m_box_tree;
230 btPrimitiveManagerBase * m_primitive_manager;
237 //! this constructor doesn't build the tree. you must call buildSet
238 btGImpactQuantizedBvh()
240 m_primitive_manager = NULL;
243 //! this constructor doesn't build the tree. you must call buildSet
244 btGImpactQuantizedBvh(btPrimitiveManagerBase * primitive_manager)
246 m_primitive_manager = primitive_manager;
249 SIMD_FORCE_INLINE btAABB getGlobalBox() const
252 getNodeBound(0, totalbox);
256 SIMD_FORCE_INLINE void setPrimitiveManager(btPrimitiveManagerBase * primitive_manager)
258 m_primitive_manager = primitive_manager;
261 SIMD_FORCE_INLINE btPrimitiveManagerBase * getPrimitiveManager() const
263 return m_primitive_manager;
267 //! node manager prototype functions
270 //! this attemps to refit the box set.
271 SIMD_FORCE_INLINE void update()
276 //! this rebuild the entire set
279 //! returns the indices of the primitives in the m_primitive_manager
280 bool boxQuery(const btAABB & box, btAlignedObjectArray<int> & collided_results) const;
282 //! returns the indices of the primitives in the m_primitive_manager
283 SIMD_FORCE_INLINE bool boxQueryTrans(const btAABB & box,
284 const btTransform & transform, btAlignedObjectArray<int> & collided_results) const
287 transbox.appy_transform(transform);
288 return boxQuery(transbox,collided_results);
291 //! returns the indices of the primitives in the m_primitive_manager
293 const btVector3 & ray_dir,const btVector3 & ray_origin ,
294 btAlignedObjectArray<int> & collided_results) const;
296 //! tells if this set has hierarcht
297 SIMD_FORCE_INLINE bool hasHierarchy() const
302 //! tells if this set is a trimesh
303 SIMD_FORCE_INLINE bool isTrimesh() const
305 return m_primitive_manager->is_trimesh();
309 SIMD_FORCE_INLINE int getNodeCount() const
311 return m_box_tree.getNodeCount();
314 //! tells if the node is a leaf
315 SIMD_FORCE_INLINE bool isLeafNode(int nodeindex) const
317 return m_box_tree.isLeafNode(nodeindex);
320 SIMD_FORCE_INLINE int getNodeData(int nodeindex) const
322 return m_box_tree.getNodeData(nodeindex);
325 SIMD_FORCE_INLINE void getNodeBound(int nodeindex, btAABB & bound) const
327 m_box_tree.getNodeBound(nodeindex, bound);
330 SIMD_FORCE_INLINE void setNodeBound(int nodeindex, const btAABB & bound)
332 m_box_tree.setNodeBound(nodeindex, bound);
336 SIMD_FORCE_INLINE int getLeftNode(int nodeindex) const
338 return m_box_tree.getLeftNode(nodeindex);
341 SIMD_FORCE_INLINE int getRightNode(int nodeindex) const
343 return m_box_tree.getRightNode(nodeindex);
346 SIMD_FORCE_INLINE int getEscapeNodeIndex(int nodeindex) const
348 return m_box_tree.getEscapeNodeIndex(nodeindex);
351 SIMD_FORCE_INLINE void getNodeTriangle(int nodeindex,btPrimitiveTriangle & triangle) const
353 m_primitive_manager->get_primitive_triangle(getNodeData(nodeindex),triangle);
357 SIMD_FORCE_INLINE const BT_QUANTIZED_BVH_NODE * get_node_pointer(int index = 0) const
359 return m_box_tree.get_node_pointer(index);
362 #ifdef TRI_COLLISION_PROFILING
363 static float getAverageTreeCollisionTime();
364 #endif //TRI_COLLISION_PROFILING
366 static void find_collision(const btGImpactQuantizedBvh * boxset1, const btTransform & trans1,
367 const btGImpactQuantizedBvh * boxset2, const btTransform & trans2,
368 btPairSet & collision_pairs);
372 #endif // GIM_BOXPRUNING_H_INCLUDED