forked from LeenkxTeam/LNXSDK
		
	
		
			
	
	
		
			1344 lines
		
	
	
		
			34 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			1344 lines
		
	
	
		
			34 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								Bullet Continuous Collision Detection and Physics Library
							 | 
						||
| 
								 | 
							
								Copyright (c) 2003-2007 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
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifndef BT_DYNAMIC_BOUNDING_VOLUME_TREE_H
							 | 
						||
| 
								 | 
							
								#define BT_DYNAMIC_BOUNDING_VOLUME_TREE_H
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include "LinearMath/btAlignedObjectArray.h"
							 | 
						||
| 
								 | 
							
								#include "LinearMath/btVector3.h"
							 | 
						||
| 
								 | 
							
								#include "LinearMath/btTransform.h"
							 | 
						||
| 
								 | 
							
								#include "LinearMath/btAabbUtil2.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// Compile time configuration
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Implementation profiles
							 | 
						||
| 
								 | 
							
								#define DBVT_IMPL_GENERIC		0	// Generic implementation	
							 | 
						||
| 
								 | 
							
								#define DBVT_IMPL_SSE			1	// SSE
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Template implementation of ICollide
							 | 
						||
| 
								 | 
							
								#ifdef _WIN32
							 | 
						||
| 
								 | 
							
								#if (defined (_MSC_VER) && _MSC_VER >= 1400)
							 | 
						||
| 
								 | 
							
								#define	DBVT_USE_TEMPLATE		1
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								#define	DBVT_USE_TEMPLATE		0
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								#define	DBVT_USE_TEMPLATE		0
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Use only intrinsics instead of inline asm
							 | 
						||
| 
								 | 
							
								#define DBVT_USE_INTRINSIC_SSE	1
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Using memmov for collideOCL
							 | 
						||
| 
								 | 
							
								#define DBVT_USE_MEMMOVE		1
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Enable benchmarking code
							 | 
						||
| 
								 | 
							
								#define	DBVT_ENABLE_BENCHMARK	0
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Inlining
							 | 
						||
| 
								 | 
							
								#define DBVT_INLINE				SIMD_FORCE_INLINE
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Specific methods implementation
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//SSE gives errors on a MSVC 7.1
							 | 
						||
| 
								 | 
							
								#if defined (BT_USE_SSE) //&& defined (_WIN32)
							 | 
						||
| 
								 | 
							
								#define DBVT_SELECT_IMPL		DBVT_IMPL_SSE
							 | 
						||
| 
								 | 
							
								#define DBVT_MERGE_IMPL			DBVT_IMPL_SSE
							 | 
						||
| 
								 | 
							
								#define DBVT_INT0_IMPL			DBVT_IMPL_SSE
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								#define DBVT_SELECT_IMPL		DBVT_IMPL_GENERIC
							 | 
						||
| 
								 | 
							
								#define DBVT_MERGE_IMPL			DBVT_IMPL_GENERIC
							 | 
						||
| 
								 | 
							
								#define DBVT_INT0_IMPL			DBVT_IMPL_GENERIC
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if	(DBVT_SELECT_IMPL==DBVT_IMPL_SSE)||	\
							 | 
						||
| 
								 | 
							
									(DBVT_MERGE_IMPL==DBVT_IMPL_SSE)||	\
							 | 
						||
| 
								 | 
							
									(DBVT_INT0_IMPL==DBVT_IMPL_SSE)
							 | 
						||
| 
								 | 
							
								#include <emmintrin.h>
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// Auto config and checks
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if DBVT_USE_TEMPLATE
							 | 
						||
| 
								 | 
							
								#define	DBVT_VIRTUAL
							 | 
						||
| 
								 | 
							
								#define DBVT_VIRTUAL_DTOR(a)
							 | 
						||
| 
								 | 
							
								#define DBVT_PREFIX					template <typename T>
							 | 
						||
| 
								 | 
							
								#define DBVT_IPOLICY				T& policy
							 | 
						||
| 
								 | 
							
								#define DBVT_CHECKTYPE				static const ICollide&	typechecker=*(T*)1;(void)typechecker;
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								#define	DBVT_VIRTUAL_DTOR(a)		virtual ~a() {}
							 | 
						||
| 
								 | 
							
								#define DBVT_VIRTUAL				virtual
							 | 
						||
| 
								 | 
							
								#define DBVT_PREFIX
							 | 
						||
| 
								 | 
							
								#define DBVT_IPOLICY				ICollide& policy
							 | 
						||
| 
								 | 
							
								#define DBVT_CHECKTYPE
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if DBVT_USE_MEMMOVE
							 | 
						||
| 
								 | 
							
								#if !defined( __CELLOS_LV2__) && !defined(__MWERKS__)
							 | 
						||
| 
								 | 
							
								#include <memory.h>
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								#include <string.h>
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifndef DBVT_USE_TEMPLATE
							 | 
						||
| 
								 | 
							
								#error "DBVT_USE_TEMPLATE undefined"
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifndef DBVT_USE_MEMMOVE
							 | 
						||
| 
								 | 
							
								#error "DBVT_USE_MEMMOVE undefined"
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifndef DBVT_ENABLE_BENCHMARK
							 | 
						||
| 
								 | 
							
								#error "DBVT_ENABLE_BENCHMARK undefined"
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifndef DBVT_SELECT_IMPL
							 | 
						||
| 
								 | 
							
								#error "DBVT_SELECT_IMPL undefined"
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifndef DBVT_MERGE_IMPL
							 | 
						||
| 
								 | 
							
								#error "DBVT_MERGE_IMPL undefined"
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifndef DBVT_INT0_IMPL
							 | 
						||
| 
								 | 
							
								#error "DBVT_INT0_IMPL undefined"
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// Defaults volumes
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* btDbvtAabbMm			*/ 
							 | 
						||
| 
								 | 
							
								struct	btDbvtAabbMm
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									DBVT_INLINE btVector3			Center() const	{ return((mi+mx)/2); }
							 | 
						||
| 
								 | 
							
									DBVT_INLINE btVector3			Lengths() const	{ return(mx-mi); }
							 | 
						||
| 
								 | 
							
									DBVT_INLINE btVector3			Extents() const	{ return((mx-mi)/2); }
							 | 
						||
| 
								 | 
							
									DBVT_INLINE const btVector3&	Mins() const	{ return(mi); }
							 | 
						||
| 
								 | 
							
									DBVT_INLINE const btVector3&	Maxs() const	{ return(mx); }
							 | 
						||
| 
								 | 
							
									static inline btDbvtAabbMm		FromCE(const btVector3& c,const btVector3& e);
							 | 
						||
| 
								 | 
							
									static inline btDbvtAabbMm		FromCR(const btVector3& c,btScalar r);
							 | 
						||
| 
								 | 
							
									static inline btDbvtAabbMm		FromMM(const btVector3& mi,const btVector3& mx);
							 | 
						||
| 
								 | 
							
									static inline btDbvtAabbMm		FromPoints(const btVector3* pts,int n);
							 | 
						||
| 
								 | 
							
									static inline btDbvtAabbMm		FromPoints(const btVector3** ppts,int n);
							 | 
						||
| 
								 | 
							
									DBVT_INLINE void				Expand(const btVector3& e);
							 | 
						||
| 
								 | 
							
									DBVT_INLINE void				SignedExpand(const btVector3& e);
							 | 
						||
| 
								 | 
							
									DBVT_INLINE bool				Contain(const btDbvtAabbMm& a) const;
							 | 
						||
| 
								 | 
							
									DBVT_INLINE int					Classify(const btVector3& n,btScalar o,int s) const;
							 | 
						||
| 
								 | 
							
									DBVT_INLINE btScalar			ProjectMinimum(const btVector3& v,unsigned signs) const;
							 | 
						||
| 
								 | 
							
									DBVT_INLINE friend bool			Intersect(	const btDbvtAabbMm& a,
							 | 
						||
| 
								 | 
							
										const btDbvtAabbMm& b);
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									DBVT_INLINE friend bool			Intersect(	const btDbvtAabbMm& a,
							 | 
						||
| 
								 | 
							
										const btVector3& b);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									DBVT_INLINE friend btScalar		Proximity(	const btDbvtAabbMm& a,
							 | 
						||
| 
								 | 
							
										const btDbvtAabbMm& b);
							 | 
						||
| 
								 | 
							
									DBVT_INLINE friend int			Select(		const btDbvtAabbMm& o,
							 | 
						||
| 
								 | 
							
										const btDbvtAabbMm& a,
							 | 
						||
| 
								 | 
							
										const btDbvtAabbMm& b);
							 | 
						||
| 
								 | 
							
									DBVT_INLINE friend void			Merge(		const btDbvtAabbMm& a,
							 | 
						||
| 
								 | 
							
										const btDbvtAabbMm& b,
							 | 
						||
| 
								 | 
							
										btDbvtAabbMm& r);
							 | 
						||
| 
								 | 
							
									DBVT_INLINE friend bool			NotEqual(	const btDbvtAabbMm& a,
							 | 
						||
| 
								 | 
							
										const btDbvtAabbMm& b);
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    DBVT_INLINE btVector3&	tMins()	{ return(mi); }
							 | 
						||
| 
								 | 
							
									DBVT_INLINE btVector3&	tMaxs()	{ return(mx); }
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								private:
							 | 
						||
| 
								 | 
							
									DBVT_INLINE void				AddSpan(const btVector3& d,btScalar& smi,btScalar& smx) const;
							 | 
						||
| 
								 | 
							
								private:
							 | 
						||
| 
								 | 
							
									btVector3	mi,mx;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Types	
							 | 
						||
