2011-02-23 10:52:22 +00:00
/*
2010-10-25 07:19:43 +00:00
* $ Id $
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 */
# include "DNA_anim_types.h"
# include "DNA_scene_types.h"
# include "DNA_object_types.h"
# 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 */
# include "view3d_intern.h" // own include
/* 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 ( wmKeyConfig * keyconf )
{
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 ( keyconf , " View3D Fly Modal " ) ;
/* this function is called for each spacetype, only needs to add map once */
if ( keymap ) return ;
keymap = WM_modalkeymap_add ( keyconf , " 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 , SPACEKEY , 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 ;
2011-07-14 21:20:45 +00:00
int mval [ 2 ] ; /* latest 2D mouse values */
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 */
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 */
/* root most parent */
Object * root_parent ;
/* 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 */
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 ;
static void drawFlyPixel ( const struct bContext * UNUSED ( C ) , struct ARegion * UNUSED ( ar ) , void * arg )
{
FlyInfo * fly = arg ;
/* draws 4 edge brackets that frame the safe area where the
mouse can move during fly mode without spinning the view */
float x1 , x2 , y1 , y2 ;
2011-03-27 15:57:27 +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 ) ;
glBegin ( GL_LINES ) ;
/* bottom left */
glVertex2f ( x1 , y1 ) ;
glVertex2f ( x1 , y1 + 5 ) ;
glVertex2f ( x1 , y1 ) ;
glVertex2f ( x1 + 5 , y1 ) ;
/* top right */
glVertex2f ( x2 , y2 ) ;
glVertex2f ( x2 , y2 - 5 ) ;
glVertex2f ( x2 , y2 ) ;
glVertex2f ( x2 - 5 , y2 ) ;
/* top left */
glVertex2f ( x1 , y2 ) ;
glVertex2f ( x1 , y2 - 5 ) ;
glVertex2f ( x1 , y2 ) ;
glVertex2f ( x1 + 5 , y2 ) ;
/* bottom right */
glVertex2f ( x2 , y1 ) ;
glVertex2f ( x2 , y1 + 5 ) ;
glVertex2f ( x2 , y1 ) ;
glVertex2f ( x2 - 5 , y1 ) ;
glEnd ( ) ;
}
/* FlyInfo->state */
# define FLY_RUNNING 0
# define FLY_CANCEL 1
# define FLY_CONFIRM 2
static 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 ) ;
2011-07-14 21:20:45 +00:00
puts ( " \n -- fly begin -- " ) ;
2010-10-25 07:09:38 +00:00
if ( fly - > rv3d - > persp = = RV3D_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 = = RV3D_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 = FALSE ;
fly - > xlock_momentum = 0.0f ;
fly - > zlock_momentum = 0.0f ;
fly - > grid = 1.0f ;
fly - > use_precision = 0 ;
2011-07-14 21:20:45 +00:00
fly - > redraw = 1 ;
2010-10-25 07:09:38 +00:00
fly - > dvec_prev [ 0 ] = fly - > dvec_prev [ 1 ] = fly - > dvec_prev [ 2 ] = 0.0f ;
fly - > timer = WM_event_add_timer ( CTX_wm_manager ( C ) , CTX_wm_window ( C ) , TIMER , 0.01f ) ;
2011-05-20 07:40:05 +00:00
VECCOPY2D ( fly - > mval , event - > mval )
2011-07-14 21:20:45 +00:00
fly - > ndof = NULL ;
2010-10-25 07:09:38 +00:00
fly - > time_lastdraw = fly - > time_lastwheel = PIL_check_seconds_timer ( ) ;
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 */
upvec [ 0 ] = 1.0f ; upvec [ 1 ] = 0.0f ; upvec [ 2 ] = 0.0f ;
copy_m3_m4 ( mat , fly - > rv3d - > viewinv ) ;
mul_m3_v3 ( 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 = = RV3D_CAMOB ) {
Object * ob_back ;
2011-05-23 02:53:30 +00:00
if ( ( U . uiflag & USER_CAM_LOCK_NO_PARENT ) = = 0 & & ( fly - > root_parent = fly - > v3d - > camera - > parent ) ) {
2010-10-25 07:09:38 +00:00
while ( fly - > root_parent - > parent )
fly - > root_parent = fly - > root_parent - > parent ;
ob_back = fly - > root_parent ;
}
else {
ob_back = fly - > v3d - > camera ;
}
/* store the original camera loc and rot */
/* TODO. axis angle etc */
fly - > obtfm = object_tfm_backup ( ob_back ) ;
where_is_object ( fly - > scene , fly - > v3d - > camera ) ;
negate_v3_v3 ( fly - > rv3d - > ofs , fly - > v3d - > camera - > obmat [ 3 ] ) ;
fly - > rv3d - > dist = 0.0 ;
} else {
/* perspective or ortho */
if ( fly - > rv3d - > persp = = RV3D_ORTHO )
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
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 . */
2010-10-25 07:09:38 +00:00
fly - > rv3d - > dist = 0.0f ;
upvec [ 2 ] = fly - > dist_backup ; /*x and y are 0*/
mul_m3_v3 ( mat , upvec ) ;
sub_v3_v3 ( fly - > rv3d - > ofs , upvec ) ;
/*Done with correcting for the dist*/
}
/* center the mouse, probably the UI mafia are against this but without its quite annoying */
WM_cursor_warp ( CTX_wm_window ( C ) , fly - > ar - > winrct . xmin + fly - > ar - > winx / 2 , fly - > ar - > winrct . ymin + fly - > ar - > winy / 2 ) ;
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 ;
2011-07-14 21:20:45 +00:00
puts ( " \n -- fly end -- " ) ;
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 ) ;
rv3d - > dist = fly - > dist_backup ;
if ( fly - > state = = FLY_CANCEL ) {
/* Revert to original view? */
if ( fly - > persp_backup = = RV3D_CAMOB ) { /* a camera view */
Object * ob_back ;
if ( fly - > root_parent ) ob_back = fly - > root_parent ;
else ob_back = fly - > v3d - > camera ;
/* store the original camera loc and rot */
object_tfm_restore ( ob_back , fly - > obtfm ) ;
2010-12-05 18:59:23 +00:00
DAG_id_tag_update ( & ob_back - > id , OB_RECALC_OB ) ;
2010-10-25 07:09:38 +00:00
} else {
/* 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 ) ;
copy_v3_v3 ( rv3d - > ofs , fly - > ofs_backup ) ;
rv3d - > persp = fly - > persp_backup ;
}
}
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 ) ;
2010-10-25 07:09:38 +00:00
}
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*/
copy_m3_m4 ( mat , rv3d - > viewinv ) ;
mul_m3_v3 ( mat , upvec ) ;
add_v3_v3 ( rv3d - > ofs , upvec ) ;
/*Done with correcting for the dist */
}
rv3d - > rflag & = ~ RV3D_NAVIGATING ;
//XXX2.5 BIF_view3d_previewrender_signal(fly->sa, PR_DBASE|PR_DISPRECT); /* not working at the moment not sure why */
if ( fly - > obtfm )
MEM_freeN ( fly - > obtfm ) ;
2011-07-14 21:20:45 +00:00
if ( fly - > ndof )
MEM_freeN ( fly - > ndof ) ;
2010-10-25 07:09:38 +00:00
if ( fly - > state = = FLY_CONFIRM ) {
MEM_freeN ( fly ) ;
return OPERATOR_FINISHED ;
}
MEM_freeN ( fly ) ;
return OPERATOR_CANCELLED ;
}
static void flyEvent ( FlyInfo * fly , wmEvent * event )
{
2011-07-14 21:20:45 +00:00
if ( event - > type = = MOUSEMOVE ) {
2011-05-20 07:40:05 +00:00
VECCOPY2D ( fly - > mval , event - > mval ) ;
2011-07-14 21:20:45 +00:00
}
else if ( event - > type = = NDOF_MOTION ) {
// do these automagically get delivered? yes.
// puts("ndof motion detected in fly mode!");
// static const char* tag_name = "3D mouse position";
wmNDOFMotionData * incoming_ndof = ( wmNDOFMotionData * ) event - > customdata ;
switch ( incoming_ndof - > progress )
{
case P_STARTING :
// start keeping track of 3D mouse position
puts ( " start keeping track of 3D mouse position " ) ;
// fall through...
case P_IN_PROGRESS :
// update 3D mouse position
putchar ( ' . ' ) ; fflush ( stdout ) ;
if ( fly - > ndof = = NULL )
// fly->ndof = MEM_mallocN(sizeof(wmNDOFMotionData), tag_name);
fly - > ndof = MEM_dupallocN ( incoming_ndof ) ;
// fly->ndof = malloc(sizeof(wmNDOFMotionData));
else
memcpy ( fly - > ndof , incoming_ndof , sizeof ( wmNDOFMotionData ) ) ;
break ;
case P_FINISHING :
// stop keeping track of 3D mouse position
puts ( " stop keeping track of 3D mouse position " ) ;
if ( fly - > ndof )
{
MEM_freeN ( fly - > ndof ) ;
// free(fly->ndof);
fly - > ndof = NULL ;
}
break ;
default :
; // should always be one of the above 3
}
}
/* 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 ;
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*/
2011-03-27 15:57:27 +00:00
time_wheel = 1.0f + ( 10.0f - ( 20.0f * MIN2 ( time_wheel , 0.5f ) ) ) ; /* 0-0.5 -> 0-5.0 */
2010-10-25 07:09:38 +00:00
if ( fly - > speed < 0.0f ) fly - > speed = 0.0f ;
else {
if ( event - > shift )
2011-03-27 15:57:27 +00:00
fly - > speed + = fly - > grid * time_wheel * 0.1f ;
2010-10-25 07:09:38 +00:00
else
2011-03-27 15:57:27 +00:00
fly - > speed + = fly - > grid * time_wheel ;
2010-10-25 07:09:38 +00:00
}
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 ;
2011-03-27 15:57:27 +00:00
time_wheel = 1.0f + ( 10.0f - ( 20.0f * MIN2 ( time_wheel , 0.5f ) ) ) ; /* 0-0.5 -> 0-5.0 */
2010-10-25 07:09:38 +00:00
if ( fly - > speed > 0 ) fly - > speed = 0 ;
else {
if ( event - > shift )
2011-03-27 15:57:27 +00:00
fly - > speed - = fly - > grid * time_wheel * 0.1f ;
2010-10-25 07:09:38 +00:00
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 :
2011-05-28 13:11:24 +00:00
if ( fly - > speed < 0.0f ) fly - > speed = - fly - > speed ; /* flip speed rather than stopping, game like motion */
2010-10-25 07:09:38 +00:00
else if ( fly - > axis = = 2 ) fly - > speed + = fly - > grid ; /* increse like mousewheel if were already moving in that difection*/
fly - > axis = 2 ;
break ;
case FLY_MODAL_DIR_BACKWARD :
if ( fly - > speed > 0.0f ) fly - > speed = - fly - > speed ;
else if ( fly - > axis = = 2 ) fly - > speed - = fly - > grid ;
fly - > axis = 2 ;
break ;
case FLY_MODAL_DIR_LEFT :
if ( fly - > speed < 0.0f ) fly - > speed = - fly - > speed ;
else if ( fly - > axis = = 0 ) fly - > speed + = fly - > grid ;
fly - > axis = 0 ;
break ;
case FLY_MODAL_DIR_RIGHT :
if ( fly - > speed > 0.0f ) fly - > speed = - fly - > speed ;
else if ( fly - > axis = = 0 ) fly - > speed - = fly - > grid ;
fly - > axis = 0 ;
break ;
case FLY_MODAL_DIR_DOWN :
if ( fly - > speed < 0.0f ) fly - > speed = - fly - > speed ;
else if ( fly - > axis = = 1 ) fly - > speed + = fly - > grid ;
fly - > axis = 1 ;
break ;
case FLY_MODAL_DIR_UP :
if ( fly - > speed > 0.0f ) fly - > speed = - fly - > speed ;
else if ( fly - > axis = = 1 ) fly - > speed - = fly - > grid ;
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 ;
}
}
}
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 */
/*
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 prev_view_mat [ 4 ] [ 4 ] ;
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 */
2011-03-28 02:34:55 +00:00
int
// cent_orig[2], /* view center */
2010-10-25 07:09:38 +00:00
//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*/
2011-07-14 21:20:45 +00:00
static unsigned int iteration = 1 ;
printf ( " fly timer %d \n " , iteration + + ) ;
2010-10-25 07:09:38 +00:00
if ( fly - > root_parent )
2011-05-23 02:23:03 +00:00
ED_view3d_to_m4 ( prev_view_mat , fly - > rv3d - > ofs , fly - > rv3d - > viewquat , fly - > rv3d - > dist ) ;
2010-10-25 07:09:38 +00:00
xmargin = ar - > winx / 20.0f ;
ymargin = ar - > winy / 20.0f ;
2011-03-28 02:34:55 +00:00
// UNUSED
// 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 */
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 ) ;
2011-03-27 15:57:27 +00:00
moffset [ 0 ] * = fabsf ( moffset [ 0 ] ) ;
2010-10-25 07:09:38 +00:00
}
if ( moffset [ 1 ] ) {
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? */
if ( fly - > speed ! = 0.0f | | moffset [ 0 ] | | moffset [ 1 ] | | fly - > zlock | | fly - > xlock | | dvec [ 0 ] | | dvec [ 1 ] | | dvec [ 2 ] ) {
float dvec_tmp [ 3 ] ;
2011-03-27 15:57:27 +00:00
double time_current ; /*time how fast it takes for us to redraw, this is so simple scenes dont fly too fast */
float time_redraw ;
2010-10-25 07:09:38 +00:00
float time_redraw_clamped ;
2011-07-14 21:20:45 +00:00
fly - > redraw = 1 ;
2010-10-25 07:09:38 +00:00
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 ) ;
copy_m3_m4 ( 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 ) {
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 ) ;
2010-10-25 07:09:38 +00:00
} 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 ;
mul_m3_v3 ( mat , upvec ) ;
axis_angle_to_quat ( tmp_quat , upvec , ( float ) moffset [ 1 ] * time_redraw * - FLY_ROTATE_FAC ) ; /* Rotate about the relative up vec */
mul_qt_qtqt ( 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 ;
mul_m3_v3 ( 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 ;
mul_m3_v3 ( mat , upvec ) ;
}
axis_angle_to_quat ( tmp_quat , upvec , ( float ) moffset [ 0 ] * time_redraw * FLY_ROTATE_FAC ) ; /* Rotate about the relative up vec */
mul_qt_qtqt ( 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 ;
mul_m3_v3 ( mat , upvec ) ;
/*make sure we have some z rolling*/
2011-03-27 15:57:27 +00:00
if ( fabsf ( upvec [ 2 ] ) > 0.00001f ) {
2010-10-25 07:09:38 +00:00
roll = upvec [ 2 ] * 5 ;
upvec [ 0 ] = 0 ; /*rotate the view about this axis*/
upvec [ 1 ] = 0 ;
upvec [ 2 ] = 1 ;
mul_m3_v3 ( mat , upvec ) ;
axis_angle_to_quat ( tmp_quat , upvec , roll * time_redraw_clamped * fly - > zlock_momentum * FLY_ZUP_CORRECT_FAC ) ; /* Rotate about the relative up vec */
mul_qt_qtqt ( rv3d - > viewquat , rv3d - > viewquat , tmp_quat ) ;
fly - > zlock_momentum + = FLY_ZUP_CORRECT_ACCEL ;
} 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 ;
mul_m3_v3 ( 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 ;
mul_m3_v3 ( mat , upvec ) ;
axis_angle_to_quat ( tmp_quat , upvec , roll * time_redraw_clamped * fly - > xlock_momentum * 0.1f ) ; /* Rotate about the relative up vec */
mul_qt_qtqt ( 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 ;
mul_m3_v3 ( mat , dvec_tmp ) ;
mul_v3_fl ( dvec_tmp , fly - > speed * time_redraw * 0.25f ) ;
}
}
/* impose a directional lag */
interp_v3_v3v3 ( dvec , dvec_tmp , fly - > dvec_prev , ( 1.0f / ( 1.0f + ( time_redraw * 5.0f ) ) ) ) ;
if ( rv3d - > persp = = RV3D_CAMOB ) {
Object * lock_ob = fly - > root_parent ? fly - > root_parent : fly - > v3d - > camera ;
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 ) ;
/* todo, dynamic keys */
#if 0
if ( fly - > zlock & & fly - > xlock )
ED_area_headerprint ( fly - > ar , " FlyKeys Speed:(+/- | Wheel), Upright Axis:X on/Z on, Slow:Shift, Direction:WASDRF, Ok:LMB, Pan:MMB, Cancel:RMB " ) ;
else if ( fly - > zlock )
ED_area_headerprint ( fly - > ar , " FlyKeys Speed:(+/- | Wheel), Upright Axis:X off/Z on, Slow:Shift, Direction:WASDRF, Ok:LMB, Pan:MMB, Cancel:RMB " ) ;
else if ( fly - > xlock )
ED_area_headerprint ( fly - > ar , " FlyKeys Speed:(+/- | Wheel), Upright Axis:X on/Z off, Slow:Shift, Direction:WASDRF, Ok:LMB, Pan:MMB, Cancel:RMB " ) ;
else
ED_area_headerprint ( fly - > ar , " FlyKeys Speed:(+/- | Wheel), Upright Axis:X off/Z off, Slow:Shift, Direction:WASDRF, Ok:LMB, Pan:MMB, Cancel:RMB " ) ;
# endif
/* 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 = = RV3D_CAMOB ) {
ID * id_key ;
/* transform the parent or the camera? */
if ( fly - > root_parent ) {
Object * ob_update ;
2011-04-21 13:11:51 +00:00
2010-10-25 07:09:38 +00:00
float view_mat [ 4 ] [ 4 ] ;
float prev_view_imat [ 4 ] [ 4 ] ;
float diff_mat [ 4 ] [ 4 ] ;
float parent_mat [ 4 ] [ 4 ] ;
invert_m4_m4 ( prev_view_imat , prev_view_mat ) ;
2011-05-23 02:23:03 +00:00
ED_view3d_to_m4 ( view_mat , rv3d - > ofs , rv3d - > viewquat , rv3d - > dist ) ;
2010-10-25 07:09:38 +00:00
mul_m4_m4m4 ( diff_mat , prev_view_imat , view_mat ) ;
mul_m4_m4m4 ( parent_mat , fly - > root_parent - > obmat , diff_mat ) ;
2010-11-08 22:32:28 +00:00
object_apply_mat4 ( fly - > root_parent , parent_mat , TRUE , FALSE ) ;
2010-10-25 07:09:38 +00:00
// where_is_object(scene, fly->root_parent);
ob_update = v3d - > camera - > parent ;
while ( ob_update ) {
2010-12-05 18:59:23 +00:00
DAG_id_tag_update ( & ob_update - > id , OB_RECALC_OB ) ;
2010-10-25 07:09:38 +00:00
ob_update = ob_update - > parent ;
}
copy_m4_m4 ( prev_view_mat , view_mat ) ;
id_key = & fly - > root_parent - > id ;
}
else {
float view_mat [ 4 ] [ 4 ] ;
2011-05-23 02:23:03 +00:00
ED_view3d_to_m4 ( view_mat , rv3d - > ofs , rv3d - > viewquat , rv3d - > dist ) ;
2010-11-08 22:32:28 +00:00
object_apply_mat4 ( v3d - > camera , view_mat , TRUE , FALSE ) ;
2010-10-25 07:09:38 +00:00
id_key = & v3d - > camera - > id ;
}
/* record the motion */
if ( autokeyframe_cfra_can_key ( scene , id_key ) ) {
ListBase dsources = { NULL , NULL } ;
/* add datasource override for the camera object */
ANIM_relative_keyingset_add_source ( & dsources , id_key , NULL , NULL ) ;
/* 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 ( fly - > xlock | | fly - > zlock | | moffset [ 0 ] | | moffset [ 1 ] ) {
KeyingSet * ks = ANIM_builtin_keyingset_get_named ( NULL , " Rotation " ) ;
ANIM_apply_keyingset ( C , & dsources , NULL , ks , MODIFYKEY_MODE_INSERT , ( float ) CFRA ) ;
}
if ( fly - > speed ) {
KeyingSet * ks = ANIM_builtin_keyingset_get_named ( NULL , " Location " ) ;
ANIM_apply_keyingset ( C , & dsources , NULL , ks , MODIFYKEY_MODE_INSERT , ( float ) CFRA ) ;
}
/* free temp data */
BLI_freelistN ( & dsources ) ;
}
}
} 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 */
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 )
{
// shorthand for oft-used variables
wmNDOFMotionData * ndof = fly - > ndof ;
const float dt = ndof - > dt ;
RegionView3D * rv3d = fly - > rv3d ;
const int shouldRotate = 1 , shouldTranslate = 1 ;
float view_inv [ 4 ] ;
invert_qt_qt ( view_inv , rv3d - > viewquat ) ;
if ( shouldRotate )
{
const float turn_sensitivity = 1.f ;
float rotation [ 4 ] ;
float axis [ 3 ] ;
float angle = turn_sensitivity * ndof_to_angle_axis ( ndof , axis ) ;
// transform rotation axis from view to world coordinates
mul_qt_v3 ( view_inv , axis ) ;
// apply rotation to view
axis_angle_to_quat ( rotation , axis , angle ) ;
mul_qt_qtqt ( rv3d - > viewquat , rv3d - > viewquat , rotation ) ;
rv3d - > view = RV3D_VIEW_USER ;
fly - > redraw = 1 ;
}
if ( shouldTranslate )
{
const float forward_sensitivity = 1.f ;
const float vertical_sensitivity = 0.4f ;
const float lateral_sensitivity = 0.6f ;
float speed = 10.f ; // blender units per second
// ^^ this is ok for default cube scene, but should scale with.. something
float trans [ 3 ] = {
lateral_sensitivity * ndof - > tx ,
vertical_sensitivity * ndof - > ty ,
forward_sensitivity * ndof - > tz
} ;
mul_v3_fl ( trans , speed * dt ) ;
// transform motion from view to world coordinates
mul_qt_v3 ( view_inv , trans ) ;
// move center of view opposite of hand motion (this is camera mode, not object mode)
sub_v3_v3 ( rv3d - > ofs , trans ) ;
fly - > redraw = 1 ;
}
return OPERATOR_FINISHED ;
}
2010-10-25 07:09:38 +00:00
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 ;
2010-10-25 07:12:29 +00:00
short do_draw = FALSE ;
2010-11-24 16:54:18 +00:00
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
fly - > redraw = 0 ;
flyEvent ( fly , event ) ;
2011-07-14 21:20:45 +00:00
if ( fly - > ndof ) // 3D mouse overrules [2D mouse + timer]
{
if ( event - > type = = NDOF_MOTION )
flyApply_ndof ( C , fly ) ;
}
else if ( event - > type = = TIMER & & event - > customdata = = fly - > timer )
2010-10-25 07:09:38 +00:00
flyApply ( C , fly ) ;
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 ) ;
if ( exit_code ! = OPERATOR_RUNNING_MODAL )
2010-10-25 07:12:29 +00:00
do_draw = TRUE ;
2010-11-24 16:54:18 +00:00
2010-10-25 07:12:29 +00:00
if ( do_draw ) {
2010-11-24 16:54:18 +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
}
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 */
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 ;
}