resetting manifest requested domain to floor
[platform/upstream/libbullet.git] / src / BulletCollision / Gimpact / btGImpactQuantizedBvh.h
1 #ifndef GIM_QUANTIZED_SET_H_INCLUDED
2 #define GIM_QUANTIZED_SET_H_INCLUDED
3
4 /*! \file btGImpactQuantizedBvh.h
5 \author Francisco Leon Najera
6 */
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
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
37 {
38         //12 bytes
39         unsigned short int      m_quantizedAabbMin[3];
40         unsigned short int      m_quantizedAabbMax[3];
41         //4 bytes
42         int     m_escapeIndexOrDataIndex;
43
44         BT_QUANTIZED_BVH_NODE()
45         {
46                 m_escapeIndexOrDataIndex = 0;
47         }
48
49         SIMD_FORCE_INLINE bool isLeafNode() const
50         {
51                 //skipindex is negative (internal node), triangleindex >=0 (leafnode)
52                 return (m_escapeIndexOrDataIndex>=0);
53         }
54
55         SIMD_FORCE_INLINE int getEscapeIndex() const
56         {
57                 //btAssert(m_escapeIndexOrDataIndex < 0);
58                 return -m_escapeIndexOrDataIndex;
59         }
60
61         SIMD_FORCE_INLINE void setEscapeIndex(int index)
62         {
63                 m_escapeIndexOrDataIndex = -index;
64         }
65
66         SIMD_FORCE_INLINE int getDataIndex() const
67         {
68                 //btAssert(m_escapeIndexOrDataIndex >= 0);
69
70                 return m_escapeIndexOrDataIndex;
71         }
72
73         SIMD_FORCE_INLINE void setDataIndex(int index)
74         {
75                 m_escapeIndexOrDataIndex = index;
76         }
77
78         SIMD_FORCE_INLINE bool testQuantizedBoxOverlapp(
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
104 //! Basic Box tree structure
105 class btQuantizedBvhTree
106 {
107 protected:
108         int m_num_nodes;
109         GIM_QUANTIZED_BVH_NODE_ARRAY m_node_array;
110         btAABB m_global_bound;
111         btVector3 m_bvhQuantization;
112 protected:
113         void calc_quantization(GIM_BVH_DATA_ARRAY & primitive_boxes, btScalar boundMargin = btScalar(1.0) );
114
115         int _sort_and_calc_splitting_index(
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:
123         btQuantizedBvhTree()
124         {
125                 m_num_nodes = 0;
126         }
127
128         //! prototype functions for box tree management
129         //!@{
130         void build_tree(GIM_BVH_DATA_ARRAY & primitive_boxes);
131
132         SIMD_FORCE_INLINE void quantizePoint(
133                 unsigned short * quantizedpoint, const btVector3 & point) const
134         {
135                 bt_quantize_clamp(quantizedpoint,point,m_global_bound.m_min,m_global_bound.m_max,m_bvhQuantization);
136         }
137
138
139         SIMD_FORCE_INLINE bool testQuantizedBoxOverlapp(
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
146         SIMD_FORCE_INLINE void clearNodes()
147         {
148                 m_node_array.clear();
149                 m_num_nodes = 0;
150         }
151
152         //! node count
153         SIMD_FORCE_INLINE int getNodeCount() const
154         {
155                 return m_num_nodes;
156         }
157
158         //! tells if the node is a leaf
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,
173                         m_global_bound.m_min,m_bvhQuantization);
174
175                 bound.m_max = bt_unquantize(
176                         m_node_array[nodeindex].m_quantizedAabbMax,
177                         m_global_bound.m_min,m_bvhQuantization);
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,
184                                                         m_global_bound.m_min,
185                                                         m_global_bound.m_max,
186                                                         m_bvhQuantization);
187
188                 bt_quantize_clamp(      m_node_array[nodeindex].m_quantizedAabbMax,
189                                                         bound.m_max,
190                                                         m_global_bound.m_min,
191                                                         m_global_bound.m_max,
192                                                         m_bvhQuantization);
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
211         SIMD_FORCE_INLINE const BT_QUANTIZED_BVH_NODE * get_node_pointer(int index = 0) const
212         {
213                 return &m_node_array[index];
214         }
215
216         //!@}
217 };
218
219
220
221 //! Structure for containing Boxes
222 /*!
223 This class offers an structure for managing a box tree of primitives.
224 Requires a Primitive prototype (like btPrimitiveManagerBase )
225 */
226 class btGImpactQuantizedBvh
227 {
228 protected:
229         btQuantizedBvhTree m_box_tree;
230         btPrimitiveManagerBase * m_primitive_manager;
231
232 protected:
233         //stackless refit
234         void refit();
235 public:
236
237         //! this constructor doesn't build the tree. you must call      buildSet
238         btGImpactQuantizedBvh()
239         {
240                 m_primitive_manager = NULL;
241         }
242
243         //! this constructor doesn't build the tree. you must call      buildSet
244         btGImpactQuantizedBvh(btPrimitiveManagerBase * primitive_manager)
245         {
246                 m_primitive_manager = primitive_manager;
247         }
248
249         SIMD_FORCE_INLINE btAABB getGlobalBox()  const
250         {
251                 btAABB totalbox;
252                 getNodeBound(0, totalbox);
253                 return totalbox;
254         }
255
256         SIMD_FORCE_INLINE void setPrimitiveManager(btPrimitiveManagerBase * primitive_manager)
257         {
258                 m_primitive_manager = primitive_manager;
259         }
260
261         SIMD_FORCE_INLINE btPrimitiveManagerBase * getPrimitiveManager() const
262         {
263                 return m_primitive_manager;
264         }
265
266
267 //! node manager prototype functions
268 ///@{
269
270         //! this attemps to refit the box set.
271         SIMD_FORCE_INLINE void update()
272         {
273                 refit();
274         }
275
276         //! this rebuild the entire set
277         void buildSet();
278
279         //! returns the indices of the primitives in the m_primitive_manager
280         bool boxQuery(const btAABB & box, btAlignedObjectArray<int> & collided_results) const;
281
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
285         {
286                 btAABB transbox=box;
287                 transbox.appy_transform(transform);
288                 return boxQuery(transbox,collided_results);
289         }
290
291         //! returns the indices of the primitives in the m_primitive_manager
292         bool rayQuery(
293                 const btVector3 & ray_dir,const btVector3 & ray_origin ,
294                 btAlignedObjectArray<int> & collided_results) const;
295
296         //! tells if this set has hierarcht
297         SIMD_FORCE_INLINE bool hasHierarchy() const
298         {
299                 return true;
300         }
301
302         //! tells if this set is a trimesh
303         SIMD_FORCE_INLINE bool isTrimesh()  const
304         {
305                 return m_primitive_manager->is_trimesh();
306         }
307
308         //! node count
309         SIMD_FORCE_INLINE int getNodeCount() const
310         {
311                 return m_box_tree.getNodeCount();
312         }
313
314         //! tells if the node is a leaf
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         {
353                 m_primitive_manager->get_primitive_triangle(getNodeData(nodeindex),triangle);
354         }
355
356
357         SIMD_FORCE_INLINE const BT_QUANTIZED_BVH_NODE * get_node_pointer(int index = 0) const
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