forked from LeenkxTeam/LNXSDK
		
	
		
			
	
	
		
			1398 lines
		
	
	
		
			50 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
		
		
			
		
	
	
			1398 lines
		
	
	
		
			50 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								Bullet Continuous Collision Detection and Physics Library
							 | 
						||
| 
								 | 
							
								Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								This software is provided 'as-is', without any express or implied warranty.
							 | 
						||
| 
								 | 
							
								In no event will the authors be held liable for any damages arising from the use of this software.
							 | 
						||
| 
								 | 
							
								Permission is granted to anyone to use this software for any purpose, 
							 | 
						||
| 
								 | 
							
								including commercial applications, and to alter it and redistribute it freely, 
							 | 
						||
| 
								 | 
							
								subject to the following restrictions:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								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.
							 | 
						||
| 
								 | 
							
								2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
							 | 
						||
| 
								 | 
							
								3. This notice may not be removed or altered from any source distribution.
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include "btQuantizedBvh.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include "LinearMath/btAabbUtil2.h"
							 | 
						||
| 
								 | 
							
								#include "LinearMath/btIDebugDraw.h"
							 | 
						||
| 
								 | 
							
								#include "LinearMath/btSerializer.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define RAYAABB2
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								btQuantizedBvh::btQuantizedBvh() : 
							 | 
						||
| 
								 | 
							
													m_bulletVersion(BT_BULLET_VERSION),
							 | 
						||
| 
								 | 
							
													m_useQuantization(false), 
							 | 
						||
| 
								 | 
							
													//m_traversalMode(TRAVERSAL_STACKLESS_CACHE_FRIENDLY)
							 | 
						||
| 
								 | 
							
													m_traversalMode(TRAVERSAL_STACKLESS)
							 | 
						||
| 
								 | 
							
													//m_traversalMode(TRAVERSAL_RECURSIVE)
							 | 
						||
| 
								 | 
							
													,m_subtreeHeaderCount(0) //PCK: add this line
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									m_bvhAabbMin.setValue(-SIMD_INFINITY,-SIMD_INFINITY,-SIMD_INFINITY);
							 | 
						||
| 
								 | 
							
									m_bvhAabbMax.setValue(SIMD_INFINITY,SIMD_INFINITY,SIMD_INFINITY);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void btQuantizedBvh::buildInternal()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									///assumes that caller filled in the m_quantizedLeafNodes
							 | 
						||
| 
								 | 
							
									m_useQuantization = true;
							 | 
						||
| 
								 | 
							
									int numLeafNodes = 0;
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									if (m_useQuantization)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										//now we have an array of leafnodes in m_leafNodes
							 | 
						||
| 
								 | 
							
										numLeafNodes = m_quantizedLeafNodes.size();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										m_quantizedContiguousNodes.resize(2*numLeafNodes);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									m_curNodeIndex = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									buildTree(0,numLeafNodes);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									///if the entire tree is small then subtree size, we need to create a header info for the tree
							 | 
						||
| 
								 | 
							
									if(m_useQuantization && !m_SubtreeHeaders.size())
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										btBvhSubtreeInfo& subtree = m_SubtreeHeaders.expand();
							 | 
						||
| 
								 | 
							
										subtree.setAabbFromQuantizeNode(m_quantizedContiguousNodes[0]);
							 | 
						||
| 
								 | 
							
										subtree.m_rootNodeIndex = 0;
							 | 
						||
| 
								 | 
							
										subtree.m_subtreeSize = m_quantizedContiguousNodes[0].isLeafNode() ? 1 : m_quantizedContiguousNodes[0].getEscapeIndex();
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									//PCK: update the copy of the size
							 | 
						||
| 
								 | 
							
									m_subtreeHeaderCount = m_SubtreeHeaders.size();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									//PCK: clear m_quantizedLeafNodes and m_leafNodes, they are temporary
							 | 
						||
| 
								 | 
							
									m_quantizedLeafNodes.clear();
							 | 
						||
| 
								 | 
							
									m_leafNodes.clear();
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								///just for debugging, to visualize the individual patches/subtrees
							 | 
						||
| 
								 | 
							
								#ifdef DEBUG_PATCH_COLORS
							 | 
						||
| 
								 | 
							
								btVector3 color[4]=
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									btVector3(1,0,0),
							 | 
						||
| 
								 | 
							
									btVector3(0,1,0),
							 | 
						||
| 
								 | 
							
									btVector3(0,0,1),
							 | 
						||
| 
								 | 
							
									btVector3(0,1,1)
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								#endif //DEBUG_PATCH_COLORS
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void	btQuantizedBvh::setQuantizationValues(const btVector3& bvhAabbMin,const btVector3& bvhAabbMax,btScalar quantizationMargin)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									//enlarge the AABB to avoid division by zero when initializing the quantization values
							 | 
						||
| 
								 | 
							
									btVector3 clampValue(quantizationMargin,quantizationMargin,quantizationMargin);
							 | 
						||
| 
								 | 
							
									m_bvhAabbMin = bvhAabbMin - clampValue;
							 | 
						||
| 
								 | 
							
									m_bvhAabbMax = bvhAabbMax + clampValue;
							 | 
						||
| 
								 | 
							
									btVector3 aabbSize = m_bvhAabbMax - m_bvhAabbMin;
							 | 
						||
| 
								 | 
							
									m_bvhQuantization = btVector3(btScalar(65533.0),btScalar(65533.0),btScalar(65533.0)) / aabbSize;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									m_useQuantization = true;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										unsigned short vecIn[3];
							 | 
						||
| 
								 | 
							
										btVector3 v;
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											quantize(vecIn,m_bvhAabbMin,false);
							 | 
						||
| 
								 | 
							
											v = unQuantize(vecIn);
							 | 
						||
| 
								 | 
							
											m_bvhAabbMin.setMin(v-clampValue);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								        aabbSize = m_bvhAabbMax - m_bvhAabbMin;
							 | 
						||
| 
								 | 
							
								        m_bvhQuantization = btVector3(btScalar(65533.0),btScalar(65533.0),btScalar(65533.0)) / aabbSize;
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											quantize(vecIn,m_bvhAabbMax,true);
							 | 
						||
| 
								 | 
							
											v = unQuantize(vecIn);
							 | 
						||
| 
								 | 
							
											m_bvhAabbMax.setMax(v+clampValue);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										aabbSize = m_bvhAabbMax - m_bvhAabbMin;
							 | 
						||
| 
								 | 
							
										m_bvhQuantization = btVector3(btScalar(65533.0),btScalar(65533.0),btScalar(65533.0)) / aabbSize;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								btQuantizedBvh::~btQuantizedBvh()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef DEBUG_TREE_BUILDING
							 | 
						||
| 
								 | 
							
								int gStackDepth = 0;
							 | 
						||
| 
								 | 
							
								int gMaxStackDepth = 0;
							 | 
						||
| 
								 | 
							
								#endif //DEBUG_TREE_BUILDING
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void	btQuantizedBvh::buildTree	(int startIndex,int endIndex)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								#ifdef DEBUG_TREE_BUILDING
							 | 
						||
| 
								 | 
							
									gStackDepth++;
							 | 
						||
| 
								 | 
							
									if (gStackDepth > gMaxStackDepth)
							 | 
						||
| 
								 | 
							
										gMaxStackDepth = gStackDepth;
							 | 
						||
| 
								 | 
							
								#endif //DEBUG_TREE_BUILDING
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									int splitAxis, splitIndex, i;
							 | 
						||
| 
								 | 
							
									int numIndices =endIndex-startIndex;
							 | 
						||
| 
								 | 
							
									int curIndex = m_curNodeIndex;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									btAssert(numIndices>0);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if (numIndices==1)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
								#ifdef DEBUG_TREE_BUILDING
							 | 
						||
| 
								 | 
							
										gStackDepth--;
							 | 
						||
| 
								 | 
							
								#endif //DEBUG_TREE_BUILDING
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										assignInternalNodeFromLeafNode(m_curNodeIndex,startIndex);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										m_curNodeIndex++;
							 | 
						||
| 
								 | 
							
										return;	
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									//calculate Best Splitting Axis and where to split it. Sort the incoming 'leafNodes' array within range 'startIndex/endIndex'.
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									splitAxis = calcSplittingAxis(startIndex,endIndex);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									splitIndex = sortAndCalcSplittingIndex(startIndex,endIndex,splitAxis);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									int internalNodeIndex = m_curNodeIndex;
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									//set the min aabb to 'inf' or a max value, and set the max aabb to a -inf/minimum value.
							 | 
						||
| 
								 | 
							
									//the aabb will be expanded during buildTree/mergeInternalNodeAabb with actual node values
							 | 
						||
| 
								 | 
							
									setInternalNodeAabbMin(m_curNodeIndex,m_bvhAabbMax);//can't use btVector3(SIMD_INFINITY,SIMD_INFINITY,SIMD_INFINITY)) because of quantization
							 | 
						||
| 
								 | 
							
									setInternalNodeAabbMax(m_curNodeIndex,m_bvhAabbMin);//can't use btVector3(-SIMD_INFINITY,-SIMD_INFINITY,-SIMD_INFINITY)) because of quantization
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									for (i=startIndex;i<endIndex;i++)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										mergeInternalNodeAabb(m_curNodeIndex,getAabbMin(i),getAabbMax(i));
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									m_curNodeIndex++;
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									//internalNode->m_escapeIndex;
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									int leftChildNodexIndex = m_curNodeIndex;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									//build left child tree
							 | 
						||
| 
								 | 
							
									buildTree(startIndex,splitIndex);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									int rightChildNodexIndex = m_curNodeIndex;
							 | 
						||
| 
								 | 
							
									//build right child tree
							 | 
						||
| 
								 | 
							
									buildTree(splitIndex,endIndex);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef DEBUG_TREE_BUILDING
							 | 
						||
| 
								 | 
							
									gStackDepth--;
							 | 
						||
| 
								 | 
							
								#endif //DEBUG_TREE_BUILDING
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									int escapeIndex = m_curNodeIndex - curIndex;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if (m_useQuantization)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										//escapeIndex is the number of nodes of this subtree
							 | 
						||
