Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/space_view3d')
-rw-r--r--source/blender/editors/space_view3d/CMakeLists.txt1
-rw-r--r--source/blender/editors/space_view3d/SConscript1
-rw-r--r--source/blender/editors/space_view3d/drawanimviz.c1
-rw-r--r--source/blender/editors/space_view3d/drawmesh.c20
-rw-r--r--source/blender/editors/space_view3d/drawobject.c810
-rw-r--r--source/blender/editors/space_view3d/drawsimdebug.c7
-rw-r--r--source/blender/editors/space_view3d/drawvolume.c110
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c18
-rw-r--r--source/blender/editors/space_view3d/view3d_buttons.c3
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c378
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c301
-rw-r--r--source/blender/editors/space_view3d/view3d_fly.c8
-rw-r--r--source/blender/editors/space_view3d/view3d_intern.h9
-rw-r--r--source/blender/editors/space_view3d/view3d_ops.c1
-rw-r--r--source/blender/editors/space_view3d/view3d_project.c8
-rw-r--r--source/blender/editors/space_view3d/view3d_ruler.c22
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c10
-rw-r--r--source/blender/editors/space_view3d/view3d_snap.c5
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c36
-rw-r--r--source/blender/editors/space_view3d/view3d_walk.c67
20 files changed, 1224 insertions, 592 deletions
diff --git a/source/blender/editors/space_view3d/CMakeLists.txt b/source/blender/editors/space_view3d/CMakeLists.txt
index ab69e67361d..d8d29d63686 100644
--- a/source/blender/editors/space_view3d/CMakeLists.txt
+++ b/source/blender/editors/space_view3d/CMakeLists.txt
@@ -30,6 +30,7 @@ set(INC
../../makesrna
../../render/extern/include
../../windowmanager
+ ../../depsgraph
../../../../intern/guardedalloc
../../../../intern/glew-mx
../../../../intern/smoke/extern
diff --git a/source/blender/editors/space_view3d/SConscript b/source/blender/editors/space_view3d/SConscript
index a21da940906..78f24948070 100644
--- a/source/blender/editors/space_view3d/SConscript
+++ b/source/blender/editors/space_view3d/SConscript
@@ -48,6 +48,7 @@ incs = [
'../../makesrna',
'../../render/extern/include',
'../../windowmanager',
+ '../../depsgraph',
]
if env['WITH_BF_PYTHON']:
diff --git a/source/blender/editors/space_view3d/drawanimviz.c b/source/blender/editors/space_view3d/drawanimviz.c
index d8b18140cde..d753ad68fcc 100644
--- a/source/blender/editors/space_view3d/drawanimviz.c
+++ b/source/blender/editors/space_view3d/drawanimviz.c
@@ -51,7 +51,6 @@
#include "BIF_gl.h"
-#include "ED_armature.h"
#include "ED_keyframes_draw.h"
diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c
index 755c633531d..96ea5d810bf 100644
--- a/source/blender/editors/space_view3d/drawmesh.c
+++ b/source/blender/editors/space_view3d/drawmesh.c
@@ -579,7 +579,7 @@ static DMDrawOption draw_tface__set_draw(MTFace *tface, const bool UNUSED(has_mc
{
Material *ma = give_current_material(Gtexdraw.ob, matnr + 1);
- if (ma && (ma->game.flag & GEMAT_INVISIBLE)) return 0;
+ if (ma && (ma->game.flag & GEMAT_INVISIBLE)) return DM_DRAW_OPTION_SKIP;
if (tface || Gtexdraw.is_texpaint)
set_draw_settings_cached(0, tface, ma, Gtexdraw);
@@ -588,15 +588,19 @@ static DMDrawOption draw_tface__set_draw(MTFace *tface, const bool UNUSED(has_mc
return DM_DRAW_OPTION_NORMAL;
}
-static void update_tface_color_layer(DerivedMesh *dm)
+static void update_tface_color_layer(DerivedMesh *dm, bool use_mcol)
{
MTFace *tface = DM_get_tessface_data_layer(dm, CD_MTFACE);
MFace *mface = dm->getTessFaceArray(dm);
MCol *finalCol;
int i, j;
- MCol *mcol = dm->getTessFaceDataArray(dm, CD_PREVIEW_MCOL);
- if (!mcol)
- mcol = dm->getTessFaceDataArray(dm, CD_MCOL);
+ MCol *mcol = NULL;
+
+ if (use_mcol) {
+ mcol = dm->getTessFaceDataArray(dm, CD_PREVIEW_MCOL);
+ if (!mcol)
+ mcol = dm->getTessFaceDataArray(dm, CD_MCOL);
+ }
if (CustomData_has_layer(&dm->faceData, CD_TEXTURE_MCOL)) {
finalCol = CustomData_get_layer(&dm->faceData, CD_TEXTURE_MCOL);
@@ -771,7 +775,7 @@ static void draw_mesh_text(Scene *scene, Object *ob, int glsl)
for (a = 0, mp = mface; a < totpoly; a++, mtpoly++, mp++) {
short matnr = mp->mat_nr;
- int mf_smooth = mp->flag & ME_SMOOTH;
+ const bool mf_smooth = (mp->flag & ME_SMOOTH) != 0;
Material *mat = (me->mat) ? me->mat[matnr] : NULL;
int mode = mat ? mat->game.flag : GEMAT_INVISIBLE;
@@ -937,7 +941,7 @@ static void draw_mesh_textured_old(Scene *scene, View3D *v3d, RegionView3D *rv3d
else {
drawTFace_userData userData;
- update_tface_color_layer(dm);
+ update_tface_color_layer(dm, !(ob->mode & OB_MODE_TEXTURE_PAINT));
userData.mf = DM_get_tessface_data_layer(dm, CD_MFACE);
userData.tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
@@ -1103,7 +1107,7 @@ void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d,
Mesh *me = ob->data;
TexMatCallback data = {scene, ob, me, dm};
bool (*set_face_cb)(void *, int);
- int glsl, picking = (G.f & G_PICKSEL);
+ bool glsl, picking = (G.f & G_PICKSEL) != 0;
/* face hiding callback depending on mode */
if (ob == scene->obedit)
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index 61c9891e201..8cca1c8b1ef 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -52,6 +52,7 @@
#include "BKE_anim.h" /* for the where_on_path function */
#include "BKE_armature.h"
#include "BKE_camera.h"
+#include "BKE_colortools.h"
#include "BKE_constraint.h" /* for the get_constraint_target function */
#include "BKE_curve.h"
#include "BKE_DerivedMesh.h"
@@ -213,6 +214,7 @@ static void drawcube_size(float size);
static void drawcircle_size(float size);
static void draw_empty_sphere(float size);
static void draw_empty_cone(float size);
+static void draw_box(float vec[8][3], bool solid);
static void ob_wire_color_blend_theme_id(const unsigned char ob_wire_col[4], const int theme_id, float fac)
{
@@ -299,11 +301,12 @@ bool draw_glsl_material(Scene *scene, Object *ob, View3D *v3d, const char dt)
if (v3d->flag2 & V3D_SHOW_SOLID_MATCAP)
return true;
- if (BKE_scene_use_new_shading_nodes(scene))
+ if (v3d->drawtype == OB_TEXTURE)
+ return (scene->gm.matmode == GAME_MAT_GLSL && !BKE_scene_use_new_shading_nodes(scene));
+ else if (v3d->drawtype == OB_MATERIAL && dt > OB_SOLID)
+ return true;
+ else
return false;
-
- return ((scene->gm.matmode == GAME_MAT_GLSL && v3d->drawtype == OB_TEXTURE) ||
- (v3d->drawtype == OB_MATERIAL)) && (dt > OB_SOLID);
}
static bool check_alpha_pass(Base *base)
@@ -402,13 +405,13 @@ static const float cosval[CIRCLE_RESOL] = {
static void draw_xyz_wire(const float c[3], float size, int axis)
{
- float v1[3] = {0.f, 0.f, 0.f}, v2[3] = {0.f, 0.f, 0.f};
+ float v1[3] = {0.0f, 0.0f, 0.0f}, v2[3] = {0.0f, 0.0f, 0.0f};
float dim = size * 0.1f;
float dx[3], dy[3], dz[3];
- dx[0] = dim; dx[1] = 0.f; dx[2] = 0.f;
- dy[0] = 0.f; dy[1] = dim; dy[2] = 0.f;
- dz[0] = 0.f; dz[1] = 0.f; dz[2] = dim;
+ dx[0] = dim; dx[1] = 0.0f; dx[2] = 0.0f;
+ dy[0] = 0.0f; dy[1] = dim; dy[2] = 0.0f;
+ dz[0] = 0.0f; dz[1] = 0.0f; dz[2] = dim;
switch (axis) {
case 0: /* x axis */
@@ -424,7 +427,7 @@ static void draw_xyz_wire(const float c[3], float size, int axis)
glVertex3fv(v2);
/* top left to bottom right */
- mul_v3_fl(dy, 2.f);
+ mul_v3_fl(dy, 2.0f);
add_v3_v3(v1, dy);
sub_v3_v3(v2, dy);
@@ -447,7 +450,7 @@ static void draw_xyz_wire(const float c[3], float size, int axis)
glVertex3fv(v2);
/* top left to center */
- mul_v3_fl(dy, 2.f);
+ mul_v3_fl(dy, 2.0f);
add_v3_v3(v1, dy);
copy_v3_v3(v2, c);
@@ -465,12 +468,12 @@ static void draw_xyz_wire(const float c[3], float size, int axis)
glVertex3fv(v1);
- mul_v3_fl(dx, 2.f);
+ mul_v3_fl(dx, 2.0f);
add_v3_v3(v1, dx);
glVertex3fv(v1);
- mul_v3_fl(dz, 2.f);
+ mul_v3_fl(dz, 2.0f);
sub_v3_v3(v1, dx);
sub_v3_v3(v1, dz);
@@ -483,7 +486,6 @@ static void draw_xyz_wire(const float c[3], float size, int axis)
glEnd();
break;
}
-
}
void drawaxes(float size, char drawtype)
@@ -597,10 +599,10 @@ void drawaxes(float size, char drawtype)
}
-/* Function to draw an Image on a empty Object */
+/* Function to draw an Image on an empty Object */
static void draw_empty_image(Object *ob, const short dflag, const unsigned char ob_wire_col[4])
{
- Image *ima = (Image *)ob->data;
+ Image *ima = ob->data;
ImBuf *ibuf = BKE_image_acquire_ibuf(ima, ob->iuser, NULL);
float scale, ofs_x, ofs_y, sca_x, sca_y;
@@ -640,16 +642,13 @@ static void draw_empty_image(Object *ob, const short dflag, const unsigned char
sca_y = 1.0f;
}
- /* Calculate the scale center based on objects origin */
+ /* Calculate the scale center based on object's origin */
ofs_x = ob->ima_ofs[0] * ima_x;
ofs_y = ob->ima_ofs[1] * ima_y;
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
- /* Make sure we are drawing at the origin */
- glTranslatef(0.0f, 0.0f, 0.0f);
-
/* Calculate Image scale */
scale = (ob->empty_drawsize / max_ff((float)ima_x * sca_x, (float)ima_y * sca_y));
@@ -943,7 +942,7 @@ void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, bool depth_write, flo
/* ******************** primitive drawing ******************* */
-/* draws a cube on given the scaling of the cube, assuming that
+/* draws a cube given the scaling of the cube, assuming that
* all required matrices have been set (used for drawing empties)
*/
static void drawcube_size(float size)
@@ -1025,8 +1024,6 @@ static void drawshadbuflimits(Lamp *la, float mat[4][4])
glPointSize(1.0);
}
-
-
static void spotvolume(float lvec[3], float vvec[3], const float inp)
{
/* camera is at 0,0,0 */
@@ -1035,8 +1032,8 @@ static void spotvolume(float lvec[3], float vvec[3], const float inp)
normalize_v3(lvec);
normalize_v3(vvec); /* is this the correct vector ? */
- cross_v3_v3v3(temp, vvec, lvec); /* equation for a plane through vvec en lvec */
- cross_v3_v3v3(plane, lvec, temp); /* a plane perpendicular to this, parrallel with lvec */
+ cross_v3_v3v3(temp, vvec, lvec); /* equation for a plane through vvec and lvec */
+ cross_v3_v3v3(plane, lvec, temp); /* a plane perpendicular to this, parallel with lvec */
/* vectors are exactly aligned, use the X axis, this is arbitrary */
if (normalize_v3(plane) == 0.0f)
@@ -1149,6 +1146,52 @@ static void draw_transp_spot_volume(Lamp *la, float x, float z)
glCullFace(GL_BACK);
}
+#ifdef WITH_GAMEENGINE
+static void draw_transp_sun_volume(Lamp *la)
+{
+ float box[8][3];
+
+ /* construct box */
+ box[0][0] = box[1][0] = box[2][0] = box[3][0] = -la->shadow_frustum_size;
+ box[4][0] = box[5][0] = box[6][0] = box[7][0] = +la->shadow_frustum_size;
+ box[0][1] = box[1][1] = box[4][1] = box[5][1] = -la->shadow_frustum_size;
+ box[2][1] = box[3][1] = box[6][1] = box[7][1] = +la->shadow_frustum_size;
+ box[0][2] = box[3][2] = box[4][2] = box[7][2] = -la->clipend;
+ box[1][2] = box[2][2] = box[5][2] = box[6][2] = -la->clipsta;
+
+ /* draw edges */
+ draw_box(box, false);
+
+ /* draw faces */
+ glEnable(GL_CULL_FACE);
+ glEnable(GL_BLEND);
+ glDepthMask(0);
+
+ /* draw backside darkening */
+ glCullFace(GL_FRONT);
+
+ glBlendFunc(GL_ZERO, GL_SRC_ALPHA);
+ glColor4f(0.0f, 0.0f, 0.0f, 0.4f);
+
+ draw_box(box, true);
+
+ /* draw front side lighting */
+ glCullFace(GL_BACK);
+
+ glBlendFunc(GL_ONE, GL_ONE);
+ glColor4f(0.2f, 0.2f, 0.2f, 1.0f);
+
+ draw_box(box, true);
+
+ /* restore state */
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glDisable(GL_BLEND);
+ glDepthMask(1);
+ glDisable(GL_CULL_FACE);
+ glCullFace(GL_BACK);
+}
+#endif
+
static void drawlamp(View3D *v3d, RegionView3D *rv3d, Base *base,
const char dt, const short dflag, const unsigned char ob_wire_col[4], const bool is_obact)
{
@@ -1161,7 +1204,7 @@ static void drawlamp(View3D *v3d, RegionView3D *rv3d, Base *base,
unsigned char curcol[4];
unsigned char col[4];
- /* cone can't be drawn for duplicated lamps, because duplilist would be freed to */
+ /* cone can't be drawn for duplicated lamps, because duplilist would be freed */
/* the moment of view3d_draw_transp() call */
const bool is_view = (rv3d->persp == RV3D_CAMOB && v3d->camera == base->object);
const bool drawcone = ((dt > OB_WIRE) &&
@@ -1171,7 +1214,22 @@ static void drawlamp(View3D *v3d, RegionView3D *rv3d, Base *base,
!(base->flag & OB_FROMDUPLI) &&
!is_view);
- if (drawcone && !v3d->transp) {
+#ifdef WITH_GAMEENGINE
+ const bool drawshadowbox = (
+ (rv3d->rflag & RV3D_IS_GAME_ENGINE) &&
+ (dt > OB_WIRE) &&
+ !(G.f & G_PICKSEL) &&
+ (la->type == LA_SUN) &&
+ ((la->mode & LA_SHAD_BUF) ||
+ (la->mode & LA_SHAD_RAY)) &&
+ (la->mode & LA_SHOW_SHADOW_BOX) &&
+ !(base->flag & OB_FROMDUPLI) &&
+ !is_view);
+#else
+ const bool drawshadowbox = false;
+#endif
+
+ if ((drawcone || drawshadowbox) && !v3d->transp) {
/* in this case we need to draw delayed */
ED_view3d_after_add(&v3d->afterdraw_transp, base, dflag);
return;
@@ -1310,7 +1368,7 @@ static void drawlamp(View3D *v3d, RegionView3D *rv3d, Base *base,
x *= y;
/* draw the circle/square at the end of the cone */
- glTranslatef(0.0, 0.0, x);
+ glTranslatef(0.0, 0.0, x);
if (la->mode & LA_SQUARE) {
float tvec[3];
float z_abs = fabsf(z);
@@ -1416,6 +1474,13 @@ static void drawlamp(View3D *v3d, RegionView3D *rv3d, Base *base,
dir = -dir;
}
}
+
+#ifdef WITH_GAMEENGINE
+ if (drawshadowbox) {
+ draw_transp_sun_volume(la);
+ }
+#endif
+
}
else if (la->type == LA_AREA) {
setlinestyle(3);
@@ -1499,10 +1564,10 @@ static void draw_limit_line(float sta, float end, const short dflag, unsigned in
static void draw_focus_cross(float dist, float size)
{
glBegin(GL_LINES);
- glVertex3f(-size, 0.f, -dist);
- glVertex3f(size, 0.f, -dist);
- glVertex3f(0.f, -size, -dist);
- glVertex3f(0.f, size, -dist);
+ glVertex3f(-size, 0.0f, -dist);
+ glVertex3f(size, 0.0f, -dist);
+ glVertex3f(0.0f, -size, -dist);
+ glVertex3f(0.0f, size, -dist);
glEnd();
}
@@ -1555,8 +1620,7 @@ static void draw_viewport_object_reconstruction(Scene *scene, Base *base, View3D
BKE_tracking_get_camera_object_matrix(scene, base->object, mat);
/* we're compensating camera size for bundles size,
- * to make it so bundles are always displayed with the same size
- */
+ * to make it so bundles are always displayed with the same size */
copy_v3_v3(camera_size, base->object->size);
if ((tracking_object->flag & TRACKING_OBJECT_CAMERA) == 0)
mul_v3_fl(camera_size, tracking_object->scale);
@@ -1624,7 +1688,7 @@ static void draw_viewport_object_reconstruction(Scene *scene, Base *base, View3D
glColor3ubv(ob_wire_col);
}
- glLineWidth(2.f);
+ glLineWidth(2.0f);
glDisable(GL_LIGHTING);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
@@ -1632,7 +1696,7 @@ static void draw_viewport_object_reconstruction(Scene *scene, Base *base, View3D
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glEnable(GL_LIGHTING);
- glLineWidth(1.f);
+ glLineWidth(1.0f);
}
if ((dflag & DRAW_CONSTCOLOR) == 0) {
@@ -1746,6 +1810,238 @@ static void draw_viewport_reconstruction(Scene *scene, Base *base, View3D *v3d,
GPU_select_load_id(base->selcol);
}
+static void drawcamera_volume(float near_plane[4][3], float far_plane[4][3], const GLenum mode)
+{
+ glBegin(mode);
+ glVertex3fv(near_plane[0]);
+ glVertex3fv(far_plane[0]);
+ glVertex3fv(far_plane[1]);
+ glVertex3fv(near_plane[1]);
+ glEnd();
+
+ glBegin(mode);
+ glVertex3fv(near_plane[1]);
+ glVertex3fv(far_plane[1]);
+ glVertex3fv(far_plane[2]);
+ glVertex3fv(near_plane[2]);
+ glEnd();
+
+ glBegin(mode);
+ glVertex3fv(near_plane[2]);
+ glVertex3fv(near_plane[1]);
+ glVertex3fv(far_plane[1]);
+ glVertex3fv(far_plane[2]);
+ glEnd();
+
+ glBegin(mode);
+ glVertex3fv(far_plane[0]);
+ glVertex3fv(near_plane[0]);
+ glVertex3fv(near_plane[3]);
+ glVertex3fv(far_plane[3]);
+ glEnd();
+}
+
+/* camera frame */
+static void drawcamera_frame(float vec[4][3], const GLenum mode)
+{
+ glBegin(mode);
+ glVertex3fv(vec[0]);
+ glVertex3fv(vec[1]);
+ glVertex3fv(vec[2]);
+ glVertex3fv(vec[3]);
+ glEnd();
+}
+
+/* center point to camera frame */
+static void drawcamera_framelines(float vec[4][3], float origin[3])
+{
+ glBegin(GL_LINE_STRIP);
+ glVertex3fv(vec[1]);
+ glVertex3fv(origin);
+ glVertex3fv(vec[0]);
+ glVertex3fv(vec[3]);
+ glVertex3fv(origin);
+ glVertex3fv(vec[2]);
+ glEnd();
+}
+
+static bool drawcamera_is_stereo3d(Scene *scene, View3D *v3d, Object *ob)
+{
+ return (ob == v3d->camera) &&
+ (scene->r.scemode & R_MULTIVIEW) != 0 &&
+ (v3d->stereo3d_flag);
+}
+
+static void drawcamera_stereo3d(
+ Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, const Camera *cam,
+ float vec[4][3], float drawsize, const float scale[3])
+{
+ int i, j;
+ float obmat[4][4];
+ float vec_lr[2][4][3];
+ const float fac = (cam->stereo.pivot == CAM_S3D_PIVOT_CENTER) ? 2.0f : 1.0f;
+ float origin[2][3] = {{0}};
+ float tvec[3];
+ const Camera *cam_lr[2];
+ const char *names[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME};
+
+ const bool is_stereo3d_cameras = (v3d->stereo3d_flag & V3D_S3D_DISPCAMERAS) && (scene->r.views_format == SCE_VIEWS_FORMAT_STEREO_3D);
+ const bool is_stereo3d_plane = (v3d->stereo3d_flag & V3D_S3D_DISPPLANE) && (scene->r.views_format == SCE_VIEWS_FORMAT_STEREO_3D);
+ const bool is_stereo3d_volume = (v3d->stereo3d_flag & V3D_S3D_DISPVOLUME);
+
+ zero_v3(tvec);
+
+ glPushMatrix();
+
+ for (i = 0; i < 2; i++) {
+ ob = BKE_camera_multiview_render(scene, ob, names[i]);
+ cam_lr[i] = ob->data;
+
+ glLoadMatrixf(rv3d->viewmat);
+ BKE_camera_multiview_model_matrix(&scene->r, ob, names[i], obmat);
+ glMultMatrixf(obmat);
+
+ copy_m3_m3(vec_lr[i], vec);
+ copy_v3_v3(vec_lr[i][3], vec[3]);
+
+ if (cam->stereo.convergence_mode == CAM_S3D_OFFAXIS) {
+ const float shift_x =
+ ((BKE_camera_multiview_shift_x(&scene->r, ob, names[i]) - cam->shiftx) *
+ (drawsize * scale[0] * fac));
+
+ for (j = 0; j < 4; j++) {
+ vec_lr[i][j][0] += shift_x;
+ }
+ }
+
+ if (is_stereo3d_cameras) {
+ /* camera frame */
+ drawcamera_frame(vec_lr[i], GL_LINE_LOOP);
+
+ /* center point to camera frame */
+ drawcamera_framelines(vec_lr[i], tvec);
+ }
+
+ /* connecting line */
+ mul_m4_v3(obmat, origin[i]);
+
+ /* convergence plane */
+ if (is_stereo3d_plane || is_stereo3d_volume) {
+ for (j = 0; j < 4; j++) {
+ mul_m4_v3(obmat, vec_lr[i][j]);
+ }
+ }
+ }
+
+
+ /* the remaining drawing takes place in the view space */
+ glLoadMatrixf(rv3d->viewmat);
+
+ if (is_stereo3d_cameras) {
+ /* draw connecting lines */
+ glPushAttrib(GL_ENABLE_BIT);
+
+ glLineStipple(2, 0xAAAA);
+ glEnable(GL_LINE_STIPPLE);
+
+ glBegin(GL_LINES);
+ glVertex3fv(origin[0]);
+ glVertex3fv(origin[1]);
+ glEnd();
+ glPopAttrib();
+ }
+
+ /* draw convergence plane*/
+ if (is_stereo3d_plane) {
+ float axis_center[3], screen_center[3];
+ float world_plane[4][3];
+ float local_plane[4][3];
+ float offset;
+
+ mid_v3_v3v3(axis_center, origin[0], origin[1]);
+
+ for (i = 0; i < 4; i++) {
+ mid_v3_v3v3(world_plane[i], vec_lr[0][i], vec_lr[1][i]);
+ sub_v3_v3v3(local_plane[i], world_plane[i], axis_center);
+ }
+
+ mid_v3_v3v3(screen_center, world_plane[0], world_plane[2]);
+ offset = cam->stereo.convergence_distance / len_v3v3(screen_center, axis_center);
+
+ for (i = 0; i < 4; i++) {
+ mul_v3_fl(local_plane[i], offset);
+ add_v3_v3(local_plane[i], axis_center);
+ }
+
+ glColor3f(0.0f, 0.0f, 0.0f);
+
+ /* camera frame */
+ drawcamera_frame(local_plane, GL_LINE_LOOP);
+
+ if (v3d->stereo3d_convergence_alpha > 0.0f) {
+ glEnable(GL_BLEND);
+ glDepthMask(0); /* disable write in zbuffer, needed for nice transp */
+
+ glColor4f(0.0f, 0.0f, 0.0f, v3d->stereo3d_convergence_alpha);
+
+ drawcamera_frame(local_plane, GL_QUADS);
+
+ glDisable(GL_BLEND);
+ glDepthMask(1); /* restore write in zbuffer */
+ }
+ }
+
+ /* draw convergence plane*/
+ if (is_stereo3d_volume) {
+ float screen_center[3];
+ float near_plane[4][3], far_plane[4][3];
+ float offset;
+ int j;
+
+ for (i = 0; i < 2; i++) {
+ mid_v3_v3v3(screen_center, vec_lr[i][0], vec_lr[i][2]);
+
+ offset = len_v3v3(screen_center, origin[i]);
+
+ for (j = 0; j < 4; j++) {
+ sub_v3_v3v3(near_plane[j], vec_lr[i][j], origin[i]);
+ mul_v3_fl(near_plane[j], cam_lr[i]->clipsta / offset);
+ add_v3_v3(near_plane[j], origin[i]);
+
+ sub_v3_v3v3(far_plane[j], vec_lr[i][j], origin[i]);
+ mul_v3_fl(far_plane[j], cam_lr[i]->clipend / offset);
+ add_v3_v3(far_plane[j], origin[i]);
+ }
+
+ /* camera frame */
+ glColor3f(0.0f, 0.0f, 0.0f);
+
+ drawcamera_frame(near_plane, GL_LINE_LOOP);
+ drawcamera_frame(far_plane, GL_LINE_LOOP);
+ drawcamera_volume(near_plane, far_plane, GL_LINE_LOOP);
+
+ if (v3d->stereo3d_volume_alpha > 0.0f) {
+ glEnable(GL_BLEND);
+ glDepthMask(0); /* disable write in zbuffer, needed for nice transp */
+
+ if (i == 0)
+ glColor4f(0.0f, 1.0f, 1.0f, v3d->stereo3d_volume_alpha);
+ else
+ glColor4f(1.0f, 0.0f, 0.0f, v3d->stereo3d_volume_alpha);
+
+ drawcamera_frame(near_plane, GL_QUADS);
+ drawcamera_frame(far_plane, GL_QUADS);
+ drawcamera_volume(near_plane, far_plane, GL_QUADS);
+
+ glDisable(GL_BLEND);
+ glDepthMask(1); /* restore write in zbuffer */
+ }
+ }
+ }
+
+ glPopMatrix();
+}
+
/* flag similar to draw_object() */
static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
const short dflag, const unsigned char ob_wire_col[4])
@@ -1757,9 +2053,20 @@ static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base
float vec[4][3], asp[2], shift[2], scale[3];
int i;
float drawsize;
- const bool is_view = (rv3d->persp == RV3D_CAMOB && ob == v3d->camera);
MovieClip *clip = BKE_object_movieclip_get(scene, base->object, false);
+ const bool is_view = (rv3d->persp == RV3D_CAMOB && ob == v3d->camera);
+ const bool is_multiview = (scene->r.scemode & R_MULTIVIEW) != 0;
+ const bool is_stereo3d = drawcamera_is_stereo3d(scene, v3d, ob);
+ const bool is_stereo3d_view = (scene->r.views_format == SCE_VIEWS_FORMAT_STEREO_3D);
+ const bool is_stereo3d_cameras = (ob == scene->camera) &&
+ is_multiview &&
+ is_stereo3d_view &&
+ (v3d->stereo3d_flag & V3D_S3D_DISPCAMERAS);
+ const bool is_selection_camera_stereo = (G.f & G_PICKSEL) &&
+ is_view && is_multiview &&
+ is_stereo3d_view;
+
/* draw data for movie clip set as active for scene */
if (clip) {
draw_viewport_reconstruction(scene, base, v3d, clip, dflag, ob_wire_col, false);
@@ -1785,9 +2092,17 @@ static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base
cam = ob->data;
- scale[0] = 1.0f / len_v3(ob->obmat[0]);
- scale[1] = 1.0f / len_v3(ob->obmat[1]);
- scale[2] = 1.0f / len_v3(ob->obmat[2]);
+ /* BKE_camera_multiview_model_matrix already accounts for scale, don't do it here */
+ if (is_selection_camera_stereo) {
+ scale[0] = 1.0f;
+ scale[1] = 1.0f;
+ scale[2] = 1.0f;
+ }
+ else {
+ scale[0] = 1.0f / len_v3(ob->obmat[0]);
+ scale[1] = 1.0f / len_v3(ob->obmat[1]);
+ scale[2] = 1.0f / len_v3(ob->obmat[2]);
+ }
BKE_camera_view_frame_ex(scene, cam, cam->drawsize, is_view, scale,
asp, shift, &drawsize, vec);
@@ -1796,12 +2111,24 @@ static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base
glDisable(GL_CULL_FACE);
/* camera frame */
- glBegin(GL_LINE_LOOP);
- glVertex3fv(vec[0]);
- glVertex3fv(vec[1]);
- glVertex3fv(vec[2]);
- glVertex3fv(vec[3]);
- glEnd();
+ if (!is_stereo3d_cameras) {
+ /* make sure selection uses the same matrix for camera as the one used while viewing */
+ if (is_selection_camera_stereo) {
+ float obmat[4][4];
+ bool is_left = v3d->multiview_eye == STEREO_LEFT_ID;
+
+ glPushMatrix();
+ glLoadMatrixf(rv3d->viewmat);
+ BKE_camera_multiview_model_matrix(&scene->r, ob, is_left ? STEREO_LEFT_NAME : STEREO_RIGHT_NAME, obmat);
+ glMultMatrixf(obmat);
+
+ drawcamera_frame(vec, GL_LINE_LOOP);
+ glPopMatrix();
+ }
+ else {
+ drawcamera_frame(vec, GL_LINE_LOOP);
+ }
+ }
if (is_view)
return;
@@ -1809,20 +2136,12 @@ static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base
zero_v3(tvec);
/* center point to camera frame */
- glBegin(GL_LINE_STRIP);
- glVertex3fv(vec[1]);
- glVertex3fv(tvec);
- glVertex3fv(vec[0]);
- glVertex3fv(vec[3]);
- glVertex3fv(tvec);
- glVertex3fv(vec[2]);
- glEnd();
-
+ if (!is_stereo3d_cameras)
+ drawcamera_framelines(vec, tvec);
/* arrow on top */
tvec[2] = vec[1][2]; /* copy the depth */
-
/* draw an outline arrow for inactive cameras and filled
* for active cameras. We actually draw both outline+filled
* for active cameras so the wire can be seen side-on */
@@ -1872,14 +2191,17 @@ static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base
glPopMatrix();
}
}
+
+ /* stereo cameras drawing */
+ if (is_stereo3d) {
+ drawcamera_stereo3d(scene, v3d, rv3d, ob, cam, vec, drawsize, scale);
+ }
}
/* flag similar to draw_object() */
static void drawspeaker(Scene *UNUSED(scene), View3D *UNUSED(v3d), RegionView3D *UNUSED(rv3d),
Object *UNUSED(ob), int UNUSED(flag))
{
- //Speaker *spk = ob->data;
-
float vec[3];
int i, j;
@@ -1990,9 +2312,9 @@ static void ensure_curve_cache(Scene *scene, Object *object)
* here, we also need to check whether display list is
* empty or not.
*
- * The trick below tries to optimie calls to displist
+ * The trick below tries to optimize calls to displist
* creation for cases curve is empty. Meaning, if the curve
- * is empty (without splies) bevel list would also be empty.
+ * is empty (without splines) bevel list would also be empty.
* And the thing is, render thread always leaves bevel list
* in a proper state. So if bevel list is here and display
* list is not we need to make display list.
@@ -2270,8 +2592,7 @@ static void draw_dm_verts__mapFunc(void *userData, int index, const float co[3],
BMVert *eve = BM_vert_at_index(data->bm, index);
if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN) && BM_elem_flag_test(eve, BM_ELEM_SELECT) == data->sel) {
- /* skin nodes: draw a red circle around the root
- * node(s) */
+ /* skin nodes: draw a red circle around the root node(s) */
if (data->cd_vskin_offset != -1) {
const MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, data->cd_vskin_offset);
if (vs->flag & MVERT_SKIN_ROOT) {
@@ -2337,7 +2658,6 @@ static void draw_dm_verts(BMEditMesh *em, DerivedMesh *dm, const char sel, BMVer
static DMDrawOption draw_dm_edges_sel__setDrawOptions(void *userData, int index)
{
BMEdge *eed;
- //unsigned char **cols = userData, *col;
drawDMEdgesSel_userData *data = userData;
unsigned char *col;
@@ -2354,7 +2674,7 @@ static DMDrawOption draw_dm_edges_sel__setDrawOptions(void *userData, int index)
else {
col = data->baseCol;
}
- /* no alpha, this is used so a transparent color can disable drawing unselected edges in editmode */
+ /* no alpha, this is used so a transparent color can disable drawing unselected edges in editmode */
if (col[3] == 0)
return DM_DRAW_OPTION_SKIP;
@@ -2751,7 +3071,7 @@ static void draw_dm_faces_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *ba
data.orig_index_mf_to_mpoly = data.orig_index_mp_to_orig = NULL;
}
- dm->drawMappedFaces(dm, draw_dm_faces_sel__setDrawOptions, GPU_enable_material, draw_dm_faces_sel__compareDrawOptions, &data, 0);
+ dm->drawMappedFaces(dm, draw_dm_faces_sel__setDrawOptions, NULL, draw_dm_faces_sel__compareDrawOptions, &data, 0);
}
static DMDrawOption draw_dm_creases__setDrawOptions(void *userData, int index)
@@ -3044,7 +3364,7 @@ static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMe
}
BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
- /* draw selected edges, or edges next to selected verts while draging */
+ /* draw selected edges, or edges next to selected verts while dragging */
if (BM_elem_flag_test(eed, BM_ELEM_SELECT) ||
(do_moving && (BM_elem_flag_test(eed->v1, BM_ELEM_SELECT) ||
BM_elem_flag_test(eed->v2, BM_ELEM_SELECT))))
@@ -3082,7 +3402,7 @@ static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMe
unit->system, B_UNIT_LENGTH, do_split, false);
}
else {
- numstr_len = BLI_snprintf(numstr, sizeof(numstr), conv_float, len_v3v3(v1, v2));
+ numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), conv_float, len_v3v3(v1, v2));
}
view3d_cached_text_draw_add(vmid, numstr, numstr_len, 0, txt_flag, col);
@@ -3101,17 +3421,15 @@ static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMe
BM_mesh_elem_index_ensure(em->bm, BM_VERT | BM_FACE);
}
- // invert_m4_m4(ob->imat, ob->obmat); // this is already called
-
BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
BMLoop *l_a, *l_b;
if (BM_edge_loop_pair(eed, &l_a, &l_b)) {
- /* draw selected edges, or edges next to selected verts while draging */
+ /* draw selected edges, or edges next to selected verts while dragging */
if (BM_elem_flag_test(eed, BM_ELEM_SELECT) ||
(do_moving && (BM_elem_flag_test(eed->v1, BM_ELEM_SELECT) ||
BM_elem_flag_test(eed->v2, BM_ELEM_SELECT) ||
- /* special case, this is useful to show when vertes connected to this edge via a
- * face are being transformed */
+ /* special case, this is useful to show when verts connected to
+ * this edge via a face are being transformed */
BM_elem_flag_test(l_a->next->next->v, BM_ELEM_SELECT) ||
BM_elem_flag_test(l_a->prev->v, BM_ELEM_SELECT) ||
BM_elem_flag_test(l_b->next->next->v, BM_ELEM_SELECT) ||
@@ -3161,7 +3479,7 @@ static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMe
angle = angle_normalized_v3v3(no_a, no_b);
- numstr_len = BLI_snprintf(numstr, sizeof(numstr), "%.3f", is_rad ? angle : RAD2DEGF(angle));
+ numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%.3f", is_rad ? angle : RAD2DEGF(angle));
view3d_cached_text_draw_add(vmid, numstr, numstr_len, 0, txt_flag, col);
}
@@ -3186,7 +3504,7 @@ static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMe
3, unit->system, B_UNIT_AREA, do_split, false); \
} \
else { \
- numstr_len = BLI_snprintf(numstr, sizeof(numstr), conv_float, area); \
+ numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), conv_float, area); \
} \
view3d_cached_text_draw_add(vmid, numstr, numstr_len, 0, txt_flag, col); \
} (void)0
@@ -3304,7 +3622,7 @@ static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMe
angle = angle_v3v3v3(v1, v2, v3);
- numstr_len = BLI_snprintf(numstr, sizeof(numstr), "%.3f", is_rad ? angle : RAD2DEGF(angle));
+ numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%.3f", is_rad ? angle : RAD2DEGF(angle));
interp_v3_v3v3(fvec, vmid, v2_local, 0.8f);
view3d_cached_text_draw_add(fvec, numstr, numstr_len, 0, txt_flag, col);
}
@@ -3335,7 +3653,7 @@ static void draw_em_indices(BMEditMesh *em)
UI_GetThemeColor3ubv(TH_DRAWEXTRA_FACEANG, col);
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
- numstr_len = BLI_snprintf(numstr, sizeof(numstr), "%d", i);
+ numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%d", i);
view3d_cached_text_draw_add(v->co, numstr, numstr_len, 0, txt_flag, col);
}
i++;
@@ -3347,7 +3665,7 @@ static void draw_em_indices(BMEditMesh *em)
UI_GetThemeColor3ubv(TH_DRAWEXTRA_EDGELEN, col);
BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
- numstr_len = BLI_snprintf(numstr, sizeof(numstr), "%d", i);
+ numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%d", i);
mid_v3_v3v3(pos, e->v1->co, e->v2->co);
view3d_cached_text_draw_add(pos, numstr, numstr_len, 0, txt_flag, col);
}
@@ -3361,7 +3679,7 @@ static void draw_em_indices(BMEditMesh *em)
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
BM_face_calc_center_mean(f, pos);
- numstr_len = BLI_snprintf(numstr, sizeof(numstr), "%d", i);
+ numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%d", i);
view3d_cached_text_draw_add(pos, numstr, numstr_len, 0, txt_flag, col);
}
i++;
@@ -3417,7 +3735,7 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d,
if (em->bm->selected.last) {
BMEditSelection *ese = em->bm->selected.last;
- /* face is handeled above */
+ /* face is handled above */
#if 0
if (ese->type == BM_FACE) {
efa_act = (BMFace *)ese->data;
@@ -3532,11 +3850,14 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d,
}
else if (efa_act) {
/* even if draw faces is off it would be nice to draw the stipple face
- * Make all other faces zero alpha except for the active
- * */
- /* col4 is only used by WITH_FREESTYLE, but keeping it here spares some #ifdef's... */
- unsigned char col1[4], col2[4], col3[4], col4[4];
- col1[3] = col2[3] = col4[3] = 0; /* don't draw */
+ * Make all other faces zero alpha except for the active */
+ unsigned char col1[4], col2[4], col3[4];
+#ifdef WITH_FREESTYLE
+ unsigned char col4[4];
+ col4[3] = 0; /* don't draw */
+#endif
+ col1[3] = col2[3] = 0; /* don't draw */
+
UI_GetThemeColor4ubv(TH_EDITMESH_ACTIVE, col3);
glEnable(GL_BLEND);
@@ -3550,7 +3871,6 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d,
glDisable(GL_BLEND);
glDepthMask(1); /* restore write in zbuffer */
-
}
/* here starts all fancy draw-extra over */
@@ -3691,7 +4011,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
#endif
Mesh *me = ob->data;
eWireDrawMode draw_wire = OBDRAW_WIRE_OFF;
- int /* totvert,*/ totedge, totface;
+ bool /* no_verts,*/ no_edges, no_faces;
DerivedMesh *dm = mesh_get_derived_final(scene, ob, scene->customdata_mask);
const bool is_obact = (ob == OBACT);
int draw_flags = (is_obact && BKE_paint_select_face_test(ob)) ? DRAW_FACE_SELECT : 0;
@@ -3714,9 +4034,9 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
draw_wire = OBDRAW_WIRE_ON_DEPTH; /* draw wire after solid using zoffset and depth buffer adjusment */
}
- /* totvert = dm->getNumVerts(dm); */ /*UNUSED*/
- totedge = dm->getNumEdges(dm);
- totface = dm->getNumTessFaces(dm);
+ /* check polys instead of tessfaces because of dyntopo where tessfaces don't exist */
+ no_edges = (dm->getNumEdges(dm) == 0);
+ no_faces = (dm->getNumPolys(dm) == 0);
/* vertexpaint, faceselect wants this, but it doesnt work for shaded? */
glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);
@@ -3725,15 +4045,15 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
if (((v3d->flag2 & V3D_RENDER_OVERRIDE) && v3d->drawtype >= OB_WIRE) == 0)
draw_bounding_volume(ob, ob->boundtype);
}
- else if ((totface == 0 && totedge == 0) ||
+ else if ((no_faces && no_edges) ||
((!is_obact || (ob->mode == OB_MODE_OBJECT)) && object_is_halo(scene, ob)))
{
glPointSize(1.5);
dm->drawVerts(dm);
glPointSize(1.0);
}
- else if (dt == OB_WIRE || totface == 0) {
- draw_wire = OBDRAW_WIRE_ON; /* draw wire only, no depth buffer stuff */
+ else if ((dt == OB_WIRE) || no_faces) {
+ draw_wire = OBDRAW_WIRE_ON; /* draw wire only, no depth buffer stuff */
}
else if (((is_obact && ob->mode & OB_MODE_TEXTURE_PAINT)) ||
check_object_draw_texture(scene, v3d, dt))
@@ -3775,8 +4095,10 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
else
dm->drawFacesGLSL(dm, GPU_enable_material);
-// if (BKE_bproperty_object_get(ob, "Text"))
-// XXX draw_mesh_text(ob, 1);
+#if 0 /* XXX */
+ if (BKE_bproperty_object_get(ob, "Text"))
+ draw_mesh_text(ob, 1);
+#endif
GPU_disable_material();
glFrontFace(GL_CCW);
@@ -3894,7 +4216,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
}
if ((draw_wire != OBDRAW_WIRE_OFF) && /* draw extra wire */
- /* when overriding with render only, don't bother */
+ /* when overriding with render only, don't bother */
(((v3d->flag2 & V3D_RENDER_OVERRIDE) && v3d->drawtype >= OB_SOLID) == 0))
{
/* When using wireframe object draw in particle edit mode
@@ -3924,7 +4246,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
glDepthMask(0); /* disable write in zbuffer, selected edge wires show better */
}
- dm->drawEdges(dm, (dt == OB_WIRE || totface == 0), (ob->dtx & OB_DRAW_ALL_EDGES) != 0);
+ dm->drawEdges(dm, ((dt == OB_WIRE) || no_faces), (ob->dtx & OB_DRAW_ALL_EDGES) != 0);
if (dt != OB_WIRE && (draw_wire == OBDRAW_WIRE_ON_DEPTH)) {
glDepthMask(1);
@@ -3933,7 +4255,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
}
if (is_obact && BKE_paint_select_vert_test(ob)) {
- const int use_depth = (v3d->flag & V3D_ZBUF_SELECT);
+ const bool use_depth = (v3d->flag & V3D_ZBUF_SELECT) != 0;
glColor3f(0.0f, 0.0f, 0.0f);
glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE));
@@ -3948,7 +4270,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
dm->release(dm);
}
-/* returns 1 if nothing was drawn, for detecting to draw an object center */
+/* returns true if nothing was drawn, for detecting to draw an object center */
static bool draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base,
const char dt, const unsigned char ob_wire_col[4], const short dflag)
{
@@ -3992,7 +4314,9 @@ static bool draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3
scene->customdata_mask);
DM_update_materials(finalDM, ob);
- DM_update_materials(cageDM, ob);
+ if (cageDM != finalDM) {
+ DM_update_materials(cageDM, ob);
+ }
if (dt > OB_WIRE) {
const bool glsl = draw_glsl_material(scene, ob, v3d, dt);
@@ -4328,7 +4652,7 @@ static bool drawCurveDerivedMesh(Scene *scene, View3D *v3d, RegionView3D *rv3d,
/**
* Only called by #drawDispList
- * \return 1 when nothing was drawn
+ * \return true when nothing was drawn
*/
static bool drawDispList_nobackface(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
const char dt, const short dflag, const unsigned char ob_wire_col[4])
@@ -4600,7 +4924,7 @@ static void draw_particle(ParticleKey *state, int draw_as, short draw, float pix
copy_v3_v3(pdd->vd, vec2); pdd->vd += 3;
vec[2] = 2.0f * pixsize;
- vec[0] = vec[1] = 0.0;
+ vec[0] = vec[1] = 0.0f;
mul_qt_v3(state->rot, vec);
if (draw_as == PART_DRAW_AXIS) {
copy_v3_v3(vec2, state->co);
@@ -4683,7 +5007,7 @@ static void draw_particle_data(ParticleSystem *psys, RegionView3D *rv3d,
if (psys->parent)
mul_m4_v3(psys->parent->obmat, state->co);
- /* create actiual particle data */
+ /* create actual particle data */
if (draw_as == PART_DRAW_BB) {
bb->offset[0] = part->bb_offset[0];
bb->offset[1] = part->bb_offset[1];
@@ -4708,16 +5032,17 @@ static void draw_particle_data(ParticleSystem *psys, RegionView3D *rv3d,
draw_particle(state, draw_as, part->draw, pixsize, imat, part->draw_line, bb, pdd);
}
-/* unified drawing of all new particle systems draw types except dupli ob & group */
-/* mostly tries to use vertex arrays for speed */
-
-/* 1. check that everything is ok & updated */
-/* 2. start initializing things */
-/* 3. initialize according to draw type */
-/* 4. allocate drawing data arrays */
-/* 5. start filling the arrays */
-/* 6. draw the arrays */
-/* 7. clean up */
+/* unified drawing of all new particle systems draw types except dupli ob & group
+ * mostly tries to use vertex arrays for speed
+ *
+ * 1. check that everything is ok & updated
+ * 2. start initializing things
+ * 3. initialize according to draw type
+ * 4. allocate drawing data arrays
+ * 5. start filling the arrays
+ * 6. draw the arrays
+ * 7. clean up
+ */
static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv3d,
Base *base, ParticleSystem *psys,
const char ob_dt, const short dflag)
@@ -4762,6 +5087,12 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
if (draw_as == PART_DRAW_NOT)
return;
+ /* prepare curvemapping tables */
+ if ((psys->part->child_flag & PART_CHILD_USE_CLUMP_CURVE) && psys->part->clumpcurve)
+ curvemapping_changed_all(psys->part->clumpcurve);
+ if ((psys->part->child_flag & PART_CHILD_USE_ROUGH_CURVE) && psys->part->roughcurve)
+ curvemapping_changed_all(psys->part->roughcurve);
+
/* 2. */
sim.scene = scene;
sim.ob = ob;
@@ -4907,7 +5238,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
int create_ndata = 0;
if (!pdd)
- pdd = psys->pdd = MEM_callocN(sizeof(ParticleDrawData), "ParticlDrawData");
+ pdd = psys->pdd = MEM_callocN(sizeof(ParticleDrawData), "ParticleDrawData");
if (part->draw_as == PART_DRAW_REND && part->trail_count > 1) {
tot_vec_size *= part->trail_count;
@@ -5010,7 +5341,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
BLI_assert(0);
break;
}
- CLAMP(intensity, 0.f, 1.f);
+ CLAMP(intensity, 0.0f, 1.0f);
weight_to_rgb(ma_col, intensity);
}
}
@@ -5069,8 +5400,8 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
}
if (drawn) {
- /* additional things to draw for each particle */
- /* (velocity, size and number) */
+ /* additional things to draw for each particle
+ * (velocity, size and number) */
if ((part->draw & PART_DRAW_VEL) && pdd && pdd->vedata) {
copy_v3_v3(pdd->ved, state.co);
pdd->ved += 3;
@@ -5098,21 +5429,21 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
if (part->draw & PART_DRAW_NUM) {
if (a < totpart && (part->draw & PART_DRAW_HEALTH) && (part->phystype == PART_PHYS_BOIDS)) {
- numstr_len = BLI_snprintf(val_pos, sizeof(numstr), "%d:%.2f", a, pa_health);
+ numstr_len = BLI_snprintf_rlen(val_pos, sizeof(numstr), "%d:%.2f", a, pa_health);
}
else {
- numstr_len = BLI_snprintf(val_pos, sizeof(numstr), "%d", a);
+ numstr_len = BLI_snprintf_rlen(val_pos, sizeof(numstr), "%d", a);
}
}
else {
if (a < totpart && (part->draw & PART_DRAW_HEALTH) && (part->phystype == PART_PHYS_BOIDS)) {
- numstr_len = BLI_snprintf(val_pos, sizeof(numstr), "%.2f", pa_health);
+ numstr_len = BLI_snprintf_rlen(val_pos, sizeof(numstr), "%.2f", pa_health);
}
}
if (numstr[0]) {
- /* in path drawing state.co is the end point */
- /* use worldspace beause object matrix is already applied */
+ /* in path drawing state.co is the end point
+ * use worldspace because object matrix is already applied */
mul_v3_m4v3(vec_txt, ob->imat, state.co);
view3d_cached_text_draw_add(vec_txt, numstr, numstr_len,
10, V3D_CACHE_TEXT_WORLDSPACE | V3D_CACHE_TEXT_ASCII, tcol);
@@ -5129,7 +5460,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
if (draw_as == PART_DRAW_PATH) {
ParticleCacheKey **cache, *path;
- float /* *cd2=NULL, */ /* UNUSED */ *cdata2 = NULL;
+ float *cdata2 = NULL;
/* setup gl flags */
if (1) { //ob_dt > OB_WIRE) {
@@ -5193,11 +5524,13 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
HairKey *hkey = pa->hair;
glVertexPointer(3, GL_FLOAT, sizeof(HairKey), hkey->world_co);
-
- // XXX use proper theme color here
-// UI_ThemeColor(TH_NORMAL);
+
+#if 0 /* XXX use proper theme color here */
+ UI_ThemeColor(TH_NORMAL);
+#else
glColor3f(0.58f, 0.67f, 1.0f);
-
+#endif
+
glDrawArrays(GL_LINE_STRIP, 0, pa->totkey);
}
}
@@ -5274,22 +5607,22 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
UI_ThemeColorShadeAlpha(TH_WIRE, 0, -100);
glEnable(GL_BLEND);
glBegin(GL_LINES);
- for (i = 1; i < res[0]-1; ++i) {
- float f = interpf(b[0], a[0], (float)i / (float)(res[0]-1));
+ for (i = 1; i < res[0] - 1; ++i) {
+ float f = interpf(b[0], a[0], (float)i / (float)(res[0] - 1));
glVertex3f(f, a[1], a[2]); glVertex3f(f, b[1], a[2]);
glVertex3f(f, b[1], a[2]); glVertex3f(f, b[1], b[2]);
glVertex3f(f, b[1], b[2]); glVertex3f(f, a[1], b[2]);
glVertex3f(f, a[1], b[2]); glVertex3f(f, a[1], a[2]);
}
- for (i = 1; i < res[1]-1; ++i) {
- float f = interpf(b[1], a[1], (float)i / (float)(res[1]-1));
+ for (i = 1; i < res[1] - 1; ++i) {
+ float f = interpf(b[1], a[1], (float)i / (float)(res[1] - 1));
glVertex3f(a[0], f, a[2]); glVertex3f(b[0], f, a[2]);
glVertex3f(b[0], f, a[2]); glVertex3f(b[0], f, b[2]);
glVertex3f(b[0], f, b[2]); glVertex3f(a[0], f, b[2]);
glVertex3f(a[0], f, b[2]); glVertex3f(a[0], f, a[2]);
}
- for (i = 1; i < res[2]-1; ++i) {
- float f = interpf(b[2], a[2], (float)i / (float)(res[2]-1));
+ for (i = 1; i < res[2] - 1; ++i) {
+ float f = interpf(b[2], a[2], (float)i / (float)(res[2] - 1));
glVertex3f(a[0], a[1], f); glVertex3f(b[0], a[1], f);
glVertex3f(b[0], a[1], f); glVertex3f(b[0], b[1], f);
glVertex3f(b[0], b[1], f); glVertex3f(a[0], b[1], f);
@@ -5326,7 +5659,6 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
glDrawArrays(GL_LINE_STRIP, 0, path->segments + 1);
}
-
/* restore & clean up */
if (1) { //ob_dt > OB_WIRE) {
if (part->draw_col == PART_DRAW_COL_MAT)
@@ -5334,9 +5666,10 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
glDisable(GL_COLOR_MATERIAL);
}
- if (cdata2)
+ if (cdata2) {
MEM_freeN(cdata2);
- /* cd2 = */ /* UNUSED */ cdata2 = NULL;
+ cdata2 = NULL;
+ }
glLineWidth(1.0f);
@@ -5345,8 +5678,8 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
for (a = 0, pa = psys->particles; a < totpart; a++, pa++) {
float vec_txt[3];
- numstr_len = BLI_snprintf(numstr, sizeof(numstr), "%i", a);
- /* use worldspace beause object matrix is already applied */
+ numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%i", a);
+ /* use worldspace because object matrix is already applied */
mul_v3_m4v3(vec_txt, ob->imat, cache[a]->co);
view3d_cached_text_draw_add(vec_txt, numstr, numstr_len,
10, V3D_CACHE_TEXT_WORLDSPACE | V3D_CACHE_TEXT_ASCII, tcol);
@@ -5474,7 +5807,7 @@ static void draw_ptcache_edit(Scene *scene, View3D *v3d, PTCacheEdit *edit)
PTCacheEditPoint *point;
PTCacheEditKey *key;
ParticleEditSettings *pset = PE_settings(scene);
- int i, k, totpoint = edit->totpoint, timed = pset->flag & PE_FADE_TIME ? pset->fade_frames : 0;
+ int i, k, totpoint = edit->totpoint, timed = (pset->flag & PE_FADE_TIME) ? pset->fade_frames : 0;
int totkeys = 1;
float sel_col[3];
float nosel_col[3];
@@ -5614,7 +5947,7 @@ static void draw_ptcache_edit(Scene *scene, View3D *v3d, PTCacheEdit *edit)
glColor3fv(nosel_col);
/* has to be like this.. otherwise selection won't work, have try glArrayElement later..*/
glBegin(GL_POINTS);
- glVertex3fv(key->flag & PEK_USE_WCO ? key->world_co : key->co);
+ glVertex3fv((key->flag & PEK_USE_WCO) ? key->world_co : key->co);
glEnd();
}
}
@@ -5630,9 +5963,9 @@ static void draw_ptcache_edit(Scene *scene, View3D *v3d, PTCacheEdit *edit)
glShadeModel(GL_FLAT);
if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
glLineWidth(1.0f);
- glPointSize(1.0);
+ glPointSize(1.0f);
}
-//static void ob_draw_RE_motion(float com[3],float rotscale[3][3],float tw,float th)
+
static void ob_draw_RE_motion(float com[3], float rotscale[3][3], float itw, float ith, float drw_size)
{
float tr[3][3];
@@ -6036,7 +6369,7 @@ static void draw_editnurb_splines(Object *ob, Nurb *nurb, const bool sel)
Nurb *nu;
BPoint *bp, *bp1;
int a, b, ofs, index;
- Curve *cu = (Curve *)ob->data;
+ Curve *cu = ob->data;
index = 0;
nu = nurb;
@@ -6396,7 +6729,7 @@ static void draw_empty_sphere(float size)
static GLuint displist = 0;
if (displist == 0) {
- GLUquadricObj *qobj;
+ GLUquadricObj *qobj;
displist = glGenLists(1);
glNewList(displist, GL_COMPILE);
@@ -6427,16 +6760,13 @@ static void draw_empty_sphere(float size)
/* draw a cone for use as an empty drawtype */
static void draw_empty_cone(float size)
{
- float cent = 0;
- float radius;
+ const float radius = size;
+
GLUquadricObj *qobj = gluNewQuadric();
gluQuadricDrawStyle(qobj, GLU_SILHOUETTE);
-
glPushMatrix();
- radius = size;
- glTranslatef(cent, cent, cent);
glScalef(radius, size * 2.0f, radius);
glRotatef(-90.0, 1.0, 0.0, 0.0);
gluCylinder(qobj, 1.0, 0.0, 1.0, 8, 1);
@@ -6449,7 +6779,7 @@ static void draw_empty_cone(float size)
static void drawspiral(const float cent[3], float rad, float tmat[4][4], int start)
{
float vec[3], vx[3], vy[3];
- const float tot_inv = (1.0f / (float)CIRCLE_RESOL);
+ const float tot_inv = 1.0f / (float)CIRCLE_RESOL;
int a;
bool inverse = false;
float x, y, fac;
@@ -6513,8 +6843,7 @@ static void drawspiral(const float cent[3], float rad, float tmat[4][4], int sta
}
/* draws a circle on x-z plane given the scaling of the circle, assuming that
- * all required matrices have been set (used for drawing empties)
- */
+ * all required matrices have been set (used for drawing empties) */
static void drawcircle_size(float size)
{
float x, y;
@@ -6522,7 +6851,7 @@ static void drawcircle_size(float size)
glBegin(GL_LINE_LOOP);
- /* coordinates are: cos(degrees * 11.25) = x, sin(degrees*11.25) = y, 0.0f = z */
+ /* coordinates are: cos(degrees * 11.25) = x, sin(degrees * 11.25) = y, 0.0f = z */
for (degrees = 0; degrees < CIRCLE_RESOL; degrees++) {
x = cosval[degrees];
y = sinval[degrees];
@@ -6666,31 +6995,23 @@ static void draw_forcefield(Object *ob, RegionView3D *rv3d,
PartDeflect *pd = ob->pd;
float imat[4][4], tmat[4][4];
float vec[3] = {0.0, 0.0, 0.0};
- float size;
-
/* scale size of circle etc with the empty drawsize */
- if (ob->type == OB_EMPTY) size = ob->empty_drawsize;
- else size = 1.0;
+ const float size = (ob->type == OB_EMPTY) ? ob->empty_drawsize : 1.0f;
/* calculus here, is reused in PFIELD_FORCE */
invert_m4_m4(imat, rv3d->viewmatob);
-// normalize_v3(imat[0]); /* we don't do this because field doesnt scale either... apart from wind! */
-// normalize_v3(imat[1]);
+#if 0
+ normalize_v3(imat[0]); /* we don't do this because field doesnt scale either... apart from wind! */
+ normalize_v3(imat[1]);
+#endif
if (pd->forcefield == PFIELD_WIND) {
- float force_val;
+ float force_val = pd->f_strength;
if ((dflag & DRAW_CONSTCOLOR) == 0) {
ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.5f);
}
- //if (has_ipo_code(ob->ipo, OB_PD_FSTR))
- // force_val = IPO_GetFloatValue(ob->ipo, OB_PD_FSTR, scene->r.cfra);
- //else
- {
- force_val = pd->f_strength;
- }
-
unit_m4(tmat);
force_val *= 0.1f;
drawcircball(GL_LINE_LOOP, vec, size, tmat);
@@ -6704,14 +7025,7 @@ static void draw_forcefield(Object *ob, RegionView3D *rv3d,
}
else if (pd->forcefield == PFIELD_FORCE) {
- float ffall_val;
-
- //if (has_ipo_code(ob->ipo, OB_PD_FFALL))
- // ffall_val = IPO_GetFloatValue(ob->ipo, OB_PD_FFALL, scene->r.cfra);
- //else
- {
- ffall_val = pd->f_power;
- }
+ float ffall_val = pd->f_power;
if ((dflag & DRAW_CONSTCOLOR) == 0) ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.5f);
drawcircball(GL_LINE_LOOP, vec, size, imat);
@@ -6721,20 +7035,9 @@ static void draw_forcefield(Object *ob, RegionView3D *rv3d,
drawcircball(GL_LINE_LOOP, vec, size * 2.0f, imat);
}
else if (pd->forcefield == PFIELD_VORTEX) {
- float /*ffall_val,*/ force_val;
+ float force_val = pd->f_strength;
unit_m4(tmat);
- //if (has_ipo_code(ob->ipo, OB_PD_FFALL))
- // ffall_val = IPO_GetFloatValue(ob->ipo, OB_PD_FFALL, scene->r.cfra);
- //else
- // ffall_val = pd->f_power;
-
- //if (has_ipo_code(ob->ipo, OB_PD_FSTR))
- // force_val = IPO_GetFloatValue(ob->ipo, OB_PD_FSTR, scene->r.cfra);
- //else
- {
- force_val = pd->f_strength;
- }
if ((dflag & DRAW_CONSTCOLOR) == 0) {
ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.7f);
@@ -6752,25 +7055,19 @@ static void draw_forcefield(Object *ob, RegionView3D *rv3d,
else if (pd->forcefield == PFIELD_GUIDE && ob->type == OB_CURVE) {
Curve *cu = ob->data;
if ((cu->flag & CU_PATH) && ob->curve_cache->path && ob->curve_cache->path->data) {
- float mindist, guidevec1[4], guidevec2[3];
-
- //if (has_ipo_code(ob->ipo, OB_PD_FSTR))
- // mindist = IPO_GetFloatValue(ob->ipo, OB_PD_FSTR, scene->r.cfra);
- //else
- {
- mindist = pd->f_strength;
- }
+ float guidevec1[4], guidevec2[3];
+ float mindist = pd->f_strength;
if ((dflag & DRAW_CONSTCOLOR) == 0) {
ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.5f);
}
- /*path end*/
+ /* path end */
setlinestyle(3);
where_on_path(ob, 1.0f, guidevec1, guidevec2, NULL, NULL, NULL);
drawcircball(GL_LINE_LOOP, guidevec1, mindist, imat);
- /*path beginning*/
+ /* path beginning */
setlinestyle(0);
where_on_path(ob, 0.0f, guidevec1, guidevec2, NULL, NULL, NULL);
drawcircball(GL_LINE_LOOP, guidevec1, mindist, imat);
@@ -6841,19 +7138,31 @@ static void draw_forcefield(Object *ob, RegionView3D *rv3d,
setlinestyle(0);
}
-static void draw_box(float vec[8][3])
+static void draw_box(float vec[8][3], bool solid)
{
- glBegin(GL_LINE_STRIP);
- glVertex3fv(vec[0]); glVertex3fv(vec[1]); glVertex3fv(vec[2]); glVertex3fv(vec[3]);
- glVertex3fv(vec[0]); glVertex3fv(vec[4]); glVertex3fv(vec[5]); glVertex3fv(vec[6]);
- glVertex3fv(vec[7]); glVertex3fv(vec[4]);
- glEnd();
+ if (!solid) {
+ glBegin(GL_LINE_STRIP);
+ glVertex3fv(vec[0]); glVertex3fv(vec[1]); glVertex3fv(vec[2]); glVertex3fv(vec[3]);
+ glVertex3fv(vec[0]); glVertex3fv(vec[4]); glVertex3fv(vec[5]); glVertex3fv(vec[6]);
+ glVertex3fv(vec[7]); glVertex3fv(vec[4]);
+ glEnd();
- glBegin(GL_LINES);
- glVertex3fv(vec[1]); glVertex3fv(vec[5]);
- glVertex3fv(vec[2]); glVertex3fv(vec[6]);
- glVertex3fv(vec[3]); glVertex3fv(vec[7]);
- glEnd();
+ glBegin(GL_LINES);
+ glVertex3fv(vec[1]); glVertex3fv(vec[5]);
+ glVertex3fv(vec[2]); glVertex3fv(vec[6]);
+ glVertex3fv(vec[3]); glVertex3fv(vec[7]);
+ glEnd();
+ }
+ else {
+ glBegin(GL_QUADS);
+ glVertex3fv(vec[0]); glVertex3fv(vec[1]); glVertex3fv(vec[2]); glVertex3fv(vec[3]);
+ glVertex3fv(vec[7]); glVertex3fv(vec[6]); glVertex3fv(vec[5]); glVertex3fv(vec[4]);
+ glVertex3fv(vec[4]); glVertex3fv(vec[5]); glVertex3fv(vec[1]); glVertex3fv(vec[0]);
+ glVertex3fv(vec[3]); glVertex3fv(vec[2]); glVertex3fv(vec[6]); glVertex3fv(vec[7]);
+ glVertex3fv(vec[3]); glVertex3fv(vec[7]); glVertex3fv(vec[4]); glVertex3fv(vec[0]);
+ glVertex3fv(vec[1]); glVertex3fv(vec[5]); glVertex3fv(vec[6]); glVertex3fv(vec[2]);
+ glEnd();
+ }
}
static void draw_bb_quadric(BoundBox *bb, char type, bool around_origin)
@@ -6947,7 +7256,7 @@ static void draw_bounding_volume(Object *ob, char type)
vec[0][2] = vec[3][2] = vec[4][2] = vec[7][2] = -size[2];
vec[1][2] = vec[2][2] = vec[5][2] = vec[6][2] = +size[2];
- draw_box(vec);
+ draw_box(vec, false);
}
else {
draw_bb_quadric(bb, type, true);
@@ -6955,7 +7264,7 @@ static void draw_bounding_volume(Object *ob, char type)
}
else {
if (type == OB_BOUND_BOX)
- draw_box(bb->vec);
+ draw_box(bb->vec, false);
else
draw_bb_quadric(bb, type, false);
}
@@ -6991,7 +7300,7 @@ static void drawtexspace(Object *ob)
setlinestyle(2);
- draw_box(vec);
+ draw_box(vec, false);
setlinestyle(0);
}
@@ -7178,7 +7487,7 @@ static void draw_object_wire_color(Scene *scene, Base *base, unsigned char r_ob_
else {
if (ob->flag & OB_FROMGROUP) {
if (base->flag & (SELECT + BA_WAS_SEL)) {
- /* uses darker active color for non-active + selected*/
+ /* uses darker active color for non-active + selected */
theme_id = TH_GROUP_ACTIVE;
if (scene->basact != base) {
@@ -7232,8 +7541,11 @@ static void draw_object_matcap_check(View3D *v3d, Object *ob)
v3d->defmaterial->preview = NULL;
}
/* first time users */
- if (v3d->matcap_icon == 0)
+ if (v3d->matcap_icon < ICON_MATCAP_01 ||
+ v3d->matcap_icon > ICON_MATCAP_24)
+ {
v3d->matcap_icon = ICON_MATCAP_01;
+ }
if (v3d->defmaterial->preview == NULL)
v3d->defmaterial->preview = UI_icon_to_preview(v3d->matcap_icon);
@@ -7265,7 +7577,7 @@ static void draw_rigidbody_shape(Object *ob)
vec[0][2] = vec[3][2] = vec[4][2] = vec[7][2] = -size[2];
vec[1][2] = vec[2][2] = vec[5][2] = vec[6][2] = +size[2];
- draw_box(vec);
+ draw_box(vec, false);
break;
case RB_SHAPE_SPHERE:
draw_bb_quadric(bb, OB_BOUND_SPHERE, true);
@@ -7302,7 +7614,8 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
const bool render_override = (v3d->flag2 & V3D_RENDER_OVERRIDE) != 0;
const bool is_picking = (G.f & G_PICKSEL) != 0;
const bool has_particles = (ob->particlesystem.first != NULL);
- bool particle_skip_object = false; /* Draw particles but not their emitter object. */
+ bool skip_object = false; /* Draw particles but not their emitter object. */
+ SmokeModifierData *smd = NULL;
if (ob != scene->obedit) {
if (ob->restrictflag & OB_RESTRICT_VIEW)
@@ -7326,17 +7639,37 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
if (ob->mode == OB_MODE_OBJECT) {
ParticleSystem *psys;
- particle_skip_object = render_override;
+ skip_object = render_override;
for (psys = ob->particlesystem.first; psys; psys = psys->next) {
/* Once we have found a psys which renders its emitter object, we are done. */
if (psys->part->draw & PART_DRAW_EMITTER) {
- particle_skip_object = false;
+ skip_object = false;
break;
}
}
}
}
+ if ((md = modifiers_findByType(ob, eModifierType_Smoke)) && (modifier_isEnabled(scene, md, eModifierMode_Realtime))) {
+ smd = (SmokeModifierData *)md;
+
+ if (smd->domain) {
+ if (!v3d->transp && (dflag & DRAW_PICKING) == 0) {
+ if (!v3d->xray && !(ob->dtx & OB_DRAWXRAY)) {
+ /* object has already been drawn so skip drawing it */
+ ED_view3d_after_add(&v3d->afterdraw_transp, base, dflag);
+ return;
+ }
+ else if (v3d->xray) {
+ /* object has already been drawn so skip drawing it */
+ ED_view3d_after_add(&v3d->afterdraw_xraytransp, base, dflag);
+ return;
+ }
+ }
+ }
+ }
+
+
/* xray delay? */
if ((dflag & DRAW_PICKING) == 0 && (base->flag & OB_FROMDUPLI) == 0 && (v3d->flag2 & V3D_RENDER_SHADOW) == 0) {
/* don't do xray in particle mode, need the z-buffer */
@@ -7435,13 +7768,12 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
if (dt >= OB_BOUNDBOX) {
dtx = ob->dtx;
if (ob->mode & OB_MODE_EDIT) {
- // the only 2 extra drawtypes alowed in editmode
+ /* the only 2 extra drawtypes alowed in editmode */
dtx = dtx & (OB_DRAWWIRE | OB_TEXSPACE);
}
-
}
- if (!particle_skip_object) {
+ if (!skip_object) {
/* draw outline for selected objects, mesh does itself */
if ((v3d->flag & V3D_SELECT_OUTLINE) && !render_override && ob->type != OB_MESH) {
if (dt > OB_WIRE && (ob->mode & OB_MODE_EDIT) == 0 && (dflag & DRAW_SCENESET) == 0) {
@@ -7496,9 +7828,6 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
}
else if (ED_view3d_boundbox_clip(rv3d, ob->bb)) {
empty_object = drawDispList(scene, v3d, rv3d, base, dt, dflag, ob_wire_col);
-
-//XXX old animsys if (cu->path)
-// curve_draw_speed(scene, ob);
}
break;
case OB_MBALL:
@@ -7663,12 +7992,10 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
}
/* draw code for smoke */
- if ((md = modifiers_findByType(ob, eModifierType_Smoke)) && (modifier_isEnabled(scene, md, eModifierMode_Realtime))) {
- SmokeModifierData *smd = (SmokeModifierData *)md;
-
- // draw collision objects
- if ((smd->type & MOD_SMOKE_TYPE_COLL) && smd->coll) {
+ if (smd) {
#if 0
+ /* draw collision objects */
+ if ((smd->type & MOD_SMOKE_TYPE_COLL) && smd->coll) {
SmokeCollSettings *scs = smd->coll;
if (scs->points) {
size_t i;
@@ -7695,30 +8022,30 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
glDisable(GL_BLEND);
glDepthMask(GL_TRUE);
if (col) cpack(col);
-
}
-#endif
}
+#endif
/* only draw domains */
if (smd->domain) {
SmokeDomainSettings *sds = smd->domain;
- float p0[3], p1[3], viewnormal[3];
- BoundBox bb;
+ float viewnormal[3];
glLoadMatrixf(rv3d->viewmat);
glMultMatrixf(ob->obmat);
/* draw adaptive domain bounds */
- if (sds->flags & MOD_SMOKE_ADAPTIVE_DOMAIN) {
+ if ((sds->flags & MOD_SMOKE_ADAPTIVE_DOMAIN) && !render_override) {
+ float p0[3], p1[3];
+ BoundBox bb;
/* draw domain max bounds */
VECSUBFAC(p0, sds->p0, sds->cell_size, sds->adapt_res);
VECADDFAC(p1, sds->p1, sds->cell_size, sds->adapt_res);
BKE_boundbox_init_from_minmax(&bb, p0, p1);
- draw_box(bb.vec);
+ draw_box(bb.vec, false);
- /* draw base resolution bounds */
#if 0
+ /* draw base resolution bounds */
BKE_boundbox_init_from_minmax(&bb, sds->p0, sds->p1);
draw_box(bb.vec);
#endif
@@ -7726,16 +8053,16 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
/* don't show smoke before simulation starts, this could be made an option in the future */
if (smd->domain->fluid && CFRA >= smd->domain->point_cache[0]->startframe) {
+ float p0[3], p1[3];
- // get view vector
- copy_v3_v3(viewnormal, rv3d->viewinv[2]);
+ /* get view vector */
invert_m4_m4(ob->imat, ob->obmat);
- mul_mat3_m4_v3(ob->imat, viewnormal);
+ mul_v3_mat3_m4v3(viewnormal, ob->imat, rv3d->viewinv[2]);
normalize_v3(viewnormal);
/* set dynamic boundaries to draw the volume
- * also scale cube to global space to equalize volume slicing on all axises
- * (its scaled back before drawing) */
+ * also scale cube to global space to equalize volume slicing on all axes
+ * (it's scaled back before drawing) */
p0[0] = (sds->p0[0] + sds->cell_size[0] * sds->res_min[0] + sds->obj_shift_f[0]) * fabsf(ob->size[0]);
p0[1] = (sds->p0[1] + sds->cell_size[1] * sds->res_min[1] + sds->obj_shift_f[1]) * fabsf(ob->size[1]);
p0[2] = (sds->p0[2] + sds->cell_size[2] * sds->res_min[2] + sds->obj_shift_f[2]) * fabsf(ob->size[2]);
@@ -7819,7 +8146,6 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
view3d_cached_text_draw_add(zero, ob->id.name + 2, strlen(ob->id.name + 2), 10, 0, ob_wire_col);
}
}
- /*if (dtx & OB_DRAWIMAGE) drawDispListwire(&ob->disp);*/
if ((dtx & OB_DRAWWIRE) && dt >= OB_SOLID) {
if ((dflag & DRAW_CONSTCOLOR) == 0) {
draw_wire_extra(scene, rv3d, ob, ob_wire_col);
@@ -7935,7 +8261,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
if (ELEM(curcon->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_OBJECTSOLVER)) {
/* special case for object solver and follow track constraints because they don't fill
* constraint targets properly (design limitation -- scene is needed for their target
- * but it can't be accessed from get_targets callvack) */
+ * but it can't be accessed from get_targets callback) */
Object *camob = NULL;
@@ -7960,7 +8286,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
}
}
else {
- bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(curcon);
+ const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(curcon);
if ((cti && cti->get_constraint_targets) && (curcon->flag & CONSTRAINT_EXPAND)) {
ListBase targets = {NULL, NULL};
@@ -8192,7 +8518,7 @@ static void bbs_mesh_solid_verts(Scene *scene, Object *ob)
static void bbs_mesh_solid_faces(Scene *scene, Object *ob)
{
DerivedMesh *dm = mesh_get_derived_final(scene, ob, scene->customdata_mask);
- Mesh *me = (Mesh *)ob->data;
+ Mesh *me = ob->data;
glColor3ub(0, 0, 0);
diff --git a/source/blender/editors/space_view3d/drawsimdebug.c b/source/blender/editors/space_view3d/drawsimdebug.c
index 6113bfd4143..46320ba6763 100644
--- a/source/blender/editors/space_view3d/drawsimdebug.c
+++ b/source/blender/editors/space_view3d/drawsimdebug.c
@@ -29,28 +29,21 @@
* \ingroup spview3d
*/
-#include "MEM_guardedalloc.h"
-
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_view3d_types.h"
#include "DNA_object_types.h"
-#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "BLI_ghash.h"
#include "BKE_effect.h"
-#include "BKE_global.h"
-#include "BKE_modifier.h"
#include "view3d_intern.h"
#include "BIF_gl.h"
-#include "BIF_glutil.h"
-#include "UI_resources.h"
static void draw_sim_debug_elements(SimDebugData *debug_data, float imat[4][4])
{
diff --git a/source/blender/editors/space_view3d/drawvolume.c b/source/blender/editors/space_view3d/drawvolume.c
index a220e1e39b0..d6691f431dd 100644
--- a/source/blender/editors/space_view3d/drawvolume.c
+++ b/source/blender/editors/space_view3d/drawvolume.c
@@ -48,8 +48,6 @@
#include "GPU_extensions.h"
-#include "ED_mesh.h"
-
#include "view3d_intern.h" // own include
struct GPUTexture;
@@ -107,7 +105,7 @@ void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob,
float cor[3] = {1.0f, 1.0f, 1.0f};
int gl_depth = 0, gl_blend = 0;
- int use_fire = (sds->active_fields & SM_ACTIVE_FIRE);
+ const bool use_fire = (sds->active_fields & SM_ACTIVE_FIRE) != 0;
/* draw slices of smoke is adapted from c++ code authored
* by: Johannes Schmid and Ingemar Rask, 2006, johnny@grob.org */
@@ -137,76 +135,8 @@ void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob,
unsigned char *spec_data;
float *spec_pixels;
GPUTexture *tex_spec;
-
- /* Fragment program to calculate the view3d of smoke */
- /* using 4 textures, density, shadow, flame and flame spectrum */
- const char *shader_basic =
- "!!ARBfp1.0\n"
- "PARAM dx = program.local[0];\n"
- "PARAM darkness = program.local[1];\n"
- "PARAM render = program.local[2];\n"
- "PARAM f = {1.442695041, 1.442695041, 1.442695041, 0.01};\n"
- "TEMP temp, shadow, flame, spec, value;\n"
- "TEX temp, fragment.texcoord[0], texture[0], 3D;\n"
- "TEX shadow, fragment.texcoord[0], texture[1], 3D;\n"
- "TEX flame, fragment.texcoord[0], texture[2], 3D;\n"
- "TEX spec, flame.r, texture[3], 1D;\n"
- /* calculate shading factor from density */
- "MUL value.r, temp.a, darkness.a;\n"
- "MUL value.r, value.r, dx.r;\n"
- "MUL value.r, value.r, f.r;\n"
- "EX2 temp, -value.r;\n"
- /* alpha */
- "SUB temp.a, 1.0, temp.r;\n"
- /* shade colors */
- "MUL temp.r, temp.r, shadow.r;\n"
- "MUL temp.g, temp.g, shadow.r;\n"
- "MUL temp.b, temp.b, shadow.r;\n"
- "MUL temp.r, temp.r, darkness.r;\n"
- "MUL temp.g, temp.g, darkness.g;\n"
- "MUL temp.b, temp.b, darkness.b;\n"
- /* for now this just replace smoke shading if rendering fire */
- "CMP result.color, render.r, temp, spec;\n"
- "END\n";
-
- /* color shader */
- const char *shader_color =
- "!!ARBfp1.0\n"
- "PARAM dx = program.local[0];\n"
- "PARAM darkness = program.local[1];\n"
- "PARAM render = program.local[2];\n"
- "PARAM f = {1.442695041, 1.442695041, 1.442695041, 1.442695041};\n"
- "TEMP temp, shadow, flame, spec, value;\n"
- "TEX temp, fragment.texcoord[0], texture[0], 3D;\n"
- "TEX shadow, fragment.texcoord[0], texture[1], 3D;\n"
- "TEX flame, fragment.texcoord[0], texture[2], 3D;\n"
- "TEX spec, flame.r, texture[3], 1D;\n"
- /* unpremultiply volume texture */
- "RCP value.r, temp.a;\n"
- "MUL temp.r, temp.r, value.r;\n"
- "MUL temp.g, temp.g, value.r;\n"
- "MUL temp.b, temp.b, value.r;\n"
- /* calculate shading factor from density */
- "MUL value.r, temp.a, darkness.a;\n"
- "MUL value.r, value.r, dx.r;\n"
- "MUL value.r, value.r, f.r;\n"
- "EX2 value.r, -value.r;\n"
- /* alpha */
- "SUB temp.a, 1.0, value.r;\n"
- /* shade colors */
- "MUL temp.r, temp.r, shadow.r;\n"
- "MUL temp.g, temp.g, shadow.r;\n"
- "MUL temp.b, temp.b, shadow.r;\n"
- "MUL temp.r, temp.r, value.r;\n"
- "MUL temp.g, temp.g, value.r;\n"
- "MUL temp.b, temp.b, value.r;\n"
- /* for now this just replace smoke shading if rendering fire */
- "CMP result.color, render.r, temp, spec;\n"
- "END\n";
-
- GLuint prog;
-
-
+ GPUProgram *smoke_program;
+ int progtype = (sds->active_fields & SM_ACTIVE_COLORS) ? GPU_PROGRAM_SMOKE_COLORED : GPU_PROGRAM_SMOKE;
float size[3];
if (!tex) {
@@ -323,8 +253,7 @@ void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob,
glGetBooleanv(GL_BLEND, (GLboolean *)&gl_blend);
glGetBooleanv(GL_DEPTH_TEST, (GLboolean *)&gl_depth);
- glDepthMask(GL_FALSE);
- glDisable(GL_DEPTH_TEST);
+ glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
/* find cube vertex that is closest to the viewer */
@@ -351,24 +280,17 @@ void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob,
// printf("i: %d\n", i);
// printf("point %f, %f, %f\n", cv[i][0], cv[i][1], cv[i][2]);
- if (GL_TRUE == glewIsSupported("GL_ARB_fragment_program")) {
- glEnable(GL_FRAGMENT_PROGRAM_ARB);
- glGenProgramsARB(1, &prog);
-
- glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, prog);
- /* set shader */
- if (sds->active_fields & SM_ACTIVE_COLORS)
- glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(shader_color), shader_color);
- else
- glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(shader_basic), shader_basic);
+ smoke_program = GPU_shader_get_builtin_program(progtype);
+ if (smoke_program) {
+ GPU_program_bind(smoke_program);
/* cell spacing */
- glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0, dx, dx, dx, 1.0);
+ GPU_program_parameter_4f(smoke_program, 0, dx, dx, dx, 1.0);
/* custom parameter for smoke style (higher = thicker) */
if (sds->active_fields & SM_ACTIVE_COLORS)
- glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 1, 1.0, 1.0, 1.0, 10.0);
+ GPU_program_parameter_4f(smoke_program, 1, 1.0, 1.0, 1.0, 10.0);
else
- glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 1, sds->active_color[0], sds->active_color[1], sds->active_color[2], 10.0);
+ GPU_program_parameter_4f(smoke_program, 1, sds->active_color[0], sds->active_color[1], sds->active_color[2], 10.0);
}
else
printf("Your gfx card does not support 3D View smoke drawing.\n");
@@ -448,7 +370,7 @@ void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob,
else
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
- glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 2, 1.0, 0.0, 0.0, 0.0);
+ GPU_program_parameter_4f(smoke_program, 2, 1.0, 0.0, 0.0, 0.0);
glBegin(GL_POLYGON);
glColor3f(1.0, 1.0, 1.0);
for (i = 0; i < numpoints; i++) {
@@ -468,7 +390,7 @@ void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob,
else
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 2, -1.0, 0.0, 0.0, 0.0);
+ GPU_program_parameter_4f(smoke_program, 2, -1.0, 0.0, 0.0, 0.0);
glBegin(GL_POLYGON);
glColor3f(1.0, 1.0, 1.0);
for (i = 0; i < numpoints; i++) {
@@ -501,10 +423,8 @@ void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob,
free(spec_data);
free(spec_pixels);
- if (GLEW_ARB_fragment_program) {
- glDisable(GL_FRAGMENT_PROGRAM_ARB);
- glDeleteProgramsARB(1, &prog);
- }
+ if (smoke_program)
+ GPU_program_unbind(smoke_program);
MEM_freeN(points);
@@ -516,8 +436,6 @@ void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob,
if (gl_depth) {
glEnable(GL_DEPTH_TEST);
}
-
- glDepthMask(GL_TRUE);
}
#ifdef SMOKE_DEBUG_VELOCITY
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index ddb3e2f20c5..096d9e8a40a 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -74,6 +74,8 @@
# include "BPY_extern.h"
#endif
+#include "DEG_depsgraph.h"
+
#include "view3d_intern.h" /* own include */
/* ******************** manage regions ********************* */
@@ -344,7 +346,13 @@ static SpaceLink *view3d_new(const bContext *C)
v3d->bundle_size = 0.2f;
v3d->bundle_drawtype = OB_PLAINAXES;
-
+
+ /* stereo */
+ v3d->stereo3d_camera = STEREO_3D_ID;
+ v3d->stereo3d_flag |= V3D_S3D_DISPPLANE;
+ v3d->stereo3d_convergence_alpha = 0.15f;
+ v3d->stereo3d_volume_alpha = 0.05f;
+
/* header */
ar = MEM_callocN(sizeof(ARegion), "header for view3d");
@@ -925,7 +933,8 @@ static void view3d_main_area_listener(bScreen *sc, ScrArea *sa, ARegion *ar, wmN
(ob && (ob->mode == OB_MODE_TEXTURE_PAINT)) ||
(v3d->drawtype == OB_TEXTURE &&
(scene->gm.matmode == GAME_MAT_GLSL ||
- BKE_scene_use_new_shading_nodes(scene))))
+ BKE_scene_use_new_shading_nodes(scene))) ||
+ !DEG_depsgraph_use_legacy())
{
ED_region_tag_redraw(ar);
}
@@ -948,7 +957,8 @@ static void view3d_main_area_listener(bScreen *sc, ScrArea *sa, ARegion *ar, wmN
switch (wmn->data) {
case ND_LIGHTING:
if ((v3d->drawtype == OB_MATERIAL) ||
- (v3d->drawtype == OB_TEXTURE && (scene->gm.matmode == GAME_MAT_GLSL)))
+ (v3d->drawtype == OB_TEXTURE && (scene->gm.matmode == GAME_MAT_GLSL)) ||
+ !DEG_depsgraph_use_legacy())
{
ED_region_tag_redraw(ar);
}
@@ -1005,7 +1015,7 @@ static void view3d_main_area_listener(bScreen *sc, ScrArea *sa, ARegion *ar, wmN
break;
case NC_GPENCIL:
- if (ELEM(wmn->action, NA_EDITED, NA_SELECTED)) {
+ if (wmn->data == ND_DATA || ELEM(wmn->action, NA_EDITED, NA_SELECTED)) {
ED_region_tag_redraw(ar);
}
break;
diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c
index 88f43ab340f..1f8a69adba0 100644
--- a/source/blender/editors/space_view3d/view3d_buttons.c
+++ b/source/blender/editors/space_view3d/view3d_buttons.c
@@ -68,7 +68,6 @@
#include "RNA_access.h"
#include "ED_armature.h"
-#include "ED_gpencil.h"
#include "ED_mesh.h"
#include "ED_screen.h"
@@ -200,7 +199,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
bool has_skinradius = false;
PointerRNA data_ptr;
- fill_vn_fl(median, NBR_TRANSFORM_PROPERTIES, 0.0f);
+ copy_vn_fl(median, NBR_TRANSFORM_PROPERTIES, 0.0f);
tot = totedgedata = totcurvedata = totlattdata = totcurvebweight = 0;
/* make sure we got storage */
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 58ef9184dd0..fb0f437884a 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -50,11 +50,13 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "BLI_endian_switch.h"
+#include "BLI_threads.h"
#include "BKE_anim.h"
#include "BKE_camera.h"
#include "BKE_context.h"
#include "BKE_customdata.h"
+#include "BKE_DerivedMesh.h"
#include "BKE_image.h"
#include "BKE_key.h"
#include "BKE_main.h"
@@ -99,6 +101,11 @@
#include "view3d_intern.h" /* own include */
+/* prototypes */
+static void view3d_stereo3d_setup(Scene *scene, View3D *v3d, ARegion *ar);
+static void view3d_stereo3d_setup_offscreen(Scene *scene, View3D *v3d, ARegion *ar,
+ float winmat[4][4], const char *viewname);
+
/* handy utility for drawing shapes in the viewport for arbitrary code.
* could add lines and points too */
// #define DEBUG_DRAW
@@ -207,7 +214,7 @@ void ED_view3d_clipping_enable(void)
}
}
-static bool view3d_clipping_test(const float co[3], float clip[6][4])
+static bool view3d_clipping_test(const float co[3], const float clip[6][4])
{
if (plane_point_side_v3(clip[0], co) > 0.0f)
if (plane_point_side_v3(clip[1], co) > 0.0f)
@@ -220,7 +227,7 @@ static bool view3d_clipping_test(const float co[3], float clip[6][4])
/* for 'local' ED_view3d_clipping_local must run first
* then all comparisons can be done in localspace */
-bool ED_view3d_clipping_test(RegionView3D *rv3d, const float co[3], const bool is_local)
+bool ED_view3d_clipping_test(const RegionView3D *rv3d, const float co[3], const bool is_local)
{
return view3d_clipping_test(co, is_local ? rv3d->clip_local : rv3d->clip);
}
@@ -465,7 +472,7 @@ float ED_view3d_grid_scale(Scene *scene, View3D *v3d, const char **grid_unit)
return v3d->grid * ED_scene_grid_scale(scene, grid_unit);
}
-static void drawfloor(Scene *scene, View3D *v3d, const char **grid_unit)
+static void drawfloor(Scene *scene, View3D *v3d, const char **grid_unit, bool write_depth)
{
float grid, grid_scale;
unsigned char col_grid[3];
@@ -477,7 +484,8 @@ static void drawfloor(Scene *scene, View3D *v3d, const char **grid_unit)
grid_scale = ED_view3d_grid_scale(scene, v3d, grid_unit);
grid = gridlines * grid_scale;
- glDepthMask(GL_FALSE);
+ if (!write_depth)
+ glDepthMask(GL_FALSE);
UI_GetThemeColor3ubv(TH_GRID, col_grid);
@@ -650,7 +658,7 @@ static void draw_rotation_guide(RegionView3D *rv3d)
glEnable(GL_POINT_SMOOTH);
glDepthMask(0); /* don't overwrite zbuf */
- if (rv3d->rot_angle != 0.f) {
+ if (rv3d->rot_angle != 0.0f) {
/* -- draw rotation axis -- */
float scaled_axis[3];
const float scale = rv3d->dist;
@@ -658,19 +666,21 @@ static void draw_rotation_guide(RegionView3D *rv3d)
glBegin(GL_LINE_STRIP);
- color[3] = 0.f; /* more transparent toward the ends */
+ color[3] = 0.0f; /* more transparent toward the ends */
glColor4fv(color);
add_v3_v3v3(end, o, scaled_axis);
glVertex3fv(end);
- // color[3] = 0.2f + fabsf(rv3d->rot_angle); /* modulate opacity with angle */
- // ^^ neat idea, but angle is frame-rate dependent, so it's usually close to 0.2
+#if 0
+ color[3] = 0.2f + fabsf(rv3d->rot_angle); /* modulate opacity with angle */
+ /* ^^ neat idea, but angle is frame-rate dependent, so it's usually close to 0.2 */
+#endif
color[3] = 0.5f; /* more opaque toward the center */
glColor4fv(color);
glVertex3fv(o);
- color[3] = 0.f;
+ color[3] = 0.0f;
glColor4fv(color);
sub_v3_v3v3(end, o, scaled_axis);
glVertex3fv(end);
@@ -681,14 +691,14 @@ static void draw_rotation_guide(RegionView3D *rv3d)
#define ROT_AXIS_DETAIL 13
const float s = 0.05f * scale;
- const float step = 2.f * (float)(M_PI / ROT_AXIS_DETAIL);
+ const float step = 2.0f * (float)(M_PI / ROT_AXIS_DETAIL);
float angle;
int i;
float q[4]; /* rotate ring so it's perpendicular to axis */
const int upright = fabsf(rv3d->rot_axis[2]) >= 0.95f;
if (!upright) {
- const float up[3] = {0.f, 0.f, 1.f};
+ const float up[3] = {0.0f, 0.0f, 1.0f};
float vis_angle, vis_axis[3];
cross_v3_v3v3(vis_axis, up, rv3d->rot_axis);
@@ -699,7 +709,7 @@ static void draw_rotation_guide(RegionView3D *rv3d)
color[3] = 0.25f; /* somewhat faint */
glColor4fv(color);
glBegin(GL_LINE_LOOP);
- for (i = 0, angle = 0.f; i < ROT_AXIS_DETAIL; ++i, angle += step) {
+ for (i = 0, angle = 0.0f; i < ROT_AXIS_DETAIL; ++i, angle += step) {
float p[3] = {s * cosf(angle), s * sinf(angle), 0.0f};
if (!upright) {
@@ -725,12 +735,12 @@ static void draw_rotation_guide(RegionView3D *rv3d)
glVertex3fv(o);
glEnd();
- /* find screen coordinates for rotation center, then draw pretty icon */
#if 0
+ /* find screen coordinates for rotation center, then draw pretty icon */
mul_m4_v3(rv3d->persinv, rot_center);
UI_icon_draw(rot_center[0], rot_center[1], ICON_NDOF_TURN);
-#endif
/* ^^ just playing around, does not work */
+#endif
glDisable(GL_BLEND);
glDisable(GL_POINT_SMOOTH);
@@ -949,8 +959,9 @@ static void draw_selected_name(Scene *scene, Object *ob, rcti *rect)
BLF_draw_default(offset, 0.5f * U.widget_unit, 0.0f, info, sizeof(info));
}
-static void view3d_camera_border(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d,
- rctf *r_viewborder, const bool no_shift, const bool no_zoom)
+static void view3d_camera_border(
+ const Scene *scene, const ARegion *ar, const View3D *v3d, const RegionView3D *rv3d,
+ rctf *r_viewborder, const bool no_shift, const bool no_zoom)
{
CameraParams params;
rctf rect_view, rect_camera;
@@ -983,7 +994,9 @@ static void view3d_camera_border(Scene *scene, ARegion *ar, View3D *v3d, RegionV
r_viewborder->ymax = ((rect_camera.ymax - rect_view.ymin) / BLI_rctf_size_y(&rect_view)) * ar->winy;
}
-void ED_view3d_calc_camera_border_size(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, float r_size[2])
+void ED_view3d_calc_camera_border_size(
+ const Scene *scene, const ARegion *ar, const View3D *v3d, const RegionView3D *rv3d,
+ float r_size[2])
{
rctf viewborder;
@@ -992,8 +1005,9 @@ void ED_view3d_calc_camera_border_size(Scene *scene, ARegion *ar, View3D *v3d, R
r_size[1] = BLI_rctf_size_y(&viewborder);
}
-void ED_view3d_calc_camera_border(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d,
- rctf *r_viewborder, const bool no_shift)
+void ED_view3d_calc_camera_border(
+ const Scene *scene, const ARegion *ar, const View3D *v3d, const RegionView3D *rv3d,
+ rctf *r_viewborder, const bool no_shift)
{
view3d_camera_border(scene, ar, v3d, rv3d, r_viewborder, no_shift, false);
}
@@ -1314,12 +1328,12 @@ static void backdrawview3d(Scene *scene, ARegion *ar, View3D *v3d)
/* do nothing */
}
else if ((base && (base->object->mode & OB_MODE_PARTICLE_EDIT)) &&
- v3d->drawtype > OB_WIRE && (v3d->flag & V3D_ZBUF_SELECT))
+ V3D_IS_ZBUF(v3d))
{
/* do nothing */
}
- else if (scene->obedit && v3d->drawtype > OB_WIRE &&
- (v3d->flag & V3D_ZBUF_SELECT))
+ else if (scene->obedit &&
+ V3D_IS_ZBUF(v3d))
{
/* do nothing */
}
@@ -1441,14 +1455,23 @@ static void view3d_opengl_read_Z_pixels(ARegion *ar, int x, int y, int w, int h,
glReadPixels(ar->winrct.xmin + x, ar->winrct.ymin + y, w, h, format, type, data);
}
-void view3d_validate_backbuf(ViewContext *vc)
+void ED_view3d_backbuf_validate(ViewContext *vc)
{
if (vc->v3d->flag & V3D_INVALID_BACKBUF)
backdrawview3d(vc->scene, vc->ar, vc->v3d);
}
+/**
+ * allow for small values [0.5 - 2.5],
+ * and large values, FLT_MAX by clamping by the area size
+ */
+int ED_view3d_backbuf_sample_size_clamp(ARegion *ar, const float dist)
+{
+ return (int)min_ff(ceilf(dist), (float)max_ii(ar->winx, ar->winx));
+}
+
/* samples a single pixel (copied from vpaint) */
-unsigned int view3d_sample_backbuf(ViewContext *vc, int x, int y)
+unsigned int ED_view3d_backbuf_sample(ViewContext *vc, int x, int y)
{
unsigned int col;
@@ -1456,7 +1479,7 @@ unsigned int view3d_sample_backbuf(ViewContext *vc, int x, int y)
return 0;
}
- view3d_validate_backbuf(vc);
+ ED_view3d_backbuf_validate(vc);
view3d_opengl_read_pixels(vc->ar, x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &col);
glReadBuffer(GL_BACK);
@@ -1469,7 +1492,7 @@ unsigned int view3d_sample_backbuf(ViewContext *vc, int x, int y)
}
/* reads full rect, converts indices */
-ImBuf *view3d_read_backbuf(ViewContext *vc, short xmin, short ymin, short xmax, short ymax)
+ImBuf *ED_view3d_backbuf_read(ViewContext *vc, short xmin, short ymin, short xmax, short ymax)
{
unsigned int *dr, *rd;
struct ImBuf *ibuf, *ibuf1;
@@ -1477,17 +1500,18 @@ ImBuf *view3d_read_backbuf(ViewContext *vc, short xmin, short ymin, short xmax,
short xminc, yminc, xmaxc, ymaxc, xs, ys;
/* clip */
- if (xmin < 0) xminc = 0; else xminc = xmin;
- if (xmax >= vc->ar->winx) xmaxc = vc->ar->winx - 1; else xmaxc = xmax;
- if (xminc > xmaxc) return NULL;
+ xminc = max_ii(xmin, 0);
+ yminc = max_ii(ymin, 0);
+ xmaxc = min_ii(xmax, vc->ar->winx - 1);
+ ymaxc = min_ii(ymax, vc->ar->winy - 1);
+
+ if (UNLIKELY((xminc > xmaxc) || (yminc > ymaxc))) {
+ return NULL;
+ }
- if (ymin < 0) yminc = 0; else yminc = ymin;
- if (ymax >= vc->ar->winy) ymaxc = vc->ar->winy - 1; else ymaxc = ymax;
- if (yminc > ymaxc) return NULL;
-
ibuf = IMB_allocImBuf((xmaxc - xminc + 1), (ymaxc - yminc + 1), 32, IB_rect);
- view3d_validate_backbuf(vc);
+ ED_view3d_backbuf_validate(vc);
view3d_opengl_read_pixels(vc->ar,
xminc, yminc,
@@ -1527,23 +1551,21 @@ ImBuf *view3d_read_backbuf(ViewContext *vc, short xmin, short ymin, short xmax,
}
/* smart function to sample a rect spiralling outside, nice for backbuf selection */
-unsigned int view3d_sample_backbuf_rect(ViewContext *vc, const int mval[2], int size,
- unsigned int min, unsigned int max, float *r_dist, short strict,
- void *handle, bool (*indextest)(void *handle, unsigned int index))
+unsigned int ED_view3d_backbuf_sample_rect(
+ ViewContext *vc, const int mval[2], int size,
+ unsigned int min, unsigned int max, float *r_dist)
{
struct ImBuf *buf;
- unsigned int *bufmin, *bufmax, *tbuf;
+ const unsigned int *bufmin, *bufmax, *tbuf;
int minx, miny;
int a, b, rc, nr, amount, dirvec[4][2];
- int distance = 0;
unsigned int index = 0;
- bool indexok = false;
amount = (size - 1) / 2;
minx = mval[0] - (amount + 1);
miny = mval[1] - (amount + 1);
- buf = view3d_read_backbuf(vc, minx, miny, minx + size - 1, miny + size - 1);
+ buf = ED_view3d_backbuf_read(vc, minx, miny, minx + size - 1, miny + size - 1);
if (!buf) return 0;
rc = 0;
@@ -1561,21 +1583,19 @@ unsigned int view3d_sample_backbuf_rect(ViewContext *vc, const int mval[2], int
for (nr = 1; nr <= size; nr++) {
for (a = 0; a < 2; a++) {
- for (b = 0; b < nr; b++, distance++) {
- if (*tbuf && *tbuf >= min && *tbuf < max) { /* we got a hit */
- if (strict) {
- indexok = indextest(handle, *tbuf - min + 1);
- if (indexok) {
- *r_dist = sqrtf((float)distance);
- index = *tbuf - min + 1;
- goto exit;
- }
- }
- else {
- *r_dist = sqrtf((float)distance); /* XXX, this distance is wrong - */
- index = *tbuf - min + 1; /* messy yah, but indices start at 1 */
- goto exit;
- }
+ for (b = 0; b < nr; b++) {
+ if (*tbuf && *tbuf >= min && *tbuf < max) {
+ /* we got a hit */
+
+ /* get x,y pixel coords from the offset
+ * (manhatten distance in keeping with other screen-based selection) */
+ *r_dist = (float)(
+ abs(((int)(tbuf - buf->rect) % size) - (size / 2)) +
+ abs(((int)(tbuf - buf->rect) / size) - (size / 2)));
+
+ /* indices start at 1 here */
+ index = (*tbuf - min) + 1;
+ goto exit;
}
tbuf += (dirvec[rc][0] + dirvec[rc][1]);
@@ -1597,6 +1617,26 @@ exit:
/* ************************************************************* */
+static void view3d_stereo_bgpic_setup(Scene *scene, View3D *v3d, Image *ima, ImageUser *iuser)
+{
+ if ((ima->flag & IMA_IS_STEREO)) {
+ iuser->flag |= IMA_SHOW_STEREO;
+
+ if ((scene->r.scemode & R_MULTIVIEW) == 0) {
+ iuser->multiview_eye = STEREO_LEFT_ID;
+ }
+ else if (v3d->stereo3d_camera != STEREO_3D_ID) {
+ /* show only left or right camera */
+ iuser->multiview_eye = v3d->stereo3d_camera;
+ }
+
+ BKE_image_multiview_index(ima, iuser);
+ }
+ else {
+ iuser->flag &= ~IMA_SHOW_STEREO;
+ }
+}
+
static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d,
const bool do_foreground, const bool do_camera_frame)
{
@@ -1620,6 +1660,7 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d,
ImBuf *ibuf = NULL, *freeibuf, *releaseibuf;
void *lock;
+ rctf clip_rect;
Image *ima = NULL;
MovieClip *clip = NULL;
@@ -1639,6 +1680,7 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d,
ibuf = NULL; /* frame is out of range, dont show */
}
else {
+ view3d_stereo_bgpic_setup(scene, v3d, ima, &bgpic->iuser);
ibuf = BKE_image_acquire_ibuf(ima, &bgpic->iuser, &lock);
releaseibuf = ibuf;
}
@@ -1782,8 +1824,12 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d,
}
/* complete clip? */
+ BLI_rctf_init(&clip_rect, x1, x2, y1, y2);
+ if (bgpic->rotation) {
+ BLI_rctf_rotate_expand(&clip_rect, &clip_rect, bgpic->rotation);
+ }
- if (x2 < 0 || y2 < 0 || x1 > ar->winx || y1 > ar->winy) {
+ if (clip_rect.xmax < 0 || clip_rect.ymax < 0 || clip_rect.xmin > ar->winx || clip_rect.ymin > ar->winy) {
if (freeibuf)
IMB_freeImBuf(freeibuf);
if (releaseibuf)
@@ -1830,9 +1876,7 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d,
ED_region_pixelspace(ar);
glTranslatef(centx, centy, 0.0);
- if (rv3d->persp != RV3D_CAMOB) {
- glRotatef(RAD2DEGF(-bgpic->rotation), 0.0f, 0.0f, 1.0f);
- }
+ glRotatef(RAD2DEGF(-bgpic->rotation), 0.0f, 0.0f, 1.0f);
if (bgpic->flag & V3D_BGPIC_FLIP_X) {
zoomx *= -1.0f;
@@ -2044,7 +2088,7 @@ static void draw_dupli_objects_color(
lb = object_duplilist(G.main->eval_ctx, scene, base->object);
// BLI_listbase_sort(lb, dupli_ob_sort); /* might be nice to have if we have a dupli list with mixed objects. */
- apply_data = duplilist_apply(base->object, lb);
+ apply_data = duplilist_apply(base->object, scene, lb);
dob = dupli_step(lb->first);
if (dob) dob_next = dupli_step(dob->next);
@@ -2479,13 +2523,14 @@ static void gpu_render_lamp_update(Scene *scene, View3D *v3d, Object *ob, Object
}
}
-static void gpu_update_lamps_shadows(Scene *scene, View3D *v3d)
+static void gpu_update_lamps_shadows_world(Scene *scene, View3D *v3d)
{
ListBase shadows;
View3DShadow *shadow;
Scene *sce_iter;
Base *base;
Object *ob;
+ World *world = scene->world;
SceneRenderLayer *srl = v3d->scenelock ? BLI_findlink(&scene->r.layers, scene->r.actlay) : NULL;
BLI_listbase_clear(&shadows);
@@ -2541,7 +2586,7 @@ static void gpu_update_lamps_shadows(Scene *scene, View3D *v3d)
ED_view3d_draw_offscreen(
scene, v3d, &ar, winsize, winsize, viewmat, winmat,
false, false, true,
- NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL);
GPU_lamp_shadow_buffer_unbind(shadow->lamp);
v3d->drawtype = drawtype;
@@ -2550,11 +2595,19 @@ static void gpu_update_lamps_shadows(Scene *scene, View3D *v3d)
}
BLI_freelistN(&shadows);
+
+ /* update world values */
+ if (world) {
+ GPU_mist_update_enable(world->mode & WO_MIST);
+ GPU_mist_update_values(world->mistype, world->miststa, world->mistdist, world->misi, &world->horr);
+ GPU_horizon_update_color(&world->horr);
+ GPU_ambient_update_color(&world->ambr);
+ }
}
/* *********************** customdata **************** */
-CustomDataMask ED_view3d_datamask(Scene *scene, View3D *v3d)
+CustomDataMask ED_view3d_datamask(const Scene *scene, const View3D *v3d)
{
CustomDataMask mask = 0;
@@ -2580,16 +2633,16 @@ CustomDataMask ED_view3d_datamask(Scene *scene, View3D *v3d)
}
/* goes over all modes and view3d settings */
-CustomDataMask ED_view3d_screen_datamask(bScreen *screen)
+CustomDataMask ED_view3d_screen_datamask(const bScreen *screen)
{
- Scene *scene = screen->scene;
+ const Scene *scene = screen->scene;
CustomDataMask mask = CD_MASK_BAREMESH;
- ScrArea *sa;
+ const ScrArea *sa;
/* check if we need tfaces & mcols due to view mode */
for (sa = screen->areabase.first; sa; sa = sa->next) {
if (sa->spacetype == SPACE_VIEW3D) {
- mask |= ED_view3d_datamask(scene, (View3D *)sa->spacedata.first);
+ mask |= ED_view3d_datamask(scene, sa->spacedata.first);
}
}
@@ -2674,7 +2727,7 @@ static void view3d_draw_objects(
const bool draw_grids = !draw_offscreen && (v3d->flag2 & V3D_RENDER_OVERRIDE) == 0;
const bool draw_floor = (rv3d->view == RV3D_VIEW_USER) || (rv3d->persp != RV3D_ORTHO);
/* only draw grids after in solid modes, else it hovers over mesh wires */
- const bool draw_grids_after = draw_grids && draw_floor && (v3d->drawtype > OB_WIRE);
+ const bool draw_grids_after = draw_grids && draw_floor && (v3d->drawtype > OB_WIRE) && fx;
bool do_composite_xray = false;
bool xrayclear = true;
@@ -2723,8 +2776,8 @@ static void view3d_draw_objects(
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(rv3d->viewmat);
}
- else {
- drawfloor(scene, v3d, grid_unit);
+ else if (!draw_grids_after) {
+ drawfloor(scene, v3d, grid_unit, true);
}
}
@@ -2802,7 +2855,7 @@ static void view3d_draw_objects(
/* perspective floor goes last to use scene depth and avoid writing to depth buffer */
if (draw_grids_after) {
- drawfloor(scene, v3d, grid_unit);
+ drawfloor(scene, v3d, grid_unit, false);
}
/* must be before xray draw which clears the depth buffer */
@@ -2873,7 +2926,7 @@ void ED_view3d_draw_offscreen_init(Scene *scene, View3D *v3d)
{
/* shadow buffers, before we setup matrices */
if (draw_glsl_material(scene, NULL, v3d, v3d->drawtype))
- gpu_update_lamps_shadows(scene, v3d);
+ gpu_update_lamps_shadows_world(scene, v3d);
}
/*
@@ -2887,21 +2940,41 @@ static void view3d_main_area_clear(Scene *scene, View3D *v3d, ARegion *ar)
if (glsl) {
RegionView3D *rv3d = ar->regiondata;
GPUMaterial *gpumat = GPU_material_world(scene, scene->world);
+ bool material_not_bound;
/* calculate full shader for background */
GPU_material_bind(gpumat, 1, 1, 1.0, false, rv3d->viewmat, rv3d->viewinv, rv3d->viewcamtexcofac, (v3d->scenelock != 0));
+ material_not_bound = !GPU_material_bound(gpumat);
+
+ if (material_not_bound) {
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+ glLoadIdentity();
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glLoadIdentity();
+ glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
+ }
+
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_ALWAYS);
glShadeModel(GL_SMOOTH);
- glBegin(GL_QUADS);
+ glBegin(GL_TRIANGLE_STRIP);
glVertex3f(-1.0, -1.0, 1.0);
glVertex3f(1.0, -1.0, 1.0);
- glVertex3f(1.0, 1.0, 1.0);
glVertex3f(-1.0, 1.0, 1.0);
+ glVertex3f(1.0, 1.0, 1.0);
glEnd();
glShadeModel(GL_FLAT);
+ if (material_not_bound) {
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix();
+ glMatrixMode(GL_MODELVIEW);
+ glPopMatrix();
+ }
+
GPU_material_unbind(gpumat);
glDepthFunc(GL_LEQUAL);
@@ -3079,7 +3152,8 @@ void ED_view3d_draw_offscreen(
float viewmat[4][4], float winmat[4][4],
bool do_bgpic, bool do_sky, bool is_persp,
GPUOffScreen *ofs,
- GPUFX *fx, GPUFXSettings *fx_settings)
+ GPUFX *fx, GPUFXSettings *fx_settings,
+ const char *viewname)
{
struct bThemeState theme_state;
int bwinx, bwiny;
@@ -3114,11 +3188,24 @@ void ED_view3d_draw_offscreen(
}
/* setup view matrices before fx or unbinding the offscreen buffers will cause issues */
- view3d_main_area_setup_view(scene, v3d, ar, viewmat, winmat);
+ if ((viewname != NULL && viewname[0] != '\0') && (viewmat == NULL) && rv3d->persp == RV3D_CAMOB && v3d->camera)
+ view3d_stereo3d_setup_offscreen(scene, v3d, ar, winmat, viewname);
+ else
+ view3d_main_area_setup_view(scene, v3d, ar, viewmat, winmat);
/* framebuffer fx needed, we need to draw offscreen first */
if (v3d->fx_settings.fx_flag && fx) {
+ GPUSSAOSettings *ssao = NULL;
+
+ if (v3d->drawtype < OB_SOLID) {
+ ssao = v3d->fx_settings.ssao;
+ v3d->fx_settings.ssao = NULL;
+ }
+
do_compositing = GPU_fx_compositor_initialize_passes(fx, &ar->winrct, NULL, fx_settings);
+
+ if (ssao)
+ v3d->fx_settings.ssao = ssao;
}
/* clear opengl buffers */
@@ -3168,13 +3255,16 @@ void ED_view3d_draw_offscreen(
/* utility func for ED_view3d_draw_offscreen */
ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, int sizex, int sizey, unsigned int flag,
- bool draw_background, int alpha_mode, char err_out[256])
+ bool draw_background, int alpha_mode, const char *viewname, char err_out[256])
{
RegionView3D *rv3d = ar->regiondata;
ImBuf *ibuf;
GPUOffScreen *ofs;
bool draw_sky = (alpha_mode == R_ADDSKY) && v3d && (v3d->flag3 & V3D_SHOW_WORLD);
+ if (UNLIKELY(v3d == NULL))
+ return NULL;
+
/* state changes make normal drawing go weird otherwise */
glPushAttrib(GL_LIGHTING_BIT);
@@ -3193,13 +3283,14 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, in
if (rv3d->persp == RV3D_CAMOB && v3d->camera) {
CameraParams params;
GPUFXSettings fx_settings = {NULL};
- Object *camera = v3d->camera;
+ Object *camera = BKE_camera_multiview_render(scene, v3d->camera, viewname);
BKE_camera_params_init(&params);
/* fallback for non camera objects */
params.clipsta = v3d->near;
params.clipend = v3d->far;
- BKE_camera_params_from_object(&params, v3d->camera);
+ BKE_camera_params_from_object(&params, camera);
+ BKE_camera_multiview_params(&scene->r, &params, camera, viewname);
BKE_camera_params_compute_viewplane(&params, sizex, sizey, scene->r.xasp, scene->r.yasp);
BKE_camera_params_compute_matrix(&params);
@@ -3208,13 +3299,13 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, in
ED_view3d_draw_offscreen(
scene, v3d, ar, sizex, sizey, NULL, params.winmat,
draw_background, draw_sky, !params.is_ortho,
- ofs, NULL, &fx_settings);
+ ofs, NULL, &fx_settings, viewname);
}
else {
ED_view3d_draw_offscreen(
scene, v3d, ar, sizex, sizey, NULL, NULL,
draw_background, draw_sky, true,
- ofs, NULL, NULL);
+ ofs, NULL, NULL, viewname);
}
/* read in pixels & stamp */
@@ -3239,7 +3330,8 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, in
/* creates own 3d views, used by the sequencer */
ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Scene *scene, Object *camera, int width, int height, unsigned int flag, int drawtype,
- bool use_solid_tex, bool use_gpencil, bool draw_background, int alpha_mode, char err_out[256])
+ bool use_solid_tex, bool use_gpencil, bool draw_background, int alpha_mode,
+ const char *viewname, char err_out[256])
{
View3D v3d = {NULL};
ARegion ar = {NULL};
@@ -3269,9 +3361,11 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Scene *scene, Object *camera, int w
{
CameraParams params;
+ Object *camera = BKE_camera_multiview_render(scene, v3d.camera, viewname);
BKE_camera_params_init(&params);
- BKE_camera_params_from_object(&params, v3d.camera);
+ BKE_camera_params_from_object(&params, camera);
+ BKE_camera_multiview_params(&scene->r, &params, camera, viewname);
BKE_camera_params_compute_viewplane(&params, width, height, scene->r.xasp, scene->r.yasp);
BKE_camera_params_compute_matrix(&params);
@@ -3285,7 +3379,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Scene *scene, Object *camera, int w
invert_m4_m4(rv3d.persinv, rv3d.viewinv);
return ED_view3d_draw_offscreen_imbuf(scene, &v3d, &ar, width, height, flag,
- draw_background, alpha_mode, err_out);
+ draw_background, alpha_mode, viewname, err_out);
// seq_view3d_cb(scene, cfra, render_size, seqrectx, seqrecty);
}
@@ -3490,6 +3584,104 @@ static void view3d_main_area_draw_engine_info(View3D *v3d, RegionView3D *rv3d, A
ED_region_info_draw(ar, rv3d->render_engine->text, 1, fill_color);
}
+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_area_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_area_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_area_setup_view(scene, v3d, ar, viewmat, NULL);
+
+ v3d->camera = view_ob;
+ BLI_unlock_thread(LOCK_VIEW3D);
+ }
+}
+
+static void view3d_stereo3d_setup_offscreen(Scene *scene, View3D *v3d, ARegion *ar,
+ float winmat[4][4], const char *viewname)
+{
+ /* update the viewport matrices with the new camera */
+ if (scene->r.views_format == SCE_VIEWS_FORMAT_STEREO_3D) {
+ float viewmat[4][4];
+ const bool is_left = STREQ(viewname, STEREO_LEFT_NAME);
+
+ BKE_camera_multiview_view_matrix(&scene->r, v3d->camera, is_left, viewmat);
+ view3d_main_area_setup_view(scene, v3d, ar, viewmat, winmat);
+ }
+ else { /* SCE_VIEWS_FORMAT_MULTIVIEW */
+ float viewmat[4][4];
+ Object *camera = BKE_camera_multiview_render(scene, v3d->camera, viewname);
+
+ BKE_camera_multiview_view_matrix(&scene->r, camera, false, viewmat);
+ view3d_main_area_setup_view(scene, v3d, ar, viewmat, winmat);
+ }
+}
+
#ifdef WITH_GAMEENGINE
static void update_lods(Scene *scene, float camera_pos[3])
{
@@ -3515,16 +3707,19 @@ static void view3d_main_area_draw_objects(const bContext *C, Scene *scene, View3
/* shadow buffers, before we setup matrices */
if (draw_glsl_material(scene, NULL, v3d, v3d->drawtype))
- gpu_update_lamps_shadows(scene, v3d);
-
+ gpu_update_lamps_shadows_world(scene, v3d);
+
/* reset default OpenGL lights if needed (i.e. after preferences have been altered) */
if (rv3d->rflag & RV3D_GPULIGHT_UPDATE) {
rv3d->rflag &= ~RV3D_GPULIGHT_UPDATE;
GPU_default_lights();
}
- /* setup view matrices */
- view3d_main_area_setup_view(scene, v3d, ar, NULL, NULL);
+ /* setup the view matrix */
+ if (view3d_stereo3d_active(C, scene, v3d, rv3d))
+ view3d_stereo3d_setup(scene, v3d, ar);
+ else
+ view3d_main_area_setup_view(scene, v3d, ar, NULL, NULL);
rv3d->rflag &= ~RV3D_IS_GAME_ENGINE;
#ifdef WITH_GAMEENGINE
@@ -3537,7 +3732,7 @@ static void view3d_main_area_draw_objects(const bContext *C, Scene *scene, View3
#endif
/* framebuffer fx needed, we need to draw offscreen first */
- if (v3d->fx_settings.fx_flag) {
+ if (v3d->fx_settings.fx_flag && v3d->drawtype >= OB_SOLID) {
GPUFXSettings fx_settings;
BKE_screen_gpu_fx_validate(&v3d->fx_settings);
fx_settings = v3d->fx_settings;
@@ -3549,6 +3744,7 @@ static void view3d_main_area_draw_objects(const bContext *C, Scene *scene, View3
else {
fx_settings.dof = NULL;
}
+
do_compositing = GPU_fx_compositor_initialize_passes(rv3d->compositor, &ar->winrct, &ar->drawrct, &fx_settings);
}
@@ -3606,7 +3802,7 @@ static bool is_cursor_visible(Scene *scene)
else if (ob->mode & OB_MODE_TEXTURE_PAINT) {
const Paint *p = BKE_paint_get_active(scene);
- if (p && p->brush->imagepaint_tool == PAINT_TOOL_CLONE) {
+ if (p && p->brush && p->brush->imagepaint_tool == PAINT_TOOL_CLONE) {
if ((scene->toolsettings->imapaint.flag & IMAGEPAINT_PROJECT_LAYER_CLONE) == 0) {
return true;
}
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index 0bced34e465..d38de4a426e 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -28,7 +28,6 @@
* \ingroup spview3d
*/
-
#include <string.h>
#include <stdio.h>
#include <math.h>
@@ -38,7 +37,6 @@
#include "DNA_curve_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
-#include "DNA_camera_types.h"
#include "MEM_guardedalloc.h"
@@ -75,7 +73,6 @@
#include "ED_transform.h"
#include "ED_mesh.h"
#include "ED_view3d.h"
-#include "ED_sculpt.h"
#include "UI_resources.h"
@@ -83,7 +80,7 @@
#include "view3d_intern.h" /* own include */
-bool ED_view3d_offset_lock_check(struct View3D *v3d, struct RegionView3D *rv3d)
+bool ED_view3d_offset_lock_check(const View3D *v3d, const RegionView3D *rv3d)
{
return (rv3d->persp != RV3D_CAMOB) && (v3d->ob_centre_cursor || v3d->ob_centre);
}
@@ -103,7 +100,7 @@ static bool view3d_operator_offset_lock_check(bContext *C, wmOperator *op)
/* ********************** view3d_edit: view manipulations ********************* */
-bool ED_view3d_camera_lock_check(View3D *v3d, RegionView3D *rv3d)
+bool ED_view3d_camera_lock_check(const View3D *v3d, const RegionView3D *rv3d)
{
return ((v3d->camera) &&
(v3d->camera->id.lib == NULL) &&
@@ -520,6 +517,7 @@ void ED_view3d_quadview_update(ScrArea *sa, ARegion *ar, bool do_clip)
typedef struct ViewOpsData {
/* context pointers (assigned by viewops_data_alloc) */
+ Scene *scene;
ScrArea *sa;
ARegion *ar;
View3D *v3d;
@@ -592,6 +590,7 @@ static void viewops_data_alloc(bContext *C, wmOperator *op)
/* store data */
op->customdata = vod;
+ vod->scene = CTX_data_scene(C);
vod->sa = CTX_wm_area(C);
vod->ar = CTX_wm_region(C);
vod->v3d = vod->sa->spacedata.first;
@@ -1313,7 +1312,7 @@ void VIEW3D_OT_rotate(wmOperatorType *ot)
ot->cancel = viewrotate_cancel;
/* flags */
- ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_POINTER;
+ ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_CURSOR;
}
/** \name NDOF Utility Functions
@@ -2056,7 +2055,7 @@ void VIEW3D_OT_move(wmOperatorType *ot)
ot->cancel = viewmove_cancel;
/* flags */
- ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_POINTER;
+ ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_CURSOR;
}
/* ************************ viewzoom ******************************** */
@@ -2096,16 +2095,63 @@ void viewzoom_modal_keymap(wmKeyConfig *keyconf)
WM_modalkeymap_assign(keymap, "VIEW3D_OT_zoom");
}
-static void view_zoom_mouseloc(ARegion *ar, float dfac, int mx, int my)
+static void view_zoom_mouseloc_camera(
+ Scene *scene, View3D *v3d,
+ ARegion *ar, float dfac, int mx, int my)
{
RegionView3D *rv3d = ar->regiondata;
+ const float zoomfac = BKE_screen_view3d_zoom_to_fac(rv3d->camzoom);
+ const float zoomfac_new = CLAMPIS(zoomfac * (1.0f / dfac), RV3D_CAMZOOM_MIN_FACTOR, RV3D_CAMZOOM_MAX_FACTOR);
+ const float camzoom_new = BKE_screen_view3d_zoom_from_fac(zoomfac_new);
+
+
+ if (U.uiflag & USER_ZOOM_TO_MOUSEPOS) {
+ float zoomfac_px;
+ rctf camera_frame_old;
+ rctf camera_frame_new;
+
+ const float pt_src[2] = {mx, my};
+ float pt_dst[2];
+ float delta_px[2];
+
+ ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &camera_frame_old, false);
+ BLI_rctf_translate(&camera_frame_old, ar->winrct.xmin, ar->winrct.ymin);
+
+ rv3d->camzoom = camzoom_new;
+ CLAMP(rv3d->camzoom, RV3D_CAMZOOM_MIN, RV3D_CAMZOOM_MAX);
+
+ ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &camera_frame_new, false);
+ BLI_rctf_translate(&camera_frame_new, ar->winrct.xmin, ar->winrct.ymin);
+
+ BLI_rctf_transform_pt_v(&camera_frame_new, &camera_frame_old, pt_dst, pt_src);
+ sub_v2_v2v2(delta_px, pt_dst, pt_src);
+
+ /* translate the camera offset using pixel space delta
+ * mapped back to the camera (same logic as panning in camera view) */
+ zoomfac_px = BKE_screen_view3d_zoom_to_fac(rv3d->camzoom) * 2.0f;
+
+ rv3d->camdx += delta_px[0] / (ar->winx * zoomfac_px);
+ rv3d->camdy += delta_px[1] / (ar->winy * zoomfac_px);
+ CLAMP(rv3d->camdx, -1.0f, 1.0f);
+ CLAMP(rv3d->camdy, -1.0f, 1.0f);
+ }
+ else {
+ rv3d->camzoom = camzoom_new;
+ CLAMP(rv3d->camzoom, RV3D_CAMZOOM_MIN, RV3D_CAMZOOM_MAX);
+ }
+}
+
+static void view_zoom_mouseloc_3d(ARegion *ar, float dfac, int mx, int my)
+{
+ RegionView3D *rv3d = ar->regiondata;
+ const float dist_new = rv3d->dist * dfac;
if (U.uiflag & USER_ZOOM_TO_MOUSEPOS) {
float dvec[3];
float tvec[3];
float tpos[3];
float mval_f[2];
- float new_dist;
+
float zfac;
negate_v3_v3(tpos, rv3d->ofs);
@@ -2122,105 +2168,133 @@ static void view_zoom_mouseloc(ARegion *ar, float dfac, int mx, int my)
negate_v3(tvec);
/* Offset to target position and dolly */
- new_dist = rv3d->dist * dfac;
-
copy_v3_v3(rv3d->ofs, tvec);
- rv3d->dist = new_dist;
+ rv3d->dist = dist_new;
/* Calculate final offset */
madd_v3_v3v3fl(rv3d->ofs, tvec, dvec, dfac);
}
else {
- rv3d->dist *= dfac;
+ rv3d->dist = dist_new;
}
}
-
-static void viewzoom_apply(ViewOpsData *vod, const int xy[2], const short viewzoom, const short zoom_invert)
+static float viewzoom_scale_value(
+ const rcti *winrct,
+ const short viewzoom,
+ const bool zoom_invert, const bool zoom_invert_force,
+ const int xy[2], const int xy_orig[2],
+ const float val, const float val_orig,
+ double *r_timer_lastdraw)
{
- float zfac = 1.0;
- bool use_cam_zoom;
- float dist_range[2];
-
- use_cam_zoom = (vod->rv3d->persp == RV3D_CAMOB) && !(vod->rv3d->is_persp && ED_view3d_camera_lock_check(vod->v3d, vod->rv3d));
-
- ED_view3d_dist_range_get(vod->v3d, dist_range);
-
- if (use_cam_zoom) {
- float delta;
- delta = (xy[0] - vod->origx + xy[1] - vod->origy) / 10.0f;
- vod->rv3d->camzoom = vod->camzoom_prev + (zoom_invert ? -delta : delta);
-
- CLAMP(vod->rv3d->camzoom, RV3D_CAMZOOM_MIN, RV3D_CAMZOOM_MAX);
- }
+ float zfac;
if (viewzoom == USER_ZOOM_CONT) {
double time = PIL_check_seconds_timer();
- float time_step = (float)(time - vod->timer_lastdraw);
+ float time_step = (float)(time - *r_timer_lastdraw);
float fac;
if (U.uiflag & USER_ZOOM_HORIZ) {
- fac = (float)(vod->origx - xy[0]);
+ fac = (float)(xy_orig[0] - xy[0]);
}
else {
- fac = (float)(vod->origy - xy[1]);
+ fac = (float)(xy_orig[1] - xy[1]);
}
- if (zoom_invert) {
+ if (zoom_invert != zoom_invert_force) {
fac = -fac;
}
/* oldstyle zoom */
zfac = 1.0f + ((fac / 20.0f) * time_step);
- vod->timer_lastdraw = time;
+ *r_timer_lastdraw = time;
}
else if (viewzoom == USER_ZOOM_SCALE) {
/* method which zooms based on how far you move the mouse */
const int ctr[2] = {
- BLI_rcti_cent_x(&vod->ar->winrct),
- BLI_rcti_cent_y(&vod->ar->winrct),
+ BLI_rcti_cent_x(winrct),
+ BLI_rcti_cent_y(winrct),
};
- const float len_new = 5 + len_v2v2_int(ctr, xy);
- const float len_old = 5 + len_v2v2_int(ctr, &vod->origx);
- zfac = vod->dist_prev * ((len_old + 5) / (len_new + 5)) / vod->rv3d->dist;
+ float len_new = 5 + len_v2v2_int(ctr, xy);
+ float len_old = 5 + len_v2v2_int(ctr, xy_orig);
+
+ /* intentionally ignore 'zoom_invert' for scale */
+ if (zoom_invert_force) {
+ SWAP(float, len_new, len_old);
+ }
+
+ zfac = val_orig * (len_old / max_ff(len_new, 1.0f)) / val;
}
else { /* USER_ZOOM_DOLLY */
- float len1, len2;
-
+ float len_new = 5;
+ float len_old = 5;
+
if (U.uiflag & USER_ZOOM_HORIZ) {
- len1 = (vod->ar->winrct.xmax - xy[0]) + 5;
- len2 = (vod->ar->winrct.xmax - vod->origx) + 5;
+ len_new += (winrct->xmax - xy[0]);
+ len_old += (winrct->xmax - xy_orig[0]);
}
else {
- len1 = (vod->ar->winrct.ymax - xy[1]) + 5;
- len2 = (vod->ar->winrct.ymax - vod->origy) + 5;
- }
- if (zoom_invert) {
- SWAP(float, len1, len2);
- }
-
- if (use_cam_zoom) {
- /* zfac is ignored in this case, see below */
-#if 0
- zfac = vod->camzoom_prev * (2.0f * ((len1 / len2) - 1.0f) + 1.0f) / vod->rv3d->camzoom;
-#endif
+ len_new += (winrct->ymax - xy[1]);
+ len_old += (winrct->ymax - xy_orig[1]);
}
- else {
- zfac = vod->dist_prev * (2.0f * ((len1 / len2) - 1.0f) + 1.0f) / vod->rv3d->dist;
+
+ if (zoom_invert != zoom_invert_force) {
+ SWAP(float, len_new, len_old);
}
+
+ zfac = val_orig * (2.0f * ((len_new / max_ff(len_old, 1.0f)) - 1.0f) + 1.0f) / val;
}
- if (!use_cam_zoom) {
- if (zfac != 1.0f) {
- const float zfac_min = dist_range[0] / vod->rv3d->dist;
- const float zfac_max = dist_range[1] / vod->rv3d->dist;
- CLAMP(zfac, zfac_min, zfac_max);
- if (zfac != 1.0f) {
- view_zoom_mouseloc(vod->ar, zfac, vod->oldx, vod->oldy);
- }
- }
+ return zfac;
+}
+
+static void viewzoom_apply_camera(
+ ViewOpsData *vod, const int xy[2],
+ const short viewzoom, const bool zoom_invert)
+{
+ float zfac;
+ float zoomfac_prev = BKE_screen_view3d_zoom_to_fac(vod->camzoom_prev) * 2.0f;
+ float zoomfac = BKE_screen_view3d_zoom_to_fac(vod->rv3d->camzoom) * 2.0f;
+
+ zfac = viewzoom_scale_value(
+ &vod->ar->winrct, viewzoom, zoom_invert, true, xy, &vod->origx,
+ zoomfac, zoomfac_prev,
+ &vod->timer_lastdraw);
+
+ if (zfac != 1.0f && zfac != 0.0f) {
+ /* calculate inverted, then invert again (needed because of camera zoom scaling) */
+ zfac = 1.0f / zfac;
+ view_zoom_mouseloc_camera(
+ vod->scene, vod->v3d,
+ vod->ar, zfac, vod->oldx, vod->oldy);
+ }
+
+ ED_region_tag_redraw(vod->ar);
+}
+
+static void viewzoom_apply_3d(
+ ViewOpsData *vod, const int xy[2],
+ const short viewzoom, const bool zoom_invert)
+{
+ float zfac;
+ float dist_range[2];
+
+ ED_view3d_dist_range_get(vod->v3d, dist_range);
+
+ zfac = viewzoom_scale_value(
+ &vod->ar->winrct, viewzoom, zoom_invert, false, xy, &vod->origx,
+ vod->rv3d->dist, vod->dist_prev,
+ &vod->timer_lastdraw);
+
+ if (zfac != 1.0f) {
+ const float zfac_min = dist_range[0] / vod->rv3d->dist;
+ const float zfac_max = dist_range[1] / vod->rv3d->dist;
+ CLAMP(zfac, zfac_min, zfac_max);
+
+ view_zoom_mouseloc_3d(
+ vod->ar, zfac, vod->oldx, vod->oldy);
}
/* these limits were in old code too */
@@ -2234,6 +2308,19 @@ static void viewzoom_apply(ViewOpsData *vod, const int xy[2], const short viewzo
ED_region_tag_redraw(vod->ar);
}
+static void viewzoom_apply(
+ ViewOpsData *vod, const int xy[2],
+ const short viewzoom, const bool zoom_invert)
+{
+ if ((vod->rv3d->persp == RV3D_CAMOB) &&
+ (vod->rv3d->is_persp && ED_view3d_camera_lock_check(vod->v3d, vod->rv3d)) == 0)
+ {
+ viewzoom_apply_camera(vod, xy, viewzoom, zoom_invert);
+ }
+ else {
+ viewzoom_apply_3d(vod, xy, viewzoom, zoom_invert);
+ }
+}
static int viewzoom_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
@@ -2294,6 +2381,7 @@ static int viewzoom_modal(bContext *C, wmOperator *op, const wmEvent *event)
static int viewzoom_exec(bContext *C, wmOperator *op)
{
+ Scene *scene = CTX_data_scene(C);
View3D *v3d;
RegionView3D *rv3d;
ScrArea *sa;
@@ -2326,22 +2414,26 @@ static int viewzoom_exec(bContext *C, wmOperator *op)
ED_view3d_dist_range_get(v3d, dist_range);
if (delta < 0) {
+ const float step = 1.2f;
/* this min and max is also in viewmove() */
if (use_cam_zoom) {
- rv3d->camzoom -= 10.0f;
- if (rv3d->camzoom < RV3D_CAMZOOM_MIN) rv3d->camzoom = RV3D_CAMZOOM_MIN;
+ view_zoom_mouseloc_camera(scene, v3d, ar, step, mx, my);
}
- else if (rv3d->dist < dist_range[1]) {
- view_zoom_mouseloc(ar, 1.2f, mx, my);
+ else {
+ if (rv3d->dist < dist_range[1]) {
+ view_zoom_mouseloc_3d(ar, step, mx, my);
+ }
}
}
else {
+ const float step = 1.0f / 1.2f;
if (use_cam_zoom) {
- rv3d->camzoom += 10.0f;
- if (rv3d->camzoom > RV3D_CAMZOOM_MAX) rv3d->camzoom = RV3D_CAMZOOM_MAX;
+ view_zoom_mouseloc_camera(scene, v3d, ar, step, mx, my);
}
- else if (rv3d->dist > dist_range[0]) {
- view_zoom_mouseloc(ar, 0.83333f, mx, my);
+ else {
+ if (rv3d->dist > dist_range[0]) {
+ view_zoom_mouseloc_3d(ar, step, mx, my);
+ }
}
}
@@ -2471,7 +2563,7 @@ void VIEW3D_OT_zoom(wmOperatorType *ot)
ot->cancel = viewzoom_cancel;
/* flags */
- ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_POINTER;
+ ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_CURSOR;
RNA_def_int(ot->srna, "delta", 0, INT_MIN, INT_MAX, "Delta", "", INT_MIN, INT_MAX);
prop = RNA_def_int(ot->srna, "mx", 0, 0, INT_MAX, "Zoom Position X", "", 0, INT_MAX);
@@ -2725,7 +2817,7 @@ void VIEW3D_OT_dolly(wmOperatorType *ot)
ot->cancel = viewdolly_cancel;
/* flags */
- ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_POINTER;
+ ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_CURSOR;
RNA_def_int(ot->srna, "delta", 0, INT_MIN, INT_MAX, "Delta", "", INT_MIN, INT_MAX);
RNA_def_int(ot->srna, "mx", 0, 0, INT_MAX, "Zoom Position X", "", 0, INT_MAX);
@@ -3862,7 +3954,7 @@ static int vieworbit_exec(bContext *C, wmOperator *op)
char view_opposite;
PropertyRNA *prop_angle = RNA_struct_find_property(op->ptr, "angle");
float angle = RNA_property_is_set(op->ptr, prop_angle) ?
- RNA_property_float_get(op->ptr, prop_angle) : DEG2RADF((float)U.pad_rot_angle);
+ RNA_property_float_get(op->ptr, prop_angle) : DEG2RADF(U.pad_rot_angle);
/* no NULL check is needed, poll checks */
v3d = CTX_wm_view3d(C);
@@ -4091,7 +4183,7 @@ static int viewroll_exec(bContext *C, wmOperator *op)
rv3d = ar->regiondata;
if ((rv3d->persp != RV3D_CAMOB) || ED_view3d_camera_lock_check(v3d, rv3d)) {
int type = RNA_enum_get(op->ptr, "type");
- float angle = (type == 0) ? RNA_float_get(op->ptr, "angle") : DEG2RADF((float)U.pad_rot_angle);
+ float angle = (type == 0) ? RNA_float_get(op->ptr, "angle") : DEG2RADF(U.pad_rot_angle);
float mousevec[3];
float quat_new[4];
@@ -4515,7 +4607,7 @@ void ED_view3d_cursor3d_position(bContext *C, float fp[3], const int mval[2])
Scene *scene = CTX_data_scene(C);
ARegion *ar = CTX_wm_region(C);
View3D *v3d = CTX_wm_view3d(C);
- RegionView3D *rv3d = CTX_wm_region_view3d(C);
+ RegionView3D *rv3d = ar->regiondata;
bool flip;
bool depth_used = false;
@@ -4550,11 +4642,30 @@ void ED_view3d_cursor3d_update(bContext *C, const int mval[2])
{
Scene *scene = CTX_data_scene(C);
View3D *v3d = CTX_wm_view3d(C);
- float *fp = ED_view3d_cursor3d_get(scene, v3d);
- ED_view3d_cursor3d_position(C, fp, mval);
+ float *fp_curr = ED_view3d_cursor3d_get(scene, v3d);
+ float fp_prev[3];
+
+ copy_v3_v3(fp_prev, fp_curr);
+
+ ED_view3d_cursor3d_position(C, fp_curr, mval);
- if (v3d && v3d->localvd)
+ /* offset the cursor lock to avoid jumping to new offset */
+ if (v3d->ob_centre_cursor) {
+ ARegion *ar = CTX_wm_region(C);
+ RegionView3D *rv3d = ar->regiondata;
+
+ float co_curr[2], co_prev[2];
+
+ if ((ED_view3d_project_float_global(ar, fp_prev, co_prev, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) &&
+ (ED_view3d_project_float_global(ar, fp_curr, co_curr, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK))
+ {
+ rv3d->ofs_lock[0] += (co_curr[0] - co_prev[0]) / (ar->winx * 0.5f);
+ rv3d->ofs_lock[1] += (co_curr[1] - co_prev[1]) / (ar->winy * 0.5f);
+ }
+ }
+
+ if (v3d->localvd)
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
else
WM_event_add_notifier(C, NC_SCENE | NA_EDITED, scene);
@@ -4564,7 +4675,7 @@ static int view3d_cursor3d_invoke(bContext *C, wmOperator *UNUSED(op), const wmE
{
ED_view3d_cursor3d_update(C, event->mval);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void VIEW3D_OT_cursor3d(wmOperatorType *ot)
@@ -4578,7 +4689,7 @@ void VIEW3D_OT_cursor3d(wmOperatorType *ot)
/* api callbacks */
ot->invoke = view3d_cursor3d_invoke;
- ot->poll = ED_operator_view3d_active;
+ ot->poll = ED_operator_region_view3d_active;
/* flags */
// ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
@@ -4704,16 +4815,24 @@ bool ED_view3d_autodist(Scene *scene, ARegion *ar, View3D *v3d,
bglMats mats; /* ZBuffer depth vars */
float depth_close;
double cent[2], p[3];
+ int margin_arr[] = {0, 2, 4};
+ int i;
+ bool depth_ok = false;
/* Get Z Depths, needed for perspective, nice for ortho */
bgl_get_mats(&mats);
ED_view3d_draw_depth(scene, ar, v3d, alphaoverride);
- depth_close = view_autodist_depth_margin(ar, mval, 4);
+ /* Attempt with low margin's first */
+ i = 0;
+ do {
+ depth_close = view_autodist_depth_margin(ar, mval, margin_arr[i++] * U.pixelsize);
+ depth_ok = (depth_close != FLT_MAX);
+ } while ((depth_ok == false) && (i < ARRAY_SIZE(margin_arr)));
- if (depth_close != FLT_MAX) {
- cent[0] = (double)mval[0];
- cent[1] = (double)mval[1];
+ if (depth_ok) {
+ cent[0] = (double)mval[0] + 0.5;
+ cent[1] = (double)mval[1] + 0.5;
if (gluUnProject(cent[0], cent[1], depth_close,
mats.modelview, mats.projection, (GLint *)mats.viewport, &p[0], &p[1], &p[2]))
@@ -4764,8 +4883,8 @@ bool ED_view3d_autodist_simple(ARegion *ar, const int mval[2], float mouse_world
if (depth == FLT_MAX)
return false;
- cent[0] = (double)mval[0];
- cent[1] = (double)mval[1];
+ cent[0] = (double)mval[0] + 0.5;
+ cent[1] = (double)mval[1] + 0.5;
bgl_get_mats(&mats);
diff --git a/source/blender/editors/space_view3d/view3d_fly.c b/source/blender/editors/space_view3d/view3d_fly.c
index da77c4f75f7..469a7e63903 100644
--- a/source/blender/editors/space_view3d/view3d_fly.c
+++ b/source/blender/editors/space_view3d/view3d_fly.c
@@ -296,10 +296,10 @@ static void fly_update_header(bContext *C, FlyInfo *fly)
"Ctrl: free look, "
"X: Upright x axis (%s), "
"Z: Upright z axis (%s), "
- "(+/- | Wheel): speed"),
+ "(+/- | Wheel): speed"),
WM_bool_as_string(fly->xlock != FLY_AXISLOCK_STATE_OFF),
- WM_bool_as_string(fly->zlock != FLY_AXISLOCK_STATE_OFF));
+ WM_bool_as_string(fly->zlock != FLY_AXISLOCK_STATE_OFF));
ED_area_headerprint(CTX_wm_area(C), header);
#undef HEADER_LENGTH
@@ -806,7 +806,7 @@ static int flyApply(bContext *C, FlyInfo *fly)
copy_v3_fl3(upvec, 1.0f, 0.0f, 0.0f);
mul_m3_v3(mat, upvec);
/* Rotate about the relative up vec */
- axis_angle_to_quat(tmp_quat, upvec, (float)moffset[1] * time_redraw * -FLY_ROTATE_FAC);
+ axis_angle_to_quat(tmp_quat, upvec, moffset[1] * time_redraw * -FLY_ROTATE_FAC);
mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat);
if (fly->xlock != FLY_AXISLOCK_STATE_OFF)
@@ -836,7 +836,7 @@ static int flyApply(bContext *C, FlyInfo *fly)
}
/* Rotate about the relative up vec */
- axis_angle_to_quat(tmp_quat, upvec, (float)moffset[0] * time_redraw * FLY_ROTATE_FAC);
+ axis_angle_to_quat(tmp_quat, upvec, moffset[0] * time_redraw * FLY_ROTATE_FAC);
mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat);
if (fly->xlock != FLY_AXISLOCK_STATE_OFF)
diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h
index 25dbc8830fe..95c0ef92680 100644
--- a/source/blender/editors/space_view3d/view3d_intern.h
+++ b/source/blender/editors/space_view3d/view3d_intern.h
@@ -41,14 +41,11 @@ struct BoundBox;
struct DerivedMesh;
struct Object;
struct SmokeDomainSettings;
-struct ViewContext;
struct bAnimVizSettings;
struct bContext;
struct bMotionPath;
struct bPoseChannel;
-struct bScreen;
struct Mesh;
-struct SimDebugData;
struct wmNDOFMotionData;
struct wmOperatorType;
struct wmWindowManager;
@@ -208,7 +205,7 @@ void VIEW3D_OT_localview(struct wmOperatorType *ot);
void VIEW3D_OT_game_start(struct wmOperatorType *ot);
-bool ED_view3d_boundbox_clip_ex(RegionView3D *rv3d, const struct BoundBox *bb, float obmat[4][4]);
+bool ED_view3d_boundbox_clip_ex(const RegionView3D *rv3d, const struct BoundBox *bb, float obmat[4][4]);
bool ED_view3d_boundbox_clip(RegionView3D *rv3d, const struct BoundBox *bb);
void ED_view3d_smooth_view_ex(
@@ -225,8 +222,8 @@ void ED_view3d_smooth_view(
const float *ofs, const float *quat, const float *dist, const float *lens,
const int smooth_viewtx);
-void view3d_winmatrix_set(ARegion *ar, View3D *v3d, const rctf *rect);
-void view3d_viewmatrix_set(Scene *scene, View3D *v3d, RegionView3D *rv3d);
+void view3d_winmatrix_set(ARegion *ar, const View3D *v3d, const rctf *rect);
+void view3d_viewmatrix_set(Scene *scene, const View3D *v3d, RegionView3D *rv3d);
void fly_modal_keymap(struct wmKeyConfig *keyconf);
void walk_modal_keymap(struct wmKeyConfig *keyconf);
diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c
index 8c668b2b8e0..6a2c948aa8d 100644
--- a/source/blender/editors/space_view3d/view3d_ops.c
+++ b/source/blender/editors/space_view3d/view3d_ops.c
@@ -236,6 +236,7 @@ void view3d_keymap(wmKeyConfig *keyconf)
WM_keymap_verify_item(keymap, "VIEW3D_OT_navigate", FKEY, KM_PRESS, KM_SHIFT, 0);
+ /* value is set to KM_NOTHING to avoid conflicts with click type (see T44251) */
WM_keymap_verify_item(keymap, "VIEW3D_OT_smoothview", TIMER1, KM_ANY, KM_ANY, 0);
WM_keymap_add_item(keymap, "VIEW3D_OT_rotate", MOUSEPAN, 0, 0, 0);
diff --git a/source/blender/editors/space_view3d/view3d_project.c b/source/blender/editors/space_view3d/view3d_project.c
index 74e3fde0eec..ba0626c58ea 100644
--- a/source/blender/editors/space_view3d/view3d_project.c
+++ b/source/blender/editors/space_view3d/view3d_project.c
@@ -605,6 +605,14 @@ void ED_view3d_ob_project_mat_get(const RegionView3D *rv3d, Object *ob, float pm
mul_m4_m4m4(pmat, (float (*)[4])rv3d->winmat, vmat);
}
+void ED_view3d_ob_project_mat_get_from_obmat(const RegionView3D *rv3d, float obmat[4][4], float pmat[4][4])
+{
+ float vmat[4][4];
+
+ mul_m4_m4m4(vmat, (float (*)[4])rv3d->viewmat, obmat);
+ mul_m4_m4m4(pmat, (float (*)[4])rv3d->winmat, vmat);
+}
+
/**
* Uses window coordinates (x,y) and depth component z to find a point in
* modelspace */
diff --git a/source/blender/editors/space_view3d/view3d_ruler.c b/source/blender/editors/space_view3d/view3d_ruler.c
index eba31866f54..98b1e846c70 100644
--- a/source/blender/editors/space_view3d/view3d_ruler.c
+++ b/source/blender/editors/space_view3d/view3d_ruler.c
@@ -187,8 +187,9 @@ typedef struct RulerInfo {
/* wm state */
wmWindow *win;
- ARegion *ar;
+ ScrArea *sa;
void *draw_handle_pixel;
+ ARegion *ar; /* re-assigned every modal update */
} RulerInfo;
/* -------------------------------------------------------------------- */
@@ -435,7 +436,7 @@ static void ruler_info_draw_pixel(const struct bContext *C, ARegion *ar, void *a
UnitSettings *unit = &scene->unit;
RulerItem *ruler_item;
RulerInfo *ruler_info = arg;
- RegionView3D *rv3d = ruler_info->ar->regiondata;
+ RegionView3D *rv3d = ar->regiondata;
// ARegion *ar = ruler_info->ar;
const float cap_size = 4.0f;
const float bg_margin = 4.0f * U.pixelsize;
@@ -798,12 +799,14 @@ static int view3d_ruler_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSE
op->customdata = ruler_info;
ruler_info->win = win;
- ruler_info->ar = ar;
+ ruler_info->sa = sa;
ruler_info->draw_handle_pixel = ED_region_draw_cb_activate(ar->type, ruler_info_draw_pixel,
ruler_info, REGION_DRAW_POST_PIXEL);
view3d_ruler_header_update(sa);
+ op->flag |= OP_IS_MODAL_CURSOR_REGION;
+
WM_cursor_modal_set(win, BC_CROSSCURSOR);
WM_event_add_modal_handler(C, op);
@@ -825,15 +828,17 @@ static int view3d_ruler_modal(bContext *C, wmOperator *op, const wmEvent *event)
int exit_code = OPERATOR_RUNNING_MODAL;
RulerInfo *ruler_info = op->customdata;
ScrArea *sa = CTX_wm_area(C);
- ARegion *ar = ruler_info->ar;
+ ARegion *ar = CTX_wm_region(C);
RegionView3D *rv3d = ar->regiondata;
/* its possible to change spaces while running the operator [#34894] */
- if (UNLIKELY(ar != CTX_wm_region(C))) {
+ if (UNLIKELY(sa != ruler_info->sa)) {
exit_code = OPERATOR_FINISHED;
goto exit;
}
+ ruler_info->ar = ar;
+
switch (event->type) {
case LEFTMOUSE:
if (event->val == KM_RELEASE) {
@@ -1019,6 +1024,13 @@ static int view3d_ruler_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
+ if (ruler_info->state == RULER_STATE_DRAG) {
+ op->flag &= ~OP_IS_MODAL_CURSOR_REGION;
+ }
+ else {
+ op->flag |= OP_IS_MODAL_CURSOR_REGION;
+ }
+
if (do_draw) {
view3d_ruler_header_update(sa);
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index d0f22ba58c5..49e42cf164a 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -725,7 +725,7 @@ static void do_lasso_select_meshobject__doSelectVert(void *userData, MVert *mv,
}
static void do_lasso_select_paintvert(ViewContext *vc, const int mcords[][2], short moves, bool extend, bool select)
{
- const int use_zbuf = (vc->v3d->flag & V3D_ZBUF_SELECT);
+ const bool use_zbuf = (vc->v3d->flag & V3D_ZBUF_SELECT) != 0;
Object *ob = vc->obact;
Mesh *me = ob->data;
rcti rect;
@@ -1641,7 +1641,7 @@ static void do_paintvert_box_select__doSelectVert(void *userData, MVert *mv, con
}
static int do_paintvert_box_select(ViewContext *vc, rcti *rect, bool select, bool extend)
{
- const int use_zbuf = (vc->v3d->flag & V3D_ZBUF_SELECT);
+ const bool use_zbuf = (vc->v3d->flag & V3D_ZBUF_SELECT) != 0;
Mesh *me;
MVert *mvert;
struct ImBuf *ibuf;
@@ -1662,7 +1662,7 @@ static int do_paintvert_box_select(ViewContext *vc, rcti *rect, bool select, boo
if (use_zbuf) {
selar = MEM_callocN(me->totvert + 1, "selar");
- view3d_validate_backbuf(vc);
+ ED_view3d_backbuf_validate(vc);
ibuf = IMB_allocImBuf(sx, sy, 32, IB_rect);
rt = ibuf->rect;
@@ -2185,7 +2185,7 @@ void VIEW3D_OT_select_border(wmOperatorType *ot)
static bool mouse_weight_paint_vertex_select(bContext *C, const int mval[2], bool extend, bool deselect, bool toggle, Object *obact)
{
View3D *v3d = CTX_wm_view3d(C);
- const int use_zbuf = (v3d->flag & V3D_ZBUF_SELECT);
+ const bool use_zbuf = (v3d->flag & V3D_ZBUF_SELECT) != 0;
Mesh *me = obact->data; /* already checked for NULL */
unsigned int index = 0;
@@ -2453,7 +2453,7 @@ static void paint_vertsel_circle_select_doSelectVert(void *userData, MVert *mv,
}
static void paint_vertsel_circle_select(ViewContext *vc, const bool select, const int mval[2], float rad)
{
- const int use_zbuf = (vc->v3d->flag & V3D_ZBUF_SELECT);
+ const bool use_zbuf = (vc->v3d->flag & V3D_ZBUF_SELECT) != 0;
Object *ob = vc->obact;
Mesh *me = ob->data;
bool bbsel;
diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c
index 0608c35129d..8bb84d00c83 100644
--- a/source/blender/editors/space_view3d/view3d_snap.c
+++ b/source/blender/editors/space_view3d/view3d_snap.c
@@ -31,9 +31,7 @@
#include "DNA_armature_types.h"
-#include "DNA_curve_types.h"
#include "DNA_object_types.h"
-#include "DNA_meta_types.h"
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
@@ -43,11 +41,9 @@
#include "BKE_armature.h"
#include "BKE_context.h"
#include "BKE_depsgraph.h"
-#include "BKE_lattice.h"
#include "BKE_main.h"
#include "BKE_mball.h"
#include "BKE_object.h"
-#include "BKE_editmesh.h"
#include "BKE_tracking.h"
#include "WM_api.h"
@@ -60,7 +56,6 @@
#include "ED_transverts.h"
#include "ED_keyframing.h"
#include "ED_screen.h"
-#include "ED_curve.h"
#include "view3d_intern.h"
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index 1c10a857179..529e5fcf756 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -688,7 +688,7 @@ static bool view3d_boundbox_clip_m4(const BoundBox *bb, float persmatob[4][4])
return false;
}
-bool ED_view3d_boundbox_clip_ex(RegionView3D *rv3d, const BoundBox *bb, float obmat[4][4])
+bool ED_view3d_boundbox_clip_ex(const RegionView3D *rv3d, const BoundBox *bb, float obmat[4][4])
{
/* return 1: draw */
@@ -697,7 +697,7 @@ bool ED_view3d_boundbox_clip_ex(RegionView3D *rv3d, const BoundBox *bb, float ob
if (bb == NULL) return true;
if (bb->flag & BOUNDBOX_DISABLED) return true;
- mul_m4_m4m4(persmatob, rv3d->persmat, obmat);
+ mul_m4_m4m4(persmatob, (float(*)[4])rv3d->persmat, obmat);
return view3d_boundbox_clip_m4(bb, persmatob);
}
@@ -710,7 +710,7 @@ bool ED_view3d_boundbox_clip(RegionView3D *rv3d, const BoundBox *bb)
return view3d_boundbox_clip_m4(bb, rv3d->persmatob);
}
-float ED_view3d_depth_read_cached(ViewContext *vc, int x, int y)
+float ED_view3d_depth_read_cached(const ViewContext *vc, int x, int y)
{
ViewDepths *vd = vc->rv3d->depths;
@@ -729,16 +729,19 @@ void ED_view3d_depth_tag_update(RegionView3D *rv3d)
rv3d->depths->damaged = true;
}
-void ED_view3d_dist_range_get(struct View3D *v3d,
- float r_dist_range[2])
+void ED_view3d_dist_range_get(
+ const View3D *v3d,
+ float r_dist_range[2])
{
r_dist_range[0] = v3d->grid * 0.001f;
r_dist_range[1] = v3d->far * 10.0f;
}
/* copies logic of get_view3d_viewplane(), keep in sync */
-bool ED_view3d_clip_range_get(View3D *v3d, RegionView3D *rv3d, float *r_clipsta, float *r_clipend,
- const bool use_ortho_factor)
+bool ED_view3d_clip_range_get(
+ const View3D *v3d, const RegionView3D *rv3d,
+ float *r_clipsta, float *r_clipend,
+ const bool use_ortho_factor)
{
CameraParams params;
@@ -758,8 +761,9 @@ bool ED_view3d_clip_range_get(View3D *v3d, RegionView3D *rv3d, float *r_clipsta,
}
/* also exposed in previewrender.c */
-bool ED_view3d_viewplane_get(View3D *v3d, RegionView3D *rv3d, int winx, int winy,
- rctf *r_viewplane, float *r_clipsta, float *r_clipend, float *r_pixsize)
+bool ED_view3d_viewplane_get(
+ const View3D *v3d, const RegionView3D *rv3d, int winx, int winy,
+ rctf *r_viewplane, float *r_clipsta, float *r_clipend, float *r_pixsize)
{
CameraParams params;
@@ -797,7 +801,7 @@ void ED_view3d_polygon_offset(const RegionView3D *rv3d, const float dist)
/**
* \param rect optional for picking (can be NULL).
*/
-void view3d_winmatrix_set(ARegion *ar, View3D *v3d, const rctf *rect)
+void view3d_winmatrix_set(ARegion *ar, const View3D *v3d, const rctf *rect)
{
RegionView3D *rv3d = ar->regiondata;
rctf viewplane;
@@ -917,7 +921,7 @@ bool ED_view3d_lock(RegionView3D *rv3d)
}
/* don't set windows active in here, is used by renderwin too */
-void view3d_viewmatrix_set(Scene *scene, View3D *v3d, RegionView3D *rv3d)
+void view3d_viewmatrix_set(Scene *scene, const View3D *v3d, RegionView3D *rv3d)
{
if (rv3d->persp == RV3D_CAMOB) { /* obs/camera */
if (v3d->camera) {
@@ -956,7 +960,7 @@ void view3d_viewmatrix_set(Scene *scene, View3D *v3d, RegionView3D *rv3d)
}
else if (v3d->ob_centre_cursor) {
float vec[3];
- copy_v3_v3(vec, ED_view3d_cursor3d_get(scene, v3d));
+ copy_v3_v3(vec, ED_view3d_cursor3d_get(scene, (View3D *)v3d));
translate_m4(rv3d->viewmat, -vec[0], -vec[1], -vec[2]);
use_lock_ofs = true;
}
@@ -1285,7 +1289,7 @@ static bool view3d_localview_init(
}
if (rv3d->persp == RV3D_ORTHO) {
- if (size < 0.0001) {
+ if (size < 0.0001f) {
ok_dist = false;
}
}
@@ -1708,9 +1712,9 @@ void VIEW3D_OT_game_start(wmOperatorType *ot)
/* ************************************** */
-float ED_view3d_pixel_size(RegionView3D *rv3d, const float co[3])
+float ED_view3d_pixel_size(const RegionView3D *rv3d, const float co[3])
{
- return mul_project_m4_v3_zfac(rv3d->persmat, co) * rv3d->pixsize * U.pixelsize;
+ return mul_project_m4_v3_zfac((float(*)[4])rv3d->persmat, co) * rv3d->pixsize * U.pixelsize;
}
float ED_view3d_radius_to_dist_persp(const float angle, const float radius)
@@ -1786,7 +1790,7 @@ float ED_view3d_radius_to_dist(
angle = focallength_to_fov(lens, sensor_size);
/* zoom influences lens, correct this by scaling the angle as a distance (by the zoom-level) */
- angle = ((atanf(tanf(angle / 2.0f) * zoom) * 2.0f));
+ angle = atanf(tanf(angle / 2.0f) * zoom) * 2.0f;
dist = ED_view3d_radius_to_dist_persp(angle, radius);
}
diff --git a/source/blender/editors/space_view3d/view3d_walk.c b/source/blender/editors/space_view3d/view3d_walk.c
index 191eeb05c71..1d5c2a3a169 100644
--- a/source/blender/editors/space_view3d/view3d_walk.c
+++ b/source/blender/editors/space_view3d/view3d_walk.c
@@ -26,8 +26,6 @@
/* defines VIEW3D_OT_navigate - walk modal operator */
-//#define NDOF_WALK_DEBUG
-//#define NDOF_WALK_DRAW_TOOMUCH /* is this needed for ndof? - commented so redraw doesnt thrash - campbell */
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
@@ -58,6 +56,11 @@
#include "view3d_intern.h" /* own include */
+//#define NDOF_WALK_DEBUG
+//#define NDOF_WALK_DRAW_TOOMUCH /* is this needed for ndof? - commented so redraw doesnt thrash - campbell */
+
+#define USE_TABLET_SUPPORT
+
/* prototypes */
static float getVelocityZeroTime(const float gravity, const float velocity);
@@ -220,8 +223,7 @@ void walk_modal_keymap(wmKeyConfig *keyconf)
}
-typedef struct WalkTeleport
-{
+typedef struct WalkTeleport {
eWalkTeleportState state;
float duration; /* from user preferences */
float origin[3];
@@ -277,6 +279,14 @@ typedef struct WalkInfo {
/* mouse reverse */
bool is_reversed;
+#ifdef USE_TABLET_SUPPORT
+ /* check if we had a cursor event before */
+ bool is_cursor_first;
+
+ /* tablet devices (we can't relocate the cursor) */
+ bool is_cursor_absolute;
+#endif
+
/* gravity system */
eWalkGravityState gravity_state;
float gravity;
@@ -345,7 +355,7 @@ static void walk_update_header(bContext *C, WalkInfo *walk)
char header[HEADER_LENGTH];
BLI_snprintf(header, HEADER_LENGTH, IFACE_("LMB/Return: confirm, Esc/RMB: cancel, "
- "Tab: gravity (%s), "
+ "Tab: gravity (%s), "
"WASD: move around, "
"Shift: fast, Alt: slow, "
"QE: up and down, MMB/Space: teleport, V: jump, "
@@ -520,6 +530,12 @@ static bool initWalkInfo(bContext *C, WalkInfo *walk, wmOperator *op)
walk->is_reversed = ((U.walk_navigation.flag & USER_WALK_MOUSE_REVERSE) != 0);
+#ifdef USE_TABLET_SUPPORT
+ walk->is_cursor_first = true;
+
+ walk->is_cursor_absolute = false;
+#endif
+
walk->active_directions = 0;
#ifdef NDOF_WALK_DRAW_TOOMUCH
@@ -587,10 +603,16 @@ static int walkEnd(bContext *C, WalkInfo *walk)
/* restore the cursor */
WM_cursor_modal_restore(win);
- /* center the mouse */
- WM_cursor_warp(win,
- walk->ar->winrct.xmin + walk->center_mval[0],
- walk->ar->winrct.ymin + walk->center_mval[1]);
+#ifdef USE_TABLET_SUPPORT
+ if (walk->is_cursor_absolute == false)
+#endif
+ {
+ /* center the mouse */
+ WM_cursor_warp(
+ win,
+ walk->ar->winrct.xmin + walk->center_mval[0],
+ walk->ar->winrct.ymin + walk->center_mval[1]);
+ }
if (walk->state == WALK_CONFIRM) {
MEM_freeN(walk);
@@ -618,6 +640,27 @@ static void walkEvent(bContext *C, wmOperator *UNUSED(op), WalkInfo *walk, const
}
else if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) {
+#ifdef USE_TABLET_SUPPORT
+ if (walk->is_cursor_first) {
+ /* wait until we get the 'warp' event */
+ if ((walk->center_mval[0] == event->mval[0]) &&
+ (walk->center_mval[1] == event->mval[1]))
+ {
+ walk->is_cursor_first = false;
+ }
+ return;
+ }
+
+ if ((walk->is_cursor_absolute == false) && WM_event_is_absolute(event)) {
+ walk->is_cursor_absolute = true;
+ copy_v2_v2_int(walk->prev_mval, event->mval);
+ copy_v2_v2_int(walk->center_mval, event->mval);
+ /* without this we can't turn 180d */
+ CLAMP_MIN(walk->mouse_speed, 4.0f);
+ }
+#endif /* USE_TABLET_SUPPORT */
+
+
walk->moffset[0] += event->mval[0] - walk->prev_mval[0];
walk->moffset[1] += event->mval[1] - walk->prev_mval[1];
@@ -628,6 +671,12 @@ static void walkEvent(bContext *C, wmOperator *UNUSED(op), WalkInfo *walk, const
{
walk->redraw = true;
+#ifdef USE_TABLET_SUPPORT
+ if (walk->is_cursor_absolute) {
+ /* pass */
+ }
+ else
+#endif
if (wm_event_is_last_mousemove(event)) {
wmWindow *win = CTX_wm_window(C);