diff options
author | Lukas Tönne <lukas.toenne@gmail.com> | 2014-09-25 17:42:08 +0400 |
---|---|---|
committer | Lukas Tönne <lukas.toenne@gmail.com> | 2015-01-20 11:30:03 +0300 |
commit | 520922876a1f7618319038728ca14a18276287d3 (patch) | |
tree | 7bf578e7008568a0912784506b1d32deb95f30d4 /source/blender/blenkernel/intern/particle_system.c | |
parent | 7d4799b41d554e2a2b56928e88a9a4afb4a3ff13 (diff) |
Target calculation for local non-straight rest shapes.
This is more involved than using simple straight bending targets
constructed from the neighboring segments, but necessary for restoring
groomed rest shapes.
The targets are defined by parallel-transporting a coordinate frame
along the hair, which smoothly rotates to avoid sudden twisting (Frenet
frame problem). The rest positions of hair vertices defines the target
vectors relative to the frame. In the deformed motion state the frame
is then recalculated and the targets constructed in world/root space.
Diffstat (limited to 'source/blender/blenkernel/intern/particle_system.c')
-rw-r--r-- | source/blender/blenkernel/intern/particle_system.c | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 8215c808c42..661e0c5c1be 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -4083,7 +4083,7 @@ static void do_hair_dynamics(ParticleSimulationData *sim) /* make vgroup for pin roots etc.. */ psys->particles->hair_index = 1; LOOP_PARTICLES { - float root_mat[4][4]; + float root_mat[4][4], hair_frame[3][3], dir[3]; bool use_hair = psys_hair_use_simulation(pa, max_length); if (p) @@ -4091,6 +4091,14 @@ static void do_hair_dynamics(ParticleSimulationData *sim) psys_mat_hair_to_object(sim->ob, sim->psmd->dm, psys->part->from, pa, hairmat); mul_m4_m4m4(root_mat, sim->ob->obmat, hairmat); + normalize_m4(root_mat); + + /* initial hair frame from root orientation */ + copy_m3_m4(hair_frame, root_mat); + /* surface normal is the initial direction, + * parallel transport then keeps it aligned to the hair direction + */ + copy_v3_v3(dir, hair_frame[2]); for (k=0, key=pa->hair; k<pa->totkey; k++,key++) { ClothHairRoot *root; @@ -4103,6 +4111,10 @@ static void do_hair_dynamics(ParticleSimulationData *sim) copy_v3_v3(root->loc, root_mat[3]); copy_m3_m4(root->rot, root_mat); + /* dir expressed in the hair frame defines the rest target direction */ + copy_v3_v3(root->rest_target, dir); + mul_transposed_m3_v3(hair_frame, root->rest_target); + sub_v3_v3v3(temp, key->co, (key+1)->co); copy_v3_v3(mvert->co, key->co); add_v3_v3v3(mvert->co, mvert->co, temp); @@ -4121,6 +4133,14 @@ static void do_hair_dynamics(ParticleSimulationData *sim) copy_v3_v3(root->loc, root_mat[3]); copy_m3_m4(root->rot, root_mat); + if (k < pa->totkey-1) + /* move frame to next hair segment */ + cloth_parallel_transport_hair_frame(hair_frame, dir, key->co, (key+1)->co); + + /* dir expressed in the hair frame defines the rest target direction */ + copy_v3_v3(root->rest_target, dir); + mul_transposed_m3_v3(hair_frame, root->rest_target); + copy_v3_v3(mvert->co, key->co); mul_m4_v3(hairmat, mvert->co); mvert++; |