| 
								 | 
							
										const int sizeQuantizedNode =sizeof(btQuantizedBvhNode);
							 | 
						||
| 
								 | 
							
										const int treeSizeInBytes = escapeIndex * sizeQuantizedNode;
							 | 
						||
| 
								 | 
							
										if (treeSizeInBytes > MAX_SUBTREE_SIZE_IN_BYTES)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											updateSubtreeHeaders(leftChildNodexIndex,rightChildNodexIndex);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									} else
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									setInternalNodeEscapeIndex(internalNodeIndex,escapeIndex);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void	btQuantizedBvh::updateSubtreeHeaders(int leftChildNodexIndex,int rightChildNodexIndex)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									btAssert(m_useQuantization);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									btQuantizedBvhNode& leftChildNode = m_quantizedContiguousNodes[leftChildNodexIndex];
							 | 
						||
| 
								 | 
							
									int leftSubTreeSize = leftChildNode.isLeafNode() ? 1 : leftChildNode.getEscapeIndex();
							 | 
						||
| 
								 | 
							
									int leftSubTreeSizeInBytes =  leftSubTreeSize * static_cast<int>(sizeof(btQuantizedBvhNode));
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									btQuantizedBvhNode& rightChildNode = m_quantizedContiguousNodes[rightChildNodexIndex];
							 | 
						||
| 
								 | 
							
									int rightSubTreeSize = rightChildNode.isLeafNode() ? 1 : rightChildNode.getEscapeIndex();
							 | 
						||
| 
								 | 
							
									int rightSubTreeSizeInBytes =  rightSubTreeSize *  static_cast<int>(sizeof(btQuantizedBvhNode));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if(leftSubTreeSizeInBytes <= MAX_SUBTREE_SIZE_IN_BYTES)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										btBvhSubtreeInfo& subtree = m_SubtreeHeaders.expand();
							 | 
						||
| 
								 | 
							
										subtree.setAabbFromQuantizeNode(leftChildNode);
							 | 
						||
| 
								 | 
							
										subtree.m_rootNodeIndex = leftChildNodexIndex;
							 | 
						||
| 
								 | 
							
										subtree.m_subtreeSize = leftSubTreeSize;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if(rightSubTreeSizeInBytes <= MAX_SUBTREE_SIZE_IN_BYTES)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										btBvhSubtreeInfo& subtree = m_SubtreeHeaders.expand();
							 | 
						||
| 
								 | 
							
										subtree.setAabbFromQuantizeNode(rightChildNode);
							 | 
						||
| 
								 | 
							
										subtree.m_rootNodeIndex = rightChildNodexIndex;
							 | 
						||
| 
								 | 
							
										subtree.m_subtreeSize = rightSubTreeSize;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									//PCK: update the copy of the size
							 | 
						||
| 
								 | 
							
									m_subtreeHeaderCount = m_SubtreeHeaders.size();
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								int	btQuantizedBvh::sortAndCalcSplittingIndex(int startIndex,int endIndex,int splitAxis)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									int i;
							 | 
						||
| 
								 | 
							
									int splitIndex =startIndex;
							 | 
						||
| 
								 | 
							
									int numIndices = endIndex - startIndex;
							 | 
						||
| 
								 | 
							
									btScalar splitValue;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									btVector3 means(btScalar(0.),btScalar(0.),btScalar(0.));
							 | 
						||
| 
								 | 
							
									for (i=startIndex;i<endIndex;i++)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										btVector3 center = btScalar(0.5)*(getAabbMax(i)+getAabbMin(i));
							 | 
						||
| 
								 | 
							
										means+=center;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									means *= (btScalar(1.)/(btScalar)numIndices);
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									splitValue = means[splitAxis];
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									//sort leafNodes so all values larger then splitValue comes first, and smaller values start from 'splitIndex'.
							 | 
						||
| 
								 | 
							
									for (i=startIndex;i<endIndex;i++)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										btVector3 center = btScalar(0.5)*(getAabbMax(i)+getAabbMin(i));
							 | 
						||
| 
								 | 
							
										if (center[splitAxis] > splitValue)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											//swap
							 | 
						||
| 
								 | 
							
											swapLeafNodes(i,splitIndex);
							 | 
						||
| 
								 | 
							
											splitIndex++;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									//if the splitIndex causes unbalanced trees, fix this by using the center in between startIndex and endIndex
							 | 
						||
| 
								 | 
							
									//otherwise the tree-building might fail due to stack-overflows in certain cases.
							 | 
						||
| 
								 | 
							
									//unbalanced1 is unsafe: it can cause stack overflows
							 | 
						||
| 
								 | 
							
									//bool unbalanced1 = ((splitIndex==startIndex) || (splitIndex == (endIndex-1)));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									//unbalanced2 should work too: always use center (perfect balanced trees)	
							 | 
						||
| 
								 | 
							
									//bool unbalanced2 = true;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									//this should be safe too:
							 | 
						||
| 
								 | 
							
									int rangeBalancedIndices = numIndices/3;
							 | 
						||
| 
								 | 
							
									bool unbalanced = ((splitIndex<=(startIndex+rangeBalancedIndices)) || (splitIndex >=(endIndex-1-rangeBalancedIndices)));
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									if (unbalanced)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										splitIndex = startIndex+ (numIndices>>1);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									bool unbal = (splitIndex==startIndex) || (splitIndex == (endIndex));
							 | 
						||
| 
								 | 
							
									(void)unbal;
							 | 
						||
| 
								 | 
							
									btAssert(!unbal);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return splitIndex;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								int	btQuantizedBvh::calcSplittingAxis(int startIndex,int endIndex)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									int i;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									btVector3 means(btScalar(0.),btScalar(0.),btScalar(0.));
							 | 
						||
| 
								 | 
							
									btVector3 variance(btScalar(0.),btScalar(0.),btScalar(0.));
							 | 
						||
| 
								 | 
							
									int numIndices = endIndex-startIndex;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									for (i=startIndex;i<endIndex;i++)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										btVector3 center = btScalar(0.5)*(getAabbMax(i)+getAabbMin(i));
							 | 
						||
| 
								 | 
							
										means+=center;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									means *= (btScalar(1.)/(btScalar)numIndices);
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
									for (i=startIndex;i<endIndex;i++)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										btVector3 center = btScalar(0.5)*(getAabbMax(i)+getAabbMin(i));
							 | 
						||
| 
								 | 
							
										btVector3 diff2 = center-means;
							 | 
						||
| 
								 | 
							
										diff2 = diff2 * diff2;
							 | 
						||
| 
								 | 
							
										variance += diff2;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									variance *= (btScalar(1.)/	((btScalar)numIndices-1)	);
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									return variance.maxAxis();
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void	btQuantizedBvh::reportAabbOverlappingNodex(btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									//either choose recursive traversal (walkTree) or stackless (walkStacklessTree)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if (m_useQuantization)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										///quantize query AABB
							 | 
						||
| 
								 | 
							
										unsigned short int quantizedQueryAabbMin[3];
							 | 
						||
| 
								 | 
							
										unsigned short int quantizedQueryAabbMax[3];
							 | 
						||
| 
								 | 
							
										quantizeWithClamp(quantizedQueryAabbMin,aabbMin,0);
							 | 
						||
| 
								 | 
							
										quantizeWithClamp(quantizedQueryAabbMax,aabbMax,1);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										switch (m_traversalMode)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
										case TRAVERSAL_STACKLESS:
							 | 
						||
| 
								 | 
							
												walkStacklessQuantizedTree(nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax,0,m_curNodeIndex);
							 | 
						||
| 
								 | 
							
											break;
							 | 
						||
| 
								 | 
							
										case TRAVERSAL_STACKLESS_CACHE_FRIENDLY:
							 | 
						||
| 
								 | 
							
												walkStacklessQuantizedTreeCacheFriendly(nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax);
							 | 
						||
| 
								 | 
							
											break;
							 | 
						||
| 
								 | 
							
										case TRAVERSAL_RECURSIVE:
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												const btQuantizedBvhNode* rootNode = &m_quantizedContiguousNodes[0];
							 | 
						||
| 
								 | 
							
												walkRecursiveQuantizedTreeAgainstQueryAabb(rootNode,nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											break;
							 | 
						||
| 
								 | 
							
										default:
							 | 
						||
| 
								 | 
							
											//unsupported
							 | 
						||
| 
								 | 
							
											btAssert(0);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									} else
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										walkStacklessTree(nodeCallback,aabbMin,aabbMax);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								int maxIterations = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void	btQuantizedBvh::walkStacklessTree(btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									btAssert(!m_useQuantization);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									const btOptimizedBvhNode* rootNode = &m_contiguousNodes[0];
							 | 
						||
| 
								 | 
							
									int escapeIndex, curIndex = 0;
							 | 
						||
| 
								 | 
							
									int walkIterations = 0;
							 | 
						||
| 
								 | 
							
									bool isLeafNode;
							 | 
						||
| 
								 | 
							
									//PCK: unsigned instead of bool
							 | 
						||
| 
								 | 
							
									unsigned aabbOverlap;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									while (curIndex < m_curNodeIndex)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										//catch bugs in tree data
							 | 
						||
| 
								 | 
							
										btAssert (walkIterations < m_curNodeIndex);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										walkIterations++;
							 | 
						||
| 
								 | 
							
										aabbOverlap = TestAabbAgainstAabb2(aabbMin,aabbMax,rootNode->m_aabbMinOrg,rootNode->m_aabbMaxOrg);
							 | 
						||
| 
								 | 
							
										isLeafNode = rootNode->m_escapeIndex == -1;
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										//PCK: unsigned instead of bool
							 | 
						||
| 
								 | 
							
										if (isLeafNode && (aabbOverlap != 0))
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											nodeCallback->processNode(rootNode->m_subPart,rootNode->m_triangleIndex);
							 | 
						||
| 
								 | 
							
										} 
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										//PCK: unsigned instead of bool
							 | 
						||
| 
								 | 
							
										if ((aabbOverlap != 0) || isLeafNode)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											rootNode++;
							 | 
						||
| 
								 | 
							
											curIndex++;
							 | 
						||
| 
								 | 
							
										} else
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											escapeIndex = rootNode->m_escapeIndex;
							 | 
						||
