529 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
		
		
			
		
	
	
			529 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| 
								 | 
							
								/*! \file gim_box_set.h
							 | 
						||
| 
								 | 
							
								\author Francisco Leon Najera
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								This source file is part of GIMPACT Library.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								For the latest info, see http://gimpact.sourceforge.net/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Copyright (c) 2007 Francisco Leon Najera. C.C. 80087371.
							 | 
						||
| 
								 | 
							
								email: projectileman@yahoo.com
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								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 "btGImpactQuantizedBvh.h"
							 | 
						||
| 
								 | 
							
								#include "LinearMath/btQuickprof.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef TRI_COLLISION_PROFILING
							 | 
						||
| 
								 | 
							
								btClock g_q_tree_clock;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								float g_q_accum_tree_collision_time = 0;
							 | 
						||
| 
								 | 
							
								int g_q_count_traversing = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void bt_begin_gim02_q_tree_time()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									g_q_tree_clock.reset();
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void bt_end_gim02_q_tree_time()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									g_q_accum_tree_collision_time += g_q_tree_clock.getTimeMicroseconds();
							 | 
						||
| 
								 | 
							
									g_q_count_traversing++;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//! Gets the average time in miliseconds of tree collisions
							 | 
						||
| 
								 | 
							
								float btGImpactQuantizedBvh::getAverageTreeCollisionTime()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									if(g_q_count_traversing == 0) return 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									float avgtime = g_q_accum_tree_collision_time;
							 | 
						||
| 
								 | 
							
									avgtime /= (float)g_q_count_traversing;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									g_q_accum_tree_collision_time = 0;
							 | 
						||
| 
								 | 
							
									g_q_count_traversing = 0;
							 | 
						||
| 
								 | 
							
									return avgtime;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//	float avgtime = g_q_count_traversing;
							 | 
						||
| 
								 | 
							
								//	g_q_count_traversing = 0;
							 | 
						||
| 
								 | 
							
								//	return avgtime;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif //TRI_COLLISION_PROFILING
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/////////////////////// btQuantizedBvhTree /////////////////////////////////
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void btQuantizedBvhTree::calc_quantization(
							 | 
						||
| 
								 | 
							
									GIM_BVH_DATA_ARRAY & primitive_boxes, btScalar boundMargin)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									//calc globa box
							 | 
						||
| 
								 | 
							
									btAABB global_bound;
							 | 
						||
| 
								 | 
							
									global_bound.invalidate();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									for (int i=0;i<primitive_boxes.size() ;i++ )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										global_bound.merge(primitive_boxes[i].m_bound);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									bt_calc_quantization_parameters(
							 | 
						||
| 
								 | 
							
										m_global_bound.m_min,m_global_bound.m_max,m_bvhQuantization,global_bound.m_min,global_bound.m_max,boundMargin);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								int btQuantizedBvhTree::_calc_splitting_axis(
							 | 
						||
| 
								 | 
							
									GIM_BVH_DATA_ARRAY & primitive_boxes, 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)*(primitive_boxes[i].m_bound.m_max +
							 | 
						||
| 
								 | 
							
													 primitive_boxes[i].m_bound.m_min);
							 | 
						||
| 
								 | 
							
										means+=center;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									means *= (btScalar(1.)/(btScalar)numIndices);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									for (i=startIndex;i<endIndex;i++)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										btVector3 center = btScalar(0.5)*(primitive_boxes[i].m_bound.m_max +
							 | 
						||
| 
								 | 
							
													 primitive_boxes[i].m_bound.m_min);
							 | 
						||
| 
								 | 
							
										btVector3 diff2 = center-means;
							 | 
						||
| 
								 | 
							
										diff2 = diff2 * diff2;
							 | 
						||
| 
								 | 
							
										variance += diff2;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									variance *= (btScalar(1.)/	((btScalar)numIndices-1)	);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return variance.maxAxis();
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								int btQuantizedBvhTree::_sort_and_calc_splitting_index(
							 | 
						||
| 
								 | 
							
									GIM_BVH_DATA_ARRAY & primitive_boxes, int startIndex,
							 | 
						||
| 
								 | 
							
									int endIndex, int splitAxis)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									int i;
							 | 
						||
| 
								 | 
							
									int splitIndex =startIndex;
							 | 
						||
| 
								 | 
							
									int numIndices = endIndex - startIndex;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// average of centers
							 | 
						||
| 
								 | 
							
									btScalar splitValue = 0.0f;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									btVector3 means(btScalar(0.),btScalar(0.),btScalar(0.));
							 | 
						||
| 
								 | 
							
									for (i=startIndex;i<endIndex;i++)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										btVector3 center = btScalar(0.5)*(primitive_boxes[i].m_bound.m_max +
							 | 
						||
| 
								 | 
							
													 primitive_boxes[i].m_bound.m_min);
							 | 
						||
| 
								 | 
							
										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)*(primitive_boxes[i].m_bound.m_max +
							 | 
						||
| 
								 | 
							
													 primitive_boxes[i].m_bound.m_min);
							 | 
						||
| 
								 | 
							
										if (center[splitAxis] > splitValue)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											//swap
							 | 
						||
| 
								 | 
							
											primitive_boxes.swap(i,splitIndex);
							 | 
						||
| 
								 | 
							
											//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);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									btAssert(!((splitIndex==startIndex) || (splitIndex == (endIndex))));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return splitIndex;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void btQuantizedBvhTree::_build_sub_tree(GIM_BVH_DATA_ARRAY & primitive_boxes, int startIndex,  int endIndex)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									int curIndex = m_num_nodes;
							 | 
						||
| 
								 | 
							
									m_num_nodes++;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									btAssert((endIndex-startIndex)>0);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if ((endIndex-startIndex)==1)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
									    //We have a leaf node
							 | 
						||
| 
								 | 
							
									    setNodeBound(curIndex,primitive_boxes[startIndex].m_bound);
							 | 
						||
| 
								 | 
							
										m_node_array[curIndex].setDataIndex(primitive_boxes[startIndex].m_data);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										return;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									//calculate Best Splitting Axis and where to split it. Sort the incoming 'leafNodes' array within range 'startIndex/endIndex'.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									//split axis
							 | 
						||
| 
								 | 
							
									int splitIndex = _calc_splitting_axis(primitive_boxes,startIndex,endIndex);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									splitIndex = _sort_and_calc_splitting_index(
							 | 
						||
| 
								 | 
							
											primitive_boxes,startIndex,endIndex,
							 | 
						||
| 
								 | 
							
											splitIndex//split axis
							 | 
						||
| 
								 | 
							
											);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									//calc this node bounding box
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									btAABB node_bound;
							 | 
						||
| 
								 | 
							
									node_bound.invalidate();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									for (int i=startIndex;i<endIndex;i++)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										node_bound.merge(primitive_boxes[i].m_bound);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									setNodeBound(curIndex,node_bound);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									//build left branch
							 | 
						||
| 
								 | 
							
									_build_sub_tree(primitive_boxes, startIndex, splitIndex );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									//build right branch
							 | 
						||
| 
								 | 
							
									 _build_sub_tree(primitive_boxes, splitIndex ,endIndex);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									m_node_array[curIndex].setEscapeIndex(m_num_nodes - curIndex);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//! stackless build tree
							 | 
						||
| 
								 | 
							
								void btQuantizedBvhTree::build_tree(
							 | 
						||
| 
								 | 
							
									GIM_BVH_DATA_ARRAY & primitive_boxes)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									calc_quantization(primitive_boxes);
							 | 
						||
| 
								 | 
							
									// initialize node count to 0
							 | 
						||
| 
								 | 
							
									m_num_nodes = 0;
							 | 
						||
| 
								 | 
							
									// allocate nodes
							 | 
						||
| 
								 | 
							
									m_node_array.resize(primitive_boxes.size()*2);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									_build_sub_tree(primitive_boxes, 0, primitive_boxes.size());
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								////////////////////////////////////class btGImpactQuantizedBvh
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void btGImpactQuantizedBvh::refit()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									int nodecount = getNodeCount();
							 | 
						||
| 
								 | 
							
									while(nodecount--)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										if(isLeafNode(nodecount))
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											btAABB leafbox;
							 | 
						||
| 
								 | 
							
											m_primitive_manager->get_primitive_box(getNodeData(nodecount),leafbox);
							 | 
						||
| 
								 | 
							
											setNodeBound(nodecount,leafbox);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											//const GIM_BVH_TREE_NODE * nodepointer = get_node_pointer(nodecount);
							 | 
						||
| 
								 | 
							
											//get left bound
							 | 
						||
| 
								 | 
							
											btAABB bound;
							 | 
						||
| 
								 | 
							
											bound.invalidate();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											btAABB temp_box;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											int child_node = getLeftNode(nodecount);
							 | 
						||
| 
								 | 
							
											if(child_node)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												getNodeBound(child_node,temp_box);
							 | 
						||
| 
								 | 
							
												bound.merge(temp_box);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											child_node = getRightNode(nodecount);
							 | 
						||
| 
								 | 
							
											if(child_node)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												getNodeBound(child_node,temp_box);
							 | 
						||
| 
								 | 
							
												bound.merge(temp_box);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											setNodeBound(nodecount,bound);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//! this rebuild the entire set
							 | 
						||
| 
								 | 
							
								void btGImpactQuantizedBvh::buildSet()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									//obtain primitive boxes
							 | 
						||
| 
								 | 
							
									GIM_BVH_DATA_ARRAY primitive_boxes;
							 | 
						||
| 
								 | 
							
									primitive_boxes.resize(m_primitive_manager->get_primitive_count());
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									for (int i = 0;i<primitive_boxes.size() ;i++ )
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										 m_primitive_manager->get_primitive_box(i,primitive_boxes[i].m_bound);
							 | 
						||
| 
								 | 
							
										 primitive_boxes[i].m_data = i;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									m_box_tree.build_tree(primitive_boxes);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//! returns the indices of the primitives in the m_primitive_manager
							 | 
						||
| 
								 | 
							
								bool btGImpactQuantizedBvh::boxQuery(const btAABB & box, btAlignedObjectArray<int> & collided_results) const
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									int curIndex = 0;
							 | 
						||
| 
								 | 
							
									int numNodes = getNodeCount();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									//quantize box
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									unsigned short quantizedMin[3];
							 | 
						||
| 
								 | 
							
									unsigned short quantizedMax[3];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									m_box_tree.quantizePoint(quantizedMin,box.m_min);
							 | 
						||
| 
								 | 
							
									m_box_tree.quantizePoint(quantizedMax,box.m_max);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									while (curIndex < numNodes)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										//catch bugs in tree data
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										bool aabbOverlap = m_box_tree.testQuantizedBoxOverlapp(curIndex, quantizedMin,quantizedMax);
							 | 
						||
| 
								 | 
							
										bool isleafnode = isLeafNode(curIndex);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if (isleafnode && aabbOverlap)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											collided_results.push_back(getNodeData(curIndex));
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if (aabbOverlap || isleafnode)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											//next subnode
							 | 
						||
| 
								 | 
							
											curIndex++;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											//skip node
							 | 
						||
| 
								 | 
							
											curIndex+= getEscapeNodeIndex(curIndex);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if(collided_results.size()>0) return true;
							 | 
						||
| 
								 | 
							
									return false;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//! returns the indices of the primitives in the m_primitive_manager
							 | 
						||
| 
								 | 
							
								bool btGImpactQuantizedBvh::rayQuery(
							 | 
						||
| 
								 | 
							
									const btVector3 & ray_dir,const btVector3 & ray_origin ,
							 | 
						||
| 
								 | 
							
									btAlignedObjectArray<int> & collided_results) const
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									int curIndex = 0;
							 | 
						||
| 
								 | 
							
									int numNodes = getNodeCount();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									while (curIndex < numNodes)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										btAABB bound;
							 | 
						||
| 
								 | 
							
										getNodeBound(curIndex,bound);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										//catch bugs in tree data
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										bool aabbOverlap = bound.collide_ray(ray_origin,ray_dir);
							 | 
						||
| 
								 | 
							
										bool isleafnode = isLeafNode(curIndex);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if (isleafnode && aabbOverlap)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											collided_results.push_back(getNodeData( curIndex));
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if (aabbOverlap || isleafnode)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											//next subnode
							 | 
						||
| 
								 | 
							
											curIndex++;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											//skip node
							 | 
						||
| 
								 | 
							
											curIndex+= getEscapeNodeIndex(curIndex);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if(collided_results.size()>0) return true;
							 | 
						||
| 
								 | 
							
									return false;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								SIMD_FORCE_INLINE bool _quantized_node_collision(
							 | 
						||
| 
								 | 
							
									const btGImpactQuantizedBvh * boxset0, const btGImpactQuantizedBvh * boxset1,
							 | 
						||
| 
								 | 
							
									const BT_BOX_BOX_TRANSFORM_CACHE & trans_cache_1to0,
							 | 
						||
| 
								 | 
							
									int node0 ,int node1, bool complete_primitive_tests)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									btAABB box0;
							 | 
						||
| 
								 | 
							
									boxset0->getNodeBound(node0,box0);
							 | 
						||
| 
								 | 
							
									btAABB box1;
							 | 
						||
| 
								 | 
							
									boxset1->getNodeBound(node1,box1);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return box0.overlapping_trans_cache(box1,trans_cache_1to0,complete_primitive_tests );
							 | 
						||
| 
								 | 
							
								//	box1.appy_transform_trans_cache(trans_cache_1to0);
							 | 
						||
| 
								 | 
							
								//	return box0.has_collision(box1);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//stackless recursive collision routine
							 | 
						||
| 
								 | 
							
								static void _find_quantized_collision_pairs_recursive(
							 | 
						||
| 
								 | 
							
									const btGImpactQuantizedBvh * boxset0, const btGImpactQuantizedBvh * boxset1,
							 | 
						||
| 
								 | 
							
									btPairSet * collision_pairs,
							 | 
						||
| 
								 | 
							
									const BT_BOX_BOX_TRANSFORM_CACHE & trans_cache_1to0,
							 | 
						||
| 
								 | 
							
									int node0, int node1, bool complete_primitive_tests)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if( _quantized_node_collision(
							 | 
						||
| 
								 | 
							
										boxset0,boxset1,trans_cache_1to0,
							 | 
						||
| 
								 | 
							
										node0,node1,complete_primitive_tests) ==false) return;//avoid colliding internal nodes
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if(boxset0->isLeafNode(node0))
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										if(boxset1->isLeafNode(node1))
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											// collision result
							 | 
						||
| 
								 | 
							
											collision_pairs->push_pair(
							 | 
						||
| 
								 | 
							
												boxset0->getNodeData(node0),boxset1->getNodeData(node1));
							 | 
						||
| 
								 | 
							
											return;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											//collide left recursive
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											_find_quantized_collision_pairs_recursive(
							 | 
						||
| 
								 | 
							
																boxset0,boxset1,
							 | 
						||
| 
								 | 
							
																collision_pairs,trans_cache_1to0,
							 | 
						||
| 
								 | 
							
																node0,boxset1->getLeftNode(node1),false);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											//collide right recursive
							 | 
						||
| 
								 | 
							
											_find_quantized_collision_pairs_recursive(
							 | 
						||
| 
								 | 
							
																boxset0,boxset1,
							 | 
						||
| 
								 | 
							
																collision_pairs,trans_cache_1to0,
							 | 
						||
| 
								 | 
							
																node0,boxset1->getRightNode(node1),false);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										if(boxset1->isLeafNode(node1))
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											//collide left recursive
							 | 
						||
| 
								 | 
							
											_find_quantized_collision_pairs_recursive(
							 | 
						||
| 
								 | 
							
																boxset0,boxset1,
							 | 
						||
| 
								 | 
							
																collision_pairs,trans_cache_1to0,
							 | 
						||
| 
								 | 
							
																boxset0->getLeftNode(node0),node1,false);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											//collide right recursive
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											_find_quantized_collision_pairs_recursive(
							 | 
						||
| 
								 | 
							
																boxset0,boxset1,
							 | 
						||
| 
								 | 
							
																collision_pairs,trans_cache_1to0,
							 | 
						||
| 
								 | 
							
																boxset0->getRightNode(node0),node1,false);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											//collide left0 left1
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											_find_quantized_collision_pairs_recursive(
							 | 
						||
| 
								 | 
							
												boxset0,boxset1,
							 | 
						||
| 
								 | 
							
												collision_pairs,trans_cache_1to0,
							 | 
						||
| 
								 | 
							
												boxset0->getLeftNode(node0),boxset1->getLeftNode(node1),false);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											//collide left0 right1
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											_find_quantized_collision_pairs_recursive(
							 | 
						||
| 
								 | 
							
												boxset0,boxset1,
							 | 
						||
| 
								 | 
							
												collision_pairs,trans_cache_1to0,
							 | 
						||
| 
								 | 
							
												boxset0->getLeftNode(node0),boxset1->getRightNode(node1),false);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											//collide right0 left1
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											_find_quantized_collision_pairs_recursive(
							 | 
						||
| 
								 | 
							
												boxset0,boxset1,
							 | 
						||
| 
								 | 
							
												collision_pairs,trans_cache_1to0,
							 | 
						||
| 
								 | 
							
												boxset0->getRightNode(node0),boxset1->getLeftNode(node1),false);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											//collide right0 right1
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											_find_quantized_collision_pairs_recursive(
							 | 
						||
| 
								 | 
							
												boxset0,boxset1,
							 | 
						||
| 
								 | 
							
												collision_pairs,trans_cache_1to0,
							 | 
						||
| 
								 | 
							
												boxset0->getRightNode(node0),boxset1->getRightNode(node1),false);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										}// else if node1 is not a leaf
							 | 
						||
| 
								 | 
							
									}// else if node0 is not a leaf
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void btGImpactQuantizedBvh::find_collision(const btGImpactQuantizedBvh * boxset0, const btTransform & trans0,
							 | 
						||
| 
								 | 
							
										const btGImpactQuantizedBvh * boxset1, const btTransform & trans1,
							 | 
						||
| 
								 | 
							
										btPairSet & collision_pairs)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if(boxset0->getNodeCount()==0 || boxset1->getNodeCount()==0 ) return;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									BT_BOX_BOX_TRANSFORM_CACHE trans_cache_1to0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									trans_cache_1to0.calc_from_homogenic(trans0,trans1);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef TRI_COLLISION_PROFILING
							 | 
						||
| 
								 | 
							
									bt_begin_gim02_q_tree_time();
							 | 
						||
| 
								 | 
							
								#endif //TRI_COLLISION_PROFILING
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									_find_quantized_collision_pairs_recursive(
							 | 
						||
| 
								 | 
							
										boxset0,boxset1,
							 | 
						||
| 
								 | 
							
										&collision_pairs,trans_cache_1to0,0,0,true);
							 | 
						||
| 
								 | 
							
								#ifdef TRI_COLLISION_PROFILING
							 | 
						||
| 
								 | 
							
									bt_end_gim02_q_tree_time();
							 | 
						||
| 
								 | 
							
								#endif //TRI_COLLISION_PROFILING
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 |