Blender V2.61 - r43446

btGImpactBvh.h

Go to the documentation of this file.
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