| 
								 | 
							
											rootNode += escapeIndex;
							 | 
						||
| 
								 | 
							
											curIndex += escapeIndex;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if (maxIterations < walkIterations)
							 | 
						||
| 
								 | 
							
										maxIterations = walkIterations;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								///this was the original recursive traversal, before we optimized towards stackless traversal
							 | 
						||
| 
								 | 
							
								void	btQuantizedBvh::walkTree(btOptimizedBvhNode* rootNode,btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									bool isLeafNode, aabbOverlap = TestAabbAgainstAabb2(aabbMin,aabbMax,rootNode->m_aabbMin,rootNode->m_aabbMax);
							 | 
						||
| 
								 | 
							
									if (aabbOverlap)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										isLeafNode = (!rootNode->m_leftChild && !rootNode->m_rightChild);
							 | 
						||
| 
								 | 
							
										if (isLeafNode)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											nodeCallback->processNode(rootNode);
							 | 
						||
| 
								 | 
							
										} else
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											walkTree(rootNode->m_leftChild,nodeCallback,aabbMin,aabbMax);
							 | 
						||
| 
								 | 
							
											walkTree(rootNode->m_rightChild,nodeCallback,aabbMin,aabbMax);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void btQuantizedBvh::walkRecursiveQuantizedTreeAgainstQueryAabb(const btQuantizedBvhNode* currentNode,btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax) const
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									btAssert(m_useQuantization);
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									bool isLeafNode;
							 | 
						||
| 
								 | 
							
									//PCK: unsigned instead of bool
							 | 
						||
| 
								 | 
							
									unsigned aabbOverlap;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									//PCK: unsigned instead of bool
							 | 
						||
| 
								 | 
							
									aabbOverlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,currentNode->m_quantizedAabbMin,currentNode->m_quantizedAabbMax);
							 | 
						||
| 
								 | 
							
									isLeafNode = currentNode->isLeafNode();
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
									//PCK: unsigned instead of bool
							 | 
						||
| 
								 | 
							
									if (aabbOverlap != 0)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										if (isLeafNode)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											nodeCallback->processNode(currentNode->getPartId(),currentNode->getTriangleIndex());
							 | 
						||
| 
								 | 
							
										} else
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											//process left and right children
							 | 
						||
| 
								 | 
							
											const btQuantizedBvhNode* leftChildNode = currentNode+1;
							 | 
						||
| 
								 | 
							
											walkRecursiveQuantizedTreeAgainstQueryAabb(leftChildNode,nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											const btQuantizedBvhNode* rightChildNode = leftChildNode->isLeafNode() ? leftChildNode+1:leftChildNode+leftChildNode->getEscapeIndex();
							 | 
						||
| 
								 | 
							
											walkRecursiveQuantizedTreeAgainstQueryAabb(rightChildNode,nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}		
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void	btQuantizedBvh::walkStacklessTreeAgainstRay(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax, int startNodeIndex,int endNodeIndex) const
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									btAssert(!m_useQuantization);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									const btOptimizedBvhNode* rootNode = &m_contiguousNodes[0];
							 | 
						||
| 
								 | 
							
									int escapeIndex, curIndex = 0;
							 | 
						||
| 
								 | 
							
									int walkIterations = 0;
							 | 
						||
| 
								 | 
							
									bool isLeafNode;
							 | 
						||
| 
								 | 
							
									//PCK: unsigned instead of bool
							 | 
						||
| 
								 | 
							
									unsigned aabbOverlap=0;
							 | 
						||
| 
								 | 
							
									unsigned rayBoxOverlap=0;
							 | 
						||
| 
								 | 
							
									btScalar lambda_max = 1.0;
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
										/* Quick pruning by quantized box */
							 | 
						||
| 
								 | 
							
									btVector3 rayAabbMin = raySource;
							 | 
						||
| 
								 | 
							
									btVector3 rayAabbMax = raySource;
							 | 
						||
| 
								 | 
							
									rayAabbMin.setMin(rayTarget);
							 | 
						||
| 
								 | 
							
									rayAabbMax.setMax(rayTarget);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* Add box cast extents to bounding box */
							 | 
						||
| 
								 | 
							
									rayAabbMin += aabbMin;
							 | 
						||
| 
								 | 
							
									rayAabbMax += aabbMax;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef RAYAABB2
							 | 
						||
| 
								 | 
							
									btVector3 rayDir = (rayTarget-raySource);
							 | 
						||
| 
								 | 
							
									rayDir.normalize ();
							 | 
						||
| 
								 | 
							
									lambda_max = rayDir.dot(rayTarget-raySource);
							 | 
						||
| 
								 | 
							
									///what about division by zero? --> just set rayDirection[i] to 1.0
							 | 
						||
| 
								 | 
							
									btVector3 rayDirectionInverse;
							 | 
						||
| 
								 | 
							
									rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[0];
							 | 
						||
| 
								 | 
							
									rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[1];
							 | 
						||
| 
								 | 
							
									rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[2];
							 | 
						||
| 
								 | 
							
									unsigned int sign[3] = { rayDirectionInverse[0] < 0.0, rayDirectionInverse[1] < 0.0, rayDirectionInverse[2] < 0.0};
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									btVector3 bounds[2];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									while (curIndex < m_curNodeIndex)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										btScalar param = 1.0;
							 | 
						||
| 
								 | 
							
										//catch bugs in tree data
							 | 
						||
| 
								 | 
							
										btAssert (walkIterations < m_curNodeIndex);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										walkIterations++;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										bounds[0] = rootNode->m_aabbMinOrg;
							 | 
						||
| 
								 | 
							
										bounds[1] = rootNode->m_aabbMaxOrg;
							 | 
						||
| 
								 | 
							
										/* Add box cast extents */
							 | 
						||
| 
								 | 
							
										bounds[0] -= aabbMax;
							 | 
						||
| 
								 | 
							
										bounds[1] -= aabbMin;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										aabbOverlap = TestAabbAgainstAabb2(rayAabbMin,rayAabbMax,rootNode->m_aabbMinOrg,rootNode->m_aabbMaxOrg);
							 | 
						||
| 
								 | 
							
										//perhaps profile if it is worth doing the aabbOverlap test first
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef RAYAABB2
							 | 
						||
| 
								 | 
							
											///careful with this check: need to check division by zero (above) and fix the unQuantize method
							 | 
						||
| 
								 | 
							
											///thanks Joerg/hiker for the reproduction case!
							 | 
						||
| 
								 | 
							
											///http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=1858
							 | 
						||
| 
								 | 
							
										rayBoxOverlap = aabbOverlap ? btRayAabb2 (raySource, rayDirectionInverse, sign, bounds, param, 0.0f, lambda_max) : false;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
										btVector3 normal;
							 | 
						||
| 
								 | 
							
										rayBoxOverlap = btRayAabb(raySource, rayTarget,bounds[0],bounds[1],param, normal);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										isLeafNode = rootNode->m_escapeIndex == -1;
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										//PCK: unsigned instead of bool
							 | 
						||
| 
								 | 
							
										if (isLeafNode && (rayBoxOverlap != 0))
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											nodeCallback->processNode(rootNode->m_subPart,rootNode->m_triangleIndex);
							 | 
						||
| 
								 | 
							
										} 
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										//PCK: unsigned instead of bool
							 | 
						||
| 
								 | 
							
										if ((rayBoxOverlap != 0) || isLeafNode)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											rootNode++;
							 | 
						||
| 
								 | 
							
											curIndex++;
							 | 
						||
| 
								 | 
							
										} else
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											escapeIndex = rootNode->m_escapeIndex;
							 | 
						||
| 
								 | 
							
											rootNode += escapeIndex;
							 | 
						||
| 
								 | 
							
											curIndex += escapeIndex;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if (maxIterations < walkIterations)
							 | 
						||
| 
								 | 
							
										maxIterations = walkIterations;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void	btQuantizedBvh::walkStacklessQuantizedTreeAgainstRay(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax, int startNodeIndex,int endNodeIndex) const
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									btAssert(m_useQuantization);
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									int curIndex = startNodeIndex;
							 | 
						||
| 
								 | 
							
									int walkIterations = 0;
							 | 
						||
| 
								 | 
							
									int subTreeSize = endNodeIndex - startNodeIndex;
							 | 
						||
| 
								 | 
							
									(void)subTreeSize;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									const btQuantizedBvhNode* rootNode = &m_quantizedContiguousNodes[startNodeIndex];
							 | 
						||
| 
								 | 
							
									int escapeIndex;
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									bool isLeafNode;
							 | 
						||
| 
								 | 
							
									//PCK: unsigned instead of bool
							 | 
						||
| 
								 | 
							
									unsigned boxBoxOverlap = 0;
							 | 
						||
| 
								 | 
							
									unsigned rayBoxOverlap = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									btScalar lambda_max = 1.0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef RAYAABB2
							 | 
						||
| 
								 | 
							
									btVector3 rayDirection = (rayTarget-raySource);
							 | 
						||
| 
								 | 
							
									rayDirection.normalize ();
							 | 
						||
| 
								 | 
							
									lambda_max = rayDirection.dot(rayTarget-raySource);
							 | 
						||
| 
								 | 
							
									///what about division by zero? --> just set rayDirection[i] to 1.0
							 | 
						||
| 
								 | 
							
									rayDirection[0] = rayDirection[0] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDirection[0];
							 | 
						||
| 
								 | 
							
									rayDirection[1] = rayDirection[1] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDirection[1];
							 | 
						||
| 
								 | 
							
									rayDirection[2] = rayDirection[2] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDirection[2];
							 | 
						||
| 
								 | 
							
									unsigned int sign[3] = { rayDirection[0] < 0.0, rayDirection[1] < 0.0, rayDirection[2] < 0.0};
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* Quick pruning by quantized box */
							 | 
						||
| 
								 | 
							
									btVector3 rayAabbMin = raySource;
							 | 
						||
