[Bf-blender-cvs] [def2bb7] hair_immediate_fixes: Fix for particle instance modifier: use a stable parallel-transport framing method instead of the Frenet frame.

Lukas Tönne noreply at git.blender.org
Mon Nov 17 14:18:25 CET 2014


Commit: def2bb7644026365ef9d44f2ad5ba7970f1cdc5e
Author: Lukas Tönne
Date:   Mon Nov 17 14:16:35 2014 +0100
Branches: hair_immediate_fixes
https://developer.blender.org/rBdef2bb7644026365ef9d44f2ad5ba7970f1cdc5e

Fix for particle instance modifier: use a stable parallel-transport
framing method instead of the Frenet frame.

The Frenet frame is very succeptible to sudden twists along straight
sections of a curve where the second derivative (curvature) becomes 0.

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

M	source/blender/modifiers/intern/MOD_particleinstance.c

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

diff --git a/source/blender/modifiers/intern/MOD_particleinstance.c b/source/blender/modifiers/intern/MOD_particleinstance.c
index 7aa81d6..e6e2295 100644
--- a/source/blender/modifiers/intern/MOD_particleinstance.c
+++ b/source/blender/modifiers/intern/MOD_particleinstance.c
@@ -43,6 +43,7 @@
 #include "BLI_utildefines.h"
 
 #include "BKE_cdderivedmesh.h"
+#include "BKE_global.h"
 #include "BKE_lattice.h"
 #include "BKE_modifier.h"
 #include "BKE_particle.h"
@@ -278,6 +279,9 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
 	orig_mloop = dm->getLoopArray(dm);
 
 	for (p = 0, p_skip = 0; p < totpart; p++) {
+		float prev_dir[3];
+		float frame[4]; /* frame orientation quaternion */
+		
 		/* skip particle? */
 		if (particle_skip(pimd, psys, p))
 			continue;
@@ -323,19 +327,54 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
 
 				normalize_v3(state.vel);
 
-				/* TODO: incremental rotations somehow */
+				/* Incrementally Rotating Frame (Bishop Frame) */
+				if (k == 0) {
+					float mat[3][3];
+					float temp[3] = {0.0f, 0.0f, 0.0f};
+					temp[axis] = 1.0f;
+					
+					/* normal direction */
+					copy_v3_v3(mat[0], state.vel);
+					/* tangent from projecting axis onto the surface plane */
+					project_v3_plane(mat[1], state.vel, temp);
+					normalize_v3(mat[1]);
+					/* cotangent */
+					cross_v3_v3v3(mat[2], mat[0], mat[1]);
+					/* to quaternion */
+					mat3_to_quat(frame, mat);
+					
+					/* note: direction is same as normal vector currently,
+					 * but best to keep this separate so the frame can be
+					 * rotated later if necessary
+					 */
+					copy_v3_v3(prev_dir, state.vel);
+				}
+				else {
+					float rot[4];
+					
+					/* incrementally rotate along bend direction */
+					rotation_between_vecs_to_quat(rot, prev_dir, state.vel);
+					mul_qt_qtqt(frame, rot, frame);
+					
+					copy_v3_v3(prev_dir, state.vel);
+					}
+				
+				copy_qt_qt(state.rot, frame);
+#if 0
+				/* Absolute Frame (Frenet Frame) */
 				if (state.vel[axis] < -0.9999f || state.vel[axis] > 0.9999f) {
 					unit_qt(state.rot);
 				}
 				else {
 					float temp[3] = {0.0f, 0.0f, 0.0f};
 					temp[axis] = 1.0f;
-
+					
 					cross_v3_v3v3(cross, temp, state.vel);
-
+					
 					/* state.vel[axis] is the only component surviving from a dot product with the axis */
 					axis_angle_to_quat(state.rot, cross, saacos(state.vel[axis]));
 				}
+#endif
 			}
 			else {
 				state.time = -1.0;




More information about the Bf-blender-cvs mailing list