forked from LeenkxTeam/LNXSDK
		
	
		
			
	
	
		
			1330 lines
		
	
	
		
			36 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
		
		
			
		
	
	
			1330 lines
		
	
	
		
			36 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.
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								///btDbvt implementation by Nathanael Presson
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include "btDbvt.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								typedef btAlignedObjectArray<btDbvtNode*>			tNodeArray;
							 | 
						||
| 
								 | 
							
								typedef btAlignedObjectArray<const btDbvtNode*>	tConstNodeArray;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								struct btDbvtNodeEnumerator : btDbvt::ICollide
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									tConstNodeArray	nodes;
							 | 
						||
| 
								 | 
							
									void Process(const btDbvtNode* n) { nodes.push_back(n); }
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								static DBVT_INLINE int			indexof(const btDbvtNode* node)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									return(node->parent->childs[1]==node);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								static DBVT_INLINE btDbvtVolume	merge(	const btDbvtVolume& a,
							 | 
						||
| 
								 | 
							
																	  const btDbvtVolume& b)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								#if (DBVT_MERGE_IMPL==DBVT_IMPL_SSE)
							 | 
						||
| 
								 | 
							
									ATTRIBUTE_ALIGNED16( char locals[sizeof(btDbvtAabbMm)]);
							 | 
						||
| 
								 | 
							
									btDbvtVolume* ptr = (btDbvtVolume*) locals;
							 | 
						||
| 
								 | 
							
									btDbvtVolume&	res=*ptr;
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
										btDbvtVolume	res;
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
									Merge(a,b,res);
							 | 
						||
| 
								 | 
							
									return(res);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// volume+edge lengths
							 | 
						||
| 
								 | 
							
								static DBVT_INLINE btScalar		size(const btDbvtVolume& a)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									const btVector3	edges=a.Lengths();
							 | 
						||
| 
								 | 
							
									return(	edges.x()*edges.y()*edges.z()+
							 | 
						||
| 
								 | 
							
										edges.x()+edges.y()+edges.z());
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								static void						getmaxdepth(const btDbvtNode* node,int depth,int& maxdepth)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									if(node->isinternal())
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										getmaxdepth(node->childs[0],depth+1,maxdepth);
							 | 
						||
| 
								 | 
							
										getmaxdepth(node->childs[1],depth+1,maxdepth);
							 | 
						||
| 
								 | 
							
									} else maxdepth=btMax(maxdepth,depth);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								static DBVT_INLINE void			deletenode(	btDbvt* pdbvt,
							 | 
						||
| 
								 | 
							
																		   btDbvtNode* node)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									btAlignedFree(pdbvt->m_free);
							 | 
						||
| 
								 | 
							
									pdbvt->m_free=node;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								static void						recursedeletenode(	btDbvt* pdbvt,
							 | 
						||
| 
								 | 
							
																				  btDbvtNode* node)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									if(!node->isleaf())
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										recursedeletenode(pdbvt,node->childs[0]);
							 | 
						||
| 
								 | 
							
										recursedeletenode(pdbvt,node->childs[1]);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if(node==pdbvt->m_root) pdbvt->m_root=0;
							 | 
						||
| 
								 | 
							
									deletenode(pdbvt,node);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								static DBVT_INLINE btDbvtNode*	createnode(	btDbvt* pdbvt,
							 | 
						||
| 
								 | 
							
																		   btDbvtNode* parent,
							 | 
						||
| 
								 | 
							
																		   void* data)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									btDbvtNode*	node;
							 | 
						||
| 
								 | 
							
									if(pdbvt->m_free)
							 | 
						||
| 
								 | 
							
									{ node=pdbvt->m_free;pdbvt->m_free=0; }
							 | 
						||
| 
								 | 
							
									else
							 | 
						||
| 
								 | 
							
									{ node=new(btAlignedAlloc(sizeof(btDbvtNode),16)) btDbvtNode(); }
							 | 
						||
| 
								 | 
							
									node->parent	=	parent;
							 | 
						||
| 
								 | 
							
									node->data		=	data;
							 | 
						||
| 
								 | 
							
									node->childs[1]	=	0;
							 | 
						||
| 
								 | 
							
									return(node);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								static DBVT_INLINE btDbvtNode*	createnode(	btDbvt* pdbvt,
							 | 
						||
| 
								 | 
							
																		   btDbvtNode* parent,
							 | 
						||
| 
								 | 
							
																		   const btDbvtVolume& volume,
							 | 
						||
| 
								 | 
							
																		   void* data)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									btDbvtNode*	node=createnode(pdbvt,parent,data);
							 | 
						||
| 
								 | 
							
									node->volume=volume;
							 | 
						||
| 
								 | 
							
									return(node);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								static DBVT_INLINE btDbvtNode*	createnode(	btDbvt* pdbvt,
							 | 
						||
| 
								 | 
							
																		   btDbvtNode* parent,
							 | 
						||
| 
								 | 
							
																		   const btDbvtVolume& volume0,
							 | 
						||
| 
								 | 
							
																		   const btDbvtVolume& volume1,
							 | 
						||
| 
								 | 
							
																		   void* data)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									btDbvtNode*	node=createnode(pdbvt,parent,data);
							 | 
						||
| 
								 | 
							
									Merge(volume0,volume1,node->volume);
							 | 
						||
| 
								 | 
							
									return(node);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								static void						insertleaf(	btDbvt* pdbvt,
							 | 
						||
| 
								 | 
							
																		   btDbvtNode* root,
							 | 
						||
| 
								 | 
							
																		   btDbvtNode* leaf)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									if(!pdbvt->m_root)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										pdbvt->m_root	=	leaf;
							 | 
						||
| 
								 | 
							
										leaf->parent	=	0;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										if(!root->isleaf())
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											do	{
							 | 
						||
| 
								 | 
							
												root=root->childs[Select(	leaf->volume,
							 | 
						||
| 
								 | 
							
													root->childs[0]->volume,
							 | 
						||
| 
								 | 
							
													root->childs[1]->volume)];
							 | 
						||
| 
								 | 
							
											} while(!root->isleaf());
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										btDbvtNode*	prev=root->parent;
							 | 
						||
| 
								 | 
							
										btDbvtNode*	node=createnode(pdbvt,prev,leaf->volume,root->volume,0);
							 | 
						||
| 
								 | 
							
										if(prev)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											prev->childs[indexof(root)]	=	node;
							 | 
						||
| 
								 | 
							
											node->childs[0]				=	root;root->parent=node;
							 | 
						||
| 
								 | 
							
											node->childs[1]				=	leaf;leaf->parent=node;
							 | 
						||
| 
								 | 
							
											do	{
							 | 
						||
| 
								 | 
							
												if(!prev->volume.Contain(node->volume))
							 | 
						||
| 
								 | 
							
													Merge(prev->childs[0]->volume,prev->childs[1]->volume,prev->volume);
							 | 
						||
| 
								 | 
							
												else
							 | 
						||
| 
								 | 
							
													break;
							 | 
						||
| 
								 | 
							
												node=prev;
							 | 
						||
| 
								 | 
							
											} while(0!=(prev=node->parent));
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											node->childs[0]	=	root;root->parent=node;
							 | 
						||
| 
								 | 
							
											node->childs[1]	=	leaf;leaf->parent=node;
							 | 
						||
| 
								 | 
							
											pdbvt->m_root	=	node;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								static btDbvtNode*				removeleaf(	btDbvt* pdbvt,
							 | 
						||
| 
								 | 
							
																		   btDbvtNode* leaf)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									if(leaf==pdbvt->m_root)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										pdbvt->m_root=0;
							 | 
						||
| 
								 | 
							
										return(0);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										btDbvtNode*	parent=leaf->parent;
							 | 
						||
| 
								 | 
							
										btDbvtNode*	prev=parent->parent;
							 | 
						||
| 
								 | 
							
										btDbvtNode*	sibling=parent->childs[1-indexof(leaf)];			
							 | 
						||
| 
								 | 
							
										if(prev)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											prev->childs[indexof(parent)]=sibling;
							 | 
						||
| 
								 | 
							
											sibling->parent=prev;
							 | 
						||
| 
								 | 
							
											deletenode(pdbvt,parent);
							 | 
						||
| 
								 | 
							
											while(prev)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												const btDbvtVolume	pb=prev->volume;
							 | 
						||
| 
								 | 
							
												Merge(prev->childs[0]->volume,prev->childs[1]->volume,prev->volume);
							 | 
						||
| 
								 | 
							
												if(NotEqual(pb,prev->volume))
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													prev=prev->parent;
							 | 
						||
| 
								 | 
							
												} else break;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											return(prev?prev:pdbvt->m_root);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else
							 | 
						||