| 
								 | 
							
									btVector3 rayAabbMax = raySource;
							 | 
						||
| 
								 | 
							
									rayAabbMin.setMin(rayTarget);
							 | 
						||
| 
								 | 
							
									rayAabbMax.setMax(rayTarget);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* Add box cast extents to bounding box */
							 | 
						||
| 
								 | 
							
									rayAabbMin += aabbMin;
							 | 
						||
| 
								 | 
							
									rayAabbMax += aabbMax;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									unsigned short int quantizedQueryAabbMin[3];
							 | 
						||
| 
								 | 
							
									unsigned short int quantizedQueryAabbMax[3];
							 | 
						||
| 
								 | 
							
									quantizeWithClamp(quantizedQueryAabbMin,rayAabbMin,0);
							 | 
						||
| 
								 | 
							
									quantizeWithClamp(quantizedQueryAabbMax,rayAabbMax,1);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									while (curIndex < endNodeIndex)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//#define VISUALLY_ANALYZE_BVH 1
							 | 
						||
| 
								 | 
							
								#ifdef VISUALLY_ANALYZE_BVH
							 | 
						||
| 
								 | 
							
										//some code snippet to debugDraw aabb, to visually analyze bvh structure
							 | 
						||
| 
								 | 
							
										static int drawPatch = 0;
							 | 
						||
| 
								 | 
							
										//need some global access to a debugDrawer
							 | 
						||
| 
								 | 
							
										extern btIDebugDraw* debugDrawerPtr;
							 | 
						||
| 
								 | 
							
										if (curIndex==drawPatch)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											btVector3 aabbMin,aabbMax;
							 | 
						||
| 
								 | 
							
											aabbMin = unQuantize(rootNode->m_quantizedAabbMin);
							 | 
						||
| 
								 | 
							
											aabbMax = unQuantize(rootNode->m_quantizedAabbMax);
							 | 
						||
| 
								 | 
							
											btVector3	color(1,0,0);
							 | 
						||
| 
								 | 
							
											debugDrawerPtr->drawAabb(aabbMin,aabbMax,color);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								#endif//VISUALLY_ANALYZE_BVH
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										//catch bugs in tree data
							 | 
						||
| 
								 | 
							
										btAssert (walkIterations < subTreeSize);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										walkIterations++;
							 | 
						||
| 
								 | 
							
										//PCK: unsigned instead of bool
							 | 
						||
| 
								 | 
							
										// only interested if this is closer than any previous hit
							 | 
						||
| 
								 | 
							
										btScalar param = 1.0;
							 | 
						||
| 
								 | 
							
										rayBoxOverlap = 0;
							 | 
						||
| 
								 | 
							
										boxBoxOverlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,rootNode->m_quantizedAabbMin,rootNode->m_quantizedAabbMax);
							 | 
						||
| 
								 | 
							
										isLeafNode = rootNode->isLeafNode();
							 | 
						||
| 
								 | 
							
										if (boxBoxOverlap)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											btVector3 bounds[2];
							 | 
						||
| 
								 | 
							
											bounds[0] = unQuantize(rootNode->m_quantizedAabbMin);
							 | 
						||
| 
								 | 
							
											bounds[1] = unQuantize(rootNode->m_quantizedAabbMax);
							 | 
						||
| 
								 | 
							
											/* Add box cast extents */
							 | 
						||
| 
								 | 
							
											bounds[0] -= aabbMax;
							 | 
						||
| 
								 | 
							
											bounds[1] -= aabbMin;
							 | 
						||
| 
								 | 
							
											btVector3 normal;
							 | 
						||
| 
								 | 
							
								#if 0
							 | 
						||
| 
								 | 
							
											bool ra2 = btRayAabb2 (raySource, rayDirection, sign, bounds, param, 0.0, lambda_max);
							 | 
						||
| 
								 | 
							
											bool ra = btRayAabb (raySource, rayTarget, bounds[0], bounds[1], param, normal);
							 | 
						||
| 
								 | 
							
											if (ra2 != ra)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												printf("functions don't match\n");
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								#ifdef RAYAABB2
							 | 
						||
| 
								 | 
							
											///careful with this check: need to check division by zero (above) and fix the unQuantize method
							 | 
						||
| 
								 | 
							
											///thanks Joerg/hiker for the reproduction case!
							 | 
						||
| 
								 | 
							
											///http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=1858
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											//BT_PROFILE("btRayAabb2");
							 | 
						||
| 
								 | 
							
											rayBoxOverlap = btRayAabb2 (raySource, rayDirection, sign, bounds, param, 0.0f, lambda_max);
							 | 
						||
| 
								 | 
							
											
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
											rayBoxOverlap = true;//btRayAabb(raySource, rayTarget, bounds[0], bounds[1], param, normal);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										if (isLeafNode && rayBoxOverlap)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											nodeCallback->processNode(rootNode->getPartId(),rootNode->getTriangleIndex());
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										//PCK: unsigned instead of bool
							 | 
						||
| 
								 | 
							
										if ((rayBoxOverlap != 0) || isLeafNode)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											rootNode++;
							 | 
						||
| 
								 | 
							
											curIndex++;
							 | 
						||
| 
								 | 
							
										} else
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											escapeIndex = rootNode->getEscapeIndex();
							 | 
						||
| 
								 | 
							
											rootNode += escapeIndex;
							 | 
						||
| 
								 | 
							
											curIndex += escapeIndex;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if (maxIterations < walkIterations)
							 | 
						||
| 
								 | 
							
										maxIterations = walkIterations;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void	btQuantizedBvh::walkStacklessQuantizedTree(btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax,int startNodeIndex,int endNodeIndex) const
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									btAssert(m_useQuantization);
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									int curIndex = startNodeIndex;
							 | 
						||
| 
								 | 
							
									int walkIterations = 0;
							 | 
						||
| 
								 | 
							
									int subTreeSize = endNodeIndex - startNodeIndex;
							 | 
						||
| 
								 | 
							
									(void)subTreeSize;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									const btQuantizedBvhNode* rootNode = &m_quantizedContiguousNodes[startNodeIndex];
							 | 
						||
| 
								 | 
							
									int escapeIndex;
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									bool isLeafNode;
							 | 
						||
| 
								 | 
							
									//PCK: unsigned instead of bool
							 | 
						||
| 
								 | 
							
									unsigned aabbOverlap;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									while (curIndex < endNodeIndex)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//#define VISUALLY_ANALYZE_BVH 1
							 | 
						||
| 
								 | 
							
								#ifdef VISUALLY_ANALYZE_BVH
							 | 
						||
| 
								 | 
							
										//some code snippet to debugDraw aabb, to visually analyze bvh structure
							 | 
						||
| 
								 | 
							
										static int drawPatch = 0;
							 | 
						||
| 
								 | 
							
										//need some global access to a debugDrawer
							 | 
						||
| 
								 | 
							
										extern btIDebugDraw* debugDrawerPtr;
							 | 
						||
| 
								 | 
							
										if (curIndex==drawPatch)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											btVector3 aabbMin,aabbMax;
							 | 
						||
| 
								 | 
							
											aabbMin = unQuantize(rootNode->m_quantizedAabbMin);
							 | 
						||
| 
								 | 
							
											aabbMax = unQuantize(rootNode->m_quantizedAabbMax);
							 | 
						||
| 
								 | 
							
											btVector3	color(1,0,0);
							 | 
						||
| 
								 | 
							
											debugDrawerPtr->drawAabb(aabbMin,aabbMax,color);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								#endif//VISUALLY_ANALYZE_BVH
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										//catch bugs in tree data
							 | 
						||
| 
								 | 
							
										btAssert (walkIterations < subTreeSize);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										walkIterations++;
							 | 
						||
| 
								 | 
							
										//PCK: unsigned instead of bool
							 | 
						||
| 
								 | 
							
										aabbOverlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,rootNode->m_quantizedAabbMin,rootNode->m_quantizedAabbMax);
							 | 
						||
| 
								 | 
							
										isLeafNode = rootNode->isLeafNode();
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										if (isLeafNode && aabbOverlap)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											nodeCallback->processNode(rootNode->getPartId(),rootNode->getTriangleIndex());
							 | 
						||
| 
								 | 
							
										} 
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										//PCK: unsigned instead of bool
							 | 
						||
| 
								 | 
							
										if ((aabbOverlap != 0) || isLeafNode)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											rootNode++;
							 | 
						||
| 
								 | 
							
											curIndex++;
							 | 
						||
| 
								 | 
							
										} else
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											escapeIndex = rootNode->getEscapeIndex();
							 | 
						||
| 
								 | 
							
											rootNode += escapeIndex;
							 | 
						||
| 
								 | 
							
											curIndex += escapeIndex;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if (maxIterations < walkIterations)
							 | 
						||
| 
								 | 
							
										maxIterations = walkIterations;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//This traversal can be called from Playstation 3 SPU
							 | 
						||
| 
								 | 
							
								void	btQuantizedBvh::walkStacklessQuantizedTreeCacheFriendly(btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax) const
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									btAssert(m_useQuantization);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									int i;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									for (i=0;i<this->m_SubtreeHeaders.size();i++)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										const btBvhSubtreeInfo& subtree = m_SubtreeHeaders[i];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										//PCK: unsigned instead of bool
							 | 
						||
| 
								 | 
							
										unsigned overlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,subtree.m_quantizedAabbMin,subtree.m_quantizedAabbMax);
							 | 
						||
