[Bf-blender-cvs] [d572d60] hair_system: Very basic Semi-implicit Euler integrator for hair particles.

Lukas Tönne noreply at git.blender.org
Sun Jul 27 17:05:38 CEST 2014


Commit: d572d60d03844361032087c4d7dbd7c8d9515e38
Author: Lukas Tönne
Date:   Sun Jul 27 17:02:47 2014 +0200
Branches: hair_system
https://developer.blender.org/rBd572d60d03844361032087c4d7dbd7c8d9515e38

Very basic Semi-implicit Euler integrator for hair particles.

The semi-implicit (aka symplectic) Euler integrator is almost as simple
as the basic Euler integration, but conserves Energy much better.
http://en.wikipedia.org/wiki/Semi-implicit_Euler_method

It is the integrator suggested originally in this paper:
http://graphics.pixar.com/library/CurlyHairA/paper.pdf

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

M	source/blender/editors/physics/hair_ops.c
M	source/blender/hair/HAIR_capi.cpp
M	source/blender/hair/HAIR_capi.h
M	source/blender/hair/intern/HAIR_curve.cpp
M	source/blender/hair/intern/HAIR_curve.h
M	source/blender/hair/intern/HAIR_solver.cpp
M	source/blender/hair/intern/HAIR_solver.h
M	source/blender/hair/intern/HAIR_types.h
M	source/blender/makesdna/DNA_hair_types.h

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

diff --git a/source/blender/editors/physics/hair_ops.c b/source/blender/editors/physics/hair_ops.c
index d9a578c..a41991d 100644
--- a/source/blender/editors/physics/hair_ops.c
+++ b/source/blender/editors/physics/hair_ops.c
@@ -92,7 +92,7 @@ static int hair_simulate_exec(bContext *C, wmOperator *UNUSED(op))
 	solver = HAIR_solver_new();
 	HAIR_solver_init(solver, hsys);
 	
-	
+	HAIR_solver_step(solver, 0.1f);
 	
 	HAIR_solver_apply(solver, hsys);
 	
@@ -146,6 +146,7 @@ static void hair_copy_from_particles_psys(Object *ob, HairSystem *hsys, Object *
 			HairPoint *point = points + k;
 			
 			mul_v3_m4v3(point->co, mat, pa_key->co);
+			zero_v3(point->vel);
 		}
 	}
 }
diff --git a/source/blender/hair/HAIR_capi.cpp b/source/blender/hair/HAIR_capi.cpp
index 0345e1c..ebf6877 100644
--- a/source/blender/hair/HAIR_capi.cpp
+++ b/source/blender/hair/HAIR_capi.cpp
@@ -76,11 +76,18 @@ void HAIR_solver_init(struct HAIR_Solver *csolver, HairSystem *hsys)
 		
 		for (int k = 0; k < hair->totpoints; ++k, ++point) {
 			HairPoint *hair_pt = hair->points + k;
-			*point = Point(float3(hair_pt->co[0], hair_pt->co[1], hair_pt->co[2]));
+			*point = Point(hair_pt->co, hair_pt->vel);
 		}
 	}
 }
 
+void HAIR_solver_step(struct HAIR_Solver *csolver, float timestep)
+{
+	Solver *solver = (Solver *)csolver;
+	
+	solver->step(timestep);
+}
+
 void HAIR_solver_apply(struct HAIR_Solver *csolver, HairSystem *hsys)
 {
 	Solver *solver = (Solver *)csolver;
@@ -98,9 +105,8 @@ void HAIR_solver_apply(struct HAIR_Solver *csolver, HairSystem *hsys)
 			Point *point = curve->points + k;
 			HairPoint *hpoint = hcurve->points + k;
 			
-			hpoint->co[0] = point->co.x;
-			hpoint->co[1] = point->co.y;
-			hpoint->co[2] = point->co.z;
+			copy_v3_v3(hpoint->co, point->cur.co.data());
+			copy_v3_v3(hpoint->vel, point->cur.vel.data());
 		}
 	}
 }
