BGE fix: 3DDview not redrawing when exiting BGE
[blender.git] / source / blender / editors / space_view3d / view3d_view.c
index 2b42b64c0a30759a876e5f2f8dc320a4241e7d87..bbf728d31c00773b5c6d5eb594bd4124f08b70cd 100644 (file)
@@ -287,6 +287,8 @@ void smooth_view(bContext *C, Object *oldcamera, Object *camera, float *ofs, flo
                        
                        /* ensure it shows correct */
                        if(sms.to_camera) rv3d->persp= RV3D_PERSP;
+
+                       rv3d->rflag |= RV3D_NAVIGATING;
                        
                        /* keep track of running timer! */
                        if(rv3d->sms==NULL)
@@ -295,7 +297,7 @@ void smooth_view(bContext *C, Object *oldcamera, Object *camera, float *ofs, flo
                        if(rv3d->smooth_timer)
                                WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), rv3d->smooth_timer);
                        /* TIMER1 is hardcoded in keymap */
-                       rv3d->smooth_timer= WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER1, 1.0/30.0);  /* max 30 frs/sec */
+                       rv3d->smooth_timer= WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER1, 1.0/100.0); /* max 30 frs/sec */
                        
                        return;
                }
@@ -349,6 +351,7 @@ static int view3d_smoothview_invoke(bContext *C, wmOperator *op, wmEvent *event)
                
                WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), rv3d->smooth_timer);
                rv3d->smooth_timer= NULL;
