forked from LeenkxTeam/LNXSDK
		
	
		
			
	
	
		
			269 lines
		
	
	
		
			8.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			269 lines
		
	
	
		
			8.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								Bullet Continuous Collision Detection and Physics Library
							 | 
						||
| 
								 | 
							
								Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								This software is provided 'as-is', without any express or implied warranty.
							 | 
						||
| 
								 | 
							
								In no event will the authors be held liable for any damages arising from the use of this software.
							 | 
						||
| 
								 | 
							
								Permission is granted to anyone to use this software for any purpose, 
							 | 
						||
| 
								 | 
							
								including commercial applications, and to alter it and redistribute it freely, 
							 | 
						||
| 
								 | 
							
								subject to the following restrictions:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
							 | 
						||
| 
								 | 
							
								2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
							 | 
						||
| 
								 | 
							
								3. This notice may not be removed or altered from any source distribution.
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifndef BT_PERSISTENT_MANIFOLD_H
							 | 
						||
| 
								 | 
							
								#define BT_PERSISTENT_MANIFOLD_H
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include "LinearMath/btVector3.h"
							 | 
						||
| 
								 | 
							
								#include "LinearMath/btTransform.h"
							 | 
						||
| 
								 | 
							
								#include "btManifoldPoint.h"
							 | 
						||
| 
								 | 
							
								class btCollisionObject;
							 | 
						||
| 
								 | 
							
								#include "LinearMath/btAlignedAllocator.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								struct btCollisionResult;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								///maximum contact breaking and merging threshold
							 | 
						||
| 
								 | 
							
								extern btScalar gContactBreakingThreshold;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifndef SWIG
							 | 
						||
| 
								 | 
							
								class btPersistentManifold;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								typedef bool (*ContactDestroyedCallback)(void* userPersistentData);
							 | 
						||
| 
								 | 
							
								typedef bool (*ContactProcessedCallback)(btManifoldPoint& cp,void* body0,void* body1);
							 | 
						||
| 
								 | 
							
								typedef void (*ContactStartedCallback)(btPersistentManifold* const &manifold);
							 | 
						||
| 
								 | 
							
								typedef void (*ContactEndedCallback)(btPersistentManifold* const &manifold);
							 | 
						||
| 
								 | 
							
								extern ContactDestroyedCallback	gContactDestroyedCallback;
							 | 
						||
| 
								 | 
							
								extern ContactProcessedCallback gContactProcessedCallback;
							 | 
						||
| 
								 | 
							
								extern ContactStartedCallback gContactStartedCallback;
							 | 
						||
| 
								 | 
							
								extern ContactEndedCallback gContactEndedCallback;
							 | 
						||
| 
								 | 
							
								#endif //SWIG
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//the enum starts at 1024 to avoid type conflicts with btTypedConstraint
							 | 
						||
| 
								 | 
							
								enum btContactManifoldTypes
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									MIN_CONTACT_MANIFOLD_TYPE = 1024,
							 | 
						||
| 
								 | 
							
									BT_PERSISTENT_MANIFOLD_TYPE
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define MANIFOLD_CACHE_SIZE 4
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								///btPersistentManifold is a contact point cache, it stays persistent as long as objects are overlapping in the broadphase.
							 | 
						||
| 
								 | 
							
								///Those contact points are created by the collision narrow phase.
							 | 
						||
| 
								 | 
							
								///The cache can be empty, or hold 1,2,3 or 4 points. Some collision algorithms (GJK) might only add one point at a time.
							 | 
						||
| 
								 | 
							
								///updates/refreshes old contact points, and throw them away if necessary (distance becomes too large)
							 | 
						||
| 
								 | 
							
								///reduces the cache to 4 points, when more then 4 points are added, using following rules:
							 | 
						||
| 
								 | 
							
								///the contact point with deepest penetration is always kept, and it tries to maximuze the area covered by the points
							 | 
						||
| 
								 | 
							
								///note that some pairs of objects might have more then one contact manifold.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//ATTRIBUTE_ALIGNED128( class) btPersistentManifold : public btTypedObject
							 | 
						||
| 
								 | 
							
								ATTRIBUTE_ALIGNED16( class) btPersistentManifold : public btTypedObject
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									btManifoldPoint m_pointCache[MANIFOLD_CACHE_SIZE];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/// this two body pointers can point to the physics rigidbody class.
							 | 
						||
| 
								 | 
							
									const btCollisionObject* m_body0;
							 | 
						||
| 
								 | 
							
									const btCollisionObject* m_body1;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									int	m_cachedPoints;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									btScalar	m_contactBreakingThreshold;
							 | 
						||
