friction fixes

This commit is contained in:
Xuchen Han
2019-08-09 16:02:44 -07:00
parent 5b8df6a708
commit fb6612c0be
5 changed files with 45 additions and 15 deletions

View File

@@ -145,3 +145,8 @@ void btDeformableBackwardEulerObjective::setConstraints()
m_world->btMultiBodyDynamicsWorld::buildIslands(); m_world->btMultiBodyDynamicsWorld::buildIslands();
projection.setConstraints(); projection.setConstraints();
} }
void btDeformableBackwardEulerObjective::projectFriction(TVStack& r)
{
projection.projectFriction(r);
}

View File

@@ -75,6 +75,8 @@ public:
projection.enforceConstraint(x); projection.enforceConstraint(x);
} }
void projectFriction(TVStack& r);
// add dv to velocity // add dv to velocity
void updateVelocity(const TVStack& dv); void updateVelocity(const TVStack& dv);

View File

@@ -38,6 +38,7 @@ void btDeformableBodySolver::solveConstraints(float solverdt)
setConstraints(); setConstraints();
m_objective->computeResidual(solverdt, m_residual); m_objective->computeResidual(solverdt, m_residual);
m_objective->projectFriction(m_residual);
computeStep(m_dv, m_residual); computeStep(m_dv, m_residual);
updateVelocity(); updateVelocity();
} }
@@ -75,7 +76,7 @@ void btDeformableBodySolver::setConstraints()
{ {
BT_PROFILE("setConstraint"); BT_PROFILE("setConstraint");
m_objective->setConstraints(); m_objective->setConstraints();
for (int i = 0; i < 10; ++i) for (int i = 0; i < 1; ++i)
{ {
m_objective->projection.update(); m_objective->projection.update();
m_objective->enforceConstraint(m_dv); m_objective->enforceConstraint(m_dv);

View File

@@ -133,10 +133,11 @@ void btDeformableContactProjection::update()
friction.m_impulse_prev[j] = friction.m_impulse[j]; friction.m_impulse_prev[j] = friction.m_impulse[j];
friction.m_dv_prev[j] = friction.m_dv[j]; friction.m_dv_prev[j] = friction.m_dv[j];
friction.m_static_prev[j] = friction.m_static[j]; friction.m_static_prev[j] = friction.m_static[j];
friction.m_direction_prev[j] = friction.m_direction[j];
// get the current tangent direction // get the current tangent direction
btScalar local_tangent_norm = impulse_tangent.norm(); btScalar local_tangent_norm = impulse_tangent.norm();
btVector3 local_tangent_dir = btVector3(0,0,0); btVector3 local_tangent_dir = -friction.m_direction[j];
if (local_tangent_norm > SIMD_EPSILON) if (local_tangent_norm > SIMD_EPSILON)
local_tangent_dir = impulse_tangent.normalized(); local_tangent_dir = impulse_tangent.normalized();
@@ -395,7 +396,9 @@ void btDeformableContactProjection::enforceConstraint(TVStack& x)
// add the friction constraint // add the friction constraint
if (friction.m_static[j] == true) if (friction.m_static[j] == true)
{ {
x[i] -= x[i].dot(friction.m_direction[j]) * friction.m_direction[j]; // if (friction.m_static_prev[j] == true)
// x[i] -= friction.m_direction_prev[j] * friction.m_dv_prev[j];
// x[i] -= x[i].dot(friction.m_direction[j]) * friction.m_direction[j];
x[i] += friction.m_direction[j] * friction.m_dv[j]; x[i] += friction.m_direction[j] * friction.m_dv[j];
} }
} }
@@ -410,8 +413,8 @@ void btDeformableContactProjection::project(TVStack& x)
for (int index = 0; index < m_constraints.size(); ++index) for (int index = 0; index < m_constraints.size(); ++index)
{ {
const btAlignedObjectArray<DeformableContactConstraint>& constraints = *m_constraints.getAtIndex(index); const btAlignedObjectArray<DeformableContactConstraint>& constraints = *m_constraints.getAtIndex(index);
size_t i = m_constraints.getKeyAtIndex(index).getUid1();
btAlignedObjectArray<DeformableFrictionConstraint>& frictions = *m_frictions[m_constraints.getKeyAtIndex(index)]; btAlignedObjectArray<DeformableFrictionConstraint>& frictions = *m_frictions[m_constraints.getKeyAtIndex(index)];
size_t i = m_constraints.getKeyAtIndex(index).getUid1();
btAssert(constraints.size() <= dim); btAssert(constraints.size() <= dim);
btAssert(constraints.size() > 0); btAssert(constraints.size() > 0);
if (constraints.size() == 1) if (constraints.size() == 1)
@@ -427,6 +430,34 @@ void btDeformableContactProjection::project(TVStack& x)
} }
else else
x[i].setZero(); x[i].setZero();
// apply the friction constraint
if (constraints.size() < 3)
{
for (int f = 0; f < frictions.size(); ++f)
{
DeformableFrictionConstraint& friction= frictions[f];
for (int j = 0; j < friction.m_direction.size(); ++j)
{
if (friction.m_static[j] == true)
{
x[i] -= x[i].dot(friction.m_direction[j]) * friction.m_direction[j];
}
}
}
}
}
}
void btDeformableContactProjection::projectFriction(TVStack& x)
{
const int dim = 3;
for (int index = 0; index < m_constraints.size(); ++index)
{
const btAlignedObjectArray<DeformableContactConstraint>& constraints = *m_constraints.getAtIndex(index);
size_t i = m_constraints.getKeyAtIndex(index).getUid1();
btAlignedObjectArray<DeformableFrictionConstraint>& frictions = *m_frictions[m_constraints.getKeyAtIndex(index)];
btAssert(constraints.size() <= dim);
btAssert(constraints.size() > 0);
// apply friction if the node is not constrained in all directions // apply friction if the node is not constrained in all directions
if (constraints.size() < 3) if (constraints.size() < 3)
@@ -444,23 +475,12 @@ void btDeformableContactProjection::project(TVStack& x)
DeformableFrictionConstraint& friction= frictions[f]; DeformableFrictionConstraint& friction= frictions[f];
for (int j = 0; j < friction.m_direction.size(); ++j) for (int j = 0; j < friction.m_direction.size(); ++j)
{ {
// clear the old friction force
if (friction.m_static_prev[j] == false)
{
x[i] -= friction.m_direction_prev[j] * friction.m_impulse_prev[j];
}
// only add to the rhs if there is no static friction constraint on the node // only add to the rhs if there is no static friction constraint on the node
if (friction.m_static[j] == false) if (friction.m_static[j] == false)
{ {
if (!has_static_constraint) if (!has_static_constraint)
x[i] += friction.m_direction[j] * friction.m_impulse[j]; x[i] += friction.m_direction[j] * friction.m_impulse[j];
} }
else
{
// otherwise clear the constraint in the friction direction
x[i] -= x[i].dot(friction.m_direction[j]) * friction.m_direction[j];
}
} }
} }
} }

View File

@@ -36,6 +36,8 @@ public:
// apply the constraints to the rhs // apply the constraints to the rhs
virtual void project(TVStack& x); virtual void project(TVStack& x);
// add to friction
virtual void projectFriction(TVStack& x);
// apply constraints to x in Ax=b // apply constraints to x in Ax=b
virtual void enforceConstraint(TVStack& x); virtual void enforceConstraint(TVStack& x);