Reorganized Bullet physics files, added preliminary vehicle simulation files (disabled).

Requires some changes to projectfiles/makefiles/scons, for the added and removed files!
This commit is contained in:
Erwin Coumans 2006-02-21 05:36:56 +00:00
parent a6e7ff5ee9
commit 90e5a9aa14
42 changed files with 1863 additions and 968 deletions

@ -12,6 +12,7 @@
#define BROADPHASE_INTERFACE_H
struct DispatcherInfo;
class Dispatcher;
struct BroadphaseProxy;
@ -21,7 +22,7 @@ struct BroadphaseProxy;
class BroadphaseInterface
{
public:
virtual BroadphaseProxy* CreateProxy( void *object,int type, const SimdVector3& min, const SimdVector3& max) =0;
virtual BroadphaseProxy* CreateProxy( const SimdVector3& min, const SimdVector3& max,int shapeType,void* userPtr ) =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;

@ -45,15 +45,19 @@ CONCAVE_SHAPES_START_HERE,
///BroadphaseProxy
struct BroadphaseProxy
{
//Usually the client CollisionObject or Rigidbody class
void* m_clientObject;
BroadphaseProxy() :m_clientObject(0),m_clientObjectType(-1){}
BroadphaseProxy(void* object,int type)
:m_clientObject(object),
m_clientObjectType(type)
BroadphaseProxy(int shapeType,void* userPtr)
:m_clientObject(userPtr),
m_clientObjectType(shapeType)
{
}
void *m_clientObject;
int GetClientObjectType ( ) const { return m_clientObjectType;}

@ -9,7 +9,7 @@
* It is provided "as is" without express or implied warranty.
*/
#include "CollisionAlgorithm.h"
#include "CollisionDispatcher.h"
#include "Dispatcher.h"
CollisionAlgorithm::CollisionAlgorithm(const CollisionAlgorithmConstructionInfo& ci)
{

@ -8,7 +8,7 @@
* of this software for any purpose.
* It is provided "as is" without express or implied warranty.
*/
#include "CollisionDispatcher.h"
#include "Dispatcher.h"
Dispatcher::~Dispatcher()
{

@ -8,8 +8,8 @@
* of this software for any purpose.
* It is provided "as is" without express or implied warranty.
*/
#ifndef COLLISION_DISPATCHER_H
#define COLLISION_DISPATCHER_H
#ifndef _DISPATCHER_H
#define _DISPATCHER_H
class CollisionAlgorithm;
struct BroadphaseProxy;
@ -18,7 +18,7 @@ class RigidBody;
enum CollisionDispatcherId
{
RIGIDBODY_DISPATCHER = 0,
RAGDOLL_DISPATCHER
USERCALLBACK_DISPATCHER
};
class PersistentManifold;
@ -45,7 +45,8 @@ struct DispatcherInfo
};
/// Collision Dispatcher can be used in combination with broadphase and collision algorithms.
/// Dispatcher can be used in combination with broadphase to dispatch overlapping pairs.
/// For example for pairwise collision detection or user callbacks (game logic).
class Dispatcher
{
@ -64,8 +65,11 @@ public:
virtual void ReleaseManifold(PersistentManifold* manifold)=0;
virtual bool NeedsCollision(BroadphaseProxy& proxy0,BroadphaseProxy& proxy1) = 0;
};
#endif //COLLISION_DISPATCHER_H
#endif //_DISPATCHER_H

@ -9,7 +9,7 @@
* It is provided "as is" without express or implied warranty.
*/
#include "SimpleBroadphase.h"
#include "BroadphaseCollision/CollisionDispatcher.h"
#include "BroadphaseCollision/Dispatcher.h"
#include "BroadphaseCollision/CollisionAlgorithm.h"
#include "SimdVector3.h"
@ -43,7 +43,7 @@ SimpleBroadphase::~SimpleBroadphase()
}
BroadphaseProxy* SimpleBroadphase::CreateProxy( void *object, int type, const SimdVector3& min, const SimdVector3& max)
BroadphaseProxy* SimpleBroadphase::CreateProxy( const SimdVector3& min, const SimdVector3& max,int shapeType,void* userPtr)
{
if (m_numProxies >= SIMPLE_MAX_PROXIES)
{
@ -53,7 +53,7 @@ BroadphaseProxy* SimpleBroadphase::CreateProxy( void *object, int type, const Si
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);
BroadphaseProxy* proxy = new (&m_proxies[freeIndex])SimpleBroadphaseProxy(min,max,shapeType,userPtr);
m_firstFreeProxy++;
m_pProxies[m_numProxies] = proxy;
@ -151,6 +151,13 @@ void SimpleBroadphase::AddOverlappingPair(BroadphaseProxy* proxy0,BroadphaseProx
assert(!m_OverlappingPairs[m_NumOverlapBroadphasePair].m_algorithms[i]);
m_OverlappingPairs[m_NumOverlapBroadphasePair].m_algorithms[i] = 0;
}
if (m_NumOverlapBroadphasePair >= SIMPLE_MAX_OVERLAP)
{
printf("Error: too many overlapping objects: m_NumOverlapBroadphasePair: %d\n",m_NumOverlapBroadphasePair);
assert(0);
}
m_NumOverlapBroadphasePair++;
}

@ -25,8 +25,8 @@ struct SimpleBroadphaseProxy : public BroadphaseProxy
SimpleBroadphaseProxy() {};
SimpleBroadphaseProxy(void* object,int type,const SimdPoint3& minpt,const SimdPoint3& maxpt)
:BroadphaseProxy(object,type),
SimpleBroadphaseProxy(const SimdPoint3& minpt,const SimdPoint3& maxpt,int shapeType,void* userPtr)
:BroadphaseProxy(shapeType,userPtr),
m_min(minpt),m_max(maxpt)
{
}
@ -64,7 +64,8 @@ public:
SimpleBroadphase();
virtual ~SimpleBroadphase();
virtual BroadphaseProxy* CreateProxy( void *object,int type, const SimdVector3& min, const SimdVector3& max) ;
virtual BroadphaseProxy* CreateProxy( const SimdVector3& min, const SimdVector3& max,int shapeType,void* userPtr);
virtual void DestroyProxy(BroadphaseProxy* proxy);
virtual void SetAabb(BroadphaseProxy* proxy,const SimdVector3& aabbMin,const SimdVector3& aabbMax);
virtual void CleanProxyFromPairs(BroadphaseProxy* proxy);

@ -233,6 +233,14 @@
RelativePath=".\NarrowPhaseCollision\CollisionMargin.h"
>
</File>
<File
RelativePath=".\NarrowPhaseCollision\CollisionObject.cpp"
>
</File>
<File
RelativePath=".\NarrowPhaseCollision\CollisionObject.h"
>
</File>
<File
RelativePath=".\NarrowPhaseCollision\ContinuousConvexCollision.cpp"
>
@ -502,11 +510,11 @@
>
</File>
<File
RelativePath=".\BroadphaseCollision\CollisionDispatcher.cpp"
RelativePath=".\BroadphaseCollision\Dispatcher.cpp"
>
</File>
<File
RelativePath=".\BroadphaseCollision\CollisionDispatcher.h"
RelativePath=".\BroadphaseCollision\Dispatcher.h"
>
</File>
<File
@ -578,6 +586,66 @@
>
</File>
</Filter>
<Filter
Name="CollisionDispatch"
>
<File
RelativePath=".\CollisionDispatch\CollisionDispatcher.cpp"
>
</File>
<File
RelativePath=".\CollisionDispatch\CollisionDispatcher.h"
>
</File>
<File
RelativePath=".\CollisionDispatch\CollisionWorld.cpp"
>
</File>
<File
RelativePath=".\CollisionDispatch\CollisionWorld.h"
>
</File>
<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\UnionFind.cpp"
>
</File>
<File
RelativePath=".\CollisionDispatch\UnionFind.h"
>
</File>
</Filter>
<File
RelativePath=".\CollisionShapes\BvhTriangleMeshShape.cpp"
>

@ -0,0 +1,224 @@
/*
* Copyright (c) 2005 Erwin Coumans http://continuousphysics.com/Bullet/
*
* 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"
#include "BroadphaseCollision/CollisionAlgorithm.h"
#include "CollisionDispatch/ConvexConvexAlgorithm.h"
#include "CollisionDispatch/EmptyCollisionAlgorithm.h"
#include "CollisionDispatch/ConvexConcaveCollisionAlgorithm.h"
#include "NarrowphaseCollision/CollisionObject.h"
#include <algorithm>
void CollisionDispatcher::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 ((((CollisionObject*)manifold->GetBody0()) && (((CollisionObject*)manifold->GetBody0())->mergesSimulationIslands())) &&
(((CollisionObject*)manifold->GetBody1()) && (((CollisionObject*)manifold->GetBody1())->mergesSimulationIslands())))
{
m_unionFind.unite(((CollisionObject*)manifold->GetBody0())->m_islandTag1,
((CollisionObject*)manifold->GetBody1())->m_islandTag1);
}
}
}
}
CollisionDispatcher::CollisionDispatcher ():
m_useIslands(true),
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* CollisionDispatcher::GetNewManifold(void* b0,void* b1)
{
CollisionObject* body0 = (CollisionObject*)b0;
CollisionObject* body1 = (CollisionObject*)b1;
PersistentManifold* manifold = new PersistentManifold (body0,body1);
m_manifoldsPtr.push_back(manifold);
return manifold;
}
void CollisionDispatcher::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 CollisionDispatcher::BuildAndProcessIslands(int numBodies, IslandCallback* callback)
{
int i;
for (int islandId=0;islandId<numBodies;islandId++)
{
std::vector<PersistentManifold*> islandmanifold;
//int numSleeping = 0;
bool allSleeping = true;
for (i=0;i<GetNumManifolds();i++)
{
PersistentManifold* manifold = this->GetManifoldByIndexInternal(i);
if ((((CollisionObject*)manifold->GetBody0()) && ((CollisionObject*)manifold->GetBody0())->m_islandTag1 == (islandId)) ||
(((CollisionObject*)manifold->GetBody1()) && ((CollisionObject*)manifold->GetBody1())->m_islandTag1 == (islandId)))
{
if ((((CollisionObject*)manifold->GetBody0()) && ((CollisionObject*)manifold->GetBody0())->GetActivationState()== ACTIVE_TAG) ||
(((CollisionObject*)manifold->GetBody1()) && ((CollisionObject*)manifold->GetBody1())->GetActivationState() == ACTIVE_TAG))
{
allSleeping = false;
}
islandmanifold.push_back(manifold);
}
}
if (allSleeping)
{
//tag all as 'ISLAND_SLEEPING'
for (i=0;i<islandmanifold.size();i++)
{
PersistentManifold* manifold = islandmanifold[i];
if (((CollisionObject*)manifold->GetBody0()))
{
((CollisionObject*)manifold->GetBody0())->SetActivationState( ISLAND_SLEEPING );
}
if (((CollisionObject*)manifold->GetBody1()))
{
((CollisionObject*)manifold->GetBody1())->SetActivationState( ISLAND_SLEEPING);
}
}
} else
{
//tag all as 'ISLAND_SLEEPING'
for (i=0;i<islandmanifold.size();i++)
{
PersistentManifold* manifold = islandmanifold[i];
CollisionObject* body0 = (CollisionObject*)manifold->GetBody0();
CollisionObject* body1 = (CollisionObject*)manifold->GetBody1();
if (body0)
{
if ( body0->GetActivationState() == ISLAND_SLEEPING)
{
body0->SetActivationState( WANTS_DEACTIVATION);
}
}
if (body1)
{
if ( body1->GetActivationState() == ISLAND_SLEEPING)
{
body1->SetActivationState(WANTS_DEACTIVATION);
}
}
}
callback->ProcessIsland(&islandmanifold[0],islandmanifold.size());
}
}
}
CollisionAlgorithm* CollisionDispatcher::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);
}
bool CollisionDispatcher::NeedsCollision(BroadphaseProxy& proxy0,BroadphaseProxy& proxy1)
{
CollisionObject* body0 = (CollisionObject*)proxy0.m_clientObject;
CollisionObject* body1 = (CollisionObject*)proxy1.m_clientObject;
assert(body0);
assert(body1);
bool needsCollision = true;
if ((body0->m_collisionFlags & CollisionObject::isStatic) &&
(body1->m_collisionFlags & CollisionObject::isStatic))
needsCollision = false;
if ((body0->GetActivationState() == 2) &&(body1->GetActivationState() == 2))
needsCollision = false;
return needsCollision ;
}

@ -1,18 +1,27 @@
#ifndef TOI_CONTACT_DISPATCHER_H
#define TOI_CONTACT_DISPATCHER_H
/*
* Copyright (c) 2002-2006 Erwin Coumans http://continuousphysics.com/Bullet/
*
* 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 "BroadphaseCollision/CollisionDispatcher.h"
#ifndef COLLISION__DISPATCHER_H
#define COLLISION__DISPATCHER_H
#include "BroadphaseCollision/Dispatcher.h"
#include "NarrowPhaseCollision/PersistentManifold.h"
#include "CollisionDispatch/UnionFind.h"
#include "BroadphaseCollision/BroadphaseProxy.h"
#include <vector>
class ConstraintSolver;
class IDebugDraw;
//island management
#define ACTIVE_TAG 1
#define ISLAND_SLEEPING 2
#define WANTS_DEACTIVATION 3
struct CollisionAlgorithmCreateFunc
@ -28,25 +37,19 @@ struct CollisionAlgorithmCreateFunc
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;
///CollisionDispatcher supports algorithms that handle ConvexConvex and ConvexConcave collision pairs.
///Time of Impact, Closest Points and Penetration Depth.
class CollisionDispatcher : public Dispatcher
{
std::vector<PersistentManifold*> m_manifoldsPtr;
UnionFind m_unionFind;
ConstraintSolver* m_solver;
bool m_useIslands;
float m_sor;
float m_tau;
float m_damping;
CollisionAlgorithmCreateFunc* m_doubleDispatch[MAX_BROADPHASE_COLLISION_TYPES][MAX_BROADPHASE_COLLISION_TYPES];
@ -54,43 +57,47 @@ public:
UnionFind& GetUnionFind() { return m_unionFind;}
// int m_firstFreeManifold;
// const PersistentManifold* GetManifoldByIndexInternal(int index)
// {
// return &m_manifolds[index];
// }
struct IslandCallback
{
virtual void ProcessIsland(PersistentManifold** manifolds,int numManifolds) = 0;
};
int GetNumManifolds() { return m_manifoldsPtr.size();}
int GetNumManifolds() const
{
return m_manifoldsPtr.size();
}
PersistentManifold* GetManifoldByIndexInternal(int index)
{
return m_manifoldsPtr[index];
return m_manifoldsPtr[index];
}
const PersistentManifold* GetManifoldByIndexInternal(int index) const
{
return m_manifoldsPtr[index];
}
void InitUnionFind()
void InitUnionFind(int n)
{
if (m_useIslands)
m_unionFind.reset();
m_unionFind.reset(n);
}
void FindUnions();
int m_count;
ToiContactDispatcher (ConstraintSolver* solver);
CollisionDispatcher ();
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,IDebugDraw* debugDrawer);
virtual void BuildAndProcessIslands(int numBodies, IslandCallback* callback);
CollisionAlgorithm* FindAlgorithm(BroadphaseProxy& proxy0,BroadphaseProxy& proxy1)
{
CollisionAlgorithm* algo = InternalFindAlgorithm(proxy0,proxy1);
@ -99,25 +106,14 @@ public:
CollisionAlgorithm* InternalFindAlgorithm(BroadphaseProxy& proxy0,BroadphaseProxy& proxy1);
virtual bool NeedsCollision(BroadphaseProxy& proxy0,BroadphaseProxy& proxy1);
virtual int GetUniqueId() { return RIGIDBODY_DISPATCHER;}
void SetSor(float sor)
{
m_sor = sor;
}
void SetTau(float tau)
{
m_tau = tau;
}
void SetDamping( float damping)
{
m_damping = damping;
}
};
#endif //TOI_CONTACT_DISPATCHER_H
#endif //COLLISION__DISPATCHER_H

@ -0,0 +1,123 @@
/*
* Copyright (c) 2002-2006 Erwin Coumans http://continuousphysics.com/Bullet/
*
* 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 "CollisionWorld.h"
#include "CollisionDispatcher.h"
#include "NarrowphaseCollision/CollisionObject.h"
#include "CollisionShapes/CollisionShape.h"
#include "BroadphaseCollision/BroadphaseInterface.h"
#include <algorithm>
void CollisionWorld::UpdateActivationState()
{
m_dispatcher->InitUnionFind(m_collisionObjects.size());
// put the index into m_controllers into m_tag
{
std::vector<CollisionObject*>::iterator i;
int index = 0;
for (i=m_collisionObjects.begin();
!(i==m_collisionObjects.end()); i++)
{
CollisionObject* collisionObject= (*i);
collisionObject->m_islandTag1 = index;
collisionObject->m_hitFraction = 1.f;
index++;
}
}
// do the union find
m_dispatcher->FindUnions();
// put the islandId ('find' value) into m_tag
{
UnionFind& unionFind = m_dispatcher->GetUnionFind();
std::vector<CollisionObject*>::iterator i;
int index = 0;
for (i=m_collisionObjects.begin();
!(i==m_collisionObjects.end()); i++)
{
CollisionObject* collisionObject= (*i);
if (collisionObject->mergesSimulationIslands())
{
collisionObject->m_islandTag1 = unionFind.find(index);
} else
{
collisionObject->m_islandTag1 = -1;
}
index++;
}
}
}
void CollisionWorld::AddCollisionObject(CollisionObject* collisionObject)
{
m_collisionObjects.push_back(collisionObject);
//calculate new AABB
SimdTransform trans = collisionObject->m_worldTransform;
SimdVector3 minAabb;
SimdVector3 maxAabb;
collisionObject->m_collisionShape->GetAabb(trans,minAabb,maxAabb);
int type = collisionObject->m_collisionShape->GetShapeType();
collisionObject->m_broadphaseHandle = GetBroadphase()->CreateProxy(
minAabb,
maxAabb,
type,
collisionObject
);
}
void CollisionWorld::RemoveCollisionObject(CollisionObject* collisionObject)
{
bool removeFromBroadphase = false;
{
BroadphaseInterface* scene = GetBroadphase();
BroadphaseProxy* bp = collisionObject->m_broadphaseHandle;
//
// only clear the cached algorithms
//
GetBroadphase()->CleanProxyFromPairs(bp);
GetBroadphase()->DestroyProxy(bp);
}
std::vector<CollisionObject*>::iterator i = std::find(m_collisionObjects.begin(), m_collisionObjects.end(), collisionObject);
if (!(i == m_collisionObjects.end()))
{
std::swap(*i, m_collisionObjects.back());
m_collisionObjects.pop_back();
}
}

@ -0,0 +1,64 @@
/*
* Copyright (c) 2002-2006 Erwin Coumans http://continuousphysics.com/Bullet/
*
* 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_WORLD_H
#define COLLISION_WORLD_H
struct CollisionObject;
class CollisionDispatcher;
class BroadphaseInterface;
#include <vector>
///CollisionWorld is interface and container for the collision detection
class CollisionWorld
{
std::vector<CollisionObject*> m_collisionObjects;
CollisionDispatcher* m_dispatcher;
BroadphaseInterface* m_broadphase;
public:
CollisionWorld(CollisionDispatcher* dispatcher,BroadphaseInterface* broadphase)
:m_dispatcher(dispatcher),
m_broadphase(broadphase)
{
}
virtual void UpdateActivationState();
BroadphaseInterface* GetBroadphase()
{
return m_broadphase;
}
CollisionDispatcher* GetDispatcher()
{
return m_dispatcher;
}
int GetNumCollisionObjects() const
{
return m_collisionObjects.size();
}
void AddCollisionObject(CollisionObject* collisionObject);
void RemoveCollisionObject(CollisionObject* collisionObject);
};
#endif //COLLISION_WORLD_H

@ -10,15 +10,12 @@
*/
#include "ConvexConcaveCollisionAlgorithm.h"
#include "Dynamics/RigidBody.h"
#include "NarrowPhaseCollision/CollisionObject.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"
@ -76,29 +73,30 @@ void BoxTriangleCallback::ProcessTriangle(SimdVector3* triangle)
//printf("triangle %d",m_triangleCount++);
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]);
tm.SetMargin(m_collisionMarginTriangle);
CollisionObject* ob = static_cast<CollisionObject*>(m_triangleProxy.m_clientObject);
RigidBody* triangleBody = (RigidBody* )m_triangleProxy.m_clientObject;
CollisionShape* tmpShape = ob->m_collisionShape;
ob->m_collisionShape = &tm;
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);
ob->m_collisionShape = tmpShape;
}
triangleBody->SetCollisionShape(tmp);
}
@ -113,13 +111,16 @@ void BoxTriangleCallback::SetTimeStepAndCounters(float timeStep,int stepCount,fl
m_collisionMarginTriangle = collisionMarginTriangle;
//recalc aabbs
RigidBody* boxBody = (RigidBody* )m_boxProxy->m_clientObject;
RigidBody* triBody = (RigidBody* )m_triangleProxy.m_clientObject;
CollisionObject* boxBody = (CollisionObject* )m_boxProxy->m_clientObject;
CollisionObject* triBody = (CollisionObject* )m_triangleProxy.m_clientObject;
SimdTransform boxInTriangleSpace;
boxInTriangleSpace = triBody->getCenterOfMassTransform().inverse() * boxBody->getCenterOfMassTransform();
boxInTriangleSpace = triBody->m_worldTransform.inverse() * boxBody->m_worldTransform;
boxBody->GetCollisionShape()->GetAabb(boxInTriangleSpace,m_aabbMin,m_aabbMax);
CollisionShape* boxshape = static_cast<CollisionShape*>(boxBody->m_collisionShape);
CollisionShape* triangleShape = static_cast<CollisionShape*>(triBody->m_collisionShape);
boxshape->GetAabb(boxInTriangleSpace,m_aabbMin,m_aabbMax);
float extraMargin = collisionMarginTriangle;//CONVEX_DISTANCE_MARGIN;//+0.1f;
@ -142,15 +143,13 @@ void ConvexConcaveCollisionAlgorithm::ProcessCollision (BroadphaseProxy* ,Broadp
if (m_concave.GetClientObjectType() == TRIANGLE_MESH_SHAPE_PROXYTYPE)
{
RigidBody* convexbody = (RigidBody* )m_convex.m_clientObject;
RigidBody* concavebody = (RigidBody* )m_concave.m_clientObject;
if (!m_dispatcher->NeedsCollision(m_convex,m_concave))
return;
//todo: move this in the dispatcher
if ((convexbody->GetActivationState() == 2) &&(concavebody->GetActivationState() == 2))
return;
TriangleMeshShape* triangleMesh = (TriangleMeshShape*) concavebody->GetCollisionShape();
CollisionObject* triOb = static_cast<CollisionObject*>(m_concave.m_clientObject);
TriangleMeshShape* triangleMesh = static_cast<TriangleMeshShape*>( triOb->m_collisionShape);
if (m_convex.IsConvexShape())
{
@ -160,7 +159,7 @@ void ConvexConcaveCollisionAlgorithm::ProcessCollision (BroadphaseProxy* ,Broadp
#ifdef USE_BOX_TRIANGLE
m_boxTriangleCallback.m_manifoldPtr->ClearManifold();
#endif
m_boxTriangleCallback.m_manifoldPtr->SetBodies(convexbody,concavebody);
m_boxTriangleCallback.m_manifoldPtr->SetBodies(m_convex.m_clientObject,m_concave.m_clientObject);
triangleMesh->ProcessAllTriangles( &m_boxTriangleCallback,m_boxTriangleCallback.GetAabbMin(),m_boxTriangleCallback.GetAabbMax());
@ -175,24 +174,11 @@ void ConvexConcaveCollisionAlgorithm::ProcessCollision (BroadphaseProxy* ,Broadp
float ConvexConcaveCollisionAlgorithm::CalculateTimeOfImpact(BroadphaseProxy* ,BroadphaseProxy* ,float timeStep,int stepCount)
{
return 1.f;
//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);
CollisionObject* convexbody = (CollisionObject* )m_convex.m_clientObject;
const SimdVector3& from = convexbody->m_worldTransform.getOrigin();
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;
SimdVector3 to = convexbody->m_nextPredictedWorldTransform.getOrigin();
//only do if the motion exceeds the 'radius'
@ -206,9 +192,9 @@ float ConvexConcaveCollisionAlgorithm::CalculateTimeOfImpact(BroadphaseProxy* ,B
if (m_concave.GetClientObjectType() == TRIANGLE_MESH_SHAPE_PROXYTYPE)
{
RigidBody* concavebody = (RigidBody* )m_concave.m_clientObject;
CollisionObject* concavebody = (CollisionObject* )m_concave.m_clientObject;
TriangleMeshShape* triangleMesh = (TriangleMeshShape*) concavebody->GetCollisionShape();
TriangleMeshShape* triangleMesh = (TriangleMeshShape*) concavebody->m_collisionShape;
if (triangleMesh)
{

@ -12,7 +12,7 @@
#define CONVEX_CONCAVE_COLLISION_ALGORITHM_H
#include "BroadphaseCollision/CollisionAlgorithm.h"
#include "BroadphaseCollision/CollisionDispatcher.h"
#include "BroadphaseCollision/Dispatcher.h"
#include "BroadphaseCollision/BroadphaseInterface.h"
#include "CollisionShapes/TriangleCallback.h"
#include "NarrowPhaseCollision/PersistentManifold.h"

@ -13,11 +13,11 @@
#include <stdio.h>
#include "NarrowPhaseCollision/DiscreteCollisionDetectorInterface.h"
#include "BroadphaseCollision/BroadphaseInterface.h"
#include "Dynamics/RigidBody.h"
#include "NarrowPhaseCollision/CollisionObject.h"
#include "CollisionShapes/ConvexShape.h"
#include "NarrowPhaseCollision/GjkPairDetector.h"
#include "BroadphaseCollision/BroadphaseProxy.h"
#include "BroadphaseCollision/CollisionDispatcher.h"
#include "CollisionDispatch/CollisionDispatcher.h"
#include "CollisionShapes/BoxShape.h"
#include "CollisionDispatch/ManifoldResult.h"
@ -75,13 +75,8 @@ m_useEpa(!gUseEpa)
{
CheckPenetrationDepthSolver();
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)
if (!m_manifoldPtr && m_dispatcher->NeedsCollision(m_box0,m_box1))
{
m_manifoldPtr = m_dispatcher->GetNewManifold(proxy0->m_clientObject,proxy1->m_clientObject);
m_ownManifold = true;
@ -169,32 +164,25 @@ void ConvexConvexAlgorithm::CheckPenetrationDepthSolver()
//
void ConvexConvexAlgorithm ::ProcessCollision (BroadphaseProxy* ,BroadphaseProxy* ,float timeStep,int stepCount, bool useContinuous)
{
if (!m_manifoldPtr)
return;
CheckPenetrationDepthSolver();
// printf("ConvexConvexAlgorithm::ProcessCollision\n");
bool needsCollision = m_dispatcher->NeedsCollision(m_box0,m_box1);
if (!needsCollision)
return;
RigidBody* body0 = (RigidBody*)m_box0.m_clientObject;
RigidBody* body1 = (RigidBody*)m_box1.m_clientObject;
//todo: move this in the dispatcher
if ((body0->GetActivationState() == 2) &&(body1->GetActivationState() == 2))
return;
if (!m_manifoldPtr)
return;
if ((body0->getInvMass() == 0.f) &&
(body1->getInvMass() == 0.f))
{
return;
}
ManifoldResult output(body0,body1,m_manifoldPtr);
CollisionObject* col0 = static_cast<CollisionObject*>(m_box0.m_clientObject);
CollisionObject* col1 = static_cast<CollisionObject*>(m_box1.m_clientObject);
ManifoldResult output(col0,col1,m_manifoldPtr);
ConvexShape* min0 = static_cast<ConvexShape*>(col0->m_collisionShape);
ConvexShape* min1 = static_cast<ConvexShape*>(col1->m_collisionShape);
ConvexShape* min0 = static_cast<ConvexShape*>(body0->GetCollisionShape());
ConvexShape* min1 = static_cast<ConvexShape*>(body1->GetCollisionShape());
GjkPairDetector::ClosestPointInput input;
SphereShape sphere(0.2f);
@ -218,8 +206,8 @@ void ConvexConvexAlgorithm ::ProcessCollision (BroadphaseProxy* ,BroadphaseProxy
input.m_maximumDistanceSquared = 1e30;//
input.m_transformA = body0->getCenterOfMassTransform();
input.m_transformB = body1->getCenterOfMassTransform();
input.m_transformA = col0->m_worldTransform;
input.m_transformB = col1->m_worldTransform;
m_gjkPairDetector.GetClosestPoints(input,output);
@ -231,35 +219,20 @@ float ConvexConvexAlgorithm::CalculateTimeOfImpact(BroadphaseProxy* proxy0,Broad
CheckPenetrationDepthSolver();
RigidBody* body0 = (RigidBody*)m_box0.m_clientObject;
RigidBody* body1 = (RigidBody*)m_box1.m_clientObject;
bool needsCollision = m_dispatcher->NeedsCollision(m_box0,m_box1);
if (!m_manifoldPtr)
if (!needsCollision)
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);
CollisionObject* col0 = static_cast<CollisionObject*>(m_box0.m_clientObject);
CollisionObject* col1 = static_cast<CollisionObject*>(m_box1.m_clientObject);
ConvexShape* min0 = static_cast<ConvexShape*>(col0->m_collisionShape);
ConvexShape* min1 = static_cast<ConvexShape*>(col1->m_collisionShape);
ConvexCast::CastResult result;
VoronoiSimplexSolver voronoiSimplex;
//SubsimplexConvexCast ccd(&voronoiSimplex);
//GjkConvexCast ccd(&voronoiSimplex);
@ -269,25 +242,22 @@ float ConvexConvexAlgorithm::CalculateTimeOfImpact(BroadphaseProxy* proxy0,Broad
if (disableCcd)
return 1.f;
if (ccd.calcTimeOfImpact(input.m_transformA,predictA,input.m_transformB,predictB,result))
if (ccd.calcTimeOfImpact(col0->m_worldTransform,col0->m_nextPredictedWorldTransform,
col1->m_worldTransform,col1->m_nextPredictedWorldTransform,result))
{
//store result.m_fraction in both bodies
int i;
i=0;
// if (result.m_fraction< 0.1f)
// result.m_fraction = 0.1f;
if (col0->m_hitFraction > result.m_fraction)
col0->m_hitFraction = result.m_fraction;
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;
if (col1->m_hitFraction > result.m_fraction)
col1->m_hitFraction = result.m_fraction;
return result.m_fraction;
}
return 1.f;

@ -11,9 +11,9 @@
#include "ManifoldResult.h"
#include "NarrowPhaseCollision/PersistentManifold.h"
#include "Dynamics/RigidBody.h"
#include "NarrowPhaseCollision/CollisionObject.h"
ManifoldResult::ManifoldResult(RigidBody* body0,RigidBody* body1,PersistentManifold* manifoldPtr)
ManifoldResult::ManifoldResult(CollisionObject* body0,CollisionObject* body1,PersistentManifold* manifoldPtr)
:m_manifoldPtr(manifoldPtr),
m_body0(body0),
m_body1(body1)
@ -25,8 +25,8 @@ void ManifoldResult::AddContactPoint(const SimdVector3& normalOnBInWorld,const S
if (depth > m_manifoldPtr->GetManifoldMargin())
return;
SimdTransform transAInv = m_body0->getCenterOfMassTransform().inverse();
SimdTransform transBInv= m_body1->getCenterOfMassTransform().inverse();
SimdTransform transAInv = m_body0->m_worldTransform.inverse();
SimdTransform transBInv= m_body1->m_worldTransform.inverse();
SimdVector3 pointA = pointInWorld + normalOnBInWorld * depth;
SimdVector3 localA = transAInv(pointA );
SimdVector3 localB = transBInv(pointInWorld);

@ -13,19 +13,19 @@
#define MANIFOLD_RESULT_H
#include "NarrowPhaseCollision/DiscreteCollisionDetectorInterface.h"
class RigidBody;
struct CollisionObject;
class PersistentManifold;
class ManifoldResult : public DiscreteCollisionDetectorInterface::Result
{
PersistentManifold* m_manifoldPtr;
RigidBody* m_body0;
RigidBody* m_body1;
CollisionObject* m_body0;
CollisionObject* m_body1;
public:
ManifoldResult(RigidBody* body0,RigidBody* body1,PersistentManifold* manifoldPtr);
ManifoldResult(CollisionObject* body0,CollisionObject* body1,PersistentManifold* manifoldPtr);
virtual void AddContactPoint(const SimdVector3& normalOnBInWorld,const SimdVector3& pointInWorld,float depth);

@ -0,0 +1,85 @@
#include "UnionFind.h"
#include <assert.h>
int UnionFind::find(int x)
{
assert(x < m_N);
assert(x >= 0);
while (x != m_id[x])
{
x = m_id[x];
assert(x < m_N);
assert(x >= 0);
}
return x;
}
UnionFind::~UnionFind()
{
Free();
}
UnionFind::UnionFind()
:m_id(0),
m_sz(0),
m_N(0)
{
}
void UnionFind::Allocate(int N)
{
if (m_N < N)
{
Free();
m_N = N;
m_id = new int[N];
m_sz = new int[N];
}
}
void UnionFind::Free()
{
if (m_N)
{
m_N=0;
delete m_id;
delete m_sz;
}
}
void UnionFind::reset(int N)
{
Allocate(N);
for (int i = 0; i < m_N; i++)
{
m_id[i] = i; m_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 (m_sz[i] < m_sz[j])
{
m_id[i] = j; m_sz[j] += m_sz[i];
}
else
{
m_id[j] = i; m_sz[i] += m_sz[j];
}
}

@ -5,16 +5,24 @@
class UnionFind
{
private:
int *id, *sz;
int m_N;
int* m_id;
int* m_sz;
int m_N;
public:
int find(int x);
UnionFind(int N);
void reset();
int find(int x);
UnionFind();
~UnionFind();
void reset(int N);
int find(int p, int q);
void unite(int p, int q);
void Allocate(int N);
void Free();
};

@ -0,0 +1,19 @@
#include "CollisionObject.h"
void CollisionObject::SetActivationState(int newState)
{
m_activationState1 = newState;
}
void CollisionObject::activate()
{
SetActivationState(1);
m_deactivationTime = 0.f;
}
bool CollisionObject::mergesSimulationIslands() const
{
return ( !(m_collisionFlags & isStatic));
}

@ -0,0 +1,67 @@
#ifndef COLLISION_OBJECT_H
#define COLLISION_OBJECT_H
#include "SimdTransform.h"
//island management, m_activationState1
#define ACTIVE_TAG 1
#define ISLAND_SLEEPING 2
#define WANTS_DEACTIVATION 3
struct BroadphaseProxy;
class CollisionShape;
struct CollisionObject
{
SimdTransform m_worldTransform;
//m_nextPredictedWorldTransform is used for CCD and interpolation
SimdTransform m_nextPredictedWorldTransform;
enum CollisionFlags
{
isStatic = 1,
};
int m_collisionFlags;
int m_islandTag1;
int m_activationState1;
float m_deactivationTime;
BroadphaseProxy* m_broadphaseHandle;
CollisionShape* m_collisionShape;
//time of impact calculation
float m_hitFraction;
bool mergesSimulationIslands() const;
CollisionObject()
: m_activationState1(1),
m_deactivationTime(0.f),
m_collisionFlags(0),
m_hitFraction(1.f),
m_broadphaseHandle(0),
m_collisionShape(0)
{
}
void SetCollisionShape(CollisionShape* collisionShape)
{
m_collisionShape = collisionShape;
}
int GetActivationState() const { return m_activationState1;}
void SetActivationState(int newState);
void activate();
};
#endif //COLLISION_OBJECT_H

@ -115,7 +115,7 @@ bool SubsimplexConvexCast::calcTimeOfImpact(
int numiter = MAX_ITERATIONS - maxIter;
// printf("number of iterations: %d", numiter);
result.m_fraction = lambda;
result.m_normal = n;
result.m_normal = -n;
return true;
}

@ -41,12 +41,12 @@
Optimization="0"
AdditionalIncludeDirectories="..\LinearMath;..\Bullet;..\BulletDynamics"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
MinimalRebuild="TRUE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
/>
<Tool
@ -72,7 +72,7 @@
Name="VCBscMakeTool"
/>
<Tool
Name="VCAppVerifierTool"
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
@ -107,7 +107,7 @@
RuntimeLibrary="0"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
@ -133,7 +133,7 @@
Name="VCBscMakeTool"
/>
<Tool
Name="VCAppVerifierTool"
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
@ -208,54 +208,50 @@
</File>
</Filter>
<Filter
Name="CollisionDispatch"
Name="Vehicle"
>
<File
RelativePath=".\CollisionDispatch\ConvexConcaveCollisionAlgorithm.cpp"
RelativePath=".\Vehicle\RaycastVehicle.cpp"
>
</File>
<File
RelativePath=".\CollisionDispatch\ConvexConcaveCollisionAlgorithm.h"
RelativePath=".\Vehicle\RaycastVehicle.h"
>
</File>
<File
RelativePath=".\CollisionDispatch\ConvexConvexAlgorithm.cpp"
RelativePath=".\Vehicle\VehicleControl.h"
>
</File>
<File
RelativePath=".\CollisionDispatch\ConvexConvexAlgorithm.h"
RelativePath=".\Vehicle\VehicleFrame.h"
>
</File>
<File
RelativePath=".\CollisionDispatch\EmptyCollisionAlgorithm.cpp"
RelativePath=".\Vehicle\VehicleInputController.h"
>
</File>
<File
RelativePath=".\CollisionDispatch\EmptyCollisionAlgorithm.h"
RelativePath=".\Vehicle\VehicleRaycaster.h"
>
</File>
<File
RelativePath=".\CollisionDispatch\ManifoldResult.cpp"
RelativePath=".\Vehicle\VehicleTuning.cpp"
>
</File>
<File
RelativePath=".\CollisionDispatch\ManifoldResult.h"
RelativePath=".\Vehicle\VehicleTuning.h"
>
</File>
<File
RelativePath=".\CollisionDispatch\ToiContactDispatcher.cpp"
RelativePath=".\Vehicle\WheelInfo.cpp"
>
</File>
<File
RelativePath=".\CollisionDispatch\ToiContactDispatcher.h"
RelativePath=".\Vehicle\WheelInfo.h"
>
</File>
<File
RelativePath=".\CollisionDispatch\UnionFind.cpp"
>
</File>
<File
RelativePath=".\CollisionDispatch\UnionFind.h"
RelativePath=".\Vehicle\WheelSkidInfo.h"
>
</File>
</Filter>

@ -1,213 +0,0 @@
#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"
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),
m_sor(1.3f),
m_tau(0.4f),
m_damping(0.9f)
{
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,IDebugDraw* debugDrawer)
{
int i;
for (int islandId=0;islandId<numRigidBodies;islandId++)
{
std::vector<PersistentManifold*> islandmanifold;
//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;
}
islandmanifold.push_back(manifold);
}
}
if (allSleeping)
{
//tag all as 'ISLAND_SLEEPING'
for (i=0;i<islandmanifold.size();i++)
{
PersistentManifold* manifold = islandmanifold[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<islandmanifold.size();i++)
{
PersistentManifold* manifold = islandmanifold[i];
RigidBody* body0 = (RigidBody*)manifold->GetBody0();
RigidBody* body1 = (RigidBody*)manifold->GetBody1();
if (body0)
{
if ( body0->GetActivationState() == ISLAND_SLEEPING)
{
body0->SetActivationState( WANTS_DEACTIVATION);
}
}
if (body1)
{
if ( body1->GetActivationState() == ISLAND_SLEEPING)
{
body1->SetActivationState(WANTS_DEACTIVATION);
}
}
}
///This island solving can all be scheduled in parallel
ContactSolverInfo info;
info.m_friction = 0.9f;
info.m_numIterations = numIterations;
info.m_timeStep = timeStep;
info.m_restitution = 0.0f;//m_restitution;
info.m_sor = m_sor;
info.m_tau = m_tau;
info.m_damping = m_damping;
m_solver->SolveGroup( &islandmanifold[0], islandmanifold.size(),info,debugDrawer );
}
}
}
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);
}

@ -1,54 +0,0 @@
#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];
}
}

@ -9,10 +9,7 @@ float gLinearAirDamping = 1.f;
static int uniqueId = 0;
RigidBody::RigidBody( const MassProps& massProps,SimdScalar linearDamping,SimdScalar angularDamping,SimdScalar friction,SimdScalar restitution)
: m_collisionShape(0),
m_activationState1(1),
m_deactivationTime(0.f),
m_hitFraction(1.f),
:
m_gravity(0.0f, 0.0f, 0.0f),
m_linearDamping(0.f),
m_angularDamping(0.5f),
@ -32,11 +29,7 @@ RigidBody::RigidBody( const MassProps& massProps,SimdScalar linearDamping,SimdSc
}
void RigidBody::activate()
{
SetActivationState(1);
m_deactivationTime = 0.f;
}
void RigidBody::setLinearVelocity(const SimdVector3& lin_vel)
{
@ -52,13 +45,9 @@ void RigidBody::predictIntegratedTransform(SimdScalar timeStep,SimdTransform& pr
void RigidBody::getAabb(SimdVector3& aabbMin,SimdVector3& aabbMax) const
{
m_collisionShape ->GetAabb(m_worldTransform,aabbMin,aabbMax);
GetCollisionShape()->GetAabb(m_worldTransform,aabbMin,aabbMax);
}
void RigidBody::SetCollisionShape(CollisionShape* mink)
{
m_collisionShape = mink;
}
void RigidBody::setGravity(const SimdVector3& acceleration)
@ -69,15 +58,8 @@ void RigidBody::setGravity(const SimdVector3& acceleration)
}
}
bool RigidBody::mergesSimulationIslands() const
{
return ( getInvMass() != 0) ;
}
void RigidBody::SetActivationState(int newState)
{
m_activationState1 = newState;
}
@ -110,7 +92,17 @@ void RigidBody::proceedToTransform(const SimdTransform& newTrans)
void RigidBody::setMassProps(SimdScalar mass, const SimdVector3& inertia)
{
m_inverseMass = mass != 0.0f ? 1.0f / mass : 0.0f;
if (mass == 0.f)
{
m_collisionFlags = CollisionObject::isStatic;
m_inverseMass = 0.f;
} else
{
m_collisionFlags = 0;
m_inverseMass = 1.0f / mass;
}
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);
@ -152,12 +144,6 @@ SimdQuaternion RigidBody::getOrientation() const
void RigidBody::setCenterOfMassTransform(const SimdTransform& xform)
{
m_worldTransform = xform;
SimdQuaternion orn;
// m_worldTransform.getBasis().getRotation(orn);
// orn.normalize();
// m_worldTransform.setBasis(SimdMatrix3x3(orn));
// m_worldTransform.getBasis().getRotation(m_orn1);
updateInertiaTensor();
}

@ -4,6 +4,10 @@
#include <vector>
#include <SimdPoint3.h>
#include <SimdTransform.h>
#include "BroadphaseCollision/BroadphaseProxy.h"
#include "NarrowPhaseCollision/CollisionObject.h"
class CollisionShape;
struct MassProps;
@ -17,14 +21,14 @@ extern bool gUseEpa;
/// RigidBody class for RigidBody Dynamics
///
class RigidBody {
class RigidBody : public CollisionObject
{
public:
RigidBody(const MassProps& massProps,SimdScalar linearDamping,SimdScalar angularDamping,SimdScalar friction,SimdScalar restitution);
void proceedToTransform(const SimdTransform& newTrans);
bool mergesSimulationIslands() const;
/// continuous collision detection needs prediction
void predictIntegratedTransform(SimdScalar step, SimdTransform& predictedTransform) const;
@ -35,7 +39,13 @@ public:
void setDamping(SimdScalar lin_damping, SimdScalar ang_damping);
CollisionShape* GetCollisionShape() { return m_collisionShape; }
inline const CollisionShape* GetCollisionShape() const {
return m_collisionShape;
}
inline CollisionShape* GetCollisionShape() {
return m_collisionShape;
}
void setMassProps(SimdScalar mass, const SimdVector3& inertia);
@ -121,12 +131,9 @@ public:
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);
void setRestitution(float rest)
{
@ -144,10 +151,9 @@ public:
{
return m_friction;
}
void activate();
private:
SimdTransform m_worldTransform;
SimdMatrix3x3 m_invInertiaTensorWorld;
SimdVector3 m_gravity;
SimdVector3 m_invInertiaLocal;
@ -166,23 +172,36 @@ private:
SimdScalar m_friction;
SimdScalar m_restitution;
CollisionShape* m_collisionShape;
BroadphaseProxy* m_broadphaseProxy;
public:
const BroadphaseProxy* GetBroadphaseProxy() const
{
return m_broadphaseProxy;
}
BroadphaseProxy* GetBroadphaseProxy()
{
return m_broadphaseProxy;
}
void SetBroadphaseProxy(BroadphaseProxy* broadphaseProxy)
{
m_broadphaseProxy = broadphaseProxy;
}
/// for ode solver-binding
dMatrix3 m_R;//temp
dMatrix3 m_I;
dMatrix3 m_invI;
int m_islandTag1;//temp
int m_activationState1;//temp
float m_deactivationTime;
int m_odeTag;
float m_padding[1024];
SimdVector3 m_tacc;//temp
SimdVector3 m_facc;
SimdScalar m_hitFraction; //time of impact calculation
int m_debugBodyId;
};

@ -3,7 +3,10 @@
#include "Dynamics/RigidBody.h"
#include "PHY_IMotionState.h"
#include "BroadphaseCollision/BroadphaseProxy.h"
#include "BroadphaseCollision/BroadphaseInterface.h"
#include "CollisionShapes/ConvexShape.h"
#include "CcdPhysicsEnvironment.h"
class BP_Proxy;
@ -20,45 +23,19 @@ float gAngularSleepingTreshold = 1.0f;
SimdVector3 startVel(0,0,0);//-10000);
CcdPhysicsController::CcdPhysicsController (const CcdConstructionInfo& ci)
:m_cci(ci)
{
m_collisionDelay = 0;
m_newClientInfo = 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,ci.m_friction,ci.m_restitution);
m_body->SetCollisionShape( ci.m_collisionShape);
CreateRigidbody();
m_broadphaseHandle = ci.m_broadphaseHandle;
//
// init the rigidbody properly
//
m_body->setMassProps(ci.m_mass, ci.m_localInertiaTensor);
m_body->setGravity( ci.m_gravity);
m_body->setDamping(ci.m_linearDamping, ci.m_angularDamping);
m_body->setCenterOfMassTransform( trans );
#ifdef WIN32
if (m_body->getInvMass())
m_body->setLinearVelocity(startVel);
@ -66,9 +43,47 @@ CcdPhysicsController::CcdPhysicsController (const CcdConstructionInfo& ci)
}
SimdTransform CcdPhysicsController::GetTransformFromMotionState(PHY_IMotionState* motionState)
{
SimdTransform trans;
float tmp[3];
motionState->getWorldPosition(tmp[0],tmp[1],tmp[2]);
trans.setOrigin(SimdVector3(tmp[0],tmp[1],tmp[2]));
SimdQuaternion orn;
motionState->getWorldOrientation(orn[0],orn[1],orn[2],orn[3]);
trans.setRotation(orn);
return trans;
}
void CcdPhysicsController::CreateRigidbody()
{
SimdTransform trans = GetTransformFromMotionState(m_cci.m_MotionState);
MassProps mp(m_cci.m_mass, m_cci.m_localInertiaTensor);
m_body = new RigidBody(mp,0,0,m_cci.m_friction,m_cci.m_restitution);
m_body->m_collisionShape = m_cci.m_collisionShape;
//
// init the rigidbody properly
//
m_body->setMassProps(m_cci.m_mass, m_cci.m_localInertiaTensor * m_cci.m_inertiaFactor);
m_body->setGravity( m_cci.m_gravity);
m_body->setDamping(m_cci.m_linearDamping, m_cci.m_angularDamping);
m_body->setCenterOfMassTransform( trans );
}
CcdPhysicsController::~CcdPhysicsController()
{
//will be reference counted, due to sharing
m_cci.m_physicsEnv->removeCcdPhysicsController(this);
delete m_MotionState;
delete m_body;
}
@ -88,20 +103,12 @@ bool CcdPhysicsController::SynchronizeMotionStates(float time)
float scale[3];
m_MotionState->getWorldScaling(scale[0],scale[1],scale[2]);
SimdVector3 scaling(scale[0],scale[1],scale[2]);
m_body->GetCollisionShape()->setLocalScaling(scaling);
GetCollisionShape()->setLocalScaling(scaling);
return true;
}
CollisionShape* CcdPhysicsController::GetCollisionShape()
{
return m_body->GetCollisionShape();
}
/**
WriteMotionStateToDynamics synchronizes dynas, kinematic and deformable entities (and do 'late binding')
*/
@ -116,13 +123,60 @@ void CcdPhysicsController::WriteDynamicsToMotionState()
// controller replication
void CcdPhysicsController::PostProcessReplica(class PHY_IMotionState* motionstate,class PHY_IPhysicsController* parentctrl)
{
m_MotionState = motionstate;
m_body = 0;
CreateRigidbody();
m_cci.m_physicsEnv->addCcdPhysicsController(this);
/* SM_Object* dynaparent=0;
SumoPhysicsController* sumoparentctrl = (SumoPhysicsController* )parentctrl;
if (sumoparentctrl)
{
dynaparent = sumoparentctrl->GetSumoObject();
}
SM_Object* orgsumoobject = m_sumoObj;
m_sumoObj = new SM_Object(
orgsumoobject->getShapeHandle(),
orgsumoobject->getMaterialProps(),
orgsumoobject->getShapeProps(),
dynaparent);
m_sumoObj->setRigidBody(orgsumoobject->isRigidBody());
m_sumoObj->setMargin(orgsumoobject->getMargin());
m_sumoObj->setPosition(orgsumoobject->getPosition());
m_sumoObj->setOrientation(orgsumoobject->getOrientation());
//if it is a dyna, register for a callback
m_sumoObj->registerCallback(*this);
m_sumoScene->add(* (m_sumoObj));
*/
}
// kinematic methods
void CcdPhysicsController::RelativeTranslate(float dlocX,float dlocY,float dlocZ,bool local)
{
SimdVector3 dloc(dlocX,dlocY,dlocZ);
SimdTransform xform = m_body->getCenterOfMassTransform();
xform.setOrigin(xform.getOrigin() + SimdVector3(dlocX,dlocY,dlocZ));
if (local)
{
dloc = xform.getBasis()*dloc;
}
xform.setOrigin(xform.getOrigin() + dloc);
this->m_body->setCenterOfMassTransform(xform);
}
@ -159,7 +213,11 @@ void CcdPhysicsController::GetWorldOrientation(SimdMatrix3x3& mat)
void CcdPhysicsController::getOrientation(float &quatImag0,float &quatImag1,float &quatImag2,float &quatReal)
{
SimdQuaternion q = m_body->getCenterOfMassTransform().getRotation();
quatImag0 = q[0];
quatImag1 = q[1];
quatImag2 = q[2];
quatReal = q[3];
}
void CcdPhysicsController::setOrientation(float quatImag0,float quatImag1,float quatImag2,float quatReal)
{
@ -186,31 +244,71 @@ void CcdPhysicsController::resolveCombinedVelocities(float linvelX,float linvel
void CcdPhysicsController::getPosition(PHY__Vector3& pos) const
{
assert(0);
const SimdTransform& xform = m_body->getCenterOfMassTransform();
pos[0] = xform.getOrigin().x();
pos[1] = xform.getOrigin().y();
pos[2] = xform.getOrigin().z();
}
void CcdPhysicsController::setScaling(float scaleX,float scaleY,float scaleZ)
{
if (!SimdFuzzyZero(m_cci.m_scaling.x()-scaleX) ||
!SimdFuzzyZero(m_cci.m_scaling.y()-scaleY) ||
!SimdFuzzyZero(m_cci.m_scaling.z()-scaleZ))
{
m_cci.m_scaling = SimdVector3(scaleX,scaleY,scaleZ);
if (m_body && m_body->GetCollisionShape())
{
m_body->GetCollisionShape()->setLocalScaling(m_cci.m_scaling);
m_body->GetCollisionShape()->CalculateLocalInertia(m_cci.m_mass, m_cci.m_localInertiaTensor);
m_body->setMassProps(m_cci.m_mass, m_cci.m_localInertiaTensor * m_cci.m_inertiaFactor);
}
}
}
// physics methods
void CcdPhysicsController::ApplyTorque(float torqueX,float torqueY,float torqueZ,bool local)
{
SimdVector3 torque(torqueX,torqueY,torqueZ);
SimdTransform xform = m_body->getCenterOfMassTransform();
if (local)
{
torque = xform.getBasis()*torque;
}
m_body->applyTorque(torque);
}
void CcdPhysicsController::ApplyForce(float forceX,float forceY,float forceZ,bool local)
{
SimdVector3 force(forceX,forceY,forceZ);
SimdTransform xform = m_body->getCenterOfMassTransform();
if (local)
{
force = xform.getBasis()*force;
}
m_body->applyCentralForce(force);
}
void CcdPhysicsController::SetAngularVelocity(float ang_velX,float ang_velY,float ang_velZ,bool local)
{
SimdVector3 angvel(ang_velX,ang_velY,ang_velZ);
SimdTransform xform = m_body->getCenterOfMassTransform();
if (local)
{
angvel = xform.getBasis()*angvel;
}
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);
SimdTransform xform = m_body->getCenterOfMassTransform();
if (local)
{
linVel = xform.getBasis()*linVel;
}
m_body->setLinearVelocity(linVel);
}
void CcdPhysicsController::applyImpulse(float attachX,float attachY,float attachZ, float impulseX,float impulseY,float impulseZ)
@ -230,9 +328,29 @@ void CcdPhysicsController::SetActive(bool active)
// reading out information from physics
void CcdPhysicsController::GetLinearVelocity(float& linvX,float& linvY,float& linvZ)
{
const SimdVector3& linvel = this->m_body->getLinearVelocity();
linvX = linvel.x();
linvY = linvel.y();
linvZ = linvel.z();
}
void CcdPhysicsController::GetAngularVelocity(float& angVelX,float& angVelY,float& angVelZ)
{
const SimdVector3& angvel= m_body->getAngularVelocity();
angVelX = angvel.x();
angVelY = angvel.y();
angVelZ = angvel.z();
}
void CcdPhysicsController::GetVelocity(const float posX,const float posY,const float posZ,float& linvX,float& linvY,float& linvZ)
{
SimdVector3 pos(posX,posY,posZ);
SimdVector3 rel_pos = pos-m_body->getCenterOfMassPosition();
SimdVector3 linvel = m_body->getVelocityInLocalPoint(rel_pos);
linvX = linvel.x();
linvY = linvel.y();
linvZ = linvel.z();
}
void CcdPhysicsController::getReactionForce(float& forceX,float& forceY,float& forceZ)
{
@ -278,8 +396,8 @@ bool CcdPhysicsController::wantsSleeping()
//disable deactivation
if (gDisableDeactivation || (gDeactivationTime == 0.f))
return false;
//2 == ISLAND_SLEEPING, 3 == WANTS_DEACTIVATION
if ( (m_body->GetActivationState() == 2) || (m_body->GetActivationState() == 3))
if ( (m_body->GetActivationState() == ISLAND_SLEEPING) || (m_body->GetActivationState() == WANTS_DEACTIVATION))
return true;
if (m_body->m_deactivationTime> gDeactivationTime)

@ -9,13 +9,18 @@
#include "SimdVector3.h"
#include "SimdScalar.h"
#include "SimdMatrix3x3.h"
#include "SimdTransform.h"
#include "Dynamics/RigidBody.h"
#include "BroadphaseCollision/BroadphaseProxy.h" //for CollisionShape access
class CollisionShape;
extern float gDeactivationTime;
extern float gLinearSleepingTreshold;
extern float gAngularSleepingTreshold;
extern bool gDisableDeactivation;
class CcdPhysicsEnvironment;
struct CcdConstructionInfo
@ -27,22 +32,26 @@ struct CcdConstructionInfo
m_linearDamping(0.1f),
m_angularDamping(0.1f),
m_MotionState(0),
m_collisionShape(0)
m_physicsEnv(0),
m_inertiaFactor(1.f),
m_scaling(1.f,1.f,1.f)
{
}
SimdVector3 m_localInertiaTensor;
SimdVector3 m_gravity;
SimdVector3 m_scaling;
SimdScalar m_mass;
SimdScalar m_restitution;
SimdScalar m_friction;
SimdScalar m_linearDamping;
SimdScalar m_angularDamping;
void* m_broadphaseHandle;
class PHY_IMotionState* m_MotionState;
CollisionShape* m_collisionShape;
class PHY_IMotionState* m_MotionState;
CcdPhysicsEnvironment* m_physicsEnv; //needed for self-replication
float m_inertiaFactor;//tweak the inertia (hooked up to Blender 'formfactor'
};
@ -53,15 +62,19 @@ class CcdPhysicsController : public PHY_IPhysicsController
{
RigidBody* m_body;
class PHY_IMotionState* m_MotionState;
void* m_newClientInfo;
CcdConstructionInfo m_cci;//needed for replication
void GetWorldOrientation(SimdMatrix3x3& mat);
void CreateRigidbody();
public:
int m_collisionDelay;
void* m_broadphaseHandle;
CcdPhysicsController (const CcdConstructionInfo& ci);
@ -70,7 +83,9 @@ class CcdPhysicsController : public PHY_IPhysicsController
RigidBody* GetRigidBody() { return m_body;}
CollisionShape* GetCollisionShape();
CollisionShape* GetCollisionShape() {
return m_body->GetCollisionShape();
}
////////////////////////////////////
// PHY_IPhysicsController interface
////////////////////////////////////
@ -109,6 +124,7 @@ class CcdPhysicsController : public PHY_IPhysicsController
// reading out information from physics
virtual void GetLinearVelocity(float& linvX,float& linvY,float& linvZ);
virtual void GetAngularVelocity(float& angVelX,float& angVelY,float& angVelZ);
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);
@ -132,6 +148,8 @@ class CcdPhysicsController : public PHY_IPhysicsController
void UpdateDeactivation(float timeStep);
static SimdTransform GetTransformFromMotionState(PHY_IMotionState* motionState);
void SetAabb(const SimdVector3& aabbMin,const SimdVector3& aabbMax);

@ -6,9 +6,10 @@
#include "Dynamics/RigidBody.h"
#include "BroadphaseCollision/BroadphaseInterface.h"
#include "BroadphaseCollision/SimpleBroadphase.h"
#include "CollisionDispatch/CollisionWorld.h"
#include "CollisionShapes/ConvexShape.h"
#include "BroadphaseCollision/CollisionDispatcher.h"
#include "BroadphaseCollision/Dispatcher.h"
#include "NarrowPhaseCollision/PersistentManifold.h"
#include "CollisionShapes/TriangleMeshShape.h"
#include "ConstraintSolver/OdeConstraintSolver.h"
@ -17,10 +18,12 @@
#include "IDebugDraw.h"
#include "NarrowPhaseCollision/VoronoiSimplexSolver.h"
#include "NarrowPhaseCollision/SubsimplexConvexCast.h"
#include "NarrowPhaseCollision/SubSimplexConvexCast.h"
#include "NarrowPhaseCollision/GjkConvexCast.h"
#include "CollisionDispatch/ToiContactDispatcher.h"
#include "CollisionDispatch/CollisionDispatcher.h"
#include "PHY_IMotionState.h"
#include "CollisionDispatch/EmptyCollisionAlgorithm.h"
#include "CollisionDispatch/UnionFind.h"
@ -30,6 +33,17 @@
bool useIslands = true;
#ifdef NEW_BULLET_VEHICLE_SUPPORT
#include "Vehicle/RaycastVehicle.h"
#include "Vehicle/VehicleRaycaster.h"
#include "Vehicle/VehicleTuning.h"
#include "Vehicle/WheelInfo.h"
#include "PHY_IVehicle.h"
VehicleTuning gTuning;
#endif //NEW_BULLET_VEHICLE_SUPPORT
#include "AabbUtil2.h"
#include "ConstraintSolver/ConstraintSolver.h"
#include "ConstraintSolver/Point2PointConstraint.h"
//#include "BroadphaseCollision/QueryDispatcher.h"
@ -44,9 +58,146 @@ void DrawRasterizerLine(const float* from,const float* to,int color);
#include "ConstraintSolver/ContactConstraint.h"
#include <stdio.h>
#ifdef NEW_BULLET_VEHICLE_SUPPORT
class WrapperVehicle : public PHY_IVehicle
{
RaycastVehicle* m_vehicle;
PHY_IPhysicsController* m_chassis;
public:
WrapperVehicle(RaycastVehicle* vehicle,PHY_IPhysicsController* chassis)
:m_vehicle(vehicle),
m_chassis(chassis)
{
}
RaycastVehicle* GetVehicle()
{
return m_vehicle;
}
PHY_IPhysicsController* GetChassis()
{
return m_chassis;
}
virtual void AddWheel(
PHY_IMotionState* motionState,
PHY__Vector3 connectionPoint,
PHY__Vector3 downDirection,
PHY__Vector3 axleDirection,
float suspensionRestLength,
float wheelRadius,
bool hasSteering
)
{
SimdVector3 connectionPointCS0(connectionPoint[0],connectionPoint[1],connectionPoint[2]);
SimdVector3 wheelDirectionCS0(downDirection[0],downDirection[1],downDirection[2]);
SimdVector3 wheelAxle(axleDirection[0],axleDirection[1],axleDirection[2]);
WheelInfo& info = m_vehicle->AddWheel(connectionPointCS0,wheelDirectionCS0,wheelAxle,
suspensionRestLength,wheelRadius,gTuning,hasSteering);
info.m_clientInfo = motionState;
}
void SyncWheels()
{
int numWheels = GetNumWheels();
int i;
for (i=0;i<numWheels;i++)
{
WheelInfo& info = m_vehicle->GetWheelInfo(i);
PHY_IMotionState* motionState = (PHY_IMotionState*)info.m_clientInfo ;
SimdTransform trans = m_vehicle->GetWheelTransformWS(i);
SimdQuaternion orn = trans.getRotation();
const SimdVector3& pos = trans.getOrigin();
motionState->setWorldOrientation(orn.x(),orn.y(),orn.z(),orn[3]);
motionState->setWorldPosition(pos.x(),pos.y(),pos.z());
}
}
virtual int GetNumWheels() const
{
return m_vehicle->GetNumWheels();
}
virtual void GetWheelPosition(int wheelIndex,float& posX,float& posY,float& posZ) const
{
SimdTransform trans = m_vehicle->GetWheelTransformWS(wheelIndex);
posX = trans.getOrigin().x();
posY = trans.getOrigin().y();
posZ = trans.getOrigin().z();
}
virtual void GetWheelOrientationQuaternion(int wheelIndex,float& quatX,float& quatY,float& quatZ,float& quatW) const
{
SimdTransform trans = m_vehicle->GetWheelTransformWS(wheelIndex);
SimdQuaternion quat = trans.getRotation();
SimdMatrix3x3 orn2(quat);
quatX = trans.getRotation().x();
quatY = trans.getRotation().y();
quatZ = trans.getRotation().z();
quatW = trans.getRotation()[3];
//printf("test");
}
virtual float GetWheelRotation(int wheelIndex) const
{
float rotation = 0.f;
if ((wheelIndex>=0) && (wheelIndex< m_vehicle->GetNumWheels()))
{
WheelInfo& info = m_vehicle->GetWheelInfo(wheelIndex);
rotation = info.m_rotation;
}
return rotation;
}
virtual int GetUserConstraintId() const
{
return m_vehicle->GetUserConstraintId();
}
virtual int GetUserConstraintType() const
{
return m_vehicle->GetUserConstraintType();
}
virtual void SetSteeringValue(float steering,int wheelIndex)
{
m_vehicle->SetSteeringValue(steering,wheelIndex);
}
virtual void ApplyEngineForce(float force,int wheelIndex)
{
m_vehicle->ApplyEngineForce(force,wheelIndex);
}
virtual void ApplyBraking(float braking,int wheelIndex)
{
if ((wheelIndex>=0) && (wheelIndex< m_vehicle->GetNumWheels()))
{
WheelInfo& info = m_vehicle->GetWheelInfo(wheelIndex);
info.m_brake = braking;
}
}
};
#endif //NEW_BULLET_VEHICLE_SUPPORT
@ -86,24 +237,23 @@ static void DrawAabb(IDebugDraw* debugDrawer,const SimdVector3& from,const SimdV
CcdPhysicsEnvironment::CcdPhysicsEnvironment(ToiContactDispatcher* dispatcher,BroadphaseInterface* bp)
:m_dispatcher(dispatcher),
m_broadphase(bp),
m_scalingPropagated(false),
CcdPhysicsEnvironment::CcdPhysicsEnvironment(CollisionDispatcher* dispatcher,BroadphaseInterface* broadphase)
:m_scalingPropagated(false),
m_numIterations(30),
m_ccdMode(0),
m_solverType(-1)
{
if (!m_dispatcher)
{
setSolverType(0);
}
if (!dispatcher)
dispatcher = new CollisionDispatcher();
if (!m_broadphase)
{
m_broadphase = new SimpleBroadphase();
}
if(!broadphase)
broadphase = new SimpleBroadphase();
setSolverType(0);
m_collisionWorld = new CollisionWorld(dispatcher,broadphase);
m_debugDrawer = 0;
m_gravity = SimdVector3(0.f,-10.f,0.f);
@ -113,19 +263,24 @@ m_solverType(-1)
void CcdPhysicsEnvironment::addCcdPhysicsController(CcdPhysicsController* ctrl)
{
ctrl->GetRigidBody()->setGravity( m_gravity );
RigidBody* body = ctrl->GetRigidBody();
body->setGravity( m_gravity );
m_controllers.push_back(ctrl);
BroadphaseInterface* scene = m_broadphase;
m_collisionWorld->AddCollisionObject(body);
assert(body->m_broadphaseHandle);
BroadphaseInterface* scene = GetBroadphase();
CollisionShape* shapeinterface = ctrl->GetCollisionShape();
assert(shapeinterface);
const SimdTransform& t = ctrl->GetRigidBody()->getCenterOfMassTransform();
RigidBody* body = ctrl->GetRigidBody();
SimdPoint3 minAabb,maxAabb;
@ -162,17 +317,6 @@ void CcdPhysicsEnvironment::addCcdPhysicsController(CcdPhysicsController* ctrl)
minAabb = SimdVector3(minAabbx,minAabby,minAabbz);
maxAabb = SimdVector3(maxAabbx,maxAabby,maxAabbz);
if (!ctrl->m_broadphaseHandle)
{
int type = shapeinterface->GetShapeType();
ctrl->m_broadphaseHandle = scene->CreateProxy(
ctrl->GetRigidBody(),
type,
minAabb,
maxAabb);
}
@ -193,7 +337,7 @@ void CcdPhysicsEnvironment::removeCcdPhysicsController(CcdPhysicsController* ctr
if ((&p2p->GetRigidBodyA() == ctrl->GetRigidBody() ||
(&p2p->GetRigidBodyB() == ctrl->GetRigidBody())))
{
removeConstraint(int(p2p));
removeConstraint(p2p->GetUserConstraintId());
//only 1 constraint per constroller
break;
}
@ -210,7 +354,7 @@ void CcdPhysicsEnvironment::removeCcdPhysicsController(CcdPhysicsController* ctr
if ((&p2p->GetRigidBodyA() == ctrl->GetRigidBody() ||
(&p2p->GetRigidBodyB() == ctrl->GetRigidBody())))
{
removeConstraint(int(p2p));
removeConstraint(p2p->GetUserConstraintId());
//only 1 constraint per constroller
break;
}
@ -218,21 +362,9 @@ void CcdPhysicsEnvironment::removeCcdPhysicsController(CcdPhysicsController* ctr
}
m_collisionWorld->RemoveCollisionObject(ctrl->GetRigidBody());
bool removeFromBroadphase = false;
{
BroadphaseInterface* scene = m_broadphase;
BroadphaseProxy* bp = (BroadphaseProxy*)ctrl->m_broadphaseHandle;
if (removeFromBroadphase)
{
}
//
// only clear the cached algorithms
//
scene->CleanProxyFromPairs(bp);
}
{
std::vector<CcdPhysicsController*>::iterator i =
std::find(m_controllers.begin(), m_controllers.end(), ctrl);
@ -244,67 +376,34 @@ void CcdPhysicsEnvironment::removeCcdPhysicsController(CcdPhysicsController* ctr
}
}
void CcdPhysicsEnvironment::UpdateActivationState()
void CcdPhysicsEnvironment::beginFrame()
{
m_dispatcher->InitUnionFind();
// put the index into m_controllers into m_tag
{
std::vector<CcdPhysicsController*>::iterator i;
int index = 0;
for (i=m_controllers.begin();
!(i==m_controllers.end()); i++)
{
CcdPhysicsController* ctrl = (*i);
RigidBody* body = ctrl->GetRigidBody();
body->m_islandTag1 = index;
body->m_hitFraction = 1.f;
index++;
}
}
// do the union find
m_dispatcher->FindUnions();
// put the islandId ('find' value) into m_tag
{
UnionFind& unionFind = m_dispatcher->GetUnionFind();
std::vector<CcdPhysicsController*>::iterator i;
int index = 0;
for (i=m_controllers.begin();
!(i==m_controllers.end()); i++)
{
CcdPhysicsController* ctrl = (*i);
RigidBody* body = ctrl->GetRigidBody();
if (body->mergesSimulationIslands())
{
body->m_islandTag1 = unionFind.find(index);
} else
{
body->m_islandTag1 = -1;
}
index++;
}
}
}
/// Perform an integration step of duration 'timeStep'.
bool CcdPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep)
{
if (!SimdFuzzyZero(timeStep))
{
//Blender runs 30hertz, so subdivide so we get 60 hertz
proceedDeltaTimeOneStep(0.5f*timeStep);
proceedDeltaTimeOneStep(0.5f*timeStep);
} else
{
//todo: interpolate
}
return true;
}
/// Perform an integration step of duration 'timeStep'.
bool CcdPhysicsEnvironment::proceedDeltaTimeOneStep(float timeStep)
{
// printf("CcdPhysicsEnvironment::proceedDeltaTime\n");
if (timeStep == 0.f)
if (SimdFuzzyZero(timeStep))
return true;
if (m_debugDrawer)
@ -314,15 +413,12 @@ bool CcdPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep)
//clamp hardcoded for now
if (timeStep > 0.02)
timeStep = 0.02;
//this is needed because scaling is not known in advance, and scaling has to propagate to the shape
if (!m_scalingPropagated)
{
//SyncMotionStates(timeStep);
//m_scalingPropagated = true;
SyncMotionStates(timeStep);
m_scalingPropagated = true;
}
@ -346,7 +442,7 @@ bool CcdPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep)
}
}
BroadphaseInterface* scene = m_broadphase;
BroadphaseInterface* scene = GetBroadphase();
//
@ -364,7 +460,7 @@ bool CcdPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep)
dispatchInfo.m_timeStep = timeStep;
dispatchInfo.m_stepCount = 0;
scene->DispatchAllCollisionPairs(*m_dispatcher,dispatchInfo);///numsubstep,g);
scene->DispatchAllCollisionPairs(*GetDispatcher(),dispatchInfo);///numsubstep,g);
@ -373,12 +469,49 @@ bool CcdPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep)
int numRigidBodies = m_controllers.size();
UpdateActivationState();
m_collisionWorld->UpdateActivationState();
//contacts
m_dispatcher->SolveConstraints(timeStep, m_numIterations ,numRigidBodies,m_debugDrawer);
struct InplaceSolverIslandCallback : public CollisionDispatcher::IslandCallback
{
ContactSolverInfo& m_solverInfo;
ConstraintSolver* m_solver;
IDebugDraw* m_debugDrawer;
InplaceSolverIslandCallback(
ContactSolverInfo& solverInfo,
ConstraintSolver* solver,
IDebugDraw* debugDrawer)
:m_solverInfo(solverInfo),
m_solver(solver),
m_debugDrawer(debugDrawer)
{
}
virtual void ProcessIsland(PersistentManifold** manifolds,int numManifolds)
{
m_solver->SolveGroup( manifolds, numManifolds,m_solverInfo,m_debugDrawer);
}
};
m_solverInfo.m_friction = 0.9f;
m_solverInfo.m_numIterations = m_numIterations;
m_solverInfo.m_timeStep = timeStep;
m_solverInfo.m_restitution = 0.f;//m_restitution;
InplaceSolverIslandCallback solverCallback(
m_solverInfo,
m_solver,
m_debugDrawer);
GetDispatcher()->BuildAndProcessIslands(numRigidBodies,&solverCallback);
for (int g=0;g<numsubstep;g++)
{
@ -399,20 +532,27 @@ bool CcdPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep)
p2p->SolveConstraint( timeStep );
}
/*
//vehicles
int numVehicles = m_vehicles.size();
for (i=0;i<numVehicles;i++)
{
Vehicle* vehicle = m_vehicles[i];
vehicle->UpdateVehicle( timeStep );
}
*/
}
#ifdef NEW_BULLET_VEHICLE_SUPPORT
//vehicles
int numVehicles = m_wrapperVehicles.size();
for (int i=0;i<numVehicles;i++)
{
WrapperVehicle* wrapperVehicle = m_wrapperVehicles[i];
RaycastVehicle* vehicle = wrapperVehicle->GetVehicle();
vehicle->UpdateVehicle( timeStep);
}
#endif //NEW_BULLET_VEHICLE_SUPPORT
{
@ -447,7 +587,7 @@ bool CcdPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep)
minAabb -= manifoldExtraExtents;
maxAabb += manifoldExtraExtents;
BroadphaseProxy* bp = (BroadphaseProxy*) ctrl->m_broadphaseHandle;
BroadphaseProxy* bp = body->m_broadphaseHandle;
if (bp)
{
@ -501,7 +641,7 @@ bool CcdPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep)
dispatchInfo.m_stepCount = 0;
dispatchInfo.m_dispatchFunc = DispatcherInfo::DISPATCH_CONTINUOUS;
scene->DispatchAllCollisionPairs( *m_dispatcher,dispatchInfo);///numsubstep,g);
scene->DispatchAllCollisionPairs( *GetDispatcher(),dispatchInfo);///numsubstep,g);
toi = dispatchInfo.m_timeOfImpact;
}
@ -578,8 +718,26 @@ bool CcdPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep)
}
SyncMotionStates(timeStep);
#ifdef NEW_BULLET_VEHICLE_SUPPORT
//sync wheels for vehicles
int numVehicles = m_wrapperVehicles.size();
for (int i=0;i<numVehicles;i++)
{
WrapperVehicle* wrapperVehicle = m_wrapperVehicles[i];
for (int j=0;j<wrapperVehicle->GetVehicle()->GetNumWheels();j++)
{
wrapperVehicle->GetVehicle()->UpdateWheelTransform(j);
}
wrapperVehicle->SyncWheels();
}
#endif //NEW_BULLET_VEHICLE_SUPPORT
}
return true;
}
@ -622,16 +780,16 @@ void CcdPhysicsEnvironment::setCcdMode(int ccdMode)
void CcdPhysicsEnvironment::setSolverSorConstant(float sor)
{
m_dispatcher->SetSor(sor);
m_solverInfo.m_sor = sor;
}
void CcdPhysicsEnvironment::setSolverTau(float tau)
{
m_dispatcher->SetTau(tau);
m_solverInfo.m_tau = tau;
}
void CcdPhysicsEnvironment::setSolverDamping(float damping)
{
m_dispatcher->SetDamping(damping);
m_solverInfo.m_damping = damping;
}
@ -654,11 +812,9 @@ void CcdPhysicsEnvironment::setSolverType(int solverType)
{
if (m_solverType != solverType)
{
if (m_dispatcher)
delete m_dispatcher;
SimpleConstraintSolver* solver= new SimpleConstraintSolver();
m_dispatcher = new ToiContactDispatcher(solver);
m_solver = new SimpleConstraintSolver();
break;
}
}
@ -667,11 +823,8 @@ void CcdPhysicsEnvironment::setSolverType(int solverType)
default:
if (m_solverType != solverType)
{
if (m_dispatcher)
delete m_dispatcher;
OdeConstraintSolver* solver= new OdeConstraintSolver();
m_dispatcher = new ToiContactDispatcher(solver);
m_solver = new OdeConstraintSolver();
break;
}
@ -719,6 +872,53 @@ void CcdPhysicsEnvironment::setGravity(float x,float y,float z)
}
#ifdef NEW_BULLET_VEHICLE_SUPPORT
class BlenderVehicleRaycaster : public VehicleRaycaster
{
CcdPhysicsEnvironment* m_physEnv;
PHY_IPhysicsController* m_chassis;
public:
BlenderVehicleRaycaster(CcdPhysicsEnvironment* physEnv,PHY_IPhysicsController* chassis):
m_physEnv(physEnv),
m_chassis(chassis)
{
}
virtual void* CastRay(const SimdVector3& from,const SimdVector3& to, VehicleRaycasterResult& result)
{
float hit[3];
float normal[3];
PHY_IPhysicsController* ignore = m_chassis;
void* hitObject = m_physEnv->rayTest(ignore,from.x(),from.y(),from.z(),to.x(),to.y(),to.z(),hit[0],hit[1],hit[2],normal[0],normal[1],normal[2]);
if (hitObject)
{
result.m_hitPointInWorld[0] = hit[0];
result.m_hitPointInWorld[1] = hit[1];
result.m_hitPointInWorld[2] = hit[2];
result.m_hitNormalInWorld[0] = normal[0];
result.m_hitNormalInWorld[1] = normal[1];
result.m_hitNormalInWorld[2] = normal[2];
result.m_hitNormalInWorld.normalize();
//calc fraction? or put it in the interface?
//calc for now
result.m_distFraction = (result.m_hitPointInWorld-from).length() / (to-from).length();
}
//?
return hitObject;
}
};
#endif //NEW_BULLET_VEHICLE_SUPPORT
static int gConstraintUid = 1;
int CcdPhysicsEnvironment::createConstraint(class PHY_IPhysicsController* ctrl0,class PHY_IPhysicsController* ctrl1,PHY_ConstraintType type,
float pivotX,float pivotY,float pivotZ,
float axisX,float axisY,float axisZ)
@ -754,10 +954,31 @@ int CcdPhysicsEnvironment::createConstraint(class PHY_IPhysicsController* ctrl
}
m_p2pConstraints.push_back(p2p);
return 0;
p2p->SetUserConstraintId(gConstraintUid++);
p2p->SetUserConstraintType(type);
//64 bit systems can't cast pointer to int. could use size_t instead.
return p2p->GetUserConstraintId();
break;
}
#ifdef NEW_BULLET_VEHICLE_SUPPORT
case PHY_VEHICLE_CONSTRAINT:
{
VehicleTuning* tuning = new VehicleTuning();
RigidBody* chassis = rb0;
BlenderVehicleRaycaster* raycaster = new BlenderVehicleRaycaster(this,ctrl0);
RaycastVehicle* vehicle = new RaycastVehicle(*tuning,chassis,raycaster);
WrapperVehicle* wrapperVehicle = new WrapperVehicle(vehicle,ctrl0);
m_wrapperVehicles.push_back(wrapperVehicle);
vehicle->SetUserConstraintId(gConstraintUid++);
vehicle->SetUserConstraintType(type);
return vehicle->GetUserConstraintId();
break;
};
#endif //NEW_BULLET_VEHICLE_SUPPORT
default:
{
}
@ -769,19 +990,24 @@ int CcdPhysicsEnvironment::createConstraint(class PHY_IPhysicsController* ctrl
}
void CcdPhysicsEnvironment::removeConstraint(int constraintid)
void CcdPhysicsEnvironment::removeConstraint(int constraintId)
{
std::vector<Point2PointConstraint*>::iterator i;
//std::find(m_p2pConstraints.begin(), m_p2pConstraints.end(),
// (Point2PointConstraint *)p2p);
Point2PointConstraint* p2p = (Point2PointConstraint*) constraintid;
std::vector<Point2PointConstraint*>::iterator i =
std::find(m_p2pConstraints.begin(), m_p2pConstraints.end(), p2p);
if (!(i == m_p2pConstraints.end()) )
{
std::swap(*i, m_p2pConstraints.back());
m_p2pConstraints.pop_back();
}
for (i=m_p2pConstraints.begin();
!(i==m_p2pConstraints.end()); i++)
{
Point2PointConstraint* p2p = (*i);
if (p2p->GetUserConstraintId() == constraintId)
{
std::swap(*i, m_p2pConstraints.back());
m_p2pConstraints.pop_back();
break;
}
}
}
PHY_IPhysicsController* CcdPhysicsEnvironment::rayTest(PHY_IPhysicsController* ignoreClient, float fromX,float fromY,float fromZ, float toX,float toY,float toZ,
@ -792,11 +1018,21 @@ PHY_IPhysicsController* CcdPhysicsEnvironment::rayTest(PHY_IPhysicsController* i
SimdTransform rayFromTrans,rayToTrans;
rayFromTrans.setIdentity();
rayFromTrans.setOrigin(SimdVector3(fromX,fromY,fromZ));
SimdVector3 rayFrom(fromX,fromY,fromZ);
rayFromTrans.setOrigin(rayFrom);
rayToTrans.setIdentity();
rayToTrans.setOrigin(SimdVector3(toX,toY,toZ));
SimdVector3 rayTo(toX,toY,toZ);
rayToTrans.setOrigin(rayTo);
//do culling based on aabb (rayFrom/rayTo)
SimdVector3 rayAabbMin = rayFrom;
SimdVector3 rayAabbMax = rayFrom;
rayAabbMin.setMin(rayTo);
rayAabbMax.setMax(rayTo);
CcdPhysicsController* nearestHit = 0;
std::vector<CcdPhysicsController*>::iterator i;
@ -808,71 +1044,91 @@ PHY_IPhysicsController* CcdPhysicsEnvironment::rayTest(PHY_IPhysicsController* i
!(i==m_controllers.end()); i++)
{
CcdPhysicsController* ctrl = (*i);
if (ctrl == ignoreClient)
continue;
RigidBody* body = ctrl->GetRigidBody();
SimdVector3 bodyAabbMin,bodyAabbMax;
body->getAabb(bodyAabbMin,bodyAabbMax);
if (body->GetCollisionShape()->IsConvex())
//check aabb overlap
if (TestAabbAgainstAabb2(rayAabbMin,rayAabbMax,bodyAabbMin,bodyAabbMax))
{
ConvexCast::CastResult rayResult;
rayResult.m_fraction = 1.f;
ConvexShape* convexShape = (ConvexShape*) body->GetCollisionShape();
VoronoiSimplexSolver simplexSolver;
SubsimplexConvexCast convexCaster(&pointShape,convexShape,&simplexSolver);
if (convexCaster.calcTimeOfImpact(rayFromTrans,rayToTrans,body->getCenterOfMassTransform(),body->getCenterOfMassTransform(),rayResult))
if (body->GetCollisionShape()->IsConvex())
{
//add hit
rayResult.m_normal.normalize();
if (rayResult.m_fraction < minFraction)
ConvexCast::CastResult rayResult;
rayResult.m_fraction = 1.f;
ConvexShape* convexShape = (ConvexShape*) body->GetCollisionShape();
VoronoiSimplexSolver simplexSolver;
SubsimplexConvexCast convexCaster(&pointShape,convexShape,&simplexSolver);
//GjkConvexCast convexCaster(&pointShape,convexShape,&simplexSolver);
if (convexCaster.calcTimeOfImpact(rayFromTrans,rayToTrans,body->getCenterOfMassTransform(),body->getCenterOfMassTransform(),rayResult))
{
minFraction = rayResult.m_fraction;
nearestHit = ctrl;
normalX = rayResult.m_normal.getX();
normalY = rayResult.m_normal.getY();
normalZ = rayResult.m_normal.getZ();
hitX = rayResult.m_hitTransformA.getOrigin().getX();
hitY = rayResult.m_hitTransformA.getOrigin().getY();
hitZ = rayResult.m_hitTransformA.getOrigin().getZ();
}
}
}
else
{
if (body->GetCollisionShape()->IsConcave())
{
TriangleMeshShape* triangleMesh = (TriangleMeshShape*)body->GetCollisionShape();
SimdTransform worldToBody = body->getCenterOfMassTransform().inverse();
SimdVector3 rayFromLocal = worldToBody * rayFromTrans.getOrigin();
SimdVector3 rayToLocal = worldToBody * rayToTrans.getOrigin();
RaycastCallback rcb(rayFromLocal,rayToLocal);
rcb.m_hitFraction = minFraction;
SimdVector3 aabbMax(1e30f,1e30f,1e30f);
triangleMesh->ProcessAllTriangles(&rcb,-aabbMax,aabbMax);
if (rcb.m_hitFound)// && (rcb.m_hitFraction < minFraction))
//add hit
if (rayResult.m_normal.length2() > 0.0001f)
{
nearestHit = ctrl;
minFraction = rcb.m_hitFraction;
SimdVector3 hitNormalWorld = body->getCenterOfMassTransform()(rcb.m_hitNormalLocal);
rayResult.m_normal.normalize();
if (rayResult.m_fraction < minFraction)
{
normalX = hitNormalWorld.getX();
normalY = hitNormalWorld.getY();
normalZ = hitNormalWorld.getZ();
SimdVector3 hitWorld;
hitWorld.setInterpolate3(rayFromTrans.getOrigin(),rayToTrans.getOrigin(),rcb.m_hitFraction);
hitX = hitWorld.getX();
hitY = hitWorld.getY();
hitZ = hitWorld.getZ();
minFraction = rayResult.m_fraction;
nearestHit = ctrl;
normalX = rayResult.m_normal.getX();
normalY = rayResult.m_normal.getY();
normalZ = rayResult.m_normal.getZ();
SimdVector3 hitWorld;
hitWorld.setInterpolate3(rayFromTrans.getOrigin(),rayToTrans.getOrigin(),rayResult.m_fraction);
hitX = hitWorld.getX();
hitY = hitWorld.getY();
hitZ = hitWorld.getZ();
}
}
}
}
else
{
if (body->GetCollisionShape()->IsConcave())
{
TriangleMeshShape* triangleMesh = (TriangleMeshShape*)body->GetCollisionShape();
SimdTransform worldToBody = body->getCenterOfMassTransform().inverse();
SimdVector3 rayFromLocal = worldToBody * rayFromTrans.getOrigin();
SimdVector3 rayToLocal = worldToBody * rayToTrans.getOrigin();
RaycastCallback rcb(rayFromLocal,rayToLocal);
rcb.m_hitFraction = minFraction;
SimdVector3 rayAabbMinLocal = rayFromLocal;
rayAabbMinLocal.setMin(rayToLocal);
SimdVector3 rayAabbMaxLocal = rayFromLocal;
rayAabbMaxLocal.setMax(rayToLocal);
triangleMesh->ProcessAllTriangles(&rcb,rayAabbMinLocal,rayAabbMaxLocal);
if (rcb.m_hitFound)
{
nearestHit = ctrl;
minFraction = rcb.m_hitFraction;
SimdVector3 hitNormalWorld = body->getCenterOfMassTransform().getBasis()*rcb.m_hitNormalLocal;
hitNormalWorld.normalize();
normalX = hitNormalWorld.getX();
normalY = hitNormalWorld.getY();
normalZ = hitNormalWorld.getZ();
SimdVector3 hitWorld;
hitWorld.setInterpolate3(rayFromTrans.getOrigin(),rayToTrans.getOrigin(),rcb.m_hitFraction);
hitX = hitWorld.getX();
hitY = hitWorld.getY();
hitZ = hitWorld.getZ();
}
}
}
}
}
@ -894,23 +1150,36 @@ void CcdPhysicsEnvironment::getContactPoint(int i,float& hitX,float& hitY,float&
BroadphaseInterface* CcdPhysicsEnvironment::GetBroadphase()
{
return m_collisionWorld->GetBroadphase();
}
Dispatcher* CcdPhysicsEnvironment::GetDispatcher()
const CollisionDispatcher* CcdPhysicsEnvironment::GetDispatcher() const
{
return m_dispatcher;
return m_collisionWorld->GetDispatcher();
}
CollisionDispatcher* CcdPhysicsEnvironment::GetDispatcher()
{
return m_collisionWorld->GetDispatcher();
}
CcdPhysicsEnvironment::~CcdPhysicsEnvironment()
{
m_vehicles.clear();
#ifdef NEW_BULLET_VEHICLE_SUPPORT
m_wrapperVehicles.clear();
#endif //NEW_BULLET_VEHICLE_SUPPORT
//m_broadphase->DestroyScene();
//delete broadphase ? release reference on broadphase ?
//first delete scene, then dispatcher, because pairs have to release manifolds on the dispatcher
delete m_dispatcher;
//delete m_dispatcher;
delete m_collisionWorld;
}
@ -929,10 +1198,32 @@ CcdPhysicsController* CcdPhysicsEnvironment::GetPhysicsController( int index)
int CcdPhysicsEnvironment::GetNumManifolds() const
{
return m_dispatcher->GetNumManifolds();
return GetDispatcher()->GetNumManifolds();
}
const PersistentManifold* CcdPhysicsEnvironment::GetManifold(int index) const
{
return m_dispatcher->GetManifoldByIndexInternal(index);
return GetDispatcher()->GetManifoldByIndexInternal(index);
}
#ifdef NEW_BULLET_VEHICLE_SUPPORT
//complex constraint for vehicles
PHY_IVehicle* CcdPhysicsEnvironment::getVehicleConstraint(int constraintId)
{
int i;
int numVehicles = m_wrapperVehicles.size();
for (i=0;i<numVehicles;i++)
{
WrapperVehicle* wrapperVehicle = m_wrapperVehicles[i];
if (wrapperVehicle->GetVehicle()->GetUserConstraintId() == constraintId)
return wrapperVehicle;
}
return 0;
}
#endif //NEW_BULLET_VEHICLE_SUPPORT

@ -9,11 +9,16 @@ class CcdPhysicsController;
class Point2PointConstraint;
class ToiContactDispatcher;
class CollisionDispatcher;
class Dispatcher;
//#include "BroadphaseInterface.h"
class Vehicle;
//switch on/off new vehicle support
#define NEW_BULLET_VEHICLE_SUPPORT 1
#include "ConstraintSolver/ContactSolverInfo.h"
class WrapperVehicle;
class PersistentManifold;
class BroadphaseInterface;
class IDebugDraw;
@ -24,14 +29,16 @@ class IDebugDraw;
class CcdPhysicsEnvironment : public PHY_IPhysicsEnvironment
{
SimdVector3 m_gravity;
BroadphaseInterface* m_broadphase;
IDebugDraw* m_debugDrawer;
int m_numIterations;
int m_ccdMode;
int m_solverType;
ContactSolverInfo m_solverInfo;
public:
CcdPhysicsEnvironment(ToiContactDispatcher* dispatcher=0, BroadphaseInterface* broadphase=0);
CcdPhysicsEnvironment(CollisionDispatcher* dispatcher=0, BroadphaseInterface* broadphase=0);
virtual ~CcdPhysicsEnvironment();
@ -59,10 +66,12 @@ class CcdPhysicsEnvironment : public PHY_IPhysicsEnvironment
virtual void setLinearAirDamping(float damping);
virtual void setUseEpa(bool epa) ;
virtual void beginFrame() {};
virtual void beginFrame();
virtual void endFrame() {};
/// Perform an integration step of duration 'timeStep'.
virtual bool proceedDeltaTime(double curTime,float timeStep);
bool proceedDeltaTimeOneStep(float timeStep);
virtual void setFixedTimeStep(bool useFixedTimeStep,float fixedTimeStep){};
//returns 0.f if no fixed timestep is used
@ -75,8 +84,17 @@ class CcdPhysicsEnvironment : public PHY_IPhysicsEnvironment
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 void removeConstraint(int constraintid);
#ifdef NEW_BULLET_VEHICLE_SUPPORT
//complex constraint for vehicles
virtual class PHY_IVehicle* getVehicleConstraint(int constraintId);
#else
virtual PHY_IVehicle* getVehicleConstraint(int constraintId)
{
return 0;
}
#endif //NEW_BULLET_VEHICLE_SUPPORT
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);
@ -104,9 +122,12 @@ class CcdPhysicsEnvironment : public PHY_IPhysicsEnvironment
void removeCcdPhysicsController(CcdPhysicsController* ctrl);
BroadphaseInterface* GetBroadphase() { return m_broadphase; }
BroadphaseInterface* GetBroadphase();
CollisionDispatcher* GetDispatcher();
const CollisionDispatcher* GetDispatcher() const;
Dispatcher* GetDispatcher();
int GetNumControllers();
@ -118,16 +139,18 @@ class CcdPhysicsEnvironment : public PHY_IPhysicsEnvironment
private:
void UpdateActivationState();
void SyncMotionStates(float timeStep);
std::vector<CcdPhysicsController*> m_controllers;
std::vector<Point2PointConstraint*> m_p2pConstraints;
std::vector<Vehicle*> m_vehicles;
std::vector<WrapperVehicle*> m_wrapperVehicles;
class ToiContactDispatcher* m_dispatcher;
class CollisionWorld* m_collisionWorld;
class ConstraintSolver* m_solver;
bool m_scalingPropagated;

@ -0,0 +1,7 @@
#include "PHY_IVehicle.h"
PHY_IVehicle::~PHY_IVehicle()
{
}

@ -0,0 +1,45 @@
#ifndef PHY_IVEHICLE_H
#define PHY_IVEHICLE_H
//PHY_IVehicle provides a generic interface for (raycast based) vehicles. Mostly targetting 4 wheel cars and 2 wheel motorbikes.
class PHY_IMotionState;
#include "PHY_DynamicTypes.h"
class PHY_IVehicle
{
public:
virtual ~PHY_IVehicle();
virtual void AddWheel(
PHY_IMotionState* motionState,
PHY__Vector3 connectionPoint,
PHY__Vector3 downDirection,
PHY__Vector3 axleDirection,
float suspensionRestLength,
float wheelRadius,
bool hasSteering
) = 0;
virtual int GetNumWheels() const = 0;
virtual void GetWheelPosition(int wheelIndex,float& posX,float& posY,float& posZ) const = 0;
virtual void GetWheelOrientationQuaternion(int wheelIndex,float& quatX,float& quatY,float& quatZ,float& quatW) const = 0;
virtual float GetWheelRotation(int wheelIndex) const = 0;
virtual int GetUserConstraintId() const =0;
virtual int GetUserConstraintType() const =0;
//some basic steering/braking/tuning/balancing (bikes)
virtual void SetSteeringValue(float steering,int wheelIndex) = 0;
virtual void ApplyEngineForce(float force,int wheelIndex) = 0;
virtual void ApplyBraking(float braking,int wheelIndex) = 0;
};
#endif //PHY_IVEHICLE_H

@ -41,12 +41,12 @@
Optimization="0"
AdditionalIncludeDirectories="..\..\..\..\LinearMath"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
MinimalRebuild="TRUE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
/>
<Tool
@ -72,7 +72,7 @@
Name="VCBscMakeTool"
/>
<Tool
Name="VCAppVerifierTool"
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
@ -107,7 +107,7 @@
RuntimeLibrary="0"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
@ -133,7 +133,7 @@
Name="VCBscMakeTool"
/>
<Tool
Name="VCAppVerifierTool"
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
@ -160,6 +160,10 @@
RelativePath="..\PHY_IPhysicsEnvironment.cpp"
>
</File>
<File
RelativePath="..\PHY_IVehicle.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"
@ -182,6 +186,10 @@
RelativePath="..\PHY_IPhysicsEnvironment.h"
>
</File>
<File
RelativePath="..\PHY_IVehicle.h"
>
</File>
<File
RelativePath="..\PHY_Pro.h"
>
@ -198,4 +206,6 @@
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

@ -662,6 +662,7 @@ void KX_ConvertODEEngineObject(KX_GameObject* gameobj,
#include "CcdPhysicsEnvironment.h"
#include "CcdPhysicsController.h"
#include "BroadphaseCollision/BroadphaseInterface.h"
#include "KX_BulletPhysicsController.h"
#include "CollisionShapes/BoxShape.h"
@ -1010,8 +1011,9 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj,
bm->SetMargin(0.06);
ci.m_collisionShape = bm;
ci.m_broadphaseHandle = 0;
ci.m_friction = 5.f* smmaterial->m_friction;//tweak the friction a bit, so the default 0.5 works nice
ci.m_friction = smmaterial->m_friction;//tweak the friction a bit, so the default 0.5 works nice
ci.m_restitution = smmaterial->m_restitution;
ci.m_physicsEnv = env;
// drag / damping is inverted
@ -1028,6 +1030,7 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj,
}
gameobj->SetPhysicsController(physicscontroller,isbulletdyna);
physicscontroller->setNewClientInfo(gameobj->getClientInfo());
bool isActor = objprop->m_isactor;

@ -3,6 +3,7 @@
#include "Dynamics/RigidBody.h"
#include "PHY_IMotionState.h"
#include "BroadphaseCollision/BroadphaseProxy.h"
#include "BroadphaseCollision/BroadphaseInterface.h"
#include "CollisionShapes/ConvexShape.h"
#include "CcdPhysicsEnvironment.h"
@ -29,12 +30,10 @@ CcdPhysicsController::CcdPhysicsController (const CcdConstructionInfo& ci)
m_MotionState = ci.m_MotionState;
m_broadphaseHandle = ci.m_broadphaseHandle;
m_collisionShape = ci.m_collisionShape;
CreateRigidbody();
#ifdef WIN32
@ -44,21 +43,31 @@ CcdPhysicsController::CcdPhysicsController (const CcdConstructionInfo& ci)
}
void CcdPhysicsController::CreateRigidbody()
SimdTransform CcdPhysicsController::GetTransformFromMotionState(PHY_IMotionState* motionState)
{
SimdTransform trans;
float tmp[3];
m_MotionState->getWorldPosition(tmp[0],tmp[1],tmp[2]);
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]);
motionState->getWorldOrientation(orn[0],orn[1],orn[2],orn[3]);
trans.setRotation(orn);
return trans;
}
void CcdPhysicsController::CreateRigidbody()
{
SimdTransform trans = GetTransformFromMotionState(m_cci.m_MotionState);
MassProps mp(m_cci.m_mass, m_cci.m_localInertiaTensor);
m_body = new RigidBody(mp,0,0,m_cci.m_friction,m_cci.m_restitution);
m_body->m_collisionShape = m_cci.m_collisionShape;
//
// init the rigidbody properly
//
@ -74,7 +83,6 @@ void CcdPhysicsController::CreateRigidbody()
CcdPhysicsController::~CcdPhysicsController()
{
//will be reference counted, due to sharing
//delete m_collisionShape;
m_cci.m_physicsEnv->removeCcdPhysicsController(this);
delete m_MotionState;
delete m_body;
@ -96,7 +104,7 @@ bool CcdPhysicsController::SynchronizeMotionStates(float time)
float scale[3];
m_MotionState->getWorldScaling(scale[0],scale[1],scale[2]);
SimdVector3 scaling(scale[0],scale[1],scale[2]);
m_collisionShape->setLocalScaling(scaling);
GetCollisionShape()->setLocalScaling(scaling);
return true;
}
@ -115,12 +123,13 @@ void CcdPhysicsController::WriteDynamicsToMotionState()
// controller replication
void CcdPhysicsController::PostProcessReplica(class PHY_IMotionState* motionstate,class PHY_IPhysicsController* parentctrl)
{
m_MotionState = motionstate;
m_broadphaseHandle = 0;
m_body = 0;
CreateRigidbody();
m_cci.m_physicsEnv->addCcdPhysicsController(this);
@ -387,8 +396,8 @@ bool CcdPhysicsController::wantsSleeping()
//disable deactivation
if (gDisableDeactivation || (gDeactivationTime == 0.f))
return false;
//2 == ISLAND_SLEEPING, 3 == WANTS_DEACTIVATION
if ( (m_body->GetActivationState() == 2) || (m_body->GetActivationState() == 3))
if ( (m_body->GetActivationState() == ISLAND_SLEEPING) || (m_body->GetActivationState() == WANTS_DEACTIVATION))
return true;
if (m_body->m_deactivationTime> gDeactivationTime)

@ -9,7 +9,11 @@
#include "SimdVector3.h"
#include "SimdScalar.h"
#include "SimdMatrix3x3.h"
#include "SimdTransform.h"
#include "Dynamics/RigidBody.h"
#include "BroadphaseCollision/BroadphaseProxy.h" //for CollisionShape access
class CollisionShape;
extern float gDeactivationTime;
@ -28,7 +32,6 @@ struct CcdConstructionInfo
m_linearDamping(0.1f),
m_angularDamping(0.1f),
m_MotionState(0),
m_collisionShape(0),
m_physicsEnv(0),
m_inertiaFactor(1.f),
m_scaling(1.f,1.f,1.f)
@ -43,10 +46,10 @@ struct CcdConstructionInfo
SimdScalar m_friction;
SimdScalar m_linearDamping;
SimdScalar m_angularDamping;
void* m_broadphaseHandle;
class PHY_IMotionState* m_MotionState;
CollisionShape* m_collisionShape;
class PHY_IMotionState* m_MotionState;
CcdPhysicsEnvironment* m_physicsEnv; //needed for self-replication
float m_inertiaFactor;//tweak the inertia (hooked up to Blender 'formfactor'
};
@ -59,7 +62,8 @@ class CcdPhysicsController : public PHY_IPhysicsController
{
RigidBody* m_body;
class PHY_IMotionState* m_MotionState;
CollisionShape* m_collisionShape;
void* m_newClientInfo;
CcdConstructionInfo m_cci;//needed for replication
@ -71,7 +75,6 @@ class CcdPhysicsController : public PHY_IPhysicsController
int m_collisionDelay;
void* m_broadphaseHandle;
CcdPhysicsController (const CcdConstructionInfo& ci);
@ -80,7 +83,9 @@ class CcdPhysicsController : public PHY_IPhysicsController
RigidBody* GetRigidBody() { return m_body;}
CollisionShape* GetCollisionShape() { return m_collisionShape;}
CollisionShape* GetCollisionShape() {
return m_body->GetCollisionShape();
}
////////////////////////////////////
// PHY_IPhysicsController interface
////////////////////////////////////
@ -143,6 +148,8 @@ class CcdPhysicsController : public PHY_IPhysicsController
void UpdateDeactivation(float timeStep);
static SimdTransform GetTransformFromMotionState(PHY_IMotionState* motionState);
void SetAabb(const SimdVector3& aabbMin,const SimdVector3& aabbMax);

@ -6,20 +6,24 @@
#include "Dynamics/RigidBody.h"
#include "BroadphaseCollision/BroadphaseInterface.h"
#include "BroadphaseCollision/SimpleBroadphase.h"
#include "CollisionDispatch/CollisionWorld.h"
#include "CollisionShapes/ConvexShape.h"
#include "BroadphaseCollision/CollisionDispatcher.h"
#include "BroadphaseCollision/Dispatcher.h"
#include "NarrowPhaseCollision/PersistentManifold.h"
#include "CollisionShapes/TriangleMeshShape.h"
#include "ConstraintSolver/OdeConstraintSolver.h"
#include "ConstraintSolver/SimpleConstraintSolver.h"
#include "IDebugDraw.h"
#include "NarrowPhaseCollision/VoronoiSimplexSolver.h"
#include "NarrowPhaseCollision/SubSimplexConvexCast.h"
#include "NarrowPhaseCollision/GjkConvexCast.h"
#include "CollisionDispatch/ToiContactDispatcher.h"
#include "CollisionDispatch/CollisionDispatcher.h"
#include "PHY_IMotionState.h"
#include "CollisionDispatch/EmptyCollisionAlgorithm.h"
@ -33,9 +37,10 @@ bool useIslands = true;
#ifdef NEW_BULLET_VEHICLE_SUPPORT
#include "Vehicle/RaycastVehicle.h"
#include "Vehicle/VehicleRaycaster.h"
#include "Vehicle/VehicleTuning.h"
#include "Vehicle/WheelInfo.h"
#include "PHY_IVehicle.h"
VehicleTuning gTuning;
RaycastVehicle::VehicleTuning gTuning;
#endif //NEW_BULLET_VEHICLE_SUPPORT
#include "AabbUtil2.h"
@ -233,24 +238,23 @@ static void DrawAabb(IDebugDraw* debugDrawer,const SimdVector3& from,const SimdV
CcdPhysicsEnvironment::CcdPhysicsEnvironment(ToiContactDispatcher* dispatcher,BroadphaseInterface* bp)
:m_dispatcher(dispatcher),
m_broadphase(bp),
m_scalingPropagated(false),
CcdPhysicsEnvironment::CcdPhysicsEnvironment(CollisionDispatcher* dispatcher,BroadphaseInterface* broadphase)
:m_scalingPropagated(false),
m_numIterations(30),
m_ccdMode(0),
m_solverType(-1)
{
if (!m_dispatcher)
{
setSolverType(0);
}
if (!dispatcher)
dispatcher = new CollisionDispatcher();
if (!m_broadphase)
{
m_broadphase = new SimpleBroadphase();
}
if(!broadphase)
broadphase = new SimpleBroadphase();
setSolverType(0);
m_collisionWorld = new CollisionWorld(dispatcher,broadphase);
m_debugDrawer = 0;
m_gravity = SimdVector3(0.f,-10.f,0.f);
@ -260,10 +264,17 @@ m_solverType(-1)
void CcdPhysicsEnvironment::addCcdPhysicsController(CcdPhysicsController* ctrl)
{
ctrl->GetRigidBody()->setGravity( m_gravity );
RigidBody* body = ctrl->GetRigidBody();
body->setGravity( m_gravity );
m_controllers.push_back(ctrl);
BroadphaseInterface* scene = m_broadphase;
m_collisionWorld->AddCollisionObject(body);
assert(body->m_broadphaseHandle);
BroadphaseInterface* scene = GetBroadphase();
CollisionShape* shapeinterface = ctrl->GetCollisionShape();
@ -271,7 +282,6 @@ void CcdPhysicsEnvironment::addCcdPhysicsController(CcdPhysicsController* ctrl)
const SimdTransform& t = ctrl->GetRigidBody()->getCenterOfMassTransform();
RigidBody* body = ctrl->GetRigidBody();
SimdPoint3 minAabb,maxAabb;
@ -308,17 +318,6 @@ void CcdPhysicsEnvironment::addCcdPhysicsController(CcdPhysicsController* ctrl)
minAabb = SimdVector3(minAabbx,minAabby,minAabbz);
maxAabb = SimdVector3(maxAabbx,maxAabby,maxAabbz);
if (!ctrl->m_broadphaseHandle)
{
int type = shapeinterface->GetShapeType();
ctrl->m_broadphaseHandle = scene->CreateProxy(
ctrl->GetRigidBody(),
type,
minAabb,
maxAabb);
}
body->SetCollisionShape( shapeinterface );
@ -364,23 +363,9 @@ void CcdPhysicsEnvironment::removeCcdPhysicsController(CcdPhysicsController* ctr
}
bool removeFromBroadphase = false;
{
BroadphaseInterface* scene = m_broadphase;
BroadphaseProxy* bp = (BroadphaseProxy*)ctrl->m_broadphaseHandle;
if (removeFromBroadphase)
{
m_collisionWorld->RemoveCollisionObject(ctrl->GetRigidBody());
}
//
// only clear the cached algorithms
//
scene->CleanProxyFromPairs(bp);
scene->DestroyProxy(bp);//??
}
{
std::vector<CcdPhysicsController*>::iterator i =
std::find(m_controllers.begin(), m_controllers.end(), ctrl);
@ -392,56 +377,6 @@ void CcdPhysicsEnvironment::removeCcdPhysicsController(CcdPhysicsController* ctr
}
}
void CcdPhysicsEnvironment::UpdateActivationState()
{
m_dispatcher->InitUnionFind();
// put the index into m_controllers into m_tag
{
std::vector<CcdPhysicsController*>::iterator i;
int index = 0;
for (i=m_controllers.begin();
!(i==m_controllers.end()); i++)
{
CcdPhysicsController* ctrl = (*i);
RigidBody* body = ctrl->GetRigidBody();
body->m_islandTag1 = index;
body->m_hitFraction = 1.f;
index++;
}
}
// do the union find
m_dispatcher->FindUnions();
// put the islandId ('find' value) into m_tag
{
UnionFind& unionFind = m_dispatcher->GetUnionFind();
std::vector<CcdPhysicsController*>::iterator i;
int index = 0;
for (i=m_controllers.begin();
!(i==m_controllers.end()); i++)
{
CcdPhysicsController* ctrl = (*i);
RigidBody* body = ctrl->GetRigidBody();
if (body->mergesSimulationIslands())
{
body->m_islandTag1 = unionFind.find(index);
} else
{
body->m_islandTag1 = -1;
}
index++;
}
}
}
void CcdPhysicsEnvironment::beginFrame()
{
@ -504,11 +439,12 @@ bool CcdPhysicsEnvironment::proceedDeltaTimeOneStep(float timeStep)
{
body->applyForces( timeStep);
body->integrateVelocities( timeStep);
body->predictIntegratedTransform(timeStep,body->m_nextPredictedWorldTransform);
}
}
}
BroadphaseInterface* scene = m_broadphase;
BroadphaseInterface* scene = GetBroadphase();
//
@ -526,7 +462,7 @@ bool CcdPhysicsEnvironment::proceedDeltaTimeOneStep(float timeStep)
dispatchInfo.m_timeStep = timeStep;
dispatchInfo.m_stepCount = 0;
scene->DispatchAllCollisionPairs(*m_dispatcher,dispatchInfo);///numsubstep,g);
scene->DispatchAllCollisionPairs(*GetDispatcher(),dispatchInfo);///numsubstep,g);
@ -535,12 +471,51 @@ bool CcdPhysicsEnvironment::proceedDeltaTimeOneStep(float timeStep)
int numRigidBodies = m_controllers.size();
UpdateActivationState();
m_collisionWorld->UpdateActivationState();
//contacts
m_dispatcher->SolveConstraints(timeStep, m_numIterations ,numRigidBodies,m_debugDrawer);
struct InplaceSolverIslandCallback : public CollisionDispatcher::IslandCallback
{
ContactSolverInfo& m_solverInfo;
ConstraintSolver* m_solver;
IDebugDraw* m_debugDrawer;
InplaceSolverIslandCallback(
ContactSolverInfo& solverInfo,
ConstraintSolver* solver,
IDebugDraw* debugDrawer)
:m_solverInfo(solverInfo),
m_solver(solver),
m_debugDrawer(debugDrawer)
{
}
virtual void ProcessIsland(PersistentManifold** manifolds,int numManifolds)
{
m_solver->SolveGroup( manifolds, numManifolds,m_solverInfo,m_debugDrawer);
}
};
m_solverInfo.m_friction = 0.9f;
m_solverInfo.m_numIterations = m_numIterations;
m_solverInfo.m_timeStep = timeStep;
m_solverInfo.m_restitution = 0.f;//m_restitution;
InplaceSolverIslandCallback solverCallback(
m_solverInfo,
m_solver,
m_debugDrawer);
GetDispatcher()->BuildAndProcessIslands(numRigidBodies,&solverCallback);
for (int g=0;g<numsubstep;g++)
{
@ -562,7 +537,13 @@ bool CcdPhysicsEnvironment::proceedDeltaTimeOneStep(float timeStep)
}
#ifdef NEW_BULLET_VEHICLE_SUPPORT
}
#ifdef NEW_BULLET_VEHICLE_SUPPORT
//vehicles
int numVehicles = m_wrapperVehicles.size();
for (int i=0;i<numVehicles;i++)
@ -574,10 +555,6 @@ bool CcdPhysicsEnvironment::proceedDeltaTimeOneStep(float timeStep)
#endif //NEW_BULLET_VEHICLE_SUPPORT
}
{
@ -614,7 +591,7 @@ bool CcdPhysicsEnvironment::proceedDeltaTimeOneStep(float timeStep)
minAabb -= manifoldExtraExtents;
maxAabb += manifoldExtraExtents;
BroadphaseProxy* bp = (BroadphaseProxy*) ctrl->m_broadphaseHandle;
BroadphaseProxy* bp = body->m_broadphaseHandle;
if (bp)
{
@ -668,7 +645,7 @@ bool CcdPhysicsEnvironment::proceedDeltaTimeOneStep(float timeStep)
dispatchInfo.m_stepCount = 0;
dispatchInfo.m_dispatchFunc = DispatcherInfo::DISPATCH_CONTINUOUS;
scene->DispatchAllCollisionPairs( *m_dispatcher,dispatchInfo);///numsubstep,g);
scene->DispatchAllCollisionPairs( *GetDispatcher(),dispatchInfo);///numsubstep,g);
toi = dispatchInfo.m_timeOfImpact;
}
@ -689,9 +666,10 @@ bool CcdPhysicsEnvironment::proceedDeltaTimeOneStep(float timeStep)
RigidBody* body = ctrl->GetRigidBody();
if (body->GetActivationState() != ISLAND_SLEEPING)
{
body->predictIntegratedTransform(timeStep* toi, predictedTrans);
body->proceedToTransform( predictedTrans);
}
}
@ -759,7 +737,7 @@ bool CcdPhysicsEnvironment::proceedDeltaTimeOneStep(float timeStep)
for (int j=0;j<wrapperVehicle->GetVehicle()->GetNumWheels();j++)
{
wrapperVehicle->GetVehicle()->UpdateWheelTransformsWS(wrapperVehicle->GetVehicle()->GetWheelInfo(j));
wrapperVehicle->GetVehicle()->UpdateWheelTransform(j);
}
wrapperVehicle->SyncWheels();
@ -807,16 +785,16 @@ void CcdPhysicsEnvironment::setCcdMode(int ccdMode)
void CcdPhysicsEnvironment::setSolverSorConstant(float sor)
{
m_dispatcher->SetSor(sor);
m_solverInfo.m_sor = sor;
}
void CcdPhysicsEnvironment::setSolverTau(float tau)
{
m_dispatcher->SetTau(tau);
m_solverInfo.m_tau = tau;
}
void CcdPhysicsEnvironment::setSolverDamping(float damping)
{
m_dispatcher->SetDamping(damping);
m_solverInfo.m_damping = damping;
}
@ -839,11 +817,9 @@ void CcdPhysicsEnvironment::setSolverType(int solverType)
{
if (m_solverType != solverType)
{
if (m_dispatcher)
delete m_dispatcher;
SimpleConstraintSolver* solver= new SimpleConstraintSolver();
m_dispatcher = new ToiContactDispatcher(solver);
m_solver = new SimpleConstraintSolver();
break;
}
}
@ -852,11 +828,8 @@ void CcdPhysicsEnvironment::setSolverType(int solverType)
default:
if (m_solverType != solverType)
{
if (m_dispatcher)
delete m_dispatcher;
OdeConstraintSolver* solver= new OdeConstraintSolver();
m_dispatcher = new ToiContactDispatcher(solver);
m_solver = new OdeConstraintSolver();
break;
}
@ -1022,11 +995,10 @@ int CcdPhysicsEnvironment::createConstraint(class PHY_IPhysicsController* ctrl
case PHY_VEHICLE_CONSTRAINT:
{
VehicleTuning* tuning = new VehicleTuning();
RaycastVehicle::VehicleTuning* tuning = new RaycastVehicle::VehicleTuning();
RigidBody* chassis = rb0;
BlenderVehicleRaycaster* raycaster = new BlenderVehicleRaycaster(this,ctrl0);
RaycastVehicle* vehicle = new RaycastVehicle(*tuning,chassis,raycaster);
vehicle->SetBalance(false);
WrapperVehicle* wrapperVehicle = new WrapperVehicle(vehicle,ctrl0);
m_wrapperVehicles.push_back(wrapperVehicle);
vehicle->SetUserConstraintId(gConstraintUid++);
@ -1120,6 +1092,7 @@ PHY_IPhysicsController* CcdPhysicsEnvironment::rayTest(PHY_IPhysicsController* i
ConvexShape* convexShape = (ConvexShape*) body->GetCollisionShape();
VoronoiSimplexSolver simplexSolver;
SubsimplexConvexCast convexCaster(&pointShape,convexShape,&simplexSolver);
//GjkConvexCast convexCaster(&pointShape,convexShape,&simplexSolver);
if (convexCaster.calcTimeOfImpact(rayFromTrans,rayToTrans,body->getCenterOfMassTransform(),body->getCenterOfMassTransform(),rayResult))
{
@ -1136,9 +1109,12 @@ PHY_IPhysicsController* CcdPhysicsEnvironment::rayTest(PHY_IPhysicsController* i
normalX = rayResult.m_normal.getX();
normalY = rayResult.m_normal.getY();
normalZ = rayResult.m_normal.getZ();
hitX = rayResult.m_hitTransformA.getOrigin().getX();
hitY = rayResult.m_hitTransformA.getOrigin().getY();
hitZ = rayResult.m_hitTransformA.getOrigin().getZ();
SimdVector3 hitWorld;
hitWorld.setInterpolate3(rayFromTrans.getOrigin(),rayToTrans.getOrigin(),rayResult.m_fraction);
hitX = hitWorld.getX();
hitY = hitWorld.getY();
hitZ = hitWorld.getZ();
}
}
}
@ -1158,12 +1134,18 @@ PHY_IPhysicsController* CcdPhysicsEnvironment::rayTest(PHY_IPhysicsController* i
RaycastCallback rcb(rayFromLocal,rayToLocal);
rcb.m_hitFraction = minFraction;
triangleMesh->ProcessAllTriangles(&rcb,rayAabbMin,rayAabbMax);
if (rcb.m_hitFound)// && (rcb.m_hitFraction < minFraction))
SimdVector3 rayAabbMinLocal = rayFromLocal;
rayAabbMinLocal.setMin(rayToLocal);
SimdVector3 rayAabbMaxLocal = rayFromLocal;
rayAabbMaxLocal.setMax(rayToLocal);
triangleMesh->ProcessAllTriangles(&rcb,rayAabbMinLocal,rayAabbMaxLocal);
if (rcb.m_hitFound)
{
nearestHit = ctrl;
minFraction = rcb.m_hitFraction;
SimdVector3 hitNormalWorld = body->getCenterOfMassTransform()(rcb.m_hitNormalLocal);
SimdVector3 hitNormalWorld = body->getCenterOfMassTransform().getBasis()*rcb.m_hitNormalLocal;
hitNormalWorld.normalize();
normalX = hitNormalWorld.getX();
normalY = hitNormalWorld.getY();
@ -1198,10 +1180,21 @@ void CcdPhysicsEnvironment::getContactPoint(int i,float& hitX,float& hitY,float&
BroadphaseInterface* CcdPhysicsEnvironment::GetBroadphase()
{
return m_collisionWorld->GetBroadphase();
}
Dispatcher* CcdPhysicsEnvironment::GetDispatcher()
const CollisionDispatcher* CcdPhysicsEnvironment::GetDispatcher() const
{
return m_dispatcher;
return m_collisionWorld->GetDispatcher();
}
CollisionDispatcher* CcdPhysicsEnvironment::GetDispatcher()
{
return m_collisionWorld->GetDispatcher();
}
CcdPhysicsEnvironment::~CcdPhysicsEnvironment()
@ -1215,7 +1208,8 @@ CcdPhysicsEnvironment::~CcdPhysicsEnvironment()
//delete broadphase ? release reference on broadphase ?
//first delete scene, then dispatcher, because pairs have to release manifolds on the dispatcher
delete m_dispatcher;
//delete m_dispatcher;
delete m_collisionWorld;
}
@ -1234,12 +1228,12 @@ CcdPhysicsController* CcdPhysicsEnvironment::GetPhysicsController( int index)
int CcdPhysicsEnvironment::GetNumManifolds() const
{
return m_dispatcher->GetNumManifolds();
return GetDispatcher()->GetNumManifolds();
}
const PersistentManifold* CcdPhysicsEnvironment::GetManifold(int index) const
{
return m_dispatcher->GetManifoldByIndexInternal(index);
return GetDispatcher()->GetManifoldByIndexInternal(index);
}

@ -9,13 +9,15 @@ class CcdPhysicsController;
class Point2PointConstraint;
class ToiContactDispatcher;
class CollisionDispatcher;
class Dispatcher;
//#include "BroadphaseInterface.h"
//switch on/off new vehicle support
//#define NEW_BULLET_VEHICLE_SUPPORT 1
#include "ConstraintSolver/ContactSolverInfo.h"
class WrapperVehicle;
class PersistentManifold;
class BroadphaseInterface;
@ -27,14 +29,16 @@ class IDebugDraw;
class CcdPhysicsEnvironment : public PHY_IPhysicsEnvironment
{
SimdVector3 m_gravity;
BroadphaseInterface* m_broadphase;
IDebugDraw* m_debugDrawer;
int m_numIterations;
int m_ccdMode;
int m_solverType;
ContactSolverInfo m_solverInfo;
public:
CcdPhysicsEnvironment(ToiContactDispatcher* dispatcher=0, BroadphaseInterface* broadphase=0);
CcdPhysicsEnvironment(CollisionDispatcher* dispatcher=0, BroadphaseInterface* broadphase=0);
virtual ~CcdPhysicsEnvironment();
@ -118,9 +122,12 @@ class CcdPhysicsEnvironment : public PHY_IPhysicsEnvironment
void removeCcdPhysicsController(CcdPhysicsController* ctrl);
BroadphaseInterface* GetBroadphase() { return m_broadphase; }
BroadphaseInterface* GetBroadphase();
CollisionDispatcher* GetDispatcher();
const CollisionDispatcher* GetDispatcher() const;
Dispatcher* GetDispatcher();
int GetNumControllers();
@ -132,7 +139,7 @@ class CcdPhysicsEnvironment : public PHY_IPhysicsEnvironment
private:
void UpdateActivationState();
void SyncMotionStates(float timeStep);
std::vector<CcdPhysicsController*> m_controllers;
@ -141,7 +148,9 @@ class CcdPhysicsEnvironment : public PHY_IPhysicsEnvironment
std::vector<WrapperVehicle*> m_wrapperVehicles;
class ToiContactDispatcher* m_dispatcher;
class CollisionWorld* m_collisionWorld;
class ConstraintSolver* m_solver;
bool m_scalingPropagated;