Blender V2.61 - r43446

btGImpactQuantizedBvh.h

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