| 
								 | 
							
								typedef	btDbvtAabbMm	btDbvtVolume;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* btDbvtNode				*/ 
							 | 
						||
| 
								 | 
							
								struct	btDbvtNode
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									btDbvtVolume	volume;
							 | 
						||
| 
								 | 
							
									btDbvtNode*		parent;
							 | 
						||
| 
								 | 
							
									DBVT_INLINE bool	isleaf() const		{ return(childs[1]==0); }
							 | 
						||
| 
								 | 
							
									DBVT_INLINE bool	isinternal() const	{ return(!isleaf()); }
							 | 
						||
| 
								 | 
							
									union
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										btDbvtNode*	childs[2];
							 | 
						||
| 
								 | 
							
										void*	data;
							 | 
						||
| 
								 | 
							
										int		dataAsInt;
							 | 
						||
| 
								 | 
							
									};
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								typedef btAlignedObjectArray<const btDbvtNode*> btNodeStack;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								///The btDbvt class implements a fast dynamic bounding volume tree based on axis aligned bounding boxes (aabb tree).
							 | 
						||
| 
								 | 
							
								///This btDbvt is used for soft body collision detection and for the btDbvtBroadphase. It has a fast insert, remove and update of nodes.
							 | 
						||
| 
								 | 
							
								///Unlike the btQuantizedBvh, nodes can be dynamically moved around, which allows for change in topology of the underlying data structure.
							 | 
						||
| 
								 | 
							
								struct	btDbvt
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									/* Stack element	*/ 
							 | 
						||
| 
								 | 
							
									struct	sStkNN
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										const btDbvtNode*	a;
							 | 
						||
| 
								 | 
							
										const btDbvtNode*	b;
							 | 
						||
| 
								 | 
							
										sStkNN() {}
							 | 
						||
| 
								 | 
							
										sStkNN(const btDbvtNode* na,const btDbvtNode* nb) : a(na),b(nb) {}
							 | 
						||
| 
								 | 
							
									};
							 | 
						||
| 
								 | 
							
									struct	sStkNP
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										const btDbvtNode*	node;
							 | 
						||
| 
								 | 
							
										int			mask;
							 | 
						||
| 
								 | 
							
										sStkNP(const btDbvtNode* n,unsigned m) : node(n),mask(m) {}
							 | 
						||
| 
								 | 
							
									};
							 | 
						||
| 
								 | 
							
									struct	sStkNPS
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										const btDbvtNode*	node;
							 | 
						||
| 
								 | 
							
										int			mask;
							 | 
						||
| 
								 | 
							
										btScalar	value;
							 | 
						||
| 
								 | 
							
										sStkNPS() {}
							 | 
						||
| 
								 | 
							
										sStkNPS(const btDbvtNode* n,unsigned m,btScalar v) : node(n),mask(m),value(v) {}
							 | 
						||
| 
								 | 
							
									};
							 | 
						||
| 
								 | 
							
									struct	sStkCLN
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										const btDbvtNode*	node;
							 | 
						||
| 
								 | 
							
										btDbvtNode*		parent;
							 | 
						||
| 
								 | 
							
										sStkCLN(const btDbvtNode* n,btDbvtNode* p) : node(n),parent(p) {}
							 | 
						||
| 
								 | 
							
									};
							 | 
						||
| 
								 | 
							
									// Policies/Interfaces
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* ICollide	*/ 
							 | 
						||
| 
								 | 
							
									struct	ICollide
							 | 
						||
| 
								 | 
							
									{		
							 | 
						||
| 
								 | 
							
										DBVT_VIRTUAL_DTOR(ICollide)
							 | 
						||
| 
								 | 
							
											DBVT_VIRTUAL void	Process(const btDbvtNode*,const btDbvtNode*)		{}
							 | 
						||
| 
								 | 
							
										DBVT_VIRTUAL void	Process(const btDbvtNode*)					{}
							 | 
						||
| 
								 | 
							
										DBVT_VIRTUAL void	Process(const btDbvtNode* n,btScalar)			{ Process(n); }
							 | 
						||
| 
								 | 
							
										DBVT_VIRTUAL bool	Descent(const btDbvtNode*)					{ return(true); }
							 | 
						||
| 
								 | 
							
										DBVT_VIRTUAL bool	AllLeaves(const btDbvtNode*)					{ return(true); }
							 | 
						||
| 
								 | 
							
									};
							 | 
						||
| 
								 | 
							
									/* IWriter	*/ 
							 | 
						||
| 
								 | 
							
									struct	IWriter
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										virtual ~IWriter() {}
							 | 
						||
| 
								 | 
							
										virtual void		Prepare(const btDbvtNode* root,int numnodes)=0;
							 | 
						||
| 
								 | 
							
										virtual void		WriteNode(const btDbvtNode*,int index,int parent,int child0,int child1)=0;
							 | 
						||
| 
								 | 
							
										virtual void		WriteLeaf(const btDbvtNode*,int index,int parent)=0;
							 | 
						||
| 
								 | 
							
									};
							 | 
						||
| 
								 | 
							
									/* IClone	*/ 
							 | 
						||
| 
								 | 
							
									struct	IClone
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										virtual ~IClone()	{}
							 | 
						||
| 
								 | 
							
										virtual void		CloneLeaf(btDbvtNode*) {}
							 | 
						||
| 
								 | 
							
									};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// Constants
							 | 
						||
| 
								 | 
							
									enum	{
							 | 
						||
| 
								 | 
							
										SIMPLE_STACKSIZE	=	64,
							 | 
						||
| 
								 | 
							
										DOUBLE_STACKSIZE	=	SIMPLE_STACKSIZE*2
							 | 
						||
| 
								 | 
							
									};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// Fields
							 | 
						||
| 
								 | 
							
									btDbvtNode*		m_root;
							 | 
						||
| 
								 | 
							
									btDbvtNode*		m_free;
							 | 
						||
| 
								 | 
							
									int				m_lkhd;
							 | 
						||
| 
								 | 
							
									int				m_leaves;
							 | 
						||
| 
								 | 
							
									unsigned		m_opath;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									btAlignedObjectArray<sStkNN>	m_stkStack;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// Methods
							 | 
						||
| 
								 | 
							
									btDbvt();
							 | 
						||
| 
								 | 
							
									~btDbvt();
							 | 
						||
| 
								 | 
							
									void			clear();
							 | 
						||
| 
								 | 
							
									bool			empty() const { return(0==m_root); }
							 | 
						||
| 
								 | 
							
									void			optimizeBottomUp();
							 | 
						||
| 
								 | 
							
									void			optimizeTopDown(int bu_treshold=128);
							 | 
						||
| 
								 | 
							
									void			optimizeIncremental(int passes);
							 | 
						||
| 
								 | 
							
									btDbvtNode*		insert(const btDbvtVolume& box,void* data);
							 | 
						||
| 
								 | 
							
									void			update(btDbvtNode* leaf,int lookahead=-1);
							 | 
						||
| 
								 | 
							
									void			update(btDbvtNode* leaf,btDbvtVolume& volume);
							 | 
						||
| 
								 | 
							
									bool			update(btDbvtNode* leaf,btDbvtVolume& volume,const btVector3& velocity,btScalar margin);
							 | 
						||
| 
								 | 
							
									bool			update(btDbvtNode* leaf,btDbvtVolume& volume,const btVector3& velocity);
							 | 
						||
| 
								 | 
							
									bool			update(btDbvtNode* leaf,btDbvtVolume& volume,btScalar margin);	
							 | 
						||
| 
								 | 
							
									void			remove(btDbvtNode* leaf);
							 | 
						||
| 
								 | 
							
									void			write(IWriter* iwriter) const;
							 | 
						||
| 
								 | 
							
									void			clone(btDbvt& dest,IClone* iclone=0) const;
							 | 
						||
| 
								 | 
							
									static int		maxdepth(const btDbvtNode* node);
							 | 
						||
| 
								 | 
							
									static int		countLeaves(const btDbvtNode* node);
							 | 
						||
| 
								 | 
							
									static void		extractLeaves(const btDbvtNode* node,btAlignedObjectArray<const btDbvtNode*>& leaves);
							 | 
						||
| 
								 | 
							
								#if DBVT_ENABLE_BENCHMARK
							 | 
						||
| 
								 | 
							
									static void		benchmark();
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
									static void		benchmark(){}
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
									// DBVT_IPOLICY must support ICollide policy/interface
							 | 
						||
| 
								 | 
							
									DBVT_PREFIX
							 | 
						||
| 
								 | 
							
										static void		enumNodes(	const btDbvtNode* root,
							 | 
						||
| 
								 | 
							
										DBVT_IPOLICY);
							 | 
						||
| 
								 | 
							
									DBVT_PREFIX
							 | 
						||
| 
								 | 
							
										static void		enumLeaves(	const btDbvtNode* root,
							 | 
						||
| 
								 | 
							
										DBVT_IPOLICY);
							 | 
						||
| 
								 | 
							
									DBVT_PREFIX
							 | 
						||
| 
								 | 
							
										void		collideTT(	const btDbvtNode* root0,
							 | 
						||
| 
								 | 
							
										const btDbvtNode* root1,
							 | 
						||
| 
								 | 
							
										DBVT_IPOLICY);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									DBVT_PREFIX
							 | 
						||
| 
								 | 
							
										void		collideTTpersistentStack(	const btDbvtNode* root0,
							 | 
						||
| 
								 | 
							
										  const btDbvtNode* root1,
							 | 
						||
| 
								 | 
							
										  DBVT_IPOLICY);
							 | 
						||
| 
								 | 
							
								#if 0
							 | 
						||
