[Bf-blender-cvs] [ea89b4a] blender2.8: Viewport: bring grid over to the new viewport

Dalai Felinto noreply at git.blender.org
Thu Oct 6 22:35:56 CEST 2016


Commit: ea89b4a918bf8dbbe98c7c0f893e04c091f714ab
Author: Dalai Felinto
Date:   Thu Oct 6 19:55:06 2016 +0000
Branches: blender2.8
https://developer.blender.org/rBea89b4a918bf8dbbe98c7c0f893e04c091f714ab

Viewport: bring grid over to the new viewport

We will keep the old system working as long as we can. At the moment even the visibility flags we are getting from the old system. That will continue like this until we have decided on the new UI

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

M	source/blender/editors/space_view3d/view3d_draw.c
M	source/blender/editors/space_view3d/view3d_draw_legacy.c
M	source/blender/editors/space_view3d/view3d_intern.h

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

diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index f7bdb1f..e8eae69 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -28,14 +28,191 @@
  *  \ingroup spview3d
  */
 
+#include <math.h>
+
 #include "BIF_gl.h"
 
+#include "BKE_camera.h"
+#include "BKE_context.h"
+#include "BKE_scene.h"
+#include "BKE_unit.h"
+
+#include "BLI_math.h"
+#include "BLI_rect.h"
+#include "BLI_threads.h"
+
+#include "DNA_camera_types.h"
+#include "DNA_object_types.h"
+#include "DNA_view3d_types.h"
+#include "DNA_windowmanager_types.h"
+
 #include "ED_screen.h"
 
-#include "BKE_context.h"
+#include "GPU_immediate.h"
+
+#include "UI_resources.h"
+
+#include "WM_api.h"
 
 #include "view3d_intern.h"  /* own include */
 