| 
								 | 
							
										if (overlap != 0)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											walkStacklessQuantizedTree(nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax,
							 | 
						||
| 
								 | 
							
												subtree.m_rootNodeIndex,
							 | 
						||
| 
								 | 
							
												subtree.m_rootNodeIndex+subtree.m_subtreeSize);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void	btQuantizedBvh::reportRayOverlappingNodex (btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget) const
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									reportBoxCastOverlappingNodex(nodeCallback,raySource,rayTarget,btVector3(0,0,0),btVector3(0,0,0));
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void	btQuantizedBvh::reportBoxCastOverlappingNodex(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin,const btVector3& aabbMax) const
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									//always use stackless
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if (m_useQuantization)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										walkStacklessQuantizedTreeAgainstRay(nodeCallback, raySource, rayTarget, aabbMin, aabbMax, 0, m_curNodeIndex);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										walkStacklessTreeAgainstRay(nodeCallback, raySource, rayTarget, aabbMin, aabbMax, 0, m_curNodeIndex);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									/*
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										//recursive traversal
							 | 
						||
| 
								 | 
							
										btVector3 qaabbMin = raySource;
							 | 
						||
| 
								 | 
							
										btVector3 qaabbMax = raySource;
							 | 
						||
| 
								 | 
							
										qaabbMin.setMin(rayTarget);
							 | 
						||
| 
								 | 
							
										qaabbMax.setMax(rayTarget);
							 | 
						||
| 
								 | 
							
										qaabbMin += aabbMin;
							 | 
						||
| 
								 | 
							
										qaabbMax += aabbMax;
							 | 
						||
| 
								 | 
							
										reportAabbOverlappingNodex(nodeCallback,qaabbMin,qaabbMax);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void	btQuantizedBvh::swapLeafNodes(int i,int splitIndex)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									if (m_useQuantization)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
											btQuantizedBvhNode tmp = m_quantizedLeafNodes[i];
							 | 
						||
| 
								 | 
							
											m_quantizedLeafNodes[i] = m_quantizedLeafNodes[splitIndex];
							 | 
						||
| 
								 | 
							
											m_quantizedLeafNodes[splitIndex] = tmp;
							 | 
						||
| 
								 | 
							
									} else
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
											btOptimizedBvhNode tmp = m_leafNodes[i];
							 | 
						||
| 
								 | 
							
											m_leafNodes[i] = m_leafNodes[splitIndex];
							 | 
						||
| 
								 | 
							
											m_leafNodes[splitIndex] = tmp;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void	btQuantizedBvh::assignInternalNodeFromLeafNode(int internalNode,int leafNodeIndex)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									if (m_useQuantization)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										m_quantizedContiguousNodes[internalNode] = m_quantizedLeafNodes[leafNodeIndex];
							 | 
						||
| 
								 | 
							
									} else
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										m_contiguousNodes[internalNode] = m_leafNodes[leafNodeIndex];
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//PCK: include
							 | 
						||
| 
								 | 
							
								#include <new>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if 0
							 | 
						||
| 
								 | 
							
								//PCK: consts
							 | 
						||
| 
								 | 
							
								static const unsigned BVH_ALIGNMENT = 16;
							 | 
						||
| 
								 | 
							
								static const unsigned BVH_ALIGNMENT_MASK = BVH_ALIGNMENT-1;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static const unsigned BVH_ALIGNMENT_BLOCKS = 2;
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								unsigned int btQuantizedBvh::getAlignmentSerializationPadding()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									// I changed this to 0 since the extra padding is not needed or used.
							 | 
						||
| 
								 | 
							
									return 0;//BVH_ALIGNMENT_BLOCKS * BVH_ALIGNMENT;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								unsigned btQuantizedBvh::calculateSerializeBufferSize() const
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									unsigned baseSize = sizeof(btQuantizedBvh) + getAlignmentSerializationPadding();
							 | 
						||
| 
								 | 
							
									baseSize += sizeof(btBvhSubtreeInfo) * m_subtreeHeaderCount;
							 | 
						||
| 
								 | 
							
									if (m_useQuantization)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										return baseSize + m_curNodeIndex * sizeof(btQuantizedBvhNode);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return baseSize + m_curNodeIndex * sizeof(btOptimizedBvhNode);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								bool btQuantizedBvh::serialize(void *o_alignedDataBuffer, unsigned /*i_dataBufferSize */, bool i_swapEndian) const
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									btAssert(m_subtreeHeaderCount == m_SubtreeHeaders.size());
							 | 
						||
| 
								 | 
							
									m_subtreeHeaderCount = m_SubtreeHeaders.size();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*	if (i_dataBufferSize < calculateSerializeBufferSize() || o_alignedDataBuffer == NULL || (((unsigned)o_alignedDataBuffer & BVH_ALIGNMENT_MASK) != 0))
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										///check alignedment for buffer?
							 | 
						||
| 
								 | 
							
										btAssert(0);
							 | 
						||
| 
								 | 
							
										return false;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									btQuantizedBvh *targetBvh = (btQuantizedBvh *)o_alignedDataBuffer;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// construct the class so the virtual function table, etc will be set up
							 | 
						||
| 
								 | 
							
									// Also, m_leafNodes and m_quantizedLeafNodes will be initialized to default values by the constructor
							 | 
						||
| 
								 | 
							
									new (targetBvh) btQuantizedBvh;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if (i_swapEndian)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										targetBvh->m_curNodeIndex = static_cast<int>(btSwapEndian(m_curNodeIndex));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										btSwapVector3Endian(m_bvhAabbMin,targetBvh->m_bvhAabbMin);
							 | 
						||
| 
								 | 
							
										btSwapVector3Endian(m_bvhAabbMax,targetBvh->m_bvhAabbMax);
							 | 
						||
| 
								 | 
							
										btSwapVector3Endian(m_bvhQuantization,targetBvh->m_bvhQuantization);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										targetBvh->m_traversalMode = (btTraversalMode)btSwapEndian(m_traversalMode);
							 | 
						||
| 
								 | 
							
										targetBvh->m_subtreeHeaderCount = static_cast<int>(btSwapEndian(m_subtreeHeaderCount));
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										targetBvh->m_curNodeIndex = m_curNodeIndex;
							 | 
						||
| 
								 | 
							
										targetBvh->m_bvhAabbMin = m_bvhAabbMin;
							 | 
						||
| 
								 | 
							
										targetBvh->m_bvhAabbMax = m_bvhAabbMax;
							 | 
						||
| 
								 | 
							
										targetBvh->m_bvhQuantization = m_bvhQuantization;
							 | 
						||
| 
								 | 
							
										targetBvh->m_traversalMode = m_traversalMode;
							 | 
						||
| 
								 | 
							
										targetBvh->m_subtreeHeaderCount = m_subtreeHeaderCount;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									targetBvh->m_useQuantization = m_useQuantization;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									unsigned char *nodeData = (unsigned char *)targetBvh;
							 | 
						||
| 
								 | 
							
									nodeData += sizeof(btQuantizedBvh);
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									unsigned sizeToAdd = 0;//(BVH_ALIGNMENT-((unsigned)nodeData & BVH_ALIGNMENT_MASK))&BVH_ALIGNMENT_MASK;
							 | 
						||
| 
								 | 
							
									nodeData += sizeToAdd;
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									int nodeCount = m_curNodeIndex;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if (m_useQuantization)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										targetBvh->m_quantizedContiguousNodes.initializeFromBuffer(nodeData, nodeCount, nodeCount);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if (i_swapEndian)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0] = btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0]);
							 | 
						||
| 
								 | 
							
												targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[1] = btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[1]);
							 | 
						||
| 
								 | 
							
												targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[2] = btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[2]);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0] = btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0]);
							 | 
						||
| 
								 | 
							
												targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[1] = btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[1]);
							 | 
						||
| 
								 | 
							
												targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[2] = btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[2]);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												targetBvh->m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex = static_cast<int>(btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex));
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
												targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0];
							 | 
						||
| 
								 | 
							
												targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[1] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[1];
							 | 
						||
| 
								 | 
							
												targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[2] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[2];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0];
							 | 
						||
| 
								 | 
							
												targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[1] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[1];
							 | 
						||
| 
								 | 
							
												targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[2] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[2];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												targetBvh->m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex = m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										nodeData += sizeof(btQuantizedBvhNode) * nodeCount;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// this clears the pointer in the member variable it doesn't really do anything to the data
							 | 
						||
| 
								 | 
							
										// it does call the destructor on the contained objects, but they are all classes with no destructor defined
							 | 
						||
| 
								 | 
							
										// so the memory (which is not freed) is left alone
							 | 
						||
| 
								 | 
							
										targetBvh->m_quantizedContiguousNodes.initializeFromBuffer(NULL, 0, 0);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										targetBvh->m_contiguousNodes.initializeFromBuffer(nodeData, nodeCount, nodeCount);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if (i_swapEndian)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												btSwapVector3Endian(m_contiguousNodes[nodeIndex].m_aabbMinOrg, targetBvh->m_contiguousNodes[nodeIndex].m_aabbMinOrg);
							 | 
						||
| 
								 | 
							
												btSwapVector3Endian(m_contiguousNodes[nodeIndex].m_aabbMaxOrg, targetBvh->m_contiguousNodes[nodeIndex].m_aabbMaxOrg);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												targetBvh->m_contiguousNodes[nodeIndex].m_escapeIndex = static_cast<int>(btSwapEndian(m_contiguousNodes[nodeIndex].m_escapeIndex));
							 | 
						||
| 
								 | 
							
												targetBvh->m_contiguousNodes[nodeIndex].m_subPart = static_cast<int>(btSwapEndian(m_contiguousNodes[nodeIndex].m_subPart));
							 | 
						||
| 
								 | 
							
												targetBvh->m_contiguousNodes[nodeIndex].m_triangleIndex = static_cast<int>(btSwapEndian(m_contiguousNodes[nodeIndex].m_triangleIndex));
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												targetBvh->m_contiguousNodes[nodeIndex].m_aabbMinOrg = m_contiguousNodes[nodeIndex].m_aabbMinOrg;
							 | 
						||
| 
								 | 
							
												targetBvh->m_contiguousNodes[nodeIndex].m_aabbMaxOrg = m_contiguousNodes[nodeIndex].m_aabbMaxOrg;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												targetBvh->m_contiguousNodes[nodeIndex].m_escapeIndex = m_contiguousNodes[nodeIndex].m_escapeIndex;
							 | 
						||
| 
								 | 
							
												targetBvh->m_contiguousNodes[nodeIndex].m_subPart = m_contiguousNodes[nodeIndex].m_subPart;
							 | 
						||
