2011-02-23 10:52:22 +00:00
|
|
|
/*
|
2008-12-19 12:14:58 +00:00
|
|
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
|
|
|
|
*
|
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
2008-12-26 10:31:44 +00:00
|
|
|
* of the License, or (at your option) any later version.
|
2008-12-19 12:14:58 +00:00
|
|
|
*
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
|
* along with this program; if not, write to the Free Software Foundation,
|
2010-02-12 13:34:04 +00:00
|
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2008-12-19 12:14:58 +00:00
|
|
|
*
|
|
|
|
|
* The Original Code is Copyright (C) 2008 Blender Foundation.
|
|
|
|
|
* All rights reserved.
|
|
|
|
|
*
|
2008-12-26 10:31:44 +00:00
|
|
|
*
|
2008-12-19 12:14:58 +00:00
|
|
|
* Contributor(s): Blender Foundation
|
|
|
|
|
*
|
|
|
|
|
* ***** END GPL LICENSE BLOCK *****
|
|
|
|
|
*/
|
|
|
|
|
|
2011-02-27 20:29:51 +00:00
|
|
|
/** \file blender/editors/space_view3d/view3d_edit.c
|
|
|
|
|
* \ingroup spview3d
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
2008-12-19 12:14:58 +00:00
|
|
|
#include <string.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <math.h>
|
|
|
|
|
#include <float.h>
|
|
|
|
|
|
2008-12-20 11:33:16 +00:00
|
|
|
#include "DNA_armature_types.h"
|
2008-12-19 12:14:58 +00:00
|
|
|
#include "DNA_object_types.h"
|
|
|
|
|
#include "DNA_scene_types.h"
|
2010-11-08 02:30:46 +00:00
|
|
|
#include "DNA_camera_types.h"
|
2011-05-14 04:25:47 +00:00
|
|
|
#include "DNA_lamp_types.h"
|
2008-12-19 12:14:58 +00:00
|
|
|
|
|
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
|
|
|
|
|
#include "BLI_blenlib.h"
|
2009-11-10 20:43:45 +00:00
|
|
|
#include "BLI_math.h"
|
2011-01-07 18:36:47 +00:00
|
|
|
#include "BLI_utildefines.h"
|
2008-12-19 12:14:58 +00:00
|
|
|
|
2011-11-18 23:32:17 +00:00
|
|
|
#include "BKE_camera.h"
|
2008-12-19 17:14:02 +00:00
|
|
|
#include "BKE_context.h"
|
2010-09-01 13:41:53 +00:00
|
|
|
#include "BKE_image.h"
|
|
|
|
|
#include "BKE_library.h"
|
2008-12-19 12:14:58 +00:00
|
|
|
#include "BKE_object.h"
|
2009-08-15 19:48:50 +00:00
|
|
|
#include "BKE_paint.h"
|
2009-01-21 02:24:12 +00:00
|
|
|
#include "BKE_report.h"
|
2008-12-19 12:14:58 +00:00
|
|
|
#include "BKE_scene.h"
|
2011-05-20 04:14:29 +00:00
|
|
|
#include "BKE_screen.h"
|
2012-05-05 16:38:23 +00:00
|
|
|
#include "BKE_action.h"
|
|
|
|
|
#include "BKE_armature.h"
|
2011-05-14 17:50:33 +00:00
|
|
|
#include "BKE_depsgraph.h" /* for ED_view3d_camera_lock_sync */
|
2008-12-19 12:14:58 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "BIF_gl.h"
|
2011-01-05 15:37:36 +00:00
|
|
|
#include "BIF_glutil.h"
|
2008-12-19 12:14:58 +00:00
|
|
|
|
|
|
|
|
#include "WM_api.h"
|
2008-12-19 17:14:02 +00:00
|
|
|
#include "WM_types.h"
|
2008-12-19 12:14:58 +00:00
|
|
|
|
2008-12-19 19:27:41 +00:00
|
|
|
#include "RNA_access.h"
|
|
|
|
|
#include "RNA_define.h"
|
|
|
|
|
|
2012-05-05 16:38:23 +00:00
|
|
|
#include "ED_armature.h"
|
2009-02-20 20:39:27 +00:00
|
|
|
#include "ED_particle.h"
|
2008-12-19 12:14:58 +00:00
|
|
|
#include "ED_screen.h"
|
2009-07-08 16:17:47 +00:00
|
|
|
#include "ED_transform.h"
|
2010-02-25 15:10:27 +00:00
|
|
|
#include "ED_mesh.h"
|
2010-10-21 07:38:09 +00:00
|
|
|
#include "ED_view3d.h"
|
2012-05-03 03:51:30 +00:00
|
|
|
#include "ED_sculpt.h"
|
2008-12-19 12:14:58 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "PIL_time.h" /* smoothview */
|
|
|
|
|
|
2012-07-08 20:36:00 +00:00
|
|
|
#include "view3d_intern.h" /* own include */
|
2008-12-19 12:14:58 +00:00
|
|
|
|
2013-05-03 07:29:25 +00:00
|
|
|
bool ED_view3d_offset_lock_check(struct View3D *v3d, struct RegionView3D *rv3d)
|
|
|
|
|
{
|
|
|
|
|
return (rv3d->persp != RV3D_CAMOB) && (v3d->ob_centre_cursor || v3d->ob_centre);
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-20 01:43:06 +00:00
|
|
|
static bool view3d_operator_offset_lock_check(bContext *C, wmOperator *op)
|
|
|
|
|
{
|
|
|
|
|
View3D *v3d = CTX_wm_view3d(C);
|
|
|
|
|
RegionView3D *rv3d = CTX_wm_region_view3d(C);
|
|
|
|
|
if (ED_view3d_offset_lock_check(v3d, rv3d)) {
|
|
|
|
|
BKE_report(op->reports, RPT_WARNING, "View offset is locked");
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
2013-05-03 07:29:25 +00:00
|
|
|
|
2008-12-19 12:14:58 +00:00
|
|
|
/* ********************** view3d_edit: view manipulations ********************* */
|
|
|
|
|
|
2013-03-20 23:14:18 +00:00
|
|
|
bool ED_view3d_camera_lock_check(View3D *v3d, RegionView3D *rv3d)
|
2011-05-23 15:46:09 +00:00
|
|
|
{
|
|
|
|
|
return ((v3d->camera) &&
|
|
|
|
|
(v3d->camera->id.lib == NULL) &&
|
|
|
|
|
(v3d->flag2 & V3D_LOCK_CAMERA) &&
|
2012-03-25 23:54:33 +00:00
|
|
|
(rv3d->persp == RV3D_CAMOB));
|
2011-05-23 15:46:09 +00:00
|
|
|
}
|
|
|
|
|
|
2014-02-24 15:15:17 +11:00
|
|
|
void ED_view3d_camera_lock_init_ex(View3D *v3d, RegionView3D *rv3d, const bool calc_dist)
|
2011-05-14 17:50:33 +00:00
|
|
|
{
|
2012-02-22 16:52:06 +00:00
|
|
|
if (ED_view3d_camera_lock_check(v3d, rv3d)) {
|
2014-02-24 15:15:17 +11:00
|
|
|
if (calc_dist) {
|
|
|
|
|
/* using a fallback dist is OK here since ED_view3d_from_object() compensates for it */
|
|
|
|
|
rv3d->dist = ED_view3d_offset_distance(v3d->camera->obmat, rv3d->ofs, VIEW3D_DIST_FALLBACK);
|
|
|
|
|
}
|
2011-05-14 17:50:33 +00:00
|
|
|
ED_view3d_from_object(v3d->camera, rv3d->ofs, rv3d->viewquat, &rv3d->dist, NULL);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-24 15:15:17 +11:00
|
|
|
void ED_view3d_camera_lock_init(View3D *v3d, RegionView3D *rv3d)
|
|
|
|
|
{
|
|
|
|
|
ED_view3d_camera_lock_init_ex(v3d, rv3d, true);
|
|
|
|
|
}
|
|
|
|
|
|
2013-03-20 23:14:18 +00:00
|
|
|
/* return true if the camera is moved */
|
|
|
|
|
bool ED_view3d_camera_lock_sync(View3D *v3d, RegionView3D *rv3d)
|
2011-05-14 17:50:33 +00:00
|
|
|
{
|
2012-02-22 16:52:06 +00:00
|
|
|
if (ED_view3d_camera_lock_check(v3d, rv3d)) {
|
2011-11-11 05:34:07 +00:00
|
|
|
ObjectTfmProtectedChannels obtfm;
|
2011-05-23 02:53:30 +00:00
|
|
|
Object *root_parent;
|
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
if ((U.uiflag & USER_CAM_LOCK_NO_PARENT) == 0 && (root_parent = v3d->camera->parent)) {
|
2011-05-23 02:53:30 +00:00
|
|
|
Object *ob_update;
|
2013-06-13 15:09:32 +00:00
|
|
|
float tmat[4][4];
|
|
|
|
|
float imat[4][4];
|
2011-05-23 02:53:30 +00:00
|
|
|
float view_mat[4][4];
|
|
|
|
|
float diff_mat[4][4];
|
|
|
|
|
float parent_mat[4][4];
|
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
while (root_parent->parent) {
|
2012-03-25 23:54:33 +00:00
|
|
|
root_parent = root_parent->parent;
|
2011-05-23 02:53:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ED_view3d_to_m4(view_mat, rv3d->ofs, rv3d->viewquat, rv3d->dist);
|
|
|
|
|
|
2013-06-13 15:09:32 +00:00
|
|
|
normalize_m4_m4(tmat, v3d->camera->obmat);
|
|
|
|
|
|
|
|
|
|
invert_m4_m4(imat, tmat);
|
|
|
|
|
mul_m4_m4m4(diff_mat, view_mat, imat);
|
2011-05-23 02:53:30 +00:00
|
|
|
|
2013-05-26 18:36:25 +00:00
|
|
|
mul_m4_m4m4(parent_mat, diff_mat, root_parent->obmat);
|
2011-11-11 05:34:07 +00:00
|
|
|
|
2012-05-05 14:03:12 +00:00
|
|
|
BKE_object_tfm_protected_backup(root_parent, &obtfm);
|
2013-03-20 23:14:18 +00:00
|
|
|
BKE_object_apply_mat4(root_parent, parent_mat, true, false);
|
2012-05-05 14:03:12 +00:00
|
|
|
BKE_object_tfm_protected_restore(root_parent, &obtfm, root_parent->protectflag);
|
2011-05-23 02:53:30 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
ob_update = v3d->camera;
|
2012-02-22 16:52:06 +00:00
|
|
|
while (ob_update) {
|
2011-05-23 02:53:30 +00:00
|
|
|
DAG_id_tag_update(&ob_update->id, OB_RECALC_OB);
|
2012-03-25 23:54:33 +00:00
|
|
|
WM_main_add_notifier(NC_OBJECT | ND_TRANSFORM, ob_update);
|
|
|
|
|
ob_update = ob_update->parent;
|
2011-05-23 02:53:30 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
2013-06-13 15:09:32 +00:00
|
|
|
/* always maintain the same scale */
|
|
|
|
|
const short protect_scale_all = (OB_LOCK_SCALEX | OB_LOCK_SCALEY | OB_LOCK_SCALEZ);
|
2012-05-05 14:03:12 +00:00
|
|
|
BKE_object_tfm_protected_backup(v3d->camera, &obtfm);
|
2011-05-23 02:53:30 +00:00
|
|
|
ED_view3d_to_object(v3d->camera, rv3d->ofs, rv3d->viewquat, rv3d->dist);
|
2013-06-13 15:09:32 +00:00
|
|
|
BKE_object_tfm_protected_restore(v3d->camera, &obtfm, v3d->camera->protectflag | protect_scale_all);
|
2011-11-11 05:34:07 +00:00
|
|
|
|
2011-05-23 02:53:30 +00:00
|
|
|
DAG_id_tag_update(&v3d->camera->id, OB_RECALC_OB);
|
2012-03-25 23:54:33 +00:00
|
|
|
WM_main_add_notifier(NC_OBJECT | ND_TRANSFORM, v3d->camera);
|
2011-05-23 02:53:30 +00:00
|
|
|
}
|
2011-08-27 11:52:59 +00:00
|
|
|
|
2013-03-20 23:14:18 +00:00
|
|
|
return true;
|
2011-08-27 11:52:59 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2013-03-20 23:14:18 +00:00
|
|
|
return false;
|
2011-05-14 17:50:33 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-20 01:24:00 +00:00
|
|
|
/**
|
|
|
|
|
* For viewport operators that exit camera persp.
|
|
|
|
|
*
|
|
|
|
|
* \note This differs from simply setting ``rv3d->persp = persp`` because it
|
|
|
|
|
* sets the ``ofs`` and ``dist`` values of the viewport so it matches the camera,
|
|
|
|
|
* otherwise switching out of camera view may jump to a different part of the scene.
|
|
|
|
|
*/
|
|
|
|
|
static void view3d_persp_switch_from_camera(View3D *v3d, RegionView3D *rv3d, const char persp)
|
|
|
|
|
{
|
|
|
|
|
BLI_assert(rv3d->persp == RV3D_CAMOB);
|
|
|
|
|
BLI_assert(persp != RV3D_CAMOB);
|
|
|
|
|
|
|
|
|
|
if (v3d->camera) {
|
|
|
|
|
rv3d->dist = ED_view3d_offset_distance(v3d->camera->obmat, rv3d->ofs, VIEW3D_DIST_FALLBACK);
|
|
|
|
|
ED_view3d_from_object(v3d->camera, rv3d->ofs, rv3d->viewquat, &rv3d->dist, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!ED_view3d_camera_lock_check(v3d, rv3d)) {
|
|
|
|
|
rv3d->persp = persp;
|
|
|
|
|
}
|
|
|
|
|
}
|
2011-05-14 17:50:33 +00:00
|
|
|
|
2009-01-20 18:31:11 +00:00
|
|
|
/* ********************* box view support ***************** */
|
|
|
|
|
|
|
|
|
|
static void view3d_boxview_clip(ScrArea *sa)
|
|
|
|
|
{
|
|
|
|
|
ARegion *ar;
|
|
|
|
|
BoundBox *bb = MEM_callocN(sizeof(BoundBox), "clipbb");
|
|
|
|
|
float clip[6][4];
|
2012-03-25 23:54:33 +00:00
|
|
|
float x1 = 0.0f, y1 = 0.0f, z1 = 0.0f, ofs[3] = {0.0f, 0.0f, 0.0f};
|
2009-01-20 18:31:11 +00:00
|
|
|
int val;
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2009-01-20 18:31:11 +00:00
|
|
|
/* create bounding box */
|
2012-03-25 23:54:33 +00:00
|
|
|
for (ar = sa->regionbase.first; ar; ar = ar->next) {
|
|
|
|
|
if (ar->regiontype == RGN_TYPE_WINDOW) {
|
|
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (rv3d->viewlock & RV3D_BOXCLIP) {
|
|
|
|
|
if (ELEM(rv3d->view, RV3D_VIEW_TOP, RV3D_VIEW_BOTTOM)) {
|
2012-03-25 23:54:33 +00:00
|
|
|
if (ar->winx > ar->winy) x1 = rv3d->dist;
|
|
|
|
|
else x1 = ar->winx * rv3d->dist / ar->winy;
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
if (ar->winx > ar->winy) y1 = ar->winy * rv3d->dist / ar->winx;
|
|
|
|
|
else y1 = rv3d->dist;
|
2010-02-25 20:26:38 +00:00
|
|
|
copy_v2_v2(ofs, rv3d->ofs);
|
2009-01-20 18:31:11 +00:00
|
|
|
}
|
2012-02-22 16:52:06 +00:00
|
|
|
else if (ELEM(rv3d->view, RV3D_VIEW_FRONT, RV3D_VIEW_BACK)) {
|
2012-03-25 23:54:33 +00:00
|
|
|
ofs[2] = rv3d->ofs[2];
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
if (ar->winx > ar->winy) z1 = ar->winy * rv3d->dist / ar->winx;
|
|
|
|
|
else z1 = rv3d->dist;
|
2009-01-20 18:31:11 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
for (val = 0; val < 8; val++) {
|
2012-02-22 16:52:06 +00:00
|
|
|
if (ELEM4(val, 0, 3, 4, 7))
|
2012-03-25 23:54:33 +00:00
|
|
|
bb->vec[val][0] = -x1 - ofs[0];
|
2009-01-20 18:31:11 +00:00
|
|
|
else
|
2012-03-25 23:54:33 +00:00
|
|
|
bb->vec[val][0] = x1 - ofs[0];
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (ELEM4(val, 0, 1, 4, 5))
|
2012-03-25 23:54:33 +00:00
|
|
|
bb->vec[val][1] = -y1 - ofs[1];
|
2009-01-20 18:31:11 +00:00
|
|
|
else
|
2012-03-25 23:54:33 +00:00
|
|
|
bb->vec[val][1] = y1 - ofs[1];
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (val > 3)
|
2012-03-25 23:54:33 +00:00
|
|
|
bb->vec[val][2] = -z1 - ofs[2];
|
2009-01-20 18:31:11 +00:00
|
|
|
else
|
2012-03-25 23:54:33 +00:00
|
|
|
bb->vec[val][2] = z1 - ofs[2];
|
2009-07-09 02:45:48 +00:00
|
|
|
}
|
|
|
|
|
|
2009-01-20 18:31:11 +00:00
|
|
|
/* normals for plane equations */
|
2012-03-25 23:54:33 +00:00
|
|
|
normal_tri_v3(clip[0], bb->vec[0], bb->vec[1], bb->vec[4]);
|
|
|
|
|
normal_tri_v3(clip[1], bb->vec[1], bb->vec[2], bb->vec[5]);
|
|
|
|
|
normal_tri_v3(clip[2], bb->vec[2], bb->vec[3], bb->vec[6]);
|
|
|
|
|
normal_tri_v3(clip[3], bb->vec[3], bb->vec[0], bb->vec[7]);
|
|
|
|
|
normal_tri_v3(clip[4], bb->vec[4], bb->vec[5], bb->vec[6]);
|
|
|
|
|
normal_tri_v3(clip[5], bb->vec[0], bb->vec[2], bb->vec[1]);
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2009-01-20 18:31:11 +00:00
|
|
|
/* then plane equations */
|
2012-03-25 23:54:33 +00:00
|
|
|
for (val = 0; val < 6; val++) {
|
2012-01-19 16:12:40 +00:00
|
|
|
clip[val][3] = -dot_v3v3(clip[val], bb->vec[val % 5]);
|
2009-01-20 18:31:11 +00:00
|
|
|
}
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2009-01-20 18:31:11 +00:00
|
|
|
/* create bounding box */
|
2012-03-25 23:54:33 +00:00
|
|
|
for (ar = sa->regionbase.first; ar; ar = ar->next) {
|
|
|
|
|
if (ar->regiontype == RGN_TYPE_WINDOW) {
|
|
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (rv3d->viewlock & RV3D_BOXCLIP) {
|
2009-01-20 18:31:11 +00:00
|
|
|
rv3d->rflag |= RV3D_CLIPPING;
|
|
|
|
|
memcpy(rv3d->clip, clip, sizeof(clip));
|
2012-02-22 16:52:06 +00:00
|
|
|
if (rv3d->clipbb) MEM_freeN(rv3d->clipbb);
|
2012-03-25 23:54:33 +00:00
|
|
|
rv3d->clipbb = MEM_dupallocN(bb);
|
2009-01-20 18:31:11 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
MEM_freeN(bb);
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-12 13:45:04 +11:00
|
|
|
/**
|
|
|
|
|
* Find which axis values are shared between both views and copy to \a rv3d_dst
|
|
|
|
|
* taking axis flipping into account.
|
|
|
|
|
*/
|
|
|
|
|
static void view3d_boxview_sync_axis(RegionView3D *rv3d_dst, RegionView3D *rv3d_src)
|
|
|
|
|
{
|
|
|
|
|
/* absolute axis values above this are considered to be set (will be ~1.0f) */
|
|
|
|
|
const float axis_eps = 0.5f;
|
|
|
|
|
float viewinv[4];
|
|
|
|
|
|
|
|
|
|
/* use the view rotation to identify which axis to sync on */
|
|
|
|
|
float view_axis_all[4][3] = {
|
|
|
|
|
{1.0f, 0.0f, 0.0f},
|
|
|
|
|
{0.0f, 1.0f, 0.0f},
|
|
|
|
|
{1.0f, 0.0f, 0.0f},
|
|
|
|
|
{0.0f, 1.0f, 0.0f}};
|
|
|
|
|
|
|
|
|
|
float *view_src_x = &view_axis_all[0][0];
|
|
|
|
|
float *view_src_y = &view_axis_all[1][0];
|
|
|
|
|
|
|
|
|
|
float *view_dst_x = &view_axis_all[2][0];
|
|
|
|
|
float *view_dst_y = &view_axis_all[3][0];
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* we could use rv3d->viewinv, but better not depend on view matrix being updated */
|
|
|
|
|
if (UNLIKELY(ED_view3d_quat_from_axis_view(rv3d_src->view, viewinv) == false)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
invert_qt(viewinv);
|
|
|
|
|
mul_qt_v3(viewinv, view_src_x);
|
|
|
|
|
mul_qt_v3(viewinv, view_src_y);
|
|
|
|
|
|
|
|
|
|
if (UNLIKELY(ED_view3d_quat_from_axis_view(rv3d_dst->view, viewinv) == false)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
invert_qt(viewinv);
|
|
|
|
|
mul_qt_v3(viewinv, view_dst_x);
|
|
|
|
|
mul_qt_v3(viewinv, view_dst_y);
|
|
|
|
|
|
|
|
|
|
/* check source and dest have a matching axis */
|
|
|
|
|
for (i = 0; i < 3; i++) {
|
|
|
|
|
if (((fabsf(view_src_x[i]) > axis_eps) || (fabsf(view_src_y[i]) > axis_eps)) &&
|
|
|
|
|
((fabsf(view_dst_x[i]) > axis_eps) || (fabsf(view_dst_y[i]) > axis_eps)))
|
|
|
|
|
{
|
|
|
|
|
rv3d_dst->ofs[i] = rv3d_src->ofs[i];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2.5
Smaller jobs, all in one commit!
- Moved object_do_update out of view3d drawing, into
the event system (currently after notifiers).
Depsgraph calls for setting update flags will have to
keep track of each Screen's needs, so a UI showing only
a Sequencer doesn't do objects.
- Added button in "Properties region" in 3D window to set
or disable 4-split, including the 3 options it has.
(lock, box, clip)
- Restored legacy code for UI, to make things work like
bone rename, autocomplete.
- Node editor now shows Curves widgets again
- Bugfix: composite job increased Viewer user id count
- Bugfix: Node editor, not "Enable nodes" still called
a Job, which didn't do anything
- Various code cleaning, unused vars and prototypes.
2009-02-11 16:54:55 +00:00
|
|
|
/* sync center/zoom view of region to others, for view transforms */
|
2009-01-20 14:23:32 +00:00
|
|
|
static void view3d_boxview_sync(ScrArea *sa, ARegion *ar)
|
|
|
|
|
{
|
|
|
|
|
ARegion *artest;
|
2012-03-25 23:54:33 +00:00
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
|
|
|
|
short clip = 0;
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
for (artest = sa->regionbase.first; artest; artest = artest->next) {
|
|
|
|
|
if (artest != ar && artest->regiontype == RGN_TYPE_WINDOW) {
|
|
|
|
|
RegionView3D *rv3dtest = artest->regiondata;
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2014-02-04 21:04:36 +11:00
|
|
|
if (rv3dtest->viewlock & RV3D_LOCKED) {
|
2012-03-25 23:54:33 +00:00
|
|
|
rv3dtest->dist = rv3d->dist;
|
2014-02-12 13:45:04 +11:00
|
|
|
view3d_boxview_sync_axis(rv3dtest, rv3d);
|
2010-11-08 03:44:52 +00:00
|
|
|
clip |= rv3dtest->viewlock & RV3D_BOXCLIP;
|
|
|
|
|
|
2009-01-20 14:23:32 +00:00
|
|
|
ED_region_tag_redraw(artest);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2010-11-08 03:44:52 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (clip) {
|
2010-11-08 03:44:52 +00:00
|
|
|
view3d_boxview_clip(sa);
|
|
|
|
|
}
|
2009-01-20 14:23:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* for home, center etc */
|
2.5
Smaller jobs, all in one commit!
- Moved object_do_update out of view3d drawing, into
the event system (currently after notifiers).
Depsgraph calls for setting update flags will have to
keep track of each Screen's needs, so a UI showing only
a Sequencer doesn't do objects.
- Added button in "Properties region" in 3D window to set
or disable 4-split, including the 3 options it has.
(lock, box, clip)
- Restored legacy code for UI, to make things work like
bone rename, autocomplete.
- Node editor now shows Curves widgets again
- Bugfix: composite job increased Viewer user id count
- Bugfix: Node editor, not "Enable nodes" still called
a Job, which didn't do anything
- Various code cleaning, unused vars and prototypes.
2009-02-11 16:54:55 +00:00
|
|
|
void view3d_boxview_copy(ScrArea *sa, ARegion *ar)
|
2009-01-20 14:23:32 +00:00
|
|
|
{
|
|
|
|
|
ARegion *artest;
|
2012-03-25 23:54:33 +00:00
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
2014-02-04 21:04:36 +11:00
|
|
|
bool clip = false;
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
for (artest = sa->regionbase.first; artest; artest = artest->next) {
|
|
|
|
|
if (artest != ar && artest->regiontype == RGN_TYPE_WINDOW) {
|
|
|
|
|
RegionView3D *rv3dtest = artest->regiondata;
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (rv3dtest->viewlock) {
|
2012-03-25 23:54:33 +00:00
|
|
|
rv3dtest->dist = rv3d->dist;
|
2010-07-26 06:34:56 +00:00
|
|
|
copy_v3_v3(rv3dtest->ofs, rv3d->ofs);
|
2009-01-20 14:23:32 +00:00
|
|
|
ED_region_tag_redraw(artest);
|
2010-11-08 03:44:52 +00:00
|
|
|
|
2014-02-04 21:04:36 +11:00
|
|
|
clip |= ((rv3dtest->viewlock & RV3D_BOXCLIP) != 0);
|
2009-01-20 14:23:32 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2010-11-08 03:44:52 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (clip) {
|
2010-11-08 03:44:52 +00:00
|
|
|
view3d_boxview_clip(sa);
|
|
|
|
|
}
|
2009-01-20 14:23:32 +00:00
|
|
|
}
|
|
|
|
|
|
2010-11-08 03:44:52 +00:00
|
|
|
/* 'clip' is used to know if our clip setting has changed */
|
2013-03-20 23:14:18 +00:00
|
|
|
void ED_view3d_quadview_update(ScrArea *sa, ARegion *ar, bool do_clip)
|
2010-01-30 03:22:22 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
ARegion *ar_sync = NULL;
|
|
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
2010-01-30 03:22:22 +00:00
|
|
|
short viewlock;
|
|
|
|
|
/* this function copies flags from the first of the 3 other quadview
|
2012-03-03 11:45:08 +00:00
|
|
|
* regions to the 2 other, so it assumes this is the region whose
|
|
|
|
|
* properties are always being edited, weak */
|
2012-03-25 23:54:33 +00:00
|
|
|
viewlock = rv3d->viewlock;
|
2010-01-30 03:22:22 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
if ((viewlock & RV3D_LOCKED) == 0)
|
|
|
|
|
viewlock = 0;
|
|
|
|
|
else if ((viewlock & RV3D_BOXVIEW) == 0) {
|
2010-01-30 03:22:22 +00:00
|
|
|
viewlock &= ~RV3D_BOXCLIP;
|
2013-03-20 23:14:18 +00:00
|
|
|
do_clip = true;
|
2010-11-08 03:44:52 +00:00
|
|
|
}
|
2010-01-30 03:22:22 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
for (; ar; ar = ar->prev) {
|
|
|
|
|
if (ar->alignment == RGN_ALIGN_QSPLIT) {
|
|
|
|
|
rv3d = ar->regiondata;
|
|
|
|
|
rv3d->viewlock = viewlock;
|
2010-11-08 03:44:52 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
if (do_clip && (viewlock & RV3D_BOXCLIP) == 0) {
|
2010-11-08 03:44:52 +00:00
|
|
|
rv3d->rflag &= ~RV3D_BOXCLIP;
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-03 11:45:08 +00:00
|
|
|
/* use ar_sync so we sync with one of the aligned views below
|
2010-11-08 03:44:52 +00:00
|
|
|
* else the view jumps on changing view settings like 'clip'
|
|
|
|
|
* since it copies from the perspective view */
|
2012-03-25 23:54:33 +00:00
|
|
|
ar_sync = ar;
|
2010-01-30 03:22:22 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (rv3d->viewlock & RV3D_BOXVIEW) {
|
2014-02-12 14:08:21 +11:00
|
|
|
view3d_boxview_sync(sa, ar_sync ? ar_sync : sa->regionbase.last);
|
2010-11-08 03:44:52 +00:00
|
|
|
}
|
2010-01-30 03:22:22 +00:00
|
|
|
|
2014-02-12 11:26:02 +11:00
|
|
|
/* ensure locked regions have an axis, locked user views don't make much sense */
|
|
|
|
|
if (viewlock & RV3D_LOCKED) {
|
|
|
|
|
int index_qsplit = 0;
|
|
|
|
|
for (ar = sa->regionbase.first; ar; ar = ar->next) {
|
|
|
|
|
if (ar->alignment == RGN_ALIGN_QSPLIT) {
|
|
|
|
|
rv3d = ar->regiondata;
|
|
|
|
|
if (rv3d->viewlock) {
|
|
|
|
|
if (!RV3D_VIEW_IS_AXIS(rv3d->view)) {
|
|
|
|
|
rv3d->view = ED_view3d_lock_view_from_index(index_qsplit);
|
|
|
|
|
rv3d->persp = RV3D_ORTHO;
|
|
|
|
|
ED_view3d_lock(rv3d);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
index_qsplit++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2010-01-30 03:22:22 +00:00
|
|
|
ED_area_tag_redraw(sa);
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-19 17:14:02 +00:00
|
|
|
/* ************************** init for view ops **********************************/
|
2008-12-19 12:14:58 +00:00
|
|
|
|
2008-12-19 17:14:02 +00:00
|
|
|
typedef struct ViewOpsData {
|
2013-09-20 01:24:00 +00:00
|
|
|
/* context pointers (assigned by viewops_data_alloc) */
|
2009-01-20 14:23:32 +00:00
|
|
|
ScrArea *sa;
|
2008-12-19 17:14:02 +00:00
|
|
|
ARegion *ar;
|
2011-05-14 05:42:58 +00:00
|
|
|
View3D *v3d;
|
2.5
View3D has been split now in a local part (RegionView3D) and a
per-area part (old View3D). Currently local is:
- view transform
- camera zoom/offset
- gpencil (todo)
- custom clipping planes
Rest is in Area still, like active camera, draw type, layers,
localview, custom centers, around-settings, transform widget,
gridlines, and so on (mostly stuff as available in header).
To see it work; also added new feature for region split,
press SHIFT+ALT+CTRL+S for four-split.
The idea is to make a preset 4-split, configured to stick
to top/right/front views for three views.
Another cool idea to explore is to then box-clip all drawing
based on these 3 views.
Note about the code:
- currently view3d still stores some depricated settings, to
convert from older files. Not all settings are copied over
though, like custom clip planes or the 'lock view to object'.
- since some view3d ops are now on area level, the operators
for it should keep track of that.
Bugfix in transform: quat initialize in operator-invoke missed
one zero.
Als brought back GE to compile for missing Ipos and channels.
2009-01-19 16:54:41 +00:00
|
|
|
RegionView3D *rv3d;
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2009-12-16 23:05:59 +00:00
|
|
|
/* needed for continuous zoom */
|
|
|
|
|
wmTimer *timer;
|
|
|
|
|
double timer_lastdraw;
|
|
|
|
|
|
2008-12-19 17:14:02 +00:00
|
|
|
float oldquat[4];
|
2011-11-11 05:34:07 +00:00
|
|
|
float viewquat[4]; /* working copy of rv3d->viewquat */
|
2008-12-19 17:14:02 +00:00
|
|
|
float trackvec[3];
|
2011-04-22 15:34:07 +00:00
|
|
|
float mousevec[3]; /* dolly only */
|
2013-04-04 04:22:38 +00:00
|
|
|
float reverse;
|
|
|
|
|
float dist_prev, camzoom_prev;
|
2.5
View3D has been split now in a local part (RegionView3D) and a
per-area part (old View3D). Currently local is:
- view transform
- camera zoom/offset
- gpencil (todo)
- custom clipping planes
Rest is in Area still, like active camera, draw type, layers,
localview, custom centers, around-settings, transform widget,
gridlines, and so on (mostly stuff as available in header).
To see it work; also added new feature for region split,
press SHIFT+ALT+CTRL+S for four-split.
The idea is to make a preset 4-split, configured to stick
to top/right/front views for three views.
Another cool idea to explore is to then box-clip all drawing
based on these 3 views.
Note about the code:
- currently view3d still stores some depricated settings, to
convert from older files. Not all settings are copied over
though, like custom clip planes or the 'lock view to object'.
- since some view3d ops are now on area level, the operators
for it should keep track of that.
Bugfix in transform: quat initialize in operator-invoke missed
one zero.
Als brought back GE to compile for missing Ipos and channels.
2009-01-19 16:54:41 +00:00
|
|
|
float grid, far;
|
2013-03-20 23:14:18 +00:00
|
|
|
bool axis_snap; /* view rotate only */
|
2013-03-09 11:40:42 +00:00
|
|
|
float zfac;
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2009-12-09 00:45:50 +00:00
|
|
|
/* use for orbit selection and auto-dist */
|
|
|
|
|
float ofs[3], dyn_ofs[3];
|
2013-03-22 04:40:45 +00:00
|
|
|
bool use_dyn_ofs;
|
2009-12-09 00:45:50 +00:00
|
|
|
|
2008-12-19 17:14:02 +00:00
|
|
|
int origx, origy, oldx, oldy;
|
2009-09-25 10:24:42 +00:00
|
|
|
int origkey; /* the key that triggered the operator */
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2008-12-19 17:14:02 +00:00
|
|
|
} ViewOpsData;
|
2008-12-19 12:14:58 +00:00
|
|
|
|
2008-12-19 17:14:02 +00:00
|
|
|
#define TRACKBALLSIZE (1.1)
|
2008-12-19 12:14:58 +00:00
|
|
|
|
2012-09-15 11:48:20 +00:00
|
|
|
static void calctrackballvec(const rcti *rect, int mx, int my, float vec[3])
|
2008-12-19 12:14:58 +00:00
|
|
|
{
|
|
|
|
|
float x, y, radius, d, z, t;
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
radius = TRACKBALLSIZE;
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2008-12-19 12:14:58 +00:00
|
|
|
/* normalize x and y */
|
2012-09-15 11:48:20 +00:00
|
|
|
x = BLI_rcti_cent_x(rect) - mx;
|
|
|
|
|
x /= (float)(BLI_rcti_size_x(rect) / 4);
|
|
|
|
|
y = BLI_rcti_cent_y(rect) - my;
|
|
|
|
|
y /= (float)(BLI_rcti_size_y(rect) / 2);
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
d = sqrt(x * x + y * y);
|
2011-08-25 15:49:52 +00:00
|
|
|
if (d < radius * (float)M_SQRT1_2) { /* Inside sphere */
|
2012-03-25 23:54:33 +00:00
|
|
|
z = sqrt(radius * radius - d * d);
|
2011-08-25 15:49:52 +00:00
|
|
|
}
|
|
|
|
|
else { /* On hyperbola */
|
2012-03-25 23:54:33 +00:00
|
|
|
t = radius / (float)M_SQRT2;
|
|
|
|
|
z = t * t / d;
|
2008-12-19 12:14:58 +00:00
|
|
|
}
|
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
vec[0] = x;
|
|
|
|
|
vec[1] = y;
|
|
|
|
|
vec[2] = -z; /* yah yah! */
|
2008-12-19 17:14:02 +00:00
|
|
|
}
|
|
|
|
|
|
2008-12-19 12:14:58 +00:00
|
|
|
|
2013-09-20 01:24:00 +00:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/* ViewOpsData */
|
|
|
|
|
|
|
|
|
|
/** \name Generic View Operator Custom-Data.
|
|
|
|
|
* \{ */
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Allocate and fill in context pointers for #ViewOpsData
|
|
|
|
|
*/
|
|
|
|
|
static void viewops_data_alloc(bContext *C, wmOperator *op)
|
2008-12-19 17:14:02 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
ViewOpsData *vod = MEM_callocN(sizeof(ViewOpsData), "viewops data");
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2008-12-19 17:14:02 +00:00
|
|
|
/* store data */
|
2012-03-25 23:54:33 +00:00
|
|
|
op->customdata = vod;
|
|
|
|
|
vod->sa = CTX_wm_area(C);
|
|
|
|
|
vod->ar = CTX_wm_region(C);
|
|
|
|
|
vod->v3d = vod->sa->spacedata.first;
|
2013-09-20 01:24:00 +00:00
|
|
|
vod->rv3d = vod->ar->regiondata;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Calculate the values for #ViewOpsData
|
|
|
|
|
*/
|
2014-02-24 12:53:31 +11:00
|
|
|
static void viewops_data_create_ex(bContext *C, wmOperator *op, const wmEvent *event,
|
|
|
|
|
const bool use_orbit_select,
|
|
|
|
|
const bool use_orbit_zbuf)
|
2013-09-20 01:24:00 +00:00
|
|
|
{
|
|
|
|
|
ViewOpsData *vod = op->customdata;
|
|
|
|
|
static float lastofs[3] = {0, 0, 0};
|
|
|
|
|
RegionView3D *rv3d = vod->rv3d;
|
2011-05-15 03:07:07 +00:00
|
|
|
|
|
|
|
|
/* set the view from the camera, if view locking is enabled.
|
|
|
|
|
* we may want to make this optional but for now its needed always */
|
|
|
|
|
ED_view3d_camera_lock_init(vod->v3d, vod->rv3d);
|
|
|
|
|
|
2013-04-04 04:22:38 +00:00
|
|
|
vod->dist_prev = rv3d->dist;
|
|
|
|
|
vod->camzoom_prev = rv3d->camzoom;
|
2011-11-11 05:34:07 +00:00
|
|
|
copy_qt_qt(vod->viewquat, rv3d->viewquat);
|
2010-07-26 06:34:56 +00:00
|
|
|
copy_qt_qt(vod->oldquat, rv3d->viewquat);
|
2012-03-25 23:54:33 +00:00
|
|
|
vod->origx = vod->oldx = event->x;
|
|
|
|
|
vod->origy = vod->oldy = event->y;
|
|
|
|
|
vod->origkey = event->type; /* the key that triggered the operator. */
|
2014-02-24 12:53:31 +11:00
|
|
|
vod->use_dyn_ofs = use_orbit_select;
|
2011-04-22 15:34:07 +00:00
|
|
|
copy_v3_v3(vod->ofs, rv3d->ofs);
|
2009-12-09 00:45:50 +00:00
|
|
|
|
|
|
|
|
if (vod->use_dyn_ofs) {
|
2012-12-13 10:51:38 +00:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
|
|
|
|
Object *ob = OBACT;
|
|
|
|
|
|
2013-04-04 04:26:13 +00:00
|
|
|
if (ob && (ob->mode & OB_MODE_ALL_PAINT) && (BKE_object_pose_armature_get(ob) == NULL)) {
|
2013-04-19 13:26:17 +00:00
|
|
|
/* in case of sculpting use last average stroke position as a rotation
|
|
|
|
|
* center, in other cases it's not clear what rotation center shall be
|
|
|
|
|
* so just rotate around object origin
|
2012-12-13 10:51:38 +00:00
|
|
|
*/
|
2013-04-19 13:26:17 +00:00
|
|
|
if (ob->mode & OB_MODE_SCULPT) {
|
|
|
|
|
float stroke[3];
|
|
|
|
|
ED_sculpt_get_average_stroke(ob, stroke);
|
|
|
|
|
copy_v3_v3(lastofs, stroke);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
copy_v3_v3(lastofs, ob->obmat[3]);
|
|
|
|
|
}
|
2012-12-13 10:51:38 +00:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* If there's no selection, lastofs is unmodified and last value since static */
|
|
|
|
|
calculateTransformCenter(C, V3D_CENTROID, lastofs, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
2010-02-26 09:02:52 +00:00
|
|
|
negate_v3_v3(vod->dyn_ofs, lastofs);
|
2009-12-09 00:45:50 +00:00
|
|
|
}
|
2014-02-24 12:53:31 +11:00
|
|
|
else if (use_orbit_zbuf) {
|
2013-03-22 04:40:45 +00:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
2013-09-16 08:59:54 +00:00
|
|
|
float fallback_depth_pt[3];
|
2009-12-09 00:45:50 +00:00
|
|
|
|
|
|
|
|
view3d_operator_needs_opengl(C); /* needed for zbuf drawing */
|
|
|
|
|
|
2013-09-16 08:59:54 +00:00
|
|
|
negate_v3_v3(fallback_depth_pt, rv3d->ofs);
|
|
|
|
|
|
|
|
|
|
if ((vod->use_dyn_ofs = ED_view3d_autodist(scene, vod->ar, vod->v3d,
|
|
|
|
|
event->mval, vod->dyn_ofs, true, fallback_depth_pt)))
|
|
|
|
|
{
|
2011-05-18 17:52:26 +00:00
|
|
|
if (rv3d->is_persp) {
|
2009-12-09 00:45:50 +00:00
|
|
|
float my_origin[3]; /* original G.vd->ofs */
|
|
|
|
|
float my_pivot[3]; /* view */
|
|
|
|
|
float dvec[3];
|
|
|
|
|
|
2012-07-08 20:36:00 +00:00
|
|
|
/* locals for dist correction */
|
2009-12-09 00:45:50 +00:00
|
|
|
float mat[3][3];
|
|
|
|
|
float upvec[3];
|
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
negate_v3_v3(my_origin, rv3d->ofs); /* ofs is flipped */
|
2009-12-09 00:45:50 +00:00
|
|
|
|
2012-03-03 11:45:08 +00:00
|
|
|
/* Set the dist value to be the distance from this 3d point
|
|
|
|
|
* this means youll always be able to zoom into it and panning wont go bad when dist was zero */
|
2009-12-09 00:45:50 +00:00
|
|
|
|
|
|
|
|
/* remove dist value */
|
|
|
|
|
upvec[0] = upvec[1] = 0;
|
|
|
|
|
upvec[2] = rv3d->dist;
|
|
|
|
|
copy_m3_m4(mat, rv3d->viewinv);
|
|
|
|
|
|
|
|
|
|
mul_m3_v3(mat, upvec);
|
|
|
|
|
sub_v3_v3v3(my_pivot, rv3d->ofs, upvec);
|
2012-03-25 23:54:33 +00:00
|
|
|
negate_v3(my_pivot); /* ofs is flipped */
|
2009-12-09 00:45:50 +00:00
|
|
|
|
2011-10-17 06:39:13 +00:00
|
|
|
/* find a new ofs value that is along the view axis (rather than the mouse location) */
|
2009-12-09 00:45:50 +00:00
|
|
|
closest_to_line_v3(dvec, vod->dyn_ofs, my_pivot, my_origin);
|
2013-04-04 04:22:38 +00:00
|
|
|
vod->dist_prev = rv3d->dist = len_v3v3(my_pivot, dvec);
|
2009-12-09 00:45:50 +00:00
|
|
|
|
2010-02-25 20:26:38 +00:00
|
|
|
negate_v3_v3(rv3d->ofs, dvec);
|
2009-12-09 00:45:50 +00:00
|
|
|
}
|
2013-09-16 08:59:54 +00:00
|
|
|
else {
|
|
|
|
|
float mval_ar_mid[2] = {
|
|
|
|
|
(float)vod->ar->winx / 2.0f,
|
|
|
|
|
(float)vod->ar->winy / 2.0f};
|
|
|
|
|
|
|
|
|
|
ED_view3d_win_to_3d(vod->ar, vod->dyn_ofs, mval_ar_mid, rv3d->ofs);
|
|
|
|
|
negate_v3(rv3d->ofs);
|
|
|
|
|
}
|
2009-12-09 00:45:50 +00:00
|
|
|
negate_v3(vod->dyn_ofs);
|
2010-07-26 06:34:56 +00:00
|
|
|
copy_v3_v3(vod->ofs, rv3d->ofs);
|
2009-12-09 00:45:50 +00:00
|
|
|
}
|
2009-10-15 15:58:12 +00:00
|
|
|
}
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2011-05-20 13:50:41 +00:00
|
|
|
{
|
|
|
|
|
/* for dolly */
|
2012-09-06 23:41:03 +00:00
|
|
|
const float mval_f[2] = {(float)event->mval[0],
|
|
|
|
|
(float)event->mval[1]};
|
2011-05-20 13:50:41 +00:00
|
|
|
ED_view3d_win_to_vector(vod->ar, mval_f, vod->mousevec);
|
|
|
|
|
}
|
2011-04-22 15:34:07 +00:00
|
|
|
|
2012-03-18 07:38:51 +00:00
|
|
|
/* lookup, we don't pass on v3d to prevent confusement */
|
2012-03-25 23:54:33 +00:00
|
|
|
vod->grid = vod->v3d->grid;
|
|
|
|
|
vod->far = vod->v3d->far;
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2008-12-19 17:14:02 +00:00
|
|
|
calctrackballvec(&vod->ar->winrct, event->x, event->y, vod->trackvec);
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2013-03-09 11:40:42 +00:00
|
|
|
{
|
|
|
|
|
float tvec[3];
|
|
|
|
|
negate_v3_v3(tvec, rv3d->ofs);
|
|
|
|
|
vod->zfac = ED_view3d_calc_zfac(rv3d, tvec, NULL);
|
|
|
|
|
}
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
vod->reverse = 1.0f;
|
2.5
View3D has been split now in a local part (RegionView3D) and a
per-area part (old View3D). Currently local is:
- view transform
- camera zoom/offset
- gpencil (todo)
- custom clipping planes
Rest is in Area still, like active camera, draw type, layers,
localview, custom centers, around-settings, transform widget,
gridlines, and so on (mostly stuff as available in header).
To see it work; also added new feature for region split,
press SHIFT+ALT+CTRL+S for four-split.
The idea is to make a preset 4-split, configured to stick
to top/right/front views for three views.
Another cool idea to explore is to then box-clip all drawing
based on these 3 views.
Note about the code:
- currently view3d still stores some depricated settings, to
convert from older files. Not all settings are copied over
though, like custom clip planes or the 'lock view to object'.
- since some view3d ops are now on area level, the operators
for it should keep track of that.
Bugfix in transform: quat initialize in operator-invoke missed
one zero.
Als brought back GE to compile for missing Ipos and channels.
2009-01-19 16:54:41 +00:00
|
|
|
if (rv3d->persmat[2][1] < 0.0f)
|
2012-03-25 23:54:33 +00:00
|
|
|
vod->reverse = -1.0f;
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2009-11-25 14:13:43 +00:00
|
|
|
rv3d->rflag |= RV3D_NAVIGATING;
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-24 12:53:31 +11:00
|
|
|
static void viewops_data_create(bContext *C, wmOperator *op, const wmEvent *event)
|
|
|
|
|
{
|
|
|
|
|
viewops_data_create_ex(
|
|
|
|
|
C, op, event,
|
|
|
|
|
(U.uiflag & USER_ORBIT_SELECTION) != 0,
|
|
|
|
|
(U.uiflag & USER_ZBUF_ORBIT) != 0);
|
|
|
|
|
}
|
|
|
|
|
|
2009-11-25 14:13:43 +00:00
|
|
|
static void viewops_data_free(bContext *C, wmOperator *op)
|
|
|
|
|
{
|
2011-01-03 01:26:54 +00:00
|
|
|
ARegion *ar;
|
Paint refactoring commit, non-disruptive (in theory :p)
* Fix precision overflow issue with overlay previews,
* Expose alpha mask mapping to UI (still not functional but coming soon).
* More overlay refactoring:
Overlay now does minimal checking for texture refresh.
Instead, we now have invalidation flags to set an aspect of the brush
overlay as invalid. This is necessary because this way we will be able to
separate and preview different brush attributes on the overlays, using
different textures:
These attributes/aspects are:
Primary texture (main texture for sculpt, vertex, imapaint)
Secondary texture (mask/alpha texture for imapaint)
Cursor texture (cursor texture. It involves brush strength and curves)
Modified the relevant RNA property update functions and C update callback
functions to call the relevant cursor invalidation functions instead
of checking every frame for multiple properties.
Properties that affect this are:
Image changes, if image is used by current brush,
Texture slot changes, similarly
Curve changes,
Object mode change invalidates the cursor
Paint tool change invalidates the cursor.
These changes give slightly more invalidation cases than simply
comparing the relevant properties each frame, but these do not occur in
performance critical moments and it's a much more elegant system than
adding more variables to check per frame each time we add something on
the system.
2013-04-12 17:21:31 +00:00
|
|
|
Paint *p = BKE_paint_get_active_from_context(C);
|
2009-11-25 14:13:43 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (op->customdata) {
|
2012-03-25 23:54:33 +00:00
|
|
|
ViewOpsData *vod = op->customdata;
|
|
|
|
|
ar = vod->ar;
|
2011-01-03 01:26:54 +00:00
|
|
|
vod->rv3d->rflag &= ~RV3D_NAVIGATING;
|
2009-11-25 14:13:43 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (vod->timer)
|
2011-01-03 01:26:54 +00:00
|
|
|
WM_event_remove_timer(CTX_wm_manager(C), vod->timer->win, vod->timer);
|
2009-11-25 14:13:43 +00:00
|
|
|
|
2011-01-03 01:26:54 +00:00
|
|
|
MEM_freeN(vod);
|
2012-03-25 23:54:33 +00:00
|
|
|
op->customdata = NULL;
|
2011-01-03 01:26:54 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2012-03-25 23:54:33 +00:00
|
|
|
ar = CTX_wm_region(C);
|
2011-01-03 01:26:54 +00:00
|
|
|
}
|
2009-12-16 23:05:59 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (p && (p->flags & PAINT_FAST_NAVIGATE))
|
2011-01-03 01:26:54 +00:00
|
|
|
ED_region_tag_redraw(ar);
|
2008-12-26 10:31:44 +00:00
|
|
|
}
|
2013-09-20 01:24:00 +00:00
|
|
|
/** \} */
|
|
|
|
|
|
2008-12-19 17:14:02 +00:00
|
|
|
|
|
|
|
|
/* ************************** viewrotate **********************************/
|
|
|
|
|
|
2012-01-21 05:27:25 +00:00
|
|
|
#define COS45 0.7071068
|
2008-12-19 17:14:02 +00:00
|
|
|
#define SIN45 COS45
|
|
|
|
|
|
2012-01-21 05:27:25 +00:00
|
|
|
#define NUM_SNAP_QUATS 39
|
|
|
|
|
|
|
|
|
|
static const float snapquats[NUM_SNAP_QUATS][5] = {
|
2010-07-26 19:57:44 +00:00
|
|
|
/*{q0, q1, q3, q4, view}*/
|
2012-01-21 05:27:25 +00:00
|
|
|
{COS45, -SIN45, 0.0, 0.0, RV3D_VIEW_FRONT},
|
|
|
|
|
{0.0, 0.0, -SIN45, -SIN45, RV3D_VIEW_BACK},
|
|
|
|
|
{1.0, 0.0, 0.0, 0.0, RV3D_VIEW_TOP},
|
|
|
|
|
{0.0, -1.0, 0.0, 0.0, RV3D_VIEW_BOTTOM},
|
|
|
|
|
{0.5, -0.5, -0.5, -0.5, RV3D_VIEW_RIGHT},
|
|
|
|
|
{0.5, -0.5, 0.5, 0.5, RV3D_VIEW_LEFT},
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2008-12-19 17:14:02 +00:00
|
|
|
/* some more 45 deg snaps */
|
2012-01-21 05:27:25 +00:00
|
|
|
{ 0.6532815, -0.6532815, 0.2705981, 0.2705981, 0},
|
|
|
|
|
{ 0.9238795, 0.0, 0.0, 0.3826834, 0},
|
|
|
|
|
{ 0.0, -0.9238795, 0.3826834, 0.0, 0},
|
|
|
|
|
{ 0.3535534, -0.8535534, 0.3535534, 0.1464466, 0},
|
|
|
|
|
{ 0.8535534, -0.3535534, 0.1464466, 0.3535534, 0},
|
|
|
|
|
{ 0.4999999, -0.4999999, 0.5, 0.5, 0},
|
|
|
|
|
{ 0.2705980, -0.6532815, 0.6532815, 0.2705980, 0},
|
|
|
|
|
{ 0.6532815, -0.2705980, 0.2705980, 0.6532815, 0},
|
|
|
|
|
{ 0.2705978, -0.2705980, 0.6532814, 0.6532814, 0},
|
|
|
|
|
{ 0.3826834, 0.0, 0.0, 0.9238794, 0},
|
|
|
|
|
{ 0.0, -0.3826834, 0.9238794, 0.0, 0},
|
|
|
|
|
{ 0.1464466, -0.3535534, 0.8535534, 0.3535534, 0},
|
|
|
|
|
{ 0.3535534, -0.1464466, 0.3535534, 0.8535534, 0},
|
|
|
|
|
{ 0.0, 0.0, 0.9238794, 0.3826834, 0},
|
|
|
|
|
{-0.0, 0.0, 0.3826834, 0.9238794, 0},
|
|
|
|
|
{-0.2705980, 0.2705980, 0.6532813, 0.6532813, 0},
|
|
|
|
|
{-0.3826834, 0.0, 0.0, 0.9238794, 0},
|
|
|
|
|
{ 0.0, 0.3826834, 0.9238794, 0.0, 0},
|
|
|
|
|
{-0.1464466, 0.3535534, 0.8535533, 0.3535533, 0},
|
|
|
|
|
{-0.3535534, 0.1464466, 0.3535533, 0.8535533, 0},
|
|
|
|
|
{-0.4999999, 0.4999999, 0.4999999, 0.4999999, 0},
|
|
|
|
|
{-0.2705980, 0.6532815, 0.6532814, 0.2705980, 0},
|
|
|
|
|
{-0.6532815, 0.2705980, 0.2705980, 0.6532814, 0},
|
|
|
|
|
{-0.6532813, 0.6532813, 0.2705979, 0.2705979, 0},
|
|
|
|
|
{-0.9238793, 0.0, 0.0, 0.3826833, 0},
|
|
|
|
|
{ 0.0, 0.9238793, 0.3826833, 0.0, 0},
|
|
|
|
|
{-0.3535533, 0.8535533, 0.3535533, 0.1464466, 0},
|
|
|
|
|
{-0.8535533, 0.3535533, 0.1464466, 0.3535533, 0},
|
|
|
|
|
{-0.3826833, 0.9238794, 0.0, 0.0, 0},
|
|
|
|
|
{-0.9238794, 0.3826833, 0.0, 0.0, 0},
|
|
|
|
|
{-COS45, 0.0, 0.0, SIN45, 0},
|
|
|
|
|
{ COS45, 0.0, 0.0, SIN45, 0},
|
|
|
|
|
{ 0.0, 0.0, 0.0, 1.0, 0}
|
2008-12-19 17:14:02 +00:00
|
|
|
};
|
|
|
|
|
|
2009-09-25 10:24:42 +00:00
|
|
|
enum {
|
2012-03-25 23:54:33 +00:00
|
|
|
VIEW_PASS = 0,
|
2009-09-25 10:24:42 +00:00
|
|
|
VIEW_APPLY,
|
|
|
|
|
VIEW_CONFIRM
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* NOTE: these defines are saved in keymap files, do not change values but just add new ones */
|
2012-03-25 23:54:33 +00:00
|
|
|
#define VIEW_MODAL_CONFIRM 1 /* used for all view operations */
|
|
|
|
|
#define VIEWROT_MODAL_AXIS_SNAP_ENABLE 2
|
|
|
|
|
#define VIEWROT_MODAL_AXIS_SNAP_DISABLE 3
|
|
|
|
|
#define VIEWROT_MODAL_SWITCH_ZOOM 4
|
|
|
|
|
#define VIEWROT_MODAL_SWITCH_MOVE 5
|
|
|
|
|
#define VIEWROT_MODAL_SWITCH_ROTATE 6
|
2009-09-25 10:24:42 +00:00
|
|
|
|
|
|
|
|
/* called in transform_ops.c, on each regeneration of keymaps */
|
Key Configuration
Keymaps are now saveable and configurable from the user preferences, note
that editing one item in a keymap means the whole keymap is now defined by
the user and will not be updated by Blender, an option for syncing might be
added later. The outliner interface is still there, but I will probably
remove it.
There's actually 3 levels now:
* Default builtin key configuration.
* Key configuration loaded from .py file, for configs like Blender 2.4x
or other 3D applications.
* Keymaps edited by the user and saved in .B.blend. These can be saved
to .py files as well to make creating distributable configurations
easier.
Also, user preferences sections were reorganized a bit, now there is:
Interface, Editing, Input, Files and System.
Implementation notes:
* wmKeyConfig was added which represents a key configuration containing
keymaps.
* wmKeymapItem was renamed to wmKeyMapItem for consistency with wmKeyMap.
* Modal maps are not wrapped yet.
* User preferences DNA file reading did not support newdataadr() yet,
added this now for reading keymaps.
* Key configuration related settings are now RNA wrapped.
* is_property_set and is_property_hidden python methods were added.
2009-10-08 18:40:03 +00:00
|
|
|
void viewrotate_modal_keymap(wmKeyConfig *keyconf)
|
2009-09-25 10:24:42 +00:00
|
|
|
{
|
|
|
|
|
static EnumPropertyItem modal_items[] = {
|
2012-03-25 23:54:33 +00:00
|
|
|
{VIEW_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""},
|
2009-09-25 10:24:42 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
{VIEWROT_MODAL_AXIS_SNAP_ENABLE, "AXIS_SNAP_ENABLE", 0, "Enable Axis Snap", ""},
|
|
|
|
|
{VIEWROT_MODAL_AXIS_SNAP_DISABLE, "AXIS_SNAP_DISABLE", 0, "Disable Axis Snap", ""},
|
2010-01-06 12:22:59 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
{VIEWROT_MODAL_SWITCH_ZOOM, "SWITCH_TO_ZOOM", 0, "Switch to Zoom"},
|
|
|
|
|
{VIEWROT_MODAL_SWITCH_MOVE, "SWITCH_TO_MOVE", 0, "Switch to Move"},
|
2009-09-25 10:24:42 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
{0, NULL, 0, NULL, NULL}
|
|
|
|
|
};
|
2009-09-25 10:24:42 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "View3D Rotate Modal");
|
2009-09-25 10:24:42 +00:00
|
|
|
|
|
|
|
|
/* this function is called for each spacetype, only needs to add map once */
|
2012-04-17 15:40:04 +00:00
|
|
|
if (keymap && keymap->modal_items) return;
|
2009-09-25 10:24:42 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
keymap = WM_modalkeymap_add(keyconf, "View3D Rotate Modal", modal_items);
|
2009-09-25 10:24:42 +00:00
|
|
|
|
|
|
|
|
/* items for modal map */
|
|
|
|
|
WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, KM_ANY, 0, VIEW_MODAL_CONFIRM);
|
|
|
|
|
WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, VIEW_MODAL_CONFIRM);
|
|
|
|
|
|
2010-01-06 12:22:59 +00:00
|
|
|
WM_modalkeymap_add_item(keymap, LEFTALTKEY, KM_PRESS, KM_ANY, 0, VIEWROT_MODAL_AXIS_SNAP_ENABLE);
|
|
|
|
|
WM_modalkeymap_add_item(keymap, LEFTALTKEY, KM_RELEASE, KM_ANY, 0, VIEWROT_MODAL_AXIS_SNAP_DISABLE);
|
2009-09-25 10:24:42 +00:00
|
|
|
|
2012-03-03 16:31:46 +00:00
|
|
|
/* disabled mode switching for now, can re-implement better, later on */
|
|
|
|
|
#if 0
|
2010-01-06 12:22:59 +00:00
|
|
|
WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, KM_ANY, 0, VIEWROT_MODAL_SWITCH_ZOOM);
|
|
|
|
|
WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_PRESS, KM_ANY, 0, VIEWROT_MODAL_SWITCH_ZOOM);
|
|
|
|
|
WM_modalkeymap_add_item(keymap, LEFTSHIFTKEY, KM_PRESS, KM_ANY, 0, VIEWROT_MODAL_SWITCH_MOVE);
|
2012-03-03 16:31:46 +00:00
|
|
|
#endif
|
2010-01-06 12:22:59 +00:00
|
|
|
|
2009-09-25 10:24:42 +00:00
|
|
|
/* assign map to operators */
|
|
|
|
|
WM_modalkeymap_assign(keymap, "VIEW3D_OT_rotate");
|
|
|
|
|
|
|
|
|
|
}
|
2008-12-19 17:14:02 +00:00
|
|
|
|
2009-09-25 10:24:42 +00:00
|
|
|
static void viewrotate_apply(ViewOpsData *vod, int x, int y)
|
2008-12-19 17:14:02 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
RegionView3D *rv3d = vod->rv3d;
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2013-05-26 12:02:29 +00:00
|
|
|
rv3d->view = RV3D_VIEW_USER; /* need to reset every time because of view snapping */
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2008-12-19 17:14:02 +00:00
|
|
|
if (U.flag & USER_TRACKBALL) {
|
|
|
|
|
float phi, si, q1[4], dvec[3], newvec[3];
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2008-12-19 17:14:02 +00:00
|
|
|
calctrackballvec(&vod->ar->winrct, x, y, newvec);
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2009-11-10 20:43:45 +00:00
|
|
|
sub_v3_v3v3(dvec, newvec, vod->trackvec);
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2012-01-22 17:20:37 +00:00
|
|
|
si = len_v3(dvec);
|
2011-03-27 15:57:27 +00:00
|
|
|
si /= (float)(2.0 * TRACKBALLSIZE);
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
cross_v3_v3v3(q1 + 1, vod->trackvec, newvec);
|
|
|
|
|
normalize_v3(q1 + 1);
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2012-03-03 16:31:46 +00:00
|
|
|
/* Allow for rotation beyond the interval [-pi, pi] */
|
2011-03-27 15:57:27 +00:00
|
|
|
while (si > 1.0f)
|
|
|
|
|
si -= 2.0f;
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2008-12-19 17:14:02 +00:00
|
|
|
/* This relation is used instead of
|
2012-03-03 11:45:08 +00:00
|
|
|
* - phi = asin(si) so that the angle
|
|
|
|
|
* - of rotation is linearly proportional
|
|
|
|
|
* - to the distance that the mouse is
|
|
|
|
|
* - dragged. */
|
2011-03-27 15:57:27 +00:00
|
|
|
phi = si * (float)(M_PI / 2.0);
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
q1[0] = cos(phi);
|
|
|
|
|
mul_v3_fl(q1 + 1, sin(phi));
|
2011-11-11 05:34:07 +00:00
|
|
|
mul_qt_qtqt(vod->viewquat, q1, vod->oldquat);
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2009-12-09 00:45:50 +00:00
|
|
|
if (vod->use_dyn_ofs) {
|
2008-12-19 17:14:02 +00:00
|
|
|
/* compute the post multiplication quat, to rotate the offset correctly */
|
2012-08-25 17:42:15 +00:00
|
|
|
conjugate_qt_qt(q1, vod->oldquat);
|
2011-11-11 05:34:07 +00:00
|
|
|
mul_qt_qtqt(q1, q1, vod->viewquat);
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2009-11-10 20:43:45 +00:00
|
|
|
conjugate_qt(q1); /* conj == inv for unit quat */
|
2010-07-26 06:34:56 +00:00
|
|
|
copy_v3_v3(rv3d->ofs, vod->ofs);
|
2010-04-23 23:57:00 +00:00
|
|
|
sub_v3_v3(rv3d->ofs, vod->dyn_ofs);
|
2009-11-10 20:43:45 +00:00
|
|
|
mul_qt_v3(q1, rv3d->ofs);
|
2010-04-21 12:27:48 +00:00
|
|
|
add_v3_v3(rv3d->ofs, vod->dyn_ofs);
|
2008-12-19 17:14:02 +00:00
|
|
|
}
|
2008-12-26 10:31:44 +00:00
|
|
|
}
|
2008-12-19 17:14:02 +00:00
|
|
|
else {
|
|
|
|
|
/* New turntable view code by John Aughey */
|
2012-04-13 13:55:55 +00:00
|
|
|
float q1[4];
|
2008-12-19 17:14:02 +00:00
|
|
|
float m[3][3];
|
|
|
|
|
float m_inv[3][3];
|
2012-04-13 13:55:55 +00:00
|
|
|
const float zvec_global[3] = {0.0f, 0.0f, 1.0f};
|
2012-04-13 15:15:13 +00:00
|
|
|
float xaxis[3];
|
|
|
|
|
|
2012-04-13 13:55:55 +00:00
|
|
|
/* Sensitivity will control how fast the viewport rotates. 0.007 was
|
2012-03-03 11:45:08 +00:00
|
|
|
* obtained experimentally by looking at viewport rotation sensitivities
|
|
|
|
|
* on other modeling programs. */
|
2008-12-19 17:14:02 +00:00
|
|
|
/* Perhaps this should be a configurable user parameter. */
|
2012-04-13 13:55:55 +00:00
|
|
|
const float sensitivity = 0.007f;
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2008-12-19 17:14:02 +00:00
|
|
|
/* Get the 3x3 matrix and its inverse from the quaternion */
|
2012-03-25 23:54:33 +00:00
|
|
|
quat_to_mat3(m, vod->viewquat);
|
|
|
|
|
invert_m3_m3(m_inv, m);
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2012-04-13 15:15:13 +00:00
|
|
|
/* avoid gimble lock */
|
|
|
|
|
#if 1
|
|
|
|
|
if (len_squared_v3v3(zvec_global, m_inv[2]) > 0.001f) {
|
|
|
|
|
float fac;
|
|
|
|
|
cross_v3_v3v3(xaxis, zvec_global, m_inv[2]);
|
|
|
|
|
if (dot_v3v3(xaxis, m_inv[0]) < 0) {
|
|
|
|
|
negate_v3(xaxis);
|
|
|
|
|
}
|
2012-05-03 21:35:04 +00:00
|
|
|
fac = angle_normalized_v3v3(zvec_global, m_inv[2]) / (float)M_PI;
|
2012-04-13 15:15:13 +00:00
|
|
|
fac = fabsf(fac - 0.5f) * 2;
|
|
|
|
|
fac = fac * fac;
|
|
|
|
|
interp_v3_v3v3(xaxis, xaxis, m_inv[0], fac);
|
|
|
|
|
}
|
2012-04-28 06:31:57 +00:00
|
|
|
else {
|
2012-04-13 15:15:13 +00:00
|
|
|
copy_v3_v3(xaxis, m_inv[0]);
|
|
|
|
|
}
|
2012-04-28 06:31:57 +00:00
|
|
|
#else
|
|
|
|
|
copy_v3_v3(xaxis, m_inv[0]);
|
|
|
|
|
#endif
|
2012-04-13 15:15:13 +00:00
|
|
|
|
2008-12-19 17:14:02 +00:00
|
|
|
/* Determine the direction of the x vector (for rotating up and down) */
|
2010-01-11 11:14:36 +00:00
|
|
|
/* This can likely be computed directly from the quaternion. */
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2008-12-19 17:14:02 +00:00
|
|
|
/* Perform the up/down rotation */
|
2012-04-13 15:15:13 +00:00
|
|
|
axis_angle_to_quat(q1, xaxis, sensitivity * -(y - vod->oldy));
|
2011-11-11 05:34:07 +00:00
|
|
|
mul_qt_qtqt(vod->viewquat, vod->viewquat, q1);
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2009-12-09 00:45:50 +00:00
|
|
|
if (vod->use_dyn_ofs) {
|
2009-11-10 20:43:45 +00:00
|
|
|
conjugate_qt(q1); /* conj == inv for unit quat */
|
2010-04-23 23:57:00 +00:00
|
|
|
sub_v3_v3(rv3d->ofs, vod->dyn_ofs);
|
2009-11-10 20:43:45 +00:00
|
|
|
mul_qt_v3(q1, rv3d->ofs);
|
2010-04-21 12:27:48 +00:00
|
|
|
add_v3_v3(rv3d->ofs, vod->dyn_ofs);
|
2008-12-19 17:14:02 +00:00
|
|
|
}
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2008-12-19 17:14:02 +00:00
|
|
|
/* Perform the orbital rotation */
|
2014-02-01 21:32:34 +11:00
|
|
|
axis_angle_normalized_to_quat(q1, zvec_global, sensitivity * vod->reverse * (x - vod->oldx));
|
2011-11-11 05:34:07 +00:00
|
|
|
mul_qt_qtqt(vod->viewquat, vod->viewquat, q1);
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2009-12-09 00:45:50 +00:00
|
|
|
if (vod->use_dyn_ofs) {
|
2009-11-10 20:43:45 +00:00
|
|
|
conjugate_qt(q1);
|
2010-04-23 23:57:00 +00:00
|
|
|
sub_v3_v3(rv3d->ofs, vod->dyn_ofs);
|
2009-11-10 20:43:45 +00:00
|
|
|
mul_qt_v3(q1, rv3d->ofs);
|
2010-04-21 12:27:48 +00:00
|
|
|
add_v3_v3(rv3d->ofs, vod->dyn_ofs);
|
2008-12-19 17:14:02 +00:00
|
|
|
}
|
2008-12-19 12:14:58 +00:00
|
|
|
}
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2008-12-19 17:14:02 +00:00
|
|
|
/* check for view snap */
|
2012-02-22 16:52:06 +00:00
|
|
|
if (vod->axis_snap) {
|
2008-12-19 17:14:02 +00:00
|
|
|
int i;
|
2010-07-26 00:11:14 +00:00
|
|
|
float viewquat_inv[4];
|
2012-03-25 23:54:33 +00:00
|
|
|
float zaxis[3] = {0, 0, 1};
|
2011-11-11 05:34:07 +00:00
|
|
|
invert_qt_qt(viewquat_inv, vod->viewquat);
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2010-07-26 00:11:14 +00:00
|
|
|
mul_qt_v3(viewquat_inv, zaxis);
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
for (i = 0; i < NUM_SNAP_QUATS; i++) {
|
2010-07-26 00:11:14 +00:00
|
|
|
|
2008-12-19 17:14:02 +00:00
|
|
|
float view = (int)snapquats[i][4];
|
2010-07-26 00:11:14 +00:00
|
|
|
float viewquat_inv_test[4];
|
2012-03-25 23:54:33 +00:00
|
|
|
float zaxis_test[3] = {0, 0, 1};
|
2010-07-26 00:11:14 +00:00
|
|
|
|
|
|
|
|
invert_qt_qt(viewquat_inv_test, snapquats[i]);
|
|
|
|
|
mul_qt_v3(viewquat_inv_test, zaxis_test);
|
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
if (angle_v3v3(zaxis_test, zaxis) < DEG2RADF(45 / 3)) {
|
2010-07-26 00:11:14 +00:00
|
|
|
/* find the best roll */
|
|
|
|
|
float quat_roll[4], quat_final[4], quat_best[4];
|
|
|
|
|
float viewquat_align[4]; /* viewquat aligned to zaxis_test */
|
|
|
|
|
float viewquat_align_inv[4]; /* viewquat aligned to zaxis_test */
|
|
|
|
|
float best_angle = FLT_MAX;
|
|
|
|
|
int j;
|
|
|
|
|
|
|
|
|
|
/* viewquat_align is the original viewquat aligned to the snapped axis
|
|
|
|
|
* for testing roll */
|
|
|
|
|
rotation_between_vecs_to_quat(viewquat_align, zaxis_test, zaxis);
|
|
|
|
|
normalize_qt(viewquat_align);
|
2011-11-11 05:34:07 +00:00
|
|
|
mul_qt_qtqt(viewquat_align, vod->viewquat, viewquat_align);
|
2010-07-26 00:11:14 +00:00
|
|
|
normalize_qt(viewquat_align);
|
|
|
|
|
invert_qt_qt(viewquat_align_inv, viewquat_align);
|
|
|
|
|
|
|
|
|
|
/* find best roll */
|
2012-03-25 23:54:33 +00:00
|
|
|
for (j = 0; j < 8; j++) {
|
2010-07-26 00:11:14 +00:00
|
|
|
float angle;
|
2012-03-25 23:54:33 +00:00
|
|
|
float xaxis1[3] = {1, 0, 0};
|
|
|
|
|
float xaxis2[3] = {1, 0, 0};
|
2010-07-26 00:11:14 +00:00
|
|
|
float quat_final_inv[4];
|
|
|
|
|
|
2011-03-27 15:57:27 +00:00
|
|
|
axis_angle_to_quat(quat_roll, zaxis_test, (float)j * DEG2RADF(45.0f));
|
2010-07-26 00:11:14 +00:00
|
|
|
normalize_qt(quat_roll);
|
|
|
|
|
|
|
|
|
|
mul_qt_qtqt(quat_final, snapquats[i], quat_roll);
|
|
|
|
|
normalize_qt(quat_final);
|
|
|
|
|
|
|
|
|
|
/* compare 2 vector angles to find the least roll */
|
|
|
|
|
invert_qt_qt(quat_final_inv, quat_final);
|
|
|
|
|
mul_qt_v3(viewquat_align_inv, xaxis1);
|
|
|
|
|
mul_qt_v3(quat_final_inv, xaxis2);
|
2012-03-25 23:54:33 +00:00
|
|
|
angle = angle_v3v3(xaxis1, xaxis2);
|
2010-07-26 00:11:14 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (angle <= best_angle) {
|
2012-03-25 23:54:33 +00:00
|
|
|
best_angle = angle;
|
2010-07-26 00:11:14 +00:00
|
|
|
copy_qt_qt(quat_best, quat_final);
|
2012-03-25 23:54:33 +00:00
|
|
|
if (j) view = 0; /* view grid assumes certain up axis */
|
2010-07-26 00:11:14 +00:00
|
|
|
}
|
|
|
|
|
}
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2011-11-11 05:34:07 +00:00
|
|
|
copy_qt_qt(vod->viewquat, quat_best);
|
2012-03-25 23:54:33 +00:00
|
|
|
rv3d->view = view; /* if we snap to a rolled camera the grid is invalid */
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2008-12-19 17:14:02 +00:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2008-12-19 12:14:58 +00:00
|
|
|
}
|
2012-03-25 23:54:33 +00:00
|
|
|
vod->oldx = x;
|
|
|
|
|
vod->oldy = y;
|
2008-12-19 17:14:02 +00:00
|
|
|
|
2011-01-21 02:32:58 +00:00
|
|
|
/* avoid precision loss over time */
|
2011-11-11 05:34:07 +00:00
|
|
|
normalize_qt(vod->viewquat);
|
|
|
|
|
|
|
|
|
|
/* use a working copy so view rotation locking doesnt overwrite the locked
|
|
|
|
|
* rotation back into the view we calculate with */
|
|
|
|
|
copy_qt_qt(rv3d->viewquat, vod->viewquat);
|
2010-12-22 02:28:06 +00:00
|
|
|
|
2011-05-14 17:50:33 +00:00
|
|
|
ED_view3d_camera_lock_sync(vod->v3d, rv3d);
|
|
|
|
|
|
2008-12-19 17:14:02 +00:00
|
|
|
ED_region_tag_redraw(vod->ar);
|
|
|
|
|
}
|
|
|
|
|
|
2013-03-13 09:03:46 +00:00
|
|
|
static int viewrotate_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
2008-12-19 17:14:02 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
ViewOpsData *vod = op->customdata;
|
|
|
|
|
short event_code = VIEW_PASS;
|
2008-12-19 17:14:02 +00:00
|
|
|
|
|
|
|
|
/* execute the events */
|
2012-03-25 23:54:33 +00:00
|
|
|
if (event->type == MOUSEMOVE) {
|
|
|
|
|
event_code = VIEW_APPLY;
|
2009-09-25 10:24:42 +00:00
|
|
|
}
|
2012-03-25 23:54:33 +00:00
|
|
|
else if (event->type == EVT_MODAL_MAP) {
|
2009-09-25 10:24:42 +00:00
|
|
|
switch (event->val) {
|
|
|
|
|
case VIEW_MODAL_CONFIRM:
|
2012-03-25 23:54:33 +00:00
|
|
|
event_code = VIEW_CONFIRM;
|
2009-09-25 10:24:42 +00:00
|
|
|
break;
|
|
|
|
|
case VIEWROT_MODAL_AXIS_SNAP_ENABLE:
|
2013-03-20 23:14:18 +00:00
|
|
|
vod->axis_snap = true;
|
2012-03-25 23:54:33 +00:00
|
|
|
event_code = VIEW_APPLY;
|
2009-09-25 10:24:42 +00:00
|
|
|
break;
|
|
|
|
|
case VIEWROT_MODAL_AXIS_SNAP_DISABLE:
|
2013-03-20 23:14:18 +00:00
|
|
|
vod->axis_snap = false;
|
2012-03-25 23:54:33 +00:00
|
|
|
event_code = VIEW_APPLY;
|
2009-09-25 10:24:42 +00:00
|
|
|
break;
|
2010-01-06 12:22:59 +00:00
|
|
|
case VIEWROT_MODAL_SWITCH_ZOOM:
|
|
|
|
|
WM_operator_name_call(C, "VIEW3D_OT_zoom", WM_OP_INVOKE_DEFAULT, NULL);
|
2012-03-25 23:54:33 +00:00
|
|
|
event_code = VIEW_CONFIRM;
|
2010-01-06 12:22:59 +00:00
|
|
|
break;
|
|
|
|
|
case VIEWROT_MODAL_SWITCH_MOVE:
|
|
|
|
|
WM_operator_name_call(C, "VIEW3D_OT_move", WM_OP_INVOKE_DEFAULT, NULL);
|
2012-03-25 23:54:33 +00:00
|
|
|
event_code = VIEW_CONFIRM;
|
2010-01-06 12:22:59 +00:00
|
|
|
break;
|
2009-09-25 10:24:42 +00:00
|
|
|
}
|
|
|
|
|
}
|
2012-03-25 23:54:33 +00:00
|
|
|
else if (event->type == vod->origkey && event->val == KM_RELEASE) {
|
|
|
|
|
event_code = VIEW_CONFIRM;
|
2009-09-25 10:24:42 +00:00
|
|
|
}
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
if (event_code == VIEW_APPLY) {
|
2009-09-25 10:24:42 +00:00
|
|
|
viewrotate_apply(vod, event->x, event->y);
|
|
|
|
|
}
|
2012-03-25 23:54:33 +00:00
|
|
|
else if (event_code == VIEW_CONFIRM) {
|
2011-05-21 08:56:37 +00:00
|
|
|
ED_view3d_depth_tag_update(vod->rv3d);
|
2009-11-25 14:13:43 +00:00
|
|
|
viewops_data_free(C, op);
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2009-09-25 10:24:42 +00:00
|
|
|
return OPERATOR_FINISHED;
|
2008-12-19 12:14:58 +00:00
|
|
|
}
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2008-12-19 17:14:02 +00:00
|
|
|
return OPERATOR_RUNNING_MODAL;
|
2008-12-19 12:14:58 +00:00
|
|
|
}
|
|
|
|
|
|
2014-02-14 17:42:21 +11:00
|
|
|
/**
|
|
|
|
|
* Action to take when rotating the view,
|
|
|
|
|
* handle auto-persp and logic for switching out of views.
|
|
|
|
|
*
|
|
|
|
|
* shared with NDOF.
|
|
|
|
|
*/
|
|
|
|
|
static void view3d_ensure_persp(struct View3D *v3d, ARegion *ar)
|
|
|
|
|
{
|
|
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
|
|
|
|
|
|
|
|
|
BLI_assert((rv3d->viewlock & RV3D_LOCKED) == 0);
|
|
|
|
|
|
2014-02-24 15:15:17 +11:00
|
|
|
if (ED_view3d_camera_lock_check(v3d, rv3d))
|
|
|
|
|
return;
|
|
|
|
|
|
2014-02-14 17:42:21 +11:00
|
|
|
if (rv3d->persp != RV3D_PERSP) {
|
|
|
|
|
if (rv3d->persp == RV3D_CAMOB) {
|
|
|
|
|
view3d_persp_switch_from_camera(v3d, rv3d, rv3d->lpersp);
|
|
|
|
|
}
|
|
|
|
|
else if ((U.uiflag & USER_AUTOPERSP) && RV3D_VIEW_IS_AXIS(rv3d->view)) {
|
2014-02-24 15:15:17 +11:00
|
|
|
rv3d->persp = RV3D_PERSP;
|
2014-02-14 17:42:21 +11:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-03-13 09:03:46 +00:00
|
|
|
static int viewrotate_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
2008-12-19 12:14:58 +00:00
|
|
|
{
|
2008-12-19 17:14:02 +00:00
|
|
|
ViewOpsData *vod;
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2008-12-19 17:14:02 +00:00
|
|
|
/* makes op->customdata */
|
2013-09-20 01:24:00 +00:00
|
|
|
viewops_data_alloc(C, op);
|
2009-11-25 14:13:43 +00:00
|
|
|
viewops_data_create(C, op, event);
|
2012-03-25 23:54:33 +00:00
|
|
|
vod = op->customdata;
|
2010-11-16 09:35:58 +00:00
|
|
|
|
2014-02-04 19:45:22 +11:00
|
|
|
/* poll should check but in some cases fails, see poll func for details */
|
2014-02-12 11:26:02 +11:00
|
|
|
if (vod->rv3d->viewlock & RV3D_LOCKED) {
|
2010-11-16 09:35:58 +00:00
|
|
|
viewops_data_free(C, op);
|
2011-02-05 19:07:54 +00:00
|
|
|
return OPERATOR_PASS_THROUGH;
|
2010-11-16 09:35:58 +00:00
|
|
|
}
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2008-12-19 17:14:02 +00:00
|
|
|
/* switch from camera view when: */
|
2014-02-14 17:42:21 +11:00
|
|
|
view3d_ensure_persp(vod->v3d, vod->ar);
|
2010-01-11 11:14:36 +00:00
|
|
|
|
|
|
|
|
if (event->type == MOUSEPAN) {
|
2013-02-08 12:12:57 +00:00
|
|
|
/* Rotate direction we keep always same */
|
|
|
|
|
if (U.uiflag2 & USER_TRACKPAD_NATURAL)
|
|
|
|
|
viewrotate_apply(vod, 2 * event->x - event->prevx, 2 * event->y - event->prevy);
|
|
|
|
|
else
|
|
|
|
|
viewrotate_apply(vod, event->prevx, event->prevy);
|
|
|
|
|
|
2013-09-20 01:24:00 +00:00
|
|
|
ED_view3d_depth_tag_update(vod->rv3d);
|
2010-01-11 11:14:36 +00:00
|
|
|
|
|
|
|
|
viewops_data_free(C, op);
|
|
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
else if (event->type == MOUSEROTATE) {
|
|
|
|
|
/* MOUSEROTATE performs orbital rotation, so y axis delta is set to 0 */
|
|
|
|
|
viewrotate_apply(vod, event->prevx, event->y);
|
2013-09-20 01:24:00 +00:00
|
|
|
ED_view3d_depth_tag_update(vod->rv3d);
|
2010-01-11 11:14:36 +00:00
|
|
|
|
|
|
|
|
viewops_data_free(C, op);
|
|
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
2012-10-21 05:46:41 +00:00
|
|
|
else {
|
2010-01-11 11:14:36 +00:00
|
|
|
/* add temp handler */
|
|
|
|
|
WM_event_add_modal_handler(C, op);
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2010-01-11 11:14:36 +00:00
|
|
|
return OPERATOR_RUNNING_MODAL;
|
|
|
|
|
}
|
2008-12-19 17:14:02 +00:00
|
|
|
}
|
|
|
|
|
|
2012-01-16 06:57:37 +00:00
|
|
|
/* test for unlocked camera view in quad view */
|
|
|
|
|
static int view3d_camera_user_poll(bContext *C)
|
|
|
|
|
{
|
|
|
|
|
View3D *v3d;
|
|
|
|
|
ARegion *ar;
|
|
|
|
|
|
|
|
|
|
if (ED_view3d_context_user_region(C, &v3d, &ar)) {
|
|
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
2012-03-25 23:54:33 +00:00
|
|
|
if (rv3d->persp == RV3D_CAMOB) {
|
2012-01-16 06:57:37 +00:00
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2013-07-19 10:54:02 +00:00
|
|
|
static int view3d_lock_poll(bContext *C)
|
|
|
|
|
{
|
|
|
|
|
View3D *v3d = CTX_wm_view3d(C);
|
2013-09-15 01:46:25 +00:00
|
|
|
if (v3d) {
|
|
|
|
|
RegionView3D *rv3d = CTX_wm_region_view3d(C);
|
|
|
|
|
if (rv3d) {
|
|
|
|
|
return ED_view3d_offset_lock_check(v3d, rv3d);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false;
|
2013-07-19 10:54:02 +00:00
|
|
|
}
|
|
|
|
|
|
2013-10-30 23:08:53 +00:00
|
|
|
static void viewrotate_cancel(bContext *C, wmOperator *op)
|
2011-06-06 11:04:54 +00:00
|
|
|
{
|
|
|
|
|
viewops_data_free(C, op);
|
|
|
|
|
}
|
|
|
|
|
|
2009-09-25 10:24:42 +00:00
|
|
|
void VIEW3D_OT_rotate(wmOperatorType *ot)
|
2008-12-19 17:14:02 +00:00
|
|
|
{
|
|
|
|
|
/* identifiers */
|
2013-01-27 07:23:58 +00:00
|
|
|
ot->name = "Rotate View";
|
2010-02-10 21:15:44 +00:00
|
|
|
ot->description = "Rotate the view";
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->idname = "VIEW3D_OT_rotate";
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2008-12-19 17:14:02 +00:00
|
|
|
/* api callbacks */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->invoke = viewrotate_invoke;
|
|
|
|
|
ot->modal = viewrotate_modal;
|
|
|
|
|
ot->poll = ED_operator_region_view3d_active;
|
|
|
|
|
ot->cancel = viewrotate_cancel;
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2009-01-31 19:40:40 +00:00
|
|
|
/* flags */
|
2012-03-25 23:54:33 +00:00
|
|
|
ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_POINTER;
|
2008-12-19 17:14:02 +00:00
|
|
|
}
|
|
|
|
|
|
2014-02-24 12:36:57 +11:00
|
|
|
/** \name NDOF Utility Functions
|
|
|
|
|
* \{ */
|
2014-02-14 17:42:21 +11:00
|
|
|
|
2014-02-19 21:19:13 +11:00
|
|
|
#define NDOF_HAS_TRANSLATE ((!ED_view3d_offset_lock_check(v3d, rv3d)) && !is_zero_v3(ndof->tvec))
|
2014-02-14 17:42:21 +11:00
|
|
|
#define NDOF_HAS_ROTATE (((rv3d->viewlock & RV3D_LOCKED) == 0) && !is_zero_v3(ndof->rvec))
|
|
|
|
|
|
2014-02-22 16:19:02 +11:00
|
|
|
static float view3d_ndof_pan_speed_calc(RegionView3D *rv3d)
|
|
|
|
|
{
|
|
|
|
|
float speed = rv3d->pixsize * NDOF_PIXELS_PER_SECOND;
|
|
|
|
|
|
|
|
|
|
if (rv3d->is_persp) {
|
2014-02-24 12:36:57 +11:00
|
|
|
float tvec[3];
|
|
|
|
|
negate_v3_v3(tvec, rv3d->ofs);
|
|
|
|
|
speed *= ED_view3d_calc_zfac(rv3d, tvec, NULL);
|
2014-02-22 16:19:02 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return speed;
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-14 18:38:23 +11:00
|
|
|
/**
|
|
|
|
|
* Zoom and pan in the same function since sometimes zoom is interpreted as dolly (pan forward).
|
|
|
|
|
*
|
|
|
|
|
* \param has_zoom zoom, otherwise dolly, often `!rv3d->is_persp` since it doesnt make sense to dolly in ortho.
|
|
|
|
|
*/
|
|
|
|
|
static void view3d_ndof_pan_zoom(const struct wmNDOFMotionData *ndof, ScrArea *sa, ARegion *ar,
|
|
|
|
|
const bool has_translate, const bool has_zoom)
|
2014-02-12 20:09:36 +11:00
|
|
|
{
|
|
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
2014-02-14 18:38:23 +11:00
|
|
|
float view_inv[4];
|
2014-02-12 20:09:36 +11:00
|
|
|
float pan_vec[3];
|
|
|
|
|
|
2014-02-14 18:38:23 +11:00
|
|
|
if (has_translate == false && has_zoom == false) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2014-02-14 17:42:21 +11:00
|
|
|
|
2014-02-18 23:51:11 +11:00
|
|
|
WM_event_ndof_pan_get(ndof, pan_vec, false);
|
2014-02-12 20:09:36 +11:00
|
|
|
|
2014-02-14 18:38:23 +11:00
|
|
|
if (has_zoom) {
|
|
|
|
|
/* zoom with Z */
|
2014-02-12 20:09:36 +11:00
|
|
|
|
2014-02-14 18:38:23 +11:00
|
|
|
/* Zoom!
|
|
|
|
|
* velocity should be proportional to the linear velocity attained by rotational motion of same strength
|
|
|
|
|
* [got that?]
|
|
|
|
|
* proportional to arclength = radius * angle
|
|
|
|
|
*/
|
2014-02-12 20:09:36 +11:00
|
|
|
|
2014-02-14 18:38:23 +11:00
|
|
|
pan_vec[2] = 0.0f;
|
2014-02-12 20:09:36 +11:00
|
|
|
|
2014-02-14 18:38:23 +11:00
|
|
|
/* "zoom in" or "translate"? depends on zoom mode in user settings? */
|
2014-02-18 23:51:11 +11:00
|
|
|
if (ndof->tvec[2]) {
|
2014-02-22 16:19:02 +11:00
|
|
|
float zoom_distance = rv3d->dist * ndof->dt * ndof->tvec[2];
|
2014-02-14 18:38:23 +11:00
|
|
|
|
|
|
|
|
if (U.ndof_flag & NDOF_ZOOM_INVERT)
|
|
|
|
|
zoom_distance = -zoom_distance;
|
|
|
|
|
|
|
|
|
|
rv3d->dist += zoom_distance;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* dolly with Z */
|
|
|
|
|
|
|
|
|
|
/* all callers must check */
|
|
|
|
|
if (has_translate) {
|
|
|
|
|
BLI_assert(ED_view3d_offset_lock_check((View3D *)sa->spacedata.first, rv3d) == false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (has_translate) {
|
2014-02-22 16:19:02 +11:00
|
|
|
const float speed = view3d_ndof_pan_speed_calc(rv3d);
|
2014-02-14 18:38:23 +11:00
|
|
|
|
2014-02-22 16:19:02 +11:00
|
|
|
mul_v3_fl(pan_vec, speed * ndof->dt);
|
2014-02-14 18:38:23 +11:00
|
|
|
|
|
|
|
|
/* transform motion from view to world coordinates */
|
|
|
|
|
invert_qt_qt(view_inv, rv3d->viewquat);
|
|
|
|
|
mul_qt_v3(view_inv, pan_vec);
|
|
|
|
|
|
|
|
|
|
/* move center of view opposite of hand motion (this is camera mode, not object mode) */
|
|
|
|
|
sub_v3_v3(rv3d->ofs, pan_vec);
|
|
|
|
|
|
|
|
|
|
if (rv3d->viewlock & RV3D_BOXVIEW) {
|
|
|
|
|
view3d_boxview_sync(sa, ar);
|
|
|
|
|
}
|
2014-02-12 20:09:36 +11:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2014-02-20 10:00:16 +11:00
|
|
|
static void view3d_ndof_orbit(const struct wmNDOFMotionData *ndof, ScrArea *sa, ARegion *ar,
|
2013-03-03 04:54:33 +00:00
|
|
|
/* optional, can be NULL*/
|
|
|
|
|
ViewOpsData *vod)
|
|
|
|
|
{
|
2014-02-20 10:00:16 +11:00
|
|
|
View3D *v3d = sa->spacedata.first;
|
|
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
|
|
|
|
|
2014-02-12 20:09:36 +11:00
|
|
|
float view_inv[4];
|
|
|
|
|
|
2014-02-14 17:42:21 +11:00
|
|
|
BLI_assert((rv3d->viewlock & RV3D_LOCKED) == 0);
|
|
|
|
|
|
2014-02-20 10:00:16 +11:00
|
|
|
view3d_ensure_persp(v3d, ar);
|
2014-02-14 17:42:21 +11:00
|
|
|
|
|
|
|
|
rv3d->view = RV3D_VIEW_USER;
|
|
|
|
|
|
2014-02-12 20:09:36 +11:00
|
|
|
invert_qt_qt(view_inv, rv3d->viewquat);
|
|
|
|
|
|
2013-03-03 04:54:33 +00:00
|
|
|
if (U.ndof_flag & NDOF_TURNTABLE) {
|
2014-02-18 23:51:11 +11:00
|
|
|
float rot[3];
|
2013-03-03 04:54:33 +00:00
|
|
|
|
|
|
|
|
/* turntable view code by John Aughey, adapted for 3D mouse by [mce] */
|
2014-02-18 23:51:11 +11:00
|
|
|
float angle, quat[4];
|
2013-03-03 04:54:33 +00:00
|
|
|
float xvec[3] = {1, 0, 0};
|
|
|
|
|
|
2014-02-18 23:51:11 +11:00
|
|
|
/* only use XY, ignore Z */
|
|
|
|
|
WM_event_ndof_rotate_get(ndof, rot);
|
|
|
|
|
|
2013-03-03 04:54:33 +00:00
|
|
|
/* Determine the direction of the x vector (for rotating up and down) */
|
|
|
|
|
mul_qt_v3(view_inv, xvec);
|
|
|
|
|
|
|
|
|
|
/* Perform the up/down rotation */
|
2014-02-20 10:00:16 +11:00
|
|
|
angle = ndof->dt * rot[0];
|
2014-02-18 23:51:11 +11:00
|
|
|
quat[0] = cosf(angle);
|
|
|
|
|
mul_v3_v3fl(quat + 1, xvec, sin(angle));
|
|
|
|
|
mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, quat);
|
2013-03-03 04:54:33 +00:00
|
|
|
|
|
|
|
|
/* Perform the orbital rotation */
|
2014-02-20 10:00:16 +11:00
|
|
|
angle = ndof->dt * rot[1];
|
2013-03-03 04:54:33 +00:00
|
|
|
|
|
|
|
|
/* update the onscreen doo-dad */
|
|
|
|
|
rv3d->rot_angle = angle;
|
|
|
|
|
rv3d->rot_axis[0] = 0;
|
|
|
|
|
rv3d->rot_axis[1] = 0;
|
|
|
|
|
rv3d->rot_axis[2] = 1;
|
|
|
|
|
|
2014-02-18 23:51:11 +11:00
|
|
|
quat[0] = cosf(angle);
|
|
|
|
|
quat[1] = 0.0f;
|
|
|
|
|
quat[2] = 0.0f;
|
|
|
|
|
quat[3] = sinf(angle);
|
|
|
|
|
mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, quat);
|
2013-03-03 04:54:33 +00:00
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else {
|
2014-02-18 23:51:11 +11:00
|
|
|
float quat[4];
|
2013-03-03 04:54:33 +00:00
|
|
|
float axis[3];
|
2014-02-18 23:51:11 +11:00
|
|
|
float angle = WM_event_ndof_to_axis_angle(ndof, axis);
|
2013-03-03 04:54:33 +00:00
|
|
|
|
|
|
|
|
/* transform rotation axis from view to world coordinates */
|
|
|
|
|
mul_qt_v3(view_inv, axis);
|
|
|
|
|
|
|
|
|
|
/* update the onscreen doo-dad */
|
|
|
|
|
rv3d->rot_angle = angle;
|
|
|
|
|
copy_v3_v3(rv3d->rot_axis, axis);
|
|
|
|
|
|
2014-02-18 23:51:11 +11:00
|
|
|
axis_angle_to_quat(quat, axis, angle);
|
2013-03-03 04:54:33 +00:00
|
|
|
|
|
|
|
|
/* apply rotation */
|
2014-02-18 23:51:11 +11:00
|
|
|
mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, quat);
|
2013-03-03 04:54:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* rotate around custom center */
|
|
|
|
|
if (vod && vod->use_dyn_ofs) {
|
|
|
|
|
float q1[4];
|
|
|
|
|
|
|
|
|
|
/* compute the post multiplication quat, to rotate the offset correctly */
|
|
|
|
|
conjugate_qt_qt(q1, vod->oldquat);
|
|
|
|
|
mul_qt_qtqt(q1, q1, rv3d->viewquat);
|
|
|
|
|
|
|
|
|
|
conjugate_qt(q1); /* conj == inv for unit quat */
|
|
|
|
|
copy_v3_v3(rv3d->ofs, vod->ofs);
|
|
|
|
|
sub_v3_v3(rv3d->ofs, vod->dyn_ofs);
|
|
|
|
|
mul_qt_v3(q1, rv3d->ofs);
|
|
|
|
|
add_v3_v3(rv3d->ofs, vod->dyn_ofs);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-19 21:19:13 +11:00
|
|
|
/**
|
|
|
|
|
* Called from both fly mode and walk mode,
|
|
|
|
|
*/
|
|
|
|
|
void view3d_ndof_fly(
|
|
|
|
|
const wmNDOFMotionData *ndof,
|
|
|
|
|
View3D *v3d, RegionView3D *rv3d,
|
|
|
|
|
const bool use_precision, const short protectflag,
|
|
|
|
|
bool *r_has_translate, bool *r_has_rotate)
|
|
|
|
|
{
|
|
|
|
|
bool has_translate = NDOF_HAS_TRANSLATE;
|
|
|
|
|
bool has_rotate = NDOF_HAS_ROTATE;
|
|
|
|
|
|
|
|
|
|
float view_inv[4];
|
|
|
|
|
invert_qt_qt(view_inv, rv3d->viewquat);
|
|
|
|
|
|
|
|
|
|
rv3d->rot_angle = 0.0f; /* disable onscreen rotation doo-dad */
|
|
|
|
|
|
|
|
|
|
if (has_translate) {
|
2014-02-22 16:19:02 +11:00
|
|
|
float speed = view3d_ndof_pan_speed_calc(rv3d);
|
2014-02-19 21:19:13 +11:00
|
|
|
float trans[3], trans_orig_y;
|
2014-02-22 16:19:02 +11:00
|
|
|
|
2014-02-19 21:19:13 +11:00
|
|
|
if (use_precision)
|
|
|
|
|
speed *= 0.2f;
|
|
|
|
|
|
|
|
|
|
WM_event_ndof_pan_get(ndof, trans, false);
|
2014-02-22 16:19:02 +11:00
|
|
|
mul_v3_fl(trans, speed * ndof->dt);
|
2014-02-19 21:19:13 +11:00
|
|
|
trans_orig_y = trans[1];
|
|
|
|
|
|
2014-02-19 21:30:57 +11:00
|
|
|
if (U.ndof_flag & NDOF_FLY_HELICOPTER) {
|
|
|
|
|
trans[1] = 0.0f;
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-19 21:19:13 +11:00
|
|
|
/* transform motion from view to world coordinates */
|
|
|
|
|
mul_qt_v3(view_inv, trans);
|
|
|
|
|
|
|
|
|
|
if (U.ndof_flag & NDOF_FLY_HELICOPTER) {
|
|
|
|
|
/* replace world z component with device y (yes it makes sense) */
|
|
|
|
|
trans[2] = trans_orig_y;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (rv3d->persp == RV3D_CAMOB) {
|
|
|
|
|
/* respect camera position locks */
|
|
|
|
|
if (protectflag & OB_LOCK_LOCX) trans[0] = 0.0f;
|
|
|
|
|
if (protectflag & OB_LOCK_LOCY) trans[1] = 0.0f;
|
|
|
|
|
if (protectflag & OB_LOCK_LOCZ) trans[2] = 0.0f;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!is_zero_v3(trans)) {
|
|
|
|
|
/* move center of view opposite of hand motion (this is camera mode, not object mode) */
|
|
|
|
|
sub_v3_v3(rv3d->ofs, trans);
|
|
|
|
|
has_translate = true;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
has_translate = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (has_rotate) {
|
|
|
|
|
const float turn_sensitivity = 1.0f;
|
|
|
|
|
|
|
|
|
|
float rotation[4];
|
|
|
|
|
float axis[3];
|
|
|
|
|
float angle = turn_sensitivity * WM_event_ndof_to_axis_angle(ndof, axis);
|
|
|
|
|
|
|
|
|
|
if (fabsf(angle) > 0.0001f) {
|
|
|
|
|
has_rotate = true;
|
|
|
|
|
|
|
|
|
|
if (use_precision)
|
|
|
|
|
angle *= 0.2f;
|
|
|
|
|
|
|
|
|
|
/* transform rotation axis from view to world coordinates */
|
|
|
|
|
mul_qt_v3(view_inv, axis);
|
|
|
|
|
|
|
|
|
|
/* apply rotation to view */
|
|
|
|
|
axis_angle_to_quat(rotation, axis, angle);
|
|
|
|
|
mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rotation);
|
|
|
|
|
|
|
|
|
|
if (U.ndof_flag & NDOF_LOCK_HORIZON) {
|
|
|
|
|
/* force an upright viewpoint
|
|
|
|
|
* TODO: make this less... sudden */
|
|
|
|
|
float view_horizon[3] = {1.0f, 0.0f, 0.0f}; /* view +x */
|
|
|
|
|
float view_direction[3] = {0.0f, 0.0f, -1.0f}; /* view -z (into screen) */
|
|
|
|
|
|
|
|
|
|
/* find new inverse since viewquat has changed */
|
|
|
|
|
invert_qt_qt(view_inv, rv3d->viewquat);
|
|
|
|
|
/* could apply reverse rotation to existing view_inv to save a few cycles */
|
|
|
|
|
|
|
|
|
|
/* transform view vectors to world coordinates */
|
|
|
|
|
mul_qt_v3(view_inv, view_horizon);
|
|
|
|
|
mul_qt_v3(view_inv, view_direction);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* find difference between view & world horizons
|
|
|
|
|
* true horizon lives in world xy plane, so look only at difference in z */
|
|
|
|
|
angle = -asinf(view_horizon[2]);
|
|
|
|
|
|
|
|
|
|
/* rotate view so view horizon = world horizon */
|
|
|
|
|
axis_angle_to_quat(rotation, view_direction, angle);
|
|
|
|
|
mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rotation);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rv3d->view = RV3D_VIEW_USER;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
has_rotate = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*r_has_translate = has_translate;
|
|
|
|
|
*r_has_rotate = has_rotate;
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-24 12:36:57 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
|
2011-08-27 11:52:59 +00:00
|
|
|
/* -- "orbit" navigation (trackball/turntable)
|
|
|
|
|
* -- zooming
|
|
|
|
|
* -- panning in rotationally-locked views
|
|
|
|
|
*/
|
2013-03-13 09:03:46 +00:00
|
|
|
static int ndof_orbit_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
2010-08-07 10:57:15 +00:00
|
|
|
{
|
2012-11-07 16:18:20 +00:00
|
|
|
|
2013-09-20 01:43:06 +00:00
|
|
|
if (event->type != NDOF_MOTION) {
|
2011-08-06 22:31:16 +00:00
|
|
|
return OPERATOR_CANCELLED;
|
2013-09-20 01:43:06 +00:00
|
|
|
}
|
2011-08-06 22:31:16 +00:00
|
|
|
else {
|
2012-12-29 15:17:26 +00:00
|
|
|
ViewOpsData *vod;
|
2014-02-12 20:51:49 +11:00
|
|
|
View3D *v3d;
|
|
|
|
|
RegionView3D *rv3d;
|
2010-08-07 10:57:15 +00:00
|
|
|
|
2014-02-20 10:00:16 +11:00
|
|
|
const wmNDOFMotionData *ndof = event->customdata;
|
2011-08-27 11:52:59 +00:00
|
|
|
|
2013-09-20 01:24:00 +00:00
|
|
|
viewops_data_alloc(C, op);
|
2014-02-24 12:53:31 +11:00
|
|
|
viewops_data_create_ex(C, op, event,
|
|
|
|
|
(U.uiflag & USER_ORBIT_SELECTION) != 0, false);
|
2014-02-12 20:51:49 +11:00
|
|
|
|
2012-12-29 15:17:26 +00:00
|
|
|
vod = op->customdata;
|
2014-02-12 20:51:49 +11:00
|
|
|
v3d = vod->v3d;
|
|
|
|
|
rv3d = vod->rv3d;
|
|
|
|
|
|
|
|
|
|
/* off by default, until changed later this function */
|
|
|
|
|
rv3d->rot_angle = 0.0f;
|
2011-06-28 15:59:46 +00:00
|
|
|
|
2014-02-24 15:15:17 +11:00
|
|
|
ED_view3d_camera_lock_init_ex(v3d, rv3d, false);
|
2014-02-18 08:29:54 +11:00
|
|
|
|
2011-08-06 22:31:16 +00:00
|
|
|
if (ndof->progress != P_FINISHING) {
|
2014-02-14 17:42:21 +11:00
|
|
|
const bool has_rotation = NDOF_HAS_ROTATE;
|
2014-02-14 18:38:23 +11:00
|
|
|
/* if we can't rotate, fallback to translate (locked axis views) */
|
|
|
|
|
const bool has_translate = NDOF_HAS_TRANSLATE && (rv3d->viewlock & RV3D_LOCKED);
|
2014-02-24 12:36:57 +11:00
|
|
|
const bool has_zoom = (ndof->tvec[2] != 0.0f) && !rv3d->is_persp;
|
2012-01-21 03:37:44 +00:00
|
|
|
|
2014-02-14 18:38:23 +11:00
|
|
|
if (has_translate || has_zoom) {
|
|
|
|
|
view3d_ndof_pan_zoom(ndof, vod->sa, vod->ar, has_translate, has_zoom);
|
2011-08-06 22:31:16 +00:00
|
|
|
}
|
2012-01-21 03:37:44 +00:00
|
|
|
|
2011-08-06 22:31:16 +00:00
|
|
|
if (has_rotation) {
|
2014-02-20 10:00:16 +11:00
|
|
|
view3d_ndof_orbit(ndof, vod->sa, vod->ar, vod);
|
2011-07-26 02:35:46 +00:00
|
|
|
}
|
2011-06-20 01:54:49 +00:00
|
|
|
}
|
2010-08-07 10:57:15 +00:00
|
|
|
|
2011-08-27 11:52:59 +00:00
|
|
|
ED_view3d_camera_lock_sync(v3d, rv3d);
|
2014-02-12 20:51:49 +11:00
|
|
|
|
|
|
|
|
ED_region_tag_redraw(vod->ar);
|
|
|
|
|
|
|
|
|
|
viewops_data_free(C, op);
|
2011-06-28 15:59:46 +00:00
|
|
|
|
2011-08-06 22:31:16 +00:00
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
2011-06-20 01:54:49 +00:00
|
|
|
}
|
2011-01-21 09:59:58 +00:00
|
|
|
|
2011-07-26 22:43:07 +00:00
|
|
|
void VIEW3D_OT_ndof_orbit(struct wmOperatorType *ot)
|
2010-08-07 10:57:15 +00:00
|
|
|
{
|
|
|
|
|
/* identifiers */
|
2011-07-26 22:43:07 +00:00
|
|
|
ot->name = "NDOF Orbit View";
|
2013-09-30 05:50:41 +00:00
|
|
|
ot->description = "Orbit the view using the 3D mouse";
|
2011-07-26 22:43:07 +00:00
|
|
|
ot->idname = "VIEW3D_OT_ndof_orbit";
|
2010-08-07 10:57:15 +00:00
|
|
|
|
|
|
|
|
/* api callbacks */
|
2011-07-14 03:28:31 +00:00
|
|
|
ot->invoke = ndof_orbit_invoke;
|
2010-08-07 10:57:15 +00:00
|
|
|
ot->poll = ED_operator_view3d_active;
|
|
|
|
|
|
|
|
|
|
/* flags */
|
|
|
|
|
ot->flag = 0;
|
|
|
|
|
}
|
|
|
|
|
|
2013-03-13 09:03:46 +00:00
|
|
|
static int ndof_orbit_zoom_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
2012-12-29 12:33:24 +00:00
|
|
|
{
|
|
|
|
|
|
2013-09-20 01:43:06 +00:00
|
|
|
if (event->type != NDOF_MOTION) {
|
2012-12-29 12:33:24 +00:00
|
|
|
return OPERATOR_CANCELLED;
|
2013-09-20 01:43:06 +00:00
|
|
|
}
|
2012-12-29 12:33:24 +00:00
|
|
|
else {
|
2012-12-29 15:17:26 +00:00
|
|
|
ViewOpsData *vod;
|
2014-02-12 20:51:49 +11:00
|
|
|
View3D *v3d;
|
|
|
|
|
RegionView3D *rv3d;
|
2012-12-29 12:33:24 +00:00
|
|
|
|
2014-02-20 10:00:16 +11:00
|
|
|
const wmNDOFMotionData *ndof = event->customdata;
|
2012-12-29 12:33:24 +00:00
|
|
|
|
2013-09-20 01:24:00 +00:00
|
|
|
viewops_data_alloc(C, op);
|
2014-02-24 12:53:31 +11:00
|
|
|
viewops_data_create_ex(C, op, event,
|
|
|
|
|
(U.uiflag & USER_ORBIT_SELECTION) != 0, false);
|
2014-02-12 20:51:49 +11:00
|
|
|
|
2012-12-29 15:17:26 +00:00
|
|
|
vod = op->customdata;
|
2014-02-12 20:51:49 +11:00
|
|
|
v3d = vod->v3d;
|
|
|
|
|
rv3d = vod->rv3d;
|
|
|
|
|
|
|
|
|
|
/* off by default, until changed later this function */
|
|
|
|
|
rv3d->rot_angle = 0.0f;
|
2012-12-29 15:17:26 +00:00
|
|
|
|
2014-02-24 15:15:17 +11:00
|
|
|
ED_view3d_camera_lock_init_ex(v3d, rv3d, false);
|
2014-02-18 08:29:54 +11:00
|
|
|
|
2014-02-20 10:00:16 +11:00
|
|
|
if (ndof->progress == P_FINISHING) {
|
|
|
|
|
/* pass */
|
|
|
|
|
}
|
2014-02-28 22:07:53 +11:00
|
|
|
else if ((rv3d->persp == RV3D_ORTHO) && RV3D_VIEW_IS_AXIS(rv3d->view)) {
|
2014-02-14 18:38:23 +11:00
|
|
|
/* if we can't rotate, fallback to translate (locked axis views) */
|
2014-02-17 22:05:10 +11:00
|
|
|
const bool has_translate = NDOF_HAS_TRANSLATE;
|
2014-02-24 12:36:57 +11:00
|
|
|
const bool has_zoom = (ndof->tvec[2] != 0.0f) && ED_view3d_offset_lock_check(v3d, rv3d);
|
2012-12-29 12:33:24 +00:00
|
|
|
|
2014-02-24 12:36:57 +11:00
|
|
|
if (has_translate || has_zoom) {
|
2014-02-14 18:38:23 +11:00
|
|
|
view3d_ndof_pan_zoom(ndof, vod->sa, vod->ar, has_translate, true);
|
2012-12-29 12:33:24 +00:00
|
|
|
}
|
2014-02-20 10:00:16 +11:00
|
|
|
}
|
2014-02-24 12:36:57 +11:00
|
|
|
else if ((U.ndof_flag & NDOF_MODE_ORBIT) ||
|
|
|
|
|
ED_view3d_offset_lock_check(v3d, rv3d))
|
|
|
|
|
{
|
2014-02-20 10:00:16 +11:00
|
|
|
const bool has_rotation = NDOF_HAS_ROTATE;
|
|
|
|
|
const bool has_zoom = (ndof->tvec[2] != 0.0f);
|
|
|
|
|
|
|
|
|
|
if (has_zoom) {
|
|
|
|
|
view3d_ndof_pan_zoom(ndof, vod->sa, vod->ar, false, has_zoom);
|
|
|
|
|
}
|
2012-12-29 12:33:24 +00:00
|
|
|
|
|
|
|
|
if (has_rotation) {
|
2014-02-20 10:00:16 +11:00
|
|
|
view3d_ndof_orbit(ndof, vod->sa, vod->ar, vod);
|
2012-12-29 12:33:24 +00:00
|
|
|
}
|
|
|
|
|
}
|
2014-02-20 10:00:16 +11:00
|
|
|
else { /* free/explore (like fly mode) */
|
|
|
|
|
const bool has_rotation = NDOF_HAS_ROTATE;
|
|
|
|
|
const bool has_translate = NDOF_HAS_TRANSLATE;
|
2014-02-24 15:15:17 +11:00
|
|
|
const bool has_zoom = (ndof->tvec[2] != 0.0f) && !rv3d->is_persp;
|
2014-02-20 10:00:16 +11:00
|
|
|
|
2014-02-24 15:15:17 +11:00
|
|
|
float dist_backup;
|
2014-02-20 10:00:16 +11:00
|
|
|
|
2014-02-24 15:15:17 +11:00
|
|
|
if (has_translate || has_zoom) {
|
|
|
|
|
view3d_ndof_pan_zoom(ndof, vod->sa, vod->ar, has_translate, has_zoom);
|
2014-02-20 10:00:16 +11:00
|
|
|
}
|
|
|
|
|
|
2014-02-24 15:15:17 +11:00
|
|
|
dist_backup = rv3d->dist;
|
2014-02-20 10:00:16 +11:00
|
|
|
ED_view3d_distance_set(rv3d, 0.0f);
|
|
|
|
|
|
|
|
|
|
if (has_rotation) {
|
|
|
|
|
view3d_ndof_orbit(ndof, vod->sa, vod->ar, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ED_view3d_distance_set(rv3d, dist_backup);
|
|
|
|
|
}
|
2012-12-29 12:33:24 +00:00
|
|
|
|
|
|
|
|
ED_view3d_camera_lock_sync(v3d, rv3d);
|
|
|
|
|
|
2014-02-12 20:51:49 +11:00
|
|
|
ED_region_tag_redraw(vod->ar);
|
|
|
|
|
|
|
|
|
|
viewops_data_free(C, op);
|
2012-12-29 12:33:24 +00:00
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VIEW3D_OT_ndof_orbit_zoom(struct wmOperatorType *ot)
|
|
|
|
|
{
|
|
|
|
|
/* identifiers */
|
2013-01-27 07:23:58 +00:00
|
|
|
ot->name = "NDOF Orbit View with Zoom";
|
2013-09-30 05:50:41 +00:00
|
|
|
ot->description = "Orbit and zoom the view using the 3D mouse";
|
2012-12-29 12:33:24 +00:00
|
|
|
ot->idname = "VIEW3D_OT_ndof_orbit_zoom";
|
|
|
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
|
ot->invoke = ndof_orbit_zoom_invoke;
|
|
|
|
|
ot->poll = ED_operator_view3d_active;
|
|
|
|
|
|
|
|
|
|
/* flags */
|
|
|
|
|
ot->flag = 0;
|
|
|
|
|
}
|
|
|
|
|
|
2011-08-27 11:52:59 +00:00
|
|
|
/* -- "pan" navigation
|
|
|
|
|
* -- zoom or dolly?
|
|
|
|
|
*/
|
2014-02-19 21:19:13 +11:00
|
|
|
static int ndof_pan_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
|
2011-07-26 22:43:07 +00:00
|
|
|
{
|
2013-09-20 01:43:06 +00:00
|
|
|
if (event->type != NDOF_MOTION) {
|
2011-08-06 22:31:16 +00:00
|
|
|
return OPERATOR_CANCELLED;
|
2013-09-20 01:43:06 +00:00
|
|
|
}
|
2011-08-06 22:31:16 +00:00
|
|
|
else {
|
2012-03-25 23:54:33 +00:00
|
|
|
View3D *v3d = CTX_wm_view3d(C);
|
2012-05-08 15:55:29 +00:00
|
|
|
RegionView3D *rv3d = CTX_wm_region_view3d(C);
|
2014-02-20 10:00:16 +11:00
|
|
|
const wmNDOFMotionData *ndof = event->customdata;
|
2014-02-14 18:38:23 +11:00
|
|
|
|
|
|
|
|
const bool has_translate = NDOF_HAS_TRANSLATE;
|
2014-02-24 12:36:57 +11:00
|
|
|
const bool has_zoom = (ndof->tvec[2] != 0.0f) && !rv3d->is_persp;
|
2011-07-26 22:43:07 +00:00
|
|
|
|
2014-02-18 08:29:54 +11:00
|
|
|
/* we're panning here! so erase any leftover rotation from other operators */
|
|
|
|
|
rv3d->rot_angle = 0.0f;
|
|
|
|
|
|
2014-02-24 17:21:25 +11:00
|
|
|
if (!(has_translate || has_zoom))
|
2013-09-20 01:43:06 +00:00
|
|
|
return OPERATOR_CANCELLED;
|
2013-05-03 07:29:25 +00:00
|
|
|
|
2014-02-24 15:15:17 +11:00
|
|
|
ED_view3d_camera_lock_init_ex(v3d, rv3d, false);
|
2011-07-26 22:43:07 +00:00
|
|
|
|
2011-08-06 22:31:16 +00:00
|
|
|
if (ndof->progress != P_FINISHING) {
|
2014-02-14 18:38:23 +11:00
|
|
|
ScrArea *sa = CTX_wm_area(C);
|
|
|
|
|
ARegion *ar = CTX_wm_region(C);
|
2011-09-07 10:33:46 +00:00
|
|
|
|
2014-02-14 18:38:23 +11:00
|
|
|
if (has_translate || has_zoom) {
|
|
|
|
|
view3d_ndof_pan_zoom(ndof, sa, ar, has_translate, has_zoom);
|
|
|
|
|
}
|
2011-08-06 22:31:16 +00:00
|
|
|
}
|
2011-07-26 22:43:07 +00:00
|
|
|
|
2011-08-27 11:52:59 +00:00
|
|
|
ED_view3d_camera_lock_sync(v3d, rv3d);
|
|
|
|
|
|
2011-08-06 22:31:16 +00:00
|
|
|
ED_region_tag_redraw(CTX_wm_region(C));
|
2011-07-26 22:43:07 +00:00
|
|
|
|
2011-08-06 22:31:16 +00:00
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
2011-07-26 22:43:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VIEW3D_OT_ndof_pan(struct wmOperatorType *ot)
|
|
|
|
|
{
|
|
|
|
|
/* identifiers */
|
|
|
|
|
ot->name = "NDOF Pan View";
|
2013-09-30 05:50:41 +00:00
|
|
|
ot->description = "Pan the view with the 3D mouse";
|
2011-07-26 22:43:07 +00:00
|
|
|
ot->idname = "VIEW3D_OT_ndof_pan";
|
|
|
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
|
ot->invoke = ndof_pan_invoke;
|
|
|
|
|
ot->poll = ED_operator_view3d_active;
|
|
|
|
|
|
|
|
|
|
/* flags */
|
|
|
|
|
ot->flag = 0;
|
|
|
|
|
}
|
|
|
|
|
|
2012-08-19 13:52:36 +00:00
|
|
|
|
2014-02-24 15:15:17 +11:00
|
|
|
/**
|
|
|
|
|
* wraps #ndof_orbit_zoom but never restrict to orbit.
|
2012-10-04 13:26:15 +00:00
|
|
|
*/
|
2013-03-13 09:03:46 +00:00
|
|
|
static int ndof_all_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
2012-08-19 13:52:36 +00:00
|
|
|
{
|
2014-02-24 15:15:17 +11:00
|
|
|
/* weak!, but it works */
|
|
|
|
|
const int ndof_flag = U.ndof_flag;
|
|
|
|
|
int ret;
|
2012-11-07 16:18:20 +00:00
|
|
|
|
2014-02-24 15:15:17 +11:00
|
|
|
U.ndof_flag &= ~NDOF_MODE_ORBIT;
|
2014-02-12 20:51:49 +11:00
|
|
|
|
2014-02-24 15:15:17 +11:00
|
|
|
ret = ndof_orbit_zoom_invoke(C, op, event);
|
2012-08-19 13:52:36 +00:00
|
|
|
|
2014-02-24 15:15:17 +11:00
|
|
|
U.ndof_flag = ndof_flag;
|
2014-02-12 20:51:49 +11:00
|
|
|
|
2014-02-24 15:15:17 +11:00
|
|
|
return ret;
|
2012-08-19 13:52:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VIEW3D_OT_ndof_all(struct wmOperatorType *ot)
|
|
|
|
|
{
|
|
|
|
|
/* identifiers */
|
2013-01-27 07:23:58 +00:00
|
|
|
ot->name = "NDOF Move View";
|
2013-09-30 05:50:41 +00:00
|
|
|
ot->description = "Pan and rotate the view with the 3D mouse";
|
2012-08-19 13:52:36 +00:00
|
|
|
ot->idname = "VIEW3D_OT_ndof_all";
|
|
|
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
|
ot->invoke = ndof_all_invoke;
|
|
|
|
|
ot->poll = ED_operator_view3d_active;
|
|
|
|
|
|
|
|
|
|
/* flags */
|
|
|
|
|
ot->flag = 0;
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-19 17:14:02 +00:00
|
|
|
/* ************************ viewmove ******************************** */
|
|
|
|
|
|
2009-09-25 10:24:42 +00:00
|
|
|
|
|
|
|
|
/* NOTE: these defines are saved in keymap files, do not change values but just add new ones */
|
|
|
|
|
|
|
|
|
|
/* called in transform_ops.c, on each regeneration of keymaps */
|
Key Configuration
Keymaps are now saveable and configurable from the user preferences, note
that editing one item in a keymap means the whole keymap is now defined by
the user and will not be updated by Blender, an option for syncing might be
added later. The outliner interface is still there, but I will probably
remove it.
There's actually 3 levels now:
* Default builtin key configuration.
* Key configuration loaded from .py file, for configs like Blender 2.4x
or other 3D applications.
* Keymaps edited by the user and saved in .B.blend. These can be saved
to .py files as well to make creating distributable configurations
easier.
Also, user preferences sections were reorganized a bit, now there is:
Interface, Editing, Input, Files and System.
Implementation notes:
* wmKeyConfig was added which represents a key configuration containing
keymaps.
* wmKeymapItem was renamed to wmKeyMapItem for consistency with wmKeyMap.
* Modal maps are not wrapped yet.
* User preferences DNA file reading did not support newdataadr() yet,
added this now for reading keymaps.
* Key configuration related settings are now RNA wrapped.
* is_property_set and is_property_hidden python methods were added.
2009-10-08 18:40:03 +00:00
|
|
|
void viewmove_modal_keymap(wmKeyConfig *keyconf)
|
2009-09-25 10:24:42 +00:00
|
|
|
{
|
|
|
|
|
static EnumPropertyItem modal_items[] = {
|
2012-03-25 23:54:33 +00:00
|
|
|
{VIEW_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""},
|
2010-07-29 07:21:57 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
{VIEWROT_MODAL_SWITCH_ZOOM, "SWITCH_TO_ZOOM", 0, "Switch to Zoom"},
|
|
|
|
|
{VIEWROT_MODAL_SWITCH_ROTATE, "SWITCH_TO_ROTATE", 0, "Switch to Rotate"},
|
2009-09-25 10:24:42 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
{0, NULL, 0, NULL, NULL}
|
|
|
|
|
};
|
2009-09-25 10:24:42 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "View3D Move Modal");
|
2009-09-25 10:24:42 +00:00
|
|
|
|
|
|
|
|
/* this function is called for each spacetype, only needs to add map once */
|
2012-04-17 15:40:04 +00:00
|
|
|
if (keymap && keymap->modal_items) return;
|
2009-09-25 10:24:42 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
keymap = WM_modalkeymap_add(keyconf, "View3D Move Modal", modal_items);
|
2009-09-25 10:24:42 +00:00
|
|
|
|
|
|
|
|
/* items for modal map */
|
|
|
|
|
WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, KM_ANY, 0, VIEW_MODAL_CONFIRM);
|
|
|
|
|
WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, VIEW_MODAL_CONFIRM);
|
|
|
|
|
|
2012-03-03 16:31:46 +00:00
|
|
|
/* disabled mode switching for now, can re-implement better, later on */
|
|
|
|
|
#if 0
|
2010-01-06 12:22:59 +00:00
|
|
|
WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, KM_ANY, 0, VIEWROT_MODAL_SWITCH_ZOOM);
|
|
|
|
|
WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_PRESS, KM_ANY, 0, VIEWROT_MODAL_SWITCH_ZOOM);
|
|
|
|
|
WM_modalkeymap_add_item(keymap, LEFTSHIFTKEY, KM_RELEASE, KM_ANY, 0, VIEWROT_MODAL_SWITCH_ROTATE);
|
2012-03-03 16:31:46 +00:00
|
|
|
#endif
|
2010-01-06 12:22:59 +00:00
|
|
|
|
2009-09-25 10:24:42 +00:00
|
|
|
/* assign map to operators */
|
|
|
|
|
WM_modalkeymap_assign(keymap, "VIEW3D_OT_move");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2008-12-19 17:14:02 +00:00
|
|
|
static void viewmove_apply(ViewOpsData *vod, int x, int y)
|
|
|
|
|
{
|
2013-07-19 10:54:02 +00:00
|
|
|
if (ED_view3d_offset_lock_check(vod->v3d, vod->rv3d)) {
|
|
|
|
|
vod->rv3d->ofs_lock[0] -= ((vod->oldx - x) * 2.0f) / (float)vod->ar->winx;
|
|
|
|
|
vod->rv3d->ofs_lock[1] -= ((vod->oldy - y) * 2.0f) / (float)vod->ar->winy;
|
|
|
|
|
}
|
|
|
|
|
else if ((vod->rv3d->persp == RV3D_CAMOB) && !ED_view3d_camera_lock_check(vod->v3d, vod->rv3d)) {
|
2012-03-25 23:54:33 +00:00
|
|
|
const float zoomfac = BKE_screen_view3d_zoom_to_fac((float)vod->rv3d->camzoom) * 2.0f;
|
|
|
|
|
vod->rv3d->camdx += (vod->oldx - x) / (vod->ar->winx * zoomfac);
|
|
|
|
|
vod->rv3d->camdy += (vod->oldy - y) / (vod->ar->winy * zoomfac);
|
2.5
View3D has been split now in a local part (RegionView3D) and a
per-area part (old View3D). Currently local is:
- view transform
- camera zoom/offset
- gpencil (todo)
- custom clipping planes
Rest is in Area still, like active camera, draw type, layers,
localview, custom centers, around-settings, transform widget,
gridlines, and so on (mostly stuff as available in header).
To see it work; also added new feature for region split,
press SHIFT+ALT+CTRL+S for four-split.
The idea is to make a preset 4-split, configured to stick
to top/right/front views for three views.
Another cool idea to explore is to then box-clip all drawing
based on these 3 views.
Note about the code:
- currently view3d still stores some depricated settings, to
convert from older files. Not all settings are copied over
though, like custom clip planes or the 'lock view to object'.
- since some view3d ops are now on area level, the operators
for it should keep track of that.
Bugfix in transform: quat initialize in operator-invoke missed
one zero.
Als brought back GE to compile for missing Ipos and channels.
2009-01-19 16:54:41 +00:00
|
|
|
CLAMP(vod->rv3d->camdx, -1.0f, 1.0f);
|
|
|
|
|
CLAMP(vod->rv3d->camdy, -1.0f, 1.0f);
|
2008-12-19 12:14:58 +00:00
|
|
|
}
|
2008-12-19 17:14:02 +00:00
|
|
|
else {
|
|
|
|
|
float dvec[3];
|
2011-05-20 13:50:41 +00:00
|
|
|
float mval_f[2];
|
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
mval_f[0] = x - vod->oldx;
|
|
|
|
|
mval_f[1] = y - vod->oldy;
|
2013-03-09 11:40:42 +00:00
|
|
|
ED_view3d_win_to_delta(vod->ar, mval_f, dvec, vod->zfac);
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2010-04-21 12:27:48 +00:00
|
|
|
add_v3_v3(vod->rv3d->ofs, dvec);
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (vod->rv3d->viewlock & RV3D_BOXVIEW)
|
2009-01-20 14:23:32 +00:00
|
|
|
view3d_boxview_sync(vod->sa, vod->ar);
|
2008-12-19 17:14:02 +00:00
|
|
|
}
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
vod->oldx = x;
|
|
|
|
|
vod->oldy = y;
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2011-05-14 17:50:33 +00:00
|
|
|
ED_view3d_camera_lock_sync(vod->v3d, vod->rv3d);
|
|
|
|
|
|
2008-12-19 17:14:02 +00:00
|
|
|
ED_region_tag_redraw(vod->ar);
|
|
|
|
|
}
|
2008-12-19 12:14:58 +00:00
|
|
|
|
|
|
|
|
|
2013-03-13 09:03:46 +00:00
|
|
|
static int viewmove_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
2008-12-26 10:31:44 +00:00
|
|
|
{
|
2009-09-25 10:24:42 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
ViewOpsData *vod = op->customdata;
|
|
|
|
|
short event_code = VIEW_PASS;
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2008-12-19 17:14:02 +00:00
|
|
|
/* execute the events */
|
2012-03-25 23:54:33 +00:00
|
|
|
if (event->type == MOUSEMOVE) {
|
|
|
|
|
event_code = VIEW_APPLY;
|
2009-09-25 10:24:42 +00:00
|
|
|
}
|
2012-03-25 23:54:33 +00:00
|
|
|
else if (event->type == EVT_MODAL_MAP) {
|
2009-09-25 10:24:42 +00:00
|
|
|
switch (event->val) {
|
|
|
|
|
case VIEW_MODAL_CONFIRM:
|
2012-03-25 23:54:33 +00:00
|
|
|
event_code = VIEW_CONFIRM;
|
2009-09-25 10:24:42 +00:00
|
|
|
break;
|
2010-01-06 12:22:59 +00:00
|
|
|
case VIEWROT_MODAL_SWITCH_ZOOM:
|
|
|
|
|
WM_operator_name_call(C, "VIEW3D_OT_zoom", WM_OP_INVOKE_DEFAULT, NULL);
|
2012-03-25 23:54:33 +00:00
|
|
|
event_code = VIEW_CONFIRM;
|
2010-01-06 12:22:59 +00:00
|
|
|
break;
|
|
|
|
|
case VIEWROT_MODAL_SWITCH_ROTATE:
|
|
|
|
|
WM_operator_name_call(C, "VIEW3D_OT_rotate", WM_OP_INVOKE_DEFAULT, NULL);
|
2012-03-25 23:54:33 +00:00
|
|
|
event_code = VIEW_CONFIRM;
|
2010-01-06 12:22:59 +00:00
|
|
|
break;
|
2009-09-25 10:24:42 +00:00
|
|
|
}
|
|
|
|
|
}
|
2012-03-25 23:54:33 +00:00
|
|
|
else if (event->type == vod->origkey && event->val == KM_RELEASE) {
|
|
|
|
|
event_code = VIEW_CONFIRM;
|
2009-09-25 10:24:42 +00:00
|
|
|
}
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
if (event_code == VIEW_APPLY) {
|
2009-09-25 10:24:42 +00:00
|
|
|
viewmove_apply(vod, event->x, event->y);
|
|
|
|
|
}
|
2012-03-25 23:54:33 +00:00
|
|
|
else if (event_code == VIEW_CONFIRM) {
|
2011-05-21 08:56:37 +00:00
|
|
|
ED_view3d_depth_tag_update(vod->rv3d);
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2009-11-25 14:13:43 +00:00
|
|
|
viewops_data_free(C, op);
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2009-09-25 10:24:42 +00:00
|
|
|
return OPERATOR_FINISHED;
|
2008-12-19 17:14:02 +00:00
|
|
|
}
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2008-12-19 17:14:02 +00:00
|
|
|
return OPERATOR_RUNNING_MODAL;
|
|
|
|
|
}
|
|
|
|
|
|
2013-03-13 09:03:46 +00:00
|
|
|
static int viewmove_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
2008-12-19 17:14:02 +00:00
|
|
|
{
|
2011-05-14 17:50:33 +00:00
|
|
|
ViewOpsData *vod;
|
|
|
|
|
|
2008-12-19 17:14:02 +00:00
|
|
|
/* makes op->customdata */
|
2013-09-20 01:24:00 +00:00
|
|
|
viewops_data_alloc(C, op);
|
2009-11-25 14:13:43 +00:00
|
|
|
viewops_data_create(C, op, event);
|
2012-03-25 23:54:33 +00:00
|
|
|
vod = op->customdata;
|
2011-05-14 17:50:33 +00:00
|
|
|
|
2010-01-11 11:14:36 +00:00
|
|
|
if (event->type == MOUSEPAN) {
|
2012-12-20 14:45:56 +00:00
|
|
|
/* invert it, trackpad scroll follows same principle as 2d windows this way */
|
|
|
|
|
viewmove_apply(vod, 2 * event->x - event->prevx, 2 * event->y - event->prevy);
|
2011-05-21 08:56:37 +00:00
|
|
|
ED_view3d_depth_tag_update(vod->rv3d);
|
2010-01-11 11:14:36 +00:00
|
|
|
|
2012-10-21 05:46:41 +00:00
|
|
|
viewops_data_free(C, op);
|
2010-01-11 11:14:36 +00:00
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* add temp handler */
|
|
|
|
|
WM_event_add_modal_handler(C, op);
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2010-01-11 11:14:36 +00:00
|
|
|
return OPERATOR_RUNNING_MODAL;
|
|
|
|
|
}
|
2008-12-19 17:14:02 +00:00
|
|
|
}
|
|
|
|
|
|
2013-10-30 23:08:53 +00:00
|
|
|
static void viewmove_cancel(bContext *C, wmOperator *op)
|
2011-06-06 11:04:54 +00:00
|
|
|
{
|
|
|
|
|
viewops_data_free(C, op);
|
|
|
|
|
}
|
|
|
|
|
|
2009-09-25 10:24:42 +00:00
|
|
|
void VIEW3D_OT_move(wmOperatorType *ot)
|
2008-12-19 17:14:02 +00:00
|
|
|
{
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2008-12-19 17:14:02 +00:00
|
|
|
/* identifiers */
|
2013-01-27 07:23:58 +00:00
|
|
|
ot->name = "Move View";
|
2010-02-10 21:15:44 +00:00
|
|
|
ot->description = "Move the view";
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->idname = "VIEW3D_OT_move";
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2008-12-19 17:14:02 +00:00
|
|
|
/* api callbacks */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->invoke = viewmove_invoke;
|
|
|
|
|
ot->modal = viewmove_modal;
|
|
|
|
|
ot->poll = ED_operator_view3d_active;
|
|
|
|
|
ot->cancel = viewmove_cancel;
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2009-01-31 19:40:40 +00:00
|
|
|
/* flags */
|
2012-03-25 23:54:33 +00:00
|
|
|
ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_POINTER;
|
2008-12-19 17:14:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ************************ viewzoom ******************************** */
|
|
|
|
|
|
2011-05-22 11:36:56 +00:00
|
|
|
/* viewdolly_modal_keymap has an exact copy of this, apply fixes to both */
|
2009-09-25 10:24:42 +00:00
|
|
|
/* called in transform_ops.c, on each regeneration of keymaps */
|
Key Configuration
Keymaps are now saveable and configurable from the user preferences, note
that editing one item in a keymap means the whole keymap is now defined by
the user and will not be updated by Blender, an option for syncing might be
added later. The outliner interface is still there, but I will probably
remove it.
There's actually 3 levels now:
* Default builtin key configuration.
* Key configuration loaded from .py file, for configs like Blender 2.4x
or other 3D applications.
* Keymaps edited by the user and saved in .B.blend. These can be saved
to .py files as well to make creating distributable configurations
easier.
Also, user preferences sections were reorganized a bit, now there is:
Interface, Editing, Input, Files and System.
Implementation notes:
* wmKeyConfig was added which represents a key configuration containing
keymaps.
* wmKeymapItem was renamed to wmKeyMapItem for consistency with wmKeyMap.
* Modal maps are not wrapped yet.
* User preferences DNA file reading did not support newdataadr() yet,
added this now for reading keymaps.
* Key configuration related settings are now RNA wrapped.
* is_property_set and is_property_hidden python methods were added.
2009-10-08 18:40:03 +00:00
|
|
|
void viewzoom_modal_keymap(wmKeyConfig *keyconf)
|
2009-09-25 10:24:42 +00:00
|
|
|
{
|
|
|
|
|
static EnumPropertyItem modal_items[] = {
|
2012-03-25 23:54:33 +00:00
|
|
|
{VIEW_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""},
|
2010-07-29 07:21:57 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
{VIEWROT_MODAL_SWITCH_ROTATE, "SWITCH_TO_ROTATE", 0, "Switch to Rotate"},
|
|
|
|
|
{VIEWROT_MODAL_SWITCH_MOVE, "SWITCH_TO_MOVE", 0, "Switch to Move"},
|
2009-09-25 10:24:42 +00:00
|
|
|
|
2012-05-16 14:30:41 +00:00
|
|
|
{0, NULL, 0, NULL, NULL}
|
|
|
|
|
};
|
2009-09-25 10:24:42 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "View3D Zoom Modal");
|
2009-09-25 10:24:42 +00:00
|
|
|
|
|
|
|
|
/* this function is called for each spacetype, only needs to add map once */
|
2012-04-17 15:40:04 +00:00
|
|
|
if (keymap && keymap->modal_items) return;
|
2009-09-25 10:24:42 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
keymap = WM_modalkeymap_add(keyconf, "View3D Zoom Modal", modal_items);
|
2009-09-25 10:24:42 +00:00
|
|
|
|
|
|
|
|
/* items for modal map */
|
|
|
|
|
WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, KM_ANY, 0, VIEW_MODAL_CONFIRM);
|
|
|
|
|
WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, VIEW_MODAL_CONFIRM);
|
|
|
|
|
|
2012-03-03 16:31:46 +00:00
|
|
|
/* disabled mode switching for now, can re-implement better, later on */
|
|
|
|
|
#if 0
|
2010-01-06 12:22:59 +00:00
|
|
|
WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_RELEASE, KM_ANY, 0, VIEWROT_MODAL_SWITCH_ROTATE);
|
|
|
|
|
WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_RELEASE, KM_ANY, 0, VIEWROT_MODAL_SWITCH_ROTATE);
|
|
|
|
|
WM_modalkeymap_add_item(keymap, LEFTSHIFTKEY, KM_PRESS, KM_ANY, 0, VIEWROT_MODAL_SWITCH_MOVE);
|
2012-03-03 16:31:46 +00:00
|
|
|
#endif
|
2010-01-06 12:22:59 +00:00
|
|
|
|
2009-09-25 10:24:42 +00:00
|
|
|
/* assign map to operators */
|
|
|
|
|
WM_modalkeymap_assign(keymap, "VIEW3D_OT_zoom");
|
|
|
|
|
}
|
|
|
|
|
|
2.5
View3D has been split now in a local part (RegionView3D) and a
per-area part (old View3D). Currently local is:
- view transform
- camera zoom/offset
- gpencil (todo)
- custom clipping planes
Rest is in Area still, like active camera, draw type, layers,
localview, custom centers, around-settings, transform widget,
gridlines, and so on (mostly stuff as available in header).
To see it work; also added new feature for region split,
press SHIFT+ALT+CTRL+S for four-split.
The idea is to make a preset 4-split, configured to stick
to top/right/front views for three views.
Another cool idea to explore is to then box-clip all drawing
based on these 3 views.
Note about the code:
- currently view3d still stores some depricated settings, to
convert from older files. Not all settings are copied over
though, like custom clip planes or the 'lock view to object'.
- since some view3d ops are now on area level, the operators
for it should keep track of that.
Bugfix in transform: quat initialize in operator-invoke missed
one zero.
Als brought back GE to compile for missing Ipos and channels.
2009-01-19 16:54:41 +00:00
|
|
|
static void view_zoom_mouseloc(ARegion *ar, float dfac, int mx, int my)
|
2008-12-19 17:14:02 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (U.uiflag & USER_ZOOM_TO_MOUSEPOS) {
|
2008-12-19 17:14:02 +00:00
|
|
|
float dvec[3];
|
|
|
|
|
float tvec[3];
|
|
|
|
|
float tpos[3];
|
2011-05-20 13:50:41 +00:00
|
|
|
float mval_f[2];
|
2008-12-19 17:14:02 +00:00
|
|
|
float new_dist;
|
2013-03-09 11:40:42 +00:00
|
|
|
float zfac;
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2010-02-25 20:26:38 +00:00
|
|
|
negate_v3_v3(tpos, rv3d->ofs);
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
mval_f[0] = (float)(((mx - ar->winrct.xmin) * 2) - ar->winx) / 2.0f;
|
|
|
|
|
mval_f[1] = (float)(((my - ar->winrct.ymin) * 2) - ar->winy) / 2.0f;
|
2013-03-09 11:40:42 +00:00
|
|
|
|
|
|
|
|
/* Project cursor position into 3D space */
|
|
|
|
|
zfac = ED_view3d_calc_zfac(rv3d, tpos, NULL);
|
|
|
|
|
ED_view3d_win_to_delta(ar, mval_f, dvec, zfac);
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2008-12-19 17:14:02 +00:00
|
|
|
/* Calculate view target position for dolly */
|
2010-02-25 20:26:38 +00:00
|
|
|
add_v3_v3v3(tvec, tpos, dvec);
|
|
|
|
|
negate_v3(tvec);
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2008-12-19 17:14:02 +00:00
|
|
|
/* Offset to target position and dolly */
|
2.5
View3D has been split now in a local part (RegionView3D) and a
per-area part (old View3D). Currently local is:
- view transform
- camera zoom/offset
- gpencil (todo)
- custom clipping planes
Rest is in Area still, like active camera, draw type, layers,
localview, custom centers, around-settings, transform widget,
gridlines, and so on (mostly stuff as available in header).
To see it work; also added new feature for region split,
press SHIFT+ALT+CTRL+S for four-split.
The idea is to make a preset 4-split, configured to stick
to top/right/front views for three views.
Another cool idea to explore is to then box-clip all drawing
based on these 3 views.
Note about the code:
- currently view3d still stores some depricated settings, to
convert from older files. Not all settings are copied over
though, like custom clip planes or the 'lock view to object'.
- since some view3d ops are now on area level, the operators
for it should keep track of that.
Bugfix in transform: quat initialize in operator-invoke missed
one zero.
Als brought back GE to compile for missing Ipos and channels.
2009-01-19 16:54:41 +00:00
|
|
|
new_dist = rv3d->dist * dfac;
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2010-07-26 06:34:56 +00:00
|
|
|
copy_v3_v3(rv3d->ofs, tvec);
|
2.5
View3D has been split now in a local part (RegionView3D) and a
per-area part (old View3D). Currently local is:
- view transform
- camera zoom/offset
- gpencil (todo)
- custom clipping planes
Rest is in Area still, like active camera, draw type, layers,
localview, custom centers, around-settings, transform widget,
gridlines, and so on (mostly stuff as available in header).
To see it work; also added new feature for region split,
press SHIFT+ALT+CTRL+S for four-split.
The idea is to make a preset 4-split, configured to stick
to top/right/front views for three views.
Another cool idea to explore is to then box-clip all drawing
based on these 3 views.
Note about the code:
- currently view3d still stores some depricated settings, to
convert from older files. Not all settings are copied over
though, like custom clip planes or the 'lock view to object'.
- since some view3d ops are now on area level, the operators
for it should keep track of that.
Bugfix in transform: quat initialize in operator-invoke missed
one zero.
Als brought back GE to compile for missing Ipos and channels.
2009-01-19 16:54:41 +00:00
|
|
|
rv3d->dist = new_dist;
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2008-12-19 17:14:02 +00:00
|
|
|
/* Calculate final offset */
|
2010-02-25 20:26:38 +00:00
|
|
|
madd_v3_v3v3fl(rv3d->ofs, tvec, dvec, dfac);
|
2012-02-22 16:52:06 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2.5
View3D has been split now in a local part (RegionView3D) and a
per-area part (old View3D). Currently local is:
- view transform
- camera zoom/offset
- gpencil (todo)
- custom clipping planes
Rest is in Area still, like active camera, draw type, layers,
localview, custom centers, around-settings, transform widget,
gridlines, and so on (mostly stuff as available in header).
To see it work; also added new feature for region split,
press SHIFT+ALT+CTRL+S for four-split.
The idea is to make a preset 4-split, configured to stick
to top/right/front views for three views.
Another cool idea to explore is to then box-clip all drawing
based on these 3 views.
Note about the code:
- currently view3d still stores some depricated settings, to
convert from older files. Not all settings are copied over
though, like custom clip planes or the 'lock view to object'.
- since some view3d ops are now on area level, the operators
for it should keep track of that.
Bugfix in transform: quat initialize in operator-invoke missed
one zero.
Als brought back GE to compile for missing Ipos and channels.
2009-01-19 16:54:41 +00:00
|
|
|
rv3d->dist *= dfac;
|
2008-12-19 17:14:02 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2012-11-25 09:52:05 +00:00
|
|
|
static void viewzoom_apply(ViewOpsData *vod, const int x, const int y, const short viewzoom, const short zoom_invert)
|
2008-12-19 17:14:02 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
float zfac = 1.0;
|
2013-03-22 04:40:45 +00:00
|
|
|
bool use_cam_zoom;
|
2008-12-19 17:14:02 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
use_cam_zoom = (vod->rv3d->persp == RV3D_CAMOB) && !(vod->rv3d->is_persp && ED_view3d_camera_lock_check(vod->v3d, vod->rv3d));
|
2012-03-07 18:34:16 +00:00
|
|
|
|
|
|
|
|
if (use_cam_zoom) {
|
|
|
|
|
float delta;
|
|
|
|
|
delta = (x - vod->origx + y - vod->origy) / 10.0f;
|
2013-04-04 04:22:38 +00:00
|
|
|
vod->rv3d->camzoom = vod->camzoom_prev + (zoom_invert ? -delta : delta);
|
2012-03-07 18:34:16 +00:00
|
|
|
|
|
|
|
|
CLAMP(vod->rv3d->camzoom, RV3D_CAMZOOM_MIN, RV3D_CAMZOOM_MAX);
|
|
|
|
|
}
|
2012-08-26 18:21:34 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
if (viewzoom == USER_ZOOM_CONT) {
|
|
|
|
|
double time = PIL_check_seconds_timer();
|
|
|
|
|
float time_step = (float)(time - vod->timer_lastdraw);
|
2011-04-22 14:47:35 +00:00
|
|
|
float fac;
|
|
|
|
|
|
|
|
|
|
if (U.uiflag & USER_ZOOM_HORIZ) {
|
2012-11-25 09:52:05 +00:00
|
|
|
fac = (float)(vod->origx - x);
|
2011-04-22 14:47:35 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2012-11-25 09:52:05 +00:00
|
|
|
fac = (float)(vod->origy - y);
|
2011-04-22 14:47:35 +00:00
|
|
|
}
|
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (zoom_invert) {
|
2012-03-25 23:54:33 +00:00
|
|
|
fac = -fac;
|
2011-04-22 14:47:35 +00:00
|
|
|
}
|
2009-12-16 23:05:59 +00:00
|
|
|
|
2012-07-08 20:36:00 +00:00
|
|
|
/* oldstyle zoom */
|
2011-04-22 14:47:35 +00:00
|
|
|
zfac = 1.0f + ((fac / 20.0f) * time_step);
|
2012-03-25 23:54:33 +00:00
|
|
|
vod->timer_lastdraw = time;
|
2008-12-19 17:14:02 +00:00
|
|
|
}
|
2012-03-25 23:54:33 +00:00
|
|
|
else if (viewzoom == USER_ZOOM_SCALE) {
|
2008-12-19 17:14:02 +00:00
|
|
|
int ctr[2], len1, len2;
|
2012-07-08 20:36:00 +00:00
|
|
|
/* method which zooms based on how far you move the mouse */
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2012-09-15 11:48:20 +00:00
|
|
|
ctr[0] = BLI_rcti_cent_x(&vod->ar->winrct);
|
|
|
|
|
ctr[1] = BLI_rcti_cent_y(&vod->ar->winrct);
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
len1 = (int)sqrt((ctr[0] - x) * (ctr[0] - x) + (ctr[1] - y) * (ctr[1] - y)) + 5;
|
|
|
|
|
len2 = (int)sqrt((ctr[0] - vod->origx) * (ctr[0] - vod->origx) + (ctr[1] - vod->origy) * (ctr[1] - vod->origy)) + 5;
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2013-04-04 04:22:38 +00:00
|
|
|
zfac = vod->dist_prev * ((float)len2 / len1) / vod->rv3d->dist;
|
2008-12-19 17:14:02 +00:00
|
|
|
}
|
2012-03-25 23:54:33 +00:00
|
|
|
else { /* USER_ZOOM_DOLLY */
|
2009-11-28 04:43:15 +00:00
|
|
|
float len1, len2;
|
|
|
|
|
|
2011-04-22 14:47:35 +00:00
|
|
|
if (U.uiflag & USER_ZOOM_HORIZ) {
|
2009-11-28 04:43:15 +00:00
|
|
|
len1 = (vod->ar->winrct.xmax - x) + 5;
|
|
|
|
|
len2 = (vod->ar->winrct.xmax - vod->origx) + 5;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
len1 = (vod->ar->winrct.ymax - y) + 5;
|
|
|
|
|
len2 = (vod->ar->winrct.ymax - vod->origy) + 5;
|
|
|
|
|
}
|
2011-04-22 14:47:35 +00:00
|
|
|
if (zoom_invert) {
|
2009-11-28 04:43:15 +00:00
|
|
|
SWAP(float, len1, len2);
|
2011-04-22 14:47:35 +00:00
|
|
|
}
|
2009-11-28 04:43:15 +00:00
|
|
|
|
2012-03-07 18:34:16 +00:00
|
|
|
if (use_cam_zoom) {
|
2012-08-26 18:21:34 +00:00
|
|
|
/* zfac is ignored in this case, see below */
|
|
|
|
|
#if 0
|
2013-04-04 04:22:38 +00:00
|
|
|
zfac = vod->camzoom_prev * (2.0f * ((len1 / len2) - 1.0f) + 1.0f) / vod->rv3d->camzoom;
|
2012-08-26 18:21:34 +00:00
|
|
|
#endif
|
2012-03-07 18:34:16 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2013-04-04 04:22:38 +00:00
|
|
|
zfac = vod->dist_prev * (2.0f * ((len1 / len2) - 1.0f) + 1.0f) / vod->rv3d->dist;
|
2012-03-07 18:34:16 +00:00
|
|
|
}
|
2008-12-19 17:14:02 +00:00
|
|
|
}
|
|
|
|
|
|
2012-03-07 18:34:16 +00:00
|
|
|
if (!use_cam_zoom) {
|
2012-03-25 23:54:33 +00:00
|
|
|
if (zfac != 1.0f && zfac * vod->rv3d->dist > 0.001f * vod->grid &&
|
|
|
|
|
zfac * vod->rv3d->dist < 10.0f * vod->far)
|
2012-04-28 06:31:57 +00:00
|
|
|
{
|
2012-03-07 18:34:16 +00:00
|
|
|
view_zoom_mouseloc(vod->ar, zfac, vod->oldx, vod->oldy);
|
2012-04-28 06:31:57 +00:00
|
|
|
}
|
2012-03-07 18:34:16 +00:00
|
|
|
}
|
2008-12-19 17:14:02 +00:00
|
|
|
|
2011-05-19 17:19:05 +00:00
|
|
|
/* these limits were in old code too */
|
2012-03-25 23:54:33 +00:00
|
|
|
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;
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (vod->rv3d->viewlock & RV3D_BOXVIEW)
|
2009-01-20 14:23:32 +00:00
|
|
|
view3d_boxview_sync(vod->sa, vod->ar);
|
|
|
|
|
|
2011-05-14 17:50:33 +00:00
|
|
|
ED_view3d_camera_lock_sync(vod->v3d, vod->rv3d);
|
|
|
|
|
|
2008-12-19 17:14:02 +00:00
|
|
|
ED_region_tag_redraw(vod->ar);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2013-03-13 09:03:46 +00:00
|
|
|
static int viewzoom_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
2008-12-26 10:31:44 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
ViewOpsData *vod = op->customdata;
|
|
|
|
|
short event_code = VIEW_PASS;
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2008-12-19 17:14:02 +00:00
|
|
|
/* execute the events */
|
2010-02-06 12:44:37 +00:00
|
|
|
if (event->type == TIMER && event->customdata == vod->timer) {
|
|
|
|
|
/* continuous zoom */
|
2012-03-25 23:54:33 +00:00
|
|
|
event_code = VIEW_APPLY;
|
2010-02-06 12:44:37 +00:00
|
|
|
}
|
2012-03-25 23:54:33 +00:00
|
|
|
else if (event->type == MOUSEMOVE) {
|
|
|
|
|
event_code = VIEW_APPLY;
|
2009-09-25 10:24:42 +00:00
|
|
|
}
|
2012-03-25 23:54:33 +00:00
|
|
|
else if (event->type == EVT_MODAL_MAP) {
|
2009-09-25 10:24:42 +00:00
|
|
|
switch (event->val) {
|
|
|
|
|
case VIEW_MODAL_CONFIRM:
|
2012-03-25 23:54:33 +00:00
|
|
|
event_code = VIEW_CONFIRM;
|
2009-09-25 10:24:42 +00:00
|
|
|
break;
|
2010-01-06 12:22:59 +00:00
|
|
|
case VIEWROT_MODAL_SWITCH_MOVE:
|
|
|
|
|
WM_operator_name_call(C, "VIEW3D_OT_move", WM_OP_INVOKE_DEFAULT, NULL);
|
2012-03-25 23:54:33 +00:00
|
|
|
event_code = VIEW_CONFIRM;
|
2010-01-06 12:22:59 +00:00
|
|
|
break;
|
|
|
|
|
case VIEWROT_MODAL_SWITCH_ROTATE:
|
|
|
|
|
WM_operator_name_call(C, "VIEW3D_OT_rotate", WM_OP_INVOKE_DEFAULT, NULL);
|
2012-03-25 23:54:33 +00:00
|
|
|
event_code = VIEW_CONFIRM;
|
2010-01-06 12:22:59 +00:00
|
|
|
break;
|
2009-09-25 10:24:42 +00:00
|
|
|
}
|
|
|
|
|
}
|
2012-03-25 23:54:33 +00:00
|
|
|
else if (event->type == vod->origkey && event->val == KM_RELEASE) {
|
|
|
|
|
event_code = VIEW_CONFIRM;
|
2009-09-25 10:24:42 +00:00
|
|
|
}
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
if (event_code == VIEW_APPLY) {
|
2011-04-22 14:47:35 +00:00
|
|
|
viewzoom_apply(vod, event->x, event->y, U.viewzoom, (U.uiflag & USER_ZOOM_INVERT) != 0);
|
2009-09-25 10:24:42 +00:00
|
|
|
}
|
2012-03-25 23:54:33 +00:00
|
|
|
else if (event_code == VIEW_CONFIRM) {
|
2011-05-21 08:56:37 +00:00
|
|
|
ED_view3d_depth_tag_update(vod->rv3d);
|
2009-11-25 14:13:43 +00:00
|
|
|
viewops_data_free(C, op);
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2009-09-25 10:24:42 +00:00
|
|
|
return OPERATOR_FINISHED;
|
2008-12-19 17:14:02 +00:00
|
|
|
}
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2008-12-19 17:14:02 +00:00
|
|
|
return OPERATOR_RUNNING_MODAL;
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-19 19:27:41 +00:00
|
|
|
static int viewzoom_exec(bContext *C, wmOperator *op)
|
2008-12-19 17:14:02 +00:00
|
|
|
{
|
2011-01-03 01:26:54 +00:00
|
|
|
View3D *v3d;
|
|
|
|
|
RegionView3D *rv3d;
|
|
|
|
|
ScrArea *sa;
|
|
|
|
|
ARegion *ar;
|
2013-03-22 04:40:45 +00:00
|
|
|
bool use_cam_zoom;
|
2011-01-03 01:26:54 +00:00
|
|
|
|
2013-03-22 04:40:45 +00:00
|
|
|
const int delta = RNA_int_get(op->ptr, "delta");
|
2011-01-03 01:26:54 +00:00
|
|
|
int mx, my;
|
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (op->customdata) {
|
2012-03-25 23:54:33 +00:00
|
|
|
ViewOpsData *vod = op->customdata;
|
2011-01-03 01:26:54 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
sa = vod->sa;
|
|
|
|
|
ar = vod->ar;
|
2011-01-03 01:26:54 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2012-03-25 23:54:33 +00:00
|
|
|
sa = CTX_wm_area(C);
|
|
|
|
|
ar = CTX_wm_region(C);
|
2011-01-03 01:26:54 +00:00
|
|
|
}
|
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
v3d = sa->spacedata.first;
|
|
|
|
|
rv3d = ar->regiondata;
|
2011-01-03 01:26:54 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
mx = RNA_struct_property_is_set(op->ptr, "mx") ? RNA_int_get(op->ptr, "mx") : ar->winx / 2;
|
|
|
|
|
my = RNA_struct_property_is_set(op->ptr, "my") ? RNA_int_get(op->ptr, "my") : ar->winy / 2;
|
2008-12-19 19:27:41 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
use_cam_zoom = (rv3d->persp == RV3D_CAMOB) && !(rv3d->is_persp && ED_view3d_camera_lock_check(v3d, rv3d));
|
2011-05-19 17:19:05 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (delta < 0) {
|
2008-12-19 19:27:41 +00:00
|
|
|
/* this min and max is also in viewmove() */
|
2012-02-22 16:52:06 +00:00
|
|
|
if (use_cam_zoom) {
|
2012-03-07 19:42:22 +00:00
|
|
|
rv3d->camzoom -= 10.0f;
|
2012-03-25 23:54:33 +00:00
|
|
|
if (rv3d->camzoom < RV3D_CAMZOOM_MIN) rv3d->camzoom = RV3D_CAMZOOM_MIN;
|
2008-12-19 19:27:41 +00:00
|
|
|
}
|
2012-02-22 16:52:06 +00:00
|
|
|
else if (rv3d->dist < 10.0f * v3d->far) {
|
2011-01-03 01:26:54 +00:00
|
|
|
view_zoom_mouseloc(ar, 1.2f, mx, my);
|
2009-10-16 00:23:40 +00:00
|
|
|
}
|
2008-12-19 19:27:41 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2012-02-22 16:52:06 +00:00
|
|
|
if (use_cam_zoom) {
|
2012-03-07 19:42:22 +00:00
|
|
|
rv3d->camzoom += 10.0f;
|
2012-03-25 23:54:33 +00:00
|
|
|
if (rv3d->camzoom > RV3D_CAMZOOM_MAX) rv3d->camzoom = RV3D_CAMZOOM_MAX;
|
2008-12-19 19:27:41 +00:00
|
|
|
}
|
2012-03-25 23:54:33 +00:00
|
|
|
else if (rv3d->dist > 0.001f * v3d->grid) {
|
2012-06-17 09:58:26 +00:00
|
|
|
view_zoom_mouseloc(ar, 0.83333f, mx, my);
|
2009-10-16 00:23:40 +00:00
|
|
|
}
|
2008-12-19 19:27:41 +00:00
|
|
|
}
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (rv3d->viewlock & RV3D_BOXVIEW)
|
2011-01-03 01:26:54 +00:00
|
|
|
view3d_boxview_sync(sa, ar);
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2011-05-21 08:56:37 +00:00
|
|
|
ED_view3d_depth_tag_update(rv3d);
|
2011-05-14 17:50:33 +00:00
|
|
|
|
|
|
|
|
ED_view3d_camera_lock_sync(v3d, rv3d);
|
|
|
|
|
|
2011-01-03 01:26:54 +00:00
|
|
|
ED_region_tag_redraw(ar);
|
|
|
|
|
|
2010-01-19 04:14:57 +00:00
|
|
|
viewops_data_free(C, op);
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2008-12-19 19:27:41 +00:00
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
2011-05-22 11:36:56 +00:00
|
|
|
/* this is an exact copy of viewzoom_modal_keymap */
|
|
|
|
|
/* called in transform_ops.c, on each regeneration of keymaps */
|
|
|
|
|
void viewdolly_modal_keymap(wmKeyConfig *keyconf)
|
|
|
|
|
{
|
|
|
|
|
static EnumPropertyItem modal_items[] = {
|
2012-03-25 23:54:33 +00:00
|
|
|
{VIEW_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""},
|
2011-05-22 11:36:56 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
{VIEWROT_MODAL_SWITCH_ROTATE, "SWITCH_TO_ROTATE", 0, "Switch to Rotate"},
|
|
|
|
|
{VIEWROT_MODAL_SWITCH_MOVE, "SWITCH_TO_MOVE", 0, "Switch to Move"},
|
2011-05-22 11:36:56 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
{0, NULL, 0, NULL, NULL}
|
|
|
|
|
};
|
2011-05-22 11:36:56 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "View3D Dolly Modal");
|
2011-05-22 11:36:56 +00:00
|
|
|
|
|
|
|
|
/* this function is called for each spacetype, only needs to add map once */
|
2012-04-17 15:40:04 +00:00
|
|
|
if (keymap && keymap->modal_items) return;
|
2011-05-22 11:36:56 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
keymap = WM_modalkeymap_add(keyconf, "View3D Dolly Modal", modal_items);
|
2011-05-22 11:36:56 +00:00
|
|
|
|
|
|
|
|
/* items for modal map */
|
|
|
|
|
WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, KM_ANY, 0, VIEW_MODAL_CONFIRM);
|
|
|
|
|
WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, VIEW_MODAL_CONFIRM);
|
|
|
|
|
|
2012-03-03 16:31:46 +00:00
|
|
|
/* disabled mode switching for now, can re-implement better, later on */
|
|
|
|
|
#if 0
|
2011-05-22 11:36:56 +00:00
|
|
|
WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_RELEASE, KM_ANY, 0, VIEWROT_MODAL_SWITCH_ROTATE);
|
|
|
|
|
WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_RELEASE, KM_ANY, 0, VIEWROT_MODAL_SWITCH_ROTATE);
|
|
|
|
|
WM_modalkeymap_add_item(keymap, LEFTSHIFTKEY, KM_PRESS, KM_ANY, 0, VIEWROT_MODAL_SWITCH_MOVE);
|
2012-03-03 16:31:46 +00:00
|
|
|
#endif
|
2011-05-22 11:36:56 +00:00
|
|
|
|
|
|
|
|
/* assign map to operators */
|
|
|
|
|
WM_modalkeymap_assign(keymap, "VIEW3D_OT_dolly");
|
|
|
|
|
}
|
|
|
|
|
|
2011-04-22 15:34:07 +00:00
|
|
|
/* viewdolly_invoke() copied this function, changes here may apply there */
|
2013-03-13 09:03:46 +00:00
|
|
|
static int viewzoom_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
2008-12-19 19:27:41 +00:00
|
|
|
{
|
2011-05-14 05:42:58 +00:00
|
|
|
ViewOpsData *vod;
|
|
|
|
|
|
|
|
|
|
/* makes op->customdata */
|
2013-09-20 01:24:00 +00:00
|
|
|
viewops_data_alloc(C, op);
|
2011-05-14 05:42:58 +00:00
|
|
|
viewops_data_create(C, op, event);
|
2012-03-25 23:54:33 +00:00
|
|
|
vod = op->customdata;
|
2011-05-14 05:42:58 +00:00
|
|
|
|
2009-10-16 00:23:40 +00:00
|
|
|
/* if one or the other zoom position aren't set, set from event */
|
2012-01-11 16:32:12 +00:00
|
|
|
if (!RNA_struct_property_is_set(op->ptr, "mx") || !RNA_struct_property_is_set(op->ptr, "my")) {
|
2009-10-16 00:23:40 +00:00
|
|
|
RNA_int_set(op->ptr, "mx", event->x);
|
|
|
|
|
RNA_int_set(op->ptr, "my", event->y);
|
|
|
|
|
}
|
2008-12-19 19:27:41 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (RNA_struct_property_is_set(op->ptr, "delta")) {
|
2008-12-19 19:27:41 +00:00
|
|
|
viewzoom_exec(C, op);
|
|
|
|
|
}
|
|
|
|
|
else {
|
Holiday coding log :)
Nice formatted version (pictures soon):
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.66/Usability
Short list of main changes:
- Transparent region option (over main region), added code to blend in/out such panels.
- Min size window now 640 x 480
- Fixed DPI for ui - lots of cleanup and changes everywhere. Icon image need correct size still, layer-in-use icon needs remake.
- Macbook retina support, use command line --no-native-pixels to disable it
- Timeline Marker label was drawing wrong
- Trackpad and magic mouse: supports zoom (hold ctrl)
- Fix for splash position: removed ghost function and made window size update after creation immediate
- Fast undo buffer save now adds UI as well. Could be checked for regular file save even...
Quit.blend and temp file saving use this now.
- Dixed filename in window on reading quit.blend or temp saves, and they now add a warning in window title: "(Recovered)"
- New Userpref option "Keep Session" - this always saves quit.blend, and loads on start.
This allows keeping UI and data without actual saves, until you actually save.
When you load startup.blend and quit, it recognises the quit.blend as a startup (no file name in header)
- Added 3D view copy/paste buffers (selected objects). Shortcuts ctrl-c, ctrl-v (OSX, cmd-c, cmd-v).
Coded partial file saving for it. Could be used for other purposes. Todo: use OS clipboards.
- User preferences (themes, keymaps, user settings) now can be saved as a separate file.
Old option is called "Save Startup File" the new one "Save User Settings".
To visualise this difference, the 'save startup file' button has been removed from user preferences window. That option is available as CTRL+U and in File menu still.
- OSX: fixed bug that stopped giving mouse events outside window.
This also fixes "Continuous Grab" for OSX. (error since 2009)
2012-12-12 18:58:11 +00:00
|
|
|
if (event->type == MOUSEZOOM || event->type == MOUSEPAN) {
|
2009-12-16 23:05:59 +00:00
|
|
|
|
2011-04-22 14:47:35 +00:00
|
|
|
if (U.uiflag & USER_ZOOM_HORIZ) {
|
2010-01-11 11:14:36 +00:00
|
|
|
vod->origx = vod->oldx = event->x;
|
2013-01-06 11:16:49 +00:00
|
|
|
viewzoom_apply(vod, event->prevx, event->prevy, USER_ZOOM_DOLLY, (U.uiflag & USER_ZOOM_INVERT) != 0);
|
2010-01-11 11:14:36 +00:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* Set y move = x move as MOUSEZOOM uses only x axis to pass magnification value */
|
2010-05-29 21:31:57 +00:00
|
|
|
vod->origy = vod->oldy = vod->origy + event->x - event->prevx;
|
2013-01-06 11:16:49 +00:00
|
|
|
viewzoom_apply(vod, event->prevx, event->prevy, USER_ZOOM_DOLLY, (U.uiflag & USER_ZOOM_INVERT) != 0);
|
2010-01-11 11:14:36 +00:00
|
|
|
}
|
2011-05-21 08:56:37 +00:00
|
|
|
ED_view3d_depth_tag_update(vod->rv3d);
|
2010-01-11 11:14:36 +00:00
|
|
|
|
|
|
|
|
viewops_data_free(C, op);
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
else {
|
2012-02-22 16:52:06 +00:00
|
|
|
if (U.viewzoom == USER_ZOOM_CONT) {
|
2010-02-06 12:44:37 +00:00
|
|
|
/* needs a timer to continue redrawing */
|
2012-03-25 23:54:33 +00:00
|
|
|
vod->timer = WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, 0.01f);
|
|
|
|
|
vod->timer_lastdraw = PIL_check_seconds_timer();
|
2010-02-06 12:44:37 +00:00
|
|
|
}
|
|
|
|
|
|
2010-01-11 11:14:36 +00:00
|
|
|
/* add temp handler */
|
|
|
|
|
WM_event_add_modal_handler(C, op);
|
|
|
|
|
|
|
|
|
|
return OPERATOR_RUNNING_MODAL;
|
|
|
|
|
}
|
2008-12-19 19:27:41 +00:00
|
|
|
}
|
|
|
|
|
return OPERATOR_FINISHED;
|
2008-12-19 17:14:02 +00:00
|
|
|
}
|
|
|
|
|
|
2013-10-30 23:08:53 +00:00
|
|
|
static void viewzoom_cancel(bContext *C, wmOperator *op)
|
2011-06-06 11:04:54 +00:00
|
|
|
{
|
|
|
|
|
viewops_data_free(C, op);
|
|
|
|
|
}
|
2008-12-19 17:14:02 +00:00
|
|
|
|
2009-03-29 02:15:13 +00:00
|
|
|
void VIEW3D_OT_zoom(wmOperatorType *ot)
|
2008-12-19 17:14:02 +00:00
|
|
|
{
|
|
|
|
|
/* identifiers */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Zoom View";
|
2010-02-10 21:15:44 +00:00
|
|
|
ot->description = "Zoom in/out in the view";
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->idname = "VIEW3D_OT_zoom";
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2008-12-19 17:14:02 +00:00
|
|
|
/* api callbacks */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->invoke = viewzoom_invoke;
|
|
|
|
|
ot->exec = viewzoom_exec;
|
|
|
|
|
ot->modal = viewzoom_modal;
|
|
|
|
|
ot->poll = ED_operator_region_view3d_active;
|
|
|
|
|
ot->cancel = viewzoom_cancel;
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2009-01-31 19:40:40 +00:00
|
|
|
/* flags */
|
2012-03-25 23:54:33 +00:00
|
|
|
ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_POINTER;
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2009-11-23 17:07:30 +00:00
|
|
|
RNA_def_int(ot->srna, "delta", 0, INT_MIN, INT_MAX, "Delta", "", INT_MIN, INT_MAX);
|
2009-10-16 00:23:40 +00:00
|
|
|
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);
|
2008-12-19 17:14:02 +00:00
|
|
|
}
|
|
|
|
|
|
2011-04-22 15:34:07 +00:00
|
|
|
|
|
|
|
|
/* ************************ viewdolly ******************************** */
|
|
|
|
|
static void view_dolly_mouseloc(ARegion *ar, float orig_ofs[3], float dvec[3], float dfac)
|
|
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
2011-08-19 16:21:29 +00:00
|
|
|
madd_v3_v3v3fl(rv3d->ofs, orig_ofs, dvec, -(1.0f - dfac));
|
2011-04-22 15:34:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void viewdolly_apply(ViewOpsData *vod, int x, int y, const short zoom_invert)
|
|
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
float zfac = 1.0;
|
2011-04-22 15:34:07 +00:00
|
|
|
|
|
|
|
|
{
|
|
|
|
|
float len1, len2;
|
|
|
|
|
|
|
|
|
|
if (U.uiflag & USER_ZOOM_HORIZ) {
|
|
|
|
|
len1 = (vod->ar->winrct.xmax - x) + 5;
|
|
|
|
|
len2 = (vod->ar->winrct.xmax - vod->origx) + 5;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
len1 = (vod->ar->winrct.ymax - y) + 5;
|
|
|
|
|
len2 = (vod->ar->winrct.ymax - vod->origy) + 5;
|
|
|
|
|
}
|
|
|
|
|
if (zoom_invert)
|
|
|
|
|
SWAP(float, len1, len2);
|
|
|
|
|
|
2012-10-13 16:42:12 +00:00
|
|
|
zfac = 1.0f + ((len1 - len2) * 0.01f * vod->rv3d->dist);
|
2011-04-22 15:34:07 +00:00
|
|
|
}
|
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (zfac != 1.0f)
|
2011-04-22 15:34:07 +00:00
|
|
|
view_dolly_mouseloc(vod->ar, vod->ofs, vod->mousevec, zfac);
|
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (vod->rv3d->viewlock & RV3D_BOXVIEW)
|
2011-04-22 15:34:07 +00:00
|
|
|
view3d_boxview_sync(vod->sa, vod->ar);
|
|
|
|
|
|
2011-05-14 17:50:33 +00:00
|
|
|
ED_view3d_camera_lock_sync(vod->v3d, vod->rv3d);
|
|
|
|
|
|
2011-04-22 15:34:07 +00:00
|
|
|
ED_region_tag_redraw(vod->ar);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2013-03-13 09:03:46 +00:00
|
|
|
static int viewdolly_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
2011-04-22 15:34:07 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
ViewOpsData *vod = op->customdata;
|
|
|
|
|
short event_code = VIEW_PASS;
|
2011-04-22 15:34:07 +00:00
|
|
|
|
|
|
|
|
/* execute the events */
|
2012-03-25 23:54:33 +00:00
|
|
|
if (event->type == MOUSEMOVE) {
|
|
|
|
|
event_code = VIEW_APPLY;
|
2011-04-22 15:34:07 +00:00
|
|
|
}
|
2012-03-25 23:54:33 +00:00
|
|
|
else if (event->type == EVT_MODAL_MAP) {
|
2011-04-22 15:34:07 +00:00
|
|
|
switch (event->val) {
|
|
|
|
|
case VIEW_MODAL_CONFIRM:
|
2012-03-25 23:54:33 +00:00
|
|
|
event_code = VIEW_CONFIRM;
|
2011-04-22 15:34:07 +00:00
|
|
|
break;
|
|
|
|
|
case VIEWROT_MODAL_SWITCH_MOVE:
|
|
|
|
|
WM_operator_name_call(C, "VIEW3D_OT_move", WM_OP_INVOKE_DEFAULT, NULL);
|
2012-03-25 23:54:33 +00:00
|
|
|
event_code = VIEW_CONFIRM;
|
2011-04-22 15:34:07 +00:00
|
|
|
break;
|
|
|
|
|
case VIEWROT_MODAL_SWITCH_ROTATE:
|
|
|
|
|
WM_operator_name_call(C, "VIEW3D_OT_rotate", WM_OP_INVOKE_DEFAULT, NULL);
|
2012-03-25 23:54:33 +00:00
|
|
|
event_code = VIEW_CONFIRM;
|
2011-04-22 15:34:07 +00:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-03-25 23:54:33 +00:00
|
|
|
else if (event->type == vod->origkey && event->val == KM_RELEASE) {
|
|
|
|
|
event_code = VIEW_CONFIRM;
|
2011-04-22 15:34:07 +00:00
|
|
|
}
|
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
if (event_code == VIEW_APPLY) {
|
2011-04-22 15:34:07 +00:00
|
|
|
viewdolly_apply(vod, event->x, event->y, (U.uiflag & USER_ZOOM_INVERT) != 0);
|
|
|
|
|
}
|
2012-03-25 23:54:33 +00:00
|
|
|
else if (event_code == VIEW_CONFIRM) {
|
2011-05-21 08:56:37 +00:00
|
|
|
ED_view3d_depth_tag_update(vod->rv3d);
|
2011-04-22 15:34:07 +00:00
|
|
|
viewops_data_free(C, op);
|
|
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return OPERATOR_RUNNING_MODAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int viewdolly_exec(bContext *C, wmOperator *op)
|
|
|
|
|
{
|
2013-07-21 09:59:08 +00:00
|
|
|
View3D *v3d;
|
2011-04-22 15:34:07 +00:00
|
|
|
RegionView3D *rv3d;
|
|
|
|
|
ScrArea *sa;
|
|
|
|
|
ARegion *ar;
|
|
|
|
|
float mousevec[3];
|
|
|
|
|
|
2013-03-22 04:40:45 +00:00
|
|
|
const int delta = RNA_int_get(op->ptr, "delta");
|
2011-04-22 15:34:07 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (op->customdata) {
|
2012-03-25 23:54:33 +00:00
|
|
|
ViewOpsData *vod = op->customdata;
|
2011-04-22 15:34:07 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
sa = vod->sa;
|
|
|
|
|
ar = vod->ar;
|
2011-04-22 15:34:07 +00:00
|
|
|
copy_v3_v3(mousevec, vod->mousevec);
|
|
|
|
|
}
|
|
|
|
|
else {
|
2012-03-25 23:54:33 +00:00
|
|
|
sa = CTX_wm_area(C);
|
|
|
|
|
ar = CTX_wm_region(C);
|
2011-05-12 06:52:24 +00:00
|
|
|
negate_v3_v3(mousevec, ((RegionView3D *)ar->regiondata)->viewinv[2]);
|
|
|
|
|
normalize_v3(mousevec);
|
2011-04-22 15:34:07 +00:00
|
|
|
}
|
|
|
|
|
|
2013-07-21 09:59:08 +00:00
|
|
|
v3d = sa->spacedata.first;
|
2012-03-25 23:54:33 +00:00
|
|
|
rv3d = ar->regiondata;
|
2011-04-22 15:34:07 +00:00
|
|
|
|
|
|
|
|
/* overwrite the mouse vector with the view direction (zoom into the center) */
|
2012-02-22 16:52:06 +00:00
|
|
|
if ((U.uiflag & USER_ZOOM_TO_MOUSEPOS) == 0) {
|
2011-04-22 15:34:07 +00:00
|
|
|
normalize_v3_v3(mousevec, rv3d->viewinv[2]);
|
|
|
|
|
}
|
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (delta < 0) {
|
2013-07-19 11:19:29 +00:00
|
|
|
view_dolly_mouseloc(ar, rv3d->ofs, mousevec, 0.2f);
|
2011-04-22 15:34:07 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2013-07-19 11:19:29 +00:00
|
|
|
view_dolly_mouseloc(ar, rv3d->ofs, mousevec, 1.8f);
|
2011-04-22 15:34:07 +00:00
|
|
|
}
|
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (rv3d->viewlock & RV3D_BOXVIEW)
|
2011-04-22 15:34:07 +00:00
|
|
|
view3d_boxview_sync(sa, ar);
|
|
|
|
|
|
2011-05-21 08:56:37 +00:00
|
|
|
ED_view3d_depth_tag_update(rv3d);
|
2013-07-21 09:59:08 +00:00
|
|
|
|
|
|
|
|
ED_view3d_camera_lock_sync(v3d, rv3d);
|
|
|
|
|
|
2011-04-22 15:34:07 +00:00
|
|
|
ED_region_tag_redraw(ar);
|
|
|
|
|
|
|
|
|
|
viewops_data_free(C, op);
|
|
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* copied from viewzoom_invoke(), changes here may apply there */
|
2013-03-13 09:03:46 +00:00
|
|
|
static int viewdolly_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
2011-05-14 05:42:58 +00:00
|
|
|
{
|
|
|
|
|
ViewOpsData *vod;
|
|
|
|
|
|
2013-09-20 01:43:06 +00:00
|
|
|
if (view3d_operator_offset_lock_check(C, op))
|
|
|
|
|
return OPERATOR_CANCELLED;
|
2013-05-03 07:29:25 +00:00
|
|
|
|
2011-05-14 05:42:58 +00:00
|
|
|
/* makes op->customdata */
|
2013-09-20 01:24:00 +00:00
|
|
|
viewops_data_alloc(C, op);
|
2012-03-25 23:54:33 +00:00
|
|
|
vod = op->customdata;
|
2011-05-14 05:42:58 +00:00
|
|
|
|
2014-02-04 21:04:36 +11:00
|
|
|
/* poll should check but in some cases fails, see poll func for details */
|
2014-02-12 11:26:02 +11:00
|
|
|
if (vod->rv3d->viewlock & RV3D_LOCKED) {
|
2013-09-20 01:24:00 +00:00
|
|
|
viewops_data_free(C, op);
|
|
|
|
|
return OPERATOR_PASS_THROUGH;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* needs to run before 'viewops_data_create' so the backup 'rv3d->ofs' is correct */
|
|
|
|
|
/* switch from camera view when: */
|
|
|
|
|
if (vod->rv3d->persp != RV3D_PERSP) {
|
|
|
|
|
if (vod->rv3d->persp == RV3D_CAMOB) {
|
|
|
|
|
/* ignore rv3d->lpersp because dolly only makes sense in perspective mode */
|
|
|
|
|
view3d_persp_switch_from_camera(vod->v3d, vod->rv3d, RV3D_PERSP);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
vod->rv3d->persp = RV3D_PERSP;
|
|
|
|
|
}
|
|
|
|
|
ED_region_tag_redraw(vod->ar);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
viewops_data_create(C, op, event);
|
|
|
|
|
|
|
|
|
|
|
2011-04-22 15:34:07 +00:00
|
|
|
/* if one or the other zoom position aren't set, set from event */
|
2012-01-11 16:32:12 +00:00
|
|
|
if (!RNA_struct_property_is_set(op->ptr, "mx") || !RNA_struct_property_is_set(op->ptr, "my")) {
|
2011-04-22 15:34:07 +00:00
|
|
|
RNA_int_set(op->ptr, "mx", event->x);
|
|
|
|
|
RNA_int_set(op->ptr, "my", event->y);
|
|
|
|
|
}
|
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (RNA_struct_property_is_set(op->ptr, "delta")) {
|
2011-04-22 15:34:07 +00:00
|
|
|
viewdolly_exec(C, op);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* overwrite the mouse vector with the view direction (zoom into the center) */
|
2012-02-22 16:52:06 +00:00
|
|
|
if ((U.uiflag & USER_ZOOM_TO_MOUSEPOS) == 0) {
|
2011-05-12 06:52:24 +00:00
|
|
|
negate_v3_v3(vod->mousevec, vod->rv3d->viewinv[2]);
|
|
|
|
|
normalize_v3(vod->mousevec);
|
2011-04-22 15:34:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (event->type == MOUSEZOOM) {
|
2013-03-20 23:14:18 +00:00
|
|
|
/* Bypass Zoom invert flag for track pads (pass false always) */
|
2011-04-22 15:34:07 +00:00
|
|
|
|
|
|
|
|
if (U.uiflag & USER_ZOOM_HORIZ) {
|
|
|
|
|
vod->origx = vod->oldx = event->x;
|
2012-10-13 16:42:12 +00:00
|
|
|
viewdolly_apply(vod, event->prevx, event->prevy, (U.uiflag & USER_ZOOM_INVERT) == 0);
|
2011-04-22 15:34:07 +00:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
|
|
/* Set y move = x move as MOUSEZOOM uses only x axis to pass magnification value */
|
|
|
|
|
vod->origy = vod->oldy = vod->origy + event->x - event->prevx;
|
2012-10-13 16:42:12 +00:00
|
|
|
viewdolly_apply(vod, event->prevx, event->prevy, (U.uiflag & USER_ZOOM_INVERT) == 0);
|
2011-04-22 15:34:07 +00:00
|
|
|
}
|
2011-05-21 08:56:37 +00:00
|
|
|
ED_view3d_depth_tag_update(vod->rv3d);
|
2011-04-22 15:34:07 +00:00
|
|
|
|
|
|
|
|
viewops_data_free(C, op);
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* add temp handler */
|
|
|
|
|
WM_event_add_modal_handler(C, op);
|
|
|
|
|
|
|
|
|
|
return OPERATOR_RUNNING_MODAL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
2013-10-30 23:08:53 +00:00
|
|
|
static void viewdolly_cancel(bContext *C, wmOperator *op)
|
2011-06-06 11:04:54 +00:00
|
|
|
{
|
|
|
|
|
viewops_data_free(C, op);
|
|
|
|
|
}
|
|
|
|
|
|
2011-04-22 15:34:07 +00:00
|
|
|
void VIEW3D_OT_dolly(wmOperatorType *ot)
|
|
|
|
|
{
|
|
|
|
|
/* identifiers */
|
2013-01-27 07:23:58 +00:00
|
|
|
ot->name = "Dolly View";
|
2011-04-22 15:34:07 +00:00
|
|
|
ot->description = "Dolly in/out in the view";
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->idname = "VIEW3D_OT_dolly";
|
2011-04-22 15:34:07 +00:00
|
|
|
|
|
|
|
|
/* api callbacks */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->invoke = viewdolly_invoke;
|
|
|
|
|
ot->exec = viewdolly_exec;
|
|
|
|
|
ot->modal = viewdolly_modal;
|
2013-09-20 01:24:00 +00:00
|
|
|
ot->poll = ED_operator_region_view3d_active;
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->cancel = viewdolly_cancel;
|
2011-04-22 15:34:07 +00:00
|
|
|
|
|
|
|
|
/* flags */
|
2012-03-25 23:54:33 +00:00
|
|
|
ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_POINTER;
|
2011-04-22 15:34:07 +00:00
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2012-10-10 12:22:45 +00:00
|
|
|
static void view3d_from_minmax(bContext *C, View3D *v3d, ARegion *ar,
|
2013-09-16 08:59:54 +00:00
|
|
|
const float min[3], const float max[3],
|
|
|
|
|
bool ok_dist, const int smooth_viewtx)
|
2012-10-10 12:22:45 +00:00
|
|
|
{
|
|
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
|
|
|
|
float afm[3];
|
|
|
|
|
float size;
|
|
|
|
|
|
|
|
|
|
/* SMOOTHVIEW */
|
|
|
|
|
float new_ofs[3];
|
|
|
|
|
float new_dist;
|
|
|
|
|
|
|
|
|
|
sub_v3_v3v3(afm, max, min);
|
2012-12-21 05:07:26 +00:00
|
|
|
size = max_fff(afm[0], afm[1], afm[2]);
|
2012-10-10 12:22:45 +00:00
|
|
|
|
|
|
|
|
if (ok_dist) {
|
|
|
|
|
/* fix up zoom distance if needed */
|
|
|
|
|
|
|
|
|
|
if (rv3d->is_persp) {
|
2012-11-30 04:40:32 +00:00
|
|
|
float lens, sensor_size;
|
2012-11-30 04:25:58 +00:00
|
|
|
/* offset the view based on the lens */
|
2012-11-30 04:40:32 +00:00
|
|
|
if (rv3d->persp == RV3D_CAMOB && ED_view3d_camera_lock_check(v3d, rv3d)) {
|
|
|
|
|
CameraParams params;
|
|
|
|
|
BKE_camera_params_init(¶ms);
|
2014-03-01 21:41:07 +11:00
|
|
|
params.clipsta = v3d->near;
|
|
|
|
|
params.clipend = v3d->far;
|
2012-11-30 04:40:32 +00:00
|
|
|
BKE_camera_params_from_object(¶ms, v3d->camera);
|
|
|
|
|
|
|
|
|
|
lens = params.lens;
|
|
|
|
|
sensor_size = BKE_camera_sensor_size(params.sensor_fit, params.sensor_x, params.sensor_y);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
lens = v3d->lens;
|
|
|
|
|
sensor_size = DEFAULT_SENSOR_WIDTH;
|
|
|
|
|
}
|
2012-11-30 06:55:36 +00:00
|
|
|
size = ED_view3d_radius_to_persp_dist(focallength_to_fov(lens, sensor_size), size / 2.0f) * VIEW3D_MARGIN;
|
2012-11-30 04:40:32 +00:00
|
|
|
|
2012-11-30 05:29:34 +00:00
|
|
|
/* do not zoom closer than the near clipping plane */
|
|
|
|
|
size = max_ff(size, v3d->near * 1.5f);
|
2012-10-10 12:22:45 +00:00
|
|
|
}
|
|
|
|
|
else { /* ortho */
|
|
|
|
|
if (size < 0.0001f) {
|
|
|
|
|
/* bounding box was a single point so do not zoom */
|
2013-03-20 23:14:18 +00:00
|
|
|
ok_dist = false;
|
2012-10-10 12:22:45 +00:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* adjust zoom so it looks nicer */
|
2012-11-30 06:55:36 +00:00
|
|
|
size = ED_view3d_radius_to_ortho_dist(v3d->lens, size / 2.0f) * VIEW3D_MARGIN;
|
2012-10-10 12:22:45 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-10-30 14:22:49 +00:00
|
|
|
mid_v3_v3v3(new_ofs, min, max);
|
|
|
|
|
negate_v3(new_ofs);
|
2012-10-10 12:22:45 +00:00
|
|
|
|
|
|
|
|
new_dist = size;
|
|
|
|
|
|
|
|
|
|
/* correction for window aspect ratio */
|
|
|
|
|
if (ar->winy > 2 && ar->winx > 2) {
|
|
|
|
|
size = (float)ar->winx / (float)ar->winy;
|
|
|
|
|
if (size < 1.0f) size = 1.0f / size;
|
|
|
|
|
new_dist *= size;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (rv3d->persp == RV3D_CAMOB && !ED_view3d_camera_lock_check(v3d, rv3d)) {
|
|
|
|
|
rv3d->persp = RV3D_PERSP;
|
2013-09-16 04:04:44 +00:00
|
|
|
ED_view3d_smooth_view(C, v3d, ar, v3d->camera, NULL,
|
|
|
|
|
new_ofs, NULL, ok_dist ? &new_dist : NULL, NULL,
|
|
|
|
|
smooth_viewtx);
|
2012-10-10 12:22:45 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2013-09-16 04:04:44 +00:00
|
|
|
ED_view3d_smooth_view(C, v3d, ar, NULL, NULL,
|
|
|
|
|
new_ofs, NULL, ok_dist ? &new_dist : NULL, NULL,
|
|
|
|
|
smooth_viewtx);
|
2012-10-10 12:22:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* smooth view does viewlock RV3D_BOXVIEW copy */
|
|
|
|
|
}
|
2011-04-22 15:34:07 +00:00
|
|
|
|
2012-10-10 12:22:45 +00:00
|
|
|
/* same as view3d_from_minmax but for all regions (except cameras) */
|
|
|
|
|
static void view3d_from_minmax_multi(bContext *C, View3D *v3d,
|
|
|
|
|
const float min[3], const float max[3],
|
2013-09-16 04:04:44 +00:00
|
|
|
const bool ok_dist, const int smooth_viewtx)
|
2012-10-10 12:22:45 +00:00
|
|
|
{
|
|
|
|
|
ScrArea *sa = CTX_wm_area(C);
|
|
|
|
|
ARegion *ar;
|
|
|
|
|
for (ar = sa->regionbase.first; ar; ar = ar->next) {
|
|
|
|
|
if (ar->regiontype == RGN_TYPE_WINDOW) {
|
|
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
|
|
|
|
/* when using all regions, don't jump out of camera view,
|
|
|
|
|
* but _do_ allow locked cameras to be moved */
|
|
|
|
|
if ((rv3d->persp != RV3D_CAMOB) || ED_view3d_camera_lock_check(v3d, rv3d)) {
|
2013-09-16 04:04:44 +00:00
|
|
|
view3d_from_minmax(C, v3d, ar, min, max, ok_dist, smooth_viewtx);
|
2012-10-10 12:22:45 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2011-04-22 15:34:07 +00:00
|
|
|
|
2010-10-05 13:15:58 +00:00
|
|
|
static int view3d_all_exec(bContext *C, wmOperator *op) /* was view3d_home() in 2.4x */
|
2008-12-20 11:33:16 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
ARegion *ar = CTX_wm_region(C);
|
2.5
View3D has been split now in a local part (RegionView3D) and a
per-area part (old View3D). Currently local is:
- view transform
- camera zoom/offset
- gpencil (todo)
- custom clipping planes
Rest is in Area still, like active camera, draw type, layers,
localview, custom centers, around-settings, transform widget,
gridlines, and so on (mostly stuff as available in header).
To see it work; also added new feature for region split,
press SHIFT+ALT+CTRL+S for four-split.
The idea is to make a preset 4-split, configured to stick
to top/right/front views for three views.
Another cool idea to explore is to then box-clip all drawing
based on these 3 views.
Note about the code:
- currently view3d still stores some depricated settings, to
convert from older files. Not all settings are copied over
though, like custom clip planes or the 'lock view to object'.
- since some view3d ops are now on area level, the operators
for it should keep track of that.
Bugfix in transform: quat initialize in operator-invoke missed
one zero.
Als brought back GE to compile for missing Ipos and channels.
2009-01-19 16:54:41 +00:00
|
|
|
View3D *v3d = CTX_wm_view3d(C);
|
2012-03-25 23:54:33 +00:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
2008-12-20 11:33:16 +00:00
|
|
|
Base *base;
|
2009-08-20 21:09:48 +00:00
|
|
|
float *curs;
|
2013-03-22 04:40:45 +00:00
|
|
|
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 */
|
|
|
|
|
(use_all_regions && v3d->flag2 & V3D_LOCK_CAMERA));
|
|
|
|
|
const bool center = RNA_boolean_get(op->ptr, "center");
|
2013-09-16 04:04:44 +00:00
|
|
|
const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2012-10-10 12:22:45 +00:00
|
|
|
float min[3], max[3];
|
2013-11-26 06:39:14 +11:00
|
|
|
bool changed = false;
|
2008-12-20 11:33:16 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (center) {
|
2009-08-20 21:09:48 +00:00
|
|
|
/* in 2.4x this also move the cursor to (0, 0, 0) (with shift+c). */
|
2013-10-26 04:07:18 +00:00
|
|
|
curs = ED_view3d_cursor3d_get(scene, v3d);
|
2010-10-05 13:15:58 +00:00
|
|
|
zero_v3(min);
|
|
|
|
|
zero_v3(max);
|
|
|
|
|
zero_v3(curs);
|
2008-12-20 11:33:16 +00:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
INIT_MINMAX(min, max);
|
|
|
|
|
}
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
for (base = scene->base.first; base; base = base->next) {
|
2012-02-22 16:52:06 +00:00
|
|
|
if (BASE_VISIBLE(v3d, base)) {
|
2013-11-26 06:39:14 +11:00
|
|
|
changed = true;
|
2011-05-14 17:50:33 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (skip_camera && base->object == v3d->camera) {
|
2011-05-14 17:50:33 +00:00
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2013-03-20 23:14:18 +00:00
|
|
|
BKE_object_minmax(base->object, min, max, false);
|
2008-12-20 11:33:16 +00:00
|
|
|
}
|
|
|
|
|
}
|
2013-11-26 06:39:14 +11:00
|
|
|
if (!changed) {
|
2010-06-22 15:46:15 +00:00
|
|
|
ED_region_tag_redraw(ar);
|
|
|
|
|
/* TODO - should this be cancel?
|
|
|
|
|
* I think no, because we always move the cursor, with or without
|
|
|
|
|
* object, but in this case there is no change in the scene,
|
|
|
|
|
* only the cursor so I choice a ED_region_tag like
|
2012-08-12 01:07:31 +00:00
|
|
|
* view3d_smooth_view do for the center_cursor.
|
2010-06-22 15:46:15 +00:00
|
|
|
* See bug #22640
|
|
|
|
|
*/
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2012-10-10 12:22:45 +00:00
|
|
|
if (use_all_regions) {
|
2013-09-16 04:04:44 +00:00
|
|
|
view3d_from_minmax_multi(C, v3d, min, max, true, smooth_viewtx);
|
2012-10-10 12:22:45 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2013-09-16 04:04:44 +00:00
|
|
|
view3d_from_minmax(C, v3d, ar, min, max, true, smooth_viewtx);
|
2012-10-10 12:22:45 +00:00
|
|
|
}
|
2008-12-20 11:33:16 +00:00
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
2010-07-03 20:47:03 +00:00
|
|
|
|
2009-07-09 08:39:58 +00:00
|
|
|
void VIEW3D_OT_view_all(wmOperatorType *ot)
|
2008-12-20 11:33:16 +00:00
|
|
|
{
|
2012-10-10 12:22:45 +00:00
|
|
|
PropertyRNA *prop;
|
|
|
|
|
|
2008-12-20 11:33:16 +00:00
|
|
|
/* identifiers */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "View All";
|
2010-02-10 21:15:44 +00:00
|
|
|
ot->description = "View all objects in scene";
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->idname = "VIEW3D_OT_view_all";
|
2008-12-20 11:33:16 +00:00
|
|
|
|
|
|
|
|
/* api callbacks */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = view3d_all_exec;
|
|
|
|
|
ot->poll = ED_operator_region_view3d_active;
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2009-01-31 19:40:40 +00:00
|
|
|
/* flags */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->flag = 0;
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2012-10-10 12:22:45 +00:00
|
|
|
prop = RNA_def_boolean(ot->srna, "use_all_regions", 0, "All Regions", "View selected for all regions");
|
|
|
|
|
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
2009-01-16 23:53:11 +00:00
|
|
|
RNA_def_boolean(ot->srna, "center", 0, "Center", "");
|
2008-12-20 11:33:16 +00:00
|
|
|
}
|
|
|
|
|
|
2012-01-19 16:04:44 +00:00
|
|
|
/* like a localview without local!, was centerview() in 2.4x */
|
2012-10-10 11:36:24 +00:00
|
|
|
static int viewselected_exec(bContext *C, wmOperator *op)
|
2008-12-26 10:31:44 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
ARegion *ar = CTX_wm_region(C);
|
2.5
View3D has been split now in a local part (RegionView3D) and a
per-area part (old View3D). Currently local is:
- view transform
- camera zoom/offset
- gpencil (todo)
- custom clipping planes
Rest is in Area still, like active camera, draw type, layers,
localview, custom centers, around-settings, transform widget,
gridlines, and so on (mostly stuff as available in header).
To see it work; also added new feature for region split,
press SHIFT+ALT+CTRL+S for four-split.
The idea is to make a preset 4-split, configured to stick
to top/right/front views for three views.
Another cool idea to explore is to then box-clip all drawing
based on these 3 views.
Note about the code:
- currently view3d still stores some depricated settings, to
convert from older files. Not all settings are copied over
though, like custom clip planes or the 'lock view to object'.
- since some view3d ops are now on area level, the operators
for it should keep track of that.
Bugfix in transform: quat initialize in operator-invoke missed
one zero.
Als brought back GE to compile for missing Ipos and channels.
2009-01-19 16:54:41 +00:00
|
|
|
View3D *v3d = CTX_wm_view3d(C);
|
2012-03-25 23:54:33 +00:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
|
|
|
|
Object *ob = OBACT;
|
|
|
|
|
Object *obedit = CTX_data_edit_object(C);
|
2012-10-10 10:05:56 +00:00
|
|
|
float min[3], max[3];
|
2013-03-20 23:14:18 +00:00
|
|
|
bool ok = false, ok_dist = true;
|
2013-03-22 04:40:45 +00:00
|
|
|
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 */
|
|
|
|
|
(use_all_regions && v3d->flag2 & V3D_LOCK_CAMERA));
|
2013-09-16 04:04:44 +00:00
|
|
|
const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
|
2008-12-20 11:33:16 +00:00
|
|
|
|
|
|
|
|
INIT_MINMAX(min, max);
|
|
|
|
|
|
2012-03-10 22:00:55 +00:00
|
|
|
if (ob && (ob->mode & OB_MODE_WEIGHT_PAINT)) {
|
|
|
|
|
/* hard-coded exception, we look for the one selected armature */
|
2008-12-20 11:33:16 +00:00
|
|
|
/* this is weak code this way, we should make a generic active/selection callback interface once... */
|
|
|
|
|
Base *base;
|
2012-03-25 23:54:33 +00:00
|
|
|
for (base = scene->base.first; base; base = base->next) {
|
2012-02-22 16:52:06 +00:00
|
|
|
if (TESTBASELIB(v3d, base)) {
|
2012-03-25 23:54:33 +00:00
|
|
|
if (base->object->type == OB_ARMATURE)
|
2012-02-22 16:52:06 +00:00
|
|
|
if (base->object->mode & OB_MODE_POSE)
|
2008-12-20 11:33:16 +00:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-02-22 16:52:06 +00:00
|
|
|
if (base)
|
2012-03-25 23:54:33 +00:00
|
|
|
ob = base->object;
|
2008-12-20 11:33:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (obedit) {
|
2012-05-12 22:34:20 +00:00
|
|
|
ok = ED_view3d_minmax_verts(obedit, min, max); /* only selected */
|
2008-12-20 11:33:16 +00:00
|
|
|
}
|
2012-02-22 16:52:06 +00:00
|
|
|
else if (ob && (ob->mode & OB_MODE_POSE)) {
|
|
|
|
|
if (ob->pose) {
|
2012-03-25 23:54:33 +00:00
|
|
|
bArmature *arm = ob->data;
|
2008-12-20 11:33:16 +00:00
|
|
|
bPoseChannel *pchan;
|
|
|
|
|
float vec[3];
|
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
|
2012-02-22 16:52:06 +00:00
|
|
|
if (pchan->bone->flag & BONE_SELECTED) {
|
|
|
|
|
if (pchan->bone->layer & arm->layer) {
|
2012-03-25 23:54:33 +00:00
|
|
|
bPoseChannel *pchan_tx = pchan->custom_tx ? pchan->custom_tx : pchan;
|
|
|
|
|
ok = 1;
|
2010-07-26 06:34:56 +00:00
|
|
|
mul_v3_m4v3(vec, ob->obmat, pchan_tx->pose_head);
|
2012-05-13 11:05:52 +00:00
|
|
|
minmax_v3v3_v3(min, max, vec);
|
2010-07-26 06:34:56 +00:00
|
|
|
mul_v3_m4v3(vec, ob->obmat, pchan_tx->pose_tail);
|
2012-05-13 11:05:52 +00:00
|
|
|
minmax_v3v3_v3(min, max, vec);
|
2008-12-20 11:33:16 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-02-26 16:00:54 +11:00
|
|
|
else if (BKE_paint_select_face_test(ob)) {
|
2012-03-25 23:54:33 +00:00
|
|
|
ok = paintface_minmax(ob, min, max);
|
2008-12-20 11:33:16 +00:00
|
|
|
}
|
2009-08-16 02:35:44 +00:00
|
|
|
else if (ob && (ob->mode & OB_MODE_PARTICLE_EDIT)) {
|
2012-03-25 23:54:33 +00:00
|
|
|
ok = PE_minmax(scene, min, max);
|
2008-12-20 11:33:16 +00:00
|
|
|
}
|
2012-05-03 03:51:30 +00:00
|
|
|
else if (ob && (ob->mode & OB_MODE_SCULPT)) {
|
|
|
|
|
ok = ED_sculpt_minmax(C, min, max);
|
|
|
|
|
ok_dist = 0; /* don't zoom */
|
|
|
|
|
}
|
2008-12-20 11:33:16 +00:00
|
|
|
else {
|
2011-05-14 17:50:33 +00:00
|
|
|
Base *base;
|
2012-03-25 23:54:33 +00:00
|
|
|
for (base = FIRSTBASE; base; base = base->next) {
|
2012-02-27 10:35:39 +00:00
|
|
|
if (TESTBASE(v3d, base)) {
|
2010-02-24 20:11:35 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (skip_camera && base->object == v3d->camera) {
|
2011-05-14 17:50:33 +00:00
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-20 11:33:16 +00:00
|
|
|
/* account for duplis */
|
2013-03-20 23:14:18 +00:00
|
|
|
if (BKE_object_minmax_dupli(scene, base->object, min, max, false) == 0)
|
|
|
|
|
BKE_object_minmax(base->object, min, max, false); /* use if duplis not found */
|
2008-12-20 11:33:16 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
ok = 1;
|
2008-12-20 11:33:16 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-10-10 10:05:56 +00:00
|
|
|
if (ok == 0) {
|
|
|
|
|
return OPERATOR_FINISHED;
|
2008-12-20 11:33:16 +00:00
|
|
|
}
|
|
|
|
|
|
2012-10-10 11:36:24 +00:00
|
|
|
if (use_all_regions) {
|
2013-09-16 04:04:44 +00:00
|
|
|
view3d_from_minmax_multi(C, v3d, min, max, ok_dist, smooth_viewtx);
|
2012-10-10 11:36:24 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2013-09-16 04:04:44 +00:00
|
|
|
view3d_from_minmax(C, v3d, ar, min, max, ok_dist, smooth_viewtx);
|
2012-10-10 11:36:24 +00:00
|
|
|
}
|
2012-10-10 12:22:45 +00:00
|
|
|
|
2008-12-20 11:33:16 +00:00
|
|
|
// XXX BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT);
|
|
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
2009-02-14 13:07:09 +00:00
|
|
|
|
2010-01-13 22:17:56 +00:00
|
|
|
void VIEW3D_OT_view_selected(wmOperatorType *ot)
|
2008-12-20 11:33:16 +00:00
|
|
|
{
|
2012-10-10 11:36:24 +00:00
|
|
|
PropertyRNA *prop;
|
2008-12-20 11:33:16 +00:00
|
|
|
|
|
|
|
|
/* identifiers */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "View Selected";
|
2010-02-10 21:15:44 +00:00
|
|
|
ot->description = "Move the view to the selection center";
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->idname = "VIEW3D_OT_view_selected";
|
2008-12-20 11:33:16 +00:00
|
|
|
|
|
|
|
|
/* api callbacks */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = viewselected_exec;
|
|
|
|
|
ot->poll = ED_operator_region_view3d_active;
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2009-01-31 19:40:40 +00:00
|
|
|
/* flags */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->flag = 0;
|
2012-10-10 11:36:24 +00:00
|
|
|
|
|
|
|
|
/* rna later */
|
|
|
|
|
prop = RNA_def_boolean(ot->srna, "use_all_regions", 0, "All Regions", "View selected for all regions");
|
|
|
|
|
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
2008-12-20 11:33:16 +00:00
|
|
|
}
|
|
|
|
|
|
2012-05-05 16:38:23 +00:00
|
|
|
static int view_lock_clear_exec(bContext *C, wmOperator *UNUSED(op))
|
|
|
|
|
{
|
|
|
|
|
View3D *v3d = CTX_wm_view3d(C);
|
|
|
|
|
|
|
|
|
|
if (v3d) {
|
|
|
|
|
ED_view3D_lock_clear(v3d);
|
|
|
|
|
|
|
|
|
|
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
|
|
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VIEW3D_OT_view_lock_clear(wmOperatorType *ot)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
/* identifiers */
|
|
|
|
|
ot->name = "View Lock Clear";
|
2012-05-07 15:50:57 +00:00
|
|
|
ot->description = "Clear all view locking";
|
2012-05-05 16:38:23 +00:00
|
|
|
ot->idname = "VIEW3D_OT_view_lock_clear";
|
|
|
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
|
ot->exec = view_lock_clear_exec;
|
|
|
|
|
ot->poll = ED_operator_region_view3d_active;
|
|
|
|
|
|
|
|
|
|
/* flags */
|
|
|
|
|
ot->flag = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int view_lock_to_active_exec(bContext *C, wmOperator *UNUSED(op))
|
|
|
|
|
{
|
|
|
|
|
View3D *v3d = CTX_wm_view3d(C);
|
|
|
|
|
Object *obact = CTX_data_active_object(C);
|
|
|
|
|
|
|
|
|
|
if (v3d) {
|
|
|
|
|
|
|
|
|
|
ED_view3D_lock_clear(v3d);
|
|
|
|
|
|
|
|
|
|
v3d->ob_centre = obact; /* can be NULL */
|
|
|
|
|
|
|
|
|
|
if (obact && obact->type == OB_ARMATURE) {
|
|
|
|
|
if (obact->mode & OB_MODE_POSE) {
|
|
|
|
|
bPoseChannel *pcham_act = BKE_pose_channel_active(obact);
|
|
|
|
|
if (pcham_act) {
|
|
|
|
|
BLI_strncpy(v3d->ob_centre_bone, pcham_act->name, sizeof(v3d->ob_centre_bone));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
EditBone *ebone_act = ((bArmature *)obact->data)->act_edbone;
|
|
|
|
|
if (ebone_act) {
|
|
|
|
|
BLI_strncpy(v3d->ob_centre_bone, ebone_act->name, sizeof(v3d->ob_centre_bone));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
|
|
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VIEW3D_OT_view_lock_to_active(wmOperatorType *ot)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
/* identifiers */
|
|
|
|
|
ot->name = "View Lock to Active";
|
|
|
|
|
ot->description = "Lock the view to the active object/bone";
|
|
|
|
|
ot->idname = "VIEW3D_OT_view_lock_to_active";
|
|
|
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
|
ot->exec = view_lock_to_active_exec;
|
|
|
|
|
ot->poll = ED_operator_region_view3d_active;
|
|
|
|
|
|
|
|
|
|
/* flags */
|
|
|
|
|
ot->flag = 0;
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-16 04:04:44 +00:00
|
|
|
static int viewcenter_cursor_exec(bContext *C, wmOperator *op)
|
2009-11-22 23:11:32 +00:00
|
|
|
{
|
|
|
|
|
View3D *v3d = CTX_wm_view3d(C);
|
2012-03-25 23:54:33 +00:00
|
|
|
RegionView3D *rv3d = CTX_wm_region_view3d(C);
|
|
|
|
|
Scene *scene = CTX_data_scene(C);
|
2009-11-22 23:11:32 +00:00
|
|
|
|
|
|
|
|
if (rv3d) {
|
2012-03-25 23:54:33 +00:00
|
|
|
ARegion *ar = CTX_wm_region(C);
|
2013-09-16 04:04:44 +00:00
|
|
|
const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
|
2011-04-28 07:55:29 +00:00
|
|
|
|
2010-07-03 20:47:03 +00:00
|
|
|
/* non camera center */
|
|
|
|
|
float new_ofs[3];
|
2013-10-26 04:07:18 +00:00
|
|
|
negate_v3_v3(new_ofs, ED_view3d_cursor3d_get(scene, v3d));
|
2013-09-16 04:04:44 +00:00
|
|
|
ED_view3d_smooth_view(C, v3d, ar, NULL, NULL,
|
|
|
|
|
new_ofs, NULL, NULL, NULL,
|
|
|
|
|
smooth_viewtx);
|
2009-11-22 23:11:32 +00:00
|
|
|
|
2010-11-07 14:57:24 +00:00
|
|
|
/* smooth view does viewlock RV3D_BOXVIEW copy */
|
2009-11-22 23:11:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VIEW3D_OT_view_center_cursor(wmOperatorType *ot)
|
|
|
|
|
{
|
|
|
|
|
/* identifiers */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Center View to Cursor";
|
|
|
|
|
ot->description = "Center the view so that the cursor is in the middle of the view";
|
|
|
|
|
ot->idname = "VIEW3D_OT_view_center_cursor";
|
2009-11-22 23:11:32 +00:00
|
|
|
|
|
|
|
|
/* api callbacks */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = viewcenter_cursor_exec;
|
|
|
|
|
ot->poll = ED_operator_view3d_active;
|
2009-11-22 23:11:32 +00:00
|
|
|
|
|
|
|
|
/* flags */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->flag = 0;
|
2009-11-22 23:11:32 +00:00
|
|
|
}
|
2008-12-20 11:33:16 +00:00
|
|
|
|
2013-09-16 04:04:44 +00:00
|
|
|
static int viewcenter_pick_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
2013-03-25 01:11:16 +00:00
|
|
|
{
|
|
|
|
|
View3D *v3d = CTX_wm_view3d(C);
|
|
|
|
|
RegionView3D *rv3d = CTX_wm_region_view3d(C);
|
|
|
|
|
Scene *scene = CTX_data_scene(C);
|
|
|
|
|
ARegion *ar = CTX_wm_region(C);
|
|
|
|
|
|
|
|
|
|
if (rv3d) {
|
|
|
|
|
float new_ofs[3];
|
2013-09-16 04:04:44 +00:00
|
|
|
const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
|
2013-03-25 01:11:16 +00:00
|
|
|
|
|
|
|
|
view3d_operator_needs_opengl(C);
|
|
|
|
|
|
2013-09-16 08:59:54 +00:00
|
|
|
if (ED_view3d_autodist(scene, ar, v3d, event->mval, new_ofs, false, NULL)) {
|
2013-03-26 01:43:00 +00:00
|
|
|
/* pass */
|
2013-03-25 01:11:16 +00:00
|
|
|
}
|
2013-03-26 01:43:00 +00:00
|
|
|
else {
|
|
|
|
|
/* fallback to simple pan */
|
|
|
|
|
negate_v3_v3(new_ofs, rv3d->ofs);
|
2013-03-26 02:37:29 +00:00
|
|
|
ED_view3d_win_to_3d_int(ar, new_ofs, event->mval, new_ofs);
|
2013-03-26 01:43:00 +00:00
|
|
|
}
|
|
|
|
|
negate_v3(new_ofs);
|
2013-09-16 04:04:44 +00:00
|
|
|
ED_view3d_smooth_view(C, v3d, ar, NULL, NULL,
|
|
|
|
|
new_ofs, NULL, NULL, NULL,
|
|
|
|
|
smooth_viewtx);
|
2013-03-25 01:11:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VIEW3D_OT_view_center_pick(wmOperatorType *ot)
|
|
|
|
|
{
|
|
|
|
|
/* identifiers */
|
|
|
|
|
ot->name = "Center View to Mouse";
|
2013-03-25 08:29:06 +00:00
|
|
|
ot->description = "Center the view to the Z-depth position under the mouse cursor";
|
2013-03-25 01:11:16 +00:00
|
|
|
ot->idname = "VIEW3D_OT_view_center_pick";
|
|
|
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
|
ot->invoke = viewcenter_pick_invoke;
|
|
|
|
|
ot->poll = ED_operator_view3d_active;
|
|
|
|
|
|
|
|
|
|
/* flags */
|
|
|
|
|
ot->flag = 0;
|
|
|
|
|
}
|
|
|
|
|
|
2010-10-15 12:29:02 +00:00
|
|
|
static int view3d_center_camera_exec(bContext *C, wmOperator *UNUSED(op)) /* was view3d_home() in 2.4x */
|
2010-07-03 20:47:03 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
2011-05-15 14:07:24 +00:00
|
|
|
float xfac, yfac;
|
|
|
|
|
float size[2];
|
2010-07-03 20:47:03 +00:00
|
|
|
|
2012-01-16 06:57:37 +00:00
|
|
|
View3D *v3d;
|
|
|
|
|
ARegion *ar;
|
|
|
|
|
RegionView3D *rv3d;
|
|
|
|
|
|
|
|
|
|
/* no NULL check is needed, poll checks */
|
|
|
|
|
ED_view3d_context_user_region(C, &v3d, &ar);
|
|
|
|
|
rv3d = ar->regiondata;
|
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
rv3d->camdx = rv3d->camdy = 0.0f;
|
2010-07-03 20:47:03 +00:00
|
|
|
|
2011-11-19 18:35:42 +00:00
|
|
|
ED_view3d_calc_camera_border_size(scene, ar, v3d, rv3d, size);
|
2011-05-15 14:07:24 +00:00
|
|
|
|
|
|
|
|
/* 4px is just a little room from the edge of the area */
|
2012-03-25 23:54:33 +00:00
|
|
|
xfac = (float)ar->winx / (float)(size[0] + 4);
|
|
|
|
|
yfac = (float)ar->winy / (float)(size[1] + 4);
|
2011-05-15 14:07:24 +00:00
|
|
|
|
2012-10-23 13:28:22 +00:00
|
|
|
rv3d->camzoom = BKE_screen_view3d_zoom_from_fac(min_ff(xfac, yfac));
|
2011-05-20 04:14:29 +00:00
|
|
|
CLAMP(rv3d->camzoom, RV3D_CAMZOOM_MIN, RV3D_CAMZOOM_MAX);
|
2011-05-15 14:07:24 +00:00
|
|
|
|
2014-03-01 21:47:46 +11:00
|
|
|
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
|
2010-07-03 20:47:03 +00:00
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VIEW3D_OT_view_center_camera(wmOperatorType *ot)
|
|
|
|
|
{
|
|
|
|
|
/* identifiers */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "View Camera Center";
|
2010-07-03 20:47:03 +00:00
|
|
|
ot->description = "Center the camera view";
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->idname = "VIEW3D_OT_view_center_camera";
|
2010-07-03 20:47:03 +00:00
|
|
|
|
|
|
|
|
/* api callbacks */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = view3d_center_camera_exec;
|
|
|
|
|
ot->poll = view3d_camera_user_poll;
|
2010-07-03 20:47:03 +00:00
|
|
|
|
|
|
|
|
/* flags */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->flag = 0;
|
2010-07-03 20:47:03 +00:00
|
|
|
}
|
|
|
|
|
|
2013-07-19 10:54:02 +00:00
|
|
|
static int view3d_center_lock_exec(bContext *C, wmOperator *UNUSED(op)) /* was view3d_home() in 2.4x */
|
|
|
|
|
{
|
|
|
|
|
RegionView3D *rv3d = CTX_wm_region_view3d(C);
|
|
|
|
|
|
|
|
|
|
zero_v2(rv3d->ofs_lock);
|
|
|
|
|
|
|
|
|
|
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, CTX_wm_view3d(C));
|
|
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VIEW3D_OT_view_center_lock(wmOperatorType *ot)
|
|
|
|
|
{
|
|
|
|
|
/* identifiers */
|
|
|
|
|
ot->name = "View Lock Center";
|
|
|
|
|
ot->description = "Center the view lock offset";
|
|
|
|
|
ot->idname = "VIEW3D_OT_view_center_lock";
|
|
|
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
|
ot->exec = view3d_center_lock_exec;
|
|
|
|
|
ot->poll = view3d_lock_poll;
|
|
|
|
|
|
|
|
|
|
/* flags */
|
|
|
|
|
ot->flag = 0;
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-27 01:29:56 +00:00
|
|
|
/* ********************* Set render border operator ****************** */
|
|
|
|
|
|
|
|
|
|
static int render_border_exec(bContext *C, wmOperator *op)
|
|
|
|
|
{
|
2.5
View3D has been split now in a local part (RegionView3D) and a
per-area part (old View3D). Currently local is:
- view transform
- camera zoom/offset
- gpencil (todo)
- custom clipping planes
Rest is in Area still, like active camera, draw type, layers,
localview, custom centers, around-settings, transform widget,
gridlines, and so on (mostly stuff as available in header).
To see it work; also added new feature for region split,
press SHIFT+ALT+CTRL+S for four-split.
The idea is to make a preset 4-split, configured to stick
to top/right/front views for three views.
Another cool idea to explore is to then box-clip all drawing
based on these 3 views.
Note about the code:
- currently view3d still stores some depricated settings, to
convert from older files. Not all settings are copied over
though, like custom clip planes or the 'lock view to object'.
- since some view3d ops are now on area level, the operators
for it should keep track of that.
Bugfix in transform: quat initialize in operator-invoke missed
one zero.
Als brought back GE to compile for missing Ipos and channels.
2009-01-19 16:54:41 +00:00
|
|
|
View3D *v3d = CTX_wm_view3d(C);
|
2012-03-25 23:54:33 +00:00
|
|
|
ARegion *ar = CTX_wm_region(C);
|
|
|
|
|
RegionView3D *rv3d = ED_view3d_context_rv3d(C);
|
2012-10-16 11:57:46 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2008-12-27 01:29:56 +00:00
|
|
|
rcti rect;
|
2012-10-16 11:57:46 +00:00
|
|
|
rctf vb, border;
|
|
|
|
|
|
2013-03-22 04:40:45 +00:00
|
|
|
const bool camera_only = RNA_boolean_get(op->ptr, "camera_only");
|
2012-10-16 11:57:46 +00:00
|
|
|
|
|
|
|
|
if (camera_only && rv3d->persp != RV3D_CAMOB)
|
|
|
|
|
return OPERATOR_PASS_THROUGH;
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2008-12-27 01:29:56 +00:00
|
|
|
/* get border select values using rna */
|
2012-08-08 20:38:55 +00:00
|
|
|
WM_operator_properties_border_to_rcti(op, &rect);
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2008-12-27 01:29:56 +00:00
|
|
|
/* calculate range */
|
|
|
|
|
|
2012-10-16 11:57:46 +00:00
|
|
|
if (rv3d->persp == RV3D_CAMOB) {
|
2013-03-20 23:14:18 +00:00
|
|
|
ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &vb, false);
|
2012-10-16 11:57:46 +00:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
vb.xmin = 0;
|
|
|
|
|
vb.ymin = 0;
|
|
|
|
|
vb.xmax = ar->winx;
|
|
|
|
|
vb.ymax = ar->winy;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
border.xmin = ((float)rect.xmin - vb.xmin) / BLI_rctf_size_x(&vb);
|
|
|
|
|
border.ymin = ((float)rect.ymin - vb.ymin) / BLI_rctf_size_y(&vb);
|
|
|
|
|
border.xmax = ((float)rect.xmax - vb.xmin) / BLI_rctf_size_x(&vb);
|
|
|
|
|
border.ymax = ((float)rect.ymax - vb.ymin) / BLI_rctf_size_y(&vb);
|
2009-07-09 02:45:48 +00:00
|
|
|
|
|
|
|
|
/* actually set border */
|
2012-10-16 11:57:46 +00:00
|
|
|
CLAMP(border.xmin, 0.0f, 1.0f);
|
|
|
|
|
CLAMP(border.ymin, 0.0f, 1.0f);
|
|
|
|
|
CLAMP(border.xmax, 0.0f, 1.0f);
|
|
|
|
|
CLAMP(border.ymax, 0.0f, 1.0f);
|
|
|
|
|
|
|
|
|
|
if (rv3d->persp == RV3D_CAMOB) {
|
|
|
|
|
scene->r.border = border;
|
|
|
|
|
|
|
|
|
|
WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, NULL);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
v3d->render_border = border;
|
|
|
|
|
|
|
|
|
|
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL);
|
|
|
|
|
}
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2008-12-27 01:29:56 +00:00
|
|
|
/* drawing a border surrounding the entire camera view switches off border rendering
|
|
|
|
|
* or the border covers no pixels */
|
2012-10-16 11:57:46 +00:00
|
|
|
if ((border.xmin <= 0.0f && border.xmax >= 1.0f &&
|
|
|
|
|
border.ymin <= 0.0f && border.ymax >= 1.0f) ||
|
|
|
|
|
(border.xmin == border.xmax || border.ymin == border.ymax))
|
2008-12-27 01:29:56 +00:00
|
|
|
{
|
2012-10-16 11:57:46 +00:00
|
|
|
if (rv3d->persp == RV3D_CAMOB)
|
|
|
|
|
scene->r.mode &= ~R_BORDER;
|
|
|
|
|
else
|
|
|
|
|
v3d->flag2 &= ~V3D_RENDER_BORDER;
|
2012-02-22 16:52:06 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2012-10-16 11:57:46 +00:00
|
|
|
if (rv3d->persp == RV3D_CAMOB)
|
|
|
|
|
scene->r.mode |= R_BORDER;
|
|
|
|
|
else
|
|
|
|
|
v3d->flag2 |= V3D_RENDER_BORDER;
|
2008-12-27 01:29:56 +00:00
|
|
|
}
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2008-12-27 01:29:56 +00:00
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VIEW3D_OT_render_border(wmOperatorType *ot)
|
|
|
|
|
{
|
|
|
|
|
/* identifiers */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Set Render Border";
|
2012-10-21 14:02:30 +00:00
|
|
|
ot->description = "Set the boundaries of the border render and enable border render";
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->idname = "VIEW3D_OT_render_border";
|
2008-12-27 01:29:56 +00:00
|
|
|
|
|
|
|
|
/* api callbacks */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->invoke = WM_border_select_invoke;
|
|
|
|
|
ot->exec = render_border_exec;
|
|
|
|
|
ot->modal = WM_border_select_modal;
|
|
|
|
|
ot->cancel = WM_border_select_cancel;
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2012-10-16 11:57:46 +00:00
|
|
|
ot->poll = ED_operator_view3d_active;
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2009-01-31 19:40:40 +00:00
|
|
|
/* flags */
|
2012-03-25 23:54:33 +00:00
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2008-12-27 01:29:56 +00:00
|
|
|
/* rna */
|
2012-08-08 20:38:55 +00:00
|
|
|
WM_operator_properties_border(ot);
|
2008-12-27 01:29:56 +00:00
|
|
|
|
2012-10-16 11:57:46 +00:00
|
|
|
RNA_def_boolean(ot->srna, "camera_only", 0, "Camera Only", "Set render border for camera view and final render only");
|
2009-01-16 00:58:33 +00:00
|
|
|
}
|
2012-10-16 11:57:46 +00:00
|
|
|
|
2012-10-21 14:02:30 +00:00
|
|
|
/* ********************* Clear render border operator ****************** */
|
2012-10-16 11:57:46 +00:00
|
|
|
|
|
|
|
|
static int clear_render_border_exec(bContext *C, wmOperator *UNUSED(op))
|
|
|
|
|
{
|
|
|
|
|
View3D *v3d = CTX_wm_view3d(C);
|
|
|
|
|
RegionView3D *rv3d = ED_view3d_context_rv3d(C);
|
|
|
|
|
|
|
|
|
|
Scene *scene = CTX_data_scene(C);
|
|
|
|
|
rctf *border = NULL;
|
|
|
|
|
|
|
|
|
|
if (rv3d->persp == RV3D_CAMOB) {
|
|
|
|
|
scene->r.mode &= ~R_BORDER;
|
|
|
|
|
border = &scene->r.border;
|
|
|
|
|
|
|
|
|
|
WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, NULL);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
v3d->flag2 &= ~V3D_RENDER_BORDER;
|
|
|
|
|
border = &v3d->render_border;
|
|
|
|
|
|
|
|
|
|
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
border->xmin = 0.0f;
|
|
|
|
|
border->ymin = 0.0f;
|
|
|
|
|
border->xmax = 1.0f;
|
|
|
|
|
border->ymax = 1.0f;
|
|
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VIEW3D_OT_clear_render_border(wmOperatorType *ot)
|
|
|
|
|
{
|
|
|
|
|
/* identifiers */
|
|
|
|
|
ot->name = "Clear Render Border";
|
2012-10-21 14:02:30 +00:00
|
|
|
ot->description = "Clear the boundaries of the border render and disable border render";
|
2012-10-16 11:57:46 +00:00
|
|
|
ot->idname = "VIEW3D_OT_clear_render_border";
|
|
|
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
|
ot->exec = clear_render_border_exec;
|
|
|
|
|
ot->poll = ED_operator_view3d_active;
|
|
|
|
|
|
|
|
|
|
/* flags */
|
|
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
|
|
|
|
}
|
|
|
|
|
|
2009-01-16 00:58:33 +00:00
|
|
|
/* ********************* Border Zoom operator ****************** */
|
|
|
|
|
|
2009-07-24 23:07:18 +00:00
|
|
|
static int view3d_zoom_border_exec(bContext *C, wmOperator *op)
|
2009-01-16 00:58:33 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
ARegion *ar = CTX_wm_region(C);
|
2.5
View3D has been split now in a local part (RegionView3D) and a
per-area part (old View3D). Currently local is:
- view transform
- camera zoom/offset
- gpencil (todo)
- custom clipping planes
Rest is in Area still, like active camera, draw type, layers,
localview, custom centers, around-settings, transform widget,
gridlines, and so on (mostly stuff as available in header).
To see it work; also added new feature for region split,
press SHIFT+ALT+CTRL+S for four-split.
The idea is to make a preset 4-split, configured to stick
to top/right/front views for three views.
Another cool idea to explore is to then box-clip all drawing
based on these 3 views.
Note about the code:
- currently view3d still stores some depricated settings, to
convert from older files. Not all settings are copied over
though, like custom clip planes or the 'lock view to object'.
- since some view3d ops are now on area level, the operators
for it should keep track of that.
Bugfix in transform: quat initialize in operator-invoke missed
one zero.
Als brought back GE to compile for missing Ipos and channels.
2009-01-19 16:54:41 +00:00
|
|
|
View3D *v3d = CTX_wm_view3d(C);
|
2012-03-25 23:54:33 +00:00
|
|
|
RegionView3D *rv3d = CTX_wm_region_view3d(C);
|
|
|
|
|
Scene *scene = CTX_data_scene(C);
|
2012-08-08 19:54:31 +00:00
|
|
|
int gesture_mode;
|
2013-09-16 04:04:44 +00:00
|
|
|
const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2009-01-16 00:58:33 +00:00
|
|
|
/* Zooms in on a border drawn by the user */
|
|
|
|
|
rcti rect;
|
2012-08-08 19:54:31 +00:00
|
|
|
float dvec[3], vb[2], xscale, yscale;
|
|
|
|
|
float dist_range_min;
|
2009-01-16 00:58:33 +00:00
|
|
|
|
|
|
|
|
/* SMOOTHVIEW */
|
|
|
|
|
float new_dist;
|
|
|
|
|
float new_ofs[3];
|
|
|
|
|
|
|
|
|
|
/* ZBuffer depth vars */
|
|
|
|
|
bglMats mats;
|
2012-03-25 23:54:33 +00:00
|
|
|
float depth_close = FLT_MAX;
|
2009-01-16 00:58:33 +00:00
|
|
|
double cent[2], p[3];
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2009-01-16 00:58:33 +00:00
|
|
|
/* note; otherwise opengl won't work */
|
|
|
|
|
view3d_operator_needs_opengl(C);
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2009-01-16 00:58:33 +00:00
|
|
|
/* get border select values using rna */
|
2012-08-08 20:38:55 +00:00
|
|
|
WM_operator_properties_border_to_rcti(op, &rect);
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2012-08-08 19:54:31 +00:00
|
|
|
/* check if zooming in/out view */
|
|
|
|
|
gesture_mode = RNA_int_get(op->ptr, "gesture_mode");
|
|
|
|
|
|
2009-01-16 00:58:33 +00:00
|
|
|
/* Get Z Depths, needed for perspective, nice for ortho */
|
|
|
|
|
bgl_get_mats(&mats);
|
2013-03-17 20:24:47 +00:00
|
|
|
draw_depth(scene, ar, v3d, NULL, true);
|
2010-10-21 07:38:09 +00:00
|
|
|
|
|
|
|
|
{
|
|
|
|
|
/* avoid allocating the whole depth buffer */
|
2012-03-25 23:54:33 +00:00
|
|
|
ViewDepths depth_temp = {0};
|
2009-01-16 00:58:33 +00:00
|
|
|
|
2010-10-21 07:38:09 +00:00
|
|
|
/* avoid view3d_update_depths() for speed. */
|
|
|
|
|
view3d_update_depths_rect(ar, &depth_temp, &rect);
|
|
|
|
|
|
|
|
|
|
/* find the closest Z pixel */
|
2012-03-25 23:54:33 +00:00
|
|
|
depth_close = view3d_depth_near(&depth_temp);
|
2010-10-21 07:38:09 +00:00
|
|
|
|
|
|
|
|
MEM_freeN(depth_temp.depths);
|
2009-01-16 00:58:33 +00:00
|
|
|
}
|
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
cent[0] = (((double)rect.xmin) + ((double)rect.xmax)) / 2;
|
|
|
|
|
cent[1] = (((double)rect.ymin) + ((double)rect.ymax)) / 2;
|
2009-01-16 00:58:33 +00:00
|
|
|
|
2011-05-20 11:15:44 +00:00
|
|
|
if (rv3d->is_persp) {
|
2009-01-16 00:58:33 +00:00
|
|
|
double p_corner[3];
|
|
|
|
|
|
|
|
|
|
/* no depths to use, we cant do anything! */
|
2012-03-25 23:54:33 +00:00
|
|
|
if (depth_close == FLT_MAX) {
|
2012-10-16 07:53:10 +00:00
|
|
|
BKE_report(op->reports, RPT_ERROR, "Depth too large");
|
2009-01-16 00:58:33 +00:00
|
|
|
return OPERATOR_CANCELLED;
|
2009-01-21 02:24:12 +00:00
|
|
|
}
|
2009-01-16 00:58:33 +00:00
|
|
|
/* convert border to 3d coordinates */
|
2012-09-09 00:00:21 +00:00
|
|
|
if ((!gluUnProject(cent[0], cent[1], depth_close,
|
|
|
|
|
mats.modelview, mats.projection, (GLint *)mats.viewport,
|
|
|
|
|
&p[0], &p[1], &p[2])) ||
|
|
|
|
|
(!gluUnProject((double)rect.xmin, (double)rect.ymin, depth_close,
|
|
|
|
|
mats.modelview, mats.projection, (GLint *)mats.viewport,
|
|
|
|
|
&p_corner[0], &p_corner[1], &p_corner[2])))
|
2012-01-19 16:04:44 +00:00
|
|
|
{
|
2009-01-16 00:58:33 +00:00
|
|
|
return OPERATOR_CANCELLED;
|
2012-01-19 16:04:44 +00:00
|
|
|
}
|
2009-01-16 00:58:33 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
dvec[0] = p[0] - p_corner[0];
|
|
|
|
|
dvec[1] = p[1] - p_corner[1];
|
|
|
|
|
dvec[2] = p[2] - p_corner[2];
|
2009-01-16 00:58:33 +00:00
|
|
|
|
|
|
|
|
new_ofs[0] = -p[0];
|
|
|
|
|
new_ofs[1] = -p[1];
|
|
|
|
|
new_ofs[2] = -p[2];
|
|
|
|
|
|
2012-08-08 19:54:31 +00:00
|
|
|
new_dist = len_v3(dvec);
|
|
|
|
|
dist_range_min = v3d->near * 1.5f;
|
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
}
|
|
|
|
|
else { /* othographic */
|
2012-03-25 23:54:33 +00:00
|
|
|
/* find the current window width and height */
|
2009-01-16 00:58:33 +00:00
|
|
|
vb[0] = ar->winx;
|
|
|
|
|
vb[1] = ar->winy;
|
|
|
|
|
|
2.5
View3D has been split now in a local part (RegionView3D) and a
per-area part (old View3D). Currently local is:
- view transform
- camera zoom/offset
- gpencil (todo)
- custom clipping planes
Rest is in Area still, like active camera, draw type, layers,
localview, custom centers, around-settings, transform widget,
gridlines, and so on (mostly stuff as available in header).
To see it work; also added new feature for region split,
press SHIFT+ALT+CTRL+S for four-split.
The idea is to make a preset 4-split, configured to stick
to top/right/front views for three views.
Another cool idea to explore is to then box-clip all drawing
based on these 3 views.
Note about the code:
- currently view3d still stores some depricated settings, to
convert from older files. Not all settings are copied over
though, like custom clip planes or the 'lock view to object'.
- since some view3d ops are now on area level, the operators
for it should keep track of that.
Bugfix in transform: quat initialize in operator-invoke missed
one zero.
Als brought back GE to compile for missing Ipos and channels.
2009-01-19 16:54:41 +00:00
|
|
|
new_dist = rv3d->dist;
|
2009-01-16 00:58:33 +00:00
|
|
|
|
|
|
|
|
/* convert the drawn rectangle into 3d space */
|
2012-01-19 16:04:44 +00:00
|
|
|
if (depth_close != FLT_MAX && gluUnProject(cent[0], cent[1], depth_close,
|
|
|
|
|
mats.modelview, mats.projection, (GLint *)mats.viewport,
|
|
|
|
|
&p[0], &p[1], &p[2]))
|
|
|
|
|
{
|
2009-01-16 00:58:33 +00:00
|
|
|
new_ofs[0] = -p[0];
|
|
|
|
|
new_ofs[1] = -p[1];
|
|
|
|
|
new_ofs[2] = -p[2];
|
2011-05-20 13:50:41 +00:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
float mval_f[2];
|
2013-03-09 11:40:42 +00:00
|
|
|
float zfac;
|
|
|
|
|
|
2009-01-16 00:58:33 +00:00
|
|
|
/* We cant use the depth, fallback to the old way that dosnt set the center depth */
|
2010-02-25 20:26:38 +00:00
|
|
|
copy_v3_v3(new_ofs, rv3d->ofs);
|
2009-01-16 00:58:33 +00:00
|
|
|
|
2013-03-09 11:40:42 +00:00
|
|
|
{
|
|
|
|
|
float tvec[3];
|
|
|
|
|
negate_v3_v3(tvec, new_ofs);
|
|
|
|
|
zfac = ED_view3d_calc_zfac(rv3d, tvec, NULL);
|
|
|
|
|
}
|
2009-01-16 00:58:33 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
mval_f[0] = (rect.xmin + rect.xmax - vb[0]) / 2.0f;
|
|
|
|
|
mval_f[1] = (rect.ymin + rect.ymax - vb[1]) / 2.0f;
|
2013-03-09 11:40:42 +00:00
|
|
|
ED_view3d_win_to_delta(ar, mval_f, dvec, zfac);
|
2009-01-16 00:58:33 +00:00
|
|
|
/* center the view to the center of the rectangle */
|
2010-04-23 23:57:00 +00:00
|
|
|
sub_v3_v3(new_ofs, dvec);
|
2009-01-16 00:58:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* work out the ratios, so that everything selected fits when we zoom */
|
2012-09-15 11:48:20 +00:00
|
|
|
xscale = (BLI_rcti_size_x(&rect) / vb[0]);
|
|
|
|
|
yscale = (BLI_rcti_size_y(&rect) / vb[1]);
|
2012-10-23 13:28:22 +00:00
|
|
|
new_dist *= max_ff(xscale, yscale);
|
2009-01-16 00:58:33 +00:00
|
|
|
|
|
|
|
|
/* zoom in as required, or as far as we can go */
|
2012-08-08 19:54:31 +00:00
|
|
|
dist_range_min = 0.001f * v3d->grid;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (gesture_mode == GESTURE_MODAL_OUT) {
|
|
|
|
|
sub_v3_v3v3(dvec, new_ofs, rv3d->ofs);
|
|
|
|
|
new_dist = rv3d->dist * (rv3d->dist / new_dist);
|
|
|
|
|
add_v3_v3v3(new_ofs, rv3d->ofs, dvec);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* clamp after because we may have been zooming out */
|
|
|
|
|
if (new_dist < dist_range_min) {
|
|
|
|
|
new_dist = dist_range_min;
|
2009-01-16 00:58:33 +00:00
|
|
|
}
|
|
|
|
|
|
2013-09-16 04:04:44 +00:00
|
|
|
ED_view3d_smooth_view(C, v3d, ar, NULL, NULL,
|
|
|
|
|
new_ofs, NULL, &new_dist, NULL,
|
|
|
|
|
smooth_viewtx);
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (rv3d->viewlock & RV3D_BOXVIEW)
|
2009-01-20 14:23:32 +00:00
|
|
|
view3d_boxview_sync(CTX_wm_area(C), ar);
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2009-01-16 00:58:33 +00:00
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
2.5
View3D has been split now in a local part (RegionView3D) and a
per-area part (old View3D). Currently local is:
- view transform
- camera zoom/offset
- gpencil (todo)
- custom clipping planes
Rest is in Area still, like active camera, draw type, layers,
localview, custom centers, around-settings, transform widget,
gridlines, and so on (mostly stuff as available in header).
To see it work; also added new feature for region split,
press SHIFT+ALT+CTRL+S for four-split.
The idea is to make a preset 4-split, configured to stick
to top/right/front views for three views.
Another cool idea to explore is to then box-clip all drawing
based on these 3 views.
Note about the code:
- currently view3d still stores some depricated settings, to
convert from older files. Not all settings are copied over
though, like custom clip planes or the 'lock view to object'.
- since some view3d ops are now on area level, the operators
for it should keep track of that.
Bugfix in transform: quat initialize in operator-invoke missed
one zero.
Als brought back GE to compile for missing Ipos and channels.
2009-01-19 16:54:41 +00:00
|
|
|
|
2013-03-13 09:03:46 +00:00
|
|
|
static int view3d_zoom_border_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
2009-01-16 00:58:33 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
View3D *v3d = CTX_wm_view3d(C);
|
|
|
|
|
RegionView3D *rv3d = CTX_wm_region_view3d(C);
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2009-01-16 00:58:33 +00:00
|
|
|
/* if in camera view do not exec the operator so we do not conflict with set render border*/
|
2011-05-23 15:46:09 +00:00
|
|
|
if ((rv3d->persp != RV3D_CAMOB) || ED_view3d_camera_lock_check(v3d, rv3d))
|
2009-07-09 02:45:48 +00:00
|
|
|
return WM_border_select_invoke(C, op, event);
|
|
|
|
|
else
|
2.5
View3D has been split now in a local part (RegionView3D) and a
per-area part (old View3D). Currently local is:
- view transform
- camera zoom/offset
- gpencil (todo)
- custom clipping planes
Rest is in Area still, like active camera, draw type, layers,
localview, custom centers, around-settings, transform widget,
gridlines, and so on (mostly stuff as available in header).
To see it work; also added new feature for region split,
press SHIFT+ALT+CTRL+S for four-split.
The idea is to make a preset 4-split, configured to stick
to top/right/front views for three views.
Another cool idea to explore is to then box-clip all drawing
based on these 3 views.
Note about the code:
- currently view3d still stores some depricated settings, to
convert from older files. Not all settings are copied over
though, like custom clip planes or the 'lock view to object'.
- since some view3d ops are now on area level, the operators
for it should keep track of that.
Bugfix in transform: quat initialize in operator-invoke missed
one zero.
Als brought back GE to compile for missing Ipos and channels.
2009-01-19 16:54:41 +00:00
|
|
|
return OPERATOR_PASS_THROUGH;
|
2009-01-16 00:58:33 +00:00
|
|
|
}
|
2.5
View3D has been split now in a local part (RegionView3D) and a
per-area part (old View3D). Currently local is:
- view transform
- camera zoom/offset
- gpencil (todo)
- custom clipping planes
Rest is in Area still, like active camera, draw type, layers,
localview, custom centers, around-settings, transform widget,
gridlines, and so on (mostly stuff as available in header).
To see it work; also added new feature for region split,
press SHIFT+ALT+CTRL+S for four-split.
The idea is to make a preset 4-split, configured to stick
to top/right/front views for three views.
Another cool idea to explore is to then box-clip all drawing
based on these 3 views.
Note about the code:
- currently view3d still stores some depricated settings, to
convert from older files. Not all settings are copied over
though, like custom clip planes or the 'lock view to object'.
- since some view3d ops are now on area level, the operators
for it should keep track of that.
Bugfix in transform: quat initialize in operator-invoke missed
one zero.
Als brought back GE to compile for missing Ipos and channels.
2009-01-19 16:54:41 +00:00
|
|
|
|
2009-03-29 02:15:13 +00:00
|
|
|
void VIEW3D_OT_zoom_border(wmOperatorType *ot)
|
2009-01-16 00:58:33 +00:00
|
|
|
{
|
|
|
|
|
/* identifiers */
|
2012-08-10 11:43:53 +00:00
|
|
|
ot->name = "Zoom to Border";
|
2010-02-10 21:15:44 +00:00
|
|
|
ot->description = "Zoom in the view to the nearest object contained in the border";
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->idname = "VIEW3D_OT_zoom_border";
|
2009-01-16 00:58:33 +00:00
|
|
|
|
|
|
|
|
/* api callbacks */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->invoke = view3d_zoom_border_invoke;
|
|
|
|
|
ot->exec = view3d_zoom_border_exec;
|
|
|
|
|
ot->modal = WM_border_select_modal;
|
|
|
|
|
ot->cancel = WM_border_select_cancel;
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->poll = ED_operator_region_view3d_active;
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2009-01-31 19:40:40 +00:00
|
|
|
/* flags */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->flag = 0;
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2009-01-16 00:58:33 +00:00
|
|
|
/* rna */
|
2013-03-20 23:14:18 +00:00
|
|
|
WM_operator_properties_gesture_border(ot, false);
|
2008-12-27 01:29:56 +00:00
|
|
|
}
|
2011-02-23 06:48:47 +00:00
|
|
|
|
|
|
|
|
/* sets the view to 1:1 camera/render-pixel */
|
2011-11-04 14:36:06 +00:00
|
|
|
static void view3d_set_1_to_1_viewborder(Scene *scene, ARegion *ar, View3D *v3d)
|
2011-02-23 06:48:47 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
2011-02-23 06:48:47 +00:00
|
|
|
float size[2];
|
2012-03-25 23:54:33 +00:00
|
|
|
int im_width = (scene->r.size * scene->r.xsch) / 100;
|
2011-02-23 06:48:47 +00:00
|
|
|
|
2011-11-19 18:35:42 +00:00
|
|
|
ED_view3d_calc_camera_border_size(scene, ar, v3d, rv3d, size);
|
2011-05-20 04:14:29 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
rv3d->camzoom = BKE_screen_view3d_zoom_from_fac((float)im_width / size[0]);
|
2011-05-20 04:14:29 +00:00
|
|
|
CLAMP(rv3d->camzoom, RV3D_CAMZOOM_MIN, RV3D_CAMZOOM_MAX);
|
2011-02-23 06:48:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int view3d_zoom_1_to_1_camera_exec(bContext *C, wmOperator *UNUSED(op))
|
|
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
2011-02-23 06:48:47 +00:00
|
|
|
|
2012-01-16 06:57:37 +00:00
|
|
|
View3D *v3d;
|
|
|
|
|
ARegion *ar;
|
2011-02-23 06:48:47 +00:00
|
|
|
|
2012-01-16 06:57:37 +00:00
|
|
|
/* no NULL check is needed, poll checks */
|
|
|
|
|
ED_view3d_context_user_region(C, &v3d, &ar);
|
|
|
|
|
|
|
|
|
|
view3d_set_1_to_1_viewborder(scene, ar, v3d);
|
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
|
2011-02-23 06:48:47 +00:00
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VIEW3D_OT_zoom_camera_1_to_1(wmOperatorType *ot)
|
|
|
|
|
{
|
|
|
|
|
/* identifiers */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Zoom Camera 1:1";
|
2011-02-23 06:48:47 +00:00
|
|
|
ot->description = "Match the camera to 1:1 to the render output";
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->idname = "VIEW3D_OT_zoom_camera_1_to_1";
|
2011-02-23 06:48:47 +00:00
|
|
|
|
|
|
|
|
/* api callbacks */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = view3d_zoom_1_to_1_camera_exec;
|
|
|
|
|
ot->poll = view3d_camera_user_poll;
|
2011-02-23 06:48:47 +00:00
|
|
|
|
|
|
|
|
/* flags */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->flag = 0;
|
2011-02-23 06:48:47 +00:00
|
|
|
}
|
|
|
|
|
|
2008-12-26 10:31:44 +00:00
|
|
|
/* ********************* Changing view operator ****************** */
|
|
|
|
|
|
2008-12-23 09:59:02 +00:00
|
|
|
static EnumPropertyItem prop_view_items[] = {
|
2009-10-27 02:54:25 +00:00
|
|
|
{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"},
|
2012-10-08 06:21:36 +00:00
|
|
|
{RV3D_VIEW_CAMERA, "CAMERA", 0, "Camera", "View From the Active Camera"},
|
2012-03-25 23:54:33 +00:00
|
|
|
{0, NULL, 0, NULL, NULL}
|
|
|
|
|
};
|
2008-12-23 09:59:02 +00:00
|
|
|
|
2009-11-06 10:38:00 +00:00
|
|
|
|
|
|
|
|
/* would like to make this a generic function - outside of transform */
|
|
|
|
|
|
2012-01-19 16:04:44 +00:00
|
|
|
static void axis_set_view(bContext *C, View3D *v3d, ARegion *ar,
|
2014-02-12 13:35:06 +11:00
|
|
|
const float quat_[4],
|
2013-09-16 04:04:44 +00:00
|
|
|
short view, int perspo, bool align_active,
|
|
|
|
|
const int smooth_viewtx)
|
2008-12-23 09:59:02 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
RegionView3D *rv3d = ar->regiondata; /* no NULL check is needed, poll checks */
|
2014-02-12 13:35:06 +11:00
|
|
|
float quat[4];
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2014-02-12 13:35:06 +11:00
|
|
|
normalize_qt_qt(quat, quat_);
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (align_active) {
|
2009-11-06 10:38:00 +00:00
|
|
|
/* align to active object */
|
2012-03-25 23:54:33 +00:00
|
|
|
Object *obact = CTX_data_active_object(C);
|
|
|
|
|
if (obact == NULL) {
|
2009-11-06 10:38:00 +00:00
|
|
|
/* no active object, ignore this option */
|
2013-03-20 23:14:18 +00:00
|
|
|
align_active = false;
|
2009-11-06 10:38:00 +00:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
float obact_quat[4];
|
2009-11-06 22:10:08 +00:00
|
|
|
float twmat[3][3];
|
2009-11-06 10:38:00 +00:00
|
|
|
|
|
|
|
|
/* same as transform manipulator when normal is set */
|
2013-07-25 11:05:08 +00:00
|
|
|
ED_getTransformOrientationMatrix(C, twmat, true);
|
2009-11-06 10:38:00 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
mat3_to_quat(obact_quat, twmat);
|
2009-11-10 20:43:45 +00:00
|
|
|
invert_qt(obact_quat);
|
2014-02-12 13:35:06 +11:00
|
|
|
mul_qt_qtqt(quat, quat, obact_quat);
|
2009-11-06 10:38:00 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
rv3d->view = view = RV3D_VIEW_USER;
|
2009-11-06 10:38:00 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-03-20 23:14:18 +00:00
|
|
|
if (align_active == false) {
|
2009-11-06 10:38:00 +00:00
|
|
|
/* normal operation */
|
2014-02-04 21:04:36 +11:00
|
|
|
if (rv3d->viewlock & RV3D_LOCKED) {
|
2009-11-06 10:38:00 +00:00
|
|
|
/* only pass on if */
|
2012-03-10 22:00:55 +00:00
|
|
|
|
|
|
|
|
/* nice confusing if-block */
|
|
|
|
|
if (!((rv3d->view == RV3D_VIEW_FRONT && view == RV3D_VIEW_BACK) ||
|
|
|
|
|
(rv3d->view == RV3D_VIEW_BACK && view == RV3D_VIEW_FRONT) ||
|
|
|
|
|
(rv3d->view == RV3D_VIEW_RIGHT && view == RV3D_VIEW_LEFT) ||
|
|
|
|
|
(rv3d->view == RV3D_VIEW_LEFT && view == RV3D_VIEW_RIGHT) ||
|
|
|
|
|
(rv3d->view == RV3D_VIEW_BOTTOM && view == RV3D_VIEW_TOP) ||
|
|
|
|
|
(rv3d->view == RV3D_VIEW_TOP && view == RV3D_VIEW_BOTTOM)))
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
2009-11-06 10:38:00 +00:00
|
|
|
}
|
|
|
|
|
|
2012-03-10 22:00:55 +00:00
|
|
|
rv3d->view = view;
|
2009-11-06 10:38:00 +00:00
|
|
|
}
|
2009-01-20 14:23:32 +00:00
|
|
|
|
2014-02-04 21:04:36 +11:00
|
|
|
if (rv3d->viewlock & RV3D_LOCKED) {
|
2011-04-28 07:55:29 +00:00
|
|
|
ED_region_tag_redraw(ar);
|
2009-01-20 14:23:32 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2013-11-25 12:53:40 +11:00
|
|
|
if (U.uiflag & USER_AUTOPERSP) {
|
|
|
|
|
rv3d->persp = RV3D_VIEW_IS_AXIS(view) ? RV3D_ORTHO : perspo;
|
|
|
|
|
}
|
|
|
|
|
else if (rv3d->persp == RV3D_CAMOB) {
|
|
|
|
|
rv3d->persp = perspo;
|
|
|
|
|
}
|
2008-12-23 09:59:02 +00:00
|
|
|
|
2013-11-25 12:53:40 +11:00
|
|
|
if (rv3d->persp == RV3D_CAMOB && v3d->camera) {
|
2013-09-16 04:04:44 +00:00
|
|
|
ED_view3d_smooth_view(C, v3d, ar, v3d->camera, NULL,
|
2014-02-12 13:35:06 +11:00
|
|
|
rv3d->ofs, quat, NULL, NULL,
|
2013-09-16 04:04:44 +00:00
|
|
|
smooth_viewtx);
|
2009-07-09 02:45:48 +00:00
|
|
|
}
|
2008-12-26 18:15:46 +00:00
|
|
|
else {
|
2013-09-16 04:04:44 +00:00
|
|
|
ED_view3d_smooth_view(C, v3d, ar, NULL, NULL,
|
2014-02-12 13:35:06 +11:00
|
|
|
NULL, quat, NULL, NULL,
|
2013-09-16 04:04:44 +00:00
|
|
|
smooth_viewtx);
|
2008-12-23 09:59:02 +00:00
|
|
|
}
|
2008-12-26 18:15:46 +00:00
|
|
|
|
2008-12-23 09:59:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int viewnumpad_exec(bContext *C, wmOperator *op)
|
|
|
|
|
{
|
2012-01-14 12:24:25 +00:00
|
|
|
View3D *v3d;
|
|
|
|
|
ARegion *ar;
|
|
|
|
|
RegionView3D *rv3d;
|
2012-03-25 23:54:33 +00:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
2012-01-14 12:24:25 +00:00
|
|
|
static int perspo = RV3D_PERSP;
|
2013-03-20 23:14:18 +00:00
|
|
|
int viewnum, nextperspo;
|
|
|
|
|
bool align_active;
|
2013-09-16 04:04:44 +00:00
|
|
|
const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
|
2008-12-23 09:59:02 +00:00
|
|
|
|
2012-01-16 06:57:37 +00:00
|
|
|
/* no NULL check is needed, poll checks */
|
2012-01-14 12:24:25 +00:00
|
|
|
ED_view3d_context_user_region(C, &v3d, &ar);
|
|
|
|
|
rv3d = ar->regiondata;
|
|
|
|
|
|
2009-02-04 05:15:39 +00:00
|
|
|
viewnum = RNA_enum_get(op->ptr, "type");
|
2009-11-06 10:38:00 +00:00
|
|
|
align_active = RNA_boolean_get(op->ptr, "align_active");
|
2008-12-23 09:59:02 +00:00
|
|
|
|
2011-02-05 19:07:54 +00:00
|
|
|
/* set this to zero, gets handled in axis_set_view */
|
2014-02-04 21:04:36 +11:00
|
|
|
if (rv3d->viewlock & RV3D_LOCKED)
|
2013-03-20 23:14:18 +00:00
|
|
|
align_active = false;
|
2009-12-07 10:40:55 +00:00
|
|
|
|
2008-12-23 09:59:02 +00:00
|
|
|
/* Use this to test if we started out with a camera */
|
|
|
|
|
|
2009-12-07 10:40:55 +00:00
|
|
|
if (rv3d->persp == RV3D_CAMOB) {
|
2012-03-25 23:54:33 +00:00
|
|
|
nextperspo = rv3d->lpersp;
|
2012-02-22 16:52:06 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2012-03-25 23:54:33 +00:00
|
|
|
nextperspo = perspo;
|
2009-12-07 10:40:55 +00:00
|
|
|
}
|
|
|
|
|
|
2014-02-12 13:35:06 +11:00
|
|
|
if (RV3D_VIEW_IS_AXIS(viewnum)) {
|
|
|
|
|
float quat[4];
|
|
|
|
|
|
|
|
|
|
ED_view3d_quat_from_axis_view(viewnum, quat);
|
|
|
|
|
axis_set_view(C, v3d, ar, quat, viewnum, nextperspo, align_active, smooth_viewtx);
|
|
|
|
|
}
|
|
|
|
|
else if (viewnum == RV3D_VIEW_CAMERA) {
|
|
|
|
|
if ((rv3d->viewlock & RV3D_LOCKED) == 0) {
|
|
|
|
|
/* lastview - */
|
|
|
|
|
|
|
|
|
|
if (rv3d->persp != RV3D_CAMOB) {
|
|
|
|
|
Object *ob = OBACT;
|
|
|
|
|
|
|
|
|
|
if (!rv3d->smooth_timer) {
|
|
|
|
|
/* store settings of current view before allowing overwriting with camera view
|
|
|
|
|
* only if we're not currently in a view transition */
|
|
|
|
|
copy_qt_qt(rv3d->lviewquat, rv3d->viewquat);
|
|
|
|
|
rv3d->lview = rv3d->view;
|
|
|
|
|
rv3d->lpersp = rv3d->persp;
|
|
|
|
|
}
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2013-12-22 14:11:10 +11:00
|
|
|
#if 0
|
2014-02-12 13:35:06 +11:00
|
|
|
if (G.qual == LR_ALTKEY) {
|
|
|
|
|
if (oldcamera && is_an_active_object(oldcamera)) {
|
|
|
|
|
v3d->camera = oldcamera;
|
2008-12-26 18:15:46 +00:00
|
|
|
}
|
2014-02-12 13:35:06 +11:00
|
|
|
handle_view3d_lock();
|
|
|
|
|
}
|
2013-12-22 14:11:10 +11:00
|
|
|
#endif
|
2014-02-12 13:35:06 +11:00
|
|
|
|
|
|
|
|
/* first get the default camera for the view lock type */
|
|
|
|
|
if (v3d->scenelock) {
|
|
|
|
|
/* sets the camera view if available */
|
|
|
|
|
v3d->camera = scene->camera;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* use scene camera if one is not set (even though we're unlocked) */
|
|
|
|
|
if (v3d->camera == NULL) {
|
2012-03-25 23:54:33 +00:00
|
|
|
v3d->camera = scene->camera;
|
2010-07-24 01:32:03 +00:00
|
|
|
}
|
2014-02-12 13:35:06 +11:00
|
|
|
}
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2014-02-12 13:35:06 +11:00
|
|
|
/* if the camera isn't found, check a number of options */
|
|
|
|
|
if (v3d->camera == NULL && ob && ob->type == OB_CAMERA)
|
|
|
|
|
v3d->camera = ob;
|
2010-07-24 01:32:03 +00:00
|
|
|
|
2014-02-12 13:35:06 +11:00
|
|
|
if (v3d->camera == NULL)
|
|
|
|
|
v3d->camera = BKE_scene_camera_find(scene);
|
2010-07-24 01:32:03 +00:00
|
|
|
|
2014-02-12 13:35:06 +11:00
|
|
|
/* couldnt find any useful camera, bail out */
|
|
|
|
|
if (v3d->camera == NULL)
|
|
|
|
|
return OPERATOR_CANCELLED;
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2014-02-12 13:35:06 +11:00
|
|
|
/* important these don't get out of sync for locked scenes */
|
|
|
|
|
if (v3d->scenelock)
|
|
|
|
|
scene->camera = v3d->camera;
|
|
|
|
|
|
|
|
|
|
/* finally do snazzy view zooming */
|
|
|
|
|
rv3d->persp = RV3D_CAMOB;
|
|
|
|
|
ED_view3d_smooth_view(C, v3d, ar, NULL, v3d->camera,
|
|
|
|
|
rv3d->ofs, rv3d->viewquat, &rv3d->dist, &v3d->lens,
|
|
|
|
|
smooth_viewtx);
|
2008-12-23 09:59:02 +00:00
|
|
|
|
2014-02-12 13:35:06 +11:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* return to settings of last view */
|
|
|
|
|
/* does view3d_smooth_view too */
|
|
|
|
|
axis_set_view(C, v3d, ar,
|
|
|
|
|
rv3d->lviewquat,
|
|
|
|
|
rv3d->lview, rv3d->lpersp, 0,
|
|
|
|
|
smooth_viewtx);
|
|
|
|
|
}
|
|
|
|
|
}
|
2008-12-23 09:59:02 +00:00
|
|
|
}
|
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
if (rv3d->persp != RV3D_CAMOB) perspo = rv3d->persp;
|
2008-12-23 09:59:02 +00:00
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
2010-11-19 17:16:25 +00:00
|
|
|
|
|
|
|
|
|
2008-12-26 11:11:21 +00:00
|
|
|
void VIEW3D_OT_viewnumpad(wmOperatorType *ot)
|
2008-12-23 09:59:02 +00:00
|
|
|
{
|
2012-03-29 15:04:54 +00:00
|
|
|
PropertyRNA *prop;
|
|
|
|
|
|
2008-12-23 09:59:02 +00:00
|
|
|
/* identifiers */
|
2013-01-27 07:23:58 +00:00
|
|
|
ot->name = "View Numpad";
|
2012-10-08 06:21:36 +00:00
|
|
|
ot->description = "Use a preset viewpoint";
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->idname = "VIEW3D_OT_viewnumpad";
|
2008-12-23 09:59:02 +00:00
|
|
|
|
|
|
|
|
/* api callbacks */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = viewnumpad_exec;
|
|
|
|
|
ot->poll = ED_operator_rv3d_user_region_poll;
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2009-01-31 19:40:40 +00:00
|
|
|
/* flags */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->flag = 0;
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2012-10-08 06:21:36 +00:00
|
|
|
ot->prop = RNA_def_enum(ot->srna, "type", prop_view_items, 0, "View", "Preset viewpoint to use");
|
|
|
|
|
RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE);
|
2012-03-29 15:04:54 +00:00
|
|
|
prop = RNA_def_boolean(ot->srna, "align_active", 0, "Align Active", "Align to the active object's axis");
|
|
|
|
|
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
2008-12-23 09:59:02 +00:00
|
|
|
}
|
|
|
|
|
|
2009-02-03 03:54:03 +00:00
|
|
|
static EnumPropertyItem prop_view_orbit_items[] = {
|
2009-06-16 00:52:21 +00:00
|
|
|
{V3D_VIEW_STEPLEFT, "ORBITLEFT", 0, "Orbit Left", "Orbit the view around to the Left"},
|
|
|
|
|
{V3D_VIEW_STEPRIGHT, "ORBITRIGHT", 0, "Orbit Right", "Orbit the view around to the Right"},
|
|
|
|
|
{V3D_VIEW_STEPUP, "ORBITUP", 0, "Orbit Up", "Orbit the view Up"},
|
|
|
|
|
{V3D_VIEW_STEPDOWN, "ORBITDOWN", 0, "Orbit Down", "Orbit the view Down"},
|
2012-03-25 23:54:33 +00:00
|
|
|
{0, NULL, 0, NULL, NULL}
|
|
|
|
|
};
|
2009-02-03 03:54:03 +00:00
|
|
|
|
|
|
|
|
static int vieworbit_exec(bContext *C, wmOperator *op)
|
|
|
|
|
{
|
2012-01-14 12:24:25 +00:00
|
|
|
View3D *v3d;
|
|
|
|
|
ARegion *ar;
|
|
|
|
|
RegionView3D *rv3d;
|
2009-02-03 03:54:03 +00:00
|
|
|
int orbitdir;
|
|
|
|
|
|
2012-01-14 12:24:25 +00:00
|
|
|
/* no NULL check is needed, poll checks */
|
|
|
|
|
ED_view3d_context_user_region(C, &v3d, &ar);
|
|
|
|
|
rv3d = ar->regiondata;
|
|
|
|
|
|
2009-02-03 03:54:03 +00:00
|
|
|
orbitdir = RNA_enum_get(op->ptr, "type");
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2014-02-04 21:04:36 +11:00
|
|
|
if ((rv3d->viewlock & RV3D_LOCKED) == 0) {
|
2012-02-22 16:52:06 +00:00
|
|
|
if ((rv3d->persp != RV3D_CAMOB) || ED_view3d_camera_lock_check(v3d, rv3d)) {
|
2013-09-16 04:04:44 +00:00
|
|
|
const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
|
2012-07-22 18:31:08 +00:00
|
|
|
float angle = DEG2RADF((float)U.pad_rot_angle);
|
|
|
|
|
float quat_mul[4];
|
|
|
|
|
float quat_new[4];
|
|
|
|
|
|
|
|
|
|
if (ELEM(orbitdir, V3D_VIEW_STEPLEFT, V3D_VIEW_STEPRIGHT)) {
|
|
|
|
|
const float zvec[3] = {0.0f, 0.0f, 1.0f};
|
|
|
|
|
|
|
|
|
|
if (orbitdir == V3D_VIEW_STEPRIGHT) {
|
|
|
|
|
angle = -angle;
|
|
|
|
|
}
|
|
|
|
|
|
2009-02-03 03:54:03 +00:00
|
|
|
/* z-axis */
|
2014-02-01 21:32:34 +11:00
|
|
|
axis_angle_normalized_to_quat(quat_mul, zvec, angle);
|
2009-02-03 03:54:03 +00:00
|
|
|
}
|
2012-07-22 18:31:08 +00:00
|
|
|
else {
|
|
|
|
|
|
|
|
|
|
if (orbitdir == V3D_VIEW_STEPDOWN) {
|
|
|
|
|
angle = -angle;
|
|
|
|
|
}
|
|
|
|
|
|
2009-02-03 03:54:03 +00:00
|
|
|
/* horizontal axis */
|
2012-07-22 18:31:08 +00:00
|
|
|
axis_angle_to_quat(quat_mul, rv3d->viewinv[0], angle);
|
2009-02-03 03:54:03 +00:00
|
|
|
}
|
2010-01-03 03:01:46 +00:00
|
|
|
|
2012-07-22 18:31:08 +00:00
|
|
|
mul_qt_qtqt(quat_new, rv3d->viewquat, quat_mul);
|
|
|
|
|
rv3d->view = RV3D_VIEW_USER;
|
|
|
|
|
|
2013-09-16 04:04:44 +00:00
|
|
|
ED_view3d_smooth_view(C, CTX_wm_view3d(C), ar, NULL, NULL,
|
|
|
|
|
NULL, quat_new, NULL, NULL,
|
|
|
|
|
smooth_viewtx);
|
2012-07-22 18:31:08 +00:00
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
2009-02-03 03:54:03 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-07-22 18:31:08 +00:00
|
|
|
return OPERATOR_CANCELLED;
|
2009-02-03 03:54:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VIEW3D_OT_view_orbit(wmOperatorType *ot)
|
|
|
|
|
{
|
|
|
|
|
/* identifiers */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "View Orbit";
|
2010-02-10 21:15:44 +00:00
|
|
|
ot->description = "Orbit the view";
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->idname = "VIEW3D_OT_view_orbit";
|
2009-02-03 03:54:03 +00:00
|
|
|
|
|
|
|
|
/* api callbacks */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = vieworbit_exec;
|
|
|
|
|
ot->poll = ED_operator_rv3d_user_region_poll;
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2009-02-03 03:54:03 +00:00
|
|
|
/* flags */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->flag = 0;
|
2012-10-08 06:21:36 +00:00
|
|
|
|
|
|
|
|
/* properties */
|
|
|
|
|
ot->prop = RNA_def_enum(ot->srna, "type", prop_view_orbit_items, 0, "Orbit", "Direction of View Orbit");
|
2009-02-03 03:54:03 +00:00
|
|
|
}
|
|
|
|
|
|
2013-08-31 08:18:08 +00:00
|
|
|
|
|
|
|
|
/* ************************ viewroll ******************************** */
|
|
|
|
|
|
|
|
|
|
static void view_roll_angle(ARegion *ar, float quat[4], const float orig_quat[4], const float dvec[3], float angle)
|
|
|
|
|
{
|
|
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
|
|
|
|
float quat_mul[4];
|
|
|
|
|
|
|
|
|
|
/* camera axis */
|
2014-02-01 21:32:34 +11:00
|
|
|
axis_angle_normalized_to_quat(quat_mul, dvec, angle);
|
2013-08-31 08:18:08 +00:00
|
|
|
|
|
|
|
|
mul_qt_qtqt(quat, orig_quat, quat_mul);
|
|
|
|
|
rv3d->view = RV3D_VIEW_USER;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void viewroll_apply(ViewOpsData *vod, int x, int UNUSED(y))
|
|
|
|
|
{
|
|
|
|
|
float angle = 0.0;
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
float len1, len2, tot;
|
|
|
|
|
|
|
|
|
|
tot = vod->ar->winrct.xmax - vod->ar->winrct.xmin;
|
|
|
|
|
len1 = (vod->ar->winrct.xmax - x) / tot;
|
|
|
|
|
len2 = (vod->ar->winrct.xmax - vod->origx) / tot;
|
|
|
|
|
angle = (len1 - len2) * (float)M_PI * 4.0f;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (angle != 0.0f)
|
|
|
|
|
view_roll_angle(vod->ar, vod->rv3d->viewquat, vod->oldquat, vod->mousevec, angle);
|
|
|
|
|
|
|
|
|
|
if (vod->rv3d->viewlock & RV3D_BOXVIEW)
|
|
|
|
|
view3d_boxview_sync(vod->sa, vod->ar);
|
|
|
|
|
|
|
|
|
|
ED_view3d_camera_lock_sync(vod->v3d, vod->rv3d);
|
|
|
|
|
|
|
|
|
|
ED_region_tag_redraw(vod->ar);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int viewroll_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
|
|
|
|
{
|
|
|
|
|
ViewOpsData *vod = op->customdata;
|
|
|
|
|
short event_code = VIEW_PASS;
|
|
|
|
|
|
|
|
|
|
/* execute the events */
|
|
|
|
|
if (event->type == MOUSEMOVE) {
|
|
|
|
|
event_code = VIEW_APPLY;
|
|
|
|
|
}
|
|
|
|
|
else if (event->type == EVT_MODAL_MAP) {
|
|
|
|
|
switch (event->val) {
|
|
|
|
|
case VIEW_MODAL_CONFIRM:
|
|
|
|
|
event_code = VIEW_CONFIRM;
|
|
|
|
|
break;
|
|
|
|
|
case VIEWROT_MODAL_SWITCH_MOVE:
|
|
|
|
|
WM_operator_name_call(C, "VIEW3D_OT_move", WM_OP_INVOKE_DEFAULT, NULL);
|
|
|
|
|
event_code = VIEW_CONFIRM;
|
|
|
|
|
break;
|
|
|
|
|
case VIEWROT_MODAL_SWITCH_ROTATE:
|
|
|
|
|
WM_operator_name_call(C, "VIEW3D_OT_rotate", WM_OP_INVOKE_DEFAULT, NULL);
|
|
|
|
|
event_code = VIEW_CONFIRM;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (event->type == vod->origkey && event->val == KM_RELEASE) {
|
|
|
|
|
event_code = VIEW_CONFIRM;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (event_code == VIEW_APPLY) {
|
|
|
|
|
viewroll_apply(vod, event->x, event->y);
|
|
|
|
|
}
|
|
|
|
|
else if (event_code == VIEW_CONFIRM) {
|
|
|
|
|
ED_view3d_depth_tag_update(vod->rv3d);
|
|
|
|
|
viewops_data_free(C, op);
|
|
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return OPERATOR_RUNNING_MODAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int viewroll_exec(bContext *C, wmOperator *op)
|
|
|
|
|
{
|
|
|
|
|
View3D *v3d;
|
|
|
|
|
RegionView3D *rv3d;
|
|
|
|
|
ARegion *ar;
|
|
|
|
|
|
|
|
|
|
if (op->customdata) {
|
|
|
|
|
ViewOpsData *vod = op->customdata;
|
|
|
|
|
ar = vod->ar;
|
|
|
|
|
v3d = vod->v3d;
|
|
|
|
|
}
|
|
|
|
|
else {
|
2014-02-04 21:44:37 +11:00
|
|
|
ED_view3d_context_user_region(C, &v3d, &ar);
|
2013-08-31 08:18:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rv3d = ar->regiondata;
|
|
|
|
|
if ((rv3d->persp != RV3D_CAMOB) || ED_view3d_camera_lock_check(v3d, rv3d)) {
|
|
|
|
|
const float angle = RNA_float_get(op->ptr, "angle");
|
|
|
|
|
float mousevec[3];
|
|
|
|
|
float quat_new[4];
|
|
|
|
|
|
2013-09-16 04:04:44 +00:00
|
|
|
const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
|
|
|
|
|
|
2013-08-31 08:18:08 +00:00
|
|
|
normalize_v3_v3(mousevec, rv3d->viewinv[2]);
|
|
|
|
|
negate_v3(mousevec);
|
|
|
|
|
view_roll_angle(ar, quat_new, rv3d->viewquat, mousevec, angle);
|
|
|
|
|
|
2013-09-16 04:04:44 +00:00
|
|
|
ED_view3d_smooth_view(C, v3d, ar, NULL, NULL,
|
|
|
|
|
NULL, quat_new, NULL, NULL,
|
|
|
|
|
smooth_viewtx);
|
2013-08-31 08:18:08 +00:00
|
|
|
|
|
|
|
|
viewops_data_free(C, op);
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
viewops_data_free(C, op);
|
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int viewroll_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
|
|
|
|
{
|
|
|
|
|
ViewOpsData *vod;
|
|
|
|
|
|
|
|
|
|
if (RNA_struct_property_is_set(op->ptr, "angle")) {
|
|
|
|
|
viewroll_exec(C, op);
|
|
|
|
|
}
|
|
|
|
|
else {
|
2014-02-04 21:44:37 +11:00
|
|
|
/* makes op->customdata */
|
|
|
|
|
viewops_data_alloc(C, op);
|
|
|
|
|
viewops_data_create(C, op, event);
|
|
|
|
|
vod = op->customdata;
|
|
|
|
|
|
2013-08-31 08:18:08 +00:00
|
|
|
/* overwrite the mouse vector with the view direction */
|
|
|
|
|
normalize_v3_v3(vod->mousevec, vod->rv3d->viewinv[2]);
|
|
|
|
|
negate_v3(vod->mousevec);
|
|
|
|
|
|
|
|
|
|
if (event->type == MOUSEROTATE) {
|
|
|
|
|
vod->origx = vod->oldx = event->x;
|
|
|
|
|
viewroll_apply(vod, event->prevx, event->prevy);
|
|
|
|
|
ED_view3d_depth_tag_update(vod->rv3d);
|
|
|
|
|
|
|
|
|
|
viewops_data_free(C, op);
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* add temp handler */
|
|
|
|
|
WM_event_add_modal_handler(C, op);
|
|
|
|
|
|
|
|
|
|
return OPERATOR_RUNNING_MODAL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
2013-10-30 23:08:53 +00:00
|
|
|
static void viewroll_cancel(bContext *C, wmOperator *op)
|
2013-08-31 08:18:08 +00:00
|
|
|
{
|
|
|
|
|
viewops_data_free(C, op);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VIEW3D_OT_view_roll(wmOperatorType *ot)
|
|
|
|
|
{
|
|
|
|
|
/* identifiers */
|
|
|
|
|
ot->name = "View Roll";
|
|
|
|
|
ot->description = "Roll the view";
|
|
|
|
|
ot->idname = "VIEW3D_OT_view_roll";
|
|
|
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
|
ot->invoke = viewroll_invoke;
|
|
|
|
|
ot->exec = viewroll_exec;
|
|
|
|
|
ot->modal = viewroll_modal;
|
|
|
|
|
ot->poll = ED_operator_rv3d_user_region_poll;
|
|
|
|
|
ot->cancel = viewroll_cancel;
|
|
|
|
|
|
|
|
|
|
/* flags */
|
|
|
|
|
ot->flag = 0;
|
|
|
|
|
|
|
|
|
|
/* properties */
|
|
|
|
|
ot->prop = RNA_def_float(ot->srna, "angle", 0, -FLT_MAX, FLT_MAX, "Roll", "", -FLT_MAX, FLT_MAX);
|
|
|
|
|
}
|
|
|
|
|
|
2009-02-03 03:54:03 +00:00
|
|
|
static EnumPropertyItem prop_view_pan_items[] = {
|
2009-06-16 00:52:21 +00:00
|
|
|
{V3D_VIEW_PANLEFT, "PANLEFT", 0, "Pan Left", "Pan the view to the Left"},
|
|
|
|
|
{V3D_VIEW_PANRIGHT, "PANRIGHT", 0, "Pan Right", "Pan the view to the Right"},
|
|
|
|
|
{V3D_VIEW_PANUP, "PANUP", 0, "Pan Up", "Pan the view Up"},
|
|
|
|
|
{V3D_VIEW_PANDOWN, "PANDOWN", 0, "Pan Down", "Pan the view Down"},
|
2012-03-25 23:54:33 +00:00
|
|
|
{0, NULL, 0, NULL, NULL}
|
|
|
|
|
};
|
2009-02-03 03:54:03 +00:00
|
|
|
|
|
|
|
|
static int viewpan_exec(bContext *C, wmOperator *op)
|
|
|
|
|
{
|
2013-04-08 11:45:20 +00:00
|
|
|
ScrArea *sa = CTX_wm_area(C);
|
2012-03-25 23:54:33 +00:00
|
|
|
ARegion *ar = CTX_wm_region(C);
|
2013-04-08 04:48:34 +00:00
|
|
|
View3D *v3d = CTX_wm_view3d(C);
|
2012-03-25 23:54:33 +00:00
|
|
|
RegionView3D *rv3d = CTX_wm_region_view3d(C);
|
2009-07-09 02:45:48 +00:00
|
|
|
float vec[3];
|
2013-03-09 11:40:42 +00:00
|
|
|
const float co_zero[3] = {0.0f};
|
2012-03-25 23:54:33 +00:00
|
|
|
float mval_f[2] = {0.0f, 0.0f};
|
2013-03-09 11:40:42 +00:00
|
|
|
float zfac;
|
2009-02-03 03:54:03 +00:00
|
|
|
int pandir;
|
|
|
|
|
|
2013-09-20 01:43:06 +00:00
|
|
|
if (view3d_operator_offset_lock_check(C, op))
|
|
|
|
|
return OPERATOR_CANCELLED;
|
2013-05-03 07:29:25 +00:00
|
|
|
|
2009-02-03 03:54:03 +00:00
|
|
|
pandir = RNA_enum_get(op->ptr, "type");
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2013-04-08 04:48:34 +00:00
|
|
|
ED_view3d_camera_lock_init(v3d, rv3d);
|
|
|
|
|
|
2013-03-09 11:40:42 +00:00
|
|
|
zfac = ED_view3d_calc_zfac(rv3d, co_zero, NULL);
|
|
|
|
|
if (pandir == V3D_VIEW_PANRIGHT) { mval_f[0] = -32.0f; }
|
|
|
|
|
else if (pandir == V3D_VIEW_PANLEFT) { mval_f[0] = 32.0f; }
|
|
|
|
|
else if (pandir == V3D_VIEW_PANUP) { mval_f[1] = -25.0f; }
|
|
|
|
|
else if (pandir == V3D_VIEW_PANDOWN) { mval_f[1] = 25.0f; }
|
|
|
|
|
ED_view3d_win_to_delta(ar, mval_f, vec, zfac);
|
2013-04-08 11:45:20 +00:00
|
|
|
add_v3_v3(rv3d->ofs, vec);
|
2009-02-03 03:54:03 +00:00
|
|
|
|
2013-04-08 11:45:20 +00:00
|
|
|
if (rv3d->viewlock & RV3D_BOXVIEW)
|
|
|
|
|
view3d_boxview_sync(sa, ar);
|
|
|
|
|
|
|
|
|
|
ED_view3d_depth_tag_update(rv3d);
|
|
|
|
|
|
|
|
|
|
ED_view3d_camera_lock_sync(v3d, rv3d);
|
|
|
|
|
|
|
|
|
|
ED_region_tag_redraw(ar);
|
2009-02-03 03:54:03 +00:00
|
|
|
|
2009-07-09 02:45:48 +00:00
|
|
|
return OPERATOR_FINISHED;
|
2009-02-03 03:54:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VIEW3D_OT_view_pan(wmOperatorType *ot)
|
|
|
|
|
{
|
|
|
|
|
/* identifiers */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "View Pan";
|
2010-02-10 21:15:44 +00:00
|
|
|
ot->description = "Pan the view";
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->idname = "VIEW3D_OT_view_pan";
|
2009-02-03 03:54:03 +00:00
|
|
|
|
|
|
|
|
/* api callbacks */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = viewpan_exec;
|
|
|
|
|
ot->poll = ED_operator_region_view3d_active;
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2009-02-03 03:54:03 +00:00
|
|
|
/* flags */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->flag = 0;
|
2012-10-08 06:21:36 +00:00
|
|
|
|
|
|
|
|
/* Properties */
|
|
|
|
|
ot->prop = RNA_def_enum(ot->srna, "type", prop_view_pan_items, 0, "Pan", "Direction of View Pan");
|
2009-02-03 03:54:03 +00:00
|
|
|
}
|
|
|
|
|
|
2010-10-15 01:36:14 +00:00
|
|
|
static int viewpersportho_exec(bContext *C, wmOperator *UNUSED(op))
|
2009-02-03 03:54:03 +00:00
|
|
|
{
|
2012-01-14 12:24:25 +00:00
|
|
|
View3D *v3d_dummy;
|
|
|
|
|
ARegion *ar;
|
|
|
|
|
RegionView3D *rv3d;
|
|
|
|
|
|
|
|
|
|
/* no NULL check is needed, poll checks */
|
|
|
|
|
ED_view3d_context_user_region(C, &v3d_dummy, &ar);
|
|
|
|
|
rv3d = ar->regiondata;
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2014-02-04 21:04:36 +11:00
|
|
|
if ((rv3d->viewlock & RV3D_LOCKED) == 0) {
|
2012-03-25 23:54:33 +00:00
|
|
|
if (rv3d->persp != RV3D_ORTHO)
|
|
|
|
|
rv3d->persp = RV3D_ORTHO;
|
|
|
|
|
else rv3d->persp = RV3D_PERSP;
|
2009-02-03 03:54:03 +00:00
|
|
|
ED_region_tag_redraw(ar);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2009-02-03 03:54:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VIEW3D_OT_view_persportho(wmOperatorType *ot)
|
|
|
|
|
{
|
|
|
|
|
/* identifiers */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "View Persp/Ortho";
|
2012-10-08 06:21:36 +00:00
|
|
|
ot->description = "Switch the current view from perspective/orthographic projection";
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->idname = "VIEW3D_OT_view_persportho";
|
2009-02-03 03:54:03 +00:00
|
|
|
|
|
|
|
|
/* api callbacks */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = viewpersportho_exec;
|
|
|
|
|
ot->poll = ED_operator_rv3d_user_region_poll;
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2009-02-03 03:54:03 +00:00
|
|
|
/* flags */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->flag = 0;
|
2009-02-03 03:54:03 +00:00
|
|
|
}
|
|
|
|
|
|
2013-12-03 03:14:09 -02:00
|
|
|
static int view3d_navigate_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
|
|
|
|
|
{
|
|
|
|
|
eViewNavigation_Method mode = U.navigation_mode;
|
|
|
|
|
|
|
|
|
|
switch (mode) {
|
|
|
|
|
case VIEW_NAVIGATION_FLY:
|
|
|
|
|
WM_operator_name_call(C, "VIEW3D_OT_fly", WM_OP_INVOKE_DEFAULT, NULL);
|
|
|
|
|
break;
|
|
|
|
|
case VIEW_NAVIGATION_WALK:
|
|
|
|
|
default:
|
|
|
|
|
WM_operator_name_call(C, "VIEW3D_OT_walk", WM_OP_INVOKE_DEFAULT, NULL);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VIEW3D_OT_navigate(wmOperatorType *ot)
|
|
|
|
|
{
|
|
|
|
|
/* identifiers */
|
|
|
|
|
ot->name = "View Navigation";
|
2013-12-03 22:42:58 +01:00
|
|
|
ot->description = "Interactively navigate around the scene (uses the mode (walk/fly) preference)";
|
2013-12-03 03:14:09 -02:00
|
|
|
ot->idname = "VIEW3D_OT_navigate";
|
|
|
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
|
ot->invoke = view3d_navigate_invoke;
|
|
|
|
|
ot->poll = ED_operator_view3d_active;
|
|
|
|
|
}
|
|
|
|
|
|
2011-04-28 08:26:49 +00:00
|
|
|
|
2010-01-19 22:44:43 +00:00
|
|
|
/* ******************** add background image operator **************** */
|
2009-02-03 03:54:03 +00:00
|
|
|
|
2010-12-08 11:42:11 +00:00
|
|
|
static BGpic *background_image_add(bContext *C)
|
2010-01-19 22:44:43 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
View3D *v3d = CTX_wm_view3d(C);
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2011-11-18 14:28:45 +00:00
|
|
|
return ED_view3D_background_image_new(v3d);
|
2010-09-01 13:41:53 +00:00
|
|
|
}
|
2010-01-19 22:44:43 +00:00
|
|
|
|
2010-12-08 11:42:11 +00:00
|
|
|
static int background_image_add_exec(bContext *C, wmOperator *UNUSED(op))
|
2010-09-01 13:41:53 +00:00
|
|
|
{
|
2010-12-08 11:42:11 +00:00
|
|
|
background_image_add(C);
|
2010-01-19 22:44:43 +00:00
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
2013-03-13 09:03:46 +00:00
|
|
|
static int background_image_add_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
|
2010-01-19 22:44:43 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
View3D *v3d = CTX_wm_view3d(C);
|
|
|
|
|
Image *ima = NULL;
|
2010-09-01 13:41:53 +00:00
|
|
|
BGpic *bgpic;
|
2012-03-25 23:54:33 +00:00
|
|
|
char name[MAX_ID_NAME - 2];
|
2010-09-01 13:41:53 +00:00
|
|
|
|
|
|
|
|
/* check input variables */
|
2012-02-22 16:52:06 +00:00
|
|
|
if (RNA_struct_property_is_set(op->ptr, "filepath")) {
|
2010-09-01 13:41:53 +00:00
|
|
|
char path[FILE_MAX];
|
|
|
|
|
|
|
|
|
|
RNA_string_get(op->ptr, "filepath", path);
|
2012-05-05 14:52:04 +00:00
|
|
|
ima = BKE_image_load_exists(path);
|
2010-09-01 13:41:53 +00:00
|
|
|
}
|
2012-02-22 16:52:06 +00:00
|
|
|
else if (RNA_struct_property_is_set(op->ptr, "name")) {
|
2010-09-01 13:41:53 +00:00
|
|
|
RNA_string_get(op->ptr, "name", name);
|
2012-05-05 17:00:11 +00:00
|
|
|
ima = (Image *)BKE_libblock_find_name(ID_IM, name);
|
2010-09-01 13:41:53 +00:00
|
|
|
}
|
|
|
|
|
|
2010-12-08 11:42:11 +00:00
|
|
|
bgpic = background_image_add(C);
|
2010-09-01 13:41:53 +00:00
|
|
|
|
|
|
|
|
if (ima) {
|
|
|
|
|
bgpic->ima = ima;
|
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
if (ima->id.us == 0) id_us_plus(&ima->id);
|
2010-09-01 13:41:53 +00:00
|
|
|
else id_lib_extern(&ima->id);
|
|
|
|
|
|
|
|
|
|
if (!(v3d->flag & V3D_DISPBGPICS))
|
|
|
|
|
v3d->flag |= V3D_DISPBGPICS;
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
|
2010-09-01 13:41:53 +00:00
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
2010-01-19 22:44:43 +00:00
|
|
|
}
|
|
|
|
|
|
2010-12-08 11:42:11 +00:00
|
|
|
void VIEW3D_OT_background_image_add(wmOperatorType *ot)
|
2010-01-19 22:44:43 +00:00
|
|
|
{
|
|
|
|
|
/* identifiers */
|
2013-03-01 14:47:06 +00:00
|
|
|
/* note: having key shortcut here is bad practice,
|
|
|
|
|
* but for now keep because this displays when dragging an image over the 3D viewport */
|
2013-02-27 10:14:36 +00:00
|
|
|
ot->name = "Add Background Image (Ctrl for Empty Object)";
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->description = "Add a new background image";
|
2010-12-08 11:42:11 +00:00
|
|
|
ot->idname = "VIEW3D_OT_background_image_add";
|
2010-01-19 22:44:43 +00:00
|
|
|
|
|
|
|
|
/* api callbacks */
|
2010-12-08 11:42:11 +00:00
|
|
|
ot->invoke = background_image_add_invoke;
|
|
|
|
|
ot->exec = background_image_add_exec;
|
2010-01-19 22:44:43 +00:00
|
|
|
ot->poll = ED_operator_view3d_active;
|
|
|
|
|
|
|
|
|
|
/* flags */
|
|
|
|
|
ot->flag = 0;
|
2010-09-01 13:41:53 +00:00
|
|
|
|
|
|
|
|
/* properties */
|
2012-03-25 23:54:33 +00:00
|
|
|
RNA_def_string(ot->srna, "name", "Image", MAX_ID_NAME - 2, "Name", "Image name to assign");
|
2010-09-01 13:41:53 +00:00
|
|
|
RNA_def_string(ot->srna, "filepath", "Path", FILE_MAX, "Filepath", "Path to image file");
|
2010-01-19 22:44:43 +00:00
|
|
|
}
|
|
|
|
|
|
2010-09-01 13:41:53 +00:00
|
|
|
|
2010-01-19 22:44:43 +00:00
|
|
|
/* ***** remove image operator ******* */
|
2010-12-08 11:42:11 +00:00
|
|
|
static int background_image_remove_exec(bContext *C, wmOperator *op)
|
2010-01-19 22:44:43 +00:00
|
|
|
{
|
2011-11-18 14:28:45 +00:00
|
|
|
View3D *v3d = CTX_wm_view3d(C);
|
2013-03-22 04:40:45 +00:00
|
|
|
const int index = RNA_int_get(op->ptr, "index");
|
2012-03-25 23:54:33 +00:00
|
|
|
BGpic *bgpic_rem = BLI_findlink(&v3d->bgpicbase, index);
|
2010-01-19 22:44:43 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (bgpic_rem) {
|
2011-11-18 14:28:45 +00:00
|
|
|
ED_view3D_background_image_remove(v3d, bgpic_rem);
|
2012-03-25 23:54:33 +00:00
|
|
|
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
|
2011-01-12 03:41:12 +00:00
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
return OPERATOR_CANCELLED;
|
2010-01-19 22:44:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2010-12-08 11:42:11 +00:00
|
|
|
void VIEW3D_OT_background_image_remove(wmOperatorType *ot)
|
2010-01-19 22:44:43 +00:00
|
|
|
{
|
|
|
|
|
/* identifiers */
|
|
|
|
|
ot->name = "Remove Background Image";
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->description = "Remove a background image from the 3D view";
|
2010-12-08 11:42:11 +00:00
|
|
|
ot->idname = "VIEW3D_OT_background_image_remove";
|
2010-01-19 22:44:43 +00:00
|
|
|
|
|
|
|
|
/* api callbacks */
|
2010-12-08 11:42:11 +00:00
|
|
|
ot->exec = background_image_remove_exec;
|
2010-01-19 22:44:43 +00:00
|
|
|
ot->poll = ED_operator_view3d_active;
|
|
|
|
|
|
|
|
|
|
/* flags */
|
|
|
|
|
ot->flag = 0;
|
2012-10-08 06:21:36 +00:00
|
|
|
|
|
|
|
|
/* properties */
|
2012-03-02 21:14:37 +00:00
|
|
|
RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "Background image index to remove", 0, INT_MAX);
|
2010-01-19 22:44:43 +00:00
|
|
|
}
|
2010-09-01 13:41:53 +00:00
|
|
|
|
2008-12-21 12:43:34 +00:00
|
|
|
/* ********************* set clipping operator ****************** */
|
|
|
|
|
|
2013-05-08 12:53:43 +00:00
|
|
|
static void calc_clipping_plane(float clip[6][4], const BoundBox *clipbb)
|
2009-11-21 16:44:05 +00:00
|
|
|
{
|
|
|
|
|
int val;
|
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
for (val = 0; val < 4; val++) {
|
|
|
|
|
normal_tri_v3(clip[val], clipbb->vec[val], clipbb->vec[val == 3 ? 0 : val + 1], clipbb->vec[val + 4]);
|
2013-05-08 12:53:43 +00:00
|
|
|
clip[val][3] = -dot_v3v3(clip[val], clipbb->vec[val]);
|
2009-11-21 16:44:05 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-12-11 14:29:01 +00:00
|
|
|
static void calc_local_clipping(float clip_local[6][4], BoundBox *clipbb, float mat[4][4])
|
2009-11-21 16:44:05 +00:00
|
|
|
{
|
|
|
|
|
BoundBox clipbb_local;
|
|
|
|
|
float imat[4][4];
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
invert_m4_m4(imat, mat);
|
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
for (i = 0; i < 8; i++) {
|
2009-11-21 16:44:05 +00:00
|
|
|
mul_v3_m4v3(clipbb_local.vec[i], imat, clipbb->vec[i]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
calc_clipping_plane(clip_local, &clipbb_local);
|
|
|
|
|
}
|
|
|
|
|
|
2012-12-11 14:29:01 +00:00
|
|
|
void ED_view3d_clipping_local(RegionView3D *rv3d, float mat[4][4])
|
2009-11-21 16:44:05 +00:00
|
|
|
{
|
2012-02-22 16:52:06 +00:00
|
|
|
if (rv3d->rflag & RV3D_CLIPPING)
|
2009-11-21 16:44:05 +00:00
|
|
|
calc_local_clipping(rv3d->clip_local, rv3d->clipbb, mat);
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-21 12:43:34 +00:00
|
|
|
static int view3d_clipping_exec(bContext *C, wmOperator *op)
|
|
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
RegionView3D *rv3d = CTX_wm_region_view3d(C);
|
2009-10-27 19:53:34 +00:00
|
|
|
ViewContext vc;
|
|
|
|
|
bglMats mats;
|
2008-12-21 12:43:34 +00:00
|
|
|
rcti rect;
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2012-08-08 20:38:55 +00:00
|
|
|
WM_operator_properties_border_to_rcti(op, &rect);
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2.5
View3D has been split now in a local part (RegionView3D) and a
per-area part (old View3D). Currently local is:
- view transform
- camera zoom/offset
- gpencil (todo)
- custom clipping planes
Rest is in Area still, like active camera, draw type, layers,
localview, custom centers, around-settings, transform widget,
gridlines, and so on (mostly stuff as available in header).
To see it work; also added new feature for region split,
press SHIFT+ALT+CTRL+S for four-split.
The idea is to make a preset 4-split, configured to stick
to top/right/front views for three views.
Another cool idea to explore is to then box-clip all drawing
based on these 3 views.
Note about the code:
- currently view3d still stores some depricated settings, to
convert from older files. Not all settings are copied over
though, like custom clip planes or the 'lock view to object'.
- since some view3d ops are now on area level, the operators
for it should keep track of that.
Bugfix in transform: quat initialize in operator-invoke missed
one zero.
Als brought back GE to compile for missing Ipos and channels.
2009-01-19 16:54:41 +00:00
|
|
|
rv3d->rflag |= RV3D_CLIPPING;
|
2012-03-25 23:54:33 +00:00
|
|
|
rv3d->clipbb = MEM_callocN(sizeof(BoundBox), "clipbb");
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2008-12-21 12:43:34 +00:00
|
|
|
/* note; otherwise opengl won't work */
|
|
|
|
|
view3d_operator_needs_opengl(C);
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2009-10-27 19:53:34 +00:00
|
|
|
view3d_set_viewcontext(C, &vc);
|
2010-01-10 20:31:23 +00:00
|
|
|
view3d_get_transformation(vc.ar, vc.rv3d, NULL, &mats); /* NULL because we don't want it in object space */
|
2012-09-20 04:56:24 +00:00
|
|
|
ED_view3d_clipping_calc(rv3d->clipbb, rv3d->clip, &mats, &rect);
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2008-12-21 12:43:34 +00:00
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
2013-03-13 09:03:46 +00:00
|
|
|
static int view3d_clipping_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
2008-12-21 12:43:34 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
RegionView3D *rv3d = CTX_wm_region_view3d(C);
|
|
|
|
|
ARegion *ar = CTX_wm_region(C);
|
2.5
View3D has been split now in a local part (RegionView3D) and a
per-area part (old View3D). Currently local is:
- view transform
- camera zoom/offset
- gpencil (todo)
- custom clipping planes
Rest is in Area still, like active camera, draw type, layers,
localview, custom centers, around-settings, transform widget,
gridlines, and so on (mostly stuff as available in header).
To see it work; also added new feature for region split,
press SHIFT+ALT+CTRL+S for four-split.
The idea is to make a preset 4-split, configured to stick
to top/right/front views for three views.
Another cool idea to explore is to then box-clip all drawing
based on these 3 views.
Note about the code:
- currently view3d still stores some depricated settings, to
convert from older files. Not all settings are copied over
though, like custom clip planes or the 'lock view to object'.
- since some view3d ops are now on area level, the operators
for it should keep track of that.
Bugfix in transform: quat initialize in operator-invoke missed
one zero.
Als brought back GE to compile for missing Ipos and channels.
2009-01-19 16:54:41 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (rv3d->rflag & RV3D_CLIPPING) {
|
2.5
View3D has been split now in a local part (RegionView3D) and a
per-area part (old View3D). Currently local is:
- view transform
- camera zoom/offset
- gpencil (todo)
- custom clipping planes
Rest is in Area still, like active camera, draw type, layers,
localview, custom centers, around-settings, transform widget,
gridlines, and so on (mostly stuff as available in header).
To see it work; also added new feature for region split,
press SHIFT+ALT+CTRL+S for four-split.
The idea is to make a preset 4-split, configured to stick
to top/right/front views for three views.
Another cool idea to explore is to then box-clip all drawing
based on these 3 views.
Note about the code:
- currently view3d still stores some depricated settings, to
convert from older files. Not all settings are copied over
though, like custom clip planes or the 'lock view to object'.
- since some view3d ops are now on area level, the operators
for it should keep track of that.
Bugfix in transform: quat initialize in operator-invoke missed
one zero.
Als brought back GE to compile for missing Ipos and channels.
2009-01-19 16:54:41 +00:00
|
|
|
rv3d->rflag &= ~RV3D_CLIPPING;
|
|
|
|
|
ED_region_tag_redraw(ar);
|
2012-02-22 16:52:06 +00:00
|
|
|
if (rv3d->clipbb) MEM_freeN(rv3d->clipbb);
|
2012-03-25 23:54:33 +00:00
|
|
|
rv3d->clipbb = NULL;
|
2008-12-21 12:43:34 +00:00
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
return WM_border_select_invoke(C, op, event);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* toggles */
|
2009-07-09 08:39:58 +00:00
|
|
|
void VIEW3D_OT_clip_border(wmOperatorType *ot)
|
2008-12-21 12:43:34 +00:00
|
|
|
{
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2008-12-21 12:43:34 +00:00
|
|
|
/* identifiers */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Clipping Border";
|
2010-02-10 21:15:44 +00:00
|
|
|
ot->description = "Set the view clipping border";
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->idname = "VIEW3D_OT_clip_border";
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2008-12-21 12:43:34 +00:00
|
|
|
/* api callbacks */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->invoke = view3d_clipping_invoke;
|
|
|
|
|
ot->exec = view3d_clipping_exec;
|
|
|
|
|
ot->modal = WM_border_select_modal;
|
|
|
|
|
ot->cancel = WM_border_select_cancel;
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->poll = ED_operator_region_view3d_active;
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2009-01-31 19:40:40 +00:00
|
|
|
/* flags */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->flag = 0;
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2008-12-21 12:43:34 +00:00
|
|
|
/* rna */
|
2012-08-08 20:38:55 +00:00
|
|
|
WM_operator_properties_border(ot);
|
2008-12-21 12:43:34 +00:00
|
|
|
}
|
|
|
|
|
|
2008-12-26 19:07:31 +00:00
|
|
|
/* ***************** 3d cursor cursor op ******************* */
|
|
|
|
|
|
2012-12-26 16:24:50 +00:00
|
|
|
/* cursor position in vec, result in vec, mval in region coords */
|
|
|
|
|
/* note: cannot use event->mval here (called by object_add() */
|
2013-02-21 17:11:38 +00:00
|
|
|
void ED_view3d_cursor3d_position(bContext *C, float fp[3], const int mval[2])
|
2008-12-26 19:07:31 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
|
|
|
|
ARegion *ar = CTX_wm_region(C);
|
2.5
View3D has been split now in a local part (RegionView3D) and a
per-area part (old View3D). Currently local is:
- view transform
- camera zoom/offset
- gpencil (todo)
- custom clipping planes
Rest is in Area still, like active camera, draw type, layers,
localview, custom centers, around-settings, transform widget,
gridlines, and so on (mostly stuff as available in header).
To see it work; also added new feature for region split,
press SHIFT+ALT+CTRL+S for four-split.
The idea is to make a preset 4-split, configured to stick
to top/right/front views for three views.
Another cool idea to explore is to then box-clip all drawing
based on these 3 views.
Note about the code:
- currently view3d still stores some depricated settings, to
convert from older files. Not all settings are copied over
though, like custom clip planes or the 'lock view to object'.
- since some view3d ops are now on area level, the operators
for it should keep track of that.
Bugfix in transform: quat initialize in operator-invoke missed
one zero.
Als brought back GE to compile for missing Ipos and channels.
2009-01-19 16:54:41 +00:00
|
|
|
View3D *v3d = CTX_wm_view3d(C);
|
2012-03-25 23:54:33 +00:00
|
|
|
RegionView3D *rv3d = CTX_wm_region_view3d(C);
|
2013-03-09 11:40:42 +00:00
|
|
|
bool flip;
|
2013-12-29 13:35:00 +11:00
|
|
|
bool depth_used = false;
|
2012-12-26 16:24:50 +00:00
|
|
|
|
2013-09-18 00:28:23 +00:00
|
|
|
/* normally the caller should ensure this,
|
|
|
|
|
* but this is called from areas that aren't already dealing with the viewport */
|
|
|
|
|
if (rv3d == NULL)
|
|
|
|
|
return;
|
|
|
|
|
|
2014-01-13 04:28:51 +02:00
|
|
|
ED_view3d_calc_zfac(rv3d, fp, &flip);
|
2010-08-06 03:52:13 +00:00
|
|
|
|
2012-10-05 01:27:28 +00:00
|
|
|
/* reset the depth based on the view offset (we _know_ the offset is infront of us) */
|
2012-02-22 16:52:06 +00:00
|
|
|
if (flip) {
|
2010-08-06 03:52:13 +00:00
|
|
|
negate_v3_v3(fp, rv3d->ofs);
|
2012-10-05 01:27:28 +00:00
|
|
|
/* re initialize, no need to check flip again */
|
2014-01-13 04:28:51 +02:00
|
|
|
ED_view3d_calc_zfac(rv3d, fp, NULL /* &flip */ );
|
2010-08-06 03:52:13 +00:00
|
|
|
}
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2013-12-29 13:35:00 +11:00
|
|
|
if (U.uiflag & USER_ZBUF_CURSOR) { /* maybe this should be accessed some other way */
|
|
|
|
|
view3d_operator_needs_opengl(C);
|
|
|
|
|
if (ED_view3d_autodist(scene, ar, v3d, mval, fp, true, NULL))
|
|
|
|
|
depth_used = true;
|
2008-12-26 19:07:31 +00:00
|
|
|
}
|
2013-11-24 21:25:05 +11:00
|
|
|
|
2013-12-29 13:35:00 +11:00
|
|
|
if (depth_used == false) {
|
|
|
|
|
float depth_pt[3];
|
|
|
|
|
copy_v3_v3(depth_pt, fp);
|
|
|
|
|
ED_view3d_win_to_3d_int(ar, depth_pt, mval, fp);
|
2008-12-26 19:07:31 +00:00
|
|
|
}
|
2012-12-26 16:24:50 +00:00
|
|
|
}
|
|
|
|
|
|
2013-03-13 09:03:46 +00:00
|
|
|
static int view3d_cursor3d_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
|
2012-12-26 16:24:50 +00:00
|
|
|
{
|
|
|
|
|
Scene *scene = CTX_data_scene(C);
|
|
|
|
|
View3D *v3d = CTX_wm_view3d(C);
|
2013-10-26 04:07:18 +00:00
|
|
|
float *fp = ED_view3d_cursor3d_get(scene, v3d);
|
2012-12-26 16:24:50 +00:00
|
|
|
|
2013-02-21 17:11:38 +00:00
|
|
|
ED_view3d_cursor3d_position(C, fp, event->mval);
|
2012-12-26 16:24:50 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (v3d && v3d->localvd)
|
2012-03-25 23:54:33 +00:00
|
|
|
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
|
2009-12-10 09:58:10 +00:00
|
|
|
else
|
2012-03-25 23:54:33 +00:00
|
|
|
WM_event_add_notifier(C, NC_SCENE | NA_EDITED, scene);
|
2012-12-26 16:24:50 +00:00
|
|
|
|
2011-10-01 13:46:20 +00:00
|
|
|
return OPERATOR_FINISHED;
|
2008-12-26 19:07:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VIEW3D_OT_cursor3d(wmOperatorType *ot)
|
|
|
|
|
{
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2008-12-26 19:07:31 +00:00
|
|
|
/* identifiers */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Set 3D Cursor";
|
2010-02-10 21:15:44 +00:00
|
|
|
ot->description = "Set the location of the 3D cursor";
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->idname = "VIEW3D_OT_cursor3d";
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2008-12-26 19:07:31 +00:00
|
|
|
/* api callbacks */
|
2012-10-05 01:27:28 +00:00
|
|
|
ot->invoke = view3d_cursor3d_invoke;
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->poll = ED_operator_view3d_active;
|
2011-04-21 13:11:51 +00:00
|
|
|
|
2009-11-02 16:07:49 +00:00
|
|
|
/* flags */
|
2012-03-22 07:26:09 +00:00
|
|
|
// ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
|
2011-04-21 13:11:51 +00:00
|
|
|
|
2008-12-26 19:07:31 +00:00
|
|
|
/* rna later */
|
|
|
|
|
|
|
|
|
|
}
|
2008-12-21 12:43:34 +00:00
|
|
|
|
2009-07-08 15:01:28 +00:00
|
|
|
/* ***************** manipulator op ******************* */
|
|
|
|
|
|
|
|
|
|
|
2013-03-13 09:03:46 +00:00
|
|
|
static int manipulator_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
2009-07-08 15:01:28 +00:00
|
|
|
{
|
|
|
|
|
View3D *v3d = CTX_wm_view3d(C);
|
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (!(v3d->twflag & V3D_USE_MANIPULATOR)) return OPERATOR_PASS_THROUGH;
|
|
|
|
|
if (!(v3d->twflag & V3D_DRAW_MANIPULATOR)) return OPERATOR_PASS_THROUGH;
|
2009-07-08 15:01:28 +00:00
|
|
|
|
2009-11-12 19:42:53 +00:00
|
|
|
/* only no modifier or shift */
|
2012-02-22 16:52:06 +00:00
|
|
|
if (event->keymodifier != 0 && event->keymodifier != KM_SHIFT) return OPERATOR_PASS_THROUGH;
|
2009-11-12 19:42:53 +00:00
|
|
|
|
2009-07-08 15:01:28 +00:00
|
|
|
/* note; otherwise opengl won't work */
|
|
|
|
|
view3d_operator_needs_opengl(C);
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
if (0 == BIF_do_manipulator(C, event, op))
|
2009-07-08 15:01:28 +00:00
|
|
|
return OPERATOR_PASS_THROUGH;
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2009-07-08 15:01:28 +00:00
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VIEW3D_OT_manipulator(wmOperatorType *ot)
|
|
|
|
|
{
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2009-07-08 15:01:28 +00:00
|
|
|
/* identifiers */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "3D Manipulator";
|
2010-02-10 21:15:44 +00:00
|
|
|
ot->description = "Manipulate selected item by axis";
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->idname = "VIEW3D_OT_manipulator";
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2009-07-08 15:01:28 +00:00
|
|
|
/* api callbacks */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->invoke = manipulator_invoke;
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->poll = ED_operator_view3d_active;
|
2009-07-09 02:45:48 +00:00
|
|
|
|
2010-04-03 17:38:43 +00:00
|
|
|
/* properties to pass to transform */
|
|
|
|
|
Transform_Properties(ot, P_CONSTRAINT);
|
2009-07-08 15:01:28 +00:00
|
|
|
}
|
|
|
|
|
|
2013-03-13 09:03:46 +00:00
|
|
|
static int enable_manipulator_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
|
2010-01-14 05:29:25 +00:00
|
|
|
{
|
|
|
|
|
View3D *v3d = CTX_wm_view3d(C);
|
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
v3d->twtype = 0;
|
2010-01-14 05:29:25 +00:00
|
|
|
|
|
|
|
|
if (RNA_boolean_get(op->ptr, "translate"))
|
|
|
|
|
v3d->twtype |= V3D_MANIP_TRANSLATE;
|
|
|
|
|
if (RNA_boolean_get(op->ptr, "rotate"))
|
|
|
|
|
v3d->twtype |= V3D_MANIP_ROTATE;
|
|
|
|
|
if (RNA_boolean_get(op->ptr, "scale"))
|
|
|
|
|
v3d->twtype |= V3D_MANIP_SCALE;
|
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
|
2010-01-14 05:29:25 +00:00
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
2009-07-08 15:01:28 +00:00
|
|
|
|
2010-01-14 05:29:25 +00:00
|
|
|
void VIEW3D_OT_enable_manipulator(wmOperatorType *ot)
|
|
|
|
|
{
|
2012-03-29 15:50:51 +00:00
|
|
|
PropertyRNA *prop;
|
|
|
|
|
|
2010-01-14 05:29:25 +00:00
|
|
|
/* identifiers */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Enable 3D Manipulator";
|
2010-02-10 21:15:44 +00:00
|
|
|
ot->description = "Enable the transform manipulator for use";
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->idname = "VIEW3D_OT_enable_manipulator";
|
2010-01-14 05:29:25 +00:00
|
|
|
|
|
|
|
|
/* api callbacks */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->invoke = enable_manipulator_invoke;
|
|
|
|
|
ot->poll = ED_operator_view3d_active;
|
2010-01-14 05:29:25 +00:00
|
|
|
|
|
|
|
|
/* rna later */
|
2012-03-29 15:50:51 +00:00
|
|
|
prop = RNA_def_boolean(ot->srna, "translate", 0, "Translate", "Enable the translate manipulator");
|
|
|
|
|
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
|
|
|
|
prop = RNA_def_boolean(ot->srna, "rotate", 0, "Rotate", "Enable the rotate manipulator");
|
|
|
|
|
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
|
|
|
|
prop = RNA_def_boolean(ot->srna, "scale", 0, "Scale", "Enable the scale manipulator");
|
|
|
|
|
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
2010-01-14 05:29:25 +00:00
|
|
|
}
|
2008-12-20 11:33:16 +00:00
|
|
|
|
2008-12-19 17:14:02 +00:00
|
|
|
/* ************************* below the line! *********************** */
|
|
|
|
|
|
|
|
|
|
|
2011-05-12 16:47:36 +00:00
|
|
|
static float view_autodist_depth_margin(ARegion *ar, const int mval[2], int margin)
|
2010-01-01 17:48:48 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
ViewDepths depth_temp = {0};
|
2010-10-21 07:38:09 +00:00
|
|
|
rcti rect;
|
|
|
|
|
float depth_close;
|
2010-01-01 17:48:48 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
if (margin == 0) {
|
2010-01-01 17:48:48 +00:00
|
|
|
/* Get Z Depths, needed for perspective, nice for ortho */
|
2012-03-24 02:51:46 +00:00
|
|
|
rect.xmin = mval[0];
|
|
|
|
|
rect.ymin = mval[1];
|
|
|
|
|
rect.xmax = mval[0] + 1;
|
|
|
|
|
rect.ymax = mval[1] + 1;
|
2010-01-01 17:48:48 +00:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
rect.xmax = mval[0] + margin;
|
|
|
|
|
rect.ymax = mval[1] + margin;
|
|
|
|
|
|
|
|
|
|
rect.xmin = mval[0] - margin;
|
|
|
|
|
rect.ymin = mval[1] - margin;
|
2010-10-21 07:38:09 +00:00
|
|
|
}
|
2010-01-01 17:48:48 +00:00
|
|
|
|
2010-10-21 07:38:09 +00:00
|
|
|
view3d_update_depths_rect(ar, &depth_temp, &rect);
|
2012-03-25 23:54:33 +00:00
|
|
|
depth_close = view3d_depth_near(&depth_temp);
|
2012-02-22 16:52:06 +00:00
|
|
|
if (depth_temp.depths) MEM_freeN(depth_temp.depths);
|
2010-10-27 08:55:13 +00:00
|
|
|
return depth_close;
|
2010-01-01 17:48:48 +00:00
|
|
|
}
|
|
|
|
|
|
2008-12-19 17:14:02 +00:00
|
|
|
/* XXX todo Zooms in on a border drawn by the user */
|
2013-09-16 08:59:54 +00:00
|
|
|
bool ED_view3d_autodist(Scene *scene, ARegion *ar, View3D *v3d,
|
|
|
|
|
const int mval[2], float mouse_worldloc[3],
|
|
|
|
|
const bool alphaoverride, const float fallback_depth_pt[3])
|
2008-12-19 17:14:02 +00:00
|
|
|
{
|
2.5
View3D has been split now in a local part (RegionView3D) and a
per-area part (old View3D). Currently local is:
- view transform
- camera zoom/offset
- gpencil (todo)
- custom clipping planes
Rest is in Area still, like active camera, draw type, layers,
localview, custom centers, around-settings, transform widget,
gridlines, and so on (mostly stuff as available in header).
To see it work; also added new feature for region split,
press SHIFT+ALT+CTRL+S for four-split.
The idea is to make a preset 4-split, configured to stick
to top/right/front views for three views.
Another cool idea to explore is to then box-clip all drawing
based on these 3 views.
Note about the code:
- currently view3d still stores some depricated settings, to
convert from older files. Not all settings are copied over
though, like custom clip planes or the 'lock view to object'.
- since some view3d ops are now on area level, the operators
for it should keep track of that.
Bugfix in transform: quat initialize in operator-invoke missed
one zero.
Als brought back GE to compile for missing Ipos and channels.
2009-01-19 16:54:41 +00:00
|
|
|
bglMats mats; /* ZBuffer depth vars */
|
2013-04-13 14:57:08 +00:00
|
|
|
float depth_close;
|
2008-12-19 17:14:02 +00:00
|
|
|
double cent[2], p[3];
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2008-12-19 17:14:02 +00:00
|
|
|
/* Get Z Depths, needed for perspective, nice for ortho */
|
|
|
|
|
bgl_get_mats(&mats);
|
2013-03-17 20:24:47 +00:00
|
|
|
draw_depth(scene, ar, v3d, NULL, alphaoverride);
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
depth_close = view_autodist_depth_margin(ar, mval, 4);
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2013-09-16 08:59:54 +00:00
|
|
|
if (depth_close != FLT_MAX) {
|
|
|
|
|
cent[0] = (double)mval[0];
|
|
|
|
|
cent[1] = (double)mval[1];
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2013-09-16 08:59:54 +00:00
|
|
|
if (gluUnProject(cent[0], cent[1], depth_close,
|
|
|
|
|
mats.modelview, mats.projection, (GLint *)mats.viewport, &p[0], &p[1], &p[2]))
|
|
|
|
|
{
|
|
|
|
|
mouse_worldloc[0] = (float)p[0];
|
|
|
|
|
mouse_worldloc[1] = (float)p[1];
|
|
|
|
|
mouse_worldloc[2] = (float)p[2];
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
2008-12-26 10:31:44 +00:00
|
|
|
|
2013-09-16 08:59:54 +00:00
|
|
|
if (fallback_depth_pt) {
|
|
|
|
|
ED_view3d_win_to_3d_int(ar, fallback_depth_pt, mval, mouse_worldloc);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
else {
|
2013-03-20 23:14:18 +00:00
|
|
|
return false;
|
2012-01-19 16:04:44 +00:00
|
|
|
}
|
2008-12-19 12:14:58 +00:00
|
|
|
}
|
|
|
|
|
|
2013-03-20 23:14:18 +00:00
|
|
|
void ED_view3d_autodist_init(Scene *scene, ARegion *ar, View3D *v3d, int mode)
|
2009-11-30 01:13:46 +00:00
|
|
|
{
|
|
|
|
|
/* Get Z Depths, needed for perspective, nice for ortho */
|
2012-03-25 23:54:33 +00:00
|
|
|
switch (mode) {
|
|
|
|
|
case 0:
|
2013-03-17 20:24:47 +00:00
|
|
|
draw_depth(scene, ar, v3d, NULL, true);
|
2012-03-25 23:54:33 +00:00
|
|
|
break;
|
|
|
|
|
case 1:
|
|
|
|
|
draw_depth_gpencil(scene, ar, v3d);
|
|
|
|
|
break;
|
2010-01-01 16:46:27 +00:00
|
|
|
}
|
2009-11-30 01:13:46 +00:00
|
|
|
}
|
|
|
|
|
|
2013-03-20 13:30:20 +00:00
|
|
|
/* no 4x4 sampling, run #ED_view3d_autodist_init first */
|
2013-03-20 23:14:18 +00:00
|
|
|
bool ED_view3d_autodist_simple(ARegion *ar, const int mval[2], float mouse_worldloc[3],
|
|
|
|
|
int margin, float *force_depth)
|
2009-11-30 01:13:46 +00:00
|
|
|
{
|
|
|
|
|
bglMats mats; /* ZBuffer depth vars, could cache? */
|
|
|
|
|
float depth;
|
|
|
|
|
double cent[2], p[3];
|
|
|
|
|
|
|
|
|
|
/* Get Z Depths, needed for perspective, nice for ortho */
|
2012-02-22 16:52:06 +00:00
|
|
|
if (force_depth)
|
2012-03-25 23:54:33 +00:00
|
|
|
depth = *force_depth;
|
2010-01-01 15:05:31 +00:00
|
|
|
else
|
2012-03-25 23:54:33 +00:00
|
|
|
depth = view_autodist_depth_margin(ar, mval, margin);
|
2008-12-19 12:14:58 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
if (depth == FLT_MAX)
|
2013-03-20 23:14:18 +00:00
|
|
|
return false;
|
2009-11-30 01:13:46 +00:00
|
|
|
|
|
|
|
|
cent[0] = (double)mval[0];
|
|
|
|
|
cent[1] = (double)mval[1];
|
|
|
|
|
|
2010-01-01 15:05:31 +00:00
|
|
|
bgl_get_mats(&mats);
|
2012-01-19 16:04:44 +00:00
|
|
|
|
|
|
|
|
if (!gluUnProject(cent[0], cent[1], depth,
|
2012-03-25 23:54:33 +00:00
|
|
|
mats.modelview, mats.projection, (GLint *)mats.viewport, &p[0], &p[1], &p[2]))
|
2012-01-19 16:04:44 +00:00
|
|
|
{
|
2013-03-20 23:14:18 +00:00
|
|
|
return false;
|
2012-01-19 16:04:44 +00:00
|
|
|
}
|
2008-12-19 12:14:58 +00:00
|
|
|
|
2009-11-30 01:13:46 +00:00
|
|
|
mouse_worldloc[0] = (float)p[0];
|
|
|
|
|
mouse_worldloc[1] = (float)p[1];
|
|
|
|
|
mouse_worldloc[2] = (float)p[2];
|
2013-03-20 23:14:18 +00:00
|
|
|
return true;
|
2009-11-30 01:13:46 +00:00
|
|
|
}
|
2008-12-19 17:14:02 +00:00
|
|
|
|
2013-03-20 23:14:18 +00:00
|
|
|
bool ED_view3d_autodist_depth(ARegion *ar, const int mval[2], int margin, float *depth)
|
2010-01-01 15:05:31 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
*depth = view_autodist_depth_margin(ar, mval, margin);
|
2010-01-01 15:05:31 +00:00
|
|
|
|
2013-03-20 23:14:18 +00:00
|
|
|
return (*depth != FLT_MAX);
|
2011-02-02 03:32:58 +00:00
|
|
|
}
|
|
|
|
|
|
2013-03-20 23:14:18 +00:00
|
|
|
static bool depth_segment_cb(int x, int y, void *userData)
|
2011-02-02 03:32:58 +00:00
|
|
|
{
|
2012-07-26 22:47:05 +00:00
|
|
|
struct { ARegion *ar; int margin; float depth; } *data = userData;
|
2011-05-12 16:47:36 +00:00
|
|
|
int mval[2];
|
2011-02-02 03:32:58 +00:00
|
|
|
float depth;
|
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
mval[0] = x;
|
|
|
|
|
mval[1] = y;
|
2011-02-02 03:32:58 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
depth = view_autodist_depth_margin(data->ar, mval, data->margin);
|
2011-02-02 03:32:58 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (depth != FLT_MAX) {
|
2012-03-25 23:54:33 +00:00
|
|
|
data->depth = depth;
|
2010-01-01 15:05:31 +00:00
|
|
|
return 0;
|
2011-02-02 03:32:58 +00:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-03-20 23:14:18 +00:00
|
|
|
bool ED_view3d_autodist_depth_seg(ARegion *ar, const int mval_sta[2], const int mval_end[2],
|
|
|
|
|
int margin, float *depth)
|
2011-02-02 03:32:58 +00:00
|
|
|
{
|
2012-07-26 22:47:05 +00:00
|
|
|
struct { ARegion *ar; int margin; float depth; } data = {NULL};
|
2011-02-02 03:32:58 +00:00
|
|
|
int p1[2];
|
|
|
|
|
int p2[2];
|
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
data.ar = ar;
|
|
|
|
|
data.margin = margin;
|
|
|
|
|
data.depth = FLT_MAX;
|
2011-02-02 03:32:58 +00:00
|
|
|
|
2011-11-07 01:38:32 +00:00
|
|
|
copy_v2_v2_int(p1, mval_sta);
|
|
|
|
|
copy_v2_v2_int(p2, mval_end);
|
2011-02-02 03:32:58 +00:00
|
|
|
|
|
|
|
|
plot_line_v2v2i(p1, p2, depth_segment_cb, &data);
|
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
*depth = data.depth;
|
2011-02-02 03:32:58 +00:00
|
|
|
|
2013-03-20 23:14:18 +00:00
|
|
|
return (*depth != FLT_MAX);
|
2010-01-01 15:05:31 +00:00
|
|
|
}
|
|
|
|
|
|
2012-12-11 15:56:11 +00:00
|
|
|
/* problem - ofs[3] can be on same location as camera itself.
|
|
|
|
|
* Blender needs proper dist value for zoom.
|
|
|
|
|
* use fallback_dist to override small values
|
|
|
|
|
*/
|
|
|
|
|
float ED_view3d_offset_distance(float mat[4][4], const float ofs[3], const float fallback_dist)
|
2012-12-11 14:45:38 +00:00
|
|
|
{
|
2012-10-24 16:15:46 +00:00
|
|
|
float pos[4] = {0.0f, 0.0f, 0.0f, 1.0f};
|
|
|
|
|
float dir[4] = {0.0f, 0.0f, 1.0f, 0.0f};
|
2012-12-11 14:45:38 +00:00
|
|
|
float dist;
|
|
|
|
|
|
2012-10-24 16:15:46 +00:00
|
|
|
mul_m4_v4(mat, pos);
|
|
|
|
|
add_v3_v3(pos, ofs);
|
|
|
|
|
mul_m4_v4(mat, dir);
|
|
|
|
|
normalize_v3(dir);
|
|
|
|
|
|
2012-12-11 14:45:38 +00:00
|
|
|
dist = dot_v3v3(pos, dir);
|
2012-12-11 15:56:11 +00:00
|
|
|
|
|
|
|
|
if ((dist < FLT_EPSILON) && (fallback_dist != 0.0f)) {
|
|
|
|
|
dist = fallback_dist;
|
2012-12-11 14:45:38 +00:00
|
|
|
}
|
2012-12-11 15:56:11 +00:00
|
|
|
|
2012-12-11 14:45:38 +00:00
|
|
|
return dist;
|
2012-10-24 16:15:46 +00:00
|
|
|
}
|
|
|
|
|
|
2014-02-20 10:00:16 +11:00
|
|
|
/**
|
|
|
|
|
* Set the dist without moving the view (compensate with #RegionView3D.ofs)
|
|
|
|
|
*
|
|
|
|
|
* \note take care that viewinv is up to date, #ED_view3d_update_viewmat first.
|
|
|
|
|
*/
|
|
|
|
|
void ED_view3d_distance_set(RegionView3D *rv3d, const float dist)
|
|
|
|
|
{
|
2014-02-24 15:15:17 +11:00
|
|
|
float viewinv[4];
|
2014-02-20 10:00:16 +11:00
|
|
|
float tvec[3];
|
|
|
|
|
|
|
|
|
|
BLI_assert(dist >= 0.0f);
|
|
|
|
|
|
|
|
|
|
copy_v3_fl3(tvec, 0.0f, 0.0f, rv3d->dist - dist);
|
2014-02-24 15:15:17 +11:00
|
|
|
/* rv3d->viewinv isn't always valid */
|
|
|
|
|
#if 0
|
2014-02-20 10:00:16 +11:00
|
|
|
mul_mat3_m4_v3(rv3d->viewinv, tvec);
|
2014-02-24 15:15:17 +11:00
|
|
|
#else
|
|
|
|
|
invert_qt_qt(viewinv, rv3d->viewquat);
|
|
|
|
|
mul_qt_v3(viewinv, tvec);
|
|
|
|
|
#endif
|
2014-02-20 10:00:16 +11:00
|
|
|
sub_v3_v3(rv3d->ofs, tvec);
|
|
|
|
|
|
|
|
|
|
rv3d->dist = dist;
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-03 11:45:08 +00:00
|
|
|
/**
|
2012-09-20 04:56:24 +00:00
|
|
|
* Set the view transformation from a 4x4 matrix.
|
2012-03-03 11:45:08 +00:00
|
|
|
*
|
2012-09-20 04:56:24 +00:00
|
|
|
* \param mat The view 4x4 transformation matrix to assign.
|
|
|
|
|
* \param ofs The view offset, normally from RegionView3D.ofs.
|
|
|
|
|
* \param quat The view rotation, quaternion normally from RegionView3D.viewquat.
|
|
|
|
|
* \param dist The view distance from ofs, normally from RegionView3D.dist.
|
2012-03-03 11:45:08 +00:00
|
|
|
*/
|
2012-12-11 14:29:01 +00:00
|
|
|
void ED_view3d_from_m4(float mat[4][4], float ofs[3], float quat[4], float *dist)
|
2011-05-14 04:25:47 +00:00
|
|
|
{
|
2013-07-27 14:44:52 +00:00
|
|
|
float nmat[3][3];
|
|
|
|
|
|
|
|
|
|
/* dist depends on offset */
|
|
|
|
|
BLI_assert(dist == NULL || ofs != NULL);
|
|
|
|
|
|
|
|
|
|
copy_m3_m4(nmat, mat);
|
|
|
|
|
normalize_m3(nmat);
|
|
|
|
|
|
2011-05-14 04:25:47 +00:00
|
|
|
/* Offset */
|
|
|
|
|
if (ofs)
|
|
|
|
|
negate_v3_v3(ofs, mat[3]);
|
|
|
|
|
|
|
|
|
|
/* Quat */
|
|
|
|
|
if (quat) {
|
2013-07-27 14:44:52 +00:00
|
|
|
float imat[3][3];
|
|
|
|
|
invert_m3_m3(imat, nmat);
|
|
|
|
|
mat3_to_quat(quat, imat);
|
2011-05-14 04:25:47 +00:00
|
|
|
}
|
|
|
|
|
|
2013-07-27 14:44:52 +00:00
|
|
|
if (ofs && dist) {
|
|
|
|
|
float vec[3] = {0.0f, 0.0f, -(*dist)};
|
2011-05-14 04:25:47 +00:00
|
|
|
|
2011-08-31 01:07:55 +00:00
|
|
|
mul_m3_v3(nmat, vec);
|
2011-05-14 04:25:47 +00:00
|
|
|
sub_v3_v3(ofs, vec);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-20 04:56:24 +00:00
|
|
|
/**
|
|
|
|
|
* Calculate the view transformation matrix from RegionView3D input.
|
|
|
|
|
* The resulting matrix is equivalent to RegionView3D.viewinv
|
|
|
|
|
* \param mat The view 4x4 transformation matrix to calculate.
|
|
|
|
|
* \param ofs The view offset, normally from RegionView3D.ofs.
|
|
|
|
|
* \param quat The view rotation, quaternion normally from RegionView3D.viewquat.
|
|
|
|
|
* \param dist The view distance from ofs, normally from RegionView3D.dist.
|
|
|
|
|
*/
|
2012-12-11 14:29:01 +00:00
|
|
|
void ED_view3d_to_m4(float mat[4][4], const float ofs[3], const float quat[4], const float dist)
|
2011-05-23 02:23:03 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
float iviewquat[4] = {-quat[0], quat[1], quat[2], quat[3]};
|
|
|
|
|
float dvec[3] = {0.0f, 0.0f, dist};
|
2011-05-23 02:23:03 +00:00
|
|
|
|
|
|
|
|
quat_to_mat4(mat, iviewquat);
|
|
|
|
|
mul_mat3_m4_v3(mat, dvec);
|
|
|
|
|
sub_v3_v3v3(mat[3], dvec, ofs);
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-20 04:56:24 +00:00
|
|
|
/**
|
|
|
|
|
* Set the RegionView3D members from an objects transformation and optionally lens.
|
|
|
|
|
* \param ob The object to set the view to.
|
|
|
|
|
* \param ofs The view offset to be set, normally from RegionView3D.ofs.
|
|
|
|
|
* \param quat The view rotation to be set, quaternion normally from RegionView3D.viewquat.
|
|
|
|
|
* \param dist The view distance from ofs to be set, normally from RegionView3D.dist.
|
|
|
|
|
* \param lens The view lens angle set for cameras and lamps, normally from View3D.lens.
|
|
|
|
|
*/
|
2011-05-14 04:25:47 +00:00
|
|
|
void ED_view3d_from_object(Object *ob, float ofs[3], float quat[4], float *dist, float *lens)
|
|
|
|
|
{
|
|
|
|
|
ED_view3d_from_m4(ob->obmat, ofs, quat, dist);
|
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (lens) {
|
2011-11-18 23:32:17 +00:00
|
|
|
CameraParams params;
|
|
|
|
|
|
2012-05-05 00:58:22 +00:00
|
|
|
BKE_camera_params_init(¶ms);
|
|
|
|
|
BKE_camera_params_from_object(¶ms, ob);
|
2012-03-25 23:54:33 +00:00
|
|
|
*lens = params.lens;
|
2011-05-14 04:25:47 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-20 04:56:24 +00:00
|
|
|
/**
|
|
|
|
|
* Set the object transformation from RegionView3D members.
|
|
|
|
|
* \param ob The object which has the transformation assigned.
|
|
|
|
|
* \param ofs The view offset, normally from RegionView3D.ofs.
|
|
|
|
|
* \param quat The view rotation, quaternion normally from RegionView3D.viewquat.
|
|
|
|
|
* \param dist The view distance from ofs, normally from RegionView3D.dist.
|
|
|
|
|
*/
|
2011-05-14 04:25:47 +00:00
|
|
|
void ED_view3d_to_object(Object *ob, const float ofs[3], const float quat[4], const float dist)
|
|
|
|
|
{
|
2011-05-23 02:23:03 +00:00
|
|
|
float mat[4][4];
|
|
|
|
|
ED_view3d_to_m4(mat, ofs, quat, dist);
|
2013-03-20 23:14:18 +00:00
|
|
|
BKE_object_apply_mat4(ob, mat, true, true);
|
2011-05-14 04:25:47 +00:00
|
|
|
}
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2011-11-18 14:28:45 +00:00
|
|
|
BGpic *ED_view3D_background_image_new(View3D *v3d)
|
2011-11-07 12:55:18 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
BGpic *bgpic = MEM_callocN(sizeof(BGpic), "Background Image");
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
bgpic->size = 5.0;
|
|
|
|
|
bgpic->blend = 0.5;
|
|
|
|
|
bgpic->iuser.fie_ima = 2;
|
|
|
|
|
bgpic->iuser.ok = 1;
|
|
|
|
|
bgpic->view = 0; /* 0 for all */
|
2011-11-18 15:29:40 +00:00
|
|
|
bgpic->flag |= V3D_BGPIC_EXPANDED;
|
2011-11-07 12:55:18 +00:00
|
|
|
|
|
|
|
|
BLI_addtail(&v3d->bgpicbase, bgpic);
|
|
|
|
|
|
|
|
|
|
return bgpic;
|
|
|
|
|
}
|
2011-11-18 14:28:45 +00:00
|
|
|
|
2011-11-23 16:12:11 +00:00
|
|
|
void ED_view3D_background_image_remove(View3D *v3d, BGpic *bgpic)
|
2011-11-18 14:28:45 +00:00
|
|
|
{
|
|
|
|
|
BLI_remlink(&v3d->bgpicbase, bgpic);
|
|
|
|
|
|
|
|
|
|
MEM_freeN(bgpic);
|
|
|
|
|
}
|
2011-11-23 16:12:11 +00:00
|
|
|
|
|
|
|
|
void ED_view3D_background_image_clear(View3D *v3d)
|
|
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
BGpic *bgpic = v3d->bgpicbase.first;
|
2011-11-23 16:12:11 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
while (bgpic) {
|
2012-03-25 23:54:33 +00:00
|
|
|
BGpic *next_bgpic = bgpic->next;
|
2011-11-23 16:12:11 +00:00
|
|
|
|
|
|
|
|
ED_view3D_background_image_remove(v3d, bgpic);
|
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
bgpic = next_bgpic;
|
2011-11-23 16:12:11 +00:00
|
|
|
}
|
|
|
|
|
}
|
2012-05-05 16:38:23 +00:00
|
|
|
|
|
|
|
|
void ED_view3D_lock_clear(View3D *v3d)
|
|
|
|
|
{
|
|
|
|
|
v3d->ob_centre = NULL;
|
|
|
|
|
v3d->ob_centre_bone[0] = '\0';
|
2013-03-20 23:14:18 +00:00
|
|
|
v3d->ob_centre_cursor = false;
|
2012-05-05 16:38:23 +00:00
|
|
|
v3d->flag2 &= ~V3D_LOCK_CAMERA;
|
|
|
|
|
}
|