+/* ******************** general functions ***************** */
+
+
+/**
+ * \note keep this synced with #ED_view3d_mats_rv3d_backup/#ED_view3d_mats_rv3d_restore
+ */
+void ED_view3d_update_viewmat(Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4])
+{
+	RegionView3D *rv3d = ar->regiondata;
+	rctf cameraborder;
+
+	/* setup window matrices */
+	if (winmat)
+		copy_m4_m4(rv3d->winmat, winmat);
+	else
+		view3d_winmatrix_set(ar, v3d, NULL);
+
+	/* setup view matrix */
+	if (viewmat)
+		copy_m4_m4(rv3d->viewmat, viewmat);
+	else
+		view3d_viewmatrix_set(scene, v3d, rv3d);  /* note: calls BKE_object_where_is_calc for camera... */
+
+	/* update utilitity matrices */
+	mul_m4_m4m4(rv3d->persmat, rv3d->winmat, rv3d->viewmat);
+	invert_m4_m4(rv3d->persinv, rv3d->persmat);
+	invert_m4_m4(rv3d->viewinv, rv3d->viewmat);
+
+	/* calculate GLSL view dependent values */
+
+	/* store window coordinates scaling/offset */
+	if (rv3d->persp == RV3D_CAMOB && v3d->camera) {
+		ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &cameraborder, false);
+		rv3d->viewcamtexcofac[0] = (float)ar->winx / BLI_rctf_size_x(&cameraborder);
+		rv3d->viewcamtexcofac[1] = (float)ar->winy / BLI_rctf_size_y(&cameraborder);
+
+		rv3d->viewcamtexcofac[2] = -rv3d->viewcamtexcofac[0] * cameraborder.xmin / (float)ar->winx;
+		rv3d->viewcamtexcofac[3] = -rv3d->viewcamtexcofac[1] * cameraborder.ymin / (float)ar->winy;
+	}
+	else {
+		rv3d->viewcamtexcofac[0] = rv3d->viewcamtexcofac[1] = 1.0f;
+		rv3d->viewcamtexcofac[2] = rv3d->viewcamtexcofac[3] = 0.0f;
+	}
+
+	/* calculate pixelsize factor once, is used for lamps and obcenters */
+	{
+		/* note:  '1.0f / len_v3(v1)'  replaced  'len_v3(rv3d->viewmat[0])'
+		* because of float point precision problems at large values [#23908] */
+		float v1[3], v2[3];
+		float len_px, len_sc;
+
+		v1[0] = rv3d->persmat[0][0];
+		v1[1] = rv3d->persmat[1][0];
+		v1[2] = rv3d->persmat[2][0];
+
+		v2[0] = rv3d->persmat[0][1];
+		v2[1] = rv3d->persmat[1][1];
+		v2[2] = rv3d->persmat[2][1];
+
+		len_px = 2.0f / sqrtf(min_ff(len_squared_v3(v1), len_squared_v3(v2)));
+		len_sc = (float)MAX2(ar->winx, ar->winy);
+
+		rv3d->pixsize = len_px / len_sc;
+	}
+}
+
+static void view3d_main_region_setup_view(Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4])
+{
+	RegionView3D *rv3d = ar->regiondata;
+
+	ED_view3d_update_viewmat(scene, v3d, ar, viewmat, winmat);
+
+	/* set for opengl */
+	glMatrixMode(GL_PROJECTION);
+	glLoadMatrixf(rv3d->winmat);
+	glMatrixMode(GL_MODELVIEW);
+	glLoadMatrixf(rv3d->viewmat);
+}
+
+static bool view3d_stereo3d_active(const bContext *C, Scene *scene, View3D *v3d, RegionView3D *rv3d)
+{
+	wmWindow *win = CTX_wm_window(C);
+
+	if ((scene->r.scemode & R_MULTIVIEW) == 0)
+		return false;
+
+	if (WM_stereo3d_enabled(win, true) == false)
+		return false;
+
+	if ((v3d->camera == NULL) || (v3d->camera->type != OB_CAMERA) || rv3d->persp != RV3D_CAMOB)
+		return false;
+
+	if (scene->r.views_format & SCE_VIEWS_FORMAT_MULTIVIEW) {
+		if (v3d->stereo3d_camera == STEREO_MONO_ID)
+			return false;
+
+		return BKE_scene_multiview_is_stereo3d(&scene->r);
+	}
+
+	return true;
+}
+
+/* setup the view and win matrices for the multiview cameras
+ *
+ * unlike view3d_stereo3d_setup_offscreen, when view3d_stereo3d_setup is called
+ * we have no winmatrix (i.e., projection matrix) defined at that time.
+ * Since the camera and the camera shift are needed for the winmat calculation
+ * we do a small hack to replace it temporarily so we don't need to change the
+ * view3d)main_region_setup_view() code to account for that.
+ */
+static void view3d_stereo3d_setup(Scene *scene, View3D *v3d, ARegion *ar)
+{
+	bool is_left;
+	const char *names[2] = { STEREO_LEFT_NAME, STEREO_RIGHT_NAME };
+	const char *viewname;
+
+	/* show only left or right camera */
+	if (v3d->stereo3d_camera != STEREO_3D_ID)
+		v3d->multiview_eye = v3d->stereo3d_camera;
+
+	is_left = v3d->multiview_eye == STEREO_LEFT_ID;
+	viewname = names[is_left ? STEREO_LEFT_ID : STEREO_RIGHT_ID];
+
+	/* update the viewport matrices with the new camera */
+	if (scene->r.views_format == SCE_VIEWS_FORMAT_STEREO_3D) {
+		Camera *data;
+		float viewmat[4][4];
+		float shiftx;
+
+		data = (Camera *)v3d->camera->data;
+		shiftx = data->shiftx;
+
+		BLI_lock_thread(LOCK_VIEW3D);
+		data->shiftx = BKE_camera_multiview_shift_x(&scene->r, v3d->camera, viewname);
+
+		BKE_camera_multiview_view_matrix(&scene->r, v3d->camera, is_left, viewmat);
+		view3d_main_region_setup_view(scene, v3d, ar, viewmat, NULL);
+
+		data->shiftx = shiftx;
+		BLI_unlock_thread(LOCK_VIEW3D);
+	}
+	else { /* SCE_VIEWS_FORMAT_MULTIVIEW */
+		float viewmat[4][4];
+		Object *view_ob = v3d->camera;
+		Object *camera = BKE_camera_multiview_render(scene, v3d->camera, viewname);
+
+		BLI_lock_thread(LOCK_VIEW3D);
+		v3d->camera = camera;
+
+		BKE_camera_multiview_view_matrix(&scene->r, camera, false, viewmat);
+		view3d_main_region_setup_view(scene, v3d, ar, viewmat, NULL);
+
+		v3d->camera = view_ob;
+		BLI_unlock_thread(LOCK_VIEW3D);
+	}
+}
+
 /* ******************** solid plates ***************** */
 
 /**
@@ -75,27 +252,573 @@ static void view3d_draw_post_draw(const bContext *C)
 /* ******************** geometry overlay ***************** */
 
 /**
-* Front/back wire frames
-*/
+ * Front/back wire frames
+ */
 static void view3d_draw_wire_plates(const bContext *C)
 {
 	/* TODO viewport */
 }
 
 /**
-* Special treatment for selected objects
-*/
+ * Special treatment for selected objects
+ */
 static void view3d_draw_outline_plates(const bContext *C)
 {
 	/* TODO viewport */
 }
 
