code clean up + check in examples
This commit is contained in:
@@ -12,66 +12,10 @@
|
||||
#include "btLagrangianForce.h"
|
||||
#include "btMassSpring.h"
|
||||
#include "btContactProjection.h"
|
||||
#include "btPreconditioner.h"
|
||||
#include "btDeformableRigidDynamicsWorld.h"
|
||||
|
||||
class btDeformableRigidDynamicsWorld;
|
||||
|
||||
class Preconditioner
|
||||
{
|
||||
public:
|
||||
using TVStack = btAlignedObjectArray<btVector3>;
|
||||
virtual void operator()(const TVStack& x, TVStack& b) = 0;
|
||||
virtual void reinitialize(bool nodeUpdated) = 0;
|
||||
};
|
||||
|
||||
class DefaultPreconditioner : public Preconditioner
|
||||
{
|
||||
public:
|
||||
virtual void operator()(const TVStack& x, TVStack& b)
|
||||
{
|
||||
btAssert(b.size() == x.size());
|
||||
for (int i = 0; i < b.size(); ++i)
|
||||
b[i] = x[i];
|
||||
}
|
||||
virtual void reinitialize(bool nodeUpdated)
|
||||
{
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
class MassPreconditioner : public Preconditioner
|
||||
{
|
||||
btAlignedObjectArray<btScalar> m_inv_mass;
|
||||
const btAlignedObjectArray<btSoftBody *>& m_softBodies;
|
||||
public:
|
||||
MassPreconditioner(const btAlignedObjectArray<btSoftBody *>& softBodies)
|
||||
: m_softBodies(softBodies)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void reinitialize(bool nodeUpdated)
|
||||
{
|
||||
if (nodeUpdated)
|
||||
{
|
||||
m_inv_mass.clear();
|
||||
for (int i = 0; i < m_softBodies.size(); ++i)
|
||||
{
|
||||
btSoftBody* psb = m_softBodies[i];
|
||||
for (int j = 0; j < psb->m_nodes.size(); ++j)
|
||||
m_inv_mass.push_back(psb->m_nodes[j].m_im);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual void operator()(const TVStack& x, TVStack& b)
|
||||
{
|
||||
btAssert(b.size() == x.size());
|
||||
btAssert(m_inv_mass.size() == x.size());
|
||||
for (int i = 0; i < b.size(); ++i)
|
||||
b[i] = x[i] * m_inv_mass[i];
|
||||
}
|
||||
};
|
||||
|
||||
class btBackwardEulerObjective
|
||||
{
|
||||
public:
|
||||
@@ -91,74 +35,60 @@ public:
|
||||
|
||||
void initialize(){}
|
||||
|
||||
void computeResidual(btScalar dt, TVStack& residual) const
|
||||
{
|
||||
// add implicit force
|
||||
for (int i = 0; i < m_lf.size(); ++i)
|
||||
{
|
||||
m_lf[i]->addScaledImplicitForce(dt, residual);
|
||||
}
|
||||
}
|
||||
// compute the rhs for CG solve, i.e, add the dt scaled implicit force to residual
|
||||
void computeResidual(btScalar dt, TVStack& residual) const;
|
||||
|
||||
void applyExplicitForce(TVStack& force)
|
||||
{
|
||||
for (int i = 0; i < m_lf.size(); ++i)
|
||||
m_lf[i]->addScaledExplicitForce(m_dt, force);
|
||||
|
||||
size_t counter = 0;
|
||||
for (int i = 0; i < m_softBodies.size(); ++i)
|
||||
{
|
||||
btSoftBody* psb = m_softBodies[i];
|
||||
for (int j = 0; j < psb->m_nodes.size(); ++j)
|
||||
{
|
||||
btScalar one_over_mass = (psb->m_nodes[j].m_im == 0) ? 0 : psb->m_nodes[j].m_im;
|
||||
psb->m_nodes[j].m_v += one_over_mass * force[counter];
|
||||
force[counter].setZero();
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
// add explicit force to the velocity
|
||||
void applyExplicitForce(TVStack& force);
|
||||
|
||||
btScalar computeNorm(const TVStack& residual) const
|
||||
{
|
||||
btScalar norm_squared = 0;
|
||||
for (int i = 0; i < residual.size(); ++i)
|
||||
{
|
||||
norm_squared += residual[i].length2();
|
||||
}
|
||||
return std::sqrt(norm_squared+SIMD_EPSILON);
|
||||
}
|
||||
// apply force to velocity and optionally reset the force to zero
|
||||
void applyForce(TVStack& force, bool setZero);
|
||||
|
||||
// compute the norm of the residual
|
||||
btScalar computeNorm(const TVStack& residual) const;
|
||||
|
||||
// compute one step of the solve (there is only one solve if the system is linear)
|
||||
void computeStep(TVStack& dv, const TVStack& residual, const btScalar& dt);
|
||||
|
||||
// perform A*x = b
|
||||
void multiply(const TVStack& x, TVStack& b) const;
|
||||
|
||||
// update the constraints treated as projections
|
||||
void updateProjection(const TVStack& dv)
|
||||
{
|
||||
projection.update(dv, m_backupVelocity);
|
||||
}
|
||||
|
||||
// set initial guess for CG solve
|
||||
void initialGuess(TVStack& dv, const TVStack& residual);
|
||||
|
||||
// reset data structure
|
||||
void reinitialize(bool nodeUpdated);
|
||||
|
||||
// enforce constraints in CG solve
|
||||
void enforceConstraint(TVStack& x)
|
||||
{
|
||||
projection.enforceConstraint(x);
|
||||
updateVelocity(x);
|
||||
}
|
||||
|
||||
// add dv to velocity
|
||||
void updateVelocity(const TVStack& dv);
|
||||
|
||||
void setConstraintDirections()
|
||||
//set constraints as projections
|
||||
void setConstraints()
|
||||
{
|
||||
projection.setConstraintDirections();
|
||||
projection.setConstraints();
|
||||
}
|
||||
|
||||
// update the projections and project the residual
|
||||
void project(TVStack& r, const TVStack& dv)
|
||||
{
|
||||
updateProjection(dv);
|
||||
projection(r);
|
||||
}
|
||||
|
||||
// perform precondition M^(-1) x = b
|
||||
void precondition(const TVStack& x, TVStack& b)
|
||||
{
|
||||
m_preconditioner->operator()(x,b);
|
||||
|
||||
Reference in New Issue
Block a user