Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/bullet/BulletCollision/Gimpact/btGImpactQuantizedBvh.h @ 2732

Last change on this file since 2732 was 2662, checked in by rgrieder, 16 years ago

Merged presentation branch back to trunk.

  • Property svn:eol-style set to native
File size: 9.2 KB
Line 
1#ifndef GIM_QUANTIZED_SET_H_INCLUDED
2#define GIM_QUANTIZED_SET_H_INCLUDED
3
4/*! \file btGImpactQuantizedBvh.h
5\author Francisco Len Nßjera
6*/
7/*
8This source file is part of GIMPACT Library.
9
10For the latest info, see http://gimpact.sourceforge.net/
11
12Copyright (c) 2007 Francisco Leon Najera. C.C. 80087371.
13email: projectileman@yahoo.com
14
15
16This software is provided 'as-is', without any express or implied warranty.
17In no event will the authors be held liable for any damages arising from the use of this software.
18Permission is granted to anyone to use this software for any purpose,
19including commercial applications, and to alter it and redistribute it freely,
20subject to the following restrictions:
21
221. 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.
232. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
243. 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).
36ATTRIBUTE_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
97class GIM_QUANTIZED_BVH_NODE_ARRAY:public btAlignedObjectArray<BT_QUANTIZED_BVH_NODE>
98{
99};
100
101
102
103
104//! Basic Box tree structure
105class btQuantizedBvhTree
106{
107protected:
108        int m_num_nodes;
109        GIM_QUANTIZED_BVH_NODE_ARRAY m_node_array;
110        btAABB m_global_bound;
111        btVector3 m_bvhQuantization;
112protected:
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);
122public:
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/*!
223This class offers an structure for managing a box tree of primitives.
224Requires a Primitive prototype (like btPrimitiveManagerBase )
225*/
226class btGImpactQuantizedBvh
227{
228protected:
229        btQuantizedBvhTree m_box_tree;
230        btPrimitiveManagerBase * m_primitive_manager;
231
232protected:
233        //stackless refit
234        void refit();
235public:
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
363        static float getAverageTreeCollisionTime();
364
365
366        static void find_collision(btGImpactQuantizedBvh * boxset1, const btTransform & trans1,
367                btGImpactQuantizedBvh * boxset2, const btTransform & trans2,
368                btPairSet & collision_pairs);
369};
370
371
372#endif // GIM_BOXPRUNING_H_INCLUDED
Note: See TracBrowser for help on using the repository browser.