+/* ******************** other elements ***************** */
+
+
+#define DEBUG_GRID 0
+
+static void gridline_range(double x0, double dx, double max, int* first_out, int* count_out)
+{
+	/* determine range of gridlines that appear in this Area -- similar calc but separate ranges for x & y
+	* x0 is gridline 0, the axis in screen space
+	* Area covers [0 .. max) pixels */
+
+	int first = (int)ceil(-x0 / dx);
+	int last = (int)floor((max - x0) / dx);
+
+	if (first <= last) {
+		*first_out = first;
+		*count_out = last - first + 1;
+	}
+	else {
+		*first_out = 0;
+		*count_out = 0;
+	}
+
+#if DEBUG_GRID
+	printf("   first %d * dx = %f\n", first, x0 + first * dx);
+	printf("   last %d * dx = %f\n", last, x0 + last * dx);
+	printf("   count = %d\n", *count_out);
+#endif
+}
+
+static int gridline_count(ARegion *ar, double x0, double y0, double dx)
+{
+	/* x0 & y0 establish the "phase" of the grid within this 2D region
+	* dx is the frequency, shared by x & y directions
+	* pass in dx of smallest (highest precision) grid we want to draw */
+
+#if DEBUG_GRID
+	printf("  %s(%f, %f, dx:%f)\n", __FUNCTION__, x0, y0, dx);
+#endif
+
+	int first, x_ct, y_ct;
+
+	gridline_range(x0, dx, ar->winx, &first, &x_ct);
+	gridline_range(y0, dx, ar->winy, &first, &y_ct);
+
+	int total_ct = x_ct + y_ct;
+
+#if DEBUG_GRID
+	printf("   %d + %d = %d gridlines\n", x_ct, y_ct, total_ct);
+#endif
+
+	return total_ct;
+}
+
+static bool drawgrid_draw(ARegion *ar, double x0, double y0, double dx, int skip_mod, unsigned pos, unsigned col, GLubyte col_value[3])
+{
+	/* skip every skip_mod lines relative to each axis; they will be overlaid by another drawgrid_draw
+	* always skip exact x0 & y0 axes; they will be drawn later in color
+	*
+	* set grid color once, just before the first line is drawn
+	* it's harmless to set same color for every line, or every vertex
+	* but if no lines are drawn, color must not be set! */
+
+#if DEBUG_GRID
+	printf("  %s(%f, %f, dx:%f, skip_mod:%d)\n", __FUNCTION__, x0, y0, dx, skip_mod);
+#endif
+
+	const float x_max = (float)ar->winx;
+	const float y_max = (float)ar->winy;
+
+	int first, ct;
+	int x_ct = 0, y_ct = 0; /* count of lines actually drawn */
+	int lines_skipped_for_next_unit = 0;
+
+	/* draw vertical lines */
+	gridline_range(x0, dx, x_max, &first, &ct);
+
+	for (int i = first; i < first + ct; ++i) {
+		if (i == 0)
+			continue;
+		else if (skip_mod && (i % skip_mod) == 0) {
+			++lines_skipped_for_next_unit;
+			continue;
+		}
+
+		if (x_ct == 0)
+			immAttrib3ub(col, col_value[0], col_value[1], col_value[2]);
+
+		float x = (float)(x0 + i * dx);
+		immVertex2f(pos, x, 0.0f);
+		immVertex2f(pos, x, y_max);
+		++x_ct;
+	}
+
+	/* draw horizontal lines */
+	gridline_range(y0, dx, y_max, &first, &ct);
+
+	for (int i = first; i < first + ct; ++i) {
+		if (i == 0)
+			continue;
+		else if (skip_mod && (i % skip_mod) == 0) {
+			++lines_skipped_for_next_unit;
+			continue;
+		}
+
+		if (x_ct + y_ct == 0)
+			immAttrib3ub(col, col_value[0], col_value[1], col_value[2]);
+
+		float y = (float)(y0 + i * dx);
+		immVertex2f(pos, 0.0f, y);
+		immVertex2f(pos, x_max, y);
+		++y_ct;
+	}
+
+#if DEBUG_GRID
+	int total_ct = x_ct + y_ct;
+	printf("    %d + %d = %d gridlines drawn, %d skipped for next unit\n", x_ct, y_ct, total_ct, lines_skipped_for_next_unit);
+#endif
+
+	return lines_skipped_for_next_unit > 0;
+}
+
+#define GRID_MIN_PX_D 6.0
+#define GRID_MIN_PX_F 6.0f
+
+static void drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char **grid_unit)
+{
+	RegionView3D *rv3d = ar->regiondata;
+
+#if DEBUG_GRID
+	printf("%s width %d, height %d\n", __FUNCTION__, ar->winx, ar->winy);
+#endif
+
+	double fx = rv3d->persmat[3][0];
+	double fy = rv3d->persmat[3][1];
+	double fw = rv3d->persmat[3][3];
+
+

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list