Blender V2.61 - r43446
|
00001 #ifndef GIM_QUANTIZED_SET_H_INCLUDED 00002 #define GIM_QUANTIZED_SET_H_INCLUDED 00003 00007 /* 00008 This source file is part of GIMPACT Library. 00009 00010 For the latest info, see http://gimpact.sourceforge.net/ 00011 00012 Copyright (c) 2007 Francisco Leon Najera. C.C. 80087371. 00013 email: projectileman@yahoo.com 00014 00015 00016 This software is provided 'as-is', without any express or implied warranty. 00017 In no event will the authors be held liable for any damages arising from the use of this software. 00018 Permission is granted to anyone to use this software for any purpose, 00019 including commercial applications, and to alter it and redistribute it freely, 00020 subject to the following restrictions: 00021 00022 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. 00023 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 00024 3. This notice may not be removed or altered from any source distribution. 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 //12 bytes 00039 unsigned short int m_quantizedAabbMin[3]; 00040 unsigned short int m_quantizedAabbMax[3]; 00041 //4 bytes 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 //skipindex is negative (internal node), triangleindex >=0 (leafnode) 00052 return (m_escapeIndexOrDataIndex>=0); 00053 } 00054 00055 SIMD_FORCE_INLINE int getEscapeIndex() const 00056 { 00057 //btAssert(m_escapeIndexOrDataIndex < 0); 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 //btAssert(m_escapeIndexOrDataIndex >= 0); 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 //stackless refit 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