[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [54928] trunk/blender/source/blender/ editors: fix for harmless glitch rotating the camera in camera mode, having the center point so close to the viewpoint caused the helper line to erratically move about because of float precision .

Campbell Barton ideasman42 at gmail.com
Thu Feb 28 12:29:27 CET 2013


Revision: 54928
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=54928
Author:   campbellbarton
Date:     2013-02-28 11:29:27 +0000 (Thu, 28 Feb 2013)
Log Message:
-----------
fix for harmless glitch rotating the camera in camera mode, having the center point so close to the viewpoint caused the helper line to erratically move about because of float precision.

Modified Paths:
--------------
    trunk/blender/source/blender/editors/include/ED_view3d.h
    trunk/blender/source/blender/editors/space_view3d/view3d_project.c
    trunk/blender/source/blender/editors/transform/transform.c
    trunk/blender/source/blender/editors/transform/transform.h

Modified: trunk/blender/source/blender/editors/include/ED_view3d.h
===================================================================
--- trunk/blender/source/blender/editors/include/ED_view3d.h	2013-02-28 11:00:06 UTC (rev 54927)
+++ trunk/blender/source/blender/editors/include/ED_view3d.h	2013-02-28 11:29:27 UTC (rev 54928)
@@ -105,9 +105,10 @@
 typedef enum {
 	V3D_PROJ_RET_OK   = 0,
 	V3D_PROJ_RET_CLIP_NEAR = 1,  /* can't avoid this when in perspective mode, (can't avoid) */
-	V3D_PROJ_RET_CLIP_BB   = 2,  /* bounding box clip - RV3D_CLIPPING */
-	V3D_PROJ_RET_CLIP_WIN  = 3,  /* outside window bounds */
-	V3D_PROJ_RET_OVERFLOW  = 4   /* outside range (mainly for short), (can't avoid) */
+	V3D_PROJ_RET_CLIP_ZERO = 2,  /* so close to zero we can't apply a perspective matrix usefully */
+	V3D_PROJ_RET_CLIP_BB   = 3,  /* bounding box clip - RV3D_CLIPPING */
+	V3D_PROJ_RET_CLIP_WIN  = 4,  /* outside window bounds */
+	V3D_PROJ_RET_OVERFLOW  = 5   /* outside range (mainly for short), (can't avoid) */
 } eV3DProjStatus;
 
 /* some clipping tests are optional */
@@ -116,10 +117,13 @@
 	V3D_PROJ_TEST_CLIP_BB    = (1 << 0),
 	V3D_PROJ_TEST_CLIP_WIN   = (1 << 1),
 	V3D_PROJ_TEST_CLIP_NEAR  = (1 << 2),
+	V3D_PROJ_TEST_CLIP_ZERO  = (1 << 3)
 } eV3DProjTest;
 
-#define V3D_PROJ_TEST_CLIP_DEFAULT (V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN | V3D_PROJ_TEST_CLIP_NEAR)
-#define V3D_PROJ_TEST_ALL          (V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN | V3D_PROJ_TEST_CLIP_NEAR)
+#define V3D_PROJ_TEST_CLIP_DEFAULT \
+	(V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN | V3D_PROJ_TEST_CLIP_NEAR)
+#define V3D_PROJ_TEST_ALL \
+	(V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN | V3D_PROJ_TEST_CLIP_NEAR | V3D_PROJ_TEST_CLIP_ZERO)
 
 
 /* view3d_iterators.c */

Modified: trunk/blender/source/blender/editors/space_view3d/view3d_project.c
===================================================================
--- trunk/blender/source/blender/editors/space_view3d/view3d_project.c	2013-02-28 11:00:06 UTC (rev 54927)
+++ trunk/blender/source/blender/editors/space_view3d/view3d_project.c	2013-02-28 11:29:27 UTC (rev 54928)
@@ -43,6 +43,7 @@
 #include "ED_view3d.h"  /* own include */
 
 #define BL_NEAR_CLIP 0.001
+#define BL_ZERO_CLIP 0.001
 
 /* Non Clipping Projection Functions
  * ********************************* */
@@ -134,30 +135,37 @@
 	vec4[3] = 1.0;
 	mul_m4_v4(perspmat, vec4);
 
