[Bf-blender-cvs] [d051465] hair_system: Implemented stretch springs for hairs based on rest length of segments.

Lukas Tönne noreply at git.blender.org
Mon Jul 28 14:25:00 CEST 2014


Commit: d051465fb40373ee51b1bc2a609b54ecd80c72a9
Author: Lukas Tönne
Date:   Mon Jul 28 13:19:24 2014 +0200
Branches: hair_system
https://developer.blender.org/rBd051465fb40373ee51b1bc2a609b54ecd80c72a9

Implemented stretch springs for hairs based on rest length of segments.

This is still totally undamped and so will start to accumulate energy
quite quickly!

The default parameters (taken from the original paper) probably require
some tweaking, but the overall result can only be judged once the other
main forces are implemented (in particular damping).

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

M	source/blender/blenkernel/intern/hair.c
M	source/blender/hair/CMakeLists.txt
M	source/blender/hair/HAIR_capi.cpp
M	source/blender/hair/intern/HAIR_curve.cpp
M	source/blender/hair/intern/HAIR_curve.h
A	source/blender/hair/intern/HAIR_math.h
M	source/blender/hair/intern/HAIR_smoothing.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/makesrna/intern/rna_hair.c

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

diff --git a/source/blender/blenkernel/intern/hair.c b/source/blender/blenkernel/intern/hair.c
index 99c764a..ad9d9cc 100644
--- a/source/blender/blenkernel/intern/hair.c
+++ b/source/blender/blenkernel/intern/hair.c
@@ -43,8 +43,8 @@ HairSystem *BKE_hairsys_new(void)
 {
 	HairSystem *hsys = MEM_callocN(sizeof(HairSystem), "hair system");
 	
-	hsys->params.stretch_stiffness = 7e6;
-	hsys->params.stretch_damping = 4500;
+	hsys->params.stretch_stiffness = 7.0e6f;
+	hsys->params.stretch_damping = 4500.0f;
 	
 	return hsys;
 }
