Blender V2.61 - r43446
|
00001 #ifndef GIM_BOX_SET_H_INCLUDED 00002 #define GIM_BOX_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 00028 #include "LinearMath/btAlignedObjectArray.h" 00029 00030 #include "btBoxCollision.h" 00031 #include "btTriangleShapeEx.h" 00032 00033 00034 00035 00036 00038 struct GIM_PAIR 00039 { 00040 int m_index1; 00041 int m_index2; 00042 GIM_PAIR() 00043 {} 00044 00045 GIM_PAIR(const GIM_PAIR & p) 00046 { 00047 m_index1 = p.m_index1; 00048 m_index2 = p.m_index2; 00049 } 00050 00051 GIM_PAIR(int index1, int index2) 00052 { 00053 m_index1 = index1; 00054 m_index2 = index2; 00055 } 00056 }; 00057 00059 class btPairSet: public btAlignedObjectArray<GIM_PAIR> 00060 { 00061 public: 00062 btPairSet() 00063 { 00064 reserve(32); 00065 } 00066 inline void push_pair(int index1,int index2) 00067 { 00068 push_back(GIM_PAIR(index1,index2)); 00069 } 00070 00071 inline void push_pair_inv(int index1,int index2) 00072 { 00073 push_back(GIM_PAIR(index2,index1)); 00074 } 00075 }; 00076 00077 00079 struct GIM_BVH_DATA 00080 { 00081 btAABB m_bound; 00082 int m_data; 00083 }; 00084 00086 class GIM_BVH_TREE_NODE 00087 { 00088 public: 00089 btAABB m_bound; 00090 protected: 00091 int m_escapeIndexOrDataIndex; 00092 public: 00093 GIM_BVH_TREE_NODE() 00094 { 00095 m_escapeIndexOrDataIndex = 0; 00096 } 00097 00098 SIMD_FORCE_INLINE bool isLeafNode() const 00099 { 00100 //skipindex is negative (internal node), triangleindex >=0 (leafnode) 00101 return (m_escapeIndexOrDataIndex>=0); 00102 } 00103 00104 SIMD_FORCE_INLINE int getEscapeIndex() const 00105 { 00106 //btAssert(m_escapeIndexOrDataIndex < 0); 00107 return -m_escapeIndexOrDataIndex; 00108 } 00109 00110 SIMD_FORCE_INLINE void setEscapeIndex(int index) 00111 { 00112 m_escapeIndexOrDataIndex = -index; 00113 } 00114 00115 SIMD_FORCE_INLINE int getDataIndex() const 00116 { 00117 //btAssert(m_escapeIndexOrDataIndex >= 0); 00118 00119 return m_escapeIndexOrDataIndex; 00120 } 00121 00122 SIMD_FORCE_INLINE void setDataIndex(int index) 00123 { 00124 m_escapeIndexOrDataIndex = index; 00125 } 00126 00127 }; 00128 00129 00130 class GIM_BVH_DATA_ARRAY:public btAlignedObjectArray<GIM_BVH_DATA> 00131 { 00132 }; 00133 00134 00135 class GIM_BVH_TREE_NODE_ARRAY:public btAlignedObjectArray<GIM_BVH_TREE_NODE> 00136 { 00137 }; 00138 00139 00140 00141 00143 class btBvhTree 00144 { 00145 protected: 00146 int m_num_nodes; 00147 GIM_BVH_TREE_NODE_ARRAY m_node_array; 00148 protected: 00149 int _sort_and_calc_splitting_index( 00150 GIM_BVH_DATA_ARRAY & primitive_boxes, 00151 int startIndex, int endIndex, int splitAxis); 00152 00153 int _calc_splitting_axis(GIM_BVH_DATA_ARRAY & primitive_boxes, int startIndex, int endIndex); 00154 00155 void _build_sub_tree(GIM_BVH_DATA_ARRAY & primitive_boxes, int startIndex, int endIndex); 00156 public: 00157 btBvhTree() 00158 { 00159 m_num_nodes = 0; 00160 } 00161 00164 void build_tree(GIM_BVH_DATA_ARRAY & primitive_boxes); 00165 00166 SIMD_FORCE_INLINE void clearNodes() 00167 { 00168 m_node_array.clear(); 00169 m_num_nodes = 0; 00170 } 00171 00173 SIMD_FORCE_INLINE int getNodeCount() const 00174 { 00175 return m_num_nodes; 00176 } 00177 00179 SIMD_FORCE_INLINE bool isLeafNode(int nodeindex) const 00180 { 00181 return m_node_array[nodeindex].isLeafNode(); 00182 } 00183 00184 SIMD_FORCE_INLINE int getNodeData(int nodeindex) const 00185 { 00186 return m_node_array[nodeindex].getDataIndex(); 00187 } 00188 00189 SIMD_FORCE_INLINE void getNodeBound(int nodeindex, btAABB & bound) const 00190 { 00191 bound = m_node_array[nodeindex].m_bound; 00192 } 00193 00194 SIMD_FORCE_INLINE void setNodeBound(int nodeindex, const btAABB & bound) 00195 { 00196 m_node_array[nodeindex].m_bound = bound; 00197 } 00198 00199 SIMD_FORCE_INLINE int getLeftNode(int nodeindex) const 00200 { 00201 return nodeindex+1; 00202 } 00203 00204 SIMD_FORCE_INLINE int getRightNode(int nodeindex) const 00205 { 00206 if(m_node_array[nodeindex+1].isLeafNode()) return nodeindex+2; 00207 return nodeindex+1 + m_node_array[nodeindex+1].getEscapeIndex(); 00208 } 00209 00210 SIMD_FORCE_INLINE int getEscapeNodeIndex(int nodeindex) const 00211 { 00212 return m_node_array[nodeindex].getEscapeIndex(); 00213 } 00214 00215 SIMD_FORCE_INLINE const GIM_BVH_TREE_NODE * get_node_pointer(int index = 0) const 00216 { 00217 return &m_node_array[index]; 00218 } 00219 00221 }; 00222 00223 00225 00230 class btPrimitiveManagerBase 00231 { 00232 public: 00233 00234 virtual ~btPrimitiveManagerBase() {} 00235 00237 virtual bool is_trimesh() const = 0; 00238 virtual int get_primitive_count() const = 0; 00239 virtual void get_primitive_box(int prim_index ,btAABB & primbox) const = 0; 00241 virtual void get_primitive_triangle(int prim_index,btPrimitiveTriangle & triangle) const= 0; 00242 }; 00243 00244 00246 00250 class btGImpactBvh 00251 { 00252 protected: 00253 btBvhTree m_box_tree; 00254 btPrimitiveManagerBase * m_primitive_manager; 00255 00256 protected: 00257 //stackless refit 00258 void refit(); 00259 public: 00260 00262 btGImpactBvh() 00263 { 00264 m_primitive_manager = NULL; 00265 } 00266 00268 btGImpactBvh(btPrimitiveManagerBase * primitive_manager) 00269 { 00270 m_primitive_manager = primitive_manager; 00271 } 00272 00273 SIMD_FORCE_INLINE btAABB getGlobalBox() const 00274 { 00275 btAABB totalbox; 00276 getNodeBound(0, totalbox); 00277 return totalbox; 00278 } 00279 00280 SIMD_FORCE_INLINE void setPrimitiveManager(btPrimitiveManagerBase * primitive_manager) 00281 { 00282 m_primitive_manager = primitive_manager; 00283 } 00284 00285 SIMD_FORCE_INLINE btPrimitiveManagerBase * getPrimitiveManager() const 00286 { 00287 return m_primitive_manager; 00288 } 00289 00290 00293 00295 SIMD_FORCE_INLINE void update() 00296 { 00297 refit(); 00298 } 00299 00301 void buildSet(); 00302 00304 bool boxQuery(const btAABB & box, btAlignedObjectArray<int> & collided_results) const; 00305 00307 SIMD_FORCE_INLINE bool boxQueryTrans(const btAABB & box, 00308 const btTransform & transform, btAlignedObjectArray<int> & collided_results) const 00309 { 00310 btAABB transbox=box; 00311 transbox.appy_transform(transform); 00312 return boxQuery(transbox,collided_results); 00313 } 00314 00316 bool rayQuery( 00317 const btVector3 & ray_dir,const btVector3 & ray_origin , 00318 btAlignedObjectArray<int> & collided_results) const; 00319 00321 SIMD_FORCE_INLINE bool hasHierarchy() const 00322 { 00323 return true; 00324 } 00325 00327 SIMD_FORCE_INLINE bool isTrimesh() const 00328 { 00329 return m_primitive_manager->is_trimesh(); 00330 } 00331 00333 SIMD_FORCE_INLINE int getNodeCount() const 00334 { 00335 return m_box_tree.getNodeCount(); 00336 } 00337 00339 SIMD_FORCE_INLINE bool isLeafNode(int nodeindex) const 00340 { 00341 return m_box_tree.isLeafNode(nodeindex); 00342 } 00343 00344 SIMD_FORCE_INLINE int getNodeData(int nodeindex) const 00345 { 00346 return m_box_tree.getNodeData(nodeindex); 00347 } 00348 00349 SIMD_FORCE_INLINE void getNodeBound(int nodeindex, btAABB & bound) const 00350 { 00351 m_box_tree.getNodeBound(nodeindex, bound); 00352 } 00353 00354 SIMD_FORCE_INLINE void setNodeBound(int nodeindex, const btAABB & bound) 00355 { 00356 m_box_tree.setNodeBound(nodeindex, bound); 00357 } 00358 00359 00360 SIMD_FORCE_INLINE int getLeftNode(int nodeindex) const 00361 { 00362 return m_box_tree.getLeftNode(nodeindex); 00363 } 00364 00365 SIMD_FORCE_INLINE int getRightNode(int nodeindex) const 00366 { 00367 return m_box_tree.getRightNode(nodeindex); 00368 } 00369 00370 SIMD_FORCE_INLINE int getEscapeNodeIndex(int nodeindex) const 00371 { 00372 return m_box_tree.getEscapeNodeIndex(nodeindex); 00373 } 00374 00375 SIMD_FORCE_INLINE void getNodeTriangle(int nodeindex,btPrimitiveTriangle & triangle) const 00376 { 00377 m_primitive_manager->get_primitive_triangle(getNodeData(nodeindex),triangle); 00378 } 00379 00380 00381 SIMD_FORCE_INLINE const GIM_BVH_TREE_NODE * get_node_pointer(int index = 0) const 00382 { 00383 return m_box_tree.get_node_pointer(index); 00384 } 00385 00386 #ifdef TRI_COLLISION_PROFILING 00387 static float getAverageTreeCollisionTime(); 00388 #endif //TRI_COLLISION_PROFILING 00389 00390 static void find_collision(btGImpactBvh * boxset1, const btTransform & trans1, 00391 btGImpactBvh * boxset2, const btTransform & trans2, 00392 btPairSet & collision_pairs); 00393 }; 00394 00395 00396 #endif // GIM_BOXPRUNING_H_INCLUDED