| 
								 | 
							
										{								
							 | 
						||
| 
								 | 
							
											pdbvt->m_root=sibling;
							 | 
						||
| 
								 | 
							
											sibling->parent=0;
							 | 
						||
| 
								 | 
							
											deletenode(pdbvt,parent);
							 | 
						||
| 
								 | 
							
											return(pdbvt->m_root);
							 | 
						||
| 
								 | 
							
										}			
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								static void						fetchleaves(btDbvt* pdbvt,
							 | 
						||
| 
								 | 
							
																			btDbvtNode* root,
							 | 
						||
| 
								 | 
							
																			tNodeArray& leaves,
							 | 
						||
| 
								 | 
							
																			int depth=-1)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									if(root->isinternal()&&depth)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										fetchleaves(pdbvt,root->childs[0],leaves,depth-1);
							 | 
						||
| 
								 | 
							
										fetchleaves(pdbvt,root->childs[1],leaves,depth-1);
							 | 
						||
| 
								 | 
							
										deletenode(pdbvt,root);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										leaves.push_back(root);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								static bool						leftOfAxis(	const btDbvtNode* node,
							 | 
						||
| 
								 | 
							
																		   const btVector3& org,
							 | 
						||
| 
								 | 
							
																		   const btVector3& axis)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									return btDot(axis, node->volume.Center() - org) <= 0;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Partitions leaves such that leaves[0, n) are on the
							 | 
						||
| 
								 | 
							
								// left of axis, and leaves[n, count) are on the right
							 | 
						||
| 
								 | 
							
								// of axis. returns N.
							 | 
						||
| 
								 | 
							
								static int						split(	btDbvtNode** leaves,
							 | 
						||
| 
								 | 
							
																	  int count,
							 | 
						||
| 
								 | 
							
																	  const btVector3& org,
							 | 
						||
| 
								 | 
							
																	  const btVector3& axis)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									int begin=0;
							 | 
						||
| 
								 | 
							
									int end=count;
							 | 
						||
| 
								 | 
							
									for(;;)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										while(begin!=end && leftOfAxis(leaves[begin],org,axis))
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											++begin;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if(begin==end)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											break;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										while(begin!=end && !leftOfAxis(leaves[end-1],org,axis))
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											--end;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if(begin==end)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											break;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// swap out of place nodes
							 | 
						||
| 
								 | 
							
										--end;
							 | 
						||
| 
								 | 
							
										btDbvtNode* temp=leaves[begin];
							 | 
						||
| 
								 | 
							
										leaves[begin]=leaves[end];
							 | 
						||
| 
								 | 
							
										leaves[end]=temp;
							 | 
						||
| 
								 | 
							
										++begin;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return begin;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								static btDbvtVolume				bounds(	btDbvtNode** leaves,
							 | 
						||
| 
								 | 
							
																	   int count)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								#if DBVT_MERGE_IMPL==DBVT_IMPL_SSE
							 | 
						||
| 
								 | 
							
									ATTRIBUTE_ALIGNED16(char	locals[sizeof(btDbvtVolume)]);
							 | 
						||
| 
								 | 
							
									btDbvtVolume* ptr = (btDbvtVolume*) locals;
							 | 
						||
| 
								 | 
							
									btDbvtVolume&	volume=*ptr;
							 | 
						||
| 
								 | 
							
									volume=leaves[0]->volume;
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
									btDbvtVolume volume=leaves[0]->volume;
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
									for(int i=1,ni=count;i<ni;++i)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										Merge(volume,leaves[i]->volume,volume);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return(volume);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								static void						bottomup(	btDbvt* pdbvt,
							 | 
						||
| 
								 | 
							
																		 btDbvtNode** leaves,
							 | 
						||
| 
								 | 
							
																		 int count)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									while(count>1)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										btScalar	minsize=SIMD_INFINITY;
							 | 
						||
| 
								 | 
							
										int			minidx[2]={-1,-1};
							 | 
						||
| 
								 | 
							
										for(int i=0;i<count;++i)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											for(int j=i+1;j<count;++j)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												const btScalar	sz=size(merge(leaves[i]->volume,leaves[j]->volume));
							 | 
						||
| 
								 | 
							
												if(sz<minsize)
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													minsize		=	sz;
							 | 
						||
| 
								 | 
							
													minidx[0]	=	i;
							 | 
						||
| 
								 | 
							
													minidx[1]	=	j;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										btDbvtNode*	n[]	=	{leaves[minidx[0]],leaves[minidx[1]]};
							 | 
						||
| 
								 | 
							
										btDbvtNode*	p	=	createnode(pdbvt,0,n[0]->volume,n[1]->volume,0);
							 | 
						||
| 
								 | 
							
										p->childs[0]		=	n[0];
							 | 
						||
| 
								 | 
							
										p->childs[1]		=	n[1];
							 | 
						||
| 
								 | 
							
										n[0]->parent		=	p;
							 | 
						||
| 
								 | 
							
										n[1]->parent		=	p;
							 | 
						||
| 
								 | 
							
										leaves[minidx[0]]	=	p;
							 | 
						||
| 
								 | 
							
										leaves[minidx[1]]	=	leaves[count-1];
							 | 
						||
| 
								 | 
							
										--count;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								static btDbvtNode*			topdown(btDbvt* pdbvt,
							 | 
						||
| 
								 | 
							
																	btDbvtNode** leaves,
							 | 
						||
| 
								 | 
							
																	int count,
							 | 
						||
| 
								 | 
							
																	int bu_treshold)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									static const btVector3	axis[]={btVector3(1,0,0),
							 | 
						||
| 
								 | 
							
										btVector3(0,1,0),
							 | 
						||
| 
								 | 
							
										btVector3(0,0,1)};
							 | 
						||
| 
								 | 
							
									btAssert(bu_treshold>2);
							 | 
						||
| 
								 | 
							
									if(count>1)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										if(count>bu_treshold)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											const btDbvtVolume	vol=bounds(leaves,count);
							 | 
						||
| 
								 | 
							
											const btVector3			org=vol.Center();
							 | 
						||
| 
								 | 
							
											int						partition;
							 | 
						||
| 
								 | 
							
											int						bestaxis=-1;
							 | 
						||
| 
								 | 
							
											int						bestmidp=count;
							 | 
						||
| 
								 | 
							
											int						splitcount[3][2]={{0,0},{0,0},{0,0}};
							 | 
						||
| 
								 | 
							
											int i;
							 | 
						||
| 
								 | 
							
											for( i=0;i<count;++i)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												const btVector3	x=leaves[i]->volume.Center()-org;
							 | 
						||
| 
								 | 
							
												for(int j=0;j<3;++j)
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													++splitcount[j][btDot(x,axis[j])>0?1:0];
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											for( i=0;i<3;++i)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												if((splitcount[i][0]>0)&&(splitcount[i][1]>0))
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													const int	midp=(int)btFabs(btScalar(splitcount[i][0]-splitcount[i][1]));
							 | 
						||
| 
								 | 
							
													if(midp<bestmidp)
							 | 
						||
