+ Added joint feedback for constraints, needs testing/demo before 2.75 release.
See also http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=2677 and http://code.google.com/p/bullet/issues/detail?id=227 To enable, use constraint->enableFeedback(true); And then either use constraint->getAppliedImpulse() for an estimated applied impulse, or constraint-> getAppliedLinearImpulse(), or constraint->getAppliedAngularImpulseA() or constraint->getAppliedAngularImpulseB(). +removed a few warnings.
This commit is contained in:
@@ -660,26 +660,25 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCol
|
||||
|
||||
int totalNumRows = 0;
|
||||
int i;
|
||||
|
||||
m_tmpConstraintSizesPool.resize(numConstraints);
|
||||
//calculate the total number of contraint rows
|
||||
for (i=0;i<numConstraints;i++)
|
||||
{
|
||||
|
||||
btTypedConstraint::btConstraintInfo1 info1;
|
||||
btTypedConstraint::btConstraintInfo1& info1 = m_tmpConstraintSizesPool[i];
|
||||
constraints[i]->getInfo1(&info1);
|
||||
totalNumRows += info1.m_numConstraintRows;
|
||||
}
|
||||
m_tmpSolverNonContactConstraintPool.resize(totalNumRows);
|
||||
|
||||
btTypedConstraint::btConstraintInfo1 info1;
|
||||
info1.m_numConstraintRows = 0;
|
||||
|
||||
|
||||
|
||||
///setup the btSolverConstraints
|
||||
int currentRow = 0;
|
||||
|
||||
for (i=0;i<numConstraints;i++,currentRow+=info1.m_numConstraintRows)
|
||||
for (i=0;i<numConstraints;i++)
|
||||
{
|
||||
constraints[i]->getInfo1(&info1);
|
||||
const btTypedConstraint::btConstraintInfo1& info1 = m_tmpConstraintSizesPool[i];
|
||||
|
||||
if (info1.m_numConstraintRows)
|
||||
{
|
||||
btAssert(currentRow<totalNumRows);
|
||||
@@ -782,6 +781,7 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCol
|
||||
}
|
||||
}
|
||||
}
|
||||
currentRow+=m_tmpConstraintSizesPool[i].m_numConstraintRows;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -972,6 +972,7 @@ btScalar btSequentialImpulseConstraintSolver::solveGroup(btCollisionObject** bod
|
||||
int numPoolConstraints = m_tmpSolverContactConstraintPool.size();
|
||||
int j;
|
||||
|
||||
//copy back the applied impulses for contacts
|
||||
for (j=0;j<numPoolConstraints;j++)
|
||||
{
|
||||
|
||||
@@ -988,6 +989,39 @@ btScalar btSequentialImpulseConstraintSolver::solveGroup(btCollisionObject** bod
|
||||
//do a callback here?
|
||||
}
|
||||
|
||||
int currentRow = 0;
|
||||
int totalNumRows = m_tmpSolverNonContactConstraintPool.size();
|
||||
#if 1
|
||||
//copy back the applied impulses for joints
|
||||
for (i=0;i<numConstraints;i++)
|
||||
{
|
||||
btTypedConstraint* constraint = constraints[i];
|
||||
if (constraint->needsFeedback())
|
||||
{
|
||||
const btTypedConstraint::btConstraintInfo1& info1 = m_tmpConstraintSizesPool[i];
|
||||
if (info1.m_numConstraintRows)
|
||||
{
|
||||
btAssert(currentRow<totalNumRows);
|
||||
btSolverConstraint* currentConstraintRow = &m_tmpSolverNonContactConstraintPool[currentRow];
|
||||
|
||||
constraint->getAppliedLinearImpulse().setValue(0,0,0);
|
||||
constraint->getAppliedAngularImpulseA().setValue(0,0,0);
|
||||
constraint->getAppliedAngularImpulseB().setValue(0,0,0);
|
||||
int j;
|
||||
btScalar maxAppliedImpulse(0.);
|
||||
for ( j=0;j<info1.m_numConstraintRows;j++)
|
||||
{
|
||||
btSetMax(maxAppliedImpulse,(btScalar)currentConstraintRow[i].m_appliedImpulse);
|
||||
constraint->getAppliedLinearImpulse() += currentConstraintRow[i].m_contactNormal*currentConstraintRow[i].m_appliedImpulse;
|
||||
constraint->getAppliedAngularImpulseA() += currentConstraintRow[i].m_relpos1CrossNormal*currentConstraintRow[i].m_appliedImpulse;
|
||||
constraint->getAppliedAngularImpulseB() += currentConstraintRow[i].m_relpos2CrossNormal*currentConstraintRow[i].m_appliedImpulse;
|
||||
}
|
||||
constraint->internalSetAppliedImpulse(maxAppliedImpulse);
|
||||
}
|
||||
}
|
||||
currentRow+=m_tmpConstraintSizesPool[i].m_numConstraintRows;
|
||||
}
|
||||
#endif
|
||||
if (infoGlobal.m_splitImpulse)
|
||||
{
|
||||
for ( i=0;i<m_tmpSolverBodyPool.size();i++)
|
||||
|
||||
@@ -21,7 +21,7 @@ class btIDebugDraw;
|
||||
#include "btContactConstraint.h"
|
||||
#include "btSolverBody.h"
|
||||
#include "btSolverConstraint.h"
|
||||
|
||||
#include "btTypedConstraint.h"
|
||||
|
||||
|
||||
///The btSequentialImpulseConstraintSolver is a fast SIMD implementation of the Projected Gauss Seidel (iterative LCP) method.
|
||||
@@ -35,6 +35,7 @@ protected:
|
||||
btConstraintArray m_tmpSolverContactFrictionConstraintPool;
|
||||
btAlignedObjectArray<int> m_orderTmpConstraintPool;
|
||||
btAlignedObjectArray<int> m_orderFrictionConstraintPool;
|
||||
btAlignedObjectArray<btTypedConstraint::btConstraintInfo1> m_tmpConstraintSizesPool;
|
||||
|
||||
btSolverConstraint& addFrictionConstraint(const btVector3& normalAxis,int solverBodyIdA,int solverBodyIdB,int frictionIndex,btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2,btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation);
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ static btRigidBody s_fixed(0, 0,0);
|
||||
btTypedConstraint::btTypedConstraint(btTypedConstraintType type)
|
||||
:m_userConstraintType(-1),
|
||||
m_userConstraintId(-1),
|
||||
m_needsFeedback(false),
|
||||
m_constraintType (type),
|
||||
m_rbA(s_fixed),
|
||||
m_rbB(s_fixed),
|
||||
@@ -35,6 +36,7 @@ m_dbgDrawSize(DEFAULT_DEBUGDRAW_SIZE)
|
||||
btTypedConstraint::btTypedConstraint(btTypedConstraintType type, btRigidBody& rbA)
|
||||
:m_userConstraintType(-1),
|
||||
m_userConstraintId(-1),
|
||||
m_needsFeedback(false),
|
||||
m_constraintType (type),
|
||||
m_rbA(rbA),
|
||||
m_rbB(s_fixed),
|
||||
@@ -49,6 +51,7 @@ m_dbgDrawSize(DEFAULT_DEBUGDRAW_SIZE)
|
||||
btTypedConstraint::btTypedConstraint(btTypedConstraintType type, btRigidBody& rbA,btRigidBody& rbB)
|
||||
:m_userConstraintType(-1),
|
||||
m_userConstraintId(-1),
|
||||
m_needsFeedback(false),
|
||||
m_constraintType (type),
|
||||
m_rbA(rbA),
|
||||
m_rbB(rbB),
|
||||
|
||||
@@ -38,6 +38,7 @@ class btTypedConstraint
|
||||
{
|
||||
int m_userConstraintType;
|
||||
int m_userConstraintId;
|
||||
bool m_needsFeedback;
|
||||
|
||||
btTypedConstraintType m_constraintType;
|
||||
|
||||
@@ -54,6 +55,9 @@ protected:
|
||||
btScalar m_appliedImpulse;
|
||||
btScalar m_dbgDrawSize;
|
||||
|
||||
btVector3 m_appliedLinearImpulse;
|
||||
btVector3 m_appliedAngularImpulseA;
|
||||
btVector3 m_appliedAngularImpulseB;
|
||||
|
||||
public:
|
||||
|
||||
@@ -95,18 +99,30 @@ public:
|
||||
int *findex;
|
||||
};
|
||||
|
||||
|
||||
///internal method used by the constraint solver, don't use them directly
|
||||
virtual void buildJacobian() = 0;
|
||||
|
||||
///internal method used by the constraint solver, don't use them directly
|
||||
virtual void setupSolverConstraint(btConstraintArray& ca, int solverBodyA,int solverBodyB, btScalar timeStep)
|
||||
{
|
||||
}
|
||||
|
||||
///internal method used by the constraint solver, don't use them directly
|
||||
virtual void getInfo1 (btConstraintInfo1* info)=0;
|
||||
|
||||
///internal method used by the constraint solver, don't use them directly
|
||||
virtual void getInfo2 (btConstraintInfo2* info)=0;
|
||||
|
||||
///internal method used by the constraint solver, don't use them directly
|
||||
void internalSetAppliedImpulse(btScalar appliedImpulse)
|
||||
{
|
||||
m_appliedImpulse = appliedImpulse;
|
||||
}
|
||||
|
||||
///internal method used by the constraint solver, don't use them directly
|
||||
virtual void solveConstraintObsolete(btSolverBody& bodyA,btSolverBody& bodyB,btScalar timeStep) = 0;
|
||||
|
||||
///internal method used by the constraint solver, don't use them directly
|
||||
btScalar getMotorFactor(btScalar pos, btScalar lowLim, btScalar uppLim, btScalar vel, btScalar timeFact);
|
||||
|
||||
const btRigidBody& getRigidBodyA() const
|
||||
@@ -152,11 +168,64 @@ public:
|
||||
return m_userConstraintId;
|
||||
}
|
||||
|
||||
bool needsFeedback() const
|
||||
{
|
||||
return m_needsFeedback;
|
||||
}
|
||||
|
||||
///enableFeedback will allow to read the applied linear and angular impulse
|
||||
///use getAppliedImpulse, getAppliedLinearImpulse and getAppliedAngularImpulse to read feedback information
|
||||
void enableFeedback(bool needsFeedback)
|
||||
{
|
||||
m_needsFeedback = needsFeedback;
|
||||
}
|
||||
|
||||
///getAppliedImpulse is an estimated total applied impulse.
|
||||
///This feedback could be used to determine breaking constraints or playing sounds.
|
||||
btScalar getAppliedImpulse() const
|
||||
{
|
||||
btAssert(m_needsFeedback);
|
||||
return m_appliedImpulse;
|
||||
}
|
||||
|
||||
const btVector3& getAppliedLinearImpulse() const
|
||||
{
|
||||
btAssert(m_needsFeedback);
|
||||
return m_appliedLinearImpulse;
|
||||
}
|
||||
|
||||
btVector3& getAppliedLinearImpulse()
|
||||
{
|
||||
btAssert(m_needsFeedback);
|
||||
return m_appliedLinearImpulse;
|
||||
}
|
||||
|
||||
const btVector3& getAppliedAngularImpulseA() const
|
||||
{
|
||||
btAssert(m_needsFeedback);
|
||||
return m_appliedAngularImpulseA;
|
||||
}
|
||||
|
||||
btVector3& getAppliedAngularImpulseA()
|
||||
{
|
||||
btAssert(m_needsFeedback);
|
||||
return m_appliedAngularImpulseA;
|
||||
}
|
||||
|
||||
const btVector3& getAppliedAngularImpulseB() const
|
||||
{
|
||||
btAssert(m_needsFeedback);
|
||||
return m_appliedAngularImpulseB;
|
||||
}
|
||||
|
||||
btVector3& getAppliedAngularImpulseB()
|
||||
{
|
||||
btAssert(m_needsFeedback);
|
||||
return m_appliedAngularImpulseB;
|
||||
}
|
||||
|
||||
|
||||
|
||||
btTypedConstraintType getConstraintType () const
|
||||
{
|
||||
return m_constraintType;
|
||||
|
||||
Reference in New Issue
Block a user