| 
								 | 
							
									DBVT_PREFIX
							 | 
						||
| 
								 | 
							
										void		collideTT(	const btDbvtNode* root0,
							 | 
						||
| 
								 | 
							
										const btDbvtNode* root1,
							 | 
						||
| 
								 | 
							
										const btTransform& xform,
							 | 
						||
| 
								 | 
							
										DBVT_IPOLICY);
							 | 
						||
| 
								 | 
							
									DBVT_PREFIX
							 | 
						||
| 
								 | 
							
										void		collideTT(	const btDbvtNode* root0,
							 | 
						||
| 
								 | 
							
										const btTransform& xform0,
							 | 
						||
| 
								 | 
							
										const btDbvtNode* root1,
							 | 
						||
| 
								 | 
							
										const btTransform& xform1,
							 | 
						||
| 
								 | 
							
										DBVT_IPOLICY);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									DBVT_PREFIX
							 | 
						||
| 
								 | 
							
										void		collideTV(	const btDbvtNode* root,
							 | 
						||
| 
								 | 
							
										const btDbvtVolume& volume,
							 | 
						||
| 
								 | 
							
										DBVT_IPOLICY) const;
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									DBVT_PREFIX
							 | 
						||
| 
								 | 
							
									void		collideTVNoStackAlloc(	const btDbvtNode* root,
							 | 
						||
| 
								 | 
							
														  const btDbvtVolume& volume,
							 | 
						||
| 
								 | 
							
														  btNodeStack& stack,
							 | 
						||
| 
								 | 
							
														  DBVT_IPOLICY) const;
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									///rayTest is a re-entrant ray test, and can be called in parallel as long as the btAlignedAlloc is thread-safe (uses locking etc)
							 | 
						||
| 
								 | 
							
									///rayTest is slower than rayTestInternal, because it builds a local stack, using memory allocations, and it recomputes signs/rayDirectionInverses each time
							 | 
						||
| 
								 | 
							
									DBVT_PREFIX
							 | 
						||
| 
								 | 
							
										static void		rayTest(	const btDbvtNode* root,
							 | 
						||
| 
								 | 
							
										const btVector3& rayFrom,
							 | 
						||
| 
								 | 
							
										const btVector3& rayTo,
							 | 
						||
| 
								 | 
							
										DBVT_IPOLICY);
							 | 
						||
| 
								 | 
							
									///rayTestInternal is faster than rayTest, because it uses a persistent stack (to reduce dynamic memory allocations to a minimum) and it uses precomputed signs/rayInverseDirections
							 | 
						||
| 
								 | 
							
									///rayTestInternal is used by btDbvtBroadphase to accelerate world ray casts
							 | 
						||
| 
								 | 
							
									DBVT_PREFIX
							 | 
						||
| 
								 | 
							
										void		rayTestInternal(	const btDbvtNode* root,
							 | 
						||
| 
								 | 
							
																const btVector3& rayFrom,
							 | 
						||
| 
								 | 
							
																const btVector3& rayTo,
							 | 
						||
| 
								 | 
							
																const btVector3& rayDirectionInverse,
							 | 
						||
| 
								 | 
							
																unsigned int signs[3],
							 | 
						||
| 
								 | 
							
																btScalar lambda_max,
							 | 
						||
| 
								 | 
							
																const btVector3& aabbMin,
							 | 
						||
| 
								 | 
							
																const btVector3& aabbMax,
							 | 
						||
| 
								 | 
							
								                                btAlignedObjectArray<const btDbvtNode*>& stack,
							 | 
						||
| 
								 | 
							
																DBVT_IPOLICY) const;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									DBVT_PREFIX
							 | 
						||
| 
								 | 
							
										static void		collideKDOP(const btDbvtNode* root,
							 | 
						||
| 
								 | 
							
										const btVector3* normals,
							 | 
						||
| 
								 | 
							
										const btScalar* offsets,
							 | 
						||
| 
								 | 
							
										int count,
							 | 
						||
| 
								 | 
							
										DBVT_IPOLICY);
							 | 
						||
| 
								 | 
							
									DBVT_PREFIX
							 | 
						||
| 
								 | 
							
										static void		collideOCL(	const btDbvtNode* root,
							 | 
						||
| 
								 | 
							
										const btVector3* normals,
							 | 
						||
| 
								 | 
							
										const btScalar* offsets,
							 | 
						||
| 
								 | 
							
										const btVector3& sortaxis,
							 | 
						||
| 
								 | 
							
										int count,								
							 | 
						||
| 
								 | 
							
										DBVT_IPOLICY,
							 | 
						||
| 
								 | 
							
										bool fullsort=true);
							 | 
						||
| 
								 | 
							
									DBVT_PREFIX
							 | 
						||
| 
								 | 
							
										static void		collideTU(	const btDbvtNode* root,
							 | 
						||
| 
								 | 
							
										DBVT_IPOLICY);
							 | 
						||
| 
								 | 
							
									// Helpers	
							 | 
						||
| 
								 | 
							
									static DBVT_INLINE int	nearest(const int* i,const btDbvt::sStkNPS* a,btScalar v,int l,int h)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										int	m=0;
							 | 
						||
| 
								 | 
							
										while(l<h)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											m=(l+h)>>1;
							 | 
						||
| 
								 | 
							
											if(a[i[m]].value>=v) l=m+1; else h=m;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										return(h);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									static DBVT_INLINE int	allocate(	btAlignedObjectArray<int>& ifree,
							 | 
						||
| 
								 | 
							
										btAlignedObjectArray<sStkNPS>& stock,
							 | 
						||
| 
								 | 
							
										const sStkNPS& value)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										int	i;
							 | 
						||
| 
								 | 
							
										if(ifree.size()>0)
							 | 
						||
| 
								 | 
							
										{ i=ifree[ifree.size()-1];ifree.pop_back();stock[i]=value; }
							 | 
						||
| 
								 | 
							
										else
							 | 
						||
| 
								 | 
							
										{ i=stock.size();stock.push_back(value); }
							 | 
						||
| 
								 | 
							
										return(i); 
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									//
							 | 
						||
| 
								 | 
							
								private:
							 | 
						||
| 
								 | 
							
									btDbvt(const btDbvt&)	{}	
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// Inline's
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								inline btDbvtAabbMm			btDbvtAabbMm::FromCE(const btVector3& c,const btVector3& e)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									btDbvtAabbMm box;
							 | 
						||
| 
								 | 
							
									box.mi=c-e;box.mx=c+e;
							 | 
						||
| 
								 | 
							
									return(box);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								inline btDbvtAabbMm			btDbvtAabbMm::FromCR(const btVector3& c,btScalar r)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									return(FromCE(c,btVector3(r,r,r)));
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								inline btDbvtAabbMm			btDbvtAabbMm::FromMM(const btVector3& mi,const btVector3& mx)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									btDbvtAabbMm box;
							 | 
						||
| 
								 | 
							
									box.mi=mi;box.mx=mx;
							 | 
						||
| 
								 | 
							
									return(box);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								inline btDbvtAabbMm			btDbvtAabbMm::FromPoints(const btVector3* pts,int n)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									btDbvtAabbMm box;
							 | 
						||
| 
								 | 
							
									box.mi=box.mx=pts[0];
							 | 
						||
| 
								 | 
							
									for(int i=1;i<n;++i)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										box.mi.setMin(pts[i]);
							 | 
						||
| 
								 | 
							
										box.mx.setMax(pts[i]);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return(box);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								inline btDbvtAabbMm			btDbvtAabbMm::FromPoints(const btVector3** ppts,int n)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									btDbvtAabbMm box;
							 | 
						||
| 
								 | 
							
									box.mi=box.mx=*ppts[0];
							 | 
						||
| 
								 | 
							
									for(int i=1;i<n;++i)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										box.mi.setMin(*ppts[i]);
							 | 
						||
| 
								 | 
							
										box.mx.setMax(*ppts[i]);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return(box);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								DBVT_INLINE void		btDbvtAabbMm::Expand(const btVector3& e)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									mi-=e;mx+=e;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								DBVT_INLINE void		btDbvtAabbMm::SignedExpand(const btVector3& e)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									if(e.x()>0) mx.setX(mx.x()+e[0]); else mi.setX(mi.x()+e[0]);
							 | 
						||
| 
								 | 
							
									if(e.y()>0) mx.setY(mx.y()+e[1]); else mi.setY(mi.y()+e[1]);
							 | 
						||
| 
								 | 
							
									if(e.z()>0) mx.setZ(mx.z()+e[2]); else mi.setZ(mi.z()+e[2]);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								DBVT_INLINE bool		btDbvtAabbMm::Contain(const btDbvtAabbMm& a) const
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									return(	(mi.x()<=a.mi.x())&&
							 | 
						||
| 
								 | 
							
										(mi.y()<=a.mi.y())&&
							 | 
						||
| 
								 | 
							
										(mi.z()<=a.mi.z())&&
							 | 
						||
| 
								 | 
							
										(mx.x()>=a.mx.x())&&
							 | 
						||
| 
								 | 
							
										(mx.y()>=a.mx.y())&&
							 | 
						||
| 
								 | 
							
										(mx.z()>=a.mx.z()));
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								DBVT_INLINE int		btDbvtAabbMm::Classify(const btVector3& n,btScalar o,int s) const
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									btVector3			pi,px;
							 | 
						||
| 
								 | 
							
									switch(s)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
									case	(0+0+0):	px=btVector3(mi.x(),mi.y(),mi.z());
							 | 
						||
| 
								 | 
							
										pi=btVector3(mx.x(),mx.y(),mx.z());break;
							 | 
						||