| 
								 | 
							
													{
							 | 
						||
| 
								 | 
							
														bestaxis=i;
							 | 
						||
| 
								 | 
							
														bestmidp=midp;
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											if(bestaxis>=0)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												partition=split(leaves,count,org,axis[bestaxis]);
							 | 
						||
| 
								 | 
							
												btAssert(partition!=0 && partition!=count);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											else
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												partition=count/2+1;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											btDbvtNode*	node=createnode(pdbvt,0,vol,0);
							 | 
						||
| 
								 | 
							
											node->childs[0]=topdown(pdbvt,&leaves[0],partition,bu_treshold);
							 | 
						||
| 
								 | 
							
											node->childs[1]=topdown(pdbvt,&leaves[partition],count-partition,bu_treshold);
							 | 
						||
| 
								 | 
							
											node->childs[0]->parent=node;
							 | 
						||
| 
								 | 
							
											node->childs[1]->parent=node;
							 | 
						||
| 
								 | 
							
											return(node);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											bottomup(pdbvt,leaves,count);
							 | 
						||
| 
								 | 
							
											return(leaves[0]);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return(leaves[0]);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								static DBVT_INLINE btDbvtNode*	sort(btDbvtNode* n,btDbvtNode*& r)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									btDbvtNode*	p=n->parent;
							 | 
						||
| 
								 | 
							
									btAssert(n->isinternal());
							 | 
						||
| 
								 | 
							
									if(p>n)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										const int		i=indexof(n);
							 | 
						||
| 
								 | 
							
										const int		j=1-i;
							 | 
						||
| 
								 | 
							
										btDbvtNode*	s=p->childs[j];
							 | 
						||
| 
								 | 
							
										btDbvtNode*	q=p->parent;
							 | 
						||
| 
								 | 
							
										btAssert(n==p->childs[i]);
							 | 
						||
| 
								 | 
							
										if(q) q->childs[indexof(p)]=n; else r=n;
							 | 
						||
| 
								 | 
							
										s->parent=n;
							 | 
						||
| 
								 | 
							
										p->parent=n;
							 | 
						||
| 
								 | 
							
										n->parent=q;
							 | 
						||
| 
								 | 
							
										p->childs[0]=n->childs[0];
							 | 
						||
| 
								 | 
							
										p->childs[1]=n->childs[1];
							 | 
						||
| 
								 | 
							
										n->childs[0]->parent=p;
							 | 
						||
| 
								 | 
							
										n->childs[1]->parent=p;
							 | 
						||
| 
								 | 
							
										n->childs[i]=p;
							 | 
						||
| 
								 | 
							
										n->childs[j]=s;
							 | 
						||
| 
								 | 
							
										btSwap(p->volume,n->volume);
							 | 
						||
| 
								 | 
							
										return(p);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return(n);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if 0
							 | 
						||
| 
								 | 
							
								static DBVT_INLINE btDbvtNode*	walkup(btDbvtNode* n,int count)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									while(n&&(count--)) n=n->parent;
							 | 
						||
| 
								 | 
							
									return(n);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// Api
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								btDbvt::btDbvt()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									m_root		=	0;
							 | 
						||
| 
								 | 
							
									m_free		=	0;
							 | 
						||
| 
								 | 
							
									m_lkhd		=	-1;
							 | 
						||
| 
								 | 
							
									m_leaves	=	0;
							 | 
						||
| 
								 | 
							
									m_opath		=	0;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								btDbvt::~btDbvt()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									clear();
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								void			btDbvt::clear()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									if(m_root)	
							 | 
						||
| 
								 | 
							
										recursedeletenode(this,m_root);
							 | 
						||
| 
								 | 
							
									btAlignedFree(m_free);
							 | 
						||
| 
								 | 
							
									m_free=0;
							 | 
						||
| 
								 | 
							
									m_lkhd		=	-1;
							 | 
						||
| 
								 | 
							
									m_stkStack.clear();
							 | 
						||
| 
								 | 
							
									m_opath		=	0;
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								void			btDbvt::optimizeBottomUp()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									if(m_root)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										tNodeArray leaves;
							 | 
						||
| 
								 | 
							
										leaves.reserve(m_leaves);
							 | 
						||
| 
								 | 
							
										fetchleaves(this,m_root,leaves);
							 | 
						||
| 
								 | 
							
										bottomup(this,&leaves[0],leaves.size());
							 | 
						||
| 
								 | 
							
										m_root=leaves[0];
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								void			btDbvt::optimizeTopDown(int bu_treshold)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									if(m_root)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										tNodeArray	leaves;
							 | 
						||
| 
								 | 
							
										leaves.reserve(m_leaves);
							 | 
						||
| 
								 | 
							
										fetchleaves(this,m_root,leaves);
							 | 
						||
| 
								 | 
							
										m_root=topdown(this,&leaves[0],leaves.size(),bu_treshold);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								void			btDbvt::optimizeIncremental(int passes)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									if(passes<0) passes=m_leaves;
							 | 
						||
| 
								 | 
							
									if(m_root&&(passes>0))
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										do	{
							 | 
						||
| 
								 | 
							
											btDbvtNode*		node=m_root;
							 | 
						||
| 
								 | 
							
											unsigned	bit=0;
							 | 
						||
| 
								 | 
							
											while(node->isinternal())
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												node=sort(node,m_root)->childs[(m_opath>>bit)&1];
							 | 
						||
| 
								 | 
							
												bit=(bit+1)&(sizeof(unsigned)*8-1);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											update(node);
							 | 
						||
| 
								 | 
							
											++m_opath;
							 | 
						||
| 
								 | 
							
										} while(--passes);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								btDbvtNode*	btDbvt::insert(const btDbvtVolume& volume,void* data)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									btDbvtNode*	leaf=createnode(this,0,volume,data);
							 | 
						||
| 
								 | 
							
									insertleaf(this,m_root,leaf);
							 | 
						||
| 
								 | 
							
									++m_leaves;
							 | 
						||
| 
								 | 
							
									return(leaf);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								void			btDbvt::update(btDbvtNode* leaf,int lookahead)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									btDbvtNode*	root=removeleaf(this,leaf);
							 | 
						||
| 
								 | 
							
									if(root)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										if(lookahead>=0)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											for(int i=0;(i<lookahead)&&root->parent;++i)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												root=root->parent;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										} else root=m_root;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									insertleaf(this,root,leaf);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								void			btDbvt::update(btDbvtNode* leaf,btDbvtVolume& volume)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									btDbvtNode*	root=removeleaf(this,leaf);
							 | 
						||
| 
								 | 
							
									if(root)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										if(m_lkhd>=0)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											for(int i=0;(i<m_lkhd)&&root->parent;++i)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												root=root->parent;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										} else root=m_root;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									leaf->volume=volume;
							 | 
						||
| 
								 | 
							
									insertleaf(this,root,leaf);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								bool			btDbvt::update(btDbvtNode* leaf,btDbvtVolume& volume,const btVector3& velocity,btScalar margin)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									if(leaf->volume.Contain(volume)) return(false);
							 | 
						||
| 
								 | 
							
									volume.Expand(btVector3(margin,margin,margin));
							 | 
						||
| 
								 | 
							
									volume.SignedExpand(velocity);
							 | 
						||
| 
								 | 
							
									update(leaf,volume);
							 | 
						||
| 
								 | 
							
									return(true);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								bool			btDbvt::update(btDbvtNode* leaf,btDbvtVolume& volume,const btVector3& velocity)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									if(leaf->volume.Contain(volume)) return(false);
							 | 
						||
| 
								 | 
							
									volume.SignedExpand(velocity);
							 | 
						||
| 
								 | 
							
									update(leaf,volume);
							 | 
						||
| 
								 | 
							
									return(true);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								bool			btDbvt::update(btDbvtNode* leaf,btDbvtVolume& volume,btScalar margin)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									if(leaf->volume.Contain(volume)) return(false);
							 | 
						||
| 
								 | 
							
									volume.Expand(btVector3(margin,margin,margin));
							 | 
						||
| 
								 | 
							
									update(leaf,volume);
							 | 
						||
| 
								 | 
							
									return(true);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								void			btDbvt::remove(btDbvtNode* leaf)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									removeleaf(this,leaf);
							 | 
						||
| 
								 | 
							
									deletenode(this,leaf);
							 | 
						||
| 
								 | 
							
									--m_leaves;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								void			btDbvt::write(IWriter* iwriter) const
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									btDbvtNodeEnumerator	nodes;
							 | 
						||
| 
								 | 
							
									nodes.nodes.reserve(m_leaves*2);
							 | 
						||
| 
								 | 
							
									enumNodes(m_root,nodes);
							 | 
						||
| 
								 | 
							
									iwriter->Prepare(m_root,nodes.nodes.size());
							 | 
						||
| 
								 | 
							
									for(int i=0;i<nodes.nodes.size();++i)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										const btDbvtNode* n=nodes.nodes[i];
							 | 
						||
| 
								 | 
							
										int			p=-1;
							 | 
						||
| 
								 | 
							
										if(n->parent) p=nodes.nodes.findLinearSearch(n->parent);
							 | 
						||
| 
								 | 
							
										if(n->isinternal())
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											const int	c0=nodes.nodes.findLinearSearch(n->childs[0]);
							 | 
						||
| 
								 | 
							
											const int	c1=nodes.nodes.findLinearSearch(n->childs[1]);
							 | 
						||
| 
								 | 
							
											iwriter->WriteNode(n,i,p,c0,c1);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											iwriter->WriteLeaf(n,i,p);
							 | 
						||
| 
								 | 
							
										}	
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								void			btDbvt::clone(btDbvt& dest,IClone* iclone) const
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									dest.clear();
							 | 
						||
| 
								 | 
							
									if(m_root!=0)
							 | 
						||
| 
								 | 
							
									{	
							 | 
						||
| 
								 | 
							
										btAlignedObjectArray<sStkCLN>	stack;
							 | 
						||
| 
								 | 
							
										stack.reserve(m_leaves);
							 | 
						||
| 
								 | 
							
										stack.push_back(sStkCLN(m_root,0));
							 | 
						||
| 
								 | 
							
										do	{
							 | 
						||
| 
								 | 
							
											const int		i=stack.size()-1;
							 | 
						||
| 
								 | 
							
											const sStkCLN	e=stack[i];
							 | 
						||
| 
								 | 
							
											btDbvtNode*			n=createnode(&dest,e.parent,e.node->volume,e.node->data);
							 | 
						||
| 
								 | 
							
											stack.pop_back();
							 | 
						||
| 
								 | 
							
											if(e.parent!=0)
							 | 
						||
| 
								 | 
							
												e.parent->childs[i&1]=n;
							 | 
						||
| 
								 | 
							
											else
							 | 
						||
| 
								 | 
							
												dest.m_root=n;
							 | 
						||
| 
								 | 
							
											if(e.node->isinternal())
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												stack.push_back(sStkCLN(e.node->childs[0],n));
							 | 
						||
| 
								 | 
							
												stack.push_back(sStkCLN(e.node->childs[1],n));
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											else
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												iclone->CloneLeaf(n);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										} while(stack.size()>0);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								int				btDbvt::maxdepth(const btDbvtNode* node)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									int	depth=0;
							 | 
						||
| 
								 | 
							
									if(node) getmaxdepth(node,1,depth);
							 | 
						||
| 
								 | 
							
									return(depth);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								int				btDbvt::countLeaves(const btDbvtNode* node)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									if(node->isinternal())
							 | 
						||
| 
								 | 
							
										return(countLeaves(node->childs[0])+countLeaves(node->childs[1]));
							 | 
						||
| 
								 | 
							
									else
							 | 
						||
| 
								 | 
							
										return(1);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								void			btDbvt::extractLeaves(const btDbvtNode* node,btAlignedObjectArray<const btDbvtNode*>& leaves)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									if(node->isinternal())
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										extractLeaves(node->childs[0],leaves);
							 | 
						||
| 
								 | 
							
										extractLeaves(node->childs[1],leaves);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										leaves.push_back(node);
							 | 
						||
| 
								 | 
							
									}	
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								#if DBVT_ENABLE_BENCHMARK
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <stdio.h>
							 | 
						||
