|
Blender
V2.59
|
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 QUANTIZED_BVH_H 00017 #define 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 int:5*8*sizeof(int); 00111 // int m_padding[5];//bad, due to alignment 00112 00113 00114 }; 00115 00116 00118 ATTRIBUTE_ALIGNED16(class) btBvhSubtreeInfo 00119 { 00120 public: 00121 BT_DECLARE_ALIGNED_ALLOCATOR(); 00122 00123 //12 bytes 00124 unsigned short int m_quantizedAabbMin[3]; 00125 unsigned short int m_quantizedAabbMax[3]; 00126 //4 bytes, points to the root of the subtree 00127 int m_rootNodeIndex; 00128 //4 bytes 00129 int m_subtreeSize; 00130 int m_padding[3]; 00131 00132 btBvhSubtreeInfo() 00133 { 00134 //memset(&m_padding[0], 0, sizeof(m_padding)); 00135 } 00136 00137 00138 void setAabbFromQuantizeNode(const btQuantizedBvhNode& quantizedNode) 00139 { 00140 m_quantizedAabbMin[0] = quantizedNode.m_quantizedAabbMin[0]; 00141 m_quantizedAabbMin[1] = quantizedNode.m_quantizedAabbMin[1]; 00142 m_quantizedAabbMin[2] = quantizedNode.m_quantizedAabbMin[2]; 00143 m_quantizedAabbMax[0] = quantizedNode.m_quantizedAabbMax[0]; 00144 m_quantizedAabbMax[1] = quantizedNode.m_quantizedAabbMax[1]; 00145 m_quantizedAabbMax[2] = quantizedNode.m_quantizedAabbMax[2]; 00146 } 00147 } 00148 ; 00149 00150 00151 class btNodeOverlapCallback 00152 { 00153 public: 00154 virtual ~btNodeOverlapCallback() {}; 00155 00156 virtual void processNode(int subPart, int triangleIndex) = 0; 00157 }; 00158 00159 #include "LinearMath/btAlignedAllocator.h" 00160 #include "LinearMath/btAlignedObjectArray.h" 00161 00162 00163 00165 typedef btAlignedObjectArray<btOptimizedBvhNode> NodeArray; 00166 typedef btAlignedObjectArray<btQuantizedBvhNode> QuantizedNodeArray; 00167 typedef btAlignedObjectArray<btBvhSubtreeInfo> BvhSubtreeInfoArray; 00168 00169 00173 ATTRIBUTE_ALIGNED16(class) btQuantizedBvh 00174 { 00175 public: 00176 enum btTraversalMode 00177 { 00178 TRAVERSAL_STACKLESS = 0, 00179 TRAVERSAL_STACKLESS_CACHE_FRIENDLY, 00180 TRAVERSAL_RECURSIVE 00181 }; 00182 00183 protected: 00184 00185 00186 btVector3 m_bvhAabbMin; 00187 btVector3 m_bvhAabbMax; 00188 btVector3 m_bvhQuantization; 00189 00190 int m_bulletVersion; //for serialization versioning. It could also be used to detect endianess. 00191 00192 int m_curNodeIndex; 00193 //quantization data 00194 bool m_useQuantization; 00195 00196 00197 00198 NodeArray m_leafNodes; 00199 NodeArray m_contiguousNodes; 00200 QuantizedNodeArray m_quantizedLeafNodes; 00201 QuantizedNodeArray m_quantizedContiguousNodes; 00202 00203 btTraversalMode m_traversalMode; 00204 BvhSubtreeInfoArray m_SubtreeHeaders; 00205 00206 //This is only used for serialization so we don't have to add serialization directly to btAlignedObjectArray 00207 mutable int m_subtreeHeaderCount; 00208 00209 00210 00211 00212 00215 void setInternalNodeAabbMin(int nodeIndex, const btVector3& aabbMin) 00216 { 00217 if (m_useQuantization) 00218 { 00219 quantize(&m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0] ,aabbMin,0); 00220 } else 00221 { 00222 m_contiguousNodes[nodeIndex].m_aabbMinOrg = aabbMin; 00223 00224 } 00225 } 00226 void setInternalNodeAabbMax(int nodeIndex,const btVector3& aabbMax) 00227 { 00228 if (m_useQuantization) 00229 { 00230 quantize(&m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0],aabbMax,1); 00231 } else 00232 { 00233 m_contiguousNodes[nodeIndex].m_aabbMaxOrg = aabbMax; 00234 } 00235 } 00236 00237 btVector3 getAabbMin(int nodeIndex) const 00238 { 00239 if (m_useQuantization) 00240 { 00241 return unQuantize(&m_quantizedLeafNodes[nodeIndex].m_quantizedAabbMin[0]); 00242 } 00243 //non-quantized 00244 return m_leafNodes[nodeIndex].m_aabbMinOrg; 00245 00246 } 00247 btVector3 getAabbMax(int nodeIndex) const 00248 { 00249 if (m_useQuantization) 00250 { 00251 return unQuantize(&m_quantizedLeafNodes[nodeIndex].m_quantizedAabbMax[0]); 00252 } 00253 //non-quantized 00254 return m_leafNodes[nodeIndex].m_aabbMaxOrg; 00255 00256 } 00257 00258 00259 void setInternalNodeEscapeIndex(int nodeIndex, int escapeIndex) 00260 { 00261 if (m_useQuantization) 00262 { 00263 m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex = -escapeIndex; 00264 } 00265 else 00266 { 00267 m_contiguousNodes[nodeIndex].m_escapeIndex = escapeIndex; 00268 } 00269 00270 } 00271 00272 void mergeInternalNodeAabb(int nodeIndex,const btVector3& newAabbMin,const btVector3& newAabbMax) 00273 { 00274 if (m_useQuantization) 00275 { 00276 unsigned short int quantizedAabbMin[3]; 00277 unsigned short int quantizedAabbMax[3]; 00278 quantize(quantizedAabbMin,newAabbMin,0); 00279 quantize(quantizedAabbMax,newAabbMax,1); 00280 for (int i=0;i<3;i++) 00281 { 00282 if (m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[i] > quantizedAabbMin[i]) 00283 m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[i] = quantizedAabbMin[i]; 00284 00285 if (m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[i] < quantizedAabbMax[i]) 00286 m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[i] = quantizedAabbMax[i]; 00287 00288 } 00289 } else 00290 { 00291 //non-quantized 00292 m_contiguousNodes[nodeIndex].m_aabbMinOrg.setMin(newAabbMin); 00293 m_contiguousNodes[nodeIndex].m_aabbMaxOrg.setMax(newAabbMax); 00294 } 00295 } 00296 00297 void swapLeafNodes(int firstIndex,int secondIndex); 00298 00299 void assignInternalNodeFromLeafNode(int internalNode,int leafNodeIndex); 00300 00301 protected: 00302 00303 00304 00305 void buildTree (int startIndex,int endIndex); 00306 00307 int calcSplittingAxis(int startIndex,int endIndex); 00308 00309 int sortAndCalcSplittingIndex(int startIndex,int endIndex,int splitAxis); 00310 00311 void walkStacklessTree(btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const; 00312 00313 void walkStacklessQuantizedTreeAgainstRay(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax, int startNodeIndex,int endNodeIndex) const; 00314 void walkStacklessQuantizedTree(btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax,int startNodeIndex,int endNodeIndex) const; 00315 void walkStacklessTreeAgainstRay(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax, int startNodeIndex,int endNodeIndex) const; 00316 00318 void walkStacklessQuantizedTreeCacheFriendly(btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax) const; 00319 00321 void walkRecursiveQuantizedTreeAgainstQueryAabb(const btQuantizedBvhNode* currentNode,btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax) const; 00322 00324 void walkRecursiveQuantizedTreeAgainstQuantizedTree(const btQuantizedBvhNode* treeNodeA,const btQuantizedBvhNode* treeNodeB,btNodeOverlapCallback* nodeCallback) const; 00325 00326 00327 00328 00329 void updateSubtreeHeaders(int leftChildNodexIndex,int rightChildNodexIndex); 00330 00331 public: 00332 00333 BT_DECLARE_ALIGNED_ALLOCATOR(); 00334 00335 btQuantizedBvh(); 00336 00337 virtual ~btQuantizedBvh(); 00338 00339 00341 void setQuantizationValues(const btVector3& bvhAabbMin,const btVector3& bvhAabbMax,btScalar quantizationMargin=btScalar(1.0)); 00342 QuantizedNodeArray& getLeafNodeArray() { return m_quantizedLeafNodes; } 00344 void buildInternal(); 00346 00347 void reportAabbOverlappingNodex(btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const; 00348 void reportRayOverlappingNodex (btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget) const; 00349 void reportBoxCastOverlappingNodex(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin,const btVector3& aabbMax) const; 00350 00351 SIMD_FORCE_INLINE void quantize(unsigned short* out, const btVector3& point,int isMax) const 00352 { 00353 00354 btAssert(m_useQuantization); 00355 00356 btAssert(point.getX() <= m_bvhAabbMax.getX()); 00357 btAssert(point.getY() <= m_bvhAabbMax.getY()); 00358 btAssert(point.getZ() <= m_bvhAabbMax.getZ()); 00359 00360 btAssert(point.getX() >= m_bvhAabbMin.getX()); 00361 btAssert(point.getY() >= m_bvhAabbMin.getY()); 00362 btAssert(point.getZ() >= m_bvhAabbMin.getZ()); 00363 00364 btVector3 v = (point - m_bvhAabbMin) * m_bvhQuantization; 00368 if (isMax) 00369 { 00370 out[0] = (unsigned short) (((unsigned short)(v.getX()+btScalar(1.)) | 1)); 00371 out[1] = (unsigned short) (((unsigned short)(v.getY()+btScalar(1.)) | 1)); 00372 out[2] = (unsigned short) (((unsigned short)(v.getZ()+btScalar(1.)) | 1)); 00373 } else 00374 { 00375 out[0] = (unsigned short) (((unsigned short)(v.getX()) & 0xfffe)); 00376 out[1] = (unsigned short) (((unsigned short)(v.getY()) & 0xfffe)); 00377 out[2] = (unsigned short) (((unsigned short)(v.getZ()) & 0xfffe)); 00378 } 00379 00380 00381 #ifdef DEBUG_CHECK_DEQUANTIZATION 00382 btVector3 newPoint = unQuantize(out); 00383 if (isMax) 00384 { 00385 if (newPoint.getX() < point.getX()) 00386 { 00387 printf("unconservative X, diffX = %f, oldX=%f,newX=%f\n",newPoint.getX()-point.getX(), newPoint.getX(),point.getX()); 00388 } 00389 if (newPoint.getY() < point.getY()) 00390 { 00391 printf("unconservative Y, diffY = %f, oldY=%f,newY=%f\n",newPoint.getY()-point.getY(), newPoint.getY(),point.getY()); 00392 } 00393 if (newPoint.getZ() < point.getZ()) 00394 { 00395 00396 printf("unconservative Z, diffZ = %f, oldZ=%f,newZ=%f\n",newPoint.getZ()-point.getZ(), newPoint.getZ(),point.getZ()); 00397 } 00398 } else 00399 { 00400 if (newPoint.getX() > point.getX()) 00401 { 00402 printf("unconservative X, diffX = %f, oldX=%f,newX=%f\n",newPoint.getX()-point.getX(), newPoint.getX(),point.getX()); 00403 } 00404 if (newPoint.getY() > point.getY()) 00405 { 00406 printf("unconservative Y, diffY = %f, oldY=%f,newY=%f\n",newPoint.getY()-point.getY(), newPoint.getY(),point.getY()); 00407 } 00408 if (newPoint.getZ() > point.getZ()) 00409 { 00410 printf("unconservative Z, diffZ = %f, oldZ=%f,newZ=%f\n",newPoint.getZ()-point.getZ(), newPoint.getZ(),point.getZ()); 00411 } 00412 } 00413 #endif //DEBUG_CHECK_DEQUANTIZATION 00414 00415 } 00416 00417 00418 SIMD_FORCE_INLINE void quantizeWithClamp(unsigned short* out, const btVector3& point2,int isMax) const 00419 { 00420 00421 btAssert(m_useQuantization); 00422 00423 btVector3 clampedPoint(point2); 00424 clampedPoint.setMax(m_bvhAabbMin); 00425 clampedPoint.setMin(m_bvhAabbMax); 00426 00427 quantize(out,clampedPoint,isMax); 00428 00429 } 00430 00431 SIMD_FORCE_INLINE btVector3 unQuantize(const unsigned short* vecIn) const 00432 { 00433 btVector3 vecOut; 00434 vecOut.setValue( 00435 (btScalar)(vecIn[0]) / (m_bvhQuantization.getX()), 00436 (btScalar)(vecIn[1]) / (m_bvhQuantization.getY()), 00437 (btScalar)(vecIn[2]) / (m_bvhQuantization.getZ())); 00438 vecOut += m_bvhAabbMin; 00439 return vecOut; 00440 } 00441 00443 void setTraversalMode(btTraversalMode traversalMode) 00444 { 00445 m_traversalMode = traversalMode; 00446 } 00447 00448 00449 SIMD_FORCE_INLINE QuantizedNodeArray& getQuantizedNodeArray() 00450 { 00451 return m_quantizedContiguousNodes; 00452 } 00453 00454 00455 SIMD_FORCE_INLINE BvhSubtreeInfoArray& getSubtreeInfoArray() 00456 { 00457 return m_SubtreeHeaders; 00458 } 00459 00461 00463 unsigned calculateSerializeBufferSize() const; 00464 00466 virtual bool serialize(void *o_alignedDataBuffer, unsigned i_dataBufferSize, bool i_swapEndian) const; 00467 00469 static btQuantizedBvh *deSerializeInPlace(void *i_alignedDataBuffer, unsigned int i_dataBufferSize, bool i_swapEndian); 00470 00471 static unsigned int getAlignmentSerializationPadding(); 00473 00474 00475 virtual int calculateSerializeBufferSizeNew() const; 00476 00478 virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; 00479 00480 virtual void deSerializeFloat(struct btQuantizedBvhFloatData& quantizedBvhFloatData); 00481 00482 virtual void deSerializeDouble(struct btQuantizedBvhDoubleData& quantizedBvhDoubleData); 00483 00484 00486 00487 SIMD_FORCE_INLINE bool isQuantized() 00488 { 00489 return m_useQuantization; 00490 } 00491 00492 private: 00493 // Special "copy" constructor that allows for in-place deserialization 00494 // Prevents btVector3's default constructor from being called, but doesn't inialize much else 00495 // 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) 00496 btQuantizedBvh(btQuantizedBvh &other, bool ownsMemory); 00497 00498 } 00499 ; 00500 00501 00502 struct btBvhSubtreeInfoData 00503 { 00504 int m_rootNodeIndex; 00505 int m_subtreeSize; 00506 unsigned short m_quantizedAabbMin[3]; 00507 unsigned short m_quantizedAabbMax[3]; 00508 }; 00509 00510 struct btOptimizedBvhNodeFloatData 00511 { 00512 btVector3FloatData m_aabbMinOrg; 00513 btVector3FloatData m_aabbMaxOrg; 00514 int m_escapeIndex; 00515 int m_subPart; 00516 int m_triangleIndex; 00517 char m_pad[4]; 00518 }; 00519 00520 struct btOptimizedBvhNodeDoubleData 00521 { 00522 btVector3DoubleData m_aabbMinOrg; 00523 btVector3DoubleData m_aabbMaxOrg; 00524 int m_escapeIndex; 00525 int m_subPart; 00526 int m_triangleIndex; 00527 char m_pad[4]; 00528 }; 00529 00530 00531 struct btQuantizedBvhNodeData 00532 { 00533 unsigned short m_quantizedAabbMin[3]; 00534 unsigned short m_quantizedAabbMax[3]; 00535 int m_escapeIndexOrTriangleIndex; 00536 }; 00537 00538 struct btQuantizedBvhFloatData 00539 { 00540 btVector3FloatData m_bvhAabbMin; 00541 btVector3FloatData m_bvhAabbMax; 00542 btVector3FloatData m_bvhQuantization; 00543 int m_curNodeIndex; 00544 int m_useQuantization; 00545 int m_numContiguousLeafNodes; 00546 int m_numQuantizedContiguousNodes; 00547 btOptimizedBvhNodeFloatData *m_contiguousNodesPtr; 00548 btQuantizedBvhNodeData *m_quantizedContiguousNodesPtr; 00549 btBvhSubtreeInfoData *m_subTreeInfoPtr; 00550 int m_traversalMode; 00551 int m_numSubtreeHeaders; 00552 00553 }; 00554 00555 struct btQuantizedBvhDoubleData 00556 { 00557 btVector3DoubleData m_bvhAabbMin; 00558 btVector3DoubleData m_bvhAabbMax; 00559 btVector3DoubleData m_bvhQuantization; 00560 int m_curNodeIndex; 00561 int m_useQuantization; 00562 int m_numContiguousLeafNodes; 00563 int m_numQuantizedContiguousNodes; 00564 btOptimizedBvhNodeDoubleData *m_contiguousNodesPtr; 00565 btQuantizedBvhNodeData *m_quantizedContiguousNodesPtr; 00566 00567 int m_traversalMode; 00568 int m_numSubtreeHeaders; 00569 btBvhSubtreeInfoData *m_subTreeInfoPtr; 00570 }; 00571 00572 00573 SIMD_FORCE_INLINE int btQuantizedBvh::calculateSerializeBufferSizeNew() const 00574 { 00575 return sizeof(btQuantizedBvhData); 00576 } 00577 00578 00579 00580 #endif //QUANTIZED_BVH_H