[Bf-blender-cvs] [4eac83d] master: Updating Eigen implicit dynamics solver implementation to adhere to the new mass-spring solver API.
Lukas Tönne
noreply at git.blender.org
Tue Jan 20 09:51:47 CET 2015
Commit: 4eac83da66a3bd8366035443e805b4b4be822f62
Author: Lukas Tönne
Date: Sun Oct 12 12:45:07 2014 +0200
Branches: master
https://developer.blender.org/rB4eac83da66a3bd8366035443e805b4b4be822f62
Updating Eigen implicit dynamics solver implementation to adhere to the
new mass-spring solver API.
Conflicts:
source/blender/physics/intern/implicit_eigen.cpp
===================================================================
M source/blender/physics/intern/implicit.h
M source/blender/physics/intern/implicit_eigen.cpp
===================================================================
diff --git a/source/blender/physics/intern/implicit.h b/source/blender/physics/intern/implicit.h
index ad714de..4659bb0 100644
--- a/source/blender/physics/intern/implicit.h
+++ b/source/blender/physics/intern/implicit.h
@@ -42,8 +42,8 @@
extern "C" {
#endif
-//#define IMPLICIT_SOLVER_EIGEN
-#define IMPLICIT_SOLVER_BLENDER
+#define IMPLICIT_SOLVER_EIGEN
+//#define IMPLICIT_SOLVER_BLENDER
#define CLOTH_ROOT_FRAME /* enable use of root frame coordinate transform */
diff --git a/source/blender/physics/intern/implicit_eigen.cpp b/source/blender/physics/intern/implicit_eigen.cpp
index 6525a49..402ffcb 100644
--- a/source/blender/physics/intern/implicit_eigen.cpp
+++ b/source/blender/physics/intern/implicit_eigen.cpp
@@ -36,6 +36,12 @@
//#define USE_EIGEN_CORE
#define USE_EIGEN_CONSTRAINED_CG
+#ifdef __GNUC__
+# pragma GCC diagnostic push
+/* XXX suppress verbose warnings in eigen */
+# pragma GCC diagnostic ignored "-Wlogical-op"
+#endif
+
#ifndef IMPLICIT_ENABLE_EIGEN_DEBUG
#ifdef NDEBUG
#define IMPLICIT_NDEBUG
@@ -58,6 +64,10 @@
#endif
#endif
+#ifdef __GNUC__
+# pragma GCC diagnostic pop
+#endif
+
#include "MEM_guardedalloc.h"
extern "C" {
@@ -81,13 +91,111 @@ extern "C" {
typedef float Scalar;
-typedef Eigen::SparseMatrix<Scalar> lMatrix;
+static float I[3][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
+static float ZERO[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
+
+/* slightly extended Eigen vector class
+ * with conversion to/from plain C float array
+ */
+class fVector : public Eigen::Vector3f {
+public:
+ typedef float *ctype;
+
+ fVector()
+ {
+ }
+
+ fVector(const ctype &v)
+ {
+ for (int k = 0; k < 3; ++k)
+ coeffRef(k) = v[k];
+ }
+
+ fVector &operator = (const ctype &v)
+ {
+ for (int k = 0; k < 3; ++k)
+ coeffRef(k) = v[k];
+ return *this;
+ }
+
+ operator ctype()
+ {
+ return data();
+ }
+};
+
+/* slightly extended Eigen matrix class
+ * with conversion to/from plain C float array
+ */
+class fMatrix : public Eigen::Matrix3f {
+public:
+ typedef float (*ctype)[3];
+
+ fMatrix()
+ {
+ }
+
+ fMatrix(const ctype &v)
+ {
+ for (int k = 0; k < 3; ++k)
+ for (int l = 0; l < 3; ++l)
+ coeffRef(l, k) = v[k][l];
+ }
+
+ fMatrix &operator = (const ctype &v)
+ {
+ for (int k = 0; k < 3; ++k)
+ for (int l = 0; l < 3; ++l)
+ coeffRef(l, k) = v[k][l];
+ return *this;
+ }
+
+ operator ctype()
+ {
+ return (ctype)data();
+ }
+};
typedef Eigen::VectorXf lVector;
typedef Eigen::Triplet<Scalar> Triplet;
typedef std::vector<Triplet> TripletList;
+typedef Eigen::SparseMatrix<Scalar> lMatrix;
+
+struct lMatrixCtor {
+ lMatrixCtor(int numverts) :
+ m_numverts(numverts)
+ {
+ /* reserve for diagonal entries */
+ m_trips.reserve(numverts * 9);
+ }
+
+ int numverts() const { return m_numverts; }
+
+ void set(int i, int j, const fMatrix &m)
+ {
+ BLI_assert(i >= 0 && i < m_numverts);
+ BLI_assert(j >= 0 && j < m_numverts);
+ i *= 3;
+ j *= 3;
+ for (int k = 0; k < 3; ++k)
+ for (int l = 0; l < 3; ++l)
+ m_trips.push_back(Triplet(i + k, j + l, m.coeff(l, k)));
+ }
+
+ inline lMatrix construct() const
+ {
+ lMatrix m(m_numverts, m_numverts);
+ m.setFromTriplets(m_trips.begin(), m_trips.end());
+ return m;
+ }
+
+private:
+ const int m_numverts;
+ TripletList m_trips;
+};
+
#ifdef USE_EIGEN_CORE
typedef Eigen::ConjugateGradient<lMatrix, Eigen::Lower, Eigen::DiagonalPreconditioner<Scalar> > ConjugateGradient;
#endif
@@ -124,9 +232,6 @@ static void print_lmatrix(const lMatrix &m)
}
}
-static float I[3][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
-static float ZERO[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
-
BLI_INLINE void lMatrix_reserve_elems(lMatrix &m, int num)
{
m.reserve(Eigen::VectorXi::Constant(m.cols(), num));
@@ -185,40 +290,6 @@ BLI_INLINE void lMatrix_sub_triplets(lMatrix &r, const TripletList &tlist)
r -= t;
}
-#if 0
-BLI_INLINE void lMatrix_copy_m3(lMatrix &r, float m[3][3], int i, int j)
-{
- i *= 3;
- j *= 3;
- for (int l = 0; l < 3; ++l) {
- for (int k = 0; k < 3; ++k) {
- r.coeffRef(i + k, j + l) = m[k][l];
- }
- }
-}
-
-BLI_INLINE void lMatrix_add_m3(lMatrix &r, float m[3][3], int i, int j)
-{
- lMatrix tmp(r.cols(), r.cols());
- lMatrix_copy_m3(tmp, m, i, j);
- r += tmp;
-}
-
-BLI_INLINE void lMatrix_sub_m3(lMatrix &r, float m[3][3], int i, int j)
-{
- lMatrix tmp(r.cols(), r.cols());
- lMatrix_copy_m3(tmp, m, i, j);
- r -= tmp;
-}
-
-BLI_INLINE void lMatrix_madd_m3(lMatrix &r, float m[3][3], float s, int i, int j)
-{
- lMatrix tmp(r.cols(), r.cols());
- lMatrix_copy_m3(tmp, m, i, j);
- r += s * tmp;
-}
-#endif
-
BLI_INLINE void outerproduct(float r[3][3], const float a[3], const float b[3])
{
mul_v3_v3fl(r[0], a, b[0]);
@@ -226,21 +297,11 @@ BLI_INLINE void outerproduct(float r[3][3], const float a[3], const float b[3])
mul_v3_v3fl(r[2], a, b[2]);
}
-struct RootTransform {
- float loc[3];
- float rot[3][3];
-
- float vel[3];
- float omega[3];
-
- float acc[3];
- float domega_dt[3];
-};
-
struct Implicit_Data {
- typedef std::vector<RootTransform> RootTransforms;
+ typedef std::vector<fMatrix> fMatrixVector;
- Implicit_Data(int numverts)
+ Implicit_Data(int numverts) :
+ M(numverts)
{
resize(numverts);
}
@@ -250,11 +311,10 @@ struct Implicit_Data {
this->numverts = numverts;
int tot = 3 * numverts;
- M.resize(tot, tot);
dFdV.resize(tot, tot);
dFdX.resize(tot, tot);
- root.resize(numverts);
+ tfm.resize(numverts, I);
X.resize(tot);
Xnew.resize(tot);
@@ -273,11 +333,11 @@ struct Implicit_Data {
int numverts;
/* inputs */
- lMatrix M; /* masses */
+ lMatrixCtor M; /* masses */
lVector F; /* forces */
lMatrix dFdV, dFdX; /* force jacobians */
- RootTransforms root; /* root transforms */
+ fMatrixVector tfm; /* local coordinate transform */
/* motion state data */
lVector X, Xnew; /* positions */
@@ -290,182 +350,39 @@ struct Implicit_Data {
lVector dV; /* velocity change (solution of A*dV = B) */
lVector z; /* target velocity in constrained directions */
lMatrix S; /* filtering matrix for constraints */
+
+ struct SimDebugData *debug_data;
};
-/* ==== Transformation of Moving Reference Frame ====
- * x_world, v_world, f_world, a_world, dfdx_world, dfdv_world : state variables in world space
- * x_root, v_root, f_root, a_root, dfdx_root, dfdv_root : state variables in root space
- *
- * x0 : translation of the root frame (hair root location)
- * v0 : linear velocity of the root frame
- * a0 : acceleration of the root frame
- * R : rotation matrix of the root frame
- * w : angular velocity of the root frame
- * dwdt : angular acceleration of the root frame
- */
-
-/* x_root = R^T * x_world */
-BLI_INLINE void loc_world_to_root(float r[3], const float v[3], const RootTransform &root)
-{
- sub_v3_v3v3(r, v, root.loc);
- mul_transposed_m3_v3((float (*)[3])root.rot, r);
-}
+/* ==== Transformation from/to root reference frames ==== */
-/* x_world = R * x_root */
-BLI_INLINE void loc_root_to_world(float r[3], const float v[3], const RootTransform &root)
+BLI_INLINE void world_to_root_v3(Implicit_Data *data, int index, float r[3], const float v[3])
{
copy_v3_v3(r, v);
- mul_m3_v3((float (*)[3])root.rot, r);
- add_v3_v3(r, root.loc);
-}
-
-/* v_root = cross(w, x_root) + R^T*(v_world - v0) */
-BLI_INLINE void vel_world_to_root(float r[3], const float x_root[3], const float v[3], const RootTransform &root)
-{
- float angvel[3];
- cross_v3_v3v3(angvel, root.omega, x_root);
-
- sub_v3_v3v3(r, v, root.vel);
- mul_transposed_m3_v3((float (*)[3])root.rot, r);
- add_v3_v3(r, angvel);
-}
-
-/* v_world = R*(v_root - cross(w, x_root)) + v0 */
-BLI_INLINE void vel_root_to_world(float r[3], const float x_root[3], const float v[3], const RootTransform &root)
-{
- float angvel[3];
- cross_v3_v3v3(angvel, root.omega, x_root);
-
- sub_v3_v3v3(r, v, angvel);
- mul_m3_v3((float (*)[3])root.rot, r);
- add_v3_v3(r, root.vel);
-}
-
-/* a_root = -cross(dwdt, x_root) - 2*cross(w, v_root) - cross(w, cross(w, x_root)) + R^T*(a_world - a0) */
-BLI_INLINE void force_world_to_root(float r[3], const float x_root[3], const float v_root[3], const float force[3], float mass, const RootTransform &root)
-{
- float euler[3], coriolis[3], centrifugal[3], rotvel[3];
-
- cross_v3_v3v3(euler, root.domega_dt, x_root);
- cross_v3_v3v3(coriolis, root.omega, v_root);
- mul_v3_fl(coriolis, 2.0f);
- cross_v3_v3v3(rotvel, root.omega, x_root);
- cross_v3_v3v3(centrifugal, root.omega, rotvel);
-
- madd_v3_v3v3fl(r, force, root.acc, mass);
- mul_transposed_m3_v3((float (*)[3])root.rot, r);
- madd_v3_v3fl(r, euler, mass);
- madd_v3_v3fl(r, coriolis, mass);
- madd_v3_v3fl(r, centrifugal, mass);
-}
-
-/* a_world = R*[ a_root + cross(dwdt, x_root) + 2*cross(w, v_root) + cross(w, cross(w, x_root)) ] + a0 */
-BLI_INLINE void force_root_to_world(float r[3], const float x_root[3], const float v_root[3], const float force[3], float mass, const RootTransform &root)
-{
- float euler[3], coriolis[3], centrifugal[3], rotvel[3];
-
- cross_v3_v3v3(euler, root.domega_dt, x_root);
- cross_v3_v3v3(coriolis, root.omega, v_root);
- mul_v3_fl(coriolis, 2.0f);
- cross_v3_v3v3(rotvel, root.omega, x_root);
- cross_v3_v3v3(centrifugal, root.omega, rotvel);
-
- madd_v3_v3v3fl(r, force, euler, mass);
- madd_v3_v3fl(r, coriolis, mass);
- madd_v3_v3fl(r, centrifugal, mass);
- mul_m3_v3((float (*)[3])root.rot, r);
- madd_v3_v3fl(r, root.acc, mass);
-}
-
-BLI_INLINE void acc_world_to_root(float r[3], const float x_root[3], const float v_root[3], const float acc[3], const RootTransform &root)
-{
- force_world_to_root(r, x_root, v_root, acc, 1.0f, root);
-}
-
-BLI_INLINE void acc_root_to_world(float r[3], const float x_root[3], const float v_root[3], const float acc[3], const RootTransform &root)
-{
- force_root_to_world(r, x_root, v_root, acc, 1.0f, root);
+ mul_transposed_m3_v3(data->tfm[index], r);
}
-BLI_INLINE void cross_m3_v3m3(float r[3][3], const float v[3], float m[3][3])
+BLI_INLINE void root_to_world_v3(Implicit_Data *data, int index, float r[3], const float v[3])
{
- cross_v3_v3v3(r[0], v, m[0]);
- cross_v3_v3v3(r[1], v, m[1]);
- cross_v3_v3v3(r[2], v, m[2]);
+ mul_v3_m
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list