[Bf-blender-cvs] [8c90910dcc3] master: Fix T66937: Blank view on navigation with auto-deph & large clip-end

Campbell Barton noreply at git.blender.org
Sun Jul 19 13:28:58 CEST 2020


Commit: 8c90910dcc3ac56ecaa3f0d0ed1a43a423ff687f
Author: Campbell Barton
Date:   Sun Jul 19 21:27:13 2020 +1000
Branches: master
https://developer.blender.org/rB8c90910dcc3ac56ecaa3f0d0ed1a43a423ff687f

Fix T66937: Blank view on navigation with auto-deph & large clip-end

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

M	source/blender/blenlib/BLI_math_geom.h
M	source/blender/blenlib/intern/math_geom.c
M	source/blender/gpu/GPU_matrix.h
M	source/blender/gpu/intern/gpu_matrix.c

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

diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h
index f51486c5e7b..64b0dcccda1 100644
--- a/source/blender/blenlib/BLI_math_geom.h
+++ b/source/blender/blenlib/BLI_math_geom.h
@@ -671,6 +671,13 @@ void projmat_dimensions(const float projmat[4][4],
                         float *r_top,
                         float *r_near,
                         float *r_far);
+void projmat_dimensions_db(const float projmat[4][4],
+                           double *r_left,
+                           double *r_right,
+                           double *r_bottom,
+                           double *r_top,
+                           double *r_near,
+                           double *r_far);
 
 void projmat_from_subregion(const float projmat[4][4],
                             const int win_size[2],
diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c
index d3dc4729617..2891279bb63 100644
--- a/source/blender/blenlib/intern/math_geom.c
+++ b/source/blender/blenlib/intern/math_geom.c
@@ -4880,6 +4880,37 @@ void projmat_dimensions(const float projmat[4][4],
   }
 }
 
+void projmat_dimensions_db(const float projmat_fl[4][4],
+                           double *r_left,
+                           double *r_right,
+                           double *r_bottom,
+                           double *r_top,
+                           double *r_near,
+                           double *r_far)
+{
+  double projmat[4][4];
+  copy_m4d_m4(projmat, projmat_fl);
+
+  bool is_persp = projmat[3][3] == 0.0f;
+
+  if (is_persp) {
+    *r_left = (projmat[2][0] - 1.0) / projmat[0][0];
+    *r_right = (projmat[2][0] + 1.0) / projmat[0][0];
+    *r_bottom = (projmat[2][1] - 1.0) / projmat[1][1];
+    *r_top = (projmat[2][1] + 1.0) / projmat[1][1];
+    *r_near = projmat[3][2] / (projmat[2][2] - 1.0);
+    *r_far = projmat[3][2] / (projmat[2][2] + 1.0);
+  }
+  else {
+    *r_left = (-projmat[3][0] - 1.0) / projmat[0][0];
+    *r_right = (-projmat[3][0] + 1.0) / projmat[0][0];
+    *r_bottom = (-projmat[3][1] - 1.0) / projmat[1][1];
+    *r_top = (-projmat[3][1] + 1.0) / projmat[1][1];
+    *r_near = (projmat[3][2] + 1.0) / projmat[2][2];
+    *r_far = (projmat[3][2] - 1.0) / projmat[2][2];
+  }
+}
+
 /**
  * Creates a projection matrix for a small region of the viewport.
  *
diff --git a/source/blender/gpu/GPU_matrix.h b/source/blender/gpu/GPU_matrix.h
index 56d640ea0e4..eabfb5d2dc3 100644
--- a/source/blender/gpu/GPU_matrix.h
+++ b/source/blender/gpu/GPU_matrix.h
@@ -102,11 +102,15 @@ struct GPUMatrixUnproject_Precalc {
   float model_inverted[4][4];
   float view[4];
   bool is_persp;
-  /** Result of 'projmat_dimensions'. */
+  /**
+   * Result of #projmat_dimensions_db.
+   * Using double precision here is important as far clipping ranges
+   * can cause divide-by-zero when using float, see: T66937.
+   */
   struct {
-    float xmin, xmax;
-    float ymin, ymax;
-    float zmin, zmax;
+    double xmin, xmax;
+    double ymin, ymax;
+    double zmin, zmax;
   } dims;
 };
 
diff --git a/source/blender/gpu/intern/gpu_matrix.c b/source/blender/gpu/intern/gpu_matrix.c
index d0f7eab32a3..669bf56b726 100644
--- a/source/blender/gpu/intern/gpu_matrix.c
+++ b/source/blender/gpu/intern/gpu_matrix.c
@@ -536,13 +536,13 @@ bool GPU_matrix_unproject_precalc(struct GPUMatrixUnproject_Precalc *precalc,
                                   const int view[4])
 {
   precalc->is_persp = proj[3][3] == 0.0f;
-  projmat_dimensions(proj,
-                     &precalc->dims.xmin,
-                     &precalc->dims.xmax,
-                     &precalc->dims.ymin,
-                     &precalc->dims.ymax,
-                     &precalc->dims.zmin,
-                     &precalc->dims.zmax);
+  projmat_dimensions_db(proj,
+                        &precalc->dims.xmin,
+                        &precalc->dims.xmax,
+                        &precalc->dims.ymin,
+                        &precalc->dims.ymax,
+                        &precalc->dims.zmin,
+                        &precalc->dims.zmax);
   if (isinf(precalc->dims.zmax)) {
     /* We cannot retrieve the actual value of the clip_end.
      * Use `FLT_MAX` to avoid nans. */



More information about the Bf-blender-cvs mailing list