| 
								 | 
							
								#include <stdlib.h>
							 | 
						||
| 
								 | 
							
								#include "LinearMath/btQuickProf.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								q6600,2.4ghz
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/Ox /Ob2 /Oi /Ot /I "." /I "..\.." /I "..\..\src" /D "NDEBUG" /D "_LIB" /D "_WINDOWS" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "WIN32"
							 | 
						||
| 
								 | 
							
								/GF /FD /MT /GS- /Gy /arch:SSE2 /Zc:wchar_t- /Fp"..\..\out\release8\build\libbulletcollision\libbulletcollision.pch"
							 | 
						||
| 
								 | 
							
								/Fo"..\..\out\release8\build\libbulletcollision\\"
							 | 
						||
| 
								 | 
							
								/Fd"..\..\out\release8\build\libbulletcollision\bulletcollision.pdb"
							 | 
						||
| 
								 | 
							
								/W3 /nologo /c /Wp64 /Zi /errorReport:prompt
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Benchmarking dbvt...
							 | 
						||
| 
								 | 
							
								World scale: 100.000000
							 | 
						||
| 
								 | 
							
								Extents base: 1.000000
							 | 
						||
| 
								 | 
							
								Extents range: 4.000000
							 | 
						||
| 
								 | 
							
								Leaves: 8192
							 | 
						||
| 
								 | 
							
								sizeof(btDbvtVolume): 32 bytes
							 | 
						||
| 
								 | 
							
								sizeof(btDbvtNode):   44 bytes
							 | 
						||
| 
								 | 
							
								[1] btDbvtVolume intersections: 3499 ms (-1%)
							 | 
						||
| 
								 | 
							
								[2] btDbvtVolume merges: 1934 ms (0%)
							 | 
						||
| 
								 | 
							
								[3] btDbvt::collideTT: 5485 ms (-21%)
							 | 
						||
| 
								 | 
							
								[4] btDbvt::collideTT self: 2814 ms (-20%)
							 | 
						||
| 
								 | 
							
								[5] btDbvt::collideTT xform: 7379 ms (-1%)
							 | 
						||
| 
								 | 
							
								[6] btDbvt::collideTT xform,self: 7270 ms (-2%)
							 | 
						||
| 
								 | 
							
								[7] btDbvt::rayTest: 6314 ms (0%),(332143 r/s)
							 | 
						||
| 
								 | 
							
								[8] insert/remove: 2093 ms (0%),(1001983 ir/s)
							 | 
						||
| 
								 | 
							
								[9] updates (teleport): 1879 ms (-3%),(1116100 u/s)
							 | 
						||
| 
								 | 
							
								[10] updates (jitter): 1244 ms (-4%),(1685813 u/s)
							 | 
						||
| 
								 | 
							
								[11] optimize (incremental): 2514 ms (0%),(1668000 o/s)
							 | 
						||
| 
								 | 
							
								[12] btDbvtVolume notequal: 3659 ms (0%)
							 | 
						||
| 
								 | 
							
								[13] culling(OCL+fullsort): 2218 ms (0%),(461 t/s)
							 | 
						||
| 
								 | 
							
								[14] culling(OCL+qsort): 3688 ms (5%),(2221 t/s)
							 | 
						||
| 
								 | 
							
								[15] culling(KDOP+qsort): 1139 ms (-1%),(7192 t/s)
							 | 
						||
| 
								 | 
							
								[16] insert/remove batch(256): 5092 ms (0%),(823704 bir/s)
							 | 
						||
| 
								 | 
							
								[17] btDbvtVolume select: 3419 ms (0%)
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								struct btDbvtBenchmark
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									struct NilPolicy : btDbvt::ICollide
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										NilPolicy() : m_pcount(0),m_depth(-SIMD_INFINITY),m_checksort(true)		{}
							 | 
						||
| 
								 | 
							
										void	Process(const btDbvtNode*,const btDbvtNode*)				{ ++m_pcount; }
							 | 
						||
| 
								 | 
							
										void	Process(const btDbvtNode*)									{ ++m_pcount; }
							 | 
						||
| 
								 | 
							
										void	Process(const btDbvtNode*,btScalar depth)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											++m_pcount;
							 | 
						||
| 
								 | 
							
											if(m_checksort)
							 | 
						||
| 
								 | 
							
											{ if(depth>=m_depth) m_depth=depth; else printf("wrong depth: %f (should be >= %f)\r\n",depth,m_depth); }
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										int			m_pcount;
							 | 
						||
| 
								 | 
							
										btScalar	m_depth;
							 | 
						||
| 
								 | 
							
										bool		m_checksort;
							 | 
						||
| 
								 | 
							
									};
							 | 
						||
| 
								 | 
							
									struct P14 : btDbvt::ICollide
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										struct Node
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											const btDbvtNode*	leaf;
							 | 
						||
| 
								 | 
							
											btScalar			depth;
							 | 
						||
| 
								 | 
							
										};
							 | 
						||
| 
								 | 
							
										void Process(const btDbvtNode* leaf,btScalar depth)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											Node	n;
							 | 
						||
| 
								 | 
							
											n.leaf	=	leaf;
							 | 
						||
| 
								 | 
							
											n.depth	=	depth;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										static int sortfnc(const Node& a,const Node& b)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											if(a.depth<b.depth) return(+1);
							 | 
						||
| 
								 | 
							
											if(a.depth>b.depth) return(-1);
							 | 
						||
| 
								 | 
							
											return(0);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										btAlignedObjectArray<Node>		m_nodes;
							 | 
						||
| 
								 | 
							
									};
							 | 
						||
| 
								 | 
							
									struct P15 : btDbvt::ICollide
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										struct Node
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											const btDbvtNode*	leaf;
							 | 
						||
| 
								 | 
							
											btScalar			depth;
							 | 
						||
| 
								 | 
							
										};
							 | 
						||
| 
								 | 
							
										void Process(const btDbvtNode* leaf)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											Node	n;
							 | 
						||
| 
								 | 
							
											n.leaf	=	leaf;
							 | 
						||
| 
								 | 
							
											n.depth	=	dot(leaf->volume.Center(),m_axis);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										static int sortfnc(const Node& a,const Node& b)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											if(a.depth<b.depth) return(+1);
							 | 
						||
| 
								 | 
							
											if(a.depth>b.depth) return(-1);
							 | 
						||
| 
								 | 
							
											return(0);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										btAlignedObjectArray<Node>		m_nodes;
							 | 
						||
| 
								 | 
							
										btVector3						m_axis;
							 | 
						||
| 
								 | 
							
									};
							 | 
						||
| 
								 | 
							
									static btScalar			RandUnit()
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										return(rand()/(btScalar)RAND_MAX);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									static btVector3		RandVector3()
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										return(btVector3(RandUnit(),RandUnit(),RandUnit()));
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									static btVector3		RandVector3(btScalar cs)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										return(RandVector3()*cs-btVector3(cs,cs,cs)/2);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									static btDbvtVolume	RandVolume(btScalar cs,btScalar eb,btScalar es)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										return(btDbvtVolume::FromCE(RandVector3(cs),btVector3(eb,eb,eb)+RandVector3()*es));
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									static btTransform		RandTransform(btScalar cs)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										btTransform	t;
							 | 
						||
| 
								 | 
							
										t.setOrigin(RandVector3(cs));
							 | 
						||
| 
								 | 
							
										t.setRotation(btQuaternion(RandUnit()*SIMD_PI*2,RandUnit()*SIMD_PI*2,RandUnit()*SIMD_PI*2).normalized());
							 | 
						||
| 
								 | 
							
										return(t);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									static void				RandTree(btScalar cs,btScalar eb,btScalar es,int leaves,btDbvt& dbvt)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										dbvt.clear();
							 | 
						||
| 
								 | 
							
										for(int i=0;i<leaves;++i)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											dbvt.insert(RandVolume(cs,eb,es),0);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void			btDbvt::benchmark()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									static const btScalar	cfgVolumeCenterScale		=	100;
							 | 
						||
