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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntony Riakiotakis <kalast@gmail.com>2015-06-10 19:38:23 +0300
committerAntony Riakiotakis <kalast@gmail.com>2015-06-10 19:38:23 +0300
commit080cf9332bc9d71e0e14326bc8efdf06b738dea1 (patch)
treee8531a509dca4d8253aa19d89edc68152421f9e5 /source/blender/editors/space_view3d
parent6d495cc4ef071171ff0686b2be898a41e05b8051 (diff)
parent9676642cc94599b3419c9aaa5cf1aae2fbbd235f (diff)
Merge branch 'gooseberry' into temp_motionpathstemp_motionpaths
Conflicts: source/blender/blenkernel/intern/object.c
Diffstat (limited to 'source/blender/editors/space_view3d')
-rw-r--r--source/blender/editors/space_view3d/CMakeLists.txt2
-rw-r--r--source/blender/editors/space_view3d/SConscript1
-rw-r--r--source/blender/editors/space_view3d/drawanimviz.c1
-rw-r--r--source/blender/editors/space_view3d/drawmesh.c18
-rw-r--r--source/blender/editors/space_view3d/drawobject.c799
-rw-r--r--source/blender/editors/space_view3d/drawsimdebug.c7
-rw-r--r--source/blender/editors/space_view3d/drawstrands.c520
-rw-r--r--source/blender/editors/space_view3d/drawvolume.c111
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c30
-rw-r--r--source/blender/editors/space_view3d/view3d_buttons.c3
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c465
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c402
-rw-r--r--source/blender/editors/space_view3d/view3d_fly.c8
-rw-r--r--source/blender/editors/space_view3d/view3d_header.c10
-rw-r--r--source/blender/editors/space_view3d/view3d_intern.h16
-rw-r--r--source/blender/editors/space_view3d/view3d_ops.c7
-rw-r--r--source/blender/editors/space_view3d/view3d_project.c8
-rw-r--r--source/blender/editors/space_view3d/view3d_ruler.c22
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c31
-rw-r--r--source/blender/editors/space_view3d/view3d_snap.c5
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c245
-rw-r--r--source/blender/editors/space_view3d/view3d_walk.c67
22 files changed, 2064 insertions, 714 deletions
diff --git a/source/blender/editors/space_view3d/CMakeLists.txt b/source/blender/editors/space_view3d/CMakeLists.txt
index ab69e67361d..57c497a2a4d 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
@@ -45,6 +46,7 @@ set(SRC
drawmesh.c
drawobject.c
drawsimdebug.c
+ drawstrands.c
drawvolume.c
space_view3d.c
view3d_buttons.c
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..b374ce64319 100644
--- a/source/blender/editors/space_view3d/drawmesh.c
+++ b/source/blender/editors/space_view3d/drawmesh.c
@@ -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 b44da8a70a6..05a2d5b3ddc 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -54,11 +54,13 @@
#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"
#include "BKE_deform.h"
#include "BKE_displist.h"
+#include "BKE_editstrands.h"
#include "BKE_font.h"
#include "BKE_global.h"
#include "BKE_image.h"
@@ -216,6 +218,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)
{
@@ -302,11 +305,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 +406,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 +428,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 +451,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 +469,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 +487,6 @@ static void draw_xyz_wire(const float c[3], float size, int axis)
glEnd();
break;
}
-
}
void drawaxes(float size, char drawtype)
@@ -597,10 +600,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 +643,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 +943,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 +1025,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 +1033,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 +1147,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 +1205,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 +1215,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 +1369,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 +1475,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 +1565,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 +1621,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 +1689,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 +1697,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 +1811,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])
@@ -1760,6 +2057,12 @@ static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base
const bool is_view = (rv3d->persp == RV3D_CAMOB && ob == v3d->camera);
MovieClip *clip = BKE_object_movieclip_get(scene, base->object, false);
+ const bool is_stereo3d = drawcamera_is_stereo3d(scene, v3d, ob);
+ const bool is_stereo3d_cameras = (ob == scene->camera) &&
+ (scene->r.scemode & R_MULTIVIEW) &&
+ (scene->r.views_format == SCE_VIEWS_FORMAT_STEREO_3D) &&
+ (v3d->stereo3d_flag & V3D_S3D_DISPCAMERAS);
+
/* draw data for movie clip set as active for scene */
if (clip) {
draw_viewport_reconstruction(scene, base, v3d, clip, dflag, ob_wire_col, false);
@@ -1796,12 +2099,8 @@ 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)
+ drawcamera_frame(vec, GL_LINE_LOOP);
if (is_view)
return;
@@ -1809,20 +2108,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 +2163,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 +2284,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 +2564,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 +2630,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 +2646,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 +3043,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 +3336,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 +3374,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 +3393,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 +3451,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 +3476,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 +3594,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 +3625,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 +3637,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 +3651,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 +3707,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 +3822,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 +3843,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 */
@@ -3653,7 +3945,7 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d,
static void draw_mesh_object_outline(View3D *v3d, Object *ob, DerivedMesh *dm)
{
if ((v3d->transp == false) && /* not when we draw the transparent pass */
- (ob->mode & OB_MODE_ALL_PAINT) == false) /* not when painting (its distracting) - campbell */
+ (ob->mode & OB_MODE_ALL_BRUSH) == false) /* not when painting (its distracting) - campbell */
{
glLineWidth(UI_GetThemeValuef(TH_OUTLINE_WIDTH) * 2.0f);
glDepthMask(0);
@@ -3691,7 +3983,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 +4006,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 +4017,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 +4067,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 +4188,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 +4218,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 +4227,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 +4242,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 +4286,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);
@@ -4336,7 +4632,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])
@@ -4980,7 +5276,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);
@@ -5064,7 +5360,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];
@@ -5089,16 +5385,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)
@@ -5146,6 +5443,12 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
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;
@@ -5291,7 +5594,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;
@@ -5397,6 +5700,12 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
case PART_DRAW_COL_PARENT:
particle_path_color(a, ma_col);
break;
+ case PART_DRAW_COL_TEX: {
+ ParticleTexture ptex;
+ psys_get_texture(&sim, pa, &ptex, PAMAP_COLOR, cfra);
+ copy_v3_v3(ma_col, ptex.color);
+ break;
+ }
default:
weight_to_rgb(ma_col, 1.0f);
BLI_assert(0);
@@ -5459,8 +5768,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;
@@ -5488,21 +5797,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);
@@ -5519,7 +5828,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) {
@@ -5583,11 +5892,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);
}
}
@@ -5720,6 +6031,9 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
glColor3fv(col);
}
break;
+ case PART_DRAW_COL_TEX:
+ // TODO
+ break;
default:
break;
}
@@ -5729,7 +6043,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)
@@ -5737,9 +6050,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);
@@ -5748,8 +6062,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);
@@ -5877,7 +6191,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];
@@ -6017,7 +6331,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();
}
}
@@ -6033,9 +6347,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];
@@ -6439,7 +6753,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;
@@ -6799,7 +7113,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);
@@ -6830,16 +7144,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);
@@ -6852,7 +7163,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;
@@ -6916,8 +7227,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;
@@ -6925,7 +7235,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];
@@ -7069,31 +7379,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);
@@ -7107,14 +7409,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);
@@ -7124,20 +7419,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);
@@ -7155,25 +7439,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);
@@ -7244,19 +7522,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)
@@ -7350,7 +7640,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);
@@ -7358,7 +7648,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);
}
@@ -7394,7 +7684,7 @@ static void drawtexspace(Object *ob)
setlinestyle(2);
- draw_box(vec);
+ draw_box(vec, false);
setlinestyle(0);
}
@@ -7581,7 +7871,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) {
@@ -7701,8 +7991,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);
@@ -7734,7 +8027,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);
@@ -7773,7 +8066,8 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
const bool is_picking = (G.f & G_PICKSEL) != 0;
const bool has_particles = (ob->particlesystem.first != NULL);
const bool is_wire_color = V3D_IS_WIRECOLOR_OBJECT(scene, v3d, ob);
- 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)
@@ -7797,17 +8091,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 */
@@ -7908,13 +8222,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) {
@@ -7969,9 +8282,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:
@@ -8090,7 +8400,8 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
/* code for new particle system */
if ((ob->particlesystem.first) &&
- (ob != scene->obedit))
+ (ob != scene->obedit) &&
+ !(ob->transflag & OB_IS_DUPLI_CACHE))
{
ParticleSystem *psys;
@@ -8107,14 +8418,16 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
view3d_cached_text_draw_begin();
for (psys = ob->particlesystem.first; psys; psys = psys->next) {
- /* run this so that possible child particles get cached */
- if (ob->mode & OB_MODE_PARTICLE_EDIT && is_obact) {
- PTCacheEdit *edit = PE_create_current(scene, ob);
- if (edit && edit->psys == psys)
- draw_update_ptcache_edit(scene, ob, edit);
+ if (!(ob->mode & OB_MODE_HAIR_EDIT)) {
+ /* run this so that possible child particles get cached */
+ if (ob->mode & OB_MODE_PARTICLE_EDIT && is_obact) {
+ PTCacheEdit *edit = PE_create_current(scene, ob);
+ if (edit && edit->psys == psys)
+ draw_update_ptcache_edit(scene, ob, edit);
+ }
+
+ draw_new_particle_system(scene, v3d, rv3d, base, psys, dt, dflag);
}
-
- draw_new_particle_system(scene, v3d, rv3d, base, psys, dt, dflag);
}
invert_m4_m4(ob->imat, ob->obmat);
view3d_cached_text_draw_end(v3d, ar, 0, NULL);
@@ -8139,15 +8452,20 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
glMultMatrixf(ob->obmat);
}
}
+
+ if (ob->mode & OB_MODE_HAIR_EDIT && is_obact) {
+ BMEditStrands *edit = BKE_editstrands_from_object(ob);
+ if (edit) {
+ draw_strands_edit_hair(scene, v3d, ar, edit);
+ }
+ }
}
/* 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;
@@ -8174,30 +8492,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
@@ -8205,16 +8523,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]);
@@ -8298,7 +8616,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);
@@ -8347,7 +8664,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
}
/* object centers, need to be drawn in viewmat space for speed, but OK for picking select */
- if (!is_obact || !(ob->mode & OB_MODE_ALL_PAINT)) {
+ if (!is_obact || !(ob->mode & OB_MODE_ALL_BRUSH)) {
int do_draw_center = -1; /* defines below are zero or positive... */
if (render_override) {
@@ -8414,7 +8731,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;
@@ -8439,7 +8756,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};
@@ -8671,7 +8988,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/drawstrands.c b/source/blender/editors/space_view3d/drawstrands.c
new file mode 100644
index 00000000000..af2e04ee3a7
--- /dev/null
+++ b/source/blender/editors/space_view3d/drawstrands.c
@@ -0,0 +1,520 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2014 by the Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Lukas Toenne
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/space_view3d/drawstrands.c
+ * \ingroup spview3d
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_utildefines.h"
+#include "BLI_math.h"
+
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_view3d_types.h"
+
+#include "BKE_editstrands.h"
+#include "BKE_global.h"
+#include "BKE_main.h"
+#include "BKE_strands.h"
+
+#include "bmesh.h"
+
+#include "ED_screen.h"
+#include "ED_types.h"
+
+#include "UI_resources.h"
+#include "UI_interface_icons.h"
+
+#include "BIF_gl.h"
+#include "BIF_glutil.h"
+
+#include "GPU_draw.h"
+#include "GPU_extensions.h"
+#include "GPU_select.h"
+
+#include "view3d_intern.h"
+
+typedef struct StrandsDrawGLState {
+ GLint polygonmode[2];
+} StrandsDrawGLState;
+
+typedef enum StrandsShadeMode {
+ STRANDS_SHADE_FLAT,
+ STRANDS_SHADE_HAIR,
+} StrandsShadeMode;
+
+static void draw_strands_begin(StrandsDrawGLState *state, short dflag)
+{
+ glGetIntegerv(GL_POLYGON_MODE, state->polygonmode);
+ glEnableClientState(GL_VERTEX_ARRAY);
+
+ /* setup gl flags */
+ glEnableClientState(GL_NORMAL_ARRAY);
+
+ if ((dflag & DRAW_CONSTCOLOR) == 0) {
+// if (part->draw_col == PART_DRAW_COL_MAT)
+// glEnableClientState(GL_COLOR_ARRAY);
+ }
+
+ glColor3f(1,1,1);
+ glEnable(GL_LIGHTING);
+// glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
+// glEnable(GL_COLOR_MATERIAL);
+}
+
+static void draw_strands_end(StrandsDrawGLState *state)
+{
+ /* restore & clean up */
+// if (part->draw_col == PART_DRAW_COL_MAT)
+// glDisableClientState(GL_COLOR_ARRAY);
+ glDisable(GL_LIGHTING);
+ glDisable(GL_COLOR_MATERIAL);
+
+ glLineWidth(1.0f);
+
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_NORMAL_ARRAY);
+
+ glPolygonMode(GL_FRONT, state->polygonmode[0]);
+ glPolygonMode(GL_BACK, state->polygonmode[1]);
+}
+
+static void draw_strand_lines(Strands *strands, short dflag)
+{
+ const bool has_motion_state = strands->state;
+ StrandsDrawGLState gl_state;
+ StrandIterator it_strand;
+
+ draw_strands_begin(&gl_state, dflag);
+
+ for (BKE_strand_iter_init(&it_strand, strands); BKE_strand_iter_valid(&it_strand); BKE_strand_iter_next(&it_strand)) {
+ if (it_strand.tot <= 0)
+ continue;
+
+ if (has_motion_state) {
+ glVertexPointer(3, GL_FLOAT, sizeof(StrandsMotionState), it_strand.state->co);
+ glNormalPointer(GL_FLOAT, sizeof(StrandsMotionState), it_strand.state->nor);
+ }
+ else {
+ glVertexPointer(3, GL_FLOAT, sizeof(StrandsVertex), it_strand.verts->co);
+ glNormalPointer(GL_FLOAT, sizeof(StrandsVertex), it_strand.verts->nor);
+ }
+ if ((dflag & DRAW_CONSTCOLOR) == 0) {
+// if (part->draw_col == PART_DRAW_COL_MAT) {
+// glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->col);
+// }
+ }
+
+ glDrawArrays(GL_LINE_STRIP, 0, it_strand.curve->numverts);
+ }
+
+ draw_strands_end(&gl_state);
+}
+
+static void draw_strand_child_lines(StrandsChildren *children, short dflag)
+{
+ StrandsDrawGLState gl_state;
+ StrandChildIterator it_strand;
+
+ draw_strands_begin(&gl_state, dflag);
+
+ for (BKE_strand_child_iter_init(&it_strand, children); BKE_strand_child_iter_valid(&it_strand); BKE_strand_child_iter_next(&it_strand)) {
+ StrandsChildCurve *curve = it_strand.curve;
+ const int numverts = curve->cutoff < 0.0f ? curve->numverts : min_ii(curve->numverts, (int)ceilf(curve->cutoff) + 1);
+
+ if (it_strand.tot <= 0)
+ continue;
+
+ glVertexPointer(3, GL_FLOAT, sizeof(StrandsChildVertex), it_strand.verts->co);
+ glNormalPointer(GL_FLOAT, sizeof(StrandsChildVertex), it_strand.verts->nor);
+
+ if ((dflag & DRAW_CONSTCOLOR) == 0) {
+// if (part->draw_col == PART_DRAW_COL_MAT) {
+// glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->col);
+// }
+ }
+
+
+ glDrawArrays(GL_LINE_STRIP, 0, numverts);
+ }
+
+ draw_strands_end(&gl_state);
+}
+
+void draw_strands(Scene *UNUSED(scene), View3D *UNUSED(v3d), ARegion *ar, Object *ob, Strands *strands, StrandsChildren *children, short dflag)
+{
+ RegionView3D *rv3d = ar->regiondata;
+ float imat[4][4];
+
+ invert_m4_m4(imat, rv3d->viewmatob);
+
+// glDepthMask(GL_FALSE);
+// glEnable(GL_BLEND);
+
+ glPushMatrix();
+
+ glLoadMatrixf(rv3d->viewmat);
+ glMultMatrixf(ob->obmat);
+
+ if (children)
+ draw_strand_child_lines(children, dflag);
+ else
+ draw_strand_lines(strands, dflag);
+
+ glPopMatrix();
+
+// glDepthMask(GL_TRUE);
+// glDisable(GL_BLEND);
+}
+
+/* ------------------------------------------------------------------------- */
+
+typedef struct StrandsDrawInfo {
+ bool has_zbuf;
+ bool use_zbuf_select;
+
+ StrandsShadeMode shade_mode;
+ int select_mode;
+
+ float col_base[4];
+ float col_select[4];
+} StrandsDrawInfo;
+
+BLI_INLINE bool strands_use_normals(const StrandsDrawInfo *info)
+{
+ return ELEM(info->shade_mode, STRANDS_SHADE_HAIR);
+}
+
+static void init_draw_info(StrandsDrawInfo *info, View3D *v3d,
+ StrandsShadeMode shade_mode, int select_mode)
+{
+ info->has_zbuf = v3d->zbuf;
+ info->use_zbuf_select = (v3d->flag & V3D_ZBUF_SELECT);
+
+ info->shade_mode = shade_mode;
+ info->select_mode = select_mode;
+
+ /* get selection theme colors */
+ UI_GetThemeColor4fv(TH_VERTEX, info->col_base);
+ UI_GetThemeColor4fv(TH_VERTEX_SELECT, info->col_select);
+}
+
+static void set_opengl_state_strands(const StrandsDrawInfo *info)
+{
+ if (!info->use_zbuf_select)
+ glDisable(GL_DEPTH_TEST);
+ glEnable(GL_BLEND);
+
+ if (ELEM(info->shade_mode, STRANDS_SHADE_HAIR)) {
+ glEnable(GL_LIGHTING);
+ glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
+ glEnable(GL_COLOR_MATERIAL);
+ glShadeModel(GL_SMOOTH);
+ }
+ else {
+ glDisable(GL_LIGHTING);
+ }
+
+ glEnableClientState(GL_VERTEX_ARRAY);
+ if (strands_use_normals(info))
+ glEnableClientState(GL_NORMAL_ARRAY);
+}
+
+static void set_opengl_state_dots(const StrandsDrawInfo *info)
+{
+ if (!info->use_zbuf_select)
+ glDisable(GL_DEPTH_TEST);
+ glEnable(GL_BLEND);
+
+ glDisable(GL_LIGHTING);
+
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glPointSize(3.0);
+}
+
+static void restore_opengl_state(const StrandsDrawInfo *info)
+{
+ glDisableClientState(GL_NORMAL_ARRAY);
+ glDisableClientState(GL_VERTEX_ARRAY);
+
+ glDisable(GL_BLEND);
+ glDisable(GL_LIGHTING);
+ glDisable(GL_COLOR_MATERIAL);
+ glShadeModel(GL_FLAT);
+ if (info->has_zbuf)
+ glEnable(GL_DEPTH_TEST);
+ glLineWidth(1.0f);
+ glPointSize(1.0);
+}
+
+/* ------------------------------------------------------------------------- */
+/* strands */
+
+static void setup_gpu_buffers_strands(BMEditStrands *edit, const StrandsDrawInfo *info)
+{
+ const size_t size_v3 = sizeof(float) * 3;
+ const size_t size_vertex = (strands_use_normals(info) ? 2*size_v3 : size_v3);
+
+// int totstrands = BM_strands_count(edit->bm);
+ int totvert = edit->bm->totvert;
+ int totedge = edit->bm->totedge;
+
+ if (!edit->vertex_glbuf)
+ glGenBuffers(1, &edit->vertex_glbuf);
+ if (!edit->elem_glbuf)
+ glGenBuffers(1, &edit->elem_glbuf);
+
+ glBindBuffer(GL_ARRAY_BUFFER, edit->vertex_glbuf);
+ glBufferData(GL_ARRAY_BUFFER, size_vertex * totvert, NULL, GL_DYNAMIC_DRAW);
+
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, edit->elem_glbuf);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * totedge * 2, NULL, GL_DYNAMIC_DRAW);
+
+ glVertexPointer(3, GL_FLOAT, size_vertex, NULL);
+ if (strands_use_normals(info))
+ glNormalPointer(GL_FLOAT, size_vertex, (GLubyte *)NULL + size_v3);
+}
+
+static void unbind_gpu_buffers_strands(void)
+{
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+}
+
+static int write_gpu_buffers_strands(BMEditStrands *edit, const StrandsDrawInfo *info)
+{
+ const size_t size_v3 = sizeof(float) * 3;
+ const size_t size_vertex = (strands_use_normals(info) ? 2*size_v3 : size_v3);
+
+ GLubyte *vertex_data;
+ unsigned int *elem_data;
+ BMVert *root, *v, *vprev;
+ BMIter iter, iter_strand;
+ int index, indexprev, index_edge;
+ int k;
+
+ vertex_data = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
+ elem_data = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
+ if (!vertex_data || !elem_data)
+ return 0;
+
+ BM_mesh_elem_index_ensure(edit->bm, BM_VERT);
+
+ index_edge = 0;
+ BM_ITER_STRANDS(root, &iter, edit->bm, BM_STRANDS_OF_MESH) {
+ BM_ITER_STRANDS_ELEM_INDEX(v, &iter_strand, root, BM_VERTS_OF_STRAND, k) {
+ size_t offset_co;
+
+ index = BM_elem_index_get(v);
+
+ offset_co = index * size_vertex;
+ copy_v3_v3((float *)(vertex_data + offset_co), v->co);
+
+ if (k > 0) {
+ if (strands_use_normals(info)) {
+ size_t offset_nor = offset_co + size_v3;
+ float nor[3];
+ sub_v3_v3v3(nor, v->co, vprev->co);
+ normalize_v3(nor);
+ copy_v3_v3((float *)(vertex_data + offset_nor), nor);
+
+ if (k == 1) {
+ /* define root normal: same as first segment */
+ size_t offset_root_nor = indexprev * size_vertex + size_v3;
+ copy_v3_v3((float *)(vertex_data + offset_root_nor), nor);
+ }
+ }
+
+ {
+ elem_data[index_edge + 0] = indexprev;
+ elem_data[index_edge + 1] = index;
+ index_edge += 2;
+ }
+ }
+
+ vprev = v;
+ indexprev = index;
+ }
+ }
+
+ glUnmapBuffer(GL_ARRAY_BUFFER);
+ glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
+
+ return index_edge;
+}
+
+/* ------------------------------------------------------------------------- */
+/* dots */
+
+static void setup_gpu_buffers_dots(BMEditStrands *edit, const StrandsDrawInfo *info, bool selected)
+{
+ const size_t size_v3 = sizeof(float) * 3;
+ const size_t size_vertex = size_v3;
+ BMesh *bm = edit->bm;
+
+ BMVert *v;
+ BMIter iter;
+ int totvert;
+
+ switch (info->select_mode) {
+ case HAIR_SELECT_STRAND:
+ totvert = 0;
+ break;
+ case HAIR_SELECT_VERTEX:
+ totvert = selected ? bm->totvertsel : bm->totvert - bm->totvertsel;
+ break;
+ case HAIR_SELECT_TIP:
+ totvert = 0;
+ BM_ITER_MESH(v, &iter, bm, BM_VERTS_OF_MESH) {
+ if (BM_elem_flag_test_bool(v, BM_ELEM_SELECT) != selected)
+ continue;
+ if (!BM_strands_vert_is_tip(v))
+ continue;
+
+ ++totvert;
+ }
+ break;
+ }
+
+ if (totvert == 0)
+ return;
+
+ if (!edit->dot_glbuf)
+ glGenBuffers(1, &edit->dot_glbuf);
+
+ glBindBuffer(GL_ARRAY_BUFFER, edit->dot_glbuf);
+ glBufferData(GL_ARRAY_BUFFER, size_vertex * totvert, NULL, GL_DYNAMIC_DRAW);
+
+ glVertexPointer(3, GL_FLOAT, size_vertex, NULL);
+}
+
+static void unbind_gpu_buffers_dots(void)
+{
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+}
+
+static int write_gpu_buffers_dots(BMEditStrands *edit, const StrandsDrawInfo *info, bool selected)
+{
+ const size_t size_v3 = sizeof(float) * 3;
+ const size_t size_vertex = size_v3;
+
+ GLubyte *vertex_data;
+ BMVert *v;
+ BMIter iter;
+ int index_dot;
+
+ if (info->select_mode == HAIR_SELECT_STRAND)
+ return 0;
+
+ vertex_data = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
+ if (!vertex_data)
+ return 0;
+
+ BM_mesh_elem_index_ensure(edit->bm, BM_VERT);
+
+ index_dot = 0;
+ switch (info->select_mode) {
+ case HAIR_SELECT_STRAND:
+ /* already exited, but keep the case for the compiler */
+ break;
+ case HAIR_SELECT_VERTEX:
+ BM_ITER_MESH(v, &iter, edit->bm, BM_VERTS_OF_MESH) {
+ size_t offset_co;
+
+ if (BM_elem_flag_test_bool(v, BM_ELEM_SELECT) != selected)
+ continue;
+
+ offset_co = index_dot * size_vertex;
+ copy_v3_v3((float *)(vertex_data + offset_co), v->co);
+ ++index_dot;
+ }
+ break;
+ case HAIR_SELECT_TIP:
+ BM_ITER_MESH(v, &iter, edit->bm, BM_VERTS_OF_MESH) {
+ size_t offset_co;
+
+ if (BM_elem_flag_test_bool(v, BM_ELEM_SELECT) != selected)
+ continue;
+ if (!BM_strands_vert_is_tip(v))
+ continue;
+
+ offset_co = index_dot * size_vertex;
+ copy_v3_v3((float *)(vertex_data + offset_co), v->co);
+ ++index_dot;
+ }
+ break;
+ }
+
+ glUnmapBuffer(GL_ARRAY_BUFFER);
+
+ return index_dot;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static void draw_dots(BMEditStrands *edit, const StrandsDrawInfo *info, bool selected)
+{
+ int totelem;
+
+ if (selected)
+ glColor3fv(info->col_select);
+ else
+ glColor3fv(info->col_base);
+
+ setup_gpu_buffers_dots(edit, info, selected);
+ totelem = write_gpu_buffers_dots(edit, info, selected);
+ if (totelem > 0)
+ glDrawArrays(GL_POINTS, 0, totelem);
+}
+
+void draw_strands_edit_hair(Scene *scene, View3D *v3d, ARegion *UNUSED(ar), BMEditStrands *edit)
+{
+ HairEditSettings *settings = &scene->toolsettings->hair_edit;
+
+ StrandsDrawInfo info;
+ int totelem;
+
+ init_draw_info(&info, v3d, STRANDS_SHADE_HAIR, settings->select_mode);
+
+ set_opengl_state_strands(&info);
+ setup_gpu_buffers_strands(edit, &info);
+ totelem = write_gpu_buffers_strands(edit, &info);
+ if (totelem > 0)
+ glDrawElements(GL_LINES, totelem, GL_UNSIGNED_INT, NULL);
+ unbind_gpu_buffers_strands();
+
+ set_opengl_state_dots(&info);
+ draw_dots(edit, &info, false);
+ draw_dots(edit, &info, true);
+ unbind_gpu_buffers_dots();
+
+ restore_opengl_state(&info);
+}
diff --git a/source/blender/editors/space_view3d/drawvolume.c b/source/blender/editors/space_view3d/drawvolume.c
index a220e1e39b0..2ee1241a2a4 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,8 @@ 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;
+ const float thickness = sds->display_thickness;
/* draw slices of smoke is adapted from c++ code authored
* by: Johannes Schmid and Ingemar Rask, 2006, johnny@grob.org */
@@ -137,76 +136,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 +254,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 +281,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 * thickness);
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 * thickness);
}
else
printf("Your gfx card does not support 3D View smoke drawing.\n");
@@ -448,7 +371,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 +391,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 +424,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 +437,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 447ceee5b13..e4f3e1d75ea 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -84,6 +84,8 @@
# include "BPY_extern.h"
#endif
+#include "DEG_depsgraph.h"
+
#include "view3d_intern.h" /* own include */
/* ******************** manage regions ********************* */
@@ -276,7 +278,7 @@ void ED_view3d_check_mats_rv3d(struct RegionView3D *rv3d)
}
#endif
-static void view3d_stop_render_preview(wmWindowManager *wm, ARegion *ar)
+void ED_view3d_stop_render_preview(wmWindowManager *wm, ARegion *ar)
{
RegionView3D *rv3d = ar->regiondata;
@@ -307,7 +309,7 @@ void ED_view3d_shade_update(Main *bmain, Scene *scene, View3D *v3d, ScrArea *sa)
for (ar = sa->regionbase.first; ar; ar = ar->next) {
if (ar->regiondata)
- view3d_stop_render_preview(wm, ar);
+ ED_view3d_stop_render_preview(wm, ar);
}
}
else if (scene->obedit != NULL && scene->obedit->type == OB_MESH) {
@@ -354,7 +356,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");
@@ -552,6 +560,9 @@ static void view3d_main_area_init(wmWindowManager *wm, ARegion *ar)
keymap = WM_keymap_find(wm->defaultconf, "Particle", 0, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
+ keymap = WM_keymap_find(wm->defaultconf, "Hair", 0, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
+
/* editfont keymap swallows all... */
keymap = WM_keymap_find(wm->defaultconf, "Font", 0, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
@@ -579,7 +590,7 @@ static void view3d_main_area_exit(wmWindowManager *wm, ARegion *ar)
{
RegionView3D *rv3d = ar->regiondata;
- view3d_stop_render_preview(wm, ar);
+ ED_view3d_stop_render_preview(wm, ar);
if (rv3d->gpuoffscreen) {
GPU_offscreen_free(rv3d->gpuoffscreen);
@@ -1097,7 +1108,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);
}
@@ -1120,7 +1132,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);
}
@@ -1177,7 +1190,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;
@@ -1324,7 +1337,8 @@ static void view3d_buttons_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa
ED_region_tag_redraw(ar);
break;
case NC_BRUSH:
- if (wmn->action == NA_EDITED)
+ /* NA_SELECTED is used on brush changes */
+ if (ELEM(wmn->action, NA_EDITED, NA_SELECTED))
ED_region_tag_redraw(ar);
break;
case NC_SPACE:
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 db29b08c5a9..5ccb16e514c 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;
@@ -2063,6 +2107,27 @@ int dupli_ob_sort(void *arg1, void *arg2)
}
#endif
+static void draw_dupli_object(Scene *scene, ARegion *ar, View3D *v3d,
+ Base *base, DupliObject *UNUSED(dob), DupliObjectData *dob_data,
+ short dflag, bool draw_dupli_strands)
+{
+ draw_object(scene, ar, v3d, base, dflag);
+
+ if (dob_data) {
+
+ /* draw strands only when not editing */
+ if (draw_dupli_strands) {
+ DupliObjectDataStrands *link;
+
+ for (link = dob_data->strands.first; link; link = link->next) {
+ struct Strands *strands = link->strands;
+ struct StrandsChildren *children = link->strands_children;
+
+ draw_strands(scene, v3d, ar, base->object, strands, children, dflag);
+ }
+ }
+ }
+}
static DupliObject *dupli_step(DupliObject *dob)
{
@@ -2084,6 +2149,7 @@ static void draw_dupli_objects_color(
GLuint displist = 0;
unsigned char color_rgb[3];
const short dflag_dupli = dflag | DRAW_CONSTCOLOR;
+ const bool draw_dupli_strands = !(base->object->mode & OB_MODE_HAIR_EDIT);
short transflag;
bool use_displist = false; /* -1 is initialize */
char dt;
@@ -2101,17 +2167,22 @@ static void draw_dupli_objects_color(
UI_GetThemeColorBlend3ubv(color, TH_BACK, 0.5f, color_rgb);
}
- tbase.flag = OB_FROMDUPLI | base->flag;
+ tbase.flag |= OB_FROMDUPLI;
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);
for (; dob; dob_prev = dob, dob = dob_next, dob_next = dob_next ? dupli_step(dob_next->next) : NULL) {
+ /* for restoring after override */
+ DupliObjectData *dob_data = NULL;
+ DerivedMesh *store_final_dm;
+
tbase.object = dob->ob;
+ store_final_dm = dob->ob->derivedFinal;
/* Make sure lod is updated from dupli's position */
@@ -2148,6 +2219,21 @@ static void draw_dupli_objects_color(
glColor3ubv(color_rgb);
}
+ /* override final DM */
+ bb_tmp = NULL;
+ tbase.object->transflag &= ~OB_IS_DUPLI_CACHE;
+ if (base->object->dup_cache) {
+ dob_data = BKE_dupli_cache_find_data(base->object->dup_cache, tbase.object);
+ if (dob_data && dob_data->dm) {
+ tbase.object->transflag |= OB_IS_DUPLI_CACHE;
+
+ tbase.object->derivedFinal = dob_data->dm;
+ bb_tmp = &dob_data->bb;
+ }
+ }
+ if (!bb_tmp)
+ bb_tmp = BKE_object_boundbox_get(dob->ob);
+
/* generate displist, test for new object */
if (dob_prev && dob_prev->ob != dob->ob) {
if (use_displist == true)
@@ -2156,7 +2242,7 @@ static void draw_dupli_objects_color(
use_displist = false;
}
- if ((bb_tmp = BKE_object_boundbox_get(dob->ob))) {
+ if (bb_tmp) {
bb = *bb_tmp; /* must make a copy */
testbb = true;
}
@@ -2194,7 +2280,7 @@ static void draw_dupli_objects_color(
displist = glGenLists(1);
glNewList(displist, GL_COMPILE);
- draw_object(scene, ar, v3d, &tbase, dflag_dupli);
+ draw_dupli_object(scene, ar, v3d, &tbase, dob, dob_data, dflag_dupli, draw_dupli_strands);
glEndList();
use_displist = true;
@@ -2210,8 +2296,24 @@ static void draw_dupli_objects_color(
}
else {
copy_m4_m4(dob->ob->obmat, dob->mat);
- draw_object(scene, ar, v3d, &tbase, dflag_dupli);
+ draw_dupli_object(scene, ar, v3d, &tbase, dob, dob_data, dflag_dupli, draw_dupli_strands);
+ }
+ }
+
+ /* restore final DM */
+ if (tbase.object->transflag & OB_IS_DUPLI_CACHE) {
+ DerivedMesh *cur = tbase.object->derivedFinal;
+
+ /* in some cases drawing code can recreate the derivedFinal,
+ * make sure we free those first before restoring
+ */
+ if (cur && cur != dob_data->dm) {
+ cur->needsFree = 1;
+ cur->release(cur);
}
+
+ tbase.object->transflag &= ~OB_IS_DUPLI_CACHE;
+ tbase.object->derivedFinal = store_final_dm;
}
tbase.object->dt = dt;
@@ -2551,13 +2653,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);
@@ -2613,7 +2716,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;
@@ -2622,11 +2725,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;
@@ -2652,16 +2763,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);
}
}
@@ -2747,7 +2858,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;
@@ -2796,8 +2907,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);
}
}
@@ -2879,7 +2990,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 */
@@ -2948,39 +3059,57 @@ 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);
}
/*
* Function to clear the view
*/
-static void view3d_main_area_clear(Scene *scene, View3D *v3d, ARegion *ar, bool force)
+static void view3d_main_area_clear(Scene *scene, View3D *v3d, ARegion *ar)
{
const bool is_wire_color = V3D_IS_WIRECOLOR(scene, v3d);
-
- /* clear background */
- if (scene->world && ((v3d->flag3 & V3D_SHOW_WORLD) || force)) {
- float alpha = (force) ? 1.0f : 0.0f;
+
+ if (scene->world && (v3d->flag3 & V3D_SHOW_WORLD)) {
bool glsl = GPU_glsl_support() && BKE_scene_use_new_shading_nodes(scene) && scene->world->nodetree && scene->world->use_nodes;
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);
@@ -3073,7 +3202,7 @@ static void view3d_main_area_clear(Scene *scene, View3D *v3d, ARegion *ar, bool
interp_v3_v3v3(col_fl, col_hor, col_zen, col_fac);
rgb_float_to_uchar(col_ub, col_fl);
- col_ub[3] = alpha * 255;
+ col_ub[3] = 255;
}
}
@@ -3114,7 +3243,7 @@ static void view3d_main_area_clear(Scene *scene, View3D *v3d, ARegion *ar, bool
IMB_colormanagement_pixel_to_display_space_v3(col_hor, &scene->world->horr, &scene->view_settings,
&scene->display_settings);
- glClearColor(col_hor[0], col_hor[1], col_hor[2], alpha);
+ glClearColor(col_hor[0], col_hor[1], col_hor[2], 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if (is_wire_color) {
@@ -3167,7 +3296,7 @@ static void view3d_main_area_clear(Scene *scene, View3D *v3d, ARegion *ar, bool
float col[3];
UI_GetThemeColor3fv(TH_HIGH_GRAD, col);
- UI_ThemeClearColor(TH_HIGH_GRAD);
+ UI_ThemeClearColorAlpha(TH_HIGH_GRAD, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if (is_wire_color) {
@@ -3185,7 +3314,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;
@@ -3220,16 +3350,29 @@ 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 */
if (do_sky) {
- view3d_main_area_clear(scene, v3d, ar, true);
+ view3d_main_area_clear(scene, v3d, ar);
}
else {
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
@@ -3274,13 +3417,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);
@@ -3298,14 +3444,15 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, in
/* render 3d view */
if (rv3d->persp == RV3D_CAMOB && v3d->camera) {
CameraParams params;
- GPUFXSettings fx_settings = {0};
- Object *camera = v3d->camera;
+ GPUFXSettings fx_settings = {NULL};
+ Object *camera = BKE_camera_multiview_render(scene, v3d->camera, viewname);
BKE_camera_params_init(&params);
/* fallback for non camera objects */
params.clipsta = v3d->near;
params.clipend = v3d->far;
- BKE_camera_params_from_object(&params, v3d->camera);
+ BKE_camera_params_from_object(&params, camera);
+ BKE_camera_multiview_params(&scene->r, &params, camera, viewname);
BKE_camera_params_compute_viewplane(&params, sizex, sizey, scene->r.xasp, scene->r.yasp);
BKE_camera_params_compute_matrix(&params);
@@ -3314,13 +3461,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 */
@@ -3345,7 +3492,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};
@@ -3375,9 +3523,11 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Scene *scene, Object *camera, int w
{
CameraParams params;
+ Object *camera = BKE_camera_multiview_render(scene, v3d.camera, viewname);
BKE_camera_params_init(&params);
- BKE_camera_params_from_object(&params, v3d.camera);
+ BKE_camera_params_from_object(&params, camera);
+ BKE_camera_multiview_params(&scene->r, &params, camera, viewname);
BKE_camera_params_compute_viewplane(&params, width, height, scene->r.xasp, scene->r.yasp);
BKE_camera_params_compute_matrix(&params);
@@ -3391,7 +3541,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);
}
@@ -3596,6 +3746,103 @@ 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])
@@ -3622,16 +3869,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
@@ -3644,7 +3894,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;
@@ -3656,11 +3906,12 @@ 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);
}
/* clear the background */
- view3d_main_area_clear(scene, v3d, ar, false);
+ view3d_main_area_clear(scene, v3d, ar);
/* enables anti-aliasing for 3D view drawing */
if (U.ogl_multisamples != USER_MULTISAMPLE_NONE) {
@@ -3715,7 +3966,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;
}
@@ -3785,7 +4036,7 @@ static void view3d_main_area_draw_info(const bContext *C, Scene *scene,
if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
wmWindowManager *wm = CTX_wm_manager(C);
- if ((U.uiflag & USER_SHOW_FPS) && ED_screen_animation_playing(wm)) {
+ if ((U.uiflag & USER_SHOW_FPS) && ED_screen_animation_no_scrub(wm)) {
ED_scene_draw_fps(scene, &rect);
}
else if (U.uiflag & USER_SHOW_VIEWPORTNAME) {
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index 39541c108ff..b8add39b0e6 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);
+ len_new += (winrct->ymax - xy[1]);
+ len_old += (winrct->ymax - xy_orig[1]);
}
- 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
- }
- 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);
@@ -2748,29 +2840,15 @@ static void view3d_from_minmax(bContext *C, View3D *v3d, ARegion *ar,
size = max_fff(afm[0], afm[1], afm[2]);
if (ok_dist) {
- /* fix up zoom distance if needed */
+ char persp;
if (rv3d->is_persp) {
- float lens, sensor_size;
- /* offset the view based on the lens */
if (rv3d->persp == RV3D_CAMOB && ED_view3d_camera_lock_check(v3d, rv3d)) {
- CameraParams params;
- BKE_camera_params_init(&params);
- params.clipsta = v3d->near;
- params.clipend = v3d->far;
- BKE_camera_params_from_object(&params, v3d->camera);
-
- lens = params.lens;
- sensor_size = BKE_camera_sensor_size(params.sensor_fit, params.sensor_x, params.sensor_y);
+ persp = RV3D_CAMOB;
}
else {
- lens = v3d->lens;
- sensor_size = DEFAULT_SENSOR_WIDTH;
+ persp = RV3D_PERSP;
}
- size = ED_view3d_radius_to_persp_dist(focallength_to_fov(lens, sensor_size), size / 2.0f) * VIEW3D_MARGIN;
-
- /* do not zoom closer than the near clipping plane */
- size = max_ff(size, v3d->near * 1.5f);
}
else { /* ortho */
if (size < 0.0001f) {
@@ -2779,7 +2857,15 @@ static void view3d_from_minmax(bContext *C, View3D *v3d, ARegion *ar,
}
else {
/* adjust zoom so it looks nicer */
- size = ED_view3d_radius_to_ortho_dist(v3d->lens, size / 2.0f) * VIEW3D_MARGIN;
+ persp = RV3D_ORTHO;
+ }
+ }
+
+ if (ok_dist) {
+ new_dist = ED_view3d_radius_to_dist(v3d, ar, persp, true, (size / 2) * VIEW3D_MARGIN);
+ if (rv3d->is_persp) {
+ /* don't zoom closer than the near clipping plane */
+ new_dist = max_ff(new_dist, v3d->near * 1.5f);
}
}
}
@@ -2787,15 +2873,6 @@ static void view3d_from_minmax(bContext *C, View3D *v3d, ARegion *ar,
mid_v3_v3v3(new_ofs, min, max);
negate_v3(new_ofs);
- new_dist = size;
-
- /* correction for window aspect ratio */
- if (ar->winy > 2 && ar->winx > 2) {
- size = (float)ar->winx / (float)ar->winy;
- if (size < 1.0f) size = 1.0f / size;
- new_dist *= size;
- }
-
if (rv3d->persp == RV3D_CAMOB && !ED_view3d_camera_lock_check(v3d, rv3d)) {
rv3d->persp = RV3D_PERSP;
ED_view3d_smooth_view(C, v3d, ar, v3d->camera, NULL,
@@ -3703,22 +3780,6 @@ static void axis_set_view(bContext *C, View3D *v3d, ARegion *ar,
}
if (align_active == false) {
- /* normal operation */
- if (rv3d->viewlock & RV3D_LOCKED) {
- /* only pass on if */
-
- /* nice confusing if-block */
- if (!((rv3d->view == RV3D_VIEW_FRONT && view == RV3D_VIEW_BACK) ||
- (rv3d->view == RV3D_VIEW_BACK && view == RV3D_VIEW_FRONT) ||
- (rv3d->view == RV3D_VIEW_RIGHT && view == RV3D_VIEW_LEFT) ||
- (rv3d->view == RV3D_VIEW_LEFT && view == RV3D_VIEW_RIGHT) ||
- (rv3d->view == RV3D_VIEW_BOTTOM && view == RV3D_VIEW_TOP) ||
- (rv3d->view == RV3D_VIEW_TOP && view == RV3D_VIEW_BOTTOM)))
- {
- return;
- }
- }
-
rv3d->view = view;
}
@@ -3765,10 +3826,6 @@ static int viewnumpad_exec(bContext *C, wmOperator *op)
viewnum = RNA_enum_get(op->ptr, "type");
align_active = RNA_boolean_get(op->ptr, "align_active");
- /* set this to zero, gets handled in axis_set_view */
- if (rv3d->viewlock & RV3D_LOCKED)
- align_active = false;
-
/* Use this to test if we started out with a camera */
if (rv3d->persp == RV3D_CAMOB) {
@@ -3894,23 +3951,37 @@ static int vieworbit_exec(bContext *C, wmOperator *op)
ARegion *ar;
RegionView3D *rv3d;
int orbitdir;
+ 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);
/* no NULL check is needed, poll checks */
- ED_view3d_context_user_region(C, &v3d, &ar);
+ v3d = CTX_wm_view3d(C);
+ ar = CTX_wm_region(C);
rv3d = ar->regiondata;
+ /* support for switching to the opposite view (even when in locked views) */
+ view_opposite = (fabsf(angle) == (float)M_PI) ? ED_view3d_axis_view_opposite(rv3d->view) : RV3D_VIEW_USER;
orbitdir = RNA_enum_get(op->ptr, "type");
- if ((rv3d->viewlock & RV3D_LOCKED) == 0) {
+ if ((rv3d->viewlock & RV3D_LOCKED) && (view_opposite == RV3D_VIEW_USER)) {
+ /* no NULL check is needed, poll checks */
+ ED_view3d_context_user_region(C, &v3d, &ar);
+ rv3d = ar->regiondata;
+ }
+
+ if ((rv3d->viewlock & RV3D_LOCKED) == 0 || (view_opposite != RV3D_VIEW_USER)) {
if ((rv3d->persp != RV3D_CAMOB) || ED_view3d_camera_lock_check(v3d, rv3d)) {
int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
- float angle = DEG2RADF((float)U.pad_rot_angle);
float quat_mul[4];
float quat_new[4];
float ofs_new[3];
float *ofs_new_pt = NULL;
- view3d_ensure_persp(v3d, ar);
+ if (view_opposite == RV3D_VIEW_USER) {
+ view3d_ensure_persp(v3d, ar);
+ }
if (ELEM(orbitdir, V3D_VIEW_STEPLEFT, V3D_VIEW_STEPRIGHT)) {
const float zvec[3] = {0.0f, 0.0f, 1.0f};
@@ -3933,7 +4004,15 @@ static int vieworbit_exec(bContext *C, wmOperator *op)
}
mul_qt_qtqt(quat_new, rv3d->viewquat, quat_mul);
- rv3d->view = RV3D_VIEW_USER;
+
+ if (view_opposite != RV3D_VIEW_USER) {
+ rv3d->view = view_opposite;
+ /* avoid float in-precision, just get a new orientation */
+ ED_view3d_quat_from_axis_view(view_opposite, quat_new);
+ }
+ else {
+ rv3d->view = RV3D_VIEW_USER;
+ }
if (U.uiflag & USER_ORBIT_SELECTION) {
float dyn_ofs[3];
@@ -3964,6 +4043,8 @@ static int vieworbit_exec(bContext *C, wmOperator *op)
void VIEW3D_OT_view_orbit(wmOperatorType *ot)
{
+ PropertyRNA *prop;
+
/* identifiers */
ot->name = "View Orbit";
ot->description = "Orbit the view";
@@ -3977,7 +4058,11 @@ void VIEW3D_OT_view_orbit(wmOperatorType *ot)
ot->flag = 0;
/* properties */
+ prop = RNA_def_float(ot->srna, "angle", 0, -FLT_MAX, FLT_MAX, "Roll", "", -FLT_MAX, FLT_MAX);
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+
ot->prop = RNA_def_enum(ot->srna, "type", prop_view_orbit_items, 0, "Orbit", "Direction of View Orbit");
+
}
@@ -4429,20 +4514,6 @@ void VIEW3D_OT_background_image_remove(wmOperatorType *ot)
/* ********************* set clipping operator ****************** */
-static void calc_clipping_plane(float clip[6][4], const BoundBox *clipbb, const bool is_flip)
-{
- int val;
-
- for (val = 0; val < 4; val++) {
- normal_tri_v3(clip[val], clipbb->vec[val], clipbb->vec[val == 3 ? 0 : val + 1], clipbb->vec[val + 4]);
- if (UNLIKELY(is_flip)) {
- negate_v3(clip[val]);
- }
-
- clip[val][3] = -dot_v3v3(clip[val], clipbb->vec[val]);
- }
-}
-
static void calc_local_clipping(float clip_local[6][4], BoundBox *clipbb, float mat[4][4])
{
BoundBox clipbb_local;
@@ -4455,7 +4526,7 @@ static void calc_local_clipping(float clip_local[6][4], BoundBox *clipbb, float
mul_v3_m4v3(clipbb_local.vec[i], imat, clipbb->vec[i]);
}
- calc_clipping_plane(clip_local, &clipbb_local, is_negative_m4(mat));
+ ED_view3d_clipping_calc_from_boundbox(clip_local, &clipbb_local, is_negative_m4(mat));
}
void ED_view3d_clipping_local(RegionView3D *rv3d, float mat[4][4])
@@ -4536,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;
@@ -4571,9 +4642,28 @@ 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);
+
+ /* 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 && v3d->localvd)
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
@@ -4599,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;
@@ -4725,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]))
@@ -4785,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_header.c b/source/blender/editors/space_view3d/view3d_header.c
index 11ed9867e2f..95532bc09a5 100644
--- a/source/blender/editors/space_view3d/view3d_header.c
+++ b/source/blender/editors/space_view3d/view3d_header.c
@@ -105,8 +105,8 @@ static void view3d_layers_editmode_ensure(Scene *scene, View3D *v3d)
if (scene->obedit && (scene->obedit->lay & v3d->lay) == 0) {
int bit;
for (bit = 0; bit < 32; bit++) {
- if (scene->obedit->lay & (1 << bit)) {
- v3d->lay |= 1 << bit;
+ if (scene->obedit->lay & (1u << bit)) {
+ v3d->lay |= (1u << bit);
break;
}
}
@@ -161,8 +161,8 @@ static int view3d_layers_exec(bContext *C, wmOperator *op)
v3d->layact = 1 << nr;
else if ((v3d->lay & v3d->layact) == 0) {
for (bit = 0; bit < 32; bit++) {
- if (v3d->lay & (1 << bit)) {
- v3d->layact = 1 << bit;
+ if (v3d->lay & (1u << bit)) {
+ v3d->layact = (1u << bit);
break;
}
}
@@ -340,7 +340,7 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C)
}
/* Manipulators aren't used in paint modes */
- if (!ELEM(ob->mode, OB_MODE_SCULPT, OB_MODE_PARTICLE_EDIT)) {
+ if (!ELEM(ob->mode, OB_MODE_SCULPT, OB_MODE_PARTICLE_EDIT, OB_MODE_HAIR_EDIT)) {
/* masks aren't used for sculpt and particle painting */
PointerRNA meshptr;
diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h
index a9b6d96d5d1..f4ecde79365 100644
--- a/source/blender/editors/space_view3d/view3d_intern.h
+++ b/source/blender/editors/space_view3d/view3d_intern.h
@@ -41,14 +41,14 @@ 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 BMEditStrands;
+struct Strands;
+struct StrandsChildren;
struct wmNDOFMotionData;
struct wmOperatorType;
struct wmWindowManager;
@@ -184,6 +184,10 @@ void draw_mesh_paint(View3D *v3d, RegionView3D *rv3d,
/* drawsimdebug.c */
void draw_sim_debug_data(Scene *scene, View3D *v3d, ARegion *ar);
+/* drawstrands.c */
+void draw_strands(Scene *scene, View3D *v3d, ARegion *ar, struct Object *ob, struct Strands *strands, struct StrandsChildren *children, short dflag);
+void draw_strands_edit_hair(Scene *scene, View3D *v3d, ARegion *ar, struct BMEditStrands *edit);
+
/* view3d_draw.c */
void view3d_main_area_draw(const struct bContext *C, struct ARegion *ar);
void ED_view3d_draw_depth(Scene *scene, struct ARegion *ar, View3D *v3d, bool alphaoverride);
@@ -210,7 +214,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(
@@ -227,8 +231,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 64124a136e8..56faf945fb9 100644
--- a/source/blender/editors/space_view3d/view3d_ops.c
+++ b/source/blender/editors/space_view3d/view3d_ops.c
@@ -236,8 +236,9 @@ 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);
WM_keymap_add_item(keymap, "VIEW3D_OT_rotate", MOUSEROTATE, 0, 0, 0);
WM_keymap_add_item(keymap, "VIEW3D_OT_move", MOUSEPAN, 0, KM_SHIFT, 0);
@@ -299,6 +300,9 @@ void view3d_keymap(wmKeyConfig *keyconf)
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_pan", PAD8, KM_PRESS, KM_CTRL, 0)->ptr, "type", V3D_VIEW_PANUP);
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_roll", PAD4, KM_PRESS, KM_SHIFT, 0)->ptr, "type", V3D_VIEW_STEPLEFT);
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_roll", PAD6, KM_PRESS, KM_SHIFT, 0)->ptr, "type", V3D_VIEW_STEPRIGHT);
+ kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_view_orbit", PAD9, KM_PRESS, 0, 0);
+ RNA_enum_set(kmi->ptr, "type", V3D_VIEW_STEPRIGHT);
+ RNA_float_set(kmi->ptr, "angle", (float)M_PI);
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_pan", WHEELUPMOUSE, KM_PRESS, KM_CTRL, 0)->ptr, "type", V3D_VIEW_PANRIGHT);
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_pan", WHEELDOWNMOUSE, KM_PRESS, KM_CTRL, 0)->ptr, "type", V3D_VIEW_PANLEFT);
@@ -523,3 +527,4 @@ void view3d_keymap(wmKeyConfig *keyconf)
viewzoom_modal_keymap(keyconf);
viewdolly_modal_keymap(keyconf);
}
+
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..1847de3c6a2 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -85,9 +85,11 @@
#include "ED_armature.h"
#include "ED_curve.h"
+#include "ED_physics.h"
#include "ED_particle.h"
#include "ED_mesh.h"
#include "ED_object.h"
+#include "ED_physics.h"
#include "ED_screen.h"
#include "ED_sculpt.h"
#include "ED_mball.h"
@@ -725,7 +727,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;
@@ -834,6 +836,8 @@ static void view3d_lasso_select(bContext *C, ViewContext *vc,
}
else if (ob && (ob->mode & OB_MODE_PARTICLE_EDIT))
PE_lasso_select(C, mcords, moves, extend, select);
+ else if (ob && (ob->mode & OB_MODE_HAIR_EDIT))
+ ED_hair_lasso_select(C, mcords, moves, extend, select);
else {
do_lasso_select_objects(vc, mcords, moves, extend, select);
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, vc->scene);
@@ -1641,7 +1645,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 +1666,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;
@@ -2146,6 +2150,9 @@ static int view3d_borderselect_exec(bContext *C, wmOperator *op)
else if (vc.obact && vc.obact->mode & OB_MODE_PARTICLE_EDIT) {
ret = PE_border_select(C, &rect, select, extend);
}
+ else if (vc.obact && vc.obact->mode & OB_MODE_HAIR_EDIT) {
+ ret = ED_hair_border_select(C, &rect, select, extend);
+ }
else { /* object mode with none active */
ret = do_object_pose_box_select(C, &vc, &rect, select, extend);
}
@@ -2185,7 +2192,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;
@@ -2276,6 +2283,8 @@ static int view3d_select_exec(bContext *C, wmOperator *op)
}
else if (obact && obact->mode & OB_MODE_PARTICLE_EDIT)
return PE_mouse_particles(C, location, extend, deselect, toggle);
+ else if (obact && obact->mode & OB_MODE_HAIR_EDIT)
+ return ED_hair_mouse_select(C, location, extend, deselect, toggle);
else if (obact && BKE_paint_select_face_test(obact))
retval = paintface_mouse_select(C, obact, location, extend, deselect, toggle);
else if (BKE_paint_select_vert_test(obact))
@@ -2453,7 +2462,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;
@@ -2791,7 +2800,7 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op)
RNA_int_get(op->ptr, "y")};
if (CTX_data_edit_object(C) || BKE_paint_select_elem_test(obact) ||
- (obact && (obact->mode & (OB_MODE_PARTICLE_EDIT | OB_MODE_POSE))) )
+ (obact && (obact->mode & (OB_MODE_PARTICLE_EDIT | OB_MODE_POSE | OB_MODE_HAIR_EDIT))) )
{
ViewContext vc;
@@ -2811,10 +2820,16 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op)
paint_vertsel_circle_select(&vc, select, mval, (float)radius);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obact->data);
}
- else if (obact->mode & OB_MODE_POSE)
+ else if (obact->mode & OB_MODE_POSE) {
pose_circle_select(&vc, select, mval, (float)radius);
- else
+ }
+ else if (obact->mode & OB_MODE_HAIR_EDIT) {
+ ED_hair_circle_select(C, select, mval, (float)radius);
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obact->data);
+ }
+ else {
return PE_circle_select(C, select, mval, (float)radius);
+ }
}
else if (obact && obact->mode & OB_MODE_SCULPT) {
return OPERATOR_CANCELLED;
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 5a3893f733f..e9cb6dcdc44 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -44,6 +44,7 @@
#include "BKE_camera.h"
#include "BKE_context.h"
#include "BKE_depsgraph.h"
+#include "BKE_DerivedMesh.h"
#include "BKE_object.h"
#include "BKE_global.h"
#include "BKE_main.h"
@@ -609,6 +610,20 @@ void VIEW3D_OT_object_as_camera(wmOperatorType *ot)
/* ********************************** */
+void ED_view3d_clipping_calc_from_boundbox(float clip[4][4], const BoundBox *bb, const bool is_flip)
+{
+ int val;
+
+ for (val = 0; val < 4; val++) {
+ normal_tri_v3(clip[val], bb->vec[val], bb->vec[val == 3 ? 0 : val + 1], bb->vec[val + 4]);
+ if (UNLIKELY(is_flip)) {
+ negate_v3(clip[val]);
+ }
+
+ clip[val][3] = -dot_v3v3(clip[val], bb->vec[val]);
+ }
+}
+
void ED_view3d_clipping_calc(BoundBox *bb, float planes[4][4], bglMats *mats, const rcti *rect)
{
float modelview[4][4];
@@ -644,16 +659,7 @@ void ED_view3d_clipping_calc(BoundBox *bb, float planes[4][4], bglMats *mats, co
((float *)modelview)[a] = mats->modelview[a];
flip_sign = is_negative_m4(modelview);
- /* then plane equations */
- for (val = 0; val < 4; val++) {
-
- normal_tri_v3(planes[val], bb->vec[val], bb->vec[val == 3 ? 0 : val + 1], bb->vec[val + 4]);
-
- if (flip_sign)
- negate_v3(planes[val]);
-
- planes[val][3] = -dot_v3v3(planes[val], bb->vec[val]);
- }
+ ED_view3d_clipping_calc_from_boundbox(planes, bb, flip_sign);
}
static bool view3d_boundbox_clip_m4(const BoundBox *bb, float persmatob[4][4])
@@ -683,7 +689,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 */
@@ -692,7 +698,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);
}
@@ -705,7 +711,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;
@@ -724,16 +730,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;
@@ -753,8 +762,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;
@@ -792,7 +802,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;
@@ -891,13 +901,28 @@ char ED_view3d_lock_view_from_index(int index)
}
+char ED_view3d_axis_view_opposite(char view)
+{
+ switch (view) {
+ case RV3D_VIEW_FRONT: return RV3D_VIEW_BACK;
+ case RV3D_VIEW_BACK: return RV3D_VIEW_FRONT;
+ case RV3D_VIEW_LEFT: return RV3D_VIEW_RIGHT;
+ case RV3D_VIEW_RIGHT: return RV3D_VIEW_LEFT;
+ case RV3D_VIEW_TOP: return RV3D_VIEW_BOTTOM;
+ case RV3D_VIEW_BOTTOM: return RV3D_VIEW_TOP;
+ }
+
+ return RV3D_VIEW_USER;
+}
+
+
bool ED_view3d_lock(RegionView3D *rv3d)
{
return ED_view3d_quat_from_axis_view(rv3d->view, rv3d->viewquat);
}
/* 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) {
@@ -936,7 +961,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;
}
@@ -1006,23 +1031,55 @@ static void view3d_select_loop(ViewContext *vc, Scene *scene, View3D *v3d, ARegi
lb = object_duplilist(G.main->eval_ctx, scene, base->object);
for (dob = lb->first; dob; dob = dob->next) {
- float omat[4][4];
+ /* for restoring after override */
+ DupliObjectData *dob_data = NULL;
+ DerivedMesh *store_final_dm;
+ float store_obmat[4][4];
tbase.object = dob->ob;
- copy_m4_m4(omat, dob->ob->obmat);
+ copy_m4_m4(store_obmat, dob->ob->obmat);
copy_m4_m4(dob->ob->obmat, dob->mat);
+ store_final_dm = dob->ob->derivedFinal;
/* extra service: draw the duplicator in drawtype of parent */
/* MIN2 for the drawtype to allow bounding box objects in groups for lods */
dt = tbase.object->dt; tbase.object->dt = MIN2(tbase.object->dt, base->object->dt);
dtx = tbase.object->dtx; tbase.object->dtx = base->object->dtx;
+ /* override final DM */
+ tbase.object->transflag &= ~OB_IS_DUPLI_CACHE;
+ if (base->object->dup_cache) {
+ dob_data = BKE_dupli_cache_find_data(base->object->dup_cache, tbase.object);
+ if (dob_data && dob_data->dm) {
+ tbase.object->transflag |= OB_IS_DUPLI_CACHE;
+
+ tbase.object->derivedFinal = dob_data->dm;
+ }
+ }
+
draw_object(scene, ar, v3d, &tbase, DRAW_PICKING | DRAW_CONSTCOLOR);
+ /* restore final DM */
+ if (tbase.object->transflag & OB_IS_DUPLI_CACHE) {
+ DerivedMesh *cur = tbase.object->derivedFinal;
+
+ /* in some cases drawing code can recreate the derivedFinal,
+ * make sure we free those first before restoring
+ */
+ if (cur && cur != dob_data->dm) {
+ cur->needsFree = 1;
+ cur->release(cur);
+ }
+
+ tbase.object->transflag &= ~OB_IS_DUPLI_CACHE;
+ tbase.object->derivedFinal = store_final_dm;
+ }
+
tbase.object->dt = dt;
tbase.object->dtx = dtx;
- copy_m4_m4(dob->ob->obmat, omat);
+ /* restore obmat and final DM */
+ copy_m4_m4(dob->ob->obmat, store_obmat);
}
free_object_duplilist(lb);
}
@@ -1194,7 +1251,7 @@ static bool view3d_localview_init(
View3D *v3d = sa->spacedata.first;
Base *base;
float min[3], max[3], box[3], mid[3];
- float size = 0.0f, size_persp = 0.0f, size_ortho = 0.0f;
+ float size = 0.0f;
unsigned int locallay;
bool ok = false;
@@ -1232,13 +1289,6 @@ static bool view3d_localview_init(
sub_v3_v3v3(box, max, min);
size = max_fff(box[0], box[1], box[2]);
-
- /* do not zoom closer than the near clipping plane */
- size = max_ff(size, v3d->near * 1.5f);
-
- /* perspective size (we always switch out of camera view so no need to use its lens size) */
- size_persp = ED_view3d_radius_to_persp_dist(focallength_to_fov(v3d->lens, DEFAULT_SENSOR_WIDTH), size / 2.0f) * VIEW3D_MARGIN;
- size_ortho = ED_view3d_radius_to_ortho_dist(v3d->lens, size / 2.0f) * VIEW3D_MARGIN;
}
if (ok == true) {
@@ -1255,6 +1305,7 @@ static bool view3d_localview_init(
for (ar = sa->regionbase.first; ar; ar = ar->next) {
if (ar->regiontype == RGN_TYPE_WINDOW) {
RegionView3D *rv3d = ar->regiondata;
+ bool ok_dist = true;
/* new view values */
Object *camera_old = NULL;
@@ -1270,25 +1321,24 @@ static bool view3d_localview_init(
camera_old = v3d->camera;
}
- /* perspective should be a bit farther away to look nice */
- if (rv3d->persp != RV3D_ORTHO) {
- dist_new = size_persp;
- }
- else {
- dist_new = size_ortho;
+ if (rv3d->persp == RV3D_ORTHO) {
+ if (size < 0.0001f) {
+ ok_dist = false;
+ }
}
- /* correction for window aspect ratio */
- if (ar->winy > 2 && ar->winx > 2) {
- float asp = (float)ar->winx / (float)ar->winy;
- if (asp < 1.0f) asp = 1.0f / asp;
- dist_new *= asp;
+ if (ok_dist) {
+ dist_new = ED_view3d_radius_to_dist(v3d, ar, rv3d->persp, true, (size / 2) * VIEW3D_MARGIN);
+ if (rv3d->persp == RV3D_PERSP) {
+ /* don't zoom closer than the near clipping plane */
+ dist_new = max_ff(dist_new, v3d->near * 1.5f);
+ }
}
ED_view3d_smooth_view_ex(
wm, win, sa,
v3d, ar, camera_old, NULL,
- ofs_new, NULL, &dist_new, NULL,
+ ofs_new, NULL, ok_dist ? &dist_new : NULL, NULL,
smooth_viewtx);
}
}
@@ -1695,21 +1745,116 @@ 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_persp_dist(const float angle, const float radius)
+float ED_view3d_radius_to_dist_persp(const float angle, const float radius)
{
- return (radius / 2.0f) * fabsf(1.0f / cosf((((float)M_PI) - angle) / 2.0f));
+ return radius * (1.0f / tanf(angle / 2.0f));
}
-float ED_view3d_radius_to_ortho_dist(const float lens, const float radius)
+float ED_view3d_radius_to_dist_ortho(const float lens, const float radius)
{
return radius / (DEFAULT_SENSOR_WIDTH / lens);
}
+/**
+ * Return a new RegionView3D.dist value to fit the \a radius.
+ *
+ * \note Depth isn't taken into account, this will fit a flat plane exactly,
+ * but points towards the view (with a perspective projection),
+ * may be within the radius but outside the view. eg:
+ *
+ * <pre>
+ * +
+ * pt --> + /^ radius
+ * / |
+ * / |
+ * view + +
+ * \ |
+ * \ |
+ * \|
+ * +
+ * </pre>
+ *
+ * \param ar Can be NULL if \a use_aspect is false.
+ * \param persp Allow the caller to tell what kind of perspective to use (ortho/view/camera)
+ * \param use_aspect Increase the distance to account for non 1:1 view aspect.
+ * \param radius The radius will be fitted exactly, typically pre-scaled by a margin (#VIEW3D_MARGIN).
+ */
+float ED_view3d_radius_to_dist(
+ const View3D *v3d, const ARegion *ar,
+ const char persp, const bool use_aspect,
+ const float radius)
+{
+ float dist;
+
+ BLI_assert(ELEM(persp, RV3D_ORTHO, RV3D_PERSP, RV3D_CAMOB));
+ BLI_assert((persp != RV3D_CAMOB) || v3d->camera);
+
+ if (persp == RV3D_ORTHO) {
+ dist = ED_view3d_radius_to_dist_ortho(v3d->lens, radius);
+ }
+ else {
+ float lens, sensor_size, zoom;
+ float angle;
+
+ if (persp == RV3D_CAMOB) {
+ CameraParams params;
+ BKE_camera_params_init(&params);
+ params.clipsta = v3d->near;
+ params.clipend = v3d->far;
+ BKE_camera_params_from_object(&params, v3d->camera);
+
+ lens = params.lens;
+ sensor_size = BKE_camera_sensor_size(params.sensor_fit, params.sensor_x, params.sensor_y);
+
+ /* ignore 'rv3d->camzoom' because we wan't to fit to the cameras frame */
+ zoom = CAMERA_PARAM_ZOOM_INIT_CAMOB;
+ }
+ else {
+ lens = v3d->lens;
+ sensor_size = DEFAULT_SENSOR_WIDTH;
+ zoom = CAMERA_PARAM_ZOOM_INIT_PERSP;
+ }
+
+ 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;
+
+ dist = ED_view3d_radius_to_dist_persp(angle, radius);
+ }
+
+ if (use_aspect) {
+ const RegionView3D *rv3d = ar->regiondata;
+
+ float winx, winy;
+
+ if (persp == RV3D_CAMOB) {
+ /* camera frame x/y in pixels */
+ winx = ar->winx / rv3d->viewcamtexcofac[0];
+ winy = ar->winy / rv3d->viewcamtexcofac[1];
+ }
+ else {
+ winx = ar->winx;
+ winy = ar->winy;
+ }
+
+ if (winx && winy) {
+ float aspect = winx / winy;
+ if (aspect < 1.0f) {
+ aspect = 1.0f / aspect;
+ }
+ dist *= aspect;
+ }
+ }
+
+ return dist;
+}
+
/* view matrix properties utilities */
/* unused */
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);