2011-02-23 10:52:22 +00:00
|
|
|
/*
|
2010-10-25 07:09:38 +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
|
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
|
*
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
|
* along with this program; if not, write to the Free Software Foundation,
|
|
|
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
|
*
|
|
|
|
|
* Contributor(s): Campbell Barton
|
|
|
|
|
*
|
|
|
|
|
* ***** END GPL LICENSE BLOCK *****
|
|
|
|
|
*/
|
|
|
|
|
|
2011-02-27 20:29:51 +00:00
|
|
|
/** \file blender/editors/space_view3d/view3d_fly.c
|
|
|
|
|
* \ingroup spview3d
|
|
|
|
|
*/
|
|
|
|
|
|
2010-10-25 07:09:38 +00:00
|
|
|
/* defines VIEW3D_OT_fly modal operator */
|
|
|
|
|
|
2011-07-31 06:26:03 +00:00
|
|
|
//#define NDOF_FLY_DEBUG
|
2012-10-20 20:20:02 +00:00
|
|
|
//#define NDOF_FLY_DRAW_TOOMUCH /* is this needed for ndof? - commented so redraw doesnt thrash - campbell */
|
2010-10-25 07:09:38 +00:00
|
|
|
#include "DNA_anim_types.h"
|
|
|
|
|
#include "DNA_scene_types.h"
|
|
|
|
|
#include "DNA_object_types.h"
|
2011-09-26 08:33:51 +00:00
|
|
|
#include "DNA_camera_types.h"
|
2010-10-25 07:09:38 +00:00
|
|
|
|
|
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
|
|
|
|
|
#include "BLI_math.h"
|
|
|
|
|
#include "BLI_blenlib.h"
|
2011-01-07 18:36:47 +00:00
|
|
|
#include "BLI_utildefines.h"
|
2010-10-25 07:09:38 +00:00
|
|
|
|
|
|
|
|
#include "BKE_context.h"
|
|
|
|
|
#include "BKE_object.h"
|
|
|
|
|
#include "BKE_report.h"
|
|
|
|
|
|
|
|
|
|
#include "BKE_depsgraph.h" /* for fly mode updating */
|
|
|
|
|
|
|
|
|
|
#include "BIF_gl.h"
|
|
|
|
|
|
|
|
|
|
#include "WM_api.h"
|
|
|
|
|
#include "WM_types.h"
|
|
|
|
|
|
|
|
|
|
#include "ED_keyframing.h"
|
|
|
|
|
#include "ED_screen.h"
|
|
|
|
|
#include "ED_space_api.h"
|
|
|
|
|
|
|
|
|
|
#include "PIL_time.h" /* smoothview */
|
|
|
|
|
|
2012-04-02 06:26:52 +00:00
|
|
|
#include "view3d_intern.h" /* own include */
|
2010-10-25 07:09:38 +00:00
|
|
|
/* NOTE: these defines are saved in keymap files, do not change values but just add new ones */
|
2011-09-25 04:47:46 +00:00
|
|
|
enum {
|
2012-03-10 06:46:23 +00:00
|
|
|
FLY_MODAL_CANCEL = 1,
|
2011-09-25 04:47:46 +00:00
|
|
|
FLY_MODAL_CONFIRM,
|
|
|
|
|
FLY_MODAL_ACCELERATE,
|
|
|
|
|
FLY_MODAL_DECELERATE,
|
|
|
|
|
FLY_MODAL_PAN_ENABLE,
|
|
|
|
|
FLY_MODAL_PAN_DISABLE,
|
|
|
|
|
FLY_MODAL_DIR_FORWARD,
|
|
|
|
|
FLY_MODAL_DIR_BACKWARD,
|
|
|
|
|
FLY_MODAL_DIR_LEFT,
|
|
|
|
|
FLY_MODAL_DIR_RIGHT,
|
|
|
|
|
FLY_MODAL_DIR_UP,
|
|
|
|
|
FLY_MODAL_DIR_DOWN,
|
|
|
|
|
FLY_MODAL_AXIS_LOCK_X,
|
|
|
|
|
FLY_MODAL_AXIS_LOCK_Z,
|
|
|
|
|
FLY_MODAL_PRECISION_ENABLE,
|
|
|
|
|
FLY_MODAL_PRECISION_DISABLE,
|
|
|
|
|
FLY_MODAL_FREELOOK_ENABLE,
|
2013-01-08 16:54:26 +00:00
|
|
|
FLY_MODAL_FREELOOK_DISABLE,
|
|
|
|
|
FLY_MODAL_SPEED, /* mousepan typically */
|
2011-09-25 04:47:46 +00:00
|
|
|
|
|
|
|
|
};
|
2010-10-25 07:09:38 +00:00
|
|
|
|
|
|
|
|
/* called in transform_ops.c, on each regeneration of keymaps */
|
|
|
|
|
void fly_modal_keymap(wmKeyConfig *keyconf)
|
|
|
|
|
{
|
|
|
|
|
static EnumPropertyItem modal_items[] = {
|
2012-03-10 06:46:23 +00:00
|
|
|
{FLY_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""},
|
|
|
|
|
{FLY_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""},
|
|
|
|
|
{FLY_MODAL_ACCELERATE, "ACCELERATE", 0, "Accelerate", ""},
|
|
|
|
|
{FLY_MODAL_DECELERATE, "DECELERATE", 0, "Decelerate", ""},
|
2010-10-25 07:09:38 +00:00
|
|
|
|
2012-03-10 06:46:23 +00:00
|
|
|
{FLY_MODAL_PAN_ENABLE, "PAN_ENABLE", 0, "Pan Enable", ""},
|
|
|
|
|
{FLY_MODAL_PAN_DISABLE, "PAN_DISABLE", 0, "Pan Disable", ""},
|
2010-10-25 07:09:38 +00:00
|
|
|
|
2012-03-10 06:46:23 +00:00
|
|
|
{FLY_MODAL_DIR_FORWARD, "FORWARD", 0, "Fly Forward", ""},
|
|
|
|
|
{FLY_MODAL_DIR_BACKWARD, "BACKWARD", 0, "Fly Backward", ""},
|
|
|
|
|
{FLY_MODAL_DIR_LEFT, "LEFT", 0, "Fly Left", ""},
|
|
|
|
|
{FLY_MODAL_DIR_RIGHT, "RIGHT", 0, "Fly Right", ""},
|
|
|
|
|
{FLY_MODAL_DIR_UP, "UP", 0, "Fly Up", ""},
|
|
|
|
|
{FLY_MODAL_DIR_DOWN, "DOWN", 0, "Fly Down", ""},
|
2010-10-25 07:09:38 +00:00
|
|
|
|
2012-03-10 06:46:23 +00:00
|
|
|
{FLY_MODAL_AXIS_LOCK_X, "AXIS_LOCK_X", 0, "X Axis Correction", "X axis correction (toggle)"},
|
|
|
|
|
{FLY_MODAL_AXIS_LOCK_Z, "AXIS_LOCK_Z", 0, "X Axis Correction", "Z axis correction (toggle)"},
|
2010-10-25 07:09:38 +00:00
|
|
|
|
2012-03-10 06:46:23 +00:00
|
|
|
{FLY_MODAL_PRECISION_ENABLE, "PRECISION_ENABLE", 0, "Precision Enable", ""},
|
|
|
|
|
{FLY_MODAL_PRECISION_DISABLE, "PRECISION_DISABLE", 0, "Precision Disable", ""},
|
2010-10-25 07:09:38 +00:00
|
|
|
|
2012-03-10 06:46:23 +00:00
|
|
|
{FLY_MODAL_FREELOOK_ENABLE, "FREELOOK_ENABLE", 0, "Rotation Enable", ""},
|
|
|
|
|
{FLY_MODAL_FREELOOK_DISABLE, "FREELOOK_DISABLE", 0, "Rotation Disable", ""},
|
2011-09-25 04:47:46 +00:00
|
|
|
|
2012-03-10 06:46:23 +00:00
|
|
|
{0, NULL, 0, NULL, NULL}};
|
2010-10-25 07:09:38 +00:00
|
|
|
|
2012-03-10 06:46:23 +00:00
|
|
|
wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "View3D Fly Modal");
|
2010-10-25 07:09:38 +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)
|
2012-03-10 06:46:23 +00:00
|
|
|
return;
|
2010-10-25 07:09:38 +00:00
|
|
|
|
2012-03-10 06:46:23 +00:00
|
|
|
keymap = WM_modalkeymap_add(keyconf, "View3D Fly Modal", modal_items);
|
2010-10-25 07:09:38 +00:00
|
|
|
|
|
|
|
|
/* items for modal map */
|
2012-03-10 06:46:23 +00:00
|
|
|
WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, FLY_MODAL_CANCEL);
|
2010-10-25 07:09:38 +00:00
|
|
|
WM_modalkeymap_add_item(keymap, RIGHTMOUSE, KM_ANY, KM_ANY, 0, FLY_MODAL_CANCEL);
|
|
|
|
|
|
|
|
|
|
WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_ANY, KM_ANY, 0, FLY_MODAL_CONFIRM);
|
|
|
|
|
WM_modalkeymap_add_item(keymap, RETKEY, KM_PRESS, KM_ANY, 0, FLY_MODAL_CONFIRM);
|
|
|
|
|
WM_modalkeymap_add_item(keymap, SPACEKEY, KM_PRESS, KM_ANY, 0, FLY_MODAL_CONFIRM);
|
|
|
|
|
WM_modalkeymap_add_item(keymap, PADENTER, KM_PRESS, KM_ANY, 0, FLY_MODAL_CONFIRM);
|
|
|
|
|
|
2011-09-25 04:47:46 +00:00
|
|
|
WM_modalkeymap_add_item(keymap, PADPLUSKEY, KM_PRESS, KM_ANY, 0, FLY_MODAL_ACCELERATE);
|
|
|
|
|
WM_modalkeymap_add_item(keymap, PADMINUS, KM_PRESS, KM_ANY, 0, FLY_MODAL_DECELERATE);
|
|
|
|
|
WM_modalkeymap_add_item(keymap, WHEELUPMOUSE, KM_PRESS, KM_ANY, 0, FLY_MODAL_ACCELERATE);
|
|
|
|
|
WM_modalkeymap_add_item(keymap, WHEELDOWNMOUSE, KM_PRESS, KM_ANY, 0, FLY_MODAL_DECELERATE);
|
2010-10-25 07:09:38 +00:00
|
|
|
|
2013-01-08 16:54:26 +00:00
|
|
|
WM_modalkeymap_add_item(keymap, MOUSEPAN, 0, 0, 0, FLY_MODAL_SPEED);
|
|
|
|
|
|
2010-10-25 07:09:38 +00:00
|
|
|
WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_PRESS, KM_ANY, 0, FLY_MODAL_PAN_ENABLE);
|
2012-01-19 16:04:44 +00:00
|
|
|
/* XXX - Bug in the event system, middle mouse release doesnt work */
|
|
|
|
|
WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, KM_ANY, 0, FLY_MODAL_PAN_DISABLE);
|
2010-10-25 07:09:38 +00:00
|
|
|
|
|
|
|
|
/* WASD */
|
|
|
|
|
WM_modalkeymap_add_item(keymap, WKEY, KM_PRESS, 0, 0, FLY_MODAL_DIR_FORWARD);
|
|
|
|
|
WM_modalkeymap_add_item(keymap, SKEY, KM_PRESS, 0, 0, FLY_MODAL_DIR_BACKWARD);
|
|
|
|
|
WM_modalkeymap_add_item(keymap, AKEY, KM_PRESS, 0, 0, FLY_MODAL_DIR_LEFT);
|
|
|
|
|
WM_modalkeymap_add_item(keymap, DKEY, KM_PRESS, 0, 0, FLY_MODAL_DIR_RIGHT);
|
|
|
|
|
WM_modalkeymap_add_item(keymap, RKEY, KM_PRESS, 0, 0, FLY_MODAL_DIR_UP);
|
|
|
|
|
WM_modalkeymap_add_item(keymap, FKEY, KM_PRESS, 0, 0, FLY_MODAL_DIR_DOWN);
|
|
|
|
|
|
|
|
|
|
WM_modalkeymap_add_item(keymap, XKEY, KM_PRESS, 0, 0, FLY_MODAL_AXIS_LOCK_X);
|
|
|
|
|
WM_modalkeymap_add_item(keymap, ZKEY, KM_PRESS, 0, 0, FLY_MODAL_AXIS_LOCK_Z);
|
|
|
|
|
|
|
|
|
|
WM_modalkeymap_add_item(keymap, LEFTSHIFTKEY, KM_PRESS, KM_ANY, 0, FLY_MODAL_PRECISION_ENABLE);
|
|
|
|
|
WM_modalkeymap_add_item(keymap, LEFTSHIFTKEY, KM_RELEASE, KM_ANY, 0, FLY_MODAL_PRECISION_DISABLE);
|
|
|
|
|
|
2011-09-25 04:47:46 +00:00
|
|
|
WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_PRESS, KM_ANY, 0, FLY_MODAL_FREELOOK_ENABLE);
|
|
|
|
|
WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_RELEASE, KM_ANY, 0, FLY_MODAL_FREELOOK_DISABLE);
|
|
|
|
|
|
2010-10-25 07:09:38 +00:00
|
|
|
/* assign map to operators */
|
|
|
|
|
WM_modalkeymap_assign(keymap, "VIEW3D_OT_fly");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
typedef struct FlyInfo {
|
|
|
|
|
/* context stuff */
|
|
|
|
|
RegionView3D *rv3d;
|
|
|
|
|
View3D *v3d;
|
|
|
|
|
ARegion *ar;
|
|
|
|
|
Scene *scene;
|
|
|
|
|
|
|
|
|
|
wmTimer *timer; /* needed for redraws */
|
|
|
|
|
|
|
|
|
|
short state;
|
|
|
|
|
short redraw;
|
2011-09-25 04:47:46 +00:00
|
|
|
unsigned char use_precision;
|
2012-03-10 06:46:23 +00:00
|
|
|
/* if the user presses shift they can look about
|
|
|
|
|
* without moving the direction there looking */
|
|
|
|
|
unsigned char use_freelook;
|
2011-07-14 21:20:45 +00:00
|
|
|
|
|
|
|
|
int mval[2]; /* latest 2D mouse values */
|
2012-05-08 15:55:29 +00:00
|
|
|
wmNDOFMotionData *ndof; /* latest 3D mouse values */
|
2010-10-25 07:09:38 +00:00
|
|
|
|
|
|
|
|
/* fly state state */
|
|
|
|
|
float speed; /* the speed the view is moving per redraw */
|
2011-10-17 06:39:13 +00:00
|
|
|
short axis; /* Axis index to move along by default Z to move along the view */
|
2010-10-25 07:09:38 +00:00
|
|
|
short pan_view; /* when true, pan the view instead of rotating */
|
|
|
|
|
|
|
|
|
|
/* relative view axis locking - xlock, zlock
|
2012-03-03 16:31:46 +00:00
|
|
|
* 0) disabled
|
2012-03-04 04:35:12 +00:00
|
|
|
* 1) enabled but not checking because mouse hasn't moved outside the margin since locking was checked an not needed
|
2012-03-03 16:31:46 +00:00
|
|
|
* when the mouse moves, locking is set to 2 so checks are done.
|
2012-03-10 22:00:55 +00:00
|
|
|
* 2) mouse moved and checking needed, if no view altering is done its changed back to 1 */
|
2010-10-25 07:09:38 +00:00
|
|
|
short xlock, zlock;
|
|
|
|
|
float xlock_momentum, zlock_momentum; /* nicer dynamics */
|
|
|
|
|
float grid; /* world scale 1.0 default */
|
|
|
|
|
|
|
|
|
|
/* root most parent */
|
|
|
|
|
Object *root_parent;
|
|
|
|
|
|
|
|
|
|
/* backup values */
|
|
|
|
|
float dist_backup; /* backup the views distance since we use a zero dist for fly mode */
|
2012-03-09 00:41:09 +00:00
|
|
|
float ofs_backup[3]; /* backup the views offset in case the user cancels flying in non camera mode */
|
2010-10-25 07:09:38 +00:00
|
|
|
|
2012-03-10 06:46:23 +00:00
|
|
|
/* backup the views quat in case the user cancels flying in non camera mode.
|
|
|
|
|
* (quat for view, eul for camera) */
|
|
|
|
|
float rot_backup[4];
|
|
|
|
|
short persp_backup; /* remember if were ortho or not, only used for restoring the view if it was a ortho view */
|
2011-09-26 08:33:51 +00:00
|
|
|
|
2012-03-10 06:46:23 +00:00
|
|
|
/* are we flying an ortho camera in perspective view,
|
|
|
|
|
* which was originall in ortho view?
|
|
|
|
|
* could probably figure it out but better be explicit */
|
|
|
|
|
short is_ortho_cam;
|
2010-10-25 07:09:38 +00:00
|
|
|
void *obtfm; /* backup the objects transform */
|
|
|
|
|
|
|
|
|
|
/* compare between last state */
|
|
|
|
|
double time_lastwheel; /* used to accelerate when using the mousewheel a lot */
|
|
|
|
|
double time_lastdraw; /* time between draws */
|
|
|
|
|
|
|
|
|
|
void *draw_handle_pixel;
|
|
|
|
|
|
|
|
|
|
/* use for some lag */
|
|
|
|
|
float dvec_prev[3]; /* old for some lag */
|
|
|
|
|
|
|
|
|
|
} FlyInfo;
|
|
|
|
|
|
2012-07-26 22:47:05 +00:00
|
|
|
static void drawFlyPixel(const struct bContext *UNUSED(C), ARegion *UNUSED(ar), void *arg)
|
2010-10-25 07:09:38 +00:00
|
|
|
{
|
|
|
|
|
FlyInfo *fly = arg;
|
|
|
|
|
|
|
|
|
|
/* draws 4 edge brackets that frame the safe area where the
|
2012-03-03 16:31:46 +00:00
|
|
|
* mouse can move during fly mode without spinning the view */
|
2010-10-25 07:09:38 +00:00
|
|
|
float x1, x2, y1, y2;
|
2012-03-10 06:46:23 +00:00
|
|
|
|
|
|
|
|
x1 = 0.45f * (float)fly->ar->winx;
|
|
|
|
|
y1 = 0.45f * (float)fly->ar->winy;
|
|
|
|
|
x2 = 0.55f * (float)fly->ar->winx;
|
|
|
|
|
y2 = 0.55f * (float)fly->ar->winy;
|
2010-10-25 07:09:38 +00:00
|
|
|
cpack(0);
|
2012-03-10 06:46:23 +00:00
|
|
|
|
2010-10-25 07:09:38 +00:00
|
|
|
glBegin(GL_LINES);
|
|
|
|
|
/* bottom left */
|
2012-03-10 06:46:23 +00:00
|
|
|
glVertex2f(x1, y1);
|
|
|
|
|
glVertex2f(x1, y1 + 5);
|
|
|
|
|
|
|
|
|
|
glVertex2f(x1, y1);
|
|
|
|
|
glVertex2f(x1 + 5, y1);
|
|
|
|
|
|
2010-10-25 07:09:38 +00:00
|
|
|
/* top right */
|
2012-03-10 06:46:23 +00:00
|
|
|
glVertex2f(x2, y2);
|
|
|
|
|
glVertex2f(x2, y2 - 5);
|
|
|
|
|
|
|
|
|
|
glVertex2f(x2, y2);
|
|
|
|
|
glVertex2f(x2 - 5, y2);
|
|
|
|
|
|
2010-10-25 07:09:38 +00:00
|
|
|
/* top left */
|
2012-03-10 06:46:23 +00:00
|
|
|
glVertex2f(x1, y2);
|
|
|
|
|
glVertex2f(x1, y2 - 5);
|
|
|
|
|
|
|
|
|
|
glVertex2f(x1, y2);
|
|
|
|
|
glVertex2f(x1 + 5, y2);
|
|
|
|
|
|
2010-10-25 07:09:38 +00:00
|
|
|
/* bottom right */
|
2012-03-10 06:46:23 +00:00
|
|
|
glVertex2f(x2, y1);
|
|
|
|
|
glVertex2f(x2, y1 + 5);
|
|
|
|
|
|
|
|
|
|
glVertex2f(x2, y1);
|
|
|
|
|
glVertex2f(x2 - 5, y1);
|
2010-10-25 07:09:38 +00:00
|
|
|
glEnd();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* FlyInfo->state */
|
2012-03-25 23:54:33 +00:00
|
|
|
#define FLY_RUNNING 0
|
|
|
|
|
#define FLY_CANCEL 1
|
|
|
|
|
#define FLY_CONFIRM 2
|
2010-10-25 07:09:38 +00:00
|
|
|
|
2012-03-10 06:46:23 +00:00
|
|
|
static int initFlyInfo(bContext *C, FlyInfo *fly, wmOperator *op, wmEvent *event)
|
2010-10-25 07:09:38 +00:00
|
|
|
{
|
2012-03-10 06:46:23 +00:00
|
|
|
wmWindow *win = CTX_wm_window(C);
|
2012-04-02 06:26:52 +00:00
|
|
|
float upvec[3]; /* tmp */
|
2010-10-25 07:09:38 +00:00
|
|
|
float mat[3][3];
|
|
|
|
|
|
2012-03-10 06:46:23 +00:00
|
|
|
fly->rv3d = CTX_wm_region_view3d(C);
|
2010-10-25 07:09:38 +00:00
|
|
|
fly->v3d = CTX_wm_view3d(C);
|
|
|
|
|
fly->ar = CTX_wm_region(C);
|
2012-03-10 06:46:23 +00:00
|
|
|
fly->scene = CTX_data_scene(C);
|
2010-10-25 07:09:38 +00:00
|
|
|
|
2011-08-02 08:12:50 +00:00
|
|
|
#ifdef NDOF_FLY_DEBUG
|
2011-07-14 21:20:45 +00:00
|
|
|
puts("\n-- fly begin --");
|
2011-08-02 08:12:50 +00:00
|
|
|
#endif
|
2011-07-14 21:20:45 +00:00
|
|
|
|
2012-10-10 08:46:52 +00:00
|
|
|
/* sanity check: for rare but possible case (if lib-linking the camera fails) */
|
|
|
|
|
if ((fly->rv3d->persp == RV3D_CAMOB) && (fly->v3d->camera == NULL)) {
|
|
|
|
|
fly->rv3d->persp = RV3D_PERSP;
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-10 06:46:23 +00:00
|
|
|
if (fly->rv3d->persp == RV3D_CAMOB && fly->v3d->camera->id.lib) {
|
2010-10-25 07:09:38 +00:00
|
|
|
BKE_report(op->reports, RPT_ERROR, "Cannot fly a camera from an external library");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2011-08-02 08:12:50 +00:00
|
|
|
if (fly->v3d->ob_centre) {
|
2010-10-25 07:09:38 +00:00
|
|
|
BKE_report(op->reports, RPT_ERROR, "Cannot fly when the view is locked to an object");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-10 06:46:23 +00:00
|
|
|
if (fly->rv3d->persp == RV3D_CAMOB && fly->v3d->camera->constraints.first) {
|
2010-10-25 07:09:38 +00:00
|
|
|
BKE_report(op->reports, RPT_ERROR, "Cannot fly an object with constraints");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-10 06:46:23 +00:00
|
|
|
fly->state = FLY_RUNNING;
|
|
|
|
|
fly->speed = 0.0f;
|
|
|
|
|
fly->axis = 2;
|
|
|
|
|
fly->pan_view = FALSE;
|
|
|
|
|
fly->xlock = FALSE;
|
|
|
|
|
fly->zlock = FALSE;
|
|
|
|
|
fly->xlock_momentum = 0.0f;
|
|
|
|
|
fly->zlock_momentum = 0.0f;
|
|
|
|
|
fly->grid = 1.0f;
|
|
|
|
|
fly->use_precision = FALSE;
|
|
|
|
|
fly->use_freelook = FALSE;
|
2010-10-25 07:09:38 +00:00
|
|
|
|
2011-08-02 07:49:34 +00:00
|
|
|
#ifdef NDOF_FLY_DRAW_TOOMUCH
|
2012-03-25 23:54:33 +00:00
|
|
|
fly->redraw = 1;
|
2011-08-02 07:49:34 +00:00
|
|
|
#endif
|
2012-03-23 20:18:09 +00:00
|
|
|
zero_v3(fly->dvec_prev);
|
2010-10-25 07:09:38 +00:00
|
|
|
|
2012-03-10 06:46:23 +00:00
|
|
|
fly->timer = WM_event_add_timer(CTX_wm_manager(C), win, TIMER, 0.01f);
|
2010-10-25 07:09:38 +00:00
|
|
|
|
2011-11-07 01:38:32 +00:00
|
|
|
copy_v2_v2_int(fly->mval, event->mval);
|
2011-07-14 21:20:45 +00:00
|
|
|
fly->ndof = NULL;
|
2010-10-25 07:09:38 +00:00
|
|
|
|
2012-03-10 06:46:23 +00:00
|
|
|
fly->time_lastdraw = fly->time_lastwheel = PIL_check_seconds_timer();
|
2010-10-25 07:09:38 +00:00
|
|
|
|
|
|
|
|
fly->draw_handle_pixel = ED_region_draw_cb_activate(fly->ar->type, drawFlyPixel, fly, REGION_DRAW_POST_PIXEL);
|
|
|
|
|
|
|
|
|
|
fly->rv3d->rflag |= RV3D_NAVIGATING; /* so we draw the corner margins */
|
|
|
|
|
|
|
|
|
|
/* detect weather to start with Z locking */
|
2012-03-10 06:46:23 +00:00
|
|
|
upvec[0] = 1.0f;
|
|
|
|
|
upvec[1] = 0.0f;
|
|
|
|
|
upvec[2] = 0.0f;
|
2010-10-25 07:09:38 +00:00
|
|
|
copy_m3_m4(mat, fly->rv3d->viewinv);
|
|
|
|
|
mul_m3_v3(mat, upvec);
|
2012-07-21 15:27:40 +00:00
|
|
|
if (fabsf(upvec[2]) < 0.1f) {
|
2010-10-25 07:09:38 +00:00
|
|
|
fly->zlock = 1;
|
2012-07-21 15:27:40 +00:00
|
|
|
}
|
2012-03-10 06:46:23 +00:00
|
|
|
upvec[0] = 0;
|
|
|
|
|
upvec[1] = 0;
|
|
|
|
|
upvec[2] = 0;
|
2010-10-25 07:09:38 +00:00
|
|
|
|
2012-03-10 06:46:23 +00:00
|
|
|
fly->persp_backup = fly->rv3d->persp;
|
|
|
|
|
fly->dist_backup = fly->rv3d->dist;
|
2011-09-26 08:33:51 +00:00
|
|
|
|
|
|
|
|
/* check for flying ortho camera - which we cant support well
|
|
|
|
|
* we _could_ also check for an ortho camera but this is easier */
|
2012-03-10 06:46:23 +00:00
|
|
|
if ((fly->rv3d->persp == RV3D_CAMOB) &&
|
|
|
|
|
(fly->rv3d->is_persp == FALSE))
|
2011-09-26 08:33:51 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
((Camera *)fly->v3d->camera->data)->type = CAM_PERSP;
|
|
|
|
|
fly->is_ortho_cam = TRUE;
|
2011-09-26 08:33:51 +00:00
|
|
|
}
|
|
|
|
|
|
2012-03-10 06:46:23 +00:00
|
|
|
if (fly->rv3d->persp == RV3D_CAMOB) {
|
2010-10-25 07:09:38 +00:00
|
|
|
Object *ob_back;
|
2012-03-10 06:46:23 +00:00
|
|
|
if ((U.uiflag & USER_CAM_LOCK_NO_PARENT) == 0 && (fly->root_parent = fly->v3d->camera->parent)) {
|
2012-02-22 16:52:06 +00:00
|
|
|
while (fly->root_parent->parent)
|
2012-03-10 06:46:23 +00:00
|
|
|
fly->root_parent = fly->root_parent->parent;
|
|
|
|
|
ob_back = fly->root_parent;
|
2010-10-25 07:09:38 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2012-03-10 06:46:23 +00:00
|
|
|
ob_back = fly->v3d->camera;
|
2010-10-25 07:09:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* store the original camera loc and rot */
|
2012-05-05 14:03:12 +00:00
|
|
|
fly->obtfm = BKE_object_tfm_backup(ob_back);
|
2010-10-25 07:09:38 +00:00
|
|
|
|
2012-05-05 14:03:12 +00:00
|
|
|
BKE_object_where_is_calc(fly->scene, fly->v3d->camera);
|
2010-10-25 07:09:38 +00:00
|
|
|
negate_v3_v3(fly->rv3d->ofs, fly->v3d->camera->obmat[3]);
|
|
|
|
|
|
2012-03-10 06:46:23 +00:00
|
|
|
fly->rv3d->dist = 0.0;
|
2011-08-02 08:12:50 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2010-10-25 07:09:38 +00:00
|
|
|
/* perspective or ortho */
|
2012-03-10 06:46:23 +00:00
|
|
|
if (fly->rv3d->persp == RV3D_ORTHO)
|
2012-04-02 06:26:52 +00:00
|
|
|
fly->rv3d->persp = RV3D_PERSP; /* if ortho projection, make perspective */
|
2011-07-14 21:20:45 +00:00
|
|
|
|
2010-10-25 07:09:38 +00:00
|
|
|
copy_qt_qt(fly->rot_backup, fly->rv3d->viewquat);
|
|
|
|
|
copy_v3_v3(fly->ofs_backup, fly->rv3d->ofs);
|
2011-07-14 21:20:45 +00:00
|
|
|
|
|
|
|
|
/* the dist defines a vector that is infront of the offset
|
2012-03-03 16:31:46 +00:00
|
|
|
* to rotate the view about.
|
|
|
|
|
* this is no good for fly mode because we
|
|
|
|
|
* want to rotate about the viewers center.
|
|
|
|
|
* but to correct the dist removal we must
|
|
|
|
|
* alter offset so the view doesn't jump. */
|
2011-07-14 21:20:45 +00:00
|
|
|
|
2012-03-10 06:46:23 +00:00
|
|
|
fly->rv3d->dist = 0.0f;
|
2010-10-25 07:09:38 +00:00
|
|
|
|
2012-04-02 06:26:52 +00:00
|
|
|
upvec[2] = fly->dist_backup; /* x and y are 0 */
|
2010-10-25 07:09:38 +00:00
|
|
|
mul_m3_v3(mat, upvec);
|
|
|
|
|
sub_v3_v3(fly->rv3d->ofs, upvec);
|
2012-04-02 06:26:52 +00:00
|
|
|
/* Done with correcting for the dist */
|
2010-10-25 07:09:38 +00:00
|
|
|
}
|
2012-03-10 06:46:23 +00:00
|
|
|
|
2010-10-25 07:09:38 +00:00
|
|
|
/* center the mouse, probably the UI mafia are against this but without its quite annoying */
|
2012-03-10 06:46:23 +00:00
|
|
|
WM_cursor_warp(win, fly->ar->winrct.xmin + fly->ar->winx / 2, fly->ar->winrct.ymin + fly->ar->winy / 2);
|
|
|
|
|
|
2010-10-25 07:09:38 +00:00
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int flyEnd(bContext *C, FlyInfo *fly)
|
|
|
|
|
{
|
2012-03-10 06:46:23 +00:00
|
|
|
RegionView3D *rv3d = fly->rv3d;
|
2010-10-25 07:09:38 +00:00
|
|
|
View3D *v3d = fly->v3d;
|
|
|
|
|
|
|
|
|
|
float upvec[3];
|
|
|
|
|
|
2011-08-02 08:12:50 +00:00
|
|
|
if (fly->state == FLY_RUNNING)
|
2010-10-25 07:09:38 +00:00
|
|
|
return OPERATOR_RUNNING_MODAL;
|
|
|
|
|
|
2011-08-02 08:12:50 +00:00
|
|
|
#ifdef NDOF_FLY_DEBUG
|
2011-07-14 21:20:45 +00:00
|
|
|
puts("\n-- fly end --");
|
2011-08-02 08:12:50 +00:00
|
|
|
#endif
|
2011-07-14 21:20:45 +00:00
|
|
|
|
2010-10-25 07:09:38 +00:00
|
|
|
WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), fly->timer);
|
|
|
|
|
|
|
|
|
|
ED_region_draw_cb_exit(fly->ar->type, fly->draw_handle_pixel);
|
|
|
|
|
|
2012-03-10 06:46:23 +00:00
|
|
|
rv3d->dist = fly->dist_backup;
|
2010-10-25 07:09:38 +00:00
|
|
|
if (fly->state == FLY_CANCEL) {
|
2012-03-10 06:46:23 +00:00
|
|
|
/* Revert to original view? */
|
|
|
|
|
if (fly->persp_backup == RV3D_CAMOB) { /* a camera view */
|
2010-10-25 07:09:38 +00:00
|
|
|
Object *ob_back;
|
2012-03-10 06:46:23 +00:00
|
|
|
ob_back = (fly->root_parent) ? fly->root_parent : fly->v3d->camera;
|
2010-10-25 07:09:38 +00:00
|
|
|
|
|
|
|
|
/* store the original camera loc and rot */
|
2012-05-05 14:03:12 +00:00
|
|
|
BKE_object_tfm_restore(ob_back, fly->obtfm);
|
2010-10-25 07:09:38 +00:00
|
|
|
|
2010-12-05 18:59:23 +00:00
|
|
|
DAG_id_tag_update(&ob_back->id, OB_RECALC_OB);
|
2011-08-02 08:12:50 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2010-10-25 07:09:38 +00:00
|
|
|
/* Non Camera we need to reset the view back to the original location bacause the user canceled*/
|
|
|
|
|
copy_qt_qt(rv3d->viewquat, fly->rot_backup);
|
2012-03-10 06:46:23 +00:00
|
|
|
rv3d->persp = fly->persp_backup;
|
2010-10-25 07:09:38 +00:00
|
|
|
}
|
2012-10-27 17:21:21 +00:00
|
|
|
/* always, is set to zero otherwise */
|
|
|
|
|
copy_v3_v3(rv3d->ofs, fly->ofs_backup);
|
2010-10-25 07:09:38 +00:00
|
|
|
}
|
2012-03-10 06:46:23 +00:00
|
|
|
else if (fly->persp_backup == RV3D_CAMOB) { /* camera */
|
2010-12-05 18:59:23 +00:00
|
|
|
DAG_id_tag_update(fly->root_parent ? &fly->root_parent->id : &v3d->camera->id, OB_RECALC_OB);
|
2012-10-27 17:21:21 +00:00
|
|
|
|
|
|
|
|
/* always, is set to zero otherwise */
|
|
|
|
|
copy_v3_v3(rv3d->ofs, fly->ofs_backup);
|
2010-10-25 07:09:38 +00:00
|
|
|
}
|
|
|
|
|
else { /* not camera */
|
2012-03-25 23:54:33 +00:00
|
|
|
|
2010-10-25 07:09:38 +00:00
|
|
|
/* Apply the fly mode view */
|
2012-03-25 23:54:33 +00:00
|
|
|
/* restore the dist */
|
2010-10-25 07:09:38 +00:00
|
|
|
float mat[3][3];
|
2012-03-10 06:46:23 +00:00
|
|
|
upvec[0] = upvec[1] = 0;
|
2012-04-02 06:26:52 +00:00
|
|
|
upvec[2] = fly->dist_backup; /* x and y are 0 */
|
2010-10-25 07:09:38 +00:00
|
|
|
copy_m3_m4(mat, rv3d->viewinv);
|
|
|
|
|
mul_m3_v3(mat, upvec);
|
|
|
|
|
add_v3_v3(rv3d->ofs, upvec);
|
2012-04-02 06:26:52 +00:00
|
|
|
/* Done with correcting for the dist */
|
2010-10-25 07:09:38 +00:00
|
|
|
}
|
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (fly->is_ortho_cam) {
|
2012-03-10 06:46:23 +00:00
|
|
|
((Camera *)fly->v3d->camera->data)->type = CAM_ORTHO;
|
2011-09-26 08:33:51 +00:00
|
|
|
}
|
|
|
|
|
|
2010-10-25 07:09:38 +00:00
|
|
|
rv3d->rflag &= ~RV3D_NAVIGATING;
|
|
|
|
|
//XXX2.5 BIF_view3d_previewrender_signal(fly->sa, PR_DBASE|PR_DISPRECT); /* not working at the moment not sure why */
|
|
|
|
|
|
2011-08-02 08:12:50 +00:00
|
|
|
if (fly->obtfm)
|
2010-10-25 07:09:38 +00:00
|
|
|
MEM_freeN(fly->obtfm);
|
2011-08-02 08:12:50 +00:00
|
|
|
if (fly->ndof)
|
2011-07-14 21:20:45 +00:00
|
|
|
MEM_freeN(fly->ndof);
|
|
|
|
|
|
2011-08-02 08:12:50 +00:00
|
|
|
if (fly->state == FLY_CONFIRM) {
|
2010-10-25 07:09:38 +00:00
|
|
|
MEM_freeN(fly);
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MEM_freeN(fly);
|
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void flyEvent(FlyInfo *fly, wmEvent *event)
|
|
|
|
|
{
|
2011-08-02 07:49:34 +00:00
|
|
|
if (event->type == TIMER && event->customdata == fly->timer) {
|
|
|
|
|
fly->redraw = 1;
|
|
|
|
|
}
|
|
|
|
|
else if (event->type == MOUSEMOVE) {
|
2011-11-07 01:38:32 +00:00
|
|
|
copy_v2_v2_int(fly->mval, event->mval);
|
2011-07-14 21:20:45 +00:00
|
|
|
}
|
|
|
|
|
else if (event->type == NDOF_MOTION) {
|
2012-04-02 06:26:52 +00:00
|
|
|
/* do these automagically get delivered? yes. */
|
2011-07-14 21:20:45 +00:00
|
|
|
// puts("ndof motion detected in fly mode!");
|
2012-08-26 11:35:43 +00:00
|
|
|
// static const char *tag_name = "3D mouse position";
|
2011-07-14 21:20:45 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
wmNDOFMotionData *incoming_ndof = (wmNDOFMotionData *)event->customdata;
|
2011-08-02 08:12:50 +00:00
|
|
|
switch (incoming_ndof->progress) {
|
2011-07-14 21:20:45 +00:00
|
|
|
case P_STARTING:
|
2012-04-02 06:26:52 +00:00
|
|
|
/* start keeping track of 3D mouse position */
|
2011-08-02 08:12:50 +00:00
|
|
|
#ifdef NDOF_FLY_DEBUG
|
2011-07-14 21:20:45 +00:00
|
|
|
puts("start keeping track of 3D mouse position");
|
2011-08-02 08:12:50 +00:00
|
|
|
#endif
|
2012-04-02 06:26:52 +00:00
|
|
|
/* fall through... */
|
2011-07-14 21:20:45 +00:00
|
|
|
case P_IN_PROGRESS:
|
2012-04-02 06:26:52 +00:00
|
|
|
/* update 3D mouse position */
|
2011-08-02 08:12:50 +00:00
|
|
|
#ifdef NDOF_FLY_DEBUG
|
2011-07-14 21:20:45 +00:00
|
|
|
putchar('.'); fflush(stdout);
|
2011-08-02 08:12:50 +00:00
|
|
|
#endif
|
|
|
|
|
if (fly->ndof == NULL) {
|
2011-07-14 21:20:45 +00:00
|
|
|
// fly->ndof = MEM_mallocN(sizeof(wmNDOFMotionData), tag_name);
|
|
|
|
|
fly->ndof = MEM_dupallocN(incoming_ndof);
|
|
|
|
|
// fly->ndof = malloc(sizeof(wmNDOFMotionData));
|
2011-08-02 08:12:50 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2011-07-14 21:20:45 +00:00
|
|
|
memcpy(fly->ndof, incoming_ndof, sizeof(wmNDOFMotionData));
|
2011-08-02 08:12:50 +00:00
|
|
|
}
|
2011-07-14 21:20:45 +00:00
|
|
|
break;
|
|
|
|
|
case P_FINISHING:
|
2012-07-08 20:36:00 +00:00
|
|
|
/* stop keeping track of 3D mouse position */
|
2011-08-02 08:12:50 +00:00
|
|
|
#ifdef NDOF_FLY_DEBUG
|
2011-07-14 21:20:45 +00:00
|
|
|
puts("stop keeping track of 3D mouse position");
|
2011-08-02 08:12:50 +00:00
|
|
|
#endif
|
|
|
|
|
if (fly->ndof) {
|
2011-07-14 21:20:45 +00:00
|
|
|
MEM_freeN(fly->ndof);
|
|
|
|
|
// free(fly->ndof);
|
|
|
|
|
fly->ndof = NULL;
|
2011-08-02 08:12:50 +00:00
|
|
|
}
|
2011-07-19 22:40:22 +00:00
|
|
|
/* update the time else the view will jump when 2D mouse/timer resume */
|
2012-03-10 06:46:23 +00:00
|
|
|
fly->time_lastdraw = PIL_check_seconds_timer();
|
2011-07-14 21:20:45 +00:00
|
|
|
break;
|
|
|
|
|
default:
|
2012-03-10 22:00:55 +00:00
|
|
|
break; /* should always be one of the above 3 */
|
2011-07-14 21:20:45 +00:00
|
|
|
}
|
2012-03-10 06:46:23 +00:00
|
|
|
}
|
2011-07-14 21:20:45 +00:00
|
|
|
/* handle modal keymap first */
|
2010-10-25 07:09:38 +00:00
|
|
|
else if (event->type == EVT_MODAL_MAP) {
|
|
|
|
|
switch (event->val) {
|
|
|
|
|
case FLY_MODAL_CANCEL:
|
|
|
|
|
fly->state = FLY_CANCEL;
|
|
|
|
|
break;
|
|
|
|
|
case FLY_MODAL_CONFIRM:
|
|
|
|
|
fly->state = FLY_CONFIRM;
|
|
|
|
|
break;
|
2013-01-08 16:54:26 +00:00
|
|
|
|
|
|
|
|
/* speed adjusting with mousepan (trackpad) */
|
|
|
|
|
case FLY_MODAL_SPEED:
|
|
|
|
|
{
|
|
|
|
|
float fac = 0.02f * (event->prevy - event->y);
|
|
|
|
|
|
|
|
|
|
/* allowing to brake immediate */
|
|
|
|
|
if (fac > 0.0f && fly->speed < 0.0f)
|
|
|
|
|
fly->speed = 0.0f;
|
|
|
|
|
else if (fac < 0.0f && fly->speed > 0.0f)
|
|
|
|
|
fly->speed = 0.0f;
|
|
|
|
|
else
|
|
|
|
|
fly->speed += fly->grid * fac;
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
2010-10-25 07:09:38 +00:00
|
|
|
case FLY_MODAL_ACCELERATE:
|
|
|
|
|
{
|
|
|
|
|
double time_currwheel;
|
|
|
|
|
float time_wheel;
|
|
|
|
|
|
2012-03-10 06:46:23 +00:00
|
|
|
time_currwheel = PIL_check_seconds_timer();
|
2010-10-25 07:09:38 +00:00
|
|
|
time_wheel = (float)(time_currwheel - fly->time_lastwheel);
|
|
|
|
|
fly->time_lastwheel = time_currwheel;
|
2012-05-25 09:51:53 +00:00
|
|
|
/* Mouse wheel delays range from (0.5 == slow) to (0.01 == fast) */
|
2012-10-23 13:28:22 +00:00
|
|
|
time_wheel = 1.0f + (10.0f - (20.0f * min_ff(time_wheel, 0.5f))); /* 0-0.5 -> 0-5.0 */
|
2010-10-25 07:09:38 +00:00
|
|
|
|
2011-08-02 08:12:50 +00:00
|
|
|
if (fly->speed < 0.0f) {
|
2012-03-10 06:46:23 +00:00
|
|
|
fly->speed = 0.0f;
|
2011-08-02 08:12:50 +00:00
|
|
|
}
|
2010-10-25 07:09:38 +00:00
|
|
|
else {
|
2012-03-10 06:46:23 +00:00
|
|
|
fly->speed += fly->grid * time_wheel * (fly->use_precision ? 0.1f : 1.0f);
|
2010-10-25 07:09:38 +00:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case FLY_MODAL_DECELERATE:
|
|
|
|
|
{
|
|
|
|
|
double time_currwheel;
|
|
|
|
|
float time_wheel;
|
|
|
|
|
|
2012-03-10 06:46:23 +00:00
|
|
|
time_currwheel = PIL_check_seconds_timer();
|
2010-10-25 07:09:38 +00:00
|
|
|
time_wheel = (float)(time_currwheel - fly->time_lastwheel);
|
|
|
|
|
fly->time_lastwheel = time_currwheel;
|
2012-10-23 13:28:22 +00:00
|
|
|
time_wheel = 1.0f + (10.0f - (20.0f * min_ff(time_wheel, 0.5f))); /* 0-0.5 -> 0-5.0 */
|
2010-10-25 07:09:38 +00:00
|
|
|
|
2011-08-02 08:12:50 +00:00
|
|
|
if (fly->speed > 0.0f) {
|
2012-03-10 06:46:23 +00:00
|
|
|
fly->speed = 0;
|
2011-08-02 08:12:50 +00:00
|
|
|
}
|
2010-10-25 07:09:38 +00:00
|
|
|
else {
|
2012-03-10 06:46:23 +00:00
|
|
|
fly->speed -= fly->grid * time_wheel * (fly->use_precision ? 0.1f : 1.0f);
|
2010-10-25 07:09:38 +00:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case FLY_MODAL_PAN_ENABLE:
|
2012-03-10 06:46:23 +00:00
|
|
|
fly->pan_view = TRUE;
|
2010-10-25 07:09:38 +00:00
|
|
|
break;
|
|
|
|
|
case FLY_MODAL_PAN_DISABLE:
|
2012-05-21 09:00:35 +00:00
|
|
|
//XXX2.5 WM_cursor_warp(CTX_wm_window(C), cent_orig[0], cent_orig[1]);
|
2012-03-10 06:46:23 +00:00
|
|
|
fly->pan_view = FALSE;
|
2010-10-25 07:09:38 +00:00
|
|
|
break;
|
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
/* implement WASD keys,
|
|
|
|
|
* comments only for 'forward '*/
|
2010-10-25 07:09:38 +00:00
|
|
|
case FLY_MODAL_DIR_FORWARD:
|
2012-03-10 04:19:25 +00:00
|
|
|
if (fly->axis == 2 && fly->speed < 0.0f) { /* reverse direction stops, tap again to continue */
|
|
|
|
|
fly->axis = -1;
|
|
|
|
|
}
|
|
|
|
|
else {
|
2012-03-10 06:46:23 +00:00
|
|
|
/* flip speed rather than stopping, game like motion,
|
|
|
|
|
* else increase like mousewheel if were already moving in that direction */
|
|
|
|
|
if (fly->speed < 0.0f) fly->speed = -fly->speed;
|
|
|
|
|
else if (fly->axis == 2) fly->speed += fly->grid;
|
|
|
|
|
fly->axis = 2;
|
2012-03-10 04:19:25 +00:00
|
|
|
}
|
2010-10-25 07:09:38 +00:00
|
|
|
break;
|
|
|
|
|
case FLY_MODAL_DIR_BACKWARD:
|
2012-03-10 06:46:23 +00:00
|
|
|
if (fly->axis == 2 && fly->speed > 0.0f) {
|
2012-03-10 04:19:25 +00:00
|
|
|
fly->axis = -1;
|
|
|
|
|
}
|
|
|
|
|
else {
|
2012-03-10 06:46:23 +00:00
|
|
|
if (fly->speed > 0.0f) fly->speed = -fly->speed;
|
|
|
|
|
else if (fly->axis == 2) fly->speed -= fly->grid;
|
2012-03-10 04:19:25 +00:00
|
|
|
|
2012-03-10 06:46:23 +00:00
|
|
|
fly->axis = 2;
|
2012-03-10 04:19:25 +00:00
|
|
|
}
|
2010-10-25 07:09:38 +00:00
|
|
|
break;
|
|
|
|
|
case FLY_MODAL_DIR_LEFT:
|
2012-03-10 06:46:23 +00:00
|
|
|
if (fly->axis == 0 && fly->speed < 0.0f) {
|
2012-03-10 04:19:25 +00:00
|
|
|
fly->axis = -1;
|
|
|
|
|
}
|
|
|
|
|
else {
|
2012-03-10 06:46:23 +00:00
|
|
|
if (fly->speed < 0.0f) fly->speed = -fly->speed;
|
|
|
|
|
else if (fly->axis == 0) fly->speed += fly->grid;
|
2012-03-10 04:19:25 +00:00
|
|
|
|
2012-03-10 06:46:23 +00:00
|
|
|
fly->axis = 0;
|
2012-03-10 04:19:25 +00:00
|
|
|
}
|
2010-10-25 07:09:38 +00:00
|
|
|
break;
|
|
|
|
|
case FLY_MODAL_DIR_RIGHT:
|
2012-03-10 06:46:23 +00:00
|
|
|
if (fly->axis == 0 && fly->speed > 0.0f) {
|
2012-03-10 04:19:25 +00:00
|
|
|
fly->axis = -1;
|
|
|
|
|
}
|
|
|
|
|
else {
|
2012-03-10 06:46:23 +00:00
|
|
|
if (fly->speed > 0.0f) fly->speed = -fly->speed;
|
|
|
|
|
else if (fly->axis == 0) fly->speed -= fly->grid;
|
2012-03-10 04:19:25 +00:00
|
|
|
|
2012-03-10 06:46:23 +00:00
|
|
|
fly->axis = 0;
|
2012-03-10 04:19:25 +00:00
|
|
|
}
|
2010-10-25 07:09:38 +00:00
|
|
|
break;
|
|
|
|
|
case FLY_MODAL_DIR_DOWN:
|
2012-03-10 06:46:23 +00:00
|
|
|
if (fly->axis == 1 && fly->speed < 0.0f) {
|
2012-03-10 04:19:25 +00:00
|
|
|
fly->axis = -1;
|
|
|
|
|
}
|
|
|
|
|
else {
|
2012-03-10 06:46:23 +00:00
|
|
|
if (fly->speed < 0.0f) fly->speed = -fly->speed;
|
|
|
|
|
else if (fly->axis == 1) fly->speed += fly->grid;
|
|
|
|
|
fly->axis = 1;
|
2012-03-10 04:19:25 +00:00
|
|
|
}
|
2010-10-25 07:09:38 +00:00
|
|
|
break;
|
|
|
|
|
case FLY_MODAL_DIR_UP:
|
2012-03-10 06:46:23 +00:00
|
|
|
if (fly->axis == 1 && fly->speed > 0.0f) {
|
2012-03-10 04:19:25 +00:00
|
|
|
fly->axis = -1;
|
|
|
|
|
}
|
|
|
|
|
else {
|
2012-03-10 06:46:23 +00:00
|
|
|
if (fly->speed > 0.0f) fly->speed = -fly->speed;
|
|
|
|
|
else if (fly->axis == 1) fly->speed -= fly->grid;
|
|
|
|
|
fly->axis = 1;
|
2012-03-10 04:19:25 +00:00
|
|
|
}
|
2010-10-25 07:09:38 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case FLY_MODAL_AXIS_LOCK_X:
|
2012-03-10 06:46:23 +00:00
|
|
|
if (fly->xlock)
|
|
|
|
|
fly->xlock = 0;
|
2010-10-25 07:09:38 +00:00
|
|
|
else {
|
|
|
|
|
fly->xlock = 2;
|
|
|
|
|
fly->xlock_momentum = 0.0;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case FLY_MODAL_AXIS_LOCK_Z:
|
2012-03-10 06:46:23 +00:00
|
|
|
if (fly->zlock)
|
|
|
|
|
fly->zlock = 0;
|
2010-10-25 07:09:38 +00:00
|
|
|
else {
|
|
|
|
|
fly->zlock = 2;
|
|
|
|
|
fly->zlock_momentum = 0.0;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case FLY_MODAL_PRECISION_ENABLE:
|
2012-03-10 06:46:23 +00:00
|
|
|
fly->use_precision = TRUE;
|
2010-10-25 07:09:38 +00:00
|
|
|
break;
|
|
|
|
|
case FLY_MODAL_PRECISION_DISABLE:
|
2012-03-10 06:46:23 +00:00
|
|
|
fly->use_precision = FALSE;
|
2010-10-25 07:09:38 +00:00
|
|
|
break;
|
2011-09-25 04:47:46 +00:00
|
|
|
|
|
|
|
|
case FLY_MODAL_FREELOOK_ENABLE:
|
2012-03-10 06:46:23 +00:00
|
|
|
fly->use_freelook = TRUE;
|
2011-09-25 04:47:46 +00:00
|
|
|
break;
|
|
|
|
|
case FLY_MODAL_FREELOOK_DISABLE:
|
2012-03-10 06:46:23 +00:00
|
|
|
fly->use_freelook = FALSE;
|
2011-09-25 04:47:46 +00:00
|
|
|
break;
|
2010-10-25 07:09:38 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
static void move_camera(bContext *C, RegionView3D *rv3d, FlyInfo *fly, int orientationChanged, int positionChanged)
|
2011-07-31 03:06:00 +00:00
|
|
|
{
|
|
|
|
|
/* we are in camera view so apply the view ofs and quat to the view matrix and set the camera to the view */
|
|
|
|
|
|
2012-05-08 15:55:29 +00:00
|
|
|
View3D *v3d = fly->v3d;
|
2012-03-10 06:46:23 +00:00
|
|
|
Scene *scene = fly->scene;
|
2011-07-31 03:06:00 +00:00
|
|
|
ID *id_key;
|
|
|
|
|
|
|
|
|
|
/* transform the parent or the camera? */
|
2011-08-02 08:12:50 +00:00
|
|
|
if (fly->root_parent) {
|
2011-07-31 03:06:00 +00:00
|
|
|
Object *ob_update;
|
|
|
|
|
|
|
|
|
|
float view_mat[4][4];
|
|
|
|
|
float prev_view_mat[4][4];
|
|
|
|
|
float prev_view_imat[4][4];
|
|
|
|
|
float diff_mat[4][4];
|
|
|
|
|
float parent_mat[4][4];
|
|
|
|
|
|
|
|
|
|
ED_view3d_to_m4(prev_view_mat, fly->rv3d->ofs, fly->rv3d->viewquat, fly->rv3d->dist);
|
|
|
|
|
invert_m4_m4(prev_view_imat, prev_view_mat);
|
|
|
|
|
ED_view3d_to_m4(view_mat, rv3d->ofs, rv3d->viewquat, rv3d->dist);
|
Math lib: matrix multiplication order fix for two functions that were
inconsistent with similar functions & math notation:
mul_m4_m4m4(R, B, A) => mult_m4_m4m4(R, A, B)
mul_m3_m3m4(R, B, A) => mult_m3_m3m4(R, A, B)
For branch maintainers, it should be relatively simple to fix things manually,
it's also possible run this script after merging to do automatic replacement:
http://www.pasteall.org/27459/python
2011-12-16 19:53:12 +00:00
|
|
|
mult_m4_m4m4(diff_mat, view_mat, prev_view_imat);
|
|
|
|
|
mult_m4_m4m4(parent_mat, diff_mat, fly->root_parent->obmat);
|
2012-05-05 14:03:12 +00:00
|
|
|
BKE_object_apply_mat4(fly->root_parent, parent_mat, TRUE, FALSE);
|
2011-07-31 03:06:00 +00:00
|
|
|
|
2012-05-05 14:03:12 +00:00
|
|
|
// BKE_object_where_is_calc(scene, fly->root_parent);
|
2011-07-31 03:06:00 +00:00
|
|
|
|
2012-03-10 06:46:23 +00:00
|
|
|
ob_update = v3d->camera->parent;
|
2012-02-22 16:52:06 +00:00
|
|
|
while (ob_update) {
|
2011-07-31 03:06:00 +00:00
|
|
|
DAG_id_tag_update(&ob_update->id, OB_RECALC_OB);
|
2012-03-10 06:46:23 +00:00
|
|
|
ob_update = ob_update->parent;
|
2011-07-31 03:06:00 +00:00
|
|
|
}
|
|
|
|
|
|
2012-03-10 06:46:23 +00:00
|
|
|
id_key = &fly->root_parent->id;
|
2011-07-31 03:06:00 +00:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
float view_mat[4][4];
|
|
|
|
|
ED_view3d_to_m4(view_mat, rv3d->ofs, rv3d->viewquat, rv3d->dist);
|
2012-05-05 14:03:12 +00:00
|
|
|
BKE_object_apply_mat4(v3d->camera, view_mat, TRUE, FALSE);
|
2012-03-10 06:46:23 +00:00
|
|
|
id_key = &v3d->camera->id;
|
2011-07-31 03:06:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* record the motion */
|
|
|
|
|
if (autokeyframe_cfra_can_key(scene, id_key)) {
|
|
|
|
|
ListBase dsources = {NULL, NULL};
|
2012-03-10 06:46:23 +00:00
|
|
|
|
2011-07-31 03:06:00 +00:00
|
|
|
/* add datasource override for the camera object */
|
2012-03-10 06:46:23 +00:00
|
|
|
ANIM_relative_keyingset_add_source(&dsources, id_key, NULL, NULL);
|
|
|
|
|
|
2011-07-31 03:06:00 +00:00
|
|
|
/* insert keyframes
|
|
|
|
|
* 1) on the first frame
|
|
|
|
|
* 2) on each subsequent frame
|
|
|
|
|
* TODO: need to check in future that frame changed before doing this
|
|
|
|
|
*/
|
|
|
|
|
if (orientationChanged) {
|
2012-03-10 06:46:23 +00:00
|
|
|
KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_ROTATION_ID);
|
2011-07-31 03:06:00 +00:00
|
|
|
ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA);
|
|
|
|
|
}
|
|
|
|
|
if (positionChanged) {
|
2012-03-10 06:46:23 +00:00
|
|
|
KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_LOCATION_ID);
|
2011-07-31 03:06:00 +00:00
|
|
|
ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA);
|
|
|
|
|
}
|
2012-03-10 06:46:23 +00:00
|
|
|
|
2011-07-31 03:06:00 +00:00
|
|
|
/* free temp data */
|
|
|
|
|
BLI_freelistN(&dsources);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2010-10-25 07:09:38 +00:00
|
|
|
static int flyApply(bContext *C, FlyInfo *fly)
|
|
|
|
|
{
|
|
|
|
|
#define FLY_ROTATE_FAC 2.5f /* more is faster */
|
2011-04-29 04:43:36 +00:00
|
|
|
#define FLY_ZUP_CORRECT_FAC 0.1f /* amount to correct per step */
|
2010-10-25 07:09:38 +00:00
|
|
|
#define FLY_ZUP_CORRECT_ACCEL 0.05f /* increase upright momentum each step */
|
|
|
|
|
|
2012-03-03 16:31:46 +00:00
|
|
|
/* fly mode - Shift+F
|
|
|
|
|
* a fly loop where the user can move move the view as if they are flying
|
|
|
|
|
*/
|
2012-03-10 06:46:23 +00:00
|
|
|
RegionView3D *rv3d = fly->rv3d;
|
2010-10-25 07:09:38 +00:00
|
|
|
ARegion *ar = fly->ar;
|
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
float mat[3][3]; /* 3x3 copy of the view matrix so we can move along the view axis */
|
|
|
|
|
float dvec[3] = {0, 0, 0}; /* this is the direction thast added to the view offset per redraw */
|
2010-10-25 07:09:38 +00:00
|
|
|
|
|
|
|
|
/* Camera Uprighting variables */
|
2012-03-25 23:54:33 +00:00
|
|
|
float upvec[3] = {0, 0, 0}; /* stores the view's up vector */
|
2010-10-25 07:09:38 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
float moffset[2]; /* mouse offset from the views center */
|
|
|
|
|
float tmp_quat[4]; /* used for rotating the view */
|
2010-10-25 07:09:38 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
// int cent_orig[2], /* view center */
|
|
|
|
|
//XXX- can avoid using // cent[2], /* view center modified */
|
|
|
|
|
int xmargin, ymargin; /* x and y margin are define the safe area where the mouses movement wont rotate the view */
|
2010-10-25 07:09:38 +00:00
|
|
|
|
2011-08-02 08:12:50 +00:00
|
|
|
#ifdef NDOF_FLY_DEBUG
|
2012-01-19 16:04:44 +00:00
|
|
|
{
|
|
|
|
|
static unsigned int iteration = 1;
|
|
|
|
|
printf("fly timer %d\n", iteration++);
|
|
|
|
|
}
|
2011-08-02 08:12:50 +00:00
|
|
|
#endif
|
2011-07-14 21:20:45 +00:00
|
|
|
|
2012-03-10 06:46:23 +00:00
|
|
|
xmargin = ar->winx / 20.0f;
|
|
|
|
|
ymargin = ar->winy / 20.0f;
|
2010-10-25 07:09:38 +00:00
|
|
|
|
2011-03-28 02:34:55 +00:00
|
|
|
// UNUSED
|
2012-10-22 08:15:51 +00:00
|
|
|
// cent_orig[0] = ar->winrct.xmin + ar->winx / 2;
|
|
|
|
|
// cent_orig[1] = ar->winrct.ymin + ar->winy / 2;
|
2010-10-25 07:09:38 +00:00
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
/* mouse offset from the center */
|
2012-03-10 06:46:23 +00:00
|
|
|
moffset[0] = fly->mval[0] - ar->winx / 2;
|
|
|
|
|
moffset[1] = fly->mval[1] - ar->winy / 2;
|
2010-10-25 07:09:38 +00:00
|
|
|
|
|
|
|
|
/* enforce a view margin */
|
2012-03-10 06:46:23 +00:00
|
|
|
if (moffset[0] > xmargin) moffset[0] -= xmargin;
|
|
|
|
|
else if (moffset[0] < -xmargin) moffset[0] += xmargin;
|
|
|
|
|
else moffset[0] = 0;
|
2010-10-25 07:09:38 +00:00
|
|
|
|
2012-03-10 06:46:23 +00:00
|
|
|
if (moffset[1] > ymargin) moffset[1] -= ymargin;
|
|
|
|
|
else if (moffset[1] < -ymargin) moffset[1] += ymargin;
|
|
|
|
|
else moffset[1] = 0;
|
2010-10-25 07:09:38 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
/* scale the mouse movement by this value - scales mouse movement to the view size
|
2013-01-08 01:48:14 +00:00
|
|
|
* moffset[0] / (ar->winx-xmargin * 2) - window size minus margin (same for y)
|
2010-10-25 07:09:38 +00:00
|
|
|
*
|
2012-03-18 07:38:51 +00:00
|
|
|
* the mouse moves isn't linear */
|
2010-10-25 07:09:38 +00:00
|
|
|
|
2011-08-02 08:12:50 +00:00
|
|
|
if (moffset[0]) {
|
2012-03-10 06:46:23 +00:00
|
|
|
moffset[0] /= ar->winx - (xmargin * 2);
|
2011-03-27 15:57:27 +00:00
|
|
|
moffset[0] *= fabsf(moffset[0]);
|
2010-10-25 07:09:38 +00:00
|
|
|
}
|
|
|
|
|
|
2011-08-02 08:12:50 +00:00
|
|
|
if (moffset[1]) {
|
2012-03-10 06:46:23 +00:00
|
|
|
moffset[1] /= ar->winy - (ymargin * 2);
|
2011-03-27 15:57:27 +00:00
|
|
|
moffset[1] *= fabsf(moffset[1]);
|
2010-10-25 07:09:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Should we redraw? */
|
2012-03-10 06:46:23 +00:00
|
|
|
if ((fly->speed != 0.0f) ||
|
|
|
|
|
moffset[0] || moffset[1] ||
|
|
|
|
|
fly->zlock || fly->xlock ||
|
|
|
|
|
dvec[0] || dvec[1] || dvec[2])
|
2012-01-19 16:04:44 +00:00
|
|
|
{
|
2010-10-25 07:09:38 +00:00
|
|
|
float dvec_tmp[3];
|
2012-03-10 06:46:23 +00:00
|
|
|
|
|
|
|
|
/* time how fast it takes for us to redraw,
|
2012-03-18 07:38:51 +00:00
|
|
|
* this is so simple scenes don't fly too fast */
|
2012-03-10 06:46:23 +00:00
|
|
|
double time_current;
|
2011-03-27 15:57:27 +00:00
|
|
|
float time_redraw;
|
2010-10-25 07:09:38 +00:00
|
|
|
float time_redraw_clamped;
|
2011-08-02 07:49:34 +00:00
|
|
|
#ifdef NDOF_FLY_DRAW_TOOMUCH
|
2012-03-25 23:54:33 +00:00
|
|
|
fly->redraw = 1;
|
2011-08-02 07:49:34 +00:00
|
|
|
#endif
|
2012-03-10 06:46:23 +00:00
|
|
|
time_current = PIL_check_seconds_timer();
|
|
|
|
|
time_redraw = (float)(time_current - fly->time_lastdraw);
|
2012-10-23 13:28:22 +00:00
|
|
|
time_redraw_clamped = min_ff(0.05f, time_redraw); /* clamp redraw time to avoid jitter in roll correction */
|
2012-03-10 06:46:23 +00:00
|
|
|
fly->time_lastdraw = time_current;
|
2010-10-25 07:09:38 +00:00
|
|
|
|
|
|
|
|
/* Scale the time to use shift to scale the speed down- just like
|
2012-03-03 16:31:46 +00:00
|
|
|
* shift slows many other areas of blender down */
|
2010-10-25 07:09:38 +00:00
|
|
|
if (fly->use_precision)
|
2012-03-10 06:46:23 +00:00
|
|
|
fly->speed = fly->speed * (1.0f - time_redraw_clamped);
|
2010-10-25 07:09:38 +00:00
|
|
|
|
|
|
|
|
copy_m3_m4(mat, rv3d->viewinv);
|
|
|
|
|
|
2012-03-10 06:46:23 +00:00
|
|
|
if (fly->pan_view == TRUE) {
|
2010-10-25 07:09:38 +00:00
|
|
|
/* pan only */
|
2012-03-10 06:46:23 +00:00
|
|
|
dvec_tmp[0] = -moffset[0];
|
|
|
|
|
dvec_tmp[1] = -moffset[1];
|
|
|
|
|
dvec_tmp[2] = 0;
|
2010-10-25 07:09:38 +00:00
|
|
|
|
|
|
|
|
if (fly->use_precision) {
|
2011-03-27 15:57:27 +00:00
|
|
|
dvec_tmp[0] *= 0.1f;
|
|
|
|
|
dvec_tmp[1] *= 0.1f;
|
2010-10-25 07:09:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mul_m3_v3(mat, dvec_tmp);
|
2011-03-27 15:57:27 +00:00
|
|
|
mul_v3_fl(dvec_tmp, time_redraw * 200.0f * fly->grid);
|
2011-08-02 08:12:50 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2012-01-19 16:04:44 +00:00
|
|
|
float roll; /* similar to the angle between the camera's up and the Z-up,
|
2012-03-25 23:54:33 +00:00
|
|
|
* but its very rough so just roll */
|
2010-10-25 07:09:38 +00:00
|
|
|
|
|
|
|
|
/* rotate about the X axis- look up/down */
|
|
|
|
|
if (moffset[1]) {
|
2012-03-10 06:46:23 +00:00
|
|
|
upvec[0] = 1;
|
|
|
|
|
upvec[1] = 0;
|
|
|
|
|
upvec[2] = 0;
|
2010-10-25 07:09:38 +00:00
|
|
|
mul_m3_v3(mat, upvec);
|
2012-01-19 16:04:44 +00:00
|
|
|
/* Rotate about the relative up vec */
|
2012-03-10 06:46:23 +00:00
|
|
|
axis_angle_to_quat(tmp_quat, upvec, (float)moffset[1] * time_redraw * -FLY_ROTATE_FAC);
|
2010-10-25 07:09:38 +00:00
|
|
|
mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat);
|
|
|
|
|
|
2012-03-10 06:46:23 +00:00
|
|
|
if (fly->xlock)
|
2012-04-02 06:26:52 +00:00
|
|
|
fly->xlock = 2; /* check for rotation */
|
2012-03-10 06:46:23 +00:00
|
|
|
if (fly->zlock)
|
|
|
|
|
fly->zlock = 2;
|
|
|
|
|
fly->xlock_momentum = 0.0f;
|
2010-10-25 07:09:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* rotate about the Y axis- look left/right */
|
|
|
|
|
if (moffset[0]) {
|
|
|
|
|
|
|
|
|
|
/* if we're upside down invert the moffset */
|
2012-03-10 06:46:23 +00:00
|
|
|
upvec[0] = 0.0f;
|
|
|
|
|
upvec[1] = 1.0f;
|
|
|
|
|
upvec[2] = 0.0f;
|
2010-10-25 07:09:38 +00:00
|
|
|
mul_m3_v3(mat, upvec);
|
|
|
|
|
|
2011-08-02 08:12:50 +00:00
|
|
|
if (upvec[2] < 0.0f)
|
2012-03-10 06:46:23 +00:00
|
|
|
moffset[0] = -moffset[0];
|
2010-10-25 07:09:38 +00:00
|
|
|
|
|
|
|
|
/* make the lock vectors */
|
|
|
|
|
if (fly->zlock) {
|
2012-03-10 06:46:23 +00:00
|
|
|
upvec[0] = 0.0f;
|
|
|
|
|
upvec[1] = 0.0f;
|
|
|
|
|
upvec[2] = 1.0f;
|
2011-08-02 08:12:50 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2012-03-10 06:46:23 +00:00
|
|
|
upvec[0] = 0.0f;
|
|
|
|
|
upvec[1] = 1.0f;
|
|
|
|
|
upvec[2] = 0.0f;
|
2010-10-25 07:09:38 +00:00
|
|
|
mul_m3_v3(mat, upvec);
|
|
|
|
|
}
|
|
|
|
|
|
2012-01-19 16:04:44 +00:00
|
|
|
/* Rotate about the relative up vec */
|
|
|
|
|
axis_angle_to_quat(tmp_quat, upvec, (float)moffset[0] * time_redraw * FLY_ROTATE_FAC);
|
2010-10-25 07:09:38 +00:00
|
|
|
mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat);
|
|
|
|
|
|
2012-03-10 06:46:23 +00:00
|
|
|
if (fly->xlock)
|
2012-04-02 06:26:52 +00:00
|
|
|
fly->xlock = 2; /* check for rotation */
|
2012-03-10 06:46:23 +00:00
|
|
|
if (fly->zlock)
|
|
|
|
|
fly->zlock = 2;
|
2010-10-25 07:09:38 +00:00
|
|
|
}
|
|
|
|
|
|
2012-03-10 06:46:23 +00:00
|
|
|
if (fly->zlock == 2) {
|
|
|
|
|
upvec[0] = 1.0f;
|
|
|
|
|
upvec[1] = 0.0f;
|
|
|
|
|
upvec[2] = 0.0f;
|
2010-10-25 07:09:38 +00:00
|
|
|
mul_m3_v3(mat, upvec);
|
|
|
|
|
|
2012-04-02 06:26:52 +00:00
|
|
|
/* make sure we have some z rolling */
|
2011-03-27 15:57:27 +00:00
|
|
|
if (fabsf(upvec[2]) > 0.00001f) {
|
2012-03-10 06:46:23 +00:00
|
|
|
roll = upvec[2] * 5.0f;
|
2012-04-02 06:26:52 +00:00
|
|
|
upvec[0] = 0.0f; /* rotate the view about this axis */
|
2012-03-10 06:46:23 +00:00
|
|
|
upvec[1] = 0.0f;
|
|
|
|
|
upvec[2] = 1.0f;
|
2010-10-25 07:09:38 +00:00
|
|
|
|
|
|
|
|
mul_m3_v3(mat, upvec);
|
2012-01-19 16:04:44 +00:00
|
|
|
/* Rotate about the relative up vec */
|
|
|
|
|
axis_angle_to_quat(tmp_quat, upvec,
|
2012-03-25 23:54:33 +00:00
|
|
|
roll * time_redraw_clamped * fly->zlock_momentum * FLY_ZUP_CORRECT_FAC);
|
2010-10-25 07:09:38 +00:00
|
|
|
mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat);
|
|
|
|
|
|
|
|
|
|
fly->zlock_momentum += FLY_ZUP_CORRECT_ACCEL;
|
2011-08-02 08:12:50 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2012-03-18 07:38:51 +00:00
|
|
|
fly->zlock = 1; /* don't check until the view rotates again */
|
2012-03-10 06:46:23 +00:00
|
|
|
fly->zlock_momentum = 0.0f;
|
2010-10-25 07:09:38 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-04-02 06:26:52 +00:00
|
|
|
if (fly->xlock == 2 && moffset[1] == 0) { /* only apply xcorrect when mouse isn't applying x rot */
|
2012-03-10 06:46:23 +00:00
|
|
|
upvec[0] = 0;
|
|
|
|
|
upvec[1] = 0;
|
|
|
|
|
upvec[2] = 1;
|
2010-10-25 07:09:38 +00:00
|
|
|
mul_m3_v3(mat, upvec);
|
2012-04-02 06:26:52 +00:00
|
|
|
/* make sure we have some z rolling */
|
2011-08-19 16:21:29 +00:00
|
|
|
if (fabsf(upvec[2]) > 0.00001f) {
|
2012-03-10 06:46:23 +00:00
|
|
|
roll = upvec[2] * -5.0f;
|
2010-10-25 07:09:38 +00:00
|
|
|
|
2012-04-02 06:26:52 +00:00
|
|
|
upvec[0] = 1.0f; /* rotate the view about this axis */
|
2012-03-10 06:46:23 +00:00
|
|
|
upvec[1] = 0.0f;
|
|
|
|
|
upvec[2] = 0.0f;
|
2010-10-25 07:09:38 +00:00
|
|
|
|
|
|
|
|
mul_m3_v3(mat, upvec);
|
|
|
|
|
|
2012-01-19 16:04:44 +00:00
|
|
|
/* Rotate about the relative up vec */
|
2012-03-10 06:46:23 +00:00
|
|
|
axis_angle_to_quat(tmp_quat, upvec, roll * time_redraw_clamped * fly->xlock_momentum * 0.1f);
|
2010-10-25 07:09:38 +00:00
|
|
|
mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat);
|
|
|
|
|
|
|
|
|
|
fly->xlock_momentum += 0.05f;
|
2011-08-02 08:12:50 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2012-03-10 06:46:23 +00:00
|
|
|
fly->xlock = 1; /* see above */
|
|
|
|
|
fly->xlock_momentum = 0.0f;
|
2010-10-25 07:09:38 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-10 04:19:25 +00:00
|
|
|
if (fly->axis == -1) {
|
|
|
|
|
/* pause */
|
|
|
|
|
zero_v3(dvec_tmp);
|
|
|
|
|
}
|
2012-04-02 05:34:58 +00:00
|
|
|
else if (!fly->use_freelook) {
|
2010-10-25 07:09:38 +00:00
|
|
|
/* Normal operation */
|
|
|
|
|
/* define dvec, view direction vector */
|
2012-04-02 05:34:58 +00:00
|
|
|
zero_v3(dvec_tmp);
|
2010-10-25 07:09:38 +00:00
|
|
|
/* move along the current axis */
|
2012-03-10 06:46:23 +00:00
|
|
|
dvec_tmp[fly->axis] = 1.0f;
|
2010-10-25 07:09:38 +00:00
|
|
|
|
|
|
|
|
mul_m3_v3(mat, dvec_tmp);
|
|
|
|
|
}
|
2011-09-25 04:47:46 +00:00
|
|
|
else {
|
|
|
|
|
normalize_v3_v3(dvec_tmp, fly->dvec_prev);
|
2012-02-22 16:52:06 +00:00
|
|
|
if (fly->speed < 0.0f) {
|
2011-09-25 04:47:46 +00:00
|
|
|
negate_v3(dvec_tmp);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mul_v3_fl(dvec_tmp, fly->speed * time_redraw * 0.25f);
|
2010-10-25 07:09:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* impose a directional lag */
|
2012-03-10 06:46:23 +00:00
|
|
|
interp_v3_v3v3(dvec, dvec_tmp, fly->dvec_prev, (1.0f / (1.0f + (time_redraw * 5.0f))));
|
2010-10-25 07:09:38 +00:00
|
|
|
|
2012-03-10 06:46:23 +00:00
|
|
|
if (rv3d->persp == RV3D_CAMOB) {
|
|
|
|
|
Object *lock_ob = fly->root_parent ? fly->root_parent : fly->v3d->camera;
|
2010-10-25 07:09:38 +00:00
|
|
|
if (lock_ob->protectflag & OB_LOCK_LOCX) dvec[0] = 0.0;
|
|
|
|
|
if (lock_ob->protectflag & OB_LOCK_LOCY) dvec[1] = 0.0;
|
|
|
|
|
if (lock_ob->protectflag & OB_LOCK_LOCZ) dvec[2] = 0.0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
add_v3_v3(rv3d->ofs, dvec);
|
|
|
|
|
|
2012-03-10 06:46:23 +00:00
|
|
|
if (rv3d->persp == RV3D_CAMOB)
|
2011-07-31 03:06:00 +00:00
|
|
|
move_camera(C, rv3d, fly, (fly->xlock || fly->zlock || moffset[0] || moffset[1]), fly->speed);
|
2010-10-25 07:09:38 +00:00
|
|
|
|
2011-08-02 08:12:50 +00:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* we're not redrawing but we need to update the time else the view will jump */
|
2012-03-10 06:46:23 +00:00
|
|
|
fly->time_lastdraw = PIL_check_seconds_timer();
|
2011-08-02 08:12:50 +00:00
|
|
|
}
|
2010-10-25 07:09:38 +00:00
|
|
|
/* end drawing */
|
|
|
|
|
copy_v3_v3(fly->dvec_prev, dvec);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
2011-07-14 21:20:45 +00:00
|
|
|
static int flyApply_ndof(bContext *C, FlyInfo *fly)
|
|
|
|
|
{
|
2011-08-02 08:12:50 +00:00
|
|
|
/* shorthand for oft-used variables */
|
2012-03-25 23:54:33 +00:00
|
|
|
wmNDOFMotionData *ndof = fly->ndof;
|
2011-07-14 21:20:45 +00:00
|
|
|
const float dt = ndof->dt;
|
2012-05-08 15:55:29 +00:00
|
|
|
RegionView3D *rv3d = fly->rv3d;
|
2011-07-21 21:40:04 +00:00
|
|
|
const int flag = U.ndof_flag;
|
2011-07-14 21:20:45 +00:00
|
|
|
|
2012-03-03 16:31:46 +00:00
|
|
|
#if 0
|
2012-12-20 00:29:31 +00:00
|
|
|
int shouldRotate = (flag & NDOF_SHOULD_ROTATE) && (fly->pan_view == FALSE);
|
|
|
|
|
int shouldTranslate = (flag & (NDOF_SHOULD_PAN | NDOF_SHOULD_ZOOM));
|
2012-03-03 16:31:46 +00:00
|
|
|
#endif
|
2011-07-31 06:26:03 +00:00
|
|
|
|
2012-04-02 06:26:52 +00:00
|
|
|
int shouldRotate = (fly->pan_view == FALSE);
|
|
|
|
|
int shouldTranslate = TRUE;
|
2011-07-14 21:20:45 +00:00
|
|
|
|
|
|
|
|
float view_inv[4];
|
|
|
|
|
invert_qt_qt(view_inv, rv3d->viewquat);
|
|
|
|
|
|
2012-04-02 06:26:52 +00:00
|
|
|
rv3d->rot_angle = 0.0f; /* disable onscreen rotation doo-dad */
|
2011-07-26 02:35:46 +00:00
|
|
|
|
2011-08-02 08:12:50 +00:00
|
|
|
if (shouldTranslate) {
|
2012-04-02 06:26:52 +00:00
|
|
|
const float forward_sensitivity = 1.0f;
|
2011-07-14 21:20:45 +00:00
|
|
|
const float vertical_sensitivity = 0.4f;
|
2012-04-02 06:26:52 +00:00
|
|
|
const float lateral_sensitivity = 0.6f;
|
2011-07-14 21:20:45 +00:00
|
|
|
|
2012-04-02 06:26:52 +00:00
|
|
|
float speed = 10.0f; /* blender units per second */
|
2011-08-02 08:12:50 +00:00
|
|
|
/* ^^ this is ok for default cube scene, but should scale with.. something */
|
2011-07-14 21:20:45 +00:00
|
|
|
|
2012-04-02 06:26:52 +00:00
|
|
|
float trans[3] = {lateral_sensitivity * ndof->tvec[0],
|
2011-09-25 04:47:46 +00:00
|
|
|
vertical_sensitivity * ndof->tvec[1],
|
|
|
|
|
forward_sensitivity * ndof->tvec[2]};
|
2011-07-14 21:20:45 +00:00
|
|
|
|
2011-07-31 03:06:00 +00:00
|
|
|
if (fly->use_precision)
|
|
|
|
|
speed *= 0.2f;
|
|
|
|
|
|
2011-07-14 21:20:45 +00:00
|
|
|
mul_v3_fl(trans, speed * dt);
|
|
|
|
|
|
2012-04-02 06:26:52 +00:00
|
|
|
/* transform motion from view to world coordinates */
|
2011-07-14 21:20:45 +00:00
|
|
|
mul_qt_v3(view_inv, trans);
|
|
|
|
|
|
2011-08-02 08:12:50 +00:00
|
|
|
if (flag & NDOF_FLY_HELICOPTER) {
|
|
|
|
|
/* replace world z component with device y (yes it makes sense) */
|
2011-08-02 07:08:22 +00:00
|
|
|
trans[2] = speed * dt * vertical_sensitivity * ndof->tvec[1];
|
2011-08-02 08:12:50 +00:00
|
|
|
}
|
2011-07-19 04:12:49 +00:00
|
|
|
|
2012-03-10 06:46:23 +00:00
|
|
|
if (rv3d->persp == RV3D_CAMOB) {
|
2012-04-02 06:26:52 +00:00
|
|
|
/* respect camera position locks */
|
2012-03-10 06:46:23 +00:00
|
|
|
Object *lock_ob = fly->root_parent ? fly->root_parent : fly->v3d->camera;
|
|
|
|
|
if (lock_ob->protectflag & OB_LOCK_LOCX) trans[0] = 0.0f;
|
|
|
|
|
if (lock_ob->protectflag & OB_LOCK_LOCY) trans[1] = 0.0f;
|
|
|
|
|
if (lock_ob->protectflag & OB_LOCK_LOCZ) trans[2] = 0.0f;
|
2011-07-31 03:06:00 +00:00
|
|
|
}
|
2011-07-14 21:20:45 +00:00
|
|
|
|
2011-08-02 08:12:50 +00:00
|
|
|
if (!is_zero_v3(trans)) {
|
2012-04-02 06:26:52 +00:00
|
|
|
/* move center of view opposite of hand motion (this is camera mode, not object mode) */
|
2011-07-31 03:06:00 +00:00
|
|
|
sub_v3_v3(rv3d->ofs, trans);
|
|
|
|
|
shouldTranslate = TRUE;
|
2011-08-02 08:12:50 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2011-07-31 03:06:00 +00:00
|
|
|
shouldTranslate = FALSE;
|
2011-07-14 21:20:45 +00:00
|
|
|
}
|
2011-08-02 08:12:50 +00:00
|
|
|
}
|
2011-07-14 21:20:45 +00:00
|
|
|
|
2011-08-02 08:12:50 +00:00
|
|
|
if (shouldRotate) {
|
2012-04-02 06:26:52 +00:00
|
|
|
const float turn_sensitivity = 1.0f;
|
2011-07-19 22:40:22 +00:00
|
|
|
|
|
|
|
|
float rotation[4];
|
|
|
|
|
float axis[3];
|
2011-08-02 08:12:50 +00:00
|
|
|
float angle = turn_sensitivity * ndof_to_axis_angle(ndof, axis);
|
2011-07-19 22:40:22 +00:00
|
|
|
|
2011-08-02 08:12:50 +00:00
|
|
|
if (fabsf(angle) > 0.0001f) {
|
2011-07-31 03:06:00 +00:00
|
|
|
shouldRotate = TRUE;
|
2011-07-19 22:40:22 +00:00
|
|
|
|
2011-07-31 03:06:00 +00:00
|
|
|
if (fly->use_precision)
|
|
|
|
|
angle *= 0.2f;
|
2011-07-19 22:40:22 +00:00
|
|
|
|
2011-08-02 08:12:50 +00:00
|
|
|
/* transform rotation axis from view to world coordinates */
|
2011-07-31 03:06:00 +00:00
|
|
|
mul_qt_v3(view_inv, axis);
|
2011-07-19 22:40:22 +00:00
|
|
|
|
2012-04-02 06:26:52 +00:00
|
|
|
/* apply rotation to view */
|
2011-07-31 03:06:00 +00:00
|
|
|
axis_angle_to_quat(rotation, axis, angle);
|
|
|
|
|
mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rotation);
|
2011-07-19 22:40:22 +00:00
|
|
|
|
2011-08-02 08:12:50 +00:00
|
|
|
if (flag & NDOF_LOCK_HORIZON) {
|
|
|
|
|
/* force an upright viewpoint
|
|
|
|
|
* TODO: make this less... sudden */
|
2012-04-02 06:26:52 +00:00
|
|
|
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) */
|
2011-07-19 22:40:22 +00:00
|
|
|
|
2011-08-02 08:12:50 +00:00
|
|
|
/* find new inverse since viewquat has changed */
|
2011-07-31 03:06:00 +00:00
|
|
|
invert_qt_qt(view_inv, rv3d->viewquat);
|
2011-08-02 08:12:50 +00:00
|
|
|
/* could apply reverse rotation to existing view_inv to save a few cycles */
|
2011-07-19 22:40:22 +00:00
|
|
|
|
2011-08-02 08:12:50 +00:00
|
|
|
/* transform view vectors to world coordinates */
|
2011-07-31 03:06:00 +00:00
|
|
|
mul_qt_v3(view_inv, view_horizon);
|
|
|
|
|
mul_qt_v3(view_inv, view_direction);
|
2011-07-19 22:40:22 +00:00
|
|
|
|
2011-08-02 08:12:50 +00:00
|
|
|
/* find difference between view & world horizons
|
|
|
|
|
* true horizon lives in world xy plane, so look only at difference in z */
|
2011-07-31 03:06:00 +00:00
|
|
|
angle = -asinf(view_horizon[2]);
|
|
|
|
|
|
2011-08-02 08:12:50 +00:00
|
|
|
#ifdef NDOF_FLY_DEBUG
|
2011-07-31 03:06:00 +00:00
|
|
|
printf("lock horizon: adjusting %.1f degrees\n\n", RAD2DEG(angle));
|
2011-08-02 08:12:50 +00:00
|
|
|
#endif
|
2011-07-31 03:06:00 +00:00
|
|
|
|
2011-08-02 08:12:50 +00:00
|
|
|
/* rotate view so view horizon = world horizon */
|
2011-07-31 03:06:00 +00:00
|
|
|
axis_angle_to_quat(rotation, view_direction, angle);
|
|
|
|
|
mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rotation);
|
2011-08-02 08:12:50 +00:00
|
|
|
}
|
2011-07-31 03:06:00 +00:00
|
|
|
|
|
|
|
|
rv3d->view = RV3D_VIEW_USER;
|
2011-08-02 08:12:50 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2011-07-31 03:06:00 +00:00
|
|
|
shouldRotate = FALSE;
|
|
|
|
|
}
|
2011-08-02 08:12:50 +00:00
|
|
|
}
|
2011-07-19 22:40:22 +00:00
|
|
|
|
2011-08-02 08:12:50 +00:00
|
|
|
if (shouldTranslate || shouldRotate) {
|
2011-07-31 03:06:00 +00:00
|
|
|
fly->redraw = TRUE;
|
2011-07-19 22:40:22 +00:00
|
|
|
|
2012-03-10 06:46:23 +00:00
|
|
|
if (rv3d->persp == RV3D_CAMOB) {
|
2011-07-31 03:06:00 +00:00
|
|
|
move_camera(C, rv3d, fly, shouldRotate, shouldTranslate);
|
2011-07-19 22:40:22 +00:00
|
|
|
}
|
2011-08-02 08:12:50 +00:00
|
|
|
}
|
2011-07-19 22:40:22 +00:00
|
|
|
|
2011-07-14 21:20:45 +00:00
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
2010-10-25 07:09:38 +00:00
|
|
|
|
|
|
|
|
static int fly_invoke(bContext *C, wmOperator *op, wmEvent *event)
|
|
|
|
|
{
|
2012-03-10 06:46:23 +00:00
|
|
|
RegionView3D *rv3d = CTX_wm_region_view3d(C);
|
2010-10-25 07:09:38 +00:00
|
|
|
FlyInfo *fly;
|
|
|
|
|
|
2011-08-02 08:12:50 +00:00
|
|
|
if (rv3d->viewlock)
|
2010-10-25 07:09:38 +00:00
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
|
2012-03-10 06:46:23 +00:00
|
|
|
fly = MEM_callocN(sizeof(FlyInfo), "FlyOperation");
|
2010-10-25 07:09:38 +00:00
|
|
|
|
2012-03-10 06:46:23 +00:00
|
|
|
op->customdata = fly;
|
2010-10-25 07:09:38 +00:00
|
|
|
|
2012-03-10 06:46:23 +00:00
|
|
|
if (initFlyInfo(C, fly, op, event) == FALSE) {
|
2010-10-25 07:09:38 +00:00
|
|
|
MEM_freeN(op->customdata);
|
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
flyEvent(fly, event);
|
|
|
|
|
|
|
|
|
|
WM_event_add_modal_handler(C, op);
|
|
|
|
|
|
|
|
|
|
return OPERATOR_RUNNING_MODAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int fly_cancel(bContext *C, wmOperator *op)
|
|
|
|
|
{
|
|
|
|
|
FlyInfo *fly = op->customdata;
|
|
|
|
|
|
|
|
|
|
fly->state = FLY_CANCEL;
|
|
|
|
|
flyEnd(C, fly);
|
2012-03-10 06:46:23 +00:00
|
|
|
op->customdata = NULL;
|
2010-10-25 07:09:38 +00:00
|
|
|
|
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int fly_modal(bContext *C, wmOperator *op, wmEvent *event)
|
|
|
|
|
{
|
|
|
|
|
int exit_code;
|
2012-03-10 06:46:23 +00:00
|
|
|
short do_draw = FALSE;
|
|
|
|
|
FlyInfo *fly = op->customdata;
|
|
|
|
|
RegionView3D *rv3d = fly->rv3d;
|
|
|
|
|
Object *fly_object = fly->root_parent ? fly->root_parent : fly->v3d->camera;
|
2010-10-25 07:09:38 +00:00
|
|
|
|
2012-03-10 06:46:23 +00:00
|
|
|
fly->redraw = 0;
|
2010-10-25 07:09:38 +00:00
|
|
|
|
|
|
|
|
flyEvent(fly, event);
|
|
|
|
|
|
2011-08-02 08:12:50 +00:00
|
|
|
if (fly->ndof) { /* 3D mouse overrules [2D mouse + timer] */
|
2012-03-10 06:46:23 +00:00
|
|
|
if (event->type == NDOF_MOTION) {
|
2011-07-14 21:20:45 +00:00
|
|
|
flyApply_ndof(C, fly);
|
|
|
|
|
}
|
2011-08-02 08:12:50 +00:00
|
|
|
}
|
2012-03-10 06:46:23 +00:00
|
|
|
else if (event->type == TIMER && event->customdata == fly->timer) {
|
2010-10-25 07:09:38 +00:00
|
|
|
flyApply(C, fly);
|
2011-08-02 08:12:50 +00:00
|
|
|
}
|
2010-10-25 07:09:38 +00:00
|
|
|
|
2010-10-25 07:12:29 +00:00
|
|
|
do_draw |= fly->redraw;
|
2010-10-25 07:09:38 +00:00
|
|
|
|
|
|
|
|
exit_code = flyEnd(C, fly);
|
|
|
|
|
|
2012-03-10 06:46:23 +00:00
|
|
|
if (exit_code != OPERATOR_RUNNING_MODAL)
|
|
|
|
|
do_draw = TRUE;
|
2010-11-24 16:54:18 +00:00
|
|
|
|
2011-08-02 08:12:50 +00:00
|
|
|
if (do_draw) {
|
2012-03-10 06:46:23 +00:00
|
|
|
if (rv3d->persp == RV3D_CAMOB) {
|
|
|
|
|
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, fly_object);
|
2010-10-25 07:12:29 +00:00
|
|
|
}
|
|
|
|
|
|
2011-08-02 07:49:34 +00:00
|
|
|
// puts("redraw!"); // too frequent, commented with NDOF_FLY_DRAW_TOOMUCH for now
|
2010-10-25 07:09:38 +00:00
|
|
|
ED_region_tag_redraw(CTX_wm_region(C));
|
2010-10-25 07:12:29 +00:00
|
|
|
}
|
2010-10-25 07:09:38 +00:00
|
|
|
|
|
|
|
|
return exit_code;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VIEW3D_OT_fly(wmOperatorType *ot)
|
|
|
|
|
{
|
|
|
|
|
/* identifiers */
|
2012-03-10 06:46:23 +00:00
|
|
|
ot->name = "Fly Navigation";
|
|
|
|
|
ot->description = "Interactively fly around the scene";
|
|
|
|
|
ot->idname = "VIEW3D_OT_fly";
|
2010-10-25 07:09:38 +00:00
|
|
|
|
|
|
|
|
/* api callbacks */
|
2012-03-10 06:46:23 +00:00
|
|
|
ot->invoke = fly_invoke;
|
|
|
|
|
ot->cancel = fly_cancel;
|
|
|
|
|
ot->modal = fly_modal;
|
|
|
|
|
ot->poll = ED_operator_view3d_active;
|
2010-10-25 07:09:38 +00:00
|
|
|
|
|
|
|
|
/* flags */
|
2012-03-10 06:46:23 +00:00
|
|
|
ot->flag = OPTYPE_BLOCKING;
|
2010-10-25 07:09:38 +00:00
|
|
|
}
|