00001 #ifndef GIM_QUANTIZED_SET_H_INCLUDED
00002 #define GIM_QUANTIZED_SET_H_INCLUDED
00003
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "btGImpactBvh.h"
00028 #include "btQuantization.h"
00029
00030
00031
00032
00033
00036 ATTRIBUTE_ALIGNED16 (struct) BT_QUANTIZED_BVH_NODE
00037 {
00038
00039 unsigned short int m_quantizedAabbMin[3];
00040 unsigned short int m_quantizedAabbMax[3];
00041
00042 int m_escapeIndexOrDataIndex;
00043
00044 BT_QUANTIZED_BVH_NODE()
00045 {
00046 m_escapeIndexOrDataIndex = 0;
00047 }
00048
00049 SIMD_FORCE_INLINE bool isLeafNode() const
00050 {
00051
00052 return (m_escapeIndexOrDataIndex>=0);
00053 }
00054
00055 SIMD_FORCE_INLINE int getEscapeIndex() const
00056 {
00057
00058 return -m_escapeIndexOrDataIndex;
00059 }
00060
00061 SIMD_FORCE_INLINE void setEscapeIndex(int index)
00062 {
00063 m_escapeIndexOrDataIndex = -index;
00064 }
00065
00066 SIMD_FORCE_INLINE int getDataIndex() const
00067 {
00068
00069
00070 return m_escapeIndexOrDataIndex;
00071 }
00072
00073 SIMD_FORCE_INLINE void setDataIndex(int index)
00074 {
00075 m_escapeIndexOrDataIndex = index;
00076 }
00077
00078 SIMD_FORCE_INLINE bool testQuantizedBoxOverlapp(
00079 unsigned short * quantizedMin,unsigned short * quantizedMax) const
00080 {
00081 if(m_quantizedAabbMin[0] > quantizedMax[0] ||
00082 m_quantizedAabbMax[0] < quantizedMin[0] ||
00083 m_quantizedAabbMin[1] > quantizedMax[1] ||
00084 m_quantizedAabbMax[1] < quantizedMin[1] ||
00085 m_quantizedAabbMin[2] > quantizedMax[2] ||
00086 m_quantizedAabbMax[2] < quantizedMin[2])
00087 {
00088 return false;
00089 }
00090 return true;
00091 }
00092
00093 };
00094
00095
00096
00097 class GIM_QUANTIZED_BVH_NODE_ARRAY:public btAlignedObjectArray<BT_QUANTIZED_BVH_NODE>
00098 {
00099 };
00100
00101
00102
00103
00105 class btQuantizedBvhTree
00106 {
00107 protected:
00108 int m_num_nodes;
00109 GIM_QUANTIZED_BVH_NODE_ARRAY m_node_array;
00110 btAABB m_global_bound;
00111 btVector3 m_bvhQuantization;
00112 protected:
00113 void calc_quantization(GIM_BVH_DATA_ARRAY & primitive_boxes, btScalar boundMargin = btScalar(1.0) );
00114
00115 int _sort_and_calc_splitting_index(
00116 GIM_BVH_DATA_ARRAY & primitive_boxes,
00117 int startIndex, int endIndex, int splitAxis);
00118
00119 int _calc_splitting_axis(GIM_BVH_DATA_ARRAY & primitive_boxes, int startIndex, int endIndex);
00120
00121 void _build_sub_tree(GIM_BVH_DATA_ARRAY & primitive_boxes, int startIndex, int endIndex);
00122 public:
00123 btQuantizedBvhTree()
00124 {
00125 m_num_nodes = 0;
00126 }
00127
00130 void build_tree(GIM_BVH_DATA_ARRAY & primitive_boxes);
00131
00132 SIMD_FORCE_INLINE void quantizePoint(
00133 unsigned short * quantizedpoint, const btVector3 & point) const
00134 {
00135 bt_quantize_clamp(quantizedpoint,point,m_global_bound.m_min,m_global_bound.m_max,m_bvhQuantization);
00136 }
00137
00138
00139 SIMD_FORCE_INLINE bool testQuantizedBoxOverlapp(
00140 int node_index,
00141 unsigned short * quantizedMin,unsigned short * quantizedMax) const
00142 {
00143 return m_node_array[node_index].testQuantizedBoxOverlapp(quantizedMin,quantizedMax);
00144 }
00145
00146 SIMD_FORCE_INLINE void clearNodes()
00147 {
00148 m_node_array.clear();
00149 m_num_nodes = 0;
00150 }
00151
00153 SIMD_FORCE_INLINE int getNodeCount() const
00154 {
00155 return m_num_nodes;
00156 }
00157
00159 SIMD_FORCE_INLINE bool isLeafNode(int nodeindex) const
00160 {
00161 return m_node_array[nodeindex].isLeafNode();
00162 }
00163
00164 SIMD_FORCE_INLINE int getNodeData(int nodeindex) const
00165 {
00166 return m_node_array[nodeindex].getDataIndex();
00167 }
00168
00169 SIMD_FORCE_INLINE void getNodeBound(int nodeindex, btAABB & bound) const
00170 {
00171 bound.m_min = bt_unquantize(
00172 m_node_array[nodeindex].m_quantizedAabbMin,
00173 m_global_bound.m_min,m_bvhQuantization);
00174
00175 bound.m_max = bt_unquantize(
00176 m_node_array[nodeindex].m_quantizedAabbMax,
00177 m_global_bound.m_min,m_bvhQuantization);
00178 }
00179
00180 SIMD_FORCE_INLINE void setNodeBound(int nodeindex, const btAABB & bound)
00181 {
00182 bt_quantize_clamp( m_node_array[nodeindex].m_quantizedAabbMin,
00183 bound.m_min,
00184 m_global_bound.m_min,
00185 m_global_bound.m_max,
00186 m_bvhQuantization);
00187
00188 bt_quantize_clamp( m_node_array[nodeindex].m_quantizedAabbMax,
00189 bound.m_max,
00190 m_global_bound.m_min,
00191 m_global_bound.m_max,
00192 m_bvhQuantization);
00193 }
00194
00195 SIMD_FORCE_INLINE int getLeftNode(int nodeindex) const
00196 {
00197 return nodeindex+1;
00198 }
00199
00200 SIMD_FORCE_INLINE int getRightNode(int nodeindex) const
00201 {
00202 if(m_node_array[nodeindex+1].isLeafNode()) return nodeindex+2;
00203 return nodeindex+1 + m_node_array[nodeindex+1].getEscapeIndex();
00204 }
00205
00206 SIMD_FORCE_INLINE int getEscapeNodeIndex(int nodeindex) const
00207 {
00208 return m_node_array[nodeindex].getEscapeIndex();
00209 }
00210
00211 SIMD_FORCE_INLINE const BT_QUANTIZED_BVH_NODE * get_node_pointer(int index = 0) const
00212 {
00213 return &m_node_array[index];
00214 }
00215
00217 };
00218
00219
00220
00222
00226 class btGImpactQuantizedBvh
00227 {
00228 protected:
00229 btQuantizedBvhTree m_box_tree;
00230 btPrimitiveManagerBase * m_primitive_manager;
00231
00232 protected:
00233
00234 void refit();
00235 public:
00236
00238 btGImpactQuantizedBvh()
00239 {
00240 m_primitive_manager = NULL;
00241 }
00242
00244 btGImpactQuantizedBvh(btPrimitiveManagerBase * primitive_manager)
00245 {
00246 m_primitive_manager = primitive_manager;
00247 }
00248
00249 SIMD_FORCE_INLINE btAABB getGlobalBox() const
00250 {
00251 btAABB totalbox;
00252 getNodeBound(0, totalbox);
00253 return totalbox;
00254 }
00255
00256 SIMD_FORCE_INLINE void setPrimitiveManager(btPrimitiveManagerBase * primitive_manager)
00257 {
00258 m_primitive_manager = primitive_manager;
00259 }
00260
00261 SIMD_FORCE_INLINE btPrimitiveManagerBase * getPrimitiveManager() const
00262 {
00263 return m_primitive_manager;
00264 }
00265
00266
00269
00271 SIMD_FORCE_INLINE void update()
00272 {
00273 refit();
00274 }
00275
00277 void buildSet();
00278
00280 bool boxQuery(const btAABB & box, btAlignedObjectArray<int> & collided_results) const;
00281
00283 SIMD_FORCE_INLINE bool boxQueryTrans(const btAABB & box,
00284 const btTransform & transform, btAlignedObjectArray<int> & collided_results) const
00285 {
00286 btAABB transbox=box;
00287 transbox.appy_transform(transform);
00288 return boxQuery(transbox,collided_results);
00289 }
00290
00292 bool rayQuery(
00293 const btVector3 & ray_dir,const btVector3 & ray_origin ,
00294 btAlignedObjectArray<int> & collided_results) const;
00295
00297 SIMD_FORCE_INLINE bool hasHierarchy() const
00298 {
00299 return true;
00300 }
00301
00303 SIMD_FORCE_INLINE bool isTrimesh() const
00304 {
00305 return m_primitive_manager->is_trimesh();
00306 }
00307
00309 SIMD_FORCE_INLINE int getNodeCount() const
00310 {
00311 return m_box_tree.getNodeCount();
00312 }
00313
00315 SIMD_FORCE_INLINE bool isLeafNode(int nodeindex) const
00316 {
00317 return m_box_tree.isLeafNode(nodeindex);
00318 }
00319
00320 SIMD_FORCE_INLINE int getNodeData(int nodeindex) const
00321 {
00322 return m_box_tree.getNodeData(nodeindex);
00323 }
00324
00325 SIMD_FORCE_INLINE void getNodeBound(int nodeindex, btAABB & bound) const
00326 {
00327 m_box_tree.getNodeBound(nodeindex, bound);
00328 }
00329
00330 SIMD_FORCE_INLINE void setNodeBound(int nodeindex, const btAABB & bound)
00331 {
00332 m_box_tree.setNodeBound(nodeindex, bound);
00333 }
00334
00335
00336 SIMD_FORCE_INLINE int getLeftNode(int nodeindex) const
00337 {
00338 return m_box_tree.getLeftNode(nodeindex);
00339 }
00340
00341 SIMD_FORCE_INLINE int getRightNode(int nodeindex) const
00342 {
00343 return m_box_tree.getRightNode(nodeindex);
00344 }
00345
00346 SIMD_FORCE_INLINE int getEscapeNodeIndex(int nodeindex) const
00347 {
00348 return m_box_tree.getEscapeNodeIndex(nodeindex);
00349 }
00350
00351 SIMD_FORCE_INLINE void getNodeTriangle(int nodeindex,btPrimitiveTriangle & triangle) const
00352 {
00353 m_primitive_manager->get_primitive_triangle(getNodeData(nodeindex),triangle);
00354 }
00355
00356
00357 SIMD_FORCE_INLINE const BT_QUANTIZED_BVH_NODE * get_node_pointer(int index = 0) const
00358 {
00359 return m_box_tree.get_node_pointer(index);
00360 }
00361
00362 #ifdef TRI_COLLISION_PROFILING
00363 static float getAverageTreeCollisionTime();
00364 #endif //TRI_COLLISION_PROFILING
00365
00366 static void find_collision(btGImpactQuantizedBvh * boxset1, const btTransform & trans1,
00367 btGImpactQuantizedBvh * boxset2, const btTransform & trans2,
00368 btPairSet & collision_pairs);
00369 };
00370
00371
00372 #endif // GIM_BOXPRUNING_H_INCLUDED