| 
								 | 
							
									static const btScalar	cfgVolumeExentsBase			=	1;
							 | 
						||
| 
								 | 
							
									static const btScalar	cfgVolumeExentsScale		=	4;
							 | 
						||
| 
								 | 
							
									static const int		cfgLeaves					=	8192;
							 | 
						||
| 
								 | 
							
									static const bool		cfgEnable					=	true;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									//[1] btDbvtVolume intersections
							 | 
						||
| 
								 | 
							
									bool					cfgBenchmark1_Enable		=	cfgEnable;
							 | 
						||
| 
								 | 
							
									static const int		cfgBenchmark1_Iterations	=	8;
							 | 
						||
| 
								 | 
							
									static const int		cfgBenchmark1_Reference		=	3499;
							 | 
						||
| 
								 | 
							
									//[2] btDbvtVolume merges
							 | 
						||
| 
								 | 
							
									bool					cfgBenchmark2_Enable		=	cfgEnable;
							 | 
						||
| 
								 | 
							
									static const int		cfgBenchmark2_Iterations	=	4;
							 | 
						||
| 
								 | 
							
									static const int		cfgBenchmark2_Reference		=	1945;
							 | 
						||
| 
								 | 
							
									//[3] btDbvt::collideTT
							 | 
						||
| 
								 | 
							
									bool					cfgBenchmark3_Enable		=	cfgEnable;
							 | 
						||
| 
								 | 
							
									static const int		cfgBenchmark3_Iterations	=	512;
							 | 
						||
| 
								 | 
							
									static const int		cfgBenchmark3_Reference		=	5485;
							 | 
						||
| 
								 | 
							
									//[4] btDbvt::collideTT self
							 | 
						||
| 
								 | 
							
									bool					cfgBenchmark4_Enable		=	cfgEnable;
							 | 
						||
| 
								 | 
							
									static const int		cfgBenchmark4_Iterations	=	512;
							 | 
						||
| 
								 | 
							
									static const int		cfgBenchmark4_Reference		=	2814;
							 | 
						||
| 
								 | 
							
									//[5] btDbvt::collideTT xform
							 | 
						||
| 
								 | 
							
									bool					cfgBenchmark5_Enable		=	cfgEnable;
							 | 
						||
| 
								 | 
							
									static const int		cfgBenchmark5_Iterations	=	512;
							 | 
						||
| 
								 | 
							
									static const btScalar	cfgBenchmark5_OffsetScale	=	2;
							 | 
						||
| 
								 | 
							
									static const int		cfgBenchmark5_Reference		=	7379;
							 | 
						||
| 
								 | 
							
									//[6] btDbvt::collideTT xform,self
							 | 
						||
| 
								 | 
							
									bool					cfgBenchmark6_Enable		=	cfgEnable;
							 | 
						||
| 
								 | 
							
									static const int		cfgBenchmark6_Iterations	=	512;
							 | 
						||
| 
								 | 
							
									static const btScalar	cfgBenchmark6_OffsetScale	=	2;
							 | 
						||
| 
								 | 
							
									static const int		cfgBenchmark6_Reference		=	7270;
							 | 
						||
| 
								 | 
							
									//[7] btDbvt::rayTest
							 | 
						||
| 
								 | 
							
									bool					cfgBenchmark7_Enable		=	cfgEnable;
							 | 
						||
| 
								 | 
							
									static const int		cfgBenchmark7_Passes		=	32;
							 | 
						||
| 
								 | 
							
									static const int		cfgBenchmark7_Iterations	=	65536;
							 | 
						||
| 
								 | 
							
									static const int		cfgBenchmark7_Reference		=	6307;
							 | 
						||
| 
								 | 
							
									//[8] insert/remove
							 | 
						||
| 
								 | 
							
									bool					cfgBenchmark8_Enable		=	cfgEnable;
							 | 
						||
| 
								 | 
							
									static const int		cfgBenchmark8_Passes		=	32;
							 | 
						||
| 
								 | 
							
									static const int		cfgBenchmark8_Iterations	=	65536;
							 | 
						||
| 
								 | 
							
									static const int		cfgBenchmark8_Reference		=	2105;
							 | 
						||
| 
								 | 
							
									//[9] updates (teleport)
							 | 
						||
| 
								 | 
							
									bool					cfgBenchmark9_Enable		=	cfgEnable;
							 | 
						||
| 
								 | 
							
									static const int		cfgBenchmark9_Passes		=	32;
							 | 
						||
| 
								 | 
							
									static const int		cfgBenchmark9_Iterations	=	65536;
							 | 
						||
| 
								 | 
							
									static const int		cfgBenchmark9_Reference		=	1879;
							 | 
						||
| 
								 | 
							
									//[10] updates (jitter)
							 | 
						||
| 
								 | 
							
									bool					cfgBenchmark10_Enable		=	cfgEnable;
							 | 
						||
| 
								 | 
							
									static const btScalar	cfgBenchmark10_Scale		=	cfgVolumeCenterScale/10000;
							 | 
						||
| 
								 | 
							
									static const int		cfgBenchmark10_Passes		=	32;
							 | 
						||
| 
								 | 
							
									static const int		cfgBenchmark10_Iterations	=	65536;
							 | 
						||
| 
								 | 
							
									static const int		cfgBenchmark10_Reference	=	1244;
							 | 
						||
| 
								 | 
							
									//[11] optimize (incremental)
							 | 
						||
| 
								 | 
							
									bool					cfgBenchmark11_Enable		=	cfgEnable;
							 | 
						||
| 
								 | 
							
									static const int		cfgBenchmark11_Passes		=	64;
							 | 
						||
| 
								 | 
							
									static const int		cfgBenchmark11_Iterations	=	65536;
							 | 
						||
| 
								 | 
							
									static const int		cfgBenchmark11_Reference	=	2510;
							 | 
						||
| 
								 | 
							
									//[12] btDbvtVolume notequal
							 | 
						||
| 
								 | 
							
									bool					cfgBenchmark12_Enable		=	cfgEnable;
							 | 
						||
| 
								 | 
							
									static const int		cfgBenchmark12_Iterations	=	32;
							 | 
						||
| 
								 | 
							
									static const int		cfgBenchmark12_Reference	=	3677;
							 | 
						||
| 
								 | 
							
									//[13] culling(OCL+fullsort)
							 | 
						||
| 
								 | 
							
									bool					cfgBenchmark13_Enable		=	cfgEnable;
							 | 
						||
| 
								 | 
							
									static const int		cfgBenchmark13_Iterations	=	1024;
							 | 
						||
| 
								 | 
							
									static const int		cfgBenchmark13_Reference	=	2231;
							 | 
						||
| 
								 | 
							
									//[14] culling(OCL+qsort)
							 | 
						||
| 
								 | 
							
									bool					cfgBenchmark14_Enable		=	cfgEnable;
							 | 
						||
| 
								 | 
							
									static const int		cfgBenchmark14_Iterations	=	8192;
							 | 
						||
| 
								 | 
							
									static const int		cfgBenchmark14_Reference	=	3500;
							 | 
						||
| 
								 | 
							
									//[15] culling(KDOP+qsort)
							 | 
						||
| 
								 | 
							
									bool					cfgBenchmark15_Enable		=	cfgEnable;
							 | 
						||
| 
								 | 
							
									static const int		cfgBenchmark15_Iterations	=	8192;
							 | 
						||
| 
								 | 
							
									static const int		cfgBenchmark15_Reference	=	1151;
							 | 
						||
| 
								 | 
							
									//[16] insert/remove batch
							 | 
						||
| 
								 | 
							
									bool					cfgBenchmark16_Enable		=	cfgEnable;
							 | 
						||
| 
								 | 
							
									static const int		cfgBenchmark16_BatchCount	=	256;
							 | 
						||
| 
								 | 
							
									static const int		cfgBenchmark16_Passes		=	16384;
							 | 
						||
| 
								 | 
							
									static const int		cfgBenchmark16_Reference	=	5138;
							 | 
						||
| 
								 | 
							
									//[17] select
							 | 
						||
| 
								 | 
							
									bool					cfgBenchmark17_Enable		=	cfgEnable;
							 | 
						||
| 
								 | 
							
									static const int		cfgBenchmark17_Iterations	=	4;
							 | 
						||
| 
								 | 
							
									static const int		cfgBenchmark17_Reference	=	3390;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									btClock					wallclock;
							 | 
						||
| 
								 | 
							
									printf("Benchmarking dbvt...\r\n");
							 | 
						||
| 
								 | 
							
									printf("\tWorld scale: %f\r\n",cfgVolumeCenterScale);
							 | 
						||
| 
								 | 
							
									printf("\tExtents base: %f\r\n",cfgVolumeExentsBase);
							 | 
						||
| 
								 | 
							
									printf("\tExtents range: %f\r\n",cfgVolumeExentsScale);
							 | 
						||
