Blender V2.61 - r43446
|
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 m_padding[5];//bad, due to alignment 00111 00112 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 //QUANTIZED_BVH_H