btQuantizedBvh.h
Go to the documentation of this file.
00001 /*
00002 Bullet Continuous Collision Detection and Physics Library
00003 Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
00004 
00005 This software is provided 'as-is', without any express or implied warranty.
00006 In no event will the authors be held liable for any damages arising from the use of this software.
00007 Permission is granted to anyone to use this software for any purpose, 
00008 including commercial applications, and to alter it and redistribute it freely, 
00009 subject to the following restrictions:
00010 
00011 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.
00012 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
00013 3. This notice may not be removed or altered from any source distribution.
00014 */
00015 
00016 #ifndef BT_QUANTIZED_BVH_H
00017 #define BT_QUANTIZED_BVH_H
00018 
00019 class btSerializer;
00020 
00021 //#define DEBUG_CHECK_DEQUANTIZATION 1
00022 #ifdef DEBUG_CHECK_DEQUANTIZATION
00023 #ifdef __SPU__
00024 #define printf spu_printf
00025 #endif //__SPU__
00026 
00027 #include <stdio.h>
00028 #include <stdlib.h>
00029 #endif //DEBUG_CHECK_DEQUANTIZATION
00030 
00031 #include "LinearMath/btVector3.h"
00032 #include "LinearMath/btAlignedAllocator.h"
00033 
00034 #ifdef BT_USE_DOUBLE_PRECISION
00035 #define btQuantizedBvhData btQuantizedBvhDoubleData
00036 #define btOptimizedBvhNodeData btOptimizedBvhNodeDoubleData
00037 #define btQuantizedBvhDataName "btQuantizedBvhDoubleData"
00038 #else
00039 #define btQuantizedBvhData btQuantizedBvhFloatData
00040 #define btOptimizedBvhNodeData btOptimizedBvhNodeFloatData
00041 #define btQuantizedBvhDataName "btQuantizedBvhFloatData"
00042 #endif
00043 
00044 
00045 
00046 //http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/vclrf__m128.asp
00047 
00048 
00049 //Note: currently we have 16 bytes per quantized node
00050 #define MAX_SUBTREE_SIZE_IN_BYTES  2048
00051 
00052 // 10 gives the potential for 1024 parts, with at most 2^21 (2097152) (minus one
00053 // actually) triangles each (since the sign bit is reserved
00054 #define MAX_NUM_PARTS_IN_BITS 10
00055 
00058 ATTRIBUTE_ALIGNED16     (struct) btQuantizedBvhNode
00059 {
00060         BT_DECLARE_ALIGNED_ALLOCATOR();
00061 
00062         //12 bytes
00063         unsigned short int      m_quantizedAabbMin[3];
00064         unsigned short int      m_quantizedAabbMax[3];
00065         //4 bytes
00066         int     m_escapeIndexOrTriangleIndex;
00067 
00068         bool isLeafNode() const
00069         {
00070                 //skipindex is negative (internal node), triangleindex >=0 (leafnode)
00071                 return (m_escapeIndexOrTriangleIndex >= 0);
00072         }
00073         int getEscapeIndex() const
00074         {
00075                 btAssert(!isLeafNode());
00076                 return -m_escapeIndexOrTriangleIndex;
00077         }
00078         int     getTriangleIndex() const
00079         {
00080                 btAssert(isLeafNode());
00081                 // Get only the lower bits where the triangle index is stored
00082                 return (m_escapeIndexOrTriangleIndex&~((~0)<<(31-MAX_NUM_PARTS_IN_BITS)));
00083         }
00084         int     getPartId() const
00085         {
00086                 btAssert(isLeafNode());
00087                 // Get only the highest bits where the part index is stored
00088                 return (m_escapeIndexOrTriangleIndex>>(31-MAX_NUM_PARTS_IN_BITS));
00089         }
00090 }
00091 ;
00092 
00095 ATTRIBUTE_ALIGNED16 (struct) btOptimizedBvhNode
00096 {
00097         BT_DECLARE_ALIGNED_ALLOCATOR();
00098 
00099         //32 bytes
00100         btVector3       m_aabbMinOrg;
00101         btVector3       m_aabbMaxOrg;
00102 
00103         //4
00104         int     m_escapeIndex;
00105 
00106         //8
00107         //for child nodes
00108         int     m_subPart;
00109         int     m_triangleIndex;
00110 
00111 //pad the size to 64 bytes
00112         char    m_padding[20];
00113 };
00114 
00115 
00117 ATTRIBUTE_ALIGNED16(class) btBvhSubtreeInfo
00118 {
00119 public:
00120         BT_DECLARE_ALIGNED_ALLOCATOR();
00121 
00122         //12 bytes
00123         unsigned short int      m_quantizedAabbMin[3];
00124         unsigned short int      m_quantizedAabbMax[3];
00125         //4 bytes, points to the root of the subtree
00126         int                     m_rootNodeIndex;
00127         //4 bytes
00128         int                     m_subtreeSize;
00129         int                     m_padding[3];
00130 
00131         btBvhSubtreeInfo()
00132         {
00133                 //memset(&m_padding[0], 0, sizeof(m_padding));
00134         }
00135 
00136 
00137         void    setAabbFromQuantizeNode(const btQuantizedBvhNode& quantizedNode)
00138         {
00139                 m_quantizedAabbMin[0] = quantizedNode.m_quantizedAabbMin[0];
00140                 m_quantizedAabbMin[1] = quantizedNode.m_quantizedAabbMin[1];
00141                 m_quantizedAabbMin[2] = quantizedNode.m_quantizedAabbMin[2];
00142                 m_quantizedAabbMax[0] = quantizedNode.m_quantizedAabbMax[0];
00143                 m_quantizedAabbMax[1] = quantizedNode.m_quantizedAabbMax[1];
00144                 m_quantizedAabbMax[2] = quantizedNode.m_quantizedAabbMax[2];
00145         }
00146 }
00147 ;
00148 
00149 
00150 class btNodeOverlapCallback
00151 {
00152 public:
00153         virtual ~btNodeOverlapCallback() {};
00154 
00155         virtual void processNode(int subPart, int triangleIndex) = 0;
00156 };
00157 
00158 #include "LinearMath/btAlignedAllocator.h"
00159 #include "LinearMath/btAlignedObjectArray.h"
00160 
00161 
00162 
00164 typedef btAlignedObjectArray<btOptimizedBvhNode>        NodeArray;
00165 typedef btAlignedObjectArray<btQuantizedBvhNode>        QuantizedNodeArray;
00166 typedef btAlignedObjectArray<btBvhSubtreeInfo>          BvhSubtreeInfoArray;
00167 
00168 
00172 ATTRIBUTE_ALIGNED16(class) btQuantizedBvh
00173 {
00174 public:
00175         enum btTraversalMode
00176         {
00177                 TRAVERSAL_STACKLESS = 0,
00178                 TRAVERSAL_STACKLESS_CACHE_FRIENDLY,
00179                 TRAVERSAL_RECURSIVE
00180         };
00181 
00182 protected:
00183 
00184 
00185         btVector3                       m_bvhAabbMin;
00186         btVector3                       m_bvhAabbMax;
00187         btVector3                       m_bvhQuantization;
00188 
00189         int                                     m_bulletVersion;        //for serialization versioning. It could also be used to detect endianess.
00190 
00191         int                                     m_curNodeIndex;
00192         //quantization data
00193         bool                            m_useQuantization;
00194 
00195 
00196 
00197         NodeArray                       m_leafNodes;
00198         NodeArray                       m_contiguousNodes;
00199         QuantizedNodeArray      m_quantizedLeafNodes;
00200         QuantizedNodeArray      m_quantizedContiguousNodes;
00201         
00202         btTraversalMode m_traversalMode;
00203         BvhSubtreeInfoArray             m_SubtreeHeaders;
00204 
00205         //This is only used for serialization so we don't have to add serialization directly to btAlignedObjectArray
00206         mutable int m_subtreeHeaderCount;
00207 
00208         
00209 
00210 
00211 
00214         void    setInternalNodeAabbMin(int nodeIndex, const btVector3& aabbMin)
00215         {
00216                 if (m_useQuantization)
00217                 {
00218                         quantize(&m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0] ,aabbMin,0);
00219                 } else
00220                 {
00221                         m_contiguousNodes[nodeIndex].m_aabbMinOrg = aabbMin;
00222 
00223                 }
00224         }
00225         void    setInternalNodeAabbMax(int nodeIndex,const btVector3& aabbMax)
00226         {
00227                 if (m_useQuantization)
00228                 {
00229                         quantize(&m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0],aabbMax,1);
00230                 } else
00231                 {
00232                         m_contiguousNodes[nodeIndex].m_aabbMaxOrg = aabbMax;
00233                 }
00234         }
00235 
00236         btVector3 getAabbMin(int nodeIndex) const
00237         {
00238                 if (m_useQuantization)
00239                 {
00240                         return unQuantize(&m_quantizedLeafNodes[nodeIndex].m_quantizedAabbMin[0]);
00241                 }
00242                 //non-quantized
00243                 return m_leafNodes[nodeIndex].m_aabbMinOrg;
00244 
00245         }
00246         btVector3 getAabbMax(int nodeIndex) const
00247         {
00248                 if (m_useQuantization)
00249                 {
00250                         return unQuantize(&m_quantizedLeafNodes[nodeIndex].m_quantizedAabbMax[0]);
00251                 } 
00252                 //non-quantized
00253                 return m_leafNodes[nodeIndex].m_aabbMaxOrg;
00254                 
00255         }
00256 
00257         
00258         void    setInternalNodeEscapeIndex(int nodeIndex, int escapeIndex)
00259         {
00260                 if (m_useQuantization)
00261                 {
00262                         m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex = -escapeIndex;
00263                 } 
00264                 else
00265                 {
00266                         m_contiguousNodes[nodeIndex].m_escapeIndex = escapeIndex;
00267                 }
00268 
00269         }
00270 
00271         void mergeInternalNodeAabb(int nodeIndex,const btVector3& newAabbMin,const btVector3& newAabbMax) 
00272         {
00273                 if (m_useQuantization)
00274                 {
00275                         unsigned short int quantizedAabbMin[3];
00276                         unsigned short int quantizedAabbMax[3];
00277                         quantize(quantizedAabbMin,newAabbMin,0);
00278                         quantize(quantizedAabbMax,newAabbMax,1);
00279                         for (int i=0;i<3;i++)
00280                         {
00281                                 if (m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[i] > quantizedAabbMin[i])
00282                                         m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[i] = quantizedAabbMin[i];
00283 
00284                                 if (m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[i] < quantizedAabbMax[i])
00285                                         m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[i] = quantizedAabbMax[i];
00286 
00287                         }
00288                 } else
00289                 {
00290                         //non-quantized
00291                         m_contiguousNodes[nodeIndex].m_aabbMinOrg.setMin(newAabbMin);
00292                         m_contiguousNodes[nodeIndex].m_aabbMaxOrg.setMax(newAabbMax);           
00293                 }
00294         }
00295 
00296         void    swapLeafNodes(int firstIndex,int secondIndex);
00297 
00298         void    assignInternalNodeFromLeafNode(int internalNode,int leafNodeIndex);
00299 
00300 protected:
00301 
00302         
00303 
00304         void    buildTree       (int startIndex,int endIndex);
00305 
00306         int     calcSplittingAxis(int startIndex,int endIndex);
00307 
00308         int     sortAndCalcSplittingIndex(int startIndex,int endIndex,int splitAxis);
00309         
00310         void    walkStacklessTree(btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const;
00311 
00312         void    walkStacklessQuantizedTreeAgainstRay(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax, int startNodeIndex,int endNodeIndex) const;
00313         void    walkStacklessQuantizedTree(btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax,int startNodeIndex,int endNodeIndex) const;
00314         void    walkStacklessTreeAgainstRay(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax, int startNodeIndex,int endNodeIndex) const;
00315 
00317         void    walkStacklessQuantizedTreeCacheFriendly(btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax) const;
00318 
00320         void    walkRecursiveQuantizedTreeAgainstQueryAabb(const btQuantizedBvhNode* currentNode,btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax) const;
00321 
00323         void    walkRecursiveQuantizedTreeAgainstQuantizedTree(const btQuantizedBvhNode* treeNodeA,const btQuantizedBvhNode* treeNodeB,btNodeOverlapCallback* nodeCallback) const;
00324         
00325 
00326 
00327 
00328         void    updateSubtreeHeaders(int leftChildNodexIndex,int rightChildNodexIndex);
00329 
00330 public:
00331         
00332         BT_DECLARE_ALIGNED_ALLOCATOR();
00333 
00334         btQuantizedBvh();
00335 
00336         virtual ~btQuantizedBvh();
00337 
00338         
00340         void    setQuantizationValues(const btVector3& bvhAabbMin,const btVector3& bvhAabbMax,btScalar quantizationMargin=btScalar(1.0));
00341         QuantizedNodeArray&     getLeafNodeArray() {                    return  m_quantizedLeafNodes;   }
00343         void    buildInternal();
00345 
00346         void    reportAabbOverlappingNodex(btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const;
00347         void    reportRayOverlappingNodex (btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget) const;
00348         void    reportBoxCastOverlappingNodex(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin,const btVector3& aabbMax) const;
00349 
00350                 SIMD_FORCE_INLINE void quantize(unsigned short* out, const btVector3& point,int isMax) const
00351         {
00352 
00353                 btAssert(m_useQuantization);
00354 
00355                 btAssert(point.getX() <= m_bvhAabbMax.getX());
00356                 btAssert(point.getY() <= m_bvhAabbMax.getY());
00357                 btAssert(point.getZ() <= m_bvhAabbMax.getZ());
00358 
00359                 btAssert(point.getX() >= m_bvhAabbMin.getX());
00360                 btAssert(point.getY() >= m_bvhAabbMin.getY());
00361                 btAssert(point.getZ() >= m_bvhAabbMin.getZ());
00362 
00363                 btVector3 v = (point - m_bvhAabbMin) * m_bvhQuantization;
00367                 if (isMax)
00368                 {
00369                         out[0] = (unsigned short) (((unsigned short)(v.getX()+btScalar(1.)) | 1));
00370                         out[1] = (unsigned short) (((unsigned short)(v.getY()+btScalar(1.)) | 1));
00371                         out[2] = (unsigned short) (((unsigned short)(v.getZ()+btScalar(1.)) | 1));
00372                 } else
00373                 {
00374                         out[0] = (unsigned short) (((unsigned short)(v.getX()) & 0xfffe));
00375                         out[1] = (unsigned short) (((unsigned short)(v.getY()) & 0xfffe));
00376                         out[2] = (unsigned short) (((unsigned short)(v.getZ()) & 0xfffe));
00377                 }
00378 
00379 
00380 #ifdef DEBUG_CHECK_DEQUANTIZATION
00381                 btVector3 newPoint = unQuantize(out);
00382                 if (isMax)
00383                 {
00384                         if (newPoint.getX() < point.getX())
00385                         {
00386                                 printf("unconservative X, diffX = %f, oldX=%f,newX=%f\n",newPoint.getX()-point.getX(), newPoint.getX(),point.getX());
00387                         }
00388                         if (newPoint.getY() < point.getY())
00389                         {
00390                                 printf("unconservative Y, diffY = %f, oldY=%f,newY=%f\n",newPoint.getY()-point.getY(), newPoint.getY(),point.getY());
00391                         }
00392                         if (newPoint.getZ() < point.getZ())
00393                         {
00394 
00395                                 printf("unconservative Z, diffZ = %f, oldZ=%f,newZ=%f\n",newPoint.getZ()-point.getZ(), newPoint.getZ(),point.getZ());
00396                         }
00397                 } else
00398                 {
00399                         if (newPoint.getX() > point.getX())
00400                         {
00401                                 printf("unconservative X, diffX = %f, oldX=%f,newX=%f\n",newPoint.getX()-point.getX(), newPoint.getX(),point.getX());
00402                         }
00403                         if (newPoint.getY() > point.getY())
00404                         {
00405                                 printf("unconservative Y, diffY = %f, oldY=%f,newY=%f\n",newPoint.getY()-point.getY(), newPoint.getY(),point.getY());
00406                         }
00407                         if (newPoint.getZ() > point.getZ())
00408                         {
00409                                 printf("unconservative Z, diffZ = %f, oldZ=%f,newZ=%f\n",newPoint.getZ()-point.getZ(), newPoint.getZ(),point.getZ());
00410                         }
00411                 }
00412 #endif //DEBUG_CHECK_DEQUANTIZATION
00413 
00414         }
00415 
00416 
00417         SIMD_FORCE_INLINE void quantizeWithClamp(unsigned short* out, const btVector3& point2,int isMax) const
00418         {
00419 
00420                 btAssert(m_useQuantization);
00421 
00422                 btVector3 clampedPoint(point2);
00423                 clampedPoint.setMax(m_bvhAabbMin);
00424                 clampedPoint.setMin(m_bvhAabbMax);
00425 
00426                 quantize(out,clampedPoint,isMax);
00427 
00428         }
00429         
00430         SIMD_FORCE_INLINE btVector3     unQuantize(const unsigned short* vecIn) const
00431         {
00432                         btVector3       vecOut;
00433                         vecOut.setValue(
00434                         (btScalar)(vecIn[0]) / (m_bvhQuantization.getX()),
00435                         (btScalar)(vecIn[1]) / (m_bvhQuantization.getY()),
00436                         (btScalar)(vecIn[2]) / (m_bvhQuantization.getZ()));
00437                         vecOut += m_bvhAabbMin;
00438                         return vecOut;
00439         }
00440 
00442         void    setTraversalMode(btTraversalMode        traversalMode)
00443         {
00444                 m_traversalMode = traversalMode;
00445         }
00446 
00447 
00448         SIMD_FORCE_INLINE QuantizedNodeArray&   getQuantizedNodeArray()
00449         {       
00450                 return  m_quantizedContiguousNodes;
00451         }
00452 
00453 
00454         SIMD_FORCE_INLINE BvhSubtreeInfoArray&  getSubtreeInfoArray()
00455         {
00456                 return m_SubtreeHeaders;
00457         }
00458 
00460 
00462         unsigned calculateSerializeBufferSize() const;
00463 
00465         virtual bool serialize(void *o_alignedDataBuffer, unsigned i_dataBufferSize, bool i_swapEndian) const;
00466 
00468         static btQuantizedBvh *deSerializeInPlace(void *i_alignedDataBuffer, unsigned int i_dataBufferSize, bool i_swapEndian);
00469 
00470         static unsigned int getAlignmentSerializationPadding();
00472 
00473         
00474         virtual int     calculateSerializeBufferSizeNew() const;
00475 
00477         virtual const char*     serialize(void* dataBuffer, btSerializer* serializer) const;
00478 
00479         virtual void deSerializeFloat(struct btQuantizedBvhFloatData& quantizedBvhFloatData);
00480 
00481         virtual void deSerializeDouble(struct btQuantizedBvhDoubleData& quantizedBvhDoubleData);
00482 
00483 
00485 
00486         SIMD_FORCE_INLINE bool isQuantized()
00487         {
00488                 return m_useQuantization;
00489         }
00490 
00491 private:
00492         // Special "copy" constructor that allows for in-place deserialization
00493         // Prevents btVector3's default constructor from being called, but doesn't inialize much else
00494         // ownsMemory should most likely be false if deserializing, and if you are not, don't call this (it also changes the function signature, which we need)
00495         btQuantizedBvh(btQuantizedBvh &other, bool ownsMemory);
00496 
00497 }
00498 ;
00499 
00500 
00501 struct  btBvhSubtreeInfoData
00502 {
00503         int                     m_rootNodeIndex;
00504         int                     m_subtreeSize;
00505         unsigned short m_quantizedAabbMin[3];
00506         unsigned short m_quantizedAabbMax[3];
00507 };
00508 
00509 struct btOptimizedBvhNodeFloatData
00510 {
00511         btVector3FloatData      m_aabbMinOrg;
00512         btVector3FloatData      m_aabbMaxOrg;
00513         int     m_escapeIndex;
00514         int     m_subPart;
00515         int     m_triangleIndex;
00516         char m_pad[4];
00517 };
00518 
00519 struct btOptimizedBvhNodeDoubleData
00520 {
00521         btVector3DoubleData     m_aabbMinOrg;
00522         btVector3DoubleData     m_aabbMaxOrg;
00523         int     m_escapeIndex;
00524         int     m_subPart;
00525         int     m_triangleIndex;
00526         char    m_pad[4];
00527 };
00528 
00529 
00530 struct btQuantizedBvhNodeData
00531 {
00532         unsigned short m_quantizedAabbMin[3];
00533         unsigned short m_quantizedAabbMax[3];
00534         int     m_escapeIndexOrTriangleIndex;
00535 };
00536 
00537 struct  btQuantizedBvhFloatData
00538 {
00539         btVector3FloatData                      m_bvhAabbMin;
00540         btVector3FloatData                      m_bvhAabbMax;
00541         btVector3FloatData                      m_bvhQuantization;
00542         int                                     m_curNodeIndex;
00543         int                                     m_useQuantization;
00544         int                                     m_numContiguousLeafNodes;
00545         int                                     m_numQuantizedContiguousNodes;
00546         btOptimizedBvhNodeFloatData     *m_contiguousNodesPtr;
00547         btQuantizedBvhNodeData          *m_quantizedContiguousNodesPtr;
00548         btBvhSubtreeInfoData    *m_subTreeInfoPtr;
00549         int                                     m_traversalMode;
00550         int                                     m_numSubtreeHeaders;
00551         
00552 };
00553 
00554 struct  btQuantizedBvhDoubleData
00555 {
00556         btVector3DoubleData                     m_bvhAabbMin;
00557         btVector3DoubleData                     m_bvhAabbMax;
00558         btVector3DoubleData                     m_bvhQuantization;
00559         int                                                     m_curNodeIndex;
00560         int                                                     m_useQuantization;
00561         int                                                     m_numContiguousLeafNodes;
00562         int                                                     m_numQuantizedContiguousNodes;
00563         btOptimizedBvhNodeDoubleData    *m_contiguousNodesPtr;
00564         btQuantizedBvhNodeData                  *m_quantizedContiguousNodesPtr;
00565 
00566         int                                                     m_traversalMode;
00567         int                                                     m_numSubtreeHeaders;
00568         btBvhSubtreeInfoData            *m_subTreeInfoPtr;
00569 };
00570 
00571 
00572 SIMD_FORCE_INLINE       int     btQuantizedBvh::calculateSerializeBufferSizeNew() const
00573 {
00574         return sizeof(btQuantizedBvhData);
00575 }
00576 
00577 
00578 
00579 #endif //BT_QUANTIZED_BVH_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines


bullet
Author(s): Erwin Coumans, ROS package maintained by Tully Foote
autogenerated on Wed Oct 31 2012 07:54:31