| 
								 | 
							
												targetBvh->m_contiguousNodes[nodeIndex].m_triangleIndex = m_contiguousNodes[nodeIndex].m_triangleIndex;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										nodeData += sizeof(btOptimizedBvhNode) * nodeCount;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// this clears the pointer in the member variable it doesn't really do anything to the data
							 | 
						||
| 
								 | 
							
										// it does call the destructor on the contained objects, but they are all classes with no destructor defined
							 | 
						||
| 
								 | 
							
										// so the memory (which is not freed) is left alone
							 | 
						||
| 
								 | 
							
										targetBvh->m_contiguousNodes.initializeFromBuffer(NULL, 0, 0);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									sizeToAdd = 0;//(BVH_ALIGNMENT-((unsigned)nodeData & BVH_ALIGNMENT_MASK))&BVH_ALIGNMENT_MASK;
							 | 
						||
| 
								 | 
							
									nodeData += sizeToAdd;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// Now serialize the subtree headers
							 | 
						||
| 
								 | 
							
									targetBvh->m_SubtreeHeaders.initializeFromBuffer(nodeData, m_subtreeHeaderCount, m_subtreeHeaderCount);
							 | 
						||
| 
								 | 
							
									if (i_swapEndian)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										for (int i = 0; i < m_subtreeHeaderCount; i++)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMin[0] = btSwapEndian(m_SubtreeHeaders[i].m_quantizedAabbMin[0]);
							 | 
						||
| 
								 | 
							
											targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMin[1] = btSwapEndian(m_SubtreeHeaders[i].m_quantizedAabbMin[1]);
							 | 
						||
| 
								 | 
							
											targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMin[2] = btSwapEndian(m_SubtreeHeaders[i].m_quantizedAabbMin[2]);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMax[0] = btSwapEndian(m_SubtreeHeaders[i].m_quantizedAabbMax[0]);
							 | 
						||
| 
								 | 
							
											targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMax[1] = btSwapEndian(m_SubtreeHeaders[i].m_quantizedAabbMax[1]);
							 | 
						||
| 
								 | 
							
											targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMax[2] = btSwapEndian(m_SubtreeHeaders[i].m_quantizedAabbMax[2]);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											targetBvh->m_SubtreeHeaders[i].m_rootNodeIndex = static_cast<int>(btSwapEndian(m_SubtreeHeaders[i].m_rootNodeIndex));
							 | 
						||
| 
								 | 
							
											targetBvh->m_SubtreeHeaders[i].m_subtreeSize = static_cast<int>(btSwapEndian(m_SubtreeHeaders[i].m_subtreeSize));
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										for (int i = 0; i < m_subtreeHeaderCount; i++)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMin[0] = (m_SubtreeHeaders[i].m_quantizedAabbMin[0]);
							 | 
						||
| 
								 | 
							
											targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMin[1] = (m_SubtreeHeaders[i].m_quantizedAabbMin[1]);
							 | 
						||
| 
								 | 
							
											targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMin[2] = (m_SubtreeHeaders[i].m_quantizedAabbMin[2]);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMax[0] = (m_SubtreeHeaders[i].m_quantizedAabbMax[0]);
							 | 
						||
| 
								 | 
							
											targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMax[1] = (m_SubtreeHeaders[i].m_quantizedAabbMax[1]);
							 | 
						||
| 
								 | 
							
											targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMax[2] = (m_SubtreeHeaders[i].m_quantizedAabbMax[2]);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											targetBvh->m_SubtreeHeaders[i].m_rootNodeIndex = (m_SubtreeHeaders[i].m_rootNodeIndex);
							 | 
						||
| 
								 | 
							
											targetBvh->m_SubtreeHeaders[i].m_subtreeSize = (m_SubtreeHeaders[i].m_subtreeSize);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											// need to clear padding in destination buffer
							 | 
						||
| 
								 | 
							
											targetBvh->m_SubtreeHeaders[i].m_padding[0] = 0;
							 | 
						||
| 
								 | 
							
											targetBvh->m_SubtreeHeaders[i].m_padding[1] = 0;
							 | 
						||
| 
								 | 
							
											targetBvh->m_SubtreeHeaders[i].m_padding[2] = 0;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									nodeData += sizeof(btBvhSubtreeInfo) * m_subtreeHeaderCount;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// this clears the pointer in the member variable it doesn't really do anything to the data
							 | 
						||
| 
								 | 
							
									// it does call the destructor on the contained objects, but they are all classes with no destructor defined
							 | 
						||
| 
								 | 
							
									// so the memory (which is not freed) is left alone
							 | 
						||
| 
								 | 
							
									targetBvh->m_SubtreeHeaders.initializeFromBuffer(NULL, 0, 0);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// this wipes the virtual function table pointer at the start of the buffer for the class
							 | 
						||
| 
								 | 
							
									*((void**)o_alignedDataBuffer) = NULL;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return true;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								btQuantizedBvh *btQuantizedBvh::deSerializeInPlace(void *i_alignedDataBuffer, unsigned int i_dataBufferSize, bool i_swapEndian)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if (i_alignedDataBuffer == NULL)// || (((unsigned)i_alignedDataBuffer & BVH_ALIGNMENT_MASK) != 0))
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										return NULL;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									btQuantizedBvh *bvh = (btQuantizedBvh *)i_alignedDataBuffer;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if (i_swapEndian)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										bvh->m_curNodeIndex = static_cast<int>(btSwapEndian(bvh->m_curNodeIndex));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										btUnSwapVector3Endian(bvh->m_bvhAabbMin);
							 | 
						||
| 
								 | 
							
										btUnSwapVector3Endian(bvh->m_bvhAabbMax);
							 | 
						||
| 
								 | 
							
										btUnSwapVector3Endian(bvh->m_bvhQuantization);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										bvh->m_traversalMode = (btTraversalMode)btSwapEndian(bvh->m_traversalMode);
							 | 
						||
| 
								 | 
							
										bvh->m_subtreeHeaderCount = static_cast<int>(btSwapEndian(bvh->m_subtreeHeaderCount));
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									unsigned int calculatedBufSize = bvh->calculateSerializeBufferSize();
							 | 
						||
| 
								 | 
							
									btAssert(calculatedBufSize <= i_dataBufferSize);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if (calculatedBufSize > i_dataBufferSize)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										return NULL;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									unsigned char *nodeData = (unsigned char *)bvh;
							 | 
						||
| 
								 | 
							
									nodeData += sizeof(btQuantizedBvh);
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									unsigned sizeToAdd = 0;//(BVH_ALIGNMENT-((unsigned)nodeData & BVH_ALIGNMENT_MASK))&BVH_ALIGNMENT_MASK;
							 | 
						||
| 
								 | 
							
									nodeData += sizeToAdd;
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									int nodeCount = bvh->m_curNodeIndex;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// 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
							 | 
						||
| 
								 | 
							
									// Also, m_leafNodes and m_quantizedLeafNodes will be initialized to default values by the constructor
							 | 
						||
| 
								 | 
							
									new (bvh) btQuantizedBvh(*bvh, false);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if (bvh->m_useQuantization)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										bvh->m_quantizedContiguousNodes.initializeFromBuffer(nodeData, nodeCount, nodeCount);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if (i_swapEndian)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0] = btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0]);
							 | 
						||
| 
								 | 
							
												bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[1] = btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[1]);
							 | 
						||
| 
								 | 
							
												bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[2] = btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[2]);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0] = btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0]);
							 | 
						||
| 
								 | 
							
												bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[1] = btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[1]);
							 | 
						||
| 
								 | 
							
												bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[2] = btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[2]);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												bvh->m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex = static_cast<int>(btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex));
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										nodeData += sizeof(btQuantizedBvhNode) * nodeCount;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										bvh->m_contiguousNodes.initializeFromBuffer(nodeData, nodeCount, nodeCount);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if (i_swapEndian)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												btUnSwapVector3Endian(bvh->m_contiguousNodes[nodeIndex].m_aabbMinOrg);
							 | 
						||
| 
								 | 
							
												btUnSwapVector3Endian(bvh->m_contiguousNodes[nodeIndex].m_aabbMaxOrg);
							 | 
						||
| 
								 | 
							
												
							 | 
						||
| 
								 | 
							
												bvh->m_contiguousNodes[nodeIndex].m_escapeIndex = static_cast<int>(btSwapEndian(bvh->m_contiguousNodes[nodeIndex].m_escapeIndex));
							 | 
						||
| 
								 | 
							
												bvh->m_contiguousNodes[nodeIndex].m_subPart = static_cast<int>(btSwapEndian(bvh->m_contiguousNodes[nodeIndex].m_subPart));
							 | 
						||
| 
								 | 
							
												bvh->m_contiguousNodes[nodeIndex].m_triangleIndex = static_cast<int>(btSwapEndian(bvh->m_contiguousNodes[nodeIndex].m_triangleIndex));
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										nodeData += sizeof(btOptimizedBvhNode) * nodeCount;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									sizeToAdd = 0;//(BVH_ALIGNMENT-((unsigned)nodeData & BVH_ALIGNMENT_MASK))&BVH_ALIGNMENT_MASK;
							 | 
						||
| 
								 | 
							
									nodeData += sizeToAdd;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// Now serialize the subtree headers
							 | 
						||
| 
								 | 
							
									bvh->m_SubtreeHeaders.initializeFromBuffer(nodeData, bvh->m_subtreeHeaderCount, bvh->m_subtreeHeaderCount);
							 | 
						||
| 
								 | 
							
									if (i_swapEndian)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										for (int i = 0; i < bvh->m_subtreeHeaderCount; i++)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											bvh->m_SubtreeHeaders[i].m_quantizedAabbMin[0] = btSwapEndian(bvh->m_SubtreeHeaders[i].m_quantizedAabbMin[0]);
							 | 
						||
| 
								 | 
							
											bvh->m_SubtreeHeaders[i].m_quantizedAabbMin[1] = btSwapEndian(bvh->m_SubtreeHeaders[i].m_quantizedAabbMin[1]);
							 | 
						||
