diff --git a/src/Bullet3Collision/NarrowPhaseCollision/b3CpuNarrowPhase.cpp b/src/Bullet3Collision/NarrowPhaseCollision/b3CpuNarrowPhase.cpp index 16f5d59b1..c3134b2c6 100644 --- a/src/Bullet3Collision/NarrowPhaseCollision/b3CpuNarrowPhase.cpp +++ b/src/Bullet3Collision/NarrowPhaseCollision/b3CpuNarrowPhase.cpp @@ -25,6 +25,12 @@ struct b3CpuNarrowPhaseInternalData int m_numAcceleratedShapes; }; + +const b3AlignedObjectArray& b3CpuNarrowPhase::getContacts() const +{ + return m_data->m_contacts; +} + b3Collidable& b3CpuNarrowPhase::getCollidableCpu(int collidableIndex) { return m_data->m_collidablesCPU[collidableIndex]; diff --git a/src/Bullet3Collision/NarrowPhaseCollision/b3CpuNarrowPhase.h b/src/Bullet3Collision/NarrowPhaseCollision/b3CpuNarrowPhase.h index 4da80ad8a..3b91acb82 100644 --- a/src/Bullet3Collision/NarrowPhaseCollision/b3CpuNarrowPhase.h +++ b/src/Bullet3Collision/NarrowPhaseCollision/b3CpuNarrowPhase.h @@ -7,6 +7,7 @@ #include "Bullet3Collision/BroadPhaseCollision/shared/b3Aabb.h" #include "Bullet3Common/shared/b3Int4.h" #include "Bullet3Collision/NarrowPhaseCollision/shared/b3RigidBodyData.h" +#include "Bullet3Collision/NarrowPhaseCollision/shared/b3Contact4Data.h" class b3CpuNarrowPhase { @@ -72,11 +73,13 @@ public: int getNumCollidablesGpu() const; - const struct b3Contact4* getContactsCPU() const; + /*const struct b3Contact4* getContactsCPU() const; int getNumContactsGpu() const; + */ + const b3AlignedObjectArray& getContacts() const; int getNumRigidBodies() const; diff --git a/src/Bullet3Dynamics/b3CpuRigidBodyPipeline.cpp b/src/Bullet3Dynamics/b3CpuRigidBodyPipeline.cpp index 48a46ecf1..598e8ce32 100644 --- a/src/Bullet3Dynamics/b3CpuRigidBodyPipeline.cpp +++ b/src/Bullet3Dynamics/b3CpuRigidBodyPipeline.cpp @@ -7,11 +7,15 @@ #include "Bullet3Collision/NarrowPhaseCollision/b3CpuNarrowPhase.h" #include "Bullet3Collision/BroadPhaseCollision/shared/b3Aabb.h" #include "Bullet3Collision/NarrowPhaseCollision/shared/b3CollidableData.h" +#include "Bullet3Common/b3Vector3.h" +#include "Bullet3Dynamics/shared/b3ContactConstraint4.h" +#include "Bullet3Dynamics/shared/b3Inertia.h" struct b3CpuRigidBodyPipelineInternalData { b3AlignedObjectArray m_rigidBodies; + b3AlignedObjectArray m_inertias; b3AlignedObjectArray m_aabbWorldSpace; b3DynamicBvhBroadphase* m_bp; @@ -64,7 +68,7 @@ void b3CpuRigidBodyPipeline::computeOverlappingPairs() int numPairs = m_data->m_bp->getOverlappingPairCache()->getNumOverlappingPairs(); m_data->m_bp->calculateOverlappingPairs(); numPairs = m_data->m_bp->getOverlappingPairCache()->getNumOverlappingPairs(); - //printf("numPairs=%d\n",numPairs); + printf("numPairs=%d\n",numPairs); } void b3CpuRigidBodyPipeline::computeContactPoints() @@ -96,6 +100,322 @@ void b3CpuRigidBodyPipeline::stepSimulation(float deltaTime) } +static inline float b3CalcRelVel(const b3Vector3& l0, const b3Vector3& l1, const b3Vector3& a0, const b3Vector3& a1, + const b3Vector3& linVel0, const b3Vector3& angVel0, const b3Vector3& linVel1, const b3Vector3& angVel1) +{ + return b3Dot(l0, linVel0) + b3Dot(a0, angVel0) + b3Dot(l1, linVel1) + b3Dot(a1, angVel1); +} + + +static inline void b3SetLinearAndAngular(const b3Vector3& n, const b3Vector3& r0, const b3Vector3& r1, + b3Vector3& linear, b3Vector3& angular0, b3Vector3& angular1) +{ + linear = -n; + angular0 = -b3Cross(r0, n); + angular1 = b3Cross(r1, n); +} + + + +static inline void b3SolveContact(b3ContactConstraint4& cs, + const b3Vector3& posA, b3Vector3& linVelA, b3Vector3& angVelA, float invMassA, const b3Matrix3x3& invInertiaA, + const b3Vector3& posB, b3Vector3& linVelB, b3Vector3& angVelB, float invMassB, const b3Matrix3x3& invInertiaB, + float maxRambdaDt[4], float minRambdaDt[4]) +{ + + b3Vector3 dLinVelA; dLinVelA.setZero(); + b3Vector3 dAngVelA; dAngVelA.setZero(); + b3Vector3 dLinVelB; dLinVelB.setZero(); + b3Vector3 dAngVelB; dAngVelB.setZero(); + + for(int ic=0; ic<4; ic++) + { + // dont necessary because this makes change to 0 + if( cs.m_jacCoeffInv[ic] == 0.f ) continue; + + { + b3Vector3 angular0, angular1, linear; + b3Vector3 r0 = cs.m_worldPos[ic] - (b3Vector3&)posA; + b3Vector3 r1 = cs.m_worldPos[ic] - (b3Vector3&)posB; + b3SetLinearAndAngular( (const b3Vector3 &)-cs.m_linear, (const b3Vector3 &)r0, (const b3Vector3 &)r1, linear, angular0, angular1 ); + + float rambdaDt = b3CalcRelVel((const b3Vector3 &)cs.m_linear,(const b3Vector3 &) -cs.m_linear, angular0, angular1, + linVelA, angVelA, linVelB, angVelB ) + cs.m_b[ic]; + rambdaDt *= cs.m_jacCoeffInv[ic]; + + { + float prevSum = cs.m_appliedRambdaDt[ic]; + float updated = prevSum; + updated += rambdaDt; + updated = b3Max( updated, minRambdaDt[ic] ); + updated = b3Min( updated, maxRambdaDt[ic] ); + rambdaDt = updated - prevSum; + cs.m_appliedRambdaDt[ic] = updated; + } + + b3Vector3 linImp0 = invMassA*linear*rambdaDt; + b3Vector3 linImp1 = invMassB*(-linear)*rambdaDt; + b3Vector3 angImp0 = (invInertiaA* angular0)*rambdaDt; + b3Vector3 angImp1 = (invInertiaB* angular1)*rambdaDt; +#ifdef _WIN32 + b3Assert(_finite(linImp0.getX())); + b3Assert(_finite(linImp1.getX())); +#endif + { + linVelA += linImp0; + angVelA += angImp0; + linVelB += linImp1; + angVelB += angImp1; + } + } + } + + +} + + + + + +static inline void b3SolveFriction(b3ContactConstraint4& cs, + const b3Vector3& posA, b3Vector3& linVelA, b3Vector3& angVelA, float invMassA, const b3Matrix3x3& invInertiaA, + const b3Vector3& posB, b3Vector3& linVelB, b3Vector3& angVelB, float invMassB, const b3Matrix3x3& invInertiaB, + float maxRambdaDt[4], float minRambdaDt[4]) +{ + + if( cs.m_fJacCoeffInv[0] == 0 && cs.m_fJacCoeffInv[0] == 0 ) return; + const b3Vector3& center = (const b3Vector3&)cs.m_center; + + b3Vector3 n = -(const b3Vector3&)cs.m_linear; + + b3Vector3 tangent[2]; + + b3PlaneSpace1 (n, tangent[0],tangent[1]); + + b3Vector3 angular0, angular1, linear; + b3Vector3 r0 = center - posA; + b3Vector3 r1 = center - posB; + for(int i=0; i<2; i++) + { + b3SetLinearAndAngular( tangent[i], r0, r1, linear, angular0, angular1 ); + float rambdaDt = b3CalcRelVel(linear, -linear, angular0, angular1, + linVelA, angVelA, linVelB, angVelB ); + rambdaDt *= cs.m_fJacCoeffInv[i]; + + { + float prevSum = cs.m_fAppliedRambdaDt[i]; + float updated = prevSum; + updated += rambdaDt; + updated = b3Max( updated, minRambdaDt[i] ); + updated = b3Min( updated, maxRambdaDt[i] ); + rambdaDt = updated - prevSum; + cs.m_fAppliedRambdaDt[i] = updated; + } + + b3Vector3 linImp0 = invMassA*linear*rambdaDt; + b3Vector3 linImp1 = invMassB*(-linear)*rambdaDt; + b3Vector3 angImp0 = (invInertiaA* angular0)*rambdaDt; + b3Vector3 angImp1 = (invInertiaB* angular1)*rambdaDt; +#ifdef _WIN32 + b3Assert(_finite(linImp0.getX())); + b3Assert(_finite(linImp1.getX())); +#endif + linVelA += linImp0; + angVelA += angImp0; + linVelB += linImp1; + angVelB += angImp1; + } + + { // angular damping for point constraint + b3Vector3 ab = ( posB - posA ).normalized(); + b3Vector3 ac = ( center - posA ).normalized(); + if( b3Dot( ab, ac ) > 0.95f || (invMassA == 0.f || invMassB == 0.f)) + { + float angNA = b3Dot( n, angVelA ); + float angNB = b3Dot( n, angVelB ); + + angVelA -= (angNA*0.1f)*n; + angVelB -= (angNB*0.1f)*n; + } + } + +} + + + + + +struct b3SolveTask// : public ThreadPool::Task +{ + b3SolveTask(b3AlignedObjectArray& bodies, + b3AlignedObjectArray& shapes, + b3AlignedObjectArray& constraints, + int start, int nConstraints, + int maxNumBatches, + b3AlignedObjectArray* wgUsedBodies, int curWgidx + ) + : m_bodies( bodies ), m_shapes( shapes ), m_constraints( constraints ), m_start( start ), m_nConstraints( nConstraints ), + m_solveFriction( true ),m_maxNumBatches(maxNumBatches), + m_wgUsedBodies(wgUsedBodies),m_curWgidx(curWgidx) + {} + + unsigned short int getType(){ return 0; } + + void run(int tIdx) + { + b3AlignedObjectArray usedBodies; + //printf("run..............\n"); + + + for (int bb=0;bb=0; ic--) + //for(int ic=0; ic& m_bodies; + b3AlignedObjectArray& m_shapes; + b3AlignedObjectArray& m_constraints; + b3AlignedObjectArray* m_wgUsedBodies; + int m_curWgidx; + int m_start; + int m_nConstraints; + bool m_solveFriction; + int m_maxNumBatches; +}; + +void b3CpuRigidBodyPipeline::solveContactConstraints() +{ + int m_nIterations = 4; + + b3AlignedObjectArray contactConstraints; + const b3AlignedObjectArray& contacts = m_data->m_np->getContacts(); + int n = contactConstraints.size(); + //convert contacts... + + + + int maxNumBatches = 250; + + for(int iter=0; iterm_rigidBodies, m_data->m_inertias, contactConstraints, 0, n ,maxNumBatches,0,0); + task.m_solveFriction = false; + task.run(0); + } + + for(int iter=0; iterm_rigidBodies, m_data->m_inertias, contactConstraints, 0, n ,maxNumBatches,0,0); + task.m_solveFriction = true; + task.run(0); + } +} + void b3CpuRigidBodyPipeline::integrate(float deltaTime) { float angDamping=0.f; diff --git a/src/Bullet3Dynamics/b3CpuRigidBodyPipeline.h b/src/Bullet3Dynamics/b3CpuRigidBodyPipeline.h index 463530601..26a86ba00 100644 --- a/src/Bullet3Dynamics/b3CpuRigidBodyPipeline.h +++ b/src/Bullet3Dynamics/b3CpuRigidBodyPipeline.h @@ -39,6 +39,7 @@ public: virtual void updateAabbWorldSpace(); virtual void computeOverlappingPairs(); virtual void computeContactPoints(); + virtual void solveContactConstraints(); int registerConvexPolyhedron(class b3ConvexUtility* convex); diff --git a/src/Bullet3Dynamics/shared/b3ContactConstraint4.h b/src/Bullet3Dynamics/shared/b3ContactConstraint4.h new file mode 100644 index 000000000..32e11fc0c --- /dev/null +++ b/src/Bullet3Dynamics/shared/b3ContactConstraint4.h @@ -0,0 +1,33 @@ +#ifndef B3_CONTACT_CONSTRAINT5_H +#define B3_CONTACT_CONSTRAINT5_H + +#include "Bullet3Common/shared/b3Float4.h" + +typedef struct b3ContactConstraint4 b3ContactConstraint4_t; + +struct b3ContactConstraint4 +{ + + b3Float4 m_linear;//normal? + b3Float4 m_worldPos[4]; + b3Float4 m_center; // friction + float m_jacCoeffInv[4]; + float m_b[4]; + float m_appliedRambdaDt[4]; + float m_fJacCoeffInv[2]; // friction + float m_fAppliedRambdaDt[2]; // friction + + unsigned int m_bodyA; + unsigned int m_bodyB; + int m_batchIdx; + unsigned int m_paddings; + +}; + +//inline void setFrictionCoeff(float value) { m_linear[3] = value; } +inline float b3GetFrictionCoeff(b3ContactConstraint4* constraint) +{ + return constraint->m_linear[3]; +} + +#endif //B3_CONTACT_CONSTRAINT5_H diff --git a/src/Bullet3Dynamics/shared/b3Inertia.h b/src/Bullet3Dynamics/shared/b3Inertia.h new file mode 100644 index 000000000..96fe9f8b3 --- /dev/null +++ b/src/Bullet3Dynamics/shared/b3Inertia.h @@ -0,0 +1,15 @@ + + +#ifndef B3_INERTIA_H +#define B3_INERTIA_H + +#include "Bullet3Common/shared/b3Mat3x3.h" + +struct b3Inertia +{ + b3Mat3x3 m_invInertiaWorld; + b3Mat3x3 m_initInvInertia; +}; + + +#endif //B3_INERTIA_H \ No newline at end of file