| 
								 | 
							
									case	(1+0+0):	px=btVector3(mx.x(),mi.y(),mi.z());
							 | 
						||
| 
								 | 
							
										pi=btVector3(mi.x(),mx.y(),mx.z());break;
							 | 
						||
| 
								 | 
							
									case	(0+2+0):	px=btVector3(mi.x(),mx.y(),mi.z());
							 | 
						||
| 
								 | 
							
										pi=btVector3(mx.x(),mi.y(),mx.z());break;
							 | 
						||
| 
								 | 
							
									case	(1+2+0):	px=btVector3(mx.x(),mx.y(),mi.z());
							 | 
						||
| 
								 | 
							
										pi=btVector3(mi.x(),mi.y(),mx.z());break;
							 | 
						||
| 
								 | 
							
									case	(0+0+4):	px=btVector3(mi.x(),mi.y(),mx.z());
							 | 
						||
| 
								 | 
							
										pi=btVector3(mx.x(),mx.y(),mi.z());break;
							 | 
						||
| 
								 | 
							
									case	(1+0+4):	px=btVector3(mx.x(),mi.y(),mx.z());
							 | 
						||
| 
								 | 
							
										pi=btVector3(mi.x(),mx.y(),mi.z());break;
							 | 
						||
| 
								 | 
							
									case	(0+2+4):	px=btVector3(mi.x(),mx.y(),mx.z());
							 | 
						||
| 
								 | 
							
										pi=btVector3(mx.x(),mi.y(),mi.z());break;
							 | 
						||
| 
								 | 
							
									case	(1+2+4):	px=btVector3(mx.x(),mx.y(),mx.z());
							 | 
						||
| 
								 | 
							
										pi=btVector3(mi.x(),mi.y(),mi.z());break;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if((btDot(n,px)+o)<0)		return(-1);
							 | 
						||
| 
								 | 
							
									if((btDot(n,pi)+o)>=0)	return(+1);
							 | 
						||
| 
								 | 
							
									return(0);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								DBVT_INLINE btScalar	btDbvtAabbMm::ProjectMinimum(const btVector3& v,unsigned signs) const
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									const btVector3*	b[]={&mx,&mi};
							 | 
						||
| 
								 | 
							
									const btVector3		p(	b[(signs>>0)&1]->x(),
							 | 
						||
| 
								 | 
							
										b[(signs>>1)&1]->y(),
							 | 
						||
| 
								 | 
							
										b[(signs>>2)&1]->z());
							 | 
						||
| 
								 | 
							
									return(btDot(p,v));
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								DBVT_INLINE void		btDbvtAabbMm::AddSpan(const btVector3& d,btScalar& smi,btScalar& smx) const
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									for(int i=0;i<3;++i)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										if(d[i]<0)
							 | 
						||
| 
								 | 
							
										{ smi+=mx[i]*d[i];smx+=mi[i]*d[i]; }
							 | 
						||
| 
								 | 
							
										else
							 | 
						||
| 
								 | 
							
										{ smi+=mi[i]*d[i];smx+=mx[i]*d[i]; }
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								DBVT_INLINE bool		Intersect(	const btDbvtAabbMm& a,
							 | 
						||
| 
								 | 
							
																  const btDbvtAabbMm& b)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								#if	DBVT_INT0_IMPL == DBVT_IMPL_SSE
							 | 
						||
| 
								 | 
							
									const __m128	rt(_mm_or_ps(	_mm_cmplt_ps(_mm_load_ps(b.mx),_mm_load_ps(a.mi)),
							 | 
						||
| 
								 | 
							
										_mm_cmplt_ps(_mm_load_ps(a.mx),_mm_load_ps(b.mi))));
							 | 
						||
| 
								 | 
							
								#if defined (_WIN32)
							 | 
						||
| 
								 | 
							
									const __int32*	pu((const __int32*)&rt);
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								    const int*	pu((const int*)&rt);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
									return((pu[0]|pu[1]|pu[2])==0);
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
									return(	(a.mi.x()<=b.mx.x())&&
							 | 
						||
| 
								 | 
							
										(a.mx.x()>=b.mi.x())&&
							 | 
						||
| 
								 | 
							
										(a.mi.y()<=b.mx.y())&&
							 | 
						||
| 
								 | 
							
										(a.mx.y()>=b.mi.y())&&
							 | 
						||
| 
								 | 
							
										(a.mi.z()<=b.mx.z())&&		
							 | 
						||
| 
								 | 
							
										(a.mx.z()>=b.mi.z()));
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								DBVT_INLINE bool		Intersect(	const btDbvtAabbMm& a,
							 | 
						||
| 
								 | 
							
																  const btVector3& b)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									return(	(b.x()>=a.mi.x())&&
							 | 
						||
| 
								 | 
							
										(b.y()>=a.mi.y())&&
							 | 
						||
| 
								 | 
							
										(b.z()>=a.mi.z())&&
							 | 
						||
| 
								 | 
							
										(b.x()<=a.mx.x())&&
							 | 
						||
| 
								 | 
							
										(b.y()<=a.mx.y())&&
							 | 
						||
| 
								 | 
							
										(b.z()<=a.mx.z()));
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//////////////////////////////////////
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								DBVT_INLINE btScalar	Proximity(	const btDbvtAabbMm& a,
							 | 
						||
| 
								 | 
							
																  const btDbvtAabbMm& b)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									const btVector3	d=(a.mi+a.mx)-(b.mi+b.mx);
							 | 
						||
| 
								 | 
							
									return(btFabs(d.x())+btFabs(d.y())+btFabs(d.z()));
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								DBVT_INLINE int			Select(	const btDbvtAabbMm& o,
							 | 
						||
| 
								 | 
							
															   const btDbvtAabbMm& a,
							 | 
						||
| 
								 | 
							
															   const btDbvtAabbMm& b)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								#if	DBVT_SELECT_IMPL == DBVT_IMPL_SSE
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								#if defined (_WIN32)
							 | 
						||
| 
								 | 
							
									static ATTRIBUTE_ALIGNED16(const unsigned __int32)	mask[]={0x7fffffff,0x7fffffff,0x7fffffff,0x7fffffff};
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								    static ATTRIBUTE_ALIGNED16(const unsigned int)	mask[]={0x7fffffff,0x7fffffff,0x7fffffff,0x00000000 /*0x7fffffff*/};
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
									///@todo: the intrinsic version is 11% slower
							 | 
						||
| 
								 | 
							
								#if DBVT_USE_INTRINSIC_SSE
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									union btSSEUnion ///NOTE: if we use more intrinsics, move btSSEUnion into the LinearMath directory
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
									   __m128		ssereg;
							 | 
						||
| 
								 | 
							
									   float		floats[4];
							 | 
						||
| 
								 | 
							
									   int			ints[4];
							 | 
						||
| 
								 | 
							
									};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									__m128	omi(_mm_load_ps(o.mi));
							 | 
						||
| 
								 | 
							
									omi=_mm_add_ps(omi,_mm_load_ps(o.mx));
							 | 
						||
| 
								 | 
							
									__m128	ami(_mm_load_ps(a.mi));
							 | 
						||
| 
								 | 
							
									ami=_mm_add_ps(ami,_mm_load_ps(a.mx));
							 | 
						||
| 
								 | 
							
									ami=_mm_sub_ps(ami,omi);
							 | 
						||
| 
								 | 
							
									ami=_mm_and_ps(ami,_mm_load_ps((const float*)mask));
							 | 
						||
| 
								 | 
							
									__m128	bmi(_mm_load_ps(b.mi));
							 | 
						||
| 
								 | 
							
									bmi=_mm_add_ps(bmi,_mm_load_ps(b.mx));
							 | 
						||
| 
								 | 
							
									bmi=_mm_sub_ps(bmi,omi);
							 | 
						||
| 
								 | 
							
									bmi=_mm_and_ps(bmi,_mm_load_ps((const float*)mask));
							 | 
						||
| 
								 | 
							
									__m128	t0(_mm_movehl_ps(ami,ami));
							 | 
						||
| 
								 | 
							
									ami=_mm_add_ps(ami,t0);
							 | 
						||
| 
								 | 
							
									ami=_mm_add_ss(ami,_mm_shuffle_ps(ami,ami,1));
							 | 
						||
| 
								 | 
							
									__m128 t1(_mm_movehl_ps(bmi,bmi));
							 | 
						||
| 
								 | 
							
									bmi=_mm_add_ps(bmi,t1);
							 | 
						||
| 
								 | 
							
									bmi=_mm_add_ss(bmi,_mm_shuffle_ps(bmi,bmi,1));
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									btSSEUnion tmp;
							 | 
						||
| 
								 | 
							
									tmp.ssereg = _mm_cmple_ss(bmi,ami);
							 | 
						||
| 
								 | 
							
									return tmp.ints[0]&1;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
									ATTRIBUTE_ALIGNED16(__int32	r[1]);
							 | 
						||
| 
								 | 
							
									__asm
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										mov		eax,o
							 | 
						||
| 
								 | 
							
											mov		ecx,a
							 | 
						||
| 
								 | 
							
											mov		edx,b
							 | 
						||
| 
								 | 
							
											movaps	xmm0,[eax]
							 | 
						||
| 
								 | 
							
										movaps	xmm5,mask
							 | 
						||
| 
								 | 
							
											addps	xmm0,[eax+16]	
							 | 
						||
| 
								 | 
							
										movaps	xmm1,[ecx]
							 | 
						||
| 
								 | 
							
										movaps	xmm2,[edx]
							 | 
						||
| 
								 | 
							
										addps	xmm1,[ecx+16]
							 | 
						||
