btQuantizedBvh.cpp

Go to the documentation of this file.
00001 /*
00002 Bullet Continuous Collision Detection and Physics Library
00003 Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
00004 
00005 This software is provided 'as-is', without any express or implied warranty.
00006 In no event will the authors be held liable for any damages arising from the use of this software.
00007 Permission is granted to anyone to use this software for any purpose, 
00008 including commercial applications, and to alter it and redistribute it freely, 
00009 subject to the following restrictions:
00010 
00011 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
00012 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
00013 3. This notice may not be removed or altered from any source distribution.
00014 */
00015 
00016 #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                                         //m_traversalMode(TRAVERSAL_STACKLESS_CACHE_FRIENDLY)
00028                                         m_traversalMode(TRAVERSAL_STACKLESS)
00029                                         //m_traversalMode(TRAVERSAL_RECURSIVE)
00030                                         ,m_subtreeHeaderCount(0) //PCK: add this line
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                 //now we have an array of leafnodes in m_leafNodes
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         //PCK: update the copy of the size
00069         m_subtreeHeaderCount = m_SubtreeHeaders.size();
00070 
00071         //PCK: clear m_quantizedLeafNodes and m_leafNodes, they are temporary
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         //enlarge the AABB to avoid division by zero when initializing the quantization values
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         //calculate Best Splitting Axis and where to split it. Sort the incoming 'leafNodes' array within range 'startIndex/endIndex'.
00159         
00160         splitAxis = calcSplittingAxis(startIndex,endIndex);
00161 
00162         splitIndex = sortAndCalcSplittingIndex(startIndex,endIndex,splitAxis);
00163 
00164         int internalNodeIndex = m_curNodeIndex;
00165         
00166         //set the min aabb to 'inf' or a max value, and set the max aabb to a -inf/minimum value.
00167         //the aabb will be expanded during buildTree/mergeInternalNodeAabb with actual node values
00168         setInternalNodeAabbMin(m_curNodeIndex,m_bvhAabbMax);//can't use btVector3(SIMD_INFINITY,SIMD_INFINITY,SIMD_INFINITY)) because of quantization
00169         setInternalNodeAabbMax(m_curNodeIndex,m_bvhAabbMin);//can't use btVector3(-SIMD_INFINITY,-SIMD_INFINITY,-SIMD_INFINITY)) because of quantization
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         //internalNode->m_escapeIndex;
00181         
00182         int leftChildNodexIndex = m_curNodeIndex;
00183 
00184         //build left child tree
00185         buildTree(startIndex,splitIndex);
00186 
00187         int rightChildNodexIndex = m_curNodeIndex;
00188         //build right child tree
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                 //escapeIndex is the number of nodes of this subtree
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         //PCK: update the copy of the size
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         //sort leafNodes so all values larger then splitValue comes first, and smaller values start from 'splitIndex'.
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                         //swap
00272                         swapLeafNodes(i,splitIndex);
00273                         splitIndex++;
00274                 }
00275         }
00276 
00277         //if the splitIndex causes unbalanced trees, fix this by using the center in between startIndex and endIndex
00278         //otherwise the tree-building might fail due to stack-overflows in certain cases.
00279         //unbalanced1 is unsafe: it can cause stack overflows
00280         //bool unbalanced1 = ((splitIndex==startIndex) || (splitIndex == (endIndex-1)));
00281 
00282         //unbalanced2 should work too: always use center (perfect balanced trees)       
00283         //bool unbalanced2 = true;
00284 
00285         //this should be safe too:
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         //either choose recursive traversal (walkTree) or stackless (walkStacklessTree)
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                         //unsupported
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         //PCK: unsigned instead of bool
00380         unsigned aabbOverlap;
00381 
00382         while (curIndex < m_curNodeIndex)
00383         {
00384                 //catch bugs in tree data
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                 //PCK: unsigned instead of bool
00392                 if (isLeafNode && (aabbOverlap != 0))
00393                 {
00394                         nodeCallback->processNode(rootNode->m_subPart,rootNode->m_triangleIndex);
00395                 } 
00396                 
00397                 //PCK: unsigned instead of bool
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 void    btQuantizedBvh::walkTree(btOptimizedBvhNode* rootNode,btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const
00417 {
00418         bool isLeafNode, aabbOverlap = TestAabbAgainstAabb2(aabbMin,aabbMax,rootNode->m_aabbMin,rootNode->m_aabbMax);
00419         if (aabbOverlap)
00420         {
00421                 isLeafNode = (!rootNode->m_leftChild && !rootNode->m_rightChild);
00422                 if (isLeafNode)
00423                 {
00424                         nodeCallback->processNode(rootNode);
00425                 } else
00426                 {
00427                         walkTree(rootNode->m_leftChild,nodeCallback,aabbMin,aabbMax);
00428                         walkTree(rootNode->m_rightChild,nodeCallback,aabbMin,aabbMax);
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         //PCK: unsigned instead of bool
00441         unsigned aabbOverlap;
00442 
00443         //PCK: unsigned instead of bool
00444         aabbOverlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,currentNode->m_quantizedAabbMin,currentNode->m_quantizedAabbMax);
00445         isLeafNode = currentNode->isLeafNode();
00446                 
00447         //PCK: unsigned instead of bool
00448         if (aabbOverlap != 0)
00449         {
00450                 if (isLeafNode)
00451                 {
00452                         nodeCallback->processNode(currentNode->getPartId(),currentNode->getTriangleIndex());
00453                 } else
00454                 {
00455                         //process left and right children
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         //PCK: unsigned instead of bool
00476         unsigned aabbOverlap=0;
00477         unsigned rayBoxOverlap=0;
00478         btScalar lambda_max = 1.0;
00479         
00480                 /* Quick pruning by quantized box */
00481         btVector3 rayAabbMin = raySource;
00482         btVector3 rayAabbMax = raySource;
00483         rayAabbMin.setMin(rayTarget);
00484         rayAabbMax.setMax(rayTarget);
00485 
00486         /* Add box cast extents to bounding box */
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                 //catch bugs in tree data
00508                 btAssert (walkIterations < m_curNodeIndex);
00509 
00510                 walkIterations++;
00511 
00512                 bounds[0] = rootNode->m_aabbMinOrg;
00513                 bounds[1] = rootNode->m_aabbMaxOrg;
00514                 /* Add box cast extents */
00515                 bounds[0] -= aabbMax;
00516                 bounds[1] -= aabbMin;
00517 
00518                 aabbOverlap = TestAabbAgainstAabb2(rayAabbMin,rayAabbMax,rootNode->m_aabbMinOrg,rootNode->m_aabbMaxOrg);
00519                 //perhaps profile if it is worth doing the aabbOverlap test first
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                 //PCK: unsigned instead of bool
00535                 if (isLeafNode && (rayBoxOverlap != 0))
00536                 {
00537                         nodeCallback->processNode(rootNode->m_subPart,rootNode->m_triangleIndex);
00538                 } 
00539                 
00540                 //PCK: unsigned instead of bool
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         //PCK: unsigned instead of bool
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         /* Quick pruning by quantized box */
00590         btVector3 rayAabbMin = raySource;
00591         btVector3 rayAabbMax = raySource;
00592         rayAabbMin.setMin(rayTarget);
00593         rayAabbMax.setMax(rayTarget);
00594 
00595         /* Add box cast extents to bounding box */
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 //#define VISUALLY_ANALYZE_BVH 1
00608 #ifdef VISUALLY_ANALYZE_BVH
00609                 //some code snippet to debugDraw aabb, to visually analyze bvh structure
00610                 static int drawPatch = 0;
00611                 //need some global access to a debugDrawer
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                 //catch bugs in tree data
00624                 btAssert (walkIterations < subTreeSize);
00625 
00626                 walkIterations++;
00627                 //PCK: unsigned instead of bool
00628                 // only interested if this is closer than any previous hit
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                         /* Add box cast extents */
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                         //BT_PROFILE("btRayAabb2");
00656                         rayBoxOverlap = btRayAabb2 (raySource, rayDirection, sign, bounds, param, 0.0f, lambda_max);
00657                         
00658 #else
00659                         rayBoxOverlap = true;//btRayAabb(raySource, rayTarget, bounds[0], bounds[1], param, normal);
00660 #endif
00661                 }
00662                 
00663                 if (isLeafNode && rayBoxOverlap)
00664                 {
00665                         nodeCallback->processNode(rootNode->getPartId(),rootNode->getTriangleIndex());
00666                 }
00667                 
00668                 //PCK: unsigned instead of bool
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         //PCK: unsigned instead of bool
00699         unsigned aabbOverlap;
00700 
00701         while (curIndex < endNodeIndex)
00702         {
00703 
00704 //#define VISUALLY_ANALYZE_BVH 1
00705 #ifdef VISUALLY_ANALYZE_BVH
00706                 //some code snippet to debugDraw aabb, to visually analyze bvh structure
00707                 static int drawPatch = 0;
00708                 //need some global access to a debugDrawer
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                 //catch bugs in tree data
00721                 btAssert (walkIterations < subTreeSize);
00722 
00723                 walkIterations++;
00724                 //PCK: unsigned instead of bool
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                 //PCK: unsigned instead of bool
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 //This traversal can be called from Playstation 3 SPU
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                 //PCK: unsigned instead of bool
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         //always use stackless
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                 //recursive traversal
00795                 btVector3 qaabbMin = raySource;
00796                 btVector3 qaabbMax = raySource;
00797                 qaabbMin.setMin(rayTarget);
00798                 qaabbMax.setMax(rayTarget);
00799                 qaabbMin += aabbMin;
00800                 qaabbMax += aabbMax;
00801                 reportAabbOverlappingNodex(nodeCallback,qaabbMin,qaabbMax);
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 //PCK: include
00835 #include <new>
00836 
00837 #if 0
00838 //PCK: consts
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         // I changed this to 0 since the extra padding is not needed or used.
00849         return 0;//BVH_ALIGNMENT_BLOCKS * BVH_ALIGNMENT;
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 /*i_dataBufferSize */, bool i_swapEndian) const
00864 {
00865         btAssert(m_subtreeHeaderCount == m_SubtreeHeaders.size());
00866         m_subtreeHeaderCount = m_SubtreeHeaders.size();
00867 
00868 /*      if (i_dataBufferSize < calculateSerializeBufferSize() || o_alignedDataBuffer == NULL || (((unsigned)o_alignedDataBuffer & BVH_ALIGNMENT_MASK) != 0))
00869         {
00871                 btAssert(0);
00872                 return false;
00873         }
00874 */
00875 
00876         btQuantizedBvh *targetBvh = (btQuantizedBvh *)o_alignedDataBuffer;
00877 
00878         // construct the class so the virtual function table, etc will be set up
00879         // Also, m_leafNodes and m_quantizedLeafNodes will be initialized to default values by the constructor
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;//(BVH_ALIGNMENT-((unsigned)nodeData & BVH_ALIGNMENT_MASK))&BVH_ALIGNMENT_MASK;
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                 // this clears the pointer in the member variable it doesn't really do anything to the data
00954                 // it does call the destructor on the contained objects, but they are all classes with no destructor defined
00955                 // so the memory (which is not freed) is left alone
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                 // this clears the pointer in the member variable it doesn't really do anything to the data
00989                 // it does call the destructor on the contained objects, but they are all classes with no destructor defined
00990                 // so the memory (which is not freed) is left alone
00991                 targetBvh->m_contiguousNodes.initializeFromBuffer(NULL, 0, 0);
00992         }
00993 
00994         sizeToAdd = 0;//(BVH_ALIGNMENT-((unsigned)nodeData & BVH_ALIGNMENT_MASK))&BVH_ALIGNMENT_MASK;
00995         nodeData += sizeToAdd;
00996 
00997         // Now serialize the subtree headers
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                         // need to clear padding in destination buffer
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         // this clears the pointer in the member variable it doesn't really do anything to the data
01039         // it does call the destructor on the contained objects, but they are all classes with no destructor defined
01040         // so the memory (which is not freed) is left alone
01041         targetBvh->m_SubtreeHeaders.initializeFromBuffer(NULL, 0, 0);
01042 
01043         // this wipes the virtual function table pointer at the start of the buffer for the class
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)// || (((unsigned)i_alignedDataBuffer & BVH_ALIGNMENT_MASK) != 0))
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;//(BVH_ALIGNMENT-((unsigned)nodeData & BVH_ALIGNMENT_MASK))&BVH_ALIGNMENT_MASK;
01082         nodeData += sizeToAdd;
01083         
01084         int nodeCount = bvh->m_curNodeIndex;
01085 
01086         // 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
01087         // Also, m_leafNodes and m_quantizedLeafNodes will be initialized to default values by the constructor
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;//(BVH_ALIGNMENT-((unsigned)nodeData & BVH_ALIGNMENT_MASK))&BVH_ALIGNMENT_MASK;
01131         nodeData += sizeToAdd;
01132 
01133         // Now serialize the subtree headers
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 // Constructor that prevents btVector3's default constructor from being called
01156 btQuantizedBvh::btQuantizedBvh(btQuantizedBvh &self, bool /* ownsMemory */) :
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 //      printf("quantizedData->m_numQuantizedContiguousNodes=%d\n",quantizedData->m_numQuantizedContiguousNodes);
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