move the SoftBody work into its own library, BulletSoftBody (work in progress)
This commit is contained in:
@@ -46,18 +46,4 @@ ADD_LIBRARY(LibBulletDynamics
|
||||
Vehicle/btRaycastVehicle.h
|
||||
Vehicle/btWheelInfo.cpp
|
||||
Vehicle/btWheelInfo.h
|
||||
SoftBody/btSoftBody.cpp
|
||||
SoftBody/btSoftBody.h
|
||||
SoftBody/btSoftBodyHelpers.cpp
|
||||
SoftBody/btSparseSDF.h
|
||||
SoftBody/btDbvt.cpp
|
||||
SoftBody/btDbvt.h
|
||||
SoftBody/btSoftBodyHelpers.h
|
||||
SoftBody/btSoftBodyRigidBodyCollisionConfiguration.cpp
|
||||
SoftBody/btSoftRigidCollisionAlgorithm.cpp
|
||||
SoftBody/btSoftRigidCollisionAlgorithm.h
|
||||
SoftBody/btSoftSoftCollisionAlgorithm.cpp
|
||||
SoftBody/btSoftSoftCollisionAlgorithm.h
|
||||
SoftBody/btSoftRigidDynamicsWorld.h
|
||||
SoftBody/btSoftRigidDynamicsWorld.cpp
|
||||
)
|
||||
|
||||
@@ -3,7 +3,6 @@ SubDir TOP src BulletDynamics ;
|
||||
Description bulletdynamics : "Bullet Rigidbody Dynamics" ;
|
||||
Library bulletdynamics :
|
||||
[ Wildcard ConstraintSolver : *.h *.cpp ]
|
||||
[ Wildcard SoftBody : *.h *.cpp ]
|
||||
[ Wildcard Dynamics : *.h *.cpp ]
|
||||
[ Wildcard Vehicle : *.h *.cpp ]
|
||||
;
|
||||
|
||||
@@ -1,532 +0,0 @@
|
||||
#include "btDbvt.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
namespace btdbvt_internals
|
||||
{
|
||||
|
||||
//
|
||||
typedef btAlignedObjectArray<btDbvt::Node*> tNodeArray;
|
||||
|
||||
//
|
||||
static inline int indexof(const btDbvt::Node* node)
|
||||
{
|
||||
return(node->parent->childs[1]==node);
|
||||
}
|
||||
|
||||
//
|
||||
static inline btDbvt::Aabb merge( const btDbvt::Aabb& a,
|
||||
const btDbvt::Aabb& b)
|
||||
{
|
||||
btDbvt::Aabb res;
|
||||
Merge(a,b,res);
|
||||
return(res);
|
||||
}
|
||||
|
||||
|
||||
// volume+edge lengths
|
||||
static inline btScalar size(const btDbvt::Aabb& a)
|
||||
{
|
||||
const btVector3 edges=a.Lengths();
|
||||
return( edges.x()*edges.y()*edges.z()+
|
||||
edges.x()+edges.y()+edges.z());
|
||||
}
|
||||
|
||||
//
|
||||
static inline void deletenode( btDbvt* pdbvt,
|
||||
btDbvt::Node* node)
|
||||
{
|
||||
delete pdbvt->m_free;
|
||||
pdbvt->m_free=node;
|
||||
}
|
||||
|
||||
//
|
||||
static inline void recursedeletenode( btDbvt* pdbvt,
|
||||
btDbvt::Node* node)
|
||||
{
|
||||
if(!node->isleaf())
|
||||
{
|
||||
recursedeletenode(pdbvt,node->childs[0]);
|
||||
recursedeletenode(pdbvt,node->childs[1]);
|
||||
}
|
||||
if(node==pdbvt->m_root) pdbvt->m_root=0;
|
||||
deletenode(pdbvt,node);
|
||||
}
|
||||
|
||||
//
|
||||
static inline btDbvt::Node* createnode( btDbvt* pdbvt,
|
||||
btDbvt::Node* parent,
|
||||
const btDbvt::Aabb& box,
|
||||
void* data)
|
||||
{
|
||||
btDbvt::Node* node;
|
||||
if(pdbvt->m_free)
|
||||
{ node=pdbvt->m_free;pdbvt->m_free=0; }
|
||||
else
|
||||
{ node=new btDbvt::Node(); }
|
||||
node->parent = parent;
|
||||
node->box = box;
|
||||
node->data = data;
|
||||
node->childs[1] = 0;
|
||||
return(node);
|
||||
}
|
||||
|
||||
//
|
||||
static inline void insertleaf( btDbvt* pdbvt,
|
||||
btDbvt::Node* root,
|
||||
btDbvt::Node* leaf)
|
||||
{
|
||||
if(!pdbvt->m_root)
|
||||
{
|
||||
pdbvt->m_root = leaf;
|
||||
leaf->parent = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!root->isleaf())
|
||||
{
|
||||
do {
|
||||
if( Proximity(root->childs[0]->box,leaf->box)<
|
||||
Proximity(root->childs[1]->box,leaf->box))
|
||||
root=root->childs[0];
|
||||
else
|
||||
root=root->childs[1];
|
||||
} while(!root->isleaf());
|
||||
}
|
||||
btDbvt::Node* prev=root->parent;
|
||||
btDbvt::Node* node=createnode(pdbvt,prev,merge(leaf->box,root->box),0);
|
||||
if(prev)
|
||||
{
|
||||
prev->childs[indexof(root)] = node;
|
||||
node->childs[0] = root;root->parent=node;
|
||||
node->childs[1] = leaf;leaf->parent=node;
|
||||
do {
|
||||
if(prev->box.Contain(node->box))
|
||||
break;
|
||||
else
|
||||
Merge(prev->childs[0]->box,prev->childs[1]->box,prev->box);
|
||||
node=prev;
|
||||
} while(0!=(prev=node->parent));
|
||||
}
|
||||
else
|
||||
{
|
||||
node->childs[0] = root;root->parent=node;
|
||||
node->childs[1] = leaf;leaf->parent=node;
|
||||
pdbvt->m_root = node;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
static inline btDbvt::Node* removeleaf( btDbvt* pdbvt,
|
||||
btDbvt::Node* leaf)
|
||||
{
|
||||
if(leaf==pdbvt->m_root)
|
||||
{
|
||||
pdbvt->m_root=0;
|
||||
return(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
btDbvt::Node* parent=leaf->parent;
|
||||
btDbvt::Node* prev=parent->parent;
|
||||
btDbvt::Node* sibling=parent->childs[1-indexof(leaf)];
|
||||
if(prev)
|
||||
{
|
||||
prev->childs[indexof(parent)]=sibling;
|
||||
sibling->parent=prev;
|
||||
deletenode(pdbvt,parent);
|
||||
while(prev)
|
||||
{
|
||||
const btDbvt::Aabb pb=prev->box;
|
||||
Merge(prev->childs[0]->box,prev->childs[1]->box,prev->box);
|
||||
if(NotEqual(pb,prev->box))
|
||||
{
|
||||
sibling = prev;
|
||||
prev = prev->parent;
|
||||
} else break;
|
||||
}
|
||||
return(prev?prev:pdbvt->m_root);
|
||||
}
|
||||
else
|
||||
{
|
||||
pdbvt->m_root=sibling;
|
||||
sibling->parent=0;
|
||||
deletenode(pdbvt,parent);
|
||||
return(pdbvt->m_root);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
static void fetchleafs( btDbvt* pdbvt,
|
||||
btDbvt::Node* root,
|
||||
tNodeArray& leafs,
|
||||
int depth=-1)
|
||||
{
|
||||
if(root->isinternal()&&depth)
|
||||
{
|
||||
fetchleafs(pdbvt,root->childs[0],leafs,depth-1);
|
||||
fetchleafs(pdbvt,root->childs[1],leafs,depth-1);
|
||||
deletenode(pdbvt,root);
|
||||
}
|
||||
else
|
||||
{
|
||||
leafs.push_back(root);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
static int leafcount(btDbvt::Node* root)
|
||||
{
|
||||
if(root->isinternal())
|
||||
{
|
||||
return( leafcount(root->childs[0])+
|
||||
leafcount(root->childs[1]));
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
//
|
||||
static void split( const tNodeArray& leafs,
|
||||
tNodeArray& left,
|
||||
tNodeArray& right,
|
||||
const btVector3& org,
|
||||
const btVector3& axis)
|
||||
{
|
||||
left.resize(0);
|
||||
right.resize(0);
|
||||
for(int i=0,ni=leafs.size();i<ni;++i)
|
||||
{
|
||||
if(dot(axis,leafs[i]->box.Center()-org)<0)
|
||||
left.push_back(leafs[i]);
|
||||
else
|
||||
right.push_back(leafs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
static btDbvt::Aabb bounds( const tNodeArray& leafs)
|
||||
{
|
||||
btDbvt::Aabb box=leafs[0]->box;
|
||||
for(int i=1,ni=leafs.size();i<ni;++i)
|
||||
{
|
||||
box=merge(box,leafs[i]->box);
|
||||
}
|
||||
return(box);
|
||||
}
|
||||
|
||||
//
|
||||
static void bottomup( btDbvt* pdbvt,
|
||||
tNodeArray& leafs)
|
||||
{
|
||||
while(leafs.size()>1)
|
||||
{
|
||||
btScalar minsize=SIMD_INFINITY;
|
||||
int minidx[2]={-1,-1};
|
||||
for(int i=0;i<leafs.size();++i)
|
||||
{
|
||||
for(int j=i+1;j<leafs.size();++j)
|
||||
{
|
||||
const btScalar sz=size(merge(leafs[i]->box,leafs[j]->box));
|
||||
if(sz<minsize)
|
||||
{
|
||||
minsize = sz;
|
||||
minidx[0] = i;
|
||||
minidx[1] = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
btDbvt::Node* n[] = {leafs[minidx[0]],leafs[minidx[1]]};
|
||||
btDbvt::Node* p = createnode(pdbvt,0,merge(n[0]->box,n[1]->box),0);
|
||||
p->childs[0] = n[0];
|
||||
p->childs[1] = n[1];
|
||||
n[0]->parent = p;
|
||||
n[1]->parent = p;
|
||||
leafs[minidx[0]] = p;
|
||||
leafs.swap(minidx[1],leafs.size()-1);
|
||||
leafs.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
static btDbvt::Node* topdown(btDbvt* pdbvt,
|
||||
tNodeArray& leafs,
|
||||
int bu_treshold)
|
||||
{
|
||||
static const btVector3 axis[]={btVector3(1,0,0),
|
||||
btVector3(0,1,0),
|
||||
btVector3(0,0,1)};
|
||||
if(leafs.size()>1)
|
||||
{
|
||||
if(leafs.size()>bu_treshold)
|
||||
{
|
||||
const btDbvt::Aabb box=bounds(leafs);
|
||||
const btVector3 org=box.Center();
|
||||
tNodeArray sets[2];
|
||||
int bestaxis=-1;
|
||||
int bestmidp=leafs.size();
|
||||
sets[0].reserve(leafs.size());
|
||||
sets[1].reserve(leafs.size());
|
||||
for(int i=0;i<3;++i)
|
||||
{
|
||||
split(leafs,sets[0],sets[1],org,axis[i]);
|
||||
if((sets[0].size()>0)&&(sets[1].size()>0))
|
||||
{
|
||||
const int midp=abs(sets[0].size()-sets[1].size());
|
||||
if(midp<bestmidp)
|
||||
{
|
||||
bestaxis=i;
|
||||
bestmidp=midp;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(bestaxis>=0)
|
||||
{
|
||||
split(leafs,sets[0],sets[1],org,axis[bestaxis]);
|
||||
}
|
||||
else
|
||||
{
|
||||
sets[0].resize(0);
|
||||
sets[1].resize(0);
|
||||
for(int i=0,ni=leafs.size();i<ni;++i)
|
||||
{
|
||||
sets[i&1].push_back(leafs[i]);
|
||||
}
|
||||
}
|
||||
btDbvt::Node* node=createnode(pdbvt,0,box,0);
|
||||
node->childs[0]=topdown(pdbvt,sets[0],bu_treshold);
|
||||
node->childs[1]=topdown(pdbvt,sets[1],bu_treshold);
|
||||
node->childs[0]->parent=node;
|
||||
node->childs[1]->parent=node;
|
||||
return(node);
|
||||
}
|
||||
else
|
||||
{
|
||||
bottomup(pdbvt,leafs);
|
||||
return(leafs[0]);
|
||||
}
|
||||
}
|
||||
return(leafs[0]);
|
||||
}
|
||||
|
||||
//
|
||||
static inline btDbvt::Node* refit( btDbvt* pdbvt,
|
||||
btDbvt::Node* node)
|
||||
{
|
||||
btDbvt::Node* parent=node->parent;
|
||||
if(parent)
|
||||
{
|
||||
const int idx=indexof(node);
|
||||
tNodeArray leafs;
|
||||
leafs.reserve(64);
|
||||
fetchleafs(pdbvt,node,leafs,3);
|
||||
if(leafs.size()>=2)
|
||||
{
|
||||
bottomup(pdbvt,leafs);
|
||||
node=leafs[0];
|
||||
node->parent=parent;
|
||||
parent->childs[idx]=node;
|
||||
}
|
||||
}
|
||||
return(node);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
using namespace btdbvt_internals;
|
||||
|
||||
//
|
||||
// Api
|
||||
//
|
||||
|
||||
//
|
||||
btDbvt::btDbvt()
|
||||
{
|
||||
m_root = 0;
|
||||
m_free = 0;
|
||||
m_lkhd = 2;
|
||||
}
|
||||
|
||||
//
|
||||
btDbvt::~btDbvt()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
//
|
||||
void btDbvt::clear()
|
||||
{
|
||||
if(m_root) recursedeletenode(this,m_root);
|
||||
delete m_free;
|
||||
m_free=0;
|
||||
}
|
||||
|
||||
//
|
||||
int btDbvt::leafCount() const
|
||||
{
|
||||
if(m_root) return(leafcount(m_root));
|
||||
else
|
||||
return(0);
|
||||
}
|
||||
|
||||
//
|
||||
void btDbvt::optimizeBottomUp()
|
||||
{
|
||||
if(m_root)
|
||||
{
|
||||
tNodeArray leafs;
|
||||
leafs.reserve(leafCount());
|
||||
fetchleafs(this,m_root,leafs);
|
||||
bottomup(this,leafs);
|
||||
m_root=leafs[0];
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
void btDbvt::optimizeTopDown(int bu_treshold)
|
||||
{
|
||||
if(m_root)
|
||||
{
|
||||
tNodeArray leafs;
|
||||
leafs.reserve(leafCount());
|
||||
fetchleafs(this,m_root,leafs);
|
||||
m_root=topdown(this,leafs,bu_treshold);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
btDbvt::Node* btDbvt::insert(const Aabb& box,void* data)
|
||||
{
|
||||
Node* leaf=createnode(this,0,box,data);
|
||||
insertleaf(this,m_root,leaf);
|
||||
return(leaf);
|
||||
}
|
||||
|
||||
//
|
||||
void btDbvt::update(Node* leaf,const Aabb& box)
|
||||
{
|
||||
Node* root=removeleaf(this,leaf);
|
||||
if(root)
|
||||
{
|
||||
for(int i=0;(i<m_lkhd)&&root->parent;++i)
|
||||
{
|
||||
root=root->parent;
|
||||
}
|
||||
}
|
||||
leaf->box=box;
|
||||
insertleaf(this,root,leaf);
|
||||
}
|
||||
|
||||
//
|
||||
bool btDbvt::update(Node* leaf,Aabb box,const btVector3& velocity,btScalar margin)
|
||||
{
|
||||
if(leaf->box.Contain(box)) return(false);
|
||||
if(margin>0)
|
||||
box.Expand(btVector3(margin,margin,margin));
|
||||
if(velocity.length2()>0)
|
||||
box.SignedExpand(velocity);
|
||||
update(leaf,box);
|
||||
return(true);
|
||||
}
|
||||
|
||||
//
|
||||
void btDbvt::remove(Node* leaf)
|
||||
{
|
||||
removeleaf(this,leaf);
|
||||
deletenode(this,leaf);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
void btDbvt::collide(btDbvt* tree,
|
||||
ICollide* icollide) const
|
||||
{
|
||||
if(tree->m_root&&m_root)
|
||||
{
|
||||
|
||||
btAlignedObjectArray<sStkElm> stack;
|
||||
stack.reserve(128);
|
||||
stack.push_back(sStkElm(m_root,tree->m_root));
|
||||
do {
|
||||
sStkElm p=stack[stack.size()-1];
|
||||
stack.pop_back();
|
||||
if(p.a==p.b)
|
||||
{
|
||||
if(p.a->isinternal())
|
||||
{
|
||||
stack.push_back(sStkElm(p.a->childs[0],p.a->childs[0]));
|
||||
stack.push_back(sStkElm(p.a->childs[1],p.a->childs[1]));
|
||||
stack.push_back(sStkElm(p.a->childs[0],p.a->childs[1]));
|
||||
}
|
||||
}
|
||||
else if(Intersect(p.a->box,p.b->box))
|
||||
{
|
||||
if(p.a->isinternal())
|
||||
{
|
||||
if(p.b->isinternal())
|
||||
{
|
||||
stack.push_back(sStkElm(p.a->childs[0],p.b->childs[0]));
|
||||
stack.push_back(sStkElm(p.a->childs[1],p.b->childs[0]));
|
||||
stack.push_back(sStkElm(p.a->childs[0],p.b->childs[1]));
|
||||
stack.push_back(sStkElm(p.a->childs[1],p.b->childs[1]));
|
||||
}
|
||||
else
|
||||
{
|
||||
stack.push_back(sStkElm(p.a->childs[0],p.b));
|
||||
stack.push_back(sStkElm(p.a->childs[1],p.b));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(p.b->isinternal())
|
||||
{
|
||||
stack.push_back(sStkElm(p.a,p.b->childs[0]));
|
||||
stack.push_back(sStkElm(p.a,p.b->childs[1]));
|
||||
}
|
||||
else
|
||||
{
|
||||
icollide->Process(p.a,p.b);
|
||||
}
|
||||
}
|
||||
}
|
||||
} while(stack.size()>0);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
void btDbvt::collide(const Aabb& box,
|
||||
ICollide* icollide) const
|
||||
{
|
||||
if(m_root)
|
||||
{
|
||||
btAlignedObjectArray<const Node*> stack;
|
||||
stack.reserve(64);
|
||||
stack.push_back(m_root);
|
||||
do {
|
||||
const Node* n=stack[stack.size()-1];
|
||||
stack.pop_back();
|
||||
if(Intersect(n->box,box))
|
||||
{
|
||||
if(n->isinternal())
|
||||
{
|
||||
stack.push_back(n->childs[0]);
|
||||
stack.push_back(n->childs[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
icollide->Process(n);
|
||||
}
|
||||
}
|
||||
} while(stack.size()>0);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
void btDbvt::collide(const btVector3& org,
|
||||
const btVector3& dir,
|
||||
ICollide* icollide) const
|
||||
{
|
||||
/* not implemented */
|
||||
}
|
||||
@@ -1,231 +0,0 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2007 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
///btSoftBody implementation by Nathanael Presson
|
||||
|
||||
#ifndef BT_DYNAMIC_BOUNDING_VOLUME_TREE_H
|
||||
#define BT_DYNAMIC_BOUNDING_VOLUME_TREE_H
|
||||
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
#include "LinearMath/btVector3.h"
|
||||
|
||||
//
|
||||
// Dynamic bounding volume tree
|
||||
//
|
||||
struct btDbvt
|
||||
{
|
||||
// Types
|
||||
|
||||
/* Aabb */
|
||||
struct Aabb
|
||||
{
|
||||
inline btVector3 Center() const { return((mi+mx)/2); }
|
||||
inline btVector3 Extent() const { return((mx-mi)/2); }
|
||||
inline const btVector3& Mins() const { return(mi); }
|
||||
inline const btVector3& Maxs() const { return(mx); }
|
||||
inline btVector3 Lengths() const { return(mx-mi); }
|
||||
static inline Aabb FromCE(const btVector3& c,const btVector3& e);
|
||||
static inline Aabb FromCR(const btVector3& c,btScalar r);
|
||||
static inline Aabb FromMM(const btVector3& mi,const btVector3& mx);
|
||||
static inline Aabb FromPoints(const btVector3* pts,int n);
|
||||
static inline Aabb FromPoints(const btVector3** ppts,int n);
|
||||
inline void Expand(const btVector3 e);
|
||||
inline void SignedExpand(const btVector3 e);
|
||||
inline bool Contain(const Aabb& a) const;
|
||||
inline friend bool Intersect( const Aabb& a,
|
||||
const Aabb& b);
|
||||
inline friend btScalar Proximity( const Aabb& a,
|
||||
const Aabb& b);
|
||||
inline friend void Merge( const Aabb& a,
|
||||
const Aabb& b,
|
||||
Aabb& r);
|
||||
inline friend bool NotEqual( const Aabb& a,
|
||||
const Aabb& b);
|
||||
btVector3 mi,mx;
|
||||
};
|
||||
/* Node */
|
||||
struct Node
|
||||
{
|
||||
Aabb box;
|
||||
Node* parent;
|
||||
bool isleaf() const { return(childs[1]==0); }
|
||||
bool isinternal() const { return(!isleaf()); }
|
||||
union {
|
||||
Node* childs[2];
|
||||
void* data;
|
||||
};
|
||||
};
|
||||
// Interfaces
|
||||
|
||||
struct sStkElm
|
||||
{
|
||||
const Node* a;
|
||||
const Node* b;
|
||||
sStkElm(const Node* na,const Node* nb) : a(na),b(nb) {}
|
||||
};
|
||||
|
||||
/* ICollide */
|
||||
struct ICollide
|
||||
{
|
||||
virtual void Process(const Node* leaf0,const Node* leaf1) {};
|
||||
virtual void Process(const Node* leaf) {};
|
||||
};
|
||||
|
||||
// Fields
|
||||
Node* m_root;
|
||||
Node* m_free;
|
||||
int m_lkhd;
|
||||
// Methods
|
||||
btDbvt();
|
||||
~btDbvt();
|
||||
void clear();
|
||||
int leafCount() const;
|
||||
void optimizeBottomUp();
|
||||
void optimizeTopDown(int bu_treshold=128);
|
||||
Node* insert(const Aabb& box,void* data);
|
||||
void update(Node* leaf,const Aabb& box);
|
||||
bool update(Node* leaf,Aabb box,const btVector3& velocity,btScalar margin);
|
||||
void remove(Node* leaf);
|
||||
void collide(btDbvt* tree,
|
||||
ICollide* icollide) const;
|
||||
void collide(const Aabb& box,
|
||||
ICollide* icollide) const;
|
||||
void collide(const btVector3& org,
|
||||
const btVector3& dir,
|
||||
ICollide* icollide) const;
|
||||
//
|
||||
private:
|
||||
btDbvt(const btDbvt&) {}
|
||||
};
|
||||
|
||||
//
|
||||
// Inline's
|
||||
//
|
||||
|
||||
//
|
||||
inline btDbvt::Aabb btDbvt::Aabb::FromCE(const btVector3& c,const btVector3& e)
|
||||
{
|
||||
Aabb box;
|
||||
box.mi=c-e;box.mx=c+e;
|
||||
return(box);
|
||||
}
|
||||
|
||||
//
|
||||
inline btDbvt::Aabb btDbvt::Aabb::FromCR(const btVector3& c,btScalar r)
|
||||
{
|
||||
return(FromCE(c,btVector3(r,r,r)));
|
||||
}
|
||||
|
||||
//
|
||||
inline btDbvt::Aabb btDbvt::Aabb::FromMM(const btVector3& mi,const btVector3& mx)
|
||||
{
|
||||
Aabb box;
|
||||
box.mi=mi;box.mx=mx;
|
||||
return(box);
|
||||
}
|
||||
|
||||
//
|
||||
inline btDbvt::Aabb btDbvt::Aabb::FromPoints(const btVector3* pts,int n)
|
||||
{
|
||||
Aabb box;
|
||||
box.mi=box.mx=pts[0];
|
||||
for(int i=1;i<n;++i)
|
||||
{
|
||||
box.mi.setMin(pts[i]);
|
||||
box.mx.setMax(pts[i]);
|
||||
}
|
||||
return(box);
|
||||
}
|
||||
|
||||
//
|
||||
inline btDbvt::Aabb btDbvt::Aabb::FromPoints(const btVector3** ppts,int n)
|
||||
{
|
||||
Aabb box;
|
||||
box.mi=box.mx=*ppts[0];
|
||||
for(int i=1;i<n;++i)
|
||||
{
|
||||
box.mi.setMin(*ppts[i]);
|
||||
box.mx.setMax(*ppts[i]);
|
||||
}
|
||||
return(box);
|
||||
}
|
||||
|
||||
//
|
||||
inline void btDbvt::Aabb::Expand(const btVector3 e)
|
||||
{
|
||||
mi-=e;mx+=e;
|
||||
}
|
||||
|
||||
//
|
||||
inline void btDbvt::Aabb::SignedExpand(const btVector3 e)
|
||||
{
|
||||
if(e.x()>0) mx.setX(mx.x()+e.x()); else mi.setX(mi.x()+e.x());
|
||||
if(e.y()>0) mx.setY(mx.y()+e.y()); else mi.setY(mi.y()+e.y());
|
||||
if(e.z()>0) mx.setZ(mx.z()+e.z()); else mi.setZ(mi.z()+e.z());
|
||||
}
|
||||
|
||||
//
|
||||
inline bool btDbvt::Aabb::Contain(const Aabb& a) const
|
||||
{
|
||||
return( (mi.x()<=a.mi.x())&&
|
||||
(mi.y()<=a.mi.y())&&
|
||||
(mi.z()<=a.mi.z())&&
|
||||
(mx.x()>=a.mx.x())&&
|
||||
(mx.y()>=a.mx.y())&&
|
||||
(mx.z()>=a.mx.z()));
|
||||
}
|
||||
|
||||
//
|
||||
inline bool Intersect( const btDbvt::Aabb& a,
|
||||
const btDbvt::Aabb& b)
|
||||
{
|
||||
return( (a.mi.x()<=b.mx.x())&&
|
||||
(a.mi.y()<=b.mx.y())&&
|
||||
(a.mi.z()<=b.mx.z())&&
|
||||
(a.mx.x()>=b.mi.x())&&
|
||||
(a.mx.y()>=b.mi.y())&&
|
||||
(a.mx.z()>=b.mi.z()));
|
||||
}
|
||||
|
||||
//
|
||||
inline btScalar Proximity( const btDbvt::Aabb& a,
|
||||
const btDbvt::Aabb& b)
|
||||
{
|
||||
const btVector3 d=(a.mi+a.mx)-(b.mi+b.mx);
|
||||
return(btFabs(d.x())+btFabs(d.y())+btFabs(d.z()));
|
||||
}
|
||||
|
||||
//
|
||||
inline void Merge( const btDbvt::Aabb& a,
|
||||
const btDbvt::Aabb& b,
|
||||
btDbvt::Aabb& r)
|
||||
{
|
||||
r=a;
|
||||
r.mi.setMin(b.mi);
|
||||
r.mx.setMax(b.mx);
|
||||
}
|
||||
|
||||
//
|
||||
inline bool NotEqual( const btDbvt::Aabb& a,
|
||||
const btDbvt::Aabb& b)
|
||||
{
|
||||
return( (a.mi.x()!=b.mi.x())||
|
||||
(a.mi.y()!=b.mi.y())||
|
||||
(a.mi.z()!=b.mi.z())||
|
||||
(a.mx.x()!=b.mx.x())||
|
||||
(a.mx.y()!=b.mx.y())||
|
||||
(a.mx.z()!=b.mx.z()));
|
||||
}
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,366 +0,0 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
///btSoftBody implementation by Nathanael Presson
|
||||
|
||||
#ifndef _BT_SOFT_BODY_H
|
||||
#define _BT_SOFT_BODY_H
|
||||
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
#include "LinearMath/btPoint3.h"
|
||||
#include "LinearMath/btTransform.h"
|
||||
#include "LinearMath/btIDebugDraw.h"
|
||||
#include "BulletDynamics/Dynamics/btRigidBody.h"
|
||||
|
||||
#include "BulletCollision/CollisionShapes/btConcaveShape.h"
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
|
||||
#include "BulletDynamics/SoftBody/btSparseSDF.h"
|
||||
#include "BulletDynamics/SoftBody/btDbvt.h"
|
||||
|
||||
class btBroadphaseInterface;
|
||||
class btCollisionDispatcher;
|
||||
|
||||
/// btSoftBody is work-in-progress
|
||||
class btSoftBody : public btCollisionObject
|
||||
{
|
||||
public:
|
||||
//
|
||||
// Enumerations
|
||||
//
|
||||
|
||||
///eLType
|
||||
struct eLType { enum _ {
|
||||
Structural, ///Master constraints
|
||||
Bending, ///Secondary constraints
|
||||
};};
|
||||
|
||||
///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
|
||||
};};
|
||||
|
||||
//
|
||||
// Flags
|
||||
//
|
||||
|
||||
///fCollision
|
||||
struct fCollision { enum _ {
|
||||
RVSmask = 0x000f, ///Rigid versus soft mask
|
||||
SDF_RS = 0x0001, ///SDF base rigid vs soft
|
||||
|
||||
SVSmask = 0x00f0, ///Rigid versus soft mask
|
||||
VF_SS = 0x0010, ///Vertex vs face soft vs soft handling
|
||||
/* presets */
|
||||
Default = SDF_RS,
|
||||
};};
|
||||
|
||||
//
|
||||
// Internal types
|
||||
//
|
||||
|
||||
typedef btAlignedObjectArray<btScalar> tScalarArray;
|
||||
typedef btAlignedObjectArray<btVector3> tVector3Array;
|
||||
|
||||
/* btSoftBodyWorldInfo */
|
||||
struct btSoftBodyWorldInfo
|
||||
{
|
||||
btScalar air_density;
|
||||
btScalar water_density;
|
||||
btScalar water_offset;
|
||||
btVector3 water_normal;
|
||||
btBroadphaseInterface* m_broadphase;
|
||||
btCollisionDispatcher* m_dispatcher;
|
||||
btVector3 m_gravity;
|
||||
btSparseSdf<3> m_sparsesdf;
|
||||
};
|
||||
|
||||
/* sCti is Softbody contact info */
|
||||
struct sCti
|
||||
{
|
||||
btRigidBody* m_body; /* Rigid body */
|
||||
btVector3 m_normal; /* Outward normal */
|
||||
btScalar m_offset; /* Offset from origin */
|
||||
};
|
||||
|
||||
/* sMedium */
|
||||
struct sMedium
|
||||
{
|
||||
btVector3 m_velocity; /* Velocity */
|
||||
btScalar m_pressure; /* Pressure */
|
||||
btScalar m_density; /* Density */
|
||||
};
|
||||
|
||||
/* Base type */
|
||||
struct Element
|
||||
{
|
||||
void* m_tag; // User data
|
||||
};
|
||||
/* Node */
|
||||
struct Node : Element
|
||||
{
|
||||
btVector3 m_x; // Position
|
||||
btVector3 m_q; // Previous step position
|
||||
btVector3 m_v; // Velocity
|
||||
btVector3 m_f; // Force accumulator
|
||||
btVector3 m_n; // Normal
|
||||
btScalar m_im; // 1/mass
|
||||
btScalar m_area; // Area
|
||||
btDbvt::Node* m_leaf; // Leaf data
|
||||
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
|
||||
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
|
||||
btDbvt::Node* m_leaf; // Leaf data
|
||||
};
|
||||
/* RContact */
|
||||
struct RContact
|
||||
{
|
||||
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
|
||||
};
|
||||
/* SContact */
|
||||
struct SContact
|
||||
{
|
||||
Node* m_node; // Node
|
||||
Face* m_face; // Face
|
||||
btVector3 m_weights; // Weigths
|
||||
btVector3 m_normal; // Normal
|
||||
btScalar m_margin; // Margin
|
||||
btScalar m_friction; // Friction
|
||||
btScalar m_cfm[2]; // Constraint force mixing
|
||||
};
|
||||
/* 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
|
||||
tVector3Array m_pos; // Reference positions
|
||||
tScalarArray m_wgh; // Weights
|
||||
btVector3 m_com; // COM
|
||||
btMatrix3x3 m_rot; // Rotation
|
||||
btMatrix3x3 m_scl; // Scale
|
||||
btMatrix3x3 m_aqq; // Base scaling
|
||||
};
|
||||
/* Config */
|
||||
struct Config
|
||||
{
|
||||
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]
|
||||
btScalar kLF; // Lift coefficient [0,+inf]
|
||||
btScalar kPR; // Pressure coefficient [-inf,+inf]
|
||||
btScalar kVC; // Volume conversation coefficient [0,+inf]
|
||||
btScalar kDF; // Dynamic friction coefficient [0,1]
|
||||
btScalar kMT; // Pose matching coefficient [0,1]
|
||||
btScalar kSOR; // SOR(w) [1,2] default 1, never use with solver!=Accurate
|
||||
btScalar kCHR; // Rigid contacts hardness [0,1]
|
||||
btScalar kSHR; // Soft contacts hardness [0,1]
|
||||
btScalar kAHR; // Anchors hardness [0,1]
|
||||
btScalar maxvolume; // Maximum volume ratio for pose
|
||||
btScalar timescale; // Time scale
|
||||
int iterations; // Solver iterations
|
||||
int collisions; // Collisions flags
|
||||
};
|
||||
/* SolverState */
|
||||
struct SolverState
|
||||
{
|
||||
btScalar iit; // 1/iterations
|
||||
btScalar sdt; // dt*timescale
|
||||
btScalar isdt; // 1/sdt
|
||||
btScalar velmrg; // velocity margin
|
||||
};
|
||||
|
||||
//
|
||||
// Typedef's
|
||||
//
|
||||
|
||||
typedef btAlignedObjectArray<Node> tNodeArray;
|
||||
typedef btAlignedObjectArray<Link> tLinkArray;
|
||||
typedef btAlignedObjectArray<Face> tFaceArray;
|
||||
typedef btAlignedObjectArray<Anchor> tAnchorArray;
|
||||
typedef btAlignedObjectArray<RContact> tRContactArray;
|
||||
typedef btAlignedObjectArray<SContact> tSContactArray;
|
||||
typedef btAlignedObjectArray<btSoftBody*> tSoftBodyArray;
|
||||
|
||||
//
|
||||
// Fields
|
||||
//
|
||||
|
||||
Config m_cfg; // Configuration
|
||||
SolverState m_sst; // Solver state
|
||||
Pose m_pose; // Pose
|
||||
void* m_tag; // User data
|
||||
btSoftBodyWorldInfo* m_worldInfo; //
|
||||
tAnchorArray m_anchors; // Anchors
|
||||
tRContactArray m_rcontacts; // Rigid contacts
|
||||
tSContactArray m_scontacts; // Soft contacts
|
||||
btScalar m_timeacc; // Time accumulator
|
||||
btVector3 m_bounds[2]; // Spatial bounds
|
||||
bool m_bUpdateRtCst; // Update runtime constants
|
||||
btDbvt m_ndbvt; // Nodes tree
|
||||
btDbvt m_fdbvt; // Faces tree
|
||||
|
||||
//
|
||||
// Api
|
||||
//
|
||||
|
||||
/* ctor */
|
||||
btSoftBody( btSoftBody::btSoftBodyWorldInfo* worldInfo,int node_count,
|
||||
const btVector3* x,
|
||||
const btScalar* m);
|
||||
/* dtor */
|
||||
virtual ~btSoftBody();
|
||||
/* Check for existing link */
|
||||
bool checkLink( int node0,
|
||||
int node1) const;
|
||||
bool checkLink( const btSoftBody::Node* node0,
|
||||
const btSoftBody::Node* node1) const;
|
||||
/* Check for existring face */
|
||||
bool checkFace( int node0,
|
||||
int node1,
|
||||
int node2) const;
|
||||
/* Append link */
|
||||
void appendLink( int node0,
|
||||
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);
|
||||
/* Append face */
|
||||
void appendFace( int node0,
|
||||
int node1,
|
||||
int node2);
|
||||
/* Append anchor */
|
||||
void appendAnchor( int node,
|
||||
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);
|
||||
/* 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);
|
||||
/* Set mass */
|
||||
void setMass( int node,
|
||||
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);
|
||||
/* Set total density */
|
||||
void setTotalDensity(btScalar density);
|
||||
/* Transform */
|
||||
void transform( const btTransform& trs);
|
||||
/* Scale */
|
||||
void scale( const btVector3& scl);
|
||||
/* Set current state as pose */
|
||||
void setPose( bool bvolume,
|
||||
bool bframe);
|
||||
/* Return the volume */
|
||||
btScalar getVolume() const;
|
||||
/* Generate bending constraints based on distance in the adjency graph */
|
||||
int generateBendingConstraints( int distance,
|
||||
btScalar stiffness);
|
||||
/* Randomize constraints to reduce solver bias */
|
||||
void randomizeConstraints();
|
||||
/* Ray casting */
|
||||
btScalar raycast(const btVector3& org,
|
||||
const btVector3& dir) const;
|
||||
/* predictMotion */
|
||||
void predictMotion(btScalar dt);
|
||||
/* solveConstraints */
|
||||
void solveConstraints();
|
||||
/* solveCommonConstraints */
|
||||
static void solveCommonConstraints(btSoftBody** bodies,int count,int iterations);
|
||||
/* integrateMotion */
|
||||
void integrateMotion();
|
||||
/* defaultCollisionHandlers */
|
||||
void defaultCollisionHandler(btCollisionObject* pco);
|
||||
void defaultCollisionHandler(btSoftBody* psb);
|
||||
|
||||
///to keep collision detection and dynamics separate we don't store a rigidbody pointer
|
||||
///but a rigidbody is derived from btCollisionObject, so we can safely perform an upcast
|
||||
static const btSoftBody* upcast(const btCollisionObject* colObj)
|
||||
{
|
||||
if (colObj->getInternalType()==CO_SOFT_BODY)
|
||||
return (const btSoftBody*)colObj;
|
||||
return 0;
|
||||
}
|
||||
static btSoftBody* upcast(btCollisionObject* colObj)
|
||||
{
|
||||
if (colObj->getInternalType()==CO_SOFT_BODY)
|
||||
return (btSoftBody*)colObj;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// ...
|
||||
//
|
||||
|
||||
tNodeArray& getNodes();
|
||||
const tNodeArray& getNodes() const;
|
||||
tLinkArray& getLinks();
|
||||
const tLinkArray& getLinks() const;
|
||||
tFaceArray& getFaces();
|
||||
const tFaceArray& getFaces() const;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif //_BT_SOFT_BODY_H
|
||||
@@ -1,485 +0,0 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
///btSoftBodyHelpers.cpp by Nathanael Presson
|
||||
|
||||
#include "btSoftBody.h"
|
||||
#include "btDbvt.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "btSoftBodyHelpers.h"
|
||||
#include "LinearMath/btConvexHull.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 void drawBox( btIDebugDraw* idraw,
|
||||
const btVector3& mins,
|
||||
const btVector3& maxs,
|
||||
const btVector3& color)
|
||||
{
|
||||
const btVector3 c[]={ btVector3(mins.x(),mins.y(),mins.z()),
|
||||
btVector3(maxs.x(),mins.y(),mins.z()),
|
||||
btVector3(maxs.x(),maxs.y(),mins.z()),
|
||||
btVector3(mins.x(),maxs.y(),mins.z()),
|
||||
btVector3(mins.x(),mins.y(),maxs.z()),
|
||||
btVector3(maxs.x(),mins.y(),maxs.z()),
|
||||
btVector3(maxs.x(),maxs.y(),maxs.z()),
|
||||
btVector3(mins.x(),maxs.y(),maxs.z())};
|
||||
idraw->drawLine(c[0],c[1],color);idraw->drawLine(c[1],c[2],color);
|
||||
idraw->drawLine(c[2],c[3],color);idraw->drawLine(c[3],c[0],color);
|
||||
idraw->drawLine(c[4],c[5],color);idraw->drawLine(c[5],c[6],color);
|
||||
idraw->drawLine(c[6],c[7],color);idraw->drawLine(c[7],c[4],color);
|
||||
idraw->drawLine(c[0],c[4],color);idraw->drawLine(c[1],c[5],color);
|
||||
idraw->drawLine(c[2],c[6],color);idraw->drawLine(c[3],c[7],color);
|
||||
}
|
||||
|
||||
//
|
||||
static void drawTree( btIDebugDraw* idraw,
|
||||
const btDbvt::Node* node,
|
||||
int depth,
|
||||
const btVector3& ncolor,
|
||||
const btVector3& lcolor,
|
||||
int mindepth,
|
||||
int maxdepth)
|
||||
{
|
||||
if(node)
|
||||
{
|
||||
if(node->isinternal()&&((depth<maxdepth)||(maxdepth<0)))
|
||||
{
|
||||
drawTree(idraw,node->childs[0],depth+1,ncolor,lcolor,mindepth,maxdepth);
|
||||
drawTree(idraw,node->childs[1],depth+1,ncolor,lcolor,mindepth,maxdepth);
|
||||
}
|
||||
if(depth>=mindepth)
|
||||
{
|
||||
const btScalar scl=(btScalar)(node->isinternal()?1:1);
|
||||
const btVector3 mi=node->box.Center()-node->box.Extent()*scl;
|
||||
const btVector3 mx=node->box.Center()+node->box.Extent()*scl;
|
||||
drawBox(idraw,mi,mx,node->isleaf()?lcolor:ncolor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
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);
|
||||
}
|
||||
|
||||
//
|
||||
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->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))
|
||||
{
|
||||
for(int i=0;i<psb->getLinks().size();++i)
|
||||
{
|
||||
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;
|
||||
case btSoftBody::eLType::Bending:
|
||||
if(0!=(drawflags&fDrawFlags::BLinks)) idraw->drawLine(l.m_n[0]->m_x,l.m_n[1]->m_x,bcolor);break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Normals */
|
||||
if(0!=(drawflags&fDrawFlags::Normals))
|
||||
{
|
||||
for(int i=0;i<psb->getNodes().size();++i)
|
||||
{
|
||||
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))
|
||||
{
|
||||
static const btVector3 axis[]={btVector3(1,0,0),
|
||||
btVector3(0,1,0),
|
||||
btVector3(0,0,1)};
|
||||
for(int i=0;i<psb->m_rcontacts.size();++i)
|
||||
{
|
||||
const btSoftBody::RContact& c=psb->m_rcontacts[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))
|
||||
{
|
||||
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));
|
||||
}
|
||||
for(int i=0;i<psb->getNodes().size();++i)
|
||||
{
|
||||
const btSoftBody::Node& n=psb->getNodes()[i];
|
||||
if(n.m_im<=0)
|
||||
{
|
||||
drawVertex(idraw,n.m_x,0.25,btVector3(1,0,0));
|
||||
}
|
||||
}
|
||||
}
|
||||
/* 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->getFaces().size();++i)
|
||||
{
|
||||
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 btSoftBodyHelpers::DrawInfos( btSoftBody* psb,
|
||||
btIDebugDraw* idraw,
|
||||
bool masses,
|
||||
bool areas,
|
||||
bool stress)
|
||||
{
|
||||
for(int i=0;i<psb->getNodes().size();++i)
|
||||
{
|
||||
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);
|
||||
}
|
||||
if(areas)
|
||||
{
|
||||
sprintf(buff," A(%.2f)",n.m_area);
|
||||
strcat(text,buff);
|
||||
}
|
||||
if(text[0]) idraw->draw3dText(n.m_x,text);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
void btSoftBodyHelpers::DrawNodeTree( btSoftBody* psb,
|
||||
btIDebugDraw* idraw,
|
||||
int mindepth,
|
||||
int maxdepth)
|
||||
{
|
||||
drawTree(idraw,psb->m_ndbvt.m_root,0,btVector3(1,0,1),btVector3(1,1,1),mindepth,maxdepth);
|
||||
}
|
||||
|
||||
//
|
||||
void btSoftBodyHelpers::DrawFaceTree( btSoftBody* psb,
|
||||
btIDebugDraw* idraw,
|
||||
int mindepth,
|
||||
int maxdepth)
|
||||
{
|
||||
drawTree(idraw,psb->m_fdbvt.m_root,0,btVector3(0,1,0),btVector3(1,0,0),mindepth,maxdepth);
|
||||
}
|
||||
|
||||
//
|
||||
void btSoftBodyHelpers::DrawFrame( btSoftBody* psb,
|
||||
btIDebugDraw* idraw)
|
||||
{
|
||||
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_rot*psb->m_pose.m_scl;
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
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)
|
||||
{
|
||||
const btScalar t=i/(btScalar)(r-1);
|
||||
x[i]=lerp(from,to,t);
|
||||
m[i]=1;
|
||||
}
|
||||
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);
|
||||
}
|
||||
/* Finished */
|
||||
return(psb);
|
||||
}
|
||||
|
||||
//
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
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->appendLink(IDX(ix+1,iy),IDX(ix,iy+1),
|
||||
1,btSoftBody::eLType::Structural);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Finished */
|
||||
#undef IDX
|
||||
return(psb);
|
||||
}
|
||||
|
||||
//
|
||||
btSoftBody* btSoftBodyHelpers::CreateEllipsoid(btSoftBody::btSoftBodyWorldInfo& worldInfo,const btVector3& center,
|
||||
const btVector3& radius,
|
||||
int res)
|
||||
{
|
||||
struct Hammersley
|
||||
{
|
||||
static void Generate(btVector3* x,int n)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
};
|
||||
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;
|
||||
}
|
||||
return(CreateFromConvexHull(worldInfo,&vtx[0],vtx.size()));
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
vtx[j]=btVector3(vertices[i],vertices[i+1],vertices[i+2]);
|
||||
}
|
||||
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++)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
#undef IDX
|
||||
psb->appendFace(idx[0],idx[1],idx[2]);
|
||||
}
|
||||
psb->randomizeConstraints();
|
||||
return(psb);
|
||||
}
|
||||
|
||||
//
|
||||
btSoftBody* btSoftBodyHelpers::CreateFromConvexHull(btSoftBody::btSoftBodyWorldInfo& worldInfo, const btVector3* vertices,
|
||||
int nvertices)
|
||||
{
|
||||
HullDesc hdsc(QF_TRIANGLES,nvertices,vertices);
|
||||
HullResult hres;
|
||||
HullLibrary hlib;/*??*/
|
||||
hdsc.mMaxVertices=nvertices;
|
||||
hlib.CreateConvexHull(hdsc,hres);
|
||||
btSoftBody* psb=new btSoftBody(&worldInfo,(int)hres.mNumOutputVertices,
|
||||
&hres.m_OutputVertices[0],0);
|
||||
for(int i=0;i<(int)hres.mNumFaces;++i)
|
||||
{
|
||||
const int idx[]={ hres.m_Indices[i*3+0],
|
||||
hres.m_Indices[i*3+1],
|
||||
hres.m_Indices[i*3+2]};
|
||||
if(idx[0]<idx[1]) psb->appendLink( idx[0],idx[1],
|
||||
1,btSoftBody::eLType::Structural);
|
||||
if(idx[1]<idx[2]) psb->appendLink( idx[1],idx[2],
|
||||
1,btSoftBody::eLType::Structural);
|
||||
if(idx[2]<idx[0]) psb->appendLink( idx[2],idx[0],
|
||||
1,btSoftBody::eLType::Structural);
|
||||
psb->appendFace(idx[0],idx[1],idx[2]);
|
||||
}
|
||||
hlib.ReleaseResult(hres);
|
||||
psb->randomizeConstraints();
|
||||
return(psb);
|
||||
}
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
/*
|
||||
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
|
||||
{
|
||||
/* 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 node tree */
|
||||
static void DrawNodeTree( btSoftBody* psb,
|
||||
btIDebugDraw* idraw,
|
||||
int mindepth=0,
|
||||
int maxdepth=-1);
|
||||
/* Draw face tree */
|
||||
static void DrawFaceTree( btSoftBody* psb,
|
||||
btIDebugDraw* idraw,
|
||||
int mindepth=0,
|
||||
int maxdepth=-1);
|
||||
/* 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
|
||||
@@ -1,77 +0,0 @@
|
||||
/*
|
||||
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);
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
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
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
/*
|
||||
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;
|
||||
|
||||
softBody->defaultCollisionHandler(rigidCollisionObject);
|
||||
|
||||
|
||||
}
|
||||
|
||||
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.);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
/*
|
||||
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"
|
||||
class 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
|
||||
|
||||
|
||||
@@ -1,132 +0,0 @@
|
||||
/*
|
||||
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 "btSoftRigidDynamicsWorld.h"
|
||||
#include "LinearMath/btQuickprof.h"
|
||||
|
||||
//softbody & helpers
|
||||
#include "BulletDynamics/SoftBody/btSoftBody.h"
|
||||
#include "BulletDynamics/SoftBody/btSoftBodyHelpers.h"
|
||||
|
||||
btSoftRigidDynamicsWorld::btSoftRigidDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration)
|
||||
:btDiscreteDynamicsWorld(dispatcher,pairCache,constraintSolver,collisionConfiguration)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
btSoftRigidDynamicsWorld::~btSoftRigidDynamicsWorld()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void btSoftRigidDynamicsWorld::predictUnconstraintMotion(btScalar timeStep)
|
||||
{
|
||||
btDiscreteDynamicsWorld::predictUnconstraintMotion( timeStep);
|
||||
|
||||
for ( int i=0;i<m_softBodies.size();++i)
|
||||
{
|
||||
btSoftBody* psb= m_softBodies[i];
|
||||
|
||||
psb->predictMotion(timeStep);
|
||||
}
|
||||
}
|
||||
|
||||
void btSoftRigidDynamicsWorld::internalSingleStepSimulation( btScalar timeStep)
|
||||
{
|
||||
|
||||
btDiscreteDynamicsWorld::internalSingleStepSimulation( timeStep );
|
||||
|
||||
///solve soft bodies constraints
|
||||
solveSoftBodiesConstraints();
|
||||
|
||||
///update soft bodies
|
||||
updateSoftBodies();
|
||||
|
||||
}
|
||||
|
||||
void btSoftRigidDynamicsWorld::updateSoftBodies()
|
||||
{
|
||||
BT_PROFILE("updateSoftBodies");
|
||||
|
||||
for ( int i=0;i<m_softBodies.size();i++)
|
||||
{
|
||||
btSoftBody* psb=(btSoftBody*)m_softBodies[i];
|
||||
psb->integrateMotion();
|
||||
}
|
||||
}
|
||||
|
||||
void btSoftRigidDynamicsWorld::solveSoftBodiesConstraints()
|
||||
{
|
||||
BT_PROFILE("solveSoftConstraints");
|
||||
|
||||
for(int i=0;i<m_softBodies.size();++i)
|
||||
{
|
||||
btSoftBody* psb=(btSoftBody*)m_softBodies[i];
|
||||
psb->solveConstraints();
|
||||
}
|
||||
}
|
||||
|
||||
void btSoftRigidDynamicsWorld::addSoftBody(btSoftBody* body)
|
||||
{
|
||||
m_softBodies.push_back(body);
|
||||
|
||||
btCollisionWorld::addCollisionObject(body,
|
||||
btBroadphaseProxy::DefaultFilter,
|
||||
btBroadphaseProxy::AllFilter);
|
||||
|
||||
}
|
||||
|
||||
void btSoftRigidDynamicsWorld::removeSoftBody(btSoftBody* body)
|
||||
{
|
||||
m_softBodies.remove(body);
|
||||
|
||||
btCollisionWorld::removeCollisionObject(body);
|
||||
}
|
||||
|
||||
void btSoftRigidDynamicsWorld::debugDrawWorld()
|
||||
{
|
||||
btDiscreteDynamicsWorld::debugDrawWorld();
|
||||
|
||||
if (getDebugDrawer() && getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe | btIDebugDraw::DBG_DrawAabb))
|
||||
{
|
||||
int i;
|
||||
for ( i=0;i<this->m_softBodies.size();i++)
|
||||
{
|
||||
btSoftBody* psb=(btSoftBody*)this->m_softBodies[i];
|
||||
btSoftBodyHelpers::DrawFrame(psb,m_debugDrawer);
|
||||
btSoftBodyHelpers::Draw(psb,m_debugDrawer,fDrawFlags::Std+fDrawFlags::Nodes);
|
||||
if (m_debugDrawer && (m_debugDrawer->getDebugMode() & btIDebugDraw::DBG_DrawAabb))
|
||||
{
|
||||
btSoftBodyHelpers::DrawNodeTree(psb,m_debugDrawer);
|
||||
//btSoftBodyHelpers::DrawFaceTree(psb,m_debugDrawer);
|
||||
}
|
||||
}
|
||||
|
||||
if (getDebugDrawer())
|
||||
{
|
||||
for (int i=0;i<this->m_softBodies.size();i++)
|
||||
{
|
||||
btSoftBody* psb=(btSoftBody*)this->m_softBodies[i];
|
||||
btSoftBodyHelpers::DrawFrame(psb,m_debugDrawer);
|
||||
btSoftBodyHelpers::Draw(psb,m_debugDrawer,fDrawFlags::Std);
|
||||
if (m_debugDrawer && (m_debugDrawer->getDebugMode() & btIDebugDraw::DBG_DrawAabb))
|
||||
{
|
||||
btSoftBodyHelpers::DrawNodeTree(psb,m_debugDrawer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
/*
|
||||
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 "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h"
|
||||
|
||||
#ifndef BT_SOFT_RIGID_DYNAMICS_WORLD_H
|
||||
#define BT_SOFT_RIGID_DYNAMICS_WORLD_H
|
||||
|
||||
class btSoftBody;
|
||||
typedef btAlignedObjectArray<btSoftBody*> btSoftBodyArray;
|
||||
|
||||
class btSoftRigidDynamicsWorld : public btDiscreteDynamicsWorld
|
||||
{
|
||||
|
||||
btSoftBodyArray m_softBodies;
|
||||
|
||||
protected:
|
||||
|
||||
virtual void predictUnconstraintMotion(btScalar timeStep);
|
||||
|
||||
virtual void internalSingleStepSimulation( btScalar timeStep);
|
||||
|
||||
void updateSoftBodies();
|
||||
|
||||
void solveSoftBodiesConstraints();
|
||||
|
||||
virtual void debugDrawWorld();
|
||||
|
||||
public:
|
||||
|
||||
btSoftRigidDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration);
|
||||
|
||||
virtual ~btSoftRigidDynamicsWorld();
|
||||
|
||||
|
||||
void addSoftBody(btSoftBody* body);
|
||||
|
||||
void removeSoftBody(btSoftBody* body);
|
||||
|
||||
|
||||
btSoftBodyArray& getSoftBodyArray()
|
||||
{
|
||||
return m_softBodies;
|
||||
}
|
||||
|
||||
const btSoftBodyArray& getSoftBodyArray() const
|
||||
{
|
||||
return m_softBodies;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif //BT_SOFT_RIGID_DYNAMICS_WORLD_H
|
||||
@@ -1,105 +0,0 @@
|
||||
/*
|
||||
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)
|
||||
{
|
||||
|
||||
btSoftBody* soft0 = (btSoftBody*)body0;
|
||||
btSoftBody* soft1 = (btSoftBody*)body1;
|
||||
|
||||
soft0->defaultCollisionHandler(soft1);
|
||||
/*
|
||||
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;
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
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;
|
||||
class 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
|
||||
|
||||
|
||||
@@ -1,267 +0,0 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
///btSparseSdf implementation by Nathanael Presson
|
||||
|
||||
#ifndef _14F9D17F_EAE8_4aba_B41C_292DB2AA70F3_
|
||||
#define _14F9D17F_EAE8_4aba_B41C_292DB2AA70F3_
|
||||
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
|
||||
#include "BulletCollision/NarrowPhaseCollision/btGjkEpa2.h"
|
||||
|
||||
template <const int CELLSIZE>
|
||||
struct btSparseSdf
|
||||
{
|
||||
//
|
||||
// Inner types
|
||||
//
|
||||
struct IntFrac
|
||||
{
|
||||
int b;
|
||||
int i;
|
||||
btScalar f;
|
||||
};
|
||||
struct Cell
|
||||
{
|
||||
btScalar d[CELLSIZE+1][CELLSIZE+1][CELLSIZE+1];
|
||||
int c[3];
|
||||
int puid;
|
||||
unsigned hash;
|
||||
btCollisionShape* pclient;
|
||||
Cell* next;
|
||||
};
|
||||
//
|
||||
// Fields
|
||||
//
|
||||
|
||||
btAlignedObjectArray<Cell*> cells;
|
||||
btScalar voxelsz;
|
||||
int puid;
|
||||
int ncells;
|
||||
int nprobes;
|
||||
int nqueries;
|
||||
|
||||
//
|
||||
// Methods
|
||||
//
|
||||
|
||||
//
|
||||
void Initialize(int hashsize=2383)
|
||||
{
|
||||
cells.resize(hashsize,0);
|
||||
Reset();
|
||||
}
|
||||
//
|
||||
void Reset()
|
||||
{
|
||||
for(int i=0,ni=cells.size();i<ni;++i)
|
||||
{
|
||||
Cell* pc=cells[i];
|
||||
cells[i]=0;
|
||||
while(pc)
|
||||
{
|
||||
Cell* pn=pc->next;
|
||||
delete pc;
|
||||
pc=pn;
|
||||
}
|
||||
}
|
||||
voxelsz =0.25;
|
||||
puid =0;
|
||||
ncells =0;
|
||||
nprobes =1;
|
||||
nqueries =1;
|
||||
}
|
||||
//
|
||||
void GarbageCollect(int lifetime=256)
|
||||
{
|
||||
const int life=puid-lifetime;
|
||||
for(int i=0;i<cells.size();++i)
|
||||
{
|
||||
Cell*& root=cells[i];
|
||||
Cell* pp=0;
|
||||
Cell* pc=root;
|
||||
while(pc)
|
||||
{
|
||||
Cell* pn=pc->next;
|
||||
if(pc->puid<life)
|
||||
{
|
||||
if(pp) pp->next=pn; else root=pn;
|
||||
delete pc;pc=pp;--ncells;
|
||||
}
|
||||
pp=pc;pc=pn;
|
||||
}
|
||||
}
|
||||
//printf("GC[%d]: %d cells, PpQ: %f\r\n",puid,ncells,nprobes/(btScalar)nqueries);
|
||||
nqueries=1;
|
||||
nprobes=1;
|
||||
++puid; /* TODO: Reset puid's when int range limit is reached */
|
||||
/* else setup a priority list... */
|
||||
}
|
||||
//
|
||||
btScalar Evaluate( const btVector3& x,
|
||||
btCollisionShape* shape,
|
||||
btVector3& normal,
|
||||
btScalar margin)
|
||||
{
|
||||
/* Lookup cell */
|
||||
const btVector3 scx=x/voxelsz;
|
||||
const IntFrac ix=Decompose(scx.x());
|
||||
const IntFrac iy=Decompose(scx.y());
|
||||
const IntFrac iz=Decompose(scx.z());
|
||||
const unsigned h=Hash(ix.b,iy.b,iz.b,shape);
|
||||
Cell*& root=cells[h%cells.size()];
|
||||
Cell* c=root;
|
||||
++nqueries;
|
||||
while(c)
|
||||
{
|
||||
++nprobes;
|
||||
if( (c->hash==h) &&
|
||||
(c->c[0]==ix.b) &&
|
||||
(c->c[1]==iy.b) &&
|
||||
(c->c[2]==iz.b) &&
|
||||
(c->pclient==shape))
|
||||
{ break; }
|
||||
else
|
||||
{ c=c->next; }
|
||||
}
|
||||
if(!c)
|
||||
{
|
||||
++nprobes;
|
||||
++ncells;
|
||||
c=new Cell();
|
||||
c->next=root;root=c;
|
||||
c->pclient=shape;
|
||||
c->hash=h;
|
||||
c->c[0]=ix.b;c->c[1]=iy.b;c->c[2]=iz.b;
|
||||
BuildCell(*c);
|
||||
}
|
||||
c->puid=puid;
|
||||
/* Extract infos */
|
||||
const int o[]={ ix.i,iy.i,iz.i};
|
||||
const btScalar d[]={ c->d[o[0]+0][o[1]+0][o[2]+0],
|
||||
c->d[o[0]+1][o[1]+0][o[2]+0],
|
||||
c->d[o[0]+1][o[1]+1][o[2]+0],
|
||||
c->d[o[0]+0][o[1]+1][o[2]+0],
|
||||
c->d[o[0]+0][o[1]+0][o[2]+1],
|
||||
c->d[o[0]+1][o[1]+0][o[2]+1],
|
||||
c->d[o[0]+1][o[1]+1][o[2]+1],
|
||||
c->d[o[0]+0][o[1]+1][o[2]+1]};
|
||||
/* Normal */
|
||||
#if 1
|
||||
const btScalar gx[]={ d[1]-d[0],d[2]-d[3],
|
||||
d[5]-d[4],d[6]-d[7]};
|
||||
const btScalar gy[]={ d[3]-d[0],d[2]-d[1],
|
||||
d[7]-d[4],d[6]-d[5]};
|
||||
const btScalar gz[]={ d[4]-d[0],d[5]-d[1],
|
||||
d[7]-d[3],d[6]-d[2]};
|
||||
normal.setX(Lerp( Lerp(gx[0],gx[1],iy.f),
|
||||
Lerp(gx[2],gx[3],iy.f),iz.f));
|
||||
normal.setY(Lerp( Lerp(gy[0],gy[1],ix.f),
|
||||
Lerp(gy[2],gy[3],ix.f),iz.f));
|
||||
normal.setZ(Lerp( Lerp(gz[0],gz[1],ix.f),
|
||||
Lerp(gz[2],gz[3],ix.f),iy.f));
|
||||
normal = normal.normalized();
|
||||
#else
|
||||
normal = btVector3(d[1]-d[0],d[3]-d[0],d[4]-d[0]).normalized();
|
||||
#endif
|
||||
/* Distance */
|
||||
const btScalar d0=Lerp(Lerp(d[0],d[1],ix.f),
|
||||
Lerp(d[3],d[2],ix.f),iy.f);
|
||||
const btScalar d1=Lerp(Lerp(d[4],d[5],ix.f),
|
||||
Lerp(d[7],d[6],ix.f),iy.f);
|
||||
return(Lerp(d0,d1,iz.f)-margin);
|
||||
}
|
||||
//
|
||||
void BuildCell(Cell& c)
|
||||
{
|
||||
const btVector3 org=btVector3( (btScalar)c.c[0],
|
||||
(btScalar)c.c[1],
|
||||
(btScalar)c.c[2]) *
|
||||
CELLSIZE*voxelsz;
|
||||
for(int k=0;k<=CELLSIZE;++k)
|
||||
{
|
||||
const btScalar z=voxelsz*k+org.z();
|
||||
for(int j=0;j<=CELLSIZE;++j)
|
||||
{
|
||||
const btScalar y=voxelsz*j+org.y();
|
||||
for(int i=0;i<=CELLSIZE;++i)
|
||||
{
|
||||
const btScalar x=voxelsz*i+org.x();
|
||||
c.d[i][j][k]=DistanceToShape( btVector3(x,y,z),
|
||||
c.pclient);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
static inline btScalar DistanceToShape(const btVector3& x,
|
||||
btCollisionShape* shape)
|
||||
{
|
||||
btTransform unit;
|
||||
unit.setIdentity();
|
||||
if(shape->isConvex())
|
||||
{
|
||||
btGjkEpaSolver2::sResults res;
|
||||
btConvexShape* csh=static_cast<btConvexShape*>(shape);
|
||||
return(btGjkEpaSolver2::SignedDistance(x,0,csh,unit,res));
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
//
|
||||
static inline IntFrac Decompose(btScalar x)
|
||||
{
|
||||
/* That one need a lot of improvements... */
|
||||
/* Remove test, faster floor... */
|
||||
IntFrac r;
|
||||
x/=CELLSIZE;
|
||||
const int o=x<0?(int)(-x+1):0;
|
||||
x+=o;r.b=(int)x;
|
||||
const btScalar k=(x-r.b)*CELLSIZE;
|
||||
r.i=(int)k;r.f=k-r.i;r.b-=o;
|
||||
return(r);
|
||||
}
|
||||
//
|
||||
static inline btScalar Lerp(btScalar a,btScalar b,btScalar t)
|
||||
{
|
||||
return(a+(b-a)*t);
|
||||
}
|
||||
//
|
||||
static inline unsigned Hash(int x,int y,int z,btCollisionShape* shape)
|
||||
{
|
||||
struct { int x,y,z;void* p; } set;
|
||||
set.x=x;set.y=y;set.z=z;set.p=shape;
|
||||
return(HsiehHash<sizeof(set)/4>(&set));
|
||||
}
|
||||
// Modified Paul Hsieh hash
|
||||
template <const int DWORDLEN>
|
||||
static inline unsigned HsiehHash(const void* pdata)
|
||||
{
|
||||
const unsigned short* data=(const unsigned short*)pdata;
|
||||
unsigned hash=DWORDLEN<<2,tmp;
|
||||
for(int i=0;i<DWORDLEN;++i)
|
||||
{
|
||||
hash += data[0];
|
||||
tmp = (data[1]<<11)^hash;
|
||||
hash = (hash<<16)^tmp;
|
||||
data += 2;
|
||||
hash += hash>>11;
|
||||
}
|
||||
hash^=hash<<3;hash+=hash>>5;
|
||||
hash^=hash<<4;hash+=hash>>17;
|
||||
hash^=hash<<25;hash+=hash>>6;
|
||||
return(hash);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user