| 
								 | 
							
										addps	xmm2,[edx+16]
							 | 
						||
| 
								 | 
							
										subps	xmm1,xmm0
							 | 
						||
| 
								 | 
							
											subps	xmm2,xmm0
							 | 
						||
| 
								 | 
							
											andps	xmm1,xmm5
							 | 
						||
| 
								 | 
							
											andps	xmm2,xmm5
							 | 
						||
| 
								 | 
							
											movhlps	xmm3,xmm1
							 | 
						||
| 
								 | 
							
											movhlps	xmm4,xmm2
							 | 
						||
| 
								 | 
							
											addps	xmm1,xmm3
							 | 
						||
| 
								 | 
							
											addps	xmm2,xmm4
							 | 
						||
| 
								 | 
							
											pshufd	xmm3,xmm1,1
							 | 
						||
| 
								 | 
							
											pshufd	xmm4,xmm2,1
							 | 
						||
| 
								 | 
							
											addss	xmm1,xmm3
							 | 
						||
| 
								 | 
							
											addss	xmm2,xmm4
							 | 
						||
| 
								 | 
							
											cmpless	xmm2,xmm1
							 | 
						||
| 
								 | 
							
											movss	r,xmm2
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return(r[0]&1);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
									return(Proximity(o,a)<Proximity(o,b)?0:1);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								DBVT_INLINE void		Merge(	const btDbvtAabbMm& a,
							 | 
						||
| 
								 | 
							
															  const btDbvtAabbMm& b,
							 | 
						||
| 
								 | 
							
															  btDbvtAabbMm& r)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								#if DBVT_MERGE_IMPL==DBVT_IMPL_SSE
							 | 
						||
| 
								 | 
							
									__m128	ami(_mm_load_ps(a.mi));
							 | 
						||
| 
								 | 
							
									__m128	amx(_mm_load_ps(a.mx));
							 | 
						||
| 
								 | 
							
									__m128	bmi(_mm_load_ps(b.mi));
							 | 
						||
| 
								 | 
							
									__m128	bmx(_mm_load_ps(b.mx));
							 | 
						||
| 
								 | 
							
									ami=_mm_min_ps(ami,bmi);
							 | 
						||
| 
								 | 
							
									amx=_mm_max_ps(amx,bmx);
							 | 
						||
| 
								 | 
							
									_mm_store_ps(r.mi,ami);
							 | 
						||
| 
								 | 
							
									_mm_store_ps(r.mx,amx);
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
									for(int i=0;i<3;++i)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										if(a.mi[i]<b.mi[i]) r.mi[i]=a.mi[i]; else r.mi[i]=b.mi[i];
							 | 
						||
| 
								 | 
							
										if(a.mx[i]>b.mx[i]) r.mx[i]=a.mx[i]; else r.mx[i]=b.mx[i];
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								DBVT_INLINE bool		NotEqual(	const btDbvtAabbMm& a,
							 | 
						||
| 
								 | 
							
																 const btDbvtAabbMm& b)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									return(	(a.mi.x()!=b.mi.x())||
							 | 
						||
| 
								 | 
							
										(a.mi.y()!=b.mi.y())||
							 | 
						||
| 
								 | 
							
										(a.mi.z()!=b.mi.z())||
							 | 
						||
| 
								 | 
							
										(a.mx.x()!=b.mx.x())||
							 | 
						||
| 
								 | 
							
										(a.mx.y()!=b.mx.y())||
							 | 
						||
| 
								 | 
							
										(a.mx.z()!=b.mx.z()));
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// Inline's
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								DBVT_PREFIX
							 | 
						||
| 
								 | 
							
								inline void		btDbvt::enumNodes(	const btDbvtNode* root,
							 | 
						||
| 
								 | 
							
																  DBVT_IPOLICY)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									DBVT_CHECKTYPE
							 | 
						||
| 
								 | 
							
										policy.Process(root);
							 | 
						||
| 
								 | 
							
									if(root->isinternal())
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										enumNodes(root->childs[0],policy);
							 | 
						||
| 
								 | 
							
										enumNodes(root->childs[1],policy);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								DBVT_PREFIX
							 | 
						||
| 
								 | 
							
								inline void		btDbvt::enumLeaves(	const btDbvtNode* root,
							 | 
						||
| 
								 | 
							
																   DBVT_IPOLICY)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									DBVT_CHECKTYPE
							 | 
						||
| 
								 | 
							
										if(root->isinternal())
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											enumLeaves(root->childs[0],policy);
							 | 
						||
| 
								 | 
							
											enumLeaves(root->childs[1],policy);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											policy.Process(root);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								DBVT_PREFIX
							 | 
						||
| 
								 | 
							
								inline void		btDbvt::collideTT(	const btDbvtNode* root0,
							 | 
						||
| 
								 | 
							
																  const btDbvtNode* root1,
							 | 
						||
| 
								 | 
							
																  DBVT_IPOLICY)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									DBVT_CHECKTYPE
							 | 
						||
| 
								 | 
							
										if(root0&&root1)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											int								depth=1;
							 | 
						||
| 
								 | 
							
											int								treshold=DOUBLE_STACKSIZE-4;
							 | 
						||
| 
								 | 
							
											btAlignedObjectArray<sStkNN>	stkStack;
							 | 
						||
| 
								 | 
							
											stkStack.resize(DOUBLE_STACKSIZE);
							 | 
						||
| 
								 | 
							
											stkStack[0]=sStkNN(root0,root1);
							 | 
						||
| 
								 | 
							
											do	{		
							 | 
						||
| 
								 | 
							
												sStkNN	p=stkStack[--depth];
							 | 
						||
| 
								 | 
							
												if(depth>treshold)
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													stkStack.resize(stkStack.size()*2);
							 | 
						||
| 
								 | 
							
													treshold=stkStack.size()-4;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												if(p.a==p.b)
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													if(p.a->isinternal())
							 | 
						||
| 
								 | 
							
													{
							 | 
						||
| 
								 | 
							
														stkStack[depth++]=sStkNN(p.a->childs[0],p.a->childs[0]);
							 | 
						||
| 
								 | 
							
														stkStack[depth++]=sStkNN(p.a->childs[1],p.a->childs[1]);
							 | 
						||
| 
								 | 
							
														stkStack[depth++]=sStkNN(p.a->childs[0],p.a->childs[1]);
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												else if(Intersect(p.a->volume,p.b->volume))
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													if(p.a->isinternal())
							 | 
						||
| 
								 | 
							
													{
							 | 
						||
| 
								 | 
							
														if(p.b->isinternal())
							 | 
						||
| 
								 | 
							
														{
							 | 
						||
| 
								 | 
							
															stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[0]);
							 | 
						||
| 
								 | 
							
															stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[0]);
							 | 
						||
| 
								 | 
							
															stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[1]);
							 | 
						||
| 
								 | 
							
															stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[1]);
							 | 
						||
| 
								 | 
							
														}
							 | 
						||
| 
								 | 
							
														else
							 | 
						||
| 
								 | 
							
														{
							 | 
						||
| 
								 | 
							
															stkStack[depth++]=sStkNN(p.a->childs[0],p.b);
							 | 
						||
| 
								 | 
							
															stkStack[depth++]=sStkNN(p.a->childs[1],p.b);
							 | 
						||
| 
								 | 
							
														}
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
													else
							 | 
						||
| 
								 | 
							
													{
							 | 
						||
| 
								 | 
							
														if(p.b->isinternal())
							 | 
						||
| 
								 | 
							
														{
							 | 
						||
| 
								 | 
							
															stkStack[depth++]=sStkNN(p.a,p.b->childs[0]);
							 | 
						||
| 
								 | 
							
															stkStack[depth++]=sStkNN(p.a,p.b->childs[1]);
							 | 
						||
| 
								 | 
							
														}
							 | 
						||
| 
								 | 
							
														else
							 | 
						||
| 
								 | 
							
														{
							 | 
						||
| 
								 | 
							
															policy.Process(p.a,p.b);
							 | 
						||
| 
								 | 
							
														}
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											} while(depth);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								DBVT_PREFIX
							 | 
						||
| 
								 | 
							
								inline void		btDbvt::collideTTpersistentStack(	const btDbvtNode* root0,
							 | 
						||
| 
								 | 
							
																  const btDbvtNode* root1,
							 | 
						||
| 
								 | 
							
																  DBVT_IPOLICY)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									DBVT_CHECKTYPE
							 | 
						||
| 
								 | 
							
										if(root0&&root1)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											int								depth=1;
							 | 
						||
| 
								 | 
							
											int								treshold=DOUBLE_STACKSIZE-4;
							 | 
						||
| 
								 | 
							
											
							 | 
						||
| 
								 | 
							
											m_stkStack.resize(DOUBLE_STACKSIZE);
							 | 
						||
| 
								 | 
							
											m_stkStack[0]=sStkNN(root0,root1);
							 | 
						||