| 
								 | 
							
									printf("\tLeaves: %u\r\n",cfgLeaves);
							 | 
						||
| 
								 | 
							
									printf("\tsizeof(btDbvtVolume): %u bytes\r\n",sizeof(btDbvtVolume));
							 | 
						||
| 
								 | 
							
									printf("\tsizeof(btDbvtNode):   %u bytes\r\n",sizeof(btDbvtNode));
							 | 
						||
| 
								 | 
							
									if(cfgBenchmark1_Enable)
							 | 
						||
| 
								 | 
							
									{// Benchmark 1	
							 | 
						||
| 
								 | 
							
										srand(380843);
							 | 
						||
| 
								 | 
							
										btAlignedObjectArray<btDbvtVolume>	volumes;
							 | 
						||
| 
								 | 
							
										btAlignedObjectArray<bool>			results;
							 | 
						||
| 
								 | 
							
										volumes.resize(cfgLeaves);
							 | 
						||
| 
								 | 
							
										results.resize(cfgLeaves);
							 | 
						||
| 
								 | 
							
										for(int i=0;i<cfgLeaves;++i)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											volumes[i]=btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										printf("[1] btDbvtVolume intersections: ");
							 | 
						||
| 
								 | 
							
										wallclock.reset();
							 | 
						||
| 
								 | 
							
										for(int i=0;i<cfgBenchmark1_Iterations;++i)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											for(int j=0;j<cfgLeaves;++j)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												for(int k=0;k<cfgLeaves;++k)
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													results[k]=Intersect(volumes[j],volumes[k]);
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										const int time=(int)wallclock.getTimeMilliseconds();
							 | 
						||
| 
								 | 
							
										printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark1_Reference)*100/time);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if(cfgBenchmark2_Enable)
							 | 
						||
| 
								 | 
							
									{// Benchmark 2	
							 | 
						||
| 
								 | 
							
										srand(380843);
							 | 
						||
| 
								 | 
							
										btAlignedObjectArray<btDbvtVolume>	volumes;
							 | 
						||
| 
								 | 
							
										btAlignedObjectArray<btDbvtVolume>	results;
							 | 
						||
| 
								 | 
							
										volumes.resize(cfgLeaves);
							 | 
						||
| 
								 | 
							
										results.resize(cfgLeaves);
							 | 
						||
| 
								 | 
							
										for(int i=0;i<cfgLeaves;++i)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											volumes[i]=btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										printf("[2] btDbvtVolume merges: ");
							 | 
						||
| 
								 | 
							
										wallclock.reset();
							 | 
						||
| 
								 | 
							
										for(int i=0;i<cfgBenchmark2_Iterations;++i)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											for(int j=0;j<cfgLeaves;++j)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												for(int k=0;k<cfgLeaves;++k)
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													Merge(volumes[j],volumes[k],results[k]);
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										const int time=(int)wallclock.getTimeMilliseconds();
							 | 
						||
| 
								 | 
							
										printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark2_Reference)*100/time);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if(cfgBenchmark3_Enable)
							 | 
						||
| 
								 | 
							
									{// Benchmark 3	
							 | 
						||
| 
								 | 
							
										srand(380843);
							 | 
						||
| 
								 | 
							
										btDbvt						dbvt[2];
							 | 
						||
| 
								 | 
							
										btDbvtBenchmark::NilPolicy	policy;
							 | 
						||
| 
								 | 
							
										btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt[0]);
							 | 
						||
| 
								 | 
							
										btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt[1]);
							 | 
						||
| 
								 | 
							
										dbvt[0].optimizeTopDown();
							 | 
						||
| 
								 | 
							
										dbvt[1].optimizeTopDown();
							 | 
						||
| 
								 | 
							
										printf("[3] btDbvt::collideTT: ");
							 | 
						||
| 
								 | 
							
										wallclock.reset();
							 | 
						||
| 
								 | 
							
										for(int i=0;i<cfgBenchmark3_Iterations;++i)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											btDbvt::collideTT(dbvt[0].m_root,dbvt[1].m_root,policy);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										const int time=(int)wallclock.getTimeMilliseconds();
							 | 
						||
| 
								 | 
							
										printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark3_Reference)*100/time);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if(cfgBenchmark4_Enable)
							 | 
						||
| 
								 | 
							
									{// Benchmark 4
							 | 
						||
| 
								 | 
							
										srand(380843);
							 | 
						||
| 
								 | 
							
										btDbvt						dbvt;
							 | 
						||
| 
								 | 
							
										btDbvtBenchmark::NilPolicy	policy;
							 | 
						||
| 
								 | 
							
										btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
							 | 
						||
| 
								 | 
							
										dbvt.optimizeTopDown();
							 | 
						||
| 
								 | 
							
										printf("[4] btDbvt::collideTT self: ");
							 | 
						||
| 
								 | 
							
										wallclock.reset();
							 | 
						||
| 
								 | 
							
										for(int i=0;i<cfgBenchmark4_Iterations;++i)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											btDbvt::collideTT(dbvt.m_root,dbvt.m_root,policy);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										const int time=(int)wallclock.getTimeMilliseconds();
							 | 
						||
| 
								 | 
							
										printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark4_Reference)*100/time);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if(cfgBenchmark5_Enable)
							 | 
						||
| 
								 | 
							
									{// Benchmark 5	
							 | 
						||
| 
								 | 
							
										srand(380843);
							 | 
						||
| 
								 | 
							
										btDbvt								dbvt[2];
							 | 
						||
| 
								 | 
							
										btAlignedObjectArray<btTransform>	transforms;
							 | 
						||
| 
								 | 
							
										btDbvtBenchmark::NilPolicy			policy;
							 | 
						||
| 
								 | 
							
										transforms.resize(cfgBenchmark5_Iterations);
							 | 
						||
| 
								 | 
							
										for(int i=0;i<transforms.size();++i)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											transforms[i]=btDbvtBenchmark::RandTransform(cfgVolumeCenterScale*cfgBenchmark5_OffsetScale);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt[0]);
							 | 
						||
| 
								 | 
							
										btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt[1]);
							 | 
						||
| 
								 | 
							
										dbvt[0].optimizeTopDown();
							 | 
						||
| 
								 | 
							
										dbvt[1].optimizeTopDown();
							 | 
						||
| 
								 | 
							
										printf("[5] btDbvt::collideTT xform: ");
							 | 
						||
| 
								 | 
							
										wallclock.reset();
							 | 
						||
| 
								 | 
							
										for(int i=0;i<cfgBenchmark5_Iterations;++i)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											btDbvt::collideTT(dbvt[0].m_root,dbvt[1].m_root,transforms[i],policy);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										const int time=(int)wallclock.getTimeMilliseconds();
							 | 
						||
| 
								 | 
							
										printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark5_Reference)*100/time);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if(cfgBenchmark6_Enable)
							 | 
						||
| 
								 | 
							
									{// Benchmark 6	
							 | 
						||
| 
								 | 
							
										srand(380843);
							 | 
						||
| 
								 | 
							
										btDbvt								dbvt;
							 | 
						||
| 
								 | 
							
										btAlignedObjectArray<btTransform>	transforms;
							 | 
						||
| 
								 | 
							
										btDbvtBenchmark::NilPolicy			policy;
							 | 
						||
| 
								 | 
							
										transforms.resize(cfgBenchmark6_Iterations);
							 | 
						||
| 
								 | 
							
										for(int i=0;i<transforms.size();++i)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											transforms[i]=btDbvtBenchmark::RandTransform(cfgVolumeCenterScale*cfgBenchmark6_OffsetScale);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
							 | 
						||
| 
								 | 
							
										dbvt.optimizeTopDown();
							 | 
						||
| 
								 | 
							
										printf("[6] btDbvt::collideTT xform,self: ");
							 | 
						||
| 
								 | 
							
										wallclock.reset();
							 | 
						||
| 
								 | 
							
										for(int i=0;i<cfgBenchmark6_Iterations;++i)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											btDbvt::collideTT(dbvt.m_root,dbvt.m_root,transforms[i],policy);		
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										const int time=(int)wallclock.getTimeMilliseconds();
							 | 
						||
| 
								 | 
							
										printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark6_Reference)*100/time);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if(cfgBenchmark7_Enable)
							 | 
						||