@@ -114,10 +120,8 @@ struct HAIR_SmoothingIteratorFloat3 *HAIR_smoothing_iter_new(HairCurve *curve, f
 		float *co0 = curve->points[0].co;
 		float *co1 = curve->points[1].co;
 		
-		float3 val = iter->begin(float3(co0[0], co0[1], co0[2]), float3(co1[0], co1[1], co1[2]));
-		cval[0] = val.x;
-		cval[1] = val.y;
-		cval[2] = val.z;
+		float3 val = iter->begin(co0, co1);
+		copy_v3_v3(cval, val.data());
 	}
 	/* XXX setting iter->num is not nice, find a better way to invalidate the iterator */
 	else if (curve->totpoints >= 1) {
@@ -149,10 +153,8 @@ void HAIR_smoothing_iter_next(HairCurve *curve, struct HAIR_SmoothingIteratorFlo
 	SmoothingIterator<float3> *iter = (SmoothingIterator<float3> *)citer;
 	
 	float *co = curve->points[iter->num].co;
-	float3 val = iter->next(float3(co[0], co[1], co[2]));
-	cval[0] = val.x;
-	cval[1] = val.y;
-	cval[2] = val.z;
+	float3 val = iter->next(co);
+	copy_v3_v3(cval, val.data());
 }
 
 void HAIR_smoothing_iter_end(HairCurve *curve, struct HAIR_SmoothingIteratorFloat3 *citer, float cval[3])
@@ -160,8 +162,6 @@ void HAIR_smoothing_iter_end(HairCurve *curve, struct HAIR_SmoothingIteratorFloa
 	SmoothingIterator<float3> *iter = (SmoothingIterator<float3> *)citer;
 	
 	float *co = curve->points[iter->num-1].co;
-	float3 val = iter->next(float3(co[0], co[1], co[2]));
-	cval[0] = val.x;
-	cval[1] = val.y;
-	cval[2] = val.z;
+	float3 val = iter->next(co);
+	copy_v3_v3(cval, val.data());
 }
diff --git a/source/blender/hair/HAIR_capi.h b/source/blender/hair/HAIR_capi.h
index d6a9581..64d3764 100644
--- a/source/blender/hair/HAIR_capi.h
+++ b/source/blender/hair/HAIR_capi.h
@@ -37,6 +37,7 @@ struct HAIR_SmoothingIteratorFloat3;
 struct HAIR_Solver *HAIR_solver_new(void);
 void HAIR_solver_free(struct HAIR_Solver *solver);
 void HAIR_solver_init(struct HAIR_Solver *solver, struct HairSystem *hsys);
+void HAIR_solver_step(struct HAIR_Solver *solver, float timestep);
 void HAIR_solver_apply(struct HAIR_Solver *solver, struct HairSystem *hsys);
 
 struct HAIR_SmoothingIteratorFloat3 *HAIR_smoothing_iter_new(struct HairCurve *curve, float rest_length, float amount, float cval[3]);
diff --git a/source/blender/hair/intern/HAIR_curve.cpp b/source/blender/hair/intern/HAIR_curve.cpp
index 8a9cfb1..1d9af11 100644
--- a/source/blender/hair/intern/HAIR_curve.cpp
+++ b/source/blender/hair/intern/HAIR_curve.cpp
@@ -32,9 +32,10 @@ Point::Point()
 {
 }
 
-Point::Point(const float3 &co) :
-    co(co)
+Point::Point(const float3 &co, const float3 &vel)
 {
+	cur.co = co;
+	cur.vel = vel;
 }
 
 Curve::Curve(int totpoints, Point *points) :
diff --git a/source/blender/hair/intern/HAIR_curve.h b/source/blender/hair/intern/HAIR_curve.h
index 70b4f13..404dbac 100644
--- a/source/blender/hair/intern/HAIR_curve.h
+++ b/source/blender/hair/intern/HAIR_curve.h
@@ -34,10 +34,16 @@
 HAIR_NAMESPACE_BEGIN
 
 struct Point {
+	struct State {
+		float3 co;
+		float3 vel;
+	};
+	
 	Point();
-	Point(const float3 &co);
+	Point(const float3 &co, const float3 &vel);
 	
-	float3 co;
+	State cur;
+	State next;
 	
 	HAIR_CXX_CLASS_ALLOC(Point)
 };
diff --git a/source/blender/hair/intern/HAIR_solver.cpp b/source/blender/hair/intern/HAIR_solver.cpp
index 834133c..84b6e39 100644
--- a/source/blender/hair/intern/HAIR_solver.cpp
+++ b/source/blender/hair/intern/HAIR_solver.cpp
@@ -86,4 +86,42 @@ void Solver::free_data()
 	}
 }
 
