[Bf-blender-cvs] [5ea31fa] hair_system: Implemented bending forces for the new hair system.

Lukas Tönne noreply at git.blender.org
Sun Oct 5 14:57:12 CEST 2014


Commit: 5ea31fad73a19fd2a838f12fb6a7b45a746a88ff
Author: Lukas Tönne
Date:   Sun Oct 5 14:55:14 2014 +0200
Branches: hair_system
https://developer.blender.org/rB5ea31fad73a19fd2a838f12fb6a7b45a746a88ff

Implemented bending forces for the new hair system.

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

M	source/blender/blenkernel/BKE_effect.h
M	source/blender/blenkernel/BKE_hair.h
M	source/blender/blenkernel/intern/effect.c
M	source/blender/blenkernel/intern/hair.c
M	source/blender/blenkernel/intern/object.c
M	source/blender/editors/physics/hair_ops.c
M	source/blender/editors/space_view3d/drawobject.c
M	source/blender/makesdna/DNA_hair_types.h
M	source/blender/physics/intern/BPH_mass_spring.cpp

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

diff --git a/source/blender/blenkernel/BKE_effect.h b/source/blender/blenkernel/BKE_effect.h
index 04853bb..c57250a 100644
--- a/source/blender/blenkernel/BKE_effect.h
+++ b/source/blender/blenkernel/BKE_effect.h
@@ -162,6 +162,7 @@ struct SimDebugData *BKE_sim_debug_data_new(void);
 void BKE_sim_debug_data_add_dot(struct SimDebugData *debug_data, const float p[3], float r, float g, float b, const char *category, int hash);
 void BKE_sim_debug_data_add_line(struct SimDebugData *debug_data, const float p1[3], const float p2[3], float r, float g, float b, const char *category, int hash);
 void BKE_sim_debug_data_add_vector(struct SimDebugData *debug_data, const float p[3], const float d[3], float r, float g, float b, const char *category, int hash);
+void BKE_sim_debug_data_add_m3(struct SimDebugData *debug_data, const float p[3], float m[3][3], float scale, float black, float white, const char *category, int hash);
 void BKE_sim_debug_data_remove(struct SimDebugData *debug_data, int hash);
 void BKE_sim_debug_data_clear(struct SimDebugData *debug_data);
 void BKE_sim_debug_data_clear_category(struct SimDebugData *debug_data, const char *category);
diff --git a/source/blender/blenkernel/BKE_hair.h b/source/blender/blenkernel/BKE_hair.h
index 22a7f9d..f46d0ba 100644
--- a/source/blender/blenkernel/BKE_hair.h
+++ b/source/blender/blenkernel/BKE_hair.h
@@ -31,10 +31,13 @@
  *  \ingroup bke
  */
 
+struct DerivedMesh;
+
 struct HairSystem;
 struct HairCurve;
 struct HairPoint;
 struct HairParams;
+struct HairModifierData;
 
 struct HairSystem *BKE_hair_system_new(void);
 void BKE_hair_system_free(struct HairSystem *hsys);
