diff options
Diffstat (limited to 'source/blender/editors/space_view3d')
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(¶ms); /* fallback for non camera objects */ params.clipsta = v3d->near; params.clipend = v3d->far; - BKE_camera_params_from_object(¶ms, v3d->camera); + BKE_camera_params_from_object(¶ms, camera); + BKE_camera_multiview_params(&scene->r, ¶ms, camera, viewname); BKE_camera_params_compute_viewplane(¶ms, sizex, sizey, scene->r.xasp, scene->r.yasp); BKE_camera_params_compute_matrix(¶ms); @@ -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(¶ms); - BKE_camera_params_from_object(¶ms, v3d.camera); + BKE_camera_params_from_object(¶ms, camera); + BKE_camera_multiview_params(&scene->r, ¶ms, camera, viewname); BKE_camera_params_compute_viewplane(¶ms, width, height, scene->r.xasp, scene->r.yasp); BKE_camera_params_compute_matrix(¶ms); @@ -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); |