| 
								 | 
							
											bvh->m_SubtreeHeaders[i].m_quantizedAabbMin[2] = btSwapEndian(bvh->m_SubtreeHeaders[i].m_quantizedAabbMin[2]);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											bvh->m_SubtreeHeaders[i].m_quantizedAabbMax[0] = btSwapEndian(bvh->m_SubtreeHeaders[i].m_quantizedAabbMax[0]);
							 | 
						||
| 
								 | 
							
											bvh->m_SubtreeHeaders[i].m_quantizedAabbMax[1] = btSwapEndian(bvh->m_SubtreeHeaders[i].m_quantizedAabbMax[1]);
							 | 
						||
| 
								 | 
							
											bvh->m_SubtreeHeaders[i].m_quantizedAabbMax[2] = btSwapEndian(bvh->m_SubtreeHeaders[i].m_quantizedAabbMax[2]);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											bvh->m_SubtreeHeaders[i].m_rootNodeIndex = static_cast<int>(btSwapEndian(bvh->m_SubtreeHeaders[i].m_rootNodeIndex));
							 | 
						||
| 
								 | 
							
											bvh->m_SubtreeHeaders[i].m_subtreeSize = static_cast<int>(btSwapEndian(bvh->m_SubtreeHeaders[i].m_subtreeSize));
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return bvh;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Constructor that prevents btVector3's default constructor from being called
							 | 
						||
| 
								 | 
							
								btQuantizedBvh::btQuantizedBvh(btQuantizedBvh &self, bool /* ownsMemory */) :
							 | 
						||
| 
								 | 
							
								m_bvhAabbMin(self.m_bvhAabbMin),
							 | 
						||
| 
								 | 
							
								m_bvhAabbMax(self.m_bvhAabbMax),
							 | 
						||
| 
								 | 
							
								m_bvhQuantization(self.m_bvhQuantization),
							 | 
						||
| 
								 | 
							
								m_bulletVersion(BT_BULLET_VERSION)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void btQuantizedBvh::deSerializeFloat(struct btQuantizedBvhFloatData& quantizedBvhFloatData)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									m_bvhAabbMax.deSerializeFloat(quantizedBvhFloatData.m_bvhAabbMax);
							 | 
						||
| 
								 | 
							
									m_bvhAabbMin.deSerializeFloat(quantizedBvhFloatData.m_bvhAabbMin);
							 | 
						||
| 
								 | 
							
									m_bvhQuantization.deSerializeFloat(quantizedBvhFloatData.m_bvhQuantization);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									m_curNodeIndex = quantizedBvhFloatData.m_curNodeIndex;
							 | 
						||
| 
								 | 
							
									m_useQuantization = quantizedBvhFloatData.m_useQuantization!=0;
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										int numElem = quantizedBvhFloatData.m_numContiguousLeafNodes;
							 | 
						||
| 
								 | 
							
										m_contiguousNodes.resize(numElem);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if (numElem)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											btOptimizedBvhNodeFloatData* memPtr = quantizedBvhFloatData.m_contiguousNodesPtr;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											for (int i=0;i<numElem;i++,memPtr++)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												m_contiguousNodes[i].m_aabbMaxOrg.deSerializeFloat(memPtr->m_aabbMaxOrg);
							 | 
						||
| 
								 | 
							
												m_contiguousNodes[i].m_aabbMinOrg.deSerializeFloat(memPtr->m_aabbMinOrg);
							 | 
						||
| 
								 | 
							
												m_contiguousNodes[i].m_escapeIndex = memPtr->m_escapeIndex;
							 | 
						||
| 
								 | 
							
												m_contiguousNodes[i].m_subPart = memPtr->m_subPart;
							 | 
						||
| 
								 | 
							
												m_contiguousNodes[i].m_triangleIndex = memPtr->m_triangleIndex;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										int numElem = quantizedBvhFloatData.m_numQuantizedContiguousNodes;
							 | 
						||
| 
								 | 
							
										m_quantizedContiguousNodes.resize(numElem);
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										if (numElem)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											btQuantizedBvhNodeData* memPtr = quantizedBvhFloatData.m_quantizedContiguousNodesPtr;
							 | 
						||
| 
								 | 
							
											for (int i=0;i<numElem;i++,memPtr++)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												m_quantizedContiguousNodes[i].m_escapeIndexOrTriangleIndex = memPtr->m_escapeIndexOrTriangleIndex;
							 | 
						||
| 
								 | 
							
												m_quantizedContiguousNodes[i].m_quantizedAabbMax[0] = memPtr->m_quantizedAabbMax[0];
							 | 
						||
| 
								 | 
							
												m_quantizedContiguousNodes[i].m_quantizedAabbMax[1] = memPtr->m_quantizedAabbMax[1];
							 | 
						||
| 
								 | 
							
												m_quantizedContiguousNodes[i].m_quantizedAabbMax[2] = memPtr->m_quantizedAabbMax[2];
							 | 
						||
| 
								 | 
							
												m_quantizedContiguousNodes[i].m_quantizedAabbMin[0] = memPtr->m_quantizedAabbMin[0];
							 | 
						||
| 
								 | 
							
												m_quantizedContiguousNodes[i].m_quantizedAabbMin[1] = memPtr->m_quantizedAabbMin[1];
							 | 
						||
| 
								 | 
							
												m_quantizedContiguousNodes[i].m_quantizedAabbMin[2] = memPtr->m_quantizedAabbMin[2];
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									m_traversalMode = btTraversalMode(quantizedBvhFloatData.m_traversalMode);
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										int numElem = quantizedBvhFloatData.m_numSubtreeHeaders;
							 | 
						||
| 
								 | 
							
										m_SubtreeHeaders.resize(numElem);
							 | 
						||
| 
								 | 
							
										if (numElem)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											btBvhSubtreeInfoData* memPtr = quantizedBvhFloatData.m_subTreeInfoPtr;
							 | 
						||
| 
								 | 
							
											for (int i=0;i<numElem;i++,memPtr++)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												m_SubtreeHeaders[i].m_quantizedAabbMax[0] = memPtr->m_quantizedAabbMax[0] ;
							 | 
						||
| 
								 | 
							
												m_SubtreeHeaders[i].m_quantizedAabbMax[1] = memPtr->m_quantizedAabbMax[1];
							 | 
						||
| 
								 | 
							
												m_SubtreeHeaders[i].m_quantizedAabbMax[2] = memPtr->m_quantizedAabbMax[2];
							 | 
						||
| 
								 | 
							
												m_SubtreeHeaders[i].m_quantizedAabbMin[0] = memPtr->m_quantizedAabbMin[0];
							 | 
						||
| 
								 | 
							
												m_SubtreeHeaders[i].m_quantizedAabbMin[1] = memPtr->m_quantizedAabbMin[1];
							 | 
						||
| 
								 | 
							
												m_SubtreeHeaders[i].m_quantizedAabbMin[2] = memPtr->m_quantizedAabbMin[2];
							 | 
						||
| 
								 | 
							
												m_SubtreeHeaders[i].m_rootNodeIndex = memPtr->m_rootNodeIndex;
							 | 
						||
| 
								 | 
							
												m_SubtreeHeaders[i].m_subtreeSize = memPtr->m_subtreeSize;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void btQuantizedBvh::deSerializeDouble(struct btQuantizedBvhDoubleData& quantizedBvhDoubleData)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									m_bvhAabbMax.deSerializeDouble(quantizedBvhDoubleData.m_bvhAabbMax);
							 | 
						||
| 
								 | 
							
									m_bvhAabbMin.deSerializeDouble(quantizedBvhDoubleData.m_bvhAabbMin);
							 | 
						||
| 
								 | 
							
									m_bvhQuantization.deSerializeDouble(quantizedBvhDoubleData.m_bvhQuantization);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									m_curNodeIndex = quantizedBvhDoubleData.m_curNodeIndex;
							 | 
						||
| 
								 | 
							
									m_useQuantization = quantizedBvhDoubleData.m_useQuantization!=0;
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										int numElem = quantizedBvhDoubleData.m_numContiguousLeafNodes;
							 | 
						||
| 
								 | 
							
										m_contiguousNodes.resize(numElem);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if (numElem)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											btOptimizedBvhNodeDoubleData* memPtr = quantizedBvhDoubleData.m_contiguousNodesPtr;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											for (int i=0;i<numElem;i++,memPtr++)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												m_contiguousNodes[i].m_aabbMaxOrg.deSerializeDouble(memPtr->m_aabbMaxOrg);
							 | 
						||
| 
								 | 
							
												m_contiguousNodes[i].m_aabbMinOrg.deSerializeDouble(memPtr->m_aabbMinOrg);
							 | 
						||
| 
								 | 
							
												m_contiguousNodes[i].m_escapeIndex = memPtr->m_escapeIndex;
							 | 
						||
| 
								 | 
							
												m_contiguousNodes[i].m_subPart = memPtr->m_subPart;
							 | 
						||
| 
								 | 
							
												m_contiguousNodes[i].m_triangleIndex = memPtr->m_triangleIndex;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										int numElem = quantizedBvhDoubleData.m_numQuantizedContiguousNodes;
							 | 
						||
| 
								 | 
							
										m_quantizedContiguousNodes.resize(numElem);
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										if (numElem)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											btQuantizedBvhNodeData* memPtr = quantizedBvhDoubleData.m_quantizedContiguousNodesPtr;
							 | 
						||
| 
								 | 
							
											for (int i=0;i<numElem;i++,memPtr++)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												m_quantizedContiguousNodes[i].m_escapeIndexOrTriangleIndex = memPtr->m_escapeIndexOrTriangleIndex;
							 | 
						||
| 
								 | 
							
												m_quantizedContiguousNodes[i].m_quantizedAabbMax[0] = memPtr->m_quantizedAabbMax[0];
							 | 
						||
| 
								 | 
							
												m_quantizedContiguousNodes[i].m_quantizedAabbMax[1] = memPtr->m_quantizedAabbMax[1];
							 | 
						||
| 
								 | 
							
												m_quantizedContiguousNodes[i].m_quantizedAabbMax[2] = memPtr->m_quantizedAabbMax[2];
							 | 
						||
| 
								 | 
							
												m_quantizedContiguousNodes[i].m_quantizedAabbMin[0] = memPtr->m_quantizedAabbMin[0];
							 | 
						||