-	if (((flag & V3D_PROJ_TEST_CLIP_NEAR) == 0)  || (vec4[3] > (float)BL_NEAR_CLIP)) {
-		const float scalar = (vec4[3] != 0.0f) ? (1.0f / vec4[3]): 0.0f;
-		const float fx = ((float)ar->winx / 2.0f) * (1.0f + (vec4[0] * scalar));
-		if (((flag & V3D_PROJ_TEST_CLIP_WIN) == 0) || (fx > 0.0f && fx < (float)ar->winx)) {
-			const float fy = ((float)ar->winy / 2.0f) * (1.0f + (vec4[1] * scalar));
-			if (((flag & V3D_PROJ_TEST_CLIP_WIN) == 0) || (fy > 0.0f && fy < (float)ar->winy)) {
-				r_co[0] = floorf(fx);
-				r_co[1] = floorf(fy);
 
-				/* check if the point is behind the view, we need to flip in this case */
-				if (UNLIKELY((flag & V3D_PROJ_TEST_CLIP_NEAR) == 0) && (vec4[3] < 0.0f)) {
-					negate_v2(r_co);
+
+	if (((flag & V3D_PROJ_TEST_CLIP_ZERO) == 0) || (fabsf(vec4[3]) > (float)BL_ZERO_CLIP)) {
+		if (((flag & V3D_PROJ_TEST_CLIP_NEAR) == 0)  || (vec4[3] > (float)BL_NEAR_CLIP)) {
+			const float scalar = (vec4[3] != 0.0f) ? (1.0f / vec4[3]): 0.0f;
+			const float fx = ((float)ar->winx / 2.0f) * (1.0f + (vec4[0] * scalar));
+			if (((flag & V3D_PROJ_TEST_CLIP_WIN) == 0) || (fx > 0.0f && fx < (float)ar->winx)) {
+				const float fy = ((float)ar->winy / 2.0f) * (1.0f + (vec4[1] * scalar));
+				if (((flag & V3D_PROJ_TEST_CLIP_WIN) == 0) || (fy > 0.0f && fy < (float)ar->winy)) {
+					r_co[0] = floorf(fx);
+					r_co[1] = floorf(fy);
+
+					/* check if the point is behind the view, we need to flip in this case */
+					if (UNLIKELY((flag & V3D_PROJ_TEST_CLIP_NEAR) == 0) && (vec4[3] < 0.0f)) {
+						negate_v2(r_co);
+					}
 				}
+				else {
+					return V3D_PROJ_RET_CLIP_WIN;
+				}
 			}
 			else {
 				return V3D_PROJ_RET_CLIP_WIN;
 			}
 		}
 		else {
-			return V3D_PROJ_RET_CLIP_WIN;
+			return V3D_PROJ_RET_CLIP_NEAR;
 		}
 	}
 	else {
-		return V3D_PROJ_RET_CLIP_NEAR;
+		return V3D_PROJ_RET_CLIP_ZERO;
 	}
 
 	return V3D_PROJ_RET_OK;

Modified: trunk/blender/source/blender/editors/transform/transform.c
===================================================================
--- trunk/blender/source/blender/editors/transform/transform.c	2013-02-28 11:00:06 UTC (rev 54927)
+++ trunk/blender/source/blender/editors/transform/transform.c	2013-02-28 11:29:27 UTC (rev 54928)
@@ -239,11 +239,11 @@
 	}
 }
 
-void projectIntView(TransInfo *t, const float vec[3], int adr[2])
+void projectIntViewEx(TransInfo *t, const float vec[3], int adr[2], const eV3DProjTest flag)
 {
 	if (t->spacetype == SPACE_VIEW3D) {
 		if (t->ar->regiontype == RGN_TYPE_WINDOW) {
-			if (ED_view3d_project_int_global(t->ar, vec, adr, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_OK) {
+			if (ED_view3d_project_int_global(t->ar, vec, adr, flag) != V3D_PROJ_RET_OK) {
 				adr[0] = (int)2140000000.0f;  /* this is what was done in 2.64, perhaps we can be smarter? */
 				adr[1] = (int)2140000000.0f;
 			}
@@ -361,15 +361,19 @@
 		UI_view2d_to_region_no_clip((View2D *)t->view, vec[0], vec[1], adr, adr + 1);
 	}
 }
+void projectIntView(TransInfo *t, const float vec[3], int adr[2])
+{
+	projectIntViewEx(t, vec, adr, V3D_PROJ_TEST_NOP);
+}
 
-void projectFloatView(TransInfo *t, const float vec[3], float adr[2])
+void projectFloatViewEx(TransInfo *t, const float vec[3], float adr[2], const eV3DProjTest flag)
 {
 	switch (t->spacetype) {
 		case SPACE_VIEW3D:
 		{
 			if (t->ar->regiontype == RGN_TYPE_WINDOW) {
 				/* allow points behind the view [#33643] */
-				if (ED_view3d_project_float_global(t->ar, vec, adr, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_OK) {
+				if (ED_view3d_project_float_global(t->ar, vec, adr, flag) != V3D_PROJ_RET_OK) {
 					/* XXX, 2.64 and prior did this, weak! */
 					adr[0] = t->ar->winx / 2.0f;
 					adr[1] = t->ar->winy / 2.0f;
@@ -393,6 +397,10 @@
 
 	zero_v2(adr);
 }
+void projectFloatView(TransInfo *t, const float vec[3], float adr[2])
+{
+	projectFloatViewEx(t, vec, adr, V3D_PROJ_TEST_NOP);
+}
 
 void applyAspectRatio(TransInfo *t, float vec[2])
 {
@@ -1543,7 +1551,7 @@
 			if (ob) mul_m4_v3(ob->obmat, vecrot);
 		}
 
-		projectFloatView(t, vecrot, cent);  // no overflow in extreme cases
+		projectFloatViewEx(t, vecrot, cent, V3D_PROJ_TEST_CLIP_ZERO);
 
 		glPushMatrix();
 

Modified: trunk/blender/source/blender/editors/transform/transform.h
===================================================================
--- trunk/blender/source/blender/editors/transform/transform.h	2013-02-28 11:00:06 UTC (rev 54927)
+++ trunk/blender/source/blender/editors/transform/transform.h	2013-02-28 11:29:27 UTC (rev 54928)
@@ -35,6 +35,7 @@
 
 #include "ED_transform.h"
 #include "ED_numinput.h"
+#include "ED_view3d.h"
 
 #include "DNA_listBase.h"
 
@@ -481,7 +482,9 @@
 
 void setTransformViewMatrices(TransInfo *t);
 void convertViewVec(TransInfo *t, float r_vec[3], int dx, int dy);
+void projectIntViewEx(TransInfo *t, const float vec[3], int adr[2], const eV3DProjTest flag);
 void projectIntView(TransInfo *t, const float vec[3], int adr[2]);
+void projectFloatViewEx(TransInfo *t, const float vec[3], float adr[2], const eV3DProjTest flag);
 void projectFloatView(TransInfo *t, const float vec[3], float adr[2]);
 
 void applyAspectRatio(TransInfo *t, float *vec);




More information about the Bf-blender-cvs mailing list