[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