diff options
Diffstat (limited to 'source/blender')
41 files changed, 309 insertions, 132 deletions
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 672b61fa122..a84124f353d 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -7355,7 +7355,8 @@ void blo_lib_link_restore(Main *newmain, wmWindowManager *curwm, Scene *curscene BKE_workspace_active_set(win->workspace_hook, workspace); /* keep cursor location through undo */ - copy_v3_v3(win->scene->cursor, oldscene->cursor); + copy_v3_v3(win->scene->cursor.location, oldscene->cursor.location); + copy_qt_qt(win->scene->cursor.rotation, oldscene->cursor.rotation); lib_link_workspace_scene_data_restore(win, win->scene); BLI_assert(win->screen == NULL); @@ -10039,7 +10040,7 @@ static void give_base_to_groups( /* Assign the group. */ ob->dup_group = group; ob->transflag |= OB_DUPLIGROUP; - copy_v3_v3(ob->loc, scene->cursor); + copy_v3_v3(ob->loc, scene->cursor.location); } } } diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index 55bc314d6b4..1ce721232f0 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -1099,5 +1099,21 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main) } } } + + if (!DNA_struct_find(fd->filesdna, "View3DCursor")) { + for (Scene *scene = main->scene.first; scene; scene = scene->id.next) { + unit_qt(scene->cursor.rotation); + } + for (bScreen *screen = main->screen.first; screen; screen = screen->id.next) { + for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { + for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + if (sl->spacetype == SPACE_VIEW3D) { + View3D *v3d = (View3D *)sl; + unit_qt(v3d->cursor.rotation); + } + } + } + } + } } } diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c index 2366fa556b9..aec1750edc5 100644 --- a/source/blender/draw/intern/draw_cache.c +++ b/source/blender/draw/intern/draw_cache.c @@ -46,6 +46,7 @@ static struct DRWShapeCache { Gwn_Batch *drw_single_vertice; Gwn_Batch *drw_cursor; + Gwn_Batch *drw_cursor_only_circle; Gwn_Batch *drw_fullscreen_quad; Gwn_Batch *drw_quad; Gwn_Batch *drw_sphere; @@ -3021,9 +3022,11 @@ Gwn_Batch *DRW_cache_particles_get_prim(int type) } /* 3D cursor */ -Gwn_Batch *DRW_cache_cursor_get(void) +Gwn_Batch *DRW_cache_cursor_get(bool crosshair_lines) { - if (!SHC.drw_cursor) { + Gwn_Batch **drw_cursor = crosshair_lines ? &SHC.drw_cursor : &SHC.drw_cursor_only_circle; + + if (*drw_cursor == NULL) { const float f5 = 0.25f; const float f10 = 0.5f; const float f20 = 1.0f; @@ -3034,8 +3037,6 @@ Gwn_Batch *DRW_cache_cursor_get(void) unsigned char red[3] = {255, 0, 0}; unsigned char white[3] = {255, 255, 255}; - unsigned char crosshair_color[3]; - UI_GetThemeColor3ubv(TH_VIEW_OVERLAY, crosshair_color); static Gwn_VertFormat format = { 0 }; static struct { uint pos, color; } attr_id; @@ -3065,45 +3066,51 @@ Gwn_Batch *DRW_cache_cursor_get(void) GWN_indexbuf_add_generic_vert(&elb, v++); } GWN_indexbuf_add_generic_vert(&elb, 0); - GWN_indexbuf_add_primitive_restart(&elb); - - GWN_vertbuf_attr_set(vbo, attr_id.pos, v, (const float[2]){-f20, 0}); - GWN_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color); - GWN_indexbuf_add_generic_vert(&elb, v++); - GWN_vertbuf_attr_set(vbo, attr_id.pos, v, (const float[2]){-f5, 0}); - GWN_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color); - GWN_indexbuf_add_generic_vert(&elb, v++); - - GWN_indexbuf_add_primitive_restart(&elb); - - GWN_vertbuf_attr_set(vbo, attr_id.pos, v, (const float[2]){+f5, 0}); - GWN_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color); - GWN_indexbuf_add_generic_vert(&elb, v++); - GWN_vertbuf_attr_set(vbo, attr_id.pos, v, (const float[2]){+f20, 0}); - GWN_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color); - GWN_indexbuf_add_generic_vert(&elb, v++); - - GWN_indexbuf_add_primitive_restart(&elb); - - GWN_vertbuf_attr_set(vbo, attr_id.pos, v, (const float[2]){0, -f20}); - GWN_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color); - GWN_indexbuf_add_generic_vert(&elb, v++); - GWN_vertbuf_attr_set(vbo, attr_id.pos, v, (const float[2]){0, -f5}); - GWN_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color); - GWN_indexbuf_add_generic_vert(&elb, v++); - - GWN_indexbuf_add_primitive_restart(&elb); - - GWN_vertbuf_attr_set(vbo, attr_id.pos, v, (const float[2]){0, +f5}); - GWN_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color); - GWN_indexbuf_add_generic_vert(&elb, v++); - GWN_vertbuf_attr_set(vbo, attr_id.pos, v, (const float[2]){0, +f20}); - GWN_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color); - GWN_indexbuf_add_generic_vert(&elb, v++); + + if (crosshair_lines) { + unsigned char crosshair_color[3]; + UI_GetThemeColor3ubv(TH_VIEW_OVERLAY, crosshair_color); + + GWN_indexbuf_add_primitive_restart(&elb); + + GWN_vertbuf_attr_set(vbo, attr_id.pos, v, (const float[2]){-f20, 0}); + GWN_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color); + GWN_indexbuf_add_generic_vert(&elb, v++); + GWN_vertbuf_attr_set(vbo, attr_id.pos, v, (const float[2]){-f5, 0}); + GWN_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color); + GWN_indexbuf_add_generic_vert(&elb, v++); + + GWN_indexbuf_add_primitive_restart(&elb); + + GWN_vertbuf_attr_set(vbo, attr_id.pos, v, (const float[2]){+f5, 0}); + GWN_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color); + GWN_indexbuf_add_generic_vert(&elb, v++); + GWN_vertbuf_attr_set(vbo, attr_id.pos, v, (const float[2]){+f20, 0}); + GWN_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color); + GWN_indexbuf_add_generic_vert(&elb, v++); + + GWN_indexbuf_add_primitive_restart(&elb); + + GWN_vertbuf_attr_set(vbo, attr_id.pos, v, (const float[2]){0, -f20}); + GWN_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color); + GWN_indexbuf_add_generic_vert(&elb, v++); + GWN_vertbuf_attr_set(vbo, attr_id.pos, v, (const float[2]){0, -f5}); + GWN_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color); + GWN_indexbuf_add_generic_vert(&elb, v++); + + GWN_indexbuf_add_primitive_restart(&elb); + + GWN_vertbuf_attr_set(vbo, attr_id.pos, v, (const float[2]){0, +f5}); + GWN_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color); + GWN_indexbuf_add_generic_vert(&elb, v++); + GWN_vertbuf_attr_set(vbo, attr_id.pos, v, (const float[2]){0, +f20}); + GWN_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color); + GWN_indexbuf_add_generic_vert(&elb, v++); + } Gwn_IndexBuf *ibo = GWN_indexbuf_build(&elb); - SHC.drw_cursor = GWN_batch_create_ex(GWN_PRIM_LINE_STRIP, vbo, ibo, GWN_BATCH_OWNS_VBO | GWN_BATCH_OWNS_INDEX); + *drw_cursor = GWN_batch_create_ex(GWN_PRIM_LINE_STRIP, vbo, ibo, GWN_BATCH_OWNS_VBO | GWN_BATCH_OWNS_INDEX); } - return SHC.drw_cursor; + return *drw_cursor; } diff --git a/source/blender/draw/intern/draw_cache.h b/source/blender/draw/intern/draw_cache.h index 18bff56920e..dfaf126e425 100644 --- a/source/blender/draw/intern/draw_cache.h +++ b/source/blender/draw/intern/draw_cache.h @@ -34,7 +34,7 @@ struct ModifierData; void DRW_shape_cache_free(void); /* 3D cursor */ -struct Gwn_Batch *DRW_cache_cursor_get(void); +struct Gwn_Batch *DRW_cache_cursor_get(bool crosshair_lines); /* Common Shapes */ struct Gwn_Batch *DRW_cache_fullscreen_quad_get(void); diff --git a/source/blender/draw/intern/draw_view.c b/source/blender/draw/intern/draw_view.c index be43f0d8c0c..be0556c8077 100644 --- a/source/blender/draw/intern/draw_view.c +++ b/source/blender/draw/intern/draw_view.c @@ -659,21 +659,66 @@ void DRW_draw_cursor(void) if (is_cursor_visible(draw_ctx, scene, view_layer)) { int co[2]; - if (ED_view3d_project_int_global(ar, ED_view3d_cursor3d_get(scene, v3d), co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { + const View3DCursor *cursor = ED_view3d_cursor3d_get(scene, v3d); + if (ED_view3d_project_int_global( + ar, cursor->location, co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) + { + RegionView3D *rv3d = ar->regiondata; + + /* Draw nice Anti Aliased cursor. */ + glLineWidth(1.0f); + glEnable(GL_BLEND); + glEnable(GL_LINE_SMOOTH); + + float eps = 1e-5f; + rv3d->viewquat[0] = -rv3d->viewquat[0]; + const bool is_aligned = compare_v4v4(cursor->rotation, rv3d->viewquat, eps); + rv3d->viewquat[0] = -rv3d->viewquat[0]; + + /* Draw lines */ + if (is_aligned == false) { + uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); + immUniformThemeColor3(TH_VIEW_OVERLAY); + immBegin(GWN_PRIM_LINES, 12); + + const float scale = ED_view3d_pixel_size(rv3d, cursor->location) * U.dpi_fac * 20; + +#define CURSOR_VERT(axis_vec, axis, fac) \ + immVertex3f( \ + pos, \ + cursor->location[0] + axis_vec[0] * (fac), \ + cursor->location[1] + axis_vec[1] * (fac), \ + cursor->location[2] + axis_vec[2] * (fac)) + +#define CURSOR_EDGE(axis_vec, axis, sign) { \ + CURSOR_VERT(axis_vec, axis, sign 1.0f); \ + CURSOR_VERT(axis_vec, axis, sign 0.3f); \ + } + + for (int axis = 0; axis < 3; axis++) { + float axis_vec[3] = {0}; + axis_vec[axis] = scale; + mul_qt_v3(cursor->rotation, axis_vec); + CURSOR_EDGE(axis_vec, axis, +); + CURSOR_EDGE(axis_vec, axis, -); + } + +#undef CURSOR_VERT +#undef CURSOR_EDGE + + immEnd(); + immUnbindProgram(); + } ED_region_pixelspace(ar); gpuTranslate2f(co[0] + 0.5f, co[1] + 0.5f); gpuScale2f(U.widget_unit, U.widget_unit); - Gwn_Batch *cursor_batch = DRW_cache_cursor_get(); + Gwn_Batch *cursor_batch = DRW_cache_cursor_get(is_aligned); GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_2D_FLAT_COLOR); GWN_batch_program_set(cursor_batch, GPU_shader_get_program(shader), GPU_shader_get_interface(shader)); - /* Draw nice Anti Aliased cursor. */ - glLineWidth(1.0f); - glEnable(GL_BLEND); - glEnable(GL_LINE_SMOOTH); - GWN_batch_draw(cursor_batch); } } diff --git a/source/blender/editors/armature/armature_add.c b/source/blender/editors/armature/armature_add.c index 8109fc27cea..07c9225c443 100644 --- a/source/blender/editors/armature/armature_add.c +++ b/source/blender/editors/armature/armature_add.c @@ -126,7 +126,6 @@ static int armature_click_extrude_exec(bContext *C, wmOperator *UNUSED(op)) bArmature *arm; EditBone *ebone, *newbone, *flipbone; float mat[3][3], imat[3][3]; - const float *curs; int a, to_root = 0; Object *obedit; Scene *scene; @@ -188,8 +187,8 @@ static int armature_click_extrude_exec(bContext *C, wmOperator *UNUSED(op)) newbone->flag |= BONE_CONNECTED; } - curs = ED_view3d_cursor3d_get(scene, v3d); - copy_v3_v3(newbone->tail, curs); + const View3DCursor *curs = ED_view3d_cursor3d_get(scene, v3d); + copy_v3_v3(newbone->tail, curs->location); sub_v3_v3v3(newbone->tail, newbone->tail, obedit->obmat[3]); if (a == 1) @@ -221,26 +220,26 @@ static int armature_click_extrude_invoke(bContext *C, wmOperator *op, const wmEv Scene *scene; ARegion *ar; View3D *v3d; - float *fp, tvec[3], oldcurs[3], mval_f[2]; + float tvec[3], oldcurs[3], mval_f[2]; int retv; scene = CTX_data_scene(C); ar = CTX_wm_region(C); v3d = CTX_wm_view3d(C); - fp = ED_view3d_cursor3d_get(scene, v3d); + View3DCursor *cursor = ED_view3d_cursor3d_get(scene, v3d); - copy_v3_v3(oldcurs, fp); + copy_v3_v3(oldcurs, cursor->location); VECCOPY2D(mval_f, event->mval); - ED_view3d_win_to_3d(v3d, ar, fp, mval_f, tvec); - copy_v3_v3(fp, tvec); + ED_view3d_win_to_3d(v3d, ar, cursor->location, mval_f, tvec); + copy_v3_v3(cursor->location, tvec); /* extrude to the where new cursor is and store the operation result */ retv = armature_click_extrude_exec(C, op); /* restore previous 3d cursor position */ - copy_v3_v3(fp, oldcurs); + copy_v3_v3(cursor->location, oldcurs); return retv; } @@ -1013,7 +1012,7 @@ static int armature_bone_primitive_add_exec(bContext *C, wmOperator *op) RNA_string_get(op->ptr, "name", name); - copy_v3_v3(curs, ED_view3d_cursor3d_get(CTX_data_scene(C), CTX_wm_view3d(C))); + copy_v3_v3(curs, ED_view3d_cursor3d_get(CTX_data_scene(C), CTX_wm_view3d(C))->location); /* Get inverse point for head and orientation for tail */ invert_m4_m4(obedit->imat, obedit->obmat); diff --git a/source/blender/editors/armature/armature_edit.c b/source/blender/editors/armature/armature_edit.c index 6a94443660b..7372be8896f 100644 --- a/source/blender/editors/armature/armature_edit.c +++ b/source/blender/editors/armature/armature_edit.c @@ -318,10 +318,10 @@ static int armature_calc_roll_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); /* can be NULL */ float cursor_local[3]; - const float *cursor = ED_view3d_cursor3d_get(scene, v3d); + const View3DCursor *cursor = ED_view3d_cursor3d_get(scene, v3d); invert_m4_m4(ob->imat, ob->obmat); - copy_v3_v3(cursor_local, cursor); + copy_v3_v3(cursor_local, cursor->location); mul_m4_v3(ob->imat, cursor_local); @@ -705,7 +705,7 @@ static int armature_fill_bones_exec(bContext *C, wmOperator *op) /* Get points - cursor (tail) */ invert_m4_m4(obedit->imat, obedit->obmat); - mul_v3_m4v3(curs, obedit->imat, ED_view3d_cursor3d_get(scene, v3d)); + mul_v3_m4v3(curs, obedit->imat, ED_view3d_cursor3d_get(scene, v3d)->location); /* Create a bone */ newbone = add_points_bone(obedit, ebp->vec, curs); @@ -743,7 +743,7 @@ static int armature_fill_bones_exec(bContext *C, wmOperator *op) /* get cursor location */ invert_m4_m4(obedit->imat, obedit->obmat); - mul_v3_m4v3(curs, obedit->imat, ED_view3d_cursor3d_get(scene, v3d)); + mul_v3_m4v3(curs, obedit->imat, ED_view3d_cursor3d_get(scene, v3d)->location); /* get distances */ dist_sq_a = len_squared_v3v3(ebp_a->vec, curs); diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index 5cfdec4d5ad..f97ac98107c 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -4528,7 +4528,7 @@ static int spin_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event) if (rv3d) copy_v3_v3(axis, rv3d->viewinv[2]); - RNA_float_set_array(op->ptr, "center", ED_view3d_cursor3d_get(scene, v3d)); + RNA_float_set_array(op->ptr, "center", ED_view3d_cursor3d_get(scene, v3d)->location); RNA_float_set_array(op->ptr, "axis", axis); return spin_exec(C, op); @@ -5004,7 +5004,7 @@ static int add_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event) mul_v3_m4v3(location, vc.obedit->obmat, bp->vec); } else { - copy_v3_v3(location, ED_view3d_cursor3d_get(vc.scene, vc.v3d)); + copy_v3_v3(location, ED_view3d_cursor3d_get(vc.scene, vc.v3d)->location); } ED_view3d_win_to_3d_int(vc.v3d, vc.ar, location, event->mval, location); diff --git a/source/blender/editors/curve/editcurve_paint.c b/source/blender/editors/curve/editcurve_paint.c index 669c6283856..05425fbcd6a 100644 --- a/source/blender/editors/curve/editcurve_paint.c +++ b/source/blender/editors/curve/editcurve_paint.c @@ -1117,7 +1117,7 @@ static int curve_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event) /* use view plane (when set or as fallback when surface can't be found) */ if (cdd->project.use_depth == false) { - plane_co = ED_view3d_cursor3d_get(cdd->vc.scene, v3d); + plane_co = ED_view3d_cursor3d_get(cdd->vc.scene, v3d)->location; plane_no = rv3d->viewinv[2]; cdd->project.use_plane = true; } diff --git a/source/blender/editors/gpencil/gpencil_brush.c b/source/blender/editors/gpencil/gpencil_brush.c index 533ab21dbb6..1cb882e9a43 100644 --- a/source/blender/editors/gpencil/gpencil_brush.c +++ b/source/blender/editors/gpencil/gpencil_brush.c @@ -404,7 +404,7 @@ static void gp_brush_grab_calc_dvec(tGP_BrushEditData *gso) if (gso->sa->spacetype == SPACE_VIEW3D) { View3D *v3d = gso->sa->spacedata.first; RegionView3D *rv3d = gso->ar->regiondata; - float *rvec = ED_view3d_cursor3d_get(gso->scene, v3d); + float *rvec = ED_view3d_cursor3d_get(gso->scene, v3d)->location; float zfac = ED_view3d_calc_zfac(rv3d, rvec, NULL); float mval_f[2]; @@ -504,7 +504,7 @@ static void gp_brush_calc_midpoint(tGP_BrushEditData *gso) */ View3D *v3d = gso->sa->spacedata.first; RegionView3D *rv3d = gso->ar->regiondata; - float *rvec = ED_view3d_cursor3d_get(gso->scene, v3d); + float *rvec = ED_view3d_cursor3d_get(gso->scene, v3d)->location; float zfac = ED_view3d_calc_zfac(rv3d, rvec, NULL); float mval_f[2] = {UNPACK2(gso->mval)}; diff --git a/source/blender/editors/gpencil/gpencil_convert.c b/source/blender/editors/gpencil/gpencil_convert.c index 19663b66f92..6dfe17f227a 100644 --- a/source/blender/editors/gpencil/gpencil_convert.c +++ b/source/blender/editors/gpencil/gpencil_convert.c @@ -176,7 +176,7 @@ static void gp_strokepoint_convertcoords( copy_v3_v3(p3d, &pt->x); } else { - const float *fp = ED_view3d_cursor3d_get(scene, v3d); + const float *fp = ED_view3d_cursor3d_get(scene, v3d)->location; float mvalf[2]; /* get screen coordinate */ diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index 4f9abff292a..d8cbbb16542 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -1464,7 +1464,7 @@ static int gp_snap_to_cursor(bContext *C, wmOperator *op) View3D *v3d = CTX_wm_view3d(C); const bool use_offset = RNA_boolean_get(op->ptr, "use_offset"); - const float *cursor_global = ED_view3d_cursor3d_get(scene, v3d); + const float *cursor_global = ED_view3d_cursor3d_get(scene, v3d)->location; for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { /* only editable and visible layers are considered */ @@ -1551,7 +1551,7 @@ static int gp_snap_cursor_to_sel(bContext *C, wmOperator *UNUSED(op)) Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); - float *cursor = ED_view3d_cursor3d_get(scene, v3d); + float *cursor = ED_view3d_cursor3d_get(scene, v3d)->location; float centroid[3] = {0.0f}; float min[3], max[3]; size_t count = 0; diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index ccd47463a9c..3f3349a752c 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -236,7 +236,7 @@ static bool gpencil_project_check(tGPsdata *p) static void gp_get_3d_reference(tGPsdata *p, float vec[3]) { View3D *v3d = p->sa->spacedata.first; - const float *fp = ED_view3d_cursor3d_get(p->scene, v3d); + const float *fp = ED_view3d_cursor3d_get(p->scene, v3d)->location; /* the reference point used depends on the owner... */ #if 0 /* XXX: disabled for now, since we can't draw relative to the owner yet */ diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c index d7e5b5a92aa..babe68ba439 100644 --- a/source/blender/editors/gpencil/gpencil_utils.c +++ b/source/blender/editors/gpencil/gpencil_utils.c @@ -745,7 +745,7 @@ bool gp_point_xy_to_3d(GP_SpaceConversion *gsc, Scene *scene, const float screen { View3D *v3d = gsc->sa->spacedata.first; RegionView3D *rv3d = gsc->ar->regiondata; - float *rvec = ED_view3d_cursor3d_get(scene, v3d); + float *rvec = ED_view3d_cursor3d_get(scene, v3d)->location; float ref[3] = {rvec[0], rvec[1], rvec[2]}; float zfac = ED_view3d_calc_zfac(rv3d, rvec, NULL); diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index 3ab08967a0d..a34571fef44 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -97,7 +97,7 @@ typedef struct ViewDepths { bool damaged; } ViewDepths; -float *ED_view3d_cursor3d_get(struct Scene *scene, struct View3D *v3d); +struct View3DCursor *ED_view3d_cursor3d_get(struct Scene *scene, struct View3D *v3d); void ED_view3d_cursor3d_position(struct bContext *C, float fp[3], const int mval[2]); void ED_view3d_cursor3d_update(struct bContext *C, const int mval[2]); diff --git a/source/blender/editors/mesh/editmesh_bisect.c b/source/blender/editors/mesh/editmesh_bisect.c index ac8c1f16477..ee06f7abd2b 100644 --- a/source/blender/editors/mesh/editmesh_bisect.c +++ b/source/blender/editors/mesh/editmesh_bisect.c @@ -243,7 +243,7 @@ static int mesh_bisect_exec(bContext *C, wmOperator *op) RNA_property_float_get_array(op->ptr, prop_plane_co, plane_co); } else { - copy_v3_v3(plane_co, ED_view3d_cursor3d_get(scene, v3d)); + copy_v3_v3(plane_co, ED_view3d_cursor3d_get(scene, v3d)->location); RNA_property_float_set_array(op->ptr, prop_plane_co, plane_co); } diff --git a/source/blender/editors/mesh/editmesh_extrude.c b/source/blender/editors/mesh/editmesh_extrude.c index ca49d4e5448..41053d423de 100644 --- a/source/blender/editors/mesh/editmesh_extrude.c +++ b/source/blender/editors/mesh/editmesh_extrude.c @@ -973,7 +973,7 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, const w BM_ELEM_SELECT, ofs); } else { - const float *cursor = ED_view3d_cursor3d_get(vc.scene, vc.v3d); + const float *cursor = ED_view3d_cursor3d_get(vc.scene, vc.v3d)->location; BMOperator bmop; BMOIter oiter; diff --git a/source/blender/editors/mesh/editmesh_extrude_screw.c b/source/blender/editors/mesh/editmesh_extrude_screw.c index debab7edf21..3be8ab9c2e4 100644 --- a/source/blender/editors/mesh/editmesh_extrude_screw.c +++ b/source/blender/editors/mesh/editmesh_extrude_screw.c @@ -148,7 +148,7 @@ static int edbm_screw_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED( PropertyRNA *prop; prop = RNA_struct_find_property(op->ptr, "center"); if (!RNA_property_is_set(op->ptr, prop)) { - RNA_property_float_set_array(op->ptr, prop, ED_view3d_cursor3d_get(scene, v3d)); + RNA_property_float_set_array(op->ptr, prop, ED_view3d_cursor3d_get(scene, v3d)->location); } if (rv3d) { prop = RNA_struct_find_property(op->ptr, "axis"); diff --git a/source/blender/editors/mesh/editmesh_extrude_spin.c b/source/blender/editors/mesh/editmesh_extrude_spin.c index a4106ebcde1..4195f7daef3 100644 --- a/source/blender/editors/mesh/editmesh_extrude_spin.c +++ b/source/blender/editors/mesh/editmesh_extrude_spin.c @@ -487,7 +487,7 @@ static int edbm_spin_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(e PropertyRNA *prop; prop = RNA_struct_find_property(op->ptr, "center"); if (!RNA_property_is_set(op->ptr, prop)) { - RNA_property_float_set_array(op->ptr, prop, ED_view3d_cursor3d_get(scene, v3d)); + RNA_property_float_set_array(op->ptr, prop, ED_view3d_cursor3d_get(scene, v3d)->location); } if (rv3d) { prop = RNA_struct_find_property(op->ptr, "axis"); diff --git a/source/blender/editors/mesh/editmesh_polybuild.c b/source/blender/editors/mesh/editmesh_polybuild.c index dff501ece13..e8bcfb5eb08 100644 --- a/source/blender/editors/mesh/editmesh_polybuild.c +++ b/source/blender/editors/mesh/editmesh_polybuild.c @@ -89,7 +89,7 @@ static int edbm_polybuild_face_at_cursor_invoke( if (ele_act == NULL || ele_act->head.htype == BM_FACE) { /* Just add vert */ - copy_v3_v3(center, ED_view3d_cursor3d_get(vc.scene, vc.v3d)); + copy_v3_v3(center, ED_view3d_cursor3d_get(vc.scene, vc.v3d)->location); mul_v3_m4v3(center, vc.obedit->obmat, center); ED_view3d_win_to_3d_int(vc.v3d, vc.ar, center, event->mval, center); mul_m4_v3(vc.obedit->imat, center); diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index e6eec41e4d6..219c3acd2f7 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -2608,7 +2608,7 @@ static bool merge_target( const float *vco = NULL; if (use_cursor) { - vco = ED_view3d_cursor3d_get(scene, v3d); + vco = ED_view3d_cursor3d_get(scene, v3d)->location; copy_v3_v3(co, vco); invert_m4_m4(ob->imat, ob->obmat); mul_m4_v3(ob->imat, co); @@ -5469,9 +5469,9 @@ static void sort_bmelem_flag( float fact = reverse ? -1.0 : 1.0; if (v3d && v3d->localvd) - copy_v3_v3(cur, v3d->cursor); + copy_v3_v3(cur, v3d->cursor.location); else - copy_v3_v3(cur, scene->cursor); + copy_v3_v3(cur, scene->cursor.location); invert_m4_m4(mat, ob->obmat); mul_m4_v3(mat, cur); diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index c2934b916d0..7a0bd44411e 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -165,7 +165,7 @@ void ED_object_location_from_view(bContext *C, float loc[3]) Scene *scene = CTX_data_scene(C); const float *cursor; - cursor = ED_view3d_cursor3d_get(scene, v3d); + cursor = ED_view3d_cursor3d_get(scene, v3d)->location; copy_v3_v3(loc, cursor); } diff --git a/source/blender/editors/object/object_hook.c b/source/blender/editors/object/object_hook.c index b5a71bb7a35..8c68431c19a 100644 --- a/source/blender/editors/object/object_hook.c +++ b/source/blender/editors/object/object_hook.c @@ -781,7 +781,7 @@ static int object_hook_recenter_exec(bContext *C, wmOperator *op) copy_m3_m4(bmat, ob->obmat); invert_m3_m3(imat, bmat); - sub_v3_v3v3(hmd->cent, scene->cursor, ob->obmat[3]); + sub_v3_v3v3(hmd->cent, scene->cursor.location, ob->obmat[3]); mul_m3_v3(imat, hmd->cent); DEG_id_tag_update(&ob->id, OB_RECALC_DATA); diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c index f3045d44826..0db880a22c6 100644 --- a/source/blender/editors/object/object_transform.c +++ b/source/blender/editors/object/object_transform.c @@ -787,7 +787,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) else { /* get the view settings if 'around' isn't set and the view is available */ View3D *v3d = CTX_wm_view3d(C); - copy_v3_v3(cursor, ED_view3d_cursor3d_get(scene, v3d)); + copy_v3_v3(cursor, ED_view3d_cursor3d_get(scene, v3d)->location); if (v3d && !RNA_struct_property_is_set(op->ptr, "center")) around = v3d->around; } diff --git a/source/blender/editors/object/object_warp.c b/source/blender/editors/object/object_warp.c index 92b82e2a31b..008593739ba 100644 --- a/source/blender/editors/object/object_warp.c +++ b/source/blender/editors/object/object_warp.c @@ -227,7 +227,7 @@ static int object_warp_verts_exec(bContext *C, wmOperator *op) View3D *v3d = CTX_wm_view3d(C); const float *cursor; - cursor = ED_view3d_cursor3d_get(scene, v3d); + cursor = ED_view3d_cursor3d_get(scene, v3d)->location; copy_v3_v3(center, cursor); RNA_property_float_set_array(op->ptr, prop_center, center); diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c index 8c148dcb313..fd8fe84cffc 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.c +++ b/source/blender/editors/sculpt_paint/paint_image_proj.c @@ -3905,7 +3905,7 @@ static void paint_proj_begin_clone(ProjPaintState *ps, const float mouse[2]) /* setup clone offset */ if (ps->tool == PAINT_TOOL_CLONE) { float projCo[4]; - copy_v3_v3(projCo, ED_view3d_cursor3d_get(ps->scene, ps->v3d)); + copy_v3_v3(projCo, ED_view3d_cursor3d_get(ps->scene, ps->v3d)->location); mul_m4_v3(ps->obmat_imat, projCo); projCo[3] = 1.0f; @@ -5015,7 +5015,7 @@ void paint_proj_stroke( struct Depsgraph *graph = CTX_data_depsgraph(C); View3D *v3d = CTX_wm_view3d(C); ARegion *ar = CTX_wm_region(C); - float *cursor = ED_view3d_cursor3d_get(scene, v3d); + float *cursor = ED_view3d_cursor3d_get(scene, v3d)->location; int mval_i[2] = {(int)pos[0], (int)pos[1]}; view3d_operator_needs_opengl(C); diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c index f51acff3ba2..ab08d6a0025 100644 --- a/source/blender/editors/space_outliner/outliner_tools.c +++ b/source/blender/editors/space_outliner/outliner_tools.c @@ -550,7 +550,7 @@ static void group_instance_cb( { Group *group = (Group *)tselem->id; - Object *ob = ED_object_add_type(C, OB_EMPTY, group->id.name + 2, scene->cursor, NULL, false, scene->layact); + Object *ob = ED_object_add_type(C, OB_EMPTY, group->id.name + 2, scene->cursor.location, NULL, false, scene->layact); ob->dup_group = group; ob->transflag |= OB_DUPLIGROUP; id_lib_extern(&group->id); diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 7e05a80781c..95e688dcc08 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_mesh.h" #include "ED_gpencil.h" #include "ED_view3d.h" +#include "ED_transform_snap_object_context.h" #include "UI_resources.h" @@ -2706,7 +2707,6 @@ static int view3d_all_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); Base *base; - float *curs; const bool use_all_regions = RNA_boolean_get(op->ptr, "use_all_regions"); const bool skip_camera = (ED_view3d_camera_lock_check(v3d, ar->regiondata) || /* any one of the regions may be locked */ @@ -2719,10 +2719,11 @@ static int view3d_all_exec(bContext *C, wmOperator *op) if (center) { /* in 2.4x this also move the cursor to (0, 0, 0) (with shift+c). */ - curs = ED_view3d_cursor3d_get(scene, v3d); + View3DCursor *cursor = ED_view3d_cursor3d_get(scene, v3d); zero_v3(min); zero_v3(max); - zero_v3(curs); + zero_v3(cursor->location); + unit_qt(cursor->rotation); } else { INIT_MINMAX(min, max); @@ -3038,7 +3039,7 @@ static int viewcenter_cursor_exec(bContext *C, wmOperator *op) /* non camera center */ float new_ofs[3]; - negate_v3_v3(new_ofs, ED_view3d_cursor3d_get(scene, v3d)); + negate_v3_v3(new_ofs, ED_view3d_cursor3d_get(scene, v3d)->location); ED_view3d_smooth_view( C, v3d, ar, smooth_viewtx, &(const V3D_SmoothParams) {.ofs = new_ofs}); @@ -4572,25 +4573,75 @@ void ED_view3d_cursor3d_update(bContext *C, const int mval[2]) { Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); + ARegion *ar = CTX_wm_region(C); + RegionView3D *rv3d = ar->regiondata; - float *fp_curr = ED_view3d_cursor3d_get(scene, v3d); - float fp_prev[3]; + View3DCursor *cursor_curr = ED_view3d_cursor3d_get(scene, v3d); + View3DCursor cursor_prev = *cursor_curr; - copy_v3_v3(fp_prev, fp_curr); + ED_view3d_cursor3d_position(C, cursor_curr->location, mval); + copy_qt_qt(cursor_curr->rotation, rv3d->viewquat); + cursor_curr->rotation[0] *= -1.0f; + + { + struct Main *bmain = CTX_data_main(C); + const float mval_fl[2] = {UNPACK2(mval)}; + float ray_no[3]; + + struct SnapObjectContext *snap_context = ED_transform_snap_object_context_create_view3d( + bmain, scene, CTX_data_depsgraph(C), 0, ar, v3d); + + float obmat[4][4]; + Object *ob_dummy = NULL; + float dist_px = 0; + if (ED_transform_snap_object_project_view3d_ex( + snap_context, + SCE_SNAP_MODE_FACE, + &(const struct SnapObjectParams){ + .snap_select = SNAP_ALL, + .use_object_edit_cage = false, + }, + mval_fl, &dist_px, NULL, + cursor_curr->location, ray_no, NULL, + &ob_dummy, obmat)) + { + float tquat[4]; + /* Math normal (Z). */ + { + float z_src[3] = {0, 0, 1}; + mul_qt_v3(cursor_curr->rotation, z_src); + rotation_between_vecs_to_quat(tquat, z_src, ray_no); + mul_qt_qtqt(cursor_curr->rotation, tquat, cursor_curr->rotation); + } - ED_view3d_cursor3d_position(C, fp_curr, mval); + /* Match object matrix (X). */ + { + const float ortho_axis_dot[3] = { + dot_v3v3(ray_no, obmat[0]), + dot_v3v3(ray_no, obmat[1]), + dot_v3v3(ray_no, obmat[2]), + }; + const int ortho_axis = axis_dominant_v3_ortho_single(ortho_axis_dot); + float x_src[3] = {1, 0, 0}; + float x_dst[3]; + mul_qt_v3(cursor_curr->rotation, x_src); + project_plane_v3_v3v3(x_dst, obmat[ortho_axis], ray_no); + normalize_v3(x_dst); + rotation_between_vecs_to_quat(tquat, x_src, x_dst); + mul_qt_qtqt(cursor_curr->rotation, tquat, cursor_curr->rotation); + } + } + ED_transform_snap_object_context_destroy(snap_context); + } /* 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; - if (U.uiflag & USER_LOCK_CURSOR_ADJUST) { 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)) + if ((ED_view3d_project_float_global(ar, cursor_prev.location, co_prev, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) && + (ED_view3d_project_float_global(ar, cursor_curr->location, 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); diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c index 970fb5f5b9d..f177a88240c 100644 --- a/source/blender/editors/space_view3d/view3d_snap.c +++ b/source/blender/editors/space_view3d/view3d_snap.c @@ -407,7 +407,7 @@ static int snap_selected_to_cursor_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); - const float *snap_target_global = ED_view3d_cursor3d_get(scene, v3d); + const float *snap_target_global = ED_view3d_cursor3d_get(scene, v3d)->location; return snap_selected_to_location(C, snap_target_global, use_offset); } @@ -468,7 +468,7 @@ static int snap_curs_to_grid_exec(bContext *C, wmOperator *UNUSED(op)) float gridf, *curs; gridf = rv3d->gridview; - curs = ED_view3d_cursor3d_get(scene, v3d); + curs = ED_view3d_cursor3d_get(scene, v3d)->location; curs[0] = gridf * floorf(0.5f + curs[0] / gridf); curs[1] = gridf * floorf(0.5f + curs[1] / gridf); @@ -651,7 +651,7 @@ static int snap_curs_to_sel_exec(bContext *C, wmOperator *UNUSED(op)) View3D *v3d = CTX_wm_view3d(C); float *curs; - curs = ED_view3d_cursor3d_get(scene, v3d); + curs = ED_view3d_cursor3d_get(scene, v3d)->location; if (snap_curs_to_sel_ex(C, curs)) { WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d); @@ -725,7 +725,7 @@ static int snap_curs_to_active_exec(bContext *C, wmOperator *UNUSED(op)) View3D *v3d = CTX_wm_view3d(C); float *curs; - curs = ED_view3d_cursor3d_get(scene, v3d); + curs = ED_view3d_cursor3d_get(scene, v3d)->location; if (snap_calc_active_center(C, false, curs)) { WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d); @@ -758,7 +758,7 @@ static int snap_curs_to_center_exec(bContext *C, wmOperator *UNUSED(op)) Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); float *curs; - curs = ED_view3d_cursor3d_get(scene, v3d); + curs = ED_view3d_cursor3d_get(scene, v3d)->location; zero_v3(curs); diff --git a/source/blender/editors/space_view3d/view3d_utils.c b/source/blender/editors/space_view3d/view3d_utils.c index 09a3202c85e..9ce427fb830 100644 --- a/source/blender/editors/space_view3d/view3d_utils.c +++ b/source/blender/editors/space_view3d/view3d_utils.c @@ -71,10 +71,14 @@ * * \{ */ -float *ED_view3d_cursor3d_get(Scene *scene, View3D *v3d) +View3DCursor *ED_view3d_cursor3d_get(Scene *scene, View3D *v3d) { - if (v3d && v3d->localvd) return v3d->cursor; - else return scene->cursor; + if (v3d && v3d->localvd) { + return &v3d->cursor; + } + else { + return &scene->cursor; + } } Camera *ED_view3d_camera_data_get(View3D *v3d, RegionView3D *rv3d) diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index b6ea68c8fe4..0e78fd02b30 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -791,7 +791,7 @@ void view3d_viewmatrix_set( } else if (v3d->ob_centre_cursor) { float vec[3]; - copy_v3_v3(vec, ED_view3d_cursor3d_get(scene, (View3D *)v3d)); + copy_v3_v3(vec, ED_view3d_cursor3d_get(scene, (View3D *)v3d)->location); translate_m4(rv3d->viewmat, -vec[0], -vec[1], -vec[2]); use_lock_ofs = true; } diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 6b36e738cc0..41cc2087dea 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -2953,7 +2953,7 @@ static void initBend(TransInfo *t) data = MEM_callocN(sizeof(*data), __func__); - curs = ED_view3d_cursor3d_get(t->scene, t->view); + curs = ED_view3d_cursor3d_get(t->scene, t->view)->location; copy_v3_v3(data->warp_sta, curs); ED_view3d_win_to_3d(t->sa->spacedata.first, t->ar, curs, mval_fl, data->warp_end); diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c index bd03c0cedba..0b222e54a67 100644 --- a/source/blender/editors/transform/transform_constraints.c +++ b/source/blender/editors/transform/transform_constraints.c @@ -689,6 +689,10 @@ void setUserConstraint(TransInfo *t, short orientation, int mode, const char fte BLI_snprintf(text, sizeof(text), ftext, IFACE_("view")); setConstraint(t, t->spacemtx, mode, text); break; + case V3D_MANIP_CURSOR: + BLI_snprintf(text, sizeof(text), ftext, IFACE_("cursor")); + setConstraint(t, t->spacemtx, mode, text); + break; case V3D_MANIP_GIMBAL: BLI_snprintf(text, sizeof(text), ftext, IFACE_("gimbal")); setConstraint(t, t->spacemtx, mode, text); diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index 195c2ef3986..c3acf8c4350 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -1791,7 +1791,7 @@ void calculateCenterCursor(TransInfo *t, float r_center[3]) { const float *cursor; - cursor = ED_view3d_cursor3d_get(t->scene, t->view); + cursor = ED_view3d_cursor3d_get(t->scene, t->view)->location; copy_v3_v3(r_center, cursor); /* If edit or pose mode, move cursor in local space */ diff --git a/source/blender/editors/transform/transform_manipulator_3d.c b/source/blender/editors/transform/transform_manipulator_3d.c index c3c4abbda37..502cff9a243 100644 --- a/source/blender/editors/transform/transform_manipulator_3d.c +++ b/source/blender/editors/transform/transform_manipulator_3d.c @@ -669,6 +669,13 @@ int ED_transform_calc_manipulator_stats( copy_m4_m3(rv3d->twmat, mat); break; } + case V3D_MANIP_CURSOR: + { + float mat[3][3]; + quat_to_mat3(mat, ED_view3d_cursor3d_get(scene, v3d)->rotation); + copy_m4_m3(rv3d->twmat, mat); + break; + } case V3D_MANIP_CUSTOM: { TransformOrientation *custom_orientation = BKE_scene_transform_orientation_find( @@ -1083,7 +1090,7 @@ static void manipulator_prepare_mat( copy_v3_v3(rv3d->twmat[3], tbounds->center); break; case V3D_AROUND_CURSOR: - copy_v3_v3(rv3d->twmat[3], ED_view3d_cursor3d_get(scene, v3d)); + copy_v3_v3(rv3d->twmat[3], ED_view3d_cursor3d_get(scene, v3d)->location); break; } } diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c index 9e6f4847b5b..c1a2c99e26d 100644 --- a/source/blender/editors/transform/transform_orientations.c +++ b/source/blender/editors/transform/transform_orientations.c @@ -481,6 +481,13 @@ void initTransformOrientation(bContext *C, TransInfo *t) unit_m3(t->spacemtx); } break; + case V3D_MANIP_CURSOR: + { + const View3DCursor *cursor = ED_view3d_cursor3d_get(t->scene, CTX_wm_view3d(C)); + BLI_strncpy(t->spacename, IFACE_("cursor"), sizeof(t->spacename)); + quat_to_mat3(t->spacemtx, cursor->rotation); + break; + } case V3D_MANIP_CUSTOM: BLI_strncpy(t->spacename, t->custom_orientation->name, sizeof(t->spacename)); diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index 1442266a3aa..74521edf45f 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -1039,7 +1039,7 @@ static void uv_map_transform_center( case V3D_AROUND_CURSOR: /* cursor center */ { invert_m4_m4(ob->imat, ob->obmat); - mul_v3_m4v3(r_center, ob->imat, ED_view3d_cursor3d_get(scene, v3d)); + mul_v3_m4v3(r_center, ob->imat, ED_view3d_cursor3d_get(scene, v3d)->location); break; } case V3D_AROUND_ACTIVE: diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 2f3d5a82730..e12a6d253a8 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -50,6 +50,7 @@ extern "C" { #include "DNA_layer_types.h" #include "DNA_material_types.h" #include "DNA_userdef_types.h" +#include "DNA_view3d_types.h" struct CurveMapping; struct Object; @@ -1368,8 +1369,7 @@ typedef struct Scene { struct Base *basact DNA_DEPRECATED; /* active base */ void *_pad1; - float cursor[3]; /* 3d cursor location */ - char _pad[4]; + View3DCursor cursor; /* 3d cursor location */ unsigned int lay; /* bitflags for layer visibility */ int layact; /* active layer */ diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h index 406f7434033..cdbfec4030d 100644 --- a/source/blender/makesdna/DNA_view3d_types.h +++ b/source/blender/makesdna/DNA_view3d_types.h @@ -131,6 +131,12 @@ typedef struct RegionView3D { float rot_axis[3]; } RegionView3D; +typedef struct View3DCursor { + float location[3]; + float rotation[4]; + char _pad[4]; +} View3DCursor; + /* 3D Viewport Shading setings */ typedef struct View3DShading { short flag; @@ -197,7 +203,10 @@ typedef struct View3D { float lens, grid; float near, far; float ofs[3] DNA_DEPRECATED; /* XXX deprecated */ - float cursor[3]; + + View3DCursor cursor; + + char _pad[4]; short matcap_icon; /* icon id */ @@ -401,7 +410,8 @@ enum { #define V3D_MANIP_NORMAL 2 #define V3D_MANIP_VIEW 3 #define V3D_MANIP_GIMBAL 4 -#define V3D_MANIP_CUSTOM 5 +#define V3D_MANIP_CURSOR 5 +#define V3D_MANIP_CUSTOM 1024 /* View3d->twflag (also) */ enum { diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index b2fca51ce38..871b260902a 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -449,6 +449,7 @@ static const EnumPropertyItem transform_orientation_items[] = { "(bone Y axis for pose mode)"}, {V3D_MANIP_GIMBAL, "GIMBAL", 0, "Gimbal", "Align each axis to the Euler rotation axis as used for input"}, {V3D_MANIP_VIEW, "VIEW", 0, "View", "Align the transformation axes to the window"}, + {V3D_MANIP_CURSOR, "CURSOR", 0, "Cursor", "Align the transformation axes to the 3D cursor"}, // {V3D_MANIP_CUSTOM, "CUSTOM", 0, "Custom", "Use a custom transform orientation"}, {0, NULL, 0, NULL, NULL} }; @@ -5700,11 +5701,16 @@ void RNA_def_scene(BlenderRNA *brna) RNA_def_property_update(prop, NC_SCENE | ND_WORLD, "rna_Scene_world_update"); prop = RNA_def_property(srna, "cursor_location", PROP_FLOAT, PROP_XYZ_LENGTH); - RNA_def_property_float_sdna(prop, NULL, "cursor"); + RNA_def_property_float_sdna(prop, NULL, "cursor.location"); RNA_def_property_ui_text(prop, "Cursor Location", "3D cursor location"); RNA_def_property_ui_range(prop, -10000.0, 10000.0, 10, 4); RNA_def_property_update(prop, NC_WINDOW, NULL); + prop = RNA_def_property(srna, "cursor_rotation", PROP_FLOAT, PROP_QUATERNION); + RNA_def_property_float_sdna(prop, NULL, "cursor.rotation"); + RNA_def_property_ui_text(prop, "Cursor Rotation", "3D cursor rotation in quaternions (keep normalized)"); + RNA_def_property_update(prop, NC_WINDOW, NULL); + prop = RNA_def_property(srna, "objects", PROP_COLLECTION, PROP_NONE); RNA_def_property_struct_type(prop, "Object"); RNA_def_property_ui_text(prop, "Objects", ""); diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 8dba90d0a2b..20e69932e47 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -443,24 +443,37 @@ static void rna_SpaceView3D_lock_camera_and_layers_set(PointerRNA *ptr, int valu } } -static void rna_View3D_CursorLocation_get(PointerRNA *ptr, float *values) + +static View3DCursor *rna_View3D_Cursor_get_from_scene_or_localview(PointerRNA *ptr) { View3D *v3d = (View3D *)(ptr->data); bScreen *screen = ptr->id.data; Scene *scene = ED_screen_scene_find(screen, G.main->wm.first); - const float *loc = ED_view3d_cursor3d_get(scene, v3d); + return ED_view3d_cursor3d_get(scene, v3d); +} - copy_v3_v3(values, loc); +static void rna_View3D_Cursor_location_get(PointerRNA *ptr, float *values) +{ + const View3DCursor *cursor = rna_View3D_Cursor_get_from_scene_or_localview(ptr); + copy_v3_v3(values, cursor->location); } -static void rna_View3D_CursorLocation_set(PointerRNA *ptr, const float *values) +static void rna_View3D_Cursor_location_set(PointerRNA *ptr, const float *values) { - View3D *v3d = (View3D *)(ptr->data); - bScreen *screen = ptr->id.data; - Scene *scene = ED_screen_scene_find(screen, G.main->wm.first); - float *cursor = ED_view3d_cursor3d_get(scene, v3d); + View3DCursor *cursor = rna_View3D_Cursor_get_from_scene_or_localview(ptr); + copy_v3_v3(cursor->location, values); +} - copy_v3_v3(cursor, values); +static void rna_View3D_Cursor_rotation_get(PointerRNA *ptr, float *values) +{ + const View3DCursor *cursor = rna_View3D_Cursor_get_from_scene_or_localview(ptr); + copy_qt_qt(values, cursor->rotation); +} + +static void rna_View3D_Cursor_rotation_set(PointerRNA *ptr, const float *values) +{ + View3DCursor *cursor = rna_View3D_Cursor_get_from_scene_or_localview(ptr); + copy_qt_qt(cursor->rotation, values); } static float rna_View3DOverlay_GridScaleUnit_get(PointerRNA *ptr) @@ -2508,12 +2521,19 @@ static void rna_def_space_view3d(BlenderRNA *brna) prop = RNA_def_property(srna, "cursor_location", PROP_FLOAT, PROP_XYZ_LENGTH); RNA_def_property_array(prop, 3); - RNA_def_property_float_funcs(prop, "rna_View3D_CursorLocation_get", "rna_View3D_CursorLocation_set", NULL); + RNA_def_property_float_funcs(prop, "rna_View3D_Cursor_location_get", "rna_View3D_Cursor_location_set", NULL); RNA_def_property_ui_text(prop, "3D Cursor Location", "3D cursor location for this view (dependent on local view setting)"); RNA_def_property_ui_range(prop, -10000.0, 10000.0, 1, RNA_TRANSLATION_PREC_DEFAULT); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + prop = RNA_def_property(srna, "cursor_rotation", PROP_FLOAT, PROP_QUATERNION); + RNA_def_property_array(prop, 4); + RNA_def_property_float_funcs(prop, "rna_View3D_Cursor_rotation_get", "rna_View3D_Cursor_rotation_set", NULL); + RNA_def_property_ui_text(prop, "3D Cursor Rotation", + "Rotation in quaternions (keep normalized)"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + prop = RNA_def_property(srna, "lens", PROP_FLOAT, PROP_UNIT_CAMERA); RNA_def_property_float_sdna(prop, NULL, "lens"); RNA_def_property_ui_text(prop, "Lens", "Viewport lens angle"); |