| 
								 | 
							
											do	{		
							 | 
						||
| 
								 | 
							
												sStkNN	p=m_stkStack[--depth];
							 | 
						||
| 
								 | 
							
												if(depth>treshold)
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													m_stkStack.resize(m_stkStack.size()*2);
							 | 
						||
| 
								 | 
							
													treshold=m_stkStack.size()-4;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												if(p.a==p.b)
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													if(p.a->isinternal())
							 | 
						||
| 
								 | 
							
													{
							 | 
						||
| 
								 | 
							
														m_stkStack[depth++]=sStkNN(p.a->childs[0],p.a->childs[0]);
							 | 
						||
| 
								 | 
							
														m_stkStack[depth++]=sStkNN(p.a->childs[1],p.a->childs[1]);
							 | 
						||
| 
								 | 
							
														m_stkStack[depth++]=sStkNN(p.a->childs[0],p.a->childs[1]);
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												else if(Intersect(p.a->volume,p.b->volume))
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													if(p.a->isinternal())
							 | 
						||
| 
								 | 
							
													{
							 | 
						||
| 
								 | 
							
														if(p.b->isinternal())
							 | 
						||
| 
								 | 
							
														{
							 | 
						||
| 
								 | 
							
															m_stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[0]);
							 | 
						||
| 
								 | 
							
															m_stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[0]);
							 | 
						||
| 
								 | 
							
															m_stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[1]);
							 | 
						||
| 
								 | 
							
															m_stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[1]);
							 | 
						||
| 
								 | 
							
														}
							 | 
						||
| 
								 | 
							
														else
							 | 
						||
| 
								 | 
							
														{
							 | 
						||
| 
								 | 
							
															m_stkStack[depth++]=sStkNN(p.a->childs[0],p.b);
							 | 
						||
| 
								 | 
							
															m_stkStack[depth++]=sStkNN(p.a->childs[1],p.b);
							 | 
						||
| 
								 | 
							
														}
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
													else
							 | 
						||
| 
								 | 
							
													{
							 | 
						||
| 
								 | 
							
														if(p.b->isinternal())
							 | 
						||
| 
								 | 
							
														{
							 | 
						||
| 
								 | 
							
															m_stkStack[depth++]=sStkNN(p.a,p.b->childs[0]);
							 | 
						||
| 
								 | 
							
															m_stkStack[depth++]=sStkNN(p.a,p.b->childs[1]);
							 | 
						||
| 
								 | 
							
														}
							 | 
						||
| 
								 | 
							
														else
							 | 
						||
| 
								 | 
							
														{
							 | 
						||
| 
								 | 
							
															policy.Process(p.a,p.b);
							 | 
						||
| 
								 | 
							
														}
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											} while(depth);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if 0
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								DBVT_PREFIX
							 | 
						||
| 
								 | 
							
								inline void		btDbvt::collideTT(	const btDbvtNode* root0,
							 | 
						||
| 
								 | 
							
																  const btDbvtNode* root1,
							 | 
						||
| 
								 | 
							
																  const btTransform& xform,
							 | 
						||
| 
								 | 
							
																  DBVT_IPOLICY)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									DBVT_CHECKTYPE
							 | 
						||
| 
								 | 
							
										if(root0&&root1)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											int								depth=1;
							 | 
						||
| 
								 | 
							
											int								treshold=DOUBLE_STACKSIZE-4;
							 | 
						||
| 
								 | 
							
											btAlignedObjectArray<sStkNN>	stkStack;
							 | 
						||
| 
								 | 
							
											stkStack.resize(DOUBLE_STACKSIZE);
							 | 
						||
| 
								 | 
							
											stkStack[0]=sStkNN(root0,root1);
							 | 
						||
| 
								 | 
							
											do	{
							 | 
						||
| 
								 | 
							
												sStkNN	p=stkStack[--depth];
							 | 
						||
| 
								 | 
							
												if(Intersect(p.a->volume,p.b->volume,xform))
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													if(depth>treshold)
							 | 
						||
| 
								 | 
							
													{
							 | 
						||
| 
								 | 
							
														stkStack.resize(stkStack.size()*2);
							 | 
						||
| 
								 | 
							
														treshold=stkStack.size()-4;
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
													if(p.a->isinternal())
							 | 
						||
| 
								 | 
							
													{
							 | 
						||
| 
								 | 
							
														if(p.b->isinternal())
							 | 
						||
| 
								 | 
							
														{					
							 | 
						||
| 
								 | 
							
															stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[0]);
							 | 
						||
| 
								 | 
							
															stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[0]);
							 | 
						||
| 
								 | 
							
															stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[1]);
							 | 
						||
| 
								 | 
							
															stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[1]);
							 | 
						||
| 
								 | 
							
														}
							 | 
						||
| 
								 | 
							
														else
							 | 
						||
| 
								 | 
							
														{
							 | 
						||
| 
								 | 
							
															stkStack[depth++]=sStkNN(p.a->childs[0],p.b);
							 | 
						||
| 
								 | 
							
															stkStack[depth++]=sStkNN(p.a->childs[1],p.b);
							 | 
						||
| 
								 | 
							
														}
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
													else
							 | 
						||
| 
								 | 
							
													{
							 | 
						||
| 
								 | 
							
														if(p.b->isinternal())
							 | 
						||
| 
								 | 
							
														{
							 | 
						||
| 
								 | 
							
															stkStack[depth++]=sStkNN(p.a,p.b->childs[0]);
							 | 
						||
| 
								 | 
							
															stkStack[depth++]=sStkNN(p.a,p.b->childs[1]);
							 | 
						||
| 
								 | 
							
														}
							 | 
						||
| 
								 | 
							
														else
							 | 
						||
| 
								 | 
							
														{
							 | 
						||
| 
								 | 
							
															policy.Process(p.a,p.b);
							 | 
						||
| 
								 | 
							
														}
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											} while(depth);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								DBVT_PREFIX
							 | 
						||
| 
								 | 
							
								inline void		btDbvt::collideTT(	const btDbvtNode* root0,
							 | 
						||
| 
								 | 
							
																  const btTransform& xform0,
							 | 
						||
| 
								 | 
							
																  const btDbvtNode* root1,
							 | 
						||
| 
								 | 
							
																  const btTransform& xform1,
							 | 
						||
| 
								 | 
							
																  DBVT_IPOLICY)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									const btTransform	xform=xform0.inverse()*xform1;
							 | 
						||
| 
								 | 
							
									collideTT(root0,root1,xform,policy);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								#endif 
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								DBVT_PREFIX
							 | 
						||
| 
								 | 
							
								inline void		btDbvt::collideTV(	const btDbvtNode* root,
							 | 
						||
| 
								 | 
							
																  const btDbvtVolume& vol,
							 | 
						||
| 
								 | 
							
																  DBVT_IPOLICY) const
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									DBVT_CHECKTYPE
							 | 
						||
| 
								 | 
							
									if(root)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										ATTRIBUTE_ALIGNED16(btDbvtVolume)		volume(vol);
							 | 
						||
| 
								 | 
							
										btAlignedObjectArray<const btDbvtNode*>	stack;
							 | 
						||
| 
								 | 
							
										stack.resize(0);
							 | 
						||
| 
								 | 
							
								#ifndef BT_DISABLE_STACK_TEMP_MEMORY
							 | 
						||
| 
								 | 
							
										char tempmemory[SIMPLE_STACKSIZE*sizeof(const btDbvtNode*)];
							 | 
						||
| 
								 | 
							
										stack.initializeFromBuffer(tempmemory, 0, SIMPLE_STACKSIZE);
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
										stack.reserve(SIMPLE_STACKSIZE);
							 | 
						||
| 
								 | 
							
								#endif //BT_DISABLE_STACK_TEMP_MEMORY
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										stack.push_back(root);
							 | 
						||
| 
								 | 
							
										do	{
							 | 
						||
| 
								 | 
							
											const btDbvtNode*	n=stack[stack.size()-1];
							 | 
						||
| 
								 | 
							
											stack.pop_back();
							 | 
						||
| 
								 | 
							
											if(Intersect(n->volume,volume))
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												if(n->isinternal())
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													stack.push_back(n->childs[0]);
							 | 
						||
| 
								 | 
							
													stack.push_back(n->childs[1]);
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												else
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													policy.Process(n);
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										} while(stack.size()>0);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								DBVT_PREFIX
							 | 
						||
| 
								 | 
							
								inline void		btDbvt::collideTVNoStackAlloc(	const btDbvtNode* root,
							 | 
						||
| 
								 | 
							
																			 const btDbvtVolume& vol,
							 | 
						||
| 
								 | 
							
																			 btNodeStack& stack,
							 | 
						||
| 
								 | 
							
																			 DBVT_IPOLICY) const
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									DBVT_CHECKTYPE
							 | 
						||
| 
								 | 
							
									if(root)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										ATTRIBUTE_ALIGNED16(btDbvtVolume)		volume(vol);
							 | 
						||
| 
								 | 
							
										stack.resize(0);
							 | 
						||
| 
								 | 
							
										stack.reserve(SIMPLE_STACKSIZE);
							 | 
						||
| 
								 | 
							
										stack.push_back(root);
							 | 
						||
| 
								 | 
							
										do	{
							 | 
						||
| 
								 | 
							
											const btDbvtNode*	n=stack[stack.size()-1];
							 | 
						||
| 
								 | 
							
											stack.pop_back();
							 | 
						||
| 
								 | 
							
											if(Intersect(n->volume,volume))
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												if(n->isinternal())
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													stack.push_back(n->childs[0]);
							 | 
						||
| 
								 | 
							
													stack.push_back(n->childs[1]);
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												else
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													policy.Process(n);
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										} while(stack.size()>0);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								DBVT_PREFIX
							 | 
						||
| 
								 | 
							
								inline void		btDbvt::rayTestInternal(	const btDbvtNode* root,
							 | 
						||
| 
								 | 
							
																const btVector3& rayFrom,
							 | 
						||
| 
								 | 
							
																const btVector3& rayTo,
							 | 
						||
| 
								 | 
							
																const btVector3& rayDirectionInverse,
							 | 
						||
| 
								 | 
							
																unsigned int signs[3],
							 | 
						||
| 
								 | 
							
																btScalar lambda_max,
							 | 
						||
| 
								 | 
							
																const btVector3& aabbMin,
							 | 
						||
| 
								 | 
							
																const btVector3& aabbMax,
							 | 
						||
| 
								 | 
							
								                                btAlignedObjectArray<const btDbvtNode*>& stack,
							 | 
						||
| 
								 | 
							
								                                DBVT_IPOLICY ) const
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								        (void) rayTo;
							 | 
						||