@@ -57,7 +60,23 @@ struct HairPoint *BKE_hair_point_insert_multi(struct HairSystem *hsys, struct Ha
 void BKE_hair_point_remove(struct HairSystem *hsys, struct HairCurve *hair, struct HairPoint *point);
 void BKE_hair_point_remove_position(struct HairSystem *hsys, struct HairCurve *hair, int pos);
 
-void BKE_hair_calculate_rest(struct HairSystem *hsys);
+void BKE_hair_get_mesh_frame(struct DerivedMesh *dm, struct HairCurve *curve, float frame[3][3]);
+void BKE_hair_calculate_rest(struct DerivedMesh *dm, struct HairCurve *curve);
+
+/* ==== Hair Framing ==== */
+
+/* Smoothed parallel transport of coordinate frames */
+typedef struct HairFrameIterator {
+	float dir[3], prev_dir[3];
+} HairFrameIterator;
+
+void BKE_hair_frame_init(struct HairFrameIterator *iter, const float dir0[3]);
+void BKE_hair_frame_next(struct HairFrameIterator *iter, const float dir[3], float rot[3][3]);
+
+void BKE_hair_frame_init_from_points(struct HairFrameIterator *iter, const float x0[3], const float x1[3]);
+void BKE_hair_frame_next_from_points(struct HairFrameIterator *iter, const float x0[3], const float x1[3], float rot[3][3]);
+
+/* ==== Render Hair Iterator ==== */
 
 /* cached per-hair data */
 typedef struct HairPointRenderCache {
@@ -108,4 +127,8 @@ void BKE_hair_render_iter_get(struct HairRenderIterator *iter, float co[3], floa
 void BKE_hair_render_iter_get_frame(struct HairRenderIterator *iter, float nor[3], float tan[3], float cotan[3]);
 float BKE_hair_render_iter_param(struct HairRenderIterator *iter);
 
+/* ==== Hair Modifier ==== */
+
+void BKE_hair_mod_verify_debug_data(struct HairModifierData *hmd);
+
 #endif
diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c
index 82c3ed8..087227f 100644
--- a/source/blender/blenkernel/intern/effect.c
+++ b/source/blender/blenkernel/intern/effect.c
@@ -1028,13 +1028,36 @@ void pdDoEffectors(ListBase *effectors, ListBase *colliders, EffectorWeights *we
 
 /* ======== Simulation Debugging ======== */
 
+BLI_INLINE unsigned int hash_int_2d(unsigned int kx, unsigned int ky)
+{
+#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k))))
+
+	unsigned int a, b, c;
+
+	a = b = c = 0xdeadbeef + (2 << 2) + 13;
+	a += kx;
+	b += ky;
+
+	c ^= b; c -= rot(b,14);
+	a ^= c; a -= rot(c,11);
+	b ^= a; b -= rot(a,25);
+	c ^= b; c -= rot(b,16);
+	a ^= c; a -= rot(c,4);
+	b ^= a; b -= rot(a,14);
+	c ^= b; c -= rot(b,24);
+
+	return c;
+
+#undef rot
+}
+
 static unsigned int debug_element_hash(const void *key)
 {
 	const SimDebugElement *elem = key;
 	return elem->hash;
 }
 
-static int debug_element_compare(const void *a, const void *b)
+static bool debug_element_compare(const void *a, const void *b)
 {
 	const SimDebugElement *elem1 = a;
 	const SimDebugElement *elem2 = b;
@@ -1056,7 +1079,6 @@ SimDebugData *BKE_sim_debug_data_new(void)
 	SimDebugData *debug_data = MEM_callocN(sizeof(SimDebugData), "sim debug data");
 	debug_data->gh = BLI_ghash_new(debug_element_hash, debug_element_compare, "sim debug element hash");
 	return debug_data;
-	
 }
 
 static void debug_data_insert(SimDebugData *debug_data, SimDebugElement *elem)
@@ -1129,6 +1151,20 @@ void BKE_sim_debug_data_add_vector(struct SimDebugData *debug_data, const float
 	debug_data_insert(debug_data, elem);
 }
 
+void BKE_sim_debug_data_add_m3(struct SimDebugData *debug_data, const float p[3], float m[3][3], float scale, float black, float white, const char *category, int hash)
+{
+	float v[3];
+	
+	mul_v3_v3fl(v, m[0], scale);
+	BKE_sim_debug_data_add_vector(debug_data, p, v, white, black, black, category, hash_int_2d(hash, 1));
+	
+	mul_v3_v3fl(v, m[1], scale);
+	BKE_sim_debug_data_add_vector(debug_data, p, v, black, white, black, category, hash_int_2d(hash, 2));
+	
+	mul_v3_v3fl(v, m[2], scale);
+	BKE_sim_debug_data_add_vector(debug_data, p, v, black, black, white, category, hash_int_2d(hash, 3));
+}
+
 void BKE_sim_debug_data_remove(SimDebugData *debug_data, int hash)
 {
 	SimDebugElement dummy;
diff --git a/source/blender/blenkernel/intern/hair.c b/source/blender/blenkernel/intern/hair.c
index 67c1bee..e44b0c5 100644
--- a/source/blender/blenkernel/intern/hair.c
+++ b/source/blender/blenkernel/intern/hair.c
@@ -247,27 +247,132 @@ void BKE_hair_point_remove_position(HairSystem *UNUSED(hsys), HairCurve *hair, i
 	hair->totpoints = ntotpoints;
 }
 
-void BKE_hair_calculate_rest(HairSystem *hsys)
+static void get_hair_frame(float frame[3][3], const float normal[3], const float tangent[3])
 {
-	HairCurve *hair;
-	int i;
+	copy_v3_v3(frame[2], normal);
 	
-	for (i = 0, hair = hsys->curves; i < hsys->totcurves; ++i, ++hair) {
-		HairPoint *point;
-		int k;
-		float tot_rest_length;
+	if (tangent) {
+		copy_v3_v3(frame[0], tangent);
+	}
+	else {
+		const float up[3] = {0.0f, 0.0f, 1.0f};
 		
-		tot_rest_length = 0.0f;
-		for (k = 1, point = hair->points + 1; k < hair->totpoints; ++k, ++point) {
-			tot_rest_length += len_v3v3((point-1)->rest_co, point->rest_co);
+		madd_v3_v3v3fl(frame[0], up, normal, -dot_v3v3(up, normal));
+		normalize_v3(frame[0]);
+	}
+	
+	cross_v3_v3v3(frame[1], frame[2], frame[0]);
+}
+
+void BKE_hair_get_mesh_frame(struct DerivedMesh *dm, HairCurve *curve, float frame[3][3])
+{
+	float vloc[3], vnor[3];
+	
+	bool ok = BKE_mesh_sample_eval(dm, &curve->root, vloc, vnor);
+	if (ok)
+		get_hair_frame(frame, vnor, NULL);
+	else
+		unit_m3(frame);
+}
+
+void BKE_hair_calculate_rest(struct DerivedMesh *dm, HairCurve *curve)
+{
+	HairPoint *point;
+	int k;
+	float tot_rest_length;
+	HairFrameIterator iter;
+	float frame[3][3], rot[3][3];
+	
+	if (curve->totpoints < 2) {
+		point = curve->points;
+		for (k = 0; k < curve->totpoints; ++k, ++point) {
+			point->rest_length = 0.0f;
+			zero_v3(point->rest_target);
 		}
-		if (hair->totpoints > 1)
-			hair->avg_rest_length = tot_rest_length / (float)(hair->totpoints-1);
+		
+		curve->avg_rest_length = 0.0f;
+		zero_m3(curve->root_rest_frame);
+		
+		return;
+	}
+	
+	tot_rest_length = 0.0f;
+	point = curve->points;
+	for (k = 0; k < curve->totpoints - 1; ++k, ++point) {
+		point->rest_length = len_v3v3(point->rest_co, (point+1)->rest_co);
+		tot_rest_length += point->rest_length;
 	}
+	curve->avg_rest_length = tot_rest_length / (float)(curve->totpoints-1);
+	
+	/* frame starts in root rest position
+	 * note: not using obmat here, doesn't matter for rest calculation
+	 */
+	BKE_hair_get_mesh_frame(dm, curve, curve->root_rest_frame);
+	copy_m3_m3(frame, curve->root_rest_frame);
+	
+	/* initialize frame iterator */
+	BKE_hair_frame_init(&iter, frame[2]);
+	
+	point = curve->points;
+	/* target is the edge vector in frame space */
+	sub_v3_v3v3(point->rest_target, (point+1)->rest_co, point->rest_co);
+	mul_transposed_m3_v3(frame, point->rest_target);
+	
+	++point;
+	for (k = 1; k < curve->totpoints - 1; ++k, ++point) {
+		/* transport the frame to the next segment */
+		BKE_hair_frame_next_from_points(&iter, (point-1)->rest_co, point->rest_co, rot);
+		mul_m3_m3m3(frame, rot, frame);
+		
+		/* target is the edge vector in frame space */
+		sub_v3_v3v3(point->rest_target, (point+1)->rest_co, point->rest_co);
+		mul_transposed_m3_v3(frame, point->rest_target);
+	}
+	
+	/* last point */
+	point->rest_length = 0.0f;
+	zero_v3(point->rest_target);
+}
+
+/* ==== Hair Framing ==== */
+
+void BKE_hair_frame_init(HairFrameIterator *iter, const float dir0[3])
+{
+	copy_v3_v3(iter->prev_dir, dir0);
+	copy_v3_v3(iter->dir, dir0);
 }
 
+void BKE_hair_frame_init_from_points(HairFrameIterator *iter, const float x0[3], const float x1[3])
+{
+	float dir0[3];
+	sub_v3_v3v3(dir0, x1, x0);
+	normalize_v3(dir0);
+	
+	BKE_hair_frame_init(iter, dir0);
+}
+
+void BKE_hair_frame_next(HairFrameIterator *iter, const float dir[3], float rot[3][3])
+{
+	/* TODO implement optional smoothing function here, as described in "Artistic Simulation of Curly Hair" */
+	
+	/* rotation between segments */
+	rotation_between_vecs_to_mat3(rot, iter->dir, dir);
+	
+	/* advance iterator state */
+	copy_v3_v3(iter->prev_dir, iter->dir);
+	copy_v3_v3(iter->dir, dir);
+}
 
-/* ================ Render ================ */
+void BKE_hair_frame_next_from_points(HairFrameIterator *iter, const float x0[3], const float x1[3], float rot[3][3])
+{
+	float dir[3];
+	sub_v3_v3v3(dir, x1, x0);
+	normalize_v3(dir);
+	
+	BKE_hair_frame_next(iter, dir, rot);
+}
+
+/* ================ Render Hair Iterator ================ */
 
 static int hair_maxpoints(HairSystem *hsys)
 {
@@ -300,25 +405,6 @@ static HairRenderChildData *hair_gen_child_data(HairParams *params, unsigned int
 	return data;
 }
 
-static void get_hair_root_frame(HairCurv

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list