00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "btQuantizedBvh.h"
00017
00018 #include "LinearMath/btAabbUtil2.h"
00019 #include "LinearMath/btIDebugDraw.h"
00020 #include "LinearMath/btSerializer.h"
00021
00022 #define RAYAABB2
00023
00024 btQuantizedBvh::btQuantizedBvh() :
00025 m_bulletVersion(BT_BULLET_VERSION),
00026 m_useQuantization(false),
00027
00028 m_traversalMode(TRAVERSAL_STACKLESS)
00029
00030 ,m_subtreeHeaderCount(0)
00031 {
00032 m_bvhAabbMin.setValue(-SIMD_INFINITY,-SIMD_INFINITY,-SIMD_INFINITY);
00033 m_bvhAabbMax.setValue(SIMD_INFINITY,SIMD_INFINITY,SIMD_INFINITY);
00034 }
00035
00036
00037
00038
00039
00040 void btQuantizedBvh::buildInternal()
00041 {
00043 m_useQuantization = true;
00044 int numLeafNodes = 0;
00045
00046 if (m_useQuantization)
00047 {
00048
00049 numLeafNodes = m_quantizedLeafNodes.size();
00050
00051 m_quantizedContiguousNodes.resize(2*numLeafNodes);
00052
00053 }
00054
00055 m_curNodeIndex = 0;
00056
00057 buildTree(0,numLeafNodes);
00058
00060 if(m_useQuantization && !m_SubtreeHeaders.size())
00061 {
00062 btBvhSubtreeInfo& subtree = m_SubtreeHeaders.expand();
00063 subtree.setAabbFromQuantizeNode(m_quantizedContiguousNodes[0]);
00064 subtree.m_rootNodeIndex = 0;
00065 subtree.m_subtreeSize = m_quantizedContiguousNodes[0].isLeafNode() ? 1 : m_quantizedContiguousNodes[0].getEscapeIndex();
00066 }
00067
00068
00069 m_subtreeHeaderCount = m_SubtreeHeaders.size();
00070
00071
00072 m_quantizedLeafNodes.clear();
00073 m_leafNodes.clear();
00074 }
00075
00076
00077
00079 #ifdef DEBUG_PATCH_COLORS
00080 btVector3 color[4]=
00081 {
00082 btVector3(1,0,0),
00083 btVector3(0,1,0),
00084 btVector3(0,0,1),
00085 btVector3(0,1,1)
00086 };
00087 #endif //DEBUG_PATCH_COLORS
00088
00089
00090
00091 void btQuantizedBvh::setQuantizationValues(const btVector3& bvhAabbMin,const btVector3& bvhAabbMax,btScalar quantizationMargin)
00092 {
00093
00094 btVector3 clampValue(quantizationMargin,quantizationMargin,quantizationMargin);
00095 m_bvhAabbMin = bvhAabbMin - clampValue;
00096 m_bvhAabbMax = bvhAabbMax + clampValue;
00097 btVector3 aabbSize = m_bvhAabbMax - m_bvhAabbMin;
00098 m_bvhQuantization = btVector3(btScalar(65533.0),btScalar(65533.0),btScalar(65533.0)) / aabbSize;
00099
00100 m_useQuantization = true;
00101
00102 {
00103 unsigned short vecIn[3];
00104 btVector3 v;
00105 {
00106 quantize(vecIn,m_bvhAabbMin,false);
00107 v = unQuantize(vecIn);
00108 m_bvhAabbMin.setMin(v-clampValue);
00109 }
00110 {
00111 quantize(vecIn,m_bvhAabbMax,true);
00112 v = unQuantize(vecIn);
00113 m_bvhAabbMax.setMax(v+clampValue);
00114 }
00115 aabbSize = m_bvhAabbMax - m_bvhAabbMin;
00116 m_bvhQuantization = btVector3(btScalar(65533.0),btScalar(65533.0),btScalar(65533.0)) / aabbSize;
00117 }
00118 }
00119
00120
00121
00122
00123 btQuantizedBvh::~btQuantizedBvh()
00124 {
00125 }
00126
00127 #ifdef DEBUG_TREE_BUILDING
00128 int gStackDepth = 0;
00129 int gMaxStackDepth = 0;
00130 #endif //DEBUG_TREE_BUILDING
00131
00132 void btQuantizedBvh::buildTree (int startIndex,int endIndex)
00133 {
00134 #ifdef DEBUG_TREE_BUILDING
00135 gStackDepth++;
00136 if (gStackDepth > gMaxStackDepth)
00137 gMaxStackDepth = gStackDepth;
00138 #endif //DEBUG_TREE_BUILDING
00139
00140
00141 int splitAxis, splitIndex, i;
00142 int numIndices =endIndex-startIndex;
00143 int curIndex = m_curNodeIndex;
00144
00145 btAssert(numIndices>0);
00146
00147 if (numIndices==1)
00148 {
00149 #ifdef DEBUG_TREE_BUILDING
00150 gStackDepth--;
00151 #endif //DEBUG_TREE_BUILDING
00152
00153 assignInternalNodeFromLeafNode(m_curNodeIndex,startIndex);
00154
00155 m_curNodeIndex++;
00156 return;
00157 }
00158
00159
00160 splitAxis = calcSplittingAxis(startIndex,endIndex);
00161
00162 splitIndex = sortAndCalcSplittingIndex(startIndex,endIndex,splitAxis);
00163
00164 int internalNodeIndex = m_curNodeIndex;
00165
00166
00167
00168 setInternalNodeAabbMin(m_curNodeIndex,m_bvhAabbMax);
00169 setInternalNodeAabbMax(m_curNodeIndex,m_bvhAabbMin);
00170
00171
00172 for (i=startIndex;i<endIndex;i++)
00173 {
00174 mergeInternalNodeAabb(m_curNodeIndex,getAabbMin(i),getAabbMax(i));
00175 }
00176
00177 m_curNodeIndex++;
00178
00179
00180
00181
00182 int leftChildNodexIndex = m_curNodeIndex;
00183
00184
00185 buildTree(startIndex,splitIndex);
00186
00187 int rightChildNodexIndex = m_curNodeIndex;
00188
00189 buildTree(splitIndex,endIndex);
00190
00191 #ifdef DEBUG_TREE_BUILDING
00192 gStackDepth--;
00193 #endif //DEBUG_TREE_BUILDING
00194
00195 int escapeIndex = m_curNodeIndex - curIndex;
00196
00197 if (m_useQuantization)
00198 {
00199
00200 const int sizeQuantizedNode =sizeof(btQuantizedBvhNode);
00201 const int treeSizeInBytes = escapeIndex * sizeQuantizedNode;
00202 if (treeSizeInBytes > MAX_SUBTREE_SIZE_IN_BYTES)
00203 {
00204 updateSubtreeHeaders(leftChildNodexIndex,rightChildNodexIndex);
00205 }
00206 } else
00207 {
00208
00209 }
00210
00211 setInternalNodeEscapeIndex(internalNodeIndex,escapeIndex);
00212
00213 }
00214
00215 void btQuantizedBvh::updateSubtreeHeaders(int leftChildNodexIndex,int rightChildNodexIndex)
00216 {
00217 btAssert(m_useQuantization);
00218
00219 btQuantizedBvhNode& leftChildNode = m_quantizedContiguousNodes[leftChildNodexIndex];
00220 int leftSubTreeSize = leftChildNode.isLeafNode() ? 1 : leftChildNode.getEscapeIndex();
00221 int leftSubTreeSizeInBytes = leftSubTreeSize * static_cast<int>(sizeof(btQuantizedBvhNode));
00222
00223 btQuantizedBvhNode& rightChildNode = m_quantizedContiguousNodes[rightChildNodexIndex];
00224 int rightSubTreeSize = rightChildNode.isLeafNode() ? 1 : rightChildNode.getEscapeIndex();
00225 int rightSubTreeSizeInBytes = rightSubTreeSize * static_cast<int>(sizeof(btQuantizedBvhNode));
00226
00227 if(leftSubTreeSizeInBytes <= MAX_SUBTREE_SIZE_IN_BYTES)
00228 {
00229 btBvhSubtreeInfo& subtree = m_SubtreeHeaders.expand();
00230 subtree.setAabbFromQuantizeNode(leftChildNode);
00231 subtree.m_rootNodeIndex = leftChildNodexIndex;
00232 subtree.m_subtreeSize = leftSubTreeSize;
00233 }
00234
00235 if(rightSubTreeSizeInBytes <= MAX_SUBTREE_SIZE_IN_BYTES)
00236 {
00237 btBvhSubtreeInfo& subtree = m_SubtreeHeaders.expand();
00238 subtree.setAabbFromQuantizeNode(rightChildNode);
00239 subtree.m_rootNodeIndex = rightChildNodexIndex;
00240 subtree.m_subtreeSize = rightSubTreeSize;
00241 }
00242
00243
00244 m_subtreeHeaderCount = m_SubtreeHeaders.size();
00245 }
00246
00247
00248 int btQuantizedBvh::sortAndCalcSplittingIndex(int startIndex,int endIndex,int splitAxis)
00249 {
00250 int i;
00251 int splitIndex =startIndex;
00252 int numIndices = endIndex - startIndex;
00253 btScalar splitValue;
00254
00255 btVector3 means(btScalar(0.),btScalar(0.),btScalar(0.));
00256 for (i=startIndex;i<endIndex;i++)
00257 {
00258 btVector3 center = btScalar(0.5)*(getAabbMax(i)+getAabbMin(i));
00259 means+=center;
00260 }
00261 means *= (btScalar(1.)/(btScalar)numIndices);
00262
00263 splitValue = means[splitAxis];
00264
00265
00266 for (i=startIndex;i<endIndex;i++)
00267 {
00268 btVector3 center = btScalar(0.5)*(getAabbMax(i)+getAabbMin(i));
00269 if (center[splitAxis] > splitValue)
00270 {
00271
00272 swapLeafNodes(i,splitIndex);
00273 splitIndex++;
00274 }
00275 }
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286 int rangeBalancedIndices = numIndices/3;
00287 bool unbalanced = ((splitIndex<=(startIndex+rangeBalancedIndices)) || (splitIndex >=(endIndex-1-rangeBalancedIndices)));
00288
00289 if (unbalanced)
00290 {
00291 splitIndex = startIndex+ (numIndices>>1);
00292 }
00293
00294 bool unbal = (splitIndex==startIndex) || (splitIndex == (endIndex));
00295 (void)unbal;
00296 btAssert(!unbal);
00297
00298 return splitIndex;
00299 }
00300
00301
00302 int btQuantizedBvh::calcSplittingAxis(int startIndex,int endIndex)
00303 {
00304 int i;
00305
00306 btVector3 means(btScalar(0.),btScalar(0.),btScalar(0.));
00307 btVector3 variance(btScalar(0.),btScalar(0.),btScalar(0.));
00308 int numIndices = endIndex-startIndex;
00309
00310 for (i=startIndex;i<endIndex;i++)
00311 {
00312 btVector3 center = btScalar(0.5)*(getAabbMax(i)+getAabbMin(i));
00313 means+=center;
00314 }
00315 means *= (btScalar(1.)/(btScalar)numIndices);
00316
00317 for (i=startIndex;i<endIndex;i++)
00318 {
00319 btVector3 center = btScalar(0.5)*(getAabbMax(i)+getAabbMin(i));
00320 btVector3 diff2 = center-means;
00321 diff2 = diff2 * diff2;
00322 variance += diff2;
00323 }
00324 variance *= (btScalar(1.)/ ((btScalar)numIndices-1) );
00325
00326 return variance.maxAxis();
00327 }
00328
00329
00330
00331 void btQuantizedBvh::reportAabbOverlappingNodex(btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const
00332 {
00333
00334
00335 if (m_useQuantization)
00336 {
00338 unsigned short int quantizedQueryAabbMin[3];
00339 unsigned short int quantizedQueryAabbMax[3];
00340 quantizeWithClamp(quantizedQueryAabbMin,aabbMin,0);
00341 quantizeWithClamp(quantizedQueryAabbMax,aabbMax,1);
00342
00343 switch (m_traversalMode)
00344 {
00345 case TRAVERSAL_STACKLESS:
00346 walkStacklessQuantizedTree(nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax,0,m_curNodeIndex);
00347 break;
00348 case TRAVERSAL_STACKLESS_CACHE_FRIENDLY:
00349 walkStacklessQuantizedTreeCacheFriendly(nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax);
00350 break;
00351 case TRAVERSAL_RECURSIVE:
00352 {
00353 const btQuantizedBvhNode* rootNode = &m_quantizedContiguousNodes[0];
00354 walkRecursiveQuantizedTreeAgainstQueryAabb(rootNode,nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax);
00355 }
00356 break;
00357 default:
00358
00359 btAssert(0);
00360 }
00361 } else
00362 {
00363 walkStacklessTree(nodeCallback,aabbMin,aabbMax);
00364 }
00365 }
00366
00367
00368 int maxIterations = 0;
00369
00370
00371 void btQuantizedBvh::walkStacklessTree(btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const
00372 {
00373 btAssert(!m_useQuantization);
00374
00375 const btOptimizedBvhNode* rootNode = &m_contiguousNodes[0];
00376 int escapeIndex, curIndex = 0;
00377 int walkIterations = 0;
00378 bool isLeafNode;
00379
00380 unsigned aabbOverlap;
00381
00382 while (curIndex < m_curNodeIndex)
00383 {
00384
00385 btAssert (walkIterations < m_curNodeIndex);
00386
00387 walkIterations++;
00388 aabbOverlap = TestAabbAgainstAabb2(aabbMin,aabbMax,rootNode->m_aabbMinOrg,rootNode->m_aabbMaxOrg);
00389 isLeafNode = rootNode->m_escapeIndex == -1;
00390
00391
00392 if (isLeafNode && (aabbOverlap != 0))
00393 {
00394 nodeCallback->processNode(rootNode->m_subPart,rootNode->m_triangleIndex);
00395 }
00396
00397
00398 if ((aabbOverlap != 0) || isLeafNode)
00399 {
00400 rootNode++;
00401 curIndex++;
00402 } else
00403 {
00404 escapeIndex = rootNode->m_escapeIndex;
00405 rootNode += escapeIndex;
00406 curIndex += escapeIndex;
00407 }
00408 }
00409 if (maxIterations < walkIterations)
00410 maxIterations = walkIterations;
00411
00412 }
00413
00414
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435 void btQuantizedBvh::walkRecursiveQuantizedTreeAgainstQueryAabb(const btQuantizedBvhNode* currentNode,btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax) const
00436 {
00437 btAssert(m_useQuantization);
00438
00439 bool isLeafNode;
00440
00441 unsigned aabbOverlap;
00442
00443
00444 aabbOverlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,currentNode->m_quantizedAabbMin,currentNode->m_quantizedAabbMax);
00445 isLeafNode = currentNode->isLeafNode();
00446
00447
00448 if (aabbOverlap != 0)
00449 {
00450 if (isLeafNode)
00451 {
00452 nodeCallback->processNode(currentNode->getPartId(),currentNode->getTriangleIndex());
00453 } else
00454 {
00455
00456 const btQuantizedBvhNode* leftChildNode = currentNode+1;
00457 walkRecursiveQuantizedTreeAgainstQueryAabb(leftChildNode,nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax);
00458
00459 const btQuantizedBvhNode* rightChildNode = leftChildNode->isLeafNode() ? leftChildNode+1:leftChildNode+leftChildNode->getEscapeIndex();
00460 walkRecursiveQuantizedTreeAgainstQueryAabb(rightChildNode,nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax);
00461 }
00462 }
00463 }
00464
00465
00466
00467 void btQuantizedBvh::walkStacklessTreeAgainstRay(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax, int startNodeIndex,int endNodeIndex) const
00468 {
00469 btAssert(!m_useQuantization);
00470
00471 const btOptimizedBvhNode* rootNode = &m_contiguousNodes[0];
00472 int escapeIndex, curIndex = 0;
00473 int walkIterations = 0;
00474 bool isLeafNode;
00475
00476 unsigned aabbOverlap=0;
00477 unsigned rayBoxOverlap=0;
00478 btScalar lambda_max = 1.0;
00479
00480
00481 btVector3 rayAabbMin = raySource;
00482 btVector3 rayAabbMax = raySource;
00483 rayAabbMin.setMin(rayTarget);
00484 rayAabbMax.setMax(rayTarget);
00485
00486
00487 rayAabbMin += aabbMin;
00488 rayAabbMax += aabbMax;
00489
00490 #ifdef RAYAABB2
00491 btVector3 rayDir = (rayTarget-raySource);
00492 rayDir.normalize ();
00493 lambda_max = rayDir.dot(rayTarget-raySource);
00495 btVector3 rayDirectionInverse;
00496 rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[0];
00497 rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[1];
00498 rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[2];
00499 unsigned int sign[3] = { rayDirectionInverse[0] < 0.0, rayDirectionInverse[1] < 0.0, rayDirectionInverse[2] < 0.0};
00500 #endif
00501
00502 btVector3 bounds[2];
00503
00504 while (curIndex < m_curNodeIndex)
00505 {
00506 btScalar param = 1.0;
00507
00508 btAssert (walkIterations < m_curNodeIndex);
00509
00510 walkIterations++;
00511
00512 bounds[0] = rootNode->m_aabbMinOrg;
00513 bounds[1] = rootNode->m_aabbMaxOrg;
00514
00515 bounds[0] -= aabbMax;
00516 bounds[1] -= aabbMin;
00517
00518 aabbOverlap = TestAabbAgainstAabb2(rayAabbMin,rayAabbMax,rootNode->m_aabbMinOrg,rootNode->m_aabbMaxOrg);
00519
00520
00521 #ifdef RAYAABB2
00522
00523
00524
00525 rayBoxOverlap = aabbOverlap ? btRayAabb2 (raySource, rayDirectionInverse, sign, bounds, param, 0.0f, lambda_max) : false;
00526
00527 #else
00528 btVector3 normal;
00529 rayBoxOverlap = btRayAabb(raySource, rayTarget,bounds[0],bounds[1],param, normal);
00530 #endif
00531
00532 isLeafNode = rootNode->m_escapeIndex == -1;
00533
00534
00535 if (isLeafNode && (rayBoxOverlap != 0))
00536 {
00537 nodeCallback->processNode(rootNode->m_subPart,rootNode->m_triangleIndex);
00538 }
00539
00540
00541 if ((rayBoxOverlap != 0) || isLeafNode)
00542 {
00543 rootNode++;
00544 curIndex++;
00545 } else
00546 {
00547 escapeIndex = rootNode->m_escapeIndex;
00548 rootNode += escapeIndex;
00549 curIndex += escapeIndex;
00550 }
00551 }
00552 if (maxIterations < walkIterations)
00553 maxIterations = walkIterations;
00554
00555 }
00556
00557
00558
00559 void btQuantizedBvh::walkStacklessQuantizedTreeAgainstRay(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax, int startNodeIndex,int endNodeIndex) const
00560 {
00561 btAssert(m_useQuantization);
00562
00563 int curIndex = startNodeIndex;
00564 int walkIterations = 0;
00565 int subTreeSize = endNodeIndex - startNodeIndex;
00566 (void)subTreeSize;
00567
00568 const btQuantizedBvhNode* rootNode = &m_quantizedContiguousNodes[startNodeIndex];
00569 int escapeIndex;
00570
00571 bool isLeafNode;
00572
00573 unsigned boxBoxOverlap = 0;
00574 unsigned rayBoxOverlap = 0;
00575
00576 btScalar lambda_max = 1.0;
00577
00578 #ifdef RAYAABB2
00579 btVector3 rayDirection = (rayTarget-raySource);
00580 rayDirection.normalize ();
00581 lambda_max = rayDirection.dot(rayTarget-raySource);
00583 rayDirection[0] = rayDirection[0] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDirection[0];
00584 rayDirection[1] = rayDirection[1] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDirection[1];
00585 rayDirection[2] = rayDirection[2] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDirection[2];
00586 unsigned int sign[3] = { rayDirection[0] < 0.0, rayDirection[1] < 0.0, rayDirection[2] < 0.0};
00587 #endif
00588
00589
00590 btVector3 rayAabbMin = raySource;
00591 btVector3 rayAabbMax = raySource;
00592 rayAabbMin.setMin(rayTarget);
00593 rayAabbMax.setMax(rayTarget);
00594
00595
00596 rayAabbMin += aabbMin;
00597 rayAabbMax += aabbMax;
00598
00599 unsigned short int quantizedQueryAabbMin[3];
00600 unsigned short int quantizedQueryAabbMax[3];
00601 quantizeWithClamp(quantizedQueryAabbMin,rayAabbMin,0);
00602 quantizeWithClamp(quantizedQueryAabbMax,rayAabbMax,1);
00603
00604 while (curIndex < endNodeIndex)
00605 {
00606
00607
00608 #ifdef VISUALLY_ANALYZE_BVH
00609
00610 static int drawPatch = 0;
00611
00612 extern btIDebugDraw* debugDrawerPtr;
00613 if (curIndex==drawPatch)
00614 {
00615 btVector3 aabbMin,aabbMax;
00616 aabbMin = unQuantize(rootNode->m_quantizedAabbMin);
00617 aabbMax = unQuantize(rootNode->m_quantizedAabbMax);
00618 btVector3 color(1,0,0);
00619 debugDrawerPtr->drawAabb(aabbMin,aabbMax,color);
00620 }
00621 #endif//VISUALLY_ANALYZE_BVH
00622
00623
00624 btAssert (walkIterations < subTreeSize);
00625
00626 walkIterations++;
00627
00628
00629 btScalar param = 1.0;
00630 rayBoxOverlap = 0;
00631 boxBoxOverlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,rootNode->m_quantizedAabbMin,rootNode->m_quantizedAabbMax);
00632 isLeafNode = rootNode->isLeafNode();
00633 if (boxBoxOverlap)
00634 {
00635 btVector3 bounds[2];
00636 bounds[0] = unQuantize(rootNode->m_quantizedAabbMin);
00637 bounds[1] = unQuantize(rootNode->m_quantizedAabbMax);
00638
00639 bounds[0] -= aabbMax;
00640 bounds[1] -= aabbMin;
00641 btVector3 normal;
00642 #if 0
00643 bool ra2 = btRayAabb2 (raySource, rayDirection, sign, bounds, param, 0.0, lambda_max);
00644 bool ra = btRayAabb (raySource, rayTarget, bounds[0], bounds[1], param, normal);
00645 if (ra2 != ra)
00646 {
00647 printf("functions don't match\n");
00648 }
00649 #endif
00650 #ifdef RAYAABB2
00651
00652
00653
00654
00655
00656 rayBoxOverlap = btRayAabb2 (raySource, rayDirection, sign, bounds, param, 0.0f, lambda_max);
00657
00658 #else
00659 rayBoxOverlap = true;
00660 #endif
00661 }
00662
00663 if (isLeafNode && rayBoxOverlap)
00664 {
00665 nodeCallback->processNode(rootNode->getPartId(),rootNode->getTriangleIndex());
00666 }
00667
00668
00669 if ((rayBoxOverlap != 0) || isLeafNode)
00670 {
00671 rootNode++;
00672 curIndex++;
00673 } else
00674 {
00675 escapeIndex = rootNode->getEscapeIndex();
00676 rootNode += escapeIndex;
00677 curIndex += escapeIndex;
00678 }
00679 }
00680 if (maxIterations < walkIterations)
00681 maxIterations = walkIterations;
00682
00683 }
00684
00685 void btQuantizedBvh::walkStacklessQuantizedTree(btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax,int startNodeIndex,int endNodeIndex) const
00686 {
00687 btAssert(m_useQuantization);
00688
00689 int curIndex = startNodeIndex;
00690 int walkIterations = 0;
00691 int subTreeSize = endNodeIndex - startNodeIndex;
00692 (void)subTreeSize;
00693
00694 const btQuantizedBvhNode* rootNode = &m_quantizedContiguousNodes[startNodeIndex];
00695 int escapeIndex;
00696
00697 bool isLeafNode;
00698
00699 unsigned aabbOverlap;
00700
00701 while (curIndex < endNodeIndex)
00702 {
00703
00704
00705 #ifdef VISUALLY_ANALYZE_BVH
00706
00707 static int drawPatch = 0;
00708
00709 extern btIDebugDraw* debugDrawerPtr;
00710 if (curIndex==drawPatch)
00711 {
00712 btVector3 aabbMin,aabbMax;
00713 aabbMin = unQuantize(rootNode->m_quantizedAabbMin);
00714 aabbMax = unQuantize(rootNode->m_quantizedAabbMax);
00715 btVector3 color(1,0,0);
00716 debugDrawerPtr->drawAabb(aabbMin,aabbMax,color);
00717 }
00718 #endif//VISUALLY_ANALYZE_BVH
00719
00720
00721 btAssert (walkIterations < subTreeSize);
00722
00723 walkIterations++;
00724
00725 aabbOverlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,rootNode->m_quantizedAabbMin,rootNode->m_quantizedAabbMax);
00726 isLeafNode = rootNode->isLeafNode();
00727
00728 if (isLeafNode && aabbOverlap)
00729 {
00730 nodeCallback->processNode(rootNode->getPartId(),rootNode->getTriangleIndex());
00731 }
00732
00733
00734 if ((aabbOverlap != 0) || isLeafNode)
00735 {
00736 rootNode++;
00737 curIndex++;
00738 } else
00739 {
00740 escapeIndex = rootNode->getEscapeIndex();
00741 rootNode += escapeIndex;
00742 curIndex += escapeIndex;
00743 }
00744 }
00745 if (maxIterations < walkIterations)
00746 maxIterations = walkIterations;
00747
00748 }
00749
00750
00751 void btQuantizedBvh::walkStacklessQuantizedTreeCacheFriendly(btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax) const
00752 {
00753 btAssert(m_useQuantization);
00754
00755 int i;
00756
00757
00758 for (i=0;i<this->m_SubtreeHeaders.size();i++)
00759 {
00760 const btBvhSubtreeInfo& subtree = m_SubtreeHeaders[i];
00761
00762
00763 unsigned overlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,subtree.m_quantizedAabbMin,subtree.m_quantizedAabbMax);
00764 if (overlap != 0)
00765 {
00766 walkStacklessQuantizedTree(nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax,
00767 subtree.m_rootNodeIndex,
00768 subtree.m_rootNodeIndex+subtree.m_subtreeSize);
00769 }
00770 }
00771 }
00772
00773
00774 void btQuantizedBvh::reportRayOverlappingNodex (btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget) const
00775 {
00776 reportBoxCastOverlappingNodex(nodeCallback,raySource,rayTarget,btVector3(0,0,0),btVector3(0,0,0));
00777 }
00778
00779
00780 void btQuantizedBvh::reportBoxCastOverlappingNodex(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin,const btVector3& aabbMax) const
00781 {
00782
00783
00784 if (m_useQuantization)
00785 {
00786 walkStacklessQuantizedTreeAgainstRay(nodeCallback, raySource, rayTarget, aabbMin, aabbMax, 0, m_curNodeIndex);
00787 }
00788 else
00789 {
00790 walkStacklessTreeAgainstRay(nodeCallback, raySource, rayTarget, aabbMin, aabbMax, 0, m_curNodeIndex);
00791 }
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805 }
00806
00807
00808 void btQuantizedBvh::swapLeafNodes(int i,int splitIndex)
00809 {
00810 if (m_useQuantization)
00811 {
00812 btQuantizedBvhNode tmp = m_quantizedLeafNodes[i];
00813 m_quantizedLeafNodes[i] = m_quantizedLeafNodes[splitIndex];
00814 m_quantizedLeafNodes[splitIndex] = tmp;
00815 } else
00816 {
00817 btOptimizedBvhNode tmp = m_leafNodes[i];
00818 m_leafNodes[i] = m_leafNodes[splitIndex];
00819 m_leafNodes[splitIndex] = tmp;
00820 }
00821 }
00822
00823 void btQuantizedBvh::assignInternalNodeFromLeafNode(int internalNode,int leafNodeIndex)
00824 {
00825 if (m_useQuantization)
00826 {
00827 m_quantizedContiguousNodes[internalNode] = m_quantizedLeafNodes[leafNodeIndex];
00828 } else
00829 {
00830 m_contiguousNodes[internalNode] = m_leafNodes[leafNodeIndex];
00831 }
00832 }
00833
00834
00835 #include <new>
00836
00837 #if 0
00838
00839 static const unsigned BVH_ALIGNMENT = 16;
00840 static const unsigned BVH_ALIGNMENT_MASK = BVH_ALIGNMENT-1;
00841
00842 static const unsigned BVH_ALIGNMENT_BLOCKS = 2;
00843 #endif
00844
00845
00846 unsigned int btQuantizedBvh::getAlignmentSerializationPadding()
00847 {
00848
00849 return 0;
00850 }
00851
00852 unsigned btQuantizedBvh::calculateSerializeBufferSize() const
00853 {
00854 unsigned baseSize = sizeof(btQuantizedBvh) + getAlignmentSerializationPadding();
00855 baseSize += sizeof(btBvhSubtreeInfo) * m_subtreeHeaderCount;
00856 if (m_useQuantization)
00857 {
00858 return baseSize + m_curNodeIndex * sizeof(btQuantizedBvhNode);
00859 }
00860 return baseSize + m_curNodeIndex * sizeof(btOptimizedBvhNode);
00861 }
00862
00863 bool btQuantizedBvh::serialize(void *o_alignedDataBuffer, unsigned , bool i_swapEndian) const
00864 {
00865 btAssert(m_subtreeHeaderCount == m_SubtreeHeaders.size());
00866 m_subtreeHeaderCount = m_SubtreeHeaders.size();
00867
00868
00869
00871
00872
00873
00874
00875
00876 btQuantizedBvh *targetBvh = (btQuantizedBvh *)o_alignedDataBuffer;
00877
00878
00879
00880 new (targetBvh) btQuantizedBvh;
00881
00882 if (i_swapEndian)
00883 {
00884 targetBvh->m_curNodeIndex = static_cast<int>(btSwapEndian(m_curNodeIndex));
00885
00886
00887 btSwapVector3Endian(m_bvhAabbMin,targetBvh->m_bvhAabbMin);
00888 btSwapVector3Endian(m_bvhAabbMax,targetBvh->m_bvhAabbMax);
00889 btSwapVector3Endian(m_bvhQuantization,targetBvh->m_bvhQuantization);
00890
00891 targetBvh->m_traversalMode = (btTraversalMode)btSwapEndian(m_traversalMode);
00892 targetBvh->m_subtreeHeaderCount = static_cast<int>(btSwapEndian(m_subtreeHeaderCount));
00893 }
00894 else
00895 {
00896 targetBvh->m_curNodeIndex = m_curNodeIndex;
00897 targetBvh->m_bvhAabbMin = m_bvhAabbMin;
00898 targetBvh->m_bvhAabbMax = m_bvhAabbMax;
00899 targetBvh->m_bvhQuantization = m_bvhQuantization;
00900 targetBvh->m_traversalMode = m_traversalMode;
00901 targetBvh->m_subtreeHeaderCount = m_subtreeHeaderCount;
00902 }
00903
00904 targetBvh->m_useQuantization = m_useQuantization;
00905
00906 unsigned char *nodeData = (unsigned char *)targetBvh;
00907 nodeData += sizeof(btQuantizedBvh);
00908
00909 unsigned sizeToAdd = 0;
00910 nodeData += sizeToAdd;
00911
00912 int nodeCount = m_curNodeIndex;
00913
00914 if (m_useQuantization)
00915 {
00916 targetBvh->m_quantizedContiguousNodes.initializeFromBuffer(nodeData, nodeCount, nodeCount);
00917
00918 if (i_swapEndian)
00919 {
00920 for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++)
00921 {
00922 targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0] = btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0]);
00923 targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[1] = btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[1]);
00924 targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[2] = btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[2]);
00925
00926 targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0] = btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0]);
00927 targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[1] = btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[1]);
00928 targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[2] = btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[2]);
00929
00930 targetBvh->m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex = static_cast<int>(btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex));
00931 }
00932 }
00933 else
00934 {
00935 for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++)
00936 {
00937
00938 targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0];
00939 targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[1] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[1];
00940 targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[2] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[2];
00941
00942 targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0];
00943 targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[1] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[1];
00944 targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[2] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[2];
00945
00946 targetBvh->m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex = m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex;
00947
00948
00949 }
00950 }
00951 nodeData += sizeof(btQuantizedBvhNode) * nodeCount;
00952
00953
00954
00955
00956 targetBvh->m_quantizedContiguousNodes.initializeFromBuffer(NULL, 0, 0);
00957 }
00958 else
00959 {
00960 targetBvh->m_contiguousNodes.initializeFromBuffer(nodeData, nodeCount, nodeCount);
00961
00962 if (i_swapEndian)
00963 {
00964 for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++)
00965 {
00966 btSwapVector3Endian(m_contiguousNodes[nodeIndex].m_aabbMinOrg, targetBvh->m_contiguousNodes[nodeIndex].m_aabbMinOrg);
00967 btSwapVector3Endian(m_contiguousNodes[nodeIndex].m_aabbMaxOrg, targetBvh->m_contiguousNodes[nodeIndex].m_aabbMaxOrg);
00968
00969 targetBvh->m_contiguousNodes[nodeIndex].m_escapeIndex = static_cast<int>(btSwapEndian(m_contiguousNodes[nodeIndex].m_escapeIndex));
00970 targetBvh->m_contiguousNodes[nodeIndex].m_subPart = static_cast<int>(btSwapEndian(m_contiguousNodes[nodeIndex].m_subPart));
00971 targetBvh->m_contiguousNodes[nodeIndex].m_triangleIndex = static_cast<int>(btSwapEndian(m_contiguousNodes[nodeIndex].m_triangleIndex));
00972 }
00973 }
00974 else
00975 {
00976 for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++)
00977 {
00978 targetBvh->m_contiguousNodes[nodeIndex].m_aabbMinOrg = m_contiguousNodes[nodeIndex].m_aabbMinOrg;
00979 targetBvh->m_contiguousNodes[nodeIndex].m_aabbMaxOrg = m_contiguousNodes[nodeIndex].m_aabbMaxOrg;
00980
00981 targetBvh->m_contiguousNodes[nodeIndex].m_escapeIndex = m_contiguousNodes[nodeIndex].m_escapeIndex;
00982 targetBvh->m_contiguousNodes[nodeIndex].m_subPart = m_contiguousNodes[nodeIndex].m_subPart;
00983 targetBvh->m_contiguousNodes[nodeIndex].m_triangleIndex = m_contiguousNodes[nodeIndex].m_triangleIndex;
00984 }
00985 }
00986 nodeData += sizeof(btOptimizedBvhNode) * nodeCount;
00987
00988
00989
00990
00991 targetBvh->m_contiguousNodes.initializeFromBuffer(NULL, 0, 0);
00992 }
00993
00994 sizeToAdd = 0;
00995 nodeData += sizeToAdd;
00996
00997
00998 targetBvh->m_SubtreeHeaders.initializeFromBuffer(nodeData, m_subtreeHeaderCount, m_subtreeHeaderCount);
00999 if (i_swapEndian)
01000 {
01001 for (int i = 0; i < m_subtreeHeaderCount; i++)
01002 {
01003 targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMin[0] = btSwapEndian(m_SubtreeHeaders[i].m_quantizedAabbMin[0]);
01004 targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMin[1] = btSwapEndian(m_SubtreeHeaders[i].m_quantizedAabbMin[1]);
01005 targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMin[2] = btSwapEndian(m_SubtreeHeaders[i].m_quantizedAabbMin[2]);
01006
01007 targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMax[0] = btSwapEndian(m_SubtreeHeaders[i].m_quantizedAabbMax[0]);
01008 targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMax[1] = btSwapEndian(m_SubtreeHeaders[i].m_quantizedAabbMax[1]);
01009 targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMax[2] = btSwapEndian(m_SubtreeHeaders[i].m_quantizedAabbMax[2]);
01010
01011 targetBvh->m_SubtreeHeaders[i].m_rootNodeIndex = static_cast<int>(btSwapEndian(m_SubtreeHeaders[i].m_rootNodeIndex));
01012 targetBvh->m_SubtreeHeaders[i].m_subtreeSize = static_cast<int>(btSwapEndian(m_SubtreeHeaders[i].m_subtreeSize));
01013 }
01014 }
01015 else
01016 {
01017 for (int i = 0; i < m_subtreeHeaderCount; i++)
01018 {
01019 targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMin[0] = (m_SubtreeHeaders[i].m_quantizedAabbMin[0]);
01020 targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMin[1] = (m_SubtreeHeaders[i].m_quantizedAabbMin[1]);
01021 targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMin[2] = (m_SubtreeHeaders[i].m_quantizedAabbMin[2]);
01022
01023 targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMax[0] = (m_SubtreeHeaders[i].m_quantizedAabbMax[0]);
01024 targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMax[1] = (m_SubtreeHeaders[i].m_quantizedAabbMax[1]);
01025 targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMax[2] = (m_SubtreeHeaders[i].m_quantizedAabbMax[2]);
01026
01027 targetBvh->m_SubtreeHeaders[i].m_rootNodeIndex = (m_SubtreeHeaders[i].m_rootNodeIndex);
01028 targetBvh->m_SubtreeHeaders[i].m_subtreeSize = (m_SubtreeHeaders[i].m_subtreeSize);
01029
01030
01031 targetBvh->m_SubtreeHeaders[i].m_padding[0] = 0;
01032 targetBvh->m_SubtreeHeaders[i].m_padding[1] = 0;
01033 targetBvh->m_SubtreeHeaders[i].m_padding[2] = 0;
01034 }
01035 }
01036 nodeData += sizeof(btBvhSubtreeInfo) * m_subtreeHeaderCount;
01037
01038
01039
01040
01041 targetBvh->m_SubtreeHeaders.initializeFromBuffer(NULL, 0, 0);
01042
01043
01044 *((void**)o_alignedDataBuffer) = NULL;
01045
01046 return true;
01047 }
01048
01049 btQuantizedBvh *btQuantizedBvh::deSerializeInPlace(void *i_alignedDataBuffer, unsigned int i_dataBufferSize, bool i_swapEndian)
01050 {
01051
01052 if (i_alignedDataBuffer == NULL)
01053 {
01054 return NULL;
01055 }
01056 btQuantizedBvh *bvh = (btQuantizedBvh *)i_alignedDataBuffer;
01057
01058 if (i_swapEndian)
01059 {
01060 bvh->m_curNodeIndex = static_cast<int>(btSwapEndian(bvh->m_curNodeIndex));
01061
01062 btUnSwapVector3Endian(bvh->m_bvhAabbMin);
01063 btUnSwapVector3Endian(bvh->m_bvhAabbMax);
01064 btUnSwapVector3Endian(bvh->m_bvhQuantization);
01065
01066 bvh->m_traversalMode = (btTraversalMode)btSwapEndian(bvh->m_traversalMode);
01067 bvh->m_subtreeHeaderCount = static_cast<int>(btSwapEndian(bvh->m_subtreeHeaderCount));
01068 }
01069
01070 unsigned int calculatedBufSize = bvh->calculateSerializeBufferSize();
01071 btAssert(calculatedBufSize <= i_dataBufferSize);
01072
01073 if (calculatedBufSize > i_dataBufferSize)
01074 {
01075 return NULL;
01076 }
01077
01078 unsigned char *nodeData = (unsigned char *)bvh;
01079 nodeData += sizeof(btQuantizedBvh);
01080
01081 unsigned sizeToAdd = 0;
01082 nodeData += sizeToAdd;
01083
01084 int nodeCount = bvh->m_curNodeIndex;
01085
01086
01087
01088 new (bvh) btQuantizedBvh(*bvh, false);
01089
01090 if (bvh->m_useQuantization)
01091 {
01092 bvh->m_quantizedContiguousNodes.initializeFromBuffer(nodeData, nodeCount, nodeCount);
01093
01094 if (i_swapEndian)
01095 {
01096 for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++)
01097 {
01098 bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0] = btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0]);
01099 bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[1] = btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[1]);
01100 bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[2] = btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[2]);
01101
01102 bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0] = btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0]);
01103 bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[1] = btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[1]);
01104 bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[2] = btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[2]);
01105
01106 bvh->m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex = static_cast<int>(btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex));
01107 }
01108 }
01109 nodeData += sizeof(btQuantizedBvhNode) * nodeCount;
01110 }
01111 else
01112 {
01113 bvh->m_contiguousNodes.initializeFromBuffer(nodeData, nodeCount, nodeCount);
01114
01115 if (i_swapEndian)
01116 {
01117 for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++)
01118 {
01119 btUnSwapVector3Endian(bvh->m_contiguousNodes[nodeIndex].m_aabbMinOrg);
01120 btUnSwapVector3Endian(bvh->m_contiguousNodes[nodeIndex].m_aabbMaxOrg);
01121
01122 bvh->m_contiguousNodes[nodeIndex].m_escapeIndex = static_cast<int>(btSwapEndian(bvh->m_contiguousNodes[nodeIndex].m_escapeIndex));
01123 bvh->m_contiguousNodes[nodeIndex].m_subPart = static_cast<int>(btSwapEndian(bvh->m_contiguousNodes[nodeIndex].m_subPart));
01124 bvh->m_contiguousNodes[nodeIndex].m_triangleIndex = static_cast<int>(btSwapEndian(bvh->m_contiguousNodes[nodeIndex].m_triangleIndex));
01125 }
01126 }
01127 nodeData += sizeof(btOptimizedBvhNode) * nodeCount;
01128 }
01129
01130 sizeToAdd = 0;
01131 nodeData += sizeToAdd;
01132
01133
01134 bvh->m_SubtreeHeaders.initializeFromBuffer(nodeData, bvh->m_subtreeHeaderCount, bvh->m_subtreeHeaderCount);
01135 if (i_swapEndian)
01136 {
01137 for (int i = 0; i < bvh->m_subtreeHeaderCount; i++)
01138 {
01139 bvh->m_SubtreeHeaders[i].m_quantizedAabbMin[0] = btSwapEndian(bvh->m_SubtreeHeaders[i].m_quantizedAabbMin[0]);
01140 bvh->m_SubtreeHeaders[i].m_quantizedAabbMin[1] = btSwapEndian(bvh->m_SubtreeHeaders[i].m_quantizedAabbMin[1]);
01141 bvh->m_SubtreeHeaders[i].m_quantizedAabbMin[2] = btSwapEndian(bvh->m_SubtreeHeaders[i].m_quantizedAabbMin[2]);
01142
01143 bvh->m_SubtreeHeaders[i].m_quantizedAabbMax[0] = btSwapEndian(bvh->m_SubtreeHeaders[i].m_quantizedAabbMax[0]);
01144 bvh->m_SubtreeHeaders[i].m_quantizedAabbMax[1] = btSwapEndian(bvh->m_SubtreeHeaders[i].m_quantizedAabbMax[1]);
01145 bvh->m_SubtreeHeaders[i].m_quantizedAabbMax[2] = btSwapEndian(bvh->m_SubtreeHeaders[i].m_quantizedAabbMax[2]);
01146
01147 bvh->m_SubtreeHeaders[i].m_rootNodeIndex = static_cast<int>(btSwapEndian(bvh->m_SubtreeHeaders[i].m_rootNodeIndex));
01148 bvh->m_SubtreeHeaders[i].m_subtreeSize = static_cast<int>(btSwapEndian(bvh->m_SubtreeHeaders[i].m_subtreeSize));
01149 }
01150 }
01151
01152 return bvh;
01153 }
01154
01155
01156 btQuantizedBvh::btQuantizedBvh(btQuantizedBvh &self, bool ) :
01157 m_bvhAabbMin(self.m_bvhAabbMin),
01158 m_bvhAabbMax(self.m_bvhAabbMax),
01159 m_bvhQuantization(self.m_bvhQuantization),
01160 m_bulletVersion(BT_BULLET_VERSION)
01161 {
01162
01163 }
01164
01165 void btQuantizedBvh::deSerializeFloat(struct btQuantizedBvhFloatData& quantizedBvhFloatData)
01166 {
01167 m_bvhAabbMax.deSerializeFloat(quantizedBvhFloatData.m_bvhAabbMax);
01168 m_bvhAabbMin.deSerializeFloat(quantizedBvhFloatData.m_bvhAabbMin);
01169 m_bvhQuantization.deSerializeFloat(quantizedBvhFloatData.m_bvhQuantization);
01170
01171 m_curNodeIndex = quantizedBvhFloatData.m_curNodeIndex;
01172 m_useQuantization = quantizedBvhFloatData.m_useQuantization!=0;
01173
01174 {
01175 int numElem = quantizedBvhFloatData.m_numContiguousLeafNodes;
01176 m_contiguousNodes.resize(numElem);
01177
01178 if (numElem)
01179 {
01180 btOptimizedBvhNodeFloatData* memPtr = quantizedBvhFloatData.m_contiguousNodesPtr;
01181
01182 for (int i=0;i<numElem;i++,memPtr++)
01183 {
01184 m_contiguousNodes[i].m_aabbMaxOrg.deSerializeFloat(memPtr->m_aabbMaxOrg);
01185 m_contiguousNodes[i].m_aabbMinOrg.deSerializeFloat(memPtr->m_aabbMinOrg);
01186 m_contiguousNodes[i].m_escapeIndex = memPtr->m_escapeIndex;
01187 m_contiguousNodes[i].m_subPart = memPtr->m_subPart;
01188 m_contiguousNodes[i].m_triangleIndex = memPtr->m_triangleIndex;
01189 }
01190 }
01191 }
01192
01193 {
01194 int numElem = quantizedBvhFloatData.m_numQuantizedContiguousNodes;
01195 m_quantizedContiguousNodes.resize(numElem);
01196
01197 if (numElem)
01198 {
01199 btQuantizedBvhNodeData* memPtr = quantizedBvhFloatData.m_quantizedContiguousNodesPtr;
01200 for (int i=0;i<numElem;i++,memPtr++)
01201 {
01202 m_quantizedContiguousNodes[i].m_escapeIndexOrTriangleIndex = memPtr->m_escapeIndexOrTriangleIndex;
01203 m_quantizedContiguousNodes[i].m_quantizedAabbMax[0] = memPtr->m_quantizedAabbMax[0];
01204 m_quantizedContiguousNodes[i].m_quantizedAabbMax[1] = memPtr->m_quantizedAabbMax[1];
01205 m_quantizedContiguousNodes[i].m_quantizedAabbMax[2] = memPtr->m_quantizedAabbMax[2];
01206 m_quantizedContiguousNodes[i].m_quantizedAabbMin[0] = memPtr->m_quantizedAabbMin[0];
01207 m_quantizedContiguousNodes[i].m_quantizedAabbMin[1] = memPtr->m_quantizedAabbMin[1];
01208 m_quantizedContiguousNodes[i].m_quantizedAabbMin[2] = memPtr->m_quantizedAabbMin[2];
01209 }
01210 }
01211 }
01212
01213 m_traversalMode = btTraversalMode(quantizedBvhFloatData.m_traversalMode);
01214
01215 {
01216 int numElem = quantizedBvhFloatData.m_numSubtreeHeaders;
01217 m_SubtreeHeaders.resize(numElem);
01218 if (numElem)
01219 {
01220 btBvhSubtreeInfoData* memPtr = quantizedBvhFloatData.m_subTreeInfoPtr;
01221 for (int i=0;i<numElem;i++,memPtr++)
01222 {
01223 m_SubtreeHeaders[i].m_quantizedAabbMax[0] = memPtr->m_quantizedAabbMax[0] ;
01224 m_SubtreeHeaders[i].m_quantizedAabbMax[1] = memPtr->m_quantizedAabbMax[1];
01225 m_SubtreeHeaders[i].m_quantizedAabbMax[2] = memPtr->m_quantizedAabbMax[2];
01226 m_SubtreeHeaders[i].m_quantizedAabbMin[0] = memPtr->m_quantizedAabbMin[0];
01227 m_SubtreeHeaders[i].m_quantizedAabbMin[1] = memPtr->m_quantizedAabbMin[1];
01228 m_SubtreeHeaders[i].m_quantizedAabbMin[2] = memPtr->m_quantizedAabbMin[2];
01229 m_SubtreeHeaders[i].m_rootNodeIndex = memPtr->m_rootNodeIndex;
01230 m_SubtreeHeaders[i].m_subtreeSize = memPtr->m_subtreeSize;
01231 }
01232 }
01233 }
01234 }
01235
01236 void btQuantizedBvh::deSerializeDouble(struct btQuantizedBvhDoubleData& quantizedBvhDoubleData)
01237 {
01238 m_bvhAabbMax.deSerializeDouble(quantizedBvhDoubleData.m_bvhAabbMax);
01239 m_bvhAabbMin.deSerializeDouble(quantizedBvhDoubleData.m_bvhAabbMin);
01240 m_bvhQuantization.deSerializeDouble(quantizedBvhDoubleData.m_bvhQuantization);
01241
01242 m_curNodeIndex = quantizedBvhDoubleData.m_curNodeIndex;
01243 m_useQuantization = quantizedBvhDoubleData.m_useQuantization!=0;
01244
01245 {
01246 int numElem = quantizedBvhDoubleData.m_numContiguousLeafNodes;
01247 m_contiguousNodes.resize(numElem);
01248
01249 if (numElem)
01250 {
01251 btOptimizedBvhNodeDoubleData* memPtr = quantizedBvhDoubleData.m_contiguousNodesPtr;
01252
01253 for (int i=0;i<numElem;i++,memPtr++)
01254 {
01255 m_contiguousNodes[i].m_aabbMaxOrg.deSerializeDouble(memPtr->m_aabbMaxOrg);
01256 m_contiguousNodes[i].m_aabbMinOrg.deSerializeDouble(memPtr->m_aabbMinOrg);
01257 m_contiguousNodes[i].m_escapeIndex = memPtr->m_escapeIndex;
01258 m_contiguousNodes[i].m_subPart = memPtr->m_subPart;
01259 m_contiguousNodes[i].m_triangleIndex = memPtr->m_triangleIndex;
01260 }
01261 }
01262 }
01263
01264 {
01265 int numElem = quantizedBvhDoubleData.m_numQuantizedContiguousNodes;
01266 m_quantizedContiguousNodes.resize(numElem);
01267
01268 if (numElem)
01269 {
01270 btQuantizedBvhNodeData* memPtr = quantizedBvhDoubleData.m_quantizedContiguousNodesPtr;
01271 for (int i=0;i<numElem;i++,memPtr++)
01272 {
01273 m_quantizedContiguousNodes[i].m_escapeIndexOrTriangleIndex = memPtr->m_escapeIndexOrTriangleIndex;
01274 m_quantizedContiguousNodes[i].m_quantizedAabbMax[0] = memPtr->m_quantizedAabbMax[0];
01275 m_quantizedContiguousNodes[i].m_quantizedAabbMax[1] = memPtr->m_quantizedAabbMax[1];
01276 m_quantizedContiguousNodes[i].m_quantizedAabbMax[2] = memPtr->m_quantizedAabbMax[2];
01277 m_quantizedContiguousNodes[i].m_quantizedAabbMin[0] = memPtr->m_quantizedAabbMin[0];
01278 m_quantizedContiguousNodes[i].m_quantizedAabbMin[1] = memPtr->m_quantizedAabbMin[1];
01279 m_quantizedContiguousNodes[i].m_quantizedAabbMin[2] = memPtr->m_quantizedAabbMin[2];
01280 }
01281 }
01282 }
01283
01284 m_traversalMode = btTraversalMode(quantizedBvhDoubleData.m_traversalMode);
01285
01286 {
01287 int numElem = quantizedBvhDoubleData.m_numSubtreeHeaders;
01288 m_SubtreeHeaders.resize(numElem);
01289 if (numElem)
01290 {
01291 btBvhSubtreeInfoData* memPtr = quantizedBvhDoubleData.m_subTreeInfoPtr;
01292 for (int i=0;i<numElem;i++,memPtr++)
01293 {
01294 m_SubtreeHeaders[i].m_quantizedAabbMax[0] = memPtr->m_quantizedAabbMax[0] ;
01295 m_SubtreeHeaders[i].m_quantizedAabbMax[1] = memPtr->m_quantizedAabbMax[1];
01296 m_SubtreeHeaders[i].m_quantizedAabbMax[2] = memPtr->m_quantizedAabbMax[2];
01297 m_SubtreeHeaders[i].m_quantizedAabbMin[0] = memPtr->m_quantizedAabbMin[0];
01298 m_SubtreeHeaders[i].m_quantizedAabbMin[1] = memPtr->m_quantizedAabbMin[1];
01299 m_SubtreeHeaders[i].m_quantizedAabbMin[2] = memPtr->m_quantizedAabbMin[2];
01300 m_SubtreeHeaders[i].m_rootNodeIndex = memPtr->m_rootNodeIndex;
01301 m_SubtreeHeaders[i].m_subtreeSize = memPtr->m_subtreeSize;
01302 }
01303 }
01304 }
01305
01306 }
01307
01308
01309
01311 const char* btQuantizedBvh::serialize(void* dataBuffer, btSerializer* serializer) const
01312 {
01313 btQuantizedBvhData* quantizedData = (btQuantizedBvhData*)dataBuffer;
01314
01315 m_bvhAabbMax.serialize(quantizedData->m_bvhAabbMax);
01316 m_bvhAabbMin.serialize(quantizedData->m_bvhAabbMin);
01317 m_bvhQuantization.serialize(quantizedData->m_bvhQuantization);
01318
01319 quantizedData->m_curNodeIndex = m_curNodeIndex;
01320 quantizedData->m_useQuantization = m_useQuantization;
01321
01322 quantizedData->m_numContiguousLeafNodes = m_contiguousNodes.size();
01323 quantizedData->m_contiguousNodesPtr = (btOptimizedBvhNodeData*) (m_contiguousNodes.size() ? serializer->getUniquePointer((void*)&m_contiguousNodes[0]) : 0);
01324 if (quantizedData->m_contiguousNodesPtr)
01325 {
01326 int sz = sizeof(btOptimizedBvhNodeData);
01327 int numElem = m_contiguousNodes.size();
01328 btChunk* chunk = serializer->allocate(sz,numElem);
01329 btOptimizedBvhNodeData* memPtr = (btOptimizedBvhNodeData*)chunk->m_oldPtr;
01330 for (int i=0;i<numElem;i++,memPtr++)
01331 {
01332 m_contiguousNodes[i].m_aabbMaxOrg.serialize(memPtr->m_aabbMaxOrg);
01333 m_contiguousNodes[i].m_aabbMinOrg.serialize(memPtr->m_aabbMinOrg);
01334 memPtr->m_escapeIndex = m_contiguousNodes[i].m_escapeIndex;
01335 memPtr->m_subPart = m_contiguousNodes[i].m_subPart;
01336 memPtr->m_triangleIndex = m_contiguousNodes[i].m_triangleIndex;
01337 }
01338 serializer->finalizeChunk(chunk,"btOptimizedBvhNodeData",BT_ARRAY_CODE,(void*)&m_contiguousNodes[0]);
01339 }
01340
01341 quantizedData->m_numQuantizedContiguousNodes = m_quantizedContiguousNodes.size();
01342
01343 quantizedData->m_quantizedContiguousNodesPtr =(btQuantizedBvhNodeData*) (m_quantizedContiguousNodes.size() ? serializer->getUniquePointer((void*)&m_quantizedContiguousNodes[0]) : 0);
01344 if (quantizedData->m_quantizedContiguousNodesPtr)
01345 {
01346 int sz = sizeof(btQuantizedBvhNodeData);
01347 int numElem = m_quantizedContiguousNodes.size();
01348 btChunk* chunk = serializer->allocate(sz,numElem);
01349 btQuantizedBvhNodeData* memPtr = (btQuantizedBvhNodeData*)chunk->m_oldPtr;
01350 for (int i=0;i<numElem;i++,memPtr++)
01351 {
01352 memPtr->m_escapeIndexOrTriangleIndex = m_quantizedContiguousNodes[i].m_escapeIndexOrTriangleIndex;
01353 memPtr->m_quantizedAabbMax[0] = m_quantizedContiguousNodes[i].m_quantizedAabbMax[0];
01354 memPtr->m_quantizedAabbMax[1] = m_quantizedContiguousNodes[i].m_quantizedAabbMax[1];
01355 memPtr->m_quantizedAabbMax[2] = m_quantizedContiguousNodes[i].m_quantizedAabbMax[2];
01356 memPtr->m_quantizedAabbMin[0] = m_quantizedContiguousNodes[i].m_quantizedAabbMin[0];
01357 memPtr->m_quantizedAabbMin[1] = m_quantizedContiguousNodes[i].m_quantizedAabbMin[1];
01358 memPtr->m_quantizedAabbMin[2] = m_quantizedContiguousNodes[i].m_quantizedAabbMin[2];
01359 }
01360 serializer->finalizeChunk(chunk,"btQuantizedBvhNodeData",BT_ARRAY_CODE,(void*)&m_quantizedContiguousNodes[0]);
01361 }
01362
01363 quantizedData->m_traversalMode = int(m_traversalMode);
01364 quantizedData->m_numSubtreeHeaders = m_SubtreeHeaders.size();
01365
01366 quantizedData->m_subTreeInfoPtr = (btBvhSubtreeInfoData*) (m_SubtreeHeaders.size() ? serializer->getUniquePointer((void*)&m_SubtreeHeaders[0]) : 0);
01367 if (quantizedData->m_subTreeInfoPtr)
01368 {
01369 int sz = sizeof(btBvhSubtreeInfoData);
01370 int numElem = m_SubtreeHeaders.size();
01371 btChunk* chunk = serializer->allocate(sz,numElem);
01372 btBvhSubtreeInfoData* memPtr = (btBvhSubtreeInfoData*)chunk->m_oldPtr;
01373 for (int i=0;i<numElem;i++,memPtr++)
01374 {
01375 memPtr->m_quantizedAabbMax[0] = m_SubtreeHeaders[i].m_quantizedAabbMax[0];
01376 memPtr->m_quantizedAabbMax[1] = m_SubtreeHeaders[i].m_quantizedAabbMax[1];
01377 memPtr->m_quantizedAabbMax[2] = m_SubtreeHeaders[i].m_quantizedAabbMax[2];
01378 memPtr->m_quantizedAabbMin[0] = m_SubtreeHeaders[i].m_quantizedAabbMin[0];
01379 memPtr->m_quantizedAabbMin[1] = m_SubtreeHeaders[i].m_quantizedAabbMin[1];
01380 memPtr->m_quantizedAabbMin[2] = m_SubtreeHeaders[i].m_quantizedAabbMin[2];
01381
01382 memPtr->m_rootNodeIndex = m_SubtreeHeaders[i].m_rootNodeIndex;
01383 memPtr->m_subtreeSize = m_SubtreeHeaders[i].m_subtreeSize;
01384 }
01385 serializer->finalizeChunk(chunk,"btBvhSubtreeInfoData",BT_ARRAY_CODE,(void*)&m_SubtreeHeaders[0]);
01386 }
01387 return btQuantizedBvhDataName;
01388 }
01389
01390
01391
01392
01393