| 
								 | 
							
									DBVT_CHECKTYPE
							 | 
						||
| 
								 | 
							
									if(root)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										btVector3 resultNormal;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										int								depth=1;
							 | 
						||
| 
								 | 
							
										int								treshold=DOUBLE_STACKSIZE-2;
							 | 
						||
| 
								 | 
							
										stack.resize(DOUBLE_STACKSIZE);
							 | 
						||
| 
								 | 
							
										stack[0]=root;
							 | 
						||
| 
								 | 
							
										btVector3 bounds[2];
							 | 
						||
| 
								 | 
							
										do	
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											const btDbvtNode*	node=stack[--depth];
							 | 
						||
| 
								 | 
							
											bounds[0] = node->volume.Mins()-aabbMax;
							 | 
						||
| 
								 | 
							
											bounds[1] = node->volume.Maxs()-aabbMin;
							 | 
						||
| 
								 | 
							
											btScalar tmin=1.f,lambda_min=0.f;
							 | 
						||
| 
								 | 
							
											unsigned int result1=false;
							 | 
						||
| 
								 | 
							
											result1 = btRayAabb2(rayFrom,rayDirectionInverse,signs,bounds,tmin,lambda_min,lambda_max);
							 | 
						||
| 
								 | 
							
											if(result1)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												if(node->isinternal())
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													if(depth>treshold)
							 | 
						||
| 
								 | 
							
													{
							 | 
						||
| 
								 | 
							
														stack.resize(stack.size()*2);
							 | 
						||
| 
								 | 
							
														treshold=stack.size()-2;
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
													stack[depth++]=node->childs[0];
							 | 
						||
| 
								 | 
							
													stack[depth++]=node->childs[1];
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												else
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													policy.Process(node);
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										} while(depth);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								DBVT_PREFIX
							 | 
						||
| 
								 | 
							
								inline void		btDbvt::rayTest(	const btDbvtNode* root,
							 | 
						||
| 
								 | 
							
																const btVector3& rayFrom,
							 | 
						||
| 
								 | 
							
																const btVector3& rayTo,
							 | 
						||
| 
								 | 
							
																DBVT_IPOLICY)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									DBVT_CHECKTYPE
							 | 
						||
| 
								 | 
							
										if(root)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											btVector3 rayDir = (rayTo-rayFrom);
							 | 
						||
| 
								 | 
							
											rayDir.normalize ();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											///what about division by zero? --> just set rayDirection[i] to INF/BT_LARGE_FLOAT
							 | 
						||
| 
								 | 
							
											btVector3 rayDirectionInverse;
							 | 
						||
| 
								 | 
							
											rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[0];
							 | 
						||
| 
								 | 
							
											rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[1];
							 | 
						||
| 
								 | 
							
											rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[2];
							 | 
						||
| 
								 | 
							
											unsigned int signs[3] = { rayDirectionInverse[0] < 0.0, rayDirectionInverse[1] < 0.0, rayDirectionInverse[2] < 0.0};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											btScalar lambda_max = rayDir.dot(rayTo-rayFrom);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											btVector3 resultNormal;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											btAlignedObjectArray<const btDbvtNode*>	stack;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											int								depth=1;
							 | 
						||
| 
								 | 
							
											int								treshold=DOUBLE_STACKSIZE-2;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											char tempmemory[DOUBLE_STACKSIZE * sizeof(const btDbvtNode*)];
							 | 
						||
| 
								 | 
							
								#ifndef BT_DISABLE_STACK_TEMP_MEMORY
							 | 
						||
| 
								 | 
							
											stack.initializeFromBuffer(tempmemory, DOUBLE_STACKSIZE, DOUBLE_STACKSIZE);
							 | 
						||
| 
								 | 
							
								#else//BT_DISABLE_STACK_TEMP_MEMORY
							 | 
						||
| 
								 | 
							
											stack.resize(DOUBLE_STACKSIZE);
							 | 
						||
| 
								 | 
							
								#endif //BT_DISABLE_STACK_TEMP_MEMORY
							 | 
						||
| 
								 | 
							
											stack[0]=root;
							 | 
						||
| 
								 | 
							
											btVector3 bounds[2];
							 | 
						||
