diff options
author | Erwin Coumans <blender@erwincoumans.com> | 2005-07-16 13:58:01 +0400 |
---|---|---|
committer | Erwin Coumans <blender@erwincoumans.com> | 2005-07-16 13:58:01 +0400 |
commit | feb4f51103a7d6d22f564510deeb53ba83eaa931 (patch) | |
tree | 3facb14b2cd84faab73db921a45865d12fa8e461 /extern | |
parent | 1921a356be5999f4eab6d13adbf80d16526c988e (diff) |
Added Bullet library.
Only windows projectfiles for now.
Will ask Hans to get unix makefiles done.
Diffstat (limited to 'extern')
156 files changed, 19816 insertions, 0 deletions
diff --git a/extern/bullet/Bullet/BroadphaseCollision/BroadphaseInterface.h b/extern/bullet/Bullet/BroadphaseCollision/BroadphaseInterface.h new file mode 100644 index 00000000000..29c6a64eedc --- /dev/null +++ b/extern/bullet/Bullet/BroadphaseCollision/BroadphaseInterface.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#ifndef BROADPHASE_INTERFACE_H +#define BROADPHASE_INTERFACE_H + + +struct DispatcherInfo; +class Dispatcher; +struct BroadphaseProxy; +#include "SimdVector3.h" + +///BroadphaseInterface for aabb-overlapping object pairs +class BroadphaseInterface +{ +public: + virtual BroadphaseProxy* CreateProxy( void *object,int type, const SimdVector3& min, const SimdVector3& max) =0; + virtual void DestroyProxy(BroadphaseProxy* proxy)=0; + virtual void SetAabb(BroadphaseProxy* proxy,const SimdVector3& aabbMin,const SimdVector3& aabbMax)=0; + virtual void CleanProxyFromPairs(BroadphaseProxy* proxy)=0; + virtual void DispatchAllCollisionPairs(Dispatcher& dispatcher,DispatcherInfo& dispatchInfo)=0; + +}; + +#endif //BROADPHASE_INTERFACE_H diff --git a/extern/bullet/Bullet/BroadphaseCollision/BroadphaseProxy.cpp b/extern/bullet/Bullet/BroadphaseCollision/BroadphaseProxy.cpp new file mode 100644 index 00000000000..b7c6c72c8be --- /dev/null +++ b/extern/bullet/Bullet/BroadphaseCollision/BroadphaseProxy.cpp @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#include "BroadphaseProxy.h" + diff --git a/extern/bullet/Bullet/BroadphaseCollision/BroadphaseProxy.h b/extern/bullet/Bullet/BroadphaseCollision/BroadphaseProxy.h new file mode 100644 index 00000000000..9dfeb370347 --- /dev/null +++ b/extern/bullet/Bullet/BroadphaseCollision/BroadphaseProxy.h @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#ifndef BROADPHASE_PROXY_H +#define BROADPHASE_PROXY_H + + + +/// Dispatcher uses these types +/// IMPORTANT NOTE:The types are ordered polyhedral, implicit convex and concave +/// to facilitate type checking +enum BroadphaseNativeTypes +{ +// polyhedral convex shapes + BOX_SHAPE_PROXYTYPE, + TRIANGLE_SHAPE_PROXYTYPE, + TETRAHEDRAL_SHAPE_PROXYTYPE, + CONVEX_HULL_SHAPE_PROXYTYPE, +//implicit convex shapes +IMPLICIT_CONVEX_SHAPES_START_HERE, + SPHERE_SHAPE_PROXYTYPE, + MULTI_SPHERE_SHAPE_PROXYTYPE, + CONE_SHAPE_PROXYTYPE, + CONVEX_SHAPE_PROXYTYPE, + CYLINDER_SHAPE_PROXYTYPE, + MINKOWSKI_SUM_SHAPE_PROXYTYPE, + MINKOWSKI_DIFFERENCE_SHAPE_PROXYTYPE, +//concave shapes +CONCAVE_SHAPES_START_HERE, + //keep all the convex shapetype below here, for the check IsConvexShape in broadphase proxy! + TRIANGLE_MESH_SHAPE_PROXYTYPE, + + MAX_BROADPHASE_COLLISION_TYPES +}; + + +///BroadphaseProxy +struct BroadphaseProxy +{ + BroadphaseProxy() :m_clientObject(0),m_clientObjectType(-1){} + BroadphaseProxy(void* object,int type) + :m_clientObject(object), + m_clientObjectType(type) + { + } + + void *m_clientObject; + + int GetClientObjectType ( ) const { return m_clientObjectType;} + + + void SetClientObjectType( int type ) { + m_clientObjectType = type; + } + + bool IsConvexShape() + { + return (GetClientObjectType () < TRIANGLE_MESH_SHAPE_PROXYTYPE); + } + bool IsConcaveShape() + { + return (GetClientObjectType() > CONCAVE_SHAPES_START_HERE); + } + +protected: + int m_clientObjectType; +}; + +class CollisionAlgorithm; + +struct BroadphaseProxy; + +#define SIMPLE_MAX_ALGORITHMS 2 + +/// contains a pair of aabb-overlapping objects +struct BroadphasePair +{ + BroadphasePair () + : + m_pProxy0(0), + m_pProxy1(0) + { + for (int i=0;i<SIMPLE_MAX_ALGORITHMS;i++) + { + m_algorithms[i] = 0; + } + } + + BroadphasePair(const BroadphasePair& other) + : m_pProxy0(other.m_pProxy0), + m_pProxy1(other.m_pProxy1) + { + for (int i=0;i<SIMPLE_MAX_ALGORITHMS;i++) + { + m_algorithms[i] = other.m_algorithms[i]; + } + } + BroadphasePair(BroadphaseProxy& proxy0,BroadphaseProxy& proxy1) + : + m_pProxy0(&proxy0), + m_pProxy1(&proxy1) + { + for (int i=0;i<SIMPLE_MAX_ALGORITHMS;i++) + { + m_algorithms[i] = 0; + } + + } + + + BroadphaseProxy* m_pProxy0; + BroadphaseProxy* m_pProxy1; + + mutable CollisionAlgorithm* m_algorithms[SIMPLE_MAX_ALGORITHMS]; +}; + +#endif //BROADPHASE_PROXY_H + diff --git a/extern/bullet/Bullet/BroadphaseCollision/CollisionAlgorithm.cpp b/extern/bullet/Bullet/BroadphaseCollision/CollisionAlgorithm.cpp new file mode 100644 index 00000000000..a4e20359aea --- /dev/null +++ b/extern/bullet/Bullet/BroadphaseCollision/CollisionAlgorithm.cpp @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#include "CollisionAlgorithm.h" +#include "CollisionDispatcher.h" + +CollisionAlgorithm::CollisionAlgorithm(const CollisionAlgorithmConstructionInfo& ci) +{ + m_dispatcher = ci.m_dispatcher; +} + diff --git a/extern/bullet/Bullet/BroadphaseCollision/CollisionAlgorithm.h b/extern/bullet/Bullet/BroadphaseCollision/CollisionAlgorithm.h new file mode 100644 index 00000000000..5699f1019df --- /dev/null +++ b/extern/bullet/Bullet/BroadphaseCollision/CollisionAlgorithm.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#ifndef COLLISION_ALGORITHM_H +#define COLLISION_ALGORITHM_H + +struct BroadphaseProxy; +class Dispatcher; + +struct CollisionAlgorithmConstructionInfo +{ + CollisionAlgorithmConstructionInfo() + :m_dispatcher(0) + { + } + CollisionAlgorithmConstructionInfo(Dispatcher* dispatcher,int temp) + :m_dispatcher(dispatcher) + { + } + + Dispatcher* m_dispatcher; + + int GetDispatcherId(); + +}; + + +///CollisionAlgorithm is an collision interface that is compatible with the Broadphase and Dispatcher. +///It is persistent over frames +class CollisionAlgorithm +{ + +protected: + + Dispatcher* m_dispatcher; + +protected: + int GetDispatcherId(); + +public: + + CollisionAlgorithm() {}; + + CollisionAlgorithm(const CollisionAlgorithmConstructionInfo& ci); + + virtual ~CollisionAlgorithm() {}; + + virtual void ProcessCollision (BroadphaseProxy* proxy0,BroadphaseProxy* proxy1,float timeStep,int stepCount, bool useContinuous) = 0; + + virtual float CalculateTimeOfImpact(BroadphaseProxy* proxy0,BroadphaseProxy* proxy1,float timeStep,int stepCount) = 0; + +}; + + +#endif //COLLISION_ALGORITHM_H diff --git a/extern/bullet/Bullet/BroadphaseCollision/CollisionDispatcher.cpp b/extern/bullet/Bullet/BroadphaseCollision/CollisionDispatcher.cpp new file mode 100644 index 00000000000..65a7b616fb2 --- /dev/null +++ b/extern/bullet/Bullet/BroadphaseCollision/CollisionDispatcher.cpp @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#include "CollisionDispatcher.h" + +Dispatcher::~Dispatcher() +{ + +} + diff --git a/extern/bullet/Bullet/BroadphaseCollision/CollisionDispatcher.h b/extern/bullet/Bullet/BroadphaseCollision/CollisionDispatcher.h new file mode 100644 index 00000000000..7787ed417c5 --- /dev/null +++ b/extern/bullet/Bullet/BroadphaseCollision/CollisionDispatcher.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#ifndef COLLISION_DISPATCHER_H +#define COLLISION_DISPATCHER_H + +class CollisionAlgorithm; +struct BroadphaseProxy; +class RigidBody; + +enum CollisionDispatcherId +{ + RIGIDBODY_DISPATCHER = 0, + RAGDOLL_DISPATCHER +}; + +class PersistentManifold; + +struct DispatcherInfo +{ + enum DispatchFunc + { + DISPATCH_DISCRETE = 1, + DISPATCH_CONTINUOUS + }; + DispatcherInfo() + :m_dispatchFunc(DISPATCH_DISCRETE), + m_timeOfImpact(1.f), + m_useContinuous(false) + { + + } + float m_timeStep; + int m_stepCount; + int m_dispatchFunc; + float m_timeOfImpact; + bool m_useContinuous; + +}; + +/// Collision Dispatcher can be used in combination with broadphase and collision algorithms. +class Dispatcher +{ + + +public: + virtual ~Dispatcher() ; + + virtual CollisionAlgorithm* FindAlgorithm(BroadphaseProxy& proxy0,BroadphaseProxy& proxy1) = 0; + + // + // asume dispatchers to have unique id's in the range [0..max dispacher] + // + virtual int GetUniqueId() = 0; + + virtual PersistentManifold* GetNewManifold(void* body0,void* body1)=0; + + virtual void ReleaseManifold(PersistentManifold* manifold)=0; + + +}; + + +#endif //COLLISION_DISPATCHER_H diff --git a/extern/bullet/Bullet/BroadphaseCollision/SimpleBroadphase.cpp b/extern/bullet/Bullet/BroadphaseCollision/SimpleBroadphase.cpp new file mode 100644 index 00000000000..5d72376825d --- /dev/null +++ b/extern/bullet/Bullet/BroadphaseCollision/SimpleBroadphase.cpp @@ -0,0 +1,273 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#include "SimpleBroadphase.h" +#include "BroadphaseCollision/CollisionDispatcher.h" +#include "BroadphaseCollision/CollisionAlgorithm.h" + +#include "SimdVector3.h" +#include "SimdTransform.h" +#include "SimdMatrix3x3.h" +#include <vector> +#include "NarrowPhaseCollision/CollisionMargin.h" + +SimpleBroadphase::SimpleBroadphase() +: m_firstFreeProxy(0), + m_numProxies(0), + m_blockedForChanges(false), + m_NumOverlapBroadphasePair(0) +{ + int i; + for (i=0;i<SIMPLE_MAX_PROXIES;i++) + { + m_freeProxies[i] = i; + } +} + +SimpleBroadphase::~SimpleBroadphase() +{ + /*int i; + for (i=m_numProxies-1;i>=0;i--) + { + BP_Proxy* proxy = m_pProxies[i]; + destroyProxy(proxy); + } + */ +} + + +BroadphaseProxy* SimpleBroadphase::CreateProxy( void *object, int type, const SimdVector3& min, const SimdVector3& max) +{ + if (m_numProxies >= SIMPLE_MAX_PROXIES) + { + assert(0); + return 0; //should never happen, but don't let the game crash ;-) + } + assert(min[0]<= max[0] && min[1]<= max[1] && min[2]<= max[2]); + + int freeIndex= m_freeProxies[m_firstFreeProxy]; + BroadphaseProxy* proxy = new (&m_proxies[freeIndex])SimpleBroadphaseProxy(object,type,min,max); + m_firstFreeProxy++; + + m_pProxies[m_numProxies] = proxy; + m_numProxies++; + + return proxy; +} +void SimpleBroadphase::DestroyProxy(BroadphaseProxy* proxy) +{ + m_numProxies--; + BroadphaseProxy* proxy1 = &m_proxies[0]; + + int index = proxy - proxy1; + m_freeProxies[--m_firstFreeProxy] = index; + +} + +SimpleBroadphaseProxy* SimpleBroadphase::GetSimpleProxyFromProxy(BroadphaseProxy* proxy) +{ + SimpleBroadphaseProxy* proxy0 = static_cast<SimpleBroadphaseProxy*>(proxy); + + int index = proxy0 - &m_proxies[0]; + assert(index < m_numProxies); + + SimpleBroadphaseProxy* sbp = &m_proxies[index]; + return sbp; +} +void SimpleBroadphase::SetAabb(BroadphaseProxy* proxy,const SimdVector3& aabbMin,const SimdVector3& aabbMax) +{ + SimpleBroadphaseProxy* sbp = GetSimpleProxyFromProxy(proxy); + sbp->m_min = aabbMin; + sbp->m_max = aabbMax; +} + +void SimpleBroadphase::CleanOverlappingPair(BroadphasePair& pair) +{ + for (int dispatcherId=0;dispatcherId<SIMPLE_MAX_ALGORITHMS;dispatcherId++) + { + if (pair.m_algorithms[dispatcherId]) + { + { + delete pair.m_algorithms[dispatcherId]; + pair.m_algorithms[dispatcherId]=0; + } + } + } +} + + +void SimpleBroadphase::CleanProxyFromPairs(BroadphaseProxy* proxy) +{ + for (int i=0;i<m_NumOverlapBroadphasePair;i++) + { + BroadphasePair& pair = m_OverlappingPairs[i]; + if (pair.m_pProxy0 == proxy || + pair.m_pProxy1 == proxy) + { + CleanOverlappingPair(pair); + } + } +} + +void SimpleBroadphase::AddOverlappingPair(BroadphaseProxy* proxy0,BroadphaseProxy* proxy1) +{ + BroadphasePair pair(*proxy0,*proxy1); + m_OverlappingPairs[m_NumOverlapBroadphasePair] = pair; + + int i; + for (i=0;i<SIMPLE_MAX_ALGORITHMS;i++) + { + assert(!m_OverlappingPairs[m_NumOverlapBroadphasePair].m_algorithms[i]); + m_OverlappingPairs[m_NumOverlapBroadphasePair].m_algorithms[i] = 0; + } + m_NumOverlapBroadphasePair++; +} + +bool SimpleBroadphase::FindPair(BroadphaseProxy* proxy0,BroadphaseProxy* proxy1) +{ + bool found = false; + int i; + for (i=m_NumOverlapBroadphasePair-1;i>=0;i--) + { + BroadphasePair& pair = m_OverlappingPairs[i]; + if (((pair.m_pProxy0 == proxy0) && (pair.m_pProxy1 == proxy1)) || + ((pair.m_pProxy0 == proxy1) && (pair.m_pProxy1 == proxy0))) + { + found = true; + break; + } + } + + return found; +} +void SimpleBroadphase::RemoveOverlappingPair(BroadphasePair& pair) +{ + CleanOverlappingPair(pair); + int index = &pair - &m_OverlappingPairs[0]; + //remove efficiently, swap with the last + m_OverlappingPairs[index] = m_OverlappingPairs[m_NumOverlapBroadphasePair-1]; + m_NumOverlapBroadphasePair--; +} + +bool SimpleBroadphase::AabbOverlap(SimpleBroadphaseProxy* proxy0,SimpleBroadphaseProxy* proxy1) +{ + return proxy0->m_min[0] <= proxy1->m_max[0] && proxy1->m_min[0] <= proxy0->m_max[0] && + proxy0->m_min[1] <= proxy1->m_max[1] && proxy1->m_min[1] <= proxy0->m_max[1] && + proxy0->m_min[2] <= proxy1->m_max[2] && proxy1->m_min[2] <= proxy0->m_max[2]; + +} +void SimpleBroadphase::RefreshOverlappingPairs() +{ + //first check for new overlapping pairs + int i,j; + + for (i=0;i<m_numProxies;i++) + { + BroadphaseProxy* proxy0 = m_pProxies[i]; + for (j=i+1;j<m_numProxies;j++) + { + BroadphaseProxy* proxy1 = m_pProxies[j]; + SimpleBroadphaseProxy* p0 = GetSimpleProxyFromProxy(proxy0); + SimpleBroadphaseProxy* p1 = GetSimpleProxyFromProxy(proxy1); + + if (AabbOverlap(p0,p1)) + { + if ( !FindPair(proxy0,proxy1)) + { + AddOverlappingPair(proxy0,proxy1); + } + } + + } + } + + //then remove non-overlapping ones + for (i=0;i<m_NumOverlapBroadphasePair;i++) + { + BroadphasePair& pair = m_OverlappingPairs[i]; + SimpleBroadphaseProxy* proxy0 = GetSimpleProxyFromProxy(pair.m_pProxy0); + SimpleBroadphaseProxy* proxy1 = GetSimpleProxyFromProxy(pair.m_pProxy1); + if (!AabbOverlap(proxy0,proxy1)) + { + RemoveOverlappingPair(pair); + } + } + + //BroadphasePair m_OverlappingPairs[SIMPLE_MAX_OVERLAP]; + //int m_NumOverlapBroadphasePair; + +} + +void SimpleBroadphase::DispatchAllCollisionPairs(Dispatcher& dispatcher,DispatcherInfo& dispatchInfo) +{ + m_blockedForChanges = true; + + int i; + + int dispatcherId = dispatcher.GetUniqueId(); + + RefreshOverlappingPairs(); + + for (i=0;i<m_NumOverlapBroadphasePair;i++) + { + + BroadphasePair& pair = m_OverlappingPairs[i]; + + if (dispatcherId>= 0) + { + //dispatcher will keep algorithms persistent in the collision pair + if (!pair.m_algorithms[dispatcherId]) + { + pair.m_algorithms[dispatcherId] = dispatcher.FindAlgorithm( + *pair.m_pProxy0, + *pair.m_pProxy1); + } + + if (pair.m_algorithms[dispatcherId]) + { + if (dispatchInfo.m_dispatchFunc == DispatcherInfo::DISPATCH_DISCRETE) + { + pair.m_algorithms[dispatcherId]->ProcessCollision(pair.m_pProxy0,pair.m_pProxy1,dispatchInfo.m_timeStep,dispatchInfo.m_stepCount,dispatchInfo.m_useContinuous); + } else + { + float toi = pair.m_algorithms[dispatcherId]->CalculateTimeOfImpact(pair.m_pProxy0,pair.m_pProxy1,dispatchInfo.m_timeStep,dispatchInfo.m_stepCount); + if (dispatchInfo.m_timeOfImpact > toi) + dispatchInfo.m_timeOfImpact = toi; + + } + } + } else + { + //non-persistent algorithm dispatcher + CollisionAlgorithm* algo = dispatcher.FindAlgorithm( + *pair.m_pProxy0, + *pair.m_pProxy1); + + if (algo) + { + if (dispatchInfo.m_dispatchFunc == DispatcherInfo::DISPATCH_DISCRETE) + { + algo->ProcessCollision(pair.m_pProxy0,pair.m_pProxy1,dispatchInfo.m_timeStep,dispatchInfo.m_stepCount,dispatchInfo.m_useContinuous); + } else + { + float toi = algo->CalculateTimeOfImpact(pair.m_pProxy0,pair.m_pProxy1,dispatchInfo.m_timeStep,dispatchInfo.m_stepCount); + if (dispatchInfo.m_timeOfImpact > toi) + dispatchInfo.m_timeOfImpact = toi; + } + } + } + + } + + m_blockedForChanges = false; + +} + + diff --git a/extern/bullet/Bullet/BroadphaseCollision/SimpleBroadphase.h b/extern/bullet/Bullet/BroadphaseCollision/SimpleBroadphase.h new file mode 100644 index 00000000000..754d004d111 --- /dev/null +++ b/extern/bullet/Bullet/BroadphaseCollision/SimpleBroadphase.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#ifndef SIMPLE_BROADPHASE_H +#define SIMPLE_BROADPHASE_H + +#define SIMPLE_MAX_PROXIES 8192 +#define SIMPLE_MAX_OVERLAP 4096 + +#include "BroadphaseInterface.h" +#include "BroadphaseProxy.h" +#include "SimdPoint3.h" + +struct SimpleBroadphaseProxy : public BroadphaseProxy +{ + SimdVector3 m_min; + SimdVector3 m_max; + + SimpleBroadphaseProxy() {}; + + SimpleBroadphaseProxy(void* object,int type,const SimdPoint3& minpt,const SimdPoint3& maxpt) + :BroadphaseProxy(object,type), + m_min(minpt),m_max(maxpt) + { + } + + +}; + +///SimpleBroadphase is a brute force aabb culling broadphase based on O(n^2) aabb checks +class SimpleBroadphase : public BroadphaseInterface +{ + + SimpleBroadphaseProxy m_proxies[SIMPLE_MAX_PROXIES]; + int m_freeProxies[SIMPLE_MAX_PROXIES]; + int m_firstFreeProxy; + + BroadphaseProxy* m_pProxies[SIMPLE_MAX_PROXIES]; + int m_numProxies; + + //during the dispatch, check that user doesn't destroy/create proxy + bool m_blockedForChanges; + + BroadphasePair m_OverlappingPairs[SIMPLE_MAX_OVERLAP]; + int m_NumOverlapBroadphasePair; + + + SimpleBroadphaseProxy* GetSimpleProxyFromProxy(BroadphaseProxy* proxy); + + bool AabbOverlap(SimpleBroadphaseProxy* proxy0,SimpleBroadphaseProxy* proxy1); + void RemoveOverlappingPair(BroadphasePair& pair); + void CleanOverlappingPair(BroadphasePair& pair); + void AddOverlappingPair(BroadphaseProxy* proxy0,BroadphaseProxy* proxy1); + bool FindPair(BroadphaseProxy* proxy0,BroadphaseProxy* proxy1); + void RefreshOverlappingPairs(); +public: + SimpleBroadphase(); + virtual ~SimpleBroadphase(); + + virtual BroadphaseProxy* CreateProxy( void *object,int type, const SimdVector3& min, const SimdVector3& max) ; + virtual void DestroyProxy(BroadphaseProxy* proxy); + virtual void SetAabb(BroadphaseProxy* proxy,const SimdVector3& aabbMin,const SimdVector3& aabbMax); + virtual void CleanProxyFromPairs(BroadphaseProxy* proxy); + virtual void DispatchAllCollisionPairs(Dispatcher& dispatcher,DispatcherInfo& dispatchInfo); + +}; + + + +#endif //SIMPLE_BROADPHASE_H + diff --git a/extern/bullet/Bullet/Bullet3.dsp b/extern/bullet/Bullet/Bullet3.dsp new file mode 100644 index 00000000000..2e4ffaf6738 --- /dev/null +++ b/extern/bullet/Bullet/Bullet3.dsp @@ -0,0 +1,412 @@ +# Microsoft Developer Studio Project File - Name="Bullet" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Static Library" 0x0104 + +CFG=Bullet - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Bullet3.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Bullet3.mak" CFG="Bullet - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Bullet - Win32 Release" (based on "Win32 (x86) Static Library") +!MESSAGE "Bullet - Win32 Debug" (based on "Win32 (x86) Static Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Bullet - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +MTL=midl.exe +LINK32=link.exe -lib +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /Zd /O2 /I "../LinearMath" /I "." /D "NDEBUG" /D "_LIB" /D "WIN32" /D "_MBCS" /D "BUM_INLINED" /D "USE_ALGEBRAIC" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ELSEIF "$(CFG)" == "Bullet - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +MTL=midl.exe +LINK32=link.exe -lib +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../LinearMath" /I "." /D "_DEBUG" /D "_LIB" /D "WIN32" /D "_MBCS" /D "BUM_INLINED" /D "USE_ALGEBRAIC" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ENDIF + +# Begin Target + +# Name "Bullet - Win32 Release" +# Name "Bullet - Win32 Debug" +# Begin Group "NarrowPhaseCollision" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\NarrowPhaseCollision\BU_AlgebraicPolynomialSolver.cpp +# End Source File +# Begin Source File + +SOURCE=.\NarrowPhaseCollision\BU_AlgebraicPolynomialSolver.h +# End Source File +# Begin Source File + +SOURCE=.\NarrowPhaseCollision\BU_Collidable.cpp +# End Source File +# Begin Source File + +SOURCE=.\NarrowPhaseCollision\BU_Collidable.h +# End Source File +# Begin Source File + +SOURCE=.\NarrowPhaseCollision\BU_CollisionPair.cpp +# End Source File +# Begin Source File + +SOURCE=.\NarrowPhaseCollision\BU_CollisionPair.h +# End Source File +# Begin Source File + +SOURCE=.\NarrowPhaseCollision\BU_EdgeEdge.cpp +# End Source File +# Begin Source File + +SOURCE=.\NarrowPhaseCollision\BU_EdgeEdge.h +# End Source File +# Begin Source File + +SOURCE=.\NarrowPhaseCollision\BU_MotionStateInterface.h +# End Source File +# Begin Source File + +SOURCE=.\NarrowPhaseCollision\BU_PolynomialSolverInterface.h +# End Source File +# Begin Source File + +SOURCE=.\NarrowPhaseCollision\BU_Screwing.cpp +# End Source File +# Begin Source File + +SOURCE=.\NarrowPhaseCollision\BU_Screwing.h +# End Source File +# Begin Source File + +SOURCE=.\NarrowPhaseCollision\BU_StaticMotionState.h +# End Source File +# Begin Source File + +SOURCE=.\NarrowPhaseCollision\BU_VertexPoly.cpp +# End Source File +# Begin Source File + +SOURCE=.\NarrowPhaseCollision\BU_VertexPoly.h +# End Source File +# Begin Source File + +SOURCE=.\NarrowPhaseCollision\CollisionMargin.h +# End Source File +# Begin Source File + +SOURCE=.\NarrowPhaseCollision\ContinuousConvexCollision.cpp +# End Source File +# Begin Source File + +SOURCE=.\NarrowPhaseCollision\ContinuousConvexCollision.h +# End Source File +# Begin Source File + +SOURCE=.\NarrowPhaseCollision\ConvexCast.cpp +# End Source File +# Begin Source File + +SOURCE=.\NarrowPhaseCollision\ConvexCast.h +# End Source File +# Begin Source File + +SOURCE=.\NarrowPhaseCollision\ConvexPenetrationDepthSolver.h +# End Source File +# Begin Source File + +SOURCE=.\NarrowPhaseCollision\DiscreteCollisionDetectorInterface.h +# End Source File +# Begin Source File + +SOURCE=.\NarrowPhaseCollision\GjkConvexCast.cpp +# End Source File +# Begin Source File + +SOURCE=.\NarrowPhaseCollision\GjkConvexCast.h +# End Source File +# Begin Source File + +SOURCE=.\NarrowPhaseCollision\GjkPairDetector.cpp +# End Source File +# Begin Source File + +SOURCE=.\NarrowPhaseCollision\GjkPairDetector.h +# End Source File +# Begin Source File + +SOURCE=.\NarrowPhaseCollision\ManifoldPoint.h +# End Source File +# Begin Source File + +SOURCE=.\NarrowPhaseCollision\MinkowskiPenetrationDepthSolver.cpp +# End Source File +# Begin Source File + +SOURCE=.\NarrowPhaseCollision\MinkowskiPenetrationDepthSolver.h +# End Source File +# Begin Source File + +SOURCE=.\NarrowPhaseCollision\PersistentManifold.cpp +# End Source File +# Begin Source File + +SOURCE=.\NarrowPhaseCollision\PersistentManifold.h +# End Source File +# Begin Source File + +SOURCE=.\NarrowPhaseCollision\PointCollector.h +# End Source File +# Begin Source File + +SOURCE=.\NarrowPhaseCollision\RaycastCallback.cpp +# End Source File +# Begin Source File + +SOURCE=.\NarrowPhaseCollision\RaycastCallback.h +# End Source File +# Begin Source File + +SOURCE=.\NarrowPhaseCollision\SimplexSolverInterface.h +# End Source File +# Begin Source File + +SOURCE=.\NarrowPhaseCollision\SubSimplexConvexCast.cpp +# End Source File +# Begin Source File + +SOURCE=.\NarrowPhaseCollision\SubSimplexConvexCast.h +# End Source File +# Begin Source File + +SOURCE=.\NarrowPhaseCollision\VoronoiSimplexSolver.cpp +# End Source File +# Begin Source File + +SOURCE=.\NarrowPhaseCollision\VoronoiSimplexSolver.h +# End Source File +# End Group +# Begin Group "BroadphaseCollision" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\BroadphaseCollision\BroadPhaseInterface.h +# End Source File +# Begin Source File + +SOURCE=.\BroadphaseCollision\BroadphaseProxy.cpp +# End Source File +# Begin Source File + +SOURCE=.\BroadphaseCollision\BroadphaseProxy.h +# End Source File +# Begin Source File + +SOURCE=.\BroadphaseCollision\CollisionAlgorithm.cpp +# End Source File +# Begin Source File + +SOURCE=.\BroadphaseCollision\CollisionAlgorithm.h +# End Source File +# Begin Source File + +SOURCE=.\BroadphaseCollision\CollisionDispatcher.cpp +# End Source File +# Begin Source File + +SOURCE=.\BroadphaseCollision\CollisionDispatcher.h +# End Source File +# Begin Source File + +SOURCE=.\BroadphaseCollision\SimpleBroadphase.cpp +# End Source File +# Begin Source File + +SOURCE=.\BroadphaseCollision\SimpleBroadphase.h +# End Source File +# End Group +# Begin Group "CollisionShapes" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\CollisionShapes\BoxShape.cpp +# End Source File +# Begin Source File + +SOURCE=.\CollisionShapes\BoxShape.h +# End Source File +# Begin Source File + +SOURCE=.\CollisionShapes\CollisionShape.cpp +# End Source File +# Begin Source File + +SOURCE=.\CollisionShapes\CollisionShape.h +# End Source File +# Begin Source File + +SOURCE=.\CollisionShapes\ConeShape.cpp +# End Source File +# Begin Source File + +SOURCE=.\CollisionShapes\ConeShape.h +# End Source File +# Begin Source File + +SOURCE=.\CollisionShapes\ConvexHullShape.cpp +# End Source File +# Begin Source File + +SOURCE=.\CollisionShapes\ConvexHullShape.h +# End Source File +# Begin Source File + +SOURCE=.\CollisionShapes\ConvexShape.cpp +# End Source File +# Begin Source File + +SOURCE=.\CollisionShapes\ConvexShape.h +# End Source File +# Begin Source File + +SOURCE=.\CollisionShapes\CylinderShape.cpp +# End Source File +# Begin Source File + +SOURCE=.\CollisionShapes\CylinderShape.h +# End Source File +# Begin Source File + +SOURCE=.\CollisionShapes\MinkowskiSumShape.cpp +# End Source File +# Begin Source File + +SOURCE=.\CollisionShapes\MinkowskiSumShape.h +# End Source File +# Begin Source File + +SOURCE=.\CollisionShapes\MultiSphereShape.cpp +# End Source File +# Begin Source File + +SOURCE=.\CollisionShapes\MultiSphereShape.h +# End Source File +# Begin Source File + +SOURCE=.\CollisionShapes\PolyhedralConvexShape.cpp +# End Source File +# Begin Source File + +SOURCE=.\CollisionShapes\PolyhedralConvexShape.h +# End Source File +# Begin Source File + +SOURCE=.\CollisionShapes\Simplex1to4Shape.cpp +# End Source File +# Begin Source File + +SOURCE=.\CollisionShapes\Simplex1to4Shape.h +# End Source File +# Begin Source File + +SOURCE=.\CollisionShapes\SphereShape.cpp +# End Source File +# Begin Source File + +SOURCE=.\CollisionShapes\SphereShape.h +# End Source File +# Begin Source File + +SOURCE=.\CollisionShapes\StridingMeshInterface.cpp +# End Source File +# Begin Source File + +SOURCE=.\CollisionShapes\StridingMeshInterface.h +# End Source File +# Begin Source File + +SOURCE=.\CollisionShapes\TriangleCallback.h +# End Source File +# Begin Source File + +SOURCE=.\CollisionShapes\TriangleMesh.cpp +# End Source File +# Begin Source File + +SOURCE=.\CollisionShapes\TriangleMesh.h +# End Source File +# Begin Source File + +SOURCE=.\CollisionShapes\TriangleMeshShape.cpp +# End Source File +# Begin Source File + +SOURCE=.\CollisionShapes\TriangleMeshShape.h +# End Source File +# Begin Source File + +SOURCE=.\CollisionShapes\TriangleShape.h +# End Source File +# End Group +# End Target +# End Project diff --git a/extern/bullet/Bullet/Bullet3_vc7.vcproj b/extern/bullet/Bullet/Bullet3_vc7.vcproj new file mode 100644 index 00000000000..dab745810a0 --- /dev/null +++ b/extern/bullet/Bullet/Bullet3_vc7.vcproj @@ -0,0 +1,427 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="7.10" + Name="Bullet3ContinuousCollision" + ProjectGUID="{FFD3C64A-30E2-4BC7-BC8F-51818C320400}" + SccProjectName="" + SccLocalPath=""> + <Platforms> + <Platform + Name="Win32"/> + </Platforms> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory=".\Debug" + IntermediateDirectory=".\Debug" + ConfigurationType="4" + UseOfMFC="0" + ATLMinimizesCRunTimeLibraryUsage="FALSE" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories=".;..\LinearMath" + PreprocessorDefinitions="_DEBUG;_LIB;WIN32;BUM_INLINED;USE_ALGEBRAIC" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="2" + PrecompiledHeaderFile=".\Debug/Bullet.pch" + AssemblerListingLocation=".\Debug/" + ObjectFile=".\Debug/" + ProgramDataBaseFileName=".\Debug/" + WarningLevel="3" + SuppressStartupBanner="TRUE" + DebugInformationFormat="4" + CompileAs="0"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLibrarianTool" + OutputFile=".\Debug\Bullet.lib" + SuppressStartupBanner="TRUE"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool" + PreprocessorDefinitions="_DEBUG" + Culture="1033"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory=".\Release" + IntermediateDirectory=".\Release" + ConfigurationType="4" + UseOfMFC="0" + ATLMinimizesCRunTimeLibraryUsage="FALSE" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + InlineFunctionExpansion="1" + AdditionalIncludeDirectories=".;..\LinearMath" + PreprocessorDefinitions="NDEBUG;_LIB;WIN32;BUM_INLINED;USE_ALGEBRAIC" + StringPooling="TRUE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="TRUE" + UsePrecompiledHeader="2" + PrecompiledHeaderFile=".\Release/Bullet.pch" + AssemblerListingLocation=".\Release/" + ObjectFile=".\Release/" + ProgramDataBaseFileName=".\Release/" + WarningLevel="3" + SuppressStartupBanner="TRUE" + DebugInformationFormat="2" + CompileAs="0"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLibrarianTool" + OutputFile="..\..\..\..\build\msvc_7\libs\extern\Bullet.lib" + SuppressStartupBanner="TRUE"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool" + CommandLine="ECHO Copying header files +IF NOT EXIST ..\..\..\..\build\msvc_7\extern\bullet\include MKDIR ..\..\..\..\build\msvc_7\extern\bullet\include +IF NOT EXIST ..\..\..\..\build\msvc_7\extern\bullet\include\BroadphaseCollision MKDIR ..\..\..\..\build\msvc_7\extern\bullet\include\BroadphaseCollision +IF NOT EXIST ..\..\..\..\build\msvc_7\extern\bullet\include\CollisionShapes MKDIR ..\..\..\..\build\msvc_7\extern\bullet\include\CollisionShapes +IF NOT EXIST ..\..\..\..\build\msvc_7\extern\bullet\include\NarrowPhaseCollision MKDIR ..\..\..\..\build\msvc_7\extern\bullet\include\NarrowPhaseCollision + +XCOPY /Y ..\LinearMath\*.h ..\..\..\..\build\msvc_7\extern\bullet\include +XCOPY /Y ..\Bullet\BroadphaseCollision\*.h ..\..\..\..\build\msvc_7\extern\bullet\include\BroadphaseCollision +XCOPY /Y ..\Bullet\CollisionShapes\*.h ..\..\..\..\build\msvc_7\extern\bullet\include\CollisionShapes +XCOPY /Y ..\Bullet\NarrowPhaseCollision\*.h ..\..\..\..\build\msvc_7\extern\bullet\include\NarrowPhaseCollision + +ECHO Done +"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool" + PreprocessorDefinitions="NDEBUG" + Culture="1033"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="NarrowPhaseCollision" + Filter=""> + <File + RelativePath=".\NarrowPhaseCollision\BU_AlgebraicPolynomialSolver.cpp"> + </File> + <File + RelativePath=".\NarrowPhaseCollision\BU_AlgebraicPolynomialSolver.h"> + </File> + <File + RelativePath=".\NarrowPhaseCollision\BU_Collidable.cpp"> + </File> + <File + RelativePath=".\NarrowPhaseCollision\BU_Collidable.h"> + </File> + <File + RelativePath=".\NarrowPhaseCollision\BU_CollisionPair.cpp"> + </File> + <File + RelativePath=".\NarrowPhaseCollision\BU_CollisionPair.h"> + </File> + <File + RelativePath=".\NarrowPhaseCollision\BU_EdgeEdge.cpp"> + </File> + <File + RelativePath=".\NarrowPhaseCollision\BU_EdgeEdge.h"> + </File> + <File + RelativePath=".\NarrowPhaseCollision\BU_MotionStateInterface.h"> + </File> + <File + RelativePath=".\NarrowPhaseCollision\BU_PolynomialSolverInterface.h"> + </File> + <File + RelativePath=".\NarrowPhaseCollision\BU_Screwing.cpp"> + </File> + <File + RelativePath=".\NarrowPhaseCollision\BU_Screwing.h"> + </File> + <File + RelativePath=".\NarrowPhaseCollision\BU_StaticMotionState.h"> + </File> + <File + RelativePath=".\NarrowPhaseCollision\BU_VertexPoly.cpp"> + </File> + <File + RelativePath=".\NarrowPhaseCollision\BU_VertexPoly.h"> + </File> + <File + RelativePath=".\NarrowPhaseCollision\CollisionMargin.h"> + </File> + <File + RelativePath=".\NarrowPhaseCollision\ContinuousConvexCollision.cpp"> + </File> + <File + RelativePath=".\NarrowPhaseCollision\ContinuousConvexCollision.h"> + </File> + <File + RelativePath=".\NarrowPhaseCollision\ConvexCast.h"> + </File> + <File + RelativePath=".\NarrowPhaseCollision\ConvexPenetrationDepthSolver.h"> + </File> + <File + RelativePath=".\NarrowPhaseCollision\DiscreteCollisionDetectorInterface.h"> + </File> + <File + RelativePath=".\NarrowPhaseCollision\GjkConvexCast.cpp"> + </File> + <File + RelativePath=".\NarrowPhaseCollision\GjkConvexCast.h"> + </File> + <File + RelativePath=".\NarrowPhaseCollision\GjkPairDetector.cpp"> + </File> + <File + RelativePath=".\NarrowPhaseCollision\GjkPairDetector.h"> + </File> + <File + RelativePath=".\NarrowPhaseCollision\ManifoldPoint.h"> + </File> + <File + RelativePath=".\NarrowPhaseCollision\MinkowskiPenetrationDepthSolver.cpp"> + </File> + <File + RelativePath=".\NarrowPhaseCollision\MinkowskiPenetrationDepthSolver.h"> + </File> + <File + RelativePath=".\NarrowPhaseCollision\PersistentManifold.cpp"> + </File> + <File + RelativePath=".\NarrowPhaseCollision\PersistentManifold.h"> + </File> + <File + RelativePath=".\NarrowPhaseCollision\PointCollector.h"> + </File> + <File + RelativePath=".\NarrowPhaseCollision\RaycastCallback.cpp"> + </File> + <File + RelativePath=".\NarrowPhaseCollision\RaycastCallback.h"> + </File> + <File + RelativePath=".\NarrowPhaseCollision\SimplexSolverInterface.h"> + </File> + <File + RelativePath=".\NarrowPhaseCollision\SubSimplexConvexCast.cpp"> + </File> + <File + RelativePath=".\NarrowPhaseCollision\SubSimplexConvexCast.h"> + </File> + <File + RelativePath=".\NarrowPhaseCollision\VoronoiSimplexSolver.cpp"> + </File> + <File + RelativePath=".\NarrowPhaseCollision\VoronoiSimplexSolver.h"> + </File> + </Filter> + <Filter + Name="CollisionShapes" + Filter=""> + <File + RelativePath=".\CollisionShapes\BoxShape.cpp"> + </File> + <File + RelativePath=".\CollisionShapes\BoxShape.h"> + </File> + <File + RelativePath=".\CollisionShapes\CollisionShape.cpp"> + </File> + <File + RelativePath=".\CollisionShapes\CollisionShape.h"> + </File> + <File + RelativePath=".\CollisionShapes\ConeShape.cpp"> + </File> + <File + RelativePath=".\CollisionShapes\ConeShape.h"> + </File> + <File + RelativePath=".\CollisionShapes\ConvexHullShape.cpp"> + </File> + <File + RelativePath=".\CollisionShapes\ConvexHullShape.h"> + </File> + <File + RelativePath=".\CollisionShapes\ConvexShape.cpp"> + </File> + <File + RelativePath=".\CollisionShapes\ConvexShape.h"> + </File> + <File + RelativePath=".\CollisionShapes\CylinderShape.cpp"> + </File> + <File + RelativePath=".\CollisionShapes\CylinderShape.h"> + </File> + <File + RelativePath=".\CollisionShapes\MinkowskiSumShape.cpp"> + </File> + <File + RelativePath=".\CollisionShapes\MinkowskiSumShape.h"> + </File> + <File + RelativePath=".\CollisionShapes\MultiSphereShape.cpp"> + </File> + <File + RelativePath=".\CollisionShapes\MultiSphereShape.h"> + </File> + <File + RelativePath=".\CollisionShapes\PolyhedralConvexShape.cpp"> + </File> + <File + RelativePath=".\CollisionShapes\PolyhedralConvexShape.h"> + </File> + <File + RelativePath=".\CollisionShapes\Simplex1to4Shape.cpp"> + </File> + <File + RelativePath=".\CollisionShapes\Simplex1to4Shape.h"> + </File> + <File + RelativePath=".\CollisionShapes\SphereShape.cpp"> + </File> + <File + RelativePath=".\CollisionShapes\SphereShape.h"> + </File> + <File + RelativePath=".\CollisionShapes\StridingMeshInterface.cpp"> + </File> + <File + RelativePath=".\CollisionShapes\StridingMeshInterface.h"> + </File> + <File + RelativePath=".\CollisionShapes\TriangleCallback.h"> + </File> + <File + RelativePath=".\CollisionShapes\TriangleMesh.cpp"> + </File> + <File + RelativePath=".\CollisionShapes\TriangleMesh.h"> + </File> + <File + RelativePath=".\CollisionShapes\TriangleMeshShape.cpp"> + </File> + <File + RelativePath=".\CollisionShapes\TriangleMeshShape.h"> + </File> + <File + RelativePath=".\CollisionShapes\TriangleShape.h"> + </File> + </Filter> + <Filter + Name="BroadphaseCollision" + Filter=""> + <File + RelativePath=".\BroadphaseCollision\BroadPhaseInterface.h"> + </File> + <File + RelativePath=".\BroadphaseCollision\BroadphaseProxy.cpp"> + </File> + <File + RelativePath=".\BroadphaseCollision\BroadphaseProxy.h"> + </File> + <File + RelativePath=".\BroadphaseCollision\CollisionAlgorithm.cpp"> + </File> + <File + RelativePath=".\BroadphaseCollision\CollisionAlgorithm.h"> + </File> + <File + RelativePath=".\BroadphaseCollision\CollisionDispatcher.cpp"> + </File> + <File + RelativePath=".\BroadphaseCollision\CollisionDispatcher.h"> + </File> + <File + RelativePath=".\BroadphaseCollision\SimpleBroadphase.cpp"> + </File> + <File + RelativePath=".\BroadphaseCollision\SimpleBroadphase.h"> + </File> + </Filter> + <Filter + Name="LinearAlgebra" + Filter=""> + <File + RelativePath="..\LinearMath\AabbUtil2.h"> + </File> + <File + RelativePath="..\LinearMath\GEN_List.h"> + </File> + <File + RelativePath="..\LinearMath\GEN_MinMax.h"> + </File> + <File + RelativePath="..\LinearMath\GEN_random.h"> + </File> + <File + RelativePath="..\LinearMath\SimdMatrix3x3.h"> + </File> + <File + RelativePath="..\LinearMath\SimdMinMax.h"> + </File> + <File + RelativePath="..\LinearMath\SimdPoint3.h"> + </File> + <File + RelativePath="..\LinearMath\SimdQuadword.h"> + </File> + <File + RelativePath="..\LinearMath\SimdQuaternion.h"> + </File> + <File + RelativePath="..\LinearMath\SimdScalar.h"> + </File> + <File + RelativePath="..\LinearMath\SimdTransform.h"> + </File> + <File + RelativePath="..\LinearMath\SimdTransformUtil.h"> + </File> + <File + RelativePath="..\LinearMath\SimdVector3.h"> + </File> + </Filter> + <File + RelativePath=".\NarrowPhaseCollision\ConvexCast.cpp"> + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/extern/bullet/Bullet/Bullet3_vc8.sln b/extern/bullet/Bullet/Bullet3_vc8.sln new file mode 100644 index 00000000000..d95ceb0fbf3 --- /dev/null +++ b/extern/bullet/Bullet/Bullet3_vc8.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Bullet3ContinuousCollision", "Bullet3_vc8.vcproj", "{FFD3C64A-30E2-4BC7-BC8F-51818C320400}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {FFD3C64A-30E2-4BC7-BC8F-51818C320400}.Debug|Win32.ActiveCfg = Debug|Win32 + {FFD3C64A-30E2-4BC7-BC8F-51818C320400}.Debug|Win32.Build.0 = Debug|Win32 + {FFD3C64A-30E2-4BC7-BC8F-51818C320400}.Release|Win32.ActiveCfg = Release|Win32 + {FFD3C64A-30E2-4BC7-BC8F-51818C320400}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/extern/bullet/Bullet/Bullet3_vc8.vcproj b/extern/bullet/Bullet/Bullet3_vc8.vcproj new file mode 100644 index 00000000000..c2f3e70180f --- /dev/null +++ b/extern/bullet/Bullet/Bullet3_vc8.vcproj @@ -0,0 +1,552 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="8.00" + Name="Bullet3ContinuousCollision" + ProjectGUID="{FFD3C64A-30E2-4BC7-BC8F-51818C320400}" + SignManifests="true" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory=".\Debug" + IntermediateDirectory=".\Debug" + ConfigurationType="4" + UseOfMFC="0" + ATLMinimizesCRunTimeLibraryUsage="false" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories=".;..\LinearMath" + PreprocessorDefinitions="_DEBUG;_LIB;WIN32;BUM_INLINED;USE_ALGEBRAIC" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + PrecompiledHeaderFile="" + AssemblerListingLocation=".\Debug/" + ObjectFile=".\Debug/" + ProgramDataBaseFileName=".\Debug/" + WarningLevel="3" + SuppressStartupBanner="true" + DebugInformationFormat="4" + CompileAs="0" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + PreprocessorDefinitions="_DEBUG" + Culture="1033" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile=".\Debug\Bullet.lib" + SuppressStartupBanner="true" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory=".\Release" + IntermediateDirectory=".\Release" + ConfigurationType="4" + UseOfMFC="0" + ATLMinimizesCRunTimeLibraryUsage="false" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + InlineFunctionExpansion="1" + AdditionalIncludeDirectories=".;..\LinearMath" + PreprocessorDefinitions="NDEBUG;_LIB;WIN32;BUM_INLINED;USE_ALGEBRAIC" + StringPooling="true" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + PrecompiledHeaderFile="" + AssemblerListingLocation=".\Release/" + ObjectFile=".\Release/" + ProgramDataBaseFileName=".\Release/" + WarningLevel="3" + SuppressStartupBanner="true" + DebugInformationFormat="3" + CompileAs="0" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + PreprocessorDefinitions="NDEBUG" + Culture="1033" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile=".\Release\Bullet.lib" + SuppressStartupBanner="true" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="NarrowPhaseCollision" + > + <File + RelativePath=".\NarrowPhaseCollision\BU_AlgebraicPolynomialSolver.cpp" + > + </File> + <File + RelativePath=".\NarrowPhaseCollision\BU_AlgebraicPolynomialSolver.h" + > + </File> + <File + RelativePath=".\NarrowPhaseCollision\BU_Collidable.cpp" + > + </File> + <File + RelativePath=".\NarrowPhaseCollision\BU_Collidable.h" + > + </File> + <File + RelativePath=".\NarrowPhaseCollision\BU_CollisionPair.cpp" + > + </File> + <File + RelativePath=".\NarrowPhaseCollision\BU_CollisionPair.h" + > + </File> + <File + RelativePath=".\NarrowPhaseCollision\BU_EdgeEdge.cpp" + > + </File> + <File + RelativePath=".\NarrowPhaseCollision\BU_EdgeEdge.h" + > + </File> + <File + RelativePath=".\NarrowPhaseCollision\BU_MotionStateInterface.h" + > + </File> + <File + RelativePath=".\NarrowPhaseCollision\BU_PolynomialSolverInterface.h" + > + </File> + <File + RelativePath=".\NarrowPhaseCollision\BU_Screwing.cpp" + > + </File> + <File + RelativePath=".\NarrowPhaseCollision\BU_Screwing.h" + > + </File> + <File + RelativePath=".\NarrowPhaseCollision\BU_StaticMotionState.h" + > + </File> + <File + RelativePath=".\NarrowPhaseCollision\BU_VertexPoly.cpp" + > + </File> + <File + RelativePath=".\NarrowPhaseCollision\BU_VertexPoly.h" + > + </File> + <File + RelativePath=".\NarrowPhaseCollision\CollisionMargin.h" + > + </File> + <File + RelativePath=".\NarrowPhaseCollision\ContinuousConvexCollision.cpp" + > + </File> + <File + RelativePath=".\NarrowPhaseCollision\ContinuousConvexCollision.h" + > + </File> + <File + RelativePath=".\NarrowPhaseCollision\ConvexCast.cpp" + > + </File> + <File + RelativePath=".\NarrowPhaseCollision\ConvexCast.h" + > + </File> + <File + RelativePath=".\NarrowPhaseCollision\ConvexPenetrationDepthSolver.h" + > + </File> + <File + RelativePath=".\NarrowPhaseCollision\DiscreteCollisionDetectorInterface.h" + > + </File> + <File + RelativePath=".\NarrowPhaseCollision\GjkConvexCast.cpp" + > + </File> + <File + RelativePath=".\NarrowPhaseCollision\GjkConvexCast.h" + > + </File> + <File + RelativePath=".\NarrowPhaseCollision\GjkPairDetector.cpp" + > + </File> + <File + RelativePath=".\NarrowPhaseCollision\GjkPairDetector.h" + > + </File> + <File + RelativePath=".\NarrowPhaseCollision\ManifoldPoint.h" + > + </File> + <File + RelativePath=".\NarrowPhaseCollision\ManifoldPointCollector.cpp" + > + </File> + <File + RelativePath=".\NarrowPhaseCollision\ManifoldPointCollector.h" + > + </File> + <File + RelativePath=".\NarrowPhaseCollision\MinkowskiPenetrationDepthSolver.cpp" + > + </File> + <File + RelativePath=".\NarrowPhaseCollision\MinkowskiPenetrationDepthSolver.h" + > + </File> + <File + RelativePath=".\NarrowPhaseCollision\PersistentManifold.cpp" + > + </File> + <File + RelativePath=".\NarrowPhaseCollision\PersistentManifold.h" + > + </File> + <File + RelativePath=".\NarrowPhaseCollision\PointCollector.h" + > + </File> + <File + RelativePath=".\NarrowPhaseCollision\RaycastCallback.cpp" + > + </File> + <File + RelativePath=".\NarrowPhaseCollision\RaycastCallback.h" + > + </File> + <File + RelativePath=".\NarrowPhaseCollision\SimplexSolverInterface.h" + > + </File> + <File + RelativePath=".\NarrowPhaseCollision\SubSimplexConvexCast.cpp" + > + </File> + <File + RelativePath=".\NarrowPhaseCollision\SubSimplexConvexCast.h" + > + </File> + <File + RelativePath=".\NarrowPhaseCollision\VoronoiSimplexSolver.cpp" + > + </File> + <File + RelativePath=".\NarrowPhaseCollision\VoronoiSimplexSolver.h" + > + </File> + </Filter> + <Filter + Name="CollisionShapes" + > + <File + RelativePath=".\CollisionShapes\BoxShape.cpp" + > + </File> + <File + RelativePath=".\CollisionShapes\BoxShape.h" + > + </File> + <File + RelativePath=".\CollisionShapes\CollisionShape.cpp" + > + </File> + <File + RelativePath=".\CollisionShapes\CollisionShape.h" + > + </File> + <File + RelativePath=".\CollisionShapes\ConeShape.cpp" + > + </File> + <File + RelativePath=".\CollisionShapes\ConeShape.h" + > + </File> + <File + RelativePath=".\CollisionShapes\ConvexHullShape.cpp" + > + </File> + <File + RelativePath=".\CollisionShapes\ConvexHullShape.h" + > + </File> + <File + RelativePath=".\CollisionShapes\ConvexShape.cpp" + > + </File> + <File + RelativePath=".\CollisionShapes\ConvexShape.h" + > + </File> + <File + RelativePath=".\CollisionShapes\CylinderShape.cpp" + > + </File> + <File + RelativePath=".\CollisionShapes\CylinderShape.h" + > + </File> + <File + RelativePath=".\CollisionShapes\MinkowskiSumShape.cpp" + > + </File> + <File + RelativePath=".\CollisionShapes\MinkowskiSumShape.h" + > + </File> + <File + RelativePath=".\CollisionShapes\MultiSphereShape.cpp" + > + </File> + <File + RelativePath=".\CollisionShapes\MultiSphereShape.h" + > + </File> + <File + RelativePath=".\CollisionShapes\PolyhedralConvexShape.cpp" + > + </File> + <File + RelativePath=".\CollisionShapes\PolyhedralConvexShape.h" + > + </File> + <File + RelativePath=".\CollisionShapes\Simplex1to4Shape.cpp" + > + </File> + <File + RelativePath=".\CollisionShapes\Simplex1to4Shape.h" + > + </File> + <File + RelativePath=".\CollisionShapes\SphereShape.cpp" + > + </File> + <File + RelativePath=".\CollisionShapes\SphereShape.h" + > + </File> + <File + RelativePath=".\CollisionShapes\StridingMeshInterface.cpp" + > + </File> + <File + RelativePath=".\CollisionShapes\StridingMeshInterface.h" + > + </File> + <File + RelativePath=".\CollisionShapes\TriangleCallback.h" + > + </File> + <File + RelativePath=".\CollisionShapes\TriangleMeshShape.cpp" + > + </File> + <File + RelativePath=".\CollisionShapes\TriangleMeshShape.h" + > + </File> + <File + RelativePath=".\CollisionShapes\TriangleShape.h" + > + </File> + </Filter> + <Filter + Name="BroadphaseCollision" + > + <File + RelativePath=".\BroadphaseCollision\BroadPhaseInterface.h" + > + </File> + <File + RelativePath=".\BroadphaseCollision\BroadphaseProxy.cpp" + > + </File> + <File + RelativePath=".\BroadphaseCollision\BroadphaseProxy.h" + > + </File> + <File + RelativePath=".\BroadphaseCollision\CollisionAlgorithm.cpp" + > + </File> + <File + RelativePath=".\BroadphaseCollision\CollisionAlgorithm.h" + > + </File> + <File + RelativePath=".\BroadphaseCollision\CollisionDispatcher.cpp" + > + </File> + <File + RelativePath=".\BroadphaseCollision\CollisionDispatcher.h" + > + </File> + <File + RelativePath=".\BroadphaseCollision\SimpleBroadphase.cpp" + > + </File> + <File + RelativePath=".\BroadphaseCollision\SimpleBroadphase.h" + > + </File> + </Filter> + <Filter + Name="LinearAlgebra" + > + <File + RelativePath="..\LinearMath\AabbUtil2.h" + > + </File> + <File + RelativePath="..\LinearMath\GEN_List.h" + > + </File> + <File + RelativePath="..\LinearMath\GEN_MinMax.h" + > + </File> + <File + RelativePath="..\LinearMath\GEN_random.h" + > + </File> + <File + RelativePath="..\LinearMath\SimdMatrix3x3.h" + > + </File> + <File + RelativePath="..\LinearMath\SimdMinMax.h" + > + </File> + <File + RelativePath="..\LinearMath\SimdPoint3.h" + > + </File> + <File + RelativePath="..\LinearMath\SimdQuadword.h" + > + </File> + <File + RelativePath="..\LinearMath\SimdQuaternion.h" + > + </File> + <File + RelativePath="..\LinearMath\SimdScalar.h" + > + </File> + <File + RelativePath="..\LinearMath\SimdTransform.h" + > + </File> + <File + RelativePath="..\LinearMath\SimdTransformUtil.h" + > + </File> + <File + RelativePath="..\LinearMath\SimdVector3.h" + > + </File> + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/extern/bullet/Bullet/CollisionShapes/BoxShape.cpp b/extern/bullet/Bullet/CollisionShapes/BoxShape.cpp new file mode 100644 index 00000000000..4edd8cf9a12 --- /dev/null +++ b/extern/bullet/Bullet/CollisionShapes/BoxShape.cpp @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. + */ + +#include "BoxShape.h" + + +void BoxShape::GetAabb(const SimdTransform& t,SimdVector3& aabbMin,SimdVector3& aabbMax) const +{ + SimdVector3 halfExtents = GetHalfExtents(); + + SimdMatrix3x3 abs_b = t.getBasis().absolute(); + SimdPoint3 center = t.getOrigin(); + SimdVector3 extent = SimdVector3(abs_b[0].dot(halfExtents), + abs_b[1].dot(halfExtents), + abs_b[2].dot(halfExtents)); + extent += SimdVector3(GetMargin(),GetMargin(),GetMargin()); + + + //todo: this is a quick fix, we need to enlarge the aabb dependent on several criteria + //extent += SimdVector3(.2f,.2f,.2f); + + aabbMin = center - extent; + aabbMax = center + extent; + + +} diff --git a/extern/bullet/Bullet/CollisionShapes/BoxShape.h b/extern/bullet/Bullet/CollisionShapes/BoxShape.h new file mode 100644 index 00000000000..620ddd7e4f6 --- /dev/null +++ b/extern/bullet/Bullet/CollisionShapes/BoxShape.h @@ -0,0 +1,274 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. + */ + +#ifndef OBB_BOX_MINKOWSKI_H +#define OBB_BOX_MINKOWSKI_H + +#include "PolyhedralConvexShape.h" +#include "NarrowPhaseCollision/CollisionMargin.h" +#include "BroadphaseCollision/BroadphaseProxy.h" +#include "SimdPoint3.h" +#include "SimdMinMax.h" + +///BoxShape implements both a feature based (vertex/edge/plane) and implicit (getSupportingVertex) Box +class BoxShape: public PolyhedralConvexShape +{ + + SimdVector3 m_boxHalfExtents1; + + +public: + + virtual ~BoxShape() + { + + } + + SimdVector3 GetHalfExtents() const{ return m_boxHalfExtents1 * m_localScaling;} + //const SimdVector3& GetHalfExtents() const{ return m_boxHalfExtents1;} + + + + virtual int GetShapeType() const { return BOX_SHAPE_PROXYTYPE;} + + virtual SimdVector3 LocalGetSupportingVertex(const SimdVector3& vec) const + { + + SimdVector3 halfExtents = GetHalfExtents(); + + SimdVector3 supVertex; + supVertex = SimdPoint3(vec.x() < SimdScalar(0.0f) ? -halfExtents.x() : halfExtents.x(), + vec.y() < SimdScalar(0.0f) ? -halfExtents.y() : halfExtents.y(), + vec.z() < SimdScalar(0.0f) ? -halfExtents.z() : halfExtents.z()); + + + if ( GetMargin()!=0.f ) + { + SimdVector3 vecnorm = vec; + if (vecnorm .length2() == 0.f) + { + vecnorm.setValue(-1.f,-1.f,-1.f); + } + vecnorm.normalize(); + supVertex+= GetMargin() * vecnorm; + } + return supVertex; + } + + + virtual SimdVector3 LocalGetSupportingVertexWithoutMargin(const SimdVector3& vec)const + { + SimdVector3 halfExtents = GetHalfExtents(); + + return SimdVector3(vec.x() < SimdScalar(0.0f) ? -halfExtents.x() : halfExtents.x(), + vec.y() < SimdScalar(0.0f) ? -halfExtents.y() : halfExtents.y(), + vec.z() < SimdScalar(0.0f) ? -halfExtents.z() : halfExtents.z()); + } + + + BoxShape( const SimdVector3& boxHalfExtents) : m_boxHalfExtents1(boxHalfExtents){}; + + virtual void GetAabb(const SimdTransform& t,SimdVector3& aabbMin,SimdVector3& aabbMax) const; + + + + virtual void CalculateLocalInertia(SimdScalar mass,SimdVector3& inertia) + { + float margin = GetMargin(); + SimdVector3 halfExtents = GetHalfExtents(); + + SimdScalar lx=2.f*(halfExtents.x()+margin); + SimdScalar ly=2.f*(halfExtents.y()+margin); + SimdScalar lz=2.f*(halfExtents.z()+margin); + const SimdScalar x2 = lx*lx; + const SimdScalar y2 = ly*ly; + const SimdScalar z2 = lz*lz; + const SimdScalar scaledmass = mass * 0.08333333f; + + inertia = scaledmass * (SimdVector3(y2+z2,x2+z2,x2+y2)); + +// inertia.x() = scaledmass * (y2+z2); +// inertia.y() = scaledmass * (x2+z2); +// inertia.z() = scaledmass * (x2+y2); + } + + + virtual void GetPlane(SimdVector3& planeNormal,SimdPoint3& planeSupport,int i ) const + { + //this plane might not be aligned... + SimdVector4 plane ; + GetPlaneEquation(plane,i); + planeNormal = SimdVector3(plane.getX(),plane.getY(),plane.getZ()); + planeSupport = LocalGetSupportingVertex(-planeNormal); + } + + + virtual int GetNumPlanes() const + { + return 6; + } + + virtual int GetNumVertices() const + { + return 8; + } + + virtual int GetNumEdges() const + { + return 12; + } + + + virtual void GetVertex(int i,SimdVector3& vtx) const + { + SimdVector3 halfExtents = GetHalfExtents(); + + vtx = SimdVector3( + halfExtents.x() * (1-(i&1)) - halfExtents.x() * (i&1), + halfExtents.y() * (1-((i&2)>>1)) - halfExtents.y() * ((i&2)>>1), + halfExtents.z() * (1-((i&4)>>2)) - halfExtents.z() * ((i&4)>>2)); + } + + + virtual void GetPlaneEquation(SimdVector4& plane,int i) const + { + SimdVector3 halfExtents = GetHalfExtents(); + + switch (i) + { + case 0: + plane.setValue(1.f,0.f,0.f); + plane[3] = -halfExtents.x(); + break; + case 1: + plane.setValue(-1.f,0.f,0.f); + plane[3] = -halfExtents.x(); + break; + case 2: + plane.setValue(0.f,1.f,0.f); + plane[3] = -halfExtents.y(); + break; + case 3: + plane.setValue(0.f,-1.f,0.f); + plane[3] = -halfExtents.y(); + break; + case 4: + plane.setValue(0.f,0.f,1.f); + plane[3] = -halfExtents.z(); + break; + case 5: + plane.setValue(0.f,0.f,-1.f); + plane[3] = -halfExtents.z(); + break; + default: + assert(0); + } + } + + + virtual void GetEdge(int i,SimdPoint3& pa,SimdPoint3& pb) const + //virtual void GetEdge(int i,Edge& edge) const + { + int edgeVert0 = 0; + int edgeVert1 = 0; + + switch (i) + { + case 0: + edgeVert0 = 0; + edgeVert1 = 1; + break; + case 1: + edgeVert0 = 0; + edgeVert1 = 2; + break; + case 2: + edgeVert0 = 1; + edgeVert1 = 3; + + break; + case 3: + edgeVert0 = 2; + edgeVert1 = 3; + break; + case 4: + edgeVert0 = 0; + edgeVert1 = 4; + break; + case 5: + edgeVert0 = 1; + edgeVert1 = 5; + + break; + case 6: + edgeVert0 = 2; + edgeVert1 = 6; + break; + case 7: + edgeVert0 = 3; + edgeVert1 = 7; + break; + case 8: + edgeVert0 = 4; + edgeVert1 = 5; + break; + case 9: + edgeVert0 = 4; + edgeVert1 = 6; + break; + case 10: + edgeVert0 = 5; + edgeVert1 = 7; + break; + case 11: + edgeVert0 = 6; + edgeVert1 = 7; + break; + default: + ASSERT(0); + + } + + GetVertex(edgeVert0,pa ); + GetVertex(edgeVert1,pb ); + } + + + + + + virtual bool IsInside(const SimdPoint3& pt,SimdScalar tolerance) const + { + SimdVector3 halfExtents = GetHalfExtents(); + + //SimdScalar minDist = 2*tolerance; + + bool result = (pt.x() <= (halfExtents.x()+tolerance)) && + (pt.x() >= (-halfExtents.x()-tolerance)) && + (pt.y() <= (halfExtents.y()+tolerance)) && + (pt.y() >= (-halfExtents.y()-tolerance)) && + (pt.z() <= (halfExtents.z()+tolerance)) && + (pt.z() >= (-halfExtents.z()-tolerance)); + + return result; + } + + + //debugging + virtual char* GetName()const + { + return "Box"; + } + + +}; + +#endif //OBB_BOX_MINKOWSKI_H diff --git a/extern/bullet/Bullet/CollisionShapes/CollisionShape.cpp b/extern/bullet/Bullet/CollisionShapes/CollisionShape.cpp new file mode 100644 index 00000000000..4bd1619cbf3 --- /dev/null +++ b/extern/bullet/Bullet/CollisionShapes/CollisionShape.cpp @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#include "CollisionShapes/CollisionShape.h" + +void CollisionShape::GetBoundingSphere(SimdVector3& center,SimdScalar& radius) const +{ + SimdTransform tr; + tr.setIdentity(); + SimdVector3 aabbMin,aabbMax; + + GetAabb(tr,aabbMin,aabbMax); + + radius = (aabbMax-aabbMin).length()*0.5f; + center = (aabbMin+aabbMax)*0.5f; +} + +float CollisionShape::GetAngularMotionDisc() const +{ + SimdVector3 center; + float disc; + GetBoundingSphere(center,disc); + disc += (center).length(); + return disc; +} + +void CollisionShape::CalculateTemporalAabb(const SimdTransform& curTrans,const SimdVector3& linvel,const SimdVector3& angvel,SimdScalar timeStep, SimdVector3& temporalAabbMin,SimdVector3& temporalAabbMax) +{ + //start with static aabb + GetAabb(curTrans,temporalAabbMin,temporalAabbMax); + + float temporalAabbMaxx = temporalAabbMax.getX(); + float temporalAabbMaxy = temporalAabbMax.getY(); + float temporalAabbMaxz = temporalAabbMax.getZ(); + float temporalAabbMinx = temporalAabbMin.getX(); + float temporalAabbMiny = temporalAabbMin.getY(); + float temporalAabbMinz = temporalAabbMin.getZ(); + + // add linear motion + SimdVector3 linMotion = linvel*timeStep; + //todo: simd would have a vector max/min operation, instead of per-element access + if (linMotion.x() > 0.f) + temporalAabbMaxx += linMotion.x(); + else + temporalAabbMinx += linMotion.x(); + if (linMotion.y() > 0.f) + temporalAabbMaxy += linMotion.y(); + else + temporalAabbMiny += linMotion.y(); + if (linMotion.z() > 0.f) + temporalAabbMaxz += linMotion.z(); + else + temporalAabbMinz += linMotion.z(); + + //add conservative angular motion + SimdScalar angularMotion = angvel.length() * GetAngularMotionDisc() * timeStep; + SimdVector3 angularMotion3d(angularMotion,angularMotion,angularMotion); + temporalAabbMin = SimdVector3(temporalAabbMinx,temporalAabbMiny,temporalAabbMinz); + temporalAabbMax = SimdVector3(temporalAabbMaxx,temporalAabbMaxy,temporalAabbMaxz); + + temporalAabbMin -= angularMotion3d; + temporalAabbMax += angularMotion3d; +} diff --git a/extern/bullet/Bullet/CollisionShapes/CollisionShape.h b/extern/bullet/Bullet/CollisionShapes/CollisionShape.h new file mode 100644 index 00000000000..6969075f38c --- /dev/null +++ b/extern/bullet/Bullet/CollisionShapes/CollisionShape.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#ifndef COLLISION_SHAPE_H +#define COLLISION_SHAPE_H + +#include "SimdTransform.h" +#include "SimdVector3.h" +#include <SimdMatrix3x3.h> +#include "SimdPoint3.h" +#include "BroadphaseCollision/BroadphaseProxy.h" //for the shape types + +///CollisionShape provides generic interface for collidable objects +class CollisionShape +{ + +public: + + CollisionShape() + :m_tempDebug(0) + { + } + virtual ~CollisionShape() + { + } + + virtual void GetAabb(const SimdTransform& t,SimdVector3& aabbMin,SimdVector3& aabbMax) const =0; + + virtual void GetBoundingSphere(SimdVector3& center,SimdScalar& radius) const; + + virtual float GetAngularMotionDisc() const; + + virtual int GetShapeType() const=0; + + ///CalculateTemporalAabb calculates the enclosing aabb for the moving object over interval [0..timeStep) + ///result is conservative + void CalculateTemporalAabb(const SimdTransform& curTrans,const SimdVector3& linvel,const SimdVector3& angvel,SimdScalar timeStep, SimdVector3& temporalAabbMin,SimdVector3& temporalAabbMax); + + bool IsPolyhedral() const + { + return (GetShapeType() < IMPLICIT_CONVEX_SHAPES_START_HERE); + } + + bool IsConvex() const + { + return (GetShapeType() < CONCAVE_SHAPES_START_HERE); + } + bool IsConcave() const + { + return (GetShapeType() > CONCAVE_SHAPES_START_HERE); + } + + + virtual void setLocalScaling(const SimdVector3& scaling) =0; + + virtual void CalculateLocalInertia(SimdScalar mass,SimdVector3& inertia) = 0; + +//debugging support + virtual char* GetName()const =0 ; + const char* GetExtraDebugInfo() const { return m_tempDebug;} + void SetExtraDebugInfo(const char* extraDebugInfo) { m_tempDebug = extraDebugInfo;} + const char * m_tempDebug; +//endif debugging support + + +}; + +#endif //COLLISION_SHAPE_H + diff --git a/extern/bullet/Bullet/CollisionShapes/ConeShape.cpp b/extern/bullet/Bullet/CollisionShapes/ConeShape.cpp new file mode 100644 index 00000000000..40e762125ac --- /dev/null +++ b/extern/bullet/Bullet/CollisionShapes/ConeShape.cpp @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#include "ConeShape.h" +#include "SimdPoint3.h" + +#ifdef WIN32 +static int coneindices[3] = {1,2,0}; +#else +static int coneindices[3] = {2,1,0}; +#endif + +ConeShape::ConeShape (SimdScalar radius,SimdScalar height): +m_radius (radius), +m_height(height) +{ + SimdVector3 halfExtents; + m_sinAngle = (m_radius / sqrt(m_radius * m_radius + m_height * m_height)); +} + + +SimdVector3 ConeShape::ConeLocalSupport(const SimdVector3& v) const +{ + + float halfHeight = m_height * 0.5f; + + if (v[coneindices[1]] > v.length() * m_sinAngle) + { + SimdVector3 tmp; + + tmp[coneindices[0]] = 0.f; + tmp[coneindices[1]] = halfHeight; + tmp[coneindices[2]] = 0.f; + return tmp; + } + else { + SimdScalar s = sqrtf(v[coneindices[0]] * v[coneindices[0]] + v[coneindices[2]] * v[coneindices[2]]); + if (s > SIMD_EPSILON) { + SimdScalar d = m_radius / s; + SimdVector3 tmp; + tmp[coneindices[0]] = v[coneindices[0]] * d; + tmp[coneindices[1]] = -halfHeight; + tmp[coneindices[2]] = v[coneindices[2]] * d; + return tmp; + } + else { + SimdVector3 tmp; + tmp[coneindices[0]] = 0.f; + tmp[coneindices[1]] = -halfHeight; + tmp[coneindices[2]] = 0.f; + return tmp; + } + } + +} + +SimdVector3 ConeShape::LocalGetSupportingVertexWithoutMargin(const SimdVector3& vec) const +{ + return ConeLocalSupport(vec); +} + +SimdVector3 ConeShape::LocalGetSupportingVertex(const SimdVector3& vec) const +{ + SimdVector3 supVertex = ConeLocalSupport(vec); + if ( GetMargin()!=0.f ) + { + SimdVector3 vecnorm = vec; + if (vecnorm .length2() == 0.f) + { + vecnorm.setValue(-1.f,-1.f,-1.f); + } + vecnorm.normalize(); + supVertex+= GetMargin() * vecnorm; + } + return supVertex; +} + + diff --git a/extern/bullet/Bullet/CollisionShapes/ConeShape.h b/extern/bullet/Bullet/CollisionShapes/ConeShape.h new file mode 100644 index 00000000000..88117e1bec3 --- /dev/null +++ b/extern/bullet/Bullet/CollisionShapes/ConeShape.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#ifndef CONE_MINKOWSKI_H +#define CONE_MINKOWSKI_H + +#include "ConvexShape.h" +#include "BroadphaseCollision/BroadphaseProxy.h" // for the types + +/// implements cone shape interface +class ConeShape : public ConvexShape + +{ + + float m_sinAngle; + float m_radius; + float m_height; + + SimdVector3 ConeLocalSupport(const SimdVector3& v) const; + + +public: + ConeShape (SimdScalar radius,SimdScalar height); + + virtual SimdVector3 LocalGetSupportingVertex(const SimdVector3& vec) const; + virtual SimdVector3 LocalGetSupportingVertexWithoutMargin(const SimdVector3& vec) const; + + + virtual void CalculateLocalInertia(SimdScalar mass,SimdVector3& inertia) + { + SimdTransform identity; + identity.setIdentity(); + SimdVector3 aabbMin,aabbMax; + GetAabb(identity,aabbMin,aabbMax); + + SimdVector3 halfExtents = (aabbMax-aabbMin)*0.5f; + + float margin = GetMargin(); + + SimdScalar lx=2.f*(halfExtents.x()+margin); + SimdScalar ly=2.f*(halfExtents.y()+margin); + SimdScalar lz=2.f*(halfExtents.z()+margin); + const SimdScalar x2 = lx*lx; + const SimdScalar y2 = ly*ly; + const SimdScalar z2 = lz*lz; + const SimdScalar scaledmass = mass * 0.08333333f; + + inertia = scaledmass * (SimdVector3(y2+z2,x2+z2,x2+y2)); + +// inertia.x() = scaledmass * (y2+z2); +// inertia.y() = scaledmass * (x2+z2); +// inertia.z() = scaledmass * (x2+y2); + } + + + + virtual int GetShapeType() const { return CONE_SHAPE_PROXYTYPE; } + + virtual char* GetName()const + { + return "Cone"; + } +}; + + +#endif //CONE_MINKOWSKI_H
\ No newline at end of file diff --git a/extern/bullet/Bullet/CollisionShapes/ConvexHullShape.cpp b/extern/bullet/Bullet/CollisionShapes/ConvexHullShape.cpp new file mode 100644 index 00000000000..0206324fa04 --- /dev/null +++ b/extern/bullet/Bullet/CollisionShapes/ConvexHullShape.cpp @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. + */ + +#include "ConvexHullShape.h" +#include "NarrowPhaseCollision/CollisionMargin.h" + +#include "SimdQuaternion.h" + + +ConvexHullShape ::ConvexHullShape (SimdPoint3* points,int numPoints) +{ + m_points.resize(numPoints); + for (int i=0;i<numPoints;i++) + m_points[i] = points[i]; +} + +SimdVector3 ConvexHullShape::LocalGetSupportingVertexWithoutMargin(const SimdVector3& vec0)const +{ + SimdVector3 supVec(0.f,0.f,0.f); + SimdScalar newDot,maxDot = -1e30f; + + SimdVector3 vec = vec0; + SimdScalar lenSqr = vec.length2(); + if (lenSqr < 0.0001f) + { + vec.setValue(1,0,0); + } else + { + float rlen = 1.f / sqrtf(lenSqr ); + vec *= rlen; + } + + + for (int i=0;i<m_points.size();i++) + { + SimdPoint3 vtx = m_points[i] * m_localScaling; + + newDot = vec.dot(vtx); + if (newDot > maxDot) + { + maxDot = newDot; + supVec = vtx; + } + } + return supVec; +} + + +SimdVector3 ConvexHullShape::LocalGetSupportingVertex(const SimdVector3& vec)const +{ + SimdVector3 supVertex = LocalGetSupportingVertexWithoutMargin(vec); + + if ( GetMargin()!=0.f ) + { + SimdVector3 vecnorm = vec; + if (vecnorm .length2() == 0.f) + { + vecnorm.setValue(-1.f,-1.f,-1.f); + } + vecnorm.normalize(); + supVertex+= GetMargin() * vecnorm; + } + return supVertex; +} + + + + + +void ConvexHullShape::CalculateLocalInertia(SimdScalar mass,SimdVector3& inertia) +{ + //not yet, return box inertia + + float margin = GetMargin(); + + SimdTransform ident; + ident.setIdentity(); + SimdVector3 aabbMin,aabbMax; + GetAabb(ident,aabbMin,aabbMax); + SimdVector3 halfExtents = (aabbMax-aabbMin)*0.5f; + + SimdScalar lx=2.f*(halfExtents.x()+margin); + SimdScalar ly=2.f*(halfExtents.y()+margin); + SimdScalar lz=2.f*(halfExtents.z()+margin); + const SimdScalar x2 = lx*lx; + const SimdScalar y2 = ly*ly; + const SimdScalar z2 = lz*lz; + const SimdScalar scaledmass = mass * 0.08333333f; + + inertia = scaledmass * (SimdVector3(y2+z2,x2+z2,x2+y2)); + +} + + + +//currently just for debugging (drawing), perhaps future support for algebraic continuous collision detection +//Please note that you can debug-draw ConvexHullShape with the Raytracer Demo +int ConvexHullShape::GetNumVertices() const +{ + return m_points.size(); +} + +int ConvexHullShape::GetNumEdges() const +{ + return m_points.size()*m_points.size(); +} + +void ConvexHullShape::GetEdge(int i,SimdPoint3& pa,SimdPoint3& pb) const +{ + + int index0 = i%m_points.size(); + int index1 = i/m_points.size(); + pa = m_points[index0]; + pb = m_points[index1]; +} + +void ConvexHullShape::GetVertex(int i,SimdPoint3& vtx) const +{ + vtx = m_points[i]; +} + +int ConvexHullShape::GetNumPlanes() const +{ + return 0; +} + +void ConvexHullShape::GetPlane(SimdVector3& planeNormal,SimdPoint3& planeSupport,int i ) const +{ + assert(0); +} + +//not yet +bool ConvexHullShape::IsInside(const SimdPoint3& pt,SimdScalar tolerance) const +{ + assert(0); + return false; +} + diff --git a/extern/bullet/Bullet/CollisionShapes/ConvexHullShape.h b/extern/bullet/Bullet/CollisionShapes/ConvexHullShape.h new file mode 100644 index 00000000000..5be0b61da6f --- /dev/null +++ b/extern/bullet/Bullet/CollisionShapes/ConvexHullShape.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. + */ + +#ifndef CONVEX_HULL_SHAPE_H +#define CONVEX_HULL_SHAPE_H + +#include "PolyhedralConvexShape.h" +#include "BroadphaseCollision/BroadphaseProxy.h" // for the types + +#include <vector> + +///ConvexHullShape implements an implicit (getSupportingVertex) Convex Hull of a Point Cloud (vertices) +///No connectivity is needed. LocalGetSupportingVertex iterates linearly though all vertices. +///on modern hardware, due to cache coherency this isn't that bad. Complex algorithms tend to trash the cash. +///(memory is much slower then the cpu) +class ConvexHullShape : public PolyhedralConvexShape +{ + std::vector<SimdPoint3> m_points; + +public: + ConvexHullShape(SimdPoint3* points,int numPoints); + + void AddPoint(const SimdPoint3& point) + { + m_points.push_back(point); + } + virtual SimdVector3 LocalGetSupportingVertex(const SimdVector3& vec)const; + virtual SimdVector3 LocalGetSupportingVertexWithoutMargin(const SimdVector3& vec)const; + + virtual void CalculateLocalInertia(SimdScalar mass,SimdVector3& inertia); + + virtual int GetShapeType()const { return CONVEX_HULL_SHAPE_PROXYTYPE; } + + //debugging + virtual char* GetName()const {return "Convex";} + + + virtual int GetNumVertices() const; + virtual int GetNumEdges() const; + virtual void GetEdge(int i,SimdPoint3& pa,SimdPoint3& pb) const; + virtual void GetVertex(int i,SimdPoint3& vtx) const; + virtual int GetNumPlanes() const; + virtual void GetPlane(SimdVector3& planeNormal,SimdPoint3& planeSupport,int i ) const; + virtual bool IsInside(const SimdPoint3& pt,SimdScalar tolerance) const; + + + +}; + + +#endif //CONVEX_HULL_SHAPE_H
\ No newline at end of file diff --git a/extern/bullet/Bullet/CollisionShapes/ConvexShape.cpp b/extern/bullet/Bullet/CollisionShapes/ConvexShape.cpp new file mode 100644 index 00000000000..f2afb338166 --- /dev/null +++ b/extern/bullet/Bullet/CollisionShapes/ConvexShape.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. + */ + +#include "ConvexShape.h" + +ConvexShape::~ConvexShape() +{ + +} + +ConvexShape::ConvexShape() +:m_collisionMargin(CONVEX_DISTANCE_MARGIN), +m_localScaling(1.f,1.f,1.f) +{ +} + + +void ConvexShape::setLocalScaling(const SimdVector3& scaling) +{ + m_localScaling = scaling; +} + + + +void ConvexShape::GetAabbSlow(const SimdTransform& trans,SimdVector3&minAabb,SimdVector3&maxAabb) const +{ + + SimdScalar margin = 0.05f; + for (int i=0;i<3;i++) + { + SimdVector3 vec(0.f,0.f,0.f); + vec[i] = 1.f; + SimdVector3 tmp = trans(LocalGetSupportingVertex(vec*trans.getBasis())); + maxAabb[i] = tmp[i]+margin; + vec[i] = -1.f; + tmp = trans(LocalGetSupportingVertex(vec*trans.getBasis())); + minAabb[i] = tmp[i]-margin; + } +}; + +SimdVector3 ConvexShape::LocalGetSupportingVertex(const SimdVector3& vec)const + { + SimdVector3 supVertex = LocalGetSupportingVertexWithoutMargin(vec); + + if ( GetMargin()!=0.f ) + { + SimdVector3 vecnorm = vec; + if (vecnorm .length2() == 0.f) + { + vecnorm.setValue(-1.f,-1.f,-1.f); + } + vecnorm.normalize(); + supVertex+= GetMargin() * vecnorm; + } + return supVertex; + + } + + diff --git a/extern/bullet/Bullet/CollisionShapes/ConvexShape.h b/extern/bullet/Bullet/CollisionShapes/ConvexShape.h new file mode 100644 index 00000000000..345358e47fc --- /dev/null +++ b/extern/bullet/Bullet/CollisionShapes/ConvexShape.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. + */ + +#ifndef CONVEX_SHAPE_INTERFACE1 +#define CONVEX_SHAPE_INTERFACE1 + +#include "CollisionShape.h" + +#include "SimdVector3.h" +#include "SimdTransform.h" +#include "SimdMatrix3x3.h" +#include <vector> +#include "NarrowPhaseCollision/CollisionMargin.h" + +//todo: get rid of this ConvexCastResult thing! +struct ConvexCastResult; + + +/// ConvexShape is an abstract shape interface. +/// The explicit part provides plane-equations, the implicit part provides GetClosestPoint interface. +/// used in combination with GJK or ConvexCast +class ConvexShape : public CollisionShape +{ +public: + ConvexShape(); + + virtual ~ConvexShape(); + + virtual SimdVector3 LocalGetSupportingVertex(const SimdVector3& vec)const; + virtual SimdVector3 LocalGetSupportingVertexWithoutMargin(const SimdVector3& vec) const= 0; + + // testing for hullnode code + + ///GetAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version + void GetAabb(const SimdTransform& t,SimdVector3& aabbMin,SimdVector3& aabbMax) const + { + GetAabbSlow(t,aabbMin,aabbMax); + } + + + + virtual void GetAabbSlow(const SimdTransform& t,SimdVector3& aabbMin,SimdVector3& aabbMax) const; + + + virtual void setLocalScaling(const SimdVector3& scaling); + + + virtual void SetMargin(float margin) + { + m_collisionMargin = margin; + } + virtual float GetMargin() const + { + return m_collisionMargin; + } +private: + SimdScalar m_collisionMargin; + //local scaling. collisionMargin is not scaled ! +protected: + SimdVector3 m_localScaling; + +}; + + + +#endif //CONVEX_SHAPE_INTERFACE1 diff --git a/extern/bullet/Bullet/CollisionShapes/CylinderShape.cpp b/extern/bullet/Bullet/CollisionShapes/CylinderShape.cpp new file mode 100644 index 00000000000..4af83d55a68 --- /dev/null +++ b/extern/bullet/Bullet/CollisionShapes/CylinderShape.cpp @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. + */ + +#include "CylinderShape.h" +#include "SimdPoint3.h" + +CylinderShape::CylinderShape (const SimdVector3& halfExtents) +:BoxShape(halfExtents) +{ + +} + + +CylinderShapeX::CylinderShapeX (const SimdVector3& halfExtents) +:CylinderShape(halfExtents) +{ +} + + +CylinderShapeZ::CylinderShapeZ (const SimdVector3& halfExtents) +:CylinderShape(halfExtents) +{ +} + + + +SimdVector3 CylinderLocalSupportX(const SimdVector3& halfExtents,const SimdVector3& v) +{ +const int cylinderUpAxis = 0; +const int XX = 1; +const int YY = 0; +const int ZZ = 2; + + //mapping depends on how cylinder local orientation is + // extents of the cylinder is: X,Y is for radius, and Z for height + + + float radius = halfExtents[XX]; + float halfHeight = halfExtents[cylinderUpAxis]; + + + SimdVector3 tmp; + SimdScalar d ; + + SimdScalar s = sqrtf(v[XX] * v[XX] + v[ZZ] * v[ZZ]); + if (s != SimdScalar(0.0)) + { + d = radius / s; + tmp[XX] = v[XX] * d; + tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight; + tmp[ZZ] = v[ZZ] * d; + return tmp; + } + else + { + tmp[XX] = radius; + tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight; + tmp[ZZ] = SimdScalar(0.0); + return tmp; + } + + +} + + + + + + +SimdVector3 CylinderLocalSupportY(const SimdVector3& halfExtents,const SimdVector3& v) +{ + +const int cylinderUpAxis = 1; +const int XX = 0; +const int YY = 1; +const int ZZ = 2; + + + float radius = halfExtents[XX]; + float halfHeight = halfExtents[cylinderUpAxis]; + + + SimdVector3 tmp; + SimdScalar d ; + + SimdScalar s = sqrtf(v[XX] * v[XX] + v[ZZ] * v[ZZ]); + if (s != SimdScalar(0.0)) + { + d = radius / s; + tmp[XX] = v[XX] * d; + tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight; + tmp[ZZ] = v[ZZ] * d; + return tmp; + } + else + { + tmp[XX] = radius; + tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight; + tmp[ZZ] = SimdScalar(0.0); + return tmp; + } + +} + +SimdVector3 CylinderLocalSupportZ(const SimdVector3& halfExtents,const SimdVector3& v) +{ +const int cylinderUpAxis = 2; +const int XX = 0; +const int YY = 2; +const int ZZ = 1; + + //mapping depends on how cylinder local orientation is + // extents of the cylinder is: X,Y is for radius, and Z for height + + + float radius = halfExtents[XX]; + float halfHeight = halfExtents[cylinderUpAxis]; + + + SimdVector3 tmp; + SimdScalar d ; + + SimdScalar s = sqrtf(v[XX] * v[XX] + v[ZZ] * v[ZZ]); + if (s != SimdScalar(0.0)) + { + d = radius / s; + tmp[XX] = v[XX] * d; + tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight; + tmp[ZZ] = v[ZZ] * d; + return tmp; + } + else + { + tmp[XX] = radius; + tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight; + tmp[ZZ] = SimdScalar(0.0); + return tmp; + } + + +} + +SimdVector3 CylinderShapeX::LocalGetSupportingVertexWithoutMargin(const SimdVector3& vec)const +{ + return CylinderLocalSupportX(GetHalfExtents(),vec); +} +SimdVector3 CylinderShapeZ::LocalGetSupportingVertexWithoutMargin(const SimdVector3& vec)const +{ + return CylinderLocalSupportZ(GetHalfExtents(),vec); +} +SimdVector3 CylinderShape::LocalGetSupportingVertexWithoutMargin(const SimdVector3& vec)const +{ + return CylinderLocalSupportY(GetHalfExtents(),vec); +} + + + + + + + diff --git a/extern/bullet/Bullet/CollisionShapes/CylinderShape.h b/extern/bullet/Bullet/CollisionShapes/CylinderShape.h new file mode 100644 index 00000000000..d60bacff962 --- /dev/null +++ b/extern/bullet/Bullet/CollisionShapes/CylinderShape.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. + */ + +#ifndef CYLINDER_MINKOWSKI_H +#define CYLINDER_MINKOWSKI_H + +#include "BoxShape.h" +#include "BroadphaseCollision/BroadphaseProxy.h" // for the types +#include "SimdVector3.h" + +/// implements cylinder shape interface +class CylinderShape : public BoxShape + +{ + +public: + CylinderShape (const SimdVector3& halfExtents); + + + virtual SimdVector3 LocalGetSupportingVertexWithoutMargin(const SimdVector3& vec)const; + + + + + //use box inertia + // virtual void CalculateLocalInertia(SimdScalar mass,SimdVector3& inertia); + + virtual int GetShapeType() const + { + return CYLINDER_SHAPE_PROXYTYPE; + } + + + +}; + +class CylinderShapeX : public CylinderShape +{ +public: + CylinderShapeX (const SimdVector3& halfExtents); + + virtual SimdVector3 LocalGetSupportingVertexWithoutMargin(const SimdVector3& vec)const; +}; + +class CylinderShapeZ : public CylinderShape +{ +public: + CylinderShapeZ (const SimdVector3& halfExtents); + + virtual SimdVector3 LocalGetSupportingVertexWithoutMargin(const SimdVector3& vec)const; + +}; + + +#endif //CYLINDER_MINKOWSKI_H
\ No newline at end of file diff --git a/extern/bullet/Bullet/CollisionShapes/MinkowskiSumShape.cpp b/extern/bullet/Bullet/CollisionShapes/MinkowskiSumShape.cpp new file mode 100644 index 00000000000..abb1bfd2449 --- /dev/null +++ b/extern/bullet/Bullet/CollisionShapes/MinkowskiSumShape.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#include "MinkowskiSumShape.h" + + +MinkowskiSumShape::MinkowskiSumShape(ConvexShape* shapeA,ConvexShape* shapeB) +:m_shapeA(shapeA), +m_shapeB(shapeB) +{ + m_transA.setIdentity(); + m_transB.setIdentity(); +} + +SimdVector3 MinkowskiSumShape::LocalGetSupportingVertexWithoutMargin(const SimdVector3& vec)const +{ + SimdVector3 supVertexA = m_transA(m_shapeA->LocalGetSupportingVertexWithoutMargin(vec*m_transA.getBasis())); + SimdVector3 supVertexB = m_transB(m_shapeB->LocalGetSupportingVertexWithoutMargin(vec*m_transB.getBasis())); + return supVertexA + supVertexB; +} + +float MinkowskiSumShape::GetMargin() const +{ + return m_shapeA->GetMargin() + m_shapeB->GetMargin(); +} + + +void MinkowskiSumShape::CalculateLocalInertia(SimdScalar mass,SimdVector3& inertia) +{ + assert(0); + inertia.setValue(0,0,0); +} diff --git a/extern/bullet/Bullet/CollisionShapes/MinkowskiSumShape.h b/extern/bullet/Bullet/CollisionShapes/MinkowskiSumShape.h new file mode 100644 index 00000000000..a286b66252b --- /dev/null +++ b/extern/bullet/Bullet/CollisionShapes/MinkowskiSumShape.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#ifndef MINKOWSKI_SUM_SHAPE_H +#define MINKOWSKI_SUM_SHAPE_H + +#include "ConvexShape.h" +#include "BroadphaseCollision/BroadphaseProxy.h" // for the types + +/// MinkowskiSumShape represents implicit (getSupportingVertex) based minkowski sum of two convex implicit shapes. +class MinkowskiSumShape : public ConvexShape +{ + + SimdTransform m_transA; + SimdTransform m_transB; + ConvexShape* m_shapeA; + ConvexShape* m_shapeB; + +public: + + MinkowskiSumShape(ConvexShape* shapeA,ConvexShape* shapeB); + + virtual SimdVector3 LocalGetSupportingVertexWithoutMargin(const SimdVector3& vec)const; + + virtual void CalculateLocalInertia(SimdScalar mass,SimdVector3& inertia); + + void SetTransformA(const SimdTransform& transA) { m_transA = transA;} + void SetTransformB(const SimdTransform& transB) { m_transB = transB;} + + const SimdTransform& GetTransformA()const { return m_transA;} + const SimdTransform& GetTransformB()const { return m_transB;} + + + virtual int GetShapeType() const { return MINKOWSKI_SUM_SHAPE_PROXYTYPE; } + + virtual float GetMargin() const; + + const ConvexShape* GetShapeA() const { return m_shapeA;} + const ConvexShape* GetShapeB() const { return m_shapeB;} + + virtual char* GetName()const + { + return "MinkowskiSum"; + } +}; + +#endif //MINKOWSKI_SUM_SHAPE_H diff --git a/extern/bullet/Bullet/CollisionShapes/MultiSphereShape.cpp b/extern/bullet/Bullet/CollisionShapes/MultiSphereShape.cpp new file mode 100644 index 00000000000..d2e7fcc273e --- /dev/null +++ b/extern/bullet/Bullet/CollisionShapes/MultiSphereShape.cpp @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#include "MultiSphereShape.h" +#include "NarrowPhaseCollision/CollisionMargin.h" +#include "SimdQuaternion.h" + +MultiSphereShape::MultiSphereShape (const SimdVector3& inertiaHalfExtents,const SimdVector3* positions,const SimdScalar* radi,int numSpheres) +:m_inertiaHalfExtents(inertiaHalfExtents) +{ + m_minRadius = 1e30f; + + m_numSpheres = numSpheres; + for (int i=0;i<m_numSpheres;i++) + { + m_localPositions[i] = positions[i]; + m_radi[i] = radi[i]; + if (radi[i] < m_minRadius) + m_minRadius = radi[i]; + } + SetMargin(m_minRadius); + +} + + + + + SimdVector3 MultiSphereShape::LocalGetSupportingVertexWithoutMargin(const SimdVector3& vec0)const +{ + int i; + SimdVector3 supVec(0,0,0); + + SimdScalar maxDot(-1e30f); + + + SimdVector3 vec = vec0; + SimdScalar lenSqr = vec.length2(); + if (lenSqr < 0.0001f) + { + vec.setValue(1,0,0); + } else + { + float rlen = 1.f / sqrtf(lenSqr ); + vec *= rlen; + } + + SimdVector3 vtx; + SimdScalar newDot; + + const SimdVector3* pos = &m_localPositions[0]; + const SimdScalar* rad = &m_radi[0]; + + for (i=0;i<m_numSpheres;i++) + { + vtx = (*pos) +vec*((*rad)-m_minRadius); + pos++; + rad++; + newDot = vec.dot(vtx); + if (newDot > maxDot) + { + maxDot = newDot; + supVec = vtx; + } + } + + return supVec; + +} + + + + + + + + + + +void MultiSphereShape::CalculateLocalInertia(SimdScalar mass,SimdVector3& inertia) +{ + //as an approximation, take the inertia of the box that bounds the spheres + + SimdTransform ident; + ident.setIdentity(); +// SimdVector3 aabbMin,aabbMax; + +// GetAabb(ident,aabbMin,aabbMax); + + SimdVector3 halfExtents = m_inertiaHalfExtents;//(aabbMax - aabbMin)* 0.5f; + + float margin = CONVEX_DISTANCE_MARGIN; + + SimdScalar lx=2.f*(halfExtents[0]+margin); + SimdScalar ly=2.f*(halfExtents[1]+margin); + SimdScalar lz=2.f*(halfExtents[2]+margin); + const SimdScalar x2 = lx*lx; + const SimdScalar y2 = ly*ly; + const SimdScalar z2 = lz*lz; + const SimdScalar scaledmass = mass * 0.08333333f; + + inertia[0] = scaledmass * (y2+z2); + inertia[1] = scaledmass * (x2+z2); + inertia[2] = scaledmass * (x2+y2); + +} + + + diff --git a/extern/bullet/Bullet/CollisionShapes/MultiSphereShape.h b/extern/bullet/Bullet/CollisionShapes/MultiSphereShape.h new file mode 100644 index 00000000000..fd23be65e84 --- /dev/null +++ b/extern/bullet/Bullet/CollisionShapes/MultiSphereShape.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#ifndef MULTI_SPHERE_MINKOWSKI_H +#define MULTI_SPHERE_MINKOWSKI_H + +#include "ConvexShape.h" +#include "BroadphaseCollision/BroadphaseProxy.h" // for the types + +#define MAX_NUM_SPHERES 5 + +///MultiSphereShape represents implicit convex hull of a collection of spheres (using getSupportingVertex) +class MultiSphereShape : public ConvexShape + +{ + + SimdVector3 m_localPositions[MAX_NUM_SPHERES]; + SimdScalar m_radi[MAX_NUM_SPHERES]; + SimdVector3 m_inertiaHalfExtents; + + int m_numSpheres; + float m_minRadius; + + + + + +public: + MultiSphereShape (const SimdVector3& inertiaHalfExtents,const SimdVector3* positions,const SimdScalar* radi,int numSpheres); + + ///CollisionShape Interface + virtual void CalculateLocalInertia(SimdScalar mass,SimdVector3& inertia); + + /// ConvexShape Interface + virtual SimdVector3 LocalGetSupportingVertexWithoutMargin(const SimdVector3& vec)const; + + + virtual int GetShapeType() const { return MULTI_SPHERE_SHAPE_PROXYTYPE; } + + virtual char* GetName()const + { + return "MultiSphere"; + } + +}; + + +#endif //MULTI_SPHERE_MINKOWSKI_H diff --git a/extern/bullet/Bullet/CollisionShapes/PolyhedralConvexShape.cpp b/extern/bullet/Bullet/CollisionShapes/PolyhedralConvexShape.cpp new file mode 100644 index 00000000000..84b164dd5c6 --- /dev/null +++ b/extern/bullet/Bullet/CollisionShapes/PolyhedralConvexShape.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#include <CollisionShapes/PolyhedralConvexShape.h> + +PolyhedralConvexShape::PolyhedralConvexShape() + +{ +} + +SimdVector3 PolyhedralConvexShape::LocalGetSupportingVertexWithoutMargin(const SimdVector3& vec0)const +{ + int i; + SimdVector3 supVec(0,0,0); + + SimdScalar maxDot(-1e30f); + + SimdVector3 vec = vec0; + SimdScalar lenSqr = vec.length2(); + if (lenSqr < 0.0001f) + { + vec.setValue(1,0,0); + } else + { + float rlen = 1.f / sqrtf(lenSqr ); + vec *= rlen; + } + + SimdVector3 vtx; + SimdScalar newDot; + + for (i=0;i<GetNumVertices();i++) + { + GetVertex(i,vtx); + newDot = vec.dot(vtx); + if (newDot > maxDot) + { + maxDot = newDot; + supVec = vtx; + } + } + + return supVec; + +} diff --git a/extern/bullet/Bullet/CollisionShapes/PolyhedralConvexShape.h b/extern/bullet/Bullet/CollisionShapes/PolyhedralConvexShape.h new file mode 100644 index 00000000000..faab0f39523 --- /dev/null +++ b/extern/bullet/Bullet/CollisionShapes/PolyhedralConvexShape.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#ifndef BU_SHAPE +#define BU_SHAPE + +#include <SimdPoint3.h> +#include <SimdMatrix3x3.h> +#include <CollisionShapes/ConvexShape.h> + + +///PolyhedralConvexShape is an interface class for feature based (vertex/edge/face) convex shapes. +class PolyhedralConvexShape : public ConvexShape +{ + +public: + + PolyhedralConvexShape(); + + //brute force implementations + virtual SimdVector3 LocalGetSupportingVertexWithoutMargin(const SimdVector3& vec)const; + + + virtual int GetNumVertices() const = 0 ; + virtual int GetNumEdges() const = 0; + virtual void GetEdge(int i,SimdPoint3& pa,SimdPoint3& pb) const = 0; + virtual void GetVertex(int i,SimdPoint3& vtx) const = 0; + virtual int GetNumPlanes() const = 0; + virtual void GetPlane(SimdVector3& planeNormal,SimdPoint3& planeSupport,int i ) const = 0; +// virtual int GetIndex(int i) const = 0 ; + + virtual bool IsInside(const SimdPoint3& pt,SimdScalar tolerance) const = 0; + +}; + +#endif //BU_SHAPE diff --git a/extern/bullet/Bullet/CollisionShapes/Simplex1to4Shape.cpp b/extern/bullet/Bullet/CollisionShapes/Simplex1to4Shape.cpp new file mode 100644 index 00000000000..8a3833c20b1 --- /dev/null +++ b/extern/bullet/Bullet/CollisionShapes/Simplex1to4Shape.cpp @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#include "Simplex1to4Shape.h" +#include "SimdMatrix3x3.h" + +BU_Simplex1to4::BU_Simplex1to4() +:m_numVertices(0) +{ +} + +BU_Simplex1to4::BU_Simplex1to4(const SimdPoint3& pt0) +:m_numVertices(0) +{ + AddVertex(pt0); +} + +BU_Simplex1to4::BU_Simplex1to4(const SimdPoint3& pt0,const SimdPoint3& pt1) +:m_numVertices(0) +{ + AddVertex(pt0); + AddVertex(pt1); +} + +BU_Simplex1to4::BU_Simplex1to4(const SimdPoint3& pt0,const SimdPoint3& pt1,const SimdPoint3& pt2) +:m_numVertices(0) +{ + AddVertex(pt0); + AddVertex(pt1); + AddVertex(pt2); +} + +BU_Simplex1to4::BU_Simplex1to4(const SimdPoint3& pt0,const SimdPoint3& pt1,const SimdPoint3& pt2,const SimdPoint3& pt3) +:m_numVertices(0) +{ + AddVertex(pt0); + AddVertex(pt1); + AddVertex(pt2); + AddVertex(pt3); +} + + + + + +void BU_Simplex1to4::AddVertex(const SimdPoint3& pt) +{ + m_vertices[m_numVertices++] = pt; +} + + +int BU_Simplex1to4::GetNumVertices() const +{ + return m_numVertices; +} + +int BU_Simplex1to4::GetNumEdges() const +{ + //euler formula, F-E+V = 2, so E = F+V-2 + + switch (m_numVertices) + { + case 0: + return 0; + case 1: return 0; + case 2: return 1; + case 3: return 3; + case 4: return 6; + + + } + + return 0; +} + +void BU_Simplex1to4::GetEdge(int i,SimdPoint3& pa,SimdPoint3& pb) const +{ + + switch (m_numVertices) + { + + case 2: + pa = m_vertices[0]; + pb = m_vertices[1]; + break; + case 3: + switch (i) + { + case 0: + pa = m_vertices[0]; + pb = m_vertices[1]; + break; + case 1: + pa = m_vertices[1]; + pb = m_vertices[2]; + break; + case 2: + pa = m_vertices[2]; + pb = m_vertices[0]; + break; + + } + break; + case 4: + switch (i) + { + case 0: + pa = m_vertices[0]; + pb = m_vertices[1]; + break; + case 1: + pa = m_vertices[1]; + pb = m_vertices[2]; + break; + case 2: + pa = m_vertices[2]; + pb = m_vertices[0]; + break; + case 3: + pa = m_vertices[0]; + pb = m_vertices[3]; + break; + case 4: + pa = m_vertices[1]; + pb = m_vertices[3]; + break; + case 5: + pa = m_vertices[2]; + pb = m_vertices[3]; + break; + } + + } + + + + +} + +void BU_Simplex1to4::GetVertex(int i,SimdPoint3& vtx) const +{ + vtx = m_vertices[i]; +} + +int BU_Simplex1to4::GetNumPlanes() const +{ + switch (m_numVertices) + { + case 0: + return 0; + case 1: + return 0; + case 2: + return 0; + case 3: + return 2; + case 4: + return 4; + default: + { + } + } + return 0; +} + + +void BU_Simplex1to4::GetPlane(SimdVector3& planeNormal,SimdPoint3& planeSupport,int i) const +{ + +} + +int BU_Simplex1to4::GetIndex(int i) const +{ + return 0; +} + +bool BU_Simplex1to4::IsInside(const SimdPoint3& pt,SimdScalar tolerance) const +{ + return false; +} + diff --git a/extern/bullet/Bullet/CollisionShapes/Simplex1to4Shape.h b/extern/bullet/Bullet/CollisionShapes/Simplex1to4Shape.h new file mode 100644 index 00000000000..8feb995a26c --- /dev/null +++ b/extern/bullet/Bullet/CollisionShapes/Simplex1to4Shape.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#ifndef BU_SIMPLEX_1TO4_SHAPE +#define BU_SIMPLEX_1TO4_SHAPE + + +#include <CollisionShapes/PolyhedralConvexShape.h> +#include "BroadphaseCollision/BroadphaseProxy.h" + + +///BU_Simplex1to4 implements feature based and implicit simplex of up to 4 vertices (tetrahedron, triangle, line, vertex). +class BU_Simplex1to4 : public PolyhedralConvexShape +{ +protected: + + int m_numVertices; + SimdPoint3 m_vertices[4]; + +public: + BU_Simplex1to4(); + + BU_Simplex1to4(const SimdPoint3& pt0); + BU_Simplex1to4(const SimdPoint3& pt0,const SimdPoint3& pt1); + BU_Simplex1to4(const SimdPoint3& pt0,const SimdPoint3& pt1,const SimdPoint3& pt2); + BU_Simplex1to4(const SimdPoint3& pt0,const SimdPoint3& pt1,const SimdPoint3& pt2,const SimdPoint3& pt3); + + + void Reset() + { + m_numVertices = 0; + } + + virtual void CalculateLocalInertia(SimdScalar mass,SimdVector3& inertia) + { + inertia = SimdVector3(1.f,1.f,1.f); + } + + virtual int GetShapeType() const{ return TETRAHEDRAL_SHAPE_PROXYTYPE; } + + void AddVertex(const SimdPoint3& pt); + + //PolyhedralConvexShape interface + + virtual int GetNumVertices() const; + + virtual int GetNumEdges() const; + + virtual void GetEdge(int i,SimdPoint3& pa,SimdPoint3& pb) const; + + virtual void GetVertex(int i,SimdPoint3& vtx) const; + + virtual int GetNumPlanes() const; + + virtual void GetPlane(SimdVector3& planeNormal,SimdPoint3& planeSupport,int i) const; + + virtual int GetIndex(int i) const; + + virtual bool IsInside(const SimdPoint3& pt,SimdScalar tolerance) const; + + + ///GetName is for debugging + virtual char* GetName()const { return "BU_Simplex1to4";} + +}; + +#endif //BU_SIMPLEX_1TO4_SHAPE diff --git a/extern/bullet/Bullet/CollisionShapes/SphereShape.cpp b/extern/bullet/Bullet/CollisionShapes/SphereShape.cpp new file mode 100644 index 00000000000..182b458ec7b --- /dev/null +++ b/extern/bullet/Bullet/CollisionShapes/SphereShape.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. + */ + +#include "SphereShape.h" +#include "NarrowPhaseCollision/CollisionMargin.h" + +#include "SimdQuaternion.h" + + +SphereShape ::SphereShape (SimdScalar radius) +: m_radius(radius) +{ + SetMargin( radius ); +} + +SimdVector3 SphereShape::LocalGetSupportingVertexWithoutMargin(const SimdVector3& vec)const +{ + return SimdVector3(0.f,0.f,0.f); +} + +SimdVector3 SphereShape::LocalGetSupportingVertex(const SimdVector3& vec)const +{ + SimdScalar len = vec.length2(); + if (fabsf(len) < 0.0001f) + { + return SimdVector3(GetMargin(),GetMargin(),GetMargin()); + } + return vec * (GetMargin() / sqrtf(len)); +} + + +void SphereShape::GetAabb(const SimdTransform& t,SimdVector3& aabbMin,SimdVector3& aabbMax) const +{ + const SimdVector3& center = t.getOrigin(); + SimdScalar radius = m_radius + CONVEX_DISTANCE_MARGIN; + radius += 1; + + const SimdVector3 extent(radius,radius,radius); + + aabbMin = center - extent; + aabbMax = center + extent; +} + + + +void SphereShape::CalculateLocalInertia(SimdScalar mass,SimdVector3& inertia) +{ + SimdScalar elem = 0.4f * mass * m_radius*m_radius; + inertia[0] = inertia[1] = inertia[2] = elem; +}
\ No newline at end of file diff --git a/extern/bullet/Bullet/CollisionShapes/SphereShape.h b/extern/bullet/Bullet/CollisionShapes/SphereShape.h new file mode 100644 index 00000000000..6765c59f18a --- /dev/null +++ b/extern/bullet/Bullet/CollisionShapes/SphereShape.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. + */ + +#ifndef SPHERE_MINKOWSKI_H +#define SPHERE_MINKOWSKI_H + +#include "ConvexShape.h" +#include "BroadphaseCollision/BroadphaseProxy.h" // for the types + +///SphereShape implements an implicit (getSupportingVertex) Sphere +class SphereShape : public ConvexShape + +{ + SimdScalar m_radius; + +public: + SphereShape (SimdScalar radius); + + + virtual SimdVector3 LocalGetSupportingVertex(const SimdVector3& vec)const; + virtual SimdVector3 LocalGetSupportingVertexWithoutMargin(const SimdVector3& vec)const; + + + virtual void CalculateLocalInertia(SimdScalar mass,SimdVector3& inertia); + + virtual void GetAabb(const SimdTransform& t,SimdVector3& aabbMin,SimdVector3& aabbMax) const; + + virtual int GetShapeType() const { return SPHERE_SHAPE_PROXYTYPE; } + + SimdScalar GetRadius() { return m_radius;} + + //debugging + virtual char* GetName()const {return "SPHERE";} + +}; + + +#endif //SPHERE_MINKOWSKI_H diff --git a/extern/bullet/Bullet/CollisionShapes/StridingMeshInterface.cpp b/extern/bullet/Bullet/CollisionShapes/StridingMeshInterface.cpp new file mode 100644 index 00000000000..bb0e7e29984 --- /dev/null +++ b/extern/bullet/Bullet/CollisionShapes/StridingMeshInterface.cpp @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#include "StridingMeshInterface.h" + +StridingMeshInterface::~StridingMeshInterface() +{ + +}
\ No newline at end of file diff --git a/extern/bullet/Bullet/CollisionShapes/StridingMeshInterface.h b/extern/bullet/Bullet/CollisionShapes/StridingMeshInterface.h new file mode 100644 index 00000000000..3bdcd7edb38 --- /dev/null +++ b/extern/bullet/Bullet/CollisionShapes/StridingMeshInterface.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#ifndef STRIDING_MESHINTERFACE_H +#define STRIDING_MESHINTERFACE_H + +#include "SimdVector3.h" + +/// PHY_ScalarType enumerates possible scalar types. +/// See the StridingMeshInterface for its use +typedef enum PHY_ScalarType { + PHY_FLOAT, + PHY_DOUBLE, + PHY_INTEGER, + PHY_SHORT, + PHY_FIXEDPOINT88 +} PHY_ScalarType; + +/// StridingMeshInterface is the interface class for high performance access to triangle meshes +/// It allows for sharing graphics and collision meshes. Also it provides locking/unlocking of graphics meshes that are in gpu memory. +class StridingMeshInterface +{ + protected: + + SimdVector3 m_scaling; + + public: + StridingMeshInterface() :m_scaling(1.f,1.f,1.f) + { + + } + + virtual ~StridingMeshInterface(); + /// get read and write access to a subpart of a triangle mesh + /// this subpart has a continuous array of vertices and indices + /// in this way the mesh can be handled as chunks of memory with striding + /// very similar to OpenGL vertexarray support + /// make a call to unLockVertexBase when the read and write access is finished + virtual void getLockedVertexIndexBase(unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& stride,unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart=0)=0; + + + /// unLockVertexBase finishes the access to a subpart of the triangle mesh + /// make a call to unLockVertexBase when the read and write access (using getLockedVertexIndexBase) is finished + virtual void unLockVertexBase(int subpart)=0; + + /// getNumSubParts returns the number of seperate subparts + /// each subpart has a continuous array of vertices and indices + virtual int getNumSubParts()=0; + + virtual void preallocateVertices(int numverts)=0; + virtual void preallocateIndices(int numindices)=0; + + const SimdVector3& getScaling() { + return m_scaling; + } + void setScaling(const SimdVector3& scaling) + { + m_scaling = scaling; + } +}; + +#endif //STRIDING_MESHINTERFACE_H diff --git a/extern/bullet/Bullet/CollisionShapes/TriangleCallback.h b/extern/bullet/Bullet/CollisionShapes/TriangleCallback.h new file mode 100644 index 00000000000..67d95565891 --- /dev/null +++ b/extern/bullet/Bullet/CollisionShapes/TriangleCallback.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#ifndef TRIANGLE_CALLBACK_H +#define TRIANGLE_CALLBACK_H + +#include "SimdVector3.h" + + +class TriangleCallback +{ +public: + + virtual ~TriangleCallback(); + virtual void ProcessTriangle(SimdVector3* triangle) = 0; +}; + +#endif //TRIANGLE_CALLBACK_H diff --git a/extern/bullet/Bullet/CollisionShapes/TriangleMesh.cpp b/extern/bullet/Bullet/CollisionShapes/TriangleMesh.cpp new file mode 100644 index 00000000000..b528a9329ed --- /dev/null +++ b/extern/bullet/Bullet/CollisionShapes/TriangleMesh.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#include "TriangleMesh.h" +#include <assert.h> + +static int myindices[3] = {0,1,2}; + +TriangleMesh::TriangleMesh () +{ + +} + +void TriangleMesh::getLockedVertexIndexBase(unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& stride,unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart) +{ + numverts = 3; + *vertexbase = (unsigned char*)&m_triangles[subpart]; + type = PHY_FLOAT; + stride = sizeof(SimdVector3); + + + numfaces = 1; + *indexbase = (unsigned char*) &myindices[0]; + indicestype = PHY_INTEGER; + indexstride = sizeof(int); + +} + +int TriangleMesh::getNumSubParts() +{ + return m_triangles.size(); +} diff --git a/extern/bullet/Bullet/CollisionShapes/TriangleMesh.h b/extern/bullet/Bullet/CollisionShapes/TriangleMesh.h new file mode 100644 index 00000000000..6701ccbc328 --- /dev/null +++ b/extern/bullet/Bullet/CollisionShapes/TriangleMesh.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ + +#ifndef TRIANGLE_MESH_H +#define TRIANGLE_MESH_H + +#include "CollisionShapes/StridingMeshInterface.h" +#include <vector> +#include <SimdVector3.h> + +struct MyTriangle +{ + SimdVector3 m_vert0; + SimdVector3 m_vert1; + SimdVector3 m_vert2; +}; + +///TriangleMesh provides storage for a concave triangle mesh. It can be used as data for the TriangleMeshShape. +class TriangleMesh : public StridingMeshInterface +{ + std::vector<MyTriangle> m_triangles; + + public: + TriangleMesh (); + + void AddTriangle(const SimdVector3& vertex0,const SimdVector3& vertex1,const SimdVector3& vertex2) + { + MyTriangle tri; + tri.m_vert0 = vertex0; + tri.m_vert1 = vertex1; + tri.m_vert2 = vertex2; + m_triangles.push_back(tri); + } + + +//StridingMeshInterface interface implementation + + virtual void getLockedVertexIndexBase(unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& stride,unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart=0); + + /// unLockVertexBase finishes the access to a subpart of the triangle mesh + /// make a call to unLockVertexBase when the read and write access (using getLockedVertexIndexBase) is finished + virtual void unLockVertexBase(int subpart) {} + + /// getNumSubParts returns the number of seperate subparts + /// each subpart has a continuous array of vertices and indices + virtual int getNumSubParts(); + + virtual void preallocateVertices(int numverts){} + virtual void preallocateIndices(int numindices){} + + + +}; + +#endif //TRIANGLE_MESH_H
\ No newline at end of file diff --git a/extern/bullet/Bullet/CollisionShapes/TriangleMeshShape.cpp b/extern/bullet/Bullet/CollisionShapes/TriangleMeshShape.cpp new file mode 100644 index 00000000000..996c740acce --- /dev/null +++ b/extern/bullet/Bullet/CollisionShapes/TriangleMeshShape.cpp @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#include "TriangleMeshShape.h" +#include "SimdVector3.h" +#include "SimdQuaternion.h" +#include "StridingMeshInterface.h" +#include "AabbUtil2.h" + + + +TriangleMeshShape::TriangleMeshShape(StridingMeshInterface* meshInterface) +: m_meshInterface(meshInterface) +{ +} + +TriangleMeshShape::~TriangleMeshShape() +{ + +} + + + + +void TriangleMeshShape::GetAabb(const SimdTransform& trans,SimdVector3& aabbMin,SimdVector3& aabbMax) const +{ + SimdScalar margin = 0.5f; + for (int i=0;i<3;i++) + { + SimdVector3 vec(0.f,0.f,0.f); + vec[i] = 1.f; + SimdVector3 tmp = trans(LocalGetSupportingVertex(vec*trans.getBasis())); + aabbMax[i] = tmp[i]+margin; + vec[i] = -1.f; + tmp = trans(LocalGetSupportingVertex(vec*trans.getBasis())); + aabbMin[i] = tmp[i]-margin; + } +} + + +TriangleCallback::~TriangleCallback() +{ + +} + +class SupportVertexCallback : public TriangleCallback +{ + + SimdVector3 m_supportVertexLocal; +public: + + SimdTransform m_worldTrans; + SimdScalar m_maxDot; + SimdVector3 m_supportVecLocal; + + SupportVertexCallback(const SimdVector3& supportVecWorld,const SimdTransform& trans) + : m_supportVertexLocal(0.f,0.f,0.f), m_worldTrans(trans) ,m_maxDot(-1e30f) + + { + m_supportVecLocal = supportVecWorld * m_worldTrans.getBasis(); + } + + virtual void ProcessTriangle( SimdVector3* triangle) + { + for (int i=0;i<3;i++) + { + SimdScalar dot = m_supportVecLocal.dot(triangle[i]); + if (dot > m_maxDot) + { + m_maxDot = dot; + m_supportVertexLocal = triangle[i]; + } + } + } + + SimdVector3 GetSupportVertexWorldSpace() + { + return m_worldTrans(m_supportVertexLocal); + } + + SimdVector3 GetSupportVertexLocal() + { + return m_supportVertexLocal; + } + +}; + + +void TriangleMeshShape::setLocalScaling(const SimdVector3& scaling) +{ + m_meshInterface->setScaling(scaling); +} + +void TriangleMeshShape::ProcessAllTriangles(TriangleCallback* callback,const SimdVector3& aabbMin,const SimdVector3& aabbMax) const +{ + + SimdVector3 meshScaling = m_meshInterface->getScaling(); + int numtotalphysicsverts = 0; + int part,graphicssubparts = m_meshInterface->getNumSubParts(); + for (part=0;part<graphicssubparts ;part++) + { + unsigned char * vertexbase; + unsigned char * indexbase; + int indexstride; + PHY_ScalarType type; + PHY_ScalarType gfxindextype; + int stride,numverts,numtriangles; + m_meshInterface->getLockedVertexIndexBase(&vertexbase,numverts,type,stride,&indexbase,indexstride,numtriangles,gfxindextype,part); + numtotalphysicsverts+=numtriangles*3; //upper bound + + + int gfxindex; + SimdVector3 triangle[3]; + + for (gfxindex=0;gfxindex<numtriangles;gfxindex++) + { + + int graphicsindex=0; + + for (int j=2;j>=0;j--) + { + ASSERT(gfxindextype == PHY_INTEGER); + int* gfxbase = (int*)(indexbase+gfxindex*indexstride); + graphicsindex = gfxbase[j]; + float* graphicsbase = (float*)(vertexbase+graphicsindex*stride); + + triangle[j] = SimdVector3( + graphicsbase[0]*meshScaling.getX(), + graphicsbase[1]*meshScaling.getY(), + graphicsbase[2]*meshScaling.getZ()); + } + + if (TestTriangleAgainstAabb2(&triangle[0],aabbMin,aabbMax)) + { + //check aabb in triangle-space, before doing this + callback->ProcessTriangle(triangle); + } + + } + + m_meshInterface->unLockVertexBase(part); + } + + +} + + + + + +void TriangleMeshShape::CalculateLocalInertia(SimdScalar mass,SimdVector3& inertia) +{ + //moving concave objects not supported + assert(0); + inertia.setValue(0.f,0.f,0.f); +} + + +SimdVector3 TriangleMeshShape::LocalGetSupportingVertex(const SimdVector3& vec) const +{ + SimdVector3 supportVertex; + + SimdTransform ident; + ident.setIdentity(); + + SupportVertexCallback supportCallback(vec,ident); + + SimdVector3 aabbMax(1e30f,1e30f,1e30f); + + ProcessAllTriangles(&supportCallback,-aabbMax,aabbMax); + + supportVertex = supportCallback.GetSupportVertexLocal(); + + return supportVertex; +} diff --git a/extern/bullet/Bullet/CollisionShapes/TriangleMeshShape.h b/extern/bullet/Bullet/CollisionShapes/TriangleMeshShape.h new file mode 100644 index 00000000000..ecd9cc530fd --- /dev/null +++ b/extern/bullet/Bullet/CollisionShapes/TriangleMeshShape.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#ifndef TRIANGLE_MESH_SHAPE_H +#define TRIANGLE_MESH_SHAPE_H + +#include "CollisionShapes/CollisionShape.h" +#include "BroadphaseCollision/BroadphaseProxy.h" // for the types + +#include "StridingMeshInterface.h" +#include "TriangleCallback.h" + + + +///Concave triangle mesh. Uses an interface to access the triangles to allow for sharing graphics/physics triangles. +class TriangleMeshShape : public CollisionShape +{ + + StridingMeshInterface* m_meshInterface; + +public: + TriangleMeshShape(StridingMeshInterface* meshInterface); + + virtual ~TriangleMeshShape(); + + + + virtual SimdVector3 LocalGetSupportingVertex(const SimdVector3& vec) const; + + virtual SimdVector3 LocalGetSupportingVertexWithoutMargin(const SimdVector3& vec)const + { + assert(0); + return LocalGetSupportingVertex(vec); + } + + virtual int GetShapeType() const + { + return TRIANGLE_MESH_SHAPE_PROXYTYPE; + } + + virtual void GetAabb(const SimdTransform& t,SimdVector3& aabbMin,SimdVector3& aabbMax) const; + + void ProcessAllTriangles(TriangleCallback* callback,const SimdVector3& aabbMin,const SimdVector3& aabbMax) const; + + virtual void CalculateLocalInertia(SimdScalar mass,SimdVector3& inertia); + + virtual void setLocalScaling(const SimdVector3& scaling); + + + //debugging + virtual char* GetName()const {return "TRIANGLEMESH";} + + +}; + +#endif //TRIANGLE_MESH_SHAPE_H diff --git a/extern/bullet/Bullet/CollisionShapes/TriangleShape.h b/extern/bullet/Bullet/CollisionShapes/TriangleShape.h new file mode 100644 index 00000000000..58f83a82e8c --- /dev/null +++ b/extern/bullet/Bullet/CollisionShapes/TriangleShape.h @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#ifndef OBB_TRIANGLE_MINKOWSKI_H +#define OBB_TRIANGLE_MINKOWSKI_H + +#include "ConvexShape.h" +#include "CollisionShapes/BoxShape.h" + +class TriangleShape : public PolyhedralConvexShape +{ + + +public: + + SimdVector3 m_vertices1[3]; + + + virtual int GetNumVertices() const + { + return 3; + } + + const SimdVector3& GetVertexPtr(int index) const + { + return m_vertices1[index]; + } + virtual void GetVertex(int index,SimdVector3& vert) const + { + vert = m_vertices1[index]; + } + virtual int GetShapeType() const + { + return TRIANGLE_SHAPE_PROXYTYPE; + } + + virtual int GetNumEdges() const + { + return 3; + } + + virtual void GetEdge(int i,SimdPoint3& pa,SimdPoint3& pb) const + { + GetVertex(i,pa); + GetVertex((i+1)%3,pb); + } + + virtual void GetAabb(const SimdTransform& t,SimdVector3& aabbMin,SimdVector3& aabbMax)const + { +// ASSERT(0); + GetAabbSlow(t,aabbMin,aabbMax); + } + + SimdVector3 LocalGetSupportingVertexWithoutMargin(const SimdVector3& dir)const + { + SimdVector3 dots(dir.dot(m_vertices1[0]), dir.dot(m_vertices1[1]), dir.dot(m_vertices1[2])); + return m_vertices1[dots.maxAxis()]; + + } + + + TriangleShape(const SimdVector3& p0,const SimdVector3& p1,const SimdVector3& p2) + { + m_vertices1[0] = p0; + m_vertices1[1] = p1; + m_vertices1[2] = p2; + } + + + + virtual void GetPlane(SimdVector3& planeNormal,SimdPoint3& planeSupport,int i) const + { + GetPlaneEquation(i,planeNormal,planeSupport); + } + + virtual int GetNumPlanes() const + { + return 1; + } + + void CalcNormal(SimdVector3& normal) const + { + normal = (m_vertices1[1]-m_vertices1[0]).cross(m_vertices1[2]-m_vertices1[0]); + normal.normalize(); + } + + virtual void GetPlaneEquation(int i, SimdVector3& planeNormal,SimdPoint3& planeSupport) const + { + CalcNormal(planeNormal); + planeSupport = m_vertices1[0]; + } + + virtual void CalculateLocalInertia(SimdScalar mass,SimdVector3& inertia) + { + ASSERT(0); + inertia.setValue(0.f,0.f,0.f); + } + + virtual bool IsInside(const SimdPoint3& pt,SimdScalar tolerance) const + { + SimdVector3 normal; + CalcNormal(normal); + //distance to plane + SimdScalar dist = pt.dot(normal); + SimdScalar planeconst = m_vertices1[0].dot(normal); + dist -= planeconst; + if (dist >= -tolerance && dist <= tolerance) + { + //inside check on edge-planes + int i; + for (i=0;i<3;i++) + { + SimdPoint3 pa,pb; + GetEdge(i,pa,pb); + SimdVector3 edge = pb-pa; + SimdVector3 edgeNormal = edge.cross(normal); + edgeNormal.normalize(); + SimdScalar dist = pt.dot( edgeNormal); + SimdScalar edgeConst = pa.dot(edgeNormal); + dist -= edgeConst; + if (dist < -tolerance) + return false; + } + + return true; + } + + return false; + } + //debugging + virtual char* GetName()const + { + return "Triangle"; + } + + +}; + +#endif //OBB_TRIANGLE_MINKOWSKI_H
\ No newline at end of file diff --git a/extern/bullet/Bullet/Doxyfile b/extern/bullet/Bullet/Doxyfile new file mode 100644 index 00000000000..94d1d3c4b27 --- /dev/null +++ b/extern/bullet/Bullet/Doxyfile @@ -0,0 +1,746 @@ +# Doxyfile 1.2.4 + +# This file describes the settings to be used by doxygen for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# General configuration options +#--------------------------------------------------------------------------- + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. +PROJECT_NAME = Continuous Collision Detection Library + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Dutch, French, Italian, Czech, Swedish, German, Finnish, Japanese, +# Korean, Hungarian, Norwegian, Spanish, Romanian, Russian, Croatian, +# Polish, Portuguese and Slovene. + +OUTPUT_LANGUAGE = English + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = YES + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these class will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = NO + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. It is allowed to use relative paths in the argument list. + +STRIP_FROM_PATH = + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a class diagram (in Html and LaTeX) for classes with base or +# super classes. Setting the tag to NO turns the diagrams off. + +CLASS_DIAGRAMS = YES + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower case letters. If set to YES upper case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# users are adviced to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like the Qt-style comments (thus requiring an +# explict @brief command for a brief description. + +JAVADOC_AUTOBRIEF = YES + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# reimplements. + +INHERIT_DOCS = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# The ENABLE_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = . + + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +FILE_PATTERNS = *.h *.cpp *.c + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. + +EXCLUDE_PATTERNS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command <filter> <input-file>, where <filter> +# is the value of the INPUT_FILTER tag, and <input-file> is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. + +INPUT_FILTER = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse. + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side pannel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript and frames is required (for instance Netscape 4.0+ +# or Internet explorer 4.0+). + +GENERATE_TREEVIEW = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = NO + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimised for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using a WORD or other. +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assigments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. Warning: This feature +# is still experimental and very incomplete. + +GENERATE_XML = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_PREDEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = ../../generic/extern + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_PREDEF_ONLY tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +#--------------------------------------------------------------------------- +# Configuration::addtions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES tag can be used to specify one or more tagfiles. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = YES + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the ENABLE_PREPROCESSING, INCLUDE_GRAPH, and HAVE_DOT tags are set to +# YES then doxygen will generate a graph for each documented file showing +# the direct and indirect include dependencies of the file with other +# documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, INCLUDED_BY_GRAPH, and HAVE_DOT tags are set to +# YES then doxygen will generate a graph for each documented header file showing +# the documented files that directly or indirectly include this file + +INCLUDED_BY_GRAPH = YES + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found on the path. + +DOT_PATH = + +# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_WIDTH = 1024 + +# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_HEIGHT = 1024 + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +#--------------------------------------------------------------------------- +# Configuration::addtions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO + +# The CGI_NAME tag should be the name of the CGI script that +# starts the search engine (doxysearch) with the correct parameters. +# A script with this name will be generated by doxygen. + +CGI_NAME = search.cgi + +# The CGI_URL tag should be the absolute URL to the directory where the +# cgi binaries are located. See the documentation of your http daemon for +# details. + +CGI_URL = + +# The DOC_URL tag should be the absolute URL to the directory where the +# documentation is located. If left blank the absolute path to the +# documentation, with file:// prepended to it, will be used. + +DOC_URL = + +# The DOC_ABSPATH tag should be the absolute path to the directory where the +# documentation is located. If left blank the directory on the local machine +# will be used. + +DOC_ABSPATH = + +# The BIN_ABSPATH tag must point to the directory where the doxysearch binary +# is installed. + +BIN_ABSPATH = c:\program files\doxygen\bin + +# The EXT_DOC_PATHS tag can be used to specify one or more paths to +# documentation generated for other projects. This allows doxysearch to search +# the documentation for these projects as well. + +EXT_DOC_PATHS = diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/BU_AlgebraicPolynomialSolver.cpp b/extern/bullet/Bullet/NarrowPhaseCollision/BU_AlgebraicPolynomialSolver.cpp new file mode 100644 index 00000000000..8253e61f17f --- /dev/null +++ b/extern/bullet/Bullet/NarrowPhaseCollision/BU_AlgebraicPolynomialSolver.cpp @@ -0,0 +1,355 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ + +#include "BU_AlgebraicPolynomialSolver.h" +#include <math.h> +#include <SimdMinMax.h> + +int BU_AlgebraicPolynomialSolver::Solve2Quadratic(SimdScalar p, SimdScalar q) +{ + + SimdScalar basic_h_local; + SimdScalar basic_h_local_delta; + + basic_h_local = p * 0.5f; + basic_h_local_delta = basic_h_local * basic_h_local - q; + if (basic_h_local_delta > 0.0f) { + basic_h_local_delta = sqrtf(basic_h_local_delta); + m_roots[0] = - basic_h_local + basic_h_local_delta; + m_roots[1] = - basic_h_local - basic_h_local_delta; + return 2; + } + else if (SimdGreaterEqual(basic_h_local_delta, SIMD_EPSILON)) { + m_roots[0] = - basic_h_local; + return 1; + } + else { + return 0; + } + } + + +int BU_AlgebraicPolynomialSolver::Solve2QuadraticFull(SimdScalar a,SimdScalar b, SimdScalar c) +{ + SimdScalar radical = b * b - 4.0f * a * c; + if(radical >= 0.f) + { + SimdScalar sqrtRadical = sqrtf(radical); + SimdScalar idenom = 1.0f/(2.0f * a); + m_roots[0]=(-b + sqrtRadical) * idenom; + m_roots[1]=(-b - sqrtRadical) * idenom; + return 2; + } + return 0; +} + + +#define cubic_rt(x) \ + ((x) > 0.0f ? powf((SimdScalar)(x), 0.333333333333333333333333f) : \ + ((x) < 0.0f ? -powf((SimdScalar)-(x), 0.333333333333333333333333f) : 0.0f)) + + + +/* */ +/* this function solves the following cubic equation: */ +/* */ +/* 3 2 */ +/* lead * x + a * x + b * x + c = 0. */ +/* */ +/* it returns the number of different roots found, and stores the roots in */ +/* roots[0,2]. it returns -1 for a degenerate equation 0 = 0. */ +/* */ +int BU_AlgebraicPolynomialSolver::Solve3Cubic(SimdScalar lead, SimdScalar a, SimdScalar b, SimdScalar c) +{ + SimdScalar p, q, r; + SimdScalar delta, u, phi; + SimdScalar dummy; + + if (lead != 1.0) { + /* */ + /* transform into normal form: x^3 + a x^2 + b x + c = 0 */ + /* */ + if (SimdEqual(lead, SIMD_EPSILON)) { + /* */ + /* we have a x^2 + b x + c = 0 */ + /* */ + if (SimdEqual(a, SIMD_EPSILON)) { + /* */ + /* we have b x + c = 0 */ + /* */ + if (SimdEqual(b, SIMD_EPSILON)) { + if (SimdEqual(c, SIMD_EPSILON)) { + return -1; + } + else { + return 0; + } + } + else { + m_roots[0] = -c / b; + return 1; + } + } + else { + p = c / a; + q = b / a; + return Solve2QuadraticFull(a,b,c); + } + } + else { + a = a / lead; + b = b / lead; + c = c / lead; + } + } + + /* */ + /* we substitute x = y - a / 3 in order to eliminate the quadric term. */ + /* we get x^3 + p x + q = 0 */ + /* */ + a /= 3.0f; + u = a * a; + p = b / 3.0f - u; + q = a * (2.0f * u - b) + c; + + /* */ + /* now use Cardano's formula */ + /* */ + if (SimdEqual(p, SIMD_EPSILON)) { + if (SimdEqual(q, SIMD_EPSILON)) { + /* */ + /* one triple root */ + /* */ + m_roots[0] = -a; + return 1; + } + else { + /* */ + /* one real and two complex roots */ + /* */ + m_roots[0] = cubic_rt(-q) - a; + return 1; + } + } + + q /= 2.0f; + delta = p * p * p + q * q; + if (delta > 0.0f) { + /* */ + /* one real and two complex roots. note that v = -p / u. */ + /* */ + u = -q + sqrtf(delta); + u = cubic_rt(u); + m_roots[0] = u - p / u - a; + return 1; + } + else if (delta < 0.0) { + /* */ + /* Casus irreducibilis: we have three real roots */ + /* */ + r = sqrtf(-p); + p *= -r; + r *= 2.0; + phi = acosf(-q / p) / 3.0f; + dummy = SIMD_2_PI / 3.0f; + m_roots[0] = r * cosf(phi) - a; + m_roots[1] = r * cosf(phi + dummy) - a; + m_roots[2] = r * cosf(phi - dummy) - a; + return 3; + } + else { + /* */ + /* one single and one SimdScalar root */ + /* */ + r = cubic_rt(-q); + m_roots[0] = 2.0f * r - a; + m_roots[1] = -r - a; + return 2; + } +} + + +/* */ +/* this function solves the following quartic equation: */ +/* */ +/* 4 3 2 */ +/* lead * x + a * x + b * x + c * x + d = 0. */ +/* */ +/* it returns the number of different roots found, and stores the roots in */ +/* roots[0,3]. it returns -1 for a degenerate equation 0 = 0. */ +/* */ +int BU_AlgebraicPolynomialSolver::Solve4Quartic(SimdScalar lead, SimdScalar a, SimdScalar b, SimdScalar c, SimdScalar d) +{ + SimdScalar p, q ,r; + SimdScalar u, v, w; + int i, num_roots, num_tmp; + //SimdScalar tmp[2]; + + if (lead != 1.0) { + /* */ + /* transform into normal form: x^4 + a x^3 + b x^2 + c x + d = 0 */ + /* */ + if (SimdEqual(lead, SIMD_EPSILON)) { + /* */ + /* we have a x^3 + b x^2 + c x + d = 0 */ + /* */ + if (SimdEqual(a, SIMD_EPSILON)) { + /* */ + /* we have b x^2 + c x + d = 0 */ + /* */ + if (SimdEqual(b, SIMD_EPSILON)) { + /* */ + /* we have c x + d = 0 */ + /* */ + if (SimdEqual(c, SIMD_EPSILON)) { + if (SimdEqual(d, SIMD_EPSILON)) { + return -1; + } + else { + return 0; + } + } + else { + m_roots[0] = -d / c; + return 1; + } + } + else { + p = c / b; + q = d / b; + return Solve2QuadraticFull(b,c,d); + + } + } + else { + return Solve3Cubic(1.0, b / a, c / a, d / a); + } + } + else { + a = a / lead; + b = b / lead; + c = c / lead; + d = d / lead; + } + } + + /* */ + /* we substitute x = y - a / 4 in order to eliminate the cubic term. */ + /* we get: y^4 + p y^2 + q y + r = 0. */ + /* */ + a /= 4.0f; + p = b - 6.0f * a * a; + q = a * (8.0f * a * a - 2.0f * b) + c; + r = a * (a * (b - 3.f * a * a) - c) + d; + if (SimdEqual(q, SIMD_EPSILON)) { + /* */ + /* biquadratic equation: y^4 + p y^2 + r = 0. */ + /* */ + num_roots = Solve2Quadratic(p, r); + if (num_roots > 0) { + if (m_roots[0] > 0.0f) { + if (num_roots > 1) { + if ((m_roots[1] > 0.0f) && (m_roots[1] != m_roots[0])) { + u = sqrtf(m_roots[1]); + m_roots[2] = u - a; + m_roots[3] = -u - a; + u = sqrtf(m_roots[0]); + m_roots[0] = u - a; + m_roots[1] = -u - a; + return 4; + } + else { + u = sqrtf(m_roots[0]); + m_roots[0] = u - a; + m_roots[1] = -u - a; + return 2; + } + } + else { + u = sqrtf(m_roots[0]); + m_roots[0] = u - a; + m_roots[1] = -u - a; + return 2; + } + } + } + return 0; + } + else if (SimdEqual(r, SIMD_EPSILON)) { + /* */ + /* no absolute term: y (y^3 + p y + q) = 0. */ + /* */ + num_roots = Solve3Cubic(1.0, 0.0, p, q); + for (i = 0; i < num_roots; ++i) m_roots[i] -= a; + if (num_roots != -1) { + m_roots[num_roots] = -a; + ++num_roots; + } + else { + m_roots[0] = -a; + num_roots = 1;; + } + return num_roots; + } + else { + /* */ + /* we solve the resolvent cubic equation */ + /* */ + num_roots = Solve3Cubic(1.0f, -0.5f * p, -r, 0.5f * r * p - 0.125f * q * q); + if (num_roots == -1) { + num_roots = 1; + m_roots[0] = 0.0f; + } + + /* */ + /* build two quadric equations */ + /* */ + w = m_roots[0]; + u = w * w - r; + v = 2.0f * w - p; + + if (SimdEqual(u, SIMD_EPSILON)) + u = 0.0; + else if (u > 0.0f) + u = sqrtf(u); + else + return 0; + + if (SimdEqual(v, SIMD_EPSILON)) + v = 0.0; + else if (v > 0.0f) + v = sqrtf(v); + else + return 0; + + if (q < 0.0f) v = -v; + w -= u; + num_roots=Solve2Quadratic(v, w); + for (i = 0; i < num_roots; ++i) + { + m_roots[i] -= a; + } + w += 2.0f *u; + SimdScalar tmp[2]; + tmp[0] = m_roots[0]; + tmp[1] = m_roots[1]; + + num_tmp = Solve2Quadratic(-v, w); + for (i = 0; i < num_tmp; ++i) + { + m_roots[i + num_roots] = tmp[i] - a; + m_roots[i]=tmp[i]; + } + + return (num_tmp + num_roots); + } +} + diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/BU_AlgebraicPolynomialSolver.h b/extern/bullet/Bullet/NarrowPhaseCollision/BU_AlgebraicPolynomialSolver.h new file mode 100644 index 00000000000..32986eb2e72 --- /dev/null +++ b/extern/bullet/Bullet/NarrowPhaseCollision/BU_AlgebraicPolynomialSolver.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ + +#ifndef BU_ALGEBRAIC_POLYNOMIAL_SOLVER_H +#define BU_ALGEBRAIC_POLYNOMIAL_SOLVER_H + +#include "BU_PolynomialSolverInterface.h" + +/// BU_AlgebraicPolynomialSolver implements polynomial root finding by analytically solving algebraic equations. +/// Polynomials up to 4rd degree are supported, Cardano's formula is used for 3rd degree +class BU_AlgebraicPolynomialSolver : public BUM_PolynomialSolverInterface +{ +public: + BU_AlgebraicPolynomialSolver() {}; + + int Solve2Quadratic(SimdScalar p, SimdScalar q); + int Solve2QuadraticFull(SimdScalar a,SimdScalar b, SimdScalar c); + int Solve3Cubic(SimdScalar lead, SimdScalar a, SimdScalar b, SimdScalar c); + int Solve4Quartic(SimdScalar lead, SimdScalar a, SimdScalar b, SimdScalar c, SimdScalar d); + + + SimdScalar GetRoot(int i) const + { + return m_roots[i]; + } + +private: + SimdScalar m_roots[4]; + +}; + +#endif //BU_ALGEBRAIC_POLYNOMIAL_SOLVER_H diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/BU_Collidable.cpp b/extern/bullet/Bullet/NarrowPhaseCollision/BU_Collidable.cpp new file mode 100644 index 00000000000..fa8091a2e93 --- /dev/null +++ b/extern/bullet/Bullet/NarrowPhaseCollision/BU_Collidable.cpp @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ + +#include "BU_Collidable.h" +#include "CollisionShapes/CollisionShape.h" +#include <SimdTransform.h> +#include "BU_MotionStateInterface.h" + +BU_Collidable::BU_Collidable(BU_MotionStateInterface& motion,PolyhedralConvexShape& shape,void* userPointer ) +:m_motionState(motion),m_shape(shape),m_userPointer(userPointer) +{ +} diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/BU_Collidable.h b/extern/bullet/Bullet/NarrowPhaseCollision/BU_Collidable.h new file mode 100644 index 00000000000..79164426fc4 --- /dev/null +++ b/extern/bullet/Bullet/NarrowPhaseCollision/BU_Collidable.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ + +#ifndef BU_COLLIDABLE +#define BU_COLLIDABLE + + +class PolyhedralConvexShape; +class BU_MotionStateInterface; +#include <SimdPoint3.h> + +class BU_Collidable +{ +public: + BU_Collidable(BU_MotionStateInterface& motion,PolyhedralConvexShape& shape, void* userPointer); + + void* GetUserPointer() const + { + return m_userPointer; + } + + BU_MotionStateInterface& GetMotionState() + { + return m_motionState; + } + inline const BU_MotionStateInterface& GetMotionState() const + { + return m_motionState; + } + + inline const PolyhedralConvexShape& GetShape() const + { + return m_shape; + }; + + +private: + BU_MotionStateInterface& m_motionState; + PolyhedralConvexShape& m_shape; + void* m_userPointer; + +}; + +#endif //BU_COLLIDABLE diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/BU_CollisionPair.cpp b/extern/bullet/Bullet/NarrowPhaseCollision/BU_CollisionPair.cpp new file mode 100644 index 00000000000..3f60f5dfb86 --- /dev/null +++ b/extern/bullet/Bullet/NarrowPhaseCollision/BU_CollisionPair.cpp @@ -0,0 +1,576 @@ + +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ + +#include "BU_CollisionPair.h" +#include "NarrowPhaseCollision/BU_VertexPoly.h" +#include "NarrowPhaseCollision/BU_EdgeEdge.h" +#include "BU_Collidable.h" + + +#include "BU_MotionStateInterface.h" +#include "CollisionShapes/PolyhedralConvexShape.h" +#include <SimdMinMax.h> +#include "SimdTransformUtil.h" + + + +BU_CollisionPair::BU_CollisionPair(const PolyhedralConvexShape* convexA,const PolyhedralConvexShape* convexB,SimdScalar tolerance) +: m_convexA(convexA),m_convexB(convexB),m_screwing(SimdVector3(0,0,0),SimdVector3(0,0,0)), +m_tolerance(tolerance) +{ + +} + +// if there exists a time-of-impact between any feature_pair (edgeA,edgeB), +// (vertexA,faceB) or (vertexB,faceA) in [0..1], report true and smallest time + + +/* +bool BU_CollisionPair::GetTimeOfImpact(const SimdVector3& linearMotionA,const SimdQuaternion& angularMotionA,const SimdVector3& linearMotionB,const SimdQuaternion& angularMotionB, SimdScalar& toi,SimdTransform& impactTransA,SimdTransform& impactTransB) + +*/ + +bool BU_CollisionPair::calcTimeOfImpact( + const SimdTransform& fromA, + const SimdTransform& toA, + const SimdTransform& fromB, + const SimdTransform& toB, + CastResult& result) +{ + + + + + SimdVector3 linvelA,angvelA; + SimdVector3 linvelB,angvelB; + + SimdTransformUtil::CalculateVelocity(fromA,toA,1.f,linvelA,angvelA); + SimdTransformUtil::CalculateVelocity(fromB,toB,1.f,linvelB,angvelB); + + + SimdVector3 linearMotionA = toA.getOrigin() - fromA.getOrigin(); + SimdQuaternion angularMotionA(0,0,0,1.f); + SimdVector3 linearMotionB = toB.getOrigin() - fromB.getOrigin(); + SimdQuaternion angularMotionB(0,0,0,1); + + + + result.m_fraction = 1.f; + + SimdTransform impactTransA; + SimdTransform impactTransB; + + int index=0; + + SimdScalar toiUnscaled=result.m_fraction; + const SimdScalar toiUnscaledLimit = result.m_fraction; + + SimdTransform a2w; + a2w = fromA; + SimdTransform b2w = fromB; + +/* debugging code + { + const int numvertsB = m_convexB->GetNumVertices(); + for (int v=0;v<numvertsB;v++) + { + SimdPoint3 pt; + m_convexB->GetVertex(v,pt); + pt = b2w * pt; + char buf[1000]; + + if (pt.y() < 0.) + { + sprintf(buf,"PRE ERROR (%d) %.20E %.20E %.20E!!!!!!!!!\n",v,pt.x(),pt.y(),pt.z()); + if (debugFile) + fwrite(buf,1,strlen(buf),debugFile); + } else + { + sprintf(buf,"PRE %d = %.20E,%.20E,%.20E\n",v,pt.x(),pt.y(),pt.z()); + if (debugFile) + fwrite(buf,1,strlen(buf),debugFile); + + } + } + } +*/ + + + SimdTransform b2wp = b2w; + + b2wp.setOrigin(b2w.getOrigin() + linearMotionB); + b2wp.setRotation( b2w.getRotation() + angularMotionB); + + impactTransB = b2wp; + + SimdTransform a2wp; + a2wp.setOrigin(a2w.getOrigin()+ linearMotionA); + a2wp.setRotation(a2w.getRotation()+angularMotionA); + + impactTransA = a2wp; + + SimdTransform a2winv; + a2winv = a2w.inverse(); + + SimdTransform b2wpinv; + b2wpinv = b2wp.inverse(); + + SimdTransform b2winv; + b2winv = b2w.inverse(); + + SimdTransform a2wpinv; + a2wpinv = a2wp.inverse(); + + //Redon's version with concatenated transforms + + SimdTransform relative; + + relative = b2w * b2wpinv * a2wp * a2winv; + + //relative = a2winv * a2wp * b2wpinv * b2w; + + SimdQuaternion qrel; + relative.getBasis().getRotation(qrel); + + SimdVector3 linvel = relative.getOrigin(); + + if (linvel.length() < SCREWEPSILON) + { + linvel.setValue(0.,0.,0.); + } + SimdVector3 angvel; + angvel[0] = 2.f * asinf (qrel[0]); + angvel[1] = 2.f * asinf (qrel[1]); + angvel[2] = 2.f * asinf (qrel[2]); + + if (angvel.length() < SCREWEPSILON) + { + angvel.setValue(0.f,0.f,0.f); + } + + //Redon's version with concatenated transforms + m_screwing = BU_Screwing(linvel,angvel); + + SimdTransform w2s; + m_screwing.LocalMatrix(w2s); + + SimdTransform s2w; + s2w = w2s.inverse(); + + //impactTransA = a2w; + //impactTransB = b2w; + + bool hit = false; + + if (SimdFuzzyZero(m_screwing.GetS()) && SimdFuzzyZero(m_screwing.GetW())) + { + //W = 0 , S = 0 , no collision + //toi = 0; + /* + { + const int numvertsB = m_convexB->GetNumVertices(); + for (int v=0;v<numvertsB;v++) + { + SimdPoint3 pt; + m_convexB->GetVertex(v,pt); + pt = impactTransB * pt; + char buf[1000]; + + if (pt.y() < 0.) + { + sprintf(buf,"EARLY POST ERROR (%d) %.20E,%.20E,%.20E!!!!!!!!!\n",v,pt.x(),pt.y(),pt.z()); + if (debugFile) + fwrite(buf,1,strlen(buf),debugFile); + } + else + { + sprintf(buf,"EARLY POST %d = %.20E,%.20E,%.20E\n",v,pt.x(),pt.y(),pt.z()); + if (debugFile) + fwrite(buf,1,strlen(buf),debugFile); + } + } + } + */ + + return false;//don't continue moving within epsilon + } + +#define EDGEEDGE +#ifdef EDGEEDGE + + BU_EdgeEdge edgeEdge; + + //for all edged in A check agains all edges in B + for (int ea = 0;ea < m_convexA->GetNumEdges();ea++) + { + SimdPoint3 pA0,pA1; + + m_convexA->GetEdge(ea,pA0,pA1); + + pA0= a2w * pA0;//in world space + pA0 = w2s * pA0;//in screwing space + + pA1= a2w * pA1;//in world space + pA1 = w2s * pA1;//in screwing space + + int numedgesB = m_convexB->GetNumEdges(); + for (int eb = 0; eb < numedgesB;eb++) + { + { + SimdPoint3 pB0,pB1; + m_convexB->GetEdge(eb,pB0,pB1); + + pB0= b2w * pB0;//in world space + pB0 = w2s * pB0;//in screwing space + + pB1= b2w * pB1;//in world space + pB1 = w2s * pB1;//in screwing space + + + SimdScalar lambda,mu; + + toiUnscaled = 1.; + + SimdVector3 edgeDirA(pA1-pA0); + SimdVector3 edgeDirB(pB1-pB0); + + if (edgeEdge.GetTimeOfImpact(m_screwing,pA0,edgeDirA,pB0,edgeDirB,toiUnscaled,lambda,mu)) + { + //printf("edgeedge potential hit\n"); + if (toiUnscaled>=0) + { + if (toiUnscaled < toiUnscaledLimit) + { + + //inside check is already done by checking the mu and gamma ! + + SimdPoint3 vtx = pA0+lambda * (pA1-pA0); + SimdPoint3 hitpt = m_screwing.InBetweenPosition(vtx,toiUnscaled); + + SimdPoint3 hitptWorld = s2w * hitpt; + { + + if (toiUnscaled < result.m_fraction) + result.m_fraction = toiUnscaled; + + hit = true; + + SimdVector3 hitNormal = edgeDirB.cross(edgeDirA); + + hitNormal = m_screwing.InBetweenVector(hitNormal,toiUnscaled); + + + hitNormal.normalize(); + + //an approximated normal can be calculated by taking the cross product of both edges + //take care of the sign ! + + SimdVector3 hitNormalWorld = s2w.getBasis() * hitNormal ; + + SimdScalar dist = m_screwing.GetU().dot(hitNormalWorld); + if (dist > 0) + hitNormalWorld *= -1; + + //todo: this is the wrong point, because b2winv is still at begin of motion + // not at time-of-impact location! + //bhitpt = b2winv * hitptWorld; + +// m_manifold.SetContactPoint(BUM_FeatureEdgeEdge,index,ea,eb,hitptWorld,hitNormalWorld); + } + + } + } + } + } + + index++; + } + }; +#endif //EDGEEDGE + +#define VERTEXFACE +#ifdef VERTEXFACE + + // for all vertices in A, for each face in B,do vertex-face + { + const int numvertsA = m_convexA->GetNumVertices(); + for (int v=0;v<numvertsA;v++) + //int v=3; + + { + SimdPoint3 vtx; + m_convexA->GetVertex(v,vtx); + + vtx = a2w * vtx;//in world space + vtx = w2s * vtx;//in screwing space + + const int numplanesB = m_convexB->GetNumPlanes(); + + for (int p = 0 ; p < numplanesB; p++) + //int p=2; + { + + { + + SimdVector3 planeNorm; + SimdPoint3 planeSupport; + + m_convexB->GetPlane(planeNorm,planeSupport,p); + + + planeSupport = b2w * planeSupport;//transform to world space + SimdVector3 planeNormWorld = b2w.getBasis() * planeNorm; + + planeSupport = w2s * planeSupport ; //transform to screwing space + planeNorm = w2s.getBasis() * planeNormWorld; + + planeNorm.normalize(); + + SimdScalar d = planeSupport.dot(planeNorm); + + SimdVector4 planeEq(planeNorm[0],planeNorm[1],planeNorm[2],d); + + BU_VertexPoly vtxApolyB; + + toiUnscaled = 1.; + + if ((p==2) && (v==6)) + { +// printf("%f toiUnscaled\n",toiUnscaled); + + } + if (vtxApolyB.GetTimeOfImpact(m_screwing,vtx,planeEq,toiUnscaled,false)) + { + + + + + if (toiUnscaled >= 0. ) + { + //not only collect the first point, get every contactpoint, later we have to check the + //manifold properly! + + if (toiUnscaled <= toiUnscaledLimit) + { + // printf("toiUnscaled %f\n",toiUnscaled ); + + SimdPoint3 hitpt = m_screwing.InBetweenPosition(vtx,toiUnscaled); + SimdVector3 hitNormal = m_screwing.InBetweenVector(planeNorm ,toiUnscaled); + + SimdVector3 hitNormalWorld = s2w.getBasis() * hitNormal ; + SimdPoint3 hitptWorld = s2w * hitpt; + + + hitpt = b2winv * hitptWorld; + //vertex has to be 'within' the facet's boundary + if (m_convexB->IsInside(hitpt,m_tolerance)) + { +// m_manifold.SetContactPoint(BUM_FeatureVertexFace, index,v,p,hitptWorld,hitNormalWorld); + + if (toiUnscaled < result.m_fraction) + result.m_fraction= toiUnscaled; + hit = true; + + } + } + } + } + + } + + index++; + } + } + } + + // + // for all vertices in B, for each face in A,do vertex-face + //copy and pasted from all verts A -> all planes B so potential typos! + //todo: make this into one method with a kind of 'swapped' logic + // + { + const int numvertsB = m_convexB->GetNumVertices(); + for (int v=0;v<numvertsB;v++) + //int v=0; + + { + SimdPoint3 vtx; + m_convexB->GetVertex(v,vtx); + + vtx = b2w * vtx;//in world space +/* + + char buf[1000]; + + if (vtx.y() < 0.) + { + sprintf(buf,"ERROR !!!!!!!!!\n",v,vtx.x(),vtx.y(),vtx.z()); + if (debugFile) + fwrite(buf,1,strlen(buf),debugFile); + } + sprintf(buf,"vertexWorld(%d) = (%.20E,%.20E,%.20E)\n",v,vtx.x(),vtx.y(),vtx.z()); + if (debugFile) + fwrite(buf,1,strlen(buf),debugFile); + +*/ + vtx = w2s * vtx;//in screwing space + + const int numplanesA = m_convexA->GetNumPlanes(); + + for (int p = 0 ; p < numplanesA; p++) + //int p=2; + { + + { + SimdVector3 planeNorm; + SimdPoint3 planeSupport; + + m_convexA->GetPlane(planeNorm,planeSupport,p); + + + planeSupport = a2w * planeSupport;//transform to world space + SimdVector3 planeNormWorld = a2w.getBasis() * planeNorm; + + planeSupport = w2s * planeSupport ; //transform to screwing space + planeNorm = w2s.getBasis() * planeNormWorld; + + planeNorm.normalize(); + + SimdScalar d = planeSupport.dot(planeNorm); + + SimdVector4 planeEq(planeNorm[0],planeNorm[1],planeNorm[2],d); + + BU_VertexPoly vtxBpolyA; + + toiUnscaled = 1.; + + if (vtxBpolyA.GetTimeOfImpact(m_screwing,vtx,planeEq,toiUnscaled,true)) + { + if (toiUnscaled>=0.) + { + if (toiUnscaled < toiUnscaledLimit) + { + SimdPoint3 hitpt = m_screwing.InBetweenPosition( vtx , -toiUnscaled); + SimdVector3 hitNormal = m_screwing.InBetweenVector(-planeNorm ,-toiUnscaled); + SimdScalar len = hitNormal.length()-1; + + //assert( SimdFuzzyZero(len) ); + + + SimdVector3 hitNormalWorld = s2w.getBasis() * hitNormal ; + SimdPoint3 hitptWorld = s2w * hitpt; + hitpt = a2winv * hitptWorld; + + + //vertex has to be 'within' the facet's boundary + if (m_convexA->IsInside(hitpt,m_tolerance)) + { + +// m_manifold.SetContactPoint(BUM_FeatureFaceVertex,index,p,v,hitptWorld,hitNormalWorld); + if (toiUnscaled <result.m_fraction) + result.m_fraction = toiUnscaled; + hit = true; + } + } + + } + + } + } + + } + + index++; + } + } + + +#endif// VERTEXFACE + + //the manifold now consists of all points/normals generated by feature-pairs that have a time-of-impact within this frame + //in addition there are contact points from previous frames + //we have to cleanup the manifold, using an additional epsilon/tolerance + //as long as the distance from the contactpoint (in worldspace) to both objects is within this epsilon we keep the point + //else throw it away + + + if (hit) + { + + //try to avoid numerical drift on close contact + + if (result.m_fraction < 0.00001) + { +// printf("toiUnscaledMin< 0.00001\n"); + impactTransA = a2w; + impactTransB = b2w; + + } else + { + + //SimdScalar vel = linearMotionB.length(); + + //todo: check this margin + result.m_fraction *= 0.99f; + + //move B to new position + impactTransB.setOrigin(b2w.getOrigin()+ result.m_fraction*linearMotionB); + SimdQuaternion ornB = b2w.getRotation()+angularMotionB*result.m_fraction; + ornB.normalize(); + impactTransB.setRotation(ornB); + + //now transform A + SimdTransform a2s,a2b; + a2s.mult( w2s , a2w); + a2s= m_screwing.InBetweenTransform(a2s,result.m_fraction); + a2s.multInverseLeft(w2s,a2s); + a2b.multInverseLeft(b2w, a2s); + + //transform by motion B + impactTransA.mult(impactTransB, a2b); + //normalize rotation + SimdQuaternion orn; + impactTransA.getBasis().getRotation(orn); + orn.normalize(); + impactTransA.setBasis(SimdMatrix3x3(orn)); + } + } + +/* + { + const int numvertsB = m_convexB->GetNumVertices(); + for (int v=0;v<numvertsB;v++) + { + SimdPoint3 pt; + m_convexB->GetVertex(v,pt); + pt = impactTransB * pt; + char buf[1000]; + + if (pt.y() < 0.) + { + sprintf(buf,"POST ERROR (%d) %.20E,%.20E,%.20E!!!!!!!!!\n",v,pt.x(),pt.y(),pt.z()); + if (debugFile) + fwrite(buf,1,strlen(buf),debugFile); + } + else + { + sprintf(buf,"POST %d = %.20E,%.20E,%.20E\n",v,pt.x(),pt.y(),pt.z()); + if (debugFile) + fwrite(buf,1,strlen(buf),debugFile); + } + } + } +*/ + return hit; +} + + diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/BU_CollisionPair.h b/extern/bullet/Bullet/NarrowPhaseCollision/BU_CollisionPair.h new file mode 100644 index 00000000000..6bc09c21cd5 --- /dev/null +++ b/extern/bullet/Bullet/NarrowPhaseCollision/BU_CollisionPair.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ + +#ifndef BU_COLLISIONPAIR +#define BU_COLLISIONPAIR + +#include <NarrowPhaseCollision/BU_Screwing.h> +#include <NarrowPhaseCollision/ConvexCast.h> + + +#include <SimdQuaternion.h> + +class PolyhedralConvexShape; + + +///BU_CollisionPair implements collision algorithm for algebraic time of impact calculation of feature based shapes. +class BU_CollisionPair : public ConvexCast +{ + +public: + BU_CollisionPair(const PolyhedralConvexShape* convexA,const PolyhedralConvexShape* convexB,SimdScalar tolerance=0.2f); + //toi + + virtual bool calcTimeOfImpact( + const SimdTransform& fromA, + const SimdTransform& toA, + const SimdTransform& fromB, + const SimdTransform& toB, + CastResult& result); + + + + +private: + const PolyhedralConvexShape* m_convexA; + const PolyhedralConvexShape* m_convexB; + BU_Screwing m_screwing; + SimdScalar m_tolerance; + +}; +#endif //BU_COLLISIONPAIR diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/BU_EdgeEdge.cpp b/extern/bullet/Bullet/NarrowPhaseCollision/BU_EdgeEdge.cpp new file mode 100644 index 00000000000..26a4fe74fbf --- /dev/null +++ b/extern/bullet/Bullet/NarrowPhaseCollision/BU_EdgeEdge.cpp @@ -0,0 +1,573 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ + +#include "BU_EdgeEdge.h" +#include "BU_Screwing.h" +#include <SimdPoint3.h> +#include <SimdPoint3.h> + +//#include "BU_IntervalArithmeticPolynomialSolver.h" +#include "BU_AlgebraicPolynomialSolver.h" + +#define USE_ALGEBRAIC +#ifdef USE_ALGEBRAIC +#define BU_Polynomial BU_AlgebraicPolynomialSolver +#else +#define BU_Polynomial BU_IntervalArithmeticPolynomialSolver +#endif + +BU_EdgeEdge::BU_EdgeEdge() +{ +} + + +bool BU_EdgeEdge::GetTimeOfImpact( + const BU_Screwing& screwAB, + const SimdPoint3& a,//edge in object A + const SimdVector3& u, + const SimdPoint3& c,//edge in object B + const SimdVector3& v, + SimdScalar &minTime, + SimdScalar &lambda1, + SimdScalar& mu1 + + ) +{ + bool hit=false; + + SimdScalar lambda; + SimdScalar mu; + + const SimdScalar w=screwAB.GetW(); + const SimdScalar s=screwAB.GetS(); + + if (SimdFuzzyZero(s) && + SimdFuzzyZero(w)) + { + //no motion, no collision + return false; + } + + if (SimdFuzzyZero(w) ) + { + //pure translation W=0, S <> 0 + //no trig, f(t)=t + SimdScalar det = u.y()*v.x()-u.x()*v.y(); + if (!SimdFuzzyZero(det)) + { + lambda = (a.x()*v.y() - c.x() * v.y() - v.x() * a.y() + v.x() * c.y()) / det; + mu = (u.y() * a.x() - u.y() * c.x() - u.x() * a.y() + u.x() * c.y()) / det; + + if (mu >=0 && mu <= 1 && lambda >= 0 && lambda <= 1) + { + // single potential collision is + SimdScalar t = (c.z()-a.z()+mu*v.z()-lambda*u.z())/s; + //if this is on the edge, and time t within [0..1] report hit + if (t>=0 && t <= minTime) + { + hit = true; + lambda1 = lambda; + mu1 = mu; + minTime=t; + } + } + + } else + { + //parallel case, not yet + } + } else + { + if (SimdFuzzyZero(s) ) + { + if (SimdFuzzyZero(u.z()) ) + { + if (SimdFuzzyZero(v.z()) ) + { + //u.z()=0,v.z()=0 + if (SimdFuzzyZero(a.z()-c.z())) + { + //printf("NOT YET planar problem, 4 vertex=edge cases\n"); + + } else + { + //printf("parallel but distinct planes, no collision\n"); + return false; + } + + } else + { + SimdScalar mu = (a.z() - c.z())/v.z(); + if (0<=mu && mu <= 1) + { + // printf("NOT YET//u.z()=0,v.z()<>0\n"); + } else + { + return false; + } + + } + } else + { + //u.z()<>0 + + if (SimdFuzzyZero(v.z()) ) + { + //printf("u.z()<>0,v.z()=0\n"); + lambda = (c.z() - a.z())/u.z(); + if (0<=lambda && lambda <= 1) + { + //printf("u.z()<>0,v.z()=0\n"); + SimdPoint3 rotPt(a.x()+lambda * u.x(), a.y()+lambda * u.y(),0.f); + SimdScalar r2 = rotPt.length2();//px*px + py*py; + + //either y=a*x+b, or x = a*x+b... + //depends on whether value v.x() is zero or not + SimdScalar aa; + SimdScalar bb; + + if (SimdFuzzyZero(v.x())) + { + aa = v.x()/v.y(); + bb= c.x()+ (-c.y() /v.y()) *v.x(); + } else + { + //line is c+mu*v; + //x = c.x()+mu*v.x(); + //mu = ((x-c.x())/v.x()); + //y = c.y()+((x-c.x())/v.x())*v.y(); + //y = c.y()+ (-c.x() /v.x()) *v.y() + (x /v.x()) *v.y(); + //y = a*x+b,where a = v.y()/v.x(), b= c.y()+ (-c.x() /v.x()) *v.y(); + aa = v.y()/v.x(); + bb= c.y()+ (-c.x() /v.x()) *v.y(); + } + + SimdScalar disc = aa*aa*r2 + r2 - bb*bb; + if (disc <0) + { + //edge doesn't intersect the circle (motion of the vertex) + return false; + } + SimdScalar rad = sqrtf(r2); + + if (SimdFuzzyZero(disc)) + { + SimdPoint3 intersectPt; + + SimdScalar mu; + //intersectionPoint edge with circle; + if (SimdFuzzyZero(v.x())) + { + intersectPt.setY( (-2*aa*bb)/(2*(aa*aa+1))); + intersectPt.setX( aa*intersectPt.y()+bb ); + mu = ((intersectPt.y()-c.y())/v.y()); + } else + { + intersectPt.setX((-2*aa*bb)/(2*(aa*aa+1))); + intersectPt.setY(aa*intersectPt.x()+bb); + mu = ((intersectPt.getX()-c.getX())/v.getX()); + + } + + if (0 <= mu && mu <= 1) + { + hit = Calc2DRotationPointPoint(rotPt,rad,screwAB.GetW(),intersectPt,minTime); + } + //only one solution + } else + { + //two points... + //intersectionPoint edge with circle; + SimdPoint3 intersectPt; + //intersectionPoint edge with circle; + if (SimdFuzzyZero(v.x())) + { + SimdScalar mu; + + intersectPt.setY((-2.f*aa*bb+2.f*sqrtf(disc))/(2.f*(aa*aa+1.f))); + intersectPt.setX(aa*intersectPt.y()+bb); + mu = ((intersectPt.getY()-c.getY())/v.getY()); + if (0.f <= mu && mu <= 1.f) + { + hit = Calc2DRotationPointPoint(rotPt,rad,screwAB.GetW(),intersectPt,minTime); + } + intersectPt.setY((-2.f*aa*bb-2.f*sqrtf(disc))/(2.f*(aa*aa+1.f))); + intersectPt.setX(aa*intersectPt.y()+bb); + mu = ((intersectPt.getY()-c.getY())/v.getY()); + if (0 <= mu && mu <= 1) + { + hit = hit || Calc2DRotationPointPoint(rotPt,rad,screwAB.GetW(),intersectPt,minTime); + } + + } else + { + SimdScalar mu; + + intersectPt.setX((-2.f*aa*bb+2.f*sqrtf(disc))/(2*(aa*aa+1.f))); + intersectPt.setY(aa*intersectPt.x()+bb); + mu = ((intersectPt.getX()-c.getX())/v.getX()); + if (0 <= mu && mu <= 1) + { + hit = Calc2DRotationPointPoint(rotPt,rad,screwAB.GetW(),intersectPt,minTime); + } + intersectPt.setX((-2.f*aa*bb-2.f*sqrtf(disc))/(2.f*(aa*aa+1.f))); + intersectPt.setY(aa*intersectPt.x()+bb); + mu = ((intersectPt.getX()-c.getX())/v.getX()); + if (0.f <= mu && mu <= 1.f) + { + hit = hit || Calc2DRotationPointPoint(rotPt,rad,screwAB.GetW(),intersectPt,minTime); + } + } + } + + + + int k=0; + + } else + { + return false; + } + + + } else + { + //u.z()<>0,v.z()<>0 + //printf("general case with s=0\n"); + hit = GetTimeOfImpactGeneralCase(screwAB,a,u,c,v,minTime,lambda,mu); + if (hit) + { + lambda1 = lambda; + mu1 = mu; + + } + } + } + + } else + { + //printf("general case, W<>0,S<>0\n"); + hit = GetTimeOfImpactGeneralCase(screwAB,a,u,c,v,minTime,lambda,mu); + if (hit) + { + lambda1 = lambda; + mu1 = mu; + } + + } + + + //W <> 0,pure rotation + } + + return hit; +} + + +bool BU_EdgeEdge::GetTimeOfImpactGeneralCase( + const BU_Screwing& screwAB, + const SimdPoint3& a,//edge in object A + const SimdVector3& u, + const SimdPoint3& c,//edge in object B + const SimdVector3& v, + SimdScalar &minTime, + SimdScalar &lambda, + SimdScalar& mu + + ) +{ + bool hit = false; + + SimdScalar coefs[4]; + BU_Polynomial polynomialSolver; + int numroots = 0; + + SimdScalar eps=1e-15f; + SimdScalar eps2=1e-20f; + SimdScalar s=screwAB.GetS(); + SimdScalar w = screwAB.GetW(); + + SimdScalar ax = a.x(); + SimdScalar ay = a.y(); + SimdScalar az = a.z(); + SimdScalar cx = c.x(); + SimdScalar cy = c.y(); + SimdScalar cz = c.z(); + SimdScalar vx = v.x(); + SimdScalar vy = v.y(); + SimdScalar vz = v.z(); + SimdScalar ux = u.x(); + SimdScalar uy = u.y(); + SimdScalar uz = u.z(); + + + if (!SimdFuzzyZero(v.z())) + { + + //Maple Autogenerated C code + SimdScalar t1,t2,t3,t4,t7,t8,t10; + SimdScalar t13,t14,t15,t16,t17,t18,t19,t20; + SimdScalar t21,t22,t23,t24,t25,t26,t27,t28,t29,t30; + SimdScalar t31,t32,t33,t34,t35,t36,t39,t40; + SimdScalar t41,t43,t48; + SimdScalar t63; + + SimdScalar aa,bb,cc,dd;//the coefficients + + t1 = v.y()*s; t2 = t1*u.x(); + t3 = v.x()*s; + t4 = t3*u.y(); + t7 = tanf(w/2.0f); + t8 = 1.0f/t7; + t10 = 1.0f/v.z(); + aa = (t2-t4)*t8*t10; + t13 = a.x()*t7; + t14 = u.z()*v.y(); + t15 = t13*t14; + t16 = u.x()*v.z(); + t17 = a.y()*t7; + t18 = t16*t17; + t19 = u.y()*v.z(); + t20 = t13*t19; + t21 = v.y()*u.x(); + t22 = c.z()*t7; + t23 = t21*t22; + t24 = v.x()*a.z(); + t25 = t7*u.y(); + t26 = t24*t25; + t27 = c.y()*t7; + t28 = t16*t27; + t29 = a.z()*t7; + t30 = t21*t29; + t31 = u.z()*v.x(); + t32 = t31*t27; + t33 = t31*t17; + t34 = c.x()*t7; + t35 = t34*t19; + t36 = t34*t14; + t39 = v.x()*c.z(); + t40 = t39*t25; + t41 = 2.0f*t1*u.y()-t15+t18-t20-t23-t26+t28+t30+t32+t33-t35-t36+2.0f*t3*u.x()+t40; + bb = t41*t8*t10; + t43 = t7*u.x(); + t48 = u.y()*v.y(); + cc = (-2.0f*t39*t43+2.0f*t24*t43+t4-2.0f*t48*t22+2.0f*t34*t16-2.0f*t31*t13-t2 + -2.0f*t17*t14+2.0f*t19*t27+2.0f*t48*t29)*t8*t10; + t63 = -t36+t26+t32-t40+t23+t35-t20+t18-t28-t33+t15-t30; + dd = t63*t8*t10; + + coefs[0]=aa; + coefs[1]=bb; + coefs[2]=cc; + coefs[3]=dd; + + } else + { + + SimdScalar t1,t2,t3,t4,t7,t8,t10; + SimdScalar t13,t14,t15,t16,t17,t18,t19,t20; + SimdScalar t21,t22,t23,t24,t25,t26,t27,t28,t29,t30; + SimdScalar t31,t32,t33,t34,t35,t36,t37,t38,t57; + SimdScalar p1,p2,p3,p4; + + t1 = uy*s; + t2 = t1*vx; + t3 = ux*s; + t4 = t3*vy; + t7 = tanf(w/2.0f); + t8 = 1/t7; + t10 = 1/uz; + t13 = ux*az; + t14 = t7*vy; + t15 = t13*t14; + t16 = ax*t7; + t17 = uy*vz; + t18 = t16*t17; + t19 = cx*t7; + t20 = t19*t17; + t21 = vy*uz; + t22 = t19*t21; + t23 = ay*t7; + t24 = vx*uz; + t25 = t23*t24; + t26 = uy*cz; + t27 = t7*vx; + t28 = t26*t27; + t29 = t16*t21; + t30 = cy*t7; + t31 = ux*vz; + t32 = t30*t31; + t33 = ux*cz; + t34 = t33*t14; + t35 = t23*t31; + t36 = t30*t24; + t37 = uy*az; + t38 = t37*t27; + + p4 = (-t2+t4)*t8*t10; + p3 = 2.0f*t1*vy+t15-t18-t20-t22+t25+t28-t29+t32-t34+t35+t36-t38+2.0f*t3*vx; + p2 = -2.0f*t33*t27-2.0f*t26*t14-2.0f*t23*t21+2.0f*t37*t14+2.0f*t30*t17+2.0f*t13 +*t27+t2-t4+2.0f*t19*t31-2.0f*t16*t24; + t57 = -t22+t29+t36-t25-t32+t34+t35-t28-t15+t20-t18+t38; + p1 = t57*t8*t10; + + coefs[0] = p4; + coefs[1] = p3; + coefs[2] = p2; + coefs[1] = p1; + + } + + numroots = polynomialSolver.Solve3Cubic(coefs[0],coefs[1],coefs[2],coefs[3]); + + for (int i=0;i<numroots;i++) + { + //SimdScalar tau = roots[i];//polynomialSolver.GetRoot(i); + SimdScalar tau = polynomialSolver.GetRoot(i); + + //check whether mu and lambda are in range [0..1] + + if (!SimdFuzzyZero(v.z())) + { + SimdScalar A1=(ux-ux*tau*tau-2.f*tau*uy)-((1.f+tau*tau)*vx*uz/vz); + SimdScalar B1=((1.f+tau*tau)*(cx*tanf(1.f/2.f*w)*vz+ + vx*az*tanf(1.f/2.f*w)-vx*cz*tanf(1.f/2.f*w)+ + vx*s*tau)/tanf(1.f/2.f*w)/vz)-(ax-ax*tau*tau-2.f*tau*ay); + lambda = B1/A1; + + mu = (a.z()-c.z()+lambda*u.z()+(s*tau)/(tanf(w/2.f)))/v.z(); + + + //double check in original equation + + SimdScalar lhs = (a.x()+lambda*u.x()) + *((1.f-tau*tau)/(1.f+tau*tau))- + (a.y()+lambda*u.y())*((2.f*tau)/(1.f+tau*tau)); + + lhs = lambda*((ux-ux*tau*tau-2.f*tau*uy)-((1.f+tau*tau)*vx*uz/vz)); + + SimdScalar rhs = c.x()+mu*v.x(); + + rhs = ((1.f+tau*tau)*(cx*tanf(1.f/2.f*w)*vz+vx*az*tanf(1.f/2.f*w)- + vx*cz*tanf(1.f/2.f*w)+vx*s*tau)/(tanf(1.f/2.f*w)*vz))- + + (ax-ax*tau*tau-2.f*tau*ay); + + SimdScalar res = coefs[0]*tau*tau*tau+ + coefs[1]*tau*tau+ + coefs[2]*tau+ + coefs[3]; + + //lhs should be rhs ! + + if (0.<= mu && mu <=1 && 0.<=lambda && lambda <= 1) + { + + } else + { + //skip this solution, not really touching + continue; + } + + } + + SimdScalar t = 2.f*atanf(tau)/screwAB.GetW(); + //tau = tan (wt/2) so 2*atan (tau)/w + if (t>=0.f && t<minTime) + { +#ifdef STATS_EDGE_EDGE + printf(" ax = %12.12f\n ay = %12.12f\n az = %12.12f\n",a.x(),a.y(),a.z()); + printf(" ux = %12.12f\n uy = %12.12f\n uz = %12.12f\n",u.x(),u.y(),u.z()); + printf(" cx = %12.12f\n cy = %12.12f\n cz = %12.12f\n",c.x(),c.y(),c.z()); + printf(" vx = %12.12f\n vy = %12.12f\n vz = %12.12f\n",v.x(),v.y(),v.z()); + printf(" s = %12.12f\n w = %12.12f\n", s, w); + + printf(" tau = %12.12f \n lambda = %12.12f \n mu = %f\n",tau,lambda,mu); + printf(" ---------------------------------------------\n"); + +#endif + + // v,u,a,c,s,w + + // BU_IntervalArithmeticPolynomialSolver iaSolver; + // int numroots2 = iaSolver.Solve3Cubic(coefs[0],coefs[1],coefs[2],coefs[3]); + + minTime = t; + hit = true; + } + } + + return hit; +} + + +//C -S +//S C + +bool BU_EdgeEdge::Calc2DRotationPointPoint(const SimdPoint3& rotPt, SimdScalar rotRadius, SimdScalar rotW,const SimdPoint3& intersectPt,SimdScalar& minTime) +{ + bool hit = false; + + // now calculate the planeEquation for the vertex motion, + // and check if the intersectionpoint is at the positive side + SimdPoint3 rotPt1(cosf(rotW)*rotPt.x()-sinf(rotW)*rotPt.y(), + sinf(rotW)*rotPt.x()+cosf(rotW)*rotPt.y(), + 0.f); + + SimdVector3 rotVec = rotPt1-rotPt; + + SimdVector3 planeNormal( -rotVec.y() , rotVec.x() ,0.f); + + //SimdPoint3 pt(a.x(),a.y());//for sake of readability,could write dot directly + SimdScalar planeD = planeNormal.dot(rotPt1); + + SimdScalar dist = (planeNormal.dot(intersectPt)-planeD); + hit = (dist >= -0.001); + + //if (hit) + { + // minTime = 0; + //calculate the time of impact, using the fact of + //toi = alpha / screwAB.getW(); + // cos (alpha) = adjacent/hypothenuse; + //adjacent = dotproduct(ipedge,point); + //hypothenuse = sqrt(r2); + SimdScalar adjacent = intersectPt.dot(rotPt)/rotRadius; + SimdScalar hypo = rotRadius; + SimdScalar alpha = acosf(adjacent/hypo); + SimdScalar t = alpha / rotW; + if (t >= 0 && t < minTime) + { + hit = true; + minTime = t; + } else + { + hit = false; + } + + } + return hit; +} + +bool BU_EdgeEdge::GetTimeOfImpactVertexEdge( + const BU_Screwing& screwAB, + const SimdPoint3& a,//edge in object A + const SimdVector3& u, + const SimdPoint3& c,//edge in object B + const SimdVector3& v, + SimdScalar &minTime, + SimdScalar &lamda, + SimdScalar& mu + + ) +{ + return false; +} diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/BU_EdgeEdge.h b/extern/bullet/Bullet/NarrowPhaseCollision/BU_EdgeEdge.h new file mode 100644 index 00000000000..32eed8bc898 --- /dev/null +++ b/extern/bullet/Bullet/NarrowPhaseCollision/BU_EdgeEdge.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ + +#ifndef BU_EDGEEDGE +#define BU_EDGEEDGE + +class BU_Screwing; +#include <SimdTransform.h> +#include <SimdPoint3.h> +#include <SimdVector3.h> + +//class BUM_Point2; + +#include <SimdScalar.h> + +///BU_EdgeEdge implements algebraic time of impact calculation between two (angular + linear) moving edges. +class BU_EdgeEdge +{ +public: + + + BU_EdgeEdge(); + bool GetTimeOfImpact( + const BU_Screwing& screwAB, + const SimdPoint3& a,//edge in object A + const SimdVector3& u, + const SimdPoint3& c,//edge in object B + const SimdVector3& v, + SimdScalar &minTime, + SimdScalar &lamda, + SimdScalar& mu + ); +private: + + bool Calc2DRotationPointPoint(const SimdPoint3& rotPt, SimdScalar rotRadius, SimdScalar rotW,const SimdPoint3& intersectPt,SimdScalar& minTime); + bool GetTimeOfImpactGeneralCase( + const BU_Screwing& screwAB, + const SimdPoint3& a,//edge in object A + const SimdVector3& u, + const SimdPoint3& c,//edge in object B + const SimdVector3& v, + SimdScalar &minTime, + SimdScalar &lamda, + SimdScalar& mu + + ); + + + bool GetTimeOfImpactVertexEdge( + const BU_Screwing& screwAB, + const SimdPoint3& a,//edge in object A + const SimdVector3& u, + const SimdPoint3& c,//edge in object B + const SimdVector3& v, + SimdScalar &minTime, + SimdScalar &lamda, + SimdScalar& mu + + ); + +}; + +#endif //BU_EDGEEDGE diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/BU_MotionStateInterface.h b/extern/bullet/Bullet/NarrowPhaseCollision/BU_MotionStateInterface.h new file mode 100644 index 00000000000..637271511e2 --- /dev/null +++ b/extern/bullet/Bullet/NarrowPhaseCollision/BU_MotionStateInterface.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ + +#ifndef BU_MOTIONSTATE +#define BU_MOTIONSTATE + + +#include <SimdTransform.h> +#include <SimdPoint3.h> +#include <SimdQuaternion.h> + +class BU_MotionStateInterface +{ +public: + virtual ~BU_MotionStateInterface(){}; + + virtual void SetTransform(const SimdTransform& trans) = 0; + virtual void GetTransform(SimdTransform& trans) const = 0; + + virtual void SetPosition(const SimdPoint3& position) = 0; + virtual void GetPosition(SimdPoint3& position) const = 0; + + virtual void SetOrientation(const SimdQuaternion& orientation) = 0; + virtual void GetOrientation(SimdQuaternion& orientation) const = 0; + + virtual void SetBasis(const SimdMatrix3x3& basis) = 0; + virtual void GetBasis(SimdMatrix3x3& basis) const = 0; + + virtual void SetLinearVelocity(const SimdVector3& linvel) = 0; + virtual void GetLinearVelocity(SimdVector3& linvel) const = 0; + + virtual void GetAngularVelocity(SimdVector3& angvel) const = 0; + virtual void SetAngularVelocity(const SimdVector3& angvel) = 0; + +}; + +#endif //BU_MOTIONSTATE diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/BU_PolynomialSolverInterface.h b/extern/bullet/Bullet/NarrowPhaseCollision/BU_PolynomialSolverInterface.h new file mode 100644 index 00000000000..4926acaf824 --- /dev/null +++ b/extern/bullet/Bullet/NarrowPhaseCollision/BU_PolynomialSolverInterface.h @@ -0,0 +1,26 @@ + +#ifndef BUM_POLYNOMIAL_SOLVER_INTERFACE +#define BUM_POLYNOMIAL_SOLVER_INTERFACE + +#include <SimdScalar.h> +// +//BUM_PolynomialSolverInterface is interface class for polynomial root finding. +//The number of roots is returned as a result, query GetRoot to get the actual solution. +// +class BUM_PolynomialSolverInterface +{ +public: + virtual ~BUM_PolynomialSolverInterface() {}; + + +// virtual int Solve2QuadraticFull(SimdScalar a,SimdScalar b, SimdScalar c) = 0; + + virtual int Solve3Cubic(SimdScalar lead, SimdScalar a, SimdScalar b, SimdScalar c) = 0; + + virtual int Solve4Quartic(SimdScalar lead, SimdScalar a, SimdScalar b, SimdScalar c, SimdScalar d) = 0; + + virtual SimdScalar GetRoot(int i) const = 0; + +}; + +#endif //BUM_POLYNOMIAL_SOLVER_INTERFACE diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/BU_Screwing.cpp b/extern/bullet/Bullet/NarrowPhaseCollision/BU_Screwing.cpp new file mode 100644 index 00000000000..f347dc4b49a --- /dev/null +++ b/extern/bullet/Bullet/NarrowPhaseCollision/BU_Screwing.cpp @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2005 Stephane Redon / Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ + +#include "BU_Screwing.h" + + + + + +BU_Screwing::BU_Screwing(const SimdVector3& relLinVel,const SimdVector3& relAngVel) { + + + const SimdScalar dx=relLinVel[0]; + const SimdScalar dy=relLinVel[1]; + const SimdScalar dz=relLinVel[2]; + const SimdScalar wx=relAngVel[0]; + const SimdScalar wy=relAngVel[1]; + const SimdScalar wz=relAngVel[2]; + + // Compute the screwing parameters : + // w : total amount of rotation + // s : total amount of translation + // u : vector along the screwing axis (||u||=1) + // o : point on the screwing axis + + m_w=sqrtf(wx*wx+wy*wy+wz*wz); + //if (!w) { + if (fabs(m_w)<SCREWEPSILON ) { + + assert(m_w == 0.f); + + m_w=0.; + m_s=sqrtf(dx*dx+dy*dy+dz*dz); + if (fabs(m_s)<SCREWEPSILON ) { + assert(m_s == 0.); + + m_s=0.; + m_u=SimdPoint3(0.,0.,1.); + m_o=SimdPoint3(0.,0.,0.); + } + else { + float t=1.f/m_s; + m_u=SimdPoint3(dx*t,dy*t,dz*t); + m_o=SimdPoint3(0.f,0.f,0.f); + } + } + else { // there is some rotation + + // we compute u + + float v(1.f/m_w); + m_u=SimdPoint3(wx*v,wy*v,wz*v); // normalization + + // decomposition of the translation along u and one orthogonal vector + + SimdPoint3 t(dx,dy,dz); + m_s=t.dot(m_u); // component along u + if (fabs(m_s)<SCREWEPSILON) + { + //printf("m_s component along u < SCREWEPSILION\n"); + m_s=0.f; + } + SimdPoint3 n1(t-(m_s*m_u)); // the remaining part (which is orthogonal to u) + + // now we have to compute o + + SimdScalar len = n1.length2(); + //(len >= BUM_EPSILON2) { + if (n1[0] || n1[1] || n1[2]) { // n1 is not the zero vector + n1.normalize(); + SimdVector3 n1orth=m_u.cross(n1); + + float n2x=cosf(0.5f*m_w); + float n2y=sinf(0.5f*m_w); + + m_o=0.5f*t.dot(n1)*(n1+n2x/n2y*n1orth); + } + else + { + m_o=SimdPoint3(0.f,0.f,0.f); + } + + } + +} + +//Then, I need to compute Pa, the matrix from the reference (global) frame to +//the screwing frame : + + +void BU_Screwing::LocalMatrix(SimdTransform &t) const { +//So the whole computations do this : align the Oz axis along the +// screwing axis (thanks to u), and then find two others orthogonal axes to +// complete the basis. + + if ((m_u[0]>SCREWEPSILON)||(m_u[0]<-SCREWEPSILON)||(m_u[1]>SCREWEPSILON)||(m_u[1]<-SCREWEPSILON)) + { + // to avoid numerical problems + float n=sqrtf(m_u[0]*m_u[0]+m_u[1]*m_u[1]); + float invn=1.0f/n; + SimdMatrix3x3 mat; + + mat[0][0]=-m_u[1]*invn; + mat[0][1]=m_u[0]*invn; + mat[0][2]=0.f; + + mat[1][0]=-m_u[0]*invn*m_u[2]; + mat[1][1]=-m_u[1]*invn*m_u[2]; + mat[1][2]=n; + + mat[2][0]=m_u[0]; + mat[2][1]=m_u[1]; + mat[2][2]=m_u[2]; + + t.setOrigin(SimdPoint3( + m_o[0]*m_u[1]*invn-m_o[1]*m_u[0]*invn, + -(m_o[0]*mat[1][0]+m_o[1]*mat[1][1]+m_o[2]*n), + -(m_o[0]*m_u[0]+m_o[1]*m_u[1]+m_o[2]*m_u[2]))); + + t.setBasis(mat); + + } + else { + + SimdMatrix3x3 m; + + m[0][0]=1.; + m[1][0]=0.; + m[2][0]=0.; + + m[0][1]=0.f; + m[1][1]=float(SimdSign(m_u[2])); + m[2][1]=0.f; + + m[0][2]=0.f; + m[1][2]=0.f; + m[2][2]=float(SimdSign(m_u[2])); + + t.setOrigin(SimdPoint3( + -m_o[0], + -SimdSign(m_u[2])*m_o[1], + -SimdSign(m_u[2])*m_o[2] + )); + t.setBasis(m); + + } +} + +//gives interpolated transform for time in [0..1] in screwing frame +SimdTransform BU_Screwing::InBetweenTransform(const SimdTransform& tr,SimdScalar t) const +{ + SimdPoint3 org = tr.getOrigin(); + + SimdPoint3 neworg ( + org.x()*cosf(m_w*t)-org.y()*sinf(m_w*t), + org.x()*sinf(m_w*t)+org.y()*cosf(m_w*t), + org.z()+m_s*CalculateF(t)); + + SimdTransform newtr; + newtr.setOrigin(neworg); + SimdMatrix3x3 basis = tr.getBasis(); + SimdMatrix3x3 basisorg = tr.getBasis(); + + SimdQuaternion rot(SimdVector3(0.,0.,1.),m_w*t); + SimdQuaternion tmpOrn; + tr.getBasis().getRotation(tmpOrn); + rot = rot * tmpOrn; + + //to avoid numerical drift, normalize quaternion + rot.normalize(); + newtr.setBasis(SimdMatrix3x3(rot)); + return newtr; + +} + + +SimdScalar BU_Screwing::CalculateF(SimdScalar t) const +{ + SimdScalar result; + if (!m_w) + { + result = t; + } else + { + result = ( tanf((m_w*t)/2.f) / tanf(m_w/2.f)); + } + return result; +} + diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/BU_Screwing.h b/extern/bullet/Bullet/NarrowPhaseCollision/BU_Screwing.h new file mode 100644 index 00000000000..09cf049d2f8 --- /dev/null +++ b/extern/bullet/Bullet/NarrowPhaseCollision/BU_Screwing.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ + +#ifndef B_SCREWING_H +#define B_SCREWING_H + + +#include <SimdVector3.h> +#include <SimdPoint3.h> +#include <SimdTransform.h> + + +#define SCREWEPSILON 0.00001f + +///BU_Screwing implements screwing motion interpolation. +class BU_Screwing +{ +public: + + + BU_Screwing(const SimdVector3& relLinVel,const SimdVector3& relAngVel); + + ~BU_Screwing() { + }; + + SimdScalar CalculateF(SimdScalar t) const; + //gives interpolated position for time in [0..1] in screwing frame + + inline SimdPoint3 InBetweenPosition(const SimdPoint3& pt,SimdScalar t) const + { + return SimdPoint3( + pt.x()*cosf(m_w*t)-pt.y()*sinf(m_w*t), + pt.x()*sinf(m_w*t)+pt.y()*cosf(m_w*t), + pt.z()+m_s*CalculateF(t)); + } + + inline SimdVector3 InBetweenVector(const SimdVector3& vec,SimdScalar t) const + { + return SimdVector3( + vec.x()*cosf(m_w*t)-vec.y()*sinf(m_w*t), + vec.x()*sinf(m_w*t)+vec.y()*cosf(m_w*t), + vec.z()); + } + + //gives interpolated transform for time in [0..1] in screwing frame + SimdTransform InBetweenTransform(const SimdTransform& tr,SimdScalar t) const; + + + //gives matrix from global frame into screwing frame + void LocalMatrix(SimdTransform &t) const; + + inline const SimdVector3& GetU() const { return m_u;} + inline const SimdVector3& GetO() const {return m_o;} + inline const SimdScalar GetS() const{ return m_s;} + inline const SimdScalar GetW() const { return m_w;} + +private: + float m_w; + float m_s; + SimdVector3 m_u; + SimdVector3 m_o; +}; + +#endif //B_SCREWING_H diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/BU_StaticMotionState.h b/extern/bullet/Bullet/NarrowPhaseCollision/BU_StaticMotionState.h new file mode 100644 index 00000000000..553fa6fea78 --- /dev/null +++ b/extern/bullet/Bullet/NarrowPhaseCollision/BU_StaticMotionState.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ + +#ifndef BU_STATIC_MOTIONSTATE +#define BU_STATIC_MOTIONSTATE + + +#include <CollisionShapes/BU_MotionStateInterface.h> + +class BU_StaticMotionState :public BU_MotionStateInterface +{ +public: + virtual ~BU_StaticMotionState(){}; + + virtual void SetTransform(const SimdTransform& trans) + { + m_trans = trans; + } + virtual void GetTransform(SimdTransform& trans) const + { + trans = m_trans; + } + virtual void SetPosition(const SimdPoint3& position) + { + m_trans.setOrigin( position ); + } + virtual void GetPosition(SimdPoint3& position) const + { + position = m_trans.getOrigin(); + } + + virtual void SetOrientation(const SimdQuaternion& orientation) + { + m_trans.setRotation( orientation); + } + virtual void GetOrientation(SimdQuaternion& orientation) const + { + orientation = m_trans.getRotation(); + } + + virtual void SetBasis(const SimdMatrix3x3& basis) + { + m_trans.setBasis( basis); + } + virtual void GetBasis(SimdMatrix3x3& basis) const + { + basis = m_trans.getBasis(); + } + + virtual void SetLinearVelocity(const SimdVector3& linvel) + { + m_linearVelocity = linvel; + } + virtual void GetLinearVelocity(SimdVector3& linvel) const + { + linvel = m_linearVelocity; + } + + virtual void SetAngularVelocity(const SimdVector3& angvel) + { + m_angularVelocity = angvel; + } + virtual void GetAngularVelocity(SimdVector3& angvel) const + { + angvel = m_angularVelocity; + } + + + +protected: + + SimdTransform m_trans; + SimdVector3 m_angularVelocity; + SimdVector3 m_linearVelocity; + +}; + +#endif //BU_STATIC_MOTIONSTATE diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/BU_VertexPoly.cpp b/extern/bullet/Bullet/NarrowPhaseCollision/BU_VertexPoly.cpp new file mode 100644 index 00000000000..8486df701e7 --- /dev/null +++ b/extern/bullet/Bullet/NarrowPhaseCollision/BU_VertexPoly.cpp @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ + + +#include "BU_VertexPoly.h" +#include "BU_Screwing.h" +#include <SimdTransform.h> +#include <SimdPoint3.h> +#include <SimdVector3.h> + +#define USE_ALGEBRAIC +#ifdef USE_ALGEBRAIC + #include "BU_AlgebraicPolynomialSolver.h" + #define BU_Polynomial BU_AlgebraicPolynomialSolver +#else + #include "BU_IntervalArithmeticPolynomialSolver.h" + #define BU_Polynomial BU_IntervalArithmeticPolynomialSolver +#endif + +inline bool TestFuzzyZero(SimdScalar x) { return fabsf(x) < 0.0001f; } + + +BU_VertexPoly::BU_VertexPoly() +{ + +} +//return true if a collision will occur between [0..1] +//false otherwise. If true, minTime contains the time of impact +bool BU_VertexPoly::GetTimeOfImpact( + const BU_Screwing& screwAB, + const SimdPoint3& a, + const SimdVector4& planeEq, + SimdScalar &minTime,bool swapAB) +{ + + bool hit = false; + + // precondition: s=0 and w= 0 is catched by caller! + if (TestFuzzyZero(screwAB.GetS()) && + TestFuzzyZero(screwAB.GetW())) + { + return false; + } + + + //case w<>0 and s<> 0 + const SimdScalar w=screwAB.GetW(); + const SimdScalar s=screwAB.GetS(); + + SimdScalar coefs[4]; + const SimdScalar p=planeEq[0]; + const SimdScalar q=planeEq[1]; + const SimdScalar r=planeEq[2]; + const SimdScalar d=planeEq[3]; + + const SimdVector3 norm(p,q,r); + BU_Polynomial polynomialSolver; + int numroots = 0; + + SimdScalar eps=1e-80f; + SimdScalar eps2=1e-100f; + + if (TestFuzzyZero(screwAB.GetS()) ) + { + //S = 0 , W <> 0 + + //ax^3+bx^2+cx+d=0 + coefs[0]=0.; + coefs[1]=(-p*a.x()-q*a.y()+r*a.z()-d); + coefs[2]=-2*p*a.y()+2*q*a.x(); + coefs[3]=p*a.x()+q*a.y()+r*a.z()-d; + +// numroots = polynomialSolver.Solve3Cubic(coefs[0],coefs[1],coefs[2],coefs[3]); + numroots = polynomialSolver.Solve2QuadraticFull(coefs[1],coefs[2],coefs[3]); + + } else + { + if (TestFuzzyZero(screwAB.GetW())) + { + // W = 0 , S <> 0 + //pax+qay+r(az+st)=d + + SimdScalar dist = (d - a.dot(norm)); + + if (TestFuzzyZero(r)) + { + if (TestFuzzyZero(dist)) + { + // no hit + } else + { + // todo a a' might hit sides of polygon T + //printf("unhandled case, w=0,s<>0,r<>0, a a' might hit sides of polygon T \n"); + } + + } else + { + SimdScalar etoi = (dist)/(r*screwAB.GetS()); + if (swapAB) + etoi *= -1; + + if (etoi >= 0. && etoi <= minTime) + { + minTime = etoi; + hit = true; + } + } + + } else + { + //ax^3+bx^2+cx+d=0 + + //degenerate coefficients mess things up :( + SimdScalar ietsje = (r*s)/tanf(w/2.f); + if (ietsje*ietsje < 0.01f) + ietsje = 0.f; + + coefs[0]=ietsje;//(r*s)/tan(w/2.); + coefs[1]=(-p*a.x()-q*a.y()+r*a.z()-d); + coefs[2]=-2.f*p*a.y()+2.f*q*a.x()+ietsje;//((r*s)/(tan(w/2.))); + coefs[3]=p*a.x()+q*a.y()+r*a.z()-d; + + numroots = polynomialSolver.Solve3Cubic(coefs[0],coefs[1],coefs[2],coefs[3]); + } + } + + + for (int i=0;i<numroots;i++) + { + SimdScalar tau = polynomialSolver.GetRoot(i); + + SimdScalar t = 2.f*atanf(tau)/w; + //tau = tan (wt/2) so 2*atan (tau)/w + if (swapAB) + { + t *= -1.; + } + if (t>=0 && t<minTime) + { + minTime = t; + hit = true; + } + } + + return hit; +} diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/BU_VertexPoly.h b/extern/bullet/Bullet/NarrowPhaseCollision/BU_VertexPoly.h new file mode 100644 index 00000000000..81c2017542f --- /dev/null +++ b/extern/bullet/Bullet/NarrowPhaseCollision/BU_VertexPoly.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ + +#ifndef VERTEX_POLY_H +#define VERTEX_POLY_H + + +class BU_Screwing; +#include <SimdTransform.h> +#include <SimdPoint3.h> +#include <SimdScalar.h> + +///BU_VertexPoly implements algebraic time of impact calculation between vertex and a plane. +class BU_VertexPoly +{ +public: + BU_VertexPoly(); + bool GetTimeOfImpact( + const BU_Screwing& screwAB, + const SimdPoint3& vtx, + const SimdVector4& planeEq, + SimdScalar &minTime, + bool swapAB); + +private: + + //cached data (frame coherency etc.) here + +}; +#endif //VERTEX_POLY_H diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/CollisionMargin.h b/extern/bullet/Bullet/NarrowPhaseCollision/CollisionMargin.h new file mode 100644 index 00000000000..7e51dc7f2b3 --- /dev/null +++ b/extern/bullet/Bullet/NarrowPhaseCollision/CollisionMargin.h @@ -0,0 +1,11 @@ +#ifndef COLLISION_MARGIN_H +#define COLLISION_MARGIN_H + +//used by Gjk and some other algorithms + +#define CONVEX_DISTANCE_MARGIN 0.05f// 0.1f//;//0.01f + + + +#endif //COLLISION_MARGIN_H + diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/ContinuousConvexCollision.cpp b/extern/bullet/Bullet/NarrowPhaseCollision/ContinuousConvexCollision.cpp new file mode 100644 index 00000000000..21baabfb864 --- /dev/null +++ b/extern/bullet/Bullet/NarrowPhaseCollision/ContinuousConvexCollision.cpp @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ + +#include "ContinuousConvexCollision.h" +#include "CollisionShapes/ConvexShape.h" +#include "CollisionShapes/MinkowskiSumShape.h" +#include "NarrowPhaseCollision/SimplexSolverInterface.h" +#include "SimdTransformUtil.h" +#include "CollisionShapes/SphereShape.h" + +#include "GjkPairDetector.h" +#include "PointCollector.h" + + + +ContinuousConvexCollision::ContinuousConvexCollision ( ConvexShape* convexA,ConvexShape* convexB,SimplexSolverInterface* simplexSolver, ConvexPenetrationDepthSolver* penetrationDepthSolver) +:m_simplexSolver(simplexSolver), +m_penetrationDepthSolver(penetrationDepthSolver), +m_convexA(convexA),m_convexB(convexB) +{ +} + +/// This maximum should not be necessary. It allows for untested/degenerate cases in production code. +/// You don't want your game ever to lock-up. +#define MAX_ITERATIONS 1000 + +bool ContinuousConvexCollision::calcTimeOfImpact( + const SimdTransform& fromA, + const SimdTransform& toA, + const SimdTransform& fromB, + const SimdTransform& toB, + CastResult& result) +{ + + m_simplexSolver->reset(); + + /// compute linear and angular velocity for this interval, to interpolate + SimdVector3 linVelA,angVelA,linVelB,angVelB; + SimdTransformUtil::CalculateVelocity(fromA,toA,1.f,linVelA,angVelA); + SimdTransformUtil::CalculateVelocity(fromB,toB,1.f,linVelB,angVelB); + + SimdScalar boundingRadiusA = m_convexA->GetAngularMotionDisc(); + SimdScalar boundingRadiusB = m_convexB->GetAngularMotionDisc(); + + SimdScalar maxAngularProjectedVelocity = angVelA.length() * boundingRadiusA + angVelB.length() * boundingRadiusB; + + float radius = 0.001f; + + SimdScalar lambda = 0.f; + SimdVector3 v(1,0,0); + + int maxIter = MAX_ITERATIONS; + + SimdVector3 n; + n.setValue(0.f,0.f,0.f); + bool hasResult = false; + SimdVector3 c; + + float lastLambda = lambda; + float epsilon = 0.001f; + + int numIter = 0; + //first solution, using GJK + + + SimdTransform identityTrans; + identityTrans.setIdentity(); + + SphereShape raySphere(0.0f); + raySphere.SetMargin(0.f); + + +// result.DrawCoordSystem(sphereTr); + + PointCollector pointCollector1; + + { + + GjkPairDetector gjk(m_convexA,m_convexB,m_simplexSolver,m_penetrationDepthSolver); + GjkPairDetector::ClosestPointInput input; + input.m_transformA = fromA; + input.m_transformB = fromB; + gjk.GetClosestPoints(input,pointCollector1); + + hasResult = pointCollector1.m_hasResult; + c = pointCollector1.m_pointInWorld; + } + + if (hasResult) + { + SimdScalar dist; + dist = pointCollector1.m_distance; + n = pointCollector1.m_normalOnBInWorld; + + //not close enough + while (dist > radius) + { + numIter++; + if (numIter > maxIter) + return false; //todo: report a failure + + float dLambda = 0.f; + + //calculate safe moving fraction from distance / (linear+rotational velocity) + + //float clippedDist = GEN_min(angularConservativeRadius,dist); + float clippedDist = dist; + + float projectedLinearVelocity = (linVelB-linVelA).dot(n); + + dLambda = dist / (projectedLinearVelocity+ maxAngularProjectedVelocity); + + lambda = lambda + dLambda; + + //todo: next check with relative epsilon + if (lambda <= lastLambda) + break; + lastLambda = lambda; + + if (lambda > 1.f) + return false; + + //interpolate to next lambda + SimdTransform interpolatedTransA,interpolatedTransB,relativeTrans; + + SimdTransformUtil::IntegrateTransform(fromA,linVelA,angVelA,lambda,interpolatedTransA); + SimdTransformUtil::IntegrateTransform(fromB,linVelB,angVelB,lambda,interpolatedTransB); + relativeTrans = interpolatedTransB.inverseTimes(interpolatedTransA); + + result.DebugDraw( lambda ); + + PointCollector pointCollector; + GjkPairDetector gjk(m_convexA,m_convexB,m_simplexSolver,m_penetrationDepthSolver); + GjkPairDetector::ClosestPointInput input; + input.m_transformA = interpolatedTransA; + input.m_transformB = interpolatedTransB; + gjk.GetClosestPoints(input,pointCollector); + if (pointCollector.m_hasResult) + { + if (pointCollector.m_distance < 0.f) + { + //degenerate ?! + result.m_fraction = lastLambda; + result.m_normal = n; + return true; + } + c = pointCollector.m_pointInWorld; + + dist = pointCollector.m_distance; + } else + { + //?? + return false; + } + + } + + result.m_fraction = lambda; + result.m_normal = n; + return true; + } + + return false; + +/* +//todo: + //if movement away from normal, discard result + SimdVector3 move = transBLocalTo.getOrigin() - transBLocalFrom.getOrigin(); + if (result.m_fraction < 1.f) + { + if (move.dot(result.m_normal) <= 0.f) + { + } + } +*/ + +} + diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/ContinuousConvexCollision.h b/extern/bullet/Bullet/NarrowPhaseCollision/ContinuousConvexCollision.h new file mode 100644 index 00000000000..0f9808f2986 --- /dev/null +++ b/extern/bullet/Bullet/NarrowPhaseCollision/ContinuousConvexCollision.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ + +#ifndef CONTINUOUS_COLLISION_CONVEX_CAST_H +#define CONTINUOUS_COLLISION_CONVEX_CAST_H + +#include "ConvexCast.h" +#include "SimplexSolverInterface.h" +class ConvexPenetrationDepthSolver; +class ConvexShape; + +/// ContinuousConvexCollision implements angular and linear time of impact for convex objects. +/// Based on Brian Mirtich's Conservative Advancement idea (PhD thesis). +/// Algorithm operates in worldspace, in order to keep inbetween motion globally consistent. +/// It uses GJK at the moment. Future improvement would use minkowski sum / supporting vertex, merging innerloops +class ContinuousConvexCollision : public ConvexCast +{ + SimplexSolverInterface* m_simplexSolver; + ConvexPenetrationDepthSolver* m_penetrationDepthSolver; + ConvexShape* m_convexA; + ConvexShape* m_convexB; + + +public: + + ContinuousConvexCollision (ConvexShape* shapeA,ConvexShape* shapeB ,SimplexSolverInterface* simplexSolver,ConvexPenetrationDepthSolver* penetrationDepthSolver); + + virtual bool calcTimeOfImpact( + const SimdTransform& fromA, + const SimdTransform& toA, + const SimdTransform& fromB, + const SimdTransform& toB, + CastResult& result); + + +}; + +#endif //CONTINUOUS_COLLISION_CONVEX_CAST_H
\ No newline at end of file diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/ConvexCast.cpp b/extern/bullet/Bullet/NarrowPhaseCollision/ConvexCast.cpp new file mode 100644 index 00000000000..d8a4956700c --- /dev/null +++ b/extern/bullet/Bullet/NarrowPhaseCollision/ConvexCast.cpp @@ -0,0 +1,5 @@ +#include "ConvexCast.h" + +ConvexCast::~ConvexCast() +{ +} diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/ConvexCast.h b/extern/bullet/Bullet/NarrowPhaseCollision/ConvexCast.h new file mode 100644 index 00000000000..f32887f6472 --- /dev/null +++ b/extern/bullet/Bullet/NarrowPhaseCollision/ConvexCast.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ + +#ifndef CONVEX_CAST_H +#define CONVEX_CAST_H + +#include <SimdTransform.h> +#include <SimdVector3.h> +#include <SimdScalar.h> +class MinkowskiSumShape; + +/// ConvexCast is an interface for Casting +class ConvexCast +{ +public: + + + virtual ~ConvexCast(); + + ///RayResult stores the closest result + /// alternatively, add a callback method to decide about closest/all results + struct CastResult + { + //virtual bool addRayResult(const SimdVector3& normal,SimdScalar fraction) = 0; + + virtual void DebugDraw(SimdScalar fraction) {} + virtual void DrawCoordSystem(const SimdTransform& trans) {} + CastResult() + :m_fraction(1e30f) + { + } + + SimdVector3 m_normal; + SimdScalar m_fraction; + SimdTransform m_hitTransformA; + SimdTransform m_hitTransformB; + }; + + + /// cast a convex against another convex object + virtual bool calcTimeOfImpact( + const SimdTransform& fromA, + const SimdTransform& toA, + const SimdTransform& fromB, + const SimdTransform& toB, + CastResult& result) = 0; +}; + +#endif //CONVEX_CAST_H diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/ConvexPenetrationDepthSolver.h b/extern/bullet/Bullet/NarrowPhaseCollision/ConvexPenetrationDepthSolver.h new file mode 100644 index 00000000000..4eef58e9775 --- /dev/null +++ b/extern/bullet/Bullet/NarrowPhaseCollision/ConvexPenetrationDepthSolver.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ + +#ifndef CONVEX_PENETRATION_DEPTH_H +#define CONVEX_PENETRATION_DEPTH_H + +class SimdVector3; +#include "SimplexSolverInterface.h" +class ConvexShape; +#include "SimdPoint3.h" +class SimdTransform; + +///ConvexPenetrationDepthSolver provides an interface for penetration depth calculation. +class ConvexPenetrationDepthSolver +{ +public: + + virtual bool CalcPenDepth( SimplexSolverInterface& simplexSolver, + ConvexShape* convexA,ConvexShape* convexB, + const SimdTransform& transA,const SimdTransform& transB, + SimdVector3& v, SimdPoint3& pa, SimdPoint3& pb) = 0; + + +}; +#endif //CONVEX_PENETRATION_DEPTH_H
\ No newline at end of file diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/DiscreteCollisionDetectorInterface.h b/extern/bullet/Bullet/NarrowPhaseCollision/DiscreteCollisionDetectorInterface.h new file mode 100644 index 00000000000..c51de7388a3 --- /dev/null +++ b/extern/bullet/Bullet/NarrowPhaseCollision/DiscreteCollisionDetectorInterface.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ + +#ifndef DISCRETE_COLLISION_DETECTOR_INTERFACE_H +#define DISCRETE_COLLISION_DETECTOR_INTERFACE_H +#include "SimdTransform.h" +#include "SimdVector3.h" + + +/// This interface is made to be used by an iterative approach to do TimeOfImpact calculations +/// This interface allows to query for closest points and penetration depth between two (convex) objects +/// the closest point is on the second object (B), and the normal points from the surface on B towards A. +/// distance is between closest points on B and closest point on A. So you can calculate closest point on A +/// by taking closestPointInA = closestPointInB + m_distance * m_normalOnSurfaceB +struct DiscreteCollisionDetectorInterface +{ + void operator delete(void* ptr) {}; + + struct Result + { + void operator delete(void* ptr) {}; + + virtual void AddContactPoint(const SimdVector3& normalOnBInWorld,const SimdVector3& pointInWorld,float depth)=0; + }; + + struct ClosestPointInput + { + ClosestPointInput() + :m_maximumDistanceSquared(1e30f) + { + } + + SimdTransform m_transformA; + SimdTransform m_transformB; + SimdScalar m_maximumDistanceSquared; + }; + + virtual ~DiscreteCollisionDetectorInterface() {}; + + // + // give either closest points (distance > 0) or penetration (distance) + // the normal always points from B towards A + // + virtual void GetClosestPoints(const ClosestPointInput& input,Result& output) = 0; + + SimdScalar getCollisionMargin() { return 0.2f;} +}; + +struct StorageResult : public DiscreteCollisionDetectorInterface::Result +{ + SimdVector3 m_normalOnSurfaceB; + SimdVector3 m_closestPointInB; + SimdScalar m_distance; //negative means penetration ! + + StorageResult() : m_distance(1e30f) + { + + } + + virtual void AddContactPoint(const SimdVector3& normalOnBInWorld,const SimdVector3& pointInWorld,float depth) + { + if (depth < m_distance) + { + m_normalOnSurfaceB = normalOnBInWorld; + m_closestPointInB = pointInWorld; + m_distance = depth; + } + } +}; + +#endif //DISCRETE_COLLISION_DETECTOR_INTERFACE_H diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/GjkConvexCast.cpp b/extern/bullet/Bullet/NarrowPhaseCollision/GjkConvexCast.cpp new file mode 100644 index 00000000000..10a4cb56dcf --- /dev/null +++ b/extern/bullet/Bullet/NarrowPhaseCollision/GjkConvexCast.cpp @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ + + +#include "GjkConvexCast.h" +#include "CollisionShapes/SphereShape.h" +#include "CollisionShapes/MinkowskiSumShape.h" +#include "GjkPairDetector.h" +#include "PointCollector.h" + + +GjkConvexCast::GjkConvexCast(ConvexShape* convexA,ConvexShape* convexB,SimplexSolverInterface* simplexSolver) +:m_simplexSolver(simplexSolver), +m_convexA(convexA), +m_convexB(convexB) +{ +} + +bool GjkConvexCast::calcTimeOfImpact( + const SimdTransform& fromA, + const SimdTransform& toA, + const SimdTransform& fromB, + const SimdTransform& toB, + CastResult& result) +{ + + + MinkowskiSumShape combi(m_convexA,m_convexB); + MinkowskiSumShape* convex = &combi; + + SimdTransform rayFromLocalA; + SimdTransform rayToLocalA; + + rayFromLocalA = fromA.inverse()* fromB; + rayToLocalA = toA.inverse()* toB; + + + SimdTransform trA,trB; + trA = SimdTransform(fromA); + trB = SimdTransform(fromB); + trA.setOrigin(SimdPoint3(0,0,0)); + trB.setOrigin(SimdPoint3(0,0,0)); + + convex->SetTransformA(trA); + convex->SetTransformB(trB); + + + + + float radius = 0.01f; + + SimdScalar lambda = 0.f; + SimdVector3 s = rayFromLocalA.getOrigin(); + SimdVector3 r = rayToLocalA.getOrigin()-rayFromLocalA.getOrigin(); + SimdVector3 x = s; + SimdVector3 n; + n.setValue(0,0,0); + bool hasResult = false; + SimdVector3 c; + + float lastLambda = lambda; + + //first solution, using GJK + + //no penetration support for now, perhaps pass a pointer when we really want it + ConvexPenetrationDepthSolver* penSolverPtr = 0; + + SimdTransform identityTrans; + identityTrans.setIdentity(); + + SphereShape raySphere(0.0f); + raySphere.SetMargin(0.f); + + SimdTransform sphereTr; + sphereTr.setIdentity(); + sphereTr.setOrigin( rayFromLocalA.getOrigin()); + + result.DrawCoordSystem(sphereTr); + { + PointCollector pointCollector1; + GjkPairDetector gjk(&raySphere,convex,m_simplexSolver,penSolverPtr); + + GjkPairDetector::ClosestPointInput input; + input.m_transformA = sphereTr; + input.m_transformB = identityTrans; + gjk.GetClosestPoints(input,pointCollector1); + + hasResult = pointCollector1.m_hasResult; + c = pointCollector1.m_pointInWorld; + n = pointCollector1.m_normalOnBInWorld; + } + + if (hasResult) + { + SimdScalar dist; + dist = (c-x).length(); + + + //not close enough + while (dist > radius) + { + + n = x - c; + SimdScalar nDotr = n.dot(r); + + if (nDotr >= 0.f) + return false; + + lambda = lambda - n.dot(n) / nDotr; + if (lambda <= lastLambda) + break; + lastLambda = lambda; + + x = s + lambda * r; + + sphereTr.setOrigin( x ); + result.DrawCoordSystem(sphereTr); + PointCollector pointCollector; + GjkPairDetector gjk(&raySphere,convex,m_simplexSolver,penSolverPtr); + GjkPairDetector::ClosestPointInput input; + input.m_transformA = sphereTr; + input.m_transformB = identityTrans; + gjk.GetClosestPoints(input,pointCollector); + if (pointCollector.m_hasResult) + { + if (pointCollector.m_distance < 0.f) + { + //degeneracy, report a hit + result.m_fraction = lastLambda; + result.m_normal = n; + return true; + } + c = pointCollector.m_pointInWorld; + dist = (c-x).length(); + } else + { + //?? + return false; + } + + } + + result.m_fraction = lambda; + result.m_normal = n; + return true; + } + + return false; +}
\ No newline at end of file diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/GjkConvexCast.h b/extern/bullet/Bullet/NarrowPhaseCollision/GjkConvexCast.h new file mode 100644 index 00000000000..f5c800f85c6 --- /dev/null +++ b/extern/bullet/Bullet/NarrowPhaseCollision/GjkConvexCast.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ + + +#ifndef GJK_CONVEX_CAST_H +#define GJK_CONVEX_CAST_H + +#include "CollisionMargin.h" +#include "SimdVector3.h" +#include "ConvexCast.h" +class ConvexShape; +class MinkowskiSumShape; +#include "SimplexSolverInterface.h" + +///GjkConvexCast performs a raycast on a convex object using support mapping. +class GjkConvexCast : public ConvexCast +{ + SimplexSolverInterface* m_simplexSolver; + ConvexShape* m_convexA; + ConvexShape* m_convexB; + +public: + + GjkConvexCast(ConvexShape* convexA,ConvexShape* convexB,SimplexSolverInterface* simplexSolver); + + /// cast a convex against another convex object + virtual bool calcTimeOfImpact( + const SimdTransform& fromA, + const SimdTransform& toA, + const SimdTransform& fromB, + const SimdTransform& toB, + CastResult& result); + +}; + +#endif //GJK_CONVEX_CAST_H diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/GjkPairDetector.cpp b/extern/bullet/Bullet/NarrowPhaseCollision/GjkPairDetector.cpp new file mode 100644 index 00000000000..f5db2661c01 --- /dev/null +++ b/extern/bullet/Bullet/NarrowPhaseCollision/GjkPairDetector.cpp @@ -0,0 +1,186 @@ +/* +* Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com +* +* Permission to use, copy, modify, distribute and sell this software +* and its documentation for any purpose is hereby granted without fee, +* provided that the above copyright notice appear in all copies. +* Erwin Coumans makes no representations about the suitability +* of this software for any purpose. +* It is provided "as is" without express or implied warranty. +*/ + +#include "GjkPairDetector.h" +#include "CollisionShapes/ConvexShape.h" +#include "NarrowPhaseCollision/SimplexSolverInterface.h" +#include "NarrowPhaseCollision/ConvexPenetrationDepthSolver.h" + +static const SimdScalar rel_error = SimdScalar(1.0e-3); +SimdScalar rel_error2 = rel_error * rel_error; +float maxdist2 = 1.e30f; + + + +GjkPairDetector::GjkPairDetector(ConvexShape* objectA,ConvexShape* objectB,SimplexSolverInterface* simplexSolver,ConvexPenetrationDepthSolver* penetrationDepthSolver) +:m_cachedSeparatingAxis(0.f,0.f,1.f), +m_penetrationDepthSolver(penetrationDepthSolver), +m_simplexSolver(simplexSolver), +m_minkowskiA(objectA), +m_minkowskiB(objectB) +{ +} + +void GjkPairDetector::GetClosestPoints(const ClosestPointInput& input,Result& output) +{ + SimdScalar distance; + SimdVector3 normalInB(0.f,0.f,0.f); + SimdVector3 pointOnA,pointOnB; + + float marginA = m_minkowskiA->GetMargin(); + float marginB = m_minkowskiB->GetMargin(); + + bool isValid = false; + bool checkSimplex = false; + bool checkPenetration = true; + + { + SimdScalar squaredDistance = SIMD_INFINITY; + SimdScalar delta = 0.f; + + SimdScalar margin = marginA + marginB; + + + + m_simplexSolver->reset(); + + while (true) + { + + SimdVector3 seperatingAxisInA = (-m_cachedSeparatingAxis)* input.m_transformA.getBasis(); + SimdVector3 seperatingAxisInB = m_cachedSeparatingAxis* input.m_transformB.getBasis(); + + SimdVector3 pInA = m_minkowskiA->LocalGetSupportingVertexWithoutMargin(seperatingAxisInA); + SimdVector3 qInB = m_minkowskiB->LocalGetSupportingVertexWithoutMargin(seperatingAxisInB); + SimdPoint3 pWorld = input.m_transformA(pInA); + SimdPoint3 qWorld = input.m_transformB(qInB); + + SimdVector3 w = pWorld - qWorld; + delta = m_cachedSeparatingAxis.dot(w); + + // potential exit, they don't overlap + if ((delta > SimdScalar(0.0)) && (delta * delta > squaredDistance * input.m_maximumDistanceSquared)) + { + checkPenetration = false; + break; + } + + //exit 0: the new point is already in the simplex, or we didn't come any closer + if (m_simplexSolver->inSimplex(w)) + { + checkSimplex = true; + break; + } + // are we getting any closer ? + if (squaredDistance - delta <= squaredDistance * rel_error2) + { + checkSimplex = true; + break; + } + //add current vertex to simplex + m_simplexSolver->addVertex(w, pWorld, qWorld); + + //calculate the closest point to the origin (update vector v) + if (!m_simplexSolver->closest(m_cachedSeparatingAxis)) + { + checkSimplex = true; + break; + } + + SimdScalar previousSquaredDistance = squaredDistance; + squaredDistance = m_cachedSeparatingAxis.length2(); + + //redundant m_simplexSolver->compute_points(pointOnA, pointOnB); + + //are we getting any closer ? + if (previousSquaredDistance - squaredDistance <= SIMD_EPSILON * previousSquaredDistance) + { + m_simplexSolver->backup_closest(m_cachedSeparatingAxis); + checkSimplex = true; + break; + } + bool check = (!m_simplexSolver->fullSimplex() && squaredDistance > SIMD_EPSILON * m_simplexSolver->maxVertex()); + + if (!check) + { + //do we need this backup_closest here ? + m_simplexSolver->backup_closest(m_cachedSeparatingAxis); + break; + } + } + + if (checkSimplex) + { + m_simplexSolver->compute_points(pointOnA, pointOnB); + normalInB = pointOnA-pointOnB; + float lenSqr = m_cachedSeparatingAxis.length2(); + //valid normal + if (lenSqr > SIMD_EPSILON) + { + float rlen = 1.f / sqrtf(lenSqr ); + normalInB *= rlen; //normalize + SimdScalar s = sqrtf(squaredDistance); + ASSERT(s > SimdScalar(0.0)); + pointOnA -= m_cachedSeparatingAxis * (marginA / s); + pointOnB += m_cachedSeparatingAxis * (marginB / s); + distance = ((1.f/rlen) - margin); + isValid = true; + } + } + + if (checkPenetration && !isValid) + { + //penetration case + m_minkowskiA->SetMargin(marginA); + m_minkowskiB->SetMargin(marginB); + + //if there is no way to handle penetrations, bail out + if (m_penetrationDepthSolver) + { + // Penetration depth case. + isValid = m_penetrationDepthSolver->CalcPenDepth( + *m_simplexSolver, + m_minkowskiA,m_minkowskiB, + input.m_transformA,input.m_transformB, + m_cachedSeparatingAxis, pointOnA, pointOnB); + + if (isValid) + { + normalInB = pointOnB-pointOnA; + float lenSqr = normalInB.length2(); + if (lenSqr > SIMD_EPSILON) + { + normalInB /= sqrtf(lenSqr); + distance = -(pointOnA-pointOnB).length(); + } else + { + isValid = false; + } + } + } + } + } + + if (isValid) + { + output.AddContactPoint( + normalInB, + pointOnB, + distance); + } + + +} + + + + + diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/GjkPairDetector.h b/extern/bullet/Bullet/NarrowPhaseCollision/GjkPairDetector.h new file mode 100644 index 00000000000..ad9e41682bf --- /dev/null +++ b/extern/bullet/Bullet/NarrowPhaseCollision/GjkPairDetector.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ + + + +#ifndef GJK_PAIR_DETECTOR_H +#define GJK_PAIR_DETECTOR_H + +#include "DiscreteCollisionDetectorInterface.h" +#include "SimdPoint3.h" + +#include "CollisionMargin.h" + +class ConvexShape; +#include "SimplexSolverInterface.h" +class ConvexPenetrationDepthSolver; + +/// GjkPairDetector uses GJK to implement the DiscreteCollisionDetectorInterface +class GjkPairDetector : public DiscreteCollisionDetectorInterface +{ + + + SimdVector3 m_cachedSeparatingAxis; + ConvexPenetrationDepthSolver* m_penetrationDepthSolver; + SimplexSolverInterface* m_simplexSolver; + ConvexShape* m_minkowskiA; + ConvexShape* m_minkowskiB; + +public: + + GjkPairDetector(ConvexShape* objectA,ConvexShape* objectB,SimplexSolverInterface* simplexSolver,ConvexPenetrationDepthSolver* penetrationDepthSolver); + virtual ~GjkPairDetector() {}; + + virtual void GetClosestPoints(const ClosestPointInput& input,Result& output); + + void SetMinkowskiA(ConvexShape* minkA) + { + m_minkowskiA = minkA; + } + + void SetMinkowskiB(ConvexShape* minkB) + { + m_minkowskiB = minkB; + } + void SetCachedSeperatingAxis(const SimdVector3& seperatingAxis) + { + m_cachedSeparatingAxis = seperatingAxis; + } + +}; + +#endif //GJK_PAIR_DETECTOR_H diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/ManifoldPoint.h b/extern/bullet/Bullet/NarrowPhaseCollision/ManifoldPoint.h new file mode 100644 index 00000000000..5376d1f51aa --- /dev/null +++ b/extern/bullet/Bullet/NarrowPhaseCollision/ManifoldPoint.h @@ -0,0 +1,59 @@ +#ifndef MANIFOLD_CONTACT_POINT_H +#define MANIFOLD_CONTACT_POINT_H + +#include "SimdVector3.h" + +/// ManifoldContactPoint collects and maintains persistent contactpoints. +/// used to improve stability and performance of rigidbody dynamics response. +class ManifoldPoint + { + public: + ManifoldPoint() + { + } + + ManifoldPoint( const SimdVector3 &pointA, const SimdVector3 &pointB, + const SimdVector3 &normal, + SimdScalar distance ) : + m_localPointA( pointA ), + m_localPointB( pointB ), + m_normalWorldOnB( normal ), + m_distance1( distance ) + ,m_appliedImpulse(0.f) + {} + + SimdVector3 m_localPointA; + SimdVector3 m_localPointB; + SimdVector3 m_positionWorldOnB; + ///m_positionWorldOnA is redundant information, see GetPositionWorldOnA(), but for clarity + SimdVector3 m_positionWorldOnA; + SimdVector3 m_normalWorldOnB; + float m_distance1; + /// total applied impulse during most recent frame + float m_appliedImpulse; + + float GetDistance() const + { + return m_distance1; + } + + SimdVector3 GetPositionWorldOnA() { + return m_positionWorldOnA; +// return m_positionWorldOnB + m_normalWorldOnB * m_distance1; + } + + const SimdVector3& GetPositionWorldOnB() + { + return m_positionWorldOnB; + } + + void SetDistance(float dist) + { + m_distance1 = dist; + } + + + + }; + +#endif //MANIFOLD_CONTACT_POINT_H diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/MinkowskiPenetrationDepthSolver.cpp b/extern/bullet/Bullet/NarrowPhaseCollision/MinkowskiPenetrationDepthSolver.cpp new file mode 100644 index 00000000000..f8679addd18 --- /dev/null +++ b/extern/bullet/Bullet/NarrowPhaseCollision/MinkowskiPenetrationDepthSolver.cpp @@ -0,0 +1,132 @@ +#include "MinkowskiPenetrationDepthSolver.h" +#include "CollisionShapes/MinkowskiSumShape.h" +#include "NarrowPhaseCollision/SubSimplexConvexCast.h" +#include "NarrowPhaseCollision/VoronoiSimplexSolver.h" +#include "NarrowPhaseCollision/GjkPairDetector.h" + + +struct MyResult : public DiscreteCollisionDetectorInterface::Result +{ + + SimdVector3 m_normalOnBInWorld; + SimdVector3 m_pointInWorld; + float m_depth; + + void AddContactPoint(const SimdVector3& normalOnBInWorld,const SimdVector3& pointInWorld,float depth) + { + m_normalOnBInWorld = normalOnBInWorld; + m_pointInWorld = pointInWorld; + m_depth = depth; + } +}; + + + +bool MinkowskiPenetrationDepthSolver::CalcPenDepth(SimplexSolverInterface& simplexSolver, + ConvexShape* convexA,ConvexShape* convexB, + const SimdTransform& transA,const SimdTransform& transB, + SimdVector3& v, SimdPoint3& pa, SimdPoint3& pb) +{ + + + //just take fixed number of orientation, and sample the penetration depth in that direction + + int N = 3; + float minProj = 1e30f; + SimdVector3 minNorm; + SimdVector3 minVertex; + SimdVector3 minA,minB; + + for (int i=-N;i<N;i++) + { + for (int j = -N;j<N;j++) + { + for (int k=-N;k<N;k++) + { + if (i | j | k) + { + SimdVector3 norm(i,j,k); + norm.normalize(); + + { + SimdVector3 seperatingAxisInA = (-norm)* transA.getBasis(); + SimdVector3 seperatingAxisInB = norm* transB.getBasis(); + + SimdVector3 pInA = convexA->LocalGetSupportingVertex(seperatingAxisInA); + SimdVector3 qInB = convexB->LocalGetSupportingVertex(seperatingAxisInB); + SimdPoint3 pWorld = transA(pInA); + SimdPoint3 qWorld = transB(qInB); + + SimdVector3 w = qWorld - pWorld; + float delta = norm.dot(w); + //find smallest delta + + if (delta < minProj) + { + minProj = delta; + minNorm = norm; + minA = pWorld; + minB = qWorld; + } + } + + { + SimdVector3 seperatingAxisInA = (norm)* transA.getBasis(); + SimdVector3 seperatingAxisInB = -norm* transB.getBasis(); + + SimdVector3 pInA = convexA->LocalGetSupportingVertex(seperatingAxisInA); + SimdVector3 qInB = convexB->LocalGetSupportingVertex(seperatingAxisInB); + SimdPoint3 pWorld = transA(pInA); + SimdPoint3 qWorld = transB(qInB); + + SimdVector3 w = qWorld - pWorld; + float delta = (-norm).dot(w); + //find smallest delta + + if (delta < minProj) + { + minProj = delta ; + minNorm = -norm; + minA = pWorld; + minB = qWorld; + } + } + + + + } + } + } + } + + SimdTransform ident; + ident.setIdentity(); + + GjkPairDetector gjkdet(convexA,convexB,&simplexSolver,0); + + + v = minNorm * minProj; + + + GjkPairDetector::ClosestPointInput input; + + SimdVector3 newOrg = transA.getOrigin() + v + v; + + SimdTransform displacedTrans = transA; + displacedTrans.setOrigin(newOrg); + + input.m_transformA = displacedTrans; + input.m_transformB = transB; + input.m_maximumDistanceSquared = 1e30f; + + MyResult res; + gjkdet.GetClosestPoints(input,res); + + SimdVector3 halfV = v*0.5f; + + //approximate pa and pb + pa = res.m_pointInWorld - halfV; + pb = res.m_pointInWorld +halfV; + + return true; +} diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/MinkowskiPenetrationDepthSolver.h b/extern/bullet/Bullet/NarrowPhaseCollision/MinkowskiPenetrationDepthSolver.h new file mode 100644 index 00000000000..fb40223b1d6 --- /dev/null +++ b/extern/bullet/Bullet/NarrowPhaseCollision/MinkowskiPenetrationDepthSolver.h @@ -0,0 +1,20 @@ + +#ifndef MINKOWSKI_PENETRATION_DEPTH_SOLVER_H +#define MINKOWSKI_PENETRATION_DEPTH_SOLVER_H + +#include "ConvexPenetrationDepthSolver.h" + +///MinkowskiPenetrationDepthSolver implements bruteforce penetration depth estimation. +///Implementation is based on sampling the depth using support mapping, and using GJK step to get the witness points. +class MinkowskiPenetrationDepthSolver : public ConvexPenetrationDepthSolver +{ +public: + + virtual bool CalcPenDepth( SimplexSolverInterface& simplexSolver, + ConvexShape* convexA,ConvexShape* convexB, + const SimdTransform& transA,const SimdTransform& transB, + SimdVector3& v, SimdPoint3& pa, SimdPoint3& pb); + +}; + +#endif //MINKOWSKI_PENETRATION_DEPTH_SOLVER_H
\ No newline at end of file diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/PersistentManifold.cpp b/extern/bullet/Bullet/NarrowPhaseCollision/PersistentManifold.cpp new file mode 100644 index 00000000000..9085ffa0ef0 --- /dev/null +++ b/extern/bullet/Bullet/NarrowPhaseCollision/PersistentManifold.cpp @@ -0,0 +1,182 @@ +/* +* Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com +* +* Permission to use, copy, modify, distribute and sell this software +* and its documentation for any purpose is hereby granted without fee, +* provided that the above copyright notice appear in all copies. +* Erwin Coumans makes no representations about the suitability +* of this software for any purpose. +* It is provided "as is" without express or implied warranty. +*/ + + +#include "PersistentManifold.h" +#include "SimdTransform.h" +#include <assert.h> + + +PersistentManifold::PersistentManifold() +:m_body0(0), +m_body1(0), +m_cachedPoints (0), +m_index1(0) +{ +} + + +void PersistentManifold::ClearManifold() +{ + m_cachedPoints = 0; +} + + + + + +int PersistentManifold::SortCachedPoints(const ManifoldPoint& pt) +{ + + //calculate 4 possible cases areas, and take biggest area + + SimdScalar res0,res1,res2,res3; + + { + SimdVector3 a0 = pt.m_localPointA-m_pointCache[1].m_localPointA; + SimdVector3 b0 = m_pointCache[3].m_localPointA-m_pointCache[2].m_localPointA; + SimdVector3 cross = a0.cross(b0); + res0 = cross.length2(); + } + { + SimdVector3 a1 = pt.m_localPointA-m_pointCache[0].m_localPointA; + SimdVector3 b1 = m_pointCache[3].m_localPointA-m_pointCache[2].m_localPointA; + SimdVector3 cross = a1.cross(b1); + res1 = cross.length2(); + } + { + SimdVector3 a2 = pt.m_localPointA-m_pointCache[0].m_localPointA; + SimdVector3 b2 = m_pointCache[3].m_localPointA-m_pointCache[1].m_localPointA; + SimdVector3 cross = a2.cross(b2); + res2 = cross.length2(); + } + { + SimdVector3 a3 = pt.m_localPointA-m_pointCache[0].m_localPointA; + SimdVector3 b3 = m_pointCache[2].m_localPointA-m_pointCache[1].m_localPointA; + SimdVector3 cross = a3.cross(b3); + res3 = cross.length2(); + } + + SimdVector4 maxvec(res0,res1,res2,res3); + int biggestarea = maxvec.closestAxis4(); + + return biggestarea; + + +} + + + +int PersistentManifold::GetCacheEntry(const ManifoldPoint& newPoint) const +{ + SimdScalar shortestDist = GetManifoldMargin() * GetManifoldMargin(); + int size = GetNumContacts(); + int nearestPoint = -1; + for( int i = 0; i < size; i++ ) + { + const ManifoldPoint &mp = m_pointCache[i]; + + SimdVector3 diffA = mp.m_localPointA- newPoint.m_localPointA; + const SimdScalar distToManiPoint = diffA.dot(diffA); + if( distToManiPoint < shortestDist ) + { + shortestDist = distToManiPoint; + nearestPoint = i; + } + } + return nearestPoint; +} + +void PersistentManifold::AddManifoldPoint(const ManifoldPoint& newPoint) +{ + assert(ValidContactDistance(newPoint)); + + int insertIndex = GetNumContacts(); + if (insertIndex == MANIFOLD_CACHE_SIZE) + { + //sort cache so best points come first + insertIndex = SortCachedPoints(newPoint); + } else + { + m_cachedPoints++; + } + ReplaceContactPoint(newPoint,insertIndex); +} + + +void PersistentManifold::RefreshContactPoints(const SimdTransform& trA,const SimdTransform& trB) +{ + int i; + + /// first refresh worldspace positions and distance + for (i=GetNumContacts()-1;i>=0;i--) + { + ManifoldPoint &manifoldPoint = m_pointCache[i]; + manifoldPoint.m_positionWorldOnA = trA( manifoldPoint.m_localPointA ); + manifoldPoint.m_positionWorldOnB = trB( manifoldPoint.m_localPointB ); + manifoldPoint.m_distance1 = (manifoldPoint.m_positionWorldOnA - manifoldPoint.m_positionWorldOnB).dot(manifoldPoint.m_normalWorldOnB); + } + + /// then + SimdScalar distance2d; + SimdVector3 projectedDifference,projectedPoint; + for (i=GetNumContacts()-1;i>=0;i--) + { + + ManifoldPoint &manifoldPoint = m_pointCache[i]; + //contact becomes invalid when signed distance exceeds margin (projected on contactnormal direction) + if (!ValidContactDistance(manifoldPoint)) + { + RemoveContactPoint(i); + } else + { + //contact also becomes invalid when relative movement orthogonal to normal exceeds margin + projectedPoint = manifoldPoint.m_positionWorldOnA - manifoldPoint.m_normalWorldOnB * manifoldPoint.m_distance1; + projectedDifference = manifoldPoint.m_positionWorldOnB - projectedPoint; + distance2d = projectedDifference.dot(projectedDifference); + if (distance2d > GetManifoldMargin()*GetManifoldMargin() ) + { + RemoveContactPoint(i); + } + } + } +} + + +//todo: remove this treshold +float gPenetrationDistanceCheck = -0.05f; + +float PersistentManifold::GetCollisionImpulse() const +{ + float averageImpulse = 0.f; + if (GetNumContacts() > 0) + { + float totalImpulse = 0.f; + + //return the sum of the applied impulses on the box + for (int i=0;i<GetNumContacts();i++) + { + const ManifoldPoint& cp = GetContactPoint(i); + //avoid conflic noice + if ( cp.GetDistance() <gPenetrationDistanceCheck) + return 0.f; + + totalImpulse += cp.m_appliedImpulse; + + } + averageImpulse = totalImpulse / ((float)GetNumContacts()); + + } + return averageImpulse; + +} + + diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/PersistentManifold.h b/extern/bullet/Bullet/NarrowPhaseCollision/PersistentManifold.h new file mode 100644 index 00000000000..c1d0314069e --- /dev/null +++ b/extern/bullet/Bullet/NarrowPhaseCollision/PersistentManifold.h @@ -0,0 +1,116 @@ +/* +* Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com +* +* Permission to use, copy, modify, distribute and sell this software +* and its documentation for any purpose is hereby granted without fee, +* provided that the above copyright notice appear in all copies. +* Erwin Coumans makes no representations about the suitability +* of this software for any purpose. +* It is provided "as is" without express or implied warranty. +*/ + +#ifndef PERSISTENT_MANIFOLD_H +#define PERSISTENT_MANIFOLD_H + + +#include "SimdVector3.h" +#include "SimdTransform.h" +#include "ManifoldPoint.h" + +struct CollisionResult; + +#define MANIFOLD_CACHE_SIZE 4 + +///PersistentManifold maintains contact points, and reduces them to 4 +class PersistentManifold +{ + + ManifoldPoint m_pointCache[MANIFOLD_CACHE_SIZE]; + + /// this two body pointers can point to the physics rigidbody class. + /// void* will allow any rigidbody class + void* m_body0; + void* m_body1; + int m_cachedPoints; + + + /// sort cached points so most isolated points come first + int SortCachedPoints(const ManifoldPoint& pt); + +public: + + int m_index1; + + PersistentManifold(); + + PersistentManifold(void* body0,void* body1) + : m_body0(body0),m_body1(body1),m_cachedPoints(0) + { + } + + inline void* GetBody0() { return m_body0;} + inline void* GetBody1() { return m_body1;} + + inline const void* GetBody0() const { return m_body0;} + inline const void* GetBody1() const { return m_body1;} + + void SetBodies(void* body0,void* body1) + { + m_body0 = body0; + m_body1 = body1; + } + + + + inline int GetNumContacts() const { return m_cachedPoints;} + + inline const ManifoldPoint& GetContactPoint(int index) const + { + ASSERT(index < m_cachedPoints); + return m_pointCache[index]; + } + + inline ManifoldPoint& GetContactPoint(int index) + { + ASSERT(index < m_cachedPoints); + return m_pointCache[index]; + } + + /// todo: get this margin from the current physics / collision environment + inline float GetManifoldMargin() const + { + return 0.02f; + } + + int GetCacheEntry(const ManifoldPoint& newPoint) const; + + void AddManifoldPoint( const ManifoldPoint& newPoint); + + void RemoveContactPoint (int index) + { + m_pointCache[index] = m_pointCache[GetNumContacts() - 1]; + m_cachedPoints--; + } + void ReplaceContactPoint(const ManifoldPoint& newPoint,int insertIndex) + { + assert(ValidContactDistance(newPoint)); + m_pointCache[insertIndex] = newPoint; + } + + bool ValidContactDistance(const ManifoldPoint& pt) const + { + return pt.m_distance1 < GetManifoldMargin(); + } + /// calculated new worldspace coordinates and depth, and reject points that exceed the collision margin + void RefreshContactPoints( const SimdTransform& trA,const SimdTransform& trB); + + void ClearManifold(); + + float GetCollisionImpulse() const; + + +}; + + + +#endif //PERSISTENT_MANIFOLD_H diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/PointCollector.h b/extern/bullet/Bullet/NarrowPhaseCollision/PointCollector.h new file mode 100644 index 00000000000..f39fa090ae4 --- /dev/null +++ b/extern/bullet/Bullet/NarrowPhaseCollision/PointCollector.h @@ -0,0 +1,36 @@ +#ifndef POINT_COLLECTOR_H +#define POINT_COLLECTOR_H + +#include "DiscreteCollisionDetectorInterface.h" + + + +struct PointCollector : public DiscreteCollisionDetectorInterface::Result +{ + + + SimdVector3 m_normalOnBInWorld; + SimdVector3 m_pointInWorld; + SimdScalar m_distance;//negative means penetration + + bool m_hasResult; + + PointCollector () + : m_hasResult(false),m_distance(1e30f) + { + } + + virtual void AddContactPoint(const SimdVector3& normalOnBInWorld,const SimdVector3& pointInWorld,float depth) + { + if (depth< m_distance) + { + m_hasResult = true; + m_normalOnBInWorld = normalOnBInWorld; + m_pointInWorld = pointInWorld; + //negative means penetration + m_distance = depth; + } + } +}; + +#endif //POINT_COLLECTOR_H
\ No newline at end of file diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/RaycastCallback.cpp b/extern/bullet/Bullet/NarrowPhaseCollision/RaycastCallback.cpp new file mode 100644 index 00000000000..f27801d224b --- /dev/null +++ b/extern/bullet/Bullet/NarrowPhaseCollision/RaycastCallback.cpp @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ + +#include "RaycastCallback.h" + +RaycastCallback::RaycastCallback(const SimdVector3& from,const SimdVector3& to) + : + m_from(from), + m_to(to), + m_hitFraction(1.f), + m_hitProxy(0) +{ + +} + + + +void RaycastCallback::ProcessTriangle(SimdVector3* triangle) +{ + + int hits_found=0; + const SimdVector3 &vert0=triangle[0]; + const SimdVector3 &vert1=triangle[1]; + const SimdVector3 &vert2=triangle[2]; + + SimdVector3 v10; v10 = vert1 - vert0 ; + SimdVector3 v20; v20 = vert2 - vert0 ; + + SimdVector3 triangleNormal; triangleNormal = v10.cross( v20 ); + + const float dist = vert0.dot(triangleNormal); + float dist_a = triangleNormal.dot(m_from) ; + dist_a-= dist; + float dist_b = triangleNormal.dot(m_to); + dist_b -= dist; + + if ( dist_a * dist_b >= 0.0f) + { + return ; // same sign + } + + const float proj_length=dist_a-dist_b; + const float distance = (dist_a)/(proj_length); + // Now we have the intersection point on the plane, we'll see if it's inside the triangle + // Add an epsilon as a tolerance for the raycast, + // in case the ray hits exacly on the edge of the triangle. + // It must be scaled for the triangle size. + if(distance < m_hitFraction) + { + float edge_tolerance =triangleNormal.length2(); + edge_tolerance *= -0.0001f; + SimdVector3 point; point.setInterpolate3( m_from, m_to, distance); + { + SimdVector3 v0p; v0p = vert0 - point; + SimdVector3 v1p; v1p = vert1 - point; + SimdVector3 cp0; cp0 = v0p.cross( v1p ); + + if ( (float)(cp0.dot(triangleNormal)) >=edge_tolerance) + { + SimdVector3 v2p; v2p = vert2 - point; + SimdVector3 cp1; + cp1 = v1p.cross( v2p); + if ( (float)(cp1.dot(triangleNormal)) >=edge_tolerance) + { + SimdVector3 cp2; + cp2 = v2p.cross(v0p); + if ( (float)(cp2.dot(triangleNormal)) >=edge_tolerance) + { + m_hitFraction = distance; + if ( dist_a > 0 ) + { + m_hitNormalWorld = triangleNormal; + } + else + { + m_hitNormalWorld = -triangleNormal; + } + hits_found = 1; + } + } + } + } + } + //return hits_found; + +} diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/RaycastCallback.h b/extern/bullet/Bullet/NarrowPhaseCollision/RaycastCallback.h new file mode 100644 index 00000000000..5dbffde4244 --- /dev/null +++ b/extern/bullet/Bullet/NarrowPhaseCollision/RaycastCallback.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#ifndef RAYCAST_TRI_CALLBACK_H +#define RAYCAST_TRI_CALLBACK_H + +#include "CollisionShapes/TriangleCallback.h" +struct BroadphaseProxy; + + +class RaycastCallback: public TriangleCallback +{ +public: + + //input + SimdVector3 m_from; + SimdVector3 m_to; + //input / output + SimdScalar m_hitFraction; + BroadphaseProxy* m_hitProxy; + + //output + SimdVector3 m_hitNormalWorld; + + + + RaycastCallback(const SimdVector3& from,const SimdVector3& to); + + + virtual void ProcessTriangle(SimdVector3* triangle); +}; + +#endif //RAYCAST_TRI_CALLBACK_H
\ No newline at end of file diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/SimplexSolverInterface.h b/extern/bullet/Bullet/NarrowPhaseCollision/SimplexSolverInterface.h new file mode 100644 index 00000000000..9fe58385904 --- /dev/null +++ b/extern/bullet/Bullet/NarrowPhaseCollision/SimplexSolverInterface.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ + + +#ifndef SIMPLEX_SOLVER_INTERFACE_H +#define SIMPLEX_SOLVER_INTERFACE_H + +#include "SimdVector3.h" +#include "SimdPoint3.h" + +#define NO_VIRTUAL_INTERFACE +#ifdef NO_VIRTUAL_INTERFACE +#include "VoronoiSimplexSolver.h" +#define SimplexSolverInterface VoronoiSimplexSolver +#else +/// for simplices from 1 to 4 vertices +/// for example Johnson-algorithm or alternative approaches based on +/// voronoi regions or barycentric coordinates +class SimplexSolverInterface +{ + public: + virtual ~SimplexSolverInterface() {}; + + virtual void reset() = 0; + + virtual void addVertex(const SimdVector3& w, const SimdPoint3& p, const SimdPoint3& q) = 0; + + virtual bool closest(SimdVector3& v) = 0; + + virtual SimdScalar maxVertex() = 0; + + virtual bool fullSimplex() const = 0; + + virtual int getSimplex(SimdPoint3 *pBuf, SimdPoint3 *qBuf, SimdVector3 *yBuf) const = 0; + + virtual bool inSimplex(const SimdVector3& w) = 0; + + virtual void backup_closest(SimdVector3& v) = 0; + + virtual bool emptySimplex() const = 0; + + virtual void compute_points(SimdPoint3& p1, SimdPoint3& p2) = 0; + + virtual int numVertices() const =0; + + +}; +#endif +#endif //SIMPLEX_SOLVER_INTERFACE_H + diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/SubSimplexConvexCast.cpp b/extern/bullet/Bullet/NarrowPhaseCollision/SubSimplexConvexCast.cpp new file mode 100644 index 00000000000..80fea519887 --- /dev/null +++ b/extern/bullet/Bullet/NarrowPhaseCollision/SubSimplexConvexCast.cpp @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ + +#include "SubSimplexConvexCast.h" +#include "CollisionShapes/ConvexShape.h" +#include "CollisionShapes/MinkowskiSumShape.h" +#include "NarrowPhaseCollision/SimplexSolverInterface.h" + + +SubsimplexConvexCast::SubsimplexConvexCast (ConvexShape* convexA,ConvexShape* convexB,SimplexSolverInterface* simplexSolver) +:m_simplexSolver(simplexSolver), +m_convexA(convexA),m_convexB(convexB) +{ +} + + +#define MAX_ITERATIONS 1000 + +bool SubsimplexConvexCast::calcTimeOfImpact( + const SimdTransform& fromA, + const SimdTransform& toA, + const SimdTransform& fromB, + const SimdTransform& toB, + CastResult& result) +{ + + MinkowskiSumShape combi(m_convexA,m_convexB); + MinkowskiSumShape* convex = &combi; + + SimdTransform rayFromLocalA; + SimdTransform rayToLocalA; + + rayFromLocalA = fromA.inverse()* fromB; + rayToLocalA = toA.inverse()* toB; + + + m_simplexSolver->reset(); + + convex->SetTransformB(SimdTransform(rayFromLocalA.getBasis())); + + float radius = 0.01f; + + SimdScalar lambda = 0.f; + SimdVector3 s = rayFromLocalA.getOrigin(); + SimdVector3 r = rayToLocalA.getOrigin()-rayFromLocalA.getOrigin(); + SimdVector3 x = s; + SimdVector3 v; + SimdVector3 arbitraryPoint = convex->LocalGetSupportingVertex(r); + + v = x - arbitraryPoint; + + int maxIter = MAX_ITERATIONS; + + SimdVector3 n; + n.setValue(0.f,0.f,0.f); + bool hasResult = false; + SimdVector3 c; + + float lastLambda = lambda; + + + float dist2 = v.length2(); + float epsilon = 0.0001f; + + SimdVector3 w,p; + float VdotR; + + while ( (dist2 > epsilon) && maxIter--) + { + p = convex->LocalGetSupportingVertex( v); + w = x - p; + + float VdotW = v.dot(w); + + if ( VdotW > 0.f) + { + VdotR = v.dot(r); + + if (VdotR >= 0.f) + return false; + else + { + lambda = lambda - VdotW / VdotR; + x = s + lambda * r; + m_simplexSolver->reset(); + //check next line + w = x-p; + lastLambda = lambda; + n = v; + hasResult = true; + } + } + m_simplexSolver->addVertex( w, x , p); + if (m_simplexSolver->closest(v)) + { + dist2 = v.length2(); + hasResult = true; + //printf("V=%f , %f, %f\n",v[0],v[1],v[2]); + //printf("DIST2=%f\n",dist2); + //printf("numverts = %i\n",m_simplexSolver->numVertices()); + } else + { + dist2 = 0.f; + } + } + + int numiter = MAX_ITERATIONS - maxIter; +// printf("number of iterations: %d", numiter); + result.m_fraction = lambda; + result.m_normal = n; + + return true; +} + + + diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/SubSimplexConvexCast.h b/extern/bullet/Bullet/NarrowPhaseCollision/SubSimplexConvexCast.h new file mode 100644 index 00000000000..38c958304bc --- /dev/null +++ b/extern/bullet/Bullet/NarrowPhaseCollision/SubSimplexConvexCast.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ + +#ifndef SUBSIMPLEX_CONVEX_CAST_H +#define SUBSIMPLEX_CONVEX_CAST_H + +#include "ConvexCast.h" +#include "SimplexSolverInterface.h" +class ConvexShape; + +/// SubsimplexConvexCast implements Gino van den Bergens' paper +/// GJK based Ray Cast, optimized version +class SubsimplexConvexCast : public ConvexCast +{ + SimplexSolverInterface* m_simplexSolver; + ConvexShape* m_convexA; + ConvexShape* m_convexB; + +public: + + SubsimplexConvexCast (ConvexShape* shapeA,ConvexShape* shapeB,SimplexSolverInterface* simplexSolver); + + //virtual ~SubsimplexConvexCast(); + + virtual bool calcTimeOfImpact( + const SimdTransform& fromA, + const SimdTransform& toA, + const SimdTransform& fromB, + const SimdTransform& toB, + CastResult& result); + +}; + +#endif //SUBSIMPLEX_CONVEX_CAST_H diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/VoronoiSimplexSolver.cpp b/extern/bullet/Bullet/NarrowPhaseCollision/VoronoiSimplexSolver.cpp new file mode 100644 index 00000000000..fed9524c66d --- /dev/null +++ b/extern/bullet/Bullet/NarrowPhaseCollision/VoronoiSimplexSolver.cpp @@ -0,0 +1,582 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ + +#include "VoronoiSimplexSolver.h" +#include <assert.h> +#include <stdio.h> + +#define VERTA 0 +#define VERTB 1 +#define VERTC 2 +#define VERTD 3 + +#define CATCH_DEGENERATE_TETRAHEDRON 1 +void VoronoiSimplexSolver::removeVertex(int index) +{ + + assert(m_numVertices>0); + m_numVertices--; + m_simplexVectorW[index] = m_simplexVectorW[m_numVertices]; + m_simplexPointsP[index] = m_simplexPointsP[m_numVertices]; + m_simplexPointsQ[index] = m_simplexPointsQ[m_numVertices]; +} + +void VoronoiSimplexSolver::ReduceVertices (const UsageBitfield& usedVerts) +{ + if ((numVertices() >= 4) && (!usedVerts.usedVertexD)) + removeVertex(3); + + if ((numVertices() >= 3) && (!usedVerts.usedVertexC)) + removeVertex(2); + + if ((numVertices() >= 2) && (!usedVerts.usedVertexB)) + removeVertex(1); + + if ((numVertices() >= 1) && (!usedVerts.usedVertexA)) + removeVertex(0); + +} + + + + + +//clear the simplex, remove all the vertices +void VoronoiSimplexSolver::reset() +{ + m_cachedValidClosest = false; + m_numVertices = 0; + m_needsUpdate = true; + m_lastW = SimdVector3(1e30f,1e30f,1e30f); + m_cachedBC.Reset(); +} + + + + //add a vertex +void VoronoiSimplexSolver::addVertex(const SimdVector3& w, const SimdPoint3& p, const SimdPoint3& q) +{ + m_lastW = w; + m_needsUpdate = true; + + m_simplexVectorW[m_numVertices] = w; + m_simplexPointsP[m_numVertices] = p; + m_simplexPointsQ[m_numVertices] = q; + + m_numVertices++; +} + +bool VoronoiSimplexSolver::UpdateClosestVectorAndPoints() +{ + + if (m_needsUpdate) + { + m_cachedBC.Reset(); + + m_needsUpdate = false; + + switch (numVertices()) + { + case 0: + m_cachedValidClosest = false; + break; + case 1: + { + m_cachedP1 = m_simplexPointsP[0]; + m_cachedP2 = m_simplexPointsQ[0]; + m_cachedV = m_cachedP1-m_cachedP2; //== m_simplexVectorW[0] + m_cachedBC.Reset(); + m_cachedBC.SetBarycentricCoordinates(1.f,0.f,0.f,0.f); + m_cachedValidClosest = m_cachedBC.IsValid(); + break; + }; + case 2: + { + //closest point origin from line segment + const SimdVector3& from = m_simplexVectorW[0]; + const SimdVector3& to = m_simplexVectorW[1]; + SimdVector3 nearest; + + SimdVector3 p (0.f,0.f,0.f); + SimdVector3 diff = p - from; + SimdVector3 v = to - from; + float t = v.dot(diff); + + if (t > 0) { + float dotVV = v.dot(v); + if (t < dotVV) { + t /= dotVV; + diff -= t*v; + m_cachedBC.m_usedVertices.usedVertexA = true; + m_cachedBC.m_usedVertices.usedVertexB = true; + } else { + t = 1; + diff -= v; + //reduce to 1 point + m_cachedBC.m_usedVertices.usedVertexB = true; + } + } else + { + t = 0; + //reduce to 1 point + m_cachedBC.m_usedVertices.usedVertexA = true; + } + m_cachedBC.SetBarycentricCoordinates(1-t,t); + nearest = from + t*v; + + m_cachedP1 = m_simplexPointsP[0] + t * (m_simplexPointsP[1] - m_simplexPointsP[0]); + m_cachedP2 = m_simplexPointsQ[0] + t * (m_simplexPointsQ[1] - m_simplexPointsQ[0]); + m_cachedV = m_cachedP1 - m_cachedP2; + + ReduceVertices(m_cachedBC.m_usedVertices); + + m_cachedValidClosest = m_cachedBC.IsValid(); + break; + } + case 3: + { + //closest point origin from triangle + SimdVector3 p (0.f,0.f,0.f); + + const SimdVector3& a = m_simplexVectorW[0]; + const SimdVector3& b = m_simplexVectorW[1]; + const SimdVector3& c = m_simplexVectorW[2]; + + ClosestPtPointTriangle(p,a,b,c,m_cachedBC); + m_cachedP1 = m_simplexPointsP[0] * m_cachedBC.m_barycentricCoords[0] + + m_simplexPointsP[1] * m_cachedBC.m_barycentricCoords[1] + + m_simplexPointsP[2] * m_cachedBC.m_barycentricCoords[2] + + m_simplexPointsP[3] * m_cachedBC.m_barycentricCoords[3]; + + m_cachedP2 = m_simplexPointsQ[0] * m_cachedBC.m_barycentricCoords[0] + + m_simplexPointsQ[1] * m_cachedBC.m_barycentricCoords[1] + + m_simplexPointsQ[2] * m_cachedBC.m_barycentricCoords[2] + + m_simplexPointsQ[3] * m_cachedBC.m_barycentricCoords[3]; + + m_cachedV = m_cachedP1-m_cachedP2; + + ReduceVertices (m_cachedBC.m_usedVertices); + m_cachedValidClosest = m_cachedBC.IsValid(); + + break; + } + case 4: + { + + + SimdVector3 p (0.f,0.f,0.f); + + const SimdVector3& a = m_simplexVectorW[0]; + const SimdVector3& b = m_simplexVectorW[1]; + const SimdVector3& c = m_simplexVectorW[2]; + const SimdVector3& d = m_simplexVectorW[3]; + + bool hasSeperation = ClosestPtPointTetrahedron(p,a,b,c,d,m_cachedBC); + + if (hasSeperation) + { + + m_cachedP1 = m_simplexPointsP[0] * m_cachedBC.m_barycentricCoords[0] + + m_simplexPointsP[1] * m_cachedBC.m_barycentricCoords[1] + + m_simplexPointsP[2] * m_cachedBC.m_barycentricCoords[2] + + m_simplexPointsP[3] * m_cachedBC.m_barycentricCoords[3]; + + m_cachedP2 = m_simplexPointsQ[0] * m_cachedBC.m_barycentricCoords[0] + + m_simplexPointsQ[1] * m_cachedBC.m_barycentricCoords[1] + + m_simplexPointsQ[2] * m_cachedBC.m_barycentricCoords[2] + + m_simplexPointsQ[3] * m_cachedBC.m_barycentricCoords[3]; + + m_cachedV = m_cachedP1-m_cachedP2; + ReduceVertices (m_cachedBC.m_usedVertices); + } else + { +// printf("sub distance got penetration\n"); + + if (m_cachedBC.m_degenerate) + { + m_cachedValidClosest = false; + } else + { + m_cachedValidClosest = true; + //degenerate case == false, penetration = true + zero + m_cachedV.setValue(0.f,0.f,0.f); + } + break; + } + + m_cachedValidClosest = m_cachedBC.IsValid(); + + //closest point origin from tetrahedron + break; + } + default: + { + m_cachedValidClosest = false; + } + }; + } + + return m_cachedValidClosest; + +} + +//return/calculate the closest vertex +bool VoronoiSimplexSolver::closest(SimdVector3& v) +{ + bool succes = UpdateClosestVectorAndPoints(); + v = m_cachedV; + return succes; +} + + + +SimdScalar VoronoiSimplexSolver::maxVertex() +{ + int i, numverts = numVertices(); + SimdScalar maxV = 0.f; + for (i=0;i<numverts;i++) + { + SimdScalar curLen2 = m_simplexVectorW[i].length2(); + if (maxV < curLen2) + maxV = curLen2; + } + return maxV; +} + + + + //return the current simplex +int VoronoiSimplexSolver::getSimplex(SimdPoint3 *pBuf, SimdPoint3 *qBuf, SimdVector3 *yBuf) const +{ + int i; + for (i=0;i<numVertices();i++) + { + yBuf[i] = m_simplexVectorW[i]; + pBuf[i] = m_simplexPointsP[i]; + qBuf[i] = m_simplexPointsQ[i]; + } + return numVertices(); +} + + + + +bool VoronoiSimplexSolver::inSimplex(const SimdVector3& w) +{ + bool found = false; + int i, numverts = numVertices(); + SimdScalar maxV = 0.f; + + //w is in the current (reduced) simplex + for (i=0;i<numverts;i++) + { + if (m_simplexVectorW[i] == w) + found = true; + } + + //check in case lastW is already removed + if (w == m_lastW) + return true; + + return found; +} + +void VoronoiSimplexSolver::backup_closest(SimdVector3& v) +{ + v = m_cachedV; +} + + +bool VoronoiSimplexSolver::emptySimplex() const +{ + return (numVertices() == 0); + +} + +void VoronoiSimplexSolver::compute_points(SimdPoint3& p1, SimdPoint3& p2) +{ + UpdateClosestVectorAndPoints(); + p1 = m_cachedP1; + p2 = m_cachedP2; + +} + + + + +bool VoronoiSimplexSolver::ClosestPtPointTriangle(const SimdPoint3& p, const SimdPoint3& a, const SimdPoint3& b, const SimdPoint3& c,SubSimplexClosestResult& result) +{ + result.m_usedVertices.reset(); + + // Check if P in vertex region outside A + SimdVector3 ab = b - a; + SimdVector3 ac = c - a; + SimdVector3 ap = p - a; + float d1 = ab.dot(ap); + float d2 = ac.dot(ap); + if (d1 <= 0.0f && d2 <= 0.0f) + { + result.m_closestPointOnSimplex = a; + result.m_usedVertices.usedVertexA = true; + result.SetBarycentricCoordinates(1,0,0); + return true;// a; // barycentric coordinates (1,0,0) + } + + // Check if P in vertex region outside B + SimdVector3 bp = p - b; + float d3 = ab.dot(bp); + float d4 = ac.dot(bp); + if (d3 >= 0.0f && d4 <= d3) + { + result.m_closestPointOnSimplex = b; + result.m_usedVertices.usedVertexB = true; + result.SetBarycentricCoordinates(0,1,0); + + return true; // b; // barycentric coordinates (0,1,0) + } + // Check if P in edge region of AB, if so return projection of P onto AB + float vc = d1*d4 - d3*d2; + if (vc <= 0.0f && d1 >= 0.0f && d3 <= 0.0f) { + float v = d1 / (d1 - d3); + result.m_closestPointOnSimplex = a + v * ab; + result.m_usedVertices.usedVertexA = true; + result.m_usedVertices.usedVertexB = true; + result.SetBarycentricCoordinates(1-v,v,0); + return true; + //return a + v * ab; // barycentric coordinates (1-v,v,0) + } + + // Check if P in vertex region outside C + SimdVector3 cp = p - c; + float d5 = ab.dot(cp); + float d6 = ac.dot(cp); + if (d6 >= 0.0f && d5 <= d6) + { + result.m_closestPointOnSimplex = c; + result.m_usedVertices.usedVertexC = true; + result.SetBarycentricCoordinates(0,0,1); + return true;//c; // barycentric coordinates (0,0,1) + } + + // Check if P in edge region of AC, if so return projection of P onto AC + float vb = d5*d2 - d1*d6; + if (vb <= 0.0f && d2 >= 0.0f && d6 <= 0.0f) { + float w = d2 / (d2 - d6); + result.m_closestPointOnSimplex = a + w * ac; + result.m_usedVertices.usedVertexA = true; + result.m_usedVertices.usedVertexC = true; + result.SetBarycentricCoordinates(1-w,0,w); + return true; + //return a + w * ac; // barycentric coordinates (1-w,0,w) + } + + // Check if P in edge region of BC, if so return projection of P onto BC + float va = d3*d6 - d5*d4; + if (va <= 0.0f && (d4 - d3) >= 0.0f && (d5 - d6) >= 0.0f) { + float w = (d4 - d3) / ((d4 - d3) + (d5 - d6)); + + result.m_closestPointOnSimplex = b + w * (c - b); + result.m_usedVertices.usedVertexB = true; + result.m_usedVertices.usedVertexC = true; + result.SetBarycentricCoordinates(0,1-w,w); + return true; + // return b + w * (c - b); // barycentric coordinates (0,1-w,w) + } + + // P inside face region. Compute Q through its barycentric coordinates (u,v,w) + float denom = 1.0f / (va + vb + vc); + float v = vb * denom; + float w = vc * denom; + + result.m_closestPointOnSimplex = a + ab * v + ac * w; + result.m_usedVertices.usedVertexA = true; + result.m_usedVertices.usedVertexB = true; + result.m_usedVertices.usedVertexC = true; + result.SetBarycentricCoordinates(1-v-w,v,w); + + return true; +// return a + ab * v + ac * w; // = u*a + v*b + w*c, u = va * denom = 1.0f - v - w + +} + + + + + +/// Test if point p and d lie on opposite sides of plane through abc +int VoronoiSimplexSolver::PointOutsideOfPlane(const SimdPoint3& p, const SimdPoint3& a, const SimdPoint3& b, const SimdPoint3& c, const SimdPoint3& d) +{ + SimdVector3 normal = (b-a).cross(c-a); + + float signp = (p - a).dot(normal); // [AP AB AC] + float signd = (d - a).dot( normal); // [AD AB AC] + +#ifdef CATCH_DEGENERATE_TETRAHEDRON + if (signd * signd < (1e-4f * 1e-4f)) + { +// printf("affine dependent/degenerate\n");// + return -1; + } +#endif + // Points on opposite sides if expression signs are opposite + return signp * signd < 0.f; +} + + +bool VoronoiSimplexSolver::ClosestPtPointTetrahedron(const SimdPoint3& p, const SimdPoint3& a, const SimdPoint3& b, const SimdPoint3& c, const SimdPoint3& d, SubSimplexClosestResult& finalResult) +{ + SubSimplexClosestResult tempResult; + + // Start out assuming point inside all halfspaces, so closest to itself + finalResult.m_closestPointOnSimplex = p; + finalResult.m_usedVertices.reset(); + finalResult.m_usedVertices.usedVertexA = true; + finalResult.m_usedVertices.usedVertexB = true; + finalResult.m_usedVertices.usedVertexC = true; + finalResult.m_usedVertices.usedVertexD = true; + + int pointOutsideABC = PointOutsideOfPlane(p, a, b, c, d); + int pointOutsideACD = PointOutsideOfPlane(p, a, c, d, b); + int pointOutsideADB = PointOutsideOfPlane(p, a, d, b, c); + int pointOutsideBDC = PointOutsideOfPlane(p, b, d, c, a); + + if (pointOutsideABC < 0 || pointOutsideACD < 0 || pointOutsideADB < 0 || pointOutsideBDC < 0) + { + finalResult.m_degenerate = true; + return false; + } + + if (!pointOutsideABC && !pointOutsideACD && !pointOutsideADB && !pointOutsideBDC) + { + return false; + } + + + float bestSqDist = FLT_MAX; + // If point outside face abc then compute closest point on abc + if (pointOutsideABC) + { + ClosestPtPointTriangle(p, a, b, c,tempResult); + SimdPoint3 q = tempResult.m_closestPointOnSimplex; + + float sqDist = (q - p).dot( q - p); + // Update best closest point if (squared) distance is less than current best + if (sqDist < bestSqDist) { + bestSqDist = sqDist; + finalResult.m_closestPointOnSimplex = q; + //convert result bitmask! + finalResult.m_usedVertices.reset(); + finalResult.m_usedVertices.usedVertexA = tempResult.m_usedVertices.usedVertexA; + finalResult.m_usedVertices.usedVertexB = tempResult.m_usedVertices.usedVertexB; + finalResult.m_usedVertices.usedVertexC = tempResult.m_usedVertices.usedVertexC; + finalResult.SetBarycentricCoordinates( + tempResult.m_barycentricCoords[VERTA], + tempResult.m_barycentricCoords[VERTB], + tempResult.m_barycentricCoords[VERTC], + 0 + ); + + } + } + + + // Repeat test for face acd + if (pointOutsideACD) + { + ClosestPtPointTriangle(p, a, c, d,tempResult); + SimdPoint3 q = tempResult.m_closestPointOnSimplex; + //convert result bitmask! + + float sqDist = (q - p).dot( q - p); + if (sqDist < bestSqDist) + { + bestSqDist = sqDist; + finalResult.m_closestPointOnSimplex = q; + finalResult.m_usedVertices.reset(); + finalResult.m_usedVertices.usedVertexA = tempResult.m_usedVertices.usedVertexA; + finalResult.m_usedVertices.usedVertexC = tempResult.m_usedVertices.usedVertexB; + finalResult.m_usedVertices.usedVertexD = tempResult.m_usedVertices.usedVertexC; + finalResult.SetBarycentricCoordinates( + tempResult.m_barycentricCoords[VERTA], + 0, + tempResult.m_barycentricCoords[VERTB], + tempResult.m_barycentricCoords[VERTC] + ); + + } + } + // Repeat test for face adb + + + if (pointOutsideADB) + { + ClosestPtPointTriangle(p, a, d, b,tempResult); + SimdPoint3 q = tempResult.m_closestPointOnSimplex; + //convert result bitmask! + + float sqDist = (q - p).dot( q - p); + if (sqDist < bestSqDist) + { + bestSqDist = sqDist; + finalResult.m_closestPointOnSimplex = q; + finalResult.m_usedVertices.reset(); + finalResult.m_usedVertices.usedVertexA = tempResult.m_usedVertices.usedVertexA; + finalResult.m_usedVertices.usedVertexD = tempResult.m_usedVertices.usedVertexB; + finalResult.m_usedVertices.usedVertexB = tempResult.m_usedVertices.usedVertexC; + finalResult.SetBarycentricCoordinates( + tempResult.m_barycentricCoords[VERTA], + tempResult.m_barycentricCoords[VERTC], + 0, + tempResult.m_barycentricCoords[VERTB] + ); + + } + } + // Repeat test for face bdc + + + if (pointOutsideBDC) + { + ClosestPtPointTriangle(p, b, d, c,tempResult); + SimdPoint3 q = tempResult.m_closestPointOnSimplex; + //convert result bitmask! + float sqDist = (q - p).dot( q - p); + if (sqDist < bestSqDist) + { + bestSqDist = sqDist; + finalResult.m_closestPointOnSimplex = q; + finalResult.m_usedVertices.reset(); + finalResult.m_usedVertices.usedVertexB = tempResult.m_usedVertices.usedVertexA; + finalResult.m_usedVertices.usedVertexD = tempResult.m_usedVertices.usedVertexB; + finalResult.m_usedVertices.usedVertexC = tempResult.m_usedVertices.usedVertexC; + + finalResult.SetBarycentricCoordinates( + 0, + tempResult.m_barycentricCoords[VERTA], + tempResult.m_barycentricCoords[VERTC], + tempResult.m_barycentricCoords[VERTB] + ); + + } + } + + //help! we ended up full ! + + if (finalResult.m_usedVertices.usedVertexA && + finalResult.m_usedVertices.usedVertexB && + finalResult.m_usedVertices.usedVertexC && + finalResult.m_usedVertices.usedVertexD) + { + return true; + } + + return true; +}
\ No newline at end of file diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/VoronoiSimplexSolver.h b/extern/bullet/Bullet/NarrowPhaseCollision/VoronoiSimplexSolver.h new file mode 100644 index 00000000000..3328b1061e5 --- /dev/null +++ b/extern/bullet/Bullet/NarrowPhaseCollision/VoronoiSimplexSolver.h @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ + + +#ifndef VoronoiSimplexSolver_H +#define VoronoiSimplexSolver_H + +#include "SimplexSolverInterface.h" + + + +#define VORONOI_SIMPLEX_MAX_VERTS 5 + +struct UsageBitfield{ + UsageBitfield() + { + reset(); + } + + void reset() + { + usedVertexA = false; + usedVertexB = false; + usedVertexC = false; + usedVertexD = false; + } + unsigned short usedVertexA : 1; + unsigned short usedVertexB : 1; + unsigned short usedVertexC : 1; + unsigned short usedVertexD : 1; + unsigned short unused1 : 1; + unsigned short unused2 : 1; + unsigned short unused3 : 1; + unsigned short unused4 : 1; +}; + + +struct SubSimplexClosestResult +{ + SimdPoint3 m_closestPointOnSimplex; + //MASK for m_usedVertices + //stores the simplex vertex-usage, using the MASK, + // if m_usedVertices & MASK then the related vertex is used + UsageBitfield m_usedVertices; + float m_barycentricCoords[4]; + bool m_degenerate; + + void Reset() + { + m_degenerate = false; + SetBarycentricCoordinates(); + m_usedVertices.reset(); + } + bool IsValid() + { + bool valid = (m_barycentricCoords[0] >= 0.f) && + (m_barycentricCoords[1] >= 0.f) && + (m_barycentricCoords[2] >= 0.f) && + (m_barycentricCoords[3] >= 0.f); + + + return valid; + } + void SetBarycentricCoordinates(float a=0.f,float b=0.f,float c=0.f,float d=0.f) + { + m_barycentricCoords[0] = a; + m_barycentricCoords[1] = b; + m_barycentricCoords[2] = c; + m_barycentricCoords[3] = d; + } + +}; + +/// VoronoiSimplexSolver is an implementation of the closest point distance algorithm from a 1-4 points simplex to the origin. +/// Can be used with GJK, as an alternative to Johnson distance algorithm. +#ifdef NO_VIRTUAL_INTERFACE +class VoronoiSimplexSolver +#else +class VoronoiSimplexSolver : public SimplexSolverInterface +#endif +{ +public: + + int m_numVertices; + + SimdVector3 m_simplexVectorW[VORONOI_SIMPLEX_MAX_VERTS]; + SimdPoint3 m_simplexPointsP[VORONOI_SIMPLEX_MAX_VERTS]; + SimdPoint3 m_simplexPointsQ[VORONOI_SIMPLEX_MAX_VERTS]; + + + + SimdPoint3 m_cachedP1; + SimdPoint3 m_cachedP2; + SimdVector3 m_cachedV; + SimdVector3 m_lastW; + bool m_cachedValidClosest; + + SubSimplexClosestResult m_cachedBC; + + bool m_needsUpdate; + + void removeVertex(int index); + void ReduceVertices (const UsageBitfield& usedVerts); + bool UpdateClosestVectorAndPoints(); + + bool ClosestPtPointTetrahedron(const SimdPoint3& p, const SimdPoint3& a, const SimdPoint3& b, const SimdPoint3& c, const SimdPoint3& d, SubSimplexClosestResult& finalResult); + int PointOutsideOfPlane(const SimdPoint3& p, const SimdPoint3& a, const SimdPoint3& b, const SimdPoint3& c, const SimdPoint3& d); + bool ClosestPtPointTriangle(const SimdPoint3& p, const SimdPoint3& a, const SimdPoint3& b, const SimdPoint3& c,SubSimplexClosestResult& result); + +public: + + void reset(); + + void addVertex(const SimdVector3& w, const SimdPoint3& p, const SimdPoint3& q); + + + bool closest(SimdVector3& v); + + SimdScalar maxVertex(); + + bool fullSimplex() const + { + return (m_numVertices == 4); + } + + int getSimplex(SimdPoint3 *pBuf, SimdPoint3 *qBuf, SimdVector3 *yBuf) const; + + bool inSimplex(const SimdVector3& w); + + void backup_closest(SimdVector3& v) ; + + bool emptySimplex() const ; + + void compute_points(SimdPoint3& p1, SimdPoint3& p2) ; + + int numVertices() const + { + return m_numVertices; + } + + +}; + +#endif //VoronoiSimplexSolver diff --git a/extern/bullet/BulletDynamics/BulletDynamics.dsp b/extern/bullet/BulletDynamics/BulletDynamics.dsp new file mode 100644 index 00000000000..1b9f9cc1985 --- /dev/null +++ b/extern/bullet/BulletDynamics/BulletDynamics.dsp @@ -0,0 +1,236 @@ +# Microsoft Developer Studio Project File - Name="BulletDynamics" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Static Library" 0x0104 + +CFG=BulletDynamics - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "BulletDynamics.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "BulletDynamics.mak" CFG="BulletDynamics - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "BulletDynamics - Win32 Release" (based on "Win32 (x86) Static Library") +!MESSAGE "BulletDynamics - Win32 Debug" (based on "Win32 (x86) Static Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "BulletDynamics - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "BulletDynamics___Win32_Release" +# PROP BASE Intermediate_Dir "BulletDynamics___Win32_Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "BulletDynamics___Win32_Release" +# PROP Intermediate_Dir "BulletDynamics___Win32_Release" +# PROP Target_Dir "" +LINK32=link.exe -lib +MTL=midl.exe +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../LinearMath" /I "../Bullet" /I "../BulletDynamics" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ELSEIF "$(CFG)" == "BulletDynamics - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "BulletDynamics___Win32_Debug" +# PROP BASE Intermediate_Dir "BulletDynamics___Win32_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "BulletDynamics___Win32_Debug" +# PROP Intermediate_Dir "BulletDynamics___Win32_Debug" +# PROP Target_Dir "" +LINK32=link.exe -lib +MTL=midl.exe +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../LinearMath" /I "../Bullet" /I "../BulletDynamics" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ENDIF + +# Begin Target + +# Name "BulletDynamics - Win32 Release" +# Name "BulletDynamics - Win32 Debug" +# Begin Group "ConstraintSolver" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\ConstraintSolver\ConstraintSolver.h +# End Source File +# Begin Source File + +SOURCE=.\ConstraintSolver\ContactConstraint.cpp +# End Source File +# Begin Source File + +SOURCE=.\ConstraintSolver\ContactConstraint.h +# End Source File +# Begin Source File + +SOURCE=.\ConstraintSolver\ContactSolverInfo.h +# End Source File +# Begin Source File + +SOURCE=.\ConstraintSolver\JacobianEntry.h +# End Source File +# Begin Source File + +SOURCE=.\ConstraintSolver\OdeConstraintSolver.cpp +# End Source File +# Begin Source File + +SOURCE=.\ConstraintSolver\OdeConstraintSolver.h +# End Source File +# Begin Source File + +SOURCE=.\ConstraintSolver\Point2PointConstraint.cpp +# End Source File +# Begin Source File + +SOURCE=.\ConstraintSolver\Point2PointConstraint.h +# End Source File +# Begin Source File + +SOURCE=.\ConstraintSolver\SimpleConstraintSolver.cpp +# End Source File +# Begin Source File + +SOURCE=.\ConstraintSolver\SimpleConstraintSolver.h +# End Source File +# Begin Source File + +SOURCE=.\ConstraintSolver\Solve2LinearConstraint.cpp +# End Source File +# Begin Source File + +SOURCE=.\ConstraintSolver\Solve2LinearConstraint.h +# End Source File +# Begin Source File + +SOURCE=.\ConstraintSolver\SorLcp.cpp +# End Source File +# Begin Source File + +SOURCE=.\ConstraintSolver\SorLcp.h +# End Source File +# End Group +# Begin Group "CollisionDispatch" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\CollisionDispatch\ConvexConcaveCollisionAlgorithm.cpp +# End Source File +# Begin Source File + +SOURCE=.\CollisionDispatch\ConvexConcaveCollisionAlgorithm.h +# End Source File +# Begin Source File + +SOURCE=.\CollisionDispatch\ConvexConvexAlgorithm.cpp +# End Source File +# Begin Source File + +SOURCE=.\CollisionDispatch\ConvexConvexAlgorithm.h +# End Source File +# Begin Source File + +SOURCE=.\CollisionDispatch\EmptyCollisionAlgorithm.cpp +# End Source File +# Begin Source File + +SOURCE=.\CollisionDispatch\EmptyCollisionAlgorithm.h +# End Source File +# Begin Source File + +SOURCE=.\CollisionDispatch\ManifoldResult.cpp +# End Source File +# Begin Source File + +SOURCE=.\CollisionDispatch\ManifoldResult.h +# End Source File +# Begin Source File + +SOURCE=.\CollisionDispatch\ToiContactDispatcher.cpp +# End Source File +# Begin Source File + +SOURCE=.\CollisionDispatch\ToiContactDispatcher.h +# End Source File +# Begin Source File + +SOURCE=.\CollisionDispatch\UnionFind.cpp +# End Source File +# Begin Source File + +SOURCE=.\CollisionDispatch\UnionFind.h +# End Source File +# End Group +# Begin Group "Dynamics" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\Dynamics\BU_Joint.cpp +# End Source File +# Begin Source File + +SOURCE=.\Dynamics\BU_Joint.h +# End Source File +# Begin Source File + +SOURCE=.\Dynamics\ContactJoint.cpp +# End Source File +# Begin Source File + +SOURCE=.\Dynamics\ContactJoint.h +# End Source File +# Begin Source File + +SOURCE=.\Dynamics\MassProps.h +# End Source File +# Begin Source File + +SOURCE=.\Dynamics\RigidBody.cpp +# End Source File +# Begin Source File + +SOURCE=.\Dynamics\RigidBody.h +# End Source File +# End Group +# End Target +# End Project diff --git a/extern/bullet/BulletDynamics/BulletDynamics_vc7.vcproj b/extern/bullet/BulletDynamics/BulletDynamics_vc7.vcproj new file mode 100644 index 00000000000..e89c175720f --- /dev/null +++ b/extern/bullet/BulletDynamics/BulletDynamics_vc7.vcproj @@ -0,0 +1,231 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="7.10" + Name="Bullet3Dynamics" + ProjectGUID="{3427A9EF-FF84-4B3E-9AE5-C37CF44D7DA4}" + Keyword="Win32Proj"> + <Platforms> + <Platform + Name="Win32"/> + </Platforms> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="4" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="..\LinearMath;..\Bullet;..\BulletDynamics" + PreprocessorDefinitions="WIN32;_DEBUG;_LIB" + MinimalRebuild="TRUE" + BasicRuntimeChecks="3" + RuntimeLibrary="5" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="TRUE" + DebugInformationFormat="4"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/BulletDynamics.lib"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="4" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="..\LinearMath;..\Bullet;..\BulletDynamics" + PreprocessorDefinitions="WIN32;NDEBUG;_LIB" + RuntimeLibrary="4" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="TRUE" + DebugInformationFormat="3"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLibrarianTool" + OutputFile="..\..\..\..\build\msvc_7\libs\extern\BulletDynamics.lib"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool" + CommandLine="ECHO Copying header files +IF NOT EXIST ..\..\..\..\build\msvc_7\extern\bullet\include MKDIR ..\..\..\..\build\msvc_7\extern\bullet\include +IF NOT EXIST ..\..\..\..\build\msvc_7\extern\bullet\include\CollisionDispatch MKDIR ..\..\..\..\build\msvc_7\extern\bullet\include\CollisionDispatch +IF NOT EXIST ..\..\..\..\build\msvc_7\extern\bullet\include\ConstraintSolver MKDIR ..\..\..\..\build\msvc_7\extern\bullet\include\ConstraintSolver +IF NOT EXIST ..\..\..\..\build\msvc_7\extern\bullet\include\Dynamics MKDIR ..\..\..\..\build\msvc_7\extern\bullet\include\Dynamics + +XCOPY /Y ..\LinearMath\*.h ..\..\..\..\build\msvc_7\extern\bullet\include +XCOPY /Y ..\BulletDynamics\CollisionDispatch\*.h ..\..\..\..\build\msvc_7\extern\bullet\include\CollisionDispatch +XCOPY /Y ..\BulletDynamics\ConstraintSolver\*.h ..\..\..\..\build\msvc_7\extern\bullet\include\ConstraintSolver +XCOPY /Y ..\BulletDynamics\Dynamics\*.h ..\..\..\..\build\msvc_7\extern\bullet\include\Dynamics + +ECHO Done +"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="ConstraintSolver" + Filter=""> + <File + RelativePath=".\ConstraintSolver\ConstraintSolver.h"> + </File> + <File + RelativePath=".\ConstraintSolver\ContactConstraint.cpp"> + </File> + <File + RelativePath=".\ConstraintSolver\ContactConstraint.h"> + </File> + <File + RelativePath=".\ConstraintSolver\ContactSolverInfo.h"> + </File> + <File + RelativePath=".\ConstraintSolver\JacobianEntry.h"> + </File> + <File + RelativePath=".\ConstraintSolver\OdeConstraintSolver.cpp"> + </File> + <File + RelativePath=".\ConstraintSolver\OdeConstraintSolver.h"> + </File> + <File + RelativePath=".\ConstraintSolver\Point2PointConstraint.cpp"> + </File> + <File + RelativePath=".\ConstraintSolver\Point2PointConstraint.h"> + </File> + <File + RelativePath=".\ConstraintSolver\SimpleConstraintSolver.cpp"> + </File> + <File + RelativePath=".\ConstraintSolver\SimpleConstraintSolver.h"> + </File> + <File + RelativePath=".\ConstraintSolver\Solve2LinearConstraint.cpp"> + </File> + <File + RelativePath=".\ConstraintSolver\Solve2LinearConstraint.h"> + </File> + <File + RelativePath=".\ConstraintSolver\SorLcp.cpp"> + </File> + <File + RelativePath=".\ConstraintSolver\SorLcp.h"> + </File> + </Filter> + <Filter + Name="CollisionDispatch" + Filter=""> + <File + RelativePath=".\CollisionDispatch\ConvexConcaveCollisionAlgorithm.cpp"> + </File> + <File + RelativePath=".\CollisionDispatch\ConvexConcaveCollisionAlgorithm.h"> + </File> + <File + RelativePath=".\CollisionDispatch\ConvexConvexAlgorithm.cpp"> + </File> + <File + RelativePath=".\CollisionDispatch\ConvexConvexAlgorithm.h"> + </File> + <File + RelativePath=".\CollisionDispatch\EmptyCollisionAlgorithm.cpp"> + </File> + <File + RelativePath=".\CollisionDispatch\EmptyCollisionAlgorithm.h"> + </File> + <File + RelativePath=".\CollisionDispatch\ManifoldResult.cpp"> + </File> + <File + RelativePath=".\CollisionDispatch\ManifoldResult.h"> + </File> + <File + RelativePath=".\CollisionDispatch\ToiContactDispatcher.cpp"> + </File> + <File + RelativePath=".\CollisionDispatch\ToiContactDispatcher.h"> + </File> + <File + RelativePath=".\CollisionDispatch\UnionFind.cpp"> + </File> + <File + RelativePath=".\CollisionDispatch\UnionFind.h"> + </File> + </Filter> + <Filter + Name="Dynamics" + Filter=""> + <File + RelativePath=".\Dynamics\BU_Joint.cpp"> + </File> + <File + RelativePath=".\Dynamics\BU_Joint.h"> + </File> + <File + RelativePath=".\Dynamics\ContactJoint.cpp"> + </File> + <File + RelativePath=".\Dynamics\ContactJoint.h"> + </File> + <File + RelativePath=".\Dynamics\MassProps.h"> + </File> + <File + RelativePath=".\Dynamics\RigidBody.cpp"> + </File> + <File + RelativePath=".\Dynamics\RigidBody.h"> + </File> + </Filter> + <File + RelativePath=".\ReadMe.txt"> + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/extern/bullet/BulletDynamics/BulletDynamics_vc8.vcproj b/extern/bullet/BulletDynamics/BulletDynamics_vc8.vcproj new file mode 100644 index 00000000000..2efa75b0f55 --- /dev/null +++ b/extern/bullet/BulletDynamics/BulletDynamics_vc8.vcproj @@ -0,0 +1,301 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="8.00" + Name="Bullet3Dynamics" + ProjectGUID="{3427A9EF-FF84-4B3E-9AE5-C37CF44D7DA4}" + Keyword="Win32Proj" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="4" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="..\LinearMath;..\Bullet;..\BulletDynamics" + PreprocessorDefinitions="WIN32;_DEBUG;_LIB" + MinimalRebuild="TRUE" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="TRUE" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/BulletDynamics.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="4" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="..\LinearMath;..\Bullet;..\BulletDynamics" + PreprocessorDefinitions="WIN32;NDEBUG;_LIB" + RuntimeLibrary="0" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="TRUE" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/BulletDynamics.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="ConstraintSolver" + > + <File + RelativePath=".\ConstraintSolver\ConstraintSolver.h" + > + </File> + <File + RelativePath=".\ConstraintSolver\ContactConstraint.cpp" + > + </File> + <File + RelativePath=".\ConstraintSolver\ContactConstraint.h" + > + </File> + <File + RelativePath=".\ConstraintSolver\ContactSolverInfo.h" + > + </File> + <File + RelativePath=".\ConstraintSolver\JacobianEntry.h" + > + </File> + <File + RelativePath=".\ConstraintSolver\OdeConstraintSolver.cpp" + > + </File> + <File + RelativePath=".\ConstraintSolver\OdeConstraintSolver.h" + > + </File> + <File + RelativePath=".\ConstraintSolver\Point2PointConstraint.cpp" + > + </File> + <File + RelativePath=".\ConstraintSolver\Point2PointConstraint.h" + > + </File> + <File + RelativePath=".\ConstraintSolver\SimpleConstraintSolver.cpp" + > + </File> + <File + RelativePath=".\ConstraintSolver\SimpleConstraintSolver.h" + > + </File> + <File + RelativePath=".\ConstraintSolver\Solve2LinearConstraint.cpp" + > + </File> + <File + RelativePath=".\ConstraintSolver\Solve2LinearConstraint.h" + > + </File> + <File + RelativePath=".\ConstraintSolver\SorLcp.cpp" + > + </File> + <File + RelativePath=".\ConstraintSolver\SorLcp.h" + > + </File> + </Filter> + <Filter + Name="CollisionDispatch" + > + <File + RelativePath=".\CollisionDispatch\ConvexConcaveCollisionAlgorithm.cpp" + > + </File> + <File + RelativePath=".\CollisionDispatch\ConvexConcaveCollisionAlgorithm.h" + > + </File> + <File + RelativePath=".\CollisionDispatch\ConvexConvexAlgorithm.cpp" + > + </File> + <File + RelativePath=".\CollisionDispatch\ConvexConvexAlgorithm.h" + > + </File> + <File + RelativePath=".\CollisionDispatch\EmptyCollisionAlgorithm.cpp" + > + </File> + <File + RelativePath=".\CollisionDispatch\EmptyCollisionAlgorithm.h" + > + </File> + <File + RelativePath=".\CollisionDispatch\ManifoldResult.cpp" + > + </File> + <File + RelativePath=".\CollisionDispatch\ManifoldResult.h" + > + </File> + <File + RelativePath=".\CollisionDispatch\ToiContactDispatcher.cpp" + > + </File> + <File + RelativePath=".\CollisionDispatch\ToiContactDispatcher.h" + > + </File> + <File + RelativePath=".\CollisionDispatch\UnionFind.cpp" + > + </File> + <File + RelativePath=".\CollisionDispatch\UnionFind.h" + > + </File> + </Filter> + <Filter + Name="Dynamics" + > + <File + RelativePath=".\Dynamics\BU_Joint.cpp" + > + </File> + <File + RelativePath=".\Dynamics\BU_Joint.h" + > + </File> + <File + RelativePath=".\Dynamics\ContactJoint.cpp" + > + </File> + <File + RelativePath=".\Dynamics\ContactJoint.h" + > + </File> + <File + RelativePath=".\Dynamics\MassProps.h" + > + </File> + <File + RelativePath=".\Dynamics\RigidBody.cpp" + > + </File> + <File + RelativePath=".\Dynamics\RigidBody.h" + > + </File> + </Filter> + <File + RelativePath=".\ReadMe.txt" + > + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/extern/bullet/BulletDynamics/CollisionDispatch/ConvexConcaveCollisionAlgorithm.cpp b/extern/bullet/BulletDynamics/CollisionDispatch/ConvexConcaveCollisionAlgorithm.cpp new file mode 100644 index 00000000000..5dac60a9e06 --- /dev/null +++ b/extern/bullet/BulletDynamics/CollisionDispatch/ConvexConcaveCollisionAlgorithm.cpp @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#include "ConvexConcaveCollisionAlgorithm.h" +#include "Dynamics/RigidBody.h" +#include "CollisionShapes/MultiSphereShape.h" +#include "ConstraintSolver/ContactConstraint.h" +#include "CollisionShapes/BoxShape.h" +#include "ConvexConvexAlgorithm.h" +#include "BroadphaseCollision/BroadphaseProxy.h" +#include "CollisionShapes/TriangleShape.h" +#include "ConstraintSolver/ConstraintSolver.h" +#include "ConstraintSolver/ContactSolverInfo.h" +#include "CollisionDispatch/ManifoldResult.h" +#include "NarrowphaseCollision/RaycastCallback.h" +#include "CollisionShapes/TriangleMeshShape.h" + + +ConvexConcaveCollisionAlgorithm::ConvexConcaveCollisionAlgorithm( const CollisionAlgorithmConstructionInfo& ci,BroadphaseProxy* proxy0,BroadphaseProxy* proxy1) +: CollisionAlgorithm(ci),m_convex(*proxy0),m_concave(*proxy1), +m_boxTriangleCallback(ci.m_dispatcher,proxy0,proxy1) +{ +} + +ConvexConcaveCollisionAlgorithm::~ConvexConcaveCollisionAlgorithm() +{ +} + + + +BoxTriangleCallback::BoxTriangleCallback(Dispatcher* dispatcher,BroadphaseProxy* proxy0,BroadphaseProxy* proxy1): + m_boxProxy(proxy0),m_triangleProxy(*proxy1),m_dispatcher(dispatcher), + m_timeStep(0.f), + m_stepCount(-1) +{ + + m_triangleProxy.SetClientObjectType(TRIANGLE_SHAPE_PROXYTYPE); + + // + // create the manifold from the dispatcher 'manifold pool' + // + m_manifoldPtr = m_dispatcher->GetNewManifold(proxy0->m_clientObject,proxy1->m_clientObject); + + ClearCache(); +} + +BoxTriangleCallback::~BoxTriangleCallback() +{ + ClearCache(); + m_dispatcher->ReleaseManifold( m_manifoldPtr ); + +} + + +void BoxTriangleCallback::ClearCache() +{ + + m_manifoldPtr->ClearManifold(); +}; + + + +void BoxTriangleCallback::ProcessTriangle(SimdVector3* triangle) +{ + + + RigidBody* triangleBody = (RigidBody*)m_triangleProxy.m_clientObject; + + //aabb filter is already applied! + + CollisionAlgorithmConstructionInfo ci; + ci.m_dispatcher = m_dispatcher; + + ConvexShape* tmp = static_cast<ConvexShape*>(triangleBody->GetCollisionShape()); + + if (m_boxProxy->IsConvexShape()) + { + TriangleShape tm(triangle[0],triangle[1],triangle[2]); + RigidBody* triangleBody = (RigidBody* )m_triangleProxy.m_clientObject; + + triangleBody->SetCollisionShape(&tm); + ConvexConvexAlgorithm cvxcvxalgo(m_manifoldPtr,ci,m_boxProxy,&m_triangleProxy); + triangleBody->SetCollisionShape(&tm); + cvxcvxalgo.ProcessCollision(m_boxProxy,&m_triangleProxy,m_timeStep,m_stepCount,m_useContinuous); + } + + triangleBody->SetCollisionShape(tmp); + +} + + + +void BoxTriangleCallback::SetTimeStepAndCounters(float timeStep,int stepCount,bool useContinuous) +{ + m_timeStep = timeStep; + m_stepCount = stepCount; + m_useContinuous = useContinuous; + + //recalc aabbs + RigidBody* boxBody = (RigidBody* )m_boxProxy->m_clientObject; + RigidBody* triBody = (RigidBody* )m_triangleProxy.m_clientObject; + + SimdTransform boxInTriangleSpace; + boxInTriangleSpace = triBody->getCenterOfMassTransform().inverse() * boxBody->getCenterOfMassTransform(); + + boxBody->GetCollisionShape()->GetAabb(boxInTriangleSpace,m_aabbMin,m_aabbMax); + + float extraMargin = CONVEX_DISTANCE_MARGIN+0.1f; + + SimdVector3 extra(extraMargin,extraMargin,extraMargin); + + m_aabbMax += extra; + m_aabbMin -= extra; + +} + +void ConvexConcaveCollisionAlgorithm::ClearCache() +{ + m_boxTriangleCallback.ClearCache(); + +} + +void ConvexConcaveCollisionAlgorithm::ProcessCollision (BroadphaseProxy* ,BroadphaseProxy* ,float timeStep,int stepCount,bool useContinuous) +{ + + + if (m_concave.GetClientObjectType() == TRIANGLE_MESH_SHAPE_PROXYTYPE) + { + + RigidBody* convexbody = (RigidBody* )m_convex.m_clientObject; + RigidBody* concavebody = (RigidBody* )m_concave.m_clientObject; + + TriangleMeshShape* triangleMesh = (TriangleMeshShape*) concavebody->GetCollisionShape(); + + if (m_convex.IsConvexShape()) + { + + m_boxTriangleCallback.SetTimeStepAndCounters(timeStep,stepCount, useContinuous); +#ifdef USE_BOX_TRIANGLE + m_boxTriangleCallback.m_manifoldPtr->ClearManifold(); +#endif + m_boxTriangleCallback.m_manifoldPtr->SetBodies(convexbody,concavebody); + + triangleMesh->ProcessAllTriangles( &m_boxTriangleCallback,m_boxTriangleCallback.GetAabbMin(),m_boxTriangleCallback.GetAabbMax()); + + + } + + } + +} + + +float ConvexConcaveCollisionAlgorithm::CalculateTimeOfImpact(BroadphaseProxy* ,BroadphaseProxy* ,float timeStep,int stepCount) +{ + + //quick approximation using raycast, todo: use proper continuou collision detection + RigidBody* convexbody = (RigidBody* )m_convex.m_clientObject; + const SimdVector3& from = convexbody->getCenterOfMassPosition(); + + SimdVector3 radVec(0,0,0); + + float minradius = 0.05f; + float lenSqr = convexbody->getLinearVelocity().length2(); + if (lenSqr > SIMD_EPSILON) + { + radVec = convexbody->getLinearVelocity(); + radVec.normalize(); + radVec *= minradius; + } + + SimdVector3 to = from + radVec + convexbody->getLinearVelocity() * timeStep*1.01f; + //only do if the motion exceeds the 'radius' + + + RaycastCallback raycastCallback(from,to); + + raycastCallback.m_hitFraction = convexbody->m_hitFraction; + + SimdVector3 aabbMin (-1e30f,-1e30f,-1e30f); + SimdVector3 aabbMax (SIMD_INFINITY,SIMD_INFINITY,SIMD_INFINITY); + + if (m_concave.GetClientObjectType() == TRIANGLE_MESH_SHAPE_PROXYTYPE) + { + + RigidBody* concavebody = (RigidBody* )m_concave.m_clientObject; + + TriangleMeshShape* triangleMesh = (TriangleMeshShape*) concavebody->GetCollisionShape(); + + if (triangleMesh) + { + triangleMesh->ProcessAllTriangles(&raycastCallback,aabbMin,aabbMax); + } + } + + + if (raycastCallback.m_hitFraction < convexbody->m_hitFraction) + { + convexbody->m_hitFraction = raycastCallback.m_hitFraction; + return raycastCallback.m_hitFraction; + } + + return 1.f; + +} diff --git a/extern/bullet/BulletDynamics/CollisionDispatch/ConvexConcaveCollisionAlgorithm.h b/extern/bullet/BulletDynamics/CollisionDispatch/ConvexConcaveCollisionAlgorithm.h new file mode 100644 index 00000000000..35248c841c6 --- /dev/null +++ b/extern/bullet/BulletDynamics/CollisionDispatch/ConvexConcaveCollisionAlgorithm.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#ifndef CONVEX_CONCAVE_COLLISION_ALGORITHM_H +#define CONVEX_CONCAVE_COLLISION_ALGORITHM_H + +#include "BroadphaseCollision/CollisionAlgorithm.h" +#include "BroadphaseCollision/CollisionDispatcher.h" +#include "BroadphaseCollision/BroadphaseInterface.h" +#include "CollisionShapes/TriangleCallback.h" +#include "NarrowPhaseCollision/PersistentManifold.h" +class Dispatcher; +#include "BroadphaseCollision/BroadphaseProxy.h" + + + +class BoxTriangleCallback : public TriangleCallback +{ + BroadphaseProxy* m_boxProxy; + BroadphaseProxy m_triangleProxy; + + SimdVector3 m_aabbMin; + SimdVector3 m_aabbMax ; + + Dispatcher* m_dispatcher; + float m_timeStep; + int m_stepCount; + bool m_useContinuous; + +public: + + PersistentManifold* m_manifoldPtr; + + BoxTriangleCallback(Dispatcher* dispatcher,BroadphaseProxy* proxy0,BroadphaseProxy* proxy1); + + void SetTimeStepAndCounters(float timeStep,int stepCount, bool useContinuous); + + virtual ~BoxTriangleCallback(); + + virtual void ProcessTriangle(SimdVector3* triangle); + + void ClearCache(); + + inline const SimdVector3& GetAabbMin() const + { + return m_aabbMin; + } + inline const SimdVector3& GetAabbMax() const + { + return m_aabbMax; + } + +}; + + + + +/// ConvexConcaveCollisionAlgorithm supports collision between convex shapes and (concave) trianges meshes. +class ConvexConcaveCollisionAlgorithm : public CollisionAlgorithm +{ + + BroadphaseProxy m_convex; + + BroadphaseProxy m_concave; + + BoxTriangleCallback m_boxTriangleCallback; + + +public: + + ConvexConcaveCollisionAlgorithm( const CollisionAlgorithmConstructionInfo& ci,BroadphaseProxy* proxy0,BroadphaseProxy* proxy1); + + virtual ~ConvexConcaveCollisionAlgorithm(); + + virtual void ProcessCollision (BroadphaseProxy* proxy0,BroadphaseProxy* proxy1,float timeStep,int stepCount, bool useContinuous); + + float CalculateTimeOfImpact(BroadphaseProxy* proxy0,BroadphaseProxy* proxy1,float timeStep,int stepCount); + + void ClearCache(); + +}; + +#endif //CONVEX_CONCAVE_COLLISION_ALGORITHM_H diff --git a/extern/bullet/BulletDynamics/CollisionDispatch/ConvexConvexAlgorithm.cpp b/extern/bullet/BulletDynamics/CollisionDispatch/ConvexConvexAlgorithm.cpp new file mode 100644 index 00000000000..42387ba271e --- /dev/null +++ b/extern/bullet/BulletDynamics/CollisionDispatch/ConvexConvexAlgorithm.cpp @@ -0,0 +1,250 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#include "ConvexConvexAlgorithm.h" + +#include <stdio.h> +#include "NarrowPhaseCollision/DiscreteCollisionDetectorInterface.h" +#include "BroadphaseCollision/BroadphaseInterface.h" +#include "Dynamics/RigidBody.h" +#include "CollisionShapes/ConvexShape.h" +#include "NarrowPhaseCollision/GjkPairDetector.h" +#include "BroadphaseCollision/BroadphaseProxy.h" +#include "BroadphaseCollision/CollisionDispatcher.h" +#include "CollisionShapes/BoxShape.h" +#include "CollisionDispatch/ManifoldResult.h" + +#include "NarrowPhaseCollision/ConvexPenetrationDepthSolver.h" +#include "NarrowPhaseCollision/ContinuousConvexCollision.h" +#include "NarrowPhaseCollision/SubsimplexConvexCast.h" +#include "NarrowPhaseCollision/GjkConvexCast.h" + + + +#include "CollisionShapes/MinkowskiSumShape.h" +#include "NarrowPhaseCollision/VoronoiSimplexSolver.h" +#include "CollisionShapes/SphereShape.h" + + +#ifdef WIN32 +void DrawRasterizerLine(const float* from,const float* to,int color); +#endif + + + + +//#define PROCESS_SINGLE_CONTACT +#ifdef WIN32 +bool gForceBoxBox = false;//false;//true; + +#else +bool gForceBoxBox = false;//false;//true; +#endif +bool gBoxBoxUseGjk = true;//true;//false; +bool gDisableConvexCollision = false; + + + + +ConvexConvexAlgorithm::ConvexConvexAlgorithm(PersistentManifold* mf,const CollisionAlgorithmConstructionInfo& ci,BroadphaseProxy* proxy0,BroadphaseProxy* proxy1) +: CollisionAlgorithm(ci), +m_gjkPairDetector(0,0,&m_simplexSolver,&m_penetrationDepthSolver), +m_box0(*proxy0), +m_box1(*proxy1), +m_collisionImpulse(0.f), +m_ownManifold (false), +m_manifoldPtr(mf), +m_lowLevelOfDetail(false) + +{ + + + RigidBody* body0 = (RigidBody*)m_box0.m_clientObject; + RigidBody* body1 = (RigidBody*)m_box1.m_clientObject; + + if ((body0->getInvMass() != 0.f) || + (body1->getInvMass() != 0.f)) + { + if (!m_manifoldPtr) + { + m_manifoldPtr = m_dispatcher->GetNewManifold(proxy0->m_clientObject,proxy1->m_clientObject); + m_ownManifold = true; + } + } + +} + + + +ConvexConvexAlgorithm::~ConvexConvexAlgorithm() +{ + if (m_ownManifold) + { + if (m_manifoldPtr) + m_dispatcher->ReleaseManifold(m_manifoldPtr); + } +} + +void ConvexConvexAlgorithm ::SetLowLevelOfDetail(bool useLowLevel) +{ + m_lowLevelOfDetail = useLowLevel; +} + +float ConvexConvexAlgorithm::GetCollisionImpulse() const +{ + if (m_manifoldPtr) + return m_manifoldPtr->GetCollisionImpulse(); + + return 0.f; +} + + +class FlippedContactResult : public DiscreteCollisionDetectorInterface::Result +{ + DiscreteCollisionDetectorInterface::Result* m_org; + +public: + + FlippedContactResult(DiscreteCollisionDetectorInterface::Result* org) + : m_org(org) + { + + } + + virtual void AddContactPoint(const SimdVector3& normalOnBInWorld,const SimdVector3& pointInWorld,float depth) + { + SimdVector3 flippedNormal = -normalOnBInWorld; + + m_org->AddContactPoint(flippedNormal,pointInWorld,depth); + } + +}; + +bool extra = false; + +float gFriction = 0.5f; +// +// box-box collision algorithm, for simplicity also applies resolution-impulse +// +void ConvexConvexAlgorithm ::ProcessCollision (BroadphaseProxy* ,BroadphaseProxy* ,float timeStep,int stepCount, bool useContinuous) +{ + +// printf("ConvexConvexAlgorithm::ProcessCollision\n"); +m_collisionImpulse = 0.f; + + RigidBody* body0 = (RigidBody*)m_box0.m_clientObject; + RigidBody* body1 = (RigidBody*)m_box1.m_clientObject; + + if (!m_manifoldPtr) + return; + + if ((body0->getInvMass() == 0.f) && + (body1->getInvMass() == 0.f)) + { + return; + } + + ManifoldResult output(body0,body1,m_manifoldPtr); + + ConvexShape* min0 = static_cast<ConvexShape*>(body0->GetCollisionShape()); + ConvexShape* min1 = static_cast<ConvexShape*>(body1->GetCollisionShape()); + GjkPairDetector::ClosestPointInput input; + + SphereShape sphere(0.2f); + MinkowskiSumShape expanded0(min0,&sphere); + MinkowskiSumShape expanded1(min1,&sphere); + + if (useContinuous) + { + m_gjkPairDetector.SetMinkowskiA(&expanded0); + m_gjkPairDetector.SetMinkowskiB(&expanded1); + input.m_maximumDistanceSquared = expanded0.GetMargin()+expanded1.GetMargin(); + input.m_maximumDistanceSquared *= input.m_maximumDistanceSquared; + } + else + { + m_gjkPairDetector.SetMinkowskiA(min0); + m_gjkPairDetector.SetMinkowskiB(min1); + input.m_maximumDistanceSquared = min0->GetMargin() + min1->GetMargin() + m_manifoldPtr->GetManifoldMargin(); + input.m_maximumDistanceSquared*= input.m_maximumDistanceSquared; + } + + input.m_transformA = body0->getCenterOfMassTransform(); + input.m_transformB = body1->getCenterOfMassTransform(); + + m_gjkPairDetector.GetClosestPoints(input,output); + +} +bool disableCcd = false; +float ConvexConvexAlgorithm::CalculateTimeOfImpact(BroadphaseProxy* proxy0,BroadphaseProxy* proxy1,float timeStep,int stepCount) +{ + + m_collisionImpulse = 0.f; + + RigidBody* body0 = (RigidBody*)m_box0.m_clientObject; + RigidBody* body1 = (RigidBody*)m_box1.m_clientObject; + + if (!m_manifoldPtr) + return 1.f; + + if ((body0->getInvMass() == 0.f) && + (body1->getInvMass() == 0.f)) + { + return 1.f; + } + + + ConvexShape* min0 = static_cast<ConvexShape*>(body0->GetCollisionShape()); + ConvexShape* min1 = static_cast<ConvexShape*>(body1->GetCollisionShape()); + + GjkPairDetector::ClosestPointInput input; + input.m_transformA = body0->getCenterOfMassTransform(); + input.m_transformB = body1->getCenterOfMassTransform(); + SimdTransform predictA,predictB; + + body0->predictIntegratedTransform(timeStep,predictA); + body1->predictIntegratedTransform(timeStep,predictB); + + + ConvexCast::CastResult result; + + + VoronoiSimplexSolver voronoiSimplex; + //SubsimplexConvexCast ccd(&voronoiSimplex); + //GjkConvexCast ccd(&voronoiSimplex); + + ContinuousConvexCollision ccd(min0,min1,&voronoiSimplex,&m_penetrationDepthSolver); + + if (disableCcd) + return 1.f; + + if (ccd.calcTimeOfImpact(input.m_transformA,predictA,input.m_transformB,predictB,result)) + { + + //store result.m_fraction in both bodies + int i; + i=0; + +// if (result.m_fraction< 0.1f) +// result.m_fraction = 0.1f; + + if (body0->m_hitFraction > result.m_fraction) + body0->m_hitFraction = result.m_fraction; + + if (body1->m_hitFraction > result.m_fraction) + body1->m_hitFraction = result.m_fraction; + + return result.m_fraction; + } + + return 1.f; + + +} diff --git a/extern/bullet/BulletDynamics/CollisionDispatch/ConvexConvexAlgorithm.h b/extern/bullet/BulletDynamics/CollisionDispatch/ConvexConvexAlgorithm.h new file mode 100644 index 00000000000..d77d6465d6b --- /dev/null +++ b/extern/bullet/BulletDynamics/CollisionDispatch/ConvexConvexAlgorithm.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#ifndef CONVEX_CONVEX_ALGORITHM_H +#define CONVEX_CONVEX_ALGORITHM_H + +#include "BroadphaseCollision/CollisionAlgorithm.h" +#include "NarrowPhaseCollision/GjkPairDetector.h" +#include "NarrowPhaseCollision/PersistentManifold.h" +#include "BroadphaseCollision/BroadphaseProxy.h" +#include "NarrowPhaseCollision/VoronoiSimplexSolver.h" +#include "NarrowPhaseCollision/MinkowskiPenetrationDepthSolver.h" + + +class ConvexPenetrationDepthSolver; + +///ConvexConvexAlgorithm collision algorithm implements time of impact, convex closest points and penetration depth calculations. +class ConvexConvexAlgorithm : public CollisionAlgorithm +{ + //hardcoded penetration and simplex solver, its easy to make this flexible later + MinkowskiPenetrationDepthSolver m_penetrationDepthSolver; + VoronoiSimplexSolver m_simplexSolver; + GjkPairDetector m_gjkPairDetector; +public: + BroadphaseProxy m_box0; + BroadphaseProxy m_box1; + float m_collisionImpulse; + bool m_ownManifold; + PersistentManifold* m_manifoldPtr; + bool m_lowLevelOfDetail; + + + +public: + + ConvexConvexAlgorithm(PersistentManifold* mf,const CollisionAlgorithmConstructionInfo& ci,BroadphaseProxy* proxy0,BroadphaseProxy* proxy1); + + virtual ~ConvexConvexAlgorithm(); + + virtual void ProcessCollision (BroadphaseProxy* proxy0,BroadphaseProxy* proxy1,float timeStep,int stepCount, bool useContinuous); + + virtual float CalculateTimeOfImpact(BroadphaseProxy* proxy0,BroadphaseProxy* proxy1,float timeStep,int stepCount); + + void SetLowLevelOfDetail(bool useLowLevel); + + float GetCollisionImpulse() const; + + const PersistentManifold* GetManifold() + { + return m_manifoldPtr; + } + +}; + +#endif //CONVEX_CONVEX_ALGORITHM_H diff --git a/extern/bullet/BulletDynamics/CollisionDispatch/EmptyCollisionAlgorithm.cpp b/extern/bullet/BulletDynamics/CollisionDispatch/EmptyCollisionAlgorithm.cpp new file mode 100644 index 00000000000..4fd6000c7aa --- /dev/null +++ b/extern/bullet/BulletDynamics/CollisionDispatch/EmptyCollisionAlgorithm.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#include "EmptyCollisionAlgorithm.h" + + + +EmptyAlgorithm::EmptyAlgorithm(const CollisionAlgorithmConstructionInfo& ci) + : CollisionAlgorithm(ci) +{ +} + +void EmptyAlgorithm::ProcessCollision (BroadphaseProxy* proxy0,BroadphaseProxy* proxy1,float timeStep, int stepCount,bool useContinuous) +{ + +} + +float EmptyAlgorithm::CalculateTimeOfImpact(BroadphaseProxy* proxy0,BroadphaseProxy* proxy1,float timeStep,int stepCount) +{ + return 1.f; +} + + diff --git a/extern/bullet/BulletDynamics/CollisionDispatch/EmptyCollisionAlgorithm.h b/extern/bullet/BulletDynamics/CollisionDispatch/EmptyCollisionAlgorithm.h new file mode 100644 index 00000000000..85a64df5b40 --- /dev/null +++ b/extern/bullet/BulletDynamics/CollisionDispatch/EmptyCollisionAlgorithm.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#ifndef EMPTY_ALGORITH +#define EMPTY_ALGORITH +#include "BroadphaseCollision/CollisionAlgorithm.h" + +#define ATTRIBUTE_ALIGNED(a) + +///EmptyAlgorithm is a stub for unsupported collision pairs. +///The dispatcher can dispatch a persistent EmptyAlgorithm to avoid a search every frame. +class EmptyAlgorithm : public CollisionAlgorithm +{ + +public: + + EmptyAlgorithm(const CollisionAlgorithmConstructionInfo& ci); + + virtual void ProcessCollision (BroadphaseProxy* proxy0,BroadphaseProxy* proxy1,float timeStep, int stepCount, bool useContinuous); + + virtual float CalculateTimeOfImpact(BroadphaseProxy* proxy0,BroadphaseProxy* proxy1,float timeStep,int stepCount); + + + + +} ATTRIBUTE_ALIGNED(16); + +#endif //EMPTY_ALGORITH diff --git a/extern/bullet/BulletDynamics/CollisionDispatch/ManifoldResult.cpp b/extern/bullet/BulletDynamics/CollisionDispatch/ManifoldResult.cpp new file mode 100644 index 00000000000..2fd712221ac --- /dev/null +++ b/extern/bullet/BulletDynamics/CollisionDispatch/ManifoldResult.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ + +#include "ManifoldResult.h" +#include "NarrowPhaseCollision/PersistentManifold.h" +#include "Dynamics/RigidBody.h" + +ManifoldResult::ManifoldResult(RigidBody* body0,RigidBody* body1,PersistentManifold* manifoldPtr) + :m_manifoldPtr(manifoldPtr), + m_body0(body0), + m_body1(body1) + { + } + +void ManifoldResult::AddContactPoint(const SimdVector3& normalOnBInWorld,const SimdVector3& pointInWorld,float depth) +{ + if (depth > m_manifoldPtr->GetManifoldMargin()) + return; + + SimdTransform transAInv = m_body0->getCenterOfMassTransform().inverse(); + SimdTransform transBInv= m_body1->getCenterOfMassTransform().inverse(); + SimdVector3 pointA = pointInWorld + normalOnBInWorld * depth; + SimdVector3 localA = transAInv(pointA ); + SimdVector3 localB = transBInv(pointInWorld); + ManifoldPoint newPt(localA,localB,normalOnBInWorld,depth); + + + + int insertIndex = m_manifoldPtr->GetCacheEntry(newPt); + if (insertIndex >= 0) + { + m_manifoldPtr->ReplaceContactPoint(newPt,insertIndex); + } else + { + m_manifoldPtr->AddManifoldPoint(newPt); + } +} + diff --git a/extern/bullet/BulletDynamics/CollisionDispatch/ManifoldResult.h b/extern/bullet/BulletDynamics/CollisionDispatch/ManifoldResult.h new file mode 100644 index 00000000000..a06497e315c --- /dev/null +++ b/extern/bullet/BulletDynamics/CollisionDispatch/ManifoldResult.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ + +#ifndef MANIFOLD_RESULT_H +#define MANIFOLD_RESULT_H + +#include "NarrowPhaseCollision/DiscreteCollisionDetectorInterface.h" +class RigidBody; +class PersistentManifold; + + +class ManifoldResult : public DiscreteCollisionDetectorInterface::Result +{ + PersistentManifold* m_manifoldPtr; + RigidBody* m_body0; + RigidBody* m_body1; + +public: + + ManifoldResult(RigidBody* body0,RigidBody* body1,PersistentManifold* manifoldPtr); + + + virtual void AddContactPoint(const SimdVector3& normalOnBInWorld,const SimdVector3& pointInWorld,float depth); + +}; + +#endif //MANIFOLD_RESULT_H diff --git a/extern/bullet/BulletDynamics/CollisionDispatch/ToiContactDispatcher.cpp b/extern/bullet/BulletDynamics/CollisionDispatch/ToiContactDispatcher.cpp new file mode 100644 index 00000000000..fab0d7e384d --- /dev/null +++ b/extern/bullet/BulletDynamics/CollisionDispatch/ToiContactDispatcher.cpp @@ -0,0 +1,221 @@ +#include "ToiContactDispatcher.h" +#include "ConstraintSolver/ConstraintSolver.h" +#include "Dynamics/RigidBody.h" +#include "BroadphaseCollision/CollisionAlgorithm.h" +#include "ConstraintSolver/ContactSolverInfo.h" +#include "CollisionDispatch/ConvexConvexAlgorithm.h" +#include "CollisionDispatch/EmptyCollisionAlgorithm.h" +#include "CollisionDispatch/ConvexConcaveCollisionAlgorithm.h" + +#define MAX_RIGIDBODIES 128 + + +void ToiContactDispatcher::FindUnions() +{ + if (m_useIslands) + { + for (int i=0;i<GetNumManifolds();i++) + { + const PersistentManifold* manifold = this->GetManifoldByIndexInternal(i); + //static objects (invmass 0.f) don't merge ! + if ((((RigidBody*)manifold->GetBody0()) && (((RigidBody*)manifold->GetBody0())->mergesSimulationIslands())) && + (((RigidBody*)manifold->GetBody1()) && (((RigidBody*)manifold->GetBody1())->mergesSimulationIslands()))) + { + + m_unionFind.unite(((RigidBody*)manifold->GetBody0())->m_islandTag1, + ((RigidBody*)manifold->GetBody1())->m_islandTag1); + } + + + } + } + +} + + + +ToiContactDispatcher::ToiContactDispatcher (ConstraintSolver* solver): + m_useIslands(true), + m_unionFind(MAX_RIGIDBODIES), + m_solver(solver), + m_count(0) + +{ + int i; + + for (i=0;i<MAX_BROADPHASE_COLLISION_TYPES;i++) + { + for (int j=0;j<MAX_BROADPHASE_COLLISION_TYPES;j++) + { + m_doubleDispatch[i][j] = 0; + } + } + + +}; + +PersistentManifold* ToiContactDispatcher::GetNewManifold(void* b0,void* b1) +{ + + RigidBody* body0 = (RigidBody*)b0; + RigidBody* body1 = (RigidBody*)b1; + + PersistentManifold* manifold = new PersistentManifold (body0,body1); + m_manifoldsPtr.push_back(manifold); + + return manifold; +} +#include <algorithm> + +void ToiContactDispatcher::ReleaseManifold(PersistentManifold* manifold) +{ + manifold->ClearManifold(); + + std::vector<PersistentManifold*>::iterator i = + std::find(m_manifoldsPtr.begin(), m_manifoldsPtr.end(), manifold); + if (!(i == m_manifoldsPtr.end())) + { + std::swap(*i, m_manifoldsPtr.back()); + m_manifoldsPtr.pop_back(); + } + + +} + + +// +// todo: this is random access, it can be walked 'cache friendly'! +// +void ToiContactDispatcher::SolveConstraints(float timeStep, int numIterations,int numRigidBodies) +{ + int i; + + int numManifolds; + + for (int islandId=0;islandId<numRigidBodies;islandId++) + { + numManifolds = 0; + + PersistentManifold* manifolds[MAX_MANIFOLDS]; + + + //int numSleeping = 0; + + bool allSleeping = true; + + for (i=0;i<GetNumManifolds();i++) + { + PersistentManifold* manifold = this->GetManifoldByIndexInternal(i); + if ((((RigidBody*)manifold->GetBody0()) && ((RigidBody*)manifold->GetBody0())->m_islandTag1 == (islandId)) || + (((RigidBody*)manifold->GetBody1()) && ((RigidBody*)manifold->GetBody1())->m_islandTag1 == (islandId))) + { + + if ((((RigidBody*)manifold->GetBody0()) && ((RigidBody*)manifold->GetBody0())->GetActivationState()== ACTIVE_TAG) || + (((RigidBody*)manifold->GetBody1()) && ((RigidBody*)manifold->GetBody1())->GetActivationState() == ACTIVE_TAG)) + { + allSleeping = false; + } + + manifolds[numManifolds] = manifold; + numManifolds++; + } + } + if (allSleeping) + { + //tag all as 'ISLAND_SLEEPING' + for (i=0;i<numManifolds;i++) + { + PersistentManifold* manifold = manifolds[i]; + if (((RigidBody*)manifold->GetBody0())) + { + ((RigidBody*)manifold->GetBody0())->SetActivationState( ISLAND_SLEEPING ); + } + if (((RigidBody*)manifold->GetBody1())) + { + ((RigidBody*)manifold->GetBody1())->SetActivationState( ISLAND_SLEEPING); + } + + } + } else + { + + //tag all as 'ISLAND_SLEEPING' + for (i=0;i<numManifolds;i++) + { + PersistentManifold* manifold = manifolds[i]; + if (((RigidBody*)manifold->GetBody0())) + { + if ( ((RigidBody*)manifold->GetBody0())->GetActivationState() == ISLAND_SLEEPING) + { + ((RigidBody*)manifold->GetBody0())->SetActivationState( WANTS_DEACTIVATION );//ACTIVE_TAG; + } + } + if (((RigidBody*)manifold->GetBody1())) + { + if ( ((RigidBody*)manifold->GetBody1())->GetActivationState() == ISLAND_SLEEPING) + { + ((RigidBody*)manifold->GetBody1())->SetActivationState(WANTS_DEACTIVATION);//ACTIVE_TAG; + } + } + + } + + ///This island solving can all be scheduled in parallel + ContactSolverInfo info; + info.m_damping = 0.9f; + info.m_friction = 0.9f; + info.m_numIterations = numIterations; + info.m_timeStep = timeStep; + info.m_tau = 0.4f; + info.m_restitution = 0.1f;//m_restitution; + + /* + int numManifolds = 0; + + for (i=0;i<m_firstFreeManifold;i++) + { + PersistentManifold* manifold = &m_manifolds[m_freeManifolds[i]]; + //ASSERT(((RigidBody*)manifold->GetBody0())); + //ASSERT(((RigidBody*)manifold->GetBody1())); + manifolds[i] = manifold; + numManifolds++; + } +*/ + m_solver->SolveGroup( manifolds, numManifolds,info ); + + } + } + + + + +} + + + +CollisionAlgorithm* ToiContactDispatcher::InternalFindAlgorithm(BroadphaseProxy& proxy0,BroadphaseProxy& proxy1) +{ + m_count++; + + CollisionAlgorithmConstructionInfo ci; + ci.m_dispatcher = this; + + if (proxy0.IsConvexShape() && proxy1.IsConvexShape() ) + { + return new ConvexConvexAlgorithm(0,ci,&proxy0,&proxy1); + } + + if (proxy0.IsConvexShape() && proxy1.IsConcaveShape()) + { + return new ConvexConcaveCollisionAlgorithm(ci,&proxy0,&proxy1); + } + + if (proxy1.IsConvexShape() && proxy0.IsConcaveShape()) + { + return new ConvexConcaveCollisionAlgorithm(ci,&proxy1,&proxy0); + } + + //failed to find an algorithm + return new EmptyAlgorithm(ci); + +} diff --git a/extern/bullet/BulletDynamics/CollisionDispatch/ToiContactDispatcher.h b/extern/bullet/BulletDynamics/CollisionDispatch/ToiContactDispatcher.h new file mode 100644 index 00000000000..818901cb901 --- /dev/null +++ b/extern/bullet/BulletDynamics/CollisionDispatch/ToiContactDispatcher.h @@ -0,0 +1,105 @@ +#ifndef TOI_CONTACT_DISPATCHER_H +#define TOI_CONTACT_DISPATCHER_H + +#include "BroadphaseCollision/CollisionDispatcher.h" +#include "NarrowPhaseCollision/PersistentManifold.h" +#include "CollisionDispatch/UnionFind.h" +#include "BroadphaseCollision/BroadphaseProxy.h" + +class ConstraintSolver; + +//island management +#define ACTIVE_TAG 1 +#define ISLAND_SLEEPING 2 +#define WANTS_DEACTIVATION 3 + +#define MAX_MANIFOLDS 512 + +struct CollisionAlgorithmCreateFunc +{ + bool m_swapped; + + CollisionAlgorithmCreateFunc() + :m_swapped(false) + { + } + virtual CollisionAlgorithm* CreateCollisionAlgorithm(BroadphaseProxy& proxy0,BroadphaseProxy& proxy1) + { + return 0; + } +}; +#include <vector> +///ToiContactDispatcher (Time of Impact) is the main collision dispatcher. +///Basic implementation supports algorithms that handle ConvexConvex and ConvexConcave collision pairs. +///Time of Impact, Closest Points and Penetration Depth. +class ToiContactDispatcher : public Dispatcher +{ + + bool m_useIslands; + + + std::vector<PersistentManifold*> m_manifoldsPtr; + +// PersistentManifold m_manifolds[MAX_MANIFOLDS]; +// int m_freeManifolds[MAX_MANIFOLDS]; + + UnionFind m_unionFind; + ConstraintSolver* m_solver; + + CollisionAlgorithmCreateFunc* m_doubleDispatch[MAX_BROADPHASE_COLLISION_TYPES][MAX_BROADPHASE_COLLISION_TYPES]; + +public: + + UnionFind& GetUnionFind() { return m_unionFind;} + +// int m_firstFreeManifold; + +// const PersistentManifold* GetManifoldByIndexInternal(int index) +// { +// return &m_manifolds[index]; +// } + + int GetNumManifolds() { return m_manifoldsPtr.size();} + + PersistentManifold* GetManifoldByIndexInternal(int index) + { + return m_manifoldsPtr[index]; + } + + + void InitUnionFind() + { + if (m_useIslands) + m_unionFind.reset(); + } + + void FindUnions(); + + int m_count; + + ToiContactDispatcher (ConstraintSolver* solver); + + virtual PersistentManifold* GetNewManifold(void* b0,void* b1); + + virtual void ReleaseManifold(PersistentManifold* manifold); + + // + // todo: this is random access, it can be walked 'cache friendly'! + // + virtual void SolveConstraints(float timeStep, int numIterations,int numRigidBodies); + + + CollisionAlgorithm* FindAlgorithm(BroadphaseProxy& proxy0,BroadphaseProxy& proxy1) + { + CollisionAlgorithm* algo = InternalFindAlgorithm(proxy0,proxy1); + return algo; + } + + CollisionAlgorithm* InternalFindAlgorithm(BroadphaseProxy& proxy0,BroadphaseProxy& proxy1); + + virtual int GetUniqueId() { return RIGIDBODY_DISPATCHER;} + +}; + +#endif //TOI_CONTACT_DISPATCHER_H + diff --git a/extern/bullet/BulletDynamics/CollisionDispatch/UnionFind.cpp b/extern/bullet/BulletDynamics/CollisionDispatch/UnionFind.cpp new file mode 100644 index 00000000000..2983b409aa3 --- /dev/null +++ b/extern/bullet/BulletDynamics/CollisionDispatch/UnionFind.cpp @@ -0,0 +1,54 @@ +#include "UnionFind.h" +#include <assert.h> + + +int UnionFind::find(int x) +{ + assert(x < m_N); + assert(x >= 0); + + while (x != id[x]) + { + x = id[x]; + assert(x < m_N); + assert(x >= 0); + + } + return x; +} + +UnionFind::UnionFind(int N) +:m_N(N) +{ + id = new int[N]; sz = new int[N]; + reset(); +} + +void UnionFind::reset() +{ + for (int i = 0; i < m_N; i++) + { + id[i] = i; sz[i] = 1; + } +} + + +int UnionFind ::find(int p, int q) +{ + return (find(p) == find(q)); +} + +void UnionFind ::unite(int p, int q) +{ + int i = find(p), j = find(q); + if (i == j) + return; + if (sz[i] < sz[j]) + { + id[i] = j; sz[j] += sz[i]; + } + else + { + id[j] = i; sz[i] += sz[j]; + } +} diff --git a/extern/bullet/BulletDynamics/CollisionDispatch/UnionFind.h b/extern/bullet/BulletDynamics/CollisionDispatch/UnionFind.h new file mode 100644 index 00000000000..0dc57783283 --- /dev/null +++ b/extern/bullet/BulletDynamics/CollisionDispatch/UnionFind.h @@ -0,0 +1,21 @@ +#ifndef UNION_FIND_H +#define UNION_FIND_H + +///UnionFind calculates connected subsets +class UnionFind + { + private: + int *id, *sz; + int m_N; + + public: + int find(int x); + UnionFind(int N); + void reset(); + + int find(int p, int q); + void unite(int p, int q); + }; + + +#endif //UNION_FIND_H diff --git a/extern/bullet/BulletDynamics/ConstraintSolver/ConstraintSolver.h b/extern/bullet/BulletDynamics/ConstraintSolver/ConstraintSolver.h new file mode 100644 index 00000000000..e1512ae1756 --- /dev/null +++ b/extern/bullet/BulletDynamics/ConstraintSolver/ConstraintSolver.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#ifndef CONSTRAINT_SOLVER_H +#define CONSTRAINT_SOLVER_H + +class PersistentManifold; +class RigidBody; + +struct ContactSolverInfo; +struct BroadphaseProxy; + +/// ConstraintSolver provides solver interface +class ConstraintSolver +{ + +public: + + virtual ~ConstraintSolver() {} + + virtual float SolveGroup(PersistentManifold** manifold,int numManifolds,const ContactSolverInfo& info) = 0; + +}; + + + + +#endif //CONSTRAINT_SOLVER_H diff --git a/extern/bullet/BulletDynamics/ConstraintSolver/ContactConstraint.cpp b/extern/bullet/BulletDynamics/ConstraintSolver/ContactConstraint.cpp new file mode 100644 index 00000000000..e3603ccec67 --- /dev/null +++ b/extern/bullet/BulletDynamics/ConstraintSolver/ContactConstraint.cpp @@ -0,0 +1,324 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#include "ContactConstraint.h" +#include "Dynamics/RigidBody.h" +#include "SimdVector3.h" +#include "JacobianEntry.h" +#include "ContactSolverInfo.h" +#include "GEN_minmax.h" + +#define ASSERT2 assert + + +static SimdScalar ContactThreshold = -10.0f; + +float useGlobalSettingContacts = false;//true; + +SimdScalar contactDamping = 0.9f; +SimdScalar contactTau = .2f;//0.02f;//*0.02f; + + + +SimdScalar restitutionCurve(SimdScalar rel_vel, SimdScalar restitution) +{ + return restitution; +// return restitution * GEN_min(1.0f, rel_vel / ContactThreshold); +} + +void applyFrictionInContactPointOld(RigidBody& body1, const SimdVector3& pos1, + RigidBody& body2, const SimdVector3& pos2, + const SimdVector3& normal,float normalImpulse, + const ContactSolverInfo& solverInfo) +{ + + + if (normalImpulse>0.f) + { + SimdVector3 rel_pos1 = pos1 - body1.getCenterOfMassPosition(); + SimdVector3 rel_pos2 = pos2 - body2.getCenterOfMassPosition(); + + SimdVector3 vel1 = body1.getVelocityInLocalPoint(rel_pos1); + SimdVector3 vel2 = body2.getVelocityInLocalPoint(rel_pos2); + SimdVector3 vel = vel1 - vel2; + + SimdScalar rel_vel = normal.dot(vel); + +#define PER_CONTACT_FRICTION +#ifdef PER_CONTACT_FRICTION + SimdVector3 lat_vel = vel - normal * rel_vel; + SimdScalar lat_rel_vel = lat_vel.length(); + + if (lat_rel_vel > SIMD_EPSILON) + { + lat_vel /= lat_rel_vel; + SimdVector3 temp1 = body1.getInvInertiaTensorWorld() * rel_pos1.cross(lat_vel); + SimdVector3 temp2 = body2.getInvInertiaTensorWorld() * rel_pos2.cross(lat_vel); + SimdScalar frictionMaxImpulse = lat_rel_vel / + (body1.getInvMass() + body2.getInvMass() + lat_vel.dot(temp1.cross(rel_pos1) + temp2.cross(rel_pos2))); + SimdScalar frictionImpulse = (normalImpulse) * solverInfo.m_friction; + GEN_set_min(frictionImpulse,frictionMaxImpulse ); + + body1.applyImpulse(lat_vel * -frictionImpulse, rel_pos1); + body2.applyImpulse(lat_vel * frictionImpulse, rel_pos2); + + } +#endif + } +} + + +//bilateral constraint between two dynamic objects +void resolveSingleBilateral(RigidBody& body1, const SimdVector3& pos1, + RigidBody& body2, const SimdVector3& pos2, + SimdScalar depth, const SimdVector3& normal,SimdScalar& impulse ,float timeStep) +{ + float normalLenSqr = normal.length2(); + ASSERT2(fabs(normalLenSqr) < 1.1f); + if (normalLenSqr > 1.1f) + { + impulse = 0.f; + return; + } + SimdVector3 rel_pos1 = pos1 - body1.getCenterOfMassPosition(); + SimdVector3 rel_pos2 = pos2 - body2.getCenterOfMassPosition(); + //this jacobian entry could be re-used for all iterations + + SimdVector3 vel1 = body1.getVelocityInLocalPoint(rel_pos1); + SimdVector3 vel2 = body2.getVelocityInLocalPoint(rel_pos2); + SimdVector3 vel = vel1 - vel2; + + SimdScalar rel_vel; + + /* + + JacobianEntry jac(body1.getCenterOfMassTransform().getBasis().transpose(), + body2.getCenterOfMassTransform().getBasis().transpose(), + rel_pos1,rel_pos2,normal,body1.getInvInertiaDiagLocal(),body1.getInvMass(), + body2.getInvInertiaDiagLocal(),body2.getInvMass()); + + SimdScalar jacDiagAB = jac.getDiagonal(); + SimdScalar jacDiagABInv = 1.f / jacDiagAB; + + SimdScalar rel_vel = jac.getRelativeVelocity( + body1.getLinearVelocity(), + body1.getCenterOfMassTransform().getBasis().transpose() * body1.getAngularVelocity(), + body2.getLinearVelocity(), + body2.getCenterOfMassTransform().getBasis().transpose() * body2.getAngularVelocity()); + float a; + a=jacDiagABInv; + + */ + rel_vel = normal.dot(vel); + + + + + /*int color = 255+255*256; + + DrawRasterizerLine(pos1,pos1+normal,color); +*/ + + + SimdScalar massTerm = 1.f / (body1.getInvMass() + body2.getInvMass()); + + float contactDamping = 0.9f; + impulse = - contactDamping * rel_vel * massTerm;//jacDiagABInv; + + //SimdScalar velocityImpulse = -contactDamping * rel_vel * jacDiagABInv; + //impulse = velocityImpulse; + +} + + + + + +//velocity + friction +//response between two dynamic objects with friction +float resolveSingleCollision(RigidBody& body1, const SimdVector3& pos1, + RigidBody& body2, const SimdVector3& pos2, + SimdScalar depth, const SimdVector3& normal, + const ContactSolverInfo& solverInfo + ) +{ + + float normalLenSqr = normal.length2(); + ASSERT2(fabs(normalLenSqr) < 1.1f); + if (normalLenSqr > 1.1f) + return 0.f; + + SimdVector3 rel_pos1 = pos1 - body1.getCenterOfMassPosition(); + SimdVector3 rel_pos2 = pos2 - body2.getCenterOfMassPosition(); + //this jacobian entry could be re-used for all iterations + + SimdVector3 vel1 = body1.getVelocityInLocalPoint(rel_pos1); + SimdVector3 vel2 = body2.getVelocityInLocalPoint(rel_pos2); + SimdVector3 vel = vel1 - vel2; + SimdScalar rel_vel; + rel_vel = normal.dot(vel); + +// if (rel_vel< 0.f)//-SIMD_EPSILON) +// { + SimdScalar rest = restitutionCurve(rel_vel, solverInfo.m_restitution); + + SimdScalar timeCorrection = 1.f;///timeStep; + float damping = solverInfo.m_damping ; + float tau = solverInfo.m_tau; + + if (useGlobalSettingContacts) + { + damping = contactDamping; + tau = contactTau; + } + + if (depth < 0.f) + return 0.f;//bdepth = 0.f; + + SimdScalar penetrationImpulse = (depth*tau*timeCorrection);// * massTerm;//jacDiagABInv + + SimdScalar velocityImpulse = -(1.0f + rest) * damping * rel_vel; + + SimdScalar impulse = penetrationImpulse + velocityImpulse; + SimdVector3 temp1 = body1.getInvInertiaTensorWorld() * rel_pos1.cross(normal); + SimdVector3 temp2 = body2.getInvInertiaTensorWorld() * rel_pos2.cross(normal); + impulse /= + (body1.getInvMass() + body2.getInvMass() + normal.dot(temp1.cross(rel_pos1) + temp2.cross(rel_pos2))); + + if (impulse > 0.f) + { + + body1.applyImpulse(normal*(impulse), rel_pos1); + body2.applyImpulse(-normal*(impulse), rel_pos2); + } else + { + impulse = 0.f; + } + + return impulse;//velocityImpulse;//impulse; + +} + + + +//velocity + friction +//response between two dynamic objects with friction +float resolveSingleCollisionWithFriction( + + RigidBody& body1, + const SimdVector3& pos1, + RigidBody& body2, + const SimdVector3& pos2, + SimdScalar depth, + const SimdVector3& normal, + + const ContactSolverInfo& solverInfo + ) +{ + float normalLenSqr = normal.length2(); + ASSERT2(fabs(normalLenSqr) < 1.1f); + if (normalLenSqr > 1.1f) + return 0.f; + + SimdVector3 rel_pos1 = pos1 - body1.getCenterOfMassPosition(); + SimdVector3 rel_pos2 = pos2 - body2.getCenterOfMassPosition(); + //this jacobian entry could be re-used for all iterations + + JacobianEntry jac(body1.getCenterOfMassTransform().getBasis().transpose(), + body2.getCenterOfMassTransform().getBasis().transpose(), + rel_pos1,rel_pos2,normal,body1.getInvInertiaDiagLocal(),body1.getInvMass(), + body2.getInvInertiaDiagLocal(),body2.getInvMass()); + + SimdScalar jacDiagAB = jac.getDiagonal(); + SimdScalar jacDiagABInv = 1.f / jacDiagAB; + SimdVector3 vel1 = body1.getVelocityInLocalPoint(rel_pos1); + SimdVector3 vel2 = body2.getVelocityInLocalPoint(rel_pos2); + SimdVector3 vel = vel1 - vel2; +SimdScalar rel_vel; + /* rel_vel = jac.getRelativeVelocity( + body1.getLinearVelocity(), + body1.getTransform().getBasis().transpose() * body1.getAngularVelocity(), + body2.getLinearVelocity(), + body2.getTransform().getBasis().transpose() * body2.getAngularVelocity()); +*/ + rel_vel = normal.dot(vel); + +// if (rel_vel< 0.f)//-SIMD_EPSILON) +// { + SimdScalar rest = restitutionCurve(rel_vel, solverInfo.m_restitution); +// SimdScalar massTerm = 1.f / (body1.getInvMass() + body2.getInvMass()); + + SimdScalar timeCorrection = 0.5f / solverInfo.m_timeStep ; + + float damping = solverInfo.m_damping ; + float tau = solverInfo.m_tau; + + if (useGlobalSettingContacts) + { + damping = contactDamping; + tau = contactTau; + } + SimdScalar penetrationImpulse = (depth* tau *timeCorrection) * jacDiagABInv; + + if (penetrationImpulse < 0.f) + penetrationImpulse = 0.f; + + + + SimdScalar velocityImpulse = -(1.0f + rest) * damping * rel_vel * jacDiagABInv; + + SimdScalar friction_impulse = 0.f; + + if (velocityImpulse <= 0.f) + velocityImpulse = 0.f; + +// SimdScalar impulse = penetrationImpulse + velocityImpulse; + //if (impulse > 0.f) + { +// SimdVector3 impulse_vector = normal * impulse; + body1.applyImpulse(normal*(velocityImpulse+penetrationImpulse), rel_pos1); + + body2.applyImpulse(-normal*(velocityImpulse+penetrationImpulse), rel_pos2); + + //friction + + { + + SimdVector3 vel1 = body1.getVelocityInLocalPoint(rel_pos1); + SimdVector3 vel2 = body2.getVelocityInLocalPoint(rel_pos2); + SimdVector3 vel = vel1 - vel2; + + rel_vel = normal.dot(vel); + +#define PER_CONTACT_FRICTION +#ifdef PER_CONTACT_FRICTION + SimdVector3 lat_vel = vel - normal * rel_vel; + SimdScalar lat_rel_vel = lat_vel.length(); + + if (lat_rel_vel > SIMD_EPSILON) + { + lat_vel /= lat_rel_vel; + SimdVector3 temp1 = body1.getInvInertiaTensorWorld() * rel_pos1.cross(lat_vel); + SimdVector3 temp2 = body2.getInvInertiaTensorWorld() * rel_pos2.cross(lat_vel); + friction_impulse = lat_rel_vel / + (body1.getInvMass() + body2.getInvMass() + lat_vel.dot(temp1.cross(rel_pos1) + temp2.cross(rel_pos2))); + SimdScalar normal_impulse = (penetrationImpulse+ + velocityImpulse) * solverInfo.m_friction; + GEN_set_min(friction_impulse, normal_impulse); + + body1.applyImpulse(lat_vel * -friction_impulse, rel_pos1); + body2.applyImpulse(lat_vel * friction_impulse, rel_pos2); + + } +#endif + } + } + return velocityImpulse + friction_impulse; +} diff --git a/extern/bullet/BulletDynamics/ConstraintSolver/ContactConstraint.h b/extern/bullet/BulletDynamics/ConstraintSolver/ContactConstraint.h new file mode 100644 index 00000000000..0f835546783 --- /dev/null +++ b/extern/bullet/BulletDynamics/ConstraintSolver/ContactConstraint.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#ifndef CONTACT_CONSTRAINT_H +#define CONTACT_CONSTRAINT_H + +//todo: make into a proper class working with the iterative constraint solver + +class RigidBody; +#include "SimdVector3.h" +#include "SimdScalar.h" +struct ContactSolverInfo; + +///bilateral constraint between two dynamic objects +void resolveSingleBilateral(RigidBody& body1, const SimdVector3& pos1, + RigidBody& body2, const SimdVector3& pos2, + SimdScalar depth, const SimdVector3& normal,SimdScalar& impulse ,float timeStep); + + +//contact constraint resolution: +//calculate and apply impulse to satisfy non-penetration and non-negative relative velocity constraint +float resolveSingleCollision(RigidBody& body1, const SimdVector3& pos1, + RigidBody& body2, const SimdVector3& pos2, + SimdScalar depth, const SimdVector3& normal, + const ContactSolverInfo& info); + + +/// apply friction force to simulate friction in a contact point related to the normal impulse +void applyFrictionInContactPointOld(RigidBody& body1, const SimdVector3& pos1, + RigidBody& body2, const SimdVector3& pos2, + const SimdVector3& normal,float normalImpulse, + const ContactSolverInfo& info); + +//contact constraint resolution: +//calculate and apply impulse to satisfy non-penetration and non-negative relative velocity constraint +float resolveSingleCollisionWithFriction(RigidBody& body1, const SimdVector3& pos1, + RigidBody& body2, const SimdVector3& pos2, + SimdScalar depth, const SimdVector3& normal, + const ContactSolverInfo& info); + +#endif //CONTACT_CONSTRAINT_H diff --git a/extern/bullet/BulletDynamics/ConstraintSolver/ContactSolverInfo.h b/extern/bullet/BulletDynamics/ConstraintSolver/ContactSolverInfo.h new file mode 100644 index 00000000000..83460771279 --- /dev/null +++ b/extern/bullet/BulletDynamics/ConstraintSolver/ContactSolverInfo.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#ifndef CONTACT_SOLVER_INFO +#define CONTACT_SOLVER_INFO + + +struct ContactSolverInfo +{ + + inline ContactSolverInfo() + { + m_tau = 0.4f; + m_damping = 0.9f; + m_friction = 0.3f; + m_restitution = 0.f; + m_maxErrorReduction = 20.f; + m_numIterations = 10; + } + + float m_tau; + float m_damping; + float m_friction; + float m_timeStep; + float m_restitution; + int m_numIterations; + float m_maxErrorReduction; + + +}; + +#endif //CONTACT_SOLVER_INFO diff --git a/extern/bullet/BulletDynamics/ConstraintSolver/JacobianEntry.h b/extern/bullet/BulletDynamics/ConstraintSolver/JacobianEntry.h new file mode 100644 index 00000000000..c1f3a521f2d --- /dev/null +++ b/extern/bullet/BulletDynamics/ConstraintSolver/JacobianEntry.h @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#ifndef JACOBIAN_ENTRY_H +#define JACOBIAN_ENTRY_H + +#include "SimdVector3.h" +#include "Dynamics/RigidBody.h" + + +//notes: +// Another memory optimization would be to store m_MbJ in the remaining 3 w components +// which makes the JacobianEntry memory layout 16 bytes +// if you only are interested in angular part, just feed massInvA and massInvB zero + +/// Jacobian entry is an abstraction that allows to describe constraints +/// it can be used in combination with a constraint solver +/// Can be used to relate the effect of an impulse to the constraint error +class JacobianEntry +{ +public: + JacobianEntry() {}; + //constraint between two different rigidbodies + JacobianEntry( + const SimdMatrix3x3& world2A, + const SimdMatrix3x3& world2B, + const SimdVector3& rel_pos1,const SimdVector3& rel_pos2, + const SimdVector3& normal, + const SimdVector3& inertiaInvA, + const SimdScalar massInvA, + const SimdVector3& inertiaInvB, + const SimdScalar massInvB) + :m_normalAxis(normal) + { + m_aJ = world2A*(rel_pos1.cross(normal)); + m_bJ = world2B*(rel_pos2.cross(normal)); + m_MaJ = inertiaInvA * m_aJ; + m_MbJ = inertiaInvB * m_bJ; + m_jacDiagAB = massInvA + m_MaJ.dot(m_aJ) + massInvB + m_MbJ.dot(m_bJ); + } + + //angular constraint between two different rigidbodies + JacobianEntry(const SimdVector3& normal, + const SimdMatrix3x3& world2A, + const SimdMatrix3x3& world2B, + const SimdVector3& inertiaInvA, + const SimdVector3& inertiaInvB) + :m_normalAxis(normal) + { + m_aJ= world2A*normal; + m_bJ = world2B*-normal; + m_MaJ = inertiaInvA * m_aJ; + m_MbJ = inertiaInvB * m_bJ; + m_jacDiagAB = m_MaJ.dot(m_aJ) + m_MbJ.dot(m_bJ); + } + + //constraint on one rigidbody + JacobianEntry( + const SimdMatrix3x3& world2A, + const SimdVector3& rel_pos1,const SimdVector3& rel_pos2, + const SimdVector3& normal, + const SimdVector3& inertiaInvA, + const SimdScalar massInvA) + :m_normalAxis(normal) + { + m_aJ= world2A*(rel_pos1.cross(normal)); + m_bJ = world2A*(rel_pos2.cross(normal)); + m_MaJ = inertiaInvA * m_aJ; + m_MbJ = SimdVector3(0.f,0.f,0.f); + m_jacDiagAB = massInvA + m_MaJ.dot(m_aJ); + } + + SimdScalar getDiagonal() const { return m_jacDiagAB; } + + // for two constraints on the same rigidbody (for example vehicle friction) + SimdScalar getNonDiagonal(const JacobianEntry& jacB, const SimdScalar massInvA) const + { + const JacobianEntry& jacA = *this; + SimdScalar lin = massInvA * jacA.m_normalAxis.dot(jacB.m_normalAxis); + SimdScalar ang = jacA.m_MaJ.dot(jacB.m_aJ); + return lin + ang; + } + + + + // for two constraints on sharing two same rigidbodies (for example two contact points between two rigidbodies) + SimdScalar getNonDiagonal(const JacobianEntry& jacB,const SimdScalar massInvA,const SimdScalar massInvB) const + { + const JacobianEntry& jacA = *this; + SimdVector3 lin = jacA.m_normalAxis * jacB.m_normalAxis; + SimdVector3 ang0 = jacA.m_MaJ * jacB.m_aJ; + SimdVector3 ang1 = jacA.m_MbJ * jacB.m_bJ; + SimdVector3 lin0 = massInvA * lin ; + SimdVector3 lin1 = massInvB * lin; + SimdVector3 sum = ang0+ang1+lin0+lin1; + return sum[0]+sum[1]+sum[2]; + } + + SimdScalar getRelativeVelocity(const SimdVector3& linvelA,const SimdVector3& angvelA,const SimdVector3& linvelB,const SimdVector3& angvelB) + { + SimdVector3 linrel = linvelA - linvelB; + SimdVector3 angvela = angvelA * m_aJ; + SimdVector3 angvelb = angvelB * m_bJ; + linrel *= m_normalAxis; + angvela += angvelb; + angvela += linrel; + SimdScalar rel_vel2 = angvela[0]+angvela[1]+angvela[2]; + return rel_vel2 + SIMD_EPSILON; + } +//private: + + SimdVector3 m_normalAxis; + SimdVector3 m_aJ; + SimdVector3 m_bJ; + SimdVector3 m_MaJ; + SimdVector3 m_MbJ; + //Optimization: can be stored in the w/last component of one of the vectors + SimdScalar m_jacDiagAB; + +}; + +#endif //JACOBIAN_ENTRY_H diff --git a/extern/bullet/BulletDynamics/ConstraintSolver/OdeConstraintSolver.cpp b/extern/bullet/BulletDynamics/ConstraintSolver/OdeConstraintSolver.cpp new file mode 100644 index 00000000000..8dc666d588f --- /dev/null +++ b/extern/bullet/BulletDynamics/ConstraintSolver/OdeConstraintSolver.cpp @@ -0,0 +1,256 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ + +#include "OdeConstraintSolver.h" + +#include "NarrowPhaseCollision/PersistentManifold.h" +#include "Dynamics/RigidBody.h" +#include "ContactConstraint.h" +#include "Solve2LinearConstraint.h" +#include "ContactSolverInfo.h" +#include "Dynamics/BU_Joint.h" +#include "Dynamics/ContactJoint.h" + +#define USE_SOR_SOLVER + +#include "SorLcp.h" + +#include <math.h> +#include <float.h>//FLT_MAX +#ifdef WIN32 +#include <memory.h> +#endif +#include <string.h> +#include <stdio.h> + +#ifdef WIN32 +#include <malloc.h> +#else +#include <alloca.h> +#endif + +class BU_Joint; + +//see below + +int gCurBody = 0; +int gCurJoint= 0; + +int ConvertBody(RigidBody* body,RigidBody** bodies,int& numBodies); +void ConvertConstraint(PersistentManifold* manifold,BU_Joint** joints,int& numJoints, + RigidBody** bodies,int bodyId0,int bodyId1); + + + + + +//iterative lcp and penalty method +float OdeConstraintSolver::SolveGroup(PersistentManifold** manifoldPtr, int numManifolds,const ContactSolverInfo& infoGlobal) +{ + gCurBody = 0; + gCurJoint = 0; + + float cfm = 1e-5f; + float erp = 0.2f; + + RigidBody* bodies [128]; + + int numBodies = 0; + BU_Joint* joints [128*5]; + int numJoints = 0; + + for (int j=0;j<numManifolds;j++) + { + + int body0=-1,body1=-1; + + PersistentManifold* manifold = manifoldPtr[j]; + if (manifold->GetNumContacts() > 0) + { + body0 = ConvertBody((RigidBody*)manifold->GetBody0(),bodies,numBodies); + body1 = ConvertBody((RigidBody*)manifold->GetBody1(),bodies,numBodies); + ConvertConstraint(manifold,joints,numJoints,bodies,body0,body1); + } + } + + SolveInternal1(cfm,erp,bodies,numBodies,joints,numJoints,infoGlobal); + + return 0.f; + +} + +///////////////////////////////////////////////////////////////////////////////// + + +typedef SimdScalar dQuaternion[4]; +#define _R(i,j) R[(i)*4+(j)] + +void dRfromQ1 (dMatrix3 R, const dQuaternion q) +{ + // q = (s,vx,vy,vz) + SimdScalar qq1 = 2*q[1]*q[1]; + SimdScalar qq2 = 2*q[2]*q[2]; + SimdScalar qq3 = 2*q[3]*q[3]; + _R(0,0) = 1 - qq2 - qq3; + _R(0,1) = 2*(q[1]*q[2] - q[0]*q[3]); + _R(0,2) = 2*(q[1]*q[3] + q[0]*q[2]); + _R(1,0) = 2*(q[1]*q[2] + q[0]*q[3]); + _R(1,1) = 1 - qq1 - qq3; + _R(1,2) = 2*(q[2]*q[3] - q[0]*q[1]); + _R(2,0) = 2*(q[1]*q[3] - q[0]*q[2]); + _R(2,1) = 2*(q[2]*q[3] + q[0]*q[1]); + _R(2,2) = 1 - qq1 - qq2; +} + + + +int ConvertBody(RigidBody* body,RigidBody** bodies,int& numBodies) +{ + if (!body || (body->getInvMass() == 0.f) ) + { + return -1; + } + //first try to find + int i,j; + for (i=0;i<numBodies;i++) + { + if (bodies[i] == body) + return i; + } + //if not found, create a new body + bodies[numBodies++] = body; + //convert data + + + body->m_facc.setValue(0,0,0); + body->m_tacc.setValue(0,0,0); + + //are the indices the same ? + for (i=0;i<4;i++) + { + for ( j=0;j<3;j++) + { + body->m_invI[i+4*j] = 0.f; + body->m_I[i+4*j] = 0.f; + } + } + body->m_invI[0+4*0] = body->getInvInertiaDiagLocal()[0]; + body->m_invI[1+4*1] = body->getInvInertiaDiagLocal()[1]; + body->m_invI[2+4*2] = body->getInvInertiaDiagLocal()[2]; + + body->m_I[0+0*4] = body->getInvInertiaDiagLocal()[0]; + body->m_I[1+1*4] = body->getInvInertiaDiagLocal()[1]; + body->m_I[2+2*4] = body->getInvInertiaDiagLocal()[2]; + + + /* + + SimdMatrix3x3 invI; + invI.setIdentity(); + invI[0][0] = body->getInvInertiaDiagLocal()[0]; + invI[1][1] = body->getInvInertiaDiagLocal()[1]; + invI[2][2] = body->getInvInertiaDiagLocal()[2]; + SimdMatrix3x3 inertia = invI.inverse(); + + for (i=0;i<3;i++) + { + for (j=0;j<3;j++) + { + body->m_I[i+4*j] = inertia[i][j]; + } + } + */ +// body->m_I[3+0*4] = 0.f; +// body->m_I[3+1*4] = 0.f; +// body->m_I[3+2*4] = 0.f; +// body->m_I[3+3*4] = 0.f; + + + dQuaternion q; + + q[1] = body->getOrientation()[0]; + q[2] = body->getOrientation()[1]; + q[3] = body->getOrientation()[2]; + q[0] = body->getOrientation()[3]; + + dRfromQ1(body->m_R,q); + + return numBodies-1; +} + + + + + +#define MAX_JOINTS_1 8192 + +static ContactJoint gJointArray[MAX_JOINTS_1]; + + +void ConvertConstraint(PersistentManifold* manifold,BU_Joint** joints,int& numJoints, + RigidBody** bodies,int _bodyId0,int _bodyId1) +{ + + + manifold->RefreshContactPoints(((RigidBody*)manifold->GetBody0())->getCenterOfMassTransform(), + ((RigidBody*)manifold->GetBody1())->getCenterOfMassTransform()); + + int bodyId0 = _bodyId0,bodyId1 = _bodyId1; + + int i,numContacts = manifold->GetNumContacts(); + + bool swapBodies = (bodyId0 < 0); + + + RigidBody* body0,*body1; + + if (swapBodies) + { + bodyId0 = _bodyId1; + bodyId1 = _bodyId0; + + body0 = (RigidBody*)manifold->GetBody1(); + body1 = (RigidBody*)manifold->GetBody0(); + + } else + { + body0 = (RigidBody*)manifold->GetBody0(); + body1 = (RigidBody*)manifold->GetBody1(); + } + + assert(bodyId0 >= 0); + + for (i=0;i<numContacts;i++) + { + + assert (gCurJoint < MAX_JOINTS_1); + + if (manifold->GetContactPoint(i).GetDistance() < 0.f) + { + ContactJoint* cont = new (&gJointArray[gCurJoint++]) ContactJoint( manifold ,i, swapBodies,body0,body1); + + cont->node[0].joint = cont; + cont->node[0].body = bodyId0 >= 0 ? bodies[bodyId0] : 0; + + cont->node[1].joint = cont; + cont->node[1].body = bodyId1 >= 0 ? bodies[bodyId1] : 0; + + joints[numJoints++] = cont; + for (int i=0;i<6;i++) + cont->lambda[i] = 0.f; + + cont->flags = 0; + } + } + + //create a new contact constraint +}; + diff --git a/extern/bullet/BulletDynamics/ConstraintSolver/OdeConstraintSolver.h b/extern/bullet/BulletDynamics/ConstraintSolver/OdeConstraintSolver.h new file mode 100644 index 00000000000..7ae8d0eaa49 --- /dev/null +++ b/extern/bullet/BulletDynamics/ConstraintSolver/OdeConstraintSolver.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#ifndef ODE_CONSTRAINT_SOLVER_H +#define ODE_CONSTRAINT_SOLVER_H + +#include "ConstraintSolver.h" + + +class OdeConstraintSolver : public ConstraintSolver +{ + +public: + + virtual ~OdeConstraintSolver() {} + + virtual float SolveGroup(PersistentManifold** manifold,int numManifolds,const ContactSolverInfo& info); + +}; + + + + +#endif //ODE_CONSTRAINT_SOLVER_H diff --git a/extern/bullet/BulletDynamics/ConstraintSolver/OdeConstraintSolver2.cpp b/extern/bullet/BulletDynamics/ConstraintSolver/OdeConstraintSolver2.cpp new file mode 100644 index 00000000000..4b343251f03 --- /dev/null +++ b/extern/bullet/BulletDynamics/ConstraintSolver/OdeConstraintSolver2.cpp @@ -0,0 +1,246 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ + +#include "OdeConstraintSolver.h" + +#include "NarrowPhaseCollision/PersistentManifold.h" +#include "Dynamics/RigidBody.h" +#include "ContactConstraint.h" +#include "Solve2LinearConstraint.h" +#include "ContactSolverInfo.h" +#include "Dynamics/BU_Joint.h" +#include "Dynamics/ContactJoint.h" + +#define USE_SOR_SOLVER + +#include "SorLcp.h" + +#include <math.h> +#include <float.h>//FLT_MAX +#ifdef WIN32 +#include <memory.h> +#endif +#include <string.h> +#include <stdio.h> + +#ifdef WIN32 +#include <malloc.h> +#else +#include <alloca.h> +#endif + +class BU_Joint; + +//see below + +int gCurBody = 0; +int gCurJoint= 0; + +int ConvertBody(RigidBody* body,RigidBody** bodies,int& numBodies); +void ConvertConstraint(PersistentManifold* manifold,BU_Joint** joints,int& numJoints, + RigidBody** bodies,int bodyId0,int bodyId1); + + + + + +//iterative lcp and penalty method +float OdeConstraintSolver::SolveGroup(PersistentManifold** manifoldPtr, int numManifolds,const ContactSolverInfo& infoGlobal) +{ + gCurBody = 0; + gCurJoint = 0; + + float cfm = 1e-5f; + float erp = 0.2f; + + RigidBody* bodies [128]; + + int numBodies = 0; + BU_Joint* joints [128*5]; + int numJoints = 0; + + for (int j=0;j<numManifolds;j++) + { + + int body0=-1,body1=-1; + + PersistentManifold* manifold = manifoldPtr[j]; + if (manifold->GetNumContacts() > 0) + { + body0 = ConvertBody((RigidBody*)manifold->GetBody0(),bodies,numBodies); + body1 = ConvertBody((RigidBody*)manifold->GetBody1(),bodies,numBodies); + ConvertConstraint(manifold,joints,numJoints,bodies,body0,body1); + } + } + + SolveInternal1(cfm,erp,bodies,numBodies,joints,numJoints,infoGlobal); + + return 0.f; + +} + +///////////////////////////////////////////////////////////////////////////////// + + +typedef SimdScalar dQuaternion[4]; +#define _R(i,j) R[(i)*4+(j)] + +void dRfromQ1 (dMatrix3 R, const dQuaternion q) +{ + // q = (s,vx,vy,vz) + SimdScalar qq1 = 2*q[1]*q[1]; + SimdScalar qq2 = 2*q[2]*q[2]; + SimdScalar qq3 = 2*q[3]*q[3]; + _R(0,0) = 1 - qq2 - qq3; + _R(0,1) = 2*(q[1]*q[2] - q[0]*q[3]); + _R(0,2) = 2*(q[1]*q[3] + q[0]*q[2]); + _R(1,0) = 2*(q[1]*q[2] + q[0]*q[3]); + _R(1,1) = 1 - qq1 - qq3; + _R(1,2) = 2*(q[2]*q[3] - q[0]*q[1]); + _R(2,0) = 2*(q[1]*q[3] - q[0]*q[2]); + _R(2,1) = 2*(q[2]*q[3] + q[0]*q[1]); + _R(2,2) = 1 - qq1 - qq2; +} + + + +int ConvertBody(RigidBody* body,RigidBody** bodies,int& numBodies) +{ + if (!body || (body->getInvMass() == 0.f) ) + { + return -1; + } + //first try to find + int i,j; + for (i=0;i<numBodies;i++) + { + if (bodies[i] == body) + return i; + } + //if not found, create a new body + bodies[numBodies++] = body; + //convert data + + + body->m_facc.setValue(0,0,0); + body->m_tacc.setValue(0,0,0); + + //are the indices the same ? + for (i=0;i<4;i++) + { + for ( j=0;j<3;j++) + { + body->m_invI[i+4*j] = 0.f; + } + } + body->m_invI[0+4*0] = body->getInvInertiaDiagLocal()[0]; + body->m_invI[1+4*1] = body->getInvInertiaDiagLocal()[1]; + body->m_invI[2+4*2] = body->getInvInertiaDiagLocal()[2]; + + + SimdMatrix3x3 invI; + invI.setIdentity(); + invI[0][0] = body->getInvInertiaDiagLocal()[0]; + invI[1][1] = body->getInvInertiaDiagLocal()[1]; + invI[2][2] = body->getInvInertiaDiagLocal()[2]; + SimdMatrix3x3 inertia = invI.inverse(); + + for (i=0;i<3;i++) + { + for (j=0;j<3;j++) + { + body->m_I[i+4*j] = inertia[i][j]; + } + } + body->m_I[3+0*4] = 0.f; + body->m_I[3+1*4] = 0.f; + body->m_I[3+2*4] = 0.f; + body->m_I[3+3*4] = 0.f; + + + dQuaternion q; + + q[1] = body->getOrientation()[0]; + q[2] = body->getOrientation()[1]; + q[3] = body->getOrientation()[2]; + q[0] = body->getOrientation()[3]; + + dRfromQ1(body->m_R,q); + + return numBodies-1; +} + + + + + +#define MAX_JOINTS_1 8192 + +static ContactJoint gJointArray[MAX_JOINTS_1]; + + +void ConvertConstraint(PersistentManifold* manifold,BU_Joint** joints,int& numJoints, + RigidBody** bodies,int _bodyId0,int _bodyId1) +{ + + + manifold->RefreshContactPoints(((RigidBody*)manifold->GetBody0())->getCenterOfMassTransform(), + ((RigidBody*)manifold->GetBody1())->getCenterOfMassTransform()); + + int bodyId0 = _bodyId0,bodyId1 = _bodyId1; + + int i,numContacts = manifold->GetNumContacts(); + + bool swapBodies = (bodyId0 < 0); + + + RigidBody* body0,*body1; + + if (swapBodies) + { + bodyId0 = _bodyId1; + bodyId1 = _bodyId0; + + body0 = (RigidBody*)manifold->GetBody1(); + body1 = (RigidBody*)manifold->GetBody0(); + + } else + { + body0 = (RigidBody*)manifold->GetBody0(); + body1 = (RigidBody*)manifold->GetBody1(); + } + + assert(bodyId0 >= 0); + + for (i=0;i<numContacts;i++) + { + + assert (gCurJoint < MAX_JOINTS_1); + + ContactJoint* cont = new (&gJointArray[gCurJoint++]) ContactJoint( manifold ,i, swapBodies,body0,body1); + + cont->node[0].joint = cont; + cont->node[0].body = bodyId0 >= 0 ? bodies[bodyId0] : 0; + + cont->node[1].joint = cont; + cont->node[1].body = bodyId1 >= 0 ? bodies[bodyId1] : 0; + + joints[numJoints++] = cont; + for (int i=0;i<6;i++) + cont->lambda[i] = 0.f; + + cont->flags = 0; + + } + + //create a new contact constraint +}; + diff --git a/extern/bullet/BulletDynamics/ConstraintSolver/OdeConstraintSolver2.h b/extern/bullet/BulletDynamics/ConstraintSolver/OdeConstraintSolver2.h new file mode 100644 index 00000000000..7ae8d0eaa49 --- /dev/null +++ b/extern/bullet/BulletDynamics/ConstraintSolver/OdeConstraintSolver2.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#ifndef ODE_CONSTRAINT_SOLVER_H +#define ODE_CONSTRAINT_SOLVER_H + +#include "ConstraintSolver.h" + + +class OdeConstraintSolver : public ConstraintSolver +{ + +public: + + virtual ~OdeConstraintSolver() {} + + virtual float SolveGroup(PersistentManifold** manifold,int numManifolds,const ContactSolverInfo& info); + +}; + + + + +#endif //ODE_CONSTRAINT_SOLVER_H diff --git a/extern/bullet/BulletDynamics/ConstraintSolver/Point2PointConstraint.cpp b/extern/bullet/BulletDynamics/ConstraintSolver/Point2PointConstraint.cpp new file mode 100644 index 00000000000..89b554cdad9 --- /dev/null +++ b/extern/bullet/BulletDynamics/ConstraintSolver/Point2PointConstraint.cpp @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#include "Point2PointConstraint.h" +#include "Dynamics/RigidBody.h" +#include "Dynamics/MassProps.h" + + +static RigidBody s_fixed(MassProps(0,SimdVector3(0.f,0.f,0.f)),0.f,0.f); + +Point2PointConstraint::Point2PointConstraint(): +m_rbA(s_fixed),m_rbB(s_fixed) +{ + s_fixed.setMassProps(0.f,SimdVector3(0.f,0.f,0.f)); +} + +Point2PointConstraint::Point2PointConstraint(RigidBody& rbA,RigidBody& rbB, const SimdVector3& pivotInA,const SimdVector3& pivotInB) +:m_rbA(rbA),m_rbB(rbB),m_pivotInA(pivotInA),m_pivotInB(pivotInB) +{ + +} + + +Point2PointConstraint::Point2PointConstraint(RigidBody& rbA,const SimdVector3& pivotInA) +:m_rbA(rbA),m_rbB(s_fixed),m_pivotInA(pivotInA),m_pivotInB(rbA.getCenterOfMassTransform()(pivotInA)) +{ + s_fixed.setMassProps(0.f,SimdVector3(1e10f,1e10f,1e10f)); +} + +void Point2PointConstraint::BuildJacobian() +{ + SimdVector3 normal(0,0,0); + + for (int i=0;i<3;i++) + { + normal[i] = 1; + new (&m_jac[i]) JacobianEntry( + m_rbA.getCenterOfMassTransform().getBasis().transpose(), + m_rbB.getCenterOfMassTransform().getBasis().transpose(), + m_rbA.getCenterOfMassTransform()*m_pivotInA - m_rbA.getCenterOfMassPosition(), + m_rbB.getCenterOfMassTransform()*m_pivotInB - m_rbB.getCenterOfMassPosition(), + normal, + m_rbA.getInvInertiaDiagLocal(), + m_rbA.getInvMass(), + m_rbB.getInvInertiaDiagLocal(), + m_rbB.getInvMass()); + normal[i] = 0; + } + +} + +void Point2PointConstraint::SolveConstraint(SimdScalar timeStep) +{ + SimdVector3 pivotAInW = m_rbA.getCenterOfMassTransform()*m_pivotInA; + SimdVector3 pivotBInW = m_rbB.getCenterOfMassTransform()*m_pivotInB; + + + SimdVector3 normal(0,0,0); + SimdScalar tau = 0.3f; + SimdScalar damping = 1.f; + +// SimdVector3 angvelA = m_rbA.getCenterOfMassTransform().getBasis().transpose() * m_rbA.getAngularVelocity(); +// SimdVector3 angvelB = m_rbB.getCenterOfMassTransform().getBasis().transpose() * m_rbB.getAngularVelocity(); + + for (int i=0;i<3;i++) + { + normal[i] = 1; + SimdScalar jacDiagABInv = 1.f / m_jac[i].getDiagonal(); + + SimdVector3 rel_pos1 = pivotAInW - m_rbA.getCenterOfMassPosition(); + SimdVector3 rel_pos2 = pivotBInW - m_rbB.getCenterOfMassPosition(); + //this jacobian entry could be re-used for all iterations + + SimdVector3 vel1 = m_rbA.getVelocityInLocalPoint(rel_pos1); + SimdVector3 vel2 = m_rbB.getVelocityInLocalPoint(rel_pos2); + SimdVector3 vel = vel1 - vel2; + + SimdScalar rel_vel; + rel_vel = normal.dot(vel); + + /* + //velocity error (first order error) + SimdScalar rel_vel = m_jac[i].getRelativeVelocity(m_rbA.getLinearVelocity(),angvelA, + m_rbB.getLinearVelocity(),angvelB); + */ + + //positional error (zeroth order error) + SimdScalar depth = -(pivotAInW - pivotBInW).dot(normal); //this is the error projected on the normal + + SimdScalar impulse = depth*tau/timeStep * jacDiagABInv - damping * rel_vel * jacDiagABInv * damping; + + SimdVector3 impulse_vector = normal * impulse; + m_rbA.applyImpulse(impulse_vector, pivotAInW - m_rbA.getCenterOfMassPosition()); + m_rbB.applyImpulse(-impulse_vector, pivotBInW - m_rbB.getCenterOfMassPosition()); + + normal[i] = 0; + } +} + +void Point2PointConstraint::UpdateRHS(SimdScalar timeStep) +{ + +} + diff --git a/extern/bullet/BulletDynamics/ConstraintSolver/Point2PointConstraint.h b/extern/bullet/BulletDynamics/ConstraintSolver/Point2PointConstraint.h new file mode 100644 index 00000000000..85e13cde21e --- /dev/null +++ b/extern/bullet/BulletDynamics/ConstraintSolver/Point2PointConstraint.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#ifndef POINT2POINTCONSTRAINT_H +#define POINT2POINTCONSTRAINT_H + +#include "SimdVector3.h" + +#include "ConstraintSolver/JacobianEntry.h" +class RigidBody; + + +/// point to point constraint between two rigidbodies each with a pivotpoint that descibes the 'ballsocket' location in local space +class Point2PointConstraint +{ + JacobianEntry m_jac[3]; //3 orthogonal linear constraints + RigidBody& m_rbA; + RigidBody& m_rbB; + + SimdVector3 m_pivotInA; + SimdVector3 m_pivotInB; + +public: + + Point2PointConstraint(RigidBody& rbA,RigidBody& rbB, const SimdVector3& pivotInA,const SimdVector3& pivotInB); + + Point2PointConstraint(RigidBody& rbA,const SimdVector3& pivotInA); + + Point2PointConstraint(); + + void BuildJacobian(); + + void SolveConstraint(SimdScalar timeStep); + + void UpdateRHS(SimdScalar timeStep); + + const RigidBody& GetRigidBodyA() const + { + return m_rbA; + } + const RigidBody& GetRigidBodyB() const + { + return m_rbB; + } + + +}; + +#endif //POINT2POINTCONSTRAINT_H diff --git a/extern/bullet/BulletDynamics/ConstraintSolver/SimpleConstraintSolver.cpp b/extern/bullet/BulletDynamics/ConstraintSolver/SimpleConstraintSolver.cpp new file mode 100644 index 00000000000..3243140b823 --- /dev/null +++ b/extern/bullet/BulletDynamics/ConstraintSolver/SimpleConstraintSolver.cpp @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#include "SimpleConstraintSolver.h" +#include "NarrowPhaseCollision/PersistentManifold.h" +#include "Dynamics/RigidBody.h" +#include "ContactConstraint.h" +#include "Solve2LinearConstraint.h" +#include "ContactSolverInfo.h" +#include "Dynamics/BU_Joint.h" +#include "Dynamics/ContactJoint.h" + +//debugging +bool doApplyImpulse = true; + + + +bool useImpulseFriction = true;//true;//false; + + + + +//iterative lcp and penalty method +float SimpleConstraintSolver::SolveGroup(PersistentManifold** manifoldPtr, int numManifolds,const ContactSolverInfo& infoGlobal) +{ + + ContactSolverInfo info = infoGlobal; + + int numiter = infoGlobal.m_numIterations; + + float substep = infoGlobal.m_timeStep / float(numiter); + + for (int i = 0;i<numiter;i++) + { + for (int j=0;j<numManifolds;j++) + { + Solve(manifoldPtr[j],info,i); + } + } + return 0.f; +} + + +float penetrationResolveFactor = 0.9f; + + +float SimpleConstraintSolver::Solve(PersistentManifold* manifoldPtr, const ContactSolverInfo& info,int iter) +{ + + RigidBody* body0 = (RigidBody*)manifoldPtr->GetBody0(); + RigidBody* body1 = (RigidBody*)manifoldPtr->GetBody1(); + + float maxImpulse = 0.f; + + + float invNumIterFl = 1.f / float(info.m_numIterations); + + float timeSubStep = info.m_timeStep * invNumIterFl; + + //only necessary to refresh the manifold once (first iteration). The integration is done outside the loop + if (iter == 0) + { + manifoldPtr->RefreshContactPoints(body0->getCenterOfMassTransform(),body1->getCenterOfMassTransform()); + } + + { + const int numpoints = manifoldPtr->GetNumContacts(); + + for (int i=0;i<numpoints ;i++) + { + + int j=i; + if (iter % 2) + j = numpoints-1-i; + else + j=i; + + ManifoldPoint& cp = manifoldPtr->GetContactPoint(j); + + { + + + float dist = invNumIterFl * cp.GetDistance() * penetrationResolveFactor / info.m_timeStep;// / timeStep;//penetrationResolveFactor*cp.m_solveDistance /timeStep;//cp.GetDistance(); + + + float impulse = 0.f; + + if (doApplyImpulse) + { + impulse = resolveSingleCollision(*body0, + cp.GetPositionWorldOnA(), + *body1, + cp.GetPositionWorldOnB(), + -dist, + cp.m_normalWorldOnB, + info); + + if (useImpulseFriction) + { + applyFrictionInContactPointOld( + *body0,cp.GetPositionWorldOnA(),*body1,cp.GetPositionWorldOnB(), + cp.m_normalWorldOnB,impulse,info) ; + } + } + if (iter == 0) + { + cp.m_appliedImpulse = impulse; + } else + { + cp.m_appliedImpulse += impulse; + } + + if (maxImpulse < impulse) + maxImpulse = impulse; + + } + } + } + return maxImpulse; +} diff --git a/extern/bullet/BulletDynamics/ConstraintSolver/SimpleConstraintSolver.h b/extern/bullet/BulletDynamics/ConstraintSolver/SimpleConstraintSolver.h new file mode 100644 index 00000000000..6bdcf3a2ac2 --- /dev/null +++ b/extern/bullet/BulletDynamics/ConstraintSolver/SimpleConstraintSolver.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#ifndef SIMPLE_CONSTRAINT_SOLVER_H +#define SIMPLE_CONSTRAINT_SOLVER_H + +#include "ConstraintSolver.h" + + +class SimpleConstraintSolver : public ConstraintSolver +{ + float Solve(PersistentManifold* manifold, const ContactSolverInfo& info,int iter); + +public: + + virtual ~SimpleConstraintSolver() {} + + virtual float SolveGroup(PersistentManifold** manifold,int numManifolds,const ContactSolverInfo& info); + +}; + + + + +#endif //SIMPLE_CONSTRAINT_SOLVER_H
\ No newline at end of file diff --git a/extern/bullet/BulletDynamics/ConstraintSolver/Solve2LinearConstraint.cpp b/extern/bullet/BulletDynamics/ConstraintSolver/Solve2LinearConstraint.cpp new file mode 100644 index 00000000000..28773d5faa8 --- /dev/null +++ b/extern/bullet/BulletDynamics/ConstraintSolver/Solve2LinearConstraint.cpp @@ -0,0 +1,234 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ + +#include "Solve2LinearConstraint.h" + +#include "Dynamics/RigidBody.h" +#include "SimdVector3.h" +#include "JacobianEntry.h" + + +void Solve2LinearConstraint::resolveUnilateralPairConstraint( + RigidBody* body1, + RigidBody* body2, + + const SimdMatrix3x3& world2A, + const SimdMatrix3x3& world2B, + + const SimdVector3& invInertiaADiag, + const SimdScalar invMassA, + const SimdVector3& linvelA,const SimdVector3& angvelA, + const SimdVector3& rel_posA1, + const SimdVector3& invInertiaBDiag, + const SimdScalar invMassB, + const SimdVector3& linvelB,const SimdVector3& angvelB, + const SimdVector3& rel_posA2, + + SimdScalar depthA, const SimdVector3& normalA, + const SimdVector3& rel_posB1,const SimdVector3& rel_posB2, + SimdScalar depthB, const SimdVector3& normalB, + SimdScalar& imp0,SimdScalar& imp1) +{ + + imp0 = 0.f; + imp1 = 0.f; + + SimdScalar len = fabs(normalA.length())-1.f; + if (fabs(len) >= SIMD_EPSILON) + return; + + ASSERT(len < SIMD_EPSILON); + + + //this jacobian entry could be re-used for all iterations + JacobianEntry jacA(world2A,world2B,rel_posA1,rel_posA2,normalA,invInertiaADiag,invMassA, + invInertiaBDiag,invMassB); + JacobianEntry jacB(world2A,world2B,rel_posB1,rel_posB2,normalB,invInertiaADiag,invMassA, + invInertiaBDiag,invMassB); + + //const SimdScalar vel0 = jacA.getRelativeVelocity(linvelA,angvelA,linvelB,angvelB); + //const SimdScalar vel1 = jacB.getRelativeVelocity(linvelA,angvelA,linvelB,angvelB); + + const SimdScalar vel0 = normalA.dot(body1->getVelocityInLocalPoint(rel_posA1)-body2->getVelocityInLocalPoint(rel_posA1)); + const SimdScalar vel1 = normalB.dot(body1->getVelocityInLocalPoint(rel_posB1)-body2->getVelocityInLocalPoint(rel_posB1)); + +// SimdScalar penetrationImpulse = (depth*contactTau*timeCorrection) * massTerm;//jacDiagABInv + SimdScalar massTerm = 1.f / (invMassA + invMassB); + + + // calculate rhs (or error) terms + const SimdScalar dv0 = depthA * m_tau * massTerm - vel0 * m_damping; + const SimdScalar dv1 = depthB * m_tau * massTerm - vel1 * m_damping; + + + // dC/dv * dv = -C + + // jacobian * impulse = -error + // + + //impulse = jacobianInverse * -error + + // inverting 2x2 symmetric system (offdiagonal are equal!) + // + + + SimdScalar nonDiag = jacA.getNonDiagonal(jacB,invMassA,invMassB); + SimdScalar invDet = 1.0f / (jacA.getDiagonal() * jacB.getDiagonal() - nonDiag * nonDiag ); + + //imp0 = dv0 * jacA.getDiagonal() * invDet + dv1 * -nonDiag * invDet; + //imp1 = dv1 * jacB.getDiagonal() * invDet + dv0 * - nonDiag * invDet; + + imp0 = dv0 * jacA.getDiagonal() * invDet + dv1 * -nonDiag * invDet; + imp1 = dv1 * jacB.getDiagonal() * invDet + dv0 * - nonDiag * invDet; + + //[a b] [d -c] + //[c d] inverse = (1 / determinant) * [-b a] where determinant is (ad - bc) + + //[jA nD] * [imp0] = [dv0] + //[nD jB] [imp1] [dv1] + +} + + + +void Solve2LinearConstraint::resolveBilateralPairConstraint( + RigidBody* body1, + RigidBody* body2, + const SimdMatrix3x3& world2A, + const SimdMatrix3x3& world2B, + + const SimdVector3& invInertiaADiag, + const SimdScalar invMassA, + const SimdVector3& linvelA,const SimdVector3& angvelA, + const SimdVector3& rel_posA1, + const SimdVector3& invInertiaBDiag, + const SimdScalar invMassB, + const SimdVector3& linvelB,const SimdVector3& angvelB, + const SimdVector3& rel_posA2, + + SimdScalar depthA, const SimdVector3& normalA, + const SimdVector3& rel_posB1,const SimdVector3& rel_posB2, + SimdScalar depthB, const SimdVector3& normalB, + SimdScalar& imp0,SimdScalar& imp1) +{ + + imp0 = 0.f; + imp1 = 0.f; + + SimdScalar len = fabs(normalA.length())-1.f; + if (fabs(len) >= SIMD_EPSILON) + return; + + ASSERT(len < SIMD_EPSILON); + + + //this jacobian entry could be re-used for all iterations + JacobianEntry jacA(world2A,world2B,rel_posA1,rel_posA2,normalA,invInertiaADiag,invMassA, + invInertiaBDiag,invMassB); + JacobianEntry jacB(world2A,world2B,rel_posB1,rel_posB2,normalB,invInertiaADiag,invMassA, + invInertiaBDiag,invMassB); + + //const SimdScalar vel0 = jacA.getRelativeVelocity(linvelA,angvelA,linvelB,angvelB); + //const SimdScalar vel1 = jacB.getRelativeVelocity(linvelA,angvelA,linvelB,angvelB); + + const SimdScalar vel0 = normalA.dot(body1->getVelocityInLocalPoint(rel_posA1)-body2->getVelocityInLocalPoint(rel_posA1)); + const SimdScalar vel1 = normalB.dot(body1->getVelocityInLocalPoint(rel_posB1)-body2->getVelocityInLocalPoint(rel_posB1)); + + // calculate rhs (or error) terms + const SimdScalar dv0 = depthA * m_tau - vel0 * m_damping; + const SimdScalar dv1 = depthB * m_tau - vel1 * m_damping; + + // dC/dv * dv = -C + + // jacobian * impulse = -error + // + + //impulse = jacobianInverse * -error + + // inverting 2x2 symmetric system (offdiagonal are equal!) + // + + + SimdScalar nonDiag = jacA.getNonDiagonal(jacB,invMassA,invMassB); + SimdScalar invDet = 1.0f / (jacA.getDiagonal() * jacB.getDiagonal() - nonDiag * nonDiag ); + + //imp0 = dv0 * jacA.getDiagonal() * invDet + dv1 * -nonDiag * invDet; + //imp1 = dv1 * jacB.getDiagonal() * invDet + dv0 * - nonDiag * invDet; + + imp0 = dv0 * jacA.getDiagonal() * invDet + dv1 * -nonDiag * invDet; + imp1 = dv1 * jacB.getDiagonal() * invDet + dv0 * - nonDiag * invDet; + + //[a b] [d -c] + //[c d] inverse = (1 / determinant) * [-b a] where determinant is (ad - bc) + + //[jA nD] * [imp0] = [dv0] + //[nD jB] [imp1] [dv1] + + if ( imp0 > 0.0f) + { + if ( imp1 > 0.0f ) + { + //both positive + } + else + { + imp1 = 0.f; + + // now imp0>0 imp1<0 + imp0 = dv0 / jacA.getDiagonal(); + if ( imp0 > 0.0f ) + { + } else + { + imp0 = 0.f; + } + } + } + else + { + imp0 = 0.f; + + imp1 = dv1 / jacB.getDiagonal(); + if ( imp1 <= 0.0f ) + { + imp1 = 0.f; + // now imp0>0 imp1<0 + imp0 = dv0 / jacA.getDiagonal(); + if ( imp0 > 0.0f ) + { + } else + { + imp0 = 0.f; + } + } else + { + } + } +} + + + +void Solve2LinearConstraint::resolveAngularConstraint( const SimdMatrix3x3& invInertiaAWS, + const SimdScalar invMassA, + const SimdVector3& linvelA,const SimdVector3& angvelA, + const SimdVector3& rel_posA1, + const SimdMatrix3x3& invInertiaBWS, + const SimdScalar invMassB, + const SimdVector3& linvelB,const SimdVector3& angvelB, + const SimdVector3& rel_posA2, + + SimdScalar depthA, const SimdVector3& normalA, + const SimdVector3& rel_posB1,const SimdVector3& rel_posB2, + SimdScalar depthB, const SimdVector3& normalB, + SimdScalar& imp0,SimdScalar& imp1) +{ + +}
\ No newline at end of file diff --git a/extern/bullet/BulletDynamics/ConstraintSolver/Solve2LinearConstraint.h b/extern/bullet/BulletDynamics/ConstraintSolver/Solve2LinearConstraint.h new file mode 100644 index 00000000000..710f9589c18 --- /dev/null +++ b/extern/bullet/BulletDynamics/ConstraintSolver/Solve2LinearConstraint.h @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#ifndef SOLVE_2LINEAR_CONSTRAINT_H +#define SOLVE_2LINEAR_CONSTRAINT_H + +#include "SimdMatrix3x3.h" +#include "SimdVector3.h" + + +class RigidBody; + + + +/// constraint class used for lateral tyre friction. +class Solve2LinearConstraint +{ + SimdScalar m_tau; + SimdScalar m_damping; + +public: + + Solve2LinearConstraint(SimdScalar tau,SimdScalar damping) + { + m_tau = tau; + m_damping = damping; + } + // + // solve unilateral constraint (equality, direct method) + // + void resolveUnilateralPairConstraint( + RigidBody* body0, + RigidBody* body1, + + const SimdMatrix3x3& world2A, + const SimdMatrix3x3& world2B, + + const SimdVector3& invInertiaADiag, + const SimdScalar invMassA, + const SimdVector3& linvelA,const SimdVector3& angvelA, + const SimdVector3& rel_posA1, + const SimdVector3& invInertiaBDiag, + const SimdScalar invMassB, + const SimdVector3& linvelB,const SimdVector3& angvelB, + const SimdVector3& rel_posA2, + + SimdScalar depthA, const SimdVector3& normalA, + const SimdVector3& rel_posB1,const SimdVector3& rel_posB2, + SimdScalar depthB, const SimdVector3& normalB, + SimdScalar& imp0,SimdScalar& imp1); + + + // + // solving 2x2 lcp problem (inequality, direct solution ) + // + void resolveBilateralPairConstraint( + RigidBody* body0, + RigidBody* body1, + const SimdMatrix3x3& world2A, + const SimdMatrix3x3& world2B, + + const SimdVector3& invInertiaADiag, + const SimdScalar invMassA, + const SimdVector3& linvelA,const SimdVector3& angvelA, + const SimdVector3& rel_posA1, + const SimdVector3& invInertiaBDiag, + const SimdScalar invMassB, + const SimdVector3& linvelB,const SimdVector3& angvelB, + const SimdVector3& rel_posA2, + + SimdScalar depthA, const SimdVector3& normalA, + const SimdVector3& rel_posB1,const SimdVector3& rel_posB2, + SimdScalar depthB, const SimdVector3& normalB, + SimdScalar& imp0,SimdScalar& imp1); + + + void resolveAngularConstraint( const SimdMatrix3x3& invInertiaAWS, + const SimdScalar invMassA, + const SimdVector3& linvelA,const SimdVector3& angvelA, + const SimdVector3& rel_posA1, + const SimdMatrix3x3& invInertiaBWS, + const SimdScalar invMassB, + const SimdVector3& linvelB,const SimdVector3& angvelB, + const SimdVector3& rel_posA2, + + SimdScalar depthA, const SimdVector3& normalA, + const SimdVector3& rel_posB1,const SimdVector3& rel_posB2, + SimdScalar depthB, const SimdVector3& normalB, + SimdScalar& imp0,SimdScalar& imp1); + + +}; + +#endif //SOLVE_2LINEAR_CONSTRAINT_H diff --git a/extern/bullet/BulletDynamics/ConstraintSolver/SorLcp.cpp b/extern/bullet/BulletDynamics/ConstraintSolver/SorLcp.cpp new file mode 100644 index 00000000000..d5c6d80552d --- /dev/null +++ b/extern/bullet/BulletDynamics/ConstraintSolver/SorLcp.cpp @@ -0,0 +1,821 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#include "SorLcp.h" + +#ifdef USE_SOR_SOLVER + +// SOR LCP taken from ode quickstep, +// todo: write own successive overrelaxation gauss-seidel, or jacobi iterative solver + + +#include "SimdScalar.h" + +#include "Dynamics/RigidBody.h" +#include <math.h> +#include <float.h>//FLT_MAX +#ifdef WIN32 +#include <memory.h> +#endif +#include <string.h> +#include <stdio.h> + +#ifdef WIN32 +#include <malloc.h> +#else +#include <alloca.h> +#endif + +#include "Dynamics/BU_Joint.h" +#include "ContactSolverInfo.h" + +//////////////////////////////////////////////////////////////////// +//math stuff + +typedef SimdScalar dVector4[4]; +typedef SimdScalar dMatrix3[4*3]; +#define dInfinity FLT_MAX + + + +#define dRecip(x) ((float)(1.0f/(x))) /* reciprocal */ + + + +#define dMULTIPLY0_331NEW(A,op,B,C) \ +{\ + float tmp[3];\ + tmp[0] = C.getX();\ + tmp[1] = C.getY();\ + tmp[2] = C.getZ();\ + dMULTIPLYOP0_331(A,op,B,tmp);\ +} + +#define dMULTIPLY0_331(A,B,C) dMULTIPLYOP0_331(A,=,B,C) +#define dMULTIPLYOP0_331(A,op,B,C) \ + (A)[0] op dDOT1((B),(C)); \ + (A)[1] op dDOT1((B+4),(C)); \ + (A)[2] op dDOT1((B+8),(C)); + +#define dAASSERT ASSERT +#define dIASSERT ASSERT + +#define REAL float +#define dDOTpq(a,b,p,q) ((a)[0]*(b)[0] + (a)[p]*(b)[q] + (a)[2*(p)]*(b)[2*(q)]) +SimdScalar dDOT1 (const SimdScalar *a, const SimdScalar *b) { return dDOTpq(a,b,1,1); } +#define dDOT14(a,b) dDOTpq(a,b,1,4) + +#define dCROSS(a,op,b,c) \ + (a)[0] op ((b)[1]*(c)[2] - (b)[2]*(c)[1]); \ + (a)[1] op ((b)[2]*(c)[0] - (b)[0]*(c)[2]); \ + (a)[2] op ((b)[0]*(c)[1] - (b)[1]*(c)[0]); + + +#define dMULTIPLYOP2_333(A,op,B,C) \ + (A)[0] op dDOT1((B),(C)); \ + (A)[1] op dDOT1((B),(C+4)); \ + (A)[2] op dDOT1((B),(C+8)); \ + (A)[4] op dDOT1((B+4),(C)); \ + (A)[5] op dDOT1((B+4),(C+4)); \ + (A)[6] op dDOT1((B+4),(C+8)); \ + (A)[8] op dDOT1((B+8),(C)); \ + (A)[9] op dDOT1((B+8),(C+4)); \ + (A)[10] op dDOT1((B+8),(C+8)); +#define dMULTIPLYOP0_333(A,op,B,C) \ + (A)[0] op dDOT14((B),(C)); \ + (A)[1] op dDOT14((B),(C+1)); \ + (A)[2] op dDOT14((B),(C+2)); \ + (A)[4] op dDOT14((B+4),(C)); \ + (A)[5] op dDOT14((B+4),(C+1)); \ + (A)[6] op dDOT14((B+4),(C+2)); \ + (A)[8] op dDOT14((B+8),(C)); \ + (A)[9] op dDOT14((B+8),(C+1)); \ + (A)[10] op dDOT14((B+8),(C+2)); + +#define dMULTIPLY2_333(A,B,C) dMULTIPLYOP2_333(A,=,B,C) +#define dMULTIPLY0_333(A,B,C) dMULTIPLYOP0_333(A,=,B,C) +#define dMULTIPLYADD0_331(A,B,C) dMULTIPLYOP0_331(A,+=,B,C) + + +//////////////////////////////////////////////////////////////////// +#define EFFICIENT_ALIGNMENT 16 +#define dEFFICIENT_SIZE(x) ((((x)-1)|(EFFICIENT_ALIGNMENT-1))+1) +/* alloca aligned to the EFFICIENT_ALIGNMENT. note that this can waste + * up to 15 bytes per allocation, depending on what alloca() returns. + */ + +#define dALLOCA16(n) \ + ((char*)dEFFICIENT_SIZE(((size_t)(alloca((n)+(EFFICIENT_ALIGNMENT-1)))))) + + + +///////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////// + +#ifdef DEBUG +#define ANSI_FTOL 1 + +extern "C" { + __declspec(naked) void _ftol2() { + __asm { +#if ANSI_FTOL + fnstcw WORD PTR [esp-2] + mov ax, WORD PTR [esp-2] + + OR AX, 0C00h + + mov WORD PTR [esp-4], ax + fldcw WORD PTR [esp-4] + fistp QWORD PTR [esp-12] + fldcw WORD PTR [esp-2] + mov eax, DWORD PTR [esp-12] + mov edx, DWORD PTR [esp-8] +#else + fistp DWORD PTR [esp-12] + mov eax, DWORD PTR [esp-12] + mov ecx, DWORD PTR [esp-8] +#endif + ret + } + } +} +#endif //DEBUG + + + + + + +#define ALLOCA dALLOCA16 + +typedef const SimdScalar *dRealPtr; +typedef SimdScalar *dRealMutablePtr; +#define dRealArray(name,n) SimdScalar name[n]; +#define dRealAllocaArray(name,n) SimdScalar *name = (SimdScalar*) ALLOCA ((n)*sizeof(SimdScalar)); + +void dSetZero1 (SimdScalar *a, int n) +{ + dAASSERT (a && n >= 0); + while (n > 0) { + *(a++) = 0; + n--; + } +} + +void dSetValue1 (SimdScalar *a, int n, SimdScalar value) +{ + dAASSERT (a && n >= 0); + while (n > 0) { + *(a++) = value; + n--; + } +} + + +//*************************************************************************** +// configuration + +// for the SOR and CG methods: +// uncomment the following line to use warm starting. this definitely +// help for motor-driven joints. unfortunately it appears to hurt +// with high-friction contacts using the SOR method. use with care + +//#define WARM_STARTING 1 + +// for the SOR method: +// uncomment the following line to randomly reorder constraint rows +// during the solution. depending on the situation, this can help a lot +// or hardly at all, but it doesn't seem to hurt. + +//#define RANDOMLY_REORDER_CONSTRAINTS 1 + + + +//*************************************************************************** +// various common computations involving the matrix J + +// compute iMJ = inv(M)*J' + +static void compute_invM_JT (int m, dRealMutablePtr J, dRealMutablePtr iMJ, int *jb, + RigidBody * const *body, dRealPtr invI) +{ + int i,j; + dRealMutablePtr iMJ_ptr = iMJ; + dRealMutablePtr J_ptr = J; + for (i=0; i<m; i++) { + int b1 = jb[i*2]; + int b2 = jb[i*2+1]; + SimdScalar k = body[b1]->getInvMass(); + for (j=0; j<3; j++) iMJ_ptr[j] = k*J_ptr[j]; + dMULTIPLY0_331 (iMJ_ptr + 3, invI + 12*b1, J_ptr + 3); + if (b2 >= 0) { + k = body[b2]->getInvMass(); + for (j=0; j<3; j++) iMJ_ptr[j+6] = k*J_ptr[j+6]; + dMULTIPLY0_331 (iMJ_ptr + 9, invI + 12*b2, J_ptr + 9); + } + J_ptr += 12; + iMJ_ptr += 12; + } +} + +static void multiply_invM_JTSpecial (int m, int nb, dRealMutablePtr iMJ, int *jb, + dRealMutablePtr in, dRealMutablePtr out,int onlyBody1,int onlyBody2) +{ + int i,j; + + + + dRealMutablePtr out_ptr1 = out + onlyBody1*6; + + for (j=0; j<6; j++) + out_ptr1[j] = 0; + + if (onlyBody2 >= 0) + { + out_ptr1 = out + onlyBody2*6; + + for (j=0; j<6; j++) + out_ptr1[j] = 0; + } + + dRealPtr iMJ_ptr = iMJ; + for (i=0; i<m; i++) { + + int b1 = jb[i*2]; + + dRealMutablePtr out_ptr = out + b1*6; + if ((b1 == onlyBody1) || (b1 == onlyBody2)) + { + for (j=0; j<6; j++) + out_ptr[j] += iMJ_ptr[j] * in[i] ; + } + + iMJ_ptr += 6; + + int b2 = jb[i*2+1]; + if ((b2 == onlyBody1) || (b2 == onlyBody2)) + { + if (b2 >= 0) + { + out_ptr = out + b2*6; + for (j=0; j<6; j++) + out_ptr[j] += iMJ_ptr[j] * in[i]; + } + } + + iMJ_ptr += 6; + + } +} + + +// compute out = inv(M)*J'*in. + +static void multiply_invM_JT (int m, int nb, dRealMutablePtr iMJ, int *jb, + dRealMutablePtr in, dRealMutablePtr out) +{ + int i,j; + dSetZero1 (out,6*nb); + dRealPtr iMJ_ptr = iMJ; + for (i=0; i<m; i++) { + int b1 = jb[i*2]; + int b2 = jb[i*2+1]; + dRealMutablePtr out_ptr = out + b1*6; + for (j=0; j<6; j++) + out_ptr[j] += iMJ_ptr[j] * in[i]; + iMJ_ptr += 6; + if (b2 >= 0) { + out_ptr = out + b2*6; + for (j=0; j<6; j++) out_ptr[j] += iMJ_ptr[j] * in[i]; + } + iMJ_ptr += 6; + } +} + + +// compute out = J*in. + +static void multiply_J (int m, dRealMutablePtr J, int *jb, + dRealMutablePtr in, dRealMutablePtr out) +{ + int i,j; + dRealPtr J_ptr = J; + for (i=0; i<m; i++) { + int b1 = jb[i*2]; + int b2 = jb[i*2+1]; + SimdScalar sum = 0; + dRealMutablePtr in_ptr = in + b1*6; + for (j=0; j<6; j++) sum += J_ptr[j] * in_ptr[j]; + J_ptr += 6; + if (b2 >= 0) { + in_ptr = in + b2*6; + for (j=0; j<6; j++) sum += J_ptr[j] * in_ptr[j]; + } + J_ptr += 6; + out[i] = sum; + } +} + +//*************************************************************************** +// SOR-LCP method + +// nb is the number of bodies in the body array. +// J is an m*12 matrix of constraint rows +// jb is an array of first and second body numbers for each constraint row +// invI is the global frame inverse inertia for each body (stacked 3x3 matrices) +// +// this returns lambda and fc (the constraint force). +// note: fc is returned as inv(M)*J'*lambda, the constraint force is actually J'*lambda +// +// b, lo and hi are modified on exit + + +struct IndexError { + SimdScalar error; // error to sort on + int findex; + int index; // row index +}; + +static unsigned long seed2 = 0; + +unsigned long dRand2() +{ + seed2 = (1664525L*seed2 + 1013904223L) & 0xffffffff; + return seed2; +} + +int dRandInt2 (int n) +{ + float a = float(n) / 4294967296.0f; + return (int) (float(dRand2()) * a); +} + + +static void SOR_LCP (int m, int nb, dRealMutablePtr J, int *jb, RigidBody * const *body, + dRealPtr invI, dRealMutablePtr lambda, dRealMutablePtr invMforce, dRealMutablePtr rhs, + dRealMutablePtr lo, dRealMutablePtr hi, dRealPtr cfm, int *findex, + int numiter,float overRelax) +{ + const int num_iterations = numiter; + const float sor_w = overRelax; // SOR over-relaxation parameter + + int i,j; + +#ifdef WARM_STARTING + // for warm starting, this seems to be necessary to prevent + // jerkiness in motor-driven joints. i have no idea why this works. + for (i=0; i<m; i++) lambda[i] *= 0.9; +#else + dSetZero1 (lambda,m); +#endif + + // the lambda computed at the previous iteration. + // this is used to measure error for when we are reordering the indexes. + dRealAllocaArray (last_lambda,m); + + // a copy of the 'hi' vector in case findex[] is being used + dRealAllocaArray (hicopy,m); + memcpy (hicopy,hi,m*sizeof(float)); + + // precompute iMJ = inv(M)*J' + dRealAllocaArray (iMJ,m*12); + compute_invM_JT (m,J,iMJ,jb,body,invI); + + // compute fc=(inv(M)*J')*lambda. we will incrementally maintain fc + // as we change lambda. +#ifdef WARM_STARTING + multiply_invM_JT (m,nb,iMJ,jb,lambda,fc); +#else + dSetZero1 (invMforce,nb*6); +#endif + + // precompute 1 / diagonals of A + dRealAllocaArray (Ad,m); + dRealPtr iMJ_ptr = iMJ; + dRealMutablePtr J_ptr = J; + for (i=0; i<m; i++) { + float sum = 0; + for (j=0; j<6; j++) sum += iMJ_ptr[j] * J_ptr[j]; + if (jb[i*2+1] >= 0) { + for (j=6; j<12; j++) sum += iMJ_ptr[j] * J_ptr[j]; + } + iMJ_ptr += 12; + J_ptr += 12; + Ad[i] = sor_w / (sum + cfm[i]); + } + + // scale J and b by Ad + J_ptr = J; + for (i=0; i<m; i++) { + for (j=0; j<12; j++) { + J_ptr[0] *= Ad[i]; + J_ptr++; + } + rhs[i] *= Ad[i]; + } + + // scale Ad by CFM + for (i=0; i<m; i++) Ad[i] *= cfm[i]; + + // order to solve constraint rows in + IndexError *order = (IndexError*) alloca (m*sizeof(IndexError)); + +#ifndef REORDER_CONSTRAINTS + // make sure constraints with findex < 0 come first. + j=0; + for (i=0; i<m; i++) if (findex[i] < 0) order[j++].index = i; + for (i=0; i<m; i++) if (findex[i] >= 0) order[j++].index = i; + dIASSERT (j==m); +#endif + + for (int iteration=0; iteration < num_iterations; iteration++) { + +#ifdef REORDER_CONSTRAINTS + // constraints with findex < 0 always come first. + if (iteration < 2) { + // for the first two iterations, solve the constraints in + // the given order + for (i=0; i<m; i++) { + order[i].error = i; + order[i].findex = findex[i]; + order[i].index = i; + } + } + else { + // sort the constraints so that the ones converging slowest + // get solved last. use the absolute (not relative) error. + for (i=0; i<m; i++) { + float v1 = dFabs (lambda[i]); + float v2 = dFabs (last_lambda[i]); + float max = (v1 > v2) ? v1 : v2; + if (max > 0) { + //@@@ relative error: order[i].error = dFabs(lambda[i]-last_lambda[i])/max; + order[i].error = dFabs(lambda[i]-last_lambda[i]); + } + else { + order[i].error = dInfinity; + } + order[i].findex = findex[i]; + order[i].index = i; + } + } + qsort (order,m,sizeof(IndexError),&compare_index_error); +#endif +#ifdef RANDOMLY_REORDER_CONSTRAINTS + if ((iteration & 7) == 0) { + for (i=1; i<m; ++i) { + IndexError tmp = order[i]; + int swapi = dRandInt2(i+1); + order[i] = order[swapi]; + order[swapi] = tmp; + } + } +#endif + + //@@@ potential optimization: swap lambda and last_lambda pointers rather + // than copying the data. we must make sure lambda is properly + // returned to the caller + memcpy (last_lambda,lambda,m*sizeof(float)); + + for (int i=0; i<m; i++) { + // @@@ potential optimization: we could pre-sort J and iMJ, thereby + // linearizing access to those arrays. hmmm, this does not seem + // like a win, but we should think carefully about our memory + // access pattern. + + int index = order[i].index; + J_ptr = J + index*12; + iMJ_ptr = iMJ + index*12; + + // set the limits for this constraint. note that 'hicopy' is used. + // this is the place where the QuickStep method differs from the + // direct LCP solving method, since that method only performs this + // limit adjustment once per time step, whereas this method performs + // once per iteration per constraint row. + // the constraints are ordered so that all lambda[] values needed have + // already been computed. + if (findex[index] >= 0) { + hi[index] = fabsf (hicopy[index] * lambda[findex[index]]); + lo[index] = -hi[index]; + } + + int b1 = jb[index*2]; + int b2 = jb[index*2+1]; + float delta = rhs[index] - lambda[index]*Ad[index]; + dRealMutablePtr fc_ptr = invMforce + 6*b1; + + // @@@ potential optimization: SIMD-ize this and the b2 >= 0 case + delta -=fc_ptr[0] * J_ptr[0] + fc_ptr[1] * J_ptr[1] + + fc_ptr[2] * J_ptr[2] + fc_ptr[3] * J_ptr[3] + + fc_ptr[4] * J_ptr[4] + fc_ptr[5] * J_ptr[5]; + // @@@ potential optimization: handle 1-body constraints in a separate + // loop to avoid the cost of test & jump? + if (b2 >= 0) { + fc_ptr = invMforce + 6*b2; + delta -=fc_ptr[0] * J_ptr[6] + fc_ptr[1] * J_ptr[7] + + fc_ptr[2] * J_ptr[8] + fc_ptr[3] * J_ptr[9] + + fc_ptr[4] * J_ptr[10] + fc_ptr[5] * J_ptr[11]; + } + + // compute lambda and clamp it to [lo,hi]. + // @@@ potential optimization: does SSE have clamping instructions + // to save test+jump penalties here? + float new_lambda = lambda[index] + delta; + if (new_lambda < lo[index]) { + delta = lo[index]-lambda[index]; + lambda[index] = lo[index]; + } + else if (new_lambda > hi[index]) { + delta = hi[index]-lambda[index]; + lambda[index] = hi[index]; + } + else { + lambda[index] = new_lambda; + } + + //@@@ a trick that may or may not help + //float ramp = (1-((float)(iteration+1)/(float)num_iterations)); + //delta *= ramp; + + // update invMforce. + // @@@ potential optimization: SIMD for this and the b2 >= 0 case + fc_ptr = invMforce + 6*b1; + fc_ptr[0] += delta * iMJ_ptr[0]; + fc_ptr[1] += delta * iMJ_ptr[1]; + fc_ptr[2] += delta * iMJ_ptr[2]; + fc_ptr[3] += delta * iMJ_ptr[3]; + fc_ptr[4] += delta * iMJ_ptr[4]; + fc_ptr[5] += delta * iMJ_ptr[5]; + // @@@ potential optimization: handle 1-body constraints in a separate + // loop to avoid the cost of test & jump? + if (b2 >= 0) { + fc_ptr = invMforce + 6*b2; + fc_ptr[0] += delta * iMJ_ptr[6]; + fc_ptr[1] += delta * iMJ_ptr[7]; + fc_ptr[2] += delta * iMJ_ptr[8]; + fc_ptr[3] += delta * iMJ_ptr[9]; + fc_ptr[4] += delta * iMJ_ptr[10]; + fc_ptr[5] += delta * iMJ_ptr[11]; + } + } + } +} + + + +void SolveInternal1 (float global_cfm, + float global_erp, + RigidBody * const *body, int nb, + BU_Joint * const *_joint, + int nj, + const ContactSolverInfo& solverInfo) +{ + + int numIter = 30; + float sOr = 1.3f; + + int i,j; + + SimdScalar stepsize1 = dRecip(solverInfo.m_timeStep); + + // number all bodies in the body list - set their tag values + for (i=0; i<nb; i++) + body[i]->m_odeTag = i; + + // make a local copy of the joint array, because we might want to modify it. + // (the "BU_Joint *const*" declaration says we're allowed to modify the joints + // but not the joint array, because the caller might need it unchanged). + //@@@ do we really need to do this? we'll be sorting constraint rows individually, not joints + BU_Joint **joint = (BU_Joint**) alloca (nj * sizeof(BU_Joint*)); + memcpy (joint,_joint,nj * sizeof(BU_Joint*)); + + // for all bodies, compute the inertia tensor and its inverse in the global + // frame, and compute the rotational force and add it to the torque + // accumulator. I and invI are a vertical stack of 3x4 matrices, one per body. + dRealAllocaArray (I,3*4*nb); + dRealAllocaArray (invI,3*4*nb); +/* for (i=0; i<nb; i++) { + dMatrix3 tmp; + // compute inertia tensor in global frame + dMULTIPLY2_333 (tmp,body[i]->m_I,body[i]->m_R); + // compute inverse inertia tensor in global frame + dMULTIPLY2_333 (tmp,body[i]->m_invI,body[i]->m_R); + dMULTIPLY0_333 (invI+i*12,body[i]->m_R,tmp); + // compute rotational force + dCROSS (body[i]->m_tacc,-=,body[i]->getAngularVelocity(),tmp); + } +*/ + for (i=0; i<nb; i++) { + dMatrix3 tmp; + // compute inertia tensor in global frame + dMULTIPLY2_333 (tmp,body[i]->m_I,body[i]->m_R); + dMULTIPLY0_333 (I+i*12,body[i]->m_R,tmp); + // compute inverse inertia tensor in global frame + dMULTIPLY2_333 (tmp,body[i]->m_invI,body[i]->m_R); + dMULTIPLY0_333 (invI+i*12,body[i]->m_R,tmp); + // compute rotational force + dMULTIPLY0_331 (tmp,I+i*12,body[i]->getAngularVelocity()); + //dCROSS (body[i]->tacc,-=,body[i]->avel,tmp); + dCROSS (body[i]->m_tacc,-=,body[i]->getAngularVelocity(),tmp); + + } + + + // get joint information (m = total constraint dimension, nub = number of unbounded variables). + // joints with m=0 are inactive and are removed from the joints array + // entirely, so that the code that follows does not consider them. + //@@@ do we really need to save all the info1's + BU_Joint::Info1 *info = (BU_Joint::Info1*) alloca (nj*sizeof(BU_Joint::Info1)); + for (i=0, j=0; j<nj; j++) { // i=dest, j=src + joint[j]->GetInfo1 (info+i); + dIASSERT (info[i].m >= 0 && info[i].m <= 6 && info[i].nub >= 0 && info[i].nub <= info[i].m); + if (info[i].m > 0) { + joint[i] = joint[j]; + i++; + } + } + nj = i; + + // create the row offset array + int m = 0; + int *ofs = (int*) alloca (nj*sizeof(int)); + for (i=0; i<nj; i++) { + ofs[i] = m; + m += info[i].m; + } + + // if there are constraints, compute the constraint force + dRealAllocaArray (J,m*12); + int *jb = (int*) alloca (m*2*sizeof(int)); + if (m > 0) { + // create a constraint equation right hand side vector `c', a constraint + // force mixing vector `cfm', and LCP low and high bound vectors, and an + // 'findex' vector. + dRealAllocaArray (c,m); + dRealAllocaArray (cfm,m); + dRealAllocaArray (lo,m); + dRealAllocaArray (hi,m); + int *findex = (int*) alloca (m*sizeof(int)); + dSetZero1 (c,m); + dSetValue1 (cfm,m,global_cfm); + dSetValue1 (lo,m,-dInfinity); + dSetValue1 (hi,m, dInfinity); + for (i=0; i<m; i++) findex[i] = -1; + + // get jacobian data from constraints. an m*12 matrix will be created + // to store the two jacobian blocks from each constraint. it has this + // format: + // + // l1 l1 l1 a1 a1 a1 l2 l2 l2 a2 a2 a2 \ . + // l1 l1 l1 a1 a1 a1 l2 l2 l2 a2 a2 a2 }-- jacobian for joint 0, body 1 and body 2 (3 rows) + // l1 l1 l1 a1 a1 a1 l2 l2 l2 a2 a2 a2 / + // l1 l1 l1 a1 a1 a1 l2 l2 l2 a2 a2 a2 }--- jacobian for joint 1, body 1 and body 2 (3 rows) + // etc... + // + // (lll) = linear jacobian data + // (aaa) = angular jacobian data + // + dSetZero1 (J,m*12); + BU_Joint::Info2 Jinfo; + Jinfo.rowskip = 12; + Jinfo.fps = stepsize1; + Jinfo.erp = global_erp; + for (i=0; i<nj; i++) { + Jinfo.J1l = J + ofs[i]*12; + Jinfo.J1a = Jinfo.J1l + 3; + Jinfo.J2l = Jinfo.J1l + 6; + Jinfo.J2a = Jinfo.J1l + 9; + Jinfo.c = c + ofs[i]; + Jinfo.cfm = cfm + ofs[i]; + Jinfo.lo = lo + ofs[i]; + Jinfo.hi = hi + ofs[i]; + Jinfo.findex = findex + ofs[i]; + joint[i]->GetInfo2 (&Jinfo); + + if (Jinfo.c[0] > solverInfo.m_maxErrorReduction) + Jinfo.c[0] = solverInfo.m_maxErrorReduction; + + + + + // adjust returned findex values for global index numbering + for (j=0; j<info[i].m; j++) { + if (findex[ofs[i] + j] >= 0) + findex[ofs[i] + j] += ofs[i]; + } + } + + // create an array of body numbers for each joint row + int *jb_ptr = jb; + for (i=0; i<nj; i++) { + int b1 = (joint[i]->node[0].body) ? (joint[i]->node[0].body->m_odeTag) : -1; + int b2 = (joint[i]->node[1].body) ? (joint[i]->node[1].body->m_odeTag) : -1; + for (j=0; j<info[i].m; j++) { + jb_ptr[0] = b1; + jb_ptr[1] = b2; + jb_ptr += 2; + } + } + dIASSERT (jb_ptr == jb+2*m); + + // compute the right hand side `rhs' + dRealAllocaArray (tmp1,nb*6); + // put v/h + invM*fe into tmp1 + for (i=0; i<nb; i++) { + SimdScalar body_invMass = body[i]->getInvMass(); + for (j=0; j<3; j++) tmp1[i*6+j] = body[i]->m_facc[j] * body_invMass + body[i]->getLinearVelocity()[j] * stepsize1; + dMULTIPLY0_331NEW (tmp1 + i*6 + 3,=,invI + i*12,body[i]->m_tacc); + for (j=0; j<3; j++) tmp1[i*6+3+j] += body[i]->getAngularVelocity()[j] * stepsize1; + } + + // put J*tmp1 into rhs + dRealAllocaArray (rhs,m); + multiply_J (m,J,jb,tmp1,rhs); + + // complete rhs + for (i=0; i<m; i++) rhs[i] = c[i]*stepsize1 - rhs[i]; + + // scale CFM + for (i=0; i<m; i++) + cfm[i] =0;//*= stepsize1; + + // load lambda from the value saved on the previous iteration + dRealAllocaArray (lambda,m); +#ifdef WARM_STARTING + dSetZero1 (lambda,m); //@@@ shouldn't be necessary + for (i=0; i<nj; i++) { + memcpy (lambda+ofs[i],joint[i]->lambda,info[i].m * sizeof(SimdScalar)); + } +#endif + + // solve the LCP problem and get lambda and invM*constraint_force + dRealAllocaArray (cforce,nb*6); + + SOR_LCP (m,nb,J,jb,body,invI,lambda,cforce,rhs,lo,hi,cfm,findex,numIter,sOr); + +#ifdef WARM_STARTING + // save lambda for the next iteration + //@@@ note that this doesn't work for contact joints yet, as they are + // recreated every iteration + for (i=0; i<nj; i++) { + memcpy (joint[i]->lambda,lambda+ofs[i],info[i].m * sizeof(SimdScalar)); + } +#endif + + + // note that the SOR method overwrites rhs and J at this point, so + // they should not be used again. + + // add stepsize * cforce to the body velocity + for (i=0; i<nb; i++) { + SimdVector3 linvel = body[i]->getLinearVelocity(); + SimdVector3 angvel = body[i]->getAngularVelocity(); + + for (j=0; j<3; j++) + linvel[j] += solverInfo.m_timeStep* cforce[i*6+j]; + for (j=0; j<3; j++) + angvel[j] += solverInfo.m_timeStep* cforce[i*6+3+j]; + + body[i]->setLinearVelocity(linvel); + body[i]->setAngularVelocity(angvel); + + } + + } + + + + // compute the velocity update: + // add stepsize * invM * fe to the body velocity + + for (i=0; i<nb; i++) { + SimdScalar body_invMass = body[i]->getInvMass(); + SimdVector3 linvel = body[i]->getLinearVelocity(); + SimdVector3 angvel = body[i]->getAngularVelocity(); + + for (j=0; j<3; j++) + { + linvel[j] += solverInfo.m_timeStep * body_invMass * body[i]->m_facc[j]; + } + for (j=0; j<3; j++) + { + body[i]->m_tacc[j] *= solverInfo.m_timeStep; + } + dMULTIPLY0_331NEW(angvel,+=,invI + i*12,body[i]->m_tacc); + body[i]->setAngularVelocity(angvel); + + } + + + +} + + +#endif //USE_SOR_SOLVER
\ No newline at end of file diff --git a/extern/bullet/BulletDynamics/ConstraintSolver/SorLcp.h b/extern/bullet/BulletDynamics/ConstraintSolver/SorLcp.h new file mode 100644 index 00000000000..64c2f04e29d --- /dev/null +++ b/extern/bullet/BulletDynamics/ConstraintSolver/SorLcp.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#define USE_SOR_SOLVER +#ifdef USE_SOR_SOLVER + +#ifndef SOR_LCP_H +#define SOR_LCP_H +class RigidBody; +class BU_Joint; +#include "SimdScalar.h" + +struct ContactSolverInfo; + +void SolveInternal1 (float global_cfm, + float global_erp, + RigidBody * const *body, int nb, + BU_Joint * const *_joint, int nj, const ContactSolverInfo& info); + +int dRandInt2 (int n); + + +#endif //SOR_LCP_H + +#endif //USE_SOR_SOLVER
\ No newline at end of file diff --git a/extern/bullet/BulletDynamics/Dynamics/BU_Joint.cpp b/extern/bullet/BulletDynamics/Dynamics/BU_Joint.cpp new file mode 100644 index 00000000000..431a1eedf18 --- /dev/null +++ b/extern/bullet/BulletDynamics/Dynamics/BU_Joint.cpp @@ -0,0 +1,10 @@ +#include "BU_Joint.h" + +BU_Joint::BU_Joint() +{ + +} +BU_Joint::~BU_Joint() +{ + +} diff --git a/extern/bullet/BulletDynamics/Dynamics/BU_Joint.h b/extern/bullet/BulletDynamics/Dynamics/BU_Joint.h new file mode 100644 index 00000000000..72536d6c2cf --- /dev/null +++ b/extern/bullet/BulletDynamics/Dynamics/BU_Joint.h @@ -0,0 +1,78 @@ +#ifndef BU_Joint_H +#define BU_Joint_H + +class RigidBody; +class BU_Joint; +#include "SimdScalar.h" + +struct BU_ContactJointNode { + BU_Joint *joint; // pointer to enclosing BU_Joint object + RigidBody*body; // *other* body this joint is connected to +}; +typedef SimdScalar dVector3[4]; + + +class BU_Joint { + +public: + // naming convention: the "first" body this is connected to is node[0].body, + // and the "second" body is node[1].body. if this joint is only connected + // to one body then the second body is 0. + + // info returned by getInfo1 function. the constraint dimension is m (<=6). + // i.e. that is the total number of rows in the jacobian. `nub' is the + // number of unbounded variables (which have lo,hi = -/+ infinity). + + BU_Joint(); + virtual ~BU_Joint(); + + + struct Info1 { + int m,nub; + }; + + // info returned by getInfo2 function + + struct Info2 { + // integrator parameters: frames per second (1/stepsize), default error + // reduction parameter (0..1). + SimdScalar fps,erp; + + // for the first and second body, pointers to two (linear and angular) + // n*3 jacobian sub matrices, stored by rows. these matrices will have + // been initialized to 0 on entry. if the second body is zero then the + // J2xx pointers may be 0. + SimdScalar *J1l,*J1a,*J2l,*J2a; + + // elements to jump from one row to the next in J's + int rowskip; + + // right hand sides of the equation J*v = c + cfm * lambda. cfm is the + // "constraint force mixing" vector. c is set to zero on entry, cfm is + // set to a constant value (typically very small or zero) value on entry. + SimdScalar *c,*cfm; + + // lo and hi limits for variables (set to -/+ infinity on entry). + SimdScalar *lo,*hi; + + // findex vector for variables. see the LCP solver interface for a + // description of what this does. this is set to -1 on entry. + // note that the returned indexes are relative to the first index of + // the constraint. + int *findex; + }; + + // virtual function table: size of the joint structure, function pointers. + // we do it this way instead of using C++ virtual functions because + // sometimes we need to allocate joints ourself within a memory pool. + + virtual void GetInfo1 (Info1 *info)=0; + virtual void GetInfo2 (Info2 *info)=0; + + int flags; // dJOINT_xxx flags + BU_ContactJointNode node[2]; // connections to bodies. node[1].body can be 0 + SimdScalar lambda[6]; // lambda generated by last step +}; + + +#endif //BU_Joint_H diff --git a/extern/bullet/BulletDynamics/Dynamics/ContactJoint.cpp b/extern/bullet/BulletDynamics/Dynamics/ContactJoint.cpp new file mode 100644 index 00000000000..130a6b98402 --- /dev/null +++ b/extern/bullet/BulletDynamics/Dynamics/ContactJoint.cpp @@ -0,0 +1,233 @@ +#include "ContactJoint.h" +#include "RigidBody.h" +#include "NarrowPhaseCollision/PersistentManifold.h" + + + +ContactJoint::ContactJoint(PersistentManifold* manifold,int index,bool swap,RigidBody* body0,RigidBody* body1) +:m_manifold(manifold), +m_index(index), +m_swapBodies(swap), +m_body0(body0), +m_body1(body1) +{ +} + +int m_numRows = 3; + +float gContactFrictionFactor = 30.5f;//100.f;//1e30f;//2.9f; + + + +void ContactJoint::GetInfo1(Info1 *info) +{ + info->m = m_numRows; + //friction adds another 2... + + info->nub = 0; +} + +#define dCROSS(a,op,b,c) \ + (a)[0] op ((b)[1]*(c)[2] - (b)[2]*(c)[1]); \ + (a)[1] op ((b)[2]*(c)[0] - (b)[0]*(c)[2]); \ + (a)[2] op ((b)[0]*(c)[1] - (b)[1]*(c)[0]); + +#define M_SQRT12 SimdScalar(0.7071067811865475244008443621048490) + +#define dRecipSqrt(x) ((float)(1.0f/sqrtf(float(x)))) /* reciprocal square root */ + + + +void dPlaneSpace1 (const dVector3 n, dVector3 p, dVector3 q) +{ + if (fabsf(n[2]) > M_SQRT12) { + // choose p in y-z plane + SimdScalar a = n[1]*n[1] + n[2]*n[2]; + SimdScalar k = dRecipSqrt (a); + p[0] = 0; + p[1] = -n[2]*k; + p[2] = n[1]*k; + // set q = n x p + q[0] = a*k; + q[1] = -n[0]*p[2]; + q[2] = n[0]*p[1]; + } + else { + // choose p in x-y plane + SimdScalar a = n[0]*n[0] + n[1]*n[1]; + SimdScalar k = dRecipSqrt (a); + p[0] = -n[1]*k; + p[1] = n[0]*k; + p[2] = 0; + // set q = n x p + q[0] = -n[2]*p[1]; + q[1] = n[2]*p[0]; + q[2] = a*k; + } +} + + + +void ContactJoint::GetInfo2(Info2 *info) +{ + + int s = info->rowskip; + int s2 = 2*s; + + float swapFactor = m_swapBodies ? -1.f : 1.f; + + // get normal, with sign adjusted for body1/body2 polarity + dVector3 normal; + + + ManifoldPoint& point = m_manifold->GetContactPoint(m_index); + + normal[0] = swapFactor*point.m_normalWorldOnB[0]; + normal[1] = swapFactor*point.m_normalWorldOnB[1]; + normal[2] = swapFactor*point.m_normalWorldOnB[2]; + normal[3] = 0; // @@@ hmmm + + // if (GetBody0()) + SimdVector3 ccc1; + { + ccc1 = point.GetPositionWorldOnA() - m_body0->getCenterOfMassPosition(); + dVector3 c1; + c1[0] = ccc1[0]; + c1[1] = ccc1[1]; + c1[2] = ccc1[2]; + + // set jacobian for normal + info->J1l[0] = normal[0]; + info->J1l[1] = normal[1]; + info->J1l[2] = normal[2]; + dCROSS (info->J1a,=,c1,normal); + + } + // if (GetBody1()) + SimdVector3 ccc2; + { + dVector3 c2; + ccc2 = point.GetPositionWorldOnB() - m_body1->getCenterOfMassPosition(); + + // for (i=0; i<3; i++) c2[i] = j->contact.geom.pos[i] - + // j->node[1].body->pos[i]; + c2[0] = ccc2[0]; + c2[1] = ccc2[1]; + c2[2] = ccc2[2]; + + info->J2l[0] = -normal[0]; + info->J2l[1] = -normal[1]; + info->J2l[2] = -normal[2]; + dCROSS (info->J2a,= -,c2,normal); + } + + SimdScalar k = info->fps * info->erp; + + float depth = -point.GetDistance(); + if (depth < 0.f) + depth = 0.f; + + info->c[0] = k * depth; + + + + // set LCP limits for normal + info->lo[0] = 0; + info->hi[0] = 1e30f;//dInfinity; + +#define DO_THE_FRICTION_2 +#ifdef DO_THE_FRICTION_2 + // now do jacobian for tangential forces + dVector3 t1,t2; // two vectors tangential to normal + + dVector3 c1; + c1[0] = ccc1[0]; + c1[1] = ccc1[1]; + c1[2] = ccc1[2]; + + dVector3 c2; + c2[0] = ccc2[0]; + c2[1] = ccc2[1]; + c2[2] = ccc2[2]; + // first friction direction + if (m_numRows >= 2) + { + + + + dPlaneSpace1 (normal,t1,t2); + + info->J1l[s+0] = t1[0]; + info->J1l[s+1] = t1[1]; + info->J1l[s+2] = t1[2]; + dCROSS (info->J1a+s,=,c1,t1); + if (1) { //j->node[1].body) { + info->J2l[s+0] = -t1[0]; + info->J2l[s+1] = -t1[1]; + info->J2l[s+2] = -t1[2]; + dCROSS (info->J2a+s,= -,c2,t1); + } + // set right hand side + if (0) {//j->contact.surface.mode & dContactMotion1) { + //info->c[1] = j->contact.surface.motion1; + } + // set LCP bounds and friction index. this depends on the approximation + // mode + //1e30f + + info->lo[1] = -gContactFrictionFactor;//-j->contact.surface.mu; + info->hi[1] = gContactFrictionFactor;//j->contact.surface.mu; + if (0)//j->contact.surface.mode & dContactApprox1_1) + info->findex[1] = 0; + + // set slip (constraint force mixing) + if (0)//j->contact.surface.mode & dContactSlip1) + { + // info->cfm[1] = j->contact.surface.slip1; + } + } + + // second friction direction + if (m_numRows >= 3) { + info->J1l[s2+0] = t2[0]; + info->J1l[s2+1] = t2[1]; + info->J1l[s2+2] = t2[2]; + dCROSS (info->J1a+s2,=,c1,t2); + if (1) { //j->node[1].body) { + info->J2l[s2+0] = -t2[0]; + info->J2l[s2+1] = -t2[1]; + info->J2l[s2+2] = -t2[2]; + dCROSS (info->J2a+s2,= -,c2,t2); + } + // set right hand side + if (0){//j->contact.surface.mode & dContactMotion2) { + //info->c[2] = j->contact.surface.motion2; + } + // set LCP bounds and friction index. this depends on the approximation + // mode + if (0){//j->contact.surface.mode & dContactMu2) { + //info->lo[2] = -j->contact.surface.mu2; + //info->hi[2] = j->contact.surface.mu2; + } + else { + info->lo[2] = -gContactFrictionFactor; + info->hi[2] = gContactFrictionFactor; + } + if (0)//j->contact.surface.mode & dContactApprox1_2) + + { + info->findex[2] = 0; + } + // set slip (constraint force mixing) + if (0) //j->contact.surface.mode & dContactSlip2) + + { + //info->cfm[2] = j->contact.surface.slip2; + + } + } + +#endif //DO_THE_FRICTION_2 + +} + diff --git a/extern/bullet/BulletDynamics/Dynamics/ContactJoint.h b/extern/bullet/BulletDynamics/Dynamics/ContactJoint.h new file mode 100644 index 00000000000..54cc5283da0 --- /dev/null +++ b/extern/bullet/BulletDynamics/Dynamics/ContactJoint.h @@ -0,0 +1,33 @@ +#ifndef CONTACT_JOINT_H +#define CONTACT_JOINT_H + +#include "BU_Joint.h" +class RigidBody; +class PersistentManifold; + +class ContactJoint : public BU_Joint +{ + PersistentManifold* m_manifold; + int m_index; + bool m_swapBodies; + RigidBody* m_body0; + RigidBody* m_body1; + + +public: + + ContactJoint() {}; + + ContactJoint(PersistentManifold* manifold,int index,bool swap,RigidBody* body0,RigidBody* body1); + + //BU_Joint interface for solver + + virtual void GetInfo1(Info1 *info); + + virtual void GetInfo2(Info2 *info); + + + + +}; +#endif //CONTACT_JOINT_H
\ No newline at end of file diff --git a/extern/bullet/BulletDynamics/Dynamics/MassProps.h b/extern/bullet/BulletDynamics/Dynamics/MassProps.h new file mode 100644 index 00000000000..892e1c0b9a8 --- /dev/null +++ b/extern/bullet/BulletDynamics/Dynamics/MassProps.h @@ -0,0 +1,18 @@ + +#ifndef MASS_PROPS_H +#define MASS_PROPS_H + +#include <SimdVector3.h> + +struct MassProps { + MassProps(float mass,const SimdVector3& inertiaLocal): + m_mass(mass), + m_inertiaLocal(inertiaLocal) + { + } + float m_mass; + SimdVector3 m_inertiaLocal; +}; + + +#endif
\ No newline at end of file diff --git a/extern/bullet/BulletDynamics/Dynamics/RigidBody.cpp b/extern/bullet/BulletDynamics/Dynamics/RigidBody.cpp new file mode 100644 index 00000000000..10dccd3dd20 --- /dev/null +++ b/extern/bullet/BulletDynamics/Dynamics/RigidBody.cpp @@ -0,0 +1,157 @@ +#include "RigidBody.h" +#include "MassProps.h" +#include "CollisionShapes/ConvexShape.h" +#include "GEN_minmax.h" +#include <SimdTransformUtil.h> + +float gRigidBodyDamping = 0.5f; +static int uniqueId = 0; + +RigidBody::RigidBody( const MassProps& massProps,SimdScalar linearDamping,SimdScalar angularDamping) +: m_collisionShape(0), + m_activationState1(1), + m_hitFraction(1.f), + m_gravity(0.0f, 0.0f, 0.0f), + m_linearDamping(0.f), + m_angularDamping(0.5f), + m_totalForce(0.0f, 0.0f, 0.0f), + m_totalTorque(0.0f, 0.0f, 0.0f), + m_linearVelocity(0.0f, 0.0f, 0.0f), + m_angularVelocity(0.f,0.f,0.f) + +{ + m_debugBodyId = uniqueId++; + + setMassProps(massProps.m_mass, massProps.m_inertiaLocal); + setDamping(linearDamping, angularDamping); + updateInertiaTensor(); + m_worldTransform.setIdentity(); + +} + +void RigidBody::setLinearVelocity(const SimdVector3& lin_vel) +{ + + m_linearVelocity = lin_vel; +} + + +void RigidBody::predictIntegratedTransform(SimdScalar timeStep,SimdTransform& predictedTransform) const +{ + SimdTransformUtil::IntegrateTransform(m_worldTransform,m_linearVelocity,m_angularVelocity,timeStep,predictedTransform); +} + + +void RigidBody::getAabb(SimdVector3& aabbMin,SimdVector3& aabbMax) const +{ + m_collisionShape ->GetAabb(m_worldTransform,aabbMin,aabbMax); +} + +void RigidBody::SetCollisionShape(CollisionShape* mink) +{ + m_collisionShape = mink; + SimdTransform ident; + ident.setIdentity(); + SimdVector3 aabbMin,aabbMax; + m_collisionShape ->GetAabb(ident,aabbMin,aabbMax); + SimdVector3 diag = (aabbMax-aabbMin)*0.5f; +} + + +void RigidBody::setGravity(const SimdVector3& acceleration) +{ + if (m_inverseMass != 0.0f) + { + m_gravity = acceleration * (1.0f / m_inverseMass); + } +} + +bool RigidBody::mergesSimulationIslands() const +{ + return ( getInvMass() != 0) ; +} + +void RigidBody::SetActivationState(int newState) +{ + m_activationState1 = newState; +} + + + +void RigidBody::setDamping(SimdScalar lin_damping, SimdScalar ang_damping) +{ + m_linearDamping = GEN_clamped(lin_damping, 0.0f, 1.0f); + m_angularDamping = GEN_clamped(ang_damping, 0.0f, 1.0f); +} + + + +#include <stdio.h> + +void RigidBody::applyForces(SimdScalar step) +{ + + applyCentralForce(m_gravity); + + m_linearVelocity *= GEN_clamped((1.f - step * m_linearDamping), 0.0f, 1.0f); + m_angularVelocity *= GEN_clamped((1.f - step * m_angularDamping), 0.0f, 1.0f); + +} + +void RigidBody::proceedToTransform(const SimdTransform& newTrans) +{ + setCenterOfMassTransform( newTrans ); +} + + +void RigidBody::setMassProps(SimdScalar mass, const SimdVector3& inertia) +{ + m_inverseMass = mass != 0.0f ? 1.0f / mass : 0.0f; + m_invInertiaLocal.setValue(inertia[0] != 0.0f ? 1.0f / inertia[0]: 0.0f, + inertia[1] != 0.0f ? 1.0f / inertia[1]: 0.0f, + inertia[2] != 0.0f ? 1.0f / inertia[2]: 0.0f); + +} + + + +void RigidBody::updateInertiaTensor() +{ + m_invInertiaTensorWorld = m_worldTransform.getBasis().scaled(m_invInertiaLocal) * m_worldTransform.getBasis().transpose(); +} + + +void RigidBody::integrateVelocities(SimdScalar step) +{ + m_linearVelocity += m_totalForce * (m_inverseMass * step); + m_angularVelocity += m_invInertiaTensorWorld * m_totalTorque * step; + +#define MAX_ANGVEL SIMD_HALF_PI + /// clamp angular velocity. collision calculations will fail on higher angular velocities + float angvel = m_angularVelocity.length(); + if (angvel*step > MAX_ANGVEL) + { + m_angularVelocity *= (MAX_ANGVEL/step) /angvel; + } + + clearForces(); +} + +SimdQuaternion RigidBody::getOrientation() const +{ + SimdQuaternion orn; + m_worldTransform.getBasis().getRotation(orn); + return orn; +} + + +void RigidBody::setCenterOfMassTransform(const SimdTransform& xform) +{ + m_worldTransform = xform; + +// m_worldTransform.getBasis().getRotation(m_orn1); + updateInertiaTensor(); +} + + + diff --git a/extern/bullet/BulletDynamics/Dynamics/RigidBody.h b/extern/bullet/BulletDynamics/Dynamics/RigidBody.h new file mode 100644 index 00000000000..ec7eb9a8678 --- /dev/null +++ b/extern/bullet/BulletDynamics/Dynamics/RigidBody.h @@ -0,0 +1,165 @@ +#ifndef RIGIDBODY_H +#define RIGIDBODY_H + +#include <vector> +#include <SimdPoint3.h> +#include <SimdTransform.h> + +class CollisionShape; +struct MassProps; +typedef SimdScalar dMatrix3[4*3]; + + +/// RigidBody class for RigidBody Dynamics +/// +class RigidBody { +public: + + RigidBody(const MassProps& massProps,SimdScalar linearDamping,SimdScalar angularDamping); + + void proceedToTransform(const SimdTransform& newTrans); + + bool mergesSimulationIslands() const; + + /// continuous collision detection needs prediction + void predictIntegratedTransform(SimdScalar step, SimdTransform& predictedTransform) const; + + void applyForces(SimdScalar step); + + void setGravity(const SimdVector3& acceleration); + + void setDamping(SimdScalar lin_damping, SimdScalar ang_damping); + + CollisionShape* GetCollisionShape() { return m_collisionShape; } + + void setMassProps(SimdScalar mass, const SimdVector3& inertia); + + SimdScalar getInvMass() const { return m_inverseMass; } + const SimdMatrix3x3& getInvInertiaTensorWorld() const { return m_invInertiaTensorWorld; } + + void integrateVelocities(SimdScalar step); + + void setCenterOfMassTransform(const SimdTransform& xform); + + void applyCentralForce(const SimdVector3& force) + { + m_totalForce += force; + } + + const SimdVector3& getInvInertiaDiagLocal() + { + return m_invInertiaLocal; + }; + + void setInvInertiaDiagLocal(const SimdVector3& diagInvInertia) + { + m_invInertiaLocal = diagInvInertia; + } + + void applyTorque(const SimdVector3& torque) + { + m_totalTorque += torque; + } + + void applyForce(const SimdVector3& force, const SimdVector3& rel_pos) + { + applyCentralForce(force); + applyTorque(rel_pos.cross(force)); + } + + void applyCentralImpulse(const SimdVector3& impulse) + { + m_linearVelocity += impulse * m_inverseMass; + } + + void applyTorqueImpulse(const SimdVector3& torque) + { + m_angularVelocity += m_invInertiaTensorWorld * torque; + + } + + void applyImpulse(const SimdVector3& impulse, const SimdVector3& rel_pos) + { + if (m_inverseMass != 0.f) + { + applyCentralImpulse(impulse); + applyTorqueImpulse(rel_pos.cross(impulse)); + } + } + + void clearForces() + { + m_totalForce.setValue(0.0f, 0.0f, 0.0f); + m_totalTorque.setValue(0.0f, 0.0f, 0.0f); + } + + void updateInertiaTensor(); + + const SimdPoint3& getCenterOfMassPosition() const { return m_worldTransform.getOrigin(); } + SimdQuaternion getOrientation() const; + + const SimdTransform& getCenterOfMassTransform() const { return m_worldTransform; } + const SimdVector3& getLinearVelocity() const { return m_linearVelocity; } + const SimdVector3& getAngularVelocity() const { return m_angularVelocity; } + + + void setLinearVelocity(const SimdVector3& lin_vel); + void setAngularVelocity(const SimdVector3& ang_vel) { m_angularVelocity = ang_vel; } + + SimdVector3 getVelocityInLocalPoint(const SimdVector3& rel_pos) const + { + return m_linearVelocity + m_angularVelocity.cross(rel_pos); + } + + void translate(const SimdVector3& v) + { + m_worldTransform.getOrigin() += v; + } + + void SetCollisionShape(CollisionShape* mink); + + void getAabb(SimdVector3& aabbMin,SimdVector3& aabbMax) const; + + int GetActivationState() const { return m_activationState1;} + void SetActivationState(int newState); + + +private: + SimdTransform m_worldTransform; + SimdMatrix3x3 m_invInertiaTensorWorld; + SimdVector3 m_gravity; + SimdVector3 m_invInertiaLocal; + SimdVector3 m_totalForce; + SimdVector3 m_totalTorque; + SimdQuaternion m_orn1; + + SimdVector3 m_linearVelocity; + + SimdVector3 m_angularVelocity; + + SimdScalar m_linearDamping; + SimdScalar m_angularDamping; + SimdScalar m_inverseMass; + + + CollisionShape* m_collisionShape; + + +public: + /// for ode solver-binding + dMatrix3 m_R;//temp + dMatrix3 m_I; + dMatrix3 m_invI; + int m_islandTag1;//temp + int m_activationState1;//temp + int m_odeTag; + SimdVector3 m_tacc;//temp + SimdVector3 m_facc; + SimdScalar m_hitFraction; //time of impact calculation + + int m_debugBodyId; +}; + + + +#endif diff --git a/extern/bullet/BulletLicense.txt b/extern/bullet/BulletLicense.txt new file mode 100644 index 00000000000..8405bef82e4 --- /dev/null +++ b/extern/bullet/BulletLicense.txt @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ + + +Free for commercial use, but please mail bullet@erwincoumans.com to report projects, and join the forum at +www.continuousphysics.com/Bullet/phpBB2 diff --git a/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysics.dsp b/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysics.dsp new file mode 100644 index 00000000000..48d42617d3d --- /dev/null +++ b/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysics.dsp @@ -0,0 +1,112 @@ +# Microsoft Developer Studio Project File - Name="CcdPhysics" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Static Library" 0x0104 + +CFG=CcdPhysics - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "CcdPhysics.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "CcdPhysics.mak" CFG="CcdPhysics - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "CcdPhysics - Win32 Release" (based on "Win32 (x86) Static Library") +!MESSAGE "CcdPhysics - Win32 Debug" (based on "Win32 (x86) Static Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "CcdPhysics - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "CcdPhysics___Win32_Release" +# PROP BASE Intermediate_Dir "CcdPhysics___Win32_Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "CcdPhysics___Win32_Release" +# PROP Intermediate_Dir "CcdPhysics___Win32_Release" +# PROP Target_Dir "" +LINK32=link.exe -lib +MTL=midl.exe +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "..\..\..\Bullet" /I "..\..\..\LinearMath" /I "..\..\..\BulletDynamics" /I "..\..\..\Extras\PhysicsInterface\Common" /I "..\..\..\Extras\PhysicsInterface\CcdPhysics" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ELSEIF "$(CFG)" == "CcdPhysics - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "CcdPhysics___Win32_Debug" +# PROP BASE Intermediate_Dir "CcdPhysics___Win32_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "CcdPhysics___Win32_Debug" +# PROP Intermediate_Dir "CcdPhysics___Win32_Debug" +# PROP Target_Dir "" +LINK32=link.exe -lib +MTL=midl.exe +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\..\..\Bullet" /I "..\..\..\LinearMath" /I "..\..\..\BulletDynamics" /I "..\..\..\Extras\PhysicsInterface\Common" /I "..\..\..\Extras\PhysicsInterface\CcdPhysics" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ENDIF + +# Begin Target + +# Name "CcdPhysics - Win32 Release" +# Name "CcdPhysics - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\CcdPhysicsController.cpp +# End Source File +# Begin Source File + +SOURCE=.\CcdPhysicsEnvironment.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\CcdPhysicsController.h +# End Source File +# Begin Source File + +SOURCE=.\CcdPhysicsEnvironment.h +# End Source File +# End Group +# End Target +# End Project diff --git a/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsController.cpp b/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsController.cpp new file mode 100644 index 00000000000..376a75f40d3 --- /dev/null +++ b/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsController.cpp @@ -0,0 +1,230 @@ +#include "CcdPhysicsController.h" + +#include "Dynamics/RigidBody.h" +#include "PHY_IMotionState.h" +#include "BroadphaseCollision/BroadphaseProxy.h" +#include "CollisionShapes/ConvexShape.h" + +class BP_Proxy; + +bool gEnableSleeping = true;//false;//true; +#include "Dynamics/MassProps.h" + +SimdVector3 startVel(0,0,0);//-10000); +CcdPhysicsController::CcdPhysicsController (const CcdConstructionInfo& ci) +{ + m_collisionDelay = 0; + + m_sleepingCounter = 0; + + m_MotionState = ci.m_MotionState; + + + SimdTransform trans; + float tmp[3]; + m_MotionState->getWorldPosition(tmp[0],tmp[1],tmp[2]); + trans.setOrigin(SimdVector3(tmp[0],tmp[1],tmp[2])); + + SimdQuaternion orn; + m_MotionState->getWorldOrientation(orn[0],orn[1],orn[2],orn[3]); + trans.setRotation(orn); + + MassProps mp(ci.m_mass, ci.m_localInertiaTensor); + + m_body = new RigidBody(mp,0,0); + + m_broadphaseHandle = ci.m_broadphaseHandle; + + m_collisionShape = ci.m_collisionShape; + + // + // init the rigidbody properly + // + + m_body->setMassProps(ci.m_mass, ci.m_localInertiaTensor); + m_body->setGravity( ci.m_gravity); + + m_friction = ci.m_friction; + m_restitution = ci.m_restitution; + + m_body->setDamping(ci.m_linearDamping, ci.m_angularDamping); + + + m_body->setCenterOfMassTransform( trans ); + + #ifdef WIN32 + if (m_body->getInvMass()) + m_body->setLinearVelocity(startVel); + #endif + +} + +CcdPhysicsController::~CcdPhysicsController() +{ + //will be reference counted, due to sharing + //delete m_collisionShape; + delete m_MotionState; + delete m_body; +} + + /** + SynchronizeMotionStates ynchronizes dynas, kinematic and deformable entities (and do 'late binding') + */ +bool CcdPhysicsController::SynchronizeMotionStates(float time) +{ + const SimdVector3& worldPos = m_body->getCenterOfMassPosition(); + m_MotionState->setWorldPosition(worldPos[0],worldPos[1],worldPos[2]); + + const SimdQuaternion& worldquat = m_body->getOrientation(); + m_MotionState->setWorldOrientation(worldquat[0],worldquat[1],worldquat[2],worldquat[3]); + + m_MotionState->calculateWorldTransformations(); + + float scale[3]; + m_MotionState->getWorldScaling(scale[0],scale[1],scale[2]); + + SimdVector3 scaling(scale[0],scale[1],scale[2]); + m_collisionShape->setLocalScaling(scaling); + + + return true; +} + + /** + WriteMotionStateToDynamics synchronizes dynas, kinematic and deformable entities (and do 'late binding') + */ + +void CcdPhysicsController::WriteMotionStateToDynamics(bool nondynaonly) +{ + +} +void CcdPhysicsController::WriteDynamicsToMotionState() +{ +} + // controller replication +void CcdPhysicsController::PostProcessReplica(class PHY_IMotionState* motionstate,class PHY_IPhysicsController* parentctrl) +{ +} + + // kinematic methods +void CcdPhysicsController::RelativeTranslate(float dlocX,float dlocY,float dlocZ,bool local) +{ + SimdTransform xform = m_body->getCenterOfMassTransform(); + xform.setOrigin(xform.getOrigin() + SimdVector3(dlocX,dlocY,dlocZ)); + this->m_body->setCenterOfMassTransform(xform); + +} + +void CcdPhysicsController::RelativeRotate(const float drot[9],bool local) +{ +} +void CcdPhysicsController::getOrientation(float &quatImag0,float &quatImag1,float &quatImag2,float &quatReal) +{ +} +void CcdPhysicsController::setOrientation(float quatImag0,float quatImag1,float quatImag2,float quatReal) +{ +} +void CcdPhysicsController::setPosition(float posX,float posY,float posZ) +{ +} +void CcdPhysicsController::resolveCombinedVelocities(float linvelX,float linvelY,float linvelZ,float angVelX,float angVelY,float angVelZ) +{ +} + +void CcdPhysicsController::getPosition(PHY__Vector3& pos) const +{ + assert(0); +} + +void CcdPhysicsController::setScaling(float scaleX,float scaleY,float scaleZ) +{ +} + + // physics methods +void CcdPhysicsController::ApplyTorque(float torqueX,float torqueY,float torqueZ,bool local) +{ +} +void CcdPhysicsController::ApplyForce(float forceX,float forceY,float forceZ,bool local) +{ +} +void CcdPhysicsController::SetAngularVelocity(float ang_velX,float ang_velY,float ang_velZ,bool local) +{ + SimdVector3 angvel(ang_velX,ang_velY,ang_velZ); + + m_body->setAngularVelocity(angvel); + +} +void CcdPhysicsController::SetLinearVelocity(float lin_velX,float lin_velY,float lin_velZ,bool local) +{ + + SimdVector3 linVel(lin_velX,lin_velY,lin_velZ); + m_body->setLinearVelocity(linVel); +} +void CcdPhysicsController::applyImpulse(float attachX,float attachY,float attachZ, float impulseX,float impulseY,float impulseZ) +{ +} +void CcdPhysicsController::SetActive(bool active) +{ +} + // reading out information from physics +void CcdPhysicsController::GetLinearVelocity(float& linvX,float& linvY,float& linvZ) +{ +} +void CcdPhysicsController::GetVelocity(const float posX,const float posY,const float posZ,float& linvX,float& linvY,float& linvZ) +{ +} +void CcdPhysicsController::getReactionForce(float& forceX,float& forceY,float& forceZ) +{ +} + + // dyna's that are rigidbody are free in orientation, dyna's with non-rigidbody are restricted +void CcdPhysicsController::setRigidBody(bool rigid) +{ +} + + // clientinfo for raycasts for example +void* CcdPhysicsController::getNewClientInfo() +{ + return 0; +} +void CcdPhysicsController::setNewClientInfo(void* clientinfo) +{ + +} + +#ifdef WIN32 +float gSleepingTreshold = 0.8f; +float gAngularSleepingTreshold = 1.f; + +#else + +float gSleepingTreshold = 0.8f; +float gAngularSleepingTreshold = 1.0f; +#endif + + +bool CcdPhysicsController::wantsSleeping() +{ + + if (!gEnableSleeping) + return false; + + if ( (m_body->GetActivationState() == 3) || (m_body->GetActivationState() == 2)) + return true; + + if ((m_body->getLinearVelocity().length2() < gSleepingTreshold*gSleepingTreshold) && + (m_body->getAngularVelocity().length2() < gAngularSleepingTreshold*gAngularSleepingTreshold)) + { + m_sleepingCounter++; + } else + { + m_sleepingCounter=0; + } + + if (m_sleepingCounter> 150) + { + return true; + } + return false; +} + diff --git a/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsController.h b/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsController.h new file mode 100644 index 00000000000..3a8590e261c --- /dev/null +++ b/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsController.h @@ -0,0 +1,133 @@ + +#ifndef BULLET2_PHYSICSCONTROLLER_H +#define BULLET2_PHYSICSCONTROLLER_H + +#include "PHY_IPhysicsController.h" + +/// PHY_IPhysicsController is the abstract simplified Interface to a physical object. +/// It contains the IMotionState and IDeformableMesh Interfaces. +#include "SimdVector3.h" +#include "SimdScalar.h" +class CollisionShape; + +struct CcdConstructionInfo +{ + CcdConstructionInfo() + : m_gravity(0,0,0), + m_mass(0.f), + m_friction(0.1f), + m_restitution(0.1f), + m_linearDamping(0.1f), + m_angularDamping(0.1f), + m_MotionState(0), + m_collisionShape(0) + + { + } + SimdVector3 m_localInertiaTensor; + SimdVector3 m_gravity; + SimdScalar m_mass; + SimdScalar m_friction; + SimdScalar m_restitution; + + SimdScalar m_linearDamping; + SimdScalar m_angularDamping; + void* m_broadphaseHandle; + class PHY_IMotionState* m_MotionState; + + CollisionShape* m_collisionShape; + +}; + + +class RigidBody; + +///CcdPhysicsController is a physics object that supports continuous collision detection and time of impact based physics resolution. +class CcdPhysicsController : public PHY_IPhysicsController +{ + RigidBody* m_body; + class PHY_IMotionState* m_MotionState; + CollisionShape* m_collisionShape; + + int m_sleepingCounter; + public: + + int m_collisionDelay; + + SimdScalar m_friction; + SimdScalar m_restitution; + void* m_broadphaseHandle; + + CcdPhysicsController (const CcdConstructionInfo& ci); + + virtual ~CcdPhysicsController(); + + + RigidBody* GetRigidBody() { return m_body;} + + CollisionShape* GetCollisionShape() { return m_collisionShape;} + //////////////////////////////////// + // PHY_IPhysicsController interface + //////////////////////////////////// + + + /** + SynchronizeMotionStates ynchronizes dynas, kinematic and deformable entities (and do 'late binding') + */ + virtual bool SynchronizeMotionStates(float time); + /** + WriteMotionStateToDynamics ynchronizes dynas, kinematic and deformable entities (and do 'late binding') + */ + + virtual void WriteMotionStateToDynamics(bool nondynaonly); + virtual void WriteDynamicsToMotionState(); + // controller replication + virtual void PostProcessReplica(class PHY_IMotionState* motionstate,class PHY_IPhysicsController* parentctrl); + + // kinematic methods + virtual void RelativeTranslate(float dlocX,float dlocY,float dlocZ,bool local); + virtual void RelativeRotate(const float drot[9],bool local); + virtual void getOrientation(float &quatImag0,float &quatImag1,float &quatImag2,float &quatReal); + virtual void setOrientation(float quatImag0,float quatImag1,float quatImag2,float quatReal); + virtual void setPosition(float posX,float posY,float posZ); + virtual void getPosition(PHY__Vector3& pos) const; + + virtual void setScaling(float scaleX,float scaleY,float scaleZ); + + // physics methods + virtual void ApplyTorque(float torqueX,float torqueY,float torqueZ,bool local); + virtual void ApplyForce(float forceX,float forceY,float forceZ,bool local); + virtual void SetAngularVelocity(float ang_velX,float ang_velY,float ang_velZ,bool local); + virtual void SetLinearVelocity(float lin_velX,float lin_velY,float lin_velZ,bool local); + virtual void applyImpulse(float attachX,float attachY,float attachZ, float impulseX,float impulseY,float impulseZ); + virtual void SetActive(bool active); + + // reading out information from physics + virtual void GetLinearVelocity(float& linvX,float& linvY,float& linvZ); + virtual void GetVelocity(const float posX,const float posY,const float posZ,float& linvX,float& linvY,float& linvZ); + virtual void getReactionForce(float& forceX,float& forceY,float& forceZ); + + // dyna's that are rigidbody are free in orientation, dyna's with non-rigidbody are restricted + virtual void setRigidBody(bool rigid); + + + virtual void resolveCombinedVelocities(float linvelX,float linvelY,float linvelZ,float angVelX,float angVelY,float angVelZ); + + // clientinfo for raycasts for example + virtual void* getNewClientInfo(); + virtual void setNewClientInfo(void* clientinfo); + virtual PHY_IPhysicsController* GetReplica() {return 0;} + + virtual void calcXform() {} ; + virtual void SetMargin(float margin) {}; + virtual float GetMargin() const {return 0.f;}; + + + bool wantsSleeping(); + + void SetAabb(const SimdVector3& aabbMin,const SimdVector3& aabbMax); + + +}; + +#endif //BULLET2_PHYSICSCONTROLLER_H diff --git a/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsEnvironment.h b/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsEnvironment.h new file mode 100644 index 00000000000..88cf4b495cf --- /dev/null +++ b/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsEnvironment.h @@ -0,0 +1,121 @@ +#ifndef CCDPHYSICSENVIRONMENT +#define CCDPHYSICSENVIRONMENT + +#include "PHY_IPhysicsEnvironment.h" +#include <vector> +class CcdPhysicsController; +#include "SimdVector3.h" + +struct PHY_IPhysicsDebugDraw +{ + virtual void DrawLine(const SimdVector3& from,const SimdVector3& to,const SimdVector3& color)=0; +}; + + +class Point2PointConstraint; +class ToiContactDispatcher; +class Dispatcher; +//#include "BroadphaseInterface.h" + +class Vehicle; +class PersistentManifold; +class BroadphaseInterface; + +/// Physics Environment takes care of stepping the simulation and is a container for physics entities. +/// It stores rigidbodies,constraints, materials etc. +/// A derived class may be able to 'construct' entities by loading and/or converting +class CcdPhysicsEnvironment : public PHY_IPhysicsEnvironment +{ + SimdVector3 m_gravity; + BroadphaseInterface* m_broadphase; + PHY_IPhysicsDebugDraw* m_debugDrawer; + + public: + CcdPhysicsEnvironment(ToiContactDispatcher* dispatcher=0, BroadphaseInterface* broadphase=0); + + virtual ~CcdPhysicsEnvironment(); + + ///////////////////////////////////// + //PHY_IPhysicsEnvironment interface + ///////////////////////////////////// + + /// Perform an integration step of duration 'timeStep'. + + virtual void setDebugDrawer(PHY_IPhysicsDebugDraw* debugDrawer) + { + m_debugDrawer = debugDrawer; + } + + + virtual void beginFrame() {}; + virtual void endFrame() {}; + /// Perform an integration step of duration 'timeStep'. + virtual bool proceedDeltaTime(double curTime,float timeStep); + virtual void setFixedTimeStep(bool useFixedTimeStep,float fixedTimeStep){}; + //returns 0.f if no fixed timestep is used + virtual float getFixedTimeStep(){ return 0.f;}; + + virtual void setGravity(float x,float y,float z); + + virtual int createConstraint(class PHY_IPhysicsController* ctrl,class PHY_IPhysicsController* ctrl2,PHY_ConstraintType type, + float pivotX,float pivotY,float pivotZ, + float axisX,float axisY,float axisZ); + virtual void removeConstraint(int constraintid); + + + virtual PHY_IPhysicsController* rayTest(PHY_IPhysicsController* ignoreClient, float fromX,float fromY,float fromZ, float toX,float toY,float toZ, + float& hitX,float& hitY,float& hitZ,float& normalX,float& normalY,float& normalZ); + + + //Methods for gamelogic collision/physics callbacks + //todo: + virtual void addSensor(PHY_IPhysicsController* ctrl) {}; + virtual void removeSensor(PHY_IPhysicsController* ctrl){}; + virtual void addTouchCallback(int response_class, PHY_ResponseCallback callback, void *user){}; + virtual void requestCollisionCallback(PHY_IPhysicsController* ctrl){}; + virtual PHY_IPhysicsController* CreateSphereController(float radius,const PHY__Vector3& position) {return 0;}; + virtual PHY_IPhysicsController* CreateConeController(float coneradius,float coneheight){ return 0;}; + + + virtual int getNumContactPoints(); + + virtual void getContactPoint(int i,float& hitX,float& hitY,float& hitZ,float& normalX,float& normalY,float& normalZ); + + ////////////////////// + //CcdPhysicsEnvironment interface + //////////////////////// + + void addCcdPhysicsController(CcdPhysicsController* ctrl); + + void removeCcdPhysicsController(CcdPhysicsController* ctrl); + + BroadphaseInterface* GetBroadphase() { return m_broadphase; } + + Dispatcher* GetDispatcher(); + + int GetNumControllers(); + + CcdPhysicsController* GetPhysicsController( int index); + + int GetNumManifolds() const; + + const PersistentManifold* GetManifold(int index) const; + + private: + + void UpdateActivationState(); + void SyncMotionStates(float timeStep); + + std::vector<CcdPhysicsController*> m_controllers; + + std::vector<Point2PointConstraint*> m_p2pConstraints; + + std::vector<Vehicle*> m_vehicles; + + class ToiContactDispatcher* m_dispatcher; + + bool m_scalingPropagated; + +}; + +#endif //CCDPHYSICSENVIRONMENT diff --git a/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysics_vc7.vcproj b/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysics_vc7.vcproj new file mode 100644 index 00000000000..72f9dca3dd6 --- /dev/null +++ b/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysics_vc7.vcproj @@ -0,0 +1,131 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="7.10" + Name="CcdPhysics" + ProjectGUID="{E3D57F36-36AC-4E9A-B0E0-2AE4510FCBFE}" + Keyword="Win32Proj"> + <Platforms> + <Platform + Name="Win32"/> + </Platforms> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="4" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="..\Common;..\..\..\LinearMath;..\..\..\Bullet;..\..\..\BulletDynamics" + PreprocessorDefinitions="WIN32;_DEBUG;_LIB" + MinimalRebuild="TRUE" + BasicRuntimeChecks="3" + RuntimeLibrary="5" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="TRUE" + DebugInformationFormat="4"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/CcdPhysics.lib"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="4" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="..\Common;..\..\..\LinearMath;..\..\..\Bullet;..\..\..\BulletDynamics" + PreprocessorDefinitions="WIN32;NDEBUG;_LIB" + RuntimeLibrary="4" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="TRUE" + DebugInformationFormat="3"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/CcdPhysics.lib"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"> + <File + RelativePath=".\CcdPhysicsController.cpp"> + </File> + <File + RelativePath=".\CcdPhysicsEnvironment.cpp"> + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"> + <File + RelativePath=".\CcdPhysicsController.h"> + </File> + <File + RelativePath=".\CcdPhysicsEnvironment.h"> + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"> + </Filter> + <File + RelativePath=".\ReadMe.txt"> + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysics_vc8.vcproj b/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysics_vc8.vcproj new file mode 100644 index 00000000000..9204aff8adb --- /dev/null +++ b/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysics_vc8.vcproj @@ -0,0 +1,185 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="8.00" + Name="CcdPhysics" + ProjectGUID="{E3D57F36-36AC-4E9A-B0E0-2AE4510FCBFE}" + Keyword="Win32Proj" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="4" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="..\Common;..\..\..\LinearMath;..\..\..\Bullet;..\..\..\BulletDynamics" + PreprocessorDefinitions="WIN32;_DEBUG;_LIB" + MinimalRebuild="TRUE" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="TRUE" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/CcdPhysics.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="4" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="..\Common;..\..\..\LinearMath;..\..\..\Bullet;..\..\..\BulletDynamics" + PreprocessorDefinitions="WIN32;NDEBUG;_LIB" + RuntimeLibrary="0" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="TRUE" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/CcdPhysics.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\CcdPhysicsController.cpp" + > + </File> + <File + RelativePath=".\CcdPhysicsEnvironment.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath=".\CcdPhysicsController.h" + > + </File> + <File + RelativePath=".\CcdPhysicsEnvironment.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + <File + RelativePath=".\ReadMe.txt" + > + </File> + </Files> +</VisualStudioProject> diff --git a/extern/bullet/Extras/PhysicsInterface/Common/PHY_DynamicTypes.h b/extern/bullet/Extras/PhysicsInterface/Common/PHY_DynamicTypes.h new file mode 100644 index 00000000000..d85efa32829 --- /dev/null +++ b/extern/bullet/Extras/PhysicsInterface/Common/PHY_DynamicTypes.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2001-2005 Erwin Coumans <phy@erwincoumans.com> + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Erwin Coumans makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +#ifndef __PHY_DYNAMIC_TYPES +#define __PHY_DYNAMIC_TYPES + + + +class PHY_ResponseTable; + +class PHY_Shape; + +struct PHY__Vector3 +{ + float m_vec[4]; + operator const float* () const + { + return &m_vec[0]; + } + operator float* () + { + return &m_vec[0]; + } +}; +//typedef float PHY__Vector3[4]; + +typedef enum +{ + PHY_FH_RESPONSE, + PHY_SENSOR_RESPONSE, /* Touch Sensors */ + PHY_CAMERA_RESPONSE, /* Visibility Culling */ + PHY_OBJECT_RESPONSE, /* Object Dynamic Geometry Response */ + PHY_STATIC_RESPONSE, /* Static Geometry Response */ + + PHY_NUM_RESPONSE +}; + + typedef struct PHY_CollData { + PHY__Vector3 m_point1; /* Point in object1 in world coordinates */ + PHY__Vector3 m_point2; /* Point in object2 in world coordinates */ + PHY__Vector3 m_normal; /* point2 - point1 */ + } PHY_CollData; + + + typedef bool (*PHY_ResponseCallback)(void *client_data, + void *client_object1, + void *client_object2, + const PHY_CollData *coll_data); + + + +/// PHY_PhysicsType enumerates all possible Physics Entities. +/// It is mainly used to create/add Physics Objects + +typedef enum PHY_PhysicsType { + PHY_CONVEX_RIGIDBODY=16386, + PHY_CONCAVE_RIGIDBODY=16399, + PHY_CONVEX_FIXEDBODY=16388,//'collision object' + PHY_CONCAVE_FIXEDBODY=16401, + PHY_CONVEX_KINEMATICBODY=16387,// + PHY_CONCAVE_KINEMATICBODY=16400, + PHY_CONVEX_PHANTOMBODY=16398, + PHY_CONCAVE_PHANTOMBODY=16402 +} PHY_PhysicsType; + +/// PHY_ConstraintType enumerates all supported Constraint Types +typedef enum PHY_ConstraintType { + PHY_POINT2POINT_CONSTRAINT=1, + PHY_LINEHINGE_CONSTRAINT, + PHY_VEHICLE_CONSTRAINT + +} PHY_ConstraintType; + +typedef float PHY_Vector3[3]; + +#endif //__PHY_DYNAMIC_TYPES + diff --git a/extern/bullet/Extras/PhysicsInterface/Common/PHY_IMotionState.cpp b/extern/bullet/Extras/PhysicsInterface/Common/PHY_IMotionState.cpp new file mode 100644 index 00000000000..b8521ffaf87 --- /dev/null +++ b/extern/bullet/Extras/PhysicsInterface/Common/PHY_IMotionState.cpp @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2001-2005 Erwin Coumans <phy@erwincoumans.com> + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Erwin Coumans makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +#include "PHY_IMotionState.h" + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +PHY_IMotionState::~PHY_IMotionState() +{ + +} diff --git a/extern/bullet/Extras/PhysicsInterface/Common/PHY_IMotionState.h b/extern/bullet/Extras/PhysicsInterface/Common/PHY_IMotionState.h new file mode 100644 index 00000000000..a951ab60d60 --- /dev/null +++ b/extern/bullet/Extras/PhysicsInterface/Common/PHY_IMotionState.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2001-2005 Erwin Coumans <phy@erwincoumans.com> + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Erwin Coumans makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +#ifndef PHY__MOTIONSTATE_H +#define PHY__MOTIONSTATE_H + +/** + PHY_IMotionState is the Interface to explicitly synchronize the world transformation. + Default implementations for mayor graphics libraries like OpenGL and DirectX can be provided. +*/ +class PHY_IMotionState + +{ + public: + + virtual ~PHY_IMotionState(); + + virtual void getWorldPosition(float& posX,float& posY,float& posZ)=0; + virtual void getWorldScaling(float& scaleX,float& scaleY,float& scaleZ)=0; + virtual void getWorldOrientation(float& quatIma0,float& quatIma1,float& quatIma2,float& quatReal)=0; + + virtual void setWorldPosition(float posX,float posY,float posZ)=0; + virtual void setWorldOrientation(float quatIma0,float quatIma1,float quatIma2,float quatReal)=0; + + virtual void calculateWorldTransformations()=0; +}; + +#endif //PHY__MOTIONSTATE_H + diff --git a/extern/bullet/Extras/PhysicsInterface/Common/PHY_IPhysicsController.cpp b/extern/bullet/Extras/PhysicsInterface/Common/PHY_IPhysicsController.cpp new file mode 100644 index 00000000000..b051a45bd13 --- /dev/null +++ b/extern/bullet/Extras/PhysicsInterface/Common/PHY_IPhysicsController.cpp @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2001-2005 Erwin Coumans <phy@erwincoumans.com> + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Erwin Coumans makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +#include "PHY_IPhysicsController.h" + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +PHY_IPhysicsController::~PHY_IPhysicsController() +{ + +} + diff --git a/extern/bullet/Extras/PhysicsInterface/Common/PHY_IPhysicsController.h b/extern/bullet/Extras/PhysicsInterface/Common/PHY_IPhysicsController.h new file mode 100644 index 00000000000..4102754be21 --- /dev/null +++ b/extern/bullet/Extras/PhysicsInterface/Common/PHY_IPhysicsController.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2001-2005 Erwin Coumans <phy@erwincoumans.com> + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Erwin Coumans makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +#ifndef PHY_IPHYSICSCONTROLLER_H +#define PHY_IPHYSICSCONTROLLER_H + +#include "PHY_DynamicTypes.h" + +/** + PHY_IPhysicsController is the abstract simplified Interface to a physical object. + It contains the IMotionState and IDeformableMesh Interfaces. +*/ + + +class PHY_IPhysicsController +{ + + public: + + virtual ~PHY_IPhysicsController(); + /** + SynchronizeMotionStates ynchronizes dynas, kinematic and deformable entities (and do 'late binding') + */ + virtual bool SynchronizeMotionStates(float time)=0; + /** + WriteMotionStateToDynamics ynchronizes dynas, kinematic and deformable entities (and do 'late binding') + */ + + virtual void WriteMotionStateToDynamics(bool nondynaonly)=0; + virtual void WriteDynamicsToMotionState()=0; + // controller replication + virtual void PostProcessReplica(class PHY_IMotionState* motionstate,class PHY_IPhysicsController* parentctrl)=0; + + // kinematic methods + virtual void RelativeTranslate(float dlocX,float dlocY,float dlocZ,bool local)=0; + virtual void RelativeRotate(const float drot[12],bool local)=0; + virtual void getOrientation(float &quatImag0,float &quatImag1,float &quatImag2,float &quatReal)=0; + virtual void setOrientation(float quatImag0,float quatImag1,float quatImag2,float quatReal)=0; + virtual void setPosition(float posX,float posY,float posZ)=0; + virtual void getPosition(PHY__Vector3& pos) const=0; + virtual void setScaling(float scaleX,float scaleY,float scaleZ)=0; + + // physics methods + virtual void ApplyTorque(float torqueX,float torqueY,float torqueZ,bool local)=0; + virtual void ApplyForce(float forceX,float forceY,float forceZ,bool local)=0; + virtual void SetAngularVelocity(float ang_velX,float ang_velY,float ang_velZ,bool local)=0; + virtual void SetLinearVelocity(float lin_velX,float lin_velY,float lin_velZ,bool local)=0; + + virtual void applyImpulse(float attachX,float attachY,float attachZ, float impulseX,float impulseY,float impulseZ)=0; + virtual void SetActive(bool active)=0; + + // reading out information from physics + virtual void GetLinearVelocity(float& linvX,float& linvY,float& linvZ)=0; + virtual void GetVelocity(const float posX,const float posY,const float posZ,float& linvX,float& linvY,float& linvZ)=0; + virtual void getReactionForce(float& forceX,float& forceY,float& forceZ)=0; + + // dyna's that are rigidbody are free in orientation, dyna's with non-rigidbody are restricted + virtual void setRigidBody(bool rigid)=0; + + + // clientinfo for raycasts for example + virtual void* getNewClientInfo()=0; + virtual void setNewClientInfo(void* clientinfo)=0; + virtual PHY_IPhysicsController* GetReplica() {return 0;} + + virtual void calcXform() =0; + virtual void SetMargin(float margin) =0; + virtual float GetMargin() const=0; + virtual float GetRadius() const { return 0.f;} + PHY__Vector3 GetWorldPosition(PHY__Vector3& localpos); + +}; + +#endif //PHY_IPHYSICSCONTROLLER_H + diff --git a/extern/bullet/Extras/PhysicsInterface/Common/PHY_IPhysicsEnvironment.cpp b/extern/bullet/Extras/PhysicsInterface/Common/PHY_IPhysicsEnvironment.cpp new file mode 100644 index 00000000000..1794606edf3 --- /dev/null +++ b/extern/bullet/Extras/PhysicsInterface/Common/PHY_IPhysicsEnvironment.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2001-2005 Erwin Coumans <phy@erwincoumans.com> + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Erwin Coumans makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +#include "PHY_IPhysicsEnvironment.h" + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +/** +* Physics Environment takes care of stepping the simulation and is a container for physics entities (rigidbodies,constraints, materials etc.) +* A derived class may be able to 'construct' entities by loading and/or converting +*/ + + + +PHY_IPhysicsEnvironment::~PHY_IPhysicsEnvironment() +{ + +} diff --git a/extern/bullet/Extras/PhysicsInterface/Common/PHY_IPhysicsEnvironment.h b/extern/bullet/Extras/PhysicsInterface/Common/PHY_IPhysicsEnvironment.h new file mode 100644 index 00000000000..baa645b40a6 --- /dev/null +++ b/extern/bullet/Extras/PhysicsInterface/Common/PHY_IPhysicsEnvironment.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2001-2005 Erwin Coumans <phy@erwincoumans.com> + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Erwin Coumans makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ +#ifndef _IPHYSICSENVIRONMENT +#define _IPHYSICSENVIRONMENT + +#include <vector> +#include "PHY_DynamicTypes.h" + +/** +* Physics Environment takes care of stepping the simulation and is a container for physics entities (rigidbodies,constraints, materials etc.) +* A derived class may be able to 'construct' entities by loading and/or converting +*/ +class PHY_IPhysicsEnvironment +{ + public: + virtual ~PHY_IPhysicsEnvironment(); + /// Perform an integration step of duration 'timeStep'. + virtual bool proceedDeltaTime(double curTime,float timeStep)=0; + + + virtual void setGravity(float x,float y,float z)=0; + + virtual int createConstraint(class PHY_IPhysicsController* ctrl,class PHY_IPhysicsController* ctrl2,PHY_ConstraintType type, + float pivotX,float pivotY,float pivotZ, + float axisX,float axisY,float axisZ)=0; + virtual void removeConstraint(int constraintid)=0; + + virtual PHY_IPhysicsController* rayTest(PHY_IPhysicsController* ignoreClient, float fromX,float fromY,float fromZ, float toX,float toY,float toZ, + float& hitX,float& hitY,float& hitZ,float& normalX,float& normalY,float& normalZ)=0; + + + //Methods for gamelogic collision/physics callbacks + //todo: + virtual void addSensor(PHY_IPhysicsController* ctrl)=0; + virtual void removeSensor(PHY_IPhysicsController* ctrl)=0; + virtual void addTouchCallback(int response_class, PHY_ResponseCallback callback, void *user)=0; + virtual void requestCollisionCallback(PHY_IPhysicsController* ctrl)=0; + virtual PHY_IPhysicsController* CreateSphereController(float radius,const PHY__Vector3& position) =0; + virtual PHY_IPhysicsController* CreateConeController(float coneradius,float coneheight)=0; + +}; + +#endif //_IPHYSICSENVIRONMENT + diff --git a/extern/bullet/Extras/PhysicsInterface/Common/PHY_Pro.h b/extern/bullet/Extras/PhysicsInterface/Common/PHY_Pro.h new file mode 100644 index 00000000000..871cc64d375 --- /dev/null +++ b/extern/bullet/Extras/PhysicsInterface/Common/PHY_Pro.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2001-2005 Erwin Coumans <phy@erwincoumans.com> + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Erwin Coumans makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +#ifndef PHY_PROPSH +#define PHY_PROPSH + + +class CollisionShape; + +// Properties of dynamic objects +struct PHY_ShapeProps { + float m_mass; // Total mass + float m_inertia; // Inertia, should be a tensor some time + float m_lin_drag; // Linear drag (air, water) 0 = concrete, 1 = vacuum + float m_ang_drag; // Angular drag + float m_friction_scaling[3]; // Scaling for anisotropic friction. Component in range [0, 1] + bool m_do_anisotropic; // Should I do anisotropic friction? + bool m_do_fh; // Should the object have a linear Fh spring? + bool m_do_rot_fh; // Should the object have an angular Fh spring? + CollisionShape* m_shape; +}; + + +// Properties of collidable objects (non-ghost objects) +struct PHY_MaterialProps { + float m_restitution; // restitution of energie after a collision 0 = inelastic, 1 = elastic + float m_friction; // Coulomb friction (= ratio between the normal en maximum friction force) + float m_fh_spring; // Spring constant (both linear and angular) + float m_fh_damping; // Damping factor (linear and angular) in range [0, 1] + float m_fh_distance; // The range above the surface where Fh is active. + bool m_fh_normal; // Should the object slide off slopes? +}; + +#endif //PHY_PROPSH + diff --git a/extern/bullet/Extras/PhysicsInterface/Common/PhysicsInterface.dsp b/extern/bullet/Extras/PhysicsInterface/Common/PhysicsInterface.dsp new file mode 100644 index 00000000000..7617570f4a7 --- /dev/null +++ b/extern/bullet/Extras/PhysicsInterface/Common/PhysicsInterface.dsp @@ -0,0 +1,128 @@ +# Microsoft Developer Studio Project File - Name="PhysicsInterface" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Static Library" 0x0104 + +CFG=PhysicsInterface - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "PhysicsInterface.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "PhysicsInterface.mak" CFG="PhysicsInterface - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "PhysicsInterface - Win32 Release" (based on "Win32 (x86) Static Library") +!MESSAGE "PhysicsInterface - Win32 Debug" (based on "Win32 (x86) Static Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "PhysicsInterface - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +LINK32=link.exe -lib +MTL=midl.exe +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "..\..\..\LinearMath" /I "..\..\..\Extras\PhysicsInterface\Common" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ELSEIF "$(CFG)" == "PhysicsInterface - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +LINK32=link.exe -lib +MTL=midl.exe +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\..\..\LinearMath" /I "..\..\..\Extras\PhysicsInterface\Common" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ENDIF + +# Begin Target + +# Name "PhysicsInterface - Win32 Release" +# Name "PhysicsInterface - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\PHY_IMotionState.cpp +# End Source File +# Begin Source File + +SOURCE=.\PHY_IPhysicsController.cpp +# End Source File +# Begin Source File + +SOURCE=.\PHY_IPhysicsEnvironment.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\PHY_DynamicTypes.h +# End Source File +# Begin Source File + +SOURCE=.\PHY_IMotionState.h +# End Source File +# Begin Source File + +SOURCE=.\PHY_IPhysicsController.h +# End Source File +# Begin Source File + +SOURCE=.\PHY_IPhysicsEnvironment.h +# End Source File +# Begin Source File + +SOURCE=.\PHY_Pro.h +# End Source File +# End Group +# End Target +# End Project diff --git a/extern/bullet/Extras/PhysicsInterface/Common/PhysicsInterfaceCommon/PhysicsInterfaceCommon_vc7.vcproj b/extern/bullet/Extras/PhysicsInterface/Common/PhysicsInterfaceCommon/PhysicsInterfaceCommon_vc7.vcproj new file mode 100644 index 00000000000..a5c82f8774f --- /dev/null +++ b/extern/bullet/Extras/PhysicsInterface/Common/PhysicsInterfaceCommon/PhysicsInterfaceCommon_vc7.vcproj @@ -0,0 +1,143 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="7.10" + Name="PhysicsInterfaceCommon" + ProjectGUID="{87D8C006-6DCC-4156-A03E-8CEA1B4C0580}" + Keyword="Win32Proj"> + <Platforms> + <Platform + Name="Win32"/> + </Platforms> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="4" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="..\..\..\..\LinearMath" + PreprocessorDefinitions="WIN32;_DEBUG;_LIB" + MinimalRebuild="TRUE" + BasicRuntimeChecks="3" + RuntimeLibrary="5" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="TRUE" + DebugInformationFormat="4"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/PhysicsInterfaceCommon.lib"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="4" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="..\..\..\..\LinearMath" + PreprocessorDefinitions="WIN32;NDEBUG;_LIB" + RuntimeLibrary="4" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="TRUE" + DebugInformationFormat="3"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/PhysicsInterfaceCommon.lib"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"> + <File + RelativePath="..\PHY_IMotionState.cpp"> + </File> + <File + RelativePath="..\PHY_IPhysicsController.cpp"> + </File> + <File + RelativePath="..\PHY_IPhysicsEnvironment.cpp"> + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"> + <File + RelativePath="..\PHY_DynamicTypes.h"> + </File> + <File + RelativePath="..\PHY_IMotionState.h"> + </File> + <File + RelativePath="..\PHY_IPhysicsController.h"> + </File> + <File + RelativePath="..\PHY_IPhysicsEnvironment.h"> + </File> + <File + RelativePath="..\PHY_Pro.h"> + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"> + </Filter> + <File + RelativePath=".\ReadMe.txt"> + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/extern/bullet/Extras/PhysicsInterface/Common/PhysicsInterfaceCommon/PhysicsInterfaceCommon_vc8.vcproj b/extern/bullet/Extras/PhysicsInterface/Common/PhysicsInterfaceCommon/PhysicsInterfaceCommon_vc8.vcproj new file mode 100644 index 00000000000..4df99f6db2c --- /dev/null +++ b/extern/bullet/Extras/PhysicsInterface/Common/PhysicsInterfaceCommon/PhysicsInterfaceCommon_vc8.vcproj @@ -0,0 +1,201 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="8.00" + Name="PhysicsInterfaceCommon" + ProjectGUID="{87D8C006-6DCC-4156-A03E-8CEA1B4C0580}" + Keyword="Win32Proj" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="4" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="..\..\..\..\LinearMath" + PreprocessorDefinitions="WIN32;_DEBUG;_LIB" + MinimalRebuild="TRUE" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="TRUE" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/PhysicsInterfaceCommon.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="4" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="..\..\..\..\LinearMath" + PreprocessorDefinitions="WIN32;NDEBUG;_LIB" + RuntimeLibrary="0" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="TRUE" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/PhysicsInterfaceCommon.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath="..\PHY_IMotionState.cpp" + > + </File> + <File + RelativePath="..\PHY_IPhysicsController.cpp" + > + </File> + <File + RelativePath="..\PHY_IPhysicsEnvironment.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\PHY_DynamicTypes.h" + > + </File> + <File + RelativePath="..\PHY_IMotionState.h" + > + </File> + <File + RelativePath="..\PHY_IPhysicsController.h" + > + </File> + <File + RelativePath="..\PHY_IPhysicsEnvironment.h" + > + </File> + <File + RelativePath="..\PHY_Pro.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + <File + RelativePath=".\ReadMe.txt" + > + </File> + </Files> +</VisualStudioProject> diff --git a/extern/bullet/LinearMath/AabbUtil2.h b/extern/bullet/LinearMath/AabbUtil2.h new file mode 100644 index 00000000000..5b00f3bb25b --- /dev/null +++ b/extern/bullet/LinearMath/AabbUtil2.h @@ -0,0 +1,67 @@ +/* + +Copyright (c) 2005 Gino van den Bergen / Erwin Coumans <www.erwincoumans.com> + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +*/ + + +#ifndef AABB_UTIL2 +#define AABB_UTIL2 + +#include "SimdVector3.h" + +#define SimdMin(a,b) ((a < b ? a : b)) +#define SimdMax(a,b) ((a > b ? a : b)) + + +/// conservative test for overlap between two aabbs +SIMD_FORCE_INLINE bool TestAabbAgainstAabb2(const SimdVector3 &aabbMin1, const SimdVector3 &aabbMax1, + const SimdVector3 &aabbMin2, const SimdVector3 &aabbMax2) +{ + if (aabbMin1[0] > aabbMax2[0] || aabbMax1[0] < aabbMin2[0]) return false; + if (aabbMin1[2] > aabbMax2[2] || aabbMax1[2] < aabbMin2[2]) return false; + if (aabbMin1[1] > aabbMax2[1] || aabbMax1[1] < aabbMin2[1]) return false; + return true; +} + +/// conservative test for overlap between triangle and aabb +SIMD_FORCE_INLINE bool TestTriangleAgainstAabb2(const SimdVector3 *vertices, + const SimdVector3 &aabbMin, const SimdVector3 &aabbMax) +{ + const SimdVector3 &p1 = vertices[0]; + const SimdVector3 &p2 = vertices[1]; + const SimdVector3 &p3 = vertices[2]; + + if (SimdMin(SimdMin(p1[0], p2[0]), p3[0]) > aabbMax[0]) return false; + if (SimdMax(SimdMax(p1[0], p2[0]), p3[0]) < aabbMin[0]) return false; + + if (SimdMin(SimdMin(p1[2], p2[2]), p3[2]) > aabbMax[2]) return false; + if (SimdMax(SimdMax(p1[2], p2[2]), p3[2]) < aabbMin[2]) return false; + + if (SimdMin(SimdMin(p1[1], p2[1]), p3[1]) > aabbMax[1]) return false; + if (SimdMax(SimdMax(p1[1], p2[1]), p3[1]) < aabbMin[1]) return false; + return true; +} + +#endif
\ No newline at end of file diff --git a/extern/bullet/LinearMath/GEN_List.h b/extern/bullet/LinearMath/GEN_List.h new file mode 100644 index 00000000000..bbcf987b462 --- /dev/null +++ b/extern/bullet/LinearMath/GEN_List.h @@ -0,0 +1,85 @@ +/* + +Copyright (c) 2005 Gino van den Bergen / Erwin Coumans <www.erwincoumans.com> + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +*/ + + +#ifndef GEN_LIST_H +#define GEN_LIST_H + +class GEN_Link { +public: + GEN_Link() : m_next(0), m_prev(0) {} + GEN_Link(GEN_Link *next, GEN_Link *prev) : m_next(next), m_prev(prev) {} + + GEN_Link *getNext() const { return m_next; } + GEN_Link *getPrev() const { return m_prev; } + + bool isHead() const { return m_prev == 0; } + bool isTail() const { return m_next == 0; } + + void insertBefore(GEN_Link *link) { + m_next = link; + m_prev = link->m_prev; + m_next->m_prev = this; + m_prev->m_next = this; + } + + void insertAfter(GEN_Link *link) { + m_next = link->m_next; + m_prev = link; + m_next->m_prev = this; + m_prev->m_next = this; + } + + void remove() { + m_next->m_prev = m_prev; + m_prev->m_next = m_next; + } + +private: + GEN_Link *m_next; + GEN_Link *m_prev; +}; + +class GEN_List { +public: + GEN_List() : m_head(&m_tail, 0), m_tail(0, &m_head) {} + + GEN_Link *getHead() const { return m_head.getNext(); } + GEN_Link *getTail() const { return m_tail.getPrev(); } + + void addHead(GEN_Link *link) { link->insertAfter(&m_head); } + void addTail(GEN_Link *link) { link->insertBefore(&m_tail); } + +private: + GEN_Link m_head; + GEN_Link m_tail; +}; + +#endif + + + diff --git a/extern/bullet/LinearMath/GEN_MinMax.h b/extern/bullet/LinearMath/GEN_MinMax.h new file mode 100644 index 00000000000..c3ab24390f7 --- /dev/null +++ b/extern/bullet/LinearMath/GEN_MinMax.h @@ -0,0 +1,81 @@ +/* + +Copyright (c) 2005 Gino van den Bergen / Erwin Coumans <www.erwincoumans.com> + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +*/ + + +#ifndef GEN_MINMAX_H +#define GEN_MINMAX_H + +template <class T> +SIMD_FORCE_INLINE const T& GEN_min(const T& a, const T& b) +{ + return b < a ? b : a; +} + +template <class T> +SIMD_FORCE_INLINE const T& GEN_max(const T& a, const T& b) +{ + return a < b ? b : a; +} + +template <class T> +SIMD_FORCE_INLINE const T& GEN_clamped(const T& a, const T& lb, const T& ub) +{ + return a < lb ? lb : (ub < a ? ub : a); +} + +template <class T> +SIMD_FORCE_INLINE void GEN_set_min(T& a, const T& b) +{ + if (b < a) + { + a = b; + } +} + +template <class T> +SIMD_FORCE_INLINE void GEN_set_max(T& a, const T& b) +{ + if (a < b) + { + a = b; + } +} + +template <class T> +SIMD_FORCE_INLINE void GEN_clamp(T& a, const T& lb, const T& ub) +{ + if (a < lb) + { + a = lb; + } + else if (ub < a) + { + a = ub; + } +} + +#endif diff --git a/extern/bullet/LinearMath/GEN_random.h b/extern/bullet/LinearMath/GEN_random.h new file mode 100644 index 00000000000..22c77d827a2 --- /dev/null +++ b/extern/bullet/LinearMath/GEN_random.h @@ -0,0 +1,54 @@ +/* + +Copyright (c) 2005 Gino van den Bergen / Erwin Coumans <www.erwincoumans.com> + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +*/ + + +#ifndef GEN_RANDOM_H +#define GEN_RANDOM_H + +#ifdef MT19937 + +#include <limits.h> +#include <mt19937.h> + +#define GEN_RAND_MAX UINT_MAX + +SIMD_FORCE_INLINE void GEN_srand(unsigned int seed) { init_genrand(seed); } +SIMD_FORCE_INLINE unsigned int GEN_rand() { return genrand_int32(); } + +#else + +#include <stdlib.h> + +#define GEN_RAND_MAX RAND_MAX + +SIMD_FORCE_INLINE void GEN_srand(unsigned int seed) { srand(seed); } +SIMD_FORCE_INLINE unsigned int GEN_rand() { return rand(); } + +#endif + +#endif + diff --git a/extern/bullet/LinearMath/SimdMatrix3x3.h b/extern/bullet/LinearMath/SimdMatrix3x3.h new file mode 100644 index 00000000000..850e2f37dea --- /dev/null +++ b/extern/bullet/LinearMath/SimdMatrix3x3.h @@ -0,0 +1,407 @@ +/* + +Copyright (c) 2005 Gino van den Bergen / Erwin Coumans <www.erwincoumans.com> + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +*/ + +#ifndef SimdMatrix3x3_H +#define SimdMatrix3x3_H + +#include "SimdScalar.h" + +#include "SimdVector3.h" +#include "SimdQuaternion.h" + + +class SimdMatrix3x3 { + public: + SimdMatrix3x3 () {} + +// explicit SimdMatrix3x3(const SimdScalar *m) { setFromOpenGLSubMatrix(m); } + + explicit SimdMatrix3x3(const SimdQuaternion& q) { setRotation(q); } + /* + template <typename SimdScalar> + Matrix3x3(const SimdScalar& yaw, const SimdScalar& pitch, const SimdScalar& roll) + { + setEulerYPR(yaw, pitch, roll); + } + */ + SimdMatrix3x3(const SimdScalar& xx, const SimdScalar& xy, const SimdScalar& xz, + const SimdScalar& yx, const SimdScalar& yy, const SimdScalar& yz, + const SimdScalar& zx, const SimdScalar& zy, const SimdScalar& zz) + { + setValue(xx, xy, xz, + yx, yy, yz, + zx, zy, zz); + } + + SimdVector3 getColumn(int i) const + { + return SimdVector3(m_el[0][i],m_el[1][i],m_el[2][i]); + } + + const SimdVector3& getRow(int i) const + { + return m_el[i]; + } + + + SIMD_FORCE_INLINE SimdVector3& operator[](int i) + { + assert(0 <= i && i < 3); + return m_el[i]; + } + + const SimdVector3& operator[](int i) const + { + assert(0 <= i && i < 3); + return m_el[i]; + } + + SimdMatrix3x3& operator*=(const SimdMatrix3x3& m); + + + void setFromOpenGLSubMatrix(const SimdScalar *m) + { + m_el[0][0] = (m[0]); + m_el[1][0] = (m[1]); + m_el[2][0] = (m[2]); + m_el[0][1] = (m[4]); + m_el[1][1] = (m[5]); + m_el[2][1] = (m[6]); + m_el[0][2] = (m[8]); + m_el[1][2] = (m[9]); + m_el[2][2] = (m[10]); + } + + void setValue(const SimdScalar& xx, const SimdScalar& xy, const SimdScalar& xz, + const SimdScalar& yx, const SimdScalar& yy, const SimdScalar& yz, + const SimdScalar& zx, const SimdScalar& zy, const SimdScalar& zz) + { + m_el[0][0] = SimdScalar(xx); + m_el[0][1] = SimdScalar(xy); + m_el[0][2] = SimdScalar(xz); + m_el[1][0] = SimdScalar(yx); + m_el[1][1] = SimdScalar(yy); + m_el[1][2] = SimdScalar(yz); + m_el[2][0] = SimdScalar(zx); + m_el[2][1] = SimdScalar(zy); + m_el[2][2] = SimdScalar(zz); + } + + void setRotation(const SimdQuaternion& q) + { + SimdScalar d = q.length2(); + assert(d != SimdScalar(0.0)); + SimdScalar s = SimdScalar(2.0) / d; + SimdScalar xs = q[0] * s, ys = q[1] * s, zs = q[2] * s; + SimdScalar wx = q[3] * xs, wy = q[3] * ys, wz = q[3] * zs; + SimdScalar xx = q[0] * xs, xy = q[0] * ys, xz = q[0] * zs; + SimdScalar yy = q[1] * ys, yz = q[1] * zs, zz = q[2] * zs; + setValue(SimdScalar(1.0) - (yy + zz), xy - wz, xz + wy, + xy + wz, SimdScalar(1.0) - (xx + zz), yz - wx, + xz - wy, yz + wx, SimdScalar(1.0) - (xx + yy)); + } + + + + void setEulerYPR(const SimdScalar& yaw, const SimdScalar& pitch, const SimdScalar& roll) + { + + SimdScalar cy(cosf(yaw)); + SimdScalar sy(sinf(yaw)); + SimdScalar cp(cosf(pitch)); + SimdScalar sp(sinf(pitch)); + SimdScalar cr(cosf(roll)); + SimdScalar sr(sinf(roll)); + SimdScalar cc = cy * cr; + SimdScalar cs = cy * sr; + SimdScalar sc = sy * cr; + SimdScalar ss = sy * sr; + setValue(cc - sp * ss, -cs - sp * sc, -sy * cp, + cp * sr, cp * cr, -sp, + sc + sp * cs, -ss + sp * cc, cy * cp); + + } + + /** + * setEulerZYX + * @param euler a const reference to a SimdVector3 of euler angles + * These angles are used to produce a rotation matrix. The euler + * angles are applied in ZYX order. I.e a vector is first rotated + * about X then Y and then Z + **/ + + void setEulerZYX(SimdScalar eulerX,SimdScalar eulerY,SimdScalar eulerZ) { + SimdScalar ci ( cosf(eulerX)); + SimdScalar cj ( cosf(eulerY)); + SimdScalar ch ( cosf(eulerZ)); + SimdScalar si ( sinf(eulerX)); + SimdScalar sj ( sinf(eulerY)); + SimdScalar sh ( sinf(eulerZ)); + SimdScalar cc = ci * ch; + SimdScalar cs = ci * sh; + SimdScalar sc = si * ch; + SimdScalar ss = si * sh; + + setValue(cj * ch, sj * sc - cs, sj * cc + ss, + cj * sh, sj * ss + cc, sj * cs - sc, + -sj, cj * si, cj * ci); + } + + void setIdentity() + { + setValue(SimdScalar(1.0), SimdScalar(0.0), SimdScalar(0.0), + SimdScalar(0.0), SimdScalar(1.0), SimdScalar(0.0), + SimdScalar(0.0), SimdScalar(0.0), SimdScalar(1.0)); + } + + void getOpenGLSubMatrix(SimdScalar *m) const + { + m[0] = SimdScalar(m_el[0][0]); + m[1] = SimdScalar(m_el[1][0]); + m[2] = SimdScalar(m_el[2][0]); + m[3] = SimdScalar(0.0); + m[4] = SimdScalar(m_el[0][1]); + m[5] = SimdScalar(m_el[1][1]); + m[6] = SimdScalar(m_el[2][1]); + m[7] = SimdScalar(0.0); + m[8] = SimdScalar(m_el[0][2]); + m[9] = SimdScalar(m_el[1][2]); + m[10] = SimdScalar(m_el[2][2]); + m[11] = SimdScalar(0.0); + } + + void getRotation(SimdQuaternion& q) const + { + SimdScalar trace = m_el[0][0] + m_el[1][1] + m_el[2][2]; + + if (trace > SimdScalar(0.0)) + { + SimdScalar s = sqrtf(trace + SimdScalar(1.0)); + q[3] = s * SimdScalar(0.5); + s = SimdScalar(0.5) / s; + + q[0] = (m_el[2][1] - m_el[1][2]) * s; + q[1] = (m_el[0][2] - m_el[2][0]) * s; + q[2] = (m_el[1][0] - m_el[0][1]) * s; + } + else + { + int i = m_el[0][0] < m_el[1][1] ? + (m_el[1][1] < m_el[2][2] ? 2 : 1) : + (m_el[0][0] < m_el[2][2] ? 2 : 0); + int j = (i + 1) % 3; + int k = (i + 2) % 3; + + SimdScalar s = sqrtf(m_el[i][i] - m_el[j][j] - m_el[k][k] + SimdScalar(1.0)); + q[i] = s * SimdScalar(0.5); + s = SimdScalar(0.5) / s; + + q[3] = (m_el[k][j] - m_el[j][k]) * s; + q[j] = (m_el[j][i] + m_el[i][j]) * s; + q[k] = (m_el[k][i] + m_el[i][k]) * s; + } + } + + + + void getEuler(SimdScalar& yaw, SimdScalar& pitch, SimdScalar& roll) const + { + pitch = SimdScalar(asinf(-m_el[2][0])); + if (pitch < SIMD_2_PI) + { + if (pitch > SIMD_2_PI) + { + yaw = SimdScalar(atan2f(m_el[1][0], m_el[0][0])); + roll = SimdScalar(atan2f(m_el[2][1], m_el[2][2])); + } + else + { + yaw = SimdScalar(-atan2f(-m_el[0][1], m_el[0][2])); + roll = SimdScalar(0.0); + } + } + else + { + yaw = SimdScalar(atan2f(-m_el[0][1], m_el[0][2])); + roll = SimdScalar(0.0); + } + } + + SimdVector3 getScaling() const + { + return SimdVector3(m_el[0][0] * m_el[0][0] + m_el[1][0] * m_el[1][0] + m_el[2][0] * m_el[2][0], + m_el[0][1] * m_el[0][1] + m_el[1][1] * m_el[1][1] + m_el[2][1] * m_el[2][1], + m_el[0][2] * m_el[0][2] + m_el[1][2] * m_el[1][2] + m_el[2][2] * m_el[2][2]); + } + + + SimdMatrix3x3 scaled(const SimdVector3& s) const + { + return SimdMatrix3x3(m_el[0][0] * s[0], m_el[0][1] * s[1], m_el[0][2] * s[2], + m_el[1][0] * s[0], m_el[1][1] * s[1], m_el[1][2] * s[2], + m_el[2][0] * s[0], m_el[2][1] * s[1], m_el[2][2] * s[2]); + } + + SimdScalar determinant() const; + SimdMatrix3x3 adjoint() const; + SimdMatrix3x3 absolute() const; + SimdMatrix3x3 transpose() const; + SimdMatrix3x3 inverse() const; + + SimdMatrix3x3 transposeTimes(const SimdMatrix3x3& m) const; + SimdMatrix3x3 timesTranspose(const SimdMatrix3x3& m) const; + + SimdScalar tdot(int c, const SimdVector3& v) const + { + return m_el[0][c] * v[0] + m_el[1][c] * v[1] + m_el[2][c] * v[2]; + } + + protected: + SimdScalar cofac(int r1, int c1, int r2, int c2) const + { + return m_el[r1][c1] * m_el[r2][c2] - m_el[r1][c2] * m_el[r2][c1]; + } + + SimdVector3 m_el[3]; + }; + + SIMD_FORCE_INLINE SimdMatrix3x3& + SimdMatrix3x3::operator*=(const SimdMatrix3x3& m) + { + setValue(m.tdot(0, m_el[0]), m.tdot(1, m_el[0]), m.tdot(2, m_el[0]), + m.tdot(0, m_el[1]), m.tdot(1, m_el[1]), m.tdot(2, m_el[1]), + m.tdot(0, m_el[2]), m.tdot(1, m_el[2]), m.tdot(2, m_el[2])); + return *this; + } + + SIMD_FORCE_INLINE SimdScalar + SimdMatrix3x3::determinant() const + { + return triple((*this)[0], (*this)[1], (*this)[2]); + } + + + SIMD_FORCE_INLINE SimdMatrix3x3 + SimdMatrix3x3::absolute() const + { + return SimdMatrix3x3( + fabsf(m_el[0][0]), fabsf(m_el[0][1]), fabsf(m_el[0][2]), + fabsf(m_el[1][0]), fabsf(m_el[1][1]), fabsf(m_el[1][2]), + fabsf(m_el[2][0]), fabsf(m_el[2][1]), fabsf(m_el[2][2])); + } + + SIMD_FORCE_INLINE SimdMatrix3x3 + SimdMatrix3x3::transpose() const + { + return SimdMatrix3x3(m_el[0][0], m_el[1][0], m_el[2][0], + m_el[0][1], m_el[1][1], m_el[2][1], + m_el[0][2], m_el[1][2], m_el[2][2]); + } + + SIMD_FORCE_INLINE SimdMatrix3x3 + SimdMatrix3x3::adjoint() const + { + return SimdMatrix3x3(cofac(1, 1, 2, 2), cofac(0, 2, 2, 1), cofac(0, 1, 1, 2), + cofac(1, 2, 2, 0), cofac(0, 0, 2, 2), cofac(0, 2, 1, 0), + cofac(1, 0, 2, 1), cofac(0, 1, 2, 0), cofac(0, 0, 1, 1)); + } + + SIMD_FORCE_INLINE SimdMatrix3x3 + SimdMatrix3x3::inverse() const + { + SimdVector3 co(cofac(1, 1, 2, 2), cofac(1, 2, 2, 0), cofac(1, 0, 2, 1)); + SimdScalar det = (*this)[0].dot(co); + assert(det != SimdScalar(0.0f)); + SimdScalar s = SimdScalar(1.0f) / det; + return SimdMatrix3x3(co[0] * s, cofac(0, 2, 2, 1) * s, cofac(0, 1, 1, 2) * s, + co[1] * s, cofac(0, 0, 2, 2) * s, cofac(0, 2, 1, 0) * s, + co[2] * s, cofac(0, 1, 2, 0) * s, cofac(0, 0, 1, 1) * s); + } + + SIMD_FORCE_INLINE SimdMatrix3x3 + SimdMatrix3x3::transposeTimes(const SimdMatrix3x3& m) const + { + return SimdMatrix3x3( + m_el[0][0] * m[0][0] + m_el[1][0] * m[1][0] + m_el[2][0] * m[2][0], + m_el[0][0] * m[0][1] + m_el[1][0] * m[1][1] + m_el[2][0] * m[2][1], + m_el[0][0] * m[0][2] + m_el[1][0] * m[1][2] + m_el[2][0] * m[2][2], + m_el[0][1] * m[0][0] + m_el[1][1] * m[1][0] + m_el[2][1] * m[2][0], + m_el[0][1] * m[0][1] + m_el[1][1] * m[1][1] + m_el[2][1] * m[2][1], + m_el[0][1] * m[0][2] + m_el[1][1] * m[1][2] + m_el[2][1] * m[2][2], + m_el[0][2] * m[0][0] + m_el[1][2] * m[1][0] + m_el[2][2] * m[2][0], + m_el[0][2] * m[0][1] + m_el[1][2] * m[1][1] + m_el[2][2] * m[2][1], + m_el[0][2] * m[0][2] + m_el[1][2] * m[1][2] + m_el[2][2] * m[2][2]); + } + + SIMD_FORCE_INLINE SimdMatrix3x3 + SimdMatrix3x3::timesTranspose(const SimdMatrix3x3& m) const + { + return SimdMatrix3x3( + m_el[0].dot(m[0]), m_el[0].dot(m[1]), m_el[0].dot(m[2]), + m_el[1].dot(m[0]), m_el[1].dot(m[1]), m_el[1].dot(m[2]), + m_el[2].dot(m[0]), m_el[2].dot(m[1]), m_el[2].dot(m[2])); + + } + + SIMD_FORCE_INLINE SimdVector3 + operator*(const SimdMatrix3x3& m, const SimdVector3& v) + { + return SimdVector3(m[0].dot(v), m[1].dot(v), m[2].dot(v)); + } + + + SIMD_FORCE_INLINE SimdVector3 + operator*(const SimdVector3& v, const SimdMatrix3x3& m) + { + return SimdVector3(m.tdot(0, v), m.tdot(1, v), m.tdot(2, v)); + } + + SIMD_FORCE_INLINE SimdMatrix3x3 + operator*(const SimdMatrix3x3& m1, const SimdMatrix3x3& m2) + { + return SimdMatrix3x3( + m2.tdot(0, m1[0]), m2.tdot(1, m1[0]), m2.tdot(2, m1[0]), + m2.tdot(0, m1[1]), m2.tdot(1, m1[1]), m2.tdot(2, m1[1]), + m2.tdot(0, m1[2]), m2.tdot(1, m1[2]), m2.tdot(2, m1[2])); + } + + + SIMD_FORCE_INLINE SimdMatrix3x3 SimdMultTransposeLeft(const SimdMatrix3x3& m1, const SimdMatrix3x3& m2) { + return SimdMatrix3x3( + m1[0][0] * m2[0][0] + m1[1][0] * m2[1][0] + m1[2][0] * m2[2][0], + m1[0][0] * m2[0][1] + m1[1][0] * m2[1][1] + m1[2][0] * m2[2][1], + m1[0][0] * m2[0][2] + m1[1][0] * m2[1][2] + m1[2][0] * m2[2][2], + m1[0][1] * m2[0][0] + m1[1][1] * m2[1][0] + m1[2][1] * m2[2][0], + m1[0][1] * m2[0][1] + m1[1][1] * m2[1][1] + m1[2][1] * m2[2][1], + m1[0][1] * m2[0][2] + m1[1][1] * m2[1][2] + m1[2][1] * m2[2][2], + m1[0][2] * m2[0][0] + m1[1][2] * m2[1][0] + m1[2][2] * m2[2][0], + m1[0][2] * m2[0][1] + m1[1][2] * m2[1][1] + m1[2][2] * m2[2][1], + m1[0][2] * m2[0][2] + m1[1][2] * m2[1][2] + m1[2][2] * m2[2][2]); +} + + +#endif diff --git a/extern/bullet/LinearMath/SimdMinMax.h b/extern/bullet/LinearMath/SimdMinMax.h new file mode 100644 index 00000000000..999cfb0c919 --- /dev/null +++ b/extern/bullet/LinearMath/SimdMinMax.h @@ -0,0 +1,52 @@ +/* + +Copyright (c) 2005 Gino van den Bergen / Erwin Coumans <www.erwincoumans.com> + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +*/ + + +#ifndef SIMD_MINMAX_H +#define SIMD_MINMAX_H + +template <class T> +SIMD_FORCE_INLINE const T& SimdMin(const T& a, const T& b) { + return b < a ? b : a; +} + +template <class T> +SIMD_FORCE_INLINE const T& SimdMax(const T& a, const T& b) { + return a < b ? b : a; +} + +template <class T> +SIMD_FORCE_INLINE void SimdSetMin(T& a, const T& b) { + if (a > b) a = b; +} + +template <class T> +SIMD_FORCE_INLINE void SimdSetMax(T& a, const T& b) { + if (a < b) a = b; +} + +#endif diff --git a/extern/bullet/LinearMath/SimdPoint3.h b/extern/bullet/LinearMath/SimdPoint3.h new file mode 100644 index 00000000000..711ac5c76cc --- /dev/null +++ b/extern/bullet/LinearMath/SimdPoint3.h @@ -0,0 +1,36 @@ +/* + +Copyright (c) 2005 Gino van den Bergen / Erwin Coumans <www.erwincoumans.com> + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +*/ + + +#ifndef SimdPoint3_H +#define SimdPoint3_H + +#include "SimdVector3.h" + +typedef SimdVector3 SimdPoint3; + +#endif diff --git a/extern/bullet/LinearMath/SimdQuadWord.h b/extern/bullet/LinearMath/SimdQuadWord.h new file mode 100644 index 00000000000..cf720ef4b32 --- /dev/null +++ b/extern/bullet/LinearMath/SimdQuadWord.h @@ -0,0 +1,113 @@ +/* + +Copyright (c) 2005 Gino van den Bergen / Erwin Coumans <www.erwincoumans.com> + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +*/ + +#ifndef SIMD_QUADWORD_H +#define SIMD_QUADWORD_H + +#include "SimdScalar.h" + + + + + +class SimdQuadWord +{ + protected: + ATTRIBUTE_ALIGNED16 (SimdScalar m_x); + SimdScalar m_y; + SimdScalar m_z; + SimdScalar m_unusedW; + + public: + + SIMD_FORCE_INLINE SimdScalar& operator[](int i) { return (&m_x)[i]; } + SIMD_FORCE_INLINE const SimdScalar& operator[](int i) const { return (&m_x)[i]; } + + SIMD_FORCE_INLINE const SimdScalar& getX() const { return m_x; } + + SIMD_FORCE_INLINE const SimdScalar& getY() const { return m_y; } + + SIMD_FORCE_INLINE const SimdScalar& getZ() const { return m_z; } + + SIMD_FORCE_INLINE void setX(float x) { m_x = x;}; + + SIMD_FORCE_INLINE void setY(float y) { m_y = y;}; + + SIMD_FORCE_INLINE void setZ(float z) { m_z = z;}; + + SIMD_FORCE_INLINE const SimdScalar& x() const { return m_x; } + + SIMD_FORCE_INLINE const SimdScalar& y() const { return m_y; } + + SIMD_FORCE_INLINE const SimdScalar& z() const { return m_z; } + + + operator SimdScalar *() { return &m_x; } + operator const SimdScalar *() const { return &m_x; } + + SIMD_FORCE_INLINE void setValue(const SimdScalar& x, const SimdScalar& y, const SimdScalar& z) + { + m_x=x; + m_y=y; + m_z=z; + } + +/* void getValue(SimdScalar *m) const + { + m[0] = m_x; + m[1] = m_y; + m[2] = m_z; + } +*/ + SIMD_FORCE_INLINE void setValue(const SimdScalar& x, const SimdScalar& y, const SimdScalar& z,const SimdScalar& w) + { + m_x=x; + m_y=y; + m_z=z; + m_unusedW=w; + } + + SIMD_FORCE_INLINE SimdQuadWord() + { + } + + SIMD_FORCE_INLINE SimdQuadWord(const SimdScalar& x, const SimdScalar& y, const SimdScalar& z) + :m_x(x),m_y(y),m_z(z) + //todo, remove this in release/simd ? + ,m_unusedW(1e30f) + { + } + + SIMD_FORCE_INLINE SimdQuadWord(const SimdScalar& x, const SimdScalar& y, const SimdScalar& z,const SimdScalar& w) + :m_x(x),m_y(y),m_z(z),m_unusedW(w) + { + } + + +}; + +#endif //SIMD_QUADWORD_H diff --git a/extern/bullet/LinearMath/SimdQuaternion.h b/extern/bullet/LinearMath/SimdQuaternion.h new file mode 100644 index 00000000000..6a8513ae0d9 --- /dev/null +++ b/extern/bullet/LinearMath/SimdQuaternion.h @@ -0,0 +1,302 @@ +/* + +Copyright (c) 2005 Gino van den Bergen / Erwin Coumans <www.erwincoumans.com> + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +*/ + + +#ifndef SIMD__QUATERNION_H_ +#define SIMD__QUATERNION_H_ + +#include "SimdVector3.h" + +class SimdQuaternion : public SimdQuadWord { +public: + SimdQuaternion() {} + + // template <typename SimdScalar> + // explicit Quaternion(const SimdScalar *v) : Tuple4<SimdScalar>(v) {} + + SimdQuaternion(const SimdScalar& x, const SimdScalar& y, const SimdScalar& z, const SimdScalar& w) + : SimdQuadWord(x, y, z, w) + {} + + SimdQuaternion(const SimdVector3& axis, const SimdScalar& angle) + { + setRotation(axis, angle); + } + + SimdQuaternion(const SimdScalar& yaw, const SimdScalar& pitch, const SimdScalar& roll) + { + setEuler(yaw, pitch, roll); + } + + void setRotation(const SimdVector3& axis, const SimdScalar& angle) + { + SimdScalar d = axis.length(); + assert(d != SimdScalar(0.0)); + SimdScalar s = sinf(angle * SimdScalar(0.5)) / d; + setValue(axis.x() * s, axis.y() * s, axis.z() * s, + cosf(angle * SimdScalar(0.5))); + } + + void setEuler(const SimdScalar& yaw, const SimdScalar& pitch, const SimdScalar& roll) + { + SimdScalar halfYaw = SimdScalar(yaw) * SimdScalar(0.5); + SimdScalar halfPitch = SimdScalar(pitch) * SimdScalar(0.5); + SimdScalar halfRoll = SimdScalar(roll) * SimdScalar(0.5); + SimdScalar cosYaw = cosf(halfYaw); + SimdScalar sinYaw = sinf(halfYaw); + SimdScalar cosPitch = cosf(halfPitch); + SimdScalar sinPitch = sinf(halfPitch); + SimdScalar cosRoll = cosf(halfRoll); + SimdScalar sinRoll = sinf(halfRoll); + setValue(cosRoll * sinPitch * cosYaw + sinRoll * cosPitch * sinYaw, + cosRoll * cosPitch * sinYaw - sinRoll * sinPitch * cosYaw, + sinRoll * cosPitch * cosYaw - cosRoll * sinPitch * sinYaw, + cosRoll * cosPitch * cosYaw + sinRoll * sinPitch * sinYaw); + } + + SimdQuaternion& operator+=(const SimdQuaternion& q) + { + m_x += q.x(); m_y += q.y(); m_z += q.z(); m_unusedW += q[3]; + return *this; + } + + SimdQuaternion& operator-=(const SimdQuaternion& q) + { + m_x -= q.x(); m_y -= q.y(); m_z -= q.z(); m_unusedW -= q[3]; + return *this; + } + + SimdQuaternion& operator*=(const SimdScalar& s) + { + m_x *= s; m_y *= s; m_z *= s; m_unusedW *= s; + return *this; + } + + + SimdQuaternion& operator*=(const SimdQuaternion& q) + { + setValue(m_unusedW * q.x() + m_x * q[3] + m_y * q.z() - m_z * q.y(), + m_unusedW * q.y() + m_y * q[3] + m_z * q.x() - m_x * q.z(), + m_unusedW * q.z() + m_z * q[3] + m_x * q.y() - m_y * q.x(), + m_unusedW * q[3] - m_x * q.x() - m_y * q.y() - m_z * q.z()); + return *this; + } + + SimdScalar dot(const SimdQuaternion& q) const + { + return m_x * q.x() + m_y * q.y() + m_z * q.z() + m_unusedW * q[3]; + } + + SimdScalar length2() const + { + return dot(*this); + } + + SimdScalar length() const + { + return sqrtf(length2()); + } + + SimdQuaternion& normalize() + { + return *this /= length(); + } + + SIMD_FORCE_INLINE SimdQuaternion + operator*(const SimdScalar& s) const + { + return SimdQuaternion(x() * s, y() * s, z() * s, m_unusedW * s); + } + + + + SimdQuaternion operator/(const SimdScalar& s) const + { + assert(s != SimdScalar(0.0)); + return *this * (SimdScalar(1.0) / s); + } + + + SimdQuaternion& operator/=(const SimdScalar& s) + { + assert(s != SimdScalar(0.0)); + return *this *= SimdScalar(1.0) / s; + } + + + SimdQuaternion normalized() const + { + return *this / length(); + } + + SimdScalar angle(const SimdQuaternion& q) const + { + SimdScalar s = sqrtf(length2() * q.length2()); + assert(s != SimdScalar(0.0)); + return acosf(dot(q) / s); + } + + SimdScalar getAngle() const + { + SimdScalar s = 2.f * acosf(m_unusedW); + return s; + } + + + + SimdQuaternion inverse() const + { + return SimdQuaternion(m_x, m_y, m_z, -m_unusedW); + } + + SIMD_FORCE_INLINE SimdQuaternion + operator+(const SimdQuaternion& q2) const + { + const SimdQuaternion& q1 = *this; + return SimdQuaternion(q1.x() + q2.x(), q1.y() + q2.y(), q1.z() + q2.z(), q1[3] + q2[3]); + } + + SIMD_FORCE_INLINE SimdQuaternion + operator-(const SimdQuaternion& q2) const + { + const SimdQuaternion& q1 = *this; + return SimdQuaternion(q1.x() - q2.x(), q1.y() - q2.y(), q1.z() - q2.z(), q1[3] - q2[3]); + } + + SIMD_FORCE_INLINE SimdQuaternion operator-() const + { + const SimdQuaternion& q2 = *this; + return SimdQuaternion( - q2.x(), - q2.y(), - q2.z(), - q2[3]); + } + + SIMD_FORCE_INLINE SimdQuaternion farthest( const SimdQuaternion& qd) const + { + SimdQuaternion diff,sum; + diff = *this - qd; + sum = *this + qd; + if( diff.dot(diff) > sum.dot(sum) ) + return qd; + return (-qd); + } + + SimdQuaternion slerp(const SimdQuaternion& q, const SimdScalar& t) const + { + SimdScalar theta = angle(q); + if (theta != SimdScalar(0.0)) + { + SimdScalar d = SimdScalar(1.0) / sinf(theta); + SimdScalar s0 = sinf((SimdScalar(1.0) - t) * theta); + SimdScalar s1 = sinf(t * theta); + return SimdQuaternion((m_x * s0 + q.x() * s1) * d, + (m_y * s0 + q.y() * s1) * d, + (m_z * s0 + q.z() * s1) * d, + (m_unusedW * s0 + q[3] * s1) * d); + } + else + { + return *this; + } + } + + + +}; + + + +SIMD_FORCE_INLINE SimdQuaternion +operator-(const SimdQuaternion& q) +{ + return SimdQuaternion(-q.x(), -q.y(), -q.z(), -q[3]); +} + + + + +SIMD_FORCE_INLINE SimdQuaternion +operator*(const SimdQuaternion& q1, const SimdQuaternion& q2) { + return SimdQuaternion(q1[3] * q2.x() + q1.x() * q2[3] + q1.y() * q2.z() - q1.z() * q2.y(), + q1[3] * q2.y() + q1.y() * q2[3] + q1.z() * q2.x() - q1.x() * q2.z(), + q1[3] * q2.z() + q1.z() * q2[3] + q1.x() * q2.y() - q1.y() * q2.x(), + q1[3] * q2[3] - q1.x() * q2.x() - q1.y() * q2.y() - q1.z() * q2.z()); +} + +SIMD_FORCE_INLINE SimdQuaternion +operator*(const SimdQuaternion& q, const SimdVector3& w) +{ + return SimdQuaternion( q[3] * w.x() + q.y() * w.z() - q.z() * w.y(), + q[3] * w.y() + q.z() * w.x() - q.x() * w.z(), + q[3] * w.z() + q.x() * w.y() - q.y() * w.x(), + -q.x() * w.x() - q.y() * w.y() - q.z() * w.z()); +} + +SIMD_FORCE_INLINE SimdQuaternion +operator*(const SimdVector3& w, const SimdQuaternion& q) +{ + return SimdQuaternion( w.x() * q[3] + w.y() * q.z() - w.z() * q.y(), + w.y() * q[3] + w.z() * q.x() - w.x() * q.z(), + w.z() * q[3] + w.x() * q.y() - w.y() * q.x(), + -w.x() * q.x() - w.y() * q.y() - w.z() * q.z()); +} + +SIMD_FORCE_INLINE SimdScalar +dot(const SimdQuaternion& q1, const SimdQuaternion& q2) +{ + return q1.dot(q2); +} + + +SIMD_FORCE_INLINE SimdScalar +length(const SimdQuaternion& q) +{ + return q.length(); +} + +SIMD_FORCE_INLINE SimdScalar +angle(const SimdQuaternion& q1, const SimdQuaternion& q2) +{ + return q1.angle(q2); +} + + +SIMD_FORCE_INLINE SimdQuaternion +inverse(const SimdQuaternion& q) +{ + return q.inverse(); +} + +SIMD_FORCE_INLINE SimdQuaternion +slerp(const SimdQuaternion& q1, const SimdQuaternion& q2, const SimdScalar& t) +{ + return q1.slerp(q2, t); +} + + +#endif + + + diff --git a/extern/bullet/LinearMath/SimdScalar.h b/extern/bullet/LinearMath/SimdScalar.h new file mode 100644 index 00000000000..6feaee53f8e --- /dev/null +++ b/extern/bullet/LinearMath/SimdScalar.h @@ -0,0 +1,95 @@ +/* + +Copyright (c) 2005 Gino van den Bergen / Erwin Coumans <www.erwincoumans.com> + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +*/ + + +#ifndef SIMD___SCALAR_H +#define SIMD___SCALAR_H + +#include <math.h> +#undef max + + + +#include <cstdlib> +#include <cfloat> +#include <float.h> + +#ifdef WIN32 +#define SIMD_FORCE_INLINE __forceinline +//#define ATTRIBUTE_ALIGNED16(a) __declspec(align(16)) a +#define ATTRIBUTE_ALIGNED16(a) a + +#include <assert.h> +#define ASSERT assert +#else +#define SIMD_FORCE_INLINE inline +#define ATTRIBUTE_ALIGNED16(a) a +#ifndef assert +#include <assert.h> +#endif + + +#define ASSERT assert + +#endif + + + +typedef float SimdScalar; + +const SimdScalar SIMD_2_PI = 6.283185307179586232f; +const SimdScalar SIMD_PI = SIMD_2_PI * SimdScalar(0.5f); +const SimdScalar SIMD_HALF_PI = SIMD_2_PI * SimdScalar(0.25f); +const SimdScalar SIMD_RADS_PER_DEG = SIMD_2_PI / SimdScalar(360.0f); +const SimdScalar SIMD_DEGS_PER_RAD = SimdScalar(360.0f) / SIMD_2_PI; +const SimdScalar SIMD_EPSILON = FLT_EPSILON; +const SimdScalar SIMD_INFINITY = FLT_MAX; + +SIMD_FORCE_INLINE bool SimdFuzzyZero(SimdScalar x) { return fabsf(x) < SIMD_EPSILON; } + +SIMD_FORCE_INLINE bool SimdEqual(SimdScalar a, SimdScalar eps) { + return (((a) <= eps) && !((a) < -eps)); +} +SIMD_FORCE_INLINE bool SimdGreaterEqual (SimdScalar a, SimdScalar eps) { + return (!((a) <= eps)); +} + +SIMD_FORCE_INLINE SimdScalar SimdCos(SimdScalar x) { return cosf(x); } +SIMD_FORCE_INLINE SimdScalar SimdSin(SimdScalar x) { return sinf(x); } +SIMD_FORCE_INLINE SimdScalar SimdTan(SimdScalar x) { return tanf(x); } +SIMD_FORCE_INLINE int SimdSign(SimdScalar x) { + return x < 0.0f ? -1 : x > 0.0f ? 1 : 0; +} +SIMD_FORCE_INLINE SimdScalar SimdAcos(SimdScalar x) { return acosf(x); } +SIMD_FORCE_INLINE SimdScalar SimdAsin(SimdScalar x) { return asinf(x); } +SIMD_FORCE_INLINE SimdScalar SimdAtan(SimdScalar x) { return atanf(x); } +SIMD_FORCE_INLINE SimdScalar SimdAtan2(SimdScalar x, SimdScalar y) { return atan2f(x, y); } + +SIMD_FORCE_INLINE SimdScalar SimdRadians(SimdScalar x) { return x * SIMD_RADS_PER_DEG; } +SIMD_FORCE_INLINE SimdScalar SimdDegrees(SimdScalar x) { return x * SIMD_DEGS_PER_RAD; } + +#endif diff --git a/extern/bullet/LinearMath/SimdTransform.h b/extern/bullet/LinearMath/SimdTransform.h new file mode 100644 index 00000000000..cbf9a95a41f --- /dev/null +++ b/extern/bullet/LinearMath/SimdTransform.h @@ -0,0 +1,248 @@ +/* + +Copyright (c) 2005 Gino van den Bergen / Erwin Coumans <www.erwincoumans.com> + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +*/ + + +#ifndef SimdTransform_H +#define SimdTransform_H + +#include "SimdVector3.h" +#include "SimdMatrix3x3.h" + + + +class SimdTransform { + enum { + TRANSLATION = 0x01, + ROTATION = 0x02, + RIGID = TRANSLATION | ROTATION, + SCALING = 0x04, + LINEAR = ROTATION | SCALING, + AFFINE = TRANSLATION | LINEAR + }; + +public: + SimdTransform() {} + + // template <typename Scalar2> + // explicit Transform(const Scalar2 *m) { setValue(m); } + + explicit SIMD_FORCE_INLINE SimdTransform(const SimdQuaternion& q, + const SimdVector3& c = SimdVector3(SimdScalar(0), SimdScalar(0), SimdScalar(0))) + : m_basis(q), + m_origin(c), + m_type(RIGID) + {} + + explicit SIMD_FORCE_INLINE SimdTransform(const SimdMatrix3x3& b, + const SimdVector3& c = SimdVector3(SimdScalar(0), SimdScalar(0), SimdScalar(0)), + unsigned int type = AFFINE) + : m_basis(b), + m_origin(c), + m_type(type) + {} + + + SIMD_FORCE_INLINE void mult(const SimdTransform& t1, const SimdTransform& t2) { + m_basis = t1.m_basis * t2.m_basis; + m_origin = t1(t2.m_origin); + m_type = t1.m_type | t2.m_type; + } + + void multInverseLeft(const SimdTransform& t1, const SimdTransform& t2) { + SimdVector3 v = t2.m_origin - t1.m_origin; + if (t1.m_type & SCALING) { + SimdMatrix3x3 inv = t1.m_basis.inverse(); + m_basis = inv * t2.m_basis; + m_origin = inv * v; + } + else { + m_basis = SimdMultTransposeLeft(t1.m_basis, t2.m_basis); + m_origin = v * t1.m_basis; + } + m_type = t1.m_type | t2.m_type; + } + + SIMD_FORCE_INLINE SimdVector3 operator()(const SimdVector3& x) const + { + return SimdVector3(m_basis[0].dot(x) + m_origin[0], + m_basis[1].dot(x) + m_origin[1], + m_basis[2].dot(x) + m_origin[2]); + } + + SIMD_FORCE_INLINE SimdVector3 operator*(const SimdVector3& x) const + { + return (*this)(x); + } + + SIMD_FORCE_INLINE SimdMatrix3x3& getBasis() { return m_basis; } + SIMD_FORCE_INLINE const SimdMatrix3x3& getBasis() const { return m_basis; } + + SIMD_FORCE_INLINE SimdVector3& getOrigin() { return m_origin; } + SIMD_FORCE_INLINE const SimdVector3& getOrigin() const { return m_origin; } + + SimdQuaternion getRotation() const { + SimdQuaternion q; + m_basis.getRotation(q); + return q; + } + template <typename Scalar2> + void setValue(const Scalar2 *m) + { + m_basis.setValue(m); + m_origin.setValue(&m[12]); + m_type = AFFINE; + } + + + void setFromOpenGLMatrix(const SimdScalar *m) + { + m_basis.setFromOpenGLSubMatrix(m); + m_origin[0] = m[12]; + m_origin[1] = m[13]; + m_origin[2] = m[14]; + } + + void getOpenGLMatrix(SimdScalar *m) const + { + m_basis.getOpenGLSubMatrix(m); + m[12] = m_origin[0]; + m[13] = m_origin[1]; + m[14] = m_origin[2]; + m[15] = SimdScalar(1.0f); + } + + SIMD_FORCE_INLINE void setOrigin(const SimdVector3& origin) + { + m_origin = origin; + m_type |= TRANSLATION; + } + + SIMD_FORCE_INLINE SimdVector3 invXform(const SimdVector3& inVec) const; + + + + SIMD_FORCE_INLINE void setBasis(const SimdMatrix3x3& basis) + { + m_basis = basis; + m_type |= LINEAR; + } + + SIMD_FORCE_INLINE void setRotation(const SimdQuaternion& q) + { + m_basis.setRotation(q); + m_type = (m_type & ~LINEAR) | ROTATION; + } + + SIMD_FORCE_INLINE void scale(const SimdVector3& scaling) + { + m_basis = m_basis.scaled(scaling); + m_type |= SCALING; + } + + void setIdentity() + { + m_basis.setIdentity(); + m_origin.setValue(SimdScalar(0.0), SimdScalar(0.0), SimdScalar(0.0)); + m_type = 0x0; + } + + SIMD_FORCE_INLINE bool isIdentity() const { return m_type == 0x0; } + + SimdTransform& operator*=(const SimdTransform& t) + { + m_origin += m_basis * t.m_origin; + m_basis *= t.m_basis; + m_type |= t.m_type; + return *this; + } + + SimdTransform inverse() const + { + if (m_type) + { + SimdMatrix3x3 inv = (m_type & SCALING) ? + m_basis.inverse() : + m_basis.transpose(); + + return SimdTransform(inv, inv * -m_origin, m_type); + } + + return *this; + } + + SimdTransform inverseTimes(const SimdTransform& t) const; + + SimdTransform operator*(const SimdTransform& t) const; + +private: + + SimdMatrix3x3 m_basis; + SimdVector3 m_origin; + unsigned int m_type; +}; + + +SIMD_FORCE_INLINE SimdVector3 +SimdTransform::invXform(const SimdVector3& inVec) const +{ + SimdVector3 v = inVec - m_origin; + return (m_basis.transpose() * v); +} + +SIMD_FORCE_INLINE SimdTransform +SimdTransform::inverseTimes(const SimdTransform& t) const +{ + SimdVector3 v = t.getOrigin() - m_origin; + if (m_type & SCALING) + { + SimdMatrix3x3 inv = m_basis.inverse(); + return SimdTransform(inv * t.getBasis(), inv * v, + m_type | t.m_type); + } + else + { + return SimdTransform(m_basis.transposeTimes(t.m_basis), + v * m_basis, m_type | t.m_type); + } +} + +SIMD_FORCE_INLINE SimdTransform +SimdTransform::operator*(const SimdTransform& t) const +{ + return SimdTransform(m_basis * t.m_basis, + (*this)(t.m_origin), + m_type | t.m_type); +} + + + +#endif + + + + + diff --git a/extern/bullet/LinearMath/SimdTransformUtil.h b/extern/bullet/LinearMath/SimdTransformUtil.h new file mode 100644 index 00000000000..f3ee76de77b --- /dev/null +++ b/extern/bullet/LinearMath/SimdTransformUtil.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ + +#ifndef SIMD_TRANSFORM_UTIL_H +#define SIMD_TRANSFORM_UTIL_H + +#include "SimdTransform.h" +#define ANGULAR_MOTION_TRESHOLD 0.5f*SIMD_HALF_PI + +/// Utils related to temporal transforms +class SimdTransformUtil +{ + +public: + + static void IntegrateTransform(const SimdTransform& curTrans,const SimdVector3& linvel,const SimdVector3& angvel,SimdScalar timeStep,SimdTransform& predictedTransform) + { + predictedTransform.setOrigin(curTrans.getOrigin() + linvel * timeStep); +// #define QUATERNION_DERIVATIVE + #ifdef QUATERNION_DERIVATIVE + SimdQuaternion orn = curTrans.getRotation(); + orn += (angvel * orn) * (timeStep * 0.5f); + orn.normalize(); + #else + //exponential map + SimdVector3 axis; + SimdScalar fAngle = angvel.length(); + //limit the angular motion + if (fAngle*timeStep > ANGULAR_MOTION_TRESHOLD) + { + fAngle = ANGULAR_MOTION_TRESHOLD / timeStep; + } + + if ( fAngle < 0.001f ) + { + // use Taylor's expansions of sync function + axis = angvel*( 0.5f*timeStep-(timeStep*timeStep*timeStep)*(0.020833333333f)*fAngle*fAngle ); + } + else + { + // sync(fAngle) = sin(c*fAngle)/t + axis = angvel*( sinf(0.5f*fAngle*timeStep)/fAngle ); + } + SimdQuaternion dorn (axis.x(),axis.y(),axis.z(),cosf( fAngle*timeStep*0.5f )); + SimdQuaternion orn0 = curTrans.getRotation(); + + SimdQuaternion predictedOrn = dorn * orn0; + #endif + predictedTransform.setRotation(predictedOrn); + } + + static void CalculateVelocity(const SimdTransform& transform0,const SimdTransform& transform1,SimdScalar timeStep,SimdVector3& linVel,SimdVector3& angVel) + { + linVel = (transform1.getOrigin() - transform0.getOrigin()) / timeStep; +#ifdef USE_QUATERNION_DIFF + SimdQuaternion orn0 = transform0.getRotation(); + SimdQuaternion orn1a = transform1.getRotation(); + SimdQuaternion orn1 = orn0.farthest(orn1a); + SimdQuaternion dorn = orn1 * orn0.inverse(); +#else + SimdMatrix3x3 dmat = transform1.getBasis() * transform0.getBasis().inverse(); + SimdQuaternion dorn; + dmat.getRotation(dorn); +#endif//USE_QUATERNION_DIFF + + SimdVector3 axis; + SimdScalar angle; + angle = dorn.getAngle(); + axis = SimdVector3(dorn.x(),dorn.y(),dorn.z()); + axis[3] = 0.f; + //check for axis length + SimdScalar len = axis.length2(); + if (len < 0.001f) + axis = SimdVector3(1.f,0.f,0.f); + else + axis /= sqrtf(len); + + + angVel = axis * angle / timeStep; + + } + + +}; + +#endif //SIMD_TRANSFORM_UTIL_H
\ No newline at end of file diff --git a/extern/bullet/LinearMath/SimdVector3.h b/extern/bullet/LinearMath/SimdVector3.h new file mode 100644 index 00000000000..b7077d828b9 --- /dev/null +++ b/extern/bullet/LinearMath/SimdVector3.h @@ -0,0 +1,396 @@ +/* + +Copyright (c) 2005 Gino van den Bergen / Erwin Coumans <www.erwincoumans.com> + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +*/ + + +#ifndef SIMD__VECTOR3_H +#define SIMD__VECTOR3_H + +#include "SimdQuadWord.h" + + +///SimdVector3 is 16byte aligned, and has an extra unused component m_w +///this extra component can be used by derived classes (Quaternion?) or by user +class SimdVector3 : public SimdQuadWord { + + +public: + SIMD_FORCE_INLINE SimdVector3() {} + + + + SIMD_FORCE_INLINE SimdVector3(const SimdScalar& x, const SimdScalar& y, const SimdScalar& z) + :SimdQuadWord(x,y,z,0.f) + { + } + +// SIMD_FORCE_INLINE SimdVector3(const SimdScalar& x, const SimdScalar& y, const SimdScalar& z,const SimdScalar& w) +// : SimdQuadWord(x,y,z,w) +// { +// } + + + + SIMD_FORCE_INLINE SimdVector3& operator+=(const SimdVector3& v) + { + m_x += v.x(); m_y += v.y(); m_z += v.z(); + return *this; + } + + + + SIMD_FORCE_INLINE SimdVector3& operator-=(const SimdVector3& v) + { + m_x -= v.x(); m_y -= v.y(); m_z -= v.z(); + return *this; + } + + SIMD_FORCE_INLINE SimdVector3& operator*=(const SimdScalar& s) + { + m_x *= s; m_y *= s; m_z *= s; + return *this; + } + + SIMD_FORCE_INLINE SimdVector3& operator/=(const SimdScalar& s) + { + assert(s != SimdScalar(0.0)); + return *this *= SimdScalar(1.0) / s; + } + + SIMD_FORCE_INLINE SimdScalar dot(const SimdVector3& v) const + { + return m_x * v.x() + m_y * v.y() + m_z * v.z(); + } + + SIMD_FORCE_INLINE SimdScalar length2() const + { + return dot(*this); + } + + SIMD_FORCE_INLINE SimdScalar length() const + { + return sqrtf(length2()); + } + + SIMD_FORCE_INLINE SimdScalar distance2(const SimdVector3& v) const; + + SIMD_FORCE_INLINE SimdScalar distance(const SimdVector3& v) const; + + SIMD_FORCE_INLINE SimdVector3& normalize() + { + return *this /= length(); + } + + SIMD_FORCE_INLINE SimdVector3 normalized() const; + + SIMD_FORCE_INLINE SimdScalar angle(const SimdVector3& v) const + { + SimdScalar s = sqrtf(length2() * v.length2()); + assert(s != SimdScalar(0.0)); + return acosf(dot(v) / s); + } + + SIMD_FORCE_INLINE SimdVector3 absolute() const + { + return SimdVector3( + fabsf(m_x), + fabsf(m_y), + fabsf(m_z)); + } + + SIMD_FORCE_INLINE SimdVector3 cross(const SimdVector3& v) const + { + return SimdVector3( + m_y * v.z() - m_z * v.y(), + m_z * v.x() - m_x * v.z(), + m_x * v.y() - m_y * v.x()); + } + + SIMD_FORCE_INLINE SimdScalar triple(const SimdVector3& v1, const SimdVector3& v2) const + { + return m_x * (v1.y() * v2.z() - v1.z() * v2.y()) + + m_y * (v1.z() * v2.x() - v1.x() * v2.z()) + + m_z * (v1.x() * v2.y() - v1.y() * v2.x()); + } + + SIMD_FORCE_INLINE int minAxis() const + { + return m_x < m_y ? (m_x < m_z ? 0 : 2) : (m_y < m_z ? 1 : 2); + } + + SIMD_FORCE_INLINE int maxAxis() const + { + return m_x < m_y ? (m_y < m_z ? 2 : 1) : (m_x < m_z ? 2 : 0); + } + + SIMD_FORCE_INLINE int furthestAxis() const + { + return absolute().minAxis(); + } + + SIMD_FORCE_INLINE int closestAxis() const + { + return absolute().maxAxis(); + } + + SIMD_FORCE_INLINE void setInterpolate3(const SimdVector3& v0, const SimdVector3& v1, SimdScalar rt) + { + SimdScalar s = 1.0f - rt; + m_x = s * v0[0] + rt * v1.x(); + m_y = s * v0[1] + rt * v1.y(); + m_z = s * v0[2] + rt * v1.z(); + //don't do the unused w component + // m_co[3] = s * v0[3] + rt * v1[3]; + } + + SIMD_FORCE_INLINE SimdVector3 lerp(const SimdVector3& v, const SimdScalar& t) const + { + return SimdVector3(m_x + (v.x() - m_x) * t, + m_y + (v.y() - m_y) * t, + m_z + (v.z() - m_z) * t); + } + + + SIMD_FORCE_INLINE SimdVector3& operator*=(const SimdVector3& v) + { + m_x *= v.x(); m_y *= v.y(); m_z *= v.z(); + return *this; + } + + + +}; + +SIMD_FORCE_INLINE SimdVector3 +operator+(const SimdVector3& v1, const SimdVector3& v2) +{ + return SimdVector3(v1.x() + v2.x(), v1.y() + v2.y(), v1.z() + v2.z()); +} + +SIMD_FORCE_INLINE SimdVector3 +operator*(const SimdVector3& v1, const SimdVector3& v2) +{ + return SimdVector3(v1.x() * v2.x(), v1.y() * v2.y(), v1.z() *+ v2.z()); +} + +SIMD_FORCE_INLINE SimdVector3 +operator-(const SimdVector3& v1, const SimdVector3& v2) +{ + return SimdVector3(v1.x() - v2.x(), v1.y() - v2.y(), v1.z() - v2.z()); +} + +SIMD_FORCE_INLINE SimdVector3 +operator-(const SimdVector3& v) +{ + return SimdVector3(-v.x(), -v.y(), -v.z()); +} + +SIMD_FORCE_INLINE SimdVector3 +operator*(const SimdVector3& v, const SimdScalar& s) +{ + return SimdVector3(v.x() * s, v.y() * s, v.z() * s); +} + +SIMD_FORCE_INLINE SimdVector3 +operator*(const SimdScalar& s, const SimdVector3& v) +{ + return v * s; +} + +SIMD_FORCE_INLINE SimdVector3 +operator/(const SimdVector3& v, const SimdScalar& s) +{ + assert(s != SimdScalar(0.0)); + return v * (SimdScalar(1.0) / s); +} + +SIMD_FORCE_INLINE SimdScalar +dot(const SimdVector3& v1, const SimdVector3& v2) +{ + return v1.dot(v2); +} + + + +SIMD_FORCE_INLINE SimdScalar +distance2(const SimdVector3& v1, const SimdVector3& v2) +{ + return v1.distance2(v2); +} + + +SIMD_FORCE_INLINE SimdScalar +distance(const SimdVector3& v1, const SimdVector3& v2) +{ + return v1.distance(v2); +} + +SIMD_FORCE_INLINE SimdScalar +angle(const SimdVector3& v1, const SimdVector3& v2) +{ + return v1.angle(v2); +} + +SIMD_FORCE_INLINE SimdVector3 +cross(const SimdVector3& v1, const SimdVector3& v2) +{ + return v1.cross(v2); +} + +SIMD_FORCE_INLINE SimdScalar +triple(const SimdVector3& v1, const SimdVector3& v2, const SimdVector3& v3) +{ + return v1.triple(v2, v3); +} + +SIMD_FORCE_INLINE SimdVector3 +lerp(const SimdVector3& v1, const SimdVector3& v2, const SimdScalar& t) +{ + return v1.lerp(v2, t); +} + + +SIMD_FORCE_INLINE bool operator==(const SimdVector3& p1, const SimdVector3& p2) +{ + return p1[0] == p2[0] && p1[1] == p2[1] && p1[2] == p2[2]; +} + +SIMD_FORCE_INLINE SimdScalar SimdVector3::distance2(const SimdVector3& v) const +{ + return (v - *this).length2(); +} + +SIMD_FORCE_INLINE SimdScalar SimdVector3::distance(const SimdVector3& v) const +{ + return (v - *this).length(); +} + +SIMD_FORCE_INLINE SimdVector3 SimdVector3::normalized() const +{ + return *this / length(); +} + +class SimdVector4 : public SimdVector3 +{ +public: + + SIMD_FORCE_INLINE SimdVector4() {} + + + SIMD_FORCE_INLINE SimdVector4(const SimdScalar& x, const SimdScalar& y, const SimdScalar& z,const SimdScalar& w) + : SimdVector3(x,y,z) + { + m_unusedW = w; + } + + + SIMD_FORCE_INLINE SimdVector4 absolute4() const + { + return SimdVector4( + fabsf(m_x), + fabsf(m_y), + fabsf(m_z), + fabsf(m_unusedW)); + } + + + + float getW() const { return m_unusedW;} + + + SIMD_FORCE_INLINE int maxAxis4() const + { + int maxIndex = -1; + float maxVal = -1e30f; + if (m_x > maxVal) + { + maxIndex = 0; + maxVal = m_x; + } + if (m_y > maxVal) + { + maxIndex = 1; + maxVal = m_y; + } + if (m_z > maxVal) + { + maxIndex = 2; + maxVal = m_z; + } + if (m_unusedW > maxVal) + { + maxIndex = 3; + maxVal = m_unusedW; + } + + + + + return maxIndex; + + } + + + SIMD_FORCE_INLINE int minAxis4() const + { + int minIndex = -1; + float minVal = 1e30f; + if (m_x < minVal) + { + minIndex = 0; + minVal = m_x; + } + if (m_y < minVal) + { + minIndex = 1; + minVal = m_y; + } + if (m_z < minVal) + { + minIndex = 2; + minVal = m_z; + } + if (m_unusedW < minVal) + { + minIndex = 3; + minVal = m_unusedW; + } + + return minIndex; + + } + + + SIMD_FORCE_INLINE int closestAxis4() const + { + return absolute4().maxAxis4(); + } + + + +}; + +#endif //SIMD__VECTOR3_H diff --git a/extern/bullet/continuous.dsw b/extern/bullet/continuous.dsw new file mode 100644 index 00000000000..2ad95b3af62 --- /dev/null +++ b/extern/bullet/continuous.dsw @@ -0,0 +1,239 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "Bullet"=.\Bullet\Bullet3.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "BulletDynamics"=.\BulletDynamics\BulletDynamics.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "CcdPhysics"=.\EXTRAS\PHYSICSINTERFACE\CcdPhysics\CcdPhysics.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "CcdPhysicsDemo"=.\Demos\CcdPhysicsDemo\CcdPhysicsDemo.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name Bullet + End Project Dependency + Begin Project Dependency + Project_Dep_Name BulletDynamics + End Project Dependency + Begin Project Dependency + Project_Dep_Name OpenGL + End Project Dependency + Begin Project Dependency + Project_Dep_Name CcdPhysics + End Project Dependency + Begin Project Dependency + Project_Dep_Name PhysicsInterface + End Project Dependency +}}} + +############################################################################### + +Project: "CollisionDemo"=.\Demos\CollisionDemo\CollisionDemo.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name Bullet + End Project Dependency + Begin Project Dependency + Project_Dep_Name OpenGL + End Project Dependency +}}} + +############################################################################### + +Project: "ConcaveDemo"=.\DEMOS\ConcaveDemo\ConcaveDemo.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name Bullet + End Project Dependency + Begin Project Dependency + Project_Dep_Name BulletDynamics + End Project Dependency + Begin Project Dependency + Project_Dep_Name CcdPhysics + End Project Dependency + Begin Project Dependency + Project_Dep_Name OpenGL + End Project Dependency + Begin Project Dependency + Project_Dep_Name PhysicsInterface + End Project Dependency +}}} + +############################################################################### + +Project: "ContinuousConvexCollision"=.\Demos\ContinuousConvexCollision\ContinuousConvexCollision.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name Bullet + End Project Dependency + Begin Project Dependency + Project_Dep_Name OpenGL + End Project Dependency +}}} + +############################################################################### + +Project: "ConvexHullDistance"=.\DEMOS\ConvexHullDistance\ConvexHullDistance.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name Bullet + End Project Dependency + Begin Project Dependency + Project_Dep_Name OpenGL + End Project Dependency +}}} + +############################################################################### + +Project: "GjkConvexCastDemo"=.\Demos\GjkConvexCastDemo\GjkConvexCastDemo.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name Bullet + End Project Dependency + Begin Project Dependency + Project_Dep_Name OpenGL + End Project Dependency +}}} + +############################################################################### + +Project: "OpenGL"=.\Demos\OpenGL\OpenGL.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "PhysicsInterface"=.\EXTRAS\PHYSICSINTERFACE\Common\PhysicsInterface.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "Raytracer"=.\Demos\Raytracer\Raytracer.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name Bullet + End Project Dependency + Begin Project Dependency + Project_Dep_Name OpenGL + End Project Dependency +}}} + +############################################################################### + +Project: "SimplexDemo"=.\Demos\SimplexDemo\SimplexDemo.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name Bullet + End Project Dependency + Begin Project Dependency + Project_Dep_Name OpenGL + End Project Dependency +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/extern/bullet/continuous_vc7.sln b/extern/bullet/continuous_vc7.sln new file mode 100644 index 00000000000..015e91e2e11 --- /dev/null +++ b/extern/bullet/continuous_vc7.sln @@ -0,0 +1,140 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OpenGLSupport", "Demos\OpenGL\OpenGL_vc7.vcproj", "{47328C1E-54A4-4065-B3DA-F88EE281D1E5}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Bullet3ContinuousCollision", "Bullet\Bullet3_vc7.vcproj", "{FFD3C64A-30E2-4BC7-BC8F-51818C320400}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SimplexDemo", "Demos\SimplexDemo\SimplexDemo_vc7.vcproj", "{F6B9DD8D-8C40-4F2B-B492-56B167D01CC0}" + ProjectSection(ProjectDependencies) = postProject + {47328C1E-54A4-4065-B3DA-F88EE281D1E5} = {47328C1E-54A4-4065-B3DA-F88EE281D1E5} + {FFD3C64A-30E2-4BC7-BC8F-51818C320400} = {FFD3C64A-30E2-4BC7-BC8F-51818C320400} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CollisionDemo", "Demos\CollisionDemo\CollisionDemo_vc7.vcproj", "{F43EFC77-3CFA-4669-BAEA-1E2BC8ABA897}" + ProjectSection(ProjectDependencies) = postProject + {47328C1E-54A4-4065-B3DA-F88EE281D1E5} = {47328C1E-54A4-4065-B3DA-F88EE281D1E5} + {47328C1E-54A4-4065-B3DA-F88EE281D1E5} = {47328C1E-54A4-4065-B3DA-F88EE281D1E5} + {FFD3C64A-30E2-4BC7-BC8F-51818C320400} = {FFD3C64A-30E2-4BC7-BC8F-51818C320400} + {FFD3C64A-30E2-4BC7-BC8F-51818C320400} = {FFD3C64A-30E2-4BC7-BC8F-51818C320400} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LinearConvexCastDemo", "Demos\GjkConvexCastDemo\GjkConvexCastDemo_vc7.vcproj", "{B395AFF6-94FE-4A2C-9E26-58E5BE85083C}" + ProjectSection(ProjectDependencies) = postProject + {47328C1E-54A4-4065-B3DA-F88EE281D1E5} = {47328C1E-54A4-4065-B3DA-F88EE281D1E5} + {FFD3C64A-30E2-4BC7-BC8F-51818C320400} = {FFD3C64A-30E2-4BC7-BC8F-51818C320400} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ContinuousConvexCollisionDemo", "Demos\ContinuousConvexCollision\ContinuousConvexCollision_vc7.vcproj", "{6A4E3433-D0CD-4A10-BE09-78C9A5F7508B}" + ProjectSection(ProjectDependencies) = postProject + {47328C1E-54A4-4065-B3DA-F88EE281D1E5} = {47328C1E-54A4-4065-B3DA-F88EE281D1E5} + {FFD3C64A-30E2-4BC7-BC8F-51818C320400} = {FFD3C64A-30E2-4BC7-BC8F-51818C320400} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Raytracer", "Demos\Raytracer\Raytracer_vc7.vcproj", "{F8B0A298-14C9-4006-8D53-51032892BEDD}" + ProjectSection(ProjectDependencies) = postProject + {47328C1E-54A4-4065-B3DA-F88EE281D1E5} = {47328C1E-54A4-4065-B3DA-F88EE281D1E5} + {FFD3C64A-30E2-4BC7-BC8F-51818C320400} = {FFD3C64A-30E2-4BC7-BC8F-51818C320400} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Bullet3Dynamics", "BulletDynamics\BulletDynamics_vc7.vcproj", "{3427A9EF-FF84-4B3E-9AE5-C37CF44D7DA4}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CcdPhysics", "Extras\PhysicsInterface\CcdPhysics\CcdPhysics_vc7.vcproj", "{E3D57F36-36AC-4E9A-B0E0-2AE4510FCBFE}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PhysicsInterfaceCommon", "Extras\PhysicsInterface\Common\PhysicsInterfaceCommon\PhysicsInterfaceCommon_vc7.vcproj", "{87D8C006-6DCC-4156-A03E-8CEA1B4C0580}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CcdPhysicsDemo", "Demos\CcdPhysicsDemo\CcdPhysicsDemo_vc7.vcproj", "{E9C93159-EC18-4121-9D73-1DE7053D81D7}" + ProjectSection(ProjectDependencies) = postProject + {87D8C006-6DCC-4156-A03E-8CEA1B4C0580} = {87D8C006-6DCC-4156-A03E-8CEA1B4C0580} + {47328C1E-54A4-4065-B3DA-F88EE281D1E5} = {47328C1E-54A4-4065-B3DA-F88EE281D1E5} + {E3D57F36-36AC-4E9A-B0E0-2AE4510FCBFE} = {E3D57F36-36AC-4E9A-B0E0-2AE4510FCBFE} + {FFD3C64A-30E2-4BC7-BC8F-51818C320400} = {FFD3C64A-30E2-4BC7-BC8F-51818C320400} + {3427A9EF-FF84-4B3E-9AE5-C37CF44D7DA4} = {3427A9EF-FF84-4B3E-9AE5-C37CF44D7DA4} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ConcaveDemo", "Demos\ConcaveDemo\ConcaveDemo.vcproj", "{F20F38CC-CFA7-40C7-81AE-945C8C09E473}" + ProjectSection(ProjectDependencies) = postProject + {87D8C006-6DCC-4156-A03E-8CEA1B4C0580} = {87D8C006-6DCC-4156-A03E-8CEA1B4C0580} + {47328C1E-54A4-4065-B3DA-F88EE281D1E5} = {47328C1E-54A4-4065-B3DA-F88EE281D1E5} + {E3D57F36-36AC-4E9A-B0E0-2AE4510FCBFE} = {E3D57F36-36AC-4E9A-B0E0-2AE4510FCBFE} + {FFD3C64A-30E2-4BC7-BC8F-51818C320400} = {FFD3C64A-30E2-4BC7-BC8F-51818C320400} + {3427A9EF-FF84-4B3E-9AE5-C37CF44D7DA4} = {3427A9EF-FF84-4B3E-9AE5-C37CF44D7DA4} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ConvexHullDistance", "Demos\ConvexHullDistance\ConvexHullDistance_vc7.vcproj", "{AF9E7C2B-BE49-4101-B056-4A628B276389}" + ProjectSection(ProjectDependencies) = postProject + {47328C1E-54A4-4065-B3DA-F88EE281D1E5} = {47328C1E-54A4-4065-B3DA-F88EE281D1E5} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {47328C1E-54A4-4065-B3DA-F88EE281D1E5}.Debug.ActiveCfg = Debug|Win32 + {47328C1E-54A4-4065-B3DA-F88EE281D1E5}.Debug.Build.0 = Debug|Win32 + {47328C1E-54A4-4065-B3DA-F88EE281D1E5}.Release.ActiveCfg = Release|Win32 + {47328C1E-54A4-4065-B3DA-F88EE281D1E5}.Release.Build.0 = Release|Win32 + {FFD3C64A-30E2-4BC7-BC8F-51818C320400}.Debug.ActiveCfg = Debug|Win32 + {FFD3C64A-30E2-4BC7-BC8F-51818C320400}.Debug.Build.0 = Debug|Win32 + {FFD3C64A-30E2-4BC7-BC8F-51818C320400}.Release.ActiveCfg = Release|Win32 + {FFD3C64A-30E2-4BC7-BC8F-51818C320400}.Release.Build.0 = Release|Win32 + {F6B9DD8D-8C40-4F2B-B492-56B167D01CC0}.Debug.ActiveCfg = Debug|Win32 + {F6B9DD8D-8C40-4F2B-B492-56B167D01CC0}.Debug.Build.0 = Debug|Win32 + {F6B9DD8D-8C40-4F2B-B492-56B167D01CC0}.Release.ActiveCfg = Release|Win32 + {F6B9DD8D-8C40-4F2B-B492-56B167D01CC0}.Release.Build.0 = Release|Win32 + {F43EFC77-3CFA-4669-BAEA-1E2BC8ABA897}.Debug.ActiveCfg = Debug|Win32 + {F43EFC77-3CFA-4669-BAEA-1E2BC8ABA897}.Debug.Build.0 = Debug|Win32 + {F43EFC77-3CFA-4669-BAEA-1E2BC8ABA897}.Release.ActiveCfg = Release|Win32 + {F43EFC77-3CFA-4669-BAEA-1E2BC8ABA897}.Release.Build.0 = Release|Win32 + {B395AFF6-94FE-4A2C-9E26-58E5BE85083C}.Debug.ActiveCfg = Debug|Win32 + {B395AFF6-94FE-4A2C-9E26-58E5BE85083C}.Debug.Build.0 = Debug|Win32 + {B395AFF6-94FE-4A2C-9E26-58E5BE85083C}.Release.ActiveCfg = Release|Win32 + {B395AFF6-94FE-4A2C-9E26-58E5BE85083C}.Release.Build.0 = Release|Win32 + {6A4E3433-D0CD-4A10-BE09-78C9A5F7508B}.Debug.ActiveCfg = Debug|Win32 + {6A4E3433-D0CD-4A10-BE09-78C9A5F7508B}.Debug.Build.0 = Debug|Win32 + {6A4E3433-D0CD-4A10-BE09-78C9A5F7508B}.Release.ActiveCfg = Release|Win32 + {6A4E3433-D0CD-4A10-BE09-78C9A5F7508B}.Release.Build.0 = Release|Win32 + {F8B0A298-14C9-4006-8D53-51032892BEDD}.Debug.ActiveCfg = Debug|Win32 + {F8B0A298-14C9-4006-8D53-51032892BEDD}.Debug.Build.0 = Debug|Win32 + {F8B0A298-14C9-4006-8D53-51032892BEDD}.Release.ActiveCfg = Release|Win32 + {F8B0A298-14C9-4006-8D53-51032892BEDD}.Release.Build.0 = Release|Win32 + {3427A9EF-FF84-4B3E-9AE5-C37CF44D7DA4}.Debug.ActiveCfg = Debug|Win32 + {3427A9EF-FF84-4B3E-9AE5-C37CF44D7DA4}.Debug.Build.0 = Debug|Win32 + {3427A9EF-FF84-4B3E-9AE5-C37CF44D7DA4}.Release.ActiveCfg = Release|Win32 + {3427A9EF-FF84-4B3E-9AE5-C37CF44D7DA4}.Release.Build.0 = Release|Win32 + {E3D57F36-36AC-4E9A-B0E0-2AE4510FCBFE}.Debug.ActiveCfg = Debug|Win32 + {E3D57F36-36AC-4E9A-B0E0-2AE4510FCBFE}.Debug.Build.0 = Debug|Win32 + {E3D57F36-36AC-4E9A-B0E0-2AE4510FCBFE}.Release.ActiveCfg = Release|Win32 + {E3D57F36-36AC-4E9A-B0E0-2AE4510FCBFE}.Release.Build.0 = Release|Win32 + {87D8C006-6DCC-4156-A03E-8CEA1B4C0580}.Debug.ActiveCfg = Debug|Win32 + {87D8C006-6DCC-4156-A03E-8CEA1B4C0580}.Debug.Build.0 = Debug|Win32 + {87D8C006-6DCC-4156-A03E-8CEA1B4C0580}.Release.ActiveCfg = Release|Win32 + {87D8C006-6DCC-4156-A03E-8CEA1B4C0580}.Release.Build.0 = Release|Win32 + {E9C93159-EC18-4121-9D73-1DE7053D81D7}.Debug.ActiveCfg = Debug|Win32 + {E9C93159-EC18-4121-9D73-1DE7053D81D7}.Debug.Build.0 = Debug|Win32 + {E9C93159-EC18-4121-9D73-1DE7053D81D7}.Release.ActiveCfg = Release|Win32 + {E9C93159-EC18-4121-9D73-1DE7053D81D7}.Release.Build.0 = Release|Win32 + {F20F38CC-CFA7-40C7-81AE-945C8C09E473}.Debug.ActiveCfg = Debug|Win32 + {F20F38CC-CFA7-40C7-81AE-945C8C09E473}.Debug.Build.0 = Debug|Win32 + {F20F38CC-CFA7-40C7-81AE-945C8C09E473}.Release.ActiveCfg = Release|Win32 + {F20F38CC-CFA7-40C7-81AE-945C8C09E473}.Release.Build.0 = Release|Win32 + {AF9E7C2B-BE49-4101-B056-4A628B276389}.Debug.ActiveCfg = Debug|Win32 + {AF9E7C2B-BE49-4101-B056-4A628B276389}.Debug.Build.0 = Debug|Win32 + {AF9E7C2B-BE49-4101-B056-4A628B276389}.Release.ActiveCfg = Release|Win32 + {AF9E7C2B-BE49-4101-B056-4A628B276389}.Release.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/extern/bullet/continuous_vc8.sln b/extern/bullet/continuous_vc8.sln new file mode 100644 index 00000000000..38a29f14627 --- /dev/null +++ b/extern/bullet/continuous_vc8.sln @@ -0,0 +1,129 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OpenGLSupport", "Demos\OpenGL\OpenGL_vc8.vcproj", "{47328C1E-54A4-4065-B3DA-F88EE281D1E5}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Bullet3ContinuousCollision", "Bullet\Bullet3_vc8.vcproj", "{FFD3C64A-30E2-4BC7-BC8F-51818C320400}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SimplexDemo", "Demos\SimplexDemo\SimplexDemo_vc8.vcproj", "{F6B9DD8D-8C40-4F2B-B492-56B167D01CC0}" + ProjectSection(ProjectDependencies) = postProject + {FFD3C64A-30E2-4BC7-BC8F-51818C320400} = {FFD3C64A-30E2-4BC7-BC8F-51818C320400} + {47328C1E-54A4-4065-B3DA-F88EE281D1E5} = {47328C1E-54A4-4065-B3DA-F88EE281D1E5} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CollisionDemo", "Demos\CollisionDemo\CollisionDemo_vc8.vcproj", "{F43EFC77-3CFA-4669-BAEA-1E2BC8ABA897}" + ProjectSection(ProjectDependencies) = postProject + {FFD3C64A-30E2-4BC7-BC8F-51818C320400} = {FFD3C64A-30E2-4BC7-BC8F-51818C320400} + {47328C1E-54A4-4065-B3DA-F88EE281D1E5} = {47328C1E-54A4-4065-B3DA-F88EE281D1E5} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LinearConvexCastDemo", "Demos\GjkConvexCastDemo\GjkConvexCastDemo_vc8.vcproj", "{B395AFF6-94FE-4A2C-9E26-58E5BE85083C}" + ProjectSection(ProjectDependencies) = postProject + {FFD3C64A-30E2-4BC7-BC8F-51818C320400} = {FFD3C64A-30E2-4BC7-BC8F-51818C320400} + {47328C1E-54A4-4065-B3DA-F88EE281D1E5} = {47328C1E-54A4-4065-B3DA-F88EE281D1E5} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ContinuousConvexCollisionDemo", "Demos\ContinuousConvexCollision\ContinuousConvexCollision_vc8.vcproj", "{6A4E3433-D0CD-4A10-BE09-78C9A5F7508B}" + ProjectSection(ProjectDependencies) = postProject + {FFD3C64A-30E2-4BC7-BC8F-51818C320400} = {FFD3C64A-30E2-4BC7-BC8F-51818C320400} + {47328C1E-54A4-4065-B3DA-F88EE281D1E5} = {47328C1E-54A4-4065-B3DA-F88EE281D1E5} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Raytracer", "Demos\Raytracer\Raytracer_vc8.vcproj", "{F8B0A298-14C9-4006-8D53-51032892BEDD}" + ProjectSection(ProjectDependencies) = postProject + {FFD3C64A-30E2-4BC7-BC8F-51818C320400} = {FFD3C64A-30E2-4BC7-BC8F-51818C320400} + {47328C1E-54A4-4065-B3DA-F88EE281D1E5} = {47328C1E-54A4-4065-B3DA-F88EE281D1E5} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Bullet3Dynamics", "BulletDynamics\BulletDynamics_vc8.vcproj", "{3427A9EF-FF84-4B3E-9AE5-C37CF44D7DA4}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CcdPhysicsDemo", "Demos\CcdPhysicsDemo\CcdPhysicsDemo_vc8.vcproj", "{E9C93159-EC18-4121-9D73-1DE7053D81D7}" + ProjectSection(ProjectDependencies) = postProject + {3427A9EF-FF84-4B3E-9AE5-C37CF44D7DA4} = {3427A9EF-FF84-4B3E-9AE5-C37CF44D7DA4} + {FFD3C64A-30E2-4BC7-BC8F-51818C320400} = {FFD3C64A-30E2-4BC7-BC8F-51818C320400} + {E3D57F36-36AC-4E9A-B0E0-2AE4510FCBFE} = {E3D57F36-36AC-4E9A-B0E0-2AE4510FCBFE} + {47328C1E-54A4-4065-B3DA-F88EE281D1E5} = {47328C1E-54A4-4065-B3DA-F88EE281D1E5} + {87D8C006-6DCC-4156-A03E-8CEA1B4C0580} = {87D8C006-6DCC-4156-A03E-8CEA1B4C0580} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CcdPhysics", "Extras\PhysicsInterface\CcdPhysics\CcdPhysics_vc8.vcproj", "{E3D57F36-36AC-4E9A-B0E0-2AE4510FCBFE}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PhysicsInterfaceCommon", "Extras\PhysicsInterface\Common\PhysicsInterfaceCommon\PhysicsInterfaceCommon_vc8.vcproj", "{87D8C006-6DCC-4156-A03E-8CEA1B4C0580}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ConvexHullDistance", "Demos\ConvexHullDistance\ConvexHullDistance_vc8.vcproj", "{39A0C0E0-773B-498D-B9B1-B54525FB6223}" + ProjectSection(ProjectDependencies) = postProject + {FFD3C64A-30E2-4BC7-BC8F-51818C320400} = {FFD3C64A-30E2-4BC7-BC8F-51818C320400} + {47328C1E-54A4-4065-B3DA-F88EE281D1E5} = {47328C1E-54A4-4065-B3DA-F88EE281D1E5} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ConcaveDemo", "Demos\ConcaveDemo\ConcaveDemo_vc8.vcproj", "{F20F38CC-CFA7-40C7-81AE-945C8C09E473}" + ProjectSection(ProjectDependencies) = postProject + {87D8C006-6DCC-4156-A03E-8CEA1B4C0580} = {87D8C006-6DCC-4156-A03E-8CEA1B4C0580} + {47328C1E-54A4-4065-B3DA-F88EE281D1E5} = {47328C1E-54A4-4065-B3DA-F88EE281D1E5} + {E3D57F36-36AC-4E9A-B0E0-2AE4510FCBFE} = {E3D57F36-36AC-4E9A-B0E0-2AE4510FCBFE} + {FFD3C64A-30E2-4BC7-BC8F-51818C320400} = {FFD3C64A-30E2-4BC7-BC8F-51818C320400} + {3427A9EF-FF84-4B3E-9AE5-C37CF44D7DA4} = {3427A9EF-FF84-4B3E-9AE5-C37CF44D7DA4} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {47328C1E-54A4-4065-B3DA-F88EE281D1E5}.Debug|Win32.ActiveCfg = Debug|Win32 + {47328C1E-54A4-4065-B3DA-F88EE281D1E5}.Debug|Win32.Build.0 = Debug|Win32 + {47328C1E-54A4-4065-B3DA-F88EE281D1E5}.Release|Win32.ActiveCfg = Release|Win32 + {47328C1E-54A4-4065-B3DA-F88EE281D1E5}.Release|Win32.Build.0 = Release|Win32 + {FFD3C64A-30E2-4BC7-BC8F-51818C320400}.Debug|Win32.ActiveCfg = Debug|Win32 + {FFD3C64A-30E2-4BC7-BC8F-51818C320400}.Debug|Win32.Build.0 = Debug|Win32 + {FFD3C64A-30E2-4BC7-BC8F-51818C320400}.Release|Win32.ActiveCfg = Release|Win32 + {FFD3C64A-30E2-4BC7-BC8F-51818C320400}.Release|Win32.Build.0 = Release|Win32 + {F6B9DD8D-8C40-4F2B-B492-56B167D01CC0}.Debug|Win32.ActiveCfg = Debug|Win32 + {F6B9DD8D-8C40-4F2B-B492-56B167D01CC0}.Debug|Win32.Build.0 = Debug|Win32 + {F6B9DD8D-8C40-4F2B-B492-56B167D01CC0}.Release|Win32.ActiveCfg = Release|Win32 + {F6B9DD8D-8C40-4F2B-B492-56B167D01CC0}.Release|Win32.Build.0 = Release|Win32 + {F43EFC77-3CFA-4669-BAEA-1E2BC8ABA897}.Debug|Win32.ActiveCfg = Debug|Win32 + {F43EFC77-3CFA-4669-BAEA-1E2BC8ABA897}.Debug|Win32.Build.0 = Debug|Win32 + {F43EFC77-3CFA-4669-BAEA-1E2BC8ABA897}.Release|Win32.ActiveCfg = Release|Win32 + {F43EFC77-3CFA-4669-BAEA-1E2BC8ABA897}.Release|Win32.Build.0 = Release|Win32 + {B395AFF6-94FE-4A2C-9E26-58E5BE85083C}.Debug|Win32.ActiveCfg = Debug|Win32 + {B395AFF6-94FE-4A2C-9E26-58E5BE85083C}.Debug|Win32.Build.0 = Debug|Win32 + {B395AFF6-94FE-4A2C-9E26-58E5BE85083C}.Release|Win32.ActiveCfg = Release|Win32 + {B395AFF6-94FE-4A2C-9E26-58E5BE85083C}.Release|Win32.Build.0 = Release|Win32 + {6A4E3433-D0CD-4A10-BE09-78C9A5F7508B}.Debug|Win32.ActiveCfg = Debug|Win32 + {6A4E3433-D0CD-4A10-BE09-78C9A5F7508B}.Debug|Win32.Build.0 = Debug|Win32 + {6A4E3433-D0CD-4A10-BE09-78C9A5F7508B}.Release|Win32.ActiveCfg = Release|Win32 + {6A4E3433-D0CD-4A10-BE09-78C9A5F7508B}.Release|Win32.Build.0 = Release|Win32 + {F8B0A298-14C9-4006-8D53-51032892BEDD}.Debug|Win32.ActiveCfg = Debug|Win32 + {F8B0A298-14C9-4006-8D53-51032892BEDD}.Debug|Win32.Build.0 = Debug|Win32 + {F8B0A298-14C9-4006-8D53-51032892BEDD}.Release|Win32.ActiveCfg = Release|Win32 + {F8B0A298-14C9-4006-8D53-51032892BEDD}.Release|Win32.Build.0 = Release|Win32 + {3427A9EF-FF84-4B3E-9AE5-C37CF44D7DA4}.Debug|Win32.ActiveCfg = Debug|Win32 + {3427A9EF-FF84-4B3E-9AE5-C37CF44D7DA4}.Debug|Win32.Build.0 = Debug|Win32 + {3427A9EF-FF84-4B3E-9AE5-C37CF44D7DA4}.Release|Win32.ActiveCfg = Release|Win32 + {3427A9EF-FF84-4B3E-9AE5-C37CF44D7DA4}.Release|Win32.Build.0 = Release|Win32 + {E9C93159-EC18-4121-9D73-1DE7053D81D7}.Debug|Win32.ActiveCfg = Debug|Win32 + {E9C93159-EC18-4121-9D73-1DE7053D81D7}.Debug|Win32.Build.0 = Debug|Win32 + {E9C93159-EC18-4121-9D73-1DE7053D81D7}.Release|Win32.ActiveCfg = Release|Win32 + {E9C93159-EC18-4121-9D73-1DE7053D81D7}.Release|Win32.Build.0 = Release|Win32 + {E3D57F36-36AC-4E9A-B0E0-2AE4510FCBFE}.Debug|Win32.ActiveCfg = Debug|Win32 + {E3D57F36-36AC-4E9A-B0E0-2AE4510FCBFE}.Debug|Win32.Build.0 = Debug|Win32 + {E3D57F36-36AC-4E9A-B0E0-2AE4510FCBFE}.Release|Win32.ActiveCfg = Release|Win32 + {E3D57F36-36AC-4E9A-B0E0-2AE4510FCBFE}.Release|Win32.Build.0 = Release|Win32 + {87D8C006-6DCC-4156-A03E-8CEA1B4C0580}.Debug|Win32.ActiveCfg = Debug|Win32 + {87D8C006-6DCC-4156-A03E-8CEA1B4C0580}.Debug|Win32.Build.0 = Debug|Win32 + {87D8C006-6DCC-4156-A03E-8CEA1B4C0580}.Release|Win32.ActiveCfg = Release|Win32 + {87D8C006-6DCC-4156-A03E-8CEA1B4C0580}.Release|Win32.Build.0 = Release|Win32 + {39A0C0E0-773B-498D-B9B1-B54525FB6223}.Debug|Win32.ActiveCfg = Debug|Win32 + {39A0C0E0-773B-498D-B9B1-B54525FB6223}.Debug|Win32.Build.0 = Debug|Win32 + {39A0C0E0-773B-498D-B9B1-B54525FB6223}.Release|Win32.ActiveCfg = Release|Win32 + {39A0C0E0-773B-498D-B9B1-B54525FB6223}.Release|Win32.Build.0 = Release|Win32 + {F20F38CC-CFA7-40C7-81AE-945C8C09E473}.Debug|Win32.ActiveCfg = Debug|Win32 + {F20F38CC-CFA7-40C7-81AE-945C8C09E473}.Debug|Win32.Build.0 = Debug|Win32 + {F20F38CC-CFA7-40C7-81AE-945C8C09E473}.Release|Win32.ActiveCfg = Release|Win32 + {F20F38CC-CFA7-40C7-81AE-945C8C09E473}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal |