summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXuchen Han <xuchenhan@xuchenhan-macbookpro.roam.corp.google.com>2019-07-12 10:35:50 -0700
committerXuchen Han <xuchenhan@xuchenhan-macbookpro.roam.corp.google.com>2019-08-02 13:12:41 -0700
commit98cd9a85e4416686e099969332691c91b60a3468 (patch)
treeea10f00aa46a3f878cc2beaf19daa978d6f940c0
parent696c96f392f41ee41045d345082032d6bfcebcd8 (diff)
downloadbullet3-98cd9a85e4416686e099969332691c91b60a3468.tar.gz
generalize preconditioner, now supports mass preconditioning
-rw-r--r--src/BulletSoftBody/btBackwardEulerObjective.cpp10
-rw-r--r--src/BulletSoftBody/btBackwardEulerObjective.h78
2 files changed, 73 insertions, 15 deletions
diff --git a/src/BulletSoftBody/btBackwardEulerObjective.cpp b/src/BulletSoftBody/btBackwardEulerObjective.cpp
index 8801e68df..12c7a7add 100644
--- a/src/BulletSoftBody/btBackwardEulerObjective.cpp
+++ b/src/BulletSoftBody/btBackwardEulerObjective.cpp
@@ -8,14 +8,15 @@
#include "btBackwardEulerObjective.h"
btBackwardEulerObjective::btBackwardEulerObjective(btAlignedObjectArray<btSoftBody *>& softBodies, const TVStack& backup_v)
-: cg(20)
+: cg(50)
, m_softBodies(softBodies)
-, precondition(DefaultPreconditioner())
, projection(m_softBodies, m_dt)
, m_backupVelocity(backup_v)
{
// TODO: this should really be specified in initialization instead of here
btMassSpring* mass_spring = new btMassSpring(m_softBodies);
+// m_preconditioner = new MassPreconditioner(m_softBodies);
+ m_preconditioner = new DefaultPreconditioner();
m_lf.push_back(mass_spring);
}
@@ -28,8 +29,9 @@ void btBackwardEulerObjective::reinitialize(bool nodeUpdated)
for (int i = 0; i < m_lf.size(); ++i)
{
m_lf[i]->reinitialize(nodeUpdated);
- projection.reinitialize(nodeUpdated);
}
+ projection.reinitialize(nodeUpdated);
+ m_preconditioner->reinitialize(nodeUpdated);
}
@@ -64,7 +66,7 @@ void btBackwardEulerObjective::multiply(const TVStack& x, TVStack& b) const
void btBackwardEulerObjective::computeStep(TVStack& dv, const TVStack& residual, const btScalar& dt)
{
m_dt = dt;
- btScalar tolerance = std::numeric_limits<float>::epsilon()* 16 * computeNorm(residual);
+ btScalar tolerance = std::numeric_limits<float>::epsilon()* 1024 * computeNorm(residual);
cg.solve(*this, dv, residual, tolerance);
}
diff --git a/src/BulletSoftBody/btBackwardEulerObjective.h b/src/BulletSoftBody/btBackwardEulerObjective.h
index 424291700..9b94341b7 100644
--- a/src/BulletSoftBody/btBackwardEulerObjective.h
+++ b/src/BulletSoftBody/btBackwardEulerObjective.h
@@ -15,25 +15,82 @@
#include "btDeformableRigidDynamicsWorld.h"
class btDeformableRigidDynamicsWorld;
-class btBackwardEulerObjective
+
+class Preconditioner
{
public:
using TVStack = btAlignedObjectArray<btVector3>;
- struct DefaultPreconditioner
+ 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)
{
- void operator()(const TVStack& x, TVStack& b)
+ }
+
+ virtual void reinitialize(bool nodeUpdated)
+ {
+ if (nodeUpdated)
{
- btAssert(b.size() == x.size());
- for (int i = 0; i < b.size(); ++i)
- b[i] = x[i];
+ 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:
+ using TVStack = btAlignedObjectArray<btVector3>;
+// struct DefaultPreconditioner
+// {
+// void operator()(const TVStack& x, TVStack& b)
+// {
+// btAssert(b.size() == x.size());
+// for (int i = 0; i < b.size(); ++i)
+// b[i] = x[i];
+// }
+// };
btScalar m_dt;
btConjugateGradient<btBackwardEulerObjective> cg;
btDeformableRigidDynamicsWorld* m_world;
btAlignedObjectArray<btLagrangianForce*> m_lf;
btAlignedObjectArray<btSoftBody *>& m_softBodies;
- std::function<void(const TVStack&, TVStack&)> precondition;
+ Preconditioner* m_preconditioner;
btContactProjection projection;
const TVStack& m_backupVelocity;
@@ -92,10 +149,9 @@ public:
projection(r);
}
- template <class Func>
- void setPreconditioner(Func preconditioner_func)
+ void precondition(const TVStack& x, TVStack& b)
{
- precondition = preconditioner_func;
+ m_preconditioner->operator()(x,b);
}
virtual void setWorld(btDeformableRigidDynamicsWorld* world)