| 
								 | 
							
									btScalar	m_contactProcessingThreshold;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									/// sort cached points so most isolated points come first
							 | 
						||
| 
								 | 
							
									int	sortCachedPoints(const btManifoldPoint& pt);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									int		findContactPoint(const btManifoldPoint* unUsed, int numUnused,const btManifoldPoint& pt);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									BT_DECLARE_ALIGNED_ALLOCATOR();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									int	m_companionIdA;
							 | 
						||
| 
								 | 
							
									int	m_companionIdB;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									int m_index1a;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									btPersistentManifold();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									btPersistentManifold(const btCollisionObject* body0,const btCollisionObject* body1,int , btScalar contactBreakingThreshold,btScalar contactProcessingThreshold)
							 | 
						||
| 
								 | 
							
										: btTypedObject(BT_PERSISTENT_MANIFOLD_TYPE),
							 | 
						||
| 
								 | 
							
									m_body0(body0),m_body1(body1),m_cachedPoints(0),
							 | 
						||
| 
								 | 
							
										m_contactBreakingThreshold(contactBreakingThreshold),
							 | 
						||
| 
								 | 
							
										m_contactProcessingThreshold(contactProcessingThreshold)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									SIMD_FORCE_INLINE const btCollisionObject* getBody0() const { return m_body0;}
							 | 
						||
| 
								 | 
							
									SIMD_FORCE_INLINE const btCollisionObject* getBody1() const { return m_body1;}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									void	setBodies(const btCollisionObject* body0,const btCollisionObject* body1)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										m_body0 = body0;
							 | 
						||
| 
								 | 
							
										m_body1 = body1;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									void clearUserCache(btManifoldPoint& pt);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef DEBUG_PERSISTENCY
							 | 
						||
| 
								 | 
							
									void	DebugPersistency();
							 | 
						||
| 
								 | 
							
								#endif //
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									SIMD_FORCE_INLINE int	getNumContacts() const { return m_cachedPoints;}
							 | 
						||
| 
								 | 
							
									/// the setNumContacts API is usually not used, except when you gather/fill all contacts manually
							 | 
						||
| 
								 | 
							
									void setNumContacts(int cachedPoints)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										m_cachedPoints = cachedPoints;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									SIMD_FORCE_INLINE const btManifoldPoint& getContactPoint(int index) const
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										btAssert(index < m_cachedPoints);
							 | 
						||
| 
								 | 
							
										return m_pointCache[index];
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									SIMD_FORCE_INLINE btManifoldPoint& getContactPoint(int index)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										btAssert(index < m_cachedPoints);
							 | 
						||
| 
								 | 
							
										return m_pointCache[index];
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									///@todo: get this margin from the current physics / collision environment
							 | 
						||
| 
								 | 
							
									btScalar	getContactBreakingThreshold() const;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									btScalar	getContactProcessingThreshold() const
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										return m_contactProcessingThreshold;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									void setContactBreakingThreshold(btScalar contactBreakingThreshold)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										m_contactBreakingThreshold = contactBreakingThreshold;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									void setContactProcessingThreshold(btScalar	contactProcessingThreshold)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										m_contactProcessingThreshold = contactProcessingThreshold;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									int getCacheEntry(const btManifoldPoint& newPoint) const;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									int addManifoldPoint( const btManifoldPoint& newPoint, bool isPredictive=false);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									void removeContactPoint (int index)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										clearUserCache(m_pointCache[index]);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										int lastUsedIndex = getNumContacts() - 1;
							 | 
						||
| 
								 | 
							
								//		m_pointCache[index] = m_pointCache[lastUsedIndex];
							 | 
						||
| 
								 | 
							
										if(index != lastUsedIndex) 
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											m_pointCache[index] = m_pointCache[lastUsedIndex]; 
							 | 
						||
| 
								 | 
							
											//get rid of duplicated userPersistentData pointer
							 | 
						||
| 
								 | 
							
											m_pointCache[lastUsedIndex].m_userPersistentData = 0;
							 | 
						||
| 
								 | 
							
											m_pointCache[lastUsedIndex].m_appliedImpulse = 0.f;
							 | 
						||
| 
								 | 
							
											m_pointCache[lastUsedIndex].m_contactPointFlags = 0;
							 | 
						||
| 
								 | 
							
											m_pointCache[lastUsedIndex].m_appliedImpulseLateral1 = 0.f;
							 | 
						||
| 
								 | 
							
											m_pointCache[lastUsedIndex].m_appliedImpulseLateral2 = 0.f;
							 | 
						||
