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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/space_view3d')
-rw-r--r--source/blender/editors/space_view3d/drawarmature.c69
-rw-r--r--source/blender/editors/space_view3d/drawmesh.c154
-rw-r--r--source/blender/editors/space_view3d/drawobject.c103
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c55
-rw-r--r--source/blender/editors/space_view3d/view3d_camera_control.c8
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c11
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c155
-rw-r--r--source/blender/editors/space_view3d/view3d_fly.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_header.c7
-rw-r--r--source/blender/editors/space_view3d/view3d_intern.h4
-rw-r--r--source/blender/editors/space_view3d/view3d_project.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c66
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c187
-rw-r--r--source/blender/editors/space_view3d/view3d_walk.c64
14 files changed, 551 insertions, 336 deletions
diff --git a/source/blender/editors/space_view3d/drawarmature.c b/source/blender/editors/space_view3d/drawarmature.c
index 245cdadc7a2..dfa373f111f 100644
--- a/source/blender/editors/space_view3d/drawarmature.c
+++ b/source/blender/editors/space_view3d/drawarmature.c
@@ -67,6 +67,7 @@
#include "view3d_intern.h"
+#include "GPU_select.h"
/* *************** Armature Drawing - Coloring API ***************************** */
@@ -93,7 +94,7 @@ static void set_pchan_colorset(Object *ob, bPoseChannel *pchan)
short color_index = 0;
/* sanity check */
- if (ELEM4(NULL, ob, arm, pose, pchan)) {
+ if (ELEM(NULL, ob, arm, pose, pchan)) {
bcolor = NULL;
return;
}
@@ -466,10 +467,10 @@ static const unsigned int bone_octahedral_solid_tris[8][3] = {
/* aligned with bone_octahedral_solid_tris */
static const float bone_octahedral_solid_normals[8][3] = {
- { 0.70710683f, -0.70710683f, 0.00000000f},
- {-0.00000000f, -0.70710683f, -0.70710683f},
- {-0.70710683f, -0.70710683f, 0.00000000f},
- { 0.00000000f, -0.70710683f, 0.70710683f},
+ { M_SQRT1_2, -M_SQRT1_2, 0.00000000f},
+ {-0.00000000f, -M_SQRT1_2, -M_SQRT1_2},
+ {-M_SQRT1_2, -M_SQRT1_2, 0.00000000f},
+ { 0.00000000f, -M_SQRT1_2, M_SQRT1_2},
{ 0.99388373f, 0.11043154f, -0.00000000f},
{ 0.00000000f, 0.11043154f, -0.99388373f},
{-0.99388373f, 0.11043154f, 0.00000000f},
@@ -551,7 +552,7 @@ static void draw_bone_points(const short dt, int armflag, unsigned int boneflag,
/* Draw root point if we are not connected */
if ((boneflag & BONE_CONNECTED) == 0) {
if (id != -1)
- glLoadName(id | BONESEL_ROOT);
+ GPU_select_load_id(id | BONESEL_ROOT);
if (dt <= OB_WIRE) {
if (armflag & ARM_EDITMODE) {
@@ -574,7 +575,7 @@ static void draw_bone_points(const short dt, int armflag, unsigned int boneflag,
/* Draw tip point */
if (id != -1)
- glLoadName(id | BONESEL_TIP);
+ GPU_select_load_id(id | BONESEL_TIP);
if (dt <= OB_WIRE) {
if (armflag & ARM_EDITMODE) {
@@ -787,7 +788,7 @@ static void draw_sphere_bone_wire(float smat[4][4], float imat[4][4],
/* Draw root point if we are not connected */
if ((boneflag & BONE_CONNECTED) == 0) {
if (id != -1)
- glLoadName(id | BONESEL_ROOT);
+ GPU_select_load_id(id | BONESEL_ROOT);
drawcircball(GL_LINE_LOOP, headvec, head, imat);
}
@@ -799,7 +800,7 @@ static void draw_sphere_bone_wire(float smat[4][4], float imat[4][4],
}
if (id != -1)
- glLoadName(id | BONESEL_TIP);
+ GPU_select_load_id(id | BONESEL_TIP);
drawcircball(GL_LINE_LOOP, tailvec, tail, imat);
@@ -830,7 +831,7 @@ static void draw_sphere_bone_wire(float smat[4][4], float imat[4][4],
cross_v3_v3v3(norvect, vec, imat[2]);
if (id != -1)
- glLoadName(id | BONESEL_BONE);
+ GPU_select_load_id(id | BONESEL_BONE);
glBegin(GL_LINES);
@@ -907,7 +908,7 @@ static void draw_sphere_bone(const short dt, int armflag, int boneflag, short co
/* Draw root point if we are not connected */
if ((boneflag & BONE_CONNECTED) == 0) {
if (id != -1)
- glLoadName(id | BONESEL_ROOT);
+ GPU_select_load_id(id | BONESEL_ROOT);
gluSphere(qobj, head, 16, 10);
}
@@ -918,7 +919,7 @@ static void draw_sphere_bone(const short dt, int armflag, int boneflag, short co
}
if (id != -1)
- glLoadName(id | BONESEL_TIP);
+ GPU_select_load_id(id | BONESEL_TIP);
glTranslatef(0.0f, 0.0f, length);
gluSphere(qobj, tail, 16, 10);
@@ -939,7 +940,7 @@ static void draw_sphere_bone(const short dt, int armflag, int boneflag, short co
if (length > (head + tail)) {
if (id != -1)
- glLoadName(id | BONESEL_BONE);
+ GPU_select_load_id(id | BONESEL_BONE);
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(-1.0f, -1.0f);
@@ -1009,7 +1010,7 @@ static void draw_line_bone(int armflag, int boneflag, short constflag, unsigned
/* Draw root point if we are not connected */
if ((boneflag & BONE_CONNECTED) == 0) {
if (G.f & G_PICKSEL) { /* no bitmap in selection mode, crashes 3d cards... */
- glLoadName(id | BONESEL_ROOT);
+ GPU_select_load_id(id | BONESEL_ROOT);
glBegin(GL_POINTS);
glVertex3f(0.0f, 0.0f, 0.0f);
glEnd();
@@ -1021,7 +1022,7 @@ static void draw_line_bone(int armflag, int boneflag, short constflag, unsigned
}
if (id != -1)
- glLoadName((GLuint) id | BONESEL_BONE);
+ GPU_select_load_id((GLuint) id | BONESEL_BONE);
glBegin(GL_LINES);
glVertex3f(0.0f, 0.0f, 0.0f);
@@ -1031,7 +1032,7 @@ static void draw_line_bone(int armflag, int boneflag, short constflag, unsigned
/* tip */
if (G.f & G_PICKSEL) {
/* no bitmap in selection mode, crashes 3d cards... */
- glLoadName(id | BONESEL_TIP);
+ GPU_select_load_id(id | BONESEL_TIP);
glBegin(GL_POINTS);
glVertex3f(0.0f, 1.0f, 0.0f);
glEnd();
@@ -1043,7 +1044,7 @@ static void draw_line_bone(int armflag, int boneflag, short constflag, unsigned
/* further we send no names */
if (id != -1)
- glLoadName(id & 0xFFFF); /* object tag, for bordersel optim */
+ GPU_select_load_id(id & 0xFFFF); /* object tag, for bordersel optim */
if (armflag & ARM_POSEMODE)
set_pchan_glColor(PCHAN_COLOR_LINEBONE, boneflag, constflag);
@@ -1161,7 +1162,7 @@ static void draw_b_bone(const short dt, int armflag, int boneflag, short constfl
}
if (id != -1) {
- glLoadName((GLuint) id | BONESEL_BONE);
+ GPU_select_load_id((GLuint) id | BONESEL_BONE);
}
/* set up solid drawing */
@@ -1266,13 +1267,13 @@ static void draw_wire_bone(const short dt, int armflag, int boneflag, short cons
/* this chunk not in object mode */
if (armflag & (ARM_EDITMODE | ARM_POSEMODE)) {
if (id != -1)
- glLoadName((GLuint) id | BONESEL_BONE);
+ GPU_select_load_id((GLuint) id | BONESEL_BONE);
draw_wire_bone_segments(pchan, bbones, length, segments);
/* further we send no names */
if (id != -1)
- glLoadName(id & 0xFFFF); /* object tag, for bordersel optim */
+ GPU_select_load_id(id & 0xFFFF); /* object tag, for bordersel optim */
}
/* colors for modes */
@@ -1315,7 +1316,7 @@ static void draw_bone(const short dt, int armflag, int boneflag, short constflag
/* now draw the bone itself */
if (id != -1) {
- glLoadName((GLuint) id | BONESEL_BONE);
+ GPU_select_load_id((GLuint) id | BONESEL_BONE);
}
/* wire? */
@@ -1370,7 +1371,7 @@ static void draw_custom_bone(Scene *scene, View3D *v3d, RegionView3D *rv3d, Obje
}
if (id != -1) {
- glLoadName((GLuint) id | BONESEL_BONE);
+ GPU_select_load_id((GLuint) id | BONESEL_BONE);
}
draw_object_instance(scene, v3d, rv3d, ob, dt, armflag & ARM_POSEMODE);
@@ -1812,12 +1813,12 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
index += 0x10000; /* pose bones count in higher 2 bytes only */
}
- /* very very confusing... but in object mode, solid draw, we cannot do glLoadName yet,
+ /* very very confusing... but in object mode, solid draw, we cannot do GPU_select_load_id yet,
* stick bones and/or wire custom-shapes are drawn in next loop
*/
- if (ELEM(arm->drawtype, ARM_LINE, ARM_WIRE) == 0 && (draw_wire == false)) {
+ if (ELEM(arm->drawtype, ARM_LINE, ARM_WIRE) == 0 && (draw_wire == false) && index != -1) {
/* object tag, for bordersel optim */
- glLoadName(index & 0xFFFF);
+ GPU_select_load_id(index & 0xFFFF);
index = -1;
}
}
@@ -1881,9 +1882,9 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
index += 0x10000; /* pose bones count in higher 2 bytes only */
}
/* stick or wire bones have not been drawn yet so don't clear object selection in this case */
- if (ELEM(arm->drawtype, ARM_LINE, ARM_WIRE) == 0 && draw_wire) {
+ if (ELEM(arm->drawtype, ARM_LINE, ARM_WIRE) == 0 && draw_wire && index != -1) {
/* object tag, for bordersel optim */
- glLoadName(index & 0xFFFF);
+ GPU_select_load_id(index & 0xFFFF);
index = -1;
}
}
@@ -1926,7 +1927,7 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
*/
if ((do_dashed & 2) && ((bone->flag & BONE_CONNECTED) == 0)) {
if (arm->flag & ARM_POSEMODE) {
- glLoadName(index & 0xFFFF); /* object tag, for bordersel optim */
+ GPU_select_load_id(index & 0xFFFF); /* object tag, for bordersel optim */
UI_ThemeColor(TH_WIRE);
}
setlinestyle(3);
@@ -1946,7 +1947,7 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
if (constflag & PCHAN_HAS_TARGET) glColor3ub(200, 120, 0);
else glColor3ub(200, 200, 50); /* add theme! */
- glLoadName(index & 0xFFFF);
+ GPU_select_load_id(index & 0xFFFF);
pchan_draw_IK_root_lines(pchan, !(do_dashed & 2));
}
}
@@ -1954,7 +1955,7 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
if (bone->flag & BONE_SELECTED) {
glColor3ub(150, 200, 50); /* add theme! */
- glLoadName(index & 0xFFFF);
+ GPU_select_load_id(index & 0xFFFF);
pchan_draw_IK_root_lines(pchan, !(do_dashed & 2));
}
}
@@ -2020,7 +2021,7 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
/* draw DoFs */
if (arm->flag & ARM_POSEMODE) {
- if (((base->flag & OB_FROMDUPLI) == 0)) {
+ if (((base->flag & OB_FROMDUPLI) == 0) && ((v3d->flag & V3D_HIDE_HELPLINES) == 0)) {
draw_pose_dofs(ob);
}
}
@@ -2174,7 +2175,7 @@ static void draw_ebones(View3D *v3d, ARegion *ar, Object *ob, const short dt)
/* if wire over solid, set offset */
index = -1;
- glLoadName(-1);
+ GPU_select_load_id(-1);
if (ELEM(arm->drawtype, ARM_LINE, ARM_WIRE)) {
if (G.f & G_PICKSEL)
index = 0;
@@ -2223,7 +2224,7 @@ static void draw_ebones(View3D *v3d, ARegion *ar, Object *ob, const short dt)
/* offset to parent */
if (eBone->parent) {
UI_ThemeColor(TH_WIRE_EDIT);
- glLoadName(-1); /* -1 here is OK! */
+ GPU_select_load_id(-1); /* -1 here is OK! */
setlinestyle(3);
glBegin(GL_LINES);
@@ -2240,7 +2241,7 @@ static void draw_ebones(View3D *v3d, ARegion *ar, Object *ob, const short dt)
/* restore */
if (index != -1) {
- glLoadName(-1);
+ GPU_select_load_id(-1);
}
if (ELEM(arm->drawtype, ARM_LINE, ARM_WIRE)) {
diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c
index 75d0f86de57..1d54cb0cff9 100644
--- a/source/blender/editors/space_view3d/drawmesh.c
+++ b/source/blender/editors/space_view3d/drawmesh.c
@@ -211,12 +211,16 @@ static Material *give_current_material_or_def(Object *ob, int matnr)
static struct TextureDrawState {
Object *ob;
+ Image *stencil; /* texture painting stencil */
+ Image *canvas; /* texture painting canvas, for image mode */
bool use_game_mat;
int is_lit, is_tex;
int color_profile;
bool use_backface_culling;
unsigned char obcol[4];
-} Gtexdraw = {NULL, false, 0, 0, 0, false, {0, 0, 0, 0}};
+ bool is_texpaint;
+ bool texpaint_material; /* use material slots for texture painting */
+} Gtexdraw = {NULL, NULL, NULL, false, 0, 0, 0, false, {0, 0, 0, 0}, false, false};
static bool set_draw_settings_cached(int clearcache, MTFace *texface, Material *ma, struct TextureDrawState gtexdraw)
{
@@ -228,13 +232,15 @@ static bool set_draw_settings_cached(int clearcache, MTFace *texface, Material *
static int c_lit;
static int c_has_texface;
- Object *litob = NULL; /* to get mode to turn off mipmap in painting mode */
int backculled = 1;
int alphablend = GPU_BLEND_SOLID;
int textured = 0;
int lit = 0;
int has_texface = texface != NULL;
bool need_set_tpage = false;
+ bool texpaint = ((gtexdraw.ob->mode & OB_MODE_TEXTURE_PAINT) != 0);
+
+ Image *ima = NULL;
if (ma != NULL) {
if (ma->mode & MA_TRANSP) {
@@ -247,10 +253,10 @@ static bool set_draw_settings_cached(int clearcache, MTFace *texface, Material *
memset(&c_texface, 0, sizeof(MTFace));
c_badtex = false;
c_has_texface = -1;
+ c_ma = NULL;
}
else {
textured = gtexdraw.is_tex;
- litob = gtexdraw.ob;
}
/* convert number of lights into boolean */
@@ -265,14 +271,19 @@ static bool set_draw_settings_cached(int clearcache, MTFace *texface, Material *
}
}
- if (texface) {
+ if (texface && !texpaint) {
textured = textured && (texface->tpage);
/* no material, render alpha if texture has depth=32 */
if (!ma && BKE_image_has_alpha(texface->tpage))
alphablend = GPU_BLEND_ALPHA;
}
-
+ else if (texpaint && ma) {
+ if (gtexdraw.texpaint_material)
+ ima = ma->texpaintslot ? ma->texpaintslot[ma->paint_active_slot].ima : NULL;
+ else
+ ima = gtexdraw.canvas;
+ }
else
textured = 0;
@@ -286,11 +297,43 @@ static bool set_draw_settings_cached(int clearcache, MTFace *texface, Material *
/* need to re-set tpage if textured flag changed or existsment of texface changed.. */
need_set_tpage = textured != c_textured || has_texface != c_has_texface;
/* ..or if settings inside texface were changed (if texface was used) */
- need_set_tpage |= texface && memcmp(&c_texface, texface, sizeof(c_texface));
+ need_set_tpage |= (texpaint && c_ma != ma) || (texface && memcmp(&c_texface, texface, sizeof(c_texface)));
if (need_set_tpage) {
if (textured) {
- c_badtex = !GPU_set_tpage(texface, !(litob->mode & OB_MODE_TEXTURE_PAINT), alphablend);
+ if (texpaint) {
+ c_badtex = false;
+ if (GPU_verify_image(ima, NULL, 0, 1, 0, false)) {
+ glEnable(GL_TEXTURE_2D);
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PRIMARY_COLOR);
+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_TEXTURE);
+
+ glActiveTexture(GL_TEXTURE1);
+ glEnable(GL_TEXTURE_2D);
+ glBindTexture(GL_TEXTURE_2D, ima->bindcode);
+ glActiveTexture(GL_TEXTURE0);
+ }
+ else {
+ glActiveTexture(GL_TEXTURE1);
+ glDisable(GL_TEXTURE_2D);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ glActiveTexture(GL_TEXTURE0);
+
+ c_badtex = true;
+ GPU_clear_tpage(true);
+ glDisable(GL_TEXTURE_2D);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ }
+ }
+ else {
+ c_badtex = !GPU_set_tpage(texface, !texpaint, alphablend);
+ }
}
else {
GPU_set_tpage(NULL, 0, 0);
@@ -324,6 +367,7 @@ static bool set_draw_settings_cached(int clearcache, MTFace *texface, Material *
glDisable(GL_COLOR_MATERIAL);
}
c_lit = lit;
+ c_ma = ma;
}
return c_badtex;
@@ -334,6 +378,7 @@ static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, O
unsigned char obcol[4];
bool is_tex, solidtex;
Mesh *me = ob->data;
+ ImagePaintSettings *imapaint = &scene->toolsettings->imapaint;
/* XXX scene->obedit warning */
@@ -363,8 +408,52 @@ static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, O
else is_tex = false;
Gtexdraw.ob = ob;
+ Gtexdraw.stencil = (imapaint->flag & IMAGEPAINT_PROJECT_LAYER_STENCIL) ? imapaint->stencil : NULL;
+ Gtexdraw.is_texpaint = (ob->mode == OB_MODE_TEXTURE_PAINT);
+ Gtexdraw.texpaint_material = (imapaint->mode == IMAGEPAINT_MODE_MATERIAL);
+ Gtexdraw.canvas = (Gtexdraw.texpaint_material) ? NULL : imapaint->canvas;
Gtexdraw.is_tex = is_tex;
+ /* naughty multitexturing hacks to quickly support stencil + shading + alpha blending
+ * in new texpaint code. The better solution here would be to support GLSL */
+ if (Gtexdraw.is_texpaint) {
+ glActiveTexture(GL_TEXTURE1);
+ glEnable(GL_TEXTURE_2D);
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PRIMARY_COLOR);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_PREVIOUS);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA);
+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
+
+ /* load the stencil texture here */
+ if (Gtexdraw.stencil != NULL) {
+ glActiveTexture(GL_TEXTURE2);
+ if (GPU_verify_image(Gtexdraw.stencil, NULL, false, false, false, false)) {
+ float col[4] = {imapaint->stencil_col[0], imapaint->stencil_col[1], imapaint->stencil_col[2], 1.0f};
+ glEnable(GL_TEXTURE_2D);
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_CONSTANT);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_TEXTURE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_TEXTURE);
+ glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, col);
+ if ((imapaint->flag & IMAGEPAINT_PROJECT_LAYER_STENCIL_INV) == 0) {
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_ONE_MINUS_SRC_COLOR);
+ }
+ else {
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR);
+ }
+ }
+ }
+ glActiveTexture(GL_TEXTURE0);
+ }
+
Gtexdraw.color_profile = BKE_scene_check_color_management_enabled(scene);
Gtexdraw.use_game_mat = (RE_engines_find(scene->r.engine)->flag & RE_GAME) != 0;
Gtexdraw.use_backface_culling = (v3d->flag2 & V3D_BACKFACE_CULLING) != 0;
@@ -378,8 +467,31 @@ static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, O
static void draw_textured_end(void)
{
- /* switch off textures */
- GPU_set_tpage(NULL, 0, 0);
+ if (Gtexdraw.ob->mode & OB_MODE_TEXTURE_PAINT) {
+ glActiveTexture(GL_TEXTURE1);
+ glDisable(GL_TEXTURE_2D);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR);
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ if (Gtexdraw.stencil != NULL) {
+ glActiveTexture(GL_TEXTURE2);
+ glDisable(GL_TEXTURE_2D);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR);
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ }
+ glActiveTexture(GL_TEXTURE0);
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ /* manual reset, since we don't use tpage */
+ glBindTexture(GL_TEXTURE_2D, 0);
+ /* force switch off textures */
+ GPU_clear_tpage(true);
+ }
+ else {
+ /* switch off textures */
+ GPU_set_tpage(NULL, 0, 0);
+ }
glShadeModel(GL_FLAT);
glDisable(GL_CULL_FACE);
@@ -455,7 +567,7 @@ static DMDrawOption draw_tface__set_draw(MTFace *tface, const bool UNUSED(has_mc
if (ma && (ma->game.flag & GEMAT_INVISIBLE)) return 0;
- if (tface)
+ if (tface || Gtexdraw.is_texpaint)
set_draw_settings_cached(0, tface, ma, Gtexdraw);
/* always use color from mcol, as set in update_tface_color_layer */
@@ -769,7 +881,8 @@ static void draw_mesh_textured_old(Scene *scene, View3D *v3d, RegionView3D *rv3d
Object *ob, DerivedMesh *dm, const int draw_flags)
{
Mesh *me = ob->data;
-
+ DMDrawFlag uvflag = DM_DRAW_USE_ACTIVE_UV;
+
/* correct for negative scale */
if (ob->transflag & OB_NEG_SCALE) glFrontFace(GL_CW);
else glFrontFace(GL_CCW);
@@ -779,6 +892,10 @@ static void draw_mesh_textured_old(Scene *scene, View3D *v3d, RegionView3D *rv3d
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+ if (ob->mode & OB_MODE_TEXTURE_PAINT) {
+ uvflag = DM_DRAW_USE_TEXPAINT_UV;
+ }
+
if (ob->mode & OB_MODE_EDIT) {
drawEMTFMapped_userData data;
@@ -788,7 +905,7 @@ static void draw_mesh_textured_old(Scene *scene, View3D *v3d, RegionView3D *rv3d
data.mf = DM_get_tessface_data_layer(dm, CD_MFACE);
data.tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
- dm->drawMappedFacesTex(dm, draw_em_tf_mapped__set_draw, compareDrawOptionsEm, &data);
+ dm->drawMappedFacesTex(dm, draw_em_tf_mapped__set_draw, compareDrawOptionsEm, &data, 0);
}
else if (draw_flags & DRAW_FACE_SELECT) {
if (ob->mode & OB_MODE_WEIGHT_PAINT)
@@ -800,15 +917,15 @@ static void draw_mesh_textured_old(Scene *scene, View3D *v3d, RegionView3D *rv3d
userData.mf = DM_get_tessface_data_layer(dm, CD_MFACE);
userData.tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
userData.me = me;
- dm->drawMappedFacesTex(dm, me->mpoly ? draw_tface_mapped__set_draw : NULL, compareDrawOptions, &userData);
+ dm->drawMappedFacesTex(dm, me->mpoly ? draw_tface_mapped__set_draw : NULL, compareDrawOptions, &userData, uvflag);
}
}
else {
if (GPU_buffer_legacy(dm)) {
if (draw_flags & DRAW_MODIFIERS_PREVIEW)
- dm->drawFacesTex(dm, draw_mcol__set_draw_legacy, NULL, NULL);
+ dm->drawFacesTex(dm, draw_mcol__set_draw_legacy, NULL, NULL, uvflag);
else
- dm->drawFacesTex(dm, draw_tface__set_draw_legacy, NULL, NULL);
+ dm->drawFacesTex(dm, draw_tface__set_draw_legacy, NULL, NULL, uvflag);
}
else {
drawTFace_userData userData;
@@ -819,7 +936,7 @@ static void draw_mesh_textured_old(Scene *scene, View3D *v3d, RegionView3D *rv3d
userData.tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
userData.me = NULL;
- dm->drawFacesTex(dm, draw_tface__set_draw, compareDrawOptions, &userData);
+ dm->drawFacesTex(dm, draw_tface__set_draw, compareDrawOptions, &userData, uvflag);
}
}
@@ -866,7 +983,7 @@ static void tex_mat_set_texture_cb(void *userData, int mat_nr, void *attribs)
int texture_set = 0;
/* draw image texture if we find one */
- if (ED_object_get_active_image(data->ob, mat_nr, &ima, &iuser, &node)) {
+ if (ED_object_get_active_image(data->ob, mat_nr, &ima, &iuser, &node, NULL)) {
/* get openl texture */
int mipmap = 1;
int bindcode = (ima) ? GPU_verify_image(ima, iuser, 0, 0, mipmap, false) : 0;
@@ -951,7 +1068,8 @@ void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d,
/* if not cycles, or preview-modifiers, or drawing matcaps */
if ((draw_flags & DRAW_MODIFIERS_PREVIEW) ||
(v3d->flag2 & V3D_SHOW_SOLID_MATCAP) ||
- (BKE_scene_use_new_shading_nodes(scene) == false))
+ (BKE_scene_use_new_shading_nodes(scene) == false) ||
+ ((ob->mode & OB_MODE_TEXTURE_PAINT) && ELEM(v3d->drawtype, OB_TEXTURE, OB_SOLID)))
{
draw_mesh_textured_old(scene, v3d, rv3d, ob, dm, draw_flags);
return;
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index e51ce652b53..5694f388780 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -86,6 +86,7 @@
#include "GPU_draw.h"
#include "GPU_extensions.h"
+#include "GPU_select.h"
#include "ED_mesh.h"
#include "ED_particle.h"
@@ -109,7 +110,7 @@
*
* Ideally we don't want to evaluate objects from drawing,
* but it'll require some major sequencer re-design. So
- * for now just fallback to legacy behaior with calling
+ * for now just fallback to legacy behavior with calling
* display ist creating from draw().
*/
#define SEQUENCER_DAG_WORKAROUND
@@ -301,7 +302,7 @@ bool draw_glsl_material(Scene *scene, Object *ob, View3D *v3d, const char dt)
if (BKE_scene_use_new_shading_nodes(scene))
return false;
- return (scene->gm.matmode == GAME_MAT_GLSL) && (dt > OB_SOLID);
+ return ((scene->gm.matmode == GAME_MAT_GLSL) || (v3d->drawtype == OB_MATERIAL)) && (dt > OB_SOLID);
}
static bool check_alpha_pass(Base *base)
@@ -1585,7 +1586,7 @@ static void draw_viewport_object_reconstruction(Scene *scene, Base *base, View3D
continue;
if (dflag & DRAW_PICKING)
- glLoadName(base->selcol + (tracknr << 16));
+ GPU_select_load_id(base->selcol + (tracknr << 16));
glPushMatrix();
glTranslatef(track->bundle_pos[0], track->bundle_pos[1], track->bundle_pos[2]);
@@ -1736,7 +1737,7 @@ static void draw_viewport_reconstruction(Scene *scene, Base *base, View3D *v3d,
}
if (dflag & DRAW_PICKING)
- glLoadName(base->selcol);
+ GPU_select_load_id(base->selcol);
}
/* flag similar to draw_object() */
@@ -3609,7 +3610,7 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d,
draw_dm_vert_normals(em, scene, ob, cageDM);
}
if (me->drawflag & ME_DRAW_LNORMALS) {
- UI_ThemeColor(TH_VNORMAL);
+ UI_ThemeColor(TH_LNORMAL);
draw_dm_loop_normals(em, scene, ob, cageDM);
}
@@ -4867,7 +4868,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
normalize_v3(imat[1]);
}
- if (ELEM3(draw_as, PART_DRAW_DOT, PART_DRAW_CROSS, PART_DRAW_LINE) &&
+ if (ELEM(draw_as, PART_DRAW_DOT, PART_DRAW_CROSS, PART_DRAW_LINE) &&
(part->draw_col > PART_DRAW_COL_MAT))
{
create_cdata = 1;
@@ -5879,7 +5880,7 @@ static void editnurb_draw_active_nurbs(Nurb *nu)
glLineWidth(1);
}
-static void draw_editnurb(Object *ob, Nurb *nurb, int sel)
+static void draw_editnurb_splines(Object *ob, Nurb *nurb, const bool sel)
{
Nurb *nu;
BPoint *bp, *bp1;
@@ -5995,8 +5996,9 @@ static void draw_editnurb(Object *ob, Nurb *nurb, int sel)
}
}
-static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, Nurb *nurb,
- const char dt, const short dflag, const unsigned char ob_wire_col[4])
+static void draw_editnurb(
+ Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, Nurb *nurb,
+ const char dt, const short dflag, const unsigned char ob_wire_col[4])
{
ToolSettings *ts = scene->toolsettings;
Object *ob = base->object;
@@ -6014,6 +6016,11 @@ static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
drawDispList(scene, v3d, rv3d, base, dt, dflag, ob_wire_col);
+ /* for shadows only show solid faces */
+ if (v3d->flag2 & V3D_RENDER_SHADOW) {
+ return;
+ }
+
if (v3d->zbuf) glDepthFunc(GL_ALWAYS);
/* first non-selected and active handles */
@@ -6026,8 +6033,8 @@ static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
}
index++;
}
- draw_editnurb(ob, nurb, 0);
- draw_editnurb(ob, nurb, 1);
+ draw_editnurb_splines(ob, nurb, false);
+ draw_editnurb_splines(ob, nurb, true);
/* selected handles */
for (nu = nurb; nu; nu = nu->next) {
if (nu->type == CU_BEZIER && (cu->drawflag & CU_HIDE_HANDLES) == 0)
@@ -6037,11 +6044,11 @@ static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
if (v3d->zbuf) glDepthFunc(GL_LEQUAL);
+ glColor3ubv(wire_col);
+
/* direction vectors for 3d curve paths
* when at its lowest, don't render normals */
if ((cu->flag & CU_3D) && (ts->normalsize > 0.0015f) && (cu->drawflag & CU_HIDE_NORMALS) == 0) {
-
- UI_ThemeColor(TH_WIRE_EDIT);
for (bl = ob->curve_cache->bev.first, nu = nurb; nu && bl; bl = bl->next, nu = nu->next) {
BevPoint *bevp = bl->bevpoints;
int nr = bl->nr;
@@ -6478,7 +6485,7 @@ static bool drawmball(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
if (G.f & G_PICKSEL) {
ml->selcol1 = code;
- glLoadName(code++);
+ GPU_select_load_id(code++);
}
}
drawcircball(GL_LINE_LOOP, &(ml->x), ml->rad, imat);
@@ -6492,7 +6499,7 @@ static bool drawmball(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
if (G.f & G_PICKSEL) {
ml->selcol2 = code;
- glLoadName(code++);
+ GPU_select_load_id(code++);
}
drawcircball(GL_LINE_LOOP, &(ml->x), ml->rad * atanf(ml->s) / (float)M_PI_2, imat);
}
@@ -6698,28 +6705,6 @@ static void draw_box(float vec[8][3])
glEnd();
}
-/* uses boundbox, function used by Ketsji */
-#if 0
-static void get_local_bounds(Object *ob, float center[3], float size[3])
-{
- BoundBox *bb = BKE_object_boundbox_get(ob);
-
- if (bb == NULL) {
- zero_v3(center);
- copy_v3_v3(size, ob->size);
- }
- else {
- size[0] = 0.5 * fabsf(bb->vec[0][0] - bb->vec[4][0]);
- size[1] = 0.5 * fabsf(bb->vec[0][1] - bb->vec[2][1]);
- size[2] = 0.5 * fabsf(bb->vec[0][2] - bb->vec[1][2]);
-
- center[0] = (bb->vec[0][0] + bb->vec[4][0]) / 2.0;
- center[1] = (bb->vec[0][1] + bb->vec[2][1]) / 2.0;
- center[2] = (bb->vec[0][2] + bb->vec[1][2]) / 2.0;
- }
-}
-#endif
-
static void draw_bb_quadric(BoundBox *bb, char type, bool around_origin)
{
float size[3], cent[3];
@@ -6727,17 +6712,13 @@ static void draw_bb_quadric(BoundBox *bb, char type, bool around_origin)
gluQuadricDrawStyle(qobj, GLU_SILHOUETTE);
- size[0] = 0.5f * fabsf(bb->vec[0][0] - bb->vec[4][0]);
- size[1] = 0.5f * fabsf(bb->vec[0][1] - bb->vec[2][1]);
- size[2] = 0.5f * fabsf(bb->vec[0][2] - bb->vec[1][2]);
+ BKE_boundbox_calc_size_aabb(bb, size);
if (around_origin) {
zero_v3(cent);
}
else {
- cent[0] = 0.5f * (bb->vec[0][0] + bb->vec[4][0]);
- cent[1] = 0.5f * (bb->vec[0][1] + bb->vec[2][1]);
- cent[2] = 0.5f * (bb->vec[0][2] + bb->vec[1][2]);
+ BKE_boundbox_calc_center_aabb(bb, cent);
}
glPushMatrix();
@@ -6781,7 +6762,7 @@ static void draw_bounding_volume(Object *ob, char type)
if (ob->type == OB_MESH) {
bb = BKE_mesh_boundbox_get(ob);
}
- else if (ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
+ else if (ELEM(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
bb = BKE_curve_boundbox_get(ob);
}
else if (ob->type == OB_MBALL) {
@@ -6806,9 +6787,7 @@ static void draw_bounding_volume(Object *ob, char type)
if (type == OB_BOUND_BOX) {
float vec[8][3], size[3];
- size[0] = 0.5f * fabsf(bb->vec[0][0] - bb->vec[4][0]);
- size[1] = 0.5f * fabsf(bb->vec[0][1] - bb->vec[2][1]);
- size[2] = 0.5f * fabsf(bb->vec[0][2] - bb->vec[1][2]);
+ BKE_boundbox_calc_size_aabb(bb, size);
vec[0][0] = vec[1][0] = vec[2][0] = vec[3][0] = -size[0];
vec[4][0] = vec[5][0] = vec[6][0] = vec[7][0] = +size[0];
@@ -6838,7 +6817,7 @@ static void drawtexspace(Object *ob)
if (ob->type == OB_MESH) {
BKE_mesh_texspace_get(ob->data, loc, NULL, size);
}
- else if (ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
+ else if (ELEM(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
BKE_curve_texspace_get(ob->data, loc, NULL, size);
}
else if (ob->type == OB_MBALL) {
@@ -6876,7 +6855,7 @@ static void drawObjectSelect(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
glLineWidth(UI_GetThemeValuef(TH_OUTLINE_WIDTH) * 2.0f);
glDepthMask(0);
- if (ELEM3(ob->type, OB_FONT, OB_CURVE, OB_SURF)) {
+ if (ELEM(ob->type, OB_FONT, OB_CURVE, OB_SURF)) {
DerivedMesh *dm = ob->derivedFinal;
bool has_faces = false;
@@ -6920,7 +6899,7 @@ static void drawObjectSelect(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
static void draw_wire_extra(Scene *scene, RegionView3D *rv3d, Object *ob, const unsigned char ob_wire_col[4])
{
- if (ELEM4(ob->type, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL)) {
+ if (ELEM(ob->type, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL)) {
if (scene->obedit == ob) {
UI_ThemeColor(TH_WIRE_EDIT);
@@ -6932,7 +6911,7 @@ static void draw_wire_extra(Scene *scene, RegionView3D *rv3d, Object *ob, const
ED_view3d_polygon_offset(rv3d, 1.0);
glDepthMask(0); /* disable write in zbuffer, selected edge wires show better */
- if (ELEM3(ob->type, OB_FONT, OB_CURVE, OB_SURF)) {
+ if (ELEM(ob->type, OB_FONT, OB_CURVE, OB_SURF)) {
if (ED_view3d_boundbox_clip(rv3d, ob->bb)) {
if (ob->derivedFinal) {
@@ -7123,9 +7102,7 @@ static void draw_rigidbody_shape(Object *ob)
switch (ob->rigidbody_object->shape) {
case RB_SHAPE_BOX:
- size[0] = 0.5f * fabsf(bb->vec[0][0] - bb->vec[4][0]);
- size[1] = 0.5f * fabsf(bb->vec[0][1] - bb->vec[2][1]);
- size[2] = 0.5f * fabsf(bb->vec[0][2] - bb->vec[1][2]);
+ BKE_boundbox_calc_size_aabb(bb, size);
vec[0][0] = vec[1][0] = vec[2][0] = vec[3][0] = -size[0];
vec[4][0] = vec[5][0] = vec[6][0] = vec[7][0] = +size[0];
@@ -7170,23 +7147,23 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
const bool is_obact = (ob == OBACT);
const bool render_override = (v3d->flag2 & V3D_RENDER_OVERRIDE) != 0;
const bool is_picking = (G.f & G_PICKSEL) != 0;
- bool skip_object = false;
+ const bool has_particles = (ob->particlesystem.first != NULL);
bool particle_skip_object = false; /* Draw particles but not their emitter object. */
if (ob != scene->obedit) {
if (ob->restrictflag & OB_RESTRICT_VIEW)
- skip_object = true;
+ return;
if (render_override) {
if (ob->restrictflag & OB_RESTRICT_RENDER)
- skip_object = true;
+ return;
- if (ob->transflag & OB_DUPLI)
- skip_object = true; /* note: can be reset by particle "draw emitter" below */
+ if (!has_particles && (ob->transflag & (OB_DUPLI & ~OB_DUPLIFRAMES)))
+ return;
}
}
- if (ob->particlesystem.first) {
+ if (has_particles) {
/* XXX particles are not safe for simultaneous threaded render */
if (G.is_rendering) {
return;
@@ -7199,7 +7176,6 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
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) {
- skip_object = false;
particle_skip_object = false;
break;
}
@@ -7207,9 +7183,6 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
}
}
- if (skip_object)
- 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 */
@@ -7354,7 +7327,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
if (cu->editnurb) {
ListBase *nurbs = BKE_curve_editNurbs_get(cu);
- drawnurb(scene, v3d, rv3d, base, nurbs->first, dt, dflag, ob_wire_col);
+ draw_editnurb(scene, v3d, rv3d, base, nurbs->first, dt, dflag, ob_wire_col);
}
else if (dt == OB_BOUNDBOX) {
if ((render_override && (v3d->drawtype >= OB_WIRE)) == 0) {
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index 7a4634bf01a..8b76ec3a56d 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -43,7 +43,9 @@
#include "BLI_utildefines.h"
#include "BKE_context.h"
+#include "BKE_depsgraph.h"
#include "BKE_icons.h"
+#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_object.h"
#include "BKE_scene.h"
@@ -285,7 +287,7 @@ static void view3d_stop_render_preview(wmWindowManager *wm, ARegion *ar)
}
}
-void ED_view3d_shade_update(Main *bmain, View3D *v3d, ScrArea *sa)
+void ED_view3d_shade_update(Main *bmain, Scene *scene, View3D *v3d, ScrArea *sa)
{
wmWindowManager *wm = bmain->wm.first;
@@ -297,6 +299,10 @@ void ED_view3d_shade_update(Main *bmain, View3D *v3d, ScrArea *sa)
view3d_stop_render_preview(wm, ar);
}
}
+ else if (scene->obedit != NULL && scene->obedit->type == OB_MESH) {
+ /* Tag mesh to load edit data. */
+ DAG_id_tag_update(scene->obedit->data, 0);
+ }
}
/* ******************** default callbacks for view3d space ***************** */
@@ -389,7 +395,16 @@ static SpaceLink *view3d_new(const bContext *C)
static void view3d_free(SpaceLink *sl)
{
View3D *vd = (View3D *) sl;
+ BGpic *bgpic;
+ for (bgpic = vd->bgpicbase.first; bgpic; bgpic = bgpic->next) {
+ if (bgpic->source == V3D_BGPIC_IMAGE) {
+ id_us_min((ID *)bgpic->ima);
+ }
+ else if (bgpic->source == V3D_BGPIC_MOVIE) {
+ id_us_min((ID *)bgpic->clip);
+ }
+ }
BLI_freelistN(&vd->bgpicbase);
if (vd->localvd) MEM_freeN(vd->localvd);
@@ -416,6 +431,7 @@ static SpaceLink *view3d_duplicate(SpaceLink *sl)
{
View3D *v3do = (View3D *)sl;
View3D *v3dn = MEM_dupallocN(sl);
+ BGpic *bgpic;
/* clear or remove stuff from old */
@@ -433,8 +449,16 @@ static SpaceLink *view3d_duplicate(SpaceLink *sl)
/* copy or clear inside new stuff */
v3dn->defmaterial = NULL;
-
+
BLI_duplicatelist(&v3dn->bgpicbase, &v3do->bgpicbase);
+ for (bgpic = v3dn->bgpicbase.first; bgpic; bgpic = bgpic->next) {
+ if (bgpic->source == V3D_BGPIC_IMAGE) {
+ id_us_plus((ID *)bgpic->ima);
+ }
+ else if (bgpic->source == V3D_BGPIC_MOVIE) {
+ id_us_plus((ID *)bgpic->clip);
+ }
+ }
v3dn->properties_storage = NULL;
@@ -464,6 +488,12 @@ static void view3d_main_area_init(wmWindowManager *wm, ARegion *ar)
keymap = WM_keymap_find(wm->defaultconf, "Object Mode", 0, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
+ keymap = WM_keymap_find(wm->defaultconf, "Paint Curve", 0, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
+
+ keymap = WM_keymap_find(wm->defaultconf, "Curve", 0, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
+
keymap = WM_keymap_find(wm->defaultconf, "Image Paint", 0, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
@@ -654,7 +684,7 @@ static void view3d_dropboxes(void)
WM_dropbox_add(lb, "MESH_OT_drop_named_image", view3d_ima_mesh_drop_poll, view3d_id_path_drop_copy);
WM_dropbox_add(lb, "OBJECT_OT_drop_named_image", view3d_ima_empty_drop_poll, view3d_id_path_drop_copy);
WM_dropbox_add(lb, "VIEW3D_OT_background_image_add", view3d_ima_bg_drop_poll, view3d_id_path_drop_copy);
- WM_dropbox_add(lb, "OBJECT_OT_group_instance_add", view3d_group_drop_poll, view3d_group_drop_copy);
+ WM_dropbox_add(lb, "OBJECT_OT_group_instance_add", view3d_group_drop_poll, view3d_group_drop_copy);
}
@@ -760,7 +790,7 @@ static void view3d_main_area_listener(bScreen *sc, ScrArea *sa, ARegion *ar, wmN
break;
case ND_NLA:
case ND_KEYFRAME:
- if (ELEM3(wmn->action, NA_EDITED, NA_ADDED, NA_REMOVED))
+ if (ELEM(wmn->action, NA_EDITED, NA_ADDED, NA_REMOVED))
ED_region_tag_redraw(ar);
break;
case ND_ANIMCHAN:
@@ -841,14 +871,18 @@ static void view3d_main_area_listener(bScreen *sc, ScrArea *sa, ARegion *ar, wmN
switch (wmn->data) {
case ND_SHADING:
case ND_NODES:
+ {
+ Object *ob = OBACT;
if ((v3d->drawtype == OB_MATERIAL) ||
+ (ob && (ob->mode == OB_MODE_TEXTURE_PAINT)) ||
(v3d->drawtype == OB_TEXTURE &&
- (scene->gm.matmode == GAME_MAT_GLSL ||
- BKE_scene_use_new_shading_nodes(scene))))
+ (scene->gm.matmode == GAME_MAT_GLSL ||
+ BKE_scene_use_new_shading_nodes(scene))))
{
ED_region_tag_redraw(ar);
}
break;
+ }
case ND_SHADING_DRAW:
case ND_SHADING_LINKS:
ED_region_tag_redraw(ar);
@@ -886,7 +920,7 @@ static void view3d_main_area_listener(bScreen *sc, ScrArea *sa, ARegion *ar, wmN
ED_region_tag_redraw(ar);
break;
case NC_MOVIECLIP:
- if (wmn->data == ND_DISPLAY)
+ if (wmn->data == ND_DISPLAY || wmn->action == NA_EDITED)
ED_region_tag_redraw(ar);
break;
case NC_SPACE:
@@ -1011,7 +1045,7 @@ static void view3d_buttons_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa
break;
case ND_NLA:
case ND_KEYFRAME:
- if (ELEM3(wmn->action, NA_EDITED, NA_ADDED, NA_REMOVED))
+ if (ELEM(wmn->action, NA_EDITED, NA_ADDED, NA_REMOVED))
ED_region_tag_redraw(ar);
break;
}
@@ -1080,6 +1114,11 @@ static void view3d_buttons_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa
if (wmn->data == ND_DATA || wmn->action == NA_EDITED)
ED_region_tag_redraw(ar);
break;
+ case NC_IMAGE:
+ /* Update for the image layers in texture paint. */
+ if (wmn->action == NA_EDITED)
+ ED_region_tag_redraw(ar);
+ break;
}
}
diff --git a/source/blender/editors/space_view3d/view3d_camera_control.c b/source/blender/editors/space_view3d/view3d_camera_control.c
index e96db2b220f..ee0f3da18b4 100644
--- a/source/blender/editors/space_view3d/view3d_camera_control.c
+++ b/source/blender/editors/space_view3d/view3d_camera_control.c
@@ -31,9 +31,9 @@
*
* Typical view-control usage:
*
- * - aquire a view-control (#ED_view3d_control_aquire).
+ * - acquire a view-control (#ED_view3d_control_acquire).
* - modify ``rv3d->ofs``, ``rv3d->viewquat``.
- * - update the view data (#ED_view3d_control_aquire) - within a loop which draws the viewport.
+ * - update the view data (#ED_view3d_control_acquire) - within a loop which draws the viewport.
* - finish and release the view-control (#ED_view3d_control_release),
* either keeping the current view or restoring the initial view.
*
@@ -138,7 +138,7 @@ Object *ED_view3d_cameracontrol_object_get(View3DCameraControl *vctrl)
* Creates a #View3DControl handle and sets up
* the view for first-person style navigation.
*/
-struct View3DCameraControl *ED_view3d_cameracontrol_aquire(
+struct View3DCameraControl *ED_view3d_cameracontrol_acquire(
Scene *scene, View3D *v3d, RegionView3D *rv3d,
const bool use_parent_root)
{
@@ -282,7 +282,7 @@ void ED_view3d_cameracontrol_update(
* Release view control.
*
* \param restore Sets the view state to the values that were set
- * before #ED_view3d_control_aquire was called.
+ * before #ED_view3d_control_acquire was called.
*/
void ED_view3d_cameracontrol_release(
View3DCameraControl *vctrl,
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 03808a82041..be3aaa13818 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -878,7 +878,7 @@ static void draw_selected_name(Scene *scene, Object *ob, rcti *rect)
}
}
}
- else if (ELEM3(ob->type, OB_MESH, OB_LATTICE, OB_CURVE)) {
+ else if (ELEM(ob->type, OB_MESH, OB_LATTICE, OB_CURVE)) {
Key *key = NULL;
KeyBlock *kb = NULL;
@@ -1283,6 +1283,12 @@ static void backdrawview3d(Scene *scene, ARegion *ar, View3D *v3d)
{
/* do nothing */
}
+ /* texture paint mode sampling */
+ else if (base && (base->object->mode & OB_MODE_TEXTURE_PAINT) &&
+ (v3d->drawtype > OB_WIRE))
+ {
+ /* do nothing */
+ }
else if ((base && (base->object->mode & OB_MODE_PARTICLE_EDIT)) &&
v3d->drawtype > OB_WIRE && (v3d->flag & V3D_ZBUF_SELECT))
{
@@ -1976,6 +1982,7 @@ static void draw_dupli_objects_color(
DupliApplyData *apply_data;
if (base->object->restrictflag & OB_RESTRICT_VIEW) return;
+ if ((base->object->restrictflag & OB_RESTRICT_RENDER) && (v3d->flag2 & V3D_RENDER_OVERRIDE)) return;
if (dflag & DRAW_CONSTCOLOR) {
BLI_assert(color == TH_UNDEFINED);
@@ -2503,7 +2510,7 @@ CustomDataMask ED_view3d_datamask(Scene *scene, View3D *v3d)
mask |= CD_MASK_ORCO;
}
else {
- if (scene->gm.matmode == GAME_MAT_GLSL)
+ if (scene->gm.matmode == GAME_MAT_GLSL || v3d->drawtype == OB_MATERIAL)
mask |= CD_MASK_ORCO;
}
}
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index e3260dba485..db675b09896 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -78,6 +78,7 @@
#include "ED_view3d.h"
#include "ED_sculpt.h"
+#include "UI_resources.h"
#include "PIL_time.h" /* smoothview */
@@ -307,12 +308,12 @@ static void view3d_boxview_clip(ScrArea *sa)
}
for (val = 0; val < 8; val++) {
- if (ELEM4(val, 0, 3, 4, 7))
+ if (ELEM(val, 0, 3, 4, 7))
bb->vec[val][0] = -x1 - ofs[0];
else
bb->vec[val][0] = x1 - ofs[0];
- if (ELEM4(val, 0, 1, 4, 5))
+ if (ELEM(val, 0, 1, 4, 5))
bb->vec[val][1] = -y1 - ofs[1];
else
bb->vec[val][1] = y1 - ofs[1];
@@ -465,11 +466,13 @@ void ED_view3d_quadview_update(ScrArea *sa, ARegion *ar, bool do_clip)
* properties are always being edited, weak */
viewlock = rv3d->viewlock;
- if ((viewlock & RV3D_LOCKED) == 0)
+ if ((viewlock & RV3D_LOCKED) == 0) {
+ do_clip = (viewlock & RV3D_BOXCLIP) != 0;
viewlock = 0;
- else if ((viewlock & RV3D_BOXVIEW) == 0) {
- viewlock &= ~RV3D_BOXCLIP;
+ }
+ else if ((viewlock & RV3D_BOXVIEW) == 0 && (viewlock & RV3D_BOXCLIP) != 0) {
do_clip = true;
+ viewlock &= ~RV3D_BOXCLIP;
}
for (; ar; ar = ar->prev) {
@@ -648,6 +651,39 @@ static bool view3d_orbit_calc_center(bContext *C, float r_dyn_ofs[3])
is_set = true;
}
+ else if (ob == NULL || ob->mode == OB_MODE_OBJECT) {
+ /* object mode use boundbox centers */
+ View3D *v3d = CTX_wm_view3d(C);
+ Base *base;
+ unsigned int tot = 0;
+ float select_center[3];
+
+ zero_v3(select_center);
+ for (base = FIRSTBASE; base; base = base->next) {
+ if (TESTBASE(v3d, base)) {
+ /* use the boundbox if we can */
+ Object *ob = base->object;
+
+ if (ob->bb && !(ob->bb->flag & BOUNDBOX_DIRTY)) {
+ float cent[3];
+
+ BKE_boundbox_calc_center_aabb(ob->bb, cent);
+
+ mul_m4_v3(ob->obmat, cent);
+ add_v3_v3(select_center, cent);
+ }
+ else {
+ add_v3_v3(select_center, ob->obmat[3]);
+ }
+ tot++;
+ }
+ }
+ if (tot) {
+ mul_v3_fl(select_center, 1.0f / (float)tot);
+ copy_v3_v3(lastofs, select_center);
+ is_set = true;
+ }
+ }
else {
/* If there's no selection, lastofs is unmodified and last value since static */
is_set = calculateTransformCenter(C, V3D_CENTROID, lastofs, NULL);
@@ -1136,7 +1172,7 @@ static int viewrotate_modal(bContext *C, wmOperator *op, const wmEvent *event)
*
* shared with NDOF.
*/
-static void view3d_ensure_persp(struct View3D *v3d, ARegion *ar)
+static bool view3d_ensure_persp(struct View3D *v3d, ARegion *ar)
{
RegionView3D *rv3d = ar->regiondata;
const bool autopersp = (U.uiflag & USER_AUTOPERSP) != 0;
@@ -1144,7 +1180,7 @@ static void view3d_ensure_persp(struct View3D *v3d, ARegion *ar)
BLI_assert((rv3d->viewlock & RV3D_LOCKED) == 0);
if (ED_view3d_camera_lock_check(v3d, rv3d))
- return;
+ return false;
if (rv3d->persp != RV3D_PERSP) {
if (rv3d->persp == RV3D_CAMOB) {
@@ -1155,7 +1191,10 @@ static void view3d_ensure_persp(struct View3D *v3d, ARegion *ar)
else if (autopersp && RV3D_VIEW_IS_AXIS(rv3d->view)) {
rv3d->persp = RV3D_PERSP;
}
+ return true;
}
+
+ return false;
}
static int viewrotate_invoke(bContext *C, wmOperator *op, const wmEvent *event)
@@ -1174,8 +1213,14 @@ static int viewrotate_invoke(bContext *C, wmOperator *op, const wmEvent *event)
}
/* switch from camera view when: */
- view3d_ensure_persp(vod->v3d, vod->ar);
-
+ if (view3d_ensure_persp(vod->v3d, vod->ar)) {
+ /* If we're switching from camera view to the perspective one,
+ * need to tag viewport update, so camera vuew and borders
+ * are properly updated.
+ */
+ ED_region_tag_redraw(vod->ar);
+ }
+
if (event->type == MOUSEPAN) {
/* Rotate direction we keep always same */
if (U.uiflag2 & USER_TRACKPAD_NATURAL)
@@ -2070,9 +2115,12 @@ static void viewzoom_apply(ViewOpsData *vod, const int xy[2], const short viewzo
{
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;
@@ -2139,16 +2187,19 @@ static void viewzoom_apply(ViewOpsData *vod, const int xy[2], const short viewzo
}
if (!use_cam_zoom) {
- if (zfac != 1.0f && zfac * vod->rv3d->dist > 0.001f * vod->grid &&
- zfac * vod->rv3d->dist < 10.0f * vod->far)
- {
- view_zoom_mouseloc(vod->ar, zfac, vod->oldx, vod->oldy);
+ 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);
+ }
}
}
/* these limits were in old code too */
- if (vod->rv3d->dist < 0.001f * vod->grid) vod->rv3d->dist = 0.001f * vod->grid;
- if (vod->rv3d->dist > 10.0f * vod->far) vod->rv3d->dist = 10.0f * vod->far;
+ CLAMP(vod->rv3d->dist, dist_range[0], dist_range[1]);
if (vod->rv3d->viewlock & RV3D_BOXVIEW)
view3d_boxview_sync(vod->sa, vod->ar);
@@ -2212,6 +2263,7 @@ static int viewzoom_exec(bContext *C, wmOperator *op)
ScrArea *sa;
ARegion *ar;
bool use_cam_zoom;
+ float dist_range[2];
const int delta = RNA_int_get(op->ptr, "delta");
int mx, my;
@@ -2235,13 +2287,15 @@ static int viewzoom_exec(bContext *C, wmOperator *op)
use_cam_zoom = (rv3d->persp == RV3D_CAMOB) && !(rv3d->is_persp && ED_view3d_camera_lock_check(v3d, rv3d));
+ ED_view3d_dist_range_get(v3d, dist_range);
+
if (delta < 0) {
/* 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;
}
- else if (rv3d->dist < 10.0f * v3d->far) {
+ else if (rv3d->dist < dist_range[1]) {
view_zoom_mouseloc(ar, 1.2f, mx, my);
}
}
@@ -2250,7 +2304,7 @@ static int viewzoom_exec(bContext *C, wmOperator *op)
rv3d->camzoom += 10.0f;
if (rv3d->camzoom > RV3D_CAMZOOM_MAX) rv3d->camzoom = RV3D_CAMZOOM_MAX;
}
- else if (rv3d->dist > 0.001f * v3d->grid) {
+ else if (rv3d->dist > dist_range[0]) {
view_zoom_mouseloc(ar, 0.83333f, mx, my);
}
}
@@ -2363,6 +2417,8 @@ static void viewzoom_cancel(bContext *C, wmOperator *op)
void VIEW3D_OT_zoom(wmOperatorType *ot)
{
+ PropertyRNA *prop;
+
/* identifiers */
ot->name = "Zoom View";
ot->description = "Zoom in/out in the view";
@@ -2379,8 +2435,10 @@ void VIEW3D_OT_zoom(wmOperatorType *ot)
ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_POINTER;
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);
- RNA_def_int(ot->srna, "my", 0, 0, INT_MAX, "Zoom Position Y", "", 0, INT_MAX);
+ prop = RNA_def_int(ot->srna, "mx", 0, 0, INT_MAX, "Zoom Position X", "", 0, INT_MAX);
+ RNA_def_property_flag(prop, PROP_HIDDEN);
+ prop = RNA_def_int(ot->srna, "my", 0, 0, INT_MAX, "Zoom Position Y", "", 0, INT_MAX);
+ RNA_def_property_flag(prop, PROP_HIDDEN);
}
@@ -3243,6 +3301,8 @@ static int render_border_exec(bContext *C, wmOperator *op)
void VIEW3D_OT_render_border(wmOperatorType *ot)
{
+ PropertyRNA *prop;
+
/* identifiers */
ot->name = "Set Render Border";
ot->description = "Set the boundaries of the border render and enable border render";
@@ -3262,7 +3322,8 @@ void VIEW3D_OT_render_border(wmOperatorType *ot)
/* rna */
WM_operator_properties_border(ot);
- RNA_def_boolean(ot->srna, "camera_only", 0, "Camera Only", "Set render border for camera view and final render only");
+ prop = RNA_def_boolean(ot->srna, "camera_only", 0, "Camera Only", "Set render border for camera view and final render only");
+ RNA_def_property_flag(prop, PROP_HIDDEN);
}
/* ********************* Clear render border operator ****************** */
@@ -3326,7 +3387,7 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op)
/* Zooms in on a border drawn by the user */
rcti rect;
float dvec[3], vb[2], xscale, yscale;
- float dist_range_min;
+ float dist_range[2];
/* SMOOTHVIEW */
float new_dist;
@@ -3346,6 +3407,8 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op)
/* check if zooming in/out view */
gesture_mode = RNA_int_get(op->ptr, "gesture_mode");
+ ED_view3d_dist_range_get(v3d, dist_range);
+
/* Get Z Depths, needed for perspective, nice for ortho */
bgl_get_mats(&mats);
ED_view3d_draw_depth(scene, ar, v3d, true);
@@ -3394,8 +3457,9 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op)
new_ofs[2] = -p[2];
new_dist = len_v3(dvec);
- dist_range_min = v3d->near * 1.5f;
+ /* ignore dist_range min */
+ dist_range[0] = v3d->near * 1.5f;
}
else { /* othographic */
/* find the current window width and height */
@@ -3437,9 +3501,6 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op)
xscale = (BLI_rcti_size_x(&rect) / vb[0]);
yscale = (BLI_rcti_size_y(&rect) / vb[1]);
new_dist *= max_ff(xscale, yscale);
-
- /* zoom in as required, or as far as we can go */
- dist_range_min = 0.001f * v3d->grid;
}
if (gesture_mode == GESTURE_MODAL_OUT) {
@@ -3449,9 +3510,7 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op)
}
/* clamp after because we may have been zooming out */
- if (new_dist < dist_range_min) {
- new_dist = dist_range_min;
- }
+ CLAMP(new_dist, dist_range[0], dist_range[1]);
ED_view3d_smooth_view(C, v3d, ar, NULL, NULL,
new_ofs, NULL, &new_dist, NULL,
@@ -3545,13 +3604,13 @@ void VIEW3D_OT_zoom_camera_1_to_1(wmOperatorType *ot)
/* ********************* Changing view operator ****************** */
static EnumPropertyItem prop_view_items[] = {
+ {RV3D_VIEW_LEFT, "LEFT", ICON_TRIA_LEFT, "Left", "View From the Left"},
+ {RV3D_VIEW_RIGHT, "RIGHT", ICON_TRIA_RIGHT, "Right", "View From the Right"},
+ {RV3D_VIEW_BOTTOM, "BOTTOM", ICON_TRIA_DOWN, "Bottom", "View From the Bottom"},
+ {RV3D_VIEW_TOP, "TOP", ICON_TRIA_UP, "Top", "View From the Top"},
{RV3D_VIEW_FRONT, "FRONT", 0, "Front", "View From the Front"},
{RV3D_VIEW_BACK, "BACK", 0, "Back", "View From the Back"},
- {RV3D_VIEW_LEFT, "LEFT", 0, "Left", "View From the Left"},
- {RV3D_VIEW_RIGHT, "RIGHT", 0, "Right", "View From the Right"},
- {RV3D_VIEW_TOP, "TOP", 0, "Top", "View From the Top"},
- {RV3D_VIEW_BOTTOM, "BOTTOM", 0, "Bottom", "View From the Bottom"},
- {RV3D_VIEW_CAMERA, "CAMERA", 0, "Camera", "View From the Active Camera"},
+ {RV3D_VIEW_CAMERA, "CAMERA", ICON_CAMERA_DATA, "Camera", "View From the Active Camera"},
{0, NULL, 0, NULL, NULL}
};
@@ -4435,7 +4494,7 @@ void ED_view3d_cursor3d_position(bContext *C, float fp[3], const int mval[2])
}
}
-static void view3d_cursor3d_update(bContext *C, const int *mval)
+void ED_view3d_cursor3d_update(bContext *C, const int mval[2])
{
Scene *scene = CTX_data_scene(C);
View3D *v3d = CTX_wm_view3d(C);
@@ -4449,32 +4508,11 @@ static void view3d_cursor3d_update(bContext *C, const int *mval)
WM_event_add_notifier(C, NC_SCENE | NA_EDITED, scene);
}
-static int view3d_cursor3d_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+static int view3d_cursor3d_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
- view3d_cursor3d_update(C, event->mval);
- op->customdata = SET_INT_IN_POINTER(event->type);
- WM_event_add_modal_handler(C, op);
+ ED_view3d_cursor3d_update(C, event->mval);
- return OPERATOR_RUNNING_MODAL;
-}
-
-static int view3d_cursor3d_modal(bContext *C, wmOperator *op, const wmEvent *event)
-{
- int event_type = GET_INT_FROM_POINTER(op->customdata);
-
- if (event->type == event_type) {
- return OPERATOR_FINISHED;
- }
-
- switch (event->type) {
- case MOUSEMOVE:
- view3d_cursor3d_update(C, event->mval);
- break;
- case LEFTMOUSE:
- return OPERATOR_FINISHED;
- }
-
- return OPERATOR_RUNNING_MODAL;
+ return OPERATOR_FINISHED;
}
void VIEW3D_OT_cursor3d(wmOperatorType *ot)
@@ -4487,7 +4525,6 @@ void VIEW3D_OT_cursor3d(wmOperatorType *ot)
/* api callbacks */
ot->invoke = view3d_cursor3d_invoke;
- ot->modal = view3d_cursor3d_modal;
ot->poll = ED_operator_view3d_active;
diff --git a/source/blender/editors/space_view3d/view3d_fly.c b/source/blender/editors/space_view3d/view3d_fly.c
index 6afe0ef896f..da77c4f75f7 100644
--- a/source/blender/editors/space_view3d/view3d_fly.c
+++ b/source/blender/editors/space_view3d/view3d_fly.c
@@ -385,7 +385,7 @@ static bool initFlyInfo(bContext *C, FlyInfo *fly, wmOperator *op, const wmEvent
fly->zlock = FLY_AXISLOCK_STATE_IDLE;
}
- fly->v3d_camera_control = ED_view3d_cameracontrol_aquire(
+ fly->v3d_camera_control = ED_view3d_cameracontrol_acquire(
fly->scene, fly->v3d, fly->rv3d,
(U.uiflag & USER_CAM_LOCK_NO_PARENT) == 0);
diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c
index e3d0e87066b..a88724a1cdd 100644
--- a/source/blender/editors/space_view3d/view3d_header.c
+++ b/source/blender/editors/space_view3d/view3d_header.c
@@ -32,6 +32,7 @@
#include <stdio.h>
#include <stdlib.h>
+#include "DNA_brush_types.h"
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
@@ -45,6 +46,7 @@
#include "BKE_depsgraph.h"
#include "BKE_main.h"
#include "BKE_modifier.h"
+#include "BKE_paint.h"
#include "BKE_screen.h"
#include "BKE_editmesh.h"
@@ -308,7 +310,7 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C)
/* mode */
if (ob) {
modeselect = ob->mode;
- is_paint = ELEM4(ob->mode, OB_MODE_SCULPT, OB_MODE_VERTEX_PAINT, OB_MODE_WEIGHT_PAINT, OB_MODE_TEXTURE_PAINT);
+ is_paint = ELEM(ob->mode, OB_MODE_SCULPT, OB_MODE_VERTEX_PAINT, OB_MODE_WEIGHT_PAINT, OB_MODE_TEXTURE_PAINT);
}
else {
modeselect = OB_MODE_OBJECT;
@@ -336,8 +338,7 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C)
uiItemR(layout, &v3dptr, "viewport_shade", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
if (obedit == NULL && is_paint) {
-
- if (ob->mode & OB_MODE_WEIGHT_PAINT) {
+ if (ob->mode & OB_MODE_ALL_PAINT) {
/* Only for Weight Paint. makes no sense in other paint modes. */
row = uiLayoutRow(layout, true);
uiItemR(row, &v3dptr, "pivot_point", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h
index 169bc494e1b..84ac4f7d02d 100644
--- a/source/blender/editors/space_view3d/view3d_intern.h
+++ b/source/blender/editors/space_view3d/view3d_intern.h
@@ -233,7 +233,7 @@ void VIEW3D_OT_properties(struct wmOperatorType *ot);
void view3d_buttons_register(struct ARegionType *art);
/* view3d_camera_control.c */
-struct View3DCameraControl *ED_view3d_cameracontrol_aquire(
+struct View3DCameraControl *ED_view3d_cameracontrol_acquire(
Scene *scene, View3D *v3d, RegionView3D *rv3d,
const bool use_parent_root);
void ED_view3d_cameracontrol_update(
@@ -285,7 +285,7 @@ void draw_smoke_heat(struct SmokeDomainSettings *domain, struct Object *ob);
/* workaround for trivial but noticeable camera bug caused by imprecision
* between view border calculation in 2D/3D space, workaround for bug [#28037].
- * without this deifne we get the old behavior which is to try and align them
+ * without this define we get the old behavior which is to try and align them
* both which _mostly_ works fine, but when the camera moves beyond ~1000 in
* any direction it starts to fail */
#define VIEW3D_CAMERA_BORDER_HACK
diff --git a/source/blender/editors/space_view3d/view3d_project.c b/source/blender/editors/space_view3d/view3d_project.c
index c1e42c97c4d..75c1d9dcd22 100644
--- a/source/blender/editors/space_view3d/view3d_project.c
+++ b/source/blender/editors/space_view3d/view3d_project.c
@@ -277,7 +277,7 @@ eV3DProjStatus ED_view3d_project_float_object(const ARegion *ar, const float co[
* *************************************************** */
/**
- * Caculate a depth value from \a co, use with #ED_view3d_win_to_delta
+ * Calculate a depth value from \a co, use with #ED_view3d_win_to_delta
*/
float ED_view3d_calc_zfac(const RegionView3D *rv3d, const float co[3], bool *r_flip)
{
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index 32f063d6154..46ea52054c5 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -1147,11 +1147,12 @@ static Base *object_mouse_select_menu(bContext *C, ViewContext *vc, unsigned int
}
{
+ wmOperatorType *ot = WM_operatortype_find("VIEW3D_OT_select_menu", false);
PointerRNA ptr;
- WM_operator_properties_create(&ptr, "VIEW3D_OT_select_menu");
+ WM_operator_properties_create_ptr(&ptr, ot);
RNA_boolean_set(&ptr, "toggle", toggle);
- WM_operator_name_call(C, "VIEW3D_OT_select_menu", WM_OP_INVOKE_DEFAULT, &ptr);
+ WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &ptr);
WM_operator_properties_free(&ptr);
}
@@ -1193,15 +1194,32 @@ static short selectbuffer_ret_hits_5(unsigned int *buffer, const short hits15, c
/* we want a select buffer with bones, if there are... */
/* so check three selection levels and compare */
-static short mixed_bones_object_selectbuffer(ViewContext *vc, unsigned int *buffer, const int mval[2])
+static short mixed_bones_object_selectbuffer(ViewContext *vc, unsigned int *buffer, const int mval[2], bool *p_do_nearest, bool enumerate)
{
rcti rect;
int offs;
short hits15, hits9 = 0, hits5 = 0;
bool has_bones15 = false, has_bones9 = false, has_bones5 = false;
-
+ static int last_mval[2] = {-100, -100};
+ bool do_nearest = false;
+ View3D *v3d = vc->v3d;
+
+ /* define if we use solid nearest select or not */
+ if (v3d->drawtype > OB_WIRE) {
+ do_nearest = true;
+ if (len_manhattan_v2v2_int(mval, last_mval) < 3) {
+ do_nearest = false;
+ }
+ }
+ copy_v2_v2_int(last_mval, mval);
+
+ if (p_do_nearest)
+ *p_do_nearest = do_nearest;
+
+ do_nearest = do_nearest && !enumerate;
+
BLI_rcti_init(&rect, mval[0] - 14, mval[0] + 14, mval[1] - 14, mval[1] + 14);
- hits15 = view3d_opengl_select(vc, buffer, MAXPICKBUF, &rect);
+ hits15 = view3d_opengl_select(vc, buffer, MAXPICKBUF, &rect, do_nearest);
if (hits15 == 1) {
return selectbuffer_ret_hits_15(buffer, hits15);
}
@@ -1210,7 +1228,7 @@ static short mixed_bones_object_selectbuffer(ViewContext *vc, unsigned int *buff
offs = 4 * hits15;
BLI_rcti_init(&rect, mval[0] - 9, mval[0] + 9, mval[1] - 9, mval[1] + 9);
- hits9 = view3d_opengl_select(vc, buffer + offs, MAXPICKBUF - offs, &rect);
+ hits9 = view3d_opengl_select(vc, buffer + offs, MAXPICKBUF - offs, &rect, do_nearest);
if (hits9 == 1) {
return selectbuffer_ret_hits_9(buffer, hits15, hits9);
}
@@ -1219,7 +1237,7 @@ static short mixed_bones_object_selectbuffer(ViewContext *vc, unsigned int *buff
offs += 4 * hits9;
BLI_rcti_init(&rect, mval[0] - 5, mval[0] + 5, mval[1] - 5, mval[1] + 5);
- hits5 = view3d_opengl_select(vc, buffer + offs, MAXPICKBUF - offs, &rect);
+ hits5 = view3d_opengl_select(vc, buffer + offs, MAXPICKBUF - offs, &rect, do_nearest);
if (hits5 == 1) {
return selectbuffer_ret_hits_5(buffer, hits15, hits9, hits5);
}
@@ -1241,25 +1259,13 @@ static short mixed_bones_object_selectbuffer(ViewContext *vc, unsigned int *buff
}
/* returns basact */
-static Base *mouse_select_eval_buffer(ViewContext *vc, unsigned int *buffer, int hits, const int mval[2],
- Base *startbase, bool has_bones)
+static Base *mouse_select_eval_buffer(ViewContext *vc, unsigned int *buffer, int hits,
+ Base *startbase, bool has_bones, bool do_nearest)
{
Scene *scene = vc->scene;
View3D *v3d = vc->v3d;
Base *base, *basact = NULL;
- static int lastmval[2] = {-100, -100};
int a;
- bool do_nearest = false;
-
- /* define if we use solid nearest select or not */
- if (v3d->drawtype > OB_WIRE) {
- do_nearest = true;
- if (ABS(mval[0] - lastmval[0]) < 3 && ABS(mval[1] - lastmval[1]) < 3) {
- if (!has_bones) /* hrms, if theres bones we always do nearest */
- do_nearest = false;
- }
- }
- lastmval[0] = mval[0]; lastmval[1] = mval[1];
if (do_nearest) {
unsigned int min = 0xFFFFFFFF;
@@ -1342,16 +1348,17 @@ Base *ED_view3d_give_base_under_cursor(bContext *C, const int mval[2])
Base *basact = NULL;
unsigned int buffer[4 * MAXPICKBUF];
int hits;
+ bool do_nearest;
/* setup view context for argument to callbacks */
view3d_operator_needs_opengl(C);
view3d_set_viewcontext(C, &vc);
- hits = mixed_bones_object_selectbuffer(&vc, buffer, mval);
+ hits = mixed_bones_object_selectbuffer(&vc, buffer, mval, &do_nearest, false);
if (hits > 0) {
const bool has_bones = selectbuffer_has_bones(buffer, hits);
- basact = mouse_select_eval_buffer(&vc, buffer, hits, mval, vc.scene->base.first, has_bones);
+ basact = mouse_select_eval_buffer(&vc, buffer, hits, vc.scene->base.first, has_bones, do_nearest);
}
return basact;
@@ -1438,10 +1445,11 @@ static bool mouse_select(bContext *C, const int mval[2],
}
else {
unsigned int buffer[4 * MAXPICKBUF];
+ bool do_nearest;
/* if objects have posemode set, the bones are in the same selection buffer */
- hits = mixed_bones_object_selectbuffer(&vc, buffer, mval);
+ hits = mixed_bones_object_selectbuffer(&vc, buffer, mval, &do_nearest, enumerate);
if (hits > 0) {
/* note: bundles are handling in the same way as bones */
@@ -1452,7 +1460,7 @@ static bool mouse_select(bContext *C, const int mval[2],
basact = object_mouse_select_menu(C, &vc, buffer, hits, mval, toggle);
}
else {
- basact = mouse_select_eval_buffer(&vc, buffer, hits, mval, startbase, has_bones);
+ basact = mouse_select_eval_buffer(&vc, buffer, hits, startbase, has_bones, do_nearest);
}
if (has_bones && basact) {
@@ -1510,7 +1518,7 @@ static bool mouse_select(bContext *C, const int mval[2],
if (!changed) {
/* fallback to regular object selection if no new bundles were selected,
* allows to select object parented to reconstruction object */
- basact = mouse_select_eval_buffer(&vc, buffer, hits, mval, startbase, 0);
+ basact = mouse_select_eval_buffer(&vc, buffer, hits, startbase, 0, do_nearest);
}
}
}
@@ -1872,7 +1880,7 @@ static int do_meta_box_select(ViewContext *vc, rcti *rect, bool select, bool ext
unsigned int buffer[4 * MAXPICKBUF];
short hits;
- hits = view3d_opengl_select(vc, buffer, MAXPICKBUF, rect);
+ hits = view3d_opengl_select(vc, buffer, MAXPICKBUF, rect, false);
if (extend == false && select)
BKE_mball_deselect_all(mb);
@@ -1906,7 +1914,7 @@ static int do_armature_box_select(ViewContext *vc, rcti *rect, bool select, bool
unsigned int buffer[4 * MAXPICKBUF];
short hits;
- hits = view3d_opengl_select(vc, buffer, MAXPICKBUF, rect);
+ hits = view3d_opengl_select(vc, buffer, MAXPICKBUF, rect, false);
/* clear flag we use to detect point was affected */
for (ebone = arm->edbo->first; ebone; ebone = ebone->next)
@@ -2000,7 +2008,7 @@ static int do_object_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, b
/* selection buffer now has bones potentially too, so we add MAXPICKBUF */
vbuffer = MEM_mallocN(4 * (totobj + MAXPICKBUF) * sizeof(unsigned int), "selection buffer");
- hits = view3d_opengl_select(vc, vbuffer, 4 * (totobj + MAXPICKBUF), rect);
+ hits = view3d_opengl_select(vc, vbuffer, 4 * (totobj + MAXPICKBUF), rect, false);
/*
* LOGIC NOTES (theeth):
* The buffer and ListBase have the same relative order, which makes the selection
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index 716f4b10fae..7d3f7ce282e 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -56,6 +56,7 @@
#include "BIF_glutil.h"
#include "GPU_draw.h"
+#include "GPU_select.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -273,7 +274,7 @@ void ED_view3d_smooth_view_ex(
rv3d->rflag |= RV3D_NAVIGATING;
/* not essential but in some cases the caller will tag the area for redraw,
- * and in that case we can get a ficker of the 'org' user view but we want to see 'src' */
+ * and in that case we can get a flicker of the 'org' user view but we want to see 'src' */
view3d_smooth_view_state_restore(&sms.src, v3d, rv3d);
/* keep track of running timer! */
@@ -723,6 +724,13 @@ 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])
+{
+ 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)
@@ -955,6 +963,78 @@ void view3d_viewmatrix_set(Scene *scene, View3D *v3d, RegionView3D *rv3d)
}
}
+static void view3d_select_loop(ViewContext *vc, Scene *scene, View3D *v3d, ARegion *ar, bool use_obedit_skip)
+{
+ short code = 1;
+ char dt;
+ short dtx;
+
+ if (vc->obedit && vc->obedit->type == OB_MBALL) {
+ draw_object(scene, ar, v3d, BASACT, DRAW_PICKING | DRAW_CONSTCOLOR);
+ }
+ else if ((vc->obedit && vc->obedit->type == OB_ARMATURE)) {
+ /* if not drawing sketch, draw bones */
+ if (!BDR_drawSketchNames(vc)) {
+ draw_object(scene, ar, v3d, BASACT, DRAW_PICKING | DRAW_CONSTCOLOR);
+ }
+ }
+ else {
+ Base *base;
+
+ v3d->xray = true; /* otherwise it postpones drawing */
+ for (base = scene->base.first; base; base = base->next) {
+ if (base->lay & v3d->lay) {
+
+ if ((base->object->restrictflag & OB_RESTRICT_SELECT) ||
+ (use_obedit_skip && (scene->obedit->data == base->object->data)))
+ {
+ base->selcol = 0;
+ }
+ else {
+ base->selcol = code;
+
+ if (GPU_select_load_id(code)) {
+ draw_object(scene, ar, v3d, base, DRAW_PICKING | DRAW_CONSTCOLOR);
+
+ /* we draw duplicators for selection too */
+ if ((base->object->transflag & OB_DUPLI)) {
+ ListBase *lb;
+ DupliObject *dob;
+ Base tbase;
+
+ tbase.flag = OB_FROMDUPLI;
+ lb = object_duplilist(G.main->eval_ctx, scene, base->object);
+
+ for (dob = lb->first; dob; dob = dob->next) {
+ float omat[4][4];
+
+ tbase.object = dob->ob;
+ copy_m4_m4(omat, dob->ob->obmat);
+ copy_m4_m4(dob->ob->obmat, dob->mat);
+
+ /* 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;
+
+ draw_object(scene, ar, v3d, &tbase, DRAW_PICKING | DRAW_CONSTCOLOR);
+
+ tbase.object->dt = dt;
+ tbase.object->dtx = dtx;
+
+ copy_m4_m4(dob->ob->obmat, omat);
+ }
+ free_object_duplilist(lb);
+ }
+ }
+ code++;
+ }
+ }
+ }
+ v3d->xray = false; /* restore */
+ }
+}
+
/**
* \warning be sure to account for a negative return value
* This is an error, "Too many objects in select buffer"
@@ -962,17 +1042,16 @@ void view3d_viewmatrix_set(Scene *scene, View3D *v3d, RegionView3D *rv3d)
*
* \note (vc->obedit == NULL) can be set to explicitly skip edit-object selection.
*/
-short view3d_opengl_select(ViewContext *vc, unsigned int *buffer, unsigned int bufsize, const rcti *input)
+short view3d_opengl_select(ViewContext *vc, unsigned int *buffer, unsigned int bufsize, const rcti *input, bool do_nearest)
{
Scene *scene = vc->scene;
View3D *v3d = vc->v3d;
ARegion *ar = vc->ar;
- rctf rect;
- short code, hits;
- char dt;
- short dtx;
+ rctf rect, selrect;
+ short hits;
const bool use_obedit_skip = (scene->obedit != NULL) && (vc->obedit == NULL);
-
+ const bool do_passes = do_nearest && GPU_select_query_check_active();
+
G.f |= G_PICKSEL;
/* case not a border select */
@@ -985,6 +1064,8 @@ short view3d_opengl_select(ViewContext *vc, unsigned int *buffer, unsigned int b
else {
BLI_rctf_rcti_copy(&rect, input);
}
+
+ selrect = rect;
view3d_winmatrix_set(ar, v3d, &rect);
mul_m4_m4m4(vc->rv3d->persmat, vc->rv3d->winmat, vc->rv3d->viewmat);
@@ -997,78 +1078,24 @@ short view3d_opengl_select(ViewContext *vc, unsigned int *buffer, unsigned int b
if (vc->rv3d->rflag & RV3D_CLIPPING)
ED_view3d_clipping_set(vc->rv3d);
- glSelectBuffer(bufsize, (GLuint *)buffer);
- glRenderMode(GL_SELECT);
- glInitNames(); /* these two calls whatfor? It doesnt work otherwise */
- glPushName(-1);
- code = 1;
+ if (do_passes)
+ GPU_select_begin(buffer, bufsize, &selrect, GPU_SELECT_NEAREST_FIRST_PASS, 0);
+ else
+ GPU_select_begin(buffer, bufsize, &selrect, GPU_SELECT_ALL, 0);
+
+ view3d_select_loop(vc, scene, v3d, ar, use_obedit_skip);
+
+ hits = GPU_select_end();
- if (vc->obedit && vc->obedit->type == OB_MBALL) {
- draw_object(scene, ar, v3d, BASACT, DRAW_PICKING | DRAW_CONSTCOLOR);
- }
- else if ((vc->obedit && vc->obedit->type == OB_ARMATURE)) {
- /* if not drawing sketch, draw bones */
- if (!BDR_drawSketchNames(vc)) {
- draw_object(scene, ar, v3d, BASACT, DRAW_PICKING | DRAW_CONSTCOLOR);
- }
- }
- else {
- Base *base;
-
- v3d->xray = true; /* otherwise it postpones drawing */
- for (base = scene->base.first; base; base = base->next) {
- if (base->lay & v3d->lay) {
-
- if ((base->object->restrictflag & OB_RESTRICT_SELECT) ||
- (use_obedit_skip && (scene->obedit->data == base->object->data)))
- {
- base->selcol = 0;
- }
- else {
- base->selcol = code;
- glLoadName(code);
- draw_object(scene, ar, v3d, base, DRAW_PICKING | DRAW_CONSTCOLOR);
-
- /* we draw duplicators for selection too */
- if ((base->object->transflag & OB_DUPLI)) {
- ListBase *lb;
- DupliObject *dob;
- Base tbase;
-
- tbase.flag = OB_FROMDUPLI;
- lb = object_duplilist(G.main->eval_ctx, scene, base->object);
-
- for (dob = lb->first; dob; dob = dob->next) {
- float omat[4][4];
-
- tbase.object = dob->ob;
- copy_m4_m4(omat, dob->ob->obmat);
- copy_m4_m4(dob->ob->obmat, dob->mat);
-
- /* 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;
-
- draw_object(scene, ar, v3d, &tbase, DRAW_PICKING | DRAW_CONSTCOLOR);
-
- tbase.object->dt = dt;
- tbase.object->dtx = dtx;
-
- copy_m4_m4(dob->ob->obmat, omat);
- }
- free_object_duplilist(lb);
- }
- code++;
- }
- }
- }
- v3d->xray = false; /* restore */
+ /* second pass, to get the closest object to camera */
+ if (do_passes) {
+ GPU_select_begin(buffer, bufsize, &selrect, GPU_SELECT_NEAREST_SECOND_PASS, hits);
+
+ view3d_select_loop(vc, scene, v3d, ar, use_obedit_skip);
+
+ GPU_select_end();
}
-
- glPopName(); /* see above (pushname) */
- hits = glRenderMode(GL_RENDER);
-
+
G.f &= ~G_PICKSEL;
view3d_winmatrix_set(ar, v3d, NULL);
mul_m4_m4m4(vc->rv3d->persmat, vc->rv3d->winmat, vc->rv3d->viewmat);
@@ -1285,7 +1312,7 @@ static bool view3d_localview_init(
return ok;
}
-static void restore_localviewdata(wmWindowManager *wm, wmWindow *win, Main *bmain, ScrArea *sa, const int smooth_viewtx)
+static void restore_localviewdata(wmWindowManager *wm, wmWindow *win, Main *bmain, Scene *scene, ScrArea *sa, const int smooth_viewtx)
{
const bool free = true;
ARegion *ar;
@@ -1335,7 +1362,7 @@ static void restore_localviewdata(wmWindowManager *wm, wmWindow *win, Main *bmai
}
}
- ED_view3d_shade_update(bmain, v3d, sa);
+ ED_view3d_shade_update(bmain, scene, v3d, sa);
}
}
}
@@ -1352,7 +1379,7 @@ static bool view3d_localview_exit(
locallay = v3d->lay & 0xFF000000;
- restore_localviewdata(wm, win, bmain, sa, smooth_viewtx);
+ restore_localviewdata(wm, win, bmain, scene, sa, smooth_viewtx);
/* for when in other window the layers have changed */
if (v3d->scenelock) v3d->lay = scene->lay;
diff --git a/source/blender/editors/space_view3d/view3d_walk.c b/source/blender/editors/space_view3d/view3d_walk.c
index 1c3e223f3ed..7bdf39d6768 100644
--- a/source/blender/editors/space_view3d/view3d_walk.c
+++ b/source/blender/editors/space_view3d/view3d_walk.c
@@ -60,10 +60,8 @@
#include "view3d_intern.h" /* own include */
-#define EARTH_GRAVITY 9.80668f /* m/s2 */
-
/* prototypes */
-static float getVelocityZeroTime(float velocity);
+static float getVelocityZeroTime(const float gravity, const float velocity);
/* NOTE: these defines are saved in keymap files, do not change values but just add new ones */
enum {
@@ -280,7 +278,8 @@ typedef struct WalkInfo {
bool is_reversed;
/* gravity system */
- eWalkGravityState gravity;
+ eWalkGravityState gravity_state;
+ float gravity;
/* height to use in walk mode */
float view_height;
@@ -360,11 +359,11 @@ static void walk_navigation_mode_set(bContext *C, WalkInfo *walk, eWalkMethod mo
{
if (mode == WALK_MODE_FREE) {
walk->navigation_mode = WALK_MODE_FREE;
- walk->gravity = WALK_GRAVITY_STATE_OFF;
+ walk->gravity_state = WALK_GRAVITY_STATE_OFF;
}
else { /* WALK_MODE_GRAVITY */
walk->navigation_mode = WALK_MODE_GRAVITY;
- walk->gravity = WALK_GRAVITY_STATE_START;
+ walk->gravity_state = WALK_GRAVITY_STATE_START;
}
walk_update_header(C, walk);
@@ -510,7 +509,14 @@ static bool initWalkInfo(bContext *C, WalkInfo *walk, wmOperator *op)
walk->speed = U.walk_navigation.walk_speed;
walk->speed_factor = U.walk_navigation.walk_speed_factor;
- walk->gravity = WALK_GRAVITY_STATE_OFF;
+ walk->gravity_state = WALK_GRAVITY_STATE_OFF;
+
+ if ((walk->scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY)) {
+ walk->gravity = fabsf(walk->scene->physics_settings.gravity[2]);
+ }
+ else {
+ walk->gravity = 9.80668f; /* m/s2 */
+ }
walk->is_reversed = ((U.walk_navigation.flag & USER_WALK_MOUSE_REVERSE) != 0);
@@ -532,7 +538,7 @@ static bool initWalkInfo(bContext *C, WalkInfo *walk, wmOperator *op)
walk->rv3d->rflag |= RV3D_NAVIGATING;
- walk->v3d_camera_control = ED_view3d_cameracontrol_aquire(
+ walk->v3d_camera_control = ED_view3d_cameracontrol_acquire(
walk->scene, walk->v3d, walk->rv3d,
(U.uiflag & USER_CAM_LOCK_NO_PARENT) == 0);
@@ -755,10 +761,10 @@ static void walkEvent(bContext *C, wmOperator *UNUSED(op), WalkInfo *walk, const
#define JUMP_SPEED_MIN 1.0f
#define JUMP_TIME_MAX 0.2f /* s */
-#define JUMP_SPEED_MAX sqrtf(2.0f * EARTH_GRAVITY * walk->jump_height)
+#define JUMP_SPEED_MAX sqrtf(2.0f * walk->gravity * walk->jump_height)
case WALK_MODAL_JUMP_STOP:
- if (walk->gravity == WALK_GRAVITY_STATE_JUMP) {
+ if (walk->gravity_state == WALK_GRAVITY_STATE_JUMP) {
float t;
/* delta time */
@@ -769,21 +775,21 @@ static void walkEvent(bContext *C, wmOperator *UNUSED(op), WalkInfo *walk, const
walk->speed_jump = JUMP_SPEED_MIN + t * (JUMP_SPEED_MAX - JUMP_SPEED_MIN) / JUMP_TIME_MAX;
/* when jumping, duration is how long it takes before we start going down */
- walk->teleport.duration = getVelocityZeroTime(walk->speed_jump);
+ walk->teleport.duration = getVelocityZeroTime(walk->gravity, walk->speed_jump);
/* no more increase of jump speed */
- walk->gravity = WALK_GRAVITY_STATE_ON;
+ walk->gravity_state = WALK_GRAVITY_STATE_ON;
}
break;
case WALK_MODAL_JUMP:
if ((walk->navigation_mode == WALK_MODE_GRAVITY) &&
- (walk->gravity == WALK_GRAVITY_STATE_OFF) &&
+ (walk->gravity_state == WALK_GRAVITY_STATE_OFF) &&
(walk->teleport.state == WALK_TELEPORT_STATE_OFF))
{
/* no need to check for ground,
* walk->gravity wouldn't be off
* if we were over a hole */
- walk->gravity = WALK_GRAVITY_STATE_JUMP;
+ walk->gravity_state = WALK_GRAVITY_STATE_JUMP;
walk->speed_jump = JUMP_SPEED_MAX;
walk->teleport.initial_time = PIL_check_seconds_timer();
@@ -793,7 +799,7 @@ static void walkEvent(bContext *C, wmOperator *UNUSED(op), WalkInfo *walk, const
copy_v2_v2(walk->teleport.direction, walk->dvec_prev);
/* when jumping, duration is how long it takes before we start going down */
- walk->teleport.duration = getVelocityZeroTime(walk->speed_jump);
+ walk->teleport.duration = getVelocityZeroTime(walk->gravity, walk->speed_jump);
}
break;
@@ -853,14 +859,14 @@ static void walkMoveCamera(bContext *C, WalkInfo *walk,
ED_view3d_cameracontrol_update(walk->v3d_camera_control, true, C, do_rotate, do_translate);
}
-static float getFreeFallDistance(const float time)
+static float getFreeFallDistance(const float gravity, const float time)
{
- return EARTH_GRAVITY * (time * time) * 0.5f;
+ return gravity * (time * time) * 0.5f;
}
-static float getVelocityZeroTime(float velocity)
+static float getVelocityZeroTime(const float gravity, const float velocity)
{
- return velocity / EARTH_GRAVITY;
+ return velocity / gravity;
}
static int walkApply(bContext *C, WalkInfo *walk)
@@ -910,7 +916,7 @@ static int walkApply(bContext *C, WalkInfo *walk)
if ((walk->active_directions) ||
moffset[0] || moffset[1] ||
walk->teleport.state == WALK_TELEPORT_STATE_ON ||
- walk->gravity != WALK_GRAVITY_STATE_OFF)
+ walk->gravity_state != WALK_GRAVITY_STATE_OFF)
{
float dvec_tmp[3];
@@ -1000,7 +1006,7 @@ static int walkApply(bContext *C, WalkInfo *walk)
/* WASD - 'move' translation code */
if ((walk->active_directions) &&
- (walk->gravity == WALK_GRAVITY_STATE_OFF))
+ (walk->gravity_state == WALK_GRAVITY_STATE_OFF))
{
short direction;
@@ -1076,7 +1082,7 @@ static int walkApply(bContext *C, WalkInfo *walk)
/* stick to the floor */
if (walk->navigation_mode == WALK_MODE_GRAVITY &&
- ELEM(walk->gravity,
+ ELEM(walk->gravity_state,
WALK_GRAVITY_STATE_OFF,
WALK_GRAVITY_STATE_START))
{
@@ -1101,13 +1107,13 @@ static int walkApply(bContext *C, WalkInfo *walk)
dvec[2] -= difference;
/* in case we switched from FREE to GRAVITY too close to the ground */
- if (walk->gravity == WALK_GRAVITY_STATE_START)
- walk->gravity = WALK_GRAVITY_STATE_OFF;
+ if (walk->gravity_state == WALK_GRAVITY_STATE_START)
+ walk->gravity_state = WALK_GRAVITY_STATE_OFF;
}
else {
/* hijack the teleport variables */
walk->teleport.initial_time = PIL_check_seconds_timer();
- walk->gravity = WALK_GRAVITY_STATE_ON;
+ walk->gravity_state = WALK_GRAVITY_STATE_ON;
walk->teleport.duration = 0.0f;
copy_v3_v3(walk->teleport.origin, walk->rv3d->viewinv[3]);
@@ -1117,7 +1123,7 @@ static int walkApply(bContext *C, WalkInfo *walk)
}
/* Falling or jumping) */
- if (ELEM(walk->gravity, WALK_GRAVITY_STATE_ON, WALK_GRAVITY_STATE_JUMP)) {
+ if (ELEM(walk->gravity_state, WALK_GRAVITY_STATE_ON, WALK_GRAVITY_STATE_JUMP)) {
float t;
float z_cur, z_new;
bool ret;
@@ -1130,7 +1136,7 @@ static int walkApply(bContext *C, WalkInfo *walk)
copy_v2_v2(dvec, walk->teleport.direction);
z_cur = walk->rv3d->viewinv[3][2];
- z_new = walk->teleport.origin[2] - getFreeFallDistance(t) * walk->grid;
+ z_new = walk->teleport.origin[2] - getFreeFallDistance(walk->gravity, t) * walk->grid;
/* jump */
z_new += t * walk->speed_jump * walk->grid;
@@ -1148,7 +1154,7 @@ static int walkApply(bContext *C, WalkInfo *walk)
if (difference > 0.0f) {
/* quit falling, lands at "view_height" from the floor */
dvec[2] -= difference;
- walk->gravity = WALK_GRAVITY_STATE_OFF;
+ walk->gravity_state = WALK_GRAVITY_STATE_OFF;
walk->speed_jump = 0.0f;
}
else {
@@ -1334,5 +1340,3 @@ void VIEW3D_OT_walk(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_BLOCKING;
}
-
-#undef EARTH_GRAVITY