+float3 Solver::calc_velocity(Curve *curve, Point *point, float time, Point::State &state) const
+{
+	return state.vel;
+}
+
+float3 Solver::calc_acceleration(Curve *curve, Point *point, float time, Point::State &state) const
+{
+	return float3(0.0f, 0.0f, -1.0f);
+}
+
+void Solver::step(float timestep)
+{
+	Curve *curve;
+	Point *point;
+	int totcurve = m_data->totcurves;
+	/*int totpoint = m_data->totpoints;*/
+	int i, k;
+	
+	for (i = 0, curve = m_data->curves; i < totcurve; ++i, ++curve) {
+		int numpoints = curve->totpoints;
+		for (k = 0, point = curve->points; k < numpoints; ++k, ++point) {
+			float3 acc = calc_acceleration(curve, point, 0.0f, point->cur);
+			point->next.vel = point->cur.vel + acc * timestep;
+			
+			float3 vel = calc_velocity(curve, point, 0.0f, point->next);
+			point->next.co = point->cur.co + vel * timestep;
+		}
+	}
+	
+	/* advance state */
+	for (i = 0, curve = m_data->curves; i < totcurve; ++i, ++curve) {
+		int numpoints = curve->totpoints;
+		for (k = 0, point = curve->points; k < numpoints; ++k, ++point) {
+			point->cur = point->next;
+		}
+	}
+}
+
 HAIR_NAMESPACE_END
diff --git a/source/blender/hair/intern/HAIR_solver.h b/source/blender/hair/intern/HAIR_solver.h
index 387570a..fb222ad 100644
--- a/source/blender/hair/intern/HAIR_solver.h
+++ b/source/blender/hair/intern/HAIR_solver.h
@@ -58,6 +58,10 @@ public:
 	
 	void step(float timestep);
 	
+protected:
+	float3 calc_velocity(Curve *curve, Point *point, float time, Point::State &state) const;
+	float3 calc_acceleration(Curve *curve, Point *point, float time, Point::State &state) const;
+	
 private:
 	SolverData *m_data;
 
diff --git a/source/blender/hair/intern/HAIR_types.h b/source/blender/hair/intern/HAIR_types.h
index 5af8e33..26e8355 100644
--- a/source/blender/hair/intern/HAIR_types.h
+++ b/source/blender/hair/intern/HAIR_types.h
@@ -58,10 +58,14 @@ struct float3 {
 
 	__forceinline float3() {}
 	__forceinline float3(float x, float y, float z) : x(x), y(y), z(z) {}
+	__forceinline float3(float *data) : x(data[0]), y(data[1]), z(data[2]) {}
 #endif
 
 	__forceinline float operator[](int i) const { return *(&x + i); }
 	__forceinline float& operator[](int i) { return *(&x + i); }
+
+	__forceinline float *data() { return &x; }
+	__forceinline const float *data() const { return &x; }
 };
 
 struct float4 {
diff --git a/source/blender/makesdna/DNA_hair_types.h b/source/blender/makesdna/DNA_hair_types.h
index 7312eda..1e83a75 100644
--- a/source/blender/makesdna/DNA_hair_types.h
+++ b/source/blender/makesdna/DNA_hair_types.h
@@ -36,6 +36,8 @@
 typedef struct HairPoint {
 	float co[3];                /* location in object space */
 	int pad;
+	float vel[3];               /* velocity */
+	int pad2;
 } HairPoint;
 
 typedef struct HairCurve {




More information about the Bf-blender-cvs mailing list