| 
								 | 
							
											m_pointCache[lastUsedIndex].m_lifeTime = 0;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										btAssert(m_pointCache[lastUsedIndex].m_userPersistentData==0);
							 | 
						||
| 
								 | 
							
										m_cachedPoints--;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if (gContactEndedCallback && m_cachedPoints == 0)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											gContactEndedCallback(this);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									void replaceContactPoint(const btManifoldPoint& newPoint, int insertIndex)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										btAssert(validContactDistance(newPoint));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define MAINTAIN_PERSISTENCY 1
							 | 
						||
| 
								 | 
							
								#ifdef MAINTAIN_PERSISTENCY
							 | 
						||
| 
								 | 
							
										int lifeTime = m_pointCache[insertIndex].getLifeTime();
							 | 
						||
| 
								 | 
							
										btScalar appliedImpulse = m_pointCache[insertIndex].m_appliedImpulse;
							 | 
						||
| 
								 | 
							
										btScalar appliedLateralImpulse1 = m_pointCache[insertIndex].m_appliedImpulseLateral1;
							 | 
						||
| 
								 | 
							
										btScalar appliedLateralImpulse2 = m_pointCache[insertIndex].m_appliedImpulseLateral2;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										bool replacePoint = true;
							 | 
						||
| 
								 | 
							
										///we keep existing contact points for friction anchors
							 | 
						||
| 
								 | 
							
										///if the friction force is within the Coulomb friction cone
							 | 
						||
| 
								 | 
							
										if (newPoint.m_contactPointFlags & BT_CONTACT_FLAG_FRICTION_ANCHOR)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											//   printf("appliedImpulse=%f\n", appliedImpulse);
							 | 
						||
| 
								 | 
							
											//   printf("appliedLateralImpulse1=%f\n", appliedLateralImpulse1);
							 | 
						||
| 
								 | 
							
											//   printf("appliedLateralImpulse2=%f\n", appliedLateralImpulse2);
							 | 
						||
| 
								 | 
							
											//   printf("mu = %f\n", m_pointCache[insertIndex].m_combinedFriction);
							 | 
						||
| 
								 | 
							
											btScalar mu = m_pointCache[insertIndex].m_combinedFriction;
							 | 
						||
| 
								 | 
							
											btScalar eps = 0;  //we could allow to enlarge or shrink the tolerance to check against the friction cone a bit, say 1e-7
							 | 
						||
| 
								 | 
							
											btScalar a = appliedLateralImpulse1 * appliedLateralImpulse1 + appliedLateralImpulse2 * appliedLateralImpulse2;
							 | 
						||
| 
								 | 
							
											btScalar b = eps + mu * appliedImpulse;
							 | 
						||
| 
								 | 
							
											b = b * b;
							 | 
						||
| 
								 | 
							
											replacePoint = (a) > (b);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if (replacePoint)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											btAssert(lifeTime >= 0);
							 | 
						||
| 
								 | 
							
											void* cache = m_pointCache[insertIndex].m_userPersistentData;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											m_pointCache[insertIndex] = newPoint;
							 | 
						||
| 
								 | 
							
											m_pointCache[insertIndex].m_userPersistentData = cache;
							 | 
						||
| 
								 | 
							
											m_pointCache[insertIndex].m_appliedImpulse = appliedImpulse;
							 | 
						||
| 
								 | 
							
											m_pointCache[insertIndex].m_appliedImpulseLateral1 = appliedLateralImpulse1;
							 | 
						||
| 
								 | 
							
											m_pointCache[insertIndex].m_appliedImpulseLateral2 = appliedLateralImpulse2;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										m_pointCache[insertIndex].m_lifeTime = lifeTime;
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
										clearUserCache(m_pointCache[insertIndex]);
							 | 
						||
| 
								 | 
							
										m_pointCache[insertIndex] = newPoint;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									bool validContactDistance(const btManifoldPoint& pt) const
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										return pt.m_distance1 <= getContactBreakingThreshold();
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									/// calculated new worldspace coordinates and depth, and reject points that exceed the collision margin
							 | 
						||
| 
								 | 
							
									void	refreshContactPoints(  const btTransform& trA,const btTransform& trB);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									SIMD_FORCE_INLINE	void	clearManifold()
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										int i;
							 | 
						||
| 
								 | 
							
										for (i=0;i<m_cachedPoints;i++)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											clearUserCache(m_pointCache[i]);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if (gContactEndedCallback && m_cachedPoints)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											gContactEndedCallback(this);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										m_cachedPoints = 0;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif //BT_PERSISTENT_MANIFOLD_H
							 |