[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [41749] trunk/blender/source/blender: fix [#29203] Camera can still move even when transforms locked

Campbell Barton ideasman42 at gmail.com
Fri Nov 11 06:34:09 CET 2011


Revision: 41749
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=41749
Author:   campbellbarton
Date:     2011-11-11 05:34:07 +0000 (Fri, 11 Nov 2011)
Log Message:
-----------
fix [#29203] Camera can still move even when transforms locked

added object_tfm_protected_backup, object_tfm_protected_restore so its easier to transform the object and respect protected channels (otherwise you need checks everywhere for each channel which is verbose).

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/BKE_object.h
    trunk/blender/source/blender/blenkernel/intern/object.c
    trunk/blender/source/blender/editors/space_view3d/view3d_edit.c
    trunk/blender/source/blender/editors/space_view3d/view3d_view.c

Modified: trunk/blender/source/blender/blenkernel/BKE_object.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_object.h	2011-11-11 03:28:46 UTC (rev 41748)
+++ trunk/blender/source/blender/blenkernel/BKE_object.h	2011-11-11 05:34:07 UTC (rev 41749)
@@ -116,6 +116,22 @@
 void *object_tfm_backup(struct Object *ob);
 void object_tfm_restore(struct Object *ob, void *obtfm_pt);
 
+typedef struct ObjectTfmProtectedChannels {
+	float loc[3],     dloc[3];
+	float size[3],    dsize[3];
+	float rot[3],     drot[3];
+	float quat[4],    dquat[4];
+	float rotAxis[3], drotAxis[3];
+	float rotAngle,   drotAngle;
+} ObjectTfmProtectedChannels;
+
+void object_tfm_protected_backup(const struct Object *ob,
+                                 ObjectTfmProtectedChannels *obtfm);
+
+void object_tfm_protected_restore(struct Object *ob,
+                                  const ObjectTfmProtectedChannels *obtfm,
+                                  const short protectflag);
+
 void object_handle_update(struct Scene *scene, struct Object *ob);
 void object_sculpt_modifiers_changed(struct Object *ob);
 

Modified: trunk/blender/source/blender/blenkernel/intern/object.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/object.c	2011-11-11 03:28:46 UTC (rev 41748)
+++ trunk/blender/source/blender/blenkernel/intern/object.c	2011-11-11 05:34:07 UTC (rev 41749)
@@ -1498,6 +1498,71 @@
 	}
 }
 
+void object_tfm_protected_backup(const Object *ob,
+                                 ObjectTfmProtectedChannels *obtfm)
+{
+
+#define TFMCPY(   _v) (obtfm->_v = ob->_v)
+#define TFMCPY3D( _v) copy_v3_v3(obtfm->_v, ob->_v)
+#define TFMCPY4D( _v) copy_v4_v4(obtfm->_v, ob->_v)
+
+	TFMCPY3D(loc);
+	TFMCPY3D(dloc);
+	TFMCPY3D(size);
+	TFMCPY3D(dsize);
+	TFMCPY3D(rot);
+	TFMCPY3D(drot);
+	TFMCPY4D(quat);
+	TFMCPY4D(dquat);
+	TFMCPY3D(rotAxis);
+	TFMCPY3D(drotAxis);
+	TFMCPY(rotAngle);
+	TFMCPY(drotAngle);
+
+#undef TFMCPY
+#undef TFMCPY3D
+#undef TFMCPY4D
+
+}
+
+void object_tfm_protected_restore(Object *ob,
+                                  const ObjectTfmProtectedChannels *obtfm,
+                                  const short protectflag)
+{
+	unsigned int i;
+
+	for (i= 0; i < 3; i++) {
+		if (protectflag & (OB_LOCK_LOCX<<i)) {
+			ob->loc[i]=  obtfm->loc[i];
+			ob->dloc[i]= obtfm->dloc[i];
+		}
+
+		if (protectflag & (OB_LOCK_SCALEX<<i)) {
+			ob->size[i]=  obtfm->size[i];
+			ob->dsize[i]= obtfm->dsize[i];
+		}
+
+		if (protectflag & (OB_LOCK_ROTX<<i)) {
+			ob->rot[i]=  obtfm->rot[i];
+			ob->drot[i]= obtfm->drot[i];
+
+			ob->quat[i + 1]=  obtfm->quat[i + 1];
+			ob->dquat[i + 1]= obtfm->dquat[i + 1];
+
+			ob->rotAxis[i]=  obtfm->rotAxis[i];
+			ob->drotAxis[i]= obtfm->drotAxis[i];
+		}
+	}
+
+	if ((protectflag & OB_LOCK_ROT4D) && (protectflag & OB_LOCK_ROTW)) {
+		ob->quat[0]=  obtfm->quat[0];
+		ob->dquat[0]= obtfm->dquat[0];
+
+		ob->rotAngle=  obtfm->rotAngle;
+		ob->drotAngle= obtfm->drotAngle;
+	}
+}
+
 /* see pchan_apply_mat4() for the equivalent 'pchan' function */
 void object_apply_mat4(Object *ob, float mat[][4], const short use_compat, const short use_parent)
 {

Modified: trunk/blender/source/blender/editors/space_view3d/view3d_edit.c
===================================================================
--- trunk/blender/source/blender/editors/space_view3d/view3d_edit.c	2011-11-11 03:28:46 UTC (rev 41748)
+++ trunk/blender/source/blender/editors/space_view3d/view3d_edit.c	2011-11-11 05:34:07 UTC (rev 41749)
@@ -99,6 +99,7 @@
 int ED_view3d_camera_lock_sync(View3D *v3d, RegionView3D *rv3d)
 {
 	if(ED_view3d_camera_lock_check(v3d, rv3d)) {
+		ObjectTfmProtectedChannels obtfm;
 		Object *root_parent;
 
 		if((U.uiflag & USER_CAM_LOCK_NO_PARENT)==0 && (root_parent= v3d->camera->parent)) {
@@ -117,7 +118,10 @@
 			mul_m4_m4m4(diff_mat, v3d->camera->imat, view_mat);
 
 			mul_m4_m4m4(parent_mat, root_parent->obmat, diff_mat);
+
+			object_tfm_protected_backup(root_parent, &obtfm);
 			object_apply_mat4(root_parent, parent_mat, TRUE, FALSE);
+			object_tfm_protected_restore(root_parent, &obtfm, root_parent->protectflag);
 
 			ob_update= v3d->camera;
 			while(ob_update) {
@@ -127,7 +131,10 @@
 			}
 		}
 		else {
+			object_tfm_protected_backup(v3d->camera, &obtfm);
 			ED_view3d_to_object(v3d->camera, rv3d->ofs, rv3d->viewquat, rv3d->dist);
+			object_tfm_protected_restore(v3d->camera, &obtfm, v3d->camera->protectflag);
+
 			DAG_id_tag_update(&v3d->camera->id, OB_RECALC_OB);
 			WM_main_add_notifier(NC_OBJECT|ND_TRANSFORM, v3d->camera);
 		}
@@ -346,6 +353,7 @@
 	double timer_lastdraw;
 
 	float oldquat[4];
+	float viewquat[4]; /* working copy of rv3d->viewquat */
 	float trackvec[3];
 	float mousevec[3]; /* dolly only */
 	float reverse, dist0;
@@ -408,6 +416,7 @@
 	ED_view3d_camera_lock_init(vod->v3d, vod->rv3d);
 
 	vod->dist0= rv3d->dist;
+	copy_qt_qt(vod->viewquat, rv3d->viewquat);
 	copy_qt_qt(vod->oldquat, rv3d->viewquat);
 	vod->origx= vod->oldx= event->x;
 	vod->origy= vod->oldy= event->y;
@@ -643,13 +652,13 @@
 
 		q1[0]= cos(phi);
 		mul_v3_fl(q1+1, sin(phi));
-		mul_qt_qtqt(rv3d->viewquat, q1, vod->oldquat);
+		mul_qt_qtqt(vod->viewquat, q1, vod->oldquat);
 
 		if (vod->use_dyn_ofs) {
 			/* compute the post multiplication quat, to rotate the offset correctly */
 			copy_qt_qt(q1, vod->oldquat);
 			conjugate_qt(q1);
-			mul_qt_qtqt(q1, q1, rv3d->viewquat);
+			mul_qt_qtqt(q1, q1, vod->viewquat);
 
 			conjugate_qt(q1); /* conj == inv for unit quat */
 			copy_v3_v3(rv3d->ofs, vod->ofs);
@@ -671,7 +680,7 @@
 		const float sensitivity = 0.0035f;
 
 		/* Get the 3x3 matrix and its inverse from the quaternion */
-		quat_to_mat3( m,rv3d->viewquat);
+		quat_to_mat3( m,vod->viewquat);
 		invert_m3_m3(m_inv,m);
 
 		/* Determine the direction of the x vector (for rotating up and down) */
@@ -682,7 +691,7 @@
 		phi = sensitivity * -(y - vod->oldy);
 		q1[0] = cos(phi);
 		mul_v3_v3fl(q1+1, xvec, sin(phi));
-		mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, q1);
+		mul_qt_qtqt(vod->viewquat, vod->viewquat, q1);
 
 		if (vod->use_dyn_ofs) {
 			conjugate_qt(q1); /* conj == inv for unit quat */
@@ -696,7 +705,7 @@
 		q1[0] = cos(phi);
 		q1[1] = q1[2] = 0.0;
 		q1[3] = sin(phi);
-		mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, q1);
+		mul_qt_qtqt(vod->viewquat, vod->viewquat, q1);
 
 		if (vod->use_dyn_ofs) {
 			conjugate_qt(q1);
@@ -711,7 +720,7 @@
 		int i;
 		float viewquat_inv[4];
 		float zaxis[3]={0,0,1};
-		invert_qt_qt(viewquat_inv, rv3d->viewquat);
+		invert_qt_qt(viewquat_inv, vod->viewquat);
 
 		mul_qt_v3(viewquat_inv, zaxis);
 
@@ -736,7 +745,7 @@
 				 * for testing roll */
 				rotation_between_vecs_to_quat(viewquat_align, zaxis_test, zaxis);
 				normalize_qt(viewquat_align);
-				mul_qt_qtqt(viewquat_align, rv3d->viewquat, viewquat_align);
+				mul_qt_qtqt(viewquat_align, vod->viewquat, viewquat_align);
 				normalize_qt(viewquat_align);
 				invert_qt_qt(viewquat_align_inv, viewquat_align);
 
@@ -766,7 +775,7 @@
 					}
 				}
 
-				copy_qt_qt(rv3d->viewquat, quat_best);
+				copy_qt_qt(vod->viewquat, quat_best);
 				rv3d->view= view; /* if we snap to a rolled camera the grid is invalid */
 
 				break;
@@ -777,8 +786,12 @@
 	vod->oldy= y;
 
 	/* avoid precision loss over time */
-	normalize_qt(rv3d->viewquat);
+	normalize_qt(vod->viewquat);
 
+	/* use a working copy so view rotation locking doesnt overwrite the locked
+	 * rotation back into the view we calculate with */
+	copy_qt_qt(rv3d->viewquat, vod->viewquat);
+
 	ED_view3d_camera_lock_sync(vod->v3d, rv3d);
 
 	ED_region_tag_redraw(vod->ar);

Modified: trunk/blender/source/blender/editors/space_view3d/view3d_view.c
===================================================================
--- trunk/blender/source/blender/editors/space_view3d/view3d_view.c	2011-11-11 03:28:46 UTC (rev 41748)
+++ trunk/blender/source/blender/editors/space_view3d/view3d_view.c	2011-11-11 05:34:07 UTC (rev 41749)
@@ -370,6 +370,7 @@
 {
 	View3D *v3d = CTX_wm_view3d(C);
 	RegionView3D *rv3d= CTX_wm_region_view3d(C);
+	ObjectTfmProtectedChannels obtfm;
 
 	copy_qt_qt(rv3d->lviewquat, rv3d->viewquat);
 	rv3d->lview= rv3d->view;
@@ -377,7 +378,12 @@
 		rv3d->lpersp= rv3d->persp;
 	}
 
+	object_tfm_protected_backup(v3d->camera, &obtfm);
+
 	ED_view3d_to_object(v3d->camera, rv3d->ofs, rv3d->viewquat, rv3d->dist);
+
+	object_tfm_protected_restore(v3d->camera, &obtfm, v3d->camera->protectflag);
+
 	DAG_id_tag_update(&v3d->camera->id, OB_RECALC_OB);
 	rv3d->persp = RV3D_CAMOB;
 	




More information about the Bf-blender-cvs mailing list