| 
								 | 
							
												m_quantizedContiguousNodes[i].m_quantizedAabbMin[1] = memPtr->m_quantizedAabbMin[1];
							 | 
						||
| 
								 | 
							
												m_quantizedContiguousNodes[i].m_quantizedAabbMin[2] = memPtr->m_quantizedAabbMin[2];
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									m_traversalMode = btTraversalMode(quantizedBvhDoubleData.m_traversalMode);
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										int numElem = quantizedBvhDoubleData.m_numSubtreeHeaders;
							 | 
						||
| 
								 | 
							
										m_SubtreeHeaders.resize(numElem);
							 | 
						||
| 
								 | 
							
										if (numElem)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											btBvhSubtreeInfoData* memPtr = quantizedBvhDoubleData.m_subTreeInfoPtr;
							 | 
						||
| 
								 | 
							
											for (int i=0;i<numElem;i++,memPtr++)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												m_SubtreeHeaders[i].m_quantizedAabbMax[0] = memPtr->m_quantizedAabbMax[0] ;
							 | 
						||
| 
								 | 
							
												m_SubtreeHeaders[i].m_quantizedAabbMax[1] = memPtr->m_quantizedAabbMax[1];
							 | 
						||
| 
								 | 
							
												m_SubtreeHeaders[i].m_quantizedAabbMax[2] = memPtr->m_quantizedAabbMax[2];
							 | 
						||
| 
								 | 
							
												m_SubtreeHeaders[i].m_quantizedAabbMin[0] = memPtr->m_quantizedAabbMin[0];
							 | 
						||
| 
								 | 
							
												m_SubtreeHeaders[i].m_quantizedAabbMin[1] = memPtr->m_quantizedAabbMin[1];
							 | 
						||
| 
								 | 
							
												m_SubtreeHeaders[i].m_quantizedAabbMin[2] = memPtr->m_quantizedAabbMin[2];
							 | 
						||
| 
								 | 
							
												m_SubtreeHeaders[i].m_rootNodeIndex = memPtr->m_rootNodeIndex;
							 | 
						||
| 
								 | 
							
												m_SubtreeHeaders[i].m_subtreeSize = memPtr->m_subtreeSize;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								///fills the dataBuffer and returns the struct name (and 0 on failure)
							 | 
						||
| 
								 | 
							
								const char*	btQuantizedBvh::serialize(void* dataBuffer, btSerializer* serializer) const
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									btQuantizedBvhData* quantizedData = (btQuantizedBvhData*)dataBuffer;
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									m_bvhAabbMax.serialize(quantizedData->m_bvhAabbMax);
							 | 
						||
| 
								 | 
							
									m_bvhAabbMin.serialize(quantizedData->m_bvhAabbMin);
							 | 
						||
| 
								 | 
							
									m_bvhQuantization.serialize(quantizedData->m_bvhQuantization);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									quantizedData->m_curNodeIndex = m_curNodeIndex;
							 | 
						||
| 
								 | 
							
									quantizedData->m_useQuantization = m_useQuantization;
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									quantizedData->m_numContiguousLeafNodes = m_contiguousNodes.size();
							 | 
						||
| 
								 | 
							
									quantizedData->m_contiguousNodesPtr = (btOptimizedBvhNodeData*) (m_contiguousNodes.size() ? serializer->getUniquePointer((void*)&m_contiguousNodes[0]) : 0);
							 | 
						||
| 
								 | 
							
									if (quantizedData->m_contiguousNodesPtr)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										int sz = sizeof(btOptimizedBvhNodeData);
							 | 
						||
| 
								 | 
							
										int numElem = m_contiguousNodes.size();
							 | 
						||
| 
								 | 
							
										btChunk* chunk = serializer->allocate(sz,numElem);
							 | 
						||
| 
								 | 
							
										btOptimizedBvhNodeData* memPtr = (btOptimizedBvhNodeData*)chunk->m_oldPtr;
							 | 
						||
| 
								 | 
							
										for (int i=0;i<numElem;i++,memPtr++)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											m_contiguousNodes[i].m_aabbMaxOrg.serialize(memPtr->m_aabbMaxOrg);
							 | 
						||
| 
								 | 
							
											m_contiguousNodes[i].m_aabbMinOrg.serialize(memPtr->m_aabbMinOrg);
							 | 
						||
| 
								 | 
							
											memPtr->m_escapeIndex = m_contiguousNodes[i].m_escapeIndex;
							 | 
						||
| 
								 | 
							
											memPtr->m_subPart = m_contiguousNodes[i].m_subPart;
							 | 
						||
| 
								 | 
							
											memPtr->m_triangleIndex = m_contiguousNodes[i].m_triangleIndex;
							 | 
						||
| 
								 | 
							
											// Fill padding with zeros to appease msan.
							 | 
						||
| 
								 | 
							
											memset(memPtr->m_pad, 0, sizeof(memPtr->m_pad));
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										serializer->finalizeChunk(chunk,"btOptimizedBvhNodeData",BT_ARRAY_CODE,(void*)&m_contiguousNodes[0]);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									quantizedData->m_numQuantizedContiguousNodes = m_quantizedContiguousNodes.size();
							 | 
						||
| 
								 | 
							
								//	printf("quantizedData->m_numQuantizedContiguousNodes=%d\n",quantizedData->m_numQuantizedContiguousNodes);
							 | 
						||
| 
								 | 
							
									quantizedData->m_quantizedContiguousNodesPtr =(btQuantizedBvhNodeData*) (m_quantizedContiguousNodes.size() ? serializer->getUniquePointer((void*)&m_quantizedContiguousNodes[0]) : 0);
							 | 
						||
| 
								 | 
							
									if (quantizedData->m_quantizedContiguousNodesPtr)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										int sz = sizeof(btQuantizedBvhNodeData);
							 | 
						||
| 
								 | 
							
										int numElem = m_quantizedContiguousNodes.size();
							 | 
						||
| 
								 | 
							
										btChunk* chunk = serializer->allocate(sz,numElem);
							 | 
						||
| 
								 | 
							
										btQuantizedBvhNodeData* memPtr = (btQuantizedBvhNodeData*)chunk->m_oldPtr;
							 | 
						||
| 
								 | 
							
										for (int i=0;i<numElem;i++,memPtr++)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											memPtr->m_escapeIndexOrTriangleIndex = m_quantizedContiguousNodes[i].m_escapeIndexOrTriangleIndex;
							 | 
						||
| 
								 | 
							
											memPtr->m_quantizedAabbMax[0] = m_quantizedContiguousNodes[i].m_quantizedAabbMax[0];
							 | 
						||
| 
								 | 
							
											memPtr->m_quantizedAabbMax[1] = m_quantizedContiguousNodes[i].m_quantizedAabbMax[1];
							 | 
						||
| 
								 | 
							
											memPtr->m_quantizedAabbMax[2] = m_quantizedContiguousNodes[i].m_quantizedAabbMax[2];
							 | 
						||
| 
								 | 
							
											memPtr->m_quantizedAabbMin[0] = m_quantizedContiguousNodes[i].m_quantizedAabbMin[0];
							 | 
						||
| 
								 | 
							
											memPtr->m_quantizedAabbMin[1] = m_quantizedContiguousNodes[i].m_quantizedAabbMin[1];
							 | 
						||
| 
								 | 
							
											memPtr->m_quantizedAabbMin[2] = m_quantizedContiguousNodes[i].m_quantizedAabbMin[2];
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										serializer->finalizeChunk(chunk,"btQuantizedBvhNodeData",BT_ARRAY_CODE,(void*)&m_quantizedContiguousNodes[0]);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									quantizedData->m_traversalMode = int(m_traversalMode);
							 | 
						||
| 
								 | 
							
									quantizedData->m_numSubtreeHeaders = m_SubtreeHeaders.size();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									quantizedData->m_subTreeInfoPtr = (btBvhSubtreeInfoData*) (m_SubtreeHeaders.size() ? serializer->getUniquePointer((void*)&m_SubtreeHeaders[0]) : 0);
							 | 
						||
| 
								 | 
							
									if (quantizedData->m_subTreeInfoPtr)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										int sz = sizeof(btBvhSubtreeInfoData);
							 | 
						||
| 
								 | 
							
										int numElem = m_SubtreeHeaders.size();
							 | 
						||
| 
								 | 
							
										btChunk* chunk = serializer->allocate(sz,numElem);
							 | 
						||
| 
								 | 
							
										btBvhSubtreeInfoData* memPtr = (btBvhSubtreeInfoData*)chunk->m_oldPtr;
							 | 
						||
| 
								 | 
							
										for (int i=0;i<numElem;i++,memPtr++)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											memPtr->m_quantizedAabbMax[0] = m_SubtreeHeaders[i].m_quantizedAabbMax[0];
							 | 
						||
| 
								 | 
							
											memPtr->m_quantizedAabbMax[1] = m_SubtreeHeaders[i].m_quantizedAabbMax[1];
							 | 
						||
| 
								 | 
							
											memPtr->m_quantizedAabbMax[2] = m_SubtreeHeaders[i].m_quantizedAabbMax[2];
							 | 
						||
| 
								 | 
							
											memPtr->m_quantizedAabbMin[0] = m_SubtreeHeaders[i].m_quantizedAabbMin[0];
							 | 
						||
| 
								 | 
							
											memPtr->m_quantizedAabbMin[1] = m_SubtreeHeaders[i].m_quantizedAabbMin[1];
							 | 
						||
| 
								 | 
							
											memPtr->m_quantizedAabbMin[2] = m_SubtreeHeaders[i].m_quantizedAabbMin[2];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											memPtr->m_rootNodeIndex = m_SubtreeHeaders[i].m_rootNodeIndex;
							 | 
						||
| 
								 | 
							
											memPtr->m_subtreeSize = m_SubtreeHeaders[i].m_subtreeSize;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										serializer->finalizeChunk(chunk,"btBvhSubtreeInfoData",BT_ARRAY_CODE,(void*)&m_SubtreeHeaders[0]);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return btQuantizedBvhDataName;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 |