[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [56062] trunk/blender/source/blender: New implementation for twist brushes.

Antony Riakiotakis kalast at gmail.com
Mon Apr 15 16:55:42 CEST 2013


Revision: 56062
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=56062
Author:   psy-fi
Date:     2013-04-15 14:55:42 +0000 (Mon, 15 Apr 2013)
Log Message:
-----------
New implementation for twist brushes.

It has much better rotation and avoids the compression effect that old
twist brushes have. Also twisting is now non periodic, meaning you can
twist beyond 180 degrees. The amount of twist is also calculated
relative to the angle formed after first translating the mouse away from
the brush center.

Modified Paths:
--------------
    trunk/blender/source/blender/blenlib/BLI_math_rotation.h
    trunk/blender/source/blender/blenlib/intern/math_rotation.c
    trunk/blender/source/blender/editors/sculpt_paint/sculpt.c

Modified: trunk/blender/source/blender/blenlib/BLI_math_rotation.h
===================================================================
--- trunk/blender/source/blender/blenlib/BLI_math_rotation.h	2013-04-15 14:55:36 UTC (rev 56061)
+++ trunk/blender/source/blender/blenlib/BLI_math_rotation.h	2013-04-15 14:55:42 UTC (rev 56062)
@@ -97,6 +97,7 @@
 /* conversion */
 void axis_angle_to_quat(float r[4], const float axis[3], const float angle);
 void axis_angle_to_mat3(float R[3][3], const float axis[3], const float angle);
+void axis_angle_to_mat3_no_norm(float R[3][3], const float axis[3], const float angle);
 void axis_angle_to_mat4(float R[4][4], const float axis[3], const float angle);
 
 void quat_to_axis_angle(float axis[3], float *angle, const float q[4]);

Modified: trunk/blender/source/blender/blenlib/intern/math_rotation.c
===================================================================
--- trunk/blender/source/blender/blenlib/intern/math_rotation.c	2013-04-15 14:55:36 UTC (rev 56061)
+++ trunk/blender/source/blender/blenlib/intern/math_rotation.c	2013-04-15 14:55:42 UTC (rev 56062)
@@ -749,10 +749,33 @@
 	quat_to_axis_angle(axis, angle, q);
 }
 