diff --git a/source/blender/hair/CMakeLists.txt b/source/blender/hair/CMakeLists.txt
index 7529cad..5b76bad 100644
--- a/source/blender/hair/CMakeLists.txt
+++ b/source/blender/hair/CMakeLists.txt
@@ -42,6 +42,7 @@ set(SRC
 
 	intern/HAIR_curve.h
 	intern/HAIR_curve.cpp
+	intern/HAIR_math.h
 	intern/HAIR_memalloc.h
 	intern/HAIR_smoothing.h
 	intern/HAIR_smoothing.cpp
diff --git a/source/blender/hair/HAIR_capi.cpp b/source/blender/hair/HAIR_capi.cpp
index 8031f42..7fb0091 100644
--- a/source/blender/hair/HAIR_capi.cpp
+++ b/source/blender/hair/HAIR_capi.cpp
@@ -25,6 +25,8 @@
  */
 
 extern "C" {
+#include "BLI_math.h"
+
 #include "DNA_hair_types.h"
 
 #include "BKE_hair.h"
@@ -76,7 +78,9 @@ 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(hair_pt->rest_co);
+			bool is_root = (k == 0);
+			
+			*point = Point(hair_pt->rest_co, !is_root);
 			point->cur.co = float3(hair_pt->co);
 			point->cur.vel = float3(hair_pt->vel);
 		}
diff --git a/source/blender/hair/intern/HAIR_curve.cpp b/source/blender/hair/intern/HAIR_curve.cpp
index 3be4db3..3d26ee5 100644
--- a/source/blender/hair/intern/HAIR_curve.cpp
+++ b/source/blender/hair/intern/HAIR_curve.cpp
@@ -32,8 +32,9 @@ Point::Point()
 {
 }
 
-Point::Point(const float3 &rest_co) :
-    rest_co(rest_co)
+Point::Point(const float3 &rest_co, bool is_dynamic) :
+    rest_co(rest_co),
+    is_dynamic(is_dynamic)
 {
 	cur.co = rest_co;
 	cur.vel = float3(0.0f, 0.0f, 0.0f);
diff --git a/source/blender/hair/intern/HAIR_curve.h b/source/blender/hair/intern/HAIR_curve.h
index bef25f5..93f402a 100644
--- a/source/blender/hair/intern/HAIR_curve.h
+++ b/source/blender/hair/intern/HAIR_curve.h
@@ -40,12 +40,13 @@ struct Point {
 	};
 	
 	Point();
-	Point(const float3 &rest_co);
+	Point(const float3 &rest_co, bool is_dynamic=true);
 	
 	State cur;
 	State next;
 	
 	float3 rest_co;
+	bool is_dynamic;
 	
 	HAIR_CXX_CLASS_ALLOC(Point)
 };
diff --git a/source/blender/hair/intern/HAIR_math.h b/source/blender/hair/intern/HAIR_math.h
new file mode 100644
index 0000000..6ff4d94
--- /dev/null
+++ b/source/blender/hair/intern/HAIR_math.h
@@ -0,0 +1,100 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2014 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation,
+ *                 Lukas Toenne
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __HAIR_MATH_H__
+#define __HAIR_MATH_H__
+
+#ifndef FREE_WINDOWS64
+#define __forceinline inline __attribute__((always_inline))
+#endif
+
+#include <math.h>
+
+#include "HAIR_types.h"
+
+HAIR_NAMESPACE_BEGIN
+
+/* utility functions */
+
+__forceinline float min_ff(float a, float b)
+{
+	return a < b ? a : b;
+}
+
+__forceinline float max_ff(float a, float b)
+{
+	return a > b ? a : b;
+}
+
+/* standard arithmetic */
+
+__forceinline float3 operator + (const float3 &a, const float3 &b)
+{
+	return float3(a.x + b.x, a.y + b.y, a.z + b.z);
+}
+
+__forceinline float3 operator - (const float3 &a, const float3 &b)
+{
+	return float3(a.x - b.x, a.y - b.y, a.z - b.z);
+}
+
+__forceinline float3 operator * (float fac, const float3 &a)
+{
+	return float3(fac * a.x, fac * a.y, fac * a.z);
+}
+
+__forceinline float3 operator * (const float3 &a, float fac)
+{
+	return float3(a.x * fac, a.y * fac, a.z * fac);
+}
+
+__forceinline float3 operator / (const float3 &a, float d)
+{
+	return float3(a.x / d, a.y / d, a.z / d);
+}
+
+/* vector functions */
+
+__forceinline float dot_v3_v3(const float3 &a, const float3 &b)
+{
+	return a.x * b.x + a.y * b.y + a.z * b.z;
+}
+
+__forceinline float len_v3(const float3 &v)
+{
+	return sqrtf(dot_v3_v3(v, v));
+}
+
+__forceinline float normalize_v3_v3(float3 &r, const float3 &v)
+{
+	float len = len_v3(v);
+	r = len > 0.0f ? v / len : float3(0.0f, 0.0f, 0.0f);
+	return len;
+}
+
+HAIR_NAMESPACE_END
+
+#endif
diff --git a/source/blender/hair/intern/HAIR_smoothing.h b/source/blender/hair/intern/HAIR_smoothing.h
index 66be0d8..119ff0a 100644
--- a/source/blender/hair/intern/HAIR_smoothing.h
+++ b/source/blender/hair/intern/HAIR_smoothing.h
@@ -27,10 +27,7 @@
 #ifndef __HAIR_SMOOTHING_H__
 #define __HAIR_SMOOTHING_H__
 
-extern "C" {
-#include "BLI_math.h"
-}
-
+#include "HAIR_math.h"
 #include "HAIR_memalloc.h"
 
 HAIR_NAMESPACE_BEGIN
diff --git a/source/blender/hair/intern/HAIR_solver.cpp b/source/blender/hair/intern/HAIR_solver.cpp
index 9d97cca..111b2d3 100644
--- a/source/blender/hair/intern/HAIR_solver.cpp
+++ b/source/blender/hair/intern/HAIR_solver.cpp
@@ -24,6 +24,7 @@
  * ***** END GPL LICENSE BLOCK *****
  */
 
+#include "HAIR_math.h"
 #include "HAIR_solver.h"
 
 HAIR_NAMESPACE_BEGIN
@@ -92,9 +93,25 @@ float3 Solver::calc_velocity(Curve *curve, Point *point, float time, Point::Stat
 	return state.vel;
 }
 
-float3 Solver::calc_acceleration(Curve *curve, Point *point, float time, Point::State &state) const
+float3 Solver::calc_stretch(Curve *curve, Point *point0, Point *point1, float time) const
 {
-	return float3(0.0f, 0.0f, -0.01f);
+	/* XXX this could be cached in SolverData */
+	float3 dir;
+	float rest_length = len_v3(point1->rest_co - point0->rest_co);
+	float length = normalize_v3_v3(dir, point1->cur.co - point0->cur.co);
+	
+	float3 stretch_acc = m_params.stretch_stiffness * (length - rest_length) * dir;
+	
+	return stretch_acc;
+}
+
+float3 Solver::calc_acceleration(Curve *curve, Point *point, float time, float3 prev_stretch, float3 stretch, Point::State &state) const
+{
+	float3 acc = float3(0.0f, 0.0f, -0.01f);
+	
+	acc = acc - prev_stretch + stretch;
+	
+	return acc;
 }
 
 void Solver::step(float timestep)
@@ -105,8 +122,11 @@ void Solver::step(float timestep)
 	/*int totpoint = m_data->totpoints;*/
 	int i, k;
 	
+	float time = 0.0f;
+	
 	for (i = 0, curve = m_data->curves; i < totcurve; ++i, ++curve) {
 		int numpoints = curve->totpoints;
+		float3 prev_stretch;
 		
 		/* Root point animation */
 		k = 0;
@@ -116,13 +136,20 @@ void Solver::step(float timestep)
 		point->next.co = point->cur.co;
 		point->next.vel = float3(0.0f, 0.0f, 0.0f);
 		
+		float3 stretch = k < numpoints-1 ? calc_stretch(curve, point, point+1, time) : float3(0.0f, 0.0f, 0.0f);
+		prev_stretch = stretch;
+		
 		/* Integrate the remaining free points */
 		for (++k, ++point; k < numpoints; ++k, ++point) {
-			float3 acc = calc_acceleration(curve, point, 0.0f, point->cur);
+			float3 stretch = k < numpoints-1 ? calc_stretch(curve, point, point+1, time) : float3(0.0f, 0.0f, 0.0f);
+			
+			float3 acc = calc_acceleration(curve, point, time, prev_stretch, stretch, point->cur);
 			point->next.vel = point->cur.vel + acc * timestep;
 			
-			float3 vel = calc_velocity(curve, point, 0.0f, point->next);
+			float3 vel = calc_velocity(curve, point, time, point->next);
 			point->next.co = point->cur.co + vel * timestep;
+			
+			prev_stretch = stretch;
 		}
 	}
 	
diff --git a/source/blender/hair/intern/HAIR_solver.h b/source/blender/hair/intern/HAIR_solver.h
index 219d6a1..3cd0e45 100644
--- a/source/blender/hair/intern/HAIR_solver.h
+++ b/source/blender/hair/intern/HAIR_solver.h
@@ -66,7 +66,8 @@ public:
 	
 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;
+	float3 calc_acceleration(Curve *curve, Point *point, float time, float3 prev_stretch, float3 stretch, Point::State &state) const;
+	float3 calc_stretch(Curve *curve, Point *point0, Point *point1, float time) const;
 	
 private:
 	HairParams m_params;
diff --git a/source/blender/hair/intern/HAIR_types.h b/source/blender/hair/intern/HAIR_types.h
index 26e8355..e711dfa 100644
--- a/source/blender/hair/intern/HAIR_types.h
+++ b/source/blender/hair/intern/HAIR_types.h
@@ -89,28 +89,6 @@ struct float4 {
 	__forceinline float& operator[](int i) { return *(&x + i); }
 };
 
-/* standard arithmetic */
-
-__forceinline float3 operator + (const float3 &a, const float3 &b)
-{
-	return float3(a.x + b.x, a.y + b.y, a.z + b.z);
-}
-
-__forceinline float3 operator - (const float3 &a, const float3 &b)
-{
-	return float3(a.x - b.x, a.y - b.y, a.z - b.z);
-}
-
-__forceinline float3 operator * (float fac, const float3 &a)
-{
-	return float3(fac * a.x, fac * a.y, fac * a.z);
-}
-
-__forceinline float3 operator * (const float3 &a, float fac)
-{
-	return float3(fac * a.x, fac * a.y, fac * a.z);
-}
-
 HAIR_NAMESPACE_END
 
 #endif
diff --git a/source/blender/makesrna/intern/rna_hair.c b/source/blender/makesrna/intern/rna_hair.c
index 81a5eb3..b5a2d93 100644
--- a/source/blender/makesrna/intern/rna_hair.c
+++ b/source/blender/makesrna/intern/rna_hair.c
@@ -62,7 +62,8 @@ static void rna_def_hair_params(BlenderRNA *brna)
 
 	prop = RNA_def_property(srna, "stretch_stiffness", PROP_FLOAT, PROP_FACTOR);
 	RNA_def_property_float_sdna(prop, NULL, "stretch_sti

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list