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:
erwincoumans
2018-09-23 14:17:31 -07:00
parent b73b05e9fb
commit ab8f16961e
1773 changed files with 1081087 additions and 474249 deletions

View File

@@ -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);
}
}
}

View File

@@ -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

View File

@@ -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.);
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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

View File

@@ -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.);
}

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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

View File

@@ -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;

View File

@@ -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

View File

@@ -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