BGE fix: 3DDview not redrawing when exiting BGE
[blender.git] / source / blender / editors / space_view3d / view3d_view.c
index ded9b44afd491517f9680ad3346a11548de8e00c..bbf728d31c00773b5c6d5eb594bd4124f08b70cd 100644 (file)
@@ -190,6 +190,7 @@ static void view_settings_from_ob(Object *ob, float *ofs, float *quat, float *di
 
 
 /* ****************** smooth view operator ****************** */
 
 
 /* ****************** smooth view operator ****************** */
+/* This operator is one of the 'timer refresh' ones like animation playback */
 
 struct SmoothViewStore {
        float orig_dist, new_dist;
 
 struct SmoothViewStore {
        float orig_dist, new_dist;
@@ -286,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;
                        
                        /* 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)
                        
                        /* keep track of running timer! */
                        if(rv3d->sms==NULL)
@@ -294,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 */
                        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;
                }
                        
                        return;
                }
@@ -348,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;
                
                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;
        }
        else {
                int i;
@@ -386,9 +390,12 @@ void VIEW3D_OT_smoothview(wmOperatorType *ot)
        ot->poll= ED_operator_view3d_active;
 }
 
        ot->poll= ED_operator_view3d_active;
 }
 
+/* ****************** change view operators ****************** */
+
 static void setcameratoview3d(View3D *v3d, RegionView3D *rv3d, Object *ob)
 {
        float dvec[3];
 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];
        
        dvec[0]= rv3d->dist*rv3d->viewinv[2][0];
        dvec[1]= rv3d->dist*rv3d->viewinv[2][1];
@@ -398,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];
 
        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;
        rv3d->viewquat[0]= -rv3d->viewquat[0];
        
        ob->recalc= OB_RECALC_OB;
@@ -445,6 +455,7 @@ void VIEW3D_OT_setcameratoview(wmOperatorType *ot)
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
 
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
 
+
 static int view3d_setobjectascamera_exec(bContext *C, wmOperator *op)
 {
        View3D *v3d = CTX_wm_view3d(C);
 static int view3d_setobjectascamera_exec(bContext *C, wmOperator *op)
 {
        View3D *v3d = CTX_wm_view3d(C);
@@ -479,8 +490,47 @@ void VIEW3D_OT_setobjectascamera(wmOperatorType *ot)
        /* flags */
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
        /* flags */
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
+
 /* ********************************** */
 
 /* ********************************** */
 
+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])
 {
 /* 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])
 {
@@ -496,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]);
                
                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);
                normalize_v3(vec);
                
                VECADDFAC(ray_start, rv3d->viewinv[3], vec, v3d->near);
@@ -680,7 +730,7 @@ void project_short(ARegion *ar, float *vec, short *adr)     /* clips */
        adr[0]= IS_CLIPPED;
        
        if(rv3d->rflag & RV3D_CLIPPING) {
        adr[0]= IS_CLIPPED;
        
        if(rv3d->rflag & RV3D_CLIPPING) {
-               if(view3d_test_clipping(rv3d, vec))
+               if(view3d_test_clipping(rv3d, vec, 0))
                        return;
        }
        
                        return;
        }
        
@@ -1258,6 +1308,74 @@ static unsigned int free_localbit(void)
        return 0;
 }
 
        return 0;
 }
 
