Code-style consistency improvement:
Apply clang-format-all.sh using the _clang-format file through all the cpp/.h files. make sure not to apply it to certain serialization structures, since some parser expects the * as part of the name, instead of type. This commit contains no other changes aside from adding and applying clang-format-all.sh
This commit is contained in:
@@ -21,11 +21,10 @@ subject to the following restrictions:
|
||||
#include "BulletCollision/CollisionShapes/btCapsuleShape.h"
|
||||
#include "BulletSoftBody/btSoftBody.h"
|
||||
|
||||
|
||||
btDefaultSoftBodySolver::btDefaultSoftBodySolver()
|
||||
{
|
||||
// Initial we will clearly need to update solver constants
|
||||
// For now this is global for the cloths linked with this solver - we should probably make this body specific
|
||||
// For now this is global for the cloths linked with this solver - we should probably make this body specific
|
||||
// for performance in future once we understand more clearly when constants need to be updated
|
||||
m_updateSolverConstants = true;
|
||||
}
|
||||
@@ -37,67 +36,65 @@ btDefaultSoftBodySolver::~btDefaultSoftBodySolver()
|
||||
// In this case the data is already in the soft bodies so there is no need for us to do anything
|
||||
void btDefaultSoftBodySolver::copyBackToSoftBodies(bool bMove)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void btDefaultSoftBodySolver::optimize( btAlignedObjectArray< btSoftBody * > &softBodies , bool forceUpdate)
|
||||
void btDefaultSoftBodySolver::optimize(btAlignedObjectArray<btSoftBody *> &softBodies, bool forceUpdate)
|
||||
{
|
||||
m_softBodySet.copyFromArray( softBodies );
|
||||
m_softBodySet.copyFromArray(softBodies);
|
||||
}
|
||||
|
||||
void btDefaultSoftBodySolver::updateSoftBodies( )
|
||||
void btDefaultSoftBodySolver::updateSoftBodies()
|
||||
{
|
||||
for ( int i=0; i < m_softBodySet.size(); i++)
|
||||
for (int i = 0; i < m_softBodySet.size(); i++)
|
||||
{
|
||||
btSoftBody* psb=(btSoftBody*)m_softBodySet[i];
|
||||
btSoftBody *psb = (btSoftBody *)m_softBodySet[i];
|
||||
if (psb->isActive())
|
||||
{
|
||||
psb->integrateMotion();
|
||||
psb->integrateMotion();
|
||||
}
|
||||
}
|
||||
} // updateSoftBodies
|
||||
} // updateSoftBodies
|
||||
|
||||
bool btDefaultSoftBodySolver::checkInitialized()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void btDefaultSoftBodySolver::solveConstraints( float solverdt )
|
||||
void btDefaultSoftBodySolver::solveConstraints(float solverdt)
|
||||
{
|
||||
// Solve constraints for non-solver softbodies
|
||||
for(int i=0; i < m_softBodySet.size(); ++i)
|
||||
for (int i = 0; i < m_softBodySet.size(); ++i)
|
||||
{
|
||||
btSoftBody* psb = static_cast<btSoftBody*>(m_softBodySet[i]);
|
||||
btSoftBody *psb = static_cast<btSoftBody *>(m_softBodySet[i]);
|
||||
if (psb->isActive())
|
||||
{
|
||||
psb->solveConstraints();
|
||||
}
|
||||
}
|
||||
} // btDefaultSoftBodySolver::solveConstraints
|
||||
}
|
||||
} // btDefaultSoftBodySolver::solveConstraints
|
||||
|
||||
|
||||
void btDefaultSoftBodySolver::copySoftBodyToVertexBuffer( const btSoftBody *const softBody, btVertexBufferDescriptor *vertexBuffer )
|
||||
void btDefaultSoftBodySolver::copySoftBodyToVertexBuffer(const btSoftBody *const softBody, btVertexBufferDescriptor *vertexBuffer)
|
||||
{
|
||||
// Currently only support CPU output buffers
|
||||
// TODO: check for DX11 buffers. Take all offsets into the same DX11 buffer
|
||||
// and use them together on a single kernel call if possible by setting up a
|
||||
// per-cloth target buffer array for the copy kernel.
|
||||
|
||||
if( vertexBuffer->getBufferType() == btVertexBufferDescriptor::CPU_BUFFER )
|
||||
if (vertexBuffer->getBufferType() == btVertexBufferDescriptor::CPU_BUFFER)
|
||||
{
|
||||
const btAlignedObjectArray<btSoftBody::Node> &clothVertices( softBody->m_nodes );
|
||||
const btAlignedObjectArray<btSoftBody::Node> &clothVertices(softBody->m_nodes);
|
||||
int numVertices = clothVertices.size();
|
||||
|
||||
const btCPUVertexBufferDescriptor *cpuVertexBuffer = static_cast< btCPUVertexBufferDescriptor* >(vertexBuffer);
|
||||
float *basePointer = cpuVertexBuffer->getBasePointer();
|
||||
const btCPUVertexBufferDescriptor *cpuVertexBuffer = static_cast<btCPUVertexBufferDescriptor *>(vertexBuffer);
|
||||
float *basePointer = cpuVertexBuffer->getBasePointer();
|
||||
|
||||
if( vertexBuffer->hasVertexPositions() )
|
||||
if (vertexBuffer->hasVertexPositions())
|
||||
{
|
||||
const int vertexOffset = cpuVertexBuffer->getVertexOffset();
|
||||
const int vertexStride = cpuVertexBuffer->getVertexStride();
|
||||
float *vertexPointer = basePointer + vertexOffset;
|
||||
|
||||
for( int vertexIndex = 0; vertexIndex < numVertices; ++vertexIndex )
|
||||
for (int vertexIndex = 0; vertexIndex < numVertices; ++vertexIndex)
|
||||
{
|
||||
btVector3 position = clothVertices[vertexIndex].m_x;
|
||||
*(vertexPointer + 0) = (float)position.getX();
|
||||
@@ -106,13 +103,13 @@ void btDefaultSoftBodySolver::copySoftBodyToVertexBuffer( const btSoftBody *cons
|
||||
vertexPointer += vertexStride;
|
||||
}
|
||||
}
|
||||
if( vertexBuffer->hasNormals() )
|
||||
if (vertexBuffer->hasNormals())
|
||||
{
|
||||
const int normalOffset = cpuVertexBuffer->getNormalOffset();
|
||||
const int normalStride = cpuVertexBuffer->getNormalStride();
|
||||
float *normalPointer = basePointer + normalOffset;
|
||||
|
||||
for( int vertexIndex = 0; vertexIndex < numVertices; ++vertexIndex )
|
||||
for (int vertexIndex = 0; vertexIndex < numVertices; ++vertexIndex)
|
||||
{
|
||||
btVector3 normal = clothVertices[vertexIndex].m_n;
|
||||
*(normalPointer + 0) = (float)normal.getX();
|
||||
@@ -122,30 +119,28 @@ void btDefaultSoftBodySolver::copySoftBodyToVertexBuffer( const btSoftBody *cons
|
||||
}
|
||||
}
|
||||
}
|
||||
} // btDefaultSoftBodySolver::copySoftBodyToVertexBuffer
|
||||
} // btDefaultSoftBodySolver::copySoftBodyToVertexBuffer
|
||||
|
||||
void btDefaultSoftBodySolver::processCollision( btSoftBody* softBody, btSoftBody* otherSoftBody)
|
||||
void btDefaultSoftBodySolver::processCollision(btSoftBody *softBody, btSoftBody *otherSoftBody)
|
||||
{
|
||||
softBody->defaultCollisionHandler( otherSoftBody);
|
||||
softBody->defaultCollisionHandler(otherSoftBody);
|
||||
}
|
||||
|
||||
// For the default solver just leave the soft body to do its collision processing
|
||||
void btDefaultSoftBodySolver::processCollision( btSoftBody *softBody, const btCollisionObjectWrapper* collisionObjectWrap )
|
||||
void btDefaultSoftBodySolver::processCollision(btSoftBody *softBody, const btCollisionObjectWrapper *collisionObjectWrap)
|
||||
{
|
||||
softBody->defaultCollisionHandler( collisionObjectWrap );
|
||||
} // btDefaultSoftBodySolver::processCollision
|
||||
softBody->defaultCollisionHandler(collisionObjectWrap);
|
||||
} // btDefaultSoftBodySolver::processCollision
|
||||
|
||||
|
||||
void btDefaultSoftBodySolver::predictMotion( float timeStep )
|
||||
void btDefaultSoftBodySolver::predictMotion(float timeStep)
|
||||
{
|
||||
for ( int i=0; i < m_softBodySet.size(); ++i)
|
||||
for (int i = 0; i < m_softBodySet.size(); ++i)
|
||||
{
|
||||
btSoftBody* psb = m_softBodySet[i];
|
||||
btSoftBody *psb = m_softBodySet[i];
|
||||
|
||||
if (psb->isActive())
|
||||
{
|
||||
psb->predictMotion(timeStep);
|
||||
psb->predictMotion(timeStep);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,25 +16,23 @@ subject to the following restrictions:
|
||||
#ifndef BT_SOFT_BODY_DEFAULT_SOLVER_H
|
||||
#define BT_SOFT_BODY_DEFAULT_SOLVER_H
|
||||
|
||||
|
||||
#include "BulletSoftBody/btSoftBodySolvers.h"
|
||||
#include "btSoftBodySolverVertexBuffer.h"
|
||||
struct btCollisionObjectWrapper;
|
||||
|
||||
class btDefaultSoftBodySolver : public btSoftBodySolver
|
||||
{
|
||||
protected:
|
||||
protected:
|
||||
/** Variable to define whether we need to update solver constants on the next iteration */
|
||||
bool m_updateSolverConstants;
|
||||
|
||||
btAlignedObjectArray< btSoftBody * > m_softBodySet;
|
||||
|
||||
btAlignedObjectArray<btSoftBody *> m_softBodySet;
|
||||
|
||||
public:
|
||||
btDefaultSoftBodySolver();
|
||||
|
||||
|
||||
virtual ~btDefaultSoftBodySolver();
|
||||
|
||||
|
||||
virtual SolverTypes getSolverType() const
|
||||
{
|
||||
return DEFAULT_SOLVER;
|
||||
@@ -42,22 +40,21 @@ public:
|
||||
|
||||
virtual bool checkInitialized();
|
||||
|
||||
virtual void updateSoftBodies( );
|
||||
virtual void updateSoftBodies();
|
||||
|
||||
virtual void optimize( btAlignedObjectArray< btSoftBody * > &softBodies,bool forceUpdate=false );
|
||||
virtual void optimize(btAlignedObjectArray<btSoftBody *> &softBodies, bool forceUpdate = false);
|
||||
|
||||
virtual void copyBackToSoftBodies(bool bMove = true);
|
||||
|
||||
virtual void solveConstraints( float solverdt );
|
||||
virtual void solveConstraints(float solverdt);
|
||||
|
||||
virtual void predictMotion( float solverdt );
|
||||
virtual void predictMotion(float solverdt);
|
||||
|
||||
virtual void copySoftBodyToVertexBuffer( const btSoftBody *const softBody, btVertexBufferDescriptor *vertexBuffer );
|
||||
virtual void copySoftBodyToVertexBuffer(const btSoftBody *const softBody, btVertexBufferDescriptor *vertexBuffer);
|
||||
|
||||
virtual void processCollision( btSoftBody *, const btCollisionObjectWrapper* );
|
||||
|
||||
virtual void processCollision( btSoftBody*, btSoftBody* );
|
||||
virtual void processCollision(btSoftBody *, const btCollisionObjectWrapper *);
|
||||
|
||||
virtual void processCollision(btSoftBody *, btSoftBody *);
|
||||
};
|
||||
|
||||
#endif // #ifndef BT_ACCELERATED_SOFT_BODY_CPU_SOLVER_H
|
||||
#endif // #ifndef BT_ACCELERATED_SOFT_BODY_CPU_SOLVER_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -13,7 +13,6 @@ subject to the following restrictions:
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
#include "btSoftBodyConcaveCollisionAlgorithm.h"
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
|
||||
#include "BulletCollision/CollisionShapes/btMultiSphereShape.h"
|
||||
@@ -27,34 +26,28 @@ subject to the following restrictions:
|
||||
#include "BulletCollision/CollisionShapes/btConvexHullShape.h"
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h"
|
||||
|
||||
|
||||
#include "LinearMath/btIDebugDraw.h"
|
||||
#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h"
|
||||
#include "BulletSoftBody/btSoftBody.h"
|
||||
|
||||
#define BT_SOFTBODY_TRIANGLE_EXTRUSION btScalar(0.06)//make this configurable
|
||||
#define BT_SOFTBODY_TRIANGLE_EXTRUSION btScalar(0.06) //make this configurable
|
||||
|
||||
btSoftBodyConcaveCollisionAlgorithm::btSoftBodyConcaveCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,bool isSwapped)
|
||||
: btCollisionAlgorithm(ci),
|
||||
m_isSwapped(isSwapped),
|
||||
m_btSoftBodyTriangleCallback(ci.m_dispatcher1,body0Wrap,body1Wrap,isSwapped)
|
||||
btSoftBodyConcaveCollisionAlgorithm::btSoftBodyConcaveCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, bool isSwapped)
|
||||
: btCollisionAlgorithm(ci),
|
||||
m_isSwapped(isSwapped),
|
||||
m_btSoftBodyTriangleCallback(ci.m_dispatcher1, body0Wrap, body1Wrap, isSwapped)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
btSoftBodyConcaveCollisionAlgorithm::~btSoftBodyConcaveCollisionAlgorithm()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
btSoftBodyTriangleCallback::btSoftBodyTriangleCallback(btDispatcher* dispatcher,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,bool isSwapped):
|
||||
m_dispatcher(dispatcher),
|
||||
m_dispatchInfoPtr(0)
|
||||
btSoftBodyTriangleCallback::btSoftBodyTriangleCallback(btDispatcher* dispatcher, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, bool isSwapped) : m_dispatcher(dispatcher),
|
||||
m_dispatchInfoPtr(0)
|
||||
{
|
||||
m_softBody = (isSwapped? (btSoftBody*)body1Wrap->getCollisionObject():(btSoftBody*)body0Wrap->getCollisionObject());
|
||||
m_triBody = isSwapped? body0Wrap->getCollisionObject():body1Wrap->getCollisionObject();
|
||||
m_softBody = (isSwapped ? (btSoftBody*)body1Wrap->getCollisionObject() : (btSoftBody*)body0Wrap->getCollisionObject());
|
||||
m_triBody = isSwapped ? body0Wrap->getCollisionObject() : body1Wrap->getCollisionObject();
|
||||
|
||||
//
|
||||
// create the manifold from the dispatcher 'manifold pool'
|
||||
@@ -68,46 +61,42 @@ btSoftBodyTriangleCallback::~btSoftBodyTriangleCallback()
|
||||
{
|
||||
clearCache();
|
||||
// m_dispatcher->releaseManifold( m_manifoldPtr );
|
||||
|
||||
}
|
||||
|
||||
|
||||
void btSoftBodyTriangleCallback::clearCache()
|
||||
void btSoftBodyTriangleCallback::clearCache()
|
||||
{
|
||||
for (int i=0;i<m_shapeCache.size();i++)
|
||||
for (int i = 0; i < m_shapeCache.size(); i++)
|
||||
{
|
||||
btTriIndex* tmp = m_shapeCache.getAtIndex(i);
|
||||
btAssert(tmp);
|
||||
btAssert(tmp->m_childShape);
|
||||
m_softBody->getWorldInfo()->m_sparsesdf.RemoveReferences(tmp->m_childShape);//necessary?
|
||||
m_softBody->getWorldInfo()->m_sparsesdf.RemoveReferences(tmp->m_childShape); //necessary?
|
||||
delete tmp->m_childShape;
|
||||
}
|
||||
m_shapeCache.clear();
|
||||
}
|
||||
|
||||
|
||||
void btSoftBodyTriangleCallback::processTriangle(btVector3* triangle,int partId, int triangleIndex)
|
||||
void btSoftBodyTriangleCallback::processTriangle(btVector3* triangle, int partId, int triangleIndex)
|
||||
{
|
||||
//just for debugging purposes
|
||||
//printf("triangle %d",m_triangleCount++);
|
||||
|
||||
|
||||
btCollisionAlgorithmConstructionInfo ci;
|
||||
ci.m_dispatcher1 = m_dispatcher;
|
||||
|
||||
///debug drawing of the overlapping triangles
|
||||
if (m_dispatchInfoPtr && m_dispatchInfoPtr->m_debugDraw && (m_dispatchInfoPtr->m_debugDraw->getDebugMode() &btIDebugDraw::DBG_DrawWireframe))
|
||||
if (m_dispatchInfoPtr && m_dispatchInfoPtr->m_debugDraw && (m_dispatchInfoPtr->m_debugDraw->getDebugMode() & btIDebugDraw::DBG_DrawWireframe))
|
||||
{
|
||||
btVector3 color(1,1,0);
|
||||
btVector3 color(1, 1, 0);
|
||||
const btTransform& tr = m_triBody->getWorldTransform();
|
||||
m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[0]),tr(triangle[1]),color);
|
||||
m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[1]),tr(triangle[2]),color);
|
||||
m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[2]),tr(triangle[0]),color);
|
||||
m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[0]), tr(triangle[1]), color);
|
||||
m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[1]), tr(triangle[2]), color);
|
||||
m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[2]), tr(triangle[0]), color);
|
||||
}
|
||||
|
||||
btTriIndex triIndex(partId,triangleIndex,0);
|
||||
btTriIndex triIndex(partId, triangleIndex, 0);
|
||||
btHashKey<btTriIndex> triKey(triIndex.getUid());
|
||||
|
||||
|
||||
btTriIndex* shapeIndex = m_shapeCache[triKey];
|
||||
if (shapeIndex)
|
||||
{
|
||||
@@ -117,82 +106,73 @@ void btSoftBodyTriangleCallback::processTriangle(btVector3* triangle,int partId,
|
||||
//copy over user pointers to temporary shape
|
||||
tm->setUserPointer(m_triBody->getCollisionShape()->getUserPointer());
|
||||
|
||||
btCollisionObjectWrapper softBody(0,m_softBody->getCollisionShape(),m_softBody,m_softBody->getWorldTransform(),-1,-1);
|
||||
btCollisionObjectWrapper softBody(0, m_softBody->getCollisionShape(), m_softBody, m_softBody->getWorldTransform(), -1, -1);
|
||||
//btCollisionObjectWrapper triBody(0,tm, ob, btTransform::getIdentity());//ob->getWorldTransform());//??
|
||||
btCollisionObjectWrapper triBody(0,tm, m_triBody, m_triBody->getWorldTransform(),partId, triangleIndex);
|
||||
btCollisionObjectWrapper triBody(0, tm, m_triBody, m_triBody->getWorldTransform(), partId, triangleIndex);
|
||||
ebtDispatcherQueryType algoType = m_resultOut->m_closestPointDistanceThreshold > 0 ? BT_CLOSEST_POINT_ALGORITHMS : BT_CONTACT_POINT_ALGORITHMS;
|
||||
btCollisionAlgorithm* colAlgo = ci.m_dispatcher1->findAlgorithm(&softBody,&triBody,0, algoType);//m_manifoldPtr);
|
||||
btCollisionAlgorithm* colAlgo = ci.m_dispatcher1->findAlgorithm(&softBody, &triBody, 0, algoType); //m_manifoldPtr);
|
||||
|
||||
colAlgo->processCollision(&softBody,&triBody,*m_dispatchInfoPtr,m_resultOut);
|
||||
colAlgo->processCollision(&softBody, &triBody, *m_dispatchInfoPtr, m_resultOut);
|
||||
colAlgo->~btCollisionAlgorithm();
|
||||
ci.m_dispatcher1->freeCollisionAlgorithm(colAlgo);
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//aabb filter is already applied!
|
||||
//aabb filter is already applied!
|
||||
|
||||
//btCollisionObject* colObj = static_cast<btCollisionObject*>(m_convexProxy->m_clientObject);
|
||||
|
||||
// if (m_softBody->getCollisionShape()->getShapeType()==
|
||||
{
|
||||
// btVector3 other;
|
||||
btVector3 normal = (triangle[1]-triangle[0]).cross(triangle[2]-triangle[0]);
|
||||
btVector3 normal = (triangle[1] - triangle[0]).cross(triangle[2] - triangle[0]);
|
||||
normal.normalize();
|
||||
normal*= BT_SOFTBODY_TRIANGLE_EXTRUSION;
|
||||
normal *= BT_SOFTBODY_TRIANGLE_EXTRUSION;
|
||||
// other=(triangle[0]+triangle[1]+triangle[2])*0.333333f;
|
||||
// other+=normal*22.f;
|
||||
btVector3 pts[6] = {triangle[0]+normal,
|
||||
triangle[1]+normal,
|
||||
triangle[2]+normal,
|
||||
triangle[0]-normal,
|
||||
triangle[1]-normal,
|
||||
triangle[2]-normal};
|
||||
|
||||
btConvexHullShape* tm = new btConvexHullShape(&pts[0].getX(),6);
|
||||
btVector3 pts[6] = {triangle[0] + normal,
|
||||
triangle[1] + normal,
|
||||
triangle[2] + normal,
|
||||
triangle[0] - normal,
|
||||
triangle[1] - normal,
|
||||
triangle[2] - normal};
|
||||
|
||||
btConvexHullShape* tm = new btConvexHullShape(&pts[0].getX(), 6);
|
||||
|
||||
// btBU_Simplex1to4 tm(triangle[0],triangle[1],triangle[2],other);
|
||||
|
||||
//btTriangleShape tm(triangle[0],triangle[1],triangle[2]);
|
||||
//btTriangleShape tm(triangle[0],triangle[1],triangle[2]);
|
||||
// tm.setMargin(m_collisionMarginTriangle);
|
||||
|
||||
//copy over user pointers to temporary shape
|
||||
tm->setUserPointer(m_triBody->getCollisionShape()->getUserPointer());
|
||||
|
||||
|
||||
btCollisionObjectWrapper softBody(0,m_softBody->getCollisionShape(),m_softBody,m_softBody->getWorldTransform(),-1,-1);
|
||||
btCollisionObjectWrapper triBody(0,tm, m_triBody, m_triBody->getWorldTransform(),partId, triangleIndex);//btTransform::getIdentity());//??
|
||||
btCollisionObjectWrapper softBody(0, m_softBody->getCollisionShape(), m_softBody, m_softBody->getWorldTransform(), -1, -1);
|
||||
btCollisionObjectWrapper triBody(0, tm, m_triBody, m_triBody->getWorldTransform(), partId, triangleIndex); //btTransform::getIdentity());//??
|
||||
|
||||
ebtDispatcherQueryType algoType = m_resultOut->m_closestPointDistanceThreshold > 0 ? BT_CLOSEST_POINT_ALGORITHMS : BT_CONTACT_POINT_ALGORITHMS;
|
||||
btCollisionAlgorithm* colAlgo = ci.m_dispatcher1->findAlgorithm(&softBody,&triBody,0, algoType);//m_manifoldPtr);
|
||||
btCollisionAlgorithm* colAlgo = ci.m_dispatcher1->findAlgorithm(&softBody, &triBody, 0, algoType); //m_manifoldPtr);
|
||||
|
||||
colAlgo->processCollision(&softBody,&triBody,*m_dispatchInfoPtr,m_resultOut);
|
||||
colAlgo->processCollision(&softBody, &triBody, *m_dispatchInfoPtr, m_resultOut);
|
||||
colAlgo->~btCollisionAlgorithm();
|
||||
ci.m_dispatcher1->freeCollisionAlgorithm(colAlgo);
|
||||
|
||||
triIndex.m_childShape = tm;
|
||||
m_shapeCache.insert(triKey,triIndex);
|
||||
|
||||
m_shapeCache.insert(triKey, triIndex);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void btSoftBodyTriangleCallback::setTimeStepAndCounters(btScalar collisionMarginTriangle,const btCollisionObjectWrapper* triBodyWrap, const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
|
||||
void btSoftBodyTriangleCallback::setTimeStepAndCounters(btScalar collisionMarginTriangle, const btCollisionObjectWrapper* triBodyWrap, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut)
|
||||
{
|
||||
m_dispatchInfoPtr = &dispatchInfo;
|
||||
m_collisionMarginTriangle = collisionMarginTriangle+btScalar(BT_SOFTBODY_TRIANGLE_EXTRUSION);
|
||||
m_collisionMarginTriangle = collisionMarginTriangle + btScalar(BT_SOFTBODY_TRIANGLE_EXTRUSION);
|
||||
m_resultOut = resultOut;
|
||||
|
||||
|
||||
btVector3 aabbWorldSpaceMin,aabbWorldSpaceMax;
|
||||
m_softBody->getAabb(aabbWorldSpaceMin,aabbWorldSpaceMax);
|
||||
btVector3 halfExtents = (aabbWorldSpaceMax-aabbWorldSpaceMin)*btScalar(0.5);
|
||||
btVector3 softBodyCenter = (aabbWorldSpaceMax+aabbWorldSpaceMin)*btScalar(0.5);
|
||||
btVector3 aabbWorldSpaceMin, aabbWorldSpaceMax;
|
||||
m_softBody->getAabb(aabbWorldSpaceMin, aabbWorldSpaceMax);
|
||||
btVector3 halfExtents = (aabbWorldSpaceMax - aabbWorldSpaceMin) * btScalar(0.5);
|
||||
btVector3 softBodyCenter = (aabbWorldSpaceMax + aabbWorldSpaceMin) * btScalar(0.5);
|
||||
|
||||
btTransform softTransform;
|
||||
softTransform.setIdentity();
|
||||
@@ -200,56 +180,45 @@ void btSoftBodyTriangleCallback::setTimeStepAndCounters(btScalar collisionMargin
|
||||
|
||||
btTransform convexInTriangleSpace;
|
||||
convexInTriangleSpace = triBodyWrap->getWorldTransform().inverse() * softTransform;
|
||||
btTransformAabb(halfExtents,m_collisionMarginTriangle,convexInTriangleSpace,m_aabbMin,m_aabbMax);
|
||||
btTransformAabb(halfExtents, m_collisionMarginTriangle, convexInTriangleSpace, m_aabbMin, m_aabbMax);
|
||||
}
|
||||
|
||||
void btSoftBodyConcaveCollisionAlgorithm::clearCache()
|
||||
{
|
||||
m_btSoftBodyTriangleCallback.clearCache();
|
||||
|
||||
}
|
||||
|
||||
void btSoftBodyConcaveCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
|
||||
void btSoftBodyConcaveCollisionAlgorithm::processCollision(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut)
|
||||
{
|
||||
|
||||
|
||||
//btCollisionObject* convexBody = m_isSwapped ? body1 : body0;
|
||||
const btCollisionObjectWrapper* triBody = m_isSwapped ? body0Wrap : body1Wrap;
|
||||
|
||||
if (triBody->getCollisionShape()->isConcave())
|
||||
{
|
||||
|
||||
|
||||
const btCollisionObject* triOb = triBody->getCollisionObject();
|
||||
const btConcaveShape* concaveShape = static_cast<const btConcaveShape*>( triOb->getCollisionShape());
|
||||
const btCollisionObject* triOb = triBody->getCollisionObject();
|
||||
const btConcaveShape* concaveShape = static_cast<const btConcaveShape*>(triOb->getCollisionShape());
|
||||
|
||||
// if (convexBody->getCollisionShape()->isConvex())
|
||||
{
|
||||
btScalar collisionMarginTriangle = concaveShape->getMargin();
|
||||
|
||||
// resultOut->setPersistentManifold(m_btSoftBodyTriangleCallback.m_manifoldPtr);
|
||||
m_btSoftBodyTriangleCallback.setTimeStepAndCounters(collisionMarginTriangle,triBody,dispatchInfo,resultOut);
|
||||
m_btSoftBodyTriangleCallback.setTimeStepAndCounters(collisionMarginTriangle, triBody, dispatchInfo, resultOut);
|
||||
|
||||
|
||||
concaveShape->processAllTriangles( &m_btSoftBodyTriangleCallback,m_btSoftBodyTriangleCallback.getAabbMin(),m_btSoftBodyTriangleCallback.getAabbMax());
|
||||
concaveShape->processAllTriangles(&m_btSoftBodyTriangleCallback, m_btSoftBodyTriangleCallback.getAabbMin(), m_btSoftBodyTriangleCallback.getAabbMax());
|
||||
|
||||
// resultOut->refreshContactPoints();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
btScalar btSoftBodyConcaveCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
|
||||
btScalar btSoftBodyConcaveCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* body0, btCollisionObject* body1, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut)
|
||||
{
|
||||
(void)resultOut;
|
||||
(void)dispatchInfo;
|
||||
btCollisionObject* convexbody = m_isSwapped ? body1 : body0;
|
||||
btCollisionObject* triBody = m_isSwapped ? body0 : body1;
|
||||
|
||||
|
||||
//quick approximation using raycast, todo: hook up to the continuous collision detection (one of the btConvexCast)
|
||||
|
||||
//only perform CCD above a certain threshold, this prevents blocking on the long run
|
||||
@@ -268,25 +237,23 @@ btScalar btSoftBodyConcaveCollisionAlgorithm::calculateTimeOfImpact(btCollisionO
|
||||
btTransform convexFromLocal = triInv * convexbody->getWorldTransform();
|
||||
btTransform convexToLocal = triInv * convexbody->getInterpolationWorldTransform();
|
||||
|
||||
struct LocalTriangleSphereCastCallback : public btTriangleCallback
|
||||
struct LocalTriangleSphereCastCallback : public btTriangleCallback
|
||||
{
|
||||
btTransform m_ccdSphereFromTrans;
|
||||
btTransform m_ccdSphereToTrans;
|
||||
btTransform m_meshTransform;
|
||||
btTransform m_meshTransform;
|
||||
|
||||
btScalar m_ccdSphereRadius;
|
||||
btScalar m_hitFraction;
|
||||
btScalar m_ccdSphereRadius;
|
||||
btScalar m_hitFraction;
|
||||
|
||||
|
||||
LocalTriangleSphereCastCallback(const btTransform& from,const btTransform& to,btScalar ccdSphereRadius,btScalar hitFraction)
|
||||
:m_ccdSphereFromTrans(from),
|
||||
m_ccdSphereToTrans(to),
|
||||
m_ccdSphereRadius(ccdSphereRadius),
|
||||
m_hitFraction(hitFraction)
|
||||
{
|
||||
LocalTriangleSphereCastCallback(const btTransform& from, const btTransform& to, btScalar ccdSphereRadius, btScalar hitFraction)
|
||||
: m_ccdSphereFromTrans(from),
|
||||
m_ccdSphereToTrans(to),
|
||||
m_ccdSphereRadius(ccdSphereRadius),
|
||||
m_hitFraction(hitFraction)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex)
|
||||
{
|
||||
(void)partId;
|
||||
@@ -296,29 +263,23 @@ btScalar btSoftBodyConcaveCollisionAlgorithm::calculateTimeOfImpact(btCollisionO
|
||||
ident.setIdentity();
|
||||
btConvexCast::CastResult castResult;
|
||||
castResult.m_fraction = m_hitFraction;
|
||||
btSphereShape pointShape(m_ccdSphereRadius);
|
||||
btTriangleShape triShape(triangle[0],triangle[1],triangle[2]);
|
||||
btVoronoiSimplexSolver simplexSolver;
|
||||
btSubsimplexConvexCast convexCaster(&pointShape,&triShape,&simplexSolver);
|
||||
btSphereShape pointShape(m_ccdSphereRadius);
|
||||
btTriangleShape triShape(triangle[0], triangle[1], triangle[2]);
|
||||
btVoronoiSimplexSolver simplexSolver;
|
||||
btSubsimplexConvexCast convexCaster(&pointShape, &triShape, &simplexSolver);
|
||||
//GjkConvexCast convexCaster(&pointShape,convexShape,&simplexSolver);
|
||||
//ContinuousConvexCollision convexCaster(&pointShape,convexShape,&simplexSolver,0);
|
||||
//local space?
|
||||
|
||||
if (convexCaster.calcTimeOfImpact(m_ccdSphereFromTrans,m_ccdSphereToTrans,
|
||||
ident,ident,castResult))
|
||||
if (convexCaster.calcTimeOfImpact(m_ccdSphereFromTrans, m_ccdSphereToTrans,
|
||||
ident, ident, castResult))
|
||||
{
|
||||
if (m_hitFraction > castResult.m_fraction)
|
||||
m_hitFraction = castResult.m_fraction;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (triBody->getCollisionShape()->isConcave())
|
||||
{
|
||||
btVector3 rayAabbMin = convexFromLocal.getOrigin();
|
||||
@@ -326,33 +287,30 @@ btScalar btSoftBodyConcaveCollisionAlgorithm::calculateTimeOfImpact(btCollisionO
|
||||
btVector3 rayAabbMax = convexFromLocal.getOrigin();
|
||||
rayAabbMax.setMax(convexToLocal.getOrigin());
|
||||
btScalar ccdRadius0 = convexbody->getCcdSweptSphereRadius();
|
||||
rayAabbMin -= btVector3(ccdRadius0,ccdRadius0,ccdRadius0);
|
||||
rayAabbMax += btVector3(ccdRadius0,ccdRadius0,ccdRadius0);
|
||||
rayAabbMin -= btVector3(ccdRadius0, ccdRadius0, ccdRadius0);
|
||||
rayAabbMax += btVector3(ccdRadius0, ccdRadius0, ccdRadius0);
|
||||
|
||||
btScalar curHitFraction = btScalar(1.); //is this available?
|
||||
LocalTriangleSphereCastCallback raycastCallback(convexFromLocal,convexToLocal,
|
||||
convexbody->getCcdSweptSphereRadius(),curHitFraction);
|
||||
btScalar curHitFraction = btScalar(1.); //is this available?
|
||||
LocalTriangleSphereCastCallback raycastCallback(convexFromLocal, convexToLocal,
|
||||
convexbody->getCcdSweptSphereRadius(), curHitFraction);
|
||||
|
||||
raycastCallback.m_hitFraction = convexbody->getHitFraction();
|
||||
|
||||
btCollisionObject* concavebody = triBody;
|
||||
|
||||
btConcaveShape* triangleMesh = (btConcaveShape*) concavebody->getCollisionShape();
|
||||
btConcaveShape* triangleMesh = (btConcaveShape*)concavebody->getCollisionShape();
|
||||
|
||||
if (triangleMesh)
|
||||
{
|
||||
triangleMesh->processAllTriangles(&raycastCallback,rayAabbMin,rayAabbMax);
|
||||
triangleMesh->processAllTriangles(&raycastCallback, rayAabbMin, rayAabbMax);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (raycastCallback.m_hitFraction < convexbody->getHitFraction())
|
||||
{
|
||||
convexbody->setHitFraction( raycastCallback.m_hitFraction);
|
||||
convexbody->setHitFraction(raycastCallback.m_hitFraction);
|
||||
return raycastCallback.m_hitFraction;
|
||||
}
|
||||
}
|
||||
|
||||
return btScalar(1.);
|
||||
|
||||
}
|
||||
|
||||
@@ -29,63 +29,62 @@ class btCollisionShape;
|
||||
|
||||
#include "LinearMath/btHashMap.h"
|
||||
|
||||
#include "BulletCollision/BroadphaseCollision/btQuantizedBvh.h" //for definition of MAX_NUM_PARTS_IN_BITS
|
||||
#include "BulletCollision/BroadphaseCollision/btQuantizedBvh.h" //for definition of MAX_NUM_PARTS_IN_BITS
|
||||
|
||||
struct btTriIndex
|
||||
{
|
||||
int m_PartIdTriangleIndex;
|
||||
class btCollisionShape* m_childShape;
|
||||
class btCollisionShape* m_childShape;
|
||||
|
||||
btTriIndex(int partId,int triangleIndex,btCollisionShape* shape)
|
||||
btTriIndex(int partId, int triangleIndex, btCollisionShape* shape)
|
||||
{
|
||||
m_PartIdTriangleIndex = (partId<<(31-MAX_NUM_PARTS_IN_BITS)) | triangleIndex;
|
||||
m_PartIdTriangleIndex = (partId << (31 - MAX_NUM_PARTS_IN_BITS)) | triangleIndex;
|
||||
m_childShape = shape;
|
||||
}
|
||||
|
||||
int getTriangleIndex() const
|
||||
int getTriangleIndex() const
|
||||
{
|
||||
// Get only the lower bits where the triangle index is stored
|
||||
unsigned int x = 0;
|
||||
unsigned int y = (~(x&0))<<(31-MAX_NUM_PARTS_IN_BITS);
|
||||
return (m_PartIdTriangleIndex&~(y));
|
||||
unsigned int y = (~(x & 0)) << (31 - MAX_NUM_PARTS_IN_BITS);
|
||||
return (m_PartIdTriangleIndex & ~(y));
|
||||
}
|
||||
int getPartId() const
|
||||
int getPartId() const
|
||||
{
|
||||
// Get only the highest bits where the part index is stored
|
||||
return (m_PartIdTriangleIndex>>(31-MAX_NUM_PARTS_IN_BITS));
|
||||
return (m_PartIdTriangleIndex >> (31 - MAX_NUM_PARTS_IN_BITS));
|
||||
}
|
||||
int getUid() const
|
||||
int getUid() const
|
||||
{
|
||||
return m_PartIdTriangleIndex;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
///For each triangle in the concave mesh that overlaps with the AABB of a soft body (m_softBody), processTriangle is called.
|
||||
class btSoftBodyTriangleCallback : public btTriangleCallback
|
||||
{
|
||||
btSoftBody* m_softBody;
|
||||
const btCollisionObject* m_triBody;
|
||||
|
||||
btVector3 m_aabbMin;
|
||||
btVector3 m_aabbMax ;
|
||||
btVector3 m_aabbMin;
|
||||
btVector3 m_aabbMax;
|
||||
|
||||
btManifoldResult* m_resultOut;
|
||||
|
||||
btDispatcher* m_dispatcher;
|
||||
btDispatcher* m_dispatcher;
|
||||
const btDispatcherInfo* m_dispatchInfoPtr;
|
||||
btScalar m_collisionMarginTriangle;
|
||||
|
||||
btHashMap<btHashKey<btTriIndex>,btTriIndex> m_shapeCache;
|
||||
btHashMap<btHashKey<btTriIndex>, btTriIndex> m_shapeCache;
|
||||
|
||||
public:
|
||||
int m_triangleCount;
|
||||
int m_triangleCount;
|
||||
|
||||
// btPersistentManifold* m_manifoldPtr;
|
||||
|
||||
btSoftBodyTriangleCallback(btDispatcher* dispatcher,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,bool isSwapped);
|
||||
btSoftBodyTriangleCallback(btDispatcher* dispatcher, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, bool isSwapped);
|
||||
|
||||
void setTimeStepAndCounters(btScalar collisionMarginTriangle,const btCollisionObjectWrapper* triObjWrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
|
||||
void setTimeStepAndCounters(btScalar collisionMarginTriangle, const btCollisionObjectWrapper* triObjWrap, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut);
|
||||
|
||||
virtual ~btSoftBodyTriangleCallback();
|
||||
|
||||
@@ -101,55 +100,48 @@ public:
|
||||
{
|
||||
return m_aabbMax;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/// btSoftBodyConcaveCollisionAlgorithm supports collision between soft body shapes and (concave) trianges meshes.
|
||||
class btSoftBodyConcaveCollisionAlgorithm : public btCollisionAlgorithm
|
||||
class btSoftBodyConcaveCollisionAlgorithm : public btCollisionAlgorithm
|
||||
{
|
||||
|
||||
bool m_isSwapped;
|
||||
bool m_isSwapped;
|
||||
|
||||
btSoftBodyTriangleCallback m_btSoftBodyTriangleCallback;
|
||||
|
||||
public:
|
||||
|
||||
btSoftBodyConcaveCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,bool isSwapped);
|
||||
btSoftBodyConcaveCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, bool isSwapped);
|
||||
|
||||
virtual ~btSoftBodyConcaveCollisionAlgorithm();
|
||||
|
||||
virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
|
||||
virtual void processCollision(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut);
|
||||
|
||||
btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
|
||||
btScalar calculateTimeOfImpact(btCollisionObject* body0, btCollisionObject* body1, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut);
|
||||
|
||||
virtual void getAllContactManifolds(btManifoldArray& manifoldArray)
|
||||
virtual void getAllContactManifolds(btManifoldArray& manifoldArray)
|
||||
{
|
||||
//we don't add any manifolds
|
||||
}
|
||||
|
||||
void clearCache();
|
||||
void clearCache();
|
||||
|
||||
struct CreateFunc :public btCollisionAlgorithmCreateFunc
|
||||
struct CreateFunc : public btCollisionAlgorithmCreateFunc
|
||||
{
|
||||
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
|
||||
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap)
|
||||
{
|
||||
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btSoftBodyConcaveCollisionAlgorithm));
|
||||
return new(mem) btSoftBodyConcaveCollisionAlgorithm(ci,body0Wrap,body1Wrap,false);
|
||||
return new (mem) btSoftBodyConcaveCollisionAlgorithm(ci, body0Wrap, body1Wrap, false);
|
||||
}
|
||||
};
|
||||
|
||||
struct SwappedCreateFunc :public btCollisionAlgorithmCreateFunc
|
||||
struct SwappedCreateFunc : public btCollisionAlgorithmCreateFunc
|
||||
{
|
||||
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
|
||||
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap)
|
||||
{
|
||||
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btSoftBodyConcaveCollisionAlgorithm));
|
||||
return new(mem) btSoftBodyConcaveCollisionAlgorithm(ci,body0Wrap,body1Wrap,true);
|
||||
return new (mem) btSoftBodyConcaveCollisionAlgorithm(ci, body0Wrap, body1Wrap, true);
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif //BT_SOFT_BODY_CONCAVE_COLLISION_ALGORITHM_H
|
||||
#endif //BT_SOFT_BODY_CONCAVE_COLLISION_ALGORITHM_H
|
||||
|
||||
@@ -19,199 +19,194 @@ subject to the following restrictions:
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
|
||||
#include "BulletDynamics/Dynamics/btRigidBody.h"
|
||||
|
||||
|
||||
struct SoftBodyMaterialData
|
||||
struct SoftBodyMaterialData
|
||||
{
|
||||
float m_linearStiffness;
|
||||
float m_angularStiffness;
|
||||
float m_volumeStiffness;
|
||||
int m_flags;
|
||||
float m_linearStiffness;
|
||||
float m_angularStiffness;
|
||||
float m_volumeStiffness;
|
||||
int m_flags;
|
||||
};
|
||||
|
||||
struct SoftBodyNodeData
|
||||
struct SoftBodyNodeData
|
||||
{
|
||||
SoftBodyMaterialData *m_material;
|
||||
btVector3FloatData m_position;
|
||||
btVector3FloatData m_previousPosition;
|
||||
btVector3FloatData m_velocity;
|
||||
btVector3FloatData m_accumulatedForce;
|
||||
btVector3FloatData m_normal;
|
||||
float m_inverseMass;
|
||||
float m_area;
|
||||
int m_attach;
|
||||
int m_pad;
|
||||
SoftBodyMaterialData *m_material;
|
||||
btVector3FloatData m_position;
|
||||
btVector3FloatData m_previousPosition;
|
||||
btVector3FloatData m_velocity;
|
||||
btVector3FloatData m_accumulatedForce;
|
||||
btVector3FloatData m_normal;
|
||||
float m_inverseMass;
|
||||
float m_area;
|
||||
int m_attach;
|
||||
int m_pad;
|
||||
};
|
||||
|
||||
struct SoftBodyLinkData
|
||||
struct SoftBodyLinkData
|
||||
{
|
||||
SoftBodyMaterialData *m_material;
|
||||
int m_nodeIndices[2]; // Node pointers
|
||||
float m_restLength; // Rest length
|
||||
int m_bbending; // Bending link
|
||||
SoftBodyMaterialData *m_material;
|
||||
int m_nodeIndices[2]; // Node pointers
|
||||
float m_restLength; // Rest length
|
||||
int m_bbending; // Bending link
|
||||
};
|
||||
|
||||
struct SoftBodyFaceData
|
||||
struct SoftBodyFaceData
|
||||
{
|
||||
btVector3FloatData m_normal; // Normal
|
||||
SoftBodyMaterialData *m_material;
|
||||
int m_nodeIndices[3]; // Node pointers
|
||||
float m_restArea; // Rest area
|
||||
};
|
||||
|
||||
struct SoftBodyTetraData
|
||||
{
|
||||
btVector3FloatData m_c0[4]; // gradients
|
||||
SoftBodyMaterialData *m_material;
|
||||
int m_nodeIndices[4]; // Node pointers
|
||||
float m_restVolume; // Rest volume
|
||||
float m_c1; // (4*kVST)/(im0+im1+im2+im3)
|
||||
float m_c2; // m_c1/sum(|g0..3|^2)
|
||||
int m_pad;
|
||||
btVector3FloatData m_normal; // Normal
|
||||
SoftBodyMaterialData *m_material;
|
||||
int m_nodeIndices[3]; // Node pointers
|
||||
float m_restArea; // Rest area
|
||||
};
|
||||
|
||||
struct SoftRigidAnchorData
|
||||
struct SoftBodyTetraData
|
||||
{
|
||||
btMatrix3x3FloatData m_c0; // Impulse matrix
|
||||
btVector3FloatData m_c1; // Relative anchor
|
||||
btVector3FloatData m_localFrame; // Anchor position in body space
|
||||
btRigidBodyData *m_rigidBody;
|
||||
int m_nodeIndex; // Node pointer
|
||||
float m_c2; // ima*dt
|
||||
btVector3FloatData m_c0[4]; // gradients
|
||||
SoftBodyMaterialData *m_material;
|
||||
int m_nodeIndices[4]; // Node pointers
|
||||
float m_restVolume; // Rest volume
|
||||
float m_c1; // (4*kVST)/(im0+im1+im2+im3)
|
||||
float m_c2; // m_c1/sum(|g0..3|^2)
|
||||
int m_pad;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct SoftBodyConfigData
|
||||
struct SoftRigidAnchorData
|
||||
{
|
||||
int m_aeroModel; // Aerodynamic model (default: V_Point)
|
||||
float m_baumgarte; // Velocities correction factor (Baumgarte)
|
||||
float m_damping; // Damping coefficient [0,1]
|
||||
float m_drag; // Drag coefficient [0,+inf]
|
||||
float m_lift; // Lift coefficient [0,+inf]
|
||||
float m_pressure; // Pressure coefficient [-inf,+inf]
|
||||
float m_volume; // Volume conversation coefficient [0,+inf]
|
||||
float m_dynamicFriction; // Dynamic friction coefficient [0,1]
|
||||
float m_poseMatch; // Pose matching coefficient [0,1]
|
||||
float m_rigidContactHardness; // Rigid contacts hardness [0,1]
|
||||
float m_kineticContactHardness; // Kinetic contacts hardness [0,1]
|
||||
float m_softContactHardness; // Soft contacts hardness [0,1]
|
||||
float m_anchorHardness; // Anchors hardness [0,1]
|
||||
float m_softRigidClusterHardness; // Soft vs rigid hardness [0,1] (cluster only)
|
||||
float m_softKineticClusterHardness; // Soft vs kinetic hardness [0,1] (cluster only)
|
||||
float m_softSoftClusterHardness; // Soft vs soft hardness [0,1] (cluster only)
|
||||
float m_softRigidClusterImpulseSplit; // Soft vs rigid impulse split [0,1] (cluster only)
|
||||
float m_softKineticClusterImpulseSplit; // Soft vs rigid impulse split [0,1] (cluster only)
|
||||
float m_softSoftClusterImpulseSplit; // Soft vs rigid impulse split [0,1] (cluster only)
|
||||
float m_maxVolume; // Maximum volume ratio for pose
|
||||
float m_timeScale; // Time scale
|
||||
int m_velocityIterations; // Velocities solver iterations
|
||||
int m_positionIterations; // Positions solver iterations
|
||||
int m_driftIterations; // Drift solver iterations
|
||||
int m_clusterIterations; // Cluster solver iterations
|
||||
int m_collisionFlags; // Collisions flags
|
||||
btMatrix3x3FloatData m_c0; // Impulse matrix
|
||||
btVector3FloatData m_c1; // Relative anchor
|
||||
btVector3FloatData m_localFrame; // Anchor position in body space
|
||||
btRigidBodyData *m_rigidBody;
|
||||
int m_nodeIndex; // Node pointer
|
||||
float m_c2; // ima*dt
|
||||
};
|
||||
|
||||
struct SoftBodyPoseData
|
||||
struct SoftBodyConfigData
|
||||
{
|
||||
btMatrix3x3FloatData m_rot; // Rotation
|
||||
btMatrix3x3FloatData m_scale; // Scale
|
||||
btMatrix3x3FloatData m_aqq; // Base scaling
|
||||
btVector3FloatData m_com; // COM
|
||||
|
||||
btVector3FloatData *m_positions; // Reference positions
|
||||
float *m_weights; // Weights
|
||||
int m_numPositions;
|
||||
int m_numWeigts;
|
||||
|
||||
int m_bvolume; // Is valid
|
||||
int m_bframe; // Is frame
|
||||
float m_restVolume; // Rest volume
|
||||
int m_pad;
|
||||
int m_aeroModel; // Aerodynamic model (default: V_Point)
|
||||
float m_baumgarte; // Velocities correction factor (Baumgarte)
|
||||
float m_damping; // Damping coefficient [0,1]
|
||||
float m_drag; // Drag coefficient [0,+inf]
|
||||
float m_lift; // Lift coefficient [0,+inf]
|
||||
float m_pressure; // Pressure coefficient [-inf,+inf]
|
||||
float m_volume; // Volume conversation coefficient [0,+inf]
|
||||
float m_dynamicFriction; // Dynamic friction coefficient [0,1]
|
||||
float m_poseMatch; // Pose matching coefficient [0,1]
|
||||
float m_rigidContactHardness; // Rigid contacts hardness [0,1]
|
||||
float m_kineticContactHardness; // Kinetic contacts hardness [0,1]
|
||||
float m_softContactHardness; // Soft contacts hardness [0,1]
|
||||
float m_anchorHardness; // Anchors hardness [0,1]
|
||||
float m_softRigidClusterHardness; // Soft vs rigid hardness [0,1] (cluster only)
|
||||
float m_softKineticClusterHardness; // Soft vs kinetic hardness [0,1] (cluster only)
|
||||
float m_softSoftClusterHardness; // Soft vs soft hardness [0,1] (cluster only)
|
||||
float m_softRigidClusterImpulseSplit; // Soft vs rigid impulse split [0,1] (cluster only)
|
||||
float m_softKineticClusterImpulseSplit; // Soft vs rigid impulse split [0,1] (cluster only)
|
||||
float m_softSoftClusterImpulseSplit; // Soft vs rigid impulse split [0,1] (cluster only)
|
||||
float m_maxVolume; // Maximum volume ratio for pose
|
||||
float m_timeScale; // Time scale
|
||||
int m_velocityIterations; // Velocities solver iterations
|
||||
int m_positionIterations; // Positions solver iterations
|
||||
int m_driftIterations; // Drift solver iterations
|
||||
int m_clusterIterations; // Cluster solver iterations
|
||||
int m_collisionFlags; // Collisions flags
|
||||
};
|
||||
|
||||
struct SoftBodyClusterData
|
||||
struct SoftBodyPoseData
|
||||
{
|
||||
btTransformFloatData m_framexform;
|
||||
btMatrix3x3FloatData m_locii;
|
||||
btMatrix3x3FloatData m_invwi;
|
||||
btVector3FloatData m_com;
|
||||
btVector3FloatData m_vimpulses[2];
|
||||
btVector3FloatData m_dimpulses[2];
|
||||
btVector3FloatData m_lv;
|
||||
btVector3FloatData m_av;
|
||||
|
||||
btVector3FloatData *m_framerefs;
|
||||
int *m_nodeIndices;
|
||||
float *m_masses;
|
||||
btMatrix3x3FloatData m_rot; // Rotation
|
||||
btMatrix3x3FloatData m_scale; // Scale
|
||||
btMatrix3x3FloatData m_aqq; // Base scaling
|
||||
btVector3FloatData m_com; // COM
|
||||
|
||||
int m_numFrameRefs;
|
||||
int m_numNodes;
|
||||
int m_numMasses;
|
||||
btVector3FloatData *m_positions; // Reference positions
|
||||
float *m_weights; // Weights
|
||||
int m_numPositions;
|
||||
int m_numWeigts;
|
||||
|
||||
float m_idmass;
|
||||
float m_imass;
|
||||
int m_nvimpulses;
|
||||
int m_ndimpulses;
|
||||
float m_ndamping;
|
||||
float m_ldamping;
|
||||
float m_adamping;
|
||||
float m_matching;
|
||||
float m_maxSelfCollisionImpulse;
|
||||
float m_selfCollisionImpulseFactor;
|
||||
int m_containsAnchor;
|
||||
int m_collide;
|
||||
int m_clusterIndex;
|
||||
int m_bvolume; // Is valid
|
||||
int m_bframe; // Is frame
|
||||
float m_restVolume; // Rest volume
|
||||
int m_pad;
|
||||
};
|
||||
|
||||
|
||||
enum btSoftJointBodyType
|
||||
struct SoftBodyClusterData
|
||||
{
|
||||
BT_JOINT_SOFT_BODY_CLUSTER=1,
|
||||
btTransformFloatData m_framexform;
|
||||
btMatrix3x3FloatData m_locii;
|
||||
btMatrix3x3FloatData m_invwi;
|
||||
btVector3FloatData m_com;
|
||||
btVector3FloatData m_vimpulses[2];
|
||||
btVector3FloatData m_dimpulses[2];
|
||||
btVector3FloatData m_lv;
|
||||
btVector3FloatData m_av;
|
||||
|
||||
btVector3FloatData *m_framerefs;
|
||||
int *m_nodeIndices;
|
||||
float *m_masses;
|
||||
|
||||
int m_numFrameRefs;
|
||||
int m_numNodes;
|
||||
int m_numMasses;
|
||||
|
||||
float m_idmass;
|
||||
float m_imass;
|
||||
int m_nvimpulses;
|
||||
int m_ndimpulses;
|
||||
float m_ndamping;
|
||||
float m_ldamping;
|
||||
float m_adamping;
|
||||
float m_matching;
|
||||
float m_maxSelfCollisionImpulse;
|
||||
float m_selfCollisionImpulseFactor;
|
||||
int m_containsAnchor;
|
||||
int m_collide;
|
||||
int m_clusterIndex;
|
||||
};
|
||||
|
||||
enum btSoftJointBodyType
|
||||
{
|
||||
BT_JOINT_SOFT_BODY_CLUSTER = 1,
|
||||
BT_JOINT_RIGID_BODY,
|
||||
BT_JOINT_COLLISION_OBJECT
|
||||
};
|
||||
|
||||
struct btSoftBodyJointData
|
||||
struct btSoftBodyJointData
|
||||
{
|
||||
void *m_bodyA;
|
||||
void *m_bodyB;
|
||||
btVector3FloatData m_refs[2];
|
||||
float m_cfm;
|
||||
float m_erp;
|
||||
float m_split;
|
||||
int m_delete;
|
||||
btVector3FloatData m_relPosition[2];//linear
|
||||
int m_bodyAtype;
|
||||
int m_bodyBtype;
|
||||
int m_jointType;
|
||||
int m_pad;
|
||||
void *m_bodyA;
|
||||
void *m_bodyB;
|
||||
btVector3FloatData m_refs[2];
|
||||
float m_cfm;
|
||||
float m_erp;
|
||||
float m_split;
|
||||
int m_delete;
|
||||
btVector3FloatData m_relPosition[2]; //linear
|
||||
int m_bodyAtype;
|
||||
int m_bodyBtype;
|
||||
int m_jointType;
|
||||
int m_pad;
|
||||
};
|
||||
|
||||
///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
|
||||
struct btSoftBodyFloatData
|
||||
struct btSoftBodyFloatData
|
||||
{
|
||||
btCollisionObjectFloatData m_collisionObjectData;
|
||||
btCollisionObjectFloatData m_collisionObjectData;
|
||||
|
||||
SoftBodyPoseData *m_pose;
|
||||
SoftBodyMaterialData **m_materials;
|
||||
SoftBodyNodeData *m_nodes;
|
||||
SoftBodyLinkData *m_links;
|
||||
SoftBodyFaceData *m_faces;
|
||||
SoftBodyTetraData *m_tetrahedra;
|
||||
SoftRigidAnchorData *m_anchors;
|
||||
SoftBodyClusterData *m_clusters;
|
||||
btSoftBodyJointData *m_joints;
|
||||
SoftBodyPoseData *m_pose;
|
||||
SoftBodyMaterialData **m_materials;
|
||||
SoftBodyNodeData *m_nodes;
|
||||
SoftBodyLinkData *m_links;
|
||||
SoftBodyFaceData *m_faces;
|
||||
SoftBodyTetraData *m_tetrahedra;
|
||||
SoftRigidAnchorData *m_anchors;
|
||||
SoftBodyClusterData *m_clusters;
|
||||
btSoftBodyJointData *m_joints;
|
||||
|
||||
int m_numMaterials;
|
||||
int m_numNodes;
|
||||
int m_numLinks;
|
||||
int m_numFaces;
|
||||
int m_numTetrahedra;
|
||||
int m_numAnchors;
|
||||
int m_numClusters;
|
||||
int m_numJoints;
|
||||
SoftBodyConfigData m_config;
|
||||
int m_numMaterials;
|
||||
int m_numNodes;
|
||||
int m_numLinks;
|
||||
int m_numFaces;
|
||||
int m_numTetrahedra;
|
||||
int m_numAnchors;
|
||||
int m_numClusters;
|
||||
int m_numJoints;
|
||||
SoftBodyConfigData m_config;
|
||||
};
|
||||
|
||||
#endif //BT_SOFTBODY_FLOAT_DATA
|
||||
|
||||
#endif //BT_SOFTBODY_FLOAT_DATA
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -22,127 +22,130 @@ subject to the following restrictions:
|
||||
// Helpers
|
||||
//
|
||||
|
||||
/* fDrawFlags */
|
||||
struct fDrawFlags { enum _ {
|
||||
Nodes = 0x0001,
|
||||
Links = 0x0002,
|
||||
Faces = 0x0004,
|
||||
Tetras = 0x0008,
|
||||
Normals = 0x0010,
|
||||
Contacts = 0x0020,
|
||||
Anchors = 0x0040,
|
||||
Notes = 0x0080,
|
||||
Clusters = 0x0100,
|
||||
NodeTree = 0x0200,
|
||||
FaceTree = 0x0400,
|
||||
ClusterTree = 0x0800,
|
||||
Joints = 0x1000,
|
||||
/* presets */
|
||||
Std = Links+Faces+Tetras+Anchors+Notes+Joints,
|
||||
StdTetra = Std-Faces+Tetras
|
||||
};};
|
||||
|
||||
struct btSoftBodyHelpers
|
||||
/* fDrawFlags */
|
||||
struct fDrawFlags
|
||||
{
|
||||
/* 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 cluster tree */
|
||||
static void DrawClusterTree(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( btSoftBodyWorldInfo& worldInfo,
|
||||
const btVector3& from,
|
||||
const btVector3& to,
|
||||
int res,
|
||||
int fixeds);
|
||||
/* Create a patch */
|
||||
static btSoftBody* CreatePatch(btSoftBodyWorldInfo& worldInfo,
|
||||
const btVector3& corner00,
|
||||
const btVector3& corner10,
|
||||
const btVector3& corner01,
|
||||
const btVector3& corner11,
|
||||
int resx,
|
||||
int resy,
|
||||
int fixeds,
|
||||
bool gendiags);
|
||||
/* Create a patch with UV Texture Coordinates */
|
||||
static btSoftBody* CreatePatchUV(btSoftBodyWorldInfo& worldInfo,
|
||||
const btVector3& corner00,
|
||||
const btVector3& corner10,
|
||||
const btVector3& corner01,
|
||||
const btVector3& corner11,
|
||||
int resx,
|
||||
int resy,
|
||||
int fixeds,
|
||||
bool gendiags,
|
||||
float* tex_coords=0);
|
||||
static float CalculateUV(int resx,int resy,int ix,int iy,int id);
|
||||
/* Create an ellipsoid */
|
||||
static btSoftBody* CreateEllipsoid(btSoftBodyWorldInfo& worldInfo,
|
||||
const btVector3& center,
|
||||
const btVector3& radius,
|
||||
int res);
|
||||
/* Create from trimesh */
|
||||
static btSoftBody* CreateFromTriMesh( btSoftBodyWorldInfo& worldInfo,
|
||||
const btScalar* vertices,
|
||||
const int* triangles,
|
||||
int ntriangles,
|
||||
bool randomizeConstraints = true);
|
||||
/* Create from convex-hull */
|
||||
static btSoftBody* CreateFromConvexHull( btSoftBodyWorldInfo& worldInfo,
|
||||
const btVector3* vertices,
|
||||
int nvertices,
|
||||
bool randomizeConstraints = true);
|
||||
enum _
|
||||
{
|
||||
Nodes = 0x0001,
|
||||
Links = 0x0002,
|
||||
Faces = 0x0004,
|
||||
Tetras = 0x0008,
|
||||
Normals = 0x0010,
|
||||
Contacts = 0x0020,
|
||||
Anchors = 0x0040,
|
||||
Notes = 0x0080,
|
||||
Clusters = 0x0100,
|
||||
NodeTree = 0x0200,
|
||||
FaceTree = 0x0400,
|
||||
ClusterTree = 0x0800,
|
||||
Joints = 0x1000,
|
||||
/* presets */
|
||||
Std = Links + Faces + Tetras + Anchors + Notes + Joints,
|
||||
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 cluster tree */
|
||||
static void DrawClusterTree(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(btSoftBodyWorldInfo& worldInfo,
|
||||
const btVector3& from,
|
||||
const btVector3& to,
|
||||
int res,
|
||||
int fixeds);
|
||||
/* Create a patch */
|
||||
static btSoftBody* CreatePatch(btSoftBodyWorldInfo& worldInfo,
|
||||
const btVector3& corner00,
|
||||
const btVector3& corner10,
|
||||
const btVector3& corner01,
|
||||
const btVector3& corner11,
|
||||
int resx,
|
||||
int resy,
|
||||
int fixeds,
|
||||
bool gendiags);
|
||||
/* Create a patch with UV Texture Coordinates */
|
||||
static btSoftBody* CreatePatchUV(btSoftBodyWorldInfo& worldInfo,
|
||||
const btVector3& corner00,
|
||||
const btVector3& corner10,
|
||||
const btVector3& corner01,
|
||||
const btVector3& corner11,
|
||||
int resx,
|
||||
int resy,
|
||||
int fixeds,
|
||||
bool gendiags,
|
||||
float* tex_coords = 0);
|
||||
static float CalculateUV(int resx, int resy, int ix, int iy, int id);
|
||||
/* Create an ellipsoid */
|
||||
static btSoftBody* CreateEllipsoid(btSoftBodyWorldInfo& worldInfo,
|
||||
const btVector3& center,
|
||||
const btVector3& radius,
|
||||
int res);
|
||||
/* Create from trimesh */
|
||||
static btSoftBody* CreateFromTriMesh(btSoftBodyWorldInfo& worldInfo,
|
||||
const btScalar* vertices,
|
||||
const int* triangles,
|
||||
int ntriangles,
|
||||
bool randomizeConstraints = true);
|
||||
/* Create from convex-hull */
|
||||
static btSoftBody* CreateFromConvexHull(btSoftBodyWorldInfo& worldInfo,
|
||||
const btVector3* vertices,
|
||||
int nvertices,
|
||||
bool randomizeConstraints = true);
|
||||
|
||||
/* Export TetGen compatible .smesh file */
|
||||
// static void ExportAsSMeshFile( btSoftBody* psb,
|
||||
// const char* filename);
|
||||
/* Create from TetGen .ele, .face, .node files */
|
||||
// static btSoftBody* CreateFromTetGenFile( btSoftBodyWorldInfo& worldInfo,
|
||||
// const char* ele,
|
||||
// const char* face,
|
||||
// const char* node,
|
||||
// bool bfacelinks,
|
||||
// bool btetralinks,
|
||||
// bool bfacesfromtetras);
|
||||
/* Create from TetGen .ele, .face, .node data */
|
||||
static btSoftBody* CreateFromTetGenData( btSoftBodyWorldInfo& worldInfo,
|
||||
const char* ele,
|
||||
const char* face,
|
||||
const char* node,
|
||||
bool bfacelinks,
|
||||
bool btetralinks,
|
||||
bool bfacesfromtetras);
|
||||
/* Export TetGen compatible .smesh file */
|
||||
// static void ExportAsSMeshFile( btSoftBody* psb,
|
||||
// const char* filename);
|
||||
/* Create from TetGen .ele, .face, .node files */
|
||||
// static btSoftBody* CreateFromTetGenFile( btSoftBodyWorldInfo& worldInfo,
|
||||
// const char* ele,
|
||||
// const char* face,
|
||||
// const char* node,
|
||||
// bool bfacelinks,
|
||||
// bool btetralinks,
|
||||
// bool bfacesfromtetras);
|
||||
/* Create from TetGen .ele, .face, .node data */
|
||||
static btSoftBody* CreateFromTetGenData(btSoftBodyWorldInfo& worldInfo,
|
||||
const char* ele,
|
||||
const char* face,
|
||||
const char* node,
|
||||
bool bfacelinks,
|
||||
bool btetralinks,
|
||||
bool bfacesfromtetras);
|
||||
|
||||
/// Sort the list of links to move link calculations that are dependent upon earlier
|
||||
/// ones as far as possible away from the calculation of those values
|
||||
/// This tends to make adjacent loop iterations not dependent upon one another,
|
||||
/// so out-of-order processors can execute instructions from multiple iterations at once
|
||||
static void ReoptimizeLinkOrder(btSoftBody *psb );
|
||||
static void ReoptimizeLinkOrder(btSoftBody* psb);
|
||||
};
|
||||
|
||||
#endif //BT_SOFT_BODY_HELPERS_H
|
||||
#endif //BT_SOFT_BODY_HELPERS_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -23,27 +23,27 @@ subject to the following restrictions:
|
||||
#define ENABLE_SOFTBODY_CONCAVE_COLLISIONS 1
|
||||
|
||||
btSoftBodyRigidBodyCollisionConfiguration::btSoftBodyRigidBodyCollisionConfiguration(const btDefaultCollisionConstructionInfo& constructionInfo)
|
||||
:btDefaultCollisionConfiguration(constructionInfo)
|
||||
: btDefaultCollisionConfiguration(constructionInfo)
|
||||
{
|
||||
void* mem;
|
||||
|
||||
mem = btAlignedAlloc(sizeof(btSoftSoftCollisionAlgorithm::CreateFunc),16);
|
||||
m_softSoftCreateFunc = new(mem) btSoftSoftCollisionAlgorithm::CreateFunc;
|
||||
mem = btAlignedAlloc(sizeof(btSoftSoftCollisionAlgorithm::CreateFunc), 16);
|
||||
m_softSoftCreateFunc = new (mem) btSoftSoftCollisionAlgorithm::CreateFunc;
|
||||
|
||||
mem = btAlignedAlloc(sizeof(btSoftRigidCollisionAlgorithm::CreateFunc),16);
|
||||
m_softRigidConvexCreateFunc = new(mem) btSoftRigidCollisionAlgorithm::CreateFunc;
|
||||
mem = btAlignedAlloc(sizeof(btSoftRigidCollisionAlgorithm::CreateFunc), 16);
|
||||
m_softRigidConvexCreateFunc = new (mem) btSoftRigidCollisionAlgorithm::CreateFunc;
|
||||
|
||||
mem = btAlignedAlloc(sizeof(btSoftRigidCollisionAlgorithm::CreateFunc),16);
|
||||
m_swappedSoftRigidConvexCreateFunc = new(mem) btSoftRigidCollisionAlgorithm::CreateFunc;
|
||||
m_swappedSoftRigidConvexCreateFunc->m_swapped=true;
|
||||
mem = btAlignedAlloc(sizeof(btSoftRigidCollisionAlgorithm::CreateFunc), 16);
|
||||
m_swappedSoftRigidConvexCreateFunc = new (mem) btSoftRigidCollisionAlgorithm::CreateFunc;
|
||||
m_swappedSoftRigidConvexCreateFunc->m_swapped = true;
|
||||
|
||||
#ifdef ENABLE_SOFTBODY_CONCAVE_COLLISIONS
|
||||
mem = btAlignedAlloc(sizeof(btSoftBodyConcaveCollisionAlgorithm::CreateFunc),16);
|
||||
m_softRigidConcaveCreateFunc = new(mem) btSoftBodyConcaveCollisionAlgorithm::CreateFunc;
|
||||
mem = btAlignedAlloc(sizeof(btSoftBodyConcaveCollisionAlgorithm::CreateFunc), 16);
|
||||
m_softRigidConcaveCreateFunc = new (mem) btSoftBodyConcaveCollisionAlgorithm::CreateFunc;
|
||||
|
||||
mem = btAlignedAlloc(sizeof(btSoftBodyConcaveCollisionAlgorithm::CreateFunc),16);
|
||||
m_swappedSoftRigidConcaveCreateFunc = new(mem) btSoftBodyConcaveCollisionAlgorithm::SwappedCreateFunc;
|
||||
m_swappedSoftRigidConcaveCreateFunc->m_swapped=true;
|
||||
mem = btAlignedAlloc(sizeof(btSoftBodyConcaveCollisionAlgorithm::CreateFunc), 16);
|
||||
m_swappedSoftRigidConcaveCreateFunc = new (mem) btSoftBodyConcaveCollisionAlgorithm::SwappedCreateFunc;
|
||||
m_swappedSoftRigidConcaveCreateFunc->m_swapped = true;
|
||||
#endif
|
||||
|
||||
//replace pool by a new one, with potential larger size
|
||||
@@ -53,82 +53,79 @@ btSoftBodyRigidBodyCollisionConfiguration::btSoftBodyRigidBodyCollisionConfigura
|
||||
int curElemSize = m_collisionAlgorithmPool->getElementSize();
|
||||
///calculate maximum element size, big enough to fit any collision algorithm in the memory pool
|
||||
|
||||
|
||||
int maxSize0 = sizeof(btSoftSoftCollisionAlgorithm);
|
||||
int maxSize1 = sizeof(btSoftRigidCollisionAlgorithm);
|
||||
int maxSize2 = sizeof(btSoftBodyConcaveCollisionAlgorithm);
|
||||
|
||||
int collisionAlgorithmMaxElementSize = btMax(maxSize0,maxSize1);
|
||||
collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize,maxSize2);
|
||||
|
||||
int collisionAlgorithmMaxElementSize = btMax(maxSize0, maxSize1);
|
||||
collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize, maxSize2);
|
||||
|
||||
if (collisionAlgorithmMaxElementSize > curElemSize)
|
||||
{
|
||||
m_collisionAlgorithmPool->~btPoolAllocator();
|
||||
btAlignedFree(m_collisionAlgorithmPool);
|
||||
void* mem = btAlignedAlloc(sizeof(btPoolAllocator),16);
|
||||
m_collisionAlgorithmPool = new(mem) btPoolAllocator(collisionAlgorithmMaxElementSize,constructionInfo.m_defaultMaxCollisionAlgorithmPoolSize);
|
||||
void* mem = btAlignedAlloc(sizeof(btPoolAllocator), 16);
|
||||
m_collisionAlgorithmPool = new (mem) btPoolAllocator(collisionAlgorithmMaxElementSize, constructionInfo.m_defaultMaxCollisionAlgorithmPoolSize);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
btSoftBodyRigidBodyCollisionConfiguration::~btSoftBodyRigidBodyCollisionConfiguration()
|
||||
{
|
||||
m_softSoftCreateFunc->~btCollisionAlgorithmCreateFunc();
|
||||
btAlignedFree( m_softSoftCreateFunc);
|
||||
btAlignedFree(m_softSoftCreateFunc);
|
||||
|
||||
m_softRigidConvexCreateFunc->~btCollisionAlgorithmCreateFunc();
|
||||
btAlignedFree( m_softRigidConvexCreateFunc);
|
||||
btAlignedFree(m_softRigidConvexCreateFunc);
|
||||
|
||||
m_swappedSoftRigidConvexCreateFunc->~btCollisionAlgorithmCreateFunc();
|
||||
btAlignedFree( m_swappedSoftRigidConvexCreateFunc);
|
||||
btAlignedFree(m_swappedSoftRigidConvexCreateFunc);
|
||||
|
||||
#ifdef ENABLE_SOFTBODY_CONCAVE_COLLISIONS
|
||||
m_softRigidConcaveCreateFunc->~btCollisionAlgorithmCreateFunc();
|
||||
btAlignedFree( m_softRigidConcaveCreateFunc);
|
||||
btAlignedFree(m_softRigidConcaveCreateFunc);
|
||||
|
||||
m_swappedSoftRigidConcaveCreateFunc->~btCollisionAlgorithmCreateFunc();
|
||||
btAlignedFree( m_swappedSoftRigidConcaveCreateFunc);
|
||||
btAlignedFree(m_swappedSoftRigidConcaveCreateFunc);
|
||||
#endif
|
||||
}
|
||||
|
||||
///creation of soft-soft and soft-rigid, and otherwise fallback to base class implementation
|
||||
btCollisionAlgorithmCreateFunc* btSoftBodyRigidBodyCollisionConfiguration::getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1)
|
||||
btCollisionAlgorithmCreateFunc* btSoftBodyRigidBodyCollisionConfiguration::getCollisionAlgorithmCreateFunc(int proxyType0, int proxyType1)
|
||||
{
|
||||
|
||||
///try to handle the softbody interactions first
|
||||
|
||||
if ((proxyType0 == SOFTBODY_SHAPE_PROXYTYPE ) && (proxyType1==SOFTBODY_SHAPE_PROXYTYPE))
|
||||
if ((proxyType0 == SOFTBODY_SHAPE_PROXYTYPE) && (proxyType1 == SOFTBODY_SHAPE_PROXYTYPE))
|
||||
{
|
||||
return m_softSoftCreateFunc;
|
||||
return m_softSoftCreateFunc;
|
||||
}
|
||||
|
||||
///softbody versus convex
|
||||
if (proxyType0 == SOFTBODY_SHAPE_PROXYTYPE && btBroadphaseProxy::isConvex(proxyType1))
|
||||
if (proxyType0 == SOFTBODY_SHAPE_PROXYTYPE && btBroadphaseProxy::isConvex(proxyType1))
|
||||
{
|
||||
return m_softRigidConvexCreateFunc;
|
||||
return m_softRigidConvexCreateFunc;
|
||||
}
|
||||
|
||||
///convex versus soft body
|
||||
if (btBroadphaseProxy::isConvex(proxyType0) && proxyType1 == SOFTBODY_SHAPE_PROXYTYPE )
|
||||
if (btBroadphaseProxy::isConvex(proxyType0) && proxyType1 == SOFTBODY_SHAPE_PROXYTYPE)
|
||||
{
|
||||
return m_swappedSoftRigidConvexCreateFunc;
|
||||
return m_swappedSoftRigidConvexCreateFunc;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_SOFTBODY_CONCAVE_COLLISIONS
|
||||
///softbody versus convex
|
||||
if (proxyType0 == SOFTBODY_SHAPE_PROXYTYPE && btBroadphaseProxy::isConcave(proxyType1))
|
||||
if (proxyType0 == SOFTBODY_SHAPE_PROXYTYPE && btBroadphaseProxy::isConcave(proxyType1))
|
||||
{
|
||||
return m_softRigidConcaveCreateFunc;
|
||||
return m_softRigidConcaveCreateFunc;
|
||||
}
|
||||
|
||||
///convex versus soft body
|
||||
if (btBroadphaseProxy::isConcave(proxyType0) && proxyType1 == SOFTBODY_SHAPE_PROXYTYPE )
|
||||
if (btBroadphaseProxy::isConcave(proxyType0) && proxyType1 == SOFTBODY_SHAPE_PROXYTYPE)
|
||||
{
|
||||
return m_swappedSoftRigidConcaveCreateFunc;
|
||||
return m_swappedSoftRigidConcaveCreateFunc;
|
||||
}
|
||||
#endif
|
||||
|
||||
///fallback to the regular rigid collision shape
|
||||
return btDefaultCollisionConfiguration::getCollisionAlgorithmCreateFunc(proxyType0,proxyType1);
|
||||
return btDefaultCollisionConfiguration::getCollisionAlgorithmCreateFunc(proxyType0, proxyType1);
|
||||
}
|
||||
|
||||
@@ -21,28 +21,23 @@ subject to the following restrictions:
|
||||
class btVoronoiSimplexSolver;
|
||||
class btGjkEpaPenetrationDepthSolver;
|
||||
|
||||
|
||||
///btSoftBodyRigidBodyCollisionConfiguration add softbody interaction on top of btDefaultCollisionConfiguration
|
||||
class btSoftBodyRigidBodyCollisionConfiguration : public btDefaultCollisionConfiguration
|
||||
class btSoftBodyRigidBodyCollisionConfiguration : public btDefaultCollisionConfiguration
|
||||
{
|
||||
|
||||
//default CreationFunctions, filling the m_doubleDispatch table
|
||||
btCollisionAlgorithmCreateFunc* m_softSoftCreateFunc;
|
||||
btCollisionAlgorithmCreateFunc* m_softRigidConvexCreateFunc;
|
||||
btCollisionAlgorithmCreateFunc* m_swappedSoftRigidConvexCreateFunc;
|
||||
btCollisionAlgorithmCreateFunc* m_softRigidConcaveCreateFunc;
|
||||
btCollisionAlgorithmCreateFunc* m_swappedSoftRigidConcaveCreateFunc;
|
||||
btCollisionAlgorithmCreateFunc* m_softSoftCreateFunc;
|
||||
btCollisionAlgorithmCreateFunc* m_softRigidConvexCreateFunc;
|
||||
btCollisionAlgorithmCreateFunc* m_swappedSoftRigidConvexCreateFunc;
|
||||
btCollisionAlgorithmCreateFunc* m_softRigidConcaveCreateFunc;
|
||||
btCollisionAlgorithmCreateFunc* m_swappedSoftRigidConcaveCreateFunc;
|
||||
|
||||
public:
|
||||
|
||||
btSoftBodyRigidBodyCollisionConfiguration(const btDefaultCollisionConstructionInfo& constructionInfo = btDefaultCollisionConstructionInfo());
|
||||
|
||||
virtual ~btSoftBodyRigidBodyCollisionConfiguration();
|
||||
|
||||
///creation of soft-soft and soft-rigid, and otherwise fallback to base class implementation
|
||||
virtual btCollisionAlgorithmCreateFunc* getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1);
|
||||
|
||||
virtual btCollisionAlgorithmCreateFunc* getCollisionAlgorithmCreateFunc(int proxyType0, int proxyType1);
|
||||
};
|
||||
|
||||
#endif //BT_SOFTBODY_RIGIDBODY_COLLISION_CONFIGURATION
|
||||
|
||||
#endif //BT_SOFTBODY_RIGIDBODY_COLLISION_CONFIGURATION
|
||||
|
||||
@@ -16,7 +16,6 @@ subject to the following restrictions:
|
||||
#ifndef BT_SOFT_BODY_SOLVER_VERTEX_BUFFER_H
|
||||
#define BT_SOFT_BODY_SOLVER_VERTEX_BUFFER_H
|
||||
|
||||
|
||||
class btVertexBufferDescriptor
|
||||
{
|
||||
public:
|
||||
@@ -27,8 +26,7 @@ public:
|
||||
OPENGL_BUFFER
|
||||
};
|
||||
|
||||
protected:
|
||||
|
||||
protected:
|
||||
bool m_hasVertexPositions;
|
||||
bool m_hasNormals;
|
||||
|
||||
@@ -51,7 +49,6 @@ public:
|
||||
|
||||
virtual ~btVertexBufferDescriptor()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
virtual bool hasVertexPositions() const
|
||||
@@ -102,7 +99,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class btCPUVertexBufferDescriptor : public btVertexBufferDescriptor
|
||||
{
|
||||
protected:
|
||||
@@ -114,7 +110,7 @@ public:
|
||||
* vertexOffset is the offset in floats to the first vertex.
|
||||
* vertexStride is the stride in floats between vertices.
|
||||
*/
|
||||
btCPUVertexBufferDescriptor( float *basePointer, int vertexOffset, int vertexStride )
|
||||
btCPUVertexBufferDescriptor(float *basePointer, int vertexOffset, int vertexStride)
|
||||
{
|
||||
m_basePointer = basePointer;
|
||||
m_vertexOffset = vertexOffset;
|
||||
@@ -127,7 +123,7 @@ public:
|
||||
* vertexOffset is the offset in floats to the first vertex.
|
||||
* vertexStride is the stride in floats between vertices.
|
||||
*/
|
||||
btCPUVertexBufferDescriptor( float *basePointer, int vertexOffset, int vertexStride, int normalOffset, int normalStride )
|
||||
btCPUVertexBufferDescriptor(float *basePointer, int vertexOffset, int vertexStride, int normalOffset, int normalStride)
|
||||
{
|
||||
m_basePointer = basePointer;
|
||||
|
||||
@@ -142,7 +138,6 @@ public:
|
||||
|
||||
virtual ~btCPUVertexBufferDescriptor()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -162,4 +157,4 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
#endif // #ifndef BT_SOFT_BODY_SOLVER_VERTEX_BUFFER_H
|
||||
#endif // #ifndef BT_SOFT_BODY_SOLVER_VERTEX_BUFFER_H
|
||||
|
||||
@@ -18,7 +18,6 @@ subject to the following restrictions:
|
||||
|
||||
#include "BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h"
|
||||
|
||||
|
||||
class btSoftBodyTriangleData;
|
||||
class btSoftBodyLinkData;
|
||||
class btSoftBodyVertexData;
|
||||
@@ -26,7 +25,6 @@ class btVertexBufferDescriptor;
|
||||
class btCollisionObject;
|
||||
class btSoftBody;
|
||||
|
||||
|
||||
class btSoftBodySolver
|
||||
{
|
||||
public:
|
||||
@@ -40,17 +38,15 @@ public:
|
||||
DX_SIMD_SOLVER
|
||||
};
|
||||
|
||||
|
||||
protected:
|
||||
int m_numberOfPositionIterations;
|
||||
int m_numberOfVelocityIterations;
|
||||
// Simulation timescale
|
||||
float m_timeScale;
|
||||
|
||||
|
||||
public:
|
||||
btSoftBodySolver() :
|
||||
m_numberOfPositionIterations( 10 ),
|
||||
m_timeScale( 1 )
|
||||
btSoftBodySolver() : m_numberOfPositionIterations(10),
|
||||
m_timeScale(1)
|
||||
{
|
||||
m_numberOfVelocityIterations = 0;
|
||||
m_numberOfPositionIterations = 5;
|
||||
@@ -59,39 +55,38 @@ public:
|
||||
virtual ~btSoftBodySolver()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the type of the solver.
|
||||
*/
|
||||
virtual SolverTypes getSolverType() const = 0;
|
||||
|
||||
|
||||
/** Ensure that this solver is initialized. */
|
||||
virtual bool checkInitialized() = 0;
|
||||
|
||||
/** Optimize soft bodies in this solver. */
|
||||
virtual void optimize( btAlignedObjectArray< btSoftBody * > &softBodies , bool forceUpdate=false) = 0;
|
||||
virtual void optimize(btAlignedObjectArray<btSoftBody *> &softBodies, bool forceUpdate = false) = 0;
|
||||
|
||||
/** Copy necessary data back to the original soft body source objects. */
|
||||
virtual void copyBackToSoftBodies(bool bMove = true) = 0;
|
||||
|
||||
/** Predict motion of soft bodies into next timestep */
|
||||
virtual void predictMotion( float solverdt ) = 0;
|
||||
virtual void predictMotion(float solverdt) = 0;
|
||||
|
||||
/** Solve constraints for a set of soft bodies */
|
||||
virtual void solveConstraints( float solverdt ) = 0;
|
||||
virtual void solveConstraints(float solverdt) = 0;
|
||||
|
||||
/** Perform necessary per-step updates of soft bodies such as recomputing normals and bounding boxes */
|
||||
virtual void updateSoftBodies() = 0;
|
||||
|
||||
/** Process a collision between one of the world's soft bodies and another collision object */
|
||||
virtual void processCollision( btSoftBody *, const struct btCollisionObjectWrapper* ) = 0;
|
||||
virtual void processCollision(btSoftBody *, const struct btCollisionObjectWrapper *) = 0;
|
||||
|
||||
/** Process a collision between two soft bodies */
|
||||
virtual void processCollision( btSoftBody*, btSoftBody* ) = 0;
|
||||
virtual void processCollision(btSoftBody *, btSoftBody *) = 0;
|
||||
|
||||
/** Set the number of velocity constraint solver iterations this solver uses. */
|
||||
virtual void setNumberOfPositionIterations( int iterations )
|
||||
virtual void setNumberOfPositionIterations(int iterations)
|
||||
{
|
||||
m_numberOfPositionIterations = iterations;
|
||||
}
|
||||
@@ -103,7 +98,7 @@ public:
|
||||
}
|
||||
|
||||
/** Set the number of velocity constraint solver iterations this solver uses. */
|
||||
virtual void setNumberOfVelocityIterations( int iterations )
|
||||
virtual void setNumberOfVelocityIterations(int iterations)
|
||||
{
|
||||
m_numberOfVelocityIterations = iterations;
|
||||
}
|
||||
@@ -135,7 +130,6 @@ public:
|
||||
class btSoftBodySolverOutput
|
||||
{
|
||||
protected:
|
||||
|
||||
public:
|
||||
btSoftBodySolverOutput()
|
||||
{
|
||||
@@ -145,10 +139,8 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/** Output current computed vertex data to the vertex buffers for all cloths in the solver. */
|
||||
virtual void copySoftBodyToVertexBuffer( const btSoftBody * const softBody, btVertexBufferDescriptor *vertexBuffer ) = 0;
|
||||
virtual void copySoftBodyToVertexBuffer(const btSoftBody *const softBody, btVertexBufferDescriptor *vertexBuffer) = 0;
|
||||
};
|
||||
|
||||
|
||||
#endif // #ifndef BT_SOFT_BODY_SOLVERS_H
|
||||
#endif // #ifndef BT_SOFT_BODY_SOLVERS_H
|
||||
|
||||
@@ -13,7 +13,6 @@ subject to the following restrictions:
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
#include "btSoftMultiBodyDynamicsWorld.h"
|
||||
#include "LinearMath/btQuickprof.h"
|
||||
|
||||
@@ -24,42 +23,38 @@ subject to the following restrictions:
|
||||
#include "BulletSoftBody/btDefaultSoftBodySolver.h"
|
||||
#include "LinearMath/btSerializer.h"
|
||||
|
||||
|
||||
btSoftMultiBodyDynamicsWorld::btSoftMultiBodyDynamicsWorld(
|
||||
btDispatcher* dispatcher,
|
||||
btBroadphaseInterface* pairCache,
|
||||
btMultiBodyConstraintSolver* constraintSolver,
|
||||
btCollisionConfiguration* collisionConfiguration,
|
||||
btSoftBodySolver *softBodySolver ) :
|
||||
btMultiBodyDynamicsWorld(dispatcher,pairCache,constraintSolver,collisionConfiguration),
|
||||
m_softBodySolver( softBodySolver ),
|
||||
m_ownsSolver(false)
|
||||
btSoftBodySolver* softBodySolver) : btMultiBodyDynamicsWorld(dispatcher, pairCache, constraintSolver, collisionConfiguration),
|
||||
m_softBodySolver(softBodySolver),
|
||||
m_ownsSolver(false)
|
||||
{
|
||||
if( !m_softBodySolver )
|
||||
if (!m_softBodySolver)
|
||||
{
|
||||
void* ptr = btAlignedAlloc(sizeof(btDefaultSoftBodySolver),16);
|
||||
m_softBodySolver = new(ptr) btDefaultSoftBodySolver();
|
||||
void* ptr = btAlignedAlloc(sizeof(btDefaultSoftBodySolver), 16);
|
||||
m_softBodySolver = new (ptr) btDefaultSoftBodySolver();
|
||||
m_ownsSolver = true;
|
||||
}
|
||||
|
||||
m_drawFlags = fDrawFlags::Std;
|
||||
m_drawNodeTree = true;
|
||||
m_drawFaceTree = false;
|
||||
m_drawClusterTree = false;
|
||||
m_drawFlags = fDrawFlags::Std;
|
||||
m_drawNodeTree = true;
|
||||
m_drawFaceTree = false;
|
||||
m_drawClusterTree = false;
|
||||
m_sbi.m_broadphase = pairCache;
|
||||
m_sbi.m_dispatcher = dispatcher;
|
||||
m_sbi.m_sparsesdf.Initialize();
|
||||
m_sbi.m_sparsesdf.Reset();
|
||||
|
||||
m_sbi.air_density = (btScalar)1.2;
|
||||
m_sbi.water_density = 0;
|
||||
m_sbi.water_offset = 0;
|
||||
m_sbi.water_normal = btVector3(0,0,0);
|
||||
m_sbi.m_gravity.setValue(0,-10,0);
|
||||
m_sbi.air_density = (btScalar)1.2;
|
||||
m_sbi.water_density = 0;
|
||||
m_sbi.water_offset = 0;
|
||||
m_sbi.water_normal = btVector3(0, 0, 0);
|
||||
m_sbi.m_gravity.setValue(0, -10, 0);
|
||||
|
||||
m_sbi.m_sparsesdf.Initialize();
|
||||
|
||||
|
||||
}
|
||||
|
||||
btSoftMultiBodyDynamicsWorld::~btSoftMultiBodyDynamicsWorld()
|
||||
@@ -71,82 +66,78 @@ btSoftMultiBodyDynamicsWorld::~btSoftMultiBodyDynamicsWorld()
|
||||
}
|
||||
}
|
||||
|
||||
void btSoftMultiBodyDynamicsWorld::predictUnconstraintMotion(btScalar timeStep)
|
||||
void btSoftMultiBodyDynamicsWorld::predictUnconstraintMotion(btScalar timeStep)
|
||||
{
|
||||
btDiscreteDynamicsWorld::predictUnconstraintMotion( timeStep );
|
||||
btDiscreteDynamicsWorld::predictUnconstraintMotion(timeStep);
|
||||
{
|
||||
BT_PROFILE("predictUnconstraintMotionSoftBody");
|
||||
m_softBodySolver->predictMotion( float(timeStep) );
|
||||
m_softBodySolver->predictMotion(float(timeStep));
|
||||
}
|
||||
}
|
||||
|
||||
void btSoftMultiBodyDynamicsWorld::internalSingleStepSimulation( btScalar timeStep )
|
||||
void btSoftMultiBodyDynamicsWorld::internalSingleStepSimulation(btScalar timeStep)
|
||||
{
|
||||
|
||||
// Let the solver grab the soft bodies and if necessary optimize for it
|
||||
m_softBodySolver->optimize( getSoftBodyArray() );
|
||||
m_softBodySolver->optimize(getSoftBodyArray());
|
||||
|
||||
if( !m_softBodySolver->checkInitialized() )
|
||||
if (!m_softBodySolver->checkInitialized())
|
||||
{
|
||||
btAssert( "Solver initialization failed\n" );
|
||||
btAssert("Solver initialization failed\n");
|
||||
}
|
||||
|
||||
btDiscreteDynamicsWorld::internalSingleStepSimulation( timeStep );
|
||||
btDiscreteDynamicsWorld::internalSingleStepSimulation(timeStep);
|
||||
|
||||
///solve soft bodies constraints
|
||||
solveSoftBodiesConstraints( timeStep );
|
||||
solveSoftBodiesConstraints(timeStep);
|
||||
|
||||
//self collisions
|
||||
for ( int i=0;i<m_softBodies.size();i++)
|
||||
for (int i = 0; i < m_softBodies.size(); i++)
|
||||
{
|
||||
btSoftBody* psb=(btSoftBody*)m_softBodies[i];
|
||||
btSoftBody* psb = (btSoftBody*)m_softBodies[i];
|
||||
psb->defaultCollisionHandler(psb);
|
||||
}
|
||||
|
||||
///update soft bodies
|
||||
m_softBodySolver->updateSoftBodies( );
|
||||
|
||||
m_softBodySolver->updateSoftBodies();
|
||||
|
||||
// End solver-wise simulation step
|
||||
// ///////////////////////////////
|
||||
|
||||
}
|
||||
|
||||
void btSoftMultiBodyDynamicsWorld::solveSoftBodiesConstraints( btScalar timeStep )
|
||||
void btSoftMultiBodyDynamicsWorld::solveSoftBodiesConstraints(btScalar timeStep)
|
||||
{
|
||||
BT_PROFILE("solveSoftConstraints");
|
||||
|
||||
if(m_softBodies.size())
|
||||
if (m_softBodies.size())
|
||||
{
|
||||
btSoftBody::solveClusters(m_softBodies);
|
||||
}
|
||||
|
||||
// Solve constraints solver-wise
|
||||
m_softBodySolver->solveConstraints( timeStep * m_softBodySolver->getTimeScale() );
|
||||
|
||||
m_softBodySolver->solveConstraints(timeStep * m_softBodySolver->getTimeScale());
|
||||
}
|
||||
|
||||
void btSoftMultiBodyDynamicsWorld::addSoftBody(btSoftBody* body, int collisionFilterGroup, int collisionFilterMask)
|
||||
void btSoftMultiBodyDynamicsWorld::addSoftBody(btSoftBody* body, int collisionFilterGroup, int collisionFilterMask)
|
||||
{
|
||||
m_softBodies.push_back(body);
|
||||
|
||||
// Set the soft body solver that will deal with this body
|
||||
// to be the world's solver
|
||||
body->setSoftBodySolver( m_softBodySolver );
|
||||
body->setSoftBodySolver(m_softBodySolver);
|
||||
|
||||
btCollisionWorld::addCollisionObject(body,
|
||||
collisionFilterGroup,
|
||||
collisionFilterMask);
|
||||
|
||||
collisionFilterGroup,
|
||||
collisionFilterMask);
|
||||
}
|
||||
|
||||
void btSoftMultiBodyDynamicsWorld::removeSoftBody(btSoftBody* body)
|
||||
void btSoftMultiBodyDynamicsWorld::removeSoftBody(btSoftBody* body)
|
||||
{
|
||||
m_softBodies.remove(body);
|
||||
|
||||
btCollisionWorld::removeCollisionObject(body);
|
||||
}
|
||||
|
||||
void btSoftMultiBodyDynamicsWorld::removeCollisionObject(btCollisionObject* collisionObject)
|
||||
void btSoftMultiBodyDynamicsWorld::removeCollisionObject(btCollisionObject* collisionObject)
|
||||
{
|
||||
btSoftBody* body = btSoftBody::upcast(collisionObject);
|
||||
if (body)
|
||||
@@ -155,60 +146,57 @@ void btSoftMultiBodyDynamicsWorld::removeCollisionObject(btCollisionObject* coll
|
||||
btDiscreteDynamicsWorld::removeCollisionObject(collisionObject);
|
||||
}
|
||||
|
||||
void btSoftMultiBodyDynamicsWorld::debugDrawWorld()
|
||||
void btSoftMultiBodyDynamicsWorld::debugDrawWorld()
|
||||
{
|
||||
btMultiBodyDynamicsWorld::debugDrawWorld();
|
||||
|
||||
if (getDebugDrawer())
|
||||
{
|
||||
int i;
|
||||
for ( i=0;i<this->m_softBodies.size();i++)
|
||||
for (i = 0; i < this->m_softBodies.size(); i++)
|
||||
{
|
||||
btSoftBody* psb=(btSoftBody*)this->m_softBodies[i];
|
||||
btSoftBody* psb = (btSoftBody*)this->m_softBodies[i];
|
||||
if (getDebugDrawer() && (getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe)))
|
||||
{
|
||||
btSoftBodyHelpers::DrawFrame(psb,m_debugDrawer);
|
||||
btSoftBodyHelpers::Draw(psb,m_debugDrawer,m_drawFlags);
|
||||
btSoftBodyHelpers::DrawFrame(psb, m_debugDrawer);
|
||||
btSoftBodyHelpers::Draw(psb, m_debugDrawer, m_drawFlags);
|
||||
}
|
||||
|
||||
|
||||
if (m_debugDrawer && (m_debugDrawer->getDebugMode() & btIDebugDraw::DBG_DrawAabb))
|
||||
{
|
||||
if(m_drawNodeTree) btSoftBodyHelpers::DrawNodeTree(psb,m_debugDrawer);
|
||||
if(m_drawFaceTree) btSoftBodyHelpers::DrawFaceTree(psb,m_debugDrawer);
|
||||
if(m_drawClusterTree) btSoftBodyHelpers::DrawClusterTree(psb,m_debugDrawer);
|
||||
if (m_drawNodeTree) btSoftBodyHelpers::DrawNodeTree(psb, m_debugDrawer);
|
||||
if (m_drawFaceTree) btSoftBodyHelpers::DrawFaceTree(psb, m_debugDrawer);
|
||||
if (m_drawClusterTree) btSoftBodyHelpers::DrawClusterTree(psb, m_debugDrawer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
struct btSoftSingleRayCallback : public btBroadphaseRayCallback
|
||||
{
|
||||
btVector3 m_rayFromWorld;
|
||||
btVector3 m_rayToWorld;
|
||||
btTransform m_rayFromTrans;
|
||||
btTransform m_rayToTrans;
|
||||
btVector3 m_hitNormal;
|
||||
btVector3 m_rayFromWorld;
|
||||
btVector3 m_rayToWorld;
|
||||
btTransform m_rayFromTrans;
|
||||
btTransform m_rayToTrans;
|
||||
btVector3 m_hitNormal;
|
||||
|
||||
const btSoftMultiBodyDynamicsWorld* m_world;
|
||||
btCollisionWorld::RayResultCallback& m_resultCallback;
|
||||
const btSoftMultiBodyDynamicsWorld* m_world;
|
||||
btCollisionWorld::RayResultCallback& m_resultCallback;
|
||||
|
||||
btSoftSingleRayCallback(const btVector3& rayFromWorld,const btVector3& rayToWorld,const btSoftMultiBodyDynamicsWorld* world,btCollisionWorld::RayResultCallback& resultCallback)
|
||||
:m_rayFromWorld(rayFromWorld),
|
||||
m_rayToWorld(rayToWorld),
|
||||
m_world(world),
|
||||
m_resultCallback(resultCallback)
|
||||
btSoftSingleRayCallback(const btVector3& rayFromWorld, const btVector3& rayToWorld, const btSoftMultiBodyDynamicsWorld* world, btCollisionWorld::RayResultCallback& resultCallback)
|
||||
: m_rayFromWorld(rayFromWorld),
|
||||
m_rayToWorld(rayToWorld),
|
||||
m_world(world),
|
||||
m_resultCallback(resultCallback)
|
||||
{
|
||||
m_rayFromTrans.setIdentity();
|
||||
m_rayFromTrans.setOrigin(m_rayFromWorld);
|
||||
m_rayToTrans.setIdentity();
|
||||
m_rayToTrans.setOrigin(m_rayToWorld);
|
||||
|
||||
btVector3 rayDir = (rayToWorld-rayFromWorld);
|
||||
btVector3 rayDir = (rayToWorld - rayFromWorld);
|
||||
|
||||
rayDir.normalize ();
|
||||
rayDir.normalize();
|
||||
///what about division by zero? --> just set rayDirection[i] to INF/1e30
|
||||
m_rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[0];
|
||||
m_rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[1];
|
||||
@@ -217,22 +205,19 @@ struct btSoftSingleRayCallback : public btBroadphaseRayCallback
|
||||
m_signs[1] = m_rayDirectionInverse[1] < 0.0;
|
||||
m_signs[2] = m_rayDirectionInverse[2] < 0.0;
|
||||
|
||||
m_lambda_max = rayDir.dot(m_rayToWorld-m_rayFromWorld);
|
||||
|
||||
m_lambda_max = rayDir.dot(m_rayToWorld - m_rayFromWorld);
|
||||
}
|
||||
|
||||
|
||||
|
||||
virtual bool process(const btBroadphaseProxy* proxy)
|
||||
virtual bool process(const btBroadphaseProxy* proxy)
|
||||
{
|
||||
///terminate further ray tests, once the closestHitFraction reached zero
|
||||
if (m_resultCallback.m_closestHitFraction == btScalar(0.f))
|
||||
return false;
|
||||
|
||||
btCollisionObject* collisionObject = (btCollisionObject*)proxy->m_clientObject;
|
||||
btCollisionObject* collisionObject = (btCollisionObject*)proxy->m_clientObject;
|
||||
|
||||
//only perform raycast if filterMask matches
|
||||
if(m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle()))
|
||||
if (m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle()))
|
||||
{
|
||||
//RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
|
||||
//btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
|
||||
@@ -250,110 +235,106 @@ struct btSoftSingleRayCallback : public btBroadphaseRayCallback
|
||||
//culling already done by broadphase
|
||||
//if (btRayAabb(m_rayFromWorld,m_rayToWorld,collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,m_hitNormal))
|
||||
{
|
||||
m_world->rayTestSingle(m_rayFromTrans,m_rayToTrans,
|
||||
collisionObject,
|
||||
collisionObject->getCollisionShape(),
|
||||
collisionObject->getWorldTransform(),
|
||||
m_resultCallback);
|
||||
m_world->rayTestSingle(m_rayFromTrans, m_rayToTrans,
|
||||
collisionObject,
|
||||
collisionObject->getCollisionShape(),
|
||||
collisionObject->getWorldTransform(),
|
||||
m_resultCallback);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
void btSoftMultiBodyDynamicsWorld::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const
|
||||
void btSoftMultiBodyDynamicsWorld::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const
|
||||
{
|
||||
BT_PROFILE("rayTest");
|
||||
/// use the broadphase to accelerate the search for objects, based on their aabb
|
||||
/// and for each object with ray-aabb overlap, perform an exact ray test
|
||||
btSoftSingleRayCallback rayCB(rayFromWorld,rayToWorld,this,resultCallback);
|
||||
btSoftSingleRayCallback rayCB(rayFromWorld, rayToWorld, this, resultCallback);
|
||||
|
||||
#ifndef USE_BRUTEFORCE_RAYBROADPHASE
|
||||
m_broadphasePairCache->rayTest(rayFromWorld,rayToWorld,rayCB);
|
||||
m_broadphasePairCache->rayTest(rayFromWorld, rayToWorld, rayCB);
|
||||
#else
|
||||
for (int i=0;i<this->getNumCollisionObjects();i++)
|
||||
for (int i = 0; i < this->getNumCollisionObjects(); i++)
|
||||
{
|
||||
rayCB.process(m_collisionObjects[i]->getBroadphaseHandle());
|
||||
}
|
||||
#endif //USE_BRUTEFORCE_RAYBROADPHASE
|
||||
|
||||
}
|
||||
#endif //USE_BRUTEFORCE_RAYBROADPHASE
|
||||
}
|
||||
|
||||
|
||||
void btSoftMultiBodyDynamicsWorld::rayTestSingle(const btTransform& rayFromTrans,const btTransform& rayToTrans,
|
||||
btCollisionObject* collisionObject,
|
||||
const btCollisionShape* collisionShape,
|
||||
const btTransform& colObjWorldTransform,
|
||||
RayResultCallback& resultCallback)
|
||||
void btSoftMultiBodyDynamicsWorld::rayTestSingle(const btTransform& rayFromTrans, const btTransform& rayToTrans,
|
||||
btCollisionObject* collisionObject,
|
||||
const btCollisionShape* collisionShape,
|
||||
const btTransform& colObjWorldTransform,
|
||||
RayResultCallback& resultCallback)
|
||||
{
|
||||
if (collisionShape->isSoftBody()) {
|
||||
if (collisionShape->isSoftBody())
|
||||
{
|
||||
btSoftBody* softBody = btSoftBody::upcast(collisionObject);
|
||||
if (softBody) {
|
||||
if (softBody)
|
||||
{
|
||||
btSoftBody::sRayCast softResult;
|
||||
if (softBody->rayTest(rayFromTrans.getOrigin(), rayToTrans.getOrigin(), softResult))
|
||||
if (softBody->rayTest(rayFromTrans.getOrigin(), rayToTrans.getOrigin(), softResult))
|
||||
{
|
||||
|
||||
if (softResult.fraction<= resultCallback.m_closestHitFraction)
|
||||
if (softResult.fraction <= resultCallback.m_closestHitFraction)
|
||||
{
|
||||
|
||||
btCollisionWorld::LocalShapeInfo shapeInfo;
|
||||
shapeInfo.m_shapePart = 0;
|
||||
shapeInfo.m_triangleIndex = softResult.index;
|
||||
// get the normal
|
||||
btVector3 rayDir = rayToTrans.getOrigin() - rayFromTrans.getOrigin();
|
||||
btVector3 normal=-rayDir;
|
||||
btVector3 normal = -rayDir;
|
||||
normal.normalize();
|
||||
|
||||
if (softResult.feature == btSoftBody::eFeature::Face)
|
||||
{
|
||||
normal = softBody->m_faces[softResult.index].m_normal;
|
||||
if (normal.dot(rayDir) > 0) {
|
||||
if (normal.dot(rayDir) > 0)
|
||||
{
|
||||
// normal always point toward origin of the ray
|
||||
normal = -normal;
|
||||
}
|
||||
}
|
||||
|
||||
btCollisionWorld::LocalRayResult rayResult
|
||||
(collisionObject,
|
||||
&shapeInfo,
|
||||
normal,
|
||||
softResult.fraction);
|
||||
bool normalInWorldSpace = true;
|
||||
resultCallback.addSingleResult(rayResult,normalInWorldSpace);
|
||||
|
||||
btCollisionWorld::LocalRayResult rayResult(collisionObject,
|
||||
&shapeInfo,
|
||||
normal,
|
||||
softResult.fraction);
|
||||
bool normalInWorldSpace = true;
|
||||
resultCallback.addSingleResult(rayResult, normalInWorldSpace);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
btCollisionWorld::rayTestSingle(rayFromTrans,rayToTrans,collisionObject,collisionShape,colObjWorldTransform,resultCallback);
|
||||
}
|
||||
else
|
||||
{
|
||||
btCollisionWorld::rayTestSingle(rayFromTrans, rayToTrans, collisionObject, collisionShape, colObjWorldTransform, resultCallback);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void btSoftMultiBodyDynamicsWorld::serializeSoftBodies(btSerializer* serializer)
|
||||
void btSoftMultiBodyDynamicsWorld::serializeSoftBodies(btSerializer* serializer)
|
||||
{
|
||||
int i;
|
||||
//serialize all collision objects
|
||||
for (i=0;i<m_collisionObjects.size();i++)
|
||||
for (i = 0; i < m_collisionObjects.size(); i++)
|
||||
{
|
||||
btCollisionObject* colObj = m_collisionObjects[i];
|
||||
if (colObj->getInternalType() & btCollisionObject::CO_SOFT_BODY)
|
||||
{
|
||||
int len = colObj->calculateSerializeBufferSize();
|
||||
btChunk* chunk = serializer->allocate(len,1);
|
||||
btChunk* chunk = serializer->allocate(len, 1);
|
||||
const char* structType = colObj->serialize(chunk->m_oldPtr, serializer);
|
||||
serializer->finalizeChunk(chunk,structType,BT_SOFTBODY_CODE,colObj);
|
||||
serializer->finalizeChunk(chunk, structType, BT_SOFTBODY_CODE, colObj);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void btSoftMultiBodyDynamicsWorld::serialize(btSerializer* serializer)
|
||||
void btSoftMultiBodyDynamicsWorld::serialize(btSerializer* serializer)
|
||||
{
|
||||
|
||||
serializer->startSerialization();
|
||||
|
||||
serializeDynamicsWorldInfo( serializer);
|
||||
serializeDynamicsWorldInfo(serializer);
|
||||
|
||||
serializeSoftBodies(serializer);
|
||||
|
||||
@@ -367,5 +348,3 @@ void btSoftMultiBodyDynamicsWorld::serialize(btSerializer* serializer)
|
||||
|
||||
serializer->finishSerialization();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -21,64 +21,61 @@ subject to the following restrictions:
|
||||
#include "BulletSoftBody/btSoftBody.h"
|
||||
|
||||
#ifndef BT_SOFT_RIGID_DYNAMICS_WORLD_H
|
||||
typedef btAlignedObjectArray<btSoftBody*> btSoftBodyArray;
|
||||
typedef btAlignedObjectArray<btSoftBody*> btSoftBodyArray;
|
||||
#endif
|
||||
|
||||
class btSoftBodySolver;
|
||||
|
||||
class btSoftMultiBodyDynamicsWorld : public btMultiBodyDynamicsWorld
|
||||
{
|
||||
|
||||
btSoftBodyArray m_softBodies;
|
||||
int m_drawFlags;
|
||||
bool m_drawNodeTree;
|
||||
bool m_drawFaceTree;
|
||||
bool m_drawClusterTree;
|
||||
btSoftBodyArray m_softBodies;
|
||||
int m_drawFlags;
|
||||
bool m_drawNodeTree;
|
||||
bool m_drawFaceTree;
|
||||
bool m_drawClusterTree;
|
||||
btSoftBodyWorldInfo m_sbi;
|
||||
///Solver classes that encapsulate multiple soft bodies for solving
|
||||
btSoftBodySolver *m_softBodySolver;
|
||||
bool m_ownsSolver;
|
||||
btSoftBodySolver* m_softBodySolver;
|
||||
bool m_ownsSolver;
|
||||
|
||||
protected:
|
||||
virtual void predictUnconstraintMotion(btScalar timeStep);
|
||||
|
||||
virtual void predictUnconstraintMotion(btScalar timeStep);
|
||||
virtual void internalSingleStepSimulation(btScalar timeStep);
|
||||
|
||||
virtual void internalSingleStepSimulation( btScalar timeStep);
|
||||
void solveSoftBodiesConstraints(btScalar timeStep);
|
||||
|
||||
void solveSoftBodiesConstraints( btScalar timeStep );
|
||||
|
||||
void serializeSoftBodies(btSerializer* serializer);
|
||||
void serializeSoftBodies(btSerializer* serializer);
|
||||
|
||||
public:
|
||||
|
||||
btSoftMultiBodyDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btMultiBodyConstraintSolver* constraintSolver, btCollisionConfiguration* collisionConfiguration, btSoftBodySolver *softBodySolver = 0 );
|
||||
btSoftMultiBodyDynamicsWorld(btDispatcher* dispatcher, btBroadphaseInterface* pairCache, btMultiBodyConstraintSolver* constraintSolver, btCollisionConfiguration* collisionConfiguration, btSoftBodySolver* softBodySolver = 0);
|
||||
|
||||
virtual ~btSoftMultiBodyDynamicsWorld();
|
||||
|
||||
virtual void debugDrawWorld();
|
||||
virtual void debugDrawWorld();
|
||||
|
||||
void addSoftBody(btSoftBody* body, int collisionFilterGroup=btBroadphaseProxy::DefaultFilter, int collisionFilterMask=btBroadphaseProxy::AllFilter);
|
||||
void addSoftBody(btSoftBody* body, int collisionFilterGroup = btBroadphaseProxy::DefaultFilter, int collisionFilterMask = btBroadphaseProxy::AllFilter);
|
||||
|
||||
void removeSoftBody(btSoftBody* body);
|
||||
void removeSoftBody(btSoftBody* body);
|
||||
|
||||
///removeCollisionObject will first check if it is a rigid body, if so call removeRigidBody otherwise call btDiscreteDynamicsWorld::removeCollisionObject
|
||||
virtual void removeCollisionObject(btCollisionObject* collisionObject);
|
||||
virtual void removeCollisionObject(btCollisionObject* collisionObject);
|
||||
|
||||
int getDrawFlags() const { return(m_drawFlags); }
|
||||
void setDrawFlags(int f) { m_drawFlags=f; }
|
||||
int getDrawFlags() const { return (m_drawFlags); }
|
||||
void setDrawFlags(int f) { m_drawFlags = f; }
|
||||
|
||||
btSoftBodyWorldInfo& getWorldInfo()
|
||||
btSoftBodyWorldInfo& getWorldInfo()
|
||||
{
|
||||
return m_sbi;
|
||||
}
|
||||
const btSoftBodyWorldInfo& getWorldInfo() const
|
||||
const btSoftBodyWorldInfo& getWorldInfo() const
|
||||
{
|
||||
return m_sbi;
|
||||
}
|
||||
|
||||
virtual btDynamicsWorldType getWorldType() const
|
||||
virtual btDynamicsWorldType getWorldType() const
|
||||
{
|
||||
return BT_SOFT_MULTIBODY_DYNAMICS_WORLD;
|
||||
return BT_SOFT_MULTIBODY_DYNAMICS_WORLD;
|
||||
}
|
||||
|
||||
btSoftBodyArray& getSoftBodyArray()
|
||||
@@ -91,20 +88,18 @@ public:
|
||||
return m_softBodies;
|
||||
}
|
||||
|
||||
|
||||
virtual void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const;
|
||||
virtual void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const;
|
||||
|
||||
/// rayTestSingle performs a raycast call and calls the resultCallback. It is used internally by rayTest.
|
||||
/// In a future implementation, we consider moving the ray test as a virtual method in btCollisionShape.
|
||||
/// This allows more customization.
|
||||
static void rayTestSingle(const btTransform& rayFromTrans,const btTransform& rayToTrans,
|
||||
btCollisionObject* collisionObject,
|
||||
const btCollisionShape* collisionShape,
|
||||
const btTransform& colObjWorldTransform,
|
||||
RayResultCallback& resultCallback);
|
||||
|
||||
virtual void serialize(btSerializer* serializer);
|
||||
static void rayTestSingle(const btTransform& rayFromTrans, const btTransform& rayToTrans,
|
||||
btCollisionObject* collisionObject,
|
||||
const btCollisionShape* collisionShape,
|
||||
const btTransform& colObjWorldTransform,
|
||||
RayResultCallback& resultCallback);
|
||||
|
||||
virtual void serialize(btSerializer* serializer);
|
||||
};
|
||||
|
||||
#endif //BT_SOFT_MULTIBODY_DYNAMICS_WORLD_H
|
||||
#endif //BT_SOFT_MULTIBODY_DYNAMICS_WORLD_H
|
||||
|
||||
@@ -27,18 +27,16 @@ subject to the following restrictions:
|
||||
|
||||
//#include <stdio.h>
|
||||
|
||||
btSoftRigidCollisionAlgorithm::btSoftRigidCollisionAlgorithm(btPersistentManifold* /*mf*/,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* ,const btCollisionObjectWrapper* , bool isSwapped)
|
||||
: btCollisionAlgorithm(ci),
|
||||
//m_ownManifold(false),
|
||||
//m_manifoldPtr(mf),
|
||||
m_isSwapped(isSwapped)
|
||||
btSoftRigidCollisionAlgorithm::btSoftRigidCollisionAlgorithm(btPersistentManifold* /*mf*/, const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper*, const btCollisionObjectWrapper*, bool isSwapped)
|
||||
: btCollisionAlgorithm(ci),
|
||||
//m_ownManifold(false),
|
||||
//m_manifoldPtr(mf),
|
||||
m_isSwapped(isSwapped)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
btSoftRigidCollisionAlgorithm::~btSoftRigidCollisionAlgorithm()
|
||||
{
|
||||
|
||||
//m_softBody->m_overlappingRigidBodies.remove(m_rigidCollisionObject);
|
||||
|
||||
/*if (m_ownManifold)
|
||||
@@ -47,31 +45,27 @@ btSoftRigidCollisionAlgorithm::~btSoftRigidCollisionAlgorithm()
|
||||
m_dispatcher->releaseManifold(m_manifoldPtr);
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
void btSoftRigidCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
|
||||
void btSoftRigidCollisionAlgorithm::processCollision(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut)
|
||||
{
|
||||
(void)dispatchInfo;
|
||||
(void)resultOut;
|
||||
//printf("btSoftRigidCollisionAlgorithm\n");
|
||||
// const btCollisionObjectWrapper* softWrap = m_isSwapped?body1Wrap:body0Wrap;
|
||||
// const btCollisionObjectWrapper* rigidWrap = m_isSwapped?body0Wrap:body1Wrap;
|
||||
btSoftBody* softBody = m_isSwapped? (btSoftBody*)body1Wrap->getCollisionObject() : (btSoftBody*)body0Wrap->getCollisionObject();
|
||||
const btCollisionObjectWrapper* rigidCollisionObjectWrap = m_isSwapped? body0Wrap : body1Wrap;
|
||||
|
||||
if (softBody->m_collisionDisabledObjects.findLinearSearch(rigidCollisionObjectWrap->getCollisionObject())==softBody->m_collisionDisabledObjects.size())
|
||||
// const btCollisionObjectWrapper* softWrap = m_isSwapped?body1Wrap:body0Wrap;
|
||||
// const btCollisionObjectWrapper* rigidWrap = m_isSwapped?body0Wrap:body1Wrap;
|
||||
btSoftBody* softBody = m_isSwapped ? (btSoftBody*)body1Wrap->getCollisionObject() : (btSoftBody*)body0Wrap->getCollisionObject();
|
||||
const btCollisionObjectWrapper* rigidCollisionObjectWrap = m_isSwapped ? body0Wrap : body1Wrap;
|
||||
|
||||
if (softBody->m_collisionDisabledObjects.findLinearSearch(rigidCollisionObjectWrap->getCollisionObject()) == softBody->m_collisionDisabledObjects.size())
|
||||
{
|
||||
softBody->getSoftBodySolver()->processCollision(softBody, rigidCollisionObjectWrap);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
btScalar btSoftRigidCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
|
||||
btScalar btSoftRigidCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* col0, btCollisionObject* col1, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut)
|
||||
{
|
||||
(void)resultOut;
|
||||
(void)dispatchInfo;
|
||||
@@ -81,6 +75,3 @@ btScalar btSoftRigidCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject*
|
||||
//not yet
|
||||
return btScalar(1.);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -35,41 +35,37 @@ class btSoftRigidCollisionAlgorithm : public btCollisionAlgorithm
|
||||
//btCollisionObject* m_rigidCollisionObject;
|
||||
|
||||
///for rigid versus soft (instead of soft versus rigid), we use this swapped boolean
|
||||
bool m_isSwapped;
|
||||
bool m_isSwapped;
|
||||
|
||||
public:
|
||||
|
||||
btSoftRigidCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* col0,const btCollisionObjectWrapper* col1Wrap, bool isSwapped);
|
||||
btSoftRigidCollisionAlgorithm(btPersistentManifold* mf, const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* col0, const btCollisionObjectWrapper* col1Wrap, bool isSwapped);
|
||||
|
||||
virtual ~btSoftRigidCollisionAlgorithm();
|
||||
|
||||
virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
|
||||
virtual void processCollision(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut);
|
||||
|
||||
virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
|
||||
virtual btScalar calculateTimeOfImpact(btCollisionObject* body0, btCollisionObject* body1, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut);
|
||||
|
||||
virtual void getAllContactManifolds(btManifoldArray& manifoldArray)
|
||||
virtual void getAllContactManifolds(btManifoldArray& manifoldArray)
|
||||
{
|
||||
//we don't add any manifolds
|
||||
}
|
||||
|
||||
|
||||
struct CreateFunc :public btCollisionAlgorithmCreateFunc
|
||||
struct CreateFunc : public btCollisionAlgorithmCreateFunc
|
||||
{
|
||||
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
|
||||
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap)
|
||||
{
|
||||
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btSoftRigidCollisionAlgorithm));
|
||||
if (!m_swapped)
|
||||
{
|
||||
return new(mem) btSoftRigidCollisionAlgorithm(0,ci,body0Wrap,body1Wrap,false);
|
||||
} else
|
||||
return new (mem) btSoftRigidCollisionAlgorithm(0, ci, body0Wrap, body1Wrap, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new(mem) btSoftRigidCollisionAlgorithm(0,ci,body0Wrap,body1Wrap,true);
|
||||
return new (mem) btSoftRigidCollisionAlgorithm(0, ci, body0Wrap, body1Wrap, true);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif //BT_SOFT_RIGID_COLLISION_ALGORITHM_H
|
||||
|
||||
|
||||
#endif //BT_SOFT_RIGID_COLLISION_ALGORITHM_H
|
||||
|
||||
@@ -13,7 +13,6 @@ subject to the following restrictions:
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
#include "btSoftRigidDynamicsWorld.h"
|
||||
#include "LinearMath/btQuickprof.h"
|
||||
|
||||
@@ -24,42 +23,38 @@ subject to the following restrictions:
|
||||
#include "btDefaultSoftBodySolver.h"
|
||||
#include "LinearMath/btSerializer.h"
|
||||
|
||||
|
||||
btSoftRigidDynamicsWorld::btSoftRigidDynamicsWorld(
|
||||
btDispatcher* dispatcher,
|
||||
btBroadphaseInterface* pairCache,
|
||||
btConstraintSolver* constraintSolver,
|
||||
btCollisionConfiguration* collisionConfiguration,
|
||||
btSoftBodySolver *softBodySolver ) :
|
||||
btDiscreteDynamicsWorld(dispatcher,pairCache,constraintSolver,collisionConfiguration),
|
||||
m_softBodySolver( softBodySolver ),
|
||||
m_ownsSolver(false)
|
||||
btSoftBodySolver* softBodySolver) : btDiscreteDynamicsWorld(dispatcher, pairCache, constraintSolver, collisionConfiguration),
|
||||
m_softBodySolver(softBodySolver),
|
||||
m_ownsSolver(false)
|
||||
{
|
||||
if( !m_softBodySolver )
|
||||
if (!m_softBodySolver)
|
||||
{
|
||||
void* ptr = btAlignedAlloc(sizeof(btDefaultSoftBodySolver),16);
|
||||
m_softBodySolver = new(ptr) btDefaultSoftBodySolver();
|
||||
void* ptr = btAlignedAlloc(sizeof(btDefaultSoftBodySolver), 16);
|
||||
m_softBodySolver = new (ptr) btDefaultSoftBodySolver();
|
||||
m_ownsSolver = true;
|
||||
}
|
||||
|
||||
m_drawFlags = fDrawFlags::Std;
|
||||
m_drawNodeTree = true;
|
||||
m_drawFaceTree = false;
|
||||
m_drawClusterTree = false;
|
||||
m_drawFlags = fDrawFlags::Std;
|
||||
m_drawNodeTree = true;
|
||||
m_drawFaceTree = false;
|
||||
m_drawClusterTree = false;
|
||||
m_sbi.m_broadphase = pairCache;
|
||||
m_sbi.m_dispatcher = dispatcher;
|
||||
m_sbi.m_sparsesdf.Initialize();
|
||||
m_sbi.m_sparsesdf.Reset();
|
||||
|
||||
m_sbi.air_density = (btScalar)1.2;
|
||||
m_sbi.water_density = 0;
|
||||
m_sbi.water_offset = 0;
|
||||
m_sbi.water_normal = btVector3(0,0,0);
|
||||
m_sbi.m_gravity.setValue(0,-10,0);
|
||||
m_sbi.air_density = (btScalar)1.2;
|
||||
m_sbi.water_density = 0;
|
||||
m_sbi.water_offset = 0;
|
||||
m_sbi.water_normal = btVector3(0, 0, 0);
|
||||
m_sbi.m_gravity.setValue(0, -10, 0);
|
||||
|
||||
m_sbi.m_sparsesdf.Initialize();
|
||||
|
||||
|
||||
}
|
||||
|
||||
btSoftRigidDynamicsWorld::~btSoftRigidDynamicsWorld()
|
||||
@@ -71,82 +66,78 @@ btSoftRigidDynamicsWorld::~btSoftRigidDynamicsWorld()
|
||||
}
|
||||
}
|
||||
|
||||
void btSoftRigidDynamicsWorld::predictUnconstraintMotion(btScalar timeStep)
|
||||
void btSoftRigidDynamicsWorld::predictUnconstraintMotion(btScalar timeStep)
|
||||
{
|
||||
btDiscreteDynamicsWorld::predictUnconstraintMotion( timeStep );
|
||||
btDiscreteDynamicsWorld::predictUnconstraintMotion(timeStep);
|
||||
{
|
||||
BT_PROFILE("predictUnconstraintMotionSoftBody");
|
||||
m_softBodySolver->predictMotion( float(timeStep) );
|
||||
m_softBodySolver->predictMotion(float(timeStep));
|
||||
}
|
||||
}
|
||||
|
||||
void btSoftRigidDynamicsWorld::internalSingleStepSimulation( btScalar timeStep )
|
||||
void btSoftRigidDynamicsWorld::internalSingleStepSimulation(btScalar timeStep)
|
||||
{
|
||||
|
||||
// Let the solver grab the soft bodies and if necessary optimize for it
|
||||
m_softBodySolver->optimize( getSoftBodyArray() );
|
||||
m_softBodySolver->optimize(getSoftBodyArray());
|
||||
|
||||
if( !m_softBodySolver->checkInitialized() )
|
||||
if (!m_softBodySolver->checkInitialized())
|
||||
{
|
||||
btAssert( "Solver initialization failed\n" );
|
||||
btAssert("Solver initialization failed\n");
|
||||
}
|
||||
|
||||
btDiscreteDynamicsWorld::internalSingleStepSimulation( timeStep );
|
||||
btDiscreteDynamicsWorld::internalSingleStepSimulation(timeStep);
|
||||
|
||||
///solve soft bodies constraints
|
||||
solveSoftBodiesConstraints( timeStep );
|
||||
solveSoftBodiesConstraints(timeStep);
|
||||
|
||||
//self collisions
|
||||
for ( int i=0;i<m_softBodies.size();i++)
|
||||
for (int i = 0; i < m_softBodies.size(); i++)
|
||||
{
|
||||
btSoftBody* psb=(btSoftBody*)m_softBodies[i];
|
||||
btSoftBody* psb = (btSoftBody*)m_softBodies[i];
|
||||
psb->defaultCollisionHandler(psb);
|
||||
}
|
||||
|
||||
///update soft bodies
|
||||
m_softBodySolver->updateSoftBodies( );
|
||||
|
||||
m_softBodySolver->updateSoftBodies();
|
||||
|
||||
// End solver-wise simulation step
|
||||
// ///////////////////////////////
|
||||
|
||||
}
|
||||
|
||||
void btSoftRigidDynamicsWorld::solveSoftBodiesConstraints( btScalar timeStep )
|
||||
void btSoftRigidDynamicsWorld::solveSoftBodiesConstraints(btScalar timeStep)
|
||||
{
|
||||
BT_PROFILE("solveSoftConstraints");
|
||||
|
||||
if(m_softBodies.size())
|
||||
if (m_softBodies.size())
|
||||
{
|
||||
btSoftBody::solveClusters(m_softBodies);
|
||||
}
|
||||
|
||||
// Solve constraints solver-wise
|
||||
m_softBodySolver->solveConstraints( timeStep * m_softBodySolver->getTimeScale() );
|
||||
|
||||
m_softBodySolver->solveConstraints(timeStep * m_softBodySolver->getTimeScale());
|
||||
}
|
||||
|
||||
void btSoftRigidDynamicsWorld::addSoftBody(btSoftBody* body, int collisionFilterGroup, int collisionFilterMask)
|
||||
void btSoftRigidDynamicsWorld::addSoftBody(btSoftBody* body, int collisionFilterGroup, int collisionFilterMask)
|
||||
{
|
||||
m_softBodies.push_back(body);
|
||||
|
||||
// Set the soft body solver that will deal with this body
|
||||
// to be the world's solver
|
||||
body->setSoftBodySolver( m_softBodySolver );
|
||||
body->setSoftBodySolver(m_softBodySolver);
|
||||
|
||||
btCollisionWorld::addCollisionObject(body,
|
||||
collisionFilterGroup,
|
||||
collisionFilterMask);
|
||||
|
||||
collisionFilterGroup,
|
||||
collisionFilterMask);
|
||||
}
|
||||
|
||||
void btSoftRigidDynamicsWorld::removeSoftBody(btSoftBody* body)
|
||||
void btSoftRigidDynamicsWorld::removeSoftBody(btSoftBody* body)
|
||||
{
|
||||
m_softBodies.remove(body);
|
||||
|
||||
btCollisionWorld::removeCollisionObject(body);
|
||||
}
|
||||
|
||||
void btSoftRigidDynamicsWorld::removeCollisionObject(btCollisionObject* collisionObject)
|
||||
void btSoftRigidDynamicsWorld::removeCollisionObject(btCollisionObject* collisionObject)
|
||||
{
|
||||
btSoftBody* body = btSoftBody::upcast(collisionObject);
|
||||
if (body)
|
||||
@@ -155,60 +146,57 @@ void btSoftRigidDynamicsWorld::removeCollisionObject(btCollisionObject* collisio
|
||||
btDiscreteDynamicsWorld::removeCollisionObject(collisionObject);
|
||||
}
|
||||
|
||||
void btSoftRigidDynamicsWorld::debugDrawWorld()
|
||||
void btSoftRigidDynamicsWorld::debugDrawWorld()
|
||||
{
|
||||
btDiscreteDynamicsWorld::debugDrawWorld();
|
||||
|
||||
if (getDebugDrawer())
|
||||
{
|
||||
int i;
|
||||
for ( i=0;i<this->m_softBodies.size();i++)
|
||||
for (i = 0; i < this->m_softBodies.size(); i++)
|
||||
{
|
||||
btSoftBody* psb=(btSoftBody*)this->m_softBodies[i];
|
||||
btSoftBody* psb = (btSoftBody*)this->m_softBodies[i];
|
||||
if (getDebugDrawer() && (getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe)))
|
||||
{
|
||||
btSoftBodyHelpers::DrawFrame(psb,m_debugDrawer);
|
||||
btSoftBodyHelpers::Draw(psb,m_debugDrawer,m_drawFlags);
|
||||
btSoftBodyHelpers::DrawFrame(psb, m_debugDrawer);
|
||||
btSoftBodyHelpers::Draw(psb, m_debugDrawer, m_drawFlags);
|
||||
}
|
||||
|
||||
|
||||
if (m_debugDrawer && (m_debugDrawer->getDebugMode() & btIDebugDraw::DBG_DrawAabb))
|
||||
{
|
||||
if(m_drawNodeTree) btSoftBodyHelpers::DrawNodeTree(psb,m_debugDrawer);
|
||||
if(m_drawFaceTree) btSoftBodyHelpers::DrawFaceTree(psb,m_debugDrawer);
|
||||
if(m_drawClusterTree) btSoftBodyHelpers::DrawClusterTree(psb,m_debugDrawer);
|
||||
if (m_drawNodeTree) btSoftBodyHelpers::DrawNodeTree(psb, m_debugDrawer);
|
||||
if (m_drawFaceTree) btSoftBodyHelpers::DrawFaceTree(psb, m_debugDrawer);
|
||||
if (m_drawClusterTree) btSoftBodyHelpers::DrawClusterTree(psb, m_debugDrawer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
struct btSoftSingleRayCallback : public btBroadphaseRayCallback
|
||||
{
|
||||
btVector3 m_rayFromWorld;
|
||||
btVector3 m_rayToWorld;
|
||||
btTransform m_rayFromTrans;
|
||||
btTransform m_rayToTrans;
|
||||
btVector3 m_hitNormal;
|
||||
btVector3 m_rayFromWorld;
|
||||
btVector3 m_rayToWorld;
|
||||
btTransform m_rayFromTrans;
|
||||
btTransform m_rayToTrans;
|
||||
btVector3 m_hitNormal;
|
||||
|
||||
const btSoftRigidDynamicsWorld* m_world;
|
||||
btCollisionWorld::RayResultCallback& m_resultCallback;
|
||||
const btSoftRigidDynamicsWorld* m_world;
|
||||
btCollisionWorld::RayResultCallback& m_resultCallback;
|
||||
|
||||
btSoftSingleRayCallback(const btVector3& rayFromWorld,const btVector3& rayToWorld,const btSoftRigidDynamicsWorld* world,btCollisionWorld::RayResultCallback& resultCallback)
|
||||
:m_rayFromWorld(rayFromWorld),
|
||||
m_rayToWorld(rayToWorld),
|
||||
m_world(world),
|
||||
m_resultCallback(resultCallback)
|
||||
btSoftSingleRayCallback(const btVector3& rayFromWorld, const btVector3& rayToWorld, const btSoftRigidDynamicsWorld* world, btCollisionWorld::RayResultCallback& resultCallback)
|
||||
: m_rayFromWorld(rayFromWorld),
|
||||
m_rayToWorld(rayToWorld),
|
||||
m_world(world),
|
||||
m_resultCallback(resultCallback)
|
||||
{
|
||||
m_rayFromTrans.setIdentity();
|
||||
m_rayFromTrans.setOrigin(m_rayFromWorld);
|
||||
m_rayToTrans.setIdentity();
|
||||
m_rayToTrans.setOrigin(m_rayToWorld);
|
||||
|
||||
btVector3 rayDir = (rayToWorld-rayFromWorld);
|
||||
btVector3 rayDir = (rayToWorld - rayFromWorld);
|
||||
|
||||
rayDir.normalize ();
|
||||
rayDir.normalize();
|
||||
///what about division by zero? --> just set rayDirection[i] to INF/1e30
|
||||
m_rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[0];
|
||||
m_rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[1];
|
||||
@@ -217,22 +205,19 @@ struct btSoftSingleRayCallback : public btBroadphaseRayCallback
|
||||
m_signs[1] = m_rayDirectionInverse[1] < 0.0;
|
||||
m_signs[2] = m_rayDirectionInverse[2] < 0.0;
|
||||
|
||||
m_lambda_max = rayDir.dot(m_rayToWorld-m_rayFromWorld);
|
||||
|
||||
m_lambda_max = rayDir.dot(m_rayToWorld - m_rayFromWorld);
|
||||
}
|
||||
|
||||
|
||||
|
||||
virtual bool process(const btBroadphaseProxy* proxy)
|
||||
virtual bool process(const btBroadphaseProxy* proxy)
|
||||
{
|
||||
///terminate further ray tests, once the closestHitFraction reached zero
|
||||
if (m_resultCallback.m_closestHitFraction == btScalar(0.f))
|
||||
return false;
|
||||
|
||||
btCollisionObject* collisionObject = (btCollisionObject*)proxy->m_clientObject;
|
||||
btCollisionObject* collisionObject = (btCollisionObject*)proxy->m_clientObject;
|
||||
|
||||
//only perform raycast if filterMask matches
|
||||
if(m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle()))
|
||||
if (m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle()))
|
||||
{
|
||||
//RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
|
||||
//btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
|
||||
@@ -250,110 +235,106 @@ struct btSoftSingleRayCallback : public btBroadphaseRayCallback
|
||||
//culling already done by broadphase
|
||||
//if (btRayAabb(m_rayFromWorld,m_rayToWorld,collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,m_hitNormal))
|
||||
{
|
||||
m_world->rayTestSingle(m_rayFromTrans,m_rayToTrans,
|
||||
collisionObject,
|
||||
collisionObject->getCollisionShape(),
|
||||
collisionObject->getWorldTransform(),
|
||||
m_resultCallback);
|
||||
m_world->rayTestSingle(m_rayFromTrans, m_rayToTrans,
|
||||
collisionObject,
|
||||
collisionObject->getCollisionShape(),
|
||||
collisionObject->getWorldTransform(),
|
||||
m_resultCallback);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
void btSoftRigidDynamicsWorld::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const
|
||||
void btSoftRigidDynamicsWorld::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const
|
||||
{
|
||||
BT_PROFILE("rayTest");
|
||||
/// use the broadphase to accelerate the search for objects, based on their aabb
|
||||
/// and for each object with ray-aabb overlap, perform an exact ray test
|
||||
btSoftSingleRayCallback rayCB(rayFromWorld,rayToWorld,this,resultCallback);
|
||||
btSoftSingleRayCallback rayCB(rayFromWorld, rayToWorld, this, resultCallback);
|
||||
|
||||
#ifndef USE_BRUTEFORCE_RAYBROADPHASE
|
||||
m_broadphasePairCache->rayTest(rayFromWorld,rayToWorld,rayCB);
|
||||
m_broadphasePairCache->rayTest(rayFromWorld, rayToWorld, rayCB);
|
||||
#else
|
||||
for (int i=0;i<this->getNumCollisionObjects();i++)
|
||||
for (int i = 0; i < this->getNumCollisionObjects(); i++)
|
||||
{
|
||||
rayCB.process(m_collisionObjects[i]->getBroadphaseHandle());
|
||||
}
|
||||
#endif //USE_BRUTEFORCE_RAYBROADPHASE
|
||||
|
||||
}
|
||||
#endif //USE_BRUTEFORCE_RAYBROADPHASE
|
||||
}
|
||||
|
||||
|
||||
void btSoftRigidDynamicsWorld::rayTestSingle(const btTransform& rayFromTrans,const btTransform& rayToTrans,
|
||||
btCollisionObject* collisionObject,
|
||||
const btCollisionShape* collisionShape,
|
||||
const btTransform& colObjWorldTransform,
|
||||
RayResultCallback& resultCallback)
|
||||
void btSoftRigidDynamicsWorld::rayTestSingle(const btTransform& rayFromTrans, const btTransform& rayToTrans,
|
||||
btCollisionObject* collisionObject,
|
||||
const btCollisionShape* collisionShape,
|
||||
const btTransform& colObjWorldTransform,
|
||||
RayResultCallback& resultCallback)
|
||||
{
|
||||
if (collisionShape->isSoftBody()) {
|
||||
if (collisionShape->isSoftBody())
|
||||
{
|
||||
btSoftBody* softBody = btSoftBody::upcast(collisionObject);
|
||||
if (softBody) {
|
||||
if (softBody)
|
||||
{
|
||||
btSoftBody::sRayCast softResult;
|
||||
if (softBody->rayTest(rayFromTrans.getOrigin(), rayToTrans.getOrigin(), softResult))
|
||||
if (softBody->rayTest(rayFromTrans.getOrigin(), rayToTrans.getOrigin(), softResult))
|
||||
{
|
||||
|
||||
if (softResult.fraction<= resultCallback.m_closestHitFraction)
|
||||
if (softResult.fraction <= resultCallback.m_closestHitFraction)
|
||||
{
|
||||
|
||||
btCollisionWorld::LocalShapeInfo shapeInfo;
|
||||
shapeInfo.m_shapePart = 0;
|
||||
shapeInfo.m_triangleIndex = softResult.index;
|
||||
// get the normal
|
||||
btVector3 rayDir = rayToTrans.getOrigin() - rayFromTrans.getOrigin();
|
||||
btVector3 normal=-rayDir;
|
||||
btVector3 normal = -rayDir;
|
||||
normal.normalize();
|
||||
|
||||
if (softResult.feature == btSoftBody::eFeature::Face)
|
||||
{
|
||||
normal = softBody->m_faces[softResult.index].m_normal;
|
||||
if (normal.dot(rayDir) > 0) {
|
||||
if (normal.dot(rayDir) > 0)
|
||||
{
|
||||
// normal always point toward origin of the ray
|
||||
normal = -normal;
|
||||
}
|
||||
}
|
||||
|
||||
btCollisionWorld::LocalRayResult rayResult
|
||||
(collisionObject,
|
||||
&shapeInfo,
|
||||
normal,
|
||||
softResult.fraction);
|
||||
bool normalInWorldSpace = true;
|
||||
resultCallback.addSingleResult(rayResult,normalInWorldSpace);
|
||||
|
||||
btCollisionWorld::LocalRayResult rayResult(collisionObject,
|
||||
&shapeInfo,
|
||||
normal,
|
||||
softResult.fraction);
|
||||
bool normalInWorldSpace = true;
|
||||
resultCallback.addSingleResult(rayResult, normalInWorldSpace);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
btCollisionWorld::rayTestSingle(rayFromTrans,rayToTrans,collisionObject,collisionShape,colObjWorldTransform,resultCallback);
|
||||
}
|
||||
else
|
||||
{
|
||||
btCollisionWorld::rayTestSingle(rayFromTrans, rayToTrans, collisionObject, collisionShape, colObjWorldTransform, resultCallback);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void btSoftRigidDynamicsWorld::serializeSoftBodies(btSerializer* serializer)
|
||||
void btSoftRigidDynamicsWorld::serializeSoftBodies(btSerializer* serializer)
|
||||
{
|
||||
int i;
|
||||
//serialize all collision objects
|
||||
for (i=0;i<m_collisionObjects.size();i++)
|
||||
for (i = 0; i < m_collisionObjects.size(); i++)
|
||||
{
|
||||
btCollisionObject* colObj = m_collisionObjects[i];
|
||||
if (colObj->getInternalType() & btCollisionObject::CO_SOFT_BODY)
|
||||
{
|
||||
int len = colObj->calculateSerializeBufferSize();
|
||||
btChunk* chunk = serializer->allocate(len,1);
|
||||
btChunk* chunk = serializer->allocate(len, 1);
|
||||
const char* structType = colObj->serialize(chunk->m_oldPtr, serializer);
|
||||
serializer->finalizeChunk(chunk,structType,BT_SOFTBODY_CODE,colObj);
|
||||
serializer->finalizeChunk(chunk, structType, BT_SOFTBODY_CODE, colObj);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void btSoftRigidDynamicsWorld::serialize(btSerializer* serializer)
|
||||
void btSoftRigidDynamicsWorld::serialize(btSerializer* serializer)
|
||||
{
|
||||
|
||||
serializer->startSerialization();
|
||||
|
||||
serializeDynamicsWorldInfo( serializer);
|
||||
serializeDynamicsWorldInfo(serializer);
|
||||
|
||||
serializeSoftBodies(serializer);
|
||||
|
||||
@@ -363,5 +344,3 @@ void btSoftRigidDynamicsWorld::serialize(btSerializer* serializer)
|
||||
|
||||
serializer->finishSerialization();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -19,63 +19,60 @@ subject to the following restrictions:
|
||||
#include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h"
|
||||
#include "btSoftBody.h"
|
||||
|
||||
typedef btAlignedObjectArray<btSoftBody*> btSoftBodyArray;
|
||||
typedef btAlignedObjectArray<btSoftBody*> btSoftBodyArray;
|
||||
|
||||
class btSoftBodySolver;
|
||||
|
||||
class btSoftRigidDynamicsWorld : public btDiscreteDynamicsWorld
|
||||
{
|
||||
|
||||
btSoftBodyArray m_softBodies;
|
||||
int m_drawFlags;
|
||||
bool m_drawNodeTree;
|
||||
bool m_drawFaceTree;
|
||||
bool m_drawClusterTree;
|
||||
btSoftBodyArray m_softBodies;
|
||||
int m_drawFlags;
|
||||
bool m_drawNodeTree;
|
||||
bool m_drawFaceTree;
|
||||
bool m_drawClusterTree;
|
||||
btSoftBodyWorldInfo m_sbi;
|
||||
///Solver classes that encapsulate multiple soft bodies for solving
|
||||
btSoftBodySolver *m_softBodySolver;
|
||||
bool m_ownsSolver;
|
||||
btSoftBodySolver* m_softBodySolver;
|
||||
bool m_ownsSolver;
|
||||
|
||||
protected:
|
||||
virtual void predictUnconstraintMotion(btScalar timeStep);
|
||||
|
||||
virtual void predictUnconstraintMotion(btScalar timeStep);
|
||||
virtual void internalSingleStepSimulation(btScalar timeStep);
|
||||
|
||||
virtual void internalSingleStepSimulation( btScalar timeStep);
|
||||
void solveSoftBodiesConstraints(btScalar timeStep);
|
||||
|
||||
void solveSoftBodiesConstraints( btScalar timeStep );
|
||||
|
||||
void serializeSoftBodies(btSerializer* serializer);
|
||||
void serializeSoftBodies(btSerializer* serializer);
|
||||
|
||||
public:
|
||||
|
||||
btSoftRigidDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver, btCollisionConfiguration* collisionConfiguration, btSoftBodySolver *softBodySolver = 0 );
|
||||
btSoftRigidDynamicsWorld(btDispatcher* dispatcher, btBroadphaseInterface* pairCache, btConstraintSolver* constraintSolver, btCollisionConfiguration* collisionConfiguration, btSoftBodySolver* softBodySolver = 0);
|
||||
|
||||
virtual ~btSoftRigidDynamicsWorld();
|
||||
|
||||
virtual void debugDrawWorld();
|
||||
virtual void debugDrawWorld();
|
||||
|
||||
void addSoftBody(btSoftBody* body, int collisionFilterGroup=btBroadphaseProxy::DefaultFilter, int collisionFilterMask=btBroadphaseProxy::AllFilter);
|
||||
void addSoftBody(btSoftBody* body, int collisionFilterGroup = btBroadphaseProxy::DefaultFilter, int collisionFilterMask = btBroadphaseProxy::AllFilter);
|
||||
|
||||
void removeSoftBody(btSoftBody* body);
|
||||
void removeSoftBody(btSoftBody* body);
|
||||
|
||||
///removeCollisionObject will first check if it is a rigid body, if so call removeRigidBody otherwise call btDiscreteDynamicsWorld::removeCollisionObject
|
||||
virtual void removeCollisionObject(btCollisionObject* collisionObject);
|
||||
virtual void removeCollisionObject(btCollisionObject* collisionObject);
|
||||
|
||||
int getDrawFlags() const { return(m_drawFlags); }
|
||||
void setDrawFlags(int f) { m_drawFlags=f; }
|
||||
int getDrawFlags() const { return (m_drawFlags); }
|
||||
void setDrawFlags(int f) { m_drawFlags = f; }
|
||||
|
||||
btSoftBodyWorldInfo& getWorldInfo()
|
||||
btSoftBodyWorldInfo& getWorldInfo()
|
||||
{
|
||||
return m_sbi;
|
||||
}
|
||||
const btSoftBodyWorldInfo& getWorldInfo() const
|
||||
const btSoftBodyWorldInfo& getWorldInfo() const
|
||||
{
|
||||
return m_sbi;
|
||||
}
|
||||
|
||||
virtual btDynamicsWorldType getWorldType() const
|
||||
virtual btDynamicsWorldType getWorldType() const
|
||||
{
|
||||
return BT_SOFT_RIGID_DYNAMICS_WORLD;
|
||||
return BT_SOFT_RIGID_DYNAMICS_WORLD;
|
||||
}
|
||||
|
||||
btSoftBodyArray& getSoftBodyArray()
|
||||
@@ -88,20 +85,18 @@ public:
|
||||
return m_softBodies;
|
||||
}
|
||||
|
||||
|
||||
virtual void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const;
|
||||
virtual void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const;
|
||||
|
||||
/// rayTestSingle performs a raycast call and calls the resultCallback. It is used internally by rayTest.
|
||||
/// In a future implementation, we consider moving the ray test as a virtual method in btCollisionShape.
|
||||
/// This allows more customization.
|
||||
static void rayTestSingle(const btTransform& rayFromTrans,const btTransform& rayToTrans,
|
||||
btCollisionObject* collisionObject,
|
||||
const btCollisionShape* collisionShape,
|
||||
const btTransform& colObjWorldTransform,
|
||||
RayResultCallback& resultCallback);
|
||||
|
||||
virtual void serialize(btSerializer* serializer);
|
||||
static void rayTestSingle(const btTransform& rayFromTrans, const btTransform& rayToTrans,
|
||||
btCollisionObject* collisionObject,
|
||||
const btCollisionShape* collisionShape,
|
||||
const btTransform& colObjWorldTransform,
|
||||
RayResultCallback& resultCallback);
|
||||
|
||||
virtual void serialize(btSerializer* serializer);
|
||||
};
|
||||
|
||||
#endif //BT_SOFT_RIGID_DYNAMICS_WORLD_H
|
||||
#endif //BT_SOFT_RIGID_DYNAMICS_WORLD_H
|
||||
|
||||
@@ -23,8 +23,8 @@ subject to the following restrictions:
|
||||
|
||||
#define USE_PERSISTENT_CONTACTS 1
|
||||
|
||||
btSoftSoftCollisionAlgorithm::btSoftSoftCollisionAlgorithm(btPersistentManifold* /*mf*/,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* /*obj0*/,const btCollisionObjectWrapper* /*obj1*/)
|
||||
: btCollisionAlgorithm(ci)
|
||||
btSoftSoftCollisionAlgorithm::btSoftSoftCollisionAlgorithm(btPersistentManifold* /*mf*/, const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* /*obj0*/, const btCollisionObjectWrapper* /*obj1*/)
|
||||
: btCollisionAlgorithm(ci)
|
||||
//m_ownManifold(false),
|
||||
//m_manifoldPtr(mf)
|
||||
{
|
||||
@@ -34,14 +34,14 @@ btSoftSoftCollisionAlgorithm::~btSoftSoftCollisionAlgorithm()
|
||||
{
|
||||
}
|
||||
|
||||
void btSoftSoftCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& /*dispatchInfo*/,btManifoldResult* /*resultOut*/)
|
||||
void btSoftSoftCollisionAlgorithm::processCollision(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, const btDispatcherInfo& /*dispatchInfo*/, btManifoldResult* /*resultOut*/)
|
||||
{
|
||||
btSoftBody* soft0 = (btSoftBody*)body0Wrap->getCollisionObject();
|
||||
btSoftBody* soft1 = (btSoftBody*)body1Wrap->getCollisionObject();
|
||||
btSoftBody* soft0 = (btSoftBody*)body0Wrap->getCollisionObject();
|
||||
btSoftBody* soft1 = (btSoftBody*)body1Wrap->getCollisionObject();
|
||||
soft0->getSoftBodySolver()->processCollision(soft0, soft1);
|
||||
}
|
||||
|
||||
btScalar btSoftSoftCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* /*body0*/,btCollisionObject* /*body1*/,const btDispatcherInfo& /*dispatchInfo*/,btManifoldResult* /*resultOut*/)
|
||||
btScalar btSoftSoftCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* /*body0*/, btCollisionObject* /*body1*/, const btDispatcherInfo& /*dispatchInfo*/, btManifoldResult* /*resultOut*/)
|
||||
{
|
||||
//not yet
|
||||
return 1.f;
|
||||
|
||||
@@ -27,43 +27,39 @@ class btSoftBody;
|
||||
///collision detection between two btSoftBody shapes
|
||||
class btSoftSoftCollisionAlgorithm : public btCollisionAlgorithm
|
||||
{
|
||||
bool m_ownManifold;
|
||||
btPersistentManifold* m_manifoldPtr;
|
||||
|
||||
// btSoftBody* m_softBody0;
|
||||
// btSoftBody* m_softBody1;
|
||||
bool m_ownManifold;
|
||||
btPersistentManifold* m_manifoldPtr;
|
||||
|
||||
// btSoftBody* m_softBody0;
|
||||
// btSoftBody* m_softBody1;
|
||||
|
||||
public:
|
||||
btSoftSoftCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci)
|
||||
: btCollisionAlgorithm(ci) {}
|
||||
|
||||
virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
|
||||
virtual void processCollision(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut);
|
||||
|
||||
virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
|
||||
virtual btScalar calculateTimeOfImpact(btCollisionObject* body0, btCollisionObject* body1, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut);
|
||||
|
||||
virtual void getAllContactManifolds(btManifoldArray& manifoldArray)
|
||||
virtual void getAllContactManifolds(btManifoldArray& manifoldArray)
|
||||
{
|
||||
if (m_manifoldPtr && m_ownManifold)
|
||||
manifoldArray.push_back(m_manifoldPtr);
|
||||
}
|
||||
|
||||
btSoftSoftCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap);
|
||||
btSoftSoftCollisionAlgorithm(btPersistentManifold* mf, const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap);
|
||||
|
||||
virtual ~btSoftSoftCollisionAlgorithm();
|
||||
|
||||
struct CreateFunc :public btCollisionAlgorithmCreateFunc
|
||||
struct CreateFunc : public btCollisionAlgorithmCreateFunc
|
||||
{
|
||||
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
|
||||
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap)
|
||||
{
|
||||
int bbsize = sizeof(btSoftSoftCollisionAlgorithm);
|
||||
void* ptr = ci.m_dispatcher1->allocateCollisionAlgorithm(bbsize);
|
||||
return new(ptr) btSoftSoftCollisionAlgorithm(0,ci,body0Wrap,body1Wrap);
|
||||
return new (ptr) btSoftSoftCollisionAlgorithm(0, ci, body0Wrap, body1Wrap);
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif //BT_SOFT_SOFT_COLLISION_ALGORITHM_H
|
||||
|
||||
|
||||
#endif //BT_SOFT_SOFT_COLLISION_ALGORITHM_H
|
||||
|
||||
@@ -24,296 +24,320 @@ subject to the following restrictions:
|
||||
template <const int DWORDLEN>
|
||||
unsigned int HsiehHash(const void* pdata)
|
||||
{
|
||||
const unsigned short* data=(const unsigned short*)pdata;
|
||||
unsigned hash=DWORDLEN<<2,tmp;
|
||||
for(int i=0;i<DWORDLEN;++i)
|
||||
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 += 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);
|
||||
hash ^= hash << 3;
|
||||
hash += hash >> 5;
|
||||
hash ^= hash << 4;
|
||||
hash += hash >> 17;
|
||||
hash ^= hash << 25;
|
||||
hash += hash >> 6;
|
||||
return (hash);
|
||||
}
|
||||
|
||||
template <const int CELLSIZE>
|
||||
struct btSparseSdf
|
||||
struct btSparseSdf
|
||||
{
|
||||
//
|
||||
// Inner types
|
||||
//
|
||||
struct IntFrac
|
||||
{
|
||||
int b;
|
||||
int i;
|
||||
btScalar f;
|
||||
int b;
|
||||
int i;
|
||||
btScalar f;
|
||||
};
|
||||
struct Cell
|
||||
struct Cell
|
||||
{
|
||||
btScalar d[CELLSIZE+1][CELLSIZE+1][CELLSIZE+1];
|
||||
int c[3];
|
||||
int puid;
|
||||
unsigned hash;
|
||||
const btCollisionShape* pclient;
|
||||
Cell* next;
|
||||
btScalar d[CELLSIZE + 1][CELLSIZE + 1][CELLSIZE + 1];
|
||||
int c[3];
|
||||
int puid;
|
||||
unsigned hash;
|
||||
const btCollisionShape* pclient;
|
||||
Cell* next;
|
||||
};
|
||||
//
|
||||
// Fields
|
||||
//
|
||||
|
||||
btAlignedObjectArray<Cell*> cells;
|
||||
btScalar voxelsz;
|
||||
int puid;
|
||||
int ncells;
|
||||
int m_clampCells;
|
||||
int nprobes;
|
||||
int nqueries;
|
||||
btAlignedObjectArray<Cell*> cells;
|
||||
btScalar voxelsz;
|
||||
int puid;
|
||||
int ncells;
|
||||
int m_clampCells;
|
||||
int nprobes;
|
||||
int nqueries;
|
||||
|
||||
//
|
||||
// Methods
|
||||
//
|
||||
|
||||
//
|
||||
void Initialize(int hashsize=2383, int clampCells = 256*1024)
|
||||
void Initialize(int hashsize = 2383, int clampCells = 256 * 1024)
|
||||
{
|
||||
//avoid a crash due to running out of memory, so clamp the maximum number of cells allocated
|
||||
//if this limit is reached, the SDF is reset (at the cost of some performance during the reset)
|
||||
m_clampCells = clampCells;
|
||||
cells.resize(hashsize,0);
|
||||
cells.resize(hashsize, 0);
|
||||
Reset();
|
||||
}
|
||||
//
|
||||
void Reset()
|
||||
void Reset()
|
||||
{
|
||||
for(int i=0,ni=cells.size();i<ni;++i)
|
||||
for (int i = 0, ni = cells.size(); i < ni; ++i)
|
||||
{
|
||||
Cell* pc=cells[i];
|
||||
cells[i]=0;
|
||||
while(pc)
|
||||
Cell* pc = cells[i];
|
||||
cells[i] = 0;
|
||||
while (pc)
|
||||
{
|
||||
Cell* pn=pc->next;
|
||||
Cell* pn = pc->next;
|
||||
delete pc;
|
||||
pc=pn;
|
||||
pc = pn;
|
||||
}
|
||||
}
|
||||
voxelsz =0.25;
|
||||
puid =0;
|
||||
ncells =0;
|
||||
nprobes =1;
|
||||
nqueries =1;
|
||||
voxelsz = 0.25;
|
||||
puid = 0;
|
||||
ncells = 0;
|
||||
nprobes = 1;
|
||||
nqueries = 1;
|
||||
}
|
||||
//
|
||||
void GarbageCollect(int lifetime=256)
|
||||
void GarbageCollect(int lifetime = 256)
|
||||
{
|
||||
const int life=puid-lifetime;
|
||||
for(int i=0;i<cells.size();++i)
|
||||
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*& root = cells[i];
|
||||
Cell* pp = 0;
|
||||
Cell* pc = root;
|
||||
while (pc)
|
||||
{
|
||||
Cell* pn=pc->next;
|
||||
if(pc->puid<life)
|
||||
Cell* pn = pc->next;
|
||||
if (pc->puid < life)
|
||||
{
|
||||
if(pp) pp->next=pn; else root=pn;
|
||||
delete pc;pc=pp;--ncells;
|
||||
if (pp)
|
||||
pp->next = pn;
|
||||
else
|
||||
root = pn;
|
||||
delete pc;
|
||||
pc = pp;
|
||||
--ncells;
|
||||
}
|
||||
pp=pc;pc=pn;
|
||||
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... */
|
||||
nqueries = 1;
|
||||
nprobes = 1;
|
||||
++puid; ///@todo: Reset puid's when int range limit is reached */
|
||||
/* else setup a priority list... */
|
||||
}
|
||||
//
|
||||
int RemoveReferences(btCollisionShape* pcs)
|
||||
int RemoveReferences(btCollisionShape* pcs)
|
||||
{
|
||||
int refcount=0;
|
||||
for(int i=0;i<cells.size();++i)
|
||||
int refcount = 0;
|
||||
for (int i = 0; i < cells.size(); ++i)
|
||||
{
|
||||
Cell*& root=cells[i];
|
||||
Cell* pp=0;
|
||||
Cell* pc=root;
|
||||
while(pc)
|
||||
Cell*& root = cells[i];
|
||||
Cell* pp = 0;
|
||||
Cell* pc = root;
|
||||
while (pc)
|
||||
{
|
||||
Cell* pn=pc->next;
|
||||
if(pc->pclient==pcs)
|
||||
Cell* pn = pc->next;
|
||||
if (pc->pclient == pcs)
|
||||
{
|
||||
if(pp) pp->next=pn; else root=pn;
|
||||
delete pc;pc=pp;++refcount;
|
||||
if (pp)
|
||||
pp->next = pn;
|
||||
else
|
||||
root = pn;
|
||||
delete pc;
|
||||
pc = pp;
|
||||
++refcount;
|
||||
}
|
||||
pp=pc;pc=pn;
|
||||
pp = pc;
|
||||
pc = pn;
|
||||
}
|
||||
}
|
||||
return(refcount);
|
||||
return (refcount);
|
||||
}
|
||||
//
|
||||
btScalar Evaluate( const btVector3& x,
|
||||
const btCollisionShape* shape,
|
||||
btVector3& normal,
|
||||
btScalar margin)
|
||||
btScalar Evaluate(const btVector3& x,
|
||||
const 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[static_cast<int>(h%cells.size())];
|
||||
Cell* c=root;
|
||||
/* 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[static_cast<int>(h % cells.size())];
|
||||
Cell* c = root;
|
||||
++nqueries;
|
||||
while(c)
|
||||
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; }
|
||||
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; }
|
||||
{
|
||||
c = c->next;
|
||||
}
|
||||
}
|
||||
if(!c)
|
||||
if (!c)
|
||||
{
|
||||
++nprobes;
|
||||
++nprobes;
|
||||
++ncells;
|
||||
//int sz = sizeof(Cell);
|
||||
if (ncells>m_clampCells)
|
||||
if (ncells > m_clampCells)
|
||||
{
|
||||
static int numResets=0;
|
||||
static int numResets = 0;
|
||||
numResets++;
|
||||
// printf("numResets=%d\n",numResets);
|
||||
// printf("numResets=%d\n",numResets);
|
||||
Reset();
|
||||
}
|
||||
|
||||
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;
|
||||
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 */
|
||||
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();
|
||||
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();
|
||||
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);
|
||||
/* 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)
|
||||
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 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 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 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);
|
||||
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,
|
||||
const btCollisionShape* shape)
|
||||
static inline btScalar DistanceToShape(const btVector3& x,
|
||||
const btCollisionShape* shape)
|
||||
{
|
||||
btTransform unit;
|
||||
btTransform unit;
|
||||
unit.setIdentity();
|
||||
if(shape->isConvex())
|
||||
if (shape->isConvex())
|
||||
{
|
||||
btGjkEpaSolver2::sResults res;
|
||||
const btConvexShape* csh=static_cast<const btConvexShape*>(shape);
|
||||
return(btGjkEpaSolver2::SignedDistance(x,0,csh,unit,res));
|
||||
btGjkEpaSolver2::sResults res;
|
||||
const btConvexShape* csh = static_cast<const btConvexShape*>(shape);
|
||||
return (btGjkEpaSolver2::SignedDistance(x, 0, csh, unit, res));
|
||||
}
|
||||
return(0);
|
||||
return (0);
|
||||
}
|
||||
//
|
||||
static inline IntFrac Decompose(btScalar x)
|
||||
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);
|
||||
/* 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)
|
||||
static inline btScalar Lerp(btScalar a, btScalar b, btScalar t)
|
||||
{
|
||||
return(a+(b-a)*t);
|
||||
return (a + (b - a) * t);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
static inline unsigned int Hash(int x,int y,int z,const btCollisionShape* shape)
|
||||
static inline unsigned int Hash(int x, int y, int z, const btCollisionShape* shape)
|
||||
{
|
||||
struct btS
|
||||
{
|
||||
int x,y,z;
|
||||
{
|
||||
int x, y, z;
|
||||
void* p;
|
||||
};
|
||||
|
||||
btS myset;
|
||||
|
||||
myset.x=x;myset.y=y;myset.z=z;myset.p=(void*)shape;
|
||||
myset.x = x;
|
||||
myset.y = y;
|
||||
myset.z = z;
|
||||
myset.p = (void*)shape;
|
||||
const void* ptr = &myset;
|
||||
|
||||
unsigned int result = HsiehHash<sizeof(btS)/4> (ptr);
|
||||
|
||||
unsigned int result = HsiehHash<sizeof(btS) / 4>(ptr);
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif //BT_SPARSE_SDF_H
|
||||
#endif //BT_SPARSE_SDF_H
|
||||
|
||||
Reference in New Issue
Block a user