[Bf-blender-cvs] [dbe2f67] hair_immediate_fixes: Updating Eigen implicit dynamics solver implementation to adhere to the new mass-spring solver API.

Lukas Tönne noreply at git.blender.org
Sun Oct 12 17:15:30 CEST 2014


Commit: dbe2f67ca5d18190564cf659b794295812a99f72
Author: Lukas Tönne
Date:   Sun Oct 12 12:45:07 2014 +0200
Branches: hair_immediate_fixes
https://developer.blender.org/rBdbe2f67ca5d18190564cf659b794295812a99f72

Updating Eigen implicit dynamics solver implementation to adhere to the
new mass-spring solver API.

===================================================================

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 d391907..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