| 
								 | 
							
											do	{
							 | 
						||
| 
								 | 
							
												const btDbvtNode*	node=stack[--depth];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												bounds[0] = node->volume.Mins();
							 | 
						||
| 
								 | 
							
												bounds[1] = node->volume.Maxs();
							 | 
						||
| 
								 | 
							
												
							 | 
						||
| 
								 | 
							
												btScalar tmin=1.f,lambda_min=0.f;
							 | 
						||
| 
								 | 
							
												unsigned int result1 = btRayAabb2(rayFrom,rayDirectionInverse,signs,bounds,tmin,lambda_min,lambda_max);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef COMPARE_BTRAY_AABB2
							 | 
						||
| 
								 | 
							
												btScalar param=1.f;
							 | 
						||
| 
								 | 
							
												bool result2 = btRayAabb(rayFrom,rayTo,node->volume.Mins(),node->volume.Maxs(),param,resultNormal);
							 | 
						||
| 
								 | 
							
												btAssert(result1 == result2);
							 | 
						||
| 
								 | 
							
								#endif //TEST_BTRAY_AABB2
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												if(result1)
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													if(node->isinternal())
							 | 
						||
| 
								 | 
							
													{
							 | 
						||
| 
								 | 
							
														if(depth>treshold)
							 | 
						||
| 
								 | 
							
														{
							 | 
						||
| 
								 | 
							
															stack.resize(stack.size()*2);
							 | 
						||
| 
								 | 
							
															treshold=stack.size()-2;
							 | 
						||
| 
								 | 
							
														}
							 | 
						||
| 
								 | 
							
														stack[depth++]=node->childs[0];
							 | 
						||
| 
								 | 
							
														stack[depth++]=node->childs[1];
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
													else
							 | 
						||
| 
								 | 
							
													{
							 | 
						||
| 
								 | 
							
														policy.Process(node);
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											} while(depth);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								DBVT_PREFIX
							 | 
						||
| 
								 | 
							
								inline void		btDbvt::collideKDOP(const btDbvtNode* root,
							 | 
						||
| 
								 | 
							
																	const btVector3* normals,
							 | 
						||
| 
								 | 
							
																	const btScalar* offsets,
							 | 
						||
| 
								 | 
							
																	int count,
							 | 
						||
| 
								 | 
							
																	DBVT_IPOLICY)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									DBVT_CHECKTYPE
							 | 
						||
| 
								 | 
							
										if(root)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											const int						inside=(1<<count)-1;
							 | 
						||
| 
								 | 
							
											btAlignedObjectArray<sStkNP>	stack;
							 | 
						||
| 
								 | 
							
											int								signs[sizeof(unsigned)*8];
							 | 
						||
| 
								 | 
							
											btAssert(count<int (sizeof(signs)/sizeof(signs[0])));
							 | 
						||
| 
								 | 
							
											for(int i=0;i<count;++i)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												signs[i]=	((normals[i].x()>=0)?1:0)+
							 | 
						||
| 
								 | 
							
													((normals[i].y()>=0)?2:0)+
							 | 
						||
| 
								 | 
							
													((normals[i].z()>=0)?4:0);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											stack.reserve(SIMPLE_STACKSIZE);
							 | 
						||
| 
								 | 
							
											stack.push_back(sStkNP(root,0));
							 | 
						||
| 
								 | 
							
											do	{
							 | 
						||
| 
								 | 
							
												sStkNP	se=stack[stack.size()-1];
							 | 
						||
| 
								 | 
							
												bool	out=false;
							 | 
						||
| 
								 | 
							
												stack.pop_back();
							 | 
						||
| 
								 | 
							
												for(int i=0,j=1;(!out)&&(i<count);++i,j<<=1)
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													if(0==(se.mask&j))
							 | 
						||
| 
								 | 
							
													{
							 | 
						||
| 
								 | 
							
														const int	side=se.node->volume.Classify(normals[i],offsets[i],signs[i]);
							 | 
						||
| 
								 | 
							
														switch(side)
							 | 
						||
| 
								 | 
							
														{
							 | 
						||
| 
								 | 
							
														case	-1:	out=true;break;
							 | 
						||
| 
								 | 
							
														case	+1:	se.mask|=j;break;
							 | 
						||
| 
								 | 
							
														}
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												if(!out)
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													if((se.mask!=inside)&&(se.node->isinternal()))
							 | 
						||
| 
								 | 
							
													{
							 | 
						||
| 
								 | 
							
														stack.push_back(sStkNP(se.node->childs[0],se.mask));
							 | 
						||
| 
								 | 
							
														stack.push_back(sStkNP(se.node->childs[1],se.mask));
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
													else
							 | 
						||
| 
								 | 
							
													{
							 | 
						||
| 
								 | 
							
														if(policy.AllLeaves(se.node)) enumLeaves(se.node,policy);
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											} while(stack.size());
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								DBVT_PREFIX
							 | 
						||
| 
								 | 
							
								inline void		btDbvt::collideOCL(	const btDbvtNode* root,
							 | 
						||
| 
								 | 
							
																   const btVector3* normals,
							 | 
						||
| 
								 | 
							
																   const btScalar* offsets,
							 | 
						||
| 
								 | 
							
																   const btVector3& sortaxis,
							 | 
						||
| 
								 | 
							
																   int count,
							 | 
						||
| 
								 | 
							
																   DBVT_IPOLICY,
							 | 
						||
| 
								 | 
							
																   bool fsort)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									DBVT_CHECKTYPE
							 | 
						||
| 
								 | 
							
										if(root)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											const unsigned					srtsgns=(sortaxis[0]>=0?1:0)+
							 | 
						||
| 
								 | 
							
												(sortaxis[1]>=0?2:0)+
							 | 
						||
| 
								 | 
							
												(sortaxis[2]>=0?4:0);
							 | 
						||
| 
								 | 
							
											const int						inside=(1<<count)-1;
							 | 
						||
| 
								 | 
							
											btAlignedObjectArray<sStkNPS>	stock;
							 | 
						||
| 
								 | 
							
											btAlignedObjectArray<int>		ifree;
							 | 
						||
| 
								 | 
							
											btAlignedObjectArray<int>		stack;
							 | 
						||
| 
								 | 
							
											int								signs[sizeof(unsigned)*8];
							 | 
						||
| 
								 | 
							
											btAssert(count<int (sizeof(signs)/sizeof(signs[0])));
							 | 
						||
| 
								 | 
							
											for(int i=0;i<count;++i)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												signs[i]=	((normals[i].x()>=0)?1:0)+
							 | 
						||
| 
								 | 
							
													((normals[i].y()>=0)?2:0)+
							 | 
						||
| 
								 | 
							
													((normals[i].z()>=0)?4:0);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											stock.reserve(SIMPLE_STACKSIZE);
							 | 
						||
| 
								 | 
							
											stack.reserve(SIMPLE_STACKSIZE);
							 | 
						||
| 
								 | 
							
											ifree.reserve(SIMPLE_STACKSIZE);
							 | 
						||
| 
								 | 
							
											stack.push_back(allocate(ifree,stock,sStkNPS(root,0,root->volume.ProjectMinimum(sortaxis,srtsgns))));
							 | 
						||
| 
								 | 
							
											do	{
							 | 
						||
| 
								 | 
							
												const int	id=stack[stack.size()-1];
							 | 
						||
| 
								 | 
							
												sStkNPS		se=stock[id];
							 | 
						||
| 
								 | 
							
												stack.pop_back();ifree.push_back(id);
							 | 
						||
| 
								 | 
							
												if(se.mask!=inside)
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													bool	out=false;
							 | 
						||
| 
								 | 
							
													for(int i=0,j=1;(!out)&&(i<count);++i,j<<=1)
							 | 
						||
| 
								 | 
							
													{
							 | 
						||
| 
								 | 
							
														if(0==(se.mask&j))
							 | 
						||
| 
								 | 
							
														{
							 | 
						||
| 
								 | 
							
															const int	side=se.node->volume.Classify(normals[i],offsets[i],signs[i]);
							 | 
						||
| 
								 | 
							
															switch(side)
							 | 
						||
| 
								 | 
							
															{
							 | 
						||
| 
								 | 
							
															case	-1:	out=true;break;
							 | 
						||
| 
								 | 
							
															case	+1:	se.mask|=j;break;
							 | 
						||
| 
								 | 
							
															}
							 | 
						||
| 
								 | 
							
														}
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
													if(out) continue;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												if(policy.Descent(se.node))
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													if(se.node->isinternal())
							 | 
						||
| 
								 | 
							
													{
							 | 
						||
| 
								 | 
							
														const btDbvtNode* pns[]={	se.node->childs[0],se.node->childs[1]};
							 | 
						||
| 
								 | 
							
														sStkNPS		nes[]={	sStkNPS(pns[0],se.mask,pns[0]->volume.ProjectMinimum(sortaxis,srtsgns)),
							 | 
						||
| 
								 | 
							
															sStkNPS(pns[1],se.mask,pns[1]->volume.ProjectMinimum(sortaxis,srtsgns))};
							 | 
						||
| 
								 | 
							
														const int	q=nes[0].value<nes[1].value?1:0;				
							 | 
						||
| 
								 | 
							
														int			j=stack.size();
							 | 
						||
| 
								 | 
							
														if(fsort&&(j>0))
							 | 
						||
| 
								 | 
							
														{
							 | 
						||
| 
								 | 
							
															/* Insert 0	*/ 
							 | 
						||
| 
								 | 
							
															j=nearest(&stack[0],&stock[0],nes[q].value,0,stack.size());
							 | 
						||
| 
								 | 
							
															stack.push_back(0);
							 | 
						||
| 
								 | 
							
															
							 | 
						||
| 
								 | 
							
															//void * memmove ( void * destination, const void * source, size_t num );
							 | 
						||
| 
								 | 
							
															
							 | 
						||
| 
								 | 
							
								#if DBVT_USE_MEMMOVE
							 | 
						||
| 
								 | 
							
								                     {
							 | 
						||
| 
								 | 
							
								                     int num_items_to_move = stack.size()-1-j;
							 | 
						||
| 
								 | 
							
								                     if(num_items_to_move > 0)
							 | 
						||
| 
								 | 
							
								                        memmove(&stack[j+1],&stack[j],sizeof(int)*num_items_to_move);
							 | 
						||
| 
								 | 
							
								                     }
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								                     for(int k=stack.size()-1;k>j;--k) {
							 | 
						||
| 
								 | 
							
																stack[k]=stack[k-1];
							 | 
						||
| 
								 | 
							
								                     }
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
															stack[j]=allocate(ifree,stock,nes[q]);
							 | 
						||
| 
								 | 
							
															/* Insert 1	*/ 
							 | 
						||
| 
								 | 
							
															j=nearest(&stack[0],&stock[0],nes[1-q].value,j,stack.size());
							 | 
						||
| 
								 | 
							
															stack.push_back(0);
							 | 
						||
| 
								 | 
							
								#if DBVT_USE_MEMMOVE
							 | 
						||
| 
								 | 
							
								                     {
							 | 
						||
| 
								 | 
							
								                     int num_items_to_move = stack.size()-1-j;
							 | 
						||
| 
								 | 
							
								                     if(num_items_to_move > 0)
							 | 
						||
| 
								 | 
							
								                        memmove(&stack[j+1],&stack[j],sizeof(int)*num_items_to_move);
							 | 
						||
| 
								 | 
							
								                     }
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								                     for(int k=stack.size()-1;k>j;--k) {
							 | 
						||
| 
								 | 
							
								                        stack[k]=stack[k-1];
							 | 
						||
| 
								 | 
							
								                     }
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
															stack[j]=allocate(ifree,stock,nes[1-q]);
							 | 
						||
| 
								 | 
							
														}
							 | 
						||
| 
								 | 
							
														else
							 | 
						||
| 
								 | 
							
														{
							 | 
						||
| 
								 | 
							
															stack.push_back(allocate(ifree,stock,nes[q]));
							 | 
						||
| 
								 | 
							
															stack.push_back(allocate(ifree,stock,nes[1-q]));
							 | 
						||
| 
								 | 
							
														}
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
													else
							 | 
						||
| 
								 | 
							
													{
							 | 
						||
| 
								 | 
							
														policy.Process(se.node,se.value);
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											} while(stack.size());
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								DBVT_PREFIX
							 | 
						||
| 
								 | 
							
								inline void		btDbvt::collideTU(	const btDbvtNode* root,
							 | 
						||
| 
								 | 
							
																  DBVT_IPOLICY)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									DBVT_CHECKTYPE
							 | 
						||
| 
								 | 
							
										if(root)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											btAlignedObjectArray<const btDbvtNode*>	stack;
							 | 
						||
| 
								 | 
							
											stack.reserve(SIMPLE_STACKSIZE);
							 | 
						||
| 
								 | 
							
											stack.push_back(root);
							 | 
						||
| 
								 | 
							
											do	{
							 | 
						||
| 
								 | 
							
												const btDbvtNode*	n=stack[stack.size()-1];
							 | 
						||
| 
								 | 
							
												stack.pop_back();
							 | 
						||
| 
								 | 
							
												if(policy.Descent(n))
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													if(n->isinternal())
							 | 
						||
| 
								 | 
							
													{ stack.push_back(n->childs[0]);stack.push_back(n->childs[1]); }
							 | 
						||
| 
								 | 
							
													else
							 | 
						||
| 
								 | 
							
													{ policy.Process(n); }
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											} while(stack.size()>0);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// PP Cleanup
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#undef DBVT_USE_MEMMOVE
							 | 
						||
| 
								 | 
							
								#undef DBVT_USE_TEMPLATE
							 | 
						||
| 
								 | 
							
								#undef DBVT_VIRTUAL_DTOR
							 | 
						||
| 
								 | 
							
								#undef DBVT_VIRTUAL
							 | 
						||
| 
								 | 
							
								#undef DBVT_PREFIX
							 | 
						||
| 
								 | 
							
								#undef DBVT_IPOLICY
							 | 
						||
| 
								 | 
							
								#undef DBVT_CHECKTYPE
							 | 
						||
| 
								 | 
							
								#undef DBVT_IMPL_GENERIC
							 | 
						||
| 
								 | 
							
								#undef DBVT_IMPL_SSE
							 | 
						||
| 
								 | 
							
								#undef DBVT_USE_INTRINSIC_SSE
							 | 
						||
| 
								 | 
							
								#undef DBVT_SELECT_IMPL
							 | 
						||
| 
								 | 
							
								#undef DBVT_MERGE_IMPL
							 | 
						||
| 
								 | 
							
								#undef DBVT_INT0_IMPL
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif
							 |