-/* axis angle to 3x3 matrix - safer version (normalization of axis performed)
- *
- * note: we may want a normalized and non normalized version of this function.
- */
+/* axis angle to 3x3 matrix - note: requires that axis is normalized */
+void axis_angle_to_mat3_no_norm(float mat[3][3], const float nor[3], const float angle)
+{
+	float nsi[3], co, si, ico;
+
+	/* now convert this to a 3x3 matrix */
+	co = cosf(angle);
+	si = sinf(angle);
+
+	ico = (1.0f - co);
+	nsi[0] = nor[0] * si;
+	nsi[1] = nor[1] * si;
+	nsi[2] = nor[2] * si;
+
+	mat[0][0] = ((nor[0] * nor[0]) * ico) + co;
+	mat[0][1] = ((nor[0] * nor[1]) * ico) + nsi[2];
+	mat[0][2] = ((nor[0] * nor[2]) * ico) - nsi[1];
+	mat[1][0] = ((nor[0] * nor[1]) * ico) - nsi[2];
+	mat[1][1] = ((nor[1] * nor[1]) * ico) + co;
+	mat[1][2] = ((nor[1] * nor[2]) * ico) + nsi[0];
+	mat[2][0] = ((nor[0] * nor[2]) * ico) + nsi[1];
+	mat[2][1] = ((nor[1] * nor[2]) * ico) - nsi[0];
+	mat[2][2] = ((nor[2] * nor[2]) * ico) + co;
+}
+
+
+/* axis angle to 3x3 matrix - safer version (normalization of axis performed) */
 void axis_angle_to_mat3(float mat[3][3], const float axis[3], const float angle)
 {
 	float nor[3], nsi[3], co, si, ico;

Modified: trunk/blender/source/blender/editors/sculpt_paint/sculpt.c
===================================================================
--- trunk/blender/source/blender/editors/sculpt_paint/sculpt.c	2013-04-15 14:55:36 UTC (rev 56061)
+++ trunk/blender/source/blender/editors/sculpt_paint/sculpt.c	2013-04-15 14:55:42 UTC (rev 56062)
@@ -286,7 +286,12 @@
 	int original;
 	float anchored_location[3];
 
-	float vertex_rotation;
+	float vertex_rotation; /* amount to rotate the vertices when using rotate brush */
+	float previous_vertex_rotation; /* previous rotation, used to detect if we rotate more than
+	                                 * PI radians */
+	short num_vertex_turns; /* records number of full 2*PI turns */
+	float initial_mouse_dir[2]; /* used to calculate initial angle */
+	bool init_dir_set; /* detect if we have initialized the initial mouse direction */
 
 	char saved_active_brush_name[MAX_ID_NAME];
 	char saved_mask_brush_tool;
@@ -2085,19 +2090,9 @@
 	Brush *brush = BKE_paint_brush(&sd->paint);
 	float bstrength = ss->cache->bstrength;
 	int n;
-	float m[4][4], rot[4][4], lmat[4][4], ilmat[4][4];
 	static const int flip[8] = { 1, -1, -1, 1, -1, 1, 1, -1 };
 	float angle = ss->cache->vertex_rotation * flip[ss->cache->mirror_symmetry_pass];
 
-	unit_m4(m);
-	unit_m4(lmat);
-
-	copy_v3_v3(lmat[3], ss->cache->location);
-	invert_m4_m4(ilmat, lmat);
-	axis_angle_to_mat4(rot, ss->cache->sculpt_normal_symm, angle);
-
-	mul_serie_m4(m, lmat, rot, ilmat, NULL, NULL, NULL, NULL, NULL);
-
 	#pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
 	for (n = 0; n < totnode; n++) {
 		PBVHVertexIter vd;
@@ -2116,6 +2111,7 @@
 			sculpt_orig_vert_data_update(&orig_data, &vd);
 
 			if (sculpt_brush_test(&test, orig_data.co)) {
+				float vec[3], rot[3][3];
 				const float fade = bstrength * tex_strength(ss, brush,
 				                                            orig_data.co,
 				                                            test.dist,
@@ -2123,9 +2119,11 @@
 				                                            orig_data.no,
 				                                            NULL, vd.mask ? *vd.mask : 0.0f);
 
-				mul_v3_m4v3(proxy[vd.i], m, orig_data.co);
+				sub_v3_v3v3(vec, orig_data.co, ss->cache->location);
+				axis_angle_to_mat3_no_norm(rot, ss->cache->sculpt_normal_symm, angle*fade);
+				mul_v3_m3v3(proxy[vd.i], rot, vec);
+				add_v3_v3(proxy[vd.i], ss->cache->location);
 				sub_v3_v3(proxy[vd.i], orig_data.co);
-				mul_v3_fl(proxy[vd.i], fade);
 
 				if (vd.mvert)
 					vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
@@ -3785,6 +3783,9 @@
 	cache->first_time = 1;
 
 	cache->vertex_rotation = 0;
+	cache->num_vertex_turns = 0;
+	cache->previous_vertex_rotation = 0;
+	cache->init_dir_set = false;
 
 	sculpt_omp_start(sd, ss);
 }
@@ -3947,11 +3948,47 @@
 	sculpt_update_brush_delta(ups, ob, brush);
 
 	if (brush->sculpt_tool == SCULPT_TOOL_ROTATE) {
+		#define PIXEL_INPUT_THRESHHOLD 5
+
 		const float dx = cache->mouse[0] - cache->initial_mouse[0];
 		const float dy = cache->mouse[1] - cache->initial_mouse[1];
 
-		cache->vertex_rotation = -atan2f(dx, dy) * cache->bstrength;
+		/* only update when we have enough precision, by having the mouse adequately away from center
+		 * may be better to convert to radial representation but square works for small values too*/
+		if(fabs(dx) > PIXEL_INPUT_THRESHHOLD && fabs(dy) > PIXEL_INPUT_THRESHHOLD) {
+			float mouse_angle;
+			float dir[2] = {dx, dy};
+			float cosval, sinval;
+			normalize_v2(dir);
 
+			if (!cache->init_dir_set) {
+				copy_v2_v2(cache->initial_mouse_dir, dir);
+				cache->init_dir_set = true;
+			}
+
+			/* calculate mouse angle between initial and final mouse position */
+			cosval = dot_v2v2(dir, cache->initial_mouse_dir);
+			sinval = cross_v2v2(dir, cache->initial_mouse_dir);
+
+			/* clamp to avoid nans in acos */
+			CLAMP(cosval, -1.0, 1.0);
+			mouse_angle = (sinval > 0)? acos(cosval) : -acos(cosval);
+
+			/* change of sign, we passed the 180 degree threshold. This means we need to add a turn.
+			 * to distinguish between transition from 0 to -1 and -PI to +PI, use comparison with PI/2 */
+			if (mouse_angle * cache->previous_vertex_rotation < 0 && fabs(cache->previous_vertex_rotation) > M_PI_2) {
+				if (cache->previous_vertex_rotation < 0)
+					cache->num_vertex_turns--;
+				else
+					cache->num_vertex_turns++;
+			}
+			cache->previous_vertex_rotation = mouse_angle;
+
+			cache->vertex_rotation = -(mouse_angle + 2*M_PI*cache->num_vertex_turns)* cache->bstrength;
+
+		#undef PIXEL_INPUT_THRESHHOLD
+		}
+
 		ups->draw_anchored = 1;
 		copy_v2_v2(ups->anchored_initial_mouse, cache->initial_mouse);
 		copy_v3_v3(cache->anchored_location, cache->true_location);




More information about the Bf-blender-cvs mailing list