+static void copy_view3d_lock_space(View3D *v3d, Scene *scene)
+{
+       int bit;
+       
+       if(v3d->scenelock && v3d->localvd==NULL) {
+               v3d->lay= scene->lay;
+               v3d->camera= scene->camera;
+               
+               if(v3d->camera==NULL) {
+                       ARegion *ar;
+                       
+                       for(ar=v3d->regionbase.first; ar; ar= ar->next) {
+                               if(ar->regiontype == RGN_TYPE_WINDOW) {
+                                       RegionView3D *rv3d= ar->regiondata;
+                                       if(rv3d->persp==RV3D_CAMOB)
+                                               rv3d->persp= RV3D_PERSP;
+                               }
+                       }
+               }
+               
+               if((v3d->lay & v3d->layact) == 0) {
+                       for(bit= 0; bit<32; bit++) {
+                               if(v3d->lay & (1<<bit)) {
+                                       v3d->layact= 1<<bit;
+                                       break;
+                               }
+                       }
+               }
+       }
+}
+
+void ED_view3d_scene_layers_update(Main *bmain, Scene *scene)
+{
+       bScreen *sc;
+       ScrArea *sa;
+       SpaceLink *sl;
+       
+       /* from scene copy to the other views */
+       for(sc=bmain->screen.first; sc; sc=sc->id.next) {
+               if(sc->scene!=scene)
+                       continue;
+               
+               for(sa=sc->areabase.first; sa; sa=sa->next)
+                       for(sl=sa->spacedata.first; sl; sl=sl->next)
+                               if(sl->spacetype==SPACE_VIEW3D)
+                                       copy_view3d_lock_space((View3D*)sl, scene);
+       }
+}
+
+int ED_view3d_scene_layer_set(int lay, const int *values)
+{
+       int i, tot= 0;
+       
+       /* ensure we always have some layer selected */
+       for(i=0; i<20; i++)
+               if(values[i])
+                       tot++;
+       
+       if(tot==0)
+               return lay;
+       
+       for(i=0; i<20; i++) {
+               if(values[i]) lay |= (1<<i);
+               else lay &= ~(1<<i);
+       }
+       
+       return lay;
+}
 
 static void initlocalview(Scene *scene, ScrArea *sa)
 {
 
 static void initlocalview(Scene *scene, ScrArea *sa)
 {
@@ -1595,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);
        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;
 
        RegionView3D *rv3d;
        rcti cam_frame;
 
@@ -1628,11 +1747,15 @@ static int game_engine_exec(bContext *C, wmOperator *unused)
 
 
        SaveState(C);
 
 
        SaveState(C);
+
        StartKetsjiShell(C, ar, &cam_frame, 1);
        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_region_set(C, prevar);
+       CTX_wm_window_set(C, prevwin);
        CTX_wm_area_set(C, prevsa);
        CTX_wm_area_set(C, prevsa);
+       RestoreState(C);
 
        //XXX restore_all_scene_cfra(scene_cfra_store);
        set_scene_bg(startscene);
 
        //XXX restore_all_scene_cfra(scene_cfra_store);
        set_scene_bg(startscene);
@@ -1795,7 +1918,7 @@ typedef struct FlyInfo {
 #define FLY_CANCEL             1
 #define FLY_CONFIRM            2
 
 #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];
 {
        float upvec[3]; // tmp
        float mat[3][3];
@@ -1847,7 +1970,7 @@ int initFlyInfo (bContext *C, FlyInfo *fly, wmOperator *op, wmEvent *event)
 
        fly->time_lastdraw= fly->time_lastwheel= PIL_check_seconds_timer();
 
 
        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;
 
        /* detect weather to start with Z locking */
        upvec[0]=1.0f; upvec[1]=0.0f; upvec[2]=0.0f;
@@ -1869,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;
                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)
 
                /* used for recording */
 //XXX2.5               if(v3d->camera->ipoflag & OB_ACTION_OB)
@@ -1909,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 */
        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);
                        VECCOPY(v3d->camera->loc, fly->ofs_backup);
                        VECCOPY(v3d->camera->rot, fly->rot_backup);
                        DAG_id_flush_update(&v3d->camera->id, OB_RECALC_OB);
@@ -1923,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);
        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
 
                DAG_id_flush_update(&v3d->camera->id, OB_RECALC_OB);
 #if 0 //XXX2.5
@@ -1947,7 +2069,7 @@ static int flyEnd(bContext *C, FlyInfo *fly)
                /*Done with correcting for the dist */
        }
 
                /*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 */
 
 
 //XXX2.5       BIF_view3d_previewrender_signal(fly->sa, PR_DBASE|PR_DISPRECT); /* not working at the moment not sure why */
 
 
@@ -1960,9 +2082,9 @@ static int flyEnd(bContext *C, FlyInfo *fly)
        return OPERATOR_CANCELLED;
 }
 
        return OPERATOR_CANCELLED;
 }
 
-void flyEvent(FlyInfo *fly, wmEvent *event)
+static void flyEvent(FlyInfo *fly, wmEvent *event)
 {
 {
-       if (event->type == TIMER) {
+       if (event->type == TIMER && event->customdata == fly->timer) {
                fly->redraw = 1;
        }
        else if (event->type == MOUSEMOVE) {
                fly->redraw = 1;
        }
        else if (event->type == MOUSEMOVE) {
@@ -2083,7 +2205,7 @@ void flyEvent(FlyInfo *fly, wmEvent *event)
 }
 
 //int fly_exec(bContext *C, wmOperator *op)
 }
 
 //int fly_exec(bContext *C, wmOperator *op)
-int flyApply(FlyInfo *fly)
+static int flyApply(FlyInfo *fly)
 {
        /*
        fly mode - Shift+F
 {
        /*
        fly mode - Shift+F
@@ -2421,7 +2543,7 @@ static int fly_modal(bContext *C, wmOperator *op, wmEvent *event)
 
        flyEvent(fly, event);
 
 
        flyEvent(fly, event);
 
-       if(event->type==TIMER)
+       if(event->type==TIMER && event->customdata == fly->timer)
                flyApply(fly);
 
        if(fly->redraw) {;
                flyApply(fly);
 
        if(fly->redraw) {;