| 
								 | 
							
									{// Benchmark 7	
							 | 
						||
| 
								 | 
							
										srand(380843);
							 | 
						||
| 
								 | 
							
										btDbvt								dbvt;
							 | 
						||
| 
								 | 
							
										btAlignedObjectArray<btVector3>		rayorg;
							 | 
						||
| 
								 | 
							
										btAlignedObjectArray<btVector3>		raydir;
							 | 
						||
| 
								 | 
							
										btDbvtBenchmark::NilPolicy			policy;
							 | 
						||
| 
								 | 
							
										rayorg.resize(cfgBenchmark7_Iterations);
							 | 
						||
| 
								 | 
							
										raydir.resize(cfgBenchmark7_Iterations);
							 | 
						||
| 
								 | 
							
										for(int i=0;i<rayorg.size();++i)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											rayorg[i]=btDbvtBenchmark::RandVector3(cfgVolumeCenterScale*2);
							 | 
						||
| 
								 | 
							
											raydir[i]=btDbvtBenchmark::RandVector3(cfgVolumeCenterScale*2);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
							 | 
						||
| 
								 | 
							
										dbvt.optimizeTopDown();
							 | 
						||
| 
								 | 
							
										printf("[7] btDbvt::rayTest: ");
							 | 
						||
| 
								 | 
							
										wallclock.reset();
							 | 
						||
| 
								 | 
							
										for(int i=0;i<cfgBenchmark7_Passes;++i)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											for(int j=0;j<cfgBenchmark7_Iterations;++j)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												btDbvt::rayTest(dbvt.m_root,rayorg[j],rayorg[j]+raydir[j],policy);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										const int	time=(int)wallclock.getTimeMilliseconds();
							 | 
						||
| 
								 | 
							
										unsigned	rays=cfgBenchmark7_Passes*cfgBenchmark7_Iterations;
							 | 
						||
| 
								 | 
							
										printf("%u ms (%i%%),(%u r/s)\r\n",time,(time-cfgBenchmark7_Reference)*100/time,(rays*1000)/time);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if(cfgBenchmark8_Enable)
							 | 
						||
| 
								 | 
							
									{// Benchmark 8	
							 | 
						||
| 
								 | 
							
										srand(380843);
							 | 
						||
| 
								 | 
							
										btDbvt								dbvt;
							 | 
						||
| 
								 | 
							
										btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
							 | 
						||
| 
								 | 
							
										dbvt.optimizeTopDown();
							 | 
						||
| 
								 | 
							
										printf("[8] insert/remove: ");
							 | 
						||
| 
								 | 
							
										wallclock.reset();
							 | 
						||
| 
								 | 
							
										for(int i=0;i<cfgBenchmark8_Passes;++i)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											for(int j=0;j<cfgBenchmark8_Iterations;++j)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												dbvt.remove(dbvt.insert(btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale),0));
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										const int	time=(int)wallclock.getTimeMilliseconds();
							 | 
						||
| 
								 | 
							
										const int	ir=cfgBenchmark8_Passes*cfgBenchmark8_Iterations;
							 | 
						||
| 
								 | 
							
										printf("%u ms (%i%%),(%u ir/s)\r\n",time,(time-cfgBenchmark8_Reference)*100/time,ir*1000/time);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if(cfgBenchmark9_Enable)
							 | 
						||
| 
								 | 
							
									{// Benchmark 9	
							 | 
						||
| 
								 | 
							
										srand(380843);
							 | 
						||
| 
								 | 
							
										btDbvt										dbvt;
							 | 
						||
| 
								 | 
							
										btAlignedObjectArray<const btDbvtNode*>	leaves;
							 | 
						||
| 
								 | 
							
										btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
							 | 
						||
| 
								 | 
							
										dbvt.optimizeTopDown();
							 | 
						||
| 
								 | 
							
										dbvt.extractLeaves(dbvt.m_root,leaves);
							 | 
						||
| 
								 | 
							
										printf("[9] updates (teleport): ");
							 | 
						||
| 
								 | 
							
										wallclock.reset();
							 | 
						||
| 
								 | 
							
										for(int i=0;i<cfgBenchmark9_Passes;++i)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											for(int j=0;j<cfgBenchmark9_Iterations;++j)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												dbvt.update(const_cast<btDbvtNode*>(leaves[rand()%cfgLeaves]),
							 | 
						||
| 
								 | 
							
													btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale));
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										const int	time=(int)wallclock.getTimeMilliseconds();
							 | 
						||
| 
								 | 
							
										const int	up=cfgBenchmark9_Passes*cfgBenchmark9_Iterations;
							 | 
						||
| 
								 | 
							
										printf("%u ms (%i%%),(%u u/s)\r\n",time,(time-cfgBenchmark9_Reference)*100/time,up*1000/time);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if(cfgBenchmark10_Enable)
							 | 
						||
| 
								 | 
							
									{// Benchmark 10	
							 | 
						||
| 
								 | 
							
										srand(380843);
							 | 
						||
| 
								 | 
							
										btDbvt										dbvt;
							 | 
						||
| 
								 | 
							
										btAlignedObjectArray<const btDbvtNode*>	leaves;
							 | 
						||
| 
								 | 
							
										btAlignedObjectArray<btVector3>				vectors;
							 | 
						||
| 
								 | 
							
										vectors.resize(cfgBenchmark10_Iterations);
							 | 
						||
| 
								 | 
							
										for(int i=0;i<vectors.size();++i)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											vectors[i]=(btDbvtBenchmark::RandVector3()*2-btVector3(1,1,1))*cfgBenchmark10_Scale;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
							 | 
						||
| 
								 | 
							
										dbvt.optimizeTopDown();
							 | 
						||
| 
								 | 
							
										dbvt.extractLeaves(dbvt.m_root,leaves);
							 | 
						||
| 
								 | 
							
										printf("[10] updates (jitter): ");
							 | 
						||
| 
								 | 
							
										wallclock.reset();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										for(int i=0;i<cfgBenchmark10_Passes;++i)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											for(int j=0;j<cfgBenchmark10_Iterations;++j)
							 | 
						||
| 
								 | 
							
											{			
							 | 
						||
| 
								 | 
							
												const btVector3&	d=vectors[j];
							 | 
						||
| 
								 | 
							
												btDbvtNode*		l=const_cast<btDbvtNode*>(leaves[rand()%cfgLeaves]);
							 | 
						||
| 
								 | 
							
												btDbvtVolume		v=btDbvtVolume::FromMM(l->volume.Mins()+d,l->volume.Maxs()+d);
							 | 
						||
| 
								 | 
							
												dbvt.update(l,v);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										const int	time=(int)wallclock.getTimeMilliseconds();
							 | 
						||
| 
								 | 
							
										const int	up=cfgBenchmark10_Passes*cfgBenchmark10_Iterations;
							 | 
						||
| 
								 | 
							
										printf("%u ms (%i%%),(%u u/s)\r\n",time,(time-cfgBenchmark10_Reference)*100/time,up*1000/time);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if(cfgBenchmark11_Enable)
							 | 
						||
| 
								 | 
							
									{// Benchmark 11	
							 | 
						||
| 
								 | 
							
										srand(380843);
							 | 
						||
| 
								 | 
							
										btDbvt										dbvt;
							 | 
						||
| 
								 | 
							
										btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
							 | 
						||
| 
								 | 
							
										dbvt.optimizeTopDown();
							 | 
						||
| 
								 | 
							
										printf("[11] optimize (incremental): ");
							 | 
						||
| 
								 | 
							
										wallclock.reset();	
							 | 
						||
| 
								 | 
							
										for(int i=0;i<cfgBenchmark11_Passes;++i)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											dbvt.optimizeIncremental(cfgBenchmark11_Iterations);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										const int	time=(int)wallclock.getTimeMilliseconds();
							 | 
						||
| 
								 | 
							
										const int	op=cfgBenchmark11_Passes*cfgBenchmark11_Iterations;
							 | 
						||
| 
								 | 
							
										printf("%u ms (%i%%),(%u o/s)\r\n",time,(time-cfgBenchmark11_Reference)*100/time,op/time*1000);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if(cfgBenchmark12_Enable)
							 | 
						||
| 
								 | 
							
									{// Benchmark 12	
							 | 
						||
| 
								 | 
							
										srand(380843);
							 | 
						||
| 
								 | 
							
										btAlignedObjectArray<btDbvtVolume>	volumes;
							 | 
						||
| 
								 | 
							
										btAlignedObjectArray<bool>				results;
							 | 
						||
| 
								 | 
							
										volumes.resize(cfgLeaves);
							 | 
						||
| 
								 | 
							
										results.resize(cfgLeaves);
							 | 
						||
| 
								 | 
							
										for(int i=0;i<cfgLeaves;++i)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											volumes[i]=btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										printf("[12] btDbvtVolume notequal: ");
							 | 
						||
| 
								 | 
							
										wallclock.reset();
							 | 
						||
| 
								 | 
							
										for(int i=0;i<cfgBenchmark12_Iterations;++i)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											for(int j=0;j<cfgLeaves;++j)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												for(int k=0;k<cfgLeaves;++k)
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													results[k]=NotEqual(volumes[j],volumes[k]);
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										const int time=(int)wallclock.getTimeMilliseconds();
							 | 
						||
| 
								 | 
							
										printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark12_Reference)*100/time);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if(cfgBenchmark13_Enable)
							 | 
						||
| 
								 | 
							
									{// Benchmark 13	
							 | 
						||
| 
								 | 
							
										srand(380843);
							 | 
						||
| 
								 | 
							
										btDbvt								dbvt;
							 | 
						||
| 
								 | 
							
										btAlignedObjectArray<btVector3>		vectors;
							 | 
						||
| 
								 | 
							
										btDbvtBenchmark::NilPolicy			policy;
							 | 
						||
| 
								 | 
							
										vectors.resize(cfgBenchmark13_Iterations);
							 | 
						||
| 
								 | 
							
										for(int i=0;i<vectors.size();++i)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											vectors[i]=(btDbvtBenchmark::RandVector3()*2-btVector3(1,1,1)).normalized();
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
							 | 
						||
| 
								 | 
							
										dbvt.optimizeTopDown();
							 | 
						||
| 
								 | 
							
										printf("[13] culling(OCL+fullsort): ");
							 | 
						||
| 
								 | 
							
										wallclock.reset();	
							 | 
						||
| 
								 | 
							
										for(int i=0;i<cfgBenchmark13_Iterations;++i)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											static const btScalar	offset=0;
							 | 
						||
| 
								 | 
							
											policy.m_depth=-SIMD_INFINITY;
							 | 
						||
| 
								 | 
							
											dbvt.collideOCL(dbvt.m_root,&vectors[i],&offset,vectors[i],1,policy);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										const int	time=(int)wallclock.getTimeMilliseconds();
							 | 
						||
| 
								 | 
							
										const int	t=cfgBenchmark13_Iterations;
							 | 
						||
| 
								 | 
							
										printf("%u ms (%i%%),(%u t/s)\r\n",time,(time-cfgBenchmark13_Reference)*100/time,(t*1000)/time);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if(cfgBenchmark14_Enable)
							 | 
						||
| 
								 | 
							
									{// Benchmark 14	
							 | 
						||
| 
								 | 
							
										srand(380843);
							 | 
						||
| 
								 | 
							
										btDbvt								dbvt;
							 | 
						||
| 
								 | 
							
										btAlignedObjectArray<btVector3>		vectors;
							 | 
						||
| 
								 | 
							
										btDbvtBenchmark::P14				policy;
							 | 
						||
| 
								 | 
							
										vectors.resize(cfgBenchmark14_Iterations);
							 | 
						||
| 
								 | 
							
										for(int i=0;i<vectors.size();++i)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											vectors[i]=(btDbvtBenchmark::RandVector3()*2-btVector3(1,1,1)).normalized();
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
							 | 
						||
| 
								 | 
							
										dbvt.optimizeTopDown();
							 | 
						||
| 
								 | 
							
										policy.m_nodes.reserve(cfgLeaves);
							 | 
						||
| 
								 | 
							
										printf("[14] culling(OCL+qsort): ");
							 | 
						||
| 
								 | 
							
										wallclock.reset();	
							 | 
						||
| 
								 | 
							
										for(int i=0;i<cfgBenchmark14_Iterations;++i)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											static const btScalar	offset=0;
							 | 
						||
| 
								 | 
							
											policy.m_nodes.resize(0);
							 | 
						||
| 
								 | 
							
											dbvt.collideOCL(dbvt.m_root,&vectors[i],&offset,vectors[i],1,policy,false);
							 | 
						||
| 
								 | 
							
											policy.m_nodes.quickSort(btDbvtBenchmark::P14::sortfnc);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										const int	time=(int)wallclock.getTimeMilliseconds();
							 | 
						||
| 
								 | 
							
										const int	t=cfgBenchmark14_Iterations;
							 | 
						||
| 
								 | 
							
										printf("%u ms (%i%%),(%u t/s)\r\n",time,(time-cfgBenchmark14_Reference)*100/time,(t*1000)/time);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if(cfgBenchmark15_Enable)
							 | 
						||
| 
								 | 
							
									{// Benchmark 15	
							 | 
						||
| 
								 | 
							
										srand(380843);
							 | 
						||
| 
								 | 
							
										btDbvt								dbvt;
							 | 
						||
| 
								 | 
							
										btAlignedObjectArray<btVector3>		vectors;
							 | 
						||
| 
								 | 
							
										btDbvtBenchmark::P15				policy;
							 | 
						||
| 
								 | 
							
										vectors.resize(cfgBenchmark15_Iterations);
							 | 
						||
| 
								 | 
							
										for(int i=0;i<vectors.size();++i)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											vectors[i]=(btDbvtBenchmark::RandVector3()*2-btVector3(1,1,1)).normalized();
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
							 | 
						||
| 
								 | 
							
										dbvt.optimizeTopDown();
							 | 
						||
| 
								 | 
							
										policy.m_nodes.reserve(cfgLeaves);
							 | 
						||
| 
								 | 
							
										printf("[15] culling(KDOP+qsort): ");
							 | 
						||
| 
								 | 
							
										wallclock.reset();	
							 | 
						||
| 
								 | 
							
										for(int i=0;i<cfgBenchmark15_Iterations;++i)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											static const btScalar	offset=0;
							 | 
						||
| 
								 | 
							
											policy.m_nodes.resize(0);
							 | 
						||
| 
								 | 
							
											policy.m_axis=vectors[i];
							 | 
						||
| 
								 | 
							
											dbvt.collideKDOP(dbvt.m_root,&vectors[i],&offset,1,policy);
							 | 
						||
| 
								 | 
							
											policy.m_nodes.quickSort(btDbvtBenchmark::P15::sortfnc);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										const int	time=(int)wallclock.getTimeMilliseconds();
							 | 
						||
| 
								 | 
							
										const int	t=cfgBenchmark15_Iterations;
							 | 
						||
| 
								 | 
							
										printf("%u ms (%i%%),(%u t/s)\r\n",time,(time-cfgBenchmark15_Reference)*100/time,(t*1000)/time);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if(cfgBenchmark16_Enable)
							 | 
						||
| 
								 | 
							
									{// Benchmark 16	
							 | 
						||
| 
								 | 
							
										srand(380843);
							 | 
						||
| 
								 | 
							
										btDbvt								dbvt;
							 | 
						||
| 
								 | 
							
										btAlignedObjectArray<btDbvtNode*>	batch;
							 | 
						||
| 
								 | 
							
										btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
							 | 
						||
| 
								 | 
							
										dbvt.optimizeTopDown();
							 | 
						||
| 
								 | 
							
										batch.reserve(cfgBenchmark16_BatchCount);
							 | 
						||
| 
								 | 
							
										printf("[16] insert/remove batch(%u): ",cfgBenchmark16_BatchCount);
							 | 
						||
| 
								 | 
							
										wallclock.reset();
							 | 
						||
| 
								 | 
							
										for(int i=0;i<cfgBenchmark16_Passes;++i)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											for(int j=0;j<cfgBenchmark16_BatchCount;++j)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												batch.push_back(dbvt.insert(btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale),0));
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											for(int j=0;j<cfgBenchmark16_BatchCount;++j)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												dbvt.remove(batch[j]);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											batch.resize(0);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										const int	time=(int)wallclock.getTimeMilliseconds();
							 | 
						||
| 
								 | 
							
										const int	ir=cfgBenchmark16_Passes*cfgBenchmark16_BatchCount;
							 | 
						||
| 
								 | 
							
										printf("%u ms (%i%%),(%u bir/s)\r\n",time,(time-cfgBenchmark16_Reference)*100/time,int(ir*1000.0/time));
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if(cfgBenchmark17_Enable)
							 | 
						||
| 
								 | 
							
									{// Benchmark 17
							 | 
						||
| 
								 | 
							
										srand(380843);
							 | 
						||
| 
								 | 
							
										btAlignedObjectArray<btDbvtVolume>	volumes;
							 | 
						||
| 
								 | 
							
										btAlignedObjectArray<int>			results;
							 | 
						||
| 
								 | 
							
										btAlignedObjectArray<int>			indices;
							 | 
						||
| 
								 | 
							
										volumes.resize(cfgLeaves);
							 | 
						||
| 
								 | 
							
										results.resize(cfgLeaves);
							 | 
						||
| 
								 | 
							
										indices.resize(cfgLeaves);
							 | 
						||
| 
								 | 
							
										for(int i=0;i<cfgLeaves;++i)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											indices[i]=i;
							 | 
						||
| 
								 | 
							
											volumes[i]=btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										for(int i=0;i<cfgLeaves;++i)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											btSwap(indices[i],indices[rand()%cfgLeaves]);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										printf("[17] btDbvtVolume select: ");
							 | 
						||
| 
								 | 
							
										wallclock.reset();
							 | 
						||
| 
								 | 
							
										for(int i=0;i<cfgBenchmark17_Iterations;++i)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											for(int j=0;j<cfgLeaves;++j)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												for(int k=0;k<cfgLeaves;++k)
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													const int idx=indices[k];
							 | 
						||
| 
								 | 
							
													results[idx]=Select(volumes[idx],volumes[j],volumes[k]);
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										const int time=(int)wallclock.getTimeMilliseconds();
							 | 
						||
| 
								 | 
							
										printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark17_Reference)*100/time);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									printf("\r\n\r\n");
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								#endif
							 |