+               rv3d->rflag &= ~RV3D_NAVIGATING;
        }
        else {
                int i;
@@ -392,6 +395,7 @@ void VIEW3D_OT_smoothview(wmOperatorType *ot)
 static void setcameratoview3d(View3D *v3d, RegionView3D *rv3d, Object *ob)
 {
        float dvec[3];
+       float mat3[3][3];
        
        dvec[0]= rv3d->dist*rv3d->viewinv[2][0];
        dvec[1]= rv3d->dist*rv3d->viewinv[2][1];
@@ -401,7 +405,10 @@ static void setcameratoview3d(View3D *v3d, RegionView3D *rv3d, Object *ob)
        sub_v3_v3v3(ob->loc, ob->loc, rv3d->ofs);
        rv3d->viewquat[0]= -rv3d->viewquat[0];
 
-       quat_to_eul( ob->rot,rv3d->viewquat);
+       // quat_to_eul( ob->rot,rv3d->viewquat); // in 2.4x for xyz eulers only
+       quat_to_mat3(mat3, rv3d->viewquat);
+       object_mat3_to_rot(ob, mat3, 0);
+
        rv3d->viewquat[0]= -rv3d->viewquat[0];
        
        ob->recalc= OB_RECALC_OB;
@@ -486,6 +493,44 @@ void VIEW3D_OT_setobjectascamera(wmOperatorType *ot)
 
 /* ********************************** */
 
+void view3d_calculate_clipping(BoundBox *bb, float planes[4][4], bglMats *mats, rcti *rect)
+{
+       double xs, ys, p[3];
+       short val;
+
+       /* near zero floating point values can give issues with gluUnProject
+               in side view on some implementations */
+       if(fabs(mats->modelview[0]) < 1e-6) mats->modelview[0]= 0.0;
+       if(fabs(mats->modelview[5]) < 1e-6) mats->modelview[5]= 0.0;
+
+       /* Set up viewport so that gluUnProject will give correct values */
+       mats->viewport[0] = 0;
+       mats->viewport[1] = 0;
+
+       /* four clipping planes and bounding volume */
+       /* first do the bounding volume */
+       for(val=0; val<4; val++) {
+               xs= (val==0||val==3)?rect->xmin:rect->xmax;
+               ys= (val==0||val==1)?rect->ymin:rect->ymax;
+
+               gluUnProject(xs, ys, 0.0, mats->modelview, mats->projection, mats->viewport, &p[0], &p[1], &p[2]);
+               VECCOPY(bb->vec[val], p);
+
+               gluUnProject(xs, ys, 1.0, mats->modelview, mats->projection, mats->viewport, &p[0], &p[1], &p[2]);
+               VECCOPY(bb->vec[4+val], p);
+       }
+
+       /* then plane equations */
+       for(val=0; val<4; val++) {
+
+               normal_tri_v3(planes[val], bb->vec[val], bb->vec[val==3?0:val+1], bb->vec[val+4]);
+
+               planes[val][3]= - planes[val][0]*bb->vec[val][0]
+                       - planes[val][1]*bb->vec[val][1]
+                       - planes[val][2]*bb->vec[val][2];
+       }
+}
+
 /* create intersection coordinates in view Z direction at mouse coordinates */
 void viewline(ARegion *ar, View3D *v3d, float mval[2], float ray_start[3], float ray_end[3])
 {
@@ -501,8 +546,8 @@ void viewline(ARegion *ar, View3D *v3d, float mval[2], float ray_start[3], float
                mul_m4_v4(rv3d->persinv, vec);
                mul_v3_fl(vec, 1.0f / vec[3]);
                
-               VECCOPY(ray_start, rv3d->viewinv[3]);
-               VECSUB(vec, vec, ray_start);
+               copy_v3_v3(ray_start, rv3d->viewinv[3]);
+               sub_v3_v3v3(vec, vec, ray_start);
                normalize_v3(vec);
                
                VECADDFAC(ray_start, rv3d->viewinv[3], vec, v3d->near);
@@ -1668,6 +1713,7 @@ static int game_engine_exec(bContext *C, wmOperator *unused)
        Scene *startscene = CTX_data_scene(C);
        ScrArea *sa, *prevsa= CTX_wm_area(C);
        ARegion *ar, *prevar= CTX_wm_region(C);
+       wmWindow *prevwin= CTX_wm_window(C);
        RegionView3D *rv3d;
        rcti cam_frame;
 
@@ -1701,11 +1747,15 @@ static int game_engine_exec(bContext *C, wmOperator *unused)
 
 
        SaveState(C);
+
        StartKetsjiShell(C, ar, &cam_frame, 1);
-       RestoreState(C);
        
+       /* restore context, in case it changed in the meantime, for
+          example by working in another window or closing it */
        CTX_wm_region_set(C, prevar);
+       CTX_wm_window_set(C, prevwin);
        CTX_wm_area_set(C, prevsa);
+       RestoreState(C);
 
        //XXX restore_all_scene_cfra(scene_cfra_store);
        set_scene_bg(startscene);
@@ -1868,7 +1918,7 @@ typedef struct FlyInfo {
 #define FLY_CANCEL             1
 #define FLY_CONFIRM            2
 
-int initFlyInfo (bContext *C, FlyInfo *fly, wmOperator *op, wmEvent *event)
+static int initFlyInfo (bContext *C, FlyInfo *fly, wmOperator *op, wmEvent *event)
 {
        float upvec[3]; // tmp
        float mat[3][3];
@@ -1920,7 +1970,7 @@ int initFlyInfo (bContext *C, FlyInfo *fly, wmOperator *op, wmEvent *event)
 
        fly->time_lastdraw= fly->time_lastwheel= PIL_check_seconds_timer();
 
-       fly->rv3d->rflag |= RV3D_FLYMODE; /* so we draw the corner margins */
+       fly->rv3d->rflag |= RV3D_FLYMODE|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;
@@ -1942,7 +1992,6 @@ int initFlyInfo (bContext *C, FlyInfo *fly, wmOperator *op, wmEvent *event)
                mul_v3_fl(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)
@@ -1982,7 +2031,7 @@ static int flyEnd(bContext *C, FlyInfo *fly)
        if (fly->state == FLY_CANCEL) {
        /* Revert to original view? */
                if (fly->persp_backup==RV3D_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);
@@ -1996,7 +2045,7 @@ static int flyEnd(bContext *C, FlyInfo *fly)
        else if (fly->persp_backup==RV3D_CAMOB) {       /* camera */
                float mat3[3][3];
                copy_m3_m4(mat3, v3d->camera->obmat);
-               mat3_to_compatible_eul( v3d->camera->rot, fly->rot_backup,mat3);
+               object_mat3_to_rot(v3d->camera, mat3, TRUE);
 
                DAG_id_flush_update(&v3d->camera->id, OB_RECALC_OB);
 #if 0 //XXX2.5
@@ -2020,7 +2069,7 @@ static int flyEnd(bContext *C, FlyInfo *fly)
                /*Done with correcting for the dist */
        }
 
-       rv3d->rflag &= ~RV3D_FLYMODE;
+       rv3d->rflag &= ~(RV3D_FLYMODE|RV3D_NAVIGATING);
 //XXX2.5       BIF_view3d_previewrender_signal(fly->sa, PR_DBASE|PR_DISPRECT); /* not working at the moment not sure why */
 
 
@@ -2033,7 +2082,7 @@ static int flyEnd(bContext *C, FlyInfo *fly)
        return OPERATOR_CANCELLED;
 }
 
-void flyEvent(FlyInfo *fly, wmEvent *event)
+static void flyEvent(FlyInfo *fly, wmEvent *event)
 {
        if (event->type == TIMER && event->customdata == fly->timer) {
                fly->redraw = 1;
@@ -2156,7 +2205,7 @@ void flyEvent(FlyInfo *fly, wmEvent *event)
 }
 
 //int fly_exec(bContext *C, wmOperator *op)
-int flyApply(FlyInfo *fly)
+static int flyApply(FlyInfo *fly)
 {
        /*
        fly mode - Shift+F