Added initial broadphase support for softbody versus softbody and softbody versus rigidbody (see btSoftSoftCollisionAlgorithm and btSoftRididCollisionAlgorithm)
Added SOFTBODY_SHAPE_PROXYTYPE. Some refactoring for btSoftBody, needs more work.
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -21,7 +21,7 @@ subject to the following restrictions:
|
||||
#include "DemoApplication.h"
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
#include "BulletDynamics/SoftBody/btSoftBody.h"
|
||||
#include "BulletDynamics/SoftBody/btSparseSDF.h"
|
||||
|
||||
|
||||
class btBroadphaseInterface;
|
||||
class btCollisionShape;
|
||||
@@ -31,31 +31,27 @@ class btConstraintSolver;
|
||||
struct btCollisionAlgorithmCreateFunc;
|
||||
class btDefaultCollisionConfiguration;
|
||||
|
||||
///collisions between two btSoftBody's
|
||||
class btSoftSoftCollisionAlgorithm;
|
||||
|
||||
///collisions between a btSoftBody and a btRigidBody
|
||||
class btSoftRididCollisionAlgorithm;
|
||||
|
||||
|
||||
///CcdPhysicsDemo shows basic stacking using Bullet physics, and allows toggle of Ccd (using key '1')
|
||||
class SoftDemo : public DemoApplication
|
||||
{
|
||||
public:
|
||||
struct SoftBodyImpl : btSoftBody::ISoftBody
|
||||
{
|
||||
void Attach(btSoftBody*);
|
||||
void Detach(btSoftBody*);
|
||||
void StartCollide(const btVector3&,const btVector3&);
|
||||
bool CheckContactPrecise(const btVector3&,
|
||||
btSoftBody::ISoftBody::sCti&);
|
||||
bool CheckContact( const btVector3&,
|
||||
btSoftBody::ISoftBody::sCti&);
|
||||
void EndCollide();
|
||||
void EvaluateMedium( const btVector3&,
|
||||
btSoftBody::ISoftBody::sMedium&);
|
||||
SoftDemo* pdemo;
|
||||
btScalar air_density;
|
||||
btScalar water_density;
|
||||
btScalar water_offset;
|
||||
btVector3 water_normal;
|
||||
} m_softbodyimpl;
|
||||
|
||||
btAlignedObjectArray<btSoftSoftCollisionAlgorithm*> m_SoftSoftCollisionAlgorithms;
|
||||
|
||||
btAlignedObjectArray<btSoftRididCollisionAlgorithm*> m_SoftRigidCollisionAlgorithms;
|
||||
|
||||
btSoftBody::btSoftBodyWorldInfo m_softBodyWorldInfo;
|
||||
|
||||
btAlignedObjectArray<btSoftBody*> m_softbodies;
|
||||
btSparseSdf<3> m_sparsesdf;
|
||||
|
||||
|
||||
bool m_autocam;
|
||||
|
||||
|
||||
@@ -66,12 +62,6 @@ struct SoftBodyImpl : btSoftBody::ISoftBody
|
||||
|
||||
btCollisionDispatcher* m_dispatcher;
|
||||
|
||||
#ifdef USE_PARALLEL_DISPATCHER
|
||||
#ifdef WIN32
|
||||
class Win32ThreadSupport* m_threadSupportCollision;
|
||||
class Win32ThreadSupport* m_threadSupportSolver;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
btConstraintSolver* m_solver;
|
||||
|
||||
@@ -80,7 +70,7 @@ struct SoftBodyImpl : btSoftBody::ISoftBody
|
||||
btDefaultCollisionConfiguration* m_collisionConfiguration;
|
||||
|
||||
|
||||
public:
|
||||
public:
|
||||
|
||||
void initPhysics();
|
||||
|
||||
|
||||
77
Demos/SoftDemo/btSoftBodyRigidBodyCollisionConfiguration.cpp
Normal file
77
Demos/SoftDemo/btSoftBodyRigidBodyCollisionConfiguration.cpp
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "btSoftBodyRigidBodyCollisionConfiguration.h"
|
||||
#include "btSoftRigidCollisionAlgorithm.h"
|
||||
#include "btSoftSoftCollisionAlgorithm.h"
|
||||
|
||||
|
||||
btSoftBodyRigidBodyCollisionConfiguration::btSoftBodyRigidBodyCollisionConfiguration(btStackAlloc* stackAlloc,btPoolAllocator* persistentManifoldPool,btPoolAllocator* collisionAlgorithmPool)
|
||||
:btDefaultCollisionConfiguration(stackAlloc,persistentManifoldPool,collisionAlgorithmPool)
|
||||
{
|
||||
void* mem;
|
||||
|
||||
mem = btAlignedAlloc(sizeof(btSoftSoftCollisionAlgorithm::CreateFunc),16);
|
||||
m_softSoftCreateFunc = new(mem) btSoftSoftCollisionAlgorithm::CreateFunc;
|
||||
|
||||
mem = btAlignedAlloc(sizeof(btSoftRigidCollisionAlgorithm::CreateFunc),16);
|
||||
m_softRigidCreateFunc = new(mem) btSoftRigidCollisionAlgorithm::CreateFunc;
|
||||
|
||||
mem = btAlignedAlloc(sizeof(btSoftRigidCollisionAlgorithm::CreateFunc),16);
|
||||
m_swappedSoftRigidCreateFunc = new(mem) btSoftRigidCollisionAlgorithm::CreateFunc;
|
||||
m_swappedSoftRigidCreateFunc->m_swapped=true;
|
||||
|
||||
}
|
||||
|
||||
btSoftBodyRigidBodyCollisionConfiguration::~btSoftBodyRigidBodyCollisionConfiguration()
|
||||
{
|
||||
m_softSoftCreateFunc->~btCollisionAlgorithmCreateFunc();
|
||||
btAlignedFree( m_softSoftCreateFunc);
|
||||
|
||||
m_softRigidCreateFunc->~btCollisionAlgorithmCreateFunc();
|
||||
btAlignedFree( m_softRigidCreateFunc);
|
||||
|
||||
m_swappedSoftRigidCreateFunc->~btCollisionAlgorithmCreateFunc();
|
||||
btAlignedFree( m_swappedSoftRigidCreateFunc);
|
||||
|
||||
|
||||
}
|
||||
|
||||
///creation of soft-soft and soft-rigid, and otherwise fallback to base class implementation
|
||||
btCollisionAlgorithmCreateFunc* btSoftBodyRigidBodyCollisionConfiguration::getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1)
|
||||
{
|
||||
|
||||
///try to handle the softbody interactions first
|
||||
|
||||
if ((proxyType0 == SOFTBODY_SHAPE_PROXYTYPE ) && (proxyType1==SOFTBODY_SHAPE_PROXYTYPE))
|
||||
{
|
||||
return m_softSoftCreateFunc;
|
||||
}
|
||||
|
||||
///other can't be also softbody, so assume rigid for now
|
||||
if (proxyType0 == SOFTBODY_SHAPE_PROXYTYPE )
|
||||
{
|
||||
return m_softRigidCreateFunc;
|
||||
}
|
||||
|
||||
///other can't be also softbody, so assume rigid for now
|
||||
if (proxyType1 == SOFTBODY_SHAPE_PROXYTYPE )
|
||||
{
|
||||
return m_swappedSoftRigidCreateFunc;
|
||||
}
|
||||
|
||||
///fallback to the regular rigid collision shape
|
||||
return btDefaultCollisionConfiguration::getCollisionAlgorithmCreateFunc(proxyType0,proxyType1);
|
||||
}
|
||||
46
Demos/SoftDemo/btSoftBodyRigidBodyCollisionConfiguration.h
Normal file
46
Demos/SoftDemo/btSoftBodyRigidBodyCollisionConfiguration.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef BT_SOFTBODY_RIGIDBODY_COLLISION_CONFIGURATION
|
||||
#define BT_SOFTBODY_RIGIDBODY_COLLISION_CONFIGURATION
|
||||
|
||||
#include "BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h"
|
||||
|
||||
class btVoronoiSimplexSolver;
|
||||
class btGjkEpaPenetrationDepthSolver;
|
||||
|
||||
|
||||
///btSoftBodyRigidBodyCollisionConfiguration add softbody interaction on top of btDefaultCollisionConfiguration
|
||||
class btSoftBodyRigidBodyCollisionConfiguration : public btDefaultCollisionConfiguration
|
||||
{
|
||||
|
||||
//default CreationFunctions, filling the m_doubleDispatch table
|
||||
btCollisionAlgorithmCreateFunc* m_softSoftCreateFunc;
|
||||
btCollisionAlgorithmCreateFunc* m_softRigidCreateFunc;
|
||||
btCollisionAlgorithmCreateFunc* m_swappedSoftRigidCreateFunc;
|
||||
|
||||
public:
|
||||
|
||||
btSoftBodyRigidBodyCollisionConfiguration(btStackAlloc* stackAlloc=0,btPoolAllocator* persistentManifoldPool=0,btPoolAllocator* collisionAlgorithmPool=0);
|
||||
|
||||
virtual ~btSoftBodyRigidBodyCollisionConfiguration();
|
||||
|
||||
///creation of soft-soft and soft-rigid, and otherwise fallback to base class implementation
|
||||
virtual btCollisionAlgorithmCreateFunc* getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1);
|
||||
|
||||
};
|
||||
|
||||
#endif //BT_SOFTBODY_RIGIDBODY_COLLISION_CONFIGURATION
|
||||
|
||||
94
Demos/SoftDemo/btSoftRigidCollisionAlgorithm.cpp
Normal file
94
Demos/SoftDemo/btSoftRigidCollisionAlgorithm.cpp
Normal file
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "btSoftRigidCollisionAlgorithm.h"
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
|
||||
#include "BulletCollision/CollisionShapes/btSphereShape.h"
|
||||
#include "BulletCollision/CollisionShapes/btBoxShape.h"
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
|
||||
#include "BulletDynamics/SoftBody/btSoftBody.h"
|
||||
///TODO: include all the shapes that the softbody can collide with
|
||||
///alternatively, implement special case collision algorithms (just like for rigid collision shapes)
|
||||
|
||||
//#include <stdio.h>
|
||||
|
||||
btSoftRigidCollisionAlgorithm::btSoftRigidCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1, bool isSwapped)
|
||||
: btCollisionAlgorithm(ci),
|
||||
//m_ownManifold(false),
|
||||
//m_manifoldPtr(mf),
|
||||
m_isSwapped(isSwapped)
|
||||
{
|
||||
|
||||
m_softBody = m_isSwapped? (btSoftBody*)col1 : (btSoftBody*)col0;
|
||||
m_rigidCollisionObject = m_isSwapped? col0 : col1;
|
||||
|
||||
//quick fix, add overlapping rigidbody to softbody, so it can be handled within btSoftBody::Step method
|
||||
m_softBody->m_overlappingRigidBodies.push_back(m_rigidCollisionObject);
|
||||
|
||||
///store the contacts straight into the btSoftBody for now?
|
||||
|
||||
/*if (!m_manifoldPtr && m_dispatcher->needsCollision(sphereObj,boxObj))
|
||||
{
|
||||
m_manifoldPtr = m_dispatcher->getNewManifold(sphereObj,boxObj);
|
||||
m_ownManifold = true;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
btSoftRigidCollisionAlgorithm::~btSoftRigidCollisionAlgorithm()
|
||||
{
|
||||
|
||||
m_softBody->m_overlappingRigidBodies.remove(m_rigidCollisionObject);
|
||||
|
||||
/*if (m_ownManifold)
|
||||
{
|
||||
if (m_manifoldPtr)
|
||||
m_dispatcher->releaseManifold(m_manifoldPtr);
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
void btSoftRigidCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
|
||||
{
|
||||
(void)dispatchInfo;
|
||||
(void)resultOut;
|
||||
//printf("btSoftRigidCollisionAlgorithm\n");
|
||||
|
||||
btSoftBody* softBody = m_isSwapped? (btSoftBody*)body1 : (btSoftBody*)body0;
|
||||
btCollisionObject* rigidCollisionObject = m_isSwapped? body0 : body1;
|
||||
///do your stuff here
|
||||
|
||||
|
||||
}
|
||||
|
||||
btScalar btSoftRigidCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
|
||||
{
|
||||
(void)resultOut;
|
||||
(void)dispatchInfo;
|
||||
(void)col0;
|
||||
(void)col1;
|
||||
|
||||
//not yet
|
||||
return btScalar(1.);
|
||||
}
|
||||
|
||||
69
Demos/SoftDemo/btSoftRigidCollisionAlgorithm.h
Normal file
69
Demos/SoftDemo/btSoftRigidCollisionAlgorithm.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SOFT_RIGID_COLLISION_ALGORITHM_H
|
||||
#define SOFT_RIGID_COLLISION_ALGORITHM_H
|
||||
|
||||
#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
|
||||
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
|
||||
class btPersistentManifold;
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
|
||||
|
||||
#include "LinearMath/btVector3.h"
|
||||
struct btSoftBody;
|
||||
|
||||
/// btSoftRigidCollisionAlgorithm provides collision detection between btSoftBody and btRigidBody
|
||||
class btSoftRigidCollisionAlgorithm : public btCollisionAlgorithm
|
||||
{
|
||||
// bool m_ownManifold;
|
||||
// btPersistentManifold* m_manifoldPtr;
|
||||
|
||||
btSoftBody* m_softBody;
|
||||
btCollisionObject* m_rigidCollisionObject;
|
||||
|
||||
///for rigid versus soft (instead of soft versus rigid), we use this swapped boolean
|
||||
bool m_isSwapped;
|
||||
|
||||
public:
|
||||
|
||||
btSoftRigidCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1, bool isSwapped);
|
||||
|
||||
virtual ~btSoftRigidCollisionAlgorithm();
|
||||
|
||||
virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
|
||||
|
||||
virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
|
||||
|
||||
|
||||
struct CreateFunc :public btCollisionAlgorithmCreateFunc
|
||||
{
|
||||
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
|
||||
{
|
||||
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btSoftRigidCollisionAlgorithm));
|
||||
if (!m_swapped)
|
||||
{
|
||||
return new(mem) btSoftRigidCollisionAlgorithm(0,ci,body0,body1,false);
|
||||
} else
|
||||
{
|
||||
return new(mem) btSoftRigidCollisionAlgorithm(0,ci,body0,body1,true);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif //SOFT_RIGID_COLLISION_ALGORITHM_H
|
||||
|
||||
104
Demos/SoftDemo/btSoftSoftCollisionAlgorithm.cpp
Normal file
104
Demos/SoftDemo/btSoftSoftCollisionAlgorithm.cpp
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "btSoftSoftCollisionAlgorithm.h"
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
|
||||
#include "BulletCollision/CollisionShapes/btBoxShape.h"
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
|
||||
#include "BulletDynamics/SoftBody/btSoftBody.h"
|
||||
|
||||
#define USE_PERSISTENT_CONTACTS 1
|
||||
|
||||
btSoftSoftCollisionAlgorithm::btSoftSoftCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* obj0,btCollisionObject* obj1)
|
||||
: btCollisionAlgorithm(ci)
|
||||
//m_ownManifold(false),
|
||||
//m_manifoldPtr(mf)
|
||||
{
|
||||
m_softBody0 = (btSoftBody*) obj0;
|
||||
m_softBody1 = (btSoftBody*) obj1;
|
||||
|
||||
m_softBody0->m_overlappingSoftBodies.push_back(m_softBody1);
|
||||
m_softBody1->m_overlappingSoftBodies.push_back(m_softBody0);
|
||||
|
||||
/*if (!m_manifoldPtr && m_dispatcher->needsCollision(obj0,obj1))
|
||||
{
|
||||
m_manifoldPtr = m_dispatcher->getNewManifold(obj0,obj1);
|
||||
m_ownManifold = true;
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
btSoftSoftCollisionAlgorithm::~btSoftSoftCollisionAlgorithm()
|
||||
{
|
||||
m_softBody0->m_overlappingSoftBodies.remove(m_softBody1);
|
||||
m_softBody1->m_overlappingSoftBodies.remove(m_softBody0);
|
||||
|
||||
//this gets called when the overlap stops.
|
||||
|
||||
//here is where contacts (manifolds) should be removed
|
||||
|
||||
/*
|
||||
if (m_ownManifold)
|
||||
{
|
||||
if (m_manifoldPtr)
|
||||
m_dispatcher->releaseManifold(m_manifoldPtr);
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
void btSoftSoftCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
|
||||
{
|
||||
|
||||
btCollisionObject* col0 = body0;
|
||||
btCollisionObject* col1 = body1;
|
||||
|
||||
/*
|
||||
btBoxShape* box0 = (btBoxShape*)col0->getCollisionShape();
|
||||
btBoxShape* box1 = (btBoxShape*)col1->getCollisionShape();
|
||||
|
||||
|
||||
|
||||
/// report a contact. internally this will be kept persistent, and contact reduction is done
|
||||
resultOut->setPersistentManifold(m_manifoldPtr);
|
||||
#ifndef USE_PERSISTENT_CONTACTS
|
||||
m_manifoldPtr->clearManifold();
|
||||
#endif //USE_PERSISTENT_CONTACTS
|
||||
|
||||
btDiscreteCollisionDetectorInterface::ClosestPointInput input;
|
||||
input.m_maximumDistanceSquared = 1e30f;
|
||||
input.m_transformA = body0->getWorldTransform();
|
||||
input.m_transformB = body1->getWorldTransform();
|
||||
|
||||
btBoxBoxDetector detector(box0,box1);
|
||||
detector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw);
|
||||
|
||||
#ifdef USE_PERSISTENT_CONTACTS
|
||||
// refreshContactPoints is only necessary when using persistent contact points. otherwise all points are newly added
|
||||
if (m_ownManifold)
|
||||
{
|
||||
resultOut->refreshContactPoints();
|
||||
}
|
||||
#endif //USE_PERSISTENT_CONTACTS
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
btScalar btSoftSoftCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
|
||||
{
|
||||
//not yet
|
||||
return 1.f;
|
||||
}
|
||||
62
Demos/SoftDemo/btSoftSoftCollisionAlgorithm.h
Normal file
62
Demos/SoftDemo/btSoftSoftCollisionAlgorithm.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SOFT_SOFT_COLLISION_ALGORITHM_H
|
||||
#define SOFT_SOFT_COLLISION_ALGORITHM_H
|
||||
|
||||
#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
|
||||
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
|
||||
#include "BulletCollision/BroadphaseCollision/btDispatcher.h"
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
|
||||
|
||||
class btPersistentManifold;
|
||||
struct btSoftBody;
|
||||
|
||||
///collision detection between two btSoftBody shapes
|
||||
class btSoftSoftCollisionAlgorithm : public btCollisionAlgorithm
|
||||
{
|
||||
bool m_ownManifold;
|
||||
btPersistentManifold* m_manifoldPtr;
|
||||
|
||||
btSoftBody* m_softBody0;
|
||||
btSoftBody* m_softBody1;
|
||||
|
||||
|
||||
public:
|
||||
btSoftSoftCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci)
|
||||
: btCollisionAlgorithm(ci) {}
|
||||
|
||||
virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
|
||||
|
||||
virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
|
||||
|
||||
btSoftSoftCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1);
|
||||
|
||||
virtual ~btSoftSoftCollisionAlgorithm();
|
||||
|
||||
struct CreateFunc :public btCollisionAlgorithmCreateFunc
|
||||
{
|
||||
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
|
||||
{
|
||||
int bbsize = sizeof(btSoftSoftCollisionAlgorithm);
|
||||
void* ptr = ci.m_dispatcher1->allocateCollisionAlgorithm(bbsize);
|
||||
return new(ptr) btSoftSoftCollisionAlgorithm(0,ci,body0,body1);
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif //SOFT_SOFT_COLLISION_ALGORITHM_H
|
||||
|
||||
@@ -59,6 +59,8 @@ CONCAVE_SHAPES_END_HERE,
|
||||
|
||||
COMPOUND_SHAPE_PROXYTYPE,
|
||||
|
||||
SOFTBODY_SHAPE_PROXYTYPE,
|
||||
|
||||
MAX_BROADPHASE_COLLISION_TYPES
|
||||
};
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ public:
|
||||
}
|
||||
|
||||
|
||||
btCollisionAlgorithmCreateFunc* getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1);
|
||||
virtual btCollisionAlgorithmCreateFunc* getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1);
|
||||
|
||||
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -14,8 +14,8 @@ subject to the following restrictions:
|
||||
*/
|
||||
///btSoftBody implementation by Nathanael Presson
|
||||
|
||||
#ifndef _312AEEF3_52DA_4ff6_B804_FCF937182E46_
|
||||
#define _312AEEF3_52DA_4ff6_B804_FCF937182E46_
|
||||
#ifndef _BT_SOFT_BODY_H
|
||||
#define _BT_SOFT_BODY_H
|
||||
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
#include "LinearMath/btPoint3.h"
|
||||
@@ -23,67 +23,100 @@ subject to the following restrictions:
|
||||
#include "LinearMath/btIDebugDraw.h"
|
||||
#include "BulletDynamics/Dynamics/btRigidBody.h"
|
||||
|
||||
//
|
||||
// btSoftBody
|
||||
//
|
||||
struct btSoftBody
|
||||
{
|
||||
#include "BulletCollision/CollisionShapes/btConcaveShape.h"
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
|
||||
#include "BulletDynamics/SoftBody/btSparseSDF.h"
|
||||
|
||||
class btBroadphaseInterface;
|
||||
class btCollisionDispatcher;
|
||||
|
||||
/// btSoftBody is work-in-progress
|
||||
struct btSoftBody : public btCollisionObject
|
||||
{
|
||||
|
||||
//
|
||||
// Enumerations
|
||||
//
|
||||
|
||||
/* eLType */
|
||||
///eLType
|
||||
struct eLType { enum _ {
|
||||
Structural, /* Master constraints */
|
||||
Bending, /* Secondary constraints */
|
||||
Structural, ///Master constraints
|
||||
Bending, ///Secondary constraints
|
||||
};};
|
||||
|
||||
/* eAeroModel */
|
||||
////eAeroModel
|
||||
struct eAeroModel { enum _ {
|
||||
V_Point, /* Vertex normals are oriented toward velocity */
|
||||
V_TwoSided, /* Vertex normals are fliped to match velocity */
|
||||
V_OneSided, /* Vertex normals are taken as it is */
|
||||
F_TwoSided, /* Face normals are fliped to match velocity */
|
||||
F_OneSided, /* Face normals are taken as it is */
|
||||
V_Point, ///Vertex normals are oriented toward velocity
|
||||
V_TwoSided, ///Vertex normals are fliped to match velocity
|
||||
V_OneSided, ///Vertex normals are taken as it is
|
||||
F_TwoSided, ///Face normals are fliped to match velocity
|
||||
F_OneSided, ///Face normals are taken as it is
|
||||
};};
|
||||
|
||||
//
|
||||
// Interfaces
|
||||
//
|
||||
struct btSoftBodyWorldInfo
|
||||
{
|
||||
btScalar air_density;
|
||||
btScalar water_density;
|
||||
btScalar water_offset;
|
||||
btVector3 water_normal;
|
||||
btBroadphaseInterface* m_broadphase;
|
||||
btCollisionDispatcher* m_dispatcher;
|
||||
|
||||
btSparseSdf<3> m_sparsesdf;
|
||||
};
|
||||
|
||||
//reference or copy?
|
||||
btSoftBodyWorldInfo& m_worldInfo;
|
||||
|
||||
///constructor
|
||||
|
||||
btSoftBody(btSoftBody::btSoftBodyWorldInfo& worldInfo,int node_count,
|
||||
const btVector3* x,
|
||||
const btScalar* m);
|
||||
|
||||
|
||||
///sCti is Softbody contact info
|
||||
struct sCti
|
||||
{
|
||||
btRigidBody* m_body; /* Rigid body */
|
||||
btVector3 m_normal; /* Outward normal */
|
||||
btScalar m_offset; /* Offset from origin */
|
||||
};
|
||||
|
||||
|
||||
void StartCollide(const btVector3& aabbMin,const btVector3& aabbMax)
|
||||
{
|
||||
//??
|
||||
}
|
||||
void EndCollide()
|
||||
{
|
||||
//??
|
||||
}
|
||||
|
||||
//
|
||||
bool CheckContact( const btVector3& x, btSoftBody::sCti& cti);
|
||||
////
|
||||
|
||||
///destructor
|
||||
virtual ~btSoftBody();
|
||||
|
||||
|
||||
|
||||
struct sMedium
|
||||
{
|
||||
btVector3 m_velocity; /* Velocity */
|
||||
btScalar m_pressure; /* Pressure */
|
||||
btScalar m_density; /* Density */
|
||||
};
|
||||
|
||||
virtual void EvaluateMedium( const btVector3& /*position*/, sMedium& medium)
|
||||
{
|
||||
medium.m_velocity=btVector3(0,0,0);
|
||||
medium.m_pressure=0;
|
||||
medium.m_density=0;
|
||||
}
|
||||
|
||||
|
||||
/* ISoftBody */
|
||||
struct ISoftBody
|
||||
{
|
||||
struct sCti
|
||||
{
|
||||
btRigidBody* m_body; /* Rigid body */
|
||||
btVector3 m_normal; /* Outward normal */
|
||||
btScalar m_offset; /* Offset from origin */
|
||||
};
|
||||
struct sMedium
|
||||
{
|
||||
btVector3 m_velocity; /* Velocity */
|
||||
btScalar m_pressure; /* Pressure */
|
||||
btScalar m_density; /* Density */
|
||||
};
|
||||
virtual void Attach(btSoftBody*)
|
||||
{}
|
||||
virtual void Detach(btSoftBody*)
|
||||
{ delete this; }
|
||||
virtual void StartCollide( const btVector3& /*minbounds*/,
|
||||
const btVector3& /*maxbounds*/)
|
||||
{}
|
||||
virtual bool CheckContact (const btVector3& /*position*/,
|
||||
sCti& /*contact*/)
|
||||
{ return(false); }
|
||||
virtual void EndCollide()
|
||||
{}
|
||||
virtual void EvaluateMedium( const btVector3& /*position*/,
|
||||
sMedium& medium)
|
||||
{ medium.m_velocity=btVector3(0,0,0);
|
||||
medium.m_pressure=0;
|
||||
medium.m_density=0; }
|
||||
};
|
||||
|
||||
//
|
||||
// Internal types
|
||||
@@ -94,12 +127,12 @@ struct btSoftBody
|
||||
|
||||
/* Base type */
|
||||
struct Element
|
||||
{
|
||||
{
|
||||
void* m_tag; // User data
|
||||
};
|
||||
/* Node */
|
||||
};
|
||||
///Node
|
||||
struct Node : Element
|
||||
{
|
||||
{
|
||||
btVector3 m_x; // Position
|
||||
btVector3 m_q; // Previous step position
|
||||
btVector3 m_v; // Velocity
|
||||
@@ -108,47 +141,47 @@ struct btSoftBody
|
||||
btScalar m_im; // 1/mass
|
||||
btScalar m_area; // Area
|
||||
int m_battach:1; // Attached
|
||||
};
|
||||
};
|
||||
/* Link */
|
||||
struct Link : Element
|
||||
{
|
||||
{
|
||||
Node* m_n[2]; // Node pointers
|
||||
btScalar m_rl; // Rest length
|
||||
btScalar m_kST; // Stiffness coefficient
|
||||
btScalar m_c0; // (ima+imb)*kLST
|
||||
btScalar m_c1; // rl^2
|
||||
eLType::_ m_type; // Link type
|
||||
};
|
||||
btSoftBody::eLType::_ m_type; // Link type
|
||||
};
|
||||
/* Face */
|
||||
struct Face : Element
|
||||
{
|
||||
{
|
||||
Node* m_n[3]; // Node pointers
|
||||
btVector3 m_normal; // Normal
|
||||
btScalar m_ra; // Rest area
|
||||
};
|
||||
};
|
||||
/* Contact */
|
||||
struct Contact
|
||||
{
|
||||
ISoftBody::sCti m_cti; // Contact infos
|
||||
{
|
||||
btSoftBody::sCti m_cti; // Contact infos
|
||||
Node* m_node; // Owner node
|
||||
btMatrix3x3 m_c0; // Impulse matrix
|
||||
btVector3 m_c1; // Relative anchor
|
||||
btScalar m_c2; // ima*dt
|
||||
btScalar m_c3; // Friction
|
||||
};
|
||||
};
|
||||
/* Anchor */
|
||||
struct Anchor
|
||||
{
|
||||
{
|
||||
Node* m_node; // Node pointer
|
||||
btVector3 m_local; // Anchor position in body space
|
||||
btRigidBody* m_body; // Body
|
||||
btMatrix3x3 m_c0; // Impulse matrix
|
||||
btVector3 m_c1; // Relative anchor
|
||||
btScalar m_c2; // ima*dt
|
||||
};
|
||||
};
|
||||
/* Pose */
|
||||
struct Pose
|
||||
{
|
||||
{
|
||||
bool m_bvolume; // Is valid
|
||||
bool m_bframe; // Is frame
|
||||
btScalar m_volume; // Rest volume
|
||||
@@ -156,11 +189,11 @@ struct btSoftBody
|
||||
tScalarArray m_wgh; // Weights
|
||||
btVector3 m_com; // COM
|
||||
btMatrix3x3 m_trs; // Transform
|
||||
};
|
||||
};
|
||||
/* Config */
|
||||
struct Config
|
||||
{
|
||||
eAeroModel::_ aeromodel; // Aerodynamic model (default: V_Point)
|
||||
{
|
||||
btSoftBody::eAeroModel::_ aeromodel; // Aerodynamic model (default: V_Point)
|
||||
btScalar kLST; // Linear stiffness coefficient [0,1]
|
||||
btScalar kDP; // Damping coefficient [0,1]
|
||||
btScalar kDG; // Drag coefficient [0,+inf]
|
||||
@@ -178,7 +211,7 @@ struct btSoftBody
|
||||
int iterations; // Solver iterations
|
||||
bool becollide; // Enable external collisions
|
||||
bool bscollide; // Enable self collisions
|
||||
};
|
||||
};
|
||||
|
||||
//
|
||||
// Typedef's
|
||||
@@ -196,11 +229,99 @@ struct btSoftBody
|
||||
|
||||
Config m_cfg; // Configuration
|
||||
Pose m_pose; // Pose
|
||||
ISoftBody* m_isb; // ISoftBody
|
||||
void* m_tag; // User data
|
||||
tNodeArray m_nodes; // Nodes
|
||||
tLinkArray m_links; // Links
|
||||
tFaceArray m_faces; // Faces
|
||||
|
||||
//////////////////////
|
||||
|
||||
///btSoftBodyCollisionShape is work-in-progress collision shape for softbodies
|
||||
class btSoftBodyCollisionShape : public btConcaveShape
|
||||
{
|
||||
static btVector3 m_sScaling;
|
||||
public:
|
||||
|
||||
tNodeArray m_nodes; // Nodes
|
||||
tLinkArray m_links; // Links
|
||||
tFaceArray m_faces; // Faces
|
||||
|
||||
btSoftBodyCollisionShape();
|
||||
|
||||
virtual ~btSoftBodyCollisionShape();
|
||||
|
||||
virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const;
|
||||
|
||||
///getAabb returns the axis aligned bounding box in the coordinate frame of the given transform t.
|
||||
virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
|
||||
{
|
||||
///not yet
|
||||
btAssert(0);
|
||||
}
|
||||
|
||||
virtual int getShapeType() const
|
||||
{
|
||||
return SOFTBODY_SHAPE_PROXYTYPE;
|
||||
}
|
||||
virtual void setLocalScaling(const btVector3& scaling)
|
||||
{
|
||||
///not yet
|
||||
btAssert(0);
|
||||
}
|
||||
virtual const btVector3& getLocalScaling() const
|
||||
{
|
||||
///not yet
|
||||
btAssert(0);
|
||||
return m_sScaling;
|
||||
}
|
||||
virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const
|
||||
{
|
||||
///not yet
|
||||
btAssert(0);
|
||||
}
|
||||
virtual const char* getName()const
|
||||
{
|
||||
return "SoftBody";
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
btSoftBodyCollisionShape* m_softBodyCollisionShape;
|
||||
|
||||
btCollisionObjectArray m_overlappingRigidBodies;
|
||||
|
||||
btAlignedObjectArray<btSoftBody*> m_overlappingSoftBodies;
|
||||
|
||||
|
||||
//////////////////////
|
||||
|
||||
inline tNodeArray& getNodes()
|
||||
{
|
||||
return m_softBodyCollisionShape->m_nodes;
|
||||
}
|
||||
inline const tNodeArray& getNodes() const
|
||||
{
|
||||
return m_softBodyCollisionShape->m_nodes;
|
||||
}
|
||||
|
||||
inline tLinkArray& getLinks()
|
||||
{
|
||||
return m_softBodyCollisionShape->m_links;
|
||||
}
|
||||
inline const tLinkArray& getLinks() const
|
||||
{
|
||||
return m_softBodyCollisionShape->m_links;
|
||||
}
|
||||
|
||||
inline tFaceArray& getFaces()
|
||||
{
|
||||
return m_softBodyCollisionShape->m_faces;
|
||||
}
|
||||
|
||||
inline const tFaceArray& getFaces() const
|
||||
{
|
||||
return m_softBodyCollisionShape->m_faces;
|
||||
}
|
||||
|
||||
|
||||
tAnchorArray m_anchors; // Anchors
|
||||
tContactArray m_contacts; // Contacts
|
||||
btScalar m_timeacc; // Time accumulator
|
||||
@@ -211,60 +332,55 @@ struct btSoftBody
|
||||
// Api
|
||||
//
|
||||
|
||||
/* Create a soft body */
|
||||
static btSoftBody* Create( ISoftBody* isoftbody,
|
||||
int node_count,
|
||||
const btVector3* x=0,
|
||||
const btScalar* m=0);
|
||||
/* Delete a body */
|
||||
void Delete();
|
||||
/* Check for existing link */
|
||||
bool CheckLink( int node0,
|
||||
int node1) const;
|
||||
int node1) const;
|
||||
bool CheckLink( const btSoftBody::Node* node0,
|
||||
const btSoftBody::Node* node1) const;
|
||||
const btSoftBody::Node* node1) const;
|
||||
/* Check for existring face */
|
||||
bool CheckFace( int node0,
|
||||
int node1,
|
||||
int node2) const;
|
||||
int node1,
|
||||
int node2) const;
|
||||
/* Append link */
|
||||
void AppendLink( int node0,
|
||||
int node1,
|
||||
btScalar kST,
|
||||
btSoftBody::eLType::_ type,
|
||||
bool bcheckexist=false);
|
||||
int node1,
|
||||
btScalar kST,
|
||||
btSoftBody::eLType::_ type,
|
||||
bool bcheckexist=false);
|
||||
void AppendLink( btSoftBody::Node* node0,
|
||||
btSoftBody::Node* node1,
|
||||
btScalar kST,
|
||||
btSoftBody::eLType::_ type,
|
||||
bool bcheckexist=false);
|
||||
btSoftBody::Node* node1,
|
||||
btScalar kST,
|
||||
btSoftBody::eLType::_ type,
|
||||
bool bcheckexist=false);
|
||||
/* Append face */
|
||||
void AppendFace( int node0,
|
||||
int node1,
|
||||
int node2);
|
||||
int node1,
|
||||
int node2);
|
||||
/* Append anchor */
|
||||
void AppendAnchor( int node,
|
||||
btRigidBody* body);
|
||||
btRigidBody* body);
|
||||
/* Add force (or gravity) to the entire body */
|
||||
void AddForce( const btVector3& force);
|
||||
/* Add force (or gravity) to a node of the body */
|
||||
void AddForce( const btVector3& force,
|
||||
int node);
|
||||
int node);
|
||||
/* Add velocity to the entire body */
|
||||
void AddVelocity( const btVector3& velocity);
|
||||
/* Add velocity to a node of the body */
|
||||
void AddVelocity( const btVector3& velocity,
|
||||
int node);
|
||||
int node);
|
||||
/* Set mass */
|
||||
void SetMass( int node,
|
||||
btScalar mass);
|
||||
btScalar mass);
|
||||
/* Get mass */
|
||||
btScalar GetMass( int node) const;
|
||||
/* Get total mass */
|
||||
btScalar GetTotalMass() const;
|
||||
/* Set total mass (weighted by previous masses) */
|
||||
void SetTotalMass( btScalar mass,
|
||||
bool fromfaces=false);
|
||||
bool fromfaces=false);
|
||||
/* Set total density */
|
||||
void SetTotalDensity(btScalar density);
|
||||
/* Transform */
|
||||
@@ -273,84 +389,30 @@ struct btSoftBody
|
||||
void Scale( const btVector3& scl);
|
||||
/* Set current state as pose */
|
||||
void SetPose( bool bvolume,
|
||||
bool bframe);
|
||||
bool bframe);
|
||||
/* Return the volume */
|
||||
btScalar GetVolume() const;
|
||||
/* Generate bending constraints based on distance in the adjency graph */
|
||||
int GenerateBendingConstraints( int distance,
|
||||
btScalar stiffness);
|
||||
btScalar stiffness);
|
||||
/* Randomize constraints to reduce solver bias */
|
||||
void RandomizeConstraints();
|
||||
/* Ray casting */
|
||||
btScalar Raycast( const btVector3& org,
|
||||
const btVector3& dir) const;
|
||||
const btVector3& dir) const;
|
||||
/* Step */
|
||||
void Step( btScalar dt);
|
||||
|
||||
};
|
||||
void updateBounds();
|
||||
|
||||
//
|
||||
// Helpers
|
||||
//
|
||||
void updateTransform()
|
||||
{
|
||||
updateBounds();
|
||||
}
|
||||
|
||||
/* fDrawFlags */
|
||||
struct fDrawFlags { enum _ {
|
||||
Nodes = 0x0001,
|
||||
SLinks = 0x0002,
|
||||
BLinks = 0x0004,
|
||||
Faces = 0x0008,
|
||||
Tetras = 0x0010,
|
||||
Normals = 0x0020,
|
||||
Contacts = 0x0040,
|
||||
Anchors = 0x0080,
|
||||
/* presets */
|
||||
Links = SLinks+BLinks,
|
||||
Std = SLinks+Faces+Anchors,
|
||||
StdTetra = Std-Faces+Tetras,
|
||||
};};
|
||||
|
||||
/* Draw body */
|
||||
void Draw( btSoftBody* psb,
|
||||
btIDebugDraw* idraw,
|
||||
int drawflags=fDrawFlags::Std);
|
||||
/* Draw body infos */
|
||||
void DrawInfos( btSoftBody* psb,
|
||||
btIDebugDraw* idraw,
|
||||
bool masses,
|
||||
bool areas,
|
||||
bool stress);
|
||||
/* Draw rigid frame */
|
||||
void DrawFrame( btSoftBody* psb,
|
||||
btIDebugDraw* idraw);
|
||||
/* Create a rope */
|
||||
btSoftBody* CreateRope( btSoftBody::ISoftBody* isoftbody,
|
||||
const btVector3& from,
|
||||
const btVector3& to,
|
||||
int res,
|
||||
int fixeds);
|
||||
/* Create a patch */
|
||||
btSoftBody* CreatePatch( btSoftBody::ISoftBody* isoftbody,
|
||||
const btVector3& corner00,
|
||||
const btVector3& corner10,
|
||||
const btVector3& corner01,
|
||||
const btVector3& corner11,
|
||||
int resx,
|
||||
int resy,
|
||||
int fixeds,
|
||||
bool gendiags);
|
||||
/* Create an ellipsoid */
|
||||
btSoftBody* CreateEllipsoid(btSoftBody::ISoftBody* isoftbody,
|
||||
const btVector3& center,
|
||||
const btVector3& radius,
|
||||
int res);
|
||||
/* Create from convex-hull */
|
||||
btSoftBody* CreateFromConvexHull( btSoftBody::ISoftBody* isoftbody,
|
||||
const btVector3* vertices,
|
||||
int nvertices);
|
||||
/* Create from trimesh */
|
||||
btSoftBody* CreateFromTriMesh( btSoftBody::ISoftBody* isoftbody,
|
||||
const btScalar* vertices,
|
||||
const int* triangles,
|
||||
int ntriangles);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif //_BT_SOFT_BODY_H
|
||||
|
||||
@@ -17,73 +17,69 @@ subject to the following restrictions:
|
||||
#include "btSoftBody.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
namespace btsoftbody_internals
|
||||
{
|
||||
#include "btSoftBodyHelpers.h"
|
||||
|
||||
//
|
||||
static void drawVertex( btIDebugDraw* idraw,
|
||||
const btVector3& x,btScalar s,const btVector3& c)
|
||||
{
|
||||
idraw->drawLine(x-btVector3(s,0,0),x+btVector3(s,0,0),c);
|
||||
idraw->drawLine(x-btVector3(0,s,0),x+btVector3(0,s,0),c);
|
||||
idraw->drawLine(x-btVector3(0,0,s),x+btVector3(0,0,s),c);
|
||||
}
|
||||
|
||||
//
|
||||
static btVector3 stresscolor(btScalar stress)
|
||||
{
|
||||
static const btVector3 spectrum[]= {
|
||||
btVector3(1,0,1),
|
||||
btVector3(0,0,1),
|
||||
btVector3(0,1,1),
|
||||
btVector3(0,1,0),
|
||||
btVector3(1,1,0),
|
||||
btVector3(1,0,0),
|
||||
btVector3(1,0,0),
|
||||
};
|
||||
static const int ncolors=sizeof(spectrum)/sizeof(spectrum[0])-1;
|
||||
static const btScalar one=1;
|
||||
stress=btMax<btScalar>(0,btMin<btScalar>(1,stress))*ncolors;
|
||||
const int sel=(int)stress;
|
||||
const btScalar frc=stress-sel;
|
||||
return(spectrum[sel]+(spectrum[sel+1]-spectrum[sel])*frc);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
using namespace btsoftbody_internals;
|
||||
|
||||
//
|
||||
void Draw( btSoftBody* psb,
|
||||
btIDebugDraw* idraw,
|
||||
int drawflags)
|
||||
{
|
||||
const btScalar scl=(btScalar)0.1;
|
||||
const btScalar nscl=scl*5;
|
||||
const btScalar alpha=(btScalar)0.5;
|
||||
const btVector3 scolor=btVector3(0,0,0);
|
||||
const btVector3 bcolor=btVector3(1,1,0);
|
||||
const btVector3 ncolor=btVector3(1,1,1);
|
||||
const btVector3 ccolor=btVector3(1,0,0);
|
||||
/* Nodes */
|
||||
if(0!=(drawflags&fDrawFlags::Nodes))
|
||||
void btSoftBodyHelpers::drawVertex( btIDebugDraw* idraw,
|
||||
const btVector3& x,btScalar s,const btVector3& c)
|
||||
{
|
||||
for(int i=0;i<psb->m_nodes.size();++i)
|
||||
idraw->drawLine(x-btVector3(s,0,0),x+btVector3(s,0,0),c);
|
||||
idraw->drawLine(x-btVector3(0,s,0),x+btVector3(0,s,0),c);
|
||||
idraw->drawLine(x-btVector3(0,0,s),x+btVector3(0,0,s),c);
|
||||
}
|
||||
|
||||
//
|
||||
btVector3 btSoftBodyHelpers::stresscolor(btScalar stress)
|
||||
{
|
||||
static const btVector3 spectrum[]= {
|
||||
btVector3(1,0,1),
|
||||
btVector3(0,0,1),
|
||||
btVector3(0,1,1),
|
||||
btVector3(0,1,0),
|
||||
btVector3(1,1,0),
|
||||
btVector3(1,0,0),
|
||||
btVector3(1,0,0),
|
||||
};
|
||||
static const int ncolors=sizeof(spectrum)/sizeof(spectrum[0])-1;
|
||||
static const btScalar one=1;
|
||||
stress=btMax<btScalar>(0,btMin<btScalar>(1,stress))*ncolors;
|
||||
const int sel=(int)stress;
|
||||
const btScalar frc=stress-sel;
|
||||
return(spectrum[sel]+(spectrum[sel+1]-spectrum[sel])*frc);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
void btSoftBodyHelpers::Draw( btSoftBody* psb,
|
||||
btIDebugDraw* idraw,
|
||||
int drawflags)
|
||||
{
|
||||
const btScalar scl=(btScalar)0.1;
|
||||
const btScalar nscl=scl*5;
|
||||
const btScalar alpha=(btScalar)0.5;
|
||||
const btVector3 scolor=btVector3(0,0,0);
|
||||
const btVector3 bcolor=btVector3(1,1,0);
|
||||
const btVector3 ncolor=btVector3(1,1,1);
|
||||
const btVector3 ccolor=btVector3(1,0,0);
|
||||
/* Nodes */
|
||||
if(0!=(drawflags&fDrawFlags::Nodes))
|
||||
{
|
||||
for(int i=0;i<psb->getNodes().size();++i)
|
||||
{
|
||||
const btSoftBody::Node& n=psb->m_nodes[i];
|
||||
idraw->drawLine(n.m_x-btVector3(scl,0,0),n.m_x+btVector3(scl,0,0),btVector3(1,0,0));
|
||||
idraw->drawLine(n.m_x-btVector3(0,scl,0),n.m_x+btVector3(0,scl,0),btVector3(0,1,0));
|
||||
idraw->drawLine(n.m_x-btVector3(0,0,scl),n.m_x+btVector3(0,0,scl),btVector3(0,0,1));
|
||||
const btSoftBody::Node& n=psb->getNodes()[i];
|
||||
idraw->drawLine(n.m_x-btVector3(scl,0,0),n.m_x+btVector3(scl,0,0),btVector3(1,0,0));
|
||||
idraw->drawLine(n.m_x-btVector3(0,scl,0),n.m_x+btVector3(0,scl,0),btVector3(0,1,0));
|
||||
idraw->drawLine(n.m_x-btVector3(0,0,scl),n.m_x+btVector3(0,0,scl),btVector3(0,0,1));
|
||||
}
|
||||
}
|
||||
/* Links */
|
||||
if(0!=(drawflags&fDrawFlags::Links))
|
||||
/* Links */
|
||||
if(0!=(drawflags&fDrawFlags::Links))
|
||||
{
|
||||
for(int i=0;i<psb->m_links.size();++i)
|
||||
for(int i=0;i<psb->getLinks().size();++i)
|
||||
{
|
||||
const btSoftBody::Link& l=psb->m_links[i];
|
||||
switch(l.m_type)
|
||||
const btSoftBody::Link& l=psb->getLinks()[i];
|
||||
switch(l.m_type)
|
||||
{
|
||||
case btSoftBody::eLType::Structural:
|
||||
if(0!=(drawflags&fDrawFlags::SLinks)) idraw->drawLine(l.m_n[0]->m_x,l.m_n[1]->m_x,scolor);break;
|
||||
@@ -92,308 +88,304 @@ if(0!=(drawflags&fDrawFlags::Links))
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Normals */
|
||||
if(0!=(drawflags&fDrawFlags::Normals))
|
||||
/* Normals */
|
||||
if(0!=(drawflags&fDrawFlags::Normals))
|
||||
{
|
||||
for(int i=0;i<psb->m_nodes.size();++i)
|
||||
for(int i=0;i<psb->getNodes().size();++i)
|
||||
{
|
||||
const btSoftBody::Node& n=psb->m_nodes[i];
|
||||
const btVector3 d=n.m_n*nscl;
|
||||
idraw->drawLine(n.m_x,n.m_x+d,ncolor);
|
||||
idraw->drawLine(n.m_x,n.m_x-d,ncolor*0.5);
|
||||
const btSoftBody::Node& n=psb->getNodes()[i];
|
||||
const btVector3 d=n.m_n*nscl;
|
||||
idraw->drawLine(n.m_x,n.m_x+d,ncolor);
|
||||
idraw->drawLine(n.m_x,n.m_x-d,ncolor*0.5);
|
||||
}
|
||||
}
|
||||
/* Contacts */
|
||||
if(0!=(drawflags&fDrawFlags::Contacts))
|
||||
/* Contacts */
|
||||
if(0!=(drawflags&fDrawFlags::Contacts))
|
||||
{
|
||||
static const btVector3 axis[]={btVector3(1,0,0),
|
||||
btVector3(0,1,0),
|
||||
btVector3(0,0,1)};
|
||||
for(int i=0;i<psb->m_contacts.size();++i)
|
||||
static const btVector3 axis[]={btVector3(1,0,0),
|
||||
btVector3(0,1,0),
|
||||
btVector3(0,0,1)};
|
||||
for(int i=0;i<psb->m_contacts.size();++i)
|
||||
{
|
||||
const btSoftBody::Contact& c=psb->m_contacts[i];
|
||||
const btVector3 o= c.m_node->m_x-c.m_cti.m_normal*
|
||||
(dot(c.m_node->m_x,c.m_cti.m_normal)+c.m_cti.m_offset);
|
||||
const btVector3 x=cross(c.m_cti.m_normal,axis[c.m_cti.m_normal.minAxis()]).normalized();
|
||||
const btVector3 y=cross(x,c.m_cti.m_normal).normalized();
|
||||
idraw->drawLine(o-x*nscl,o+x*nscl,ccolor);
|
||||
idraw->drawLine(o-y*nscl,o+y*nscl,ccolor);
|
||||
idraw->drawLine(o,o+c.m_cti.m_normal*nscl*3,btVector3(1,1,0));
|
||||
const btSoftBody::Contact& c=psb->m_contacts[i];
|
||||
const btVector3 o= c.m_node->m_x-c.m_cti.m_normal*
|
||||
(dot(c.m_node->m_x,c.m_cti.m_normal)+c.m_cti.m_offset);
|
||||
const btVector3 x=cross(c.m_cti.m_normal,axis[c.m_cti.m_normal.minAxis()]).normalized();
|
||||
const btVector3 y=cross(x,c.m_cti.m_normal).normalized();
|
||||
idraw->drawLine(o-x*nscl,o+x*nscl,ccolor);
|
||||
idraw->drawLine(o-y*nscl,o+y*nscl,ccolor);
|
||||
idraw->drawLine(o,o+c.m_cti.m_normal*nscl*3,btVector3(1,1,0));
|
||||
}
|
||||
}
|
||||
/* Anchors */
|
||||
if(0!=(drawflags&fDrawFlags::Anchors))
|
||||
/* Anchors */
|
||||
if(0!=(drawflags&fDrawFlags::Anchors))
|
||||
{
|
||||
for(int i=0;i<psb->m_anchors.size();++i)
|
||||
for(int i=0;i<psb->m_anchors.size();++i)
|
||||
{
|
||||
const btSoftBody::Anchor& a=psb->m_anchors[i];
|
||||
const btVector3 q=a.m_body->getWorldTransform()*a.m_local;
|
||||
drawVertex(idraw,a.m_node->m_x,0.25,btVector3(1,0,0));
|
||||
drawVertex(idraw,q,0.25,btVector3(0,1,0));
|
||||
idraw->drawLine(a.m_node->m_x,q,btVector3(1,1,1));
|
||||
const btSoftBody::Anchor& a=psb->m_anchors[i];
|
||||
const btVector3 q=a.m_body->getWorldTransform()*a.m_local;
|
||||
drawVertex(idraw,a.m_node->m_x,0.25,btVector3(1,0,0));
|
||||
drawVertex(idraw,q,0.25,btVector3(0,1,0));
|
||||
idraw->drawLine(a.m_node->m_x,q,btVector3(1,1,1));
|
||||
}
|
||||
for(int i=0;i<psb->m_nodes.size();++i)
|
||||
for(int i=0;i<psb->getNodes().size();++i)
|
||||
{
|
||||
const btSoftBody::Node& n=psb->m_nodes[i];
|
||||
if(n.m_im<=0)
|
||||
const btSoftBody::Node& n=psb->getNodes()[i];
|
||||
if(n.m_im<=0)
|
||||
{
|
||||
drawVertex(idraw,n.m_x,0.25,btVector3(1,0,0));
|
||||
drawVertex(idraw,n.m_x,0.25,btVector3(1,0,0));
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Faces */
|
||||
if(0!=(drawflags&fDrawFlags::Faces))
|
||||
/* Faces */
|
||||
if(0!=(drawflags&fDrawFlags::Faces))
|
||||
{
|
||||
const btScalar scl=(btScalar)0.7;
|
||||
const btScalar alp=(btScalar)1;
|
||||
const btVector3 col(0,(btScalar)0.7,0);
|
||||
for(int i=0;i<psb->m_faces.size();++i)
|
||||
const btScalar scl=(btScalar)0.7;
|
||||
const btScalar alp=(btScalar)1;
|
||||
const btVector3 col(0,(btScalar)0.7,0);
|
||||
for(int i=0;i<psb->getFaces().size();++i)
|
||||
{
|
||||
const btSoftBody::Face& f=psb->m_faces[i];
|
||||
const btVector3 x[]={f.m_n[0]->m_x,f.m_n[1]->m_x,f.m_n[2]->m_x};
|
||||
const btVector3 c=(x[0]+x[1]+x[2])/3;
|
||||
idraw->drawTriangle((x[0]-c)*scl+c,
|
||||
(x[1]-c)*scl+c,
|
||||
(x[2]-c)*scl+c,
|
||||
f.m_n[0]->m_n,f.m_n[1]->m_n,f.m_n[2]->m_n,
|
||||
col,alp);
|
||||
const btSoftBody::Face& f=psb->getFaces()[i];
|
||||
const btVector3 x[]={f.m_n[0]->m_x,f.m_n[1]->m_x,f.m_n[2]->m_x};
|
||||
const btVector3 c=(x[0]+x[1]+x[2])/3;
|
||||
idraw->drawTriangle((x[0]-c)*scl+c,
|
||||
(x[1]-c)*scl+c,
|
||||
(x[2]-c)*scl+c,
|
||||
f.m_n[0]->m_n,f.m_n[1]->m_n,f.m_n[2]->m_n,
|
||||
col,alp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
void DrawInfos( btSoftBody* psb,
|
||||
btIDebugDraw* idraw,
|
||||
bool masses,
|
||||
bool areas,
|
||||
bool stress)
|
||||
void btSoftBodyHelpers::DrawInfos( btSoftBody* psb,
|
||||
btIDebugDraw* idraw,
|
||||
bool masses,
|
||||
bool areas,
|
||||
bool stress)
|
||||
{
|
||||
for(int i=0;i<psb->m_nodes.size();++i)
|
||||
for(int i=0;i<psb->getNodes().size();++i)
|
||||
{
|
||||
const btSoftBody::Node& n=psb->m_nodes[i];
|
||||
char text[2048]={0};
|
||||
char buff[1024];
|
||||
if(masses)
|
||||
const btSoftBody::Node& n=psb->getNodes()[i];
|
||||
char text[2048]={0};
|
||||
char buff[1024];
|
||||
if(masses)
|
||||
{
|
||||
sprintf(buff," M(%.2f)",1/n.m_im);
|
||||
strcat(text,buff);
|
||||
sprintf(buff," M(%.2f)",1/n.m_im);
|
||||
strcat(text,buff);
|
||||
}
|
||||
if(areas)
|
||||
if(areas)
|
||||
{
|
||||
sprintf(buff," A(%.2f)",n.m_area);
|
||||
strcat(text,buff);
|
||||
sprintf(buff," A(%.2f)",n.m_area);
|
||||
strcat(text,buff);
|
||||
}
|
||||
if(text[0]) idraw->draw3dText(n.m_x,text);
|
||||
if(text[0]) idraw->draw3dText(n.m_x,text);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
void DrawFrame( btSoftBody* psb,
|
||||
btIDebugDraw* idraw)
|
||||
void btSoftBodyHelpers::DrawFrame( btSoftBody* psb,
|
||||
btIDebugDraw* idraw)
|
||||
{
|
||||
if(psb->m_pose.m_bframe)
|
||||
if(psb->m_pose.m_bframe)
|
||||
{
|
||||
static const btScalar ascl=10;
|
||||
static const btScalar nscl=(btScalar)0.1;
|
||||
const btVector3 com=psb->m_pose.m_com;
|
||||
const btMatrix3x3& trs=psb->m_pose.m_trs;
|
||||
const btVector3 Xaxis=(trs*btVector3(1,0,0)).normalized();
|
||||
const btVector3 Yaxis=(trs*btVector3(0,1,0)).normalized();
|
||||
const btVector3 Zaxis=(trs*btVector3(0,0,1)).normalized();
|
||||
idraw->drawLine(com,com+Xaxis*ascl,btVector3(1,0,0));
|
||||
idraw->drawLine(com,com+Yaxis*ascl,btVector3(0,1,0));
|
||||
idraw->drawLine(com,com+Zaxis*ascl,btVector3(0,0,1));
|
||||
for(int i=0;i<psb->m_pose.m_pos.size();++i)
|
||||
static const btScalar ascl=10;
|
||||
static const btScalar nscl=(btScalar)0.1;
|
||||
const btVector3 com=psb->m_pose.m_com;
|
||||
const btMatrix3x3& trs=psb->m_pose.m_trs;
|
||||
const btVector3 Xaxis=(trs*btVector3(1,0,0)).normalized();
|
||||
const btVector3 Yaxis=(trs*btVector3(0,1,0)).normalized();
|
||||
const btVector3 Zaxis=(trs*btVector3(0,0,1)).normalized();
|
||||
idraw->drawLine(com,com+Xaxis*ascl,btVector3(1,0,0));
|
||||
idraw->drawLine(com,com+Yaxis*ascl,btVector3(0,1,0));
|
||||
idraw->drawLine(com,com+Zaxis*ascl,btVector3(0,0,1));
|
||||
for(int i=0;i<psb->m_pose.m_pos.size();++i)
|
||||
{
|
||||
const btVector3 x=com+trs*psb->m_pose.m_pos[i];
|
||||
idraw->drawLine(x-btVector3(1,0,0)*nscl,x+btVector3(1,0,0)*nscl,btVector3(1,0,1));
|
||||
idraw->drawLine(x-btVector3(0,1,0)*nscl,x+btVector3(0,1,0)*nscl,btVector3(1,0,1));
|
||||
idraw->drawLine(x-btVector3(0,0,1)*nscl,x+btVector3(0,0,1)*nscl,btVector3(1,0,1));
|
||||
const btVector3 x=com+trs*psb->m_pose.m_pos[i];
|
||||
idraw->drawLine(x-btVector3(1,0,0)*nscl,x+btVector3(1,0,0)*nscl,btVector3(1,0,1));
|
||||
idraw->drawLine(x-btVector3(0,1,0)*nscl,x+btVector3(0,1,0)*nscl,btVector3(1,0,1));
|
||||
idraw->drawLine(x-btVector3(0,0,1)*nscl,x+btVector3(0,0,1)*nscl,btVector3(1,0,1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
btSoftBody* CreateRope( btSoftBody::ISoftBody* isoftbody,
|
||||
const btVector3& from,
|
||||
const btVector3& to,
|
||||
int res,
|
||||
int fixeds)
|
||||
btSoftBody* btSoftBodyHelpers::CreateRope( btSoftBody::btSoftBodyWorldInfo& worldInfo, const btVector3& from,
|
||||
const btVector3& to,
|
||||
int res,
|
||||
int fixeds)
|
||||
{
|
||||
/* Create nodes */
|
||||
const int r=res+2;
|
||||
btVector3* x=new btVector3[r];
|
||||
btScalar* m=new btScalar[r];
|
||||
for(int i=0;i<r;++i)
|
||||
/* Create nodes */
|
||||
const int r=res+2;
|
||||
btVector3* x=new btVector3[r];
|
||||
btScalar* m=new btScalar[r];
|
||||
for(int i=0;i<r;++i)
|
||||
{
|
||||
const btScalar t=i/(btScalar)(r-1);
|
||||
x[i]=lerp(from,to,t);
|
||||
m[i]=1;
|
||||
const btScalar t=i/(btScalar)(r-1);
|
||||
x[i]=lerp(from,to,t);
|
||||
m[i]=1;
|
||||
}
|
||||
btSoftBody* psb=btSoftBody::Create(isoftbody,r,x,m);
|
||||
if(fixeds&1) psb->SetMass(0,0);
|
||||
if(fixeds&2) psb->SetMass(r-1,0);
|
||||
delete[] x;
|
||||
delete[] m;
|
||||
/* Create links */
|
||||
for(int i=1;i<r;++i)
|
||||
btSoftBody* psb= new btSoftBody(worldInfo,r,x,m);
|
||||
if(fixeds&1) psb->SetMass(0,0);
|
||||
if(fixeds&2) psb->SetMass(r-1,0);
|
||||
delete[] x;
|
||||
delete[] m;
|
||||
/* Create links */
|
||||
for(int i=1;i<r;++i)
|
||||
{
|
||||
psb->AppendLink(i-1,i,1,btSoftBody::eLType::Structural);
|
||||
psb->AppendLink(i-1,i,1,btSoftBody::eLType::Structural);
|
||||
}
|
||||
/* Finished */
|
||||
return(psb);
|
||||
/* Finished */
|
||||
return(psb);
|
||||
}
|
||||
|
||||
//
|
||||
btSoftBody* CreatePatch( btSoftBody::ISoftBody* isoftbody,
|
||||
const btVector3& corner00,
|
||||
const btVector3& corner10,
|
||||
const btVector3& corner01,
|
||||
const btVector3& corner11,
|
||||
int resx,
|
||||
int resy,
|
||||
int fixeds,
|
||||
bool gendiags)
|
||||
btSoftBody* btSoftBodyHelpers::CreatePatch(btSoftBody::btSoftBodyWorldInfo& worldInfo,const btVector3& corner00,
|
||||
const btVector3& corner10,
|
||||
const btVector3& corner01,
|
||||
const btVector3& corner11,
|
||||
int resx,
|
||||
int resy,
|
||||
int fixeds,
|
||||
bool gendiags)
|
||||
{
|
||||
#define IDX(_x_,_y_) ((_y_)*rx+(_x_))
|
||||
/* Create nodes */
|
||||
if((resx<2)||(resy<2)) return(0);
|
||||
const int rx=resx;
|
||||
const int ry=resy;
|
||||
const int tot=rx*ry;
|
||||
btVector3* x=new btVector3[tot];
|
||||
btScalar* m=new btScalar[tot];
|
||||
for(int iy=0;iy<ry;++iy)
|
||||
/* Create nodes */
|
||||
if((resx<2)||(resy<2)) return(0);
|
||||
const int rx=resx;
|
||||
const int ry=resy;
|
||||
const int tot=rx*ry;
|
||||
btVector3* x=new btVector3[tot];
|
||||
btScalar* m=new btScalar[tot];
|
||||
for(int iy=0;iy<ry;++iy)
|
||||
{
|
||||
const btScalar ty=iy/(btScalar)(ry-1);
|
||||
const btVector3 py0=lerp(corner00,corner01,ty);
|
||||
const btVector3 py1=lerp(corner10,corner11,ty);
|
||||
for(int ix=0;ix<rx;++ix)
|
||||
const btScalar ty=iy/(btScalar)(ry-1);
|
||||
const btVector3 py0=lerp(corner00,corner01,ty);
|
||||
const btVector3 py1=lerp(corner10,corner11,ty);
|
||||
for(int ix=0;ix<rx;++ix)
|
||||
{
|
||||
const btScalar tx=ix/(btScalar)(rx-1);
|
||||
x[IDX(ix,iy)]=lerp(py0,py1,tx);
|
||||
m[IDX(ix,iy)]=1;
|
||||
const btScalar tx=ix/(btScalar)(rx-1);
|
||||
x[IDX(ix,iy)]=lerp(py0,py1,tx);
|
||||
m[IDX(ix,iy)]=1;
|
||||
}
|
||||
}
|
||||
btSoftBody* psb=btSoftBody::Create(isoftbody,tot,x,m);
|
||||
if(fixeds&1) psb->SetMass(IDX(0,0),0);
|
||||
if(fixeds&2) psb->SetMass(IDX(rx-1,0),0);
|
||||
if(fixeds&4) psb->SetMass(IDX(0,ry-1),0);
|
||||
if(fixeds&8) psb->SetMass(IDX(rx-1,ry-1),0);
|
||||
delete[] x;
|
||||
delete[] m;
|
||||
/* Create links and faces */
|
||||
for(int iy=0;iy<ry;++iy)
|
||||
btSoftBody* psb=new btSoftBody(worldInfo,tot,x,m);
|
||||
if(fixeds&1) psb->SetMass(IDX(0,0),0);
|
||||
if(fixeds&2) psb->SetMass(IDX(rx-1,0),0);
|
||||
if(fixeds&4) psb->SetMass(IDX(0,ry-1),0);
|
||||
if(fixeds&8) psb->SetMass(IDX(rx-1,ry-1),0);
|
||||
delete[] x;
|
||||
delete[] m;
|
||||
/* Create links and faces */
|
||||
for(int iy=0;iy<ry;++iy)
|
||||
{
|
||||
for(int ix=0;ix<rx;++ix)
|
||||
for(int ix=0;ix<rx;++ix)
|
||||
{
|
||||
const int idx=IDX(ix,iy);
|
||||
const bool mdx=(ix+1)<rx;
|
||||
const bool mdy=(iy+1)<ry;
|
||||
if(mdx) psb->AppendLink(idx,IDX(ix+1,iy),
|
||||
1,btSoftBody::eLType::Structural);
|
||||
if(mdy) psb->AppendLink(idx,IDX(ix,iy+1),
|
||||
1,btSoftBody::eLType::Structural);
|
||||
if(mdx&&mdy)
|
||||
const int idx=IDX(ix,iy);
|
||||
const bool mdx=(ix+1)<rx;
|
||||
const bool mdy=(iy+1)<ry;
|
||||
if(mdx) psb->AppendLink(idx,IDX(ix+1,iy),
|
||||
1,btSoftBody::eLType::Structural);
|
||||
if(mdy) psb->AppendLink(idx,IDX(ix,iy+1),
|
||||
1,btSoftBody::eLType::Structural);
|
||||
if(mdx&&mdy)
|
||||
{
|
||||
if((ix+iy)&1)
|
||||
if((ix+iy)&1)
|
||||
{
|
||||
psb->AppendFace(IDX(ix,iy),IDX(ix+1,iy),IDX(ix+1,iy+1));
|
||||
psb->AppendFace(IDX(ix,iy),IDX(ix+1,iy+1),IDX(ix,iy+1));
|
||||
if(gendiags)
|
||||
psb->AppendFace(IDX(ix,iy),IDX(ix+1,iy),IDX(ix+1,iy+1));
|
||||
psb->AppendFace(IDX(ix,iy),IDX(ix+1,iy+1),IDX(ix,iy+1));
|
||||
if(gendiags)
|
||||
{
|
||||
psb->AppendLink(IDX(ix,iy),IDX(ix+1,iy+1),
|
||||
1,btSoftBody::eLType::Structural);
|
||||
psb->AppendLink(IDX(ix,iy),IDX(ix+1,iy+1),
|
||||
1,btSoftBody::eLType::Structural);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
psb->AppendFace(IDX(ix,iy+1),IDX(ix,iy),IDX(ix+1,iy));
|
||||
psb->AppendFace(IDX(ix,iy+1),IDX(ix+1,iy),IDX(ix+1,iy+1));
|
||||
if(gendiags)
|
||||
psb->AppendFace(IDX(ix,iy+1),IDX(ix,iy),IDX(ix+1,iy));
|
||||
psb->AppendFace(IDX(ix,iy+1),IDX(ix+1,iy),IDX(ix+1,iy+1));
|
||||
if(gendiags)
|
||||
{
|
||||
psb->AppendLink(IDX(ix+1,iy),IDX(ix,iy+1),
|
||||
1,btSoftBody::eLType::Structural);
|
||||
psb->AppendLink(IDX(ix+1,iy),IDX(ix,iy+1),
|
||||
1,btSoftBody::eLType::Structural);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Finished */
|
||||
/* Finished */
|
||||
#undef IDX
|
||||
return(psb);
|
||||
return(psb);
|
||||
}
|
||||
|
||||
//
|
||||
btSoftBody* CreateEllipsoid(btSoftBody::ISoftBody* isoftbody,
|
||||
const btVector3& center,
|
||||
btSoftBody* btSoftBodyHelpers::CreateEllipsoid(btSoftBody::btSoftBodyWorldInfo& worldInfo,const btVector3& center,
|
||||
const btVector3& radius,
|
||||
int res)
|
||||
{
|
||||
struct Hammersley
|
||||
struct Hammersley
|
||||
{
|
||||
static void Generate(btVector3* x,int n)
|
||||
static void Generate(btVector3* x,int n)
|
||||
{
|
||||
for(int i=0;i<n;i++)
|
||||
for(int i=0;i<n;i++)
|
||||
{
|
||||
btScalar p=0.5,t=0;
|
||||
for(int j=i;j;p*=0.5,j>>=1) if(j&1) t+=p;
|
||||
btScalar w=2*t-1;
|
||||
btScalar a=(SIMD_PI+2*i*SIMD_PI)/n;
|
||||
btScalar s=btSqrt(1-w*w);
|
||||
*x++=btVector3(s*btCos(a),s*btSin(a),w);
|
||||
btScalar p=0.5,t=0;
|
||||
for(int j=i;j;p*=0.5,j>>=1) if(j&1) t+=p;
|
||||
btScalar w=2*t-1;
|
||||
btScalar a=(SIMD_PI+2*i*SIMD_PI)/n;
|
||||
btScalar s=btSqrt(1-w*w);
|
||||
*x++=btVector3(s*btCos(a),s*btSin(a),w);
|
||||
}
|
||||
}
|
||||
};
|
||||
btAlignedObjectArray<btVector3> vtx;
|
||||
vtx.resize(3+res);
|
||||
Hammersley::Generate(&vtx[0],vtx.size());
|
||||
for(int i=0;i<vtx.size();++i)
|
||||
btAlignedObjectArray<btVector3> vtx;
|
||||
vtx.resize(3+res);
|
||||
Hammersley::Generate(&vtx[0],vtx.size());
|
||||
for(int i=0;i<vtx.size();++i)
|
||||
{
|
||||
vtx[i]=vtx[i]*radius+center;
|
||||
vtx[i]=vtx[i]*radius+center;
|
||||
}
|
||||
return(CreateFromConvexHull(isoftbody,&vtx[0],vtx.size()));
|
||||
return(CreateFromConvexHull(worldInfo,&vtx[0],vtx.size()));
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
btSoftBody* CreateFromTriMesh( btSoftBody::ISoftBody* isoftbody,
|
||||
const btScalar* vertices,
|
||||
const int* triangles,
|
||||
int ntriangles)
|
||||
btSoftBody* btSoftBodyHelpers::CreateFromTriMesh(btSoftBody::btSoftBodyWorldInfo& worldInfo,const btScalar* vertices,
|
||||
const int* triangles,
|
||||
int ntriangles)
|
||||
{
|
||||
int maxidx=0;
|
||||
for(int i=0,ni=ntriangles*3;i<ni;++i)
|
||||
int maxidx=0;
|
||||
for(int i=0,ni=ntriangles*3;i<ni;++i)
|
||||
{
|
||||
maxidx=btMax(triangles[i],maxidx);
|
||||
maxidx=btMax(triangles[i],maxidx);
|
||||
}
|
||||
++maxidx;
|
||||
btAlignedObjectArray<bool> chks;
|
||||
btAlignedObjectArray<btVector3> vtx;
|
||||
chks.resize(maxidx*maxidx,false);
|
||||
vtx.resize(maxidx);
|
||||
for(int i=0,j=0,ni=maxidx*3;i<ni;++j,i+=3)
|
||||
++maxidx;
|
||||
btAlignedObjectArray<bool> chks;
|
||||
btAlignedObjectArray<btVector3> vtx;
|
||||
chks.resize(maxidx*maxidx,false);
|
||||
vtx.resize(maxidx);
|
||||
for(int i=0,j=0,ni=maxidx*3;i<ni;++j,i+=3)
|
||||
{
|
||||
vtx[j]=btVector3(vertices[i],vertices[i+1],vertices[i+2]);
|
||||
vtx[j]=btVector3(vertices[i],vertices[i+1],vertices[i+2]);
|
||||
}
|
||||
btSoftBody* psb=btSoftBody::Create(isoftbody,vtx.size(),&vtx[0],0);
|
||||
for(int i=0,ni=ntriangles*3;i<ni;i+=3)
|
||||
btSoftBody* psb=new btSoftBody(worldInfo,vtx.size(),&vtx[0],0);
|
||||
for(int i=0,ni=ntriangles*3;i<ni;i+=3)
|
||||
{
|
||||
const int idx[]={triangles[i],triangles[i+1],triangles[i+2]};
|
||||
#define IDX(_x_,_y_) ((_y_)*maxidx+(_x_))
|
||||
for(int j=2,k=0;k<3;j=k++)
|
||||
const int idx[]={triangles[i],triangles[i+1],triangles[i+2]};
|
||||
#define IDX(_x_,_y_) ((_y_)*maxidx+(_x_))
|
||||
for(int j=2,k=0;k<3;j=k++)
|
||||
{
|
||||
if(!chks[IDX(idx[j],idx[k])])
|
||||
if(!chks[IDX(idx[j],idx[k])])
|
||||
{
|
||||
chks[IDX(idx[j],idx[k])]=true;
|
||||
chks[IDX(idx[k],idx[k])]=true;
|
||||
psb->AppendLink(idx[j],idx[k],1,btSoftBody::eLType::Structural);
|
||||
chks[IDX(idx[j],idx[k])]=true;
|
||||
chks[IDX(idx[k],idx[k])]=true;
|
||||
psb->AppendLink(idx[j],idx[k],1,btSoftBody::eLType::Structural);
|
||||
}
|
||||
}
|
||||
#undef IDX
|
||||
psb->AppendFace(idx[0],idx[1],idx[2]);
|
||||
#undef IDX
|
||||
psb->AppendFace(idx[0],idx[1],idx[2]);
|
||||
}
|
||||
psb->RandomizeConstraints();
|
||||
return(psb);
|
||||
psb->RandomizeConstraints();
|
||||
return(psb);
|
||||
}
|
||||
|
||||
90
src/BulletDynamics/SoftBody/btSoftBodyHelpers.h
Normal file
90
src/BulletDynamics/SoftBody/btSoftBodyHelpers.h
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2008 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SOFT_BODY_HELPERS_H
|
||||
#define SOFT_BODY_HELPERS_H
|
||||
|
||||
#include "btSoftBody.h"
|
||||
|
||||
//
|
||||
// Helpers
|
||||
//
|
||||
|
||||
/* fDrawFlags */
|
||||
struct fDrawFlags { enum _ {
|
||||
Nodes = 0x0001,
|
||||
SLinks = 0x0002,
|
||||
BLinks = 0x0004,
|
||||
Faces = 0x0008,
|
||||
Tetras = 0x0010,
|
||||
Normals = 0x0020,
|
||||
Contacts = 0x0040,
|
||||
Anchors = 0x0080,
|
||||
/* presets */
|
||||
Links = SLinks+BLinks,
|
||||
Std = SLinks+Faces+Anchors,
|
||||
StdTetra = Std-Faces+Tetras,
|
||||
};};
|
||||
|
||||
struct btSoftBodyHelpers
|
||||
{
|
||||
|
||||
static btVector3 stresscolor(btScalar stress);
|
||||
|
||||
static void drawVertex( btIDebugDraw* idraw,
|
||||
const btVector3& x,btScalar s,const btVector3& c);
|
||||
|
||||
|
||||
/* Draw body */
|
||||
static void Draw( btSoftBody* psb,
|
||||
btIDebugDraw* idraw,
|
||||
int drawflags=fDrawFlags::Std);
|
||||
/* Draw body infos */
|
||||
static void DrawInfos( btSoftBody* psb,
|
||||
btIDebugDraw* idraw,
|
||||
bool masses,
|
||||
bool areas,
|
||||
bool stress);
|
||||
/* Draw rigid frame */
|
||||
static void DrawFrame( btSoftBody* psb,
|
||||
btIDebugDraw* idraw);
|
||||
/* Create a rope */
|
||||
static btSoftBody* CreateRope( btSoftBody::btSoftBodyWorldInfo& worldInfo,const btVector3& from,
|
||||
const btVector3& to,
|
||||
int res,
|
||||
int fixeds);
|
||||
/* Create a patch */
|
||||
static btSoftBody* CreatePatch( btSoftBody::btSoftBodyWorldInfo& worldInfo,const btVector3& corner00,
|
||||
const btVector3& corner10,
|
||||
const btVector3& corner01,
|
||||
const btVector3& corner11,
|
||||
int resx,
|
||||
int resy,
|
||||
int fixeds,
|
||||
bool gendiags);
|
||||
/* Create an ellipsoid */
|
||||
static btSoftBody* CreateEllipsoid(btSoftBody::btSoftBodyWorldInfo& worldInfo,const btVector3& center,
|
||||
const btVector3& radius,
|
||||
int res);
|
||||
/* Create from convex-hull */
|
||||
static btSoftBody* CreateFromConvexHull( btSoftBody::btSoftBodyWorldInfo& worldInfo, const btVector3* vertices,
|
||||
int nvertices);
|
||||
/* Create from trimesh */
|
||||
static btSoftBody* CreateFromTriMesh( btSoftBody::btSoftBodyWorldInfo& worldInfo, const btScalar* vertices,
|
||||
const int* triangles,
|
||||
int ntriangles);
|
||||
};
|
||||
|
||||
#endif //SOFT_BODY_HELPERS_H
|
||||
Reference in New Issue
Block a user