|
|
|
|
@@ -56,9 +56,11 @@
|
|
|
|
|
#include "BKE_object.h"
|
|
|
|
|
#include "BKE_global.h"
|
|
|
|
|
#include "BKE_main.h"
|
|
|
|
|
#include "BKE_report.h"
|
|
|
|
|
#include "BKE_scene.h"
|
|
|
|
|
#include "BKE_screen.h"
|
|
|
|
|
#include "BKE_utildefines.h"
|
|
|
|
|
#include "BKE_depsgraph.h" /* for fly mode updating */
|
|
|
|
|
|
|
|
|
|
#include "RE_pipeline.h" // make_stars
|
|
|
|
|
|
|
|
|
|
@@ -384,26 +386,31 @@ void VIEW3D_OT_smoothview(wmOperatorType *ot)
|
|
|
|
|
ot->poll= ED_operator_view3d_active;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int view3d_setcameratoview_exec(bContext *C, wmOperator *op)
|
|
|
|
|
static void setcameratoview3d(View3D *v3d, RegionView3D *rv3d, Object *ob)
|
|
|
|
|
{
|
|
|
|
|
View3D *v3d = CTX_wm_view3d(C);
|
|
|
|
|
RegionView3D *rv3d= CTX_wm_region_view3d(C);
|
|
|
|
|
Object *ob;
|
|
|
|
|
float dvec[3];
|
|
|
|
|
|
|
|
|
|
ob= v3d->camera;
|
|
|
|
|
dvec[0]= rv3d->dist*rv3d->viewinv[2][0];
|
|
|
|
|
dvec[1]= rv3d->dist*rv3d->viewinv[2][1];
|
|
|
|
|
dvec[2]= rv3d->dist*rv3d->viewinv[2][2];
|
|
|
|
|
|
|
|
|
|
VECCOPY(ob->loc, dvec);
|
|
|
|
|
VecSubf(ob->loc, ob->loc, v3d->ofs);
|
|
|
|
|
VecSubf(ob->loc, ob->loc, rv3d->ofs);
|
|
|
|
|
rv3d->viewquat[0]= -rv3d->viewquat[0];
|
|
|
|
|
|
|
|
|
|
QuatToEul(rv3d->viewquat, ob->rot);
|
|
|
|
|
rv3d->viewquat[0]= -rv3d->viewquat[0];
|
|
|
|
|
|
|
|
|
|
ob->recalc= OB_RECALC_OB;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int view3d_setcameratoview_exec(bContext *C, wmOperator *op)
|
|
|
|
|
{
|
|
|
|
|
View3D *v3d = CTX_wm_view3d(C);
|
|
|
|
|
RegionView3D *rv3d= CTX_wm_region_view3d(C);
|
|
|
|
|
|
|
|
|
|
setcameratoview3d(v3d, rv3d, v3d->camera);
|
|
|
|
|
|
|
|
|
|
WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, CTX_data_scene(C));
|
|
|
|
|
|
|
|
|
|
@@ -1572,6 +1579,802 @@ void VIEW3D_OT_game_start(wmOperatorType *ot)
|
|
|
|
|
ot->poll= game_engine_poll;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* NOTE: these defines are saved in keymap files, do not change values but just add new ones */
|
|
|
|
|
#define FLY_MODAL_CANCEL 1
|
|
|
|
|
#define FLY_MODAL_CONFIRM 2
|
|
|
|
|
#define FLY_MODAL_ACCELERATE 3
|
|
|
|
|
#define FLY_MODAL_DECELERATE 4
|
|
|
|
|
#define FLY_MODAL_PAN_ENABLE 5
|
|
|
|
|
#define FLY_MODAL_PAN_DISABLE 6
|
|
|
|
|
#define FLY_MODAL_DIR_FORWARD 7
|
|
|
|
|
#define FLY_MODAL_DIR_BACKWARD 8
|
|
|
|
|
#define FLY_MODAL_DIR_LEFT 9
|
|
|
|
|
#define FLY_MODAL_DIR_RIGHT 10
|
|
|
|
|
#define FLY_MODAL_DIR_UP 11
|
|
|
|
|
#define FLY_MODAL_DIR_DOWN 12
|
|
|
|
|
#define FLY_MODAL_AXIS_LOCK_X 13
|
|
|
|
|
#define FLY_MODAL_AXIS_LOCK_Z 14
|
|
|
|
|
#define FLY_MODAL_PRECISION_ENABLE 15
|
|
|
|
|
#define FLY_MODAL_PRECISION_DISABLE 16
|
|
|
|
|
|
|
|
|
|
/* called in transform_ops.c, on each regeneration of keymaps */
|
|
|
|
|
void fly_modal_keymap(wmWindowManager *wm)
|
|
|
|
|
{
|
|
|
|
|
static EnumPropertyItem modal_items[] = {
|
|
|
|
|
{FLY_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""},
|
|
|
|
|
{FLY_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""},
|
|
|
|
|
{FLY_MODAL_ACCELERATE, "ACCELERATE", 0, "Accelerate", ""},
|
|
|
|
|
{FLY_MODAL_DECELERATE, "DECELERATE", 0, "Decelerate", ""},
|
|
|
|
|
|
|
|
|
|
{FLY_MODAL_PAN_ENABLE, "PAN_ENABLE", 0, "Pan Enable", ""},
|
|
|
|
|
{FLY_MODAL_PAN_DISABLE, "PAN_DISABLE", 0, "Pan Disable", ""},
|
|
|
|
|
|
|
|
|
|
{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", ""},
|
|
|
|
|
|
|
|
|
|
{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)"},
|
|
|
|
|
|
|
|
|
|
{FLY_MODAL_PRECISION_ENABLE, "PRECISION_ENABLE", 0, "Precision Enable", ""},
|
|
|
|
|
{FLY_MODAL_PRECISION_DISABLE, "PRECISION_DISABLE", 0, "Precision Disable", ""},
|
|
|
|
|
|
|
|
|
|
{0, NULL, 0, NULL, NULL}};
|
|
|
|
|
|
|
|
|
|
wmKeyMap *keymap= WM_modalkeymap_get(wm, "View3D Fly Modal");
|
|
|
|
|
|
|
|
|
|
/* this function is called for each spacetype, only needs to add map once */
|
|
|
|
|
if(keymap) return;
|
|
|
|
|
|
|
|
|
|
keymap= WM_modalkeymap_add(wm, "View3D Fly Modal", modal_items);
|
|
|
|
|
|
|
|
|
|
/* items for modal map */
|
|
|
|
|
WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, FLY_MODAL_CANCEL);
|
|
|
|
|
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, PADENTER, KM_PRESS, KM_ANY, 0, FLY_MODAL_CONFIRM);
|
|
|
|
|
|
|
|
|
|
WM_modalkeymap_add_item(keymap, PADPLUSKEY, KM_PRESS, 0, 0, FLY_MODAL_ACCELERATE);
|
|
|
|
|
WM_modalkeymap_add_item(keymap, PADMINUS, KM_PRESS, 0, 0, FLY_MODAL_DECELERATE);
|
|
|
|
|
WM_modalkeymap_add_item(keymap, WHEELUPMOUSE, KM_PRESS, 0, 0, FLY_MODAL_ACCELERATE);
|
|
|
|
|
WM_modalkeymap_add_item(keymap, WHEELDOWNMOUSE, KM_PRESS, 0, 0, FLY_MODAL_DECELERATE);
|
|
|
|
|
|
|
|
|
|
WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_PRESS, KM_ANY, 0, FLY_MODAL_PAN_ENABLE);
|
|
|
|
|
WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, KM_ANY, 0, FLY_MODAL_PAN_DISABLE); /* XXX - Bug in the event system, middle mouse release doesnt work */
|
|
|
|
|
|
|
|
|
|
/* 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);
|
|
|
|
|
|
|
|
|
|
/* 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 use_precision;
|
|
|
|
|
short redraw;
|
|
|
|
|
short mval[2];
|
|
|
|
|
|
|
|
|
|
/* fly state state */
|
|
|
|
|
float speed; /* the speed the view is moving per redraw */
|
|
|
|
|
short axis; /* Axis index to move allong by default Z to move allong the view */
|
|
|
|
|
short pan_view; /* when true, pan the view instead of rotating */
|
|
|
|
|
|
|
|
|
|
/* relative view axis locking - xlock, zlock
|
|
|
|
|
0; disabled
|
|
|
|
|
1; enabled but not checking because mouse hasnt moved outside the margin since locking was checked an not needed
|
|
|
|
|
when the mouse moves, locking is set to 2 so checks are done.
|
|
|
|
|
2; mouse moved and checking needed, if no view altering is donem its changed back to 1 */
|
|
|
|
|
short xlock, zlock;
|
|
|
|
|
float xlock_momentum, zlock_momentum; /* nicer dynamics */
|
|
|
|
|
float grid; /* world scale 1.0 default */
|
|
|
|
|
|
|
|
|
|
/* backup values */
|
|
|
|
|
float dist_backup; /* backup the views distance since we use a zero dist for fly mode */
|
|
|
|
|
float ofs_backup[3]; /* backup the views offset incase the user cancels flying in non camera mode */
|
|
|
|
|
float rot_backup[4]; /* backup the views quat incase the user cancels flying in non camera mode. (quat for view, eul for camera) */
|
|
|
|
|
short persp_backup; /* remember if were ortho or not, only used for restoring the view if it was a ortho view */
|
|
|
|
|
|
|
|
|
|
/* compare between last state */
|
|
|
|
|
double time_lastwheel; /* used to accelerate when using the mousewheel a lot */
|
|
|
|
|
double time_lastdraw; /* time between draws */
|
|
|
|
|
|
|
|
|
|
/* use for some lag */
|
|
|
|
|
float dvec_prev[3]; /* old for some lag */
|
|
|
|
|
|
|
|
|
|
} FlyInfo;
|
|
|
|
|
|
|
|
|
|
/* FlyInfo->state */
|
|
|
|
|
#define FLY_RUNNING 0
|
|
|
|
|
#define FLY_CANCEL 1
|
|
|
|
|
#define FLY_CONFIRM 2
|
|
|
|
|
|
|
|
|
|
int initFlyInfo (bContext *C, FlyInfo *fly, wmOperator *op, wmEvent *event)
|
|
|
|
|
{
|
|
|
|
|
float upvec[3]; // tmp
|
|
|
|
|
float mat[3][3];
|
|
|
|
|
|
|
|
|
|
fly->rv3d= CTX_wm_region_view3d(C);
|
|
|
|
|
fly->v3d = CTX_wm_view3d(C);
|
|
|
|
|
fly->ar = CTX_wm_region(C);
|
|
|
|
|
fly->scene= CTX_data_scene(C);
|
|
|
|
|
|
|
|
|
|
if(fly->rv3d->persp==V3D_CAMOB && fly->v3d->camera->id.lib) {
|
|
|
|
|
BKE_report(op->reports, RPT_ERROR, "Cannot fly a camera from an external library");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(fly->v3d->ob_centre) {
|
|
|
|
|
BKE_report(op->reports, RPT_ERROR, "Cannot fly when the view is locked to an object");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(fly->rv3d->persp==V3D_CAMOB && fly->v3d->camera->constraints.first) {
|
|
|
|
|
BKE_report(op->reports, RPT_ERROR, "Cannot fly an object with constraints");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fly->state= FLY_RUNNING;
|
|
|
|
|
fly->speed= 0.0f;
|
|
|
|
|
fly->axis= 2;
|
|
|
|
|
fly->pan_view= FALSE;
|
|
|
|
|
fly->xlock= FALSE;
|
|
|
|
|
fly->zlock= TRUE;
|
|
|
|
|
fly->xlock_momentum=0.0f;
|
|
|
|
|
fly->zlock_momentum=0.0f;
|
|
|
|
|
fly->grid= 1.0f;
|
|
|
|
|
fly->use_precision= 0;
|
|
|
|
|
|
|
|
|
|
fly->dvec_prev[0]= fly->dvec_prev[1]= fly->dvec_prev[2]= 0.0f;
|
|
|
|
|
|
|
|
|
|
fly->timer= WM_event_add_window_timer(CTX_wm_window(C), TIMER, 0.01f);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* we have to rely on events to give proper mousecoords after a warp_pointer */
|
|
|
|
|
//XXX2.5 warp_pointer(cent_orig[0], cent_orig[1]);
|
|
|
|
|
//fly->mval[0]= (fly->sa->winx)/2;
|
|
|
|
|
//fly->mval[1]= (fly->sa->winy)/2;
|
|
|
|
|
|
|
|
|
|
fly->mval[0] = event->x - fly->ar->winrct.xmin;
|
|
|
|
|
fly->mval[1] = event->y - fly->ar->winrct.ymin;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fly->time_lastdraw= fly->time_lastwheel= PIL_check_seconds_timer();
|
|
|
|
|
|
|
|
|
|
fly->rv3d->rflag |= RV3D_FLYMODE; /* so we draw the corner margins */
|
|
|
|
|
|
|
|
|
|
/* detect weather to start with Z locking */
|
|
|
|
|
upvec[0]=1.0f; upvec[1]=0.0f; upvec[2]=0.0f;
|
|
|
|
|
Mat3CpyMat4(mat, fly->rv3d->viewinv);
|
|
|
|
|
Mat3MulVecfl(mat, upvec);
|
|
|
|
|
if (fabs(upvec[2]) < 0.1)
|
|
|
|
|
fly->zlock = 1;
|
|
|
|
|
upvec[0]=0; upvec[1]=0; upvec[2]=0;
|
|
|
|
|
|
|
|
|
|
fly->persp_backup= fly->rv3d->persp;
|
|
|
|
|
fly->dist_backup= fly->rv3d->dist;
|
|
|
|
|
if (fly->rv3d->persp==V3D_CAMOB) {
|
|
|
|
|
/* store the origoinal camera loc and rot */
|
|
|
|
|
VECCOPY(fly->ofs_backup, fly->v3d->camera->loc);
|
|
|
|
|
VECCOPY(fly->rot_backup, fly->v3d->camera->rot);
|
|
|
|
|
|
|
|
|
|
where_is_object(fly->scene, fly->v3d->camera);
|
|
|
|
|
VECCOPY(fly->rv3d->ofs, fly->v3d->camera->obmat[3]);
|
|
|
|
|
VecMulf(fly->rv3d->ofs, -1.0f); /*flip the vector*/
|
|
|
|
|
|
|
|
|
|
fly->rv3d->dist=0.0;
|
|
|
|
|
fly->rv3d->viewbut=0;
|
|
|
|
|
|
|
|
|
|
/* used for recording */
|
|
|
|
|
//XXX2.5 if(v3d->camera->ipoflag & OB_ACTION_OB)
|
|
|
|
|
//XXX2.5 actname= "Object";
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
/* perspective or ortho */
|
|
|
|
|
if (fly->rv3d->persp==V3D_ORTHO)
|
|
|
|
|
fly->rv3d->persp= V3D_PERSP; /*if ortho projection, make perspective */
|
|
|
|
|
QUATCOPY(fly->rot_backup, fly->rv3d->viewquat);
|
|
|
|
|
VECCOPY(fly->ofs_backup, fly->rv3d->ofs);
|
|
|
|
|
fly->rv3d->dist= 0.0;
|
|
|
|
|
|
|
|
|
|
upvec[2]= fly->dist_backup; /*x and y are 0*/
|
|
|
|
|
Mat3MulVecfl(mat, upvec);
|
|
|
|
|
VecSubf(fly->rv3d->ofs, fly->rv3d->ofs, upvec);
|
|
|
|
|
/*Done with correcting for the dist*/
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int flyEnd(bContext *C, FlyInfo *fly)
|
|
|
|
|
{
|
|
|
|
|
RegionView3D *rv3d= fly->rv3d;
|
|
|
|
|
View3D *v3d = fly->v3d;
|
|
|
|
|
|
|
|
|
|
float upvec[3];
|
|
|
|
|
|
|
|
|
|
if(fly->state == FLY_RUNNING)
|
|
|
|
|
return OPERATOR_RUNNING_MODAL;
|
|
|
|
|
|
|
|
|
|
WM_event_remove_window_timer(CTX_wm_window(C), fly->timer);
|
|
|
|
|
|
|
|
|
|
rv3d->dist= fly->dist_backup;
|
|
|
|
|
|
|
|
|
|
if (fly->state == FLY_CANCEL) {
|
|
|
|
|
/* Revert to original view? */
|
|
|
|
|
if (fly->persp_backup==V3D_CAMOB) { /* a camera view */
|
|
|
|
|
rv3d->viewbut=1;
|
|
|
|
|
VECCOPY(v3d->camera->loc, fly->ofs_backup);
|
|
|
|
|
VECCOPY(v3d->camera->rot, fly->rot_backup);
|
|
|
|
|
DAG_id_flush_update(&v3d->camera->id, OB_RECALC_OB);
|
|
|
|
|
} else {
|
|
|
|
|
/* Non Camera we need to reset the view back to the original location bacause the user canceled*/
|
|
|
|
|
QUATCOPY(rv3d->viewquat, fly->rot_backup);
|
|
|
|
|
VECCOPY(rv3d->ofs, fly->ofs_backup);
|
|
|
|
|
rv3d->persp= fly->persp_backup;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (fly->persp_backup==V3D_CAMOB) { /* camera */
|
|
|
|
|
float mat3[3][3];
|
|
|
|
|
Mat3CpyMat4(mat3, v3d->camera->obmat);
|
|
|
|
|
Mat3ToCompatibleEul(mat3, v3d->camera->rot, fly->rot_backup);
|
|
|
|
|
|
|
|
|
|
DAG_id_flush_update(&v3d->camera->id, OB_RECALC_OB);
|
|
|
|
|
#if 0 //XXX2.5
|
|
|
|
|
if (IS_AUTOKEY_MODE(NORMAL)) {
|
|
|
|
|
allqueue(REDRAWIPO, 0);
|
|
|
|
|
allspace(REMAKEIPO, 0);
|
|
|
|
|
allqueue(REDRAWNLA, 0);
|
|
|
|
|
allqueue(REDRAWTIME, 0);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
else { /* not camera */
|
|
|
|
|
/* Apply the fly mode view */
|
|
|
|
|
/*restore the dist*/
|
|
|
|
|
float mat[3][3];
|
|
|
|
|
upvec[0]= upvec[1]= 0;
|
|
|
|
|
upvec[2]= fly->dist_backup; /*x and y are 0*/
|
|
|
|
|
Mat3CpyMat4(mat, rv3d->viewinv);
|
|
|
|
|
Mat3MulVecfl(mat, upvec);
|
|
|
|
|
VecAddf(rv3d->ofs, rv3d->ofs, upvec);
|
|
|
|
|
/*Done with correcting for the dist */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rv3d->rflag &= ~RV3D_FLYMODE;
|
|
|
|
|
//XXX2.5 BIF_view3d_previewrender_signal(fly->sa, PR_DBASE|PR_DISPRECT); /* not working at the moment not sure why */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(fly->state == FLY_CONFIRM) {
|
|
|
|
|
MEM_freeN(fly);
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MEM_freeN(fly);
|
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void flyEvent(FlyInfo *fly, wmEvent *event)
|
|
|
|
|
{
|
|
|
|
|
if (event->type == TIMER) {
|
|
|
|
|
fly->redraw = 1;
|
|
|
|
|
}
|
|
|
|
|
else if (event->type == MOUSEMOVE) {
|
|
|
|
|
fly->mval[0] = event->x - fly->ar->winrct.xmin;
|
|
|
|
|
fly->mval[1] = event->y - fly->ar->winrct.ymin;
|
|
|
|
|
} /* handle modal keymap first */
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
case FLY_MODAL_ACCELERATE:
|
|
|
|
|
{
|
|
|
|
|
double time_currwheel;
|
|
|
|
|
float time_wheel;
|
|
|
|
|
|
|
|
|
|
time_currwheel= PIL_check_seconds_timer();
|
|
|
|
|
time_wheel = (float)(time_currwheel - fly->time_lastwheel);
|
|
|
|
|
fly->time_lastwheel = time_currwheel;
|
|
|
|
|
/*printf("Wheel %f\n", time_wheel);*/
|
|
|
|
|
/*Mouse wheel delays range from 0.5==slow to 0.01==fast*/
|
|
|
|
|
time_wheel = 1+ (10 - (20*MIN2(time_wheel, 0.5))); /* 0-0.5 -> 0-5.0 */
|
|
|
|
|
|
|
|
|
|
if (fly->speed<0.0f) fly->speed= 0.0f;
|
|
|
|
|
else {
|
|
|
|
|
if (event->shift)
|
|
|
|
|
fly->speed+= fly->grid*time_wheel*0.1;
|
|
|
|
|
else
|
|
|
|
|
fly->speed+= fly->grid*time_wheel;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case FLY_MODAL_DECELERATE:
|
|
|
|
|
{
|
|
|
|
|
double time_currwheel;
|
|
|
|
|
float time_wheel;
|
|
|
|
|
|
|
|
|
|
time_currwheel= PIL_check_seconds_timer();
|
|
|
|
|
time_wheel = (float)(time_currwheel - fly->time_lastwheel);
|
|
|
|
|
fly->time_lastwheel = time_currwheel;
|
|
|
|
|
time_wheel = 1+ (10 - (20*MIN2(time_wheel, 0.5))); /* 0-0.5 -> 0-5.0 */
|
|
|
|
|
|
|
|
|
|
if (fly->speed>0) fly->speed=0;
|
|
|
|
|
else {
|
|
|
|
|
if (event->shift)
|
|
|
|
|
fly->speed-= fly->grid*time_wheel*0.1;
|
|
|
|
|
else
|
|
|
|
|
fly->speed-= fly->grid*time_wheel;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case FLY_MODAL_PAN_ENABLE:
|
|
|
|
|
fly->pan_view= TRUE;
|
|
|
|
|
break;
|
|
|
|
|
case FLY_MODAL_PAN_DISABLE:
|
|
|
|
|
//XXX2.5 warp_pointer(cent_orig[0], cent_orig[1]);
|
|
|
|
|
fly->pan_view= FALSE;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
/* impliment WASD keys */
|
|
|
|
|
case FLY_MODAL_DIR_FORWARD:
|
|
|
|
|
if (fly->speed < 0.0f) fly->speed= -fly->speed; /* flip speed rather then stopping, game like motion */
|
|
|
|
|
else fly->speed += fly->grid; /* increse like mousewheel if were alredy moving in that difection*/
|
|
|
|
|
fly->axis= 2;
|
|
|
|
|
break;
|
|
|
|
|
case FLY_MODAL_DIR_BACKWARD:
|
|
|
|
|
if (fly->speed>0) fly->speed= -fly->speed;
|
|
|
|
|
else fly->speed -= fly->grid;
|
|
|
|
|
fly->axis= 2;
|
|
|
|
|
break;
|
|
|
|
|
case FLY_MODAL_DIR_LEFT:
|
|
|
|
|
if (fly->speed < 0.0f) fly->speed= -fly->speed;
|
|
|
|
|
fly->axis= 0;
|
|
|
|
|
break;
|
|
|
|
|
case FLY_MODAL_DIR_RIGHT:
|
|
|
|
|
if (fly->speed > 0.0f) fly->speed= -fly->speed;
|
|
|
|
|
fly->axis= 0;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case FLY_MODAL_DIR_UP:
|
|
|
|
|
if (fly->speed < 0.0f) fly->speed= -fly->speed;
|
|
|
|
|
fly->axis= 1;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case FLY_MODAL_DIR_DOWN:
|
|
|
|
|
if (fly->speed > 0.0f) fly->speed= -fly->speed;
|
|
|
|
|
fly->axis= 1;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case FLY_MODAL_AXIS_LOCK_X:
|
|
|
|
|
if (fly->xlock) fly->xlock=0;
|
|
|
|
|
else {
|
|
|
|
|
fly->xlock = 2;
|
|
|
|
|
fly->xlock_momentum = 0.0;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case FLY_MODAL_AXIS_LOCK_Z:
|
|
|
|
|
if (fly->zlock) fly->zlock=0;
|
|
|
|
|
else {
|
|
|
|
|
fly->zlock = 2;
|
|
|
|
|
fly->zlock_momentum = 0.0;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case FLY_MODAL_PRECISION_ENABLE:
|
|
|
|
|
fly->use_precision= TRUE;
|
|
|
|
|
break;
|
|
|
|
|
case FLY_MODAL_PRECISION_DISABLE:
|
|
|
|
|
fly->use_precision= FALSE;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//int fly_exec(bContext *C, wmOperator *op)
|
|
|
|
|
int flyApply(FlyInfo *fly)
|
|
|
|
|
{
|
|
|
|
|
/*
|
|
|
|
|
fly mode - Shift+F
|
|
|
|
|
a fly loop where the user can move move the view as if they are flying
|
|
|
|
|
*/
|
|
|
|
|
RegionView3D *rv3d= fly->rv3d;
|
|
|
|
|
View3D *v3d = fly->v3d;
|
|
|
|
|
ARegion *ar = fly->ar;
|
|
|
|
|
Scene *scene= fly->scene;
|
|
|
|
|
|
|
|
|
|
float mat[3][3], /* 3x3 copy of the view matrix so we can move allong the view axis */
|
|
|
|
|
dvec[3]={0,0,0}, /* this is the direction thast added to the view offset per redraw */
|
|
|
|
|
|
|
|
|
|
/* Camera Uprighting variables */
|
|
|
|
|
upvec[3]={0,0,0}, /* stores the view's up vector */
|
|
|
|
|
|
|
|
|
|
moffset[2], /* mouse offset from the views center */
|
|
|
|
|
tmp_quat[4]; /* used for rotating the view */
|
|
|
|
|
|
|
|
|
|
int cent_orig[2], /* view center */
|
|
|
|
|
//XXX- can avoid using // cent[2], /* view center modified */
|
|
|
|
|
xmargin, ymargin; /* x and y margin are define the safe area where the mouses movement wont rotate the view */
|
|
|
|
|
unsigned char
|
|
|
|
|
apply_rotation= 1; /* if the user presses shift they can look about without movinf the direction there looking*/
|
|
|
|
|
|
|
|
|
|
/* for recording */
|
|
|
|
|
#if 0 //XXX2.5 todo, get animation recording working again.
|
|
|
|
|
int playing_anim = 0; //XXX has_screenhandler(G.curscreen, SCREEN_HANDLER_ANIM);
|
|
|
|
|
int cfra = -1; /*so the first frame always has a key added */
|
|
|
|
|
char *actname="";
|
|
|
|
|
#endif
|
|
|
|
|
/* the dist defines a vector that is infront of the offset
|
|
|
|
|
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. */
|
|
|
|
|
|
|
|
|
|
xmargin= ar->winx/20.0f;
|
|
|
|
|
ymargin= ar->winy/20.0f;
|
|
|
|
|
|
|
|
|
|
cent_orig[0]= ar->winrct.xmin + ar->winx/2;
|
|
|
|
|
cent_orig[1]= ar->winrct.ymin + ar->winy/2;
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
/* mouse offset from the center */
|
|
|
|
|
moffset[0]= fly->mval[0]- ar->winx/2;
|
|
|
|
|
moffset[1]= fly->mval[1]- ar->winy/2;
|
|
|
|
|
|
|
|
|
|
/* enforce a view margin */
|
|
|
|
|
if (moffset[0]>xmargin) moffset[0]-=xmargin;
|
|
|
|
|
else if (moffset[0] < -xmargin) moffset[0]+=xmargin;
|
|
|
|
|
else moffset[0]=0;
|
|
|
|
|
|
|
|
|
|
if (moffset[1]>ymargin) moffset[1]-=ymargin;
|
|
|
|
|
else if (moffset[1] < -ymargin) moffset[1]+=ymargin;
|
|
|
|
|
else moffset[1]=0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* scale the mouse movement by this value - scales mouse movement to the view size
|
|
|
|
|
* moffset[0]/(ar->winx-xmargin*2) - window size minus margin (same for y)
|
|
|
|
|
*
|
|
|
|
|
* the mouse moves isnt linear */
|
|
|
|
|
|
|
|
|
|
if(moffset[0]) {
|
|
|
|
|
moffset[0] /= ar->winx - (xmargin*2);
|
|
|
|
|
moffset[0] *= fabs(moffset[0]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(moffset[1]) {
|
|
|
|
|
moffset[1] /= ar->winy - (ymargin*2);
|
|
|
|
|
moffset[1] *= fabs(moffset[1]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Should we redraw? */
|
|
|
|
|
if(fly->speed != 0.0f || moffset[0] || moffset[1] || fly->zlock || fly->xlock || dvec[0] || dvec[1] || dvec[2] ) {
|
|
|
|
|
float dvec_tmp[3];
|
|
|
|
|
double time_current, time_redraw; /*time how fast it takes for us to redraw, this is so simple scenes dont fly too fast */
|
|
|
|
|
float time_redraw_clamped;
|
|
|
|
|
|
|
|
|
|
time_current= PIL_check_seconds_timer();
|
|
|
|
|
time_redraw= (float)(time_current - fly->time_lastdraw);
|
|
|
|
|
time_redraw_clamped= MIN2(0.05f, time_redraw); /* clamt the redraw time to avoid jitter in roll correction */
|
|
|
|
|
fly->time_lastdraw= time_current;
|
|
|
|
|
/*fprintf(stderr, "%f\n", time_redraw);*/ /* 0.002 is a small redraw 0.02 is larger */
|
|
|
|
|
|
|
|
|
|
/* Scale the time to use shift to scale the speed down- just like
|
|
|
|
|
shift slows many other areas of blender down */
|
|
|
|
|
if (fly->use_precision)
|
|
|
|
|
fly->speed= fly->speed * (1.0f-time_redraw_clamped);
|
|
|
|
|
|
|
|
|
|
Mat3CpyMat4(mat, rv3d->viewinv);
|
|
|
|
|
|
|
|
|
|
if (fly->pan_view==TRUE) {
|
|
|
|
|
/* pan only */
|
|
|
|
|
dvec_tmp[0]= -moffset[0];
|
|
|
|
|
dvec_tmp[1]= -moffset[1];
|
|
|
|
|
dvec_tmp[2]= 0;
|
|
|
|
|
|
|
|
|
|
if (fly->use_precision) {
|
|
|
|
|
dvec_tmp[0] *= 0.1;
|
|
|
|
|
dvec_tmp[1] *= 0.1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Mat3MulVecfl(mat, dvec_tmp);
|
|
|
|
|
VecMulf(dvec_tmp, time_redraw*200.0 * fly->grid);
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
float roll; /* similar to the angle between the camera's up and the Z-up, but its very rough so just roll*/
|
|
|
|
|
|
|
|
|
|
/* rotate about the X axis- look up/down */
|
|
|
|
|
if (moffset[1]) {
|
|
|
|
|
upvec[0]=1;
|
|
|
|
|
upvec[1]=0;
|
|
|
|
|
upvec[2]=0;
|
|
|
|
|
Mat3MulVecfl(mat, upvec);
|
|
|
|
|
VecRotToQuat( upvec, (float)moffset[1]*-time_redraw*20, tmp_quat); /* Rotate about the relative up vec */
|
|
|
|
|
QuatMul(rv3d->viewquat, rv3d->viewquat, tmp_quat);
|
|
|
|
|
|
|
|
|
|
if (fly->xlock) fly->xlock = 2; /*check for rotation*/
|
|
|
|
|
if (fly->zlock) fly->zlock = 2;
|
|
|
|
|
fly->xlock_momentum= 0.0f;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* rotate about the Y axis- look left/right */
|
|
|
|
|
if (moffset[0]) {
|
|
|
|
|
|
|
|
|
|
/* if we're upside down invert the moffset */
|
|
|
|
|
upvec[0]=0;
|
|
|
|
|
upvec[1]=1;
|
|
|
|
|
upvec[2]=0;
|
|
|
|
|
Mat3MulVecfl(mat, upvec);
|
|
|
|
|
|
|
|
|
|
if(upvec[2] < 0.0f)
|
|
|
|
|
moffset[0]= -moffset[0];
|
|
|
|
|
|
|
|
|
|
/* make the lock vectors */
|
|
|
|
|
if (fly->zlock) {
|
|
|
|
|
upvec[0]=0;
|
|
|
|
|
upvec[1]=0;
|
|
|
|
|
upvec[2]=1;
|
|
|
|
|
} else {
|
|
|
|
|
upvec[0]=0;
|
|
|
|
|
upvec[1]=1;
|
|
|
|
|
upvec[2]=0;
|
|
|
|
|
Mat3MulVecfl(mat, upvec);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VecRotToQuat( upvec, (float)moffset[0]*time_redraw*20, tmp_quat); /* Rotate about the relative up vec */
|
|
|
|
|
QuatMul(rv3d->viewquat, rv3d->viewquat, tmp_quat);
|
|
|
|
|
|
|
|
|
|
if (fly->xlock) fly->xlock = 2;/*check for rotation*/
|
|
|
|
|
if (fly->zlock) fly->zlock = 2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (fly->zlock==2) {
|
|
|
|
|
upvec[0]=1;
|
|
|
|
|
upvec[1]=0;
|
|
|
|
|
upvec[2]=0;
|
|
|
|
|
Mat3MulVecfl(mat, upvec);
|
|
|
|
|
|
|
|
|
|
/*make sure we have some z rolling*/
|
|
|
|
|
if (fabs(upvec[2]) > 0.00001f) {
|
|
|
|
|
roll= upvec[2]*5;
|
|
|
|
|
upvec[0]=0; /*rotate the view about this axis*/
|
|
|
|
|
upvec[1]=0;
|
|
|
|
|
upvec[2]=1;
|
|
|
|
|
|
|
|
|
|
Mat3MulVecfl(mat, upvec);
|
|
|
|
|
VecRotToQuat( upvec, roll*time_redraw_clamped*fly->zlock_momentum*0.1, tmp_quat); /* Rotate about the relative up vec */
|
|
|
|
|
QuatMul(rv3d->viewquat, rv3d->viewquat, tmp_quat);
|
|
|
|
|
|
|
|
|
|
fly->zlock_momentum += 0.05f;
|
|
|
|
|
} else {
|
|
|
|
|
fly->zlock=1; /* dont check until the view rotates again */
|
|
|
|
|
fly->zlock_momentum= 0.0f;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (fly->xlock==2 && moffset[1]==0) { /*only apply xcorrect when mouse isnt applying x rot*/
|
|
|
|
|
upvec[0]=0;
|
|
|
|
|
upvec[1]=0;
|
|
|
|
|
upvec[2]=1;
|
|
|
|
|
Mat3MulVecfl(mat, upvec);
|
|
|
|
|
/*make sure we have some z rolling*/
|
|
|
|
|
if (fabs(upvec[2]) > 0.00001) {
|
|
|
|
|
roll= upvec[2] * -5;
|
|
|
|
|
|
|
|
|
|
upvec[0]= 1.0f; /*rotate the view about this axis*/
|
|
|
|
|
upvec[1]= 0.0f;
|
|
|
|
|
upvec[2]= 0.0f;
|
|
|
|
|
|
|
|
|
|
Mat3MulVecfl(mat, upvec);
|
|
|
|
|
|
|
|
|
|
VecRotToQuat( upvec, roll*time_redraw_clamped*fly->xlock_momentum*0.1f, tmp_quat); /* Rotate about the relative up vec */
|
|
|
|
|
QuatMul(rv3d->viewquat, rv3d->viewquat, tmp_quat);
|
|
|
|
|
|
|
|
|
|
fly->xlock_momentum += 0.05f;
|
|
|
|
|
} else {
|
|
|
|
|
fly->xlock=1; /* see above */
|
|
|
|
|
fly->xlock_momentum= 0.0f;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (apply_rotation) {
|
|
|
|
|
/* Normal operation */
|
|
|
|
|
/* define dvec, view direction vector */
|
|
|
|
|
dvec_tmp[0]= dvec_tmp[1]= dvec_tmp[2]= 0.0f;
|
|
|
|
|
/* move along the current axis */
|
|
|
|
|
dvec_tmp[fly->axis]= 1.0f;
|
|
|
|
|
|
|
|
|
|
Mat3MulVecfl(mat, dvec_tmp);
|
|
|
|
|
|
|
|
|
|
VecMulf(dvec_tmp, fly->speed * time_redraw * 0.25f);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* impose a directional lag */
|
|
|
|
|
VecLerpf(dvec, dvec_tmp, fly->dvec_prev, (1.0f/(1.0f+(time_redraw*5.0f))));
|
|
|
|
|
|
|
|
|
|
if (rv3d->persp==V3D_CAMOB) {
|
|
|
|
|
if (v3d->camera->protectflag & OB_LOCK_LOCX)
|
|
|
|
|
dvec[0] = 0.0;
|
|
|
|
|
if (v3d->camera->protectflag & OB_LOCK_LOCY)
|
|
|
|
|
dvec[1] = 0.0;
|
|
|
|
|
if (v3d->camera->protectflag & OB_LOCK_LOCZ)
|
|
|
|
|
dvec[2] = 0.0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VecAddf(rv3d->ofs, rv3d->ofs, dvec);
|
|
|
|
|
#if 0 //XXX2.5
|
|
|
|
|
if (fly->zlock && fly->xlock)
|
|
|
|
|
headerprint("FlyKeys Speed:(+/- | Wheel), Upright Axis:X on/Z on, Slow:Shift, Direction:WASDRF, Ok:LMB, Pan:MMB, Cancel:RMB");
|
|
|
|
|
else if (fly->zlock)
|
|
|
|
|
headerprint("FlyKeys Speed:(+/- | Wheel), Upright Axis:X off/Z on, Slow:Shift, Direction:WASDRF, Ok:LMB, Pan:MMB, Cancel:RMB");
|
|
|
|
|
else if (fly->xlock)
|
|
|
|
|
headerprint("FlyKeys Speed:(+/- | Wheel), Upright Axis:X on/Z off, Slow:Shift, Direction:WASDRF, Ok:LMB, Pan:MMB, Cancel:RMB");
|
|
|
|
|
else
|
|
|
|
|
headerprint("FlyKeys Speed:(+/- | Wheel), Upright Axis:X off/Z off, Slow:Shift, Direction:WASDRF, Ok:LMB, Pan:MMB, Cancel:RMB");
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
//XXX2.5 do_screenhandlers(G.curscreen); /* advance the next frame */
|
|
|
|
|
|
|
|
|
|
/* we are in camera view so apply the view ofs and quat to the view matrix and set the camera to the view */
|
|
|
|
|
if (rv3d->persp==V3D_CAMOB) {
|
|
|
|
|
rv3d->persp= V3D_PERSP; /*set this so setviewmatrixview3d uses the ofs and quat instead of the camera */
|
|
|
|
|
setviewmatrixview3d(scene, v3d, rv3d);
|
|
|
|
|
|
|
|
|
|
setcameratoview3d(v3d, rv3d, v3d->camera);
|
|
|
|
|
|
|
|
|
|
{ //XXX - some reason setcameratoview3d doesnt copy, shouldnt not be needed!
|
|
|
|
|
VECCOPY(v3d->camera->loc, rv3d->ofs);
|
|
|
|
|
VecNegf(v3d->camera->loc);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rv3d->persp= V3D_CAMOB;
|
|
|
|
|
#if 0 //XXX2.5
|
|
|
|
|
/* record the motion */
|
|
|
|
|
if (IS_AUTOKEY_MODE(NORMAL) && (!playing_anim || cfra != G.scene->r.cfra)) {
|
|
|
|
|
cfra = G.scene->r.cfra;
|
|
|
|
|
|
|
|
|
|
if (fly->xlock || fly->zlock || moffset[0] || moffset[1]) {
|
|
|
|
|
insertkey(&v3d->camera->id, ID_OB, actname, NULL, OB_ROT_X, 0);
|
|
|
|
|
insertkey(&v3d->camera->id, ID_OB, actname, NULL, OB_ROT_Y, 0);
|
|
|
|
|
insertkey(&v3d->camera->id, ID_OB, actname, NULL, OB_ROT_Z, 0);
|
|
|
|
|
}
|
|
|
|
|
if (fly->speed) {
|
|
|
|
|
insertkey(&v3d->camera->id, ID_OB, actname, NULL, OB_LOC_X, 0);
|
|
|
|
|
insertkey(&v3d->camera->id, ID_OB, actname, NULL, OB_LOC_Y, 0);
|
|
|
|
|
insertkey(&v3d->camera->id, ID_OB, actname, NULL, OB_LOC_Z, 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
//XXX2.5 scrarea_do_windraw(curarea);
|
|
|
|
|
//XXX2.5 screen_swapbuffers();
|
|
|
|
|
} else
|
|
|
|
|
/*were not redrawing but we need to update the time else the view will jump */
|
|
|
|
|
fly->time_lastdraw= PIL_check_seconds_timer();
|
|
|
|
|
/* end drawing */
|
|
|
|
|
VECCOPY(fly->dvec_prev, dvec);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* moved to flyEnd() */
|
|
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int fly_invoke(bContext *C, wmOperator *op, wmEvent *event)
|
|
|
|
|
{
|
|
|
|
|
RegionView3D *rv3d= CTX_wm_region_view3d(C);
|
|
|
|
|
FlyInfo *fly;
|
|
|
|
|
|
|
|
|
|
if(rv3d->viewlock)
|
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
|
|
|
|
|
fly= MEM_callocN(sizeof(FlyInfo), "FlyOperation");
|
|
|
|
|
|
|
|
|
|
op->customdata= fly;
|
|
|
|
|
|
|
|
|
|
if(initFlyInfo(C, fly, op, event)==FALSE) {
|
|
|
|
|
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);
|
|
|
|
|
op->customdata= NULL;
|
|
|
|
|
|
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int fly_modal(bContext *C, wmOperator *op, wmEvent *event)
|
|
|
|
|
{
|
|
|
|
|
int exit_code;
|
|
|
|
|
|
|
|
|
|
FlyInfo *fly = op->customdata;
|
|
|
|
|
|
|
|
|
|
fly->redraw= 0;
|
|
|
|
|
|
|
|
|
|
flyEvent(fly, event);
|
|
|
|
|
|
|
|
|
|
if(event->type==TIMER)
|
|
|
|
|
flyApply(fly);
|
|
|
|
|
|
|
|
|
|
if(fly->redraw) {;
|
|
|
|
|
ED_region_tag_redraw(CTX_wm_region(C));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
exit_code = flyEnd(C, fly);
|
|
|
|
|
|
|
|
|
|
if(exit_code!=OPERATOR_RUNNING_MODAL)
|
|
|
|
|
ED_region_tag_redraw(CTX_wm_region(C));
|
|
|
|
|
|
|
|
|
|
return exit_code;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VIEW3D_OT_fly(wmOperatorType *ot)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
/* identifiers */
|
|
|
|
|
ot->name= "Fly Navigation";
|
|
|
|
|
ot->description= "Interactively fly around the scene.";
|
|
|
|
|
ot->idname= "VIEW3D_OT_fly";
|
|
|
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
|
ot->invoke= fly_invoke;
|
|
|
|
|
ot->cancel= fly_cancel;
|
|
|
|
|
ot->modal= fly_modal;
|
|
|
|
|
ot->poll= ED_operator_view3d_active;
|
|
|
|
|
|
|
|
|
|
/* flags */
|
|
|
|
|
ot->flag= OPTYPE_BLOCKING;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ************************************** */
|
|
|
|
|
|
|
|
|
|
void view3d_align_axis_to_vector(View3D *v3d, RegionView3D *rv3d, int axisidx, float vec[3])
|
|
|
|
|
|