2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
5 This software is provided 'as-is', without any express or implied warranty.
6 In no event will the authors be held liable for any damages arising from the use of this software.
7 Permission is granted to anyone to use this software for any purpose,
8 including commercial applications, and to alter it and redistribute it freely,
9 subject to the following restrictions:
11 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.
12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
13 3. This notice may not be removed or altered from any source distribution.
16 #include "btQuantizedBvh.h"
18 #include "LinearMath/btAabbUtil2.h"
19 #include "LinearMath/btIDebugDraw.h"
20 #include "LinearMath/btSerializer.h"
24 btQuantizedBvh::btQuantizedBvh() :
25 m_bulletVersion(BT_BULLET_VERSION),
26 m_useQuantization(false),
27 //m_traversalMode(TRAVERSAL_STACKLESS_CACHE_FRIENDLY)
28 m_traversalMode(TRAVERSAL_STACKLESS)
29 //m_traversalMode(TRAVERSAL_RECURSIVE)
30 ,m_subtreeHeaderCount(0) //PCK: add this line
32 m_bvhAabbMin.setValue(-SIMD_INFINITY,-SIMD_INFINITY,-SIMD_INFINITY);
33 m_bvhAabbMax.setValue(SIMD_INFINITY,SIMD_INFINITY,SIMD_INFINITY);
40 void btQuantizedBvh::buildInternal()
42 ///assumes that caller filled in the m_quantizedLeafNodes
43 m_useQuantization = true;
46 if (m_useQuantization)
48 //now we have an array of leafnodes in m_leafNodes
49 numLeafNodes = m_quantizedLeafNodes.size();
51 m_quantizedContiguousNodes.resize(2*numLeafNodes);
57 buildTree(0,numLeafNodes);
59 ///if the entire tree is small then subtree size, we need to create a header info for the tree
60 if(m_useQuantization && !m_SubtreeHeaders.size())
62 btBvhSubtreeInfo& subtree = m_SubtreeHeaders.expand();
63 subtree.setAabbFromQuantizeNode(m_quantizedContiguousNodes[0]);
64 subtree.m_rootNodeIndex = 0;
65 subtree.m_subtreeSize = m_quantizedContiguousNodes[0].isLeafNode() ? 1 : m_quantizedContiguousNodes[0].getEscapeIndex();
68 //PCK: update the copy of the size
69 m_subtreeHeaderCount = m_SubtreeHeaders.size();
71 //PCK: clear m_quantizedLeafNodes and m_leafNodes, they are temporary
72 m_quantizedLeafNodes.clear();
78 ///just for debugging, to visualize the individual patches/subtrees
79 #ifdef DEBUG_PATCH_COLORS
87 #endif //DEBUG_PATCH_COLORS
91 void btQuantizedBvh::setQuantizationValues(const btVector3& bvhAabbMin,const btVector3& bvhAabbMax,btScalar quantizationMargin)
93 //enlarge the AABB to avoid division by zero when initializing the quantization values
94 btVector3 clampValue(quantizationMargin,quantizationMargin,quantizationMargin);
95 m_bvhAabbMin = bvhAabbMin - clampValue;
96 m_bvhAabbMax = bvhAabbMax + clampValue;
97 btVector3 aabbSize = m_bvhAabbMax - m_bvhAabbMin;
98 m_bvhQuantization = btVector3(btScalar(65533.0),btScalar(65533.0),btScalar(65533.0)) / aabbSize;
99 m_useQuantization = true;
105 btQuantizedBvh::~btQuantizedBvh()
109 #ifdef DEBUG_TREE_BUILDING
111 int gMaxStackDepth = 0;
112 #endif //DEBUG_TREE_BUILDING
114 void btQuantizedBvh::buildTree (int startIndex,int endIndex)
116 #ifdef DEBUG_TREE_BUILDING
118 if (gStackDepth > gMaxStackDepth)
119 gMaxStackDepth = gStackDepth;
120 #endif //DEBUG_TREE_BUILDING
123 int splitAxis, splitIndex, i;
124 int numIndices =endIndex-startIndex;
125 int curIndex = m_curNodeIndex;
127 btAssert(numIndices>0);
131 #ifdef DEBUG_TREE_BUILDING
133 #endif //DEBUG_TREE_BUILDING
135 assignInternalNodeFromLeafNode(m_curNodeIndex,startIndex);
140 //calculate Best Splitting Axis and where to split it. Sort the incoming 'leafNodes' array within range 'startIndex/endIndex'.
142 splitAxis = calcSplittingAxis(startIndex,endIndex);
144 splitIndex = sortAndCalcSplittingIndex(startIndex,endIndex,splitAxis);
146 int internalNodeIndex = m_curNodeIndex;
148 //set the min aabb to 'inf' or a max value, and set the max aabb to a -inf/minimum value.
149 //the aabb will be expanded during buildTree/mergeInternalNodeAabb with actual node values
150 setInternalNodeAabbMin(m_curNodeIndex,m_bvhAabbMax);//can't use btVector3(SIMD_INFINITY,SIMD_INFINITY,SIMD_INFINITY)) because of quantization
151 setInternalNodeAabbMax(m_curNodeIndex,m_bvhAabbMin);//can't use btVector3(-SIMD_INFINITY,-SIMD_INFINITY,-SIMD_INFINITY)) because of quantization
154 for (i=startIndex;i<endIndex;i++)
156 mergeInternalNodeAabb(m_curNodeIndex,getAabbMin(i),getAabbMax(i));
162 //internalNode->m_escapeIndex;
164 int leftChildNodexIndex = m_curNodeIndex;
166 //build left child tree
167 buildTree(startIndex,splitIndex);
169 int rightChildNodexIndex = m_curNodeIndex;
170 //build right child tree
171 buildTree(splitIndex,endIndex);
173 #ifdef DEBUG_TREE_BUILDING
175 #endif //DEBUG_TREE_BUILDING
177 int escapeIndex = m_curNodeIndex - curIndex;
179 if (m_useQuantization)
181 //escapeIndex is the number of nodes of this subtree
182 const int sizeQuantizedNode =sizeof(btQuantizedBvhNode);
183 const int treeSizeInBytes = escapeIndex * sizeQuantizedNode;
184 if (treeSizeInBytes > MAX_SUBTREE_SIZE_IN_BYTES)
186 updateSubtreeHeaders(leftChildNodexIndex,rightChildNodexIndex);
193 setInternalNodeEscapeIndex(internalNodeIndex,escapeIndex);
197 void btQuantizedBvh::updateSubtreeHeaders(int leftChildNodexIndex,int rightChildNodexIndex)
199 btAssert(m_useQuantization);
201 btQuantizedBvhNode& leftChildNode = m_quantizedContiguousNodes[leftChildNodexIndex];
202 int leftSubTreeSize = leftChildNode.isLeafNode() ? 1 : leftChildNode.getEscapeIndex();
203 int leftSubTreeSizeInBytes = leftSubTreeSize * static_cast<int>(sizeof(btQuantizedBvhNode));
205 btQuantizedBvhNode& rightChildNode = m_quantizedContiguousNodes[rightChildNodexIndex];
206 int rightSubTreeSize = rightChildNode.isLeafNode() ? 1 : rightChildNode.getEscapeIndex();
207 int rightSubTreeSizeInBytes = rightSubTreeSize * static_cast<int>(sizeof(btQuantizedBvhNode));
209 if(leftSubTreeSizeInBytes <= MAX_SUBTREE_SIZE_IN_BYTES)
211 btBvhSubtreeInfo& subtree = m_SubtreeHeaders.expand();
212 subtree.setAabbFromQuantizeNode(leftChildNode);
213 subtree.m_rootNodeIndex = leftChildNodexIndex;
214 subtree.m_subtreeSize = leftSubTreeSize;
217 if(rightSubTreeSizeInBytes <= MAX_SUBTREE_SIZE_IN_BYTES)
219 btBvhSubtreeInfo& subtree = m_SubtreeHeaders.expand();
220 subtree.setAabbFromQuantizeNode(rightChildNode);
221 subtree.m_rootNodeIndex = rightChildNodexIndex;
222 subtree.m_subtreeSize = rightSubTreeSize;
225 //PCK: update the copy of the size
226 m_subtreeHeaderCount = m_SubtreeHeaders.size();
230 int btQuantizedBvh::sortAndCalcSplittingIndex(int startIndex,int endIndex,int splitAxis)
233 int splitIndex =startIndex;
234 int numIndices = endIndex - startIndex;
237 btVector3 means(btScalar(0.),btScalar(0.),btScalar(0.));
238 for (i=startIndex;i<endIndex;i++)
240 btVector3 center = btScalar(0.5)*(getAabbMax(i)+getAabbMin(i));
243 means *= (btScalar(1.)/(btScalar)numIndices);
245 splitValue = means[splitAxis];
247 //sort leafNodes so all values larger then splitValue comes first, and smaller values start from 'splitIndex'.
248 for (i=startIndex;i<endIndex;i++)
250 btVector3 center = btScalar(0.5)*(getAabbMax(i)+getAabbMin(i));
251 if (center[splitAxis] > splitValue)
254 swapLeafNodes(i,splitIndex);
259 //if the splitIndex causes unbalanced trees, fix this by using the center in between startIndex and endIndex
260 //otherwise the tree-building might fail due to stack-overflows in certain cases.
261 //unbalanced1 is unsafe: it can cause stack overflows
262 //bool unbalanced1 = ((splitIndex==startIndex) || (splitIndex == (endIndex-1)));
264 //unbalanced2 should work too: always use center (perfect balanced trees)
265 //bool unbalanced2 = true;
267 //this should be safe too:
268 int rangeBalancedIndices = numIndices/3;
269 bool unbalanced = ((splitIndex<=(startIndex+rangeBalancedIndices)) || (splitIndex >=(endIndex-1-rangeBalancedIndices)));
273 splitIndex = startIndex+ (numIndices>>1);
276 bool unbal = (splitIndex==startIndex) || (splitIndex == (endIndex));
284 int btQuantizedBvh::calcSplittingAxis(int startIndex,int endIndex)
288 btVector3 means(btScalar(0.),btScalar(0.),btScalar(0.));
289 btVector3 variance(btScalar(0.),btScalar(0.),btScalar(0.));
290 int numIndices = endIndex-startIndex;
292 for (i=startIndex;i<endIndex;i++)
294 btVector3 center = btScalar(0.5)*(getAabbMax(i)+getAabbMin(i));
297 means *= (btScalar(1.)/(btScalar)numIndices);
299 for (i=startIndex;i<endIndex;i++)
301 btVector3 center = btScalar(0.5)*(getAabbMax(i)+getAabbMin(i));
302 btVector3 diff2 = center-means;
303 diff2 = diff2 * diff2;
306 variance *= (btScalar(1.)/ ((btScalar)numIndices-1) );
308 return variance.maxAxis();
313 void btQuantizedBvh::reportAabbOverlappingNodex(btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const
315 //either choose recursive traversal (walkTree) or stackless (walkStacklessTree)
317 if (m_useQuantization)
319 ///quantize query AABB
320 unsigned short int quantizedQueryAabbMin[3];
321 unsigned short int quantizedQueryAabbMax[3];
322 quantizeWithClamp(quantizedQueryAabbMin,aabbMin,0);
323 quantizeWithClamp(quantizedQueryAabbMax,aabbMax,1);
325 switch (m_traversalMode)
327 case TRAVERSAL_STACKLESS:
328 walkStacklessQuantizedTree(nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax,0,m_curNodeIndex);
330 case TRAVERSAL_STACKLESS_CACHE_FRIENDLY:
331 walkStacklessQuantizedTreeCacheFriendly(nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax);
333 case TRAVERSAL_RECURSIVE:
335 const btQuantizedBvhNode* rootNode = &m_quantizedContiguousNodes[0];
336 walkRecursiveQuantizedTreeAgainstQueryAabb(rootNode,nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax);
345 walkStacklessTree(nodeCallback,aabbMin,aabbMax);
350 int maxIterations = 0;
353 void btQuantizedBvh::walkStacklessTree(btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const
355 btAssert(!m_useQuantization);
357 const btOptimizedBvhNode* rootNode = &m_contiguousNodes[0];
358 int escapeIndex, curIndex = 0;
359 int walkIterations = 0;
361 //PCK: unsigned instead of bool
362 unsigned aabbOverlap;
364 while (curIndex < m_curNodeIndex)
366 //catch bugs in tree data
367 btAssert (walkIterations < m_curNodeIndex);
370 aabbOverlap = TestAabbAgainstAabb2(aabbMin,aabbMax,rootNode->m_aabbMinOrg,rootNode->m_aabbMaxOrg);
371 isLeafNode = rootNode->m_escapeIndex == -1;
373 //PCK: unsigned instead of bool
374 if (isLeafNode && (aabbOverlap != 0))
376 nodeCallback->processNode(rootNode->m_subPart,rootNode->m_triangleIndex);
379 //PCK: unsigned instead of bool
380 if ((aabbOverlap != 0) || isLeafNode)
386 escapeIndex = rootNode->m_escapeIndex;
387 rootNode += escapeIndex;
388 curIndex += escapeIndex;
391 if (maxIterations < walkIterations)
392 maxIterations = walkIterations;
397 ///this was the original recursive traversal, before we optimized towards stackless traversal
398 void btQuantizedBvh::walkTree(btOptimizedBvhNode* rootNode,btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const
400 bool isLeafNode, aabbOverlap = TestAabbAgainstAabb2(aabbMin,aabbMax,rootNode->m_aabbMin,rootNode->m_aabbMax);
403 isLeafNode = (!rootNode->m_leftChild && !rootNode->m_rightChild);
406 nodeCallback->processNode(rootNode);
409 walkTree(rootNode->m_leftChild,nodeCallback,aabbMin,aabbMax);
410 walkTree(rootNode->m_rightChild,nodeCallback,aabbMin,aabbMax);
417 void btQuantizedBvh::walkRecursiveQuantizedTreeAgainstQueryAabb(const btQuantizedBvhNode* currentNode,btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax) const
419 btAssert(m_useQuantization);
422 //PCK: unsigned instead of bool
423 unsigned aabbOverlap;
425 //PCK: unsigned instead of bool
426 aabbOverlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,currentNode->m_quantizedAabbMin,currentNode->m_quantizedAabbMax);
427 isLeafNode = currentNode->isLeafNode();
429 //PCK: unsigned instead of bool
430 if (aabbOverlap != 0)
434 nodeCallback->processNode(currentNode->getPartId(),currentNode->getTriangleIndex());
437 //process left and right children
438 const btQuantizedBvhNode* leftChildNode = currentNode+1;
439 walkRecursiveQuantizedTreeAgainstQueryAabb(leftChildNode,nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax);
441 const btQuantizedBvhNode* rightChildNode = leftChildNode->isLeafNode() ? leftChildNode+1:leftChildNode+leftChildNode->getEscapeIndex();
442 walkRecursiveQuantizedTreeAgainstQueryAabb(rightChildNode,nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax);
449 void btQuantizedBvh::walkStacklessTreeAgainstRay(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax, int startNodeIndex,int endNodeIndex) const
451 btAssert(!m_useQuantization);
453 const btOptimizedBvhNode* rootNode = &m_contiguousNodes[0];
454 int escapeIndex, curIndex = 0;
455 int walkIterations = 0;
457 //PCK: unsigned instead of bool
458 unsigned aabbOverlap=0;
459 unsigned rayBoxOverlap=0;
460 btScalar lambda_max = 1.0;
462 /* Quick pruning by quantized box */
463 btVector3 rayAabbMin = raySource;
464 btVector3 rayAabbMax = raySource;
465 rayAabbMin.setMin(rayTarget);
466 rayAabbMax.setMax(rayTarget);
468 /* Add box cast extents to bounding box */
469 rayAabbMin += aabbMin;
470 rayAabbMax += aabbMax;
473 btVector3 rayDir = (rayTarget-raySource);
475 lambda_max = rayDir.dot(rayTarget-raySource);
476 ///what about division by zero? --> just set rayDirection[i] to 1.0
477 btVector3 rayDirectionInverse;
478 rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[0];
479 rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[1];
480 rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[2];
481 unsigned int sign[3] = { rayDirectionInverse[0] < 0.0, rayDirectionInverse[1] < 0.0, rayDirectionInverse[2] < 0.0};
486 while (curIndex < m_curNodeIndex)
488 btScalar param = 1.0;
489 //catch bugs in tree data
490 btAssert (walkIterations < m_curNodeIndex);
494 bounds[0] = rootNode->m_aabbMinOrg;
495 bounds[1] = rootNode->m_aabbMaxOrg;
496 /* Add box cast extents */
497 bounds[0] -= aabbMax;
498 bounds[1] -= aabbMin;
500 aabbOverlap = TestAabbAgainstAabb2(rayAabbMin,rayAabbMax,rootNode->m_aabbMinOrg,rootNode->m_aabbMaxOrg);
501 //perhaps profile if it is worth doing the aabbOverlap test first
504 ///careful with this check: need to check division by zero (above) and fix the unQuantize method
505 ///thanks Joerg/hiker for the reproduction case!
506 ///http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=1858
507 rayBoxOverlap = aabbOverlap ? btRayAabb2 (raySource, rayDirectionInverse, sign, bounds, param, 0.0f, lambda_max) : false;
511 rayBoxOverlap = btRayAabb(raySource, rayTarget,bounds[0],bounds[1],param, normal);
514 isLeafNode = rootNode->m_escapeIndex == -1;
516 //PCK: unsigned instead of bool
517 if (isLeafNode && (rayBoxOverlap != 0))
519 nodeCallback->processNode(rootNode->m_subPart,rootNode->m_triangleIndex);
522 //PCK: unsigned instead of bool
523 if ((rayBoxOverlap != 0) || isLeafNode)
529 escapeIndex = rootNode->m_escapeIndex;
530 rootNode += escapeIndex;
531 curIndex += escapeIndex;
534 if (maxIterations < walkIterations)
535 maxIterations = walkIterations;
541 void btQuantizedBvh::walkStacklessQuantizedTreeAgainstRay(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax, int startNodeIndex,int endNodeIndex) const
543 btAssert(m_useQuantization);
545 int curIndex = startNodeIndex;
546 int walkIterations = 0;
547 int subTreeSize = endNodeIndex - startNodeIndex;
550 const btQuantizedBvhNode* rootNode = &m_quantizedContiguousNodes[startNodeIndex];
554 //PCK: unsigned instead of bool
555 unsigned boxBoxOverlap = 0;
556 unsigned rayBoxOverlap = 0;
558 btScalar lambda_max = 1.0;
561 btVector3 rayDirection = (rayTarget-raySource);
562 rayDirection.normalize ();
563 lambda_max = rayDirection.dot(rayTarget-raySource);
564 ///what about division by zero? --> just set rayDirection[i] to 1.0
565 rayDirection[0] = rayDirection[0] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDirection[0];
566 rayDirection[1] = rayDirection[1] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDirection[1];
567 rayDirection[2] = rayDirection[2] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDirection[2];
568 unsigned int sign[3] = { rayDirection[0] < 0.0, rayDirection[1] < 0.0, rayDirection[2] < 0.0};
571 /* Quick pruning by quantized box */
572 btVector3 rayAabbMin = raySource;
573 btVector3 rayAabbMax = raySource;
574 rayAabbMin.setMin(rayTarget);
575 rayAabbMax.setMax(rayTarget);
577 /* Add box cast extents to bounding box */
578 rayAabbMin += aabbMin;
579 rayAabbMax += aabbMax;
581 unsigned short int quantizedQueryAabbMin[3];
582 unsigned short int quantizedQueryAabbMax[3];
583 quantizeWithClamp(quantizedQueryAabbMin,rayAabbMin,0);
584 quantizeWithClamp(quantizedQueryAabbMax,rayAabbMax,1);
586 while (curIndex < endNodeIndex)
589 //#define VISUALLY_ANALYZE_BVH 1
590 #ifdef VISUALLY_ANALYZE_BVH
591 //some code snippet to debugDraw aabb, to visually analyze bvh structure
592 static int drawPatch = 0;
593 //need some global access to a debugDrawer
594 extern btIDebugDraw* debugDrawerPtr;
595 if (curIndex==drawPatch)
597 btVector3 aabbMin,aabbMax;
598 aabbMin = unQuantize(rootNode->m_quantizedAabbMin);
599 aabbMax = unQuantize(rootNode->m_quantizedAabbMax);
600 btVector3 color(1,0,0);
601 debugDrawerPtr->drawAabb(aabbMin,aabbMax,color);
603 #endif//VISUALLY_ANALYZE_BVH
605 //catch bugs in tree data
606 btAssert (walkIterations < subTreeSize);
609 //PCK: unsigned instead of bool
610 // only interested if this is closer than any previous hit
611 btScalar param = 1.0;
613 boxBoxOverlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,rootNode->m_quantizedAabbMin,rootNode->m_quantizedAabbMax);
614 isLeafNode = rootNode->isLeafNode();
618 bounds[0] = unQuantize(rootNode->m_quantizedAabbMin);
619 bounds[1] = unQuantize(rootNode->m_quantizedAabbMax);
620 /* Add box cast extents */
621 bounds[0] -= aabbMax;
622 bounds[1] -= aabbMin;
625 bool ra2 = btRayAabb2 (raySource, rayDirection, sign, bounds, param, 0.0, lambda_max);
626 bool ra = btRayAabb (raySource, rayTarget, bounds[0], bounds[1], param, normal);
629 printf("functions don't match\n");
633 ///careful with this check: need to check division by zero (above) and fix the unQuantize method
634 ///thanks Joerg/hiker for the reproduction case!
635 ///http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=1858
637 //BT_PROFILE("btRayAabb2");
638 rayBoxOverlap = btRayAabb2 (raySource, rayDirection, sign, bounds, param, 0.0f, lambda_max);
641 rayBoxOverlap = true;//btRayAabb(raySource, rayTarget, bounds[0], bounds[1], param, normal);
645 if (isLeafNode && rayBoxOverlap)
647 nodeCallback->processNode(rootNode->getPartId(),rootNode->getTriangleIndex());
650 //PCK: unsigned instead of bool
651 if ((rayBoxOverlap != 0) || isLeafNode)
657 escapeIndex = rootNode->getEscapeIndex();
658 rootNode += escapeIndex;
659 curIndex += escapeIndex;
662 if (maxIterations < walkIterations)
663 maxIterations = walkIterations;
667 void btQuantizedBvh::walkStacklessQuantizedTree(btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax,int startNodeIndex,int endNodeIndex) const
669 btAssert(m_useQuantization);
671 int curIndex = startNodeIndex;
672 int walkIterations = 0;
673 int subTreeSize = endNodeIndex - startNodeIndex;
676 const btQuantizedBvhNode* rootNode = &m_quantizedContiguousNodes[startNodeIndex];
680 //PCK: unsigned instead of bool
681 unsigned aabbOverlap;
683 while (curIndex < endNodeIndex)
686 //#define VISUALLY_ANALYZE_BVH 1
687 #ifdef VISUALLY_ANALYZE_BVH
688 //some code snippet to debugDraw aabb, to visually analyze bvh structure
689 static int drawPatch = 0;
690 //need some global access to a debugDrawer
691 extern btIDebugDraw* debugDrawerPtr;
692 if (curIndex==drawPatch)
694 btVector3 aabbMin,aabbMax;
695 aabbMin = unQuantize(rootNode->m_quantizedAabbMin);
696 aabbMax = unQuantize(rootNode->m_quantizedAabbMax);
697 btVector3 color(1,0,0);
698 debugDrawerPtr->drawAabb(aabbMin,aabbMax,color);
700 #endif//VISUALLY_ANALYZE_BVH
702 //catch bugs in tree data
703 btAssert (walkIterations < subTreeSize);
706 //PCK: unsigned instead of bool
707 aabbOverlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,rootNode->m_quantizedAabbMin,rootNode->m_quantizedAabbMax);
708 isLeafNode = rootNode->isLeafNode();
710 if (isLeafNode && aabbOverlap)
712 nodeCallback->processNode(rootNode->getPartId(),rootNode->getTriangleIndex());
715 //PCK: unsigned instead of bool
716 if ((aabbOverlap != 0) || isLeafNode)
722 escapeIndex = rootNode->getEscapeIndex();
723 rootNode += escapeIndex;
724 curIndex += escapeIndex;
727 if (maxIterations < walkIterations)
728 maxIterations = walkIterations;
732 //This traversal can be called from Playstation 3 SPU
733 void btQuantizedBvh::walkStacklessQuantizedTreeCacheFriendly(btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax) const
735 btAssert(m_useQuantization);
740 for (i=0;i<this->m_SubtreeHeaders.size();i++)
742 const btBvhSubtreeInfo& subtree = m_SubtreeHeaders[i];
744 //PCK: unsigned instead of bool
745 unsigned overlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,subtree.m_quantizedAabbMin,subtree.m_quantizedAabbMax);
748 walkStacklessQuantizedTree(nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax,
749 subtree.m_rootNodeIndex,
750 subtree.m_rootNodeIndex+subtree.m_subtreeSize);
756 void btQuantizedBvh::reportRayOverlappingNodex (btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget) const
758 reportBoxCastOverlappingNodex(nodeCallback,raySource,rayTarget,btVector3(0,0,0),btVector3(0,0,0));
762 void btQuantizedBvh::reportBoxCastOverlappingNodex(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin,const btVector3& aabbMax) const
764 //always use stackless
766 if (m_useQuantization)
768 walkStacklessQuantizedTreeAgainstRay(nodeCallback, raySource, rayTarget, aabbMin, aabbMax, 0, m_curNodeIndex);
772 walkStacklessTreeAgainstRay(nodeCallback, raySource, rayTarget, aabbMin, aabbMax, 0, m_curNodeIndex);
776 //recursive traversal
777 btVector3 qaabbMin = raySource;
778 btVector3 qaabbMax = raySource;
779 qaabbMin.setMin(rayTarget);
780 qaabbMax.setMax(rayTarget);
783 reportAabbOverlappingNodex(nodeCallback,qaabbMin,qaabbMax);
790 void btQuantizedBvh::swapLeafNodes(int i,int splitIndex)
792 if (m_useQuantization)
794 btQuantizedBvhNode tmp = m_quantizedLeafNodes[i];
795 m_quantizedLeafNodes[i] = m_quantizedLeafNodes[splitIndex];
796 m_quantizedLeafNodes[splitIndex] = tmp;
799 btOptimizedBvhNode tmp = m_leafNodes[i];
800 m_leafNodes[i] = m_leafNodes[splitIndex];
801 m_leafNodes[splitIndex] = tmp;
805 void btQuantizedBvh::assignInternalNodeFromLeafNode(int internalNode,int leafNodeIndex)
807 if (m_useQuantization)
809 m_quantizedContiguousNodes[internalNode] = m_quantizedLeafNodes[leafNodeIndex];
812 m_contiguousNodes[internalNode] = m_leafNodes[leafNodeIndex];
821 static const unsigned BVH_ALIGNMENT = 16;
822 static const unsigned BVH_ALIGNMENT_MASK = BVH_ALIGNMENT-1;
824 static const unsigned BVH_ALIGNMENT_BLOCKS = 2;
828 unsigned int btQuantizedBvh::getAlignmentSerializationPadding()
830 // I changed this to 0 since the extra padding is not needed or used.
831 return 0;//BVH_ALIGNMENT_BLOCKS * BVH_ALIGNMENT;
834 unsigned btQuantizedBvh::calculateSerializeBufferSize() const
836 unsigned baseSize = sizeof(btQuantizedBvh) + getAlignmentSerializationPadding();
837 baseSize += sizeof(btBvhSubtreeInfo) * m_subtreeHeaderCount;
838 if (m_useQuantization)
840 return baseSize + m_curNodeIndex * sizeof(btQuantizedBvhNode);
842 return baseSize + m_curNodeIndex * sizeof(btOptimizedBvhNode);
845 bool btQuantizedBvh::serialize(void *o_alignedDataBuffer, unsigned /*i_dataBufferSize */, bool i_swapEndian) const
847 btAssert(m_subtreeHeaderCount == m_SubtreeHeaders.size());
848 m_subtreeHeaderCount = m_SubtreeHeaders.size();
850 /* if (i_dataBufferSize < calculateSerializeBufferSize() || o_alignedDataBuffer == NULL || (((unsigned)o_alignedDataBuffer & BVH_ALIGNMENT_MASK) != 0))
852 ///check alignedment for buffer?
858 btQuantizedBvh *targetBvh = (btQuantizedBvh *)o_alignedDataBuffer;
860 // construct the class so the virtual function table, etc will be set up
861 // Also, m_leafNodes and m_quantizedLeafNodes will be initialized to default values by the constructor
862 new (targetBvh) btQuantizedBvh;
866 targetBvh->m_curNodeIndex = static_cast<int>(btSwapEndian(m_curNodeIndex));
869 btSwapVector3Endian(m_bvhAabbMin,targetBvh->m_bvhAabbMin);
870 btSwapVector3Endian(m_bvhAabbMax,targetBvh->m_bvhAabbMax);
871 btSwapVector3Endian(m_bvhQuantization,targetBvh->m_bvhQuantization);
873 targetBvh->m_traversalMode = (btTraversalMode)btSwapEndian(m_traversalMode);
874 targetBvh->m_subtreeHeaderCount = static_cast<int>(btSwapEndian(m_subtreeHeaderCount));
878 targetBvh->m_curNodeIndex = m_curNodeIndex;
879 targetBvh->m_bvhAabbMin = m_bvhAabbMin;
880 targetBvh->m_bvhAabbMax = m_bvhAabbMax;
881 targetBvh->m_bvhQuantization = m_bvhQuantization;
882 targetBvh->m_traversalMode = m_traversalMode;
883 targetBvh->m_subtreeHeaderCount = m_subtreeHeaderCount;
886 targetBvh->m_useQuantization = m_useQuantization;
888 unsigned char *nodeData = (unsigned char *)targetBvh;
889 nodeData += sizeof(btQuantizedBvh);
891 unsigned sizeToAdd = 0;//(BVH_ALIGNMENT-((unsigned)nodeData & BVH_ALIGNMENT_MASK))&BVH_ALIGNMENT_MASK;
892 nodeData += sizeToAdd;
894 int nodeCount = m_curNodeIndex;
896 if (m_useQuantization)
898 targetBvh->m_quantizedContiguousNodes.initializeFromBuffer(nodeData, nodeCount, nodeCount);
902 for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++)
904 targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0] = btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0]);
905 targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[1] = btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[1]);
906 targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[2] = btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[2]);
908 targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0] = btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0]);
909 targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[1] = btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[1]);
910 targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[2] = btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[2]);
912 targetBvh->m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex = static_cast<int>(btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex));
917 for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++)
920 targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0];
921 targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[1] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[1];
922 targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[2] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[2];
924 targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0];
925 targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[1] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[1];
926 targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[2] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[2];
928 targetBvh->m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex = m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex;
933 nodeData += sizeof(btQuantizedBvhNode) * nodeCount;
935 // this clears the pointer in the member variable it doesn't really do anything to the data
936 // it does call the destructor on the contained objects, but they are all classes with no destructor defined
937 // so the memory (which is not freed) is left alone
938 targetBvh->m_quantizedContiguousNodes.initializeFromBuffer(NULL, 0, 0);
942 targetBvh->m_contiguousNodes.initializeFromBuffer(nodeData, nodeCount, nodeCount);
946 for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++)
948 btSwapVector3Endian(m_contiguousNodes[nodeIndex].m_aabbMinOrg, targetBvh->m_contiguousNodes[nodeIndex].m_aabbMinOrg);
949 btSwapVector3Endian(m_contiguousNodes[nodeIndex].m_aabbMaxOrg, targetBvh->m_contiguousNodes[nodeIndex].m_aabbMaxOrg);
951 targetBvh->m_contiguousNodes[nodeIndex].m_escapeIndex = static_cast<int>(btSwapEndian(m_contiguousNodes[nodeIndex].m_escapeIndex));
952 targetBvh->m_contiguousNodes[nodeIndex].m_subPart = static_cast<int>(btSwapEndian(m_contiguousNodes[nodeIndex].m_subPart));
953 targetBvh->m_contiguousNodes[nodeIndex].m_triangleIndex = static_cast<int>(btSwapEndian(m_contiguousNodes[nodeIndex].m_triangleIndex));
958 for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++)
960 targetBvh->m_contiguousNodes[nodeIndex].m_aabbMinOrg = m_contiguousNodes[nodeIndex].m_aabbMinOrg;
961 targetBvh->m_contiguousNodes[nodeIndex].m_aabbMaxOrg = m_contiguousNodes[nodeIndex].m_aabbMaxOrg;
963 targetBvh->m_contiguousNodes[nodeIndex].m_escapeIndex = m_contiguousNodes[nodeIndex].m_escapeIndex;
964 targetBvh->m_contiguousNodes[nodeIndex].m_subPart = m_contiguousNodes[nodeIndex].m_subPart;
965 targetBvh->m_contiguousNodes[nodeIndex].m_triangleIndex = m_contiguousNodes[nodeIndex].m_triangleIndex;
968 nodeData += sizeof(btOptimizedBvhNode) * nodeCount;
970 // this clears the pointer in the member variable it doesn't really do anything to the data
971 // it does call the destructor on the contained objects, but they are all classes with no destructor defined
972 // so the memory (which is not freed) is left alone
973 targetBvh->m_contiguousNodes.initializeFromBuffer(NULL, 0, 0);
976 sizeToAdd = 0;//(BVH_ALIGNMENT-((unsigned)nodeData & BVH_ALIGNMENT_MASK))&BVH_ALIGNMENT_MASK;
977 nodeData += sizeToAdd;
979 // Now serialize the subtree headers
980 targetBvh->m_SubtreeHeaders.initializeFromBuffer(nodeData, m_subtreeHeaderCount, m_subtreeHeaderCount);
983 for (int i = 0; i < m_subtreeHeaderCount; i++)
985 targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMin[0] = btSwapEndian(m_SubtreeHeaders[i].m_quantizedAabbMin[0]);
986 targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMin[1] = btSwapEndian(m_SubtreeHeaders[i].m_quantizedAabbMin[1]);
987 targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMin[2] = btSwapEndian(m_SubtreeHeaders[i].m_quantizedAabbMin[2]);
989 targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMax[0] = btSwapEndian(m_SubtreeHeaders[i].m_quantizedAabbMax[0]);
990 targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMax[1] = btSwapEndian(m_SubtreeHeaders[i].m_quantizedAabbMax[1]);
991 targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMax[2] = btSwapEndian(m_SubtreeHeaders[i].m_quantizedAabbMax[2]);
993 targetBvh->m_SubtreeHeaders[i].m_rootNodeIndex = static_cast<int>(btSwapEndian(m_SubtreeHeaders[i].m_rootNodeIndex));
994 targetBvh->m_SubtreeHeaders[i].m_subtreeSize = static_cast<int>(btSwapEndian(m_SubtreeHeaders[i].m_subtreeSize));
999 for (int i = 0; i < m_subtreeHeaderCount; i++)
1001 targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMin[0] = (m_SubtreeHeaders[i].m_quantizedAabbMin[0]);
1002 targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMin[1] = (m_SubtreeHeaders[i].m_quantizedAabbMin[1]);
1003 targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMin[2] = (m_SubtreeHeaders[i].m_quantizedAabbMin[2]);
1005 targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMax[0] = (m_SubtreeHeaders[i].m_quantizedAabbMax[0]);
1006 targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMax[1] = (m_SubtreeHeaders[i].m_quantizedAabbMax[1]);
1007 targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMax[2] = (m_SubtreeHeaders[i].m_quantizedAabbMax[2]);
1009 targetBvh->m_SubtreeHeaders[i].m_rootNodeIndex = (m_SubtreeHeaders[i].m_rootNodeIndex);
1010 targetBvh->m_SubtreeHeaders[i].m_subtreeSize = (m_SubtreeHeaders[i].m_subtreeSize);
1012 // need to clear padding in destination buffer
1013 targetBvh->m_SubtreeHeaders[i].m_padding[0] = 0;
1014 targetBvh->m_SubtreeHeaders[i].m_padding[1] = 0;
1015 targetBvh->m_SubtreeHeaders[i].m_padding[2] = 0;
1018 nodeData += sizeof(btBvhSubtreeInfo) * m_subtreeHeaderCount;
1020 // this clears the pointer in the member variable it doesn't really do anything to the data
1021 // it does call the destructor on the contained objects, but they are all classes with no destructor defined
1022 // so the memory (which is not freed) is left alone
1023 targetBvh->m_SubtreeHeaders.initializeFromBuffer(NULL, 0, 0);
1025 // this wipes the virtual function table pointer at the start of the buffer for the class
1026 *((void**)o_alignedDataBuffer) = NULL;
1031 btQuantizedBvh *btQuantizedBvh::deSerializeInPlace(void *i_alignedDataBuffer, unsigned int i_dataBufferSize, bool i_swapEndian)
1034 if (i_alignedDataBuffer == NULL)// || (((unsigned)i_alignedDataBuffer & BVH_ALIGNMENT_MASK) != 0))
1038 btQuantizedBvh *bvh = (btQuantizedBvh *)i_alignedDataBuffer;
1042 bvh->m_curNodeIndex = static_cast<int>(btSwapEndian(bvh->m_curNodeIndex));
1044 btUnSwapVector3Endian(bvh->m_bvhAabbMin);
1045 btUnSwapVector3Endian(bvh->m_bvhAabbMax);
1046 btUnSwapVector3Endian(bvh->m_bvhQuantization);
1048 bvh->m_traversalMode = (btTraversalMode)btSwapEndian(bvh->m_traversalMode);
1049 bvh->m_subtreeHeaderCount = static_cast<int>(btSwapEndian(bvh->m_subtreeHeaderCount));
1052 unsigned int calculatedBufSize = bvh->calculateSerializeBufferSize();
1053 btAssert(calculatedBufSize <= i_dataBufferSize);
1055 if (calculatedBufSize > i_dataBufferSize)
1060 unsigned char *nodeData = (unsigned char *)bvh;
1061 nodeData += sizeof(btQuantizedBvh);
1063 unsigned sizeToAdd = 0;//(BVH_ALIGNMENT-((unsigned)nodeData & BVH_ALIGNMENT_MASK))&BVH_ALIGNMENT_MASK;
1064 nodeData += sizeToAdd;
1066 int nodeCount = bvh->m_curNodeIndex;
1068 // Must call placement new to fill in virtual function table, etc, but we don't want to overwrite most data, so call a special version of the constructor
1069 // Also, m_leafNodes and m_quantizedLeafNodes will be initialized to default values by the constructor
1070 new (bvh) btQuantizedBvh(*bvh, false);
1072 if (bvh->m_useQuantization)
1074 bvh->m_quantizedContiguousNodes.initializeFromBuffer(nodeData, nodeCount, nodeCount);
1078 for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++)
1080 bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0] = btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0]);
1081 bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[1] = btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[1]);
1082 bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[2] = btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[2]);
1084 bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0] = btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0]);
1085 bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[1] = btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[1]);
1086 bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[2] = btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[2]);
1088 bvh->m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex = static_cast<int>(btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex));
1091 nodeData += sizeof(btQuantizedBvhNode) * nodeCount;
1095 bvh->m_contiguousNodes.initializeFromBuffer(nodeData, nodeCount, nodeCount);
1099 for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++)
1101 btUnSwapVector3Endian(bvh->m_contiguousNodes[nodeIndex].m_aabbMinOrg);
1102 btUnSwapVector3Endian(bvh->m_contiguousNodes[nodeIndex].m_aabbMaxOrg);
1104 bvh->m_contiguousNodes[nodeIndex].m_escapeIndex = static_cast<int>(btSwapEndian(bvh->m_contiguousNodes[nodeIndex].m_escapeIndex));
1105 bvh->m_contiguousNodes[nodeIndex].m_subPart = static_cast<int>(btSwapEndian(bvh->m_contiguousNodes[nodeIndex].m_subPart));
1106 bvh->m_contiguousNodes[nodeIndex].m_triangleIndex = static_cast<int>(btSwapEndian(bvh->m_contiguousNodes[nodeIndex].m_triangleIndex));
1109 nodeData += sizeof(btOptimizedBvhNode) * nodeCount;
1112 sizeToAdd = 0;//(BVH_ALIGNMENT-((unsigned)nodeData & BVH_ALIGNMENT_MASK))&BVH_ALIGNMENT_MASK;
1113 nodeData += sizeToAdd;
1115 // Now serialize the subtree headers
1116 bvh->m_SubtreeHeaders.initializeFromBuffer(nodeData, bvh->m_subtreeHeaderCount, bvh->m_subtreeHeaderCount);
1119 for (int i = 0; i < bvh->m_subtreeHeaderCount; i++)
1121 bvh->m_SubtreeHeaders[i].m_quantizedAabbMin[0] = btSwapEndian(bvh->m_SubtreeHeaders[i].m_quantizedAabbMin[0]);
1122 bvh->m_SubtreeHeaders[i].m_quantizedAabbMin[1] = btSwapEndian(bvh->m_SubtreeHeaders[i].m_quantizedAabbMin[1]);
1123 bvh->m_SubtreeHeaders[i].m_quantizedAabbMin[2] = btSwapEndian(bvh->m_SubtreeHeaders[i].m_quantizedAabbMin[2]);
1125 bvh->m_SubtreeHeaders[i].m_quantizedAabbMax[0] = btSwapEndian(bvh->m_SubtreeHeaders[i].m_quantizedAabbMax[0]);
1126 bvh->m_SubtreeHeaders[i].m_quantizedAabbMax[1] = btSwapEndian(bvh->m_SubtreeHeaders[i].m_quantizedAabbMax[1]);
1127 bvh->m_SubtreeHeaders[i].m_quantizedAabbMax[2] = btSwapEndian(bvh->m_SubtreeHeaders[i].m_quantizedAabbMax[2]);
1129 bvh->m_SubtreeHeaders[i].m_rootNodeIndex = static_cast<int>(btSwapEndian(bvh->m_SubtreeHeaders[i].m_rootNodeIndex));
1130 bvh->m_SubtreeHeaders[i].m_subtreeSize = static_cast<int>(btSwapEndian(bvh->m_SubtreeHeaders[i].m_subtreeSize));
1137 // Constructor that prevents btVector3's default constructor from being called
1138 btQuantizedBvh::btQuantizedBvh(btQuantizedBvh &self, bool /* ownsMemory */) :
1139 m_bvhAabbMin(self.m_bvhAabbMin),
1140 m_bvhAabbMax(self.m_bvhAabbMax),
1141 m_bvhQuantization(self.m_bvhQuantization),
1142 m_bulletVersion(BT_BULLET_VERSION)
1147 void btQuantizedBvh::deSerializeFloat(struct btQuantizedBvhFloatData& quantizedBvhFloatData)
1149 m_bvhAabbMax.deSerializeFloat(quantizedBvhFloatData.m_bvhAabbMax);
1150 m_bvhAabbMin.deSerializeFloat(quantizedBvhFloatData.m_bvhAabbMin);
1151 m_bvhQuantization.deSerializeFloat(quantizedBvhFloatData.m_bvhQuantization);
1153 m_curNodeIndex = quantizedBvhFloatData.m_curNodeIndex;
1154 m_useQuantization = quantizedBvhFloatData.m_useQuantization!=0;
1157 int numElem = quantizedBvhFloatData.m_numContiguousLeafNodes;
1158 m_contiguousNodes.resize(numElem);
1162 btOptimizedBvhNodeFloatData* memPtr = quantizedBvhFloatData.m_contiguousNodesPtr;
1164 for (int i=0;i<numElem;i++,memPtr++)
1166 m_contiguousNodes[i].m_aabbMaxOrg.deSerializeFloat(memPtr->m_aabbMaxOrg);
1167 m_contiguousNodes[i].m_aabbMinOrg.deSerializeFloat(memPtr->m_aabbMinOrg);
1168 m_contiguousNodes[i].m_escapeIndex = memPtr->m_escapeIndex;
1169 m_contiguousNodes[i].m_subPart = memPtr->m_subPart;
1170 m_contiguousNodes[i].m_triangleIndex = memPtr->m_triangleIndex;
1176 int numElem = quantizedBvhFloatData.m_numQuantizedContiguousNodes;
1177 m_quantizedContiguousNodes.resize(numElem);
1181 btQuantizedBvhNodeData* memPtr = quantizedBvhFloatData.m_quantizedContiguousNodesPtr;
1182 for (int i=0;i<numElem;i++,memPtr++)
1184 m_quantizedContiguousNodes[i].m_escapeIndexOrTriangleIndex = memPtr->m_escapeIndexOrTriangleIndex;
1185 m_quantizedContiguousNodes[i].m_quantizedAabbMax[0] = memPtr->m_quantizedAabbMax[0];
1186 m_quantizedContiguousNodes[i].m_quantizedAabbMax[1] = memPtr->m_quantizedAabbMax[1];
1187 m_quantizedContiguousNodes[i].m_quantizedAabbMax[2] = memPtr->m_quantizedAabbMax[2];
1188 m_quantizedContiguousNodes[i].m_quantizedAabbMin[0] = memPtr->m_quantizedAabbMin[0];
1189 m_quantizedContiguousNodes[i].m_quantizedAabbMin[1] = memPtr->m_quantizedAabbMin[1];
1190 m_quantizedContiguousNodes[i].m_quantizedAabbMin[2] = memPtr->m_quantizedAabbMin[2];
1195 m_traversalMode = btTraversalMode(quantizedBvhFloatData.m_traversalMode);
1198 int numElem = quantizedBvhFloatData.m_numSubtreeHeaders;
1199 m_SubtreeHeaders.resize(numElem);
1202 btBvhSubtreeInfoData* memPtr = quantizedBvhFloatData.m_subTreeInfoPtr;
1203 for (int i=0;i<numElem;i++,memPtr++)
1205 m_SubtreeHeaders[i].m_quantizedAabbMax[0] = memPtr->m_quantizedAabbMax[0] ;
1206 m_SubtreeHeaders[i].m_quantizedAabbMax[1] = memPtr->m_quantizedAabbMax[1];
1207 m_SubtreeHeaders[i].m_quantizedAabbMax[2] = memPtr->m_quantizedAabbMax[2];
1208 m_SubtreeHeaders[i].m_quantizedAabbMin[0] = memPtr->m_quantizedAabbMin[0];
1209 m_SubtreeHeaders[i].m_quantizedAabbMin[1] = memPtr->m_quantizedAabbMin[1];
1210 m_SubtreeHeaders[i].m_quantizedAabbMin[2] = memPtr->m_quantizedAabbMin[2];
1211 m_SubtreeHeaders[i].m_rootNodeIndex = memPtr->m_rootNodeIndex;
1212 m_SubtreeHeaders[i].m_subtreeSize = memPtr->m_subtreeSize;
1218 void btQuantizedBvh::deSerializeDouble(struct btQuantizedBvhDoubleData& quantizedBvhDoubleData)
1220 m_bvhAabbMax.deSerializeDouble(quantizedBvhDoubleData.m_bvhAabbMax);
1221 m_bvhAabbMin.deSerializeDouble(quantizedBvhDoubleData.m_bvhAabbMin);
1222 m_bvhQuantization.deSerializeDouble(quantizedBvhDoubleData.m_bvhQuantization);
1224 m_curNodeIndex = quantizedBvhDoubleData.m_curNodeIndex;
1225 m_useQuantization = quantizedBvhDoubleData.m_useQuantization!=0;
1228 int numElem = quantizedBvhDoubleData.m_numContiguousLeafNodes;
1229 m_contiguousNodes.resize(numElem);
1233 btOptimizedBvhNodeDoubleData* memPtr = quantizedBvhDoubleData.m_contiguousNodesPtr;
1235 for (int i=0;i<numElem;i++,memPtr++)
1237 m_contiguousNodes[i].m_aabbMaxOrg.deSerializeDouble(memPtr->m_aabbMaxOrg);
1238 m_contiguousNodes[i].m_aabbMinOrg.deSerializeDouble(memPtr->m_aabbMinOrg);
1239 m_contiguousNodes[i].m_escapeIndex = memPtr->m_escapeIndex;
1240 m_contiguousNodes[i].m_subPart = memPtr->m_subPart;
1241 m_contiguousNodes[i].m_triangleIndex = memPtr->m_triangleIndex;
1247 int numElem = quantizedBvhDoubleData.m_numQuantizedContiguousNodes;
1248 m_quantizedContiguousNodes.resize(numElem);
1252 btQuantizedBvhNodeData* memPtr = quantizedBvhDoubleData.m_quantizedContiguousNodesPtr;
1253 for (int i=0;i<numElem;i++,memPtr++)
1255 m_quantizedContiguousNodes[i].m_escapeIndexOrTriangleIndex = memPtr->m_escapeIndexOrTriangleIndex;
1256 m_quantizedContiguousNodes[i].m_quantizedAabbMax[0] = memPtr->m_quantizedAabbMax[0];
1257 m_quantizedContiguousNodes[i].m_quantizedAabbMax[1] = memPtr->m_quantizedAabbMax[1];
1258 m_quantizedContiguousNodes[i].m_quantizedAabbMax[2] = memPtr->m_quantizedAabbMax[2];
1259 m_quantizedContiguousNodes[i].m_quantizedAabbMin[0] = memPtr->m_quantizedAabbMin[0];
1260 m_quantizedContiguousNodes[i].m_quantizedAabbMin[1] = memPtr->m_quantizedAabbMin[1];
1261 m_quantizedContiguousNodes[i].m_quantizedAabbMin[2] = memPtr->m_quantizedAabbMin[2];
1266 m_traversalMode = btTraversalMode(quantizedBvhDoubleData.m_traversalMode);
1269 int numElem = quantizedBvhDoubleData.m_numSubtreeHeaders;
1270 m_SubtreeHeaders.resize(numElem);
1273 btBvhSubtreeInfoData* memPtr = quantizedBvhDoubleData.m_subTreeInfoPtr;
1274 for (int i=0;i<numElem;i++,memPtr++)
1276 m_SubtreeHeaders[i].m_quantizedAabbMax[0] = memPtr->m_quantizedAabbMax[0] ;
1277 m_SubtreeHeaders[i].m_quantizedAabbMax[1] = memPtr->m_quantizedAabbMax[1];
1278 m_SubtreeHeaders[i].m_quantizedAabbMax[2] = memPtr->m_quantizedAabbMax[2];
1279 m_SubtreeHeaders[i].m_quantizedAabbMin[0] = memPtr->m_quantizedAabbMin[0];
1280 m_SubtreeHeaders[i].m_quantizedAabbMin[1] = memPtr->m_quantizedAabbMin[1];
1281 m_SubtreeHeaders[i].m_quantizedAabbMin[2] = memPtr->m_quantizedAabbMin[2];
1282 m_SubtreeHeaders[i].m_rootNodeIndex = memPtr->m_rootNodeIndex;
1283 m_SubtreeHeaders[i].m_subtreeSize = memPtr->m_subtreeSize;
1292 ///fills the dataBuffer and returns the struct name (and 0 on failure)
1293 const char* btQuantizedBvh::serialize(void* dataBuffer, btSerializer* serializer) const
1295 btQuantizedBvhData* quantizedData = (btQuantizedBvhData*)dataBuffer;
1297 m_bvhAabbMax.serialize(quantizedData->m_bvhAabbMax);
1298 m_bvhAabbMin.serialize(quantizedData->m_bvhAabbMin);
1299 m_bvhQuantization.serialize(quantizedData->m_bvhQuantization);
1301 quantizedData->m_curNodeIndex = m_curNodeIndex;
1302 quantizedData->m_useQuantization = m_useQuantization;
1304 quantizedData->m_numContiguousLeafNodes = m_contiguousNodes.size();
1305 quantizedData->m_contiguousNodesPtr = (btOptimizedBvhNodeData*) (m_contiguousNodes.size() ? serializer->getUniquePointer((void*)&m_contiguousNodes[0]) : 0);
1306 if (quantizedData->m_contiguousNodesPtr)
1308 int sz = sizeof(btOptimizedBvhNodeData);
1309 int numElem = m_contiguousNodes.size();
1310 btChunk* chunk = serializer->allocate(sz,numElem);
1311 btOptimizedBvhNodeData* memPtr = (btOptimizedBvhNodeData*)chunk->m_oldPtr;
1312 for (int i=0;i<numElem;i++,memPtr++)
1314 m_contiguousNodes[i].m_aabbMaxOrg.serialize(memPtr->m_aabbMaxOrg);
1315 m_contiguousNodes[i].m_aabbMinOrg.serialize(memPtr->m_aabbMinOrg);
1316 memPtr->m_escapeIndex = m_contiguousNodes[i].m_escapeIndex;
1317 memPtr->m_subPart = m_contiguousNodes[i].m_subPart;
1318 memPtr->m_triangleIndex = m_contiguousNodes[i].m_triangleIndex;
1320 serializer->finalizeChunk(chunk,"btOptimizedBvhNodeData",BT_ARRAY_CODE,(void*)&m_contiguousNodes[0]);
1323 quantizedData->m_numQuantizedContiguousNodes = m_quantizedContiguousNodes.size();
1324 // printf("quantizedData->m_numQuantizedContiguousNodes=%d\n",quantizedData->m_numQuantizedContiguousNodes);
1325 quantizedData->m_quantizedContiguousNodesPtr =(btQuantizedBvhNodeData*) (m_quantizedContiguousNodes.size() ? serializer->getUniquePointer((void*)&m_quantizedContiguousNodes[0]) : 0);
1326 if (quantizedData->m_quantizedContiguousNodesPtr)
1328 int sz = sizeof(btQuantizedBvhNodeData);
1329 int numElem = m_quantizedContiguousNodes.size();
1330 btChunk* chunk = serializer->allocate(sz,numElem);
1331 btQuantizedBvhNodeData* memPtr = (btQuantizedBvhNodeData*)chunk->m_oldPtr;
1332 for (int i=0;i<numElem;i++,memPtr++)
1334 memPtr->m_escapeIndexOrTriangleIndex = m_quantizedContiguousNodes[i].m_escapeIndexOrTriangleIndex;
1335 memPtr->m_quantizedAabbMax[0] = m_quantizedContiguousNodes[i].m_quantizedAabbMax[0];
1336 memPtr->m_quantizedAabbMax[1] = m_quantizedContiguousNodes[i].m_quantizedAabbMax[1];
1337 memPtr->m_quantizedAabbMax[2] = m_quantizedContiguousNodes[i].m_quantizedAabbMax[2];
1338 memPtr->m_quantizedAabbMin[0] = m_quantizedContiguousNodes[i].m_quantizedAabbMin[0];
1339 memPtr->m_quantizedAabbMin[1] = m_quantizedContiguousNodes[i].m_quantizedAabbMin[1];
1340 memPtr->m_quantizedAabbMin[2] = m_quantizedContiguousNodes[i].m_quantizedAabbMin[2];
1342 serializer->finalizeChunk(chunk,"btQuantizedBvhNodeData",BT_ARRAY_CODE,(void*)&m_quantizedContiguousNodes[0]);
1345 quantizedData->m_traversalMode = int(m_traversalMode);
1346 quantizedData->m_numSubtreeHeaders = m_SubtreeHeaders.size();
1348 quantizedData->m_subTreeInfoPtr = (btBvhSubtreeInfoData*) (m_SubtreeHeaders.size() ? serializer->getUniquePointer((void*)&m_SubtreeHeaders[0]) : 0);
1349 if (quantizedData->m_subTreeInfoPtr)
1351 int sz = sizeof(btBvhSubtreeInfoData);
1352 int numElem = m_SubtreeHeaders.size();
1353 btChunk* chunk = serializer->allocate(sz,numElem);
1354 btBvhSubtreeInfoData* memPtr = (btBvhSubtreeInfoData*)chunk->m_oldPtr;
1355 for (int i=0;i<numElem;i++,memPtr++)
1357 memPtr->m_quantizedAabbMax[0] = m_SubtreeHeaders[i].m_quantizedAabbMax[0];
1358 memPtr->m_quantizedAabbMax[1] = m_SubtreeHeaders[i].m_quantizedAabbMax[1];
1359 memPtr->m_quantizedAabbMax[2] = m_SubtreeHeaders[i].m_quantizedAabbMax[2];
1360 memPtr->m_quantizedAabbMin[0] = m_SubtreeHeaders[i].m_quantizedAabbMin[0];
1361 memPtr->m_quantizedAabbMin[1] = m_SubtreeHeaders[i].m_quantizedAabbMin[1];
1362 memPtr->m_quantizedAabbMin[2] = m_SubtreeHeaders[i].m_quantizedAabbMin[2];
1364 memPtr->m_rootNodeIndex = m_SubtreeHeaders[i].m_rootNodeIndex;
1365 memPtr->m_subtreeSize = m_SubtreeHeaders[i].m_subtreeSize;
1367 serializer->finalizeChunk(chunk,"btBvhSubtreeInfoData",BT_ARRAY_CODE,(void*)&m_SubtreeHeaders[0]);
1369 return btQuantizedBvhDataName;