Camera: more code refactoring, adding a function to create CameraParams from
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Fri, 18 Nov 2011 21:19:03 +0000 (21:19 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Fri, 18 Nov 2011 21:19:03 +0000 (21:19 +0000)
3d view, deduplicating the complex code for setting up the viewplane.

source/blender/blenkernel/BKE_camera.h
source/blender/blenkernel/intern/camera.c
source/blender/editors/include/ED_view3d.h
source/blender/editors/render/render_opengl.c
source/blender/editors/sculpt_paint/paint_image.c
source/blender/editors/space_view3d/view3d_view.c
source/blender/makesrna/intern/rna_camera.c

index 4a0f38d926cc4ebc06985eaf609634d6c02a45bc..8aec576b96333f069fb0e6e626fa73573d3b26dd 100644 (file)
@@ -40,21 +40,27 @@ extern "C" {
 
 struct Camera;
 struct Object;
+struct RegionView3D;
 struct RenderData;
 struct Scene;
 struct rctf;
 struct View3D;
 
+/* Camera Datablock */
+
 void *add_camera(const char *name);
 struct Camera *copy_camera(struct Camera *cam);
 void make_local_camera(struct Camera *cam);
 void free_camera(struct Camera *ca);
 
-/* Camera Object */
+/* Camera Usage */
 
 float object_camera_dof_distance(struct Object *ob);
 void object_camera_mode(struct RenderData *rd, struct Object *ob);
 
+int camera_sensor_fit(int sensor_fit, float sizex, float sizey);
+float camera_sensor_size(int sensor_fit, float sensor_x, float sensor_y);
+
 /* Camera Parameters:
  *
  * Intermediate struct for storing camera parameters from various sources,
@@ -65,9 +71,12 @@ typedef struct CameraParams {
        int is_ortho;
        float lens;
        float ortho_scale;
+       float zoom;
 
        float shiftx;
        float shifty;
+       float offsetx;
+       float offsety;
 
        /* sensor */
        float sensor_x;
@@ -95,6 +104,7 @@ typedef struct CameraParams {
 
 void camera_params_init(CameraParams *params);
 void camera_params_from_object(CameraParams *params, struct Object *camera);
+void camera_params_from_view3d(CameraParams *params, struct View3D *v3d, struct RegionView3D *rv3d);
 void camera_params_compute(CameraParams *params, int winx, int winy, float aspx, float aspy);
 
 /* Camera View Frame */
index 858351ebbf31509eb0565496ddb23cbda4e861c8..29770e37ea19da2a76cf363389776bd0938dadf8 100644 (file)
@@ -35,6 +35,7 @@
 #include "DNA_lamp_types.h"
 #include "DNA_object_types.h"
 #include "DNA_scene_types.h"
+#include "DNA_view3d_types.h"
 
 #include "BLI_math.h"
 #include "BLI_utildefines.h"
@@ -45,6 +46,7 @@
 #include "BKE_global.h"
 #include "BKE_library.h"
 #include "BKE_main.h"
+#include "BKE_screen.h"
 
 /****************************** Camera Datablock *****************************/
 
@@ -161,9 +163,16 @@ float object_camera_dof_distance(Object *ob)
        return cam->YF_dofdist;
 }
 
-/******************************** Camera Params *******************************/
+float camera_sensor_size(int sensor_fit, float sensor_x, float sensor_y)
+{
+       /* sensor size used to fit to. for auto, sensor_x is both x and y. */
+       if(sensor_fit == CAMERA_SENSOR_FIT_VERT)
+               return sensor_y;
 
-static int camera_sensor_fit(int sensor_fit, float sizex, float sizey)
+       return sensor_x;
+}
+
+int camera_sensor_fit(int sensor_fit, float sizex, float sizey)
 {
        if(sensor_fit == CAMERA_SENSOR_FIT_AUTO) {
                if(sizex >= sizey)
@@ -175,6 +184,8 @@ static int camera_sensor_fit(int sensor_fit, float sizex, float sizey)
        return sensor_fit;
 }
 
+/******************************** Camera Params *******************************/
+
 void camera_params_init(CameraParams *params)
 {
        memset(params, 0, sizeof(CameraParams));
@@ -183,6 +194,8 @@ void camera_params_init(CameraParams *params)
        params->sensor_x= DEFAULT_SENSOR_WIDTH;
        params->sensor_y= DEFAULT_SENSOR_HEIGHT;
        params->sensor_fit= CAMERA_SENSOR_FIT_AUTO;
+
+       params->zoom= 1.0f;
 }
 
 void camera_params_from_object(CameraParams *params, Object *ob)
@@ -224,10 +237,42 @@ void camera_params_from_object(CameraParams *params, Object *ob)
        }
 }
 
+void camera_params_from_view3d(CameraParams *params, View3D *v3d, RegionView3D *rv3d)
+{
+       /* perspective view */
+       params->lens= v3d->lens;
+       params->clipsta= v3d->near;
+       params->clipend= v3d->far;
+
+       if(rv3d->persp==RV3D_CAMOB) {
+               /* camera view */
+               camera_params_from_object(params, v3d->camera);
+
+               params->zoom= BKE_screen_view3d_zoom_to_fac((float)rv3d->camzoom) * 2.0f;
+               params->zoom= 1.0f/params->zoom;
+
+               params->offsetx= rv3d->camdx;
+               params->offsety= rv3d->camdy;
+
+               params->shiftx *= 0.5f;
+               params->shifty *= 0.5f;
+       }
+       else if(rv3d->persp==RV3D_ORTHO) {
+               /* orthographic view */
+               params->clipend *= 0.5f;        // otherwise too extreme low zbuffer quality
+               params->clipsta= - params->clipend;
+
+               params->is_ortho= 1;
+               params->ortho_scale = rv3d->dist;
+       }
+
+       params->zoom *= 2.0f;
+}
+
 void camera_params_compute(CameraParams *params, int winx, int winy, float xasp, float yasp)
 {
        rctf viewplane;
-       float pixsize, winside, viewfac;
+       float pixsize, viewfac, sensor_size, dx, dy;
        int sensor_fit;
 
        /* fields rendering */
@@ -235,48 +280,47 @@ void camera_params_compute(CameraParams *params, int winx, int winy, float xasp,
        if(params->use_fields)
                params->ycor *= 2.0f;
 
-       /* determine sensor fit */
-       sensor_fit = camera_sensor_fit(params->sensor_fit, xasp*winx, yasp*winy);
-
        if(params->is_ortho) {
-               /* orthographic camera, scale == 1.0 means exact 1 to 1 mapping */
-               if(sensor_fit==CAMERA_SENSOR_FIT_HOR)
-                       viewfac= winx;
-               else
-                       viewfac= params->ycor * winy;
-
-               pixsize= params->ortho_scale/viewfac;
+               /* orthographic camera */
+               /* scale == 1.0 means exact 1 to 1 mapping */
+               pixsize= params->ortho_scale;
        }
        else {
                /* perspective camera */
-               float sensor_size;
+               sensor_size= camera_sensor_size(params->sensor_fit, params->sensor_x, params->sensor_y);
+               pixsize= (sensor_size * params->clipsta)/params->lens;
+       }
 
-               /* note for auto fit sensor_x is both width and height */
-               if(params->sensor_fit == CAMERA_SENSOR_FIT_VERT)
-                       sensor_size= params->sensor_y;
-               else
-                       sensor_size= params->sensor_x;
-               
-               if(sensor_fit == CAMERA_SENSOR_FIT_HOR)
-                       viewfac= (params->lens * winx) / sensor_size;
-               else
-                       viewfac= params->ycor * (params->lens * winy) / sensor_size;
+       /* determine sensor fit */
+       sensor_fit = camera_sensor_fit(params->sensor_fit, xasp*winx, yasp*winy);
 
-               pixsize= params->clipsta/viewfac;
-       }
+       if(sensor_fit==CAMERA_SENSOR_FIT_HOR)
+               viewfac= winx;
+       else
+               viewfac= params->ycor * winy;
+
+       pixsize /= viewfac;
+
+       /* extra zoom factor */
+       pixsize *= params->zoom;
 
        /* compute view plane:
         * fully centered, zbuffer fills in jittered between -.5 and +.5 */
-       if(sensor_fit == CAMERA_SENSOR_FIT_HOR)
-               winside= winx;
-       else
-               winside= winy;
+       viewplane.xmin= -0.5f*(float)winx;
+       viewplane.ymin= -0.5f*params->ycor*(float)winy;
+       viewplane.xmax=  0.5f*(float)winx;
+       viewplane.ymax=  0.5f*params->ycor*(float)winy;
 
-       viewplane.xmin= -0.5f*(float)winx + params->shiftx*winside;
-       viewplane.ymin= -0.5f*params->ycor*(float)winy + params->shifty*winside;
-       viewplane.xmax=  0.5f*(float)winx + params->shiftx*winside;
-       viewplane.ymax=  0.5f*params->ycor*(float)winy + params->shifty*winside;
+       /* lens shift and offset */
+       dx= params->shiftx*viewfac + winx*params->offsetx;
+       dy= params->shifty*viewfac + winy*params->offsety;
 
+       viewplane.xmin += dx;
+       viewplane.ymin += dy;
+       viewplane.xmax += dx;
+       viewplane.ymax += dy;
+
+       /* fields offset */
        if(params->field_second) {
                if(params->field_odd) {
                        viewplane.ymin-= 0.5f * params->ycor;
@@ -297,15 +341,15 @@ void camera_params_compute(CameraParams *params, int winx, int winy, float xasp,
 
        params->viewdx= pixsize;
        params->viewdy= params->ycor * pixsize;
+       params->viewplane= viewplane;
 
+       /* compute projection matrix */
        if(params->is_ortho)
                orthographic_m4(params->winmat, viewplane.xmin, viewplane.xmax,
                        viewplane.ymin, viewplane.ymax, params->clipsta, params->clipend);
        else
                perspective_m4(params->winmat, viewplane.xmin, viewplane.xmax,
                        viewplane.ymin, viewplane.ymax, params->clipsta, params->clipend);
-       
-       params->viewplane= viewplane;
 }
 
 /***************************** Camera View Frame *****************************/
index 6536741af003cc22934a403e92e26b13dc483c1b..e2405425891df07b006588818b9bce1fbbcde114 100644 (file)
@@ -208,7 +208,7 @@ void project_float_noclip(struct ARegion *ar, const float vec[3], float adr[2]);
 
 void ED_view3d_ob_clip_range_get(struct Object *ob, float *lens, float *clipsta, float *clipend);
 int ED_view3d_clip_range_get(struct View3D *v3d, struct RegionView3D *rv3d, float *clipsta, float *clipend);
-int ED_view3d_viewplane_get(struct View3D *v3d, struct RegionView3D *rv3d, int winxi, int winyi, struct rctf *viewplane, float *clipsta, float *clipend, float *pixsize);
+int ED_view3d_viewplane_get(struct View3D *v3d, struct RegionView3D *rv3d, int winxi, int winyi, struct rctf *viewplane, float *clipsta, float *clipend);
 void ED_view3d_ob_project_mat_get(struct RegionView3D *v3d, struct Object *ob, float pmat[4][4]);
 void ED_view3d_project_float(struct ARegion *a, const float vec[3], float adr[2], float mat[4][4]);
 void ED_view3d_calc_camera_border(struct Scene *scene, struct ARegion *ar, struct View3D *v3d, struct RegionView3D *rv3d, struct rctf *viewborder_r, short do_shift);
index fa764e6eefc2af4492959fe4010302a1047588e9..843918e9173d0e0fb9b585d3e1c93ba158552c2d 100644 (file)
@@ -147,7 +147,7 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
                        rctf viewplane;
                        float clipsta, clipend;
 
-                       int is_ortho= ED_view3d_viewplane_get(v3d, rv3d, sizex, sizey, &viewplane, &clipsta, &clipend, NULL);
+                       int is_ortho= ED_view3d_viewplane_get(v3d, rv3d, sizex, sizey, &viewplane, &clipsta, &clipend);
                        if(is_ortho) orthographic_m4(winmat, viewplane.xmin, viewplane.xmax, viewplane.ymin, viewplane.ymax, -clipend, clipend);
                        else  perspective_m4(winmat, viewplane.xmin, viewplane.xmax, viewplane.ymin, viewplane.ymax, clipsta, clipend);
                }
index 97a0c92d1977373cff846b8027f6db93efbd036e..a856f959b499bbad403d5f0c81409f932a688005 100644 (file)
@@ -3068,7 +3068,7 @@ static void project_paint_begin(ProjPaintState *ps)
                                /* window matrix, clipping and ortho */
                                camera_params_init(&params);
                                camera_params_from_object(&params, cam_ob);
-                               camera_params_compute(&params, ps->winx, ps->winy, 1.0f, 1.0f); /* XXX aspect? */
+                               camera_params_compute(&params, ps->winx, ps->winy, 1.0f, 1.0f);
 
                                copy_m4_m4(winmat, params.winmat);
                                ps->clipsta= params.clipsta;
index d2d6d6b095940d7efca9c86c31c202757f41db86..cf838cb94ce1758e9a2534238e2a97bb892bf196 100644 (file)
@@ -1018,169 +1018,19 @@ int ED_view3d_clip_range_get(View3D *v3d, RegionView3D *rv3d, float *clipsta, fl
 }
 
 /* also exposed in previewrender.c */
-int ED_view3d_viewplane_get(View3D *v3d, RegionView3D *rv3d, int winxi, int winyi, rctf *viewplane, float *clipsta, float *clipend, float *pixsize)
+int ED_view3d_viewplane_get(View3D *v3d, RegionView3D *rv3d, int winx, int winy, rctf *viewplane, float *clipsta, float *clipend)
 {
-       Camera *cam=NULL;
-       float lens, sensor_x =DEFAULT_SENSOR_WIDTH, sensor_y= DEFAULT_SENSOR_HEIGHT, fac, x1, y1, x2, y2;
-       float winx= (float)winxi, winy= (float)winyi;
-       int orth= 0;
-       short sensor_fit= CAMERA_SENSOR_FIT_AUTO;
-
-       /* currnetly using sensor size (depends on fov calculating method) */
-       float sensor= DEFAULT_SENSOR_WIDTH;
-
-       lens= v3d->lens;        
-       
-       *clipsta= v3d->near;
-       *clipend= v3d->far;
-       
-       if(rv3d->persp==RV3D_CAMOB) {
-               if(v3d->camera) {
-                       if(v3d->camera->type==OB_LAMP ) {
-                               Lamp *la;
-                               
-                               la= v3d->camera->data;
-                               fac= cosf(((float)M_PI)*la->spotsize/360.0f);
-                               
-                               x1= saacos(fac);
-                               lens= 16.0f*fac/sinf(x1);
-                               
-                               *clipsta= la->clipsta;
-                               *clipend= la->clipend;
-                       }
-                       else if(v3d->camera->type==OB_CAMERA) {
-                               cam= v3d->camera->data;
-                               lens= cam->lens;
-                               sensor_x= cam->sensor_x;
-                               sensor_y= cam->sensor_y;
-                               *clipsta= cam->clipsta;
-                               *clipend= cam->clipend;
-                               sensor_fit= cam->sensor_fit;
-
-                               sensor= (cam->sensor_fit==CAMERA_SENSOR_FIT_VERT) ? (cam->sensor_y) : (cam->sensor_x);
-                       }
-               }
-       }
-       
-       if(rv3d->persp==RV3D_ORTHO) {
-               if(winx>winy) x1= -rv3d->dist;
-               else x1= -winx*rv3d->dist/winy;
-               x2= -x1;
-               
-               if(winx>winy) y1= -winy*rv3d->dist/winx;
-               else y1= -rv3d->dist;
-               y2= -y1;
-               
-               *clipend *= 0.5f;       // otherwise too extreme low zbuffer quality
-               *clipsta= - *clipend;
-               orth= 1;
-       }
-       else {
-               /* fac for zoom, also used for camdx */
-               if(rv3d->persp==RV3D_CAMOB) {
-                       fac= BKE_screen_view3d_zoom_to_fac((float)rv3d->camzoom) * 4.0f;
-               }
-               else {
-                       fac= 2.0;
-               }
-               
-               /* viewplane size depends... */
-               if(cam && cam->type==CAM_ORTHO) {
-                       /* ortho_scale == 1 means exact 1 to 1 mapping */
-                       float dfac= 2.0f*cam->ortho_scale/fac;
-
-                       if(sensor_fit==CAMERA_SENSOR_FIT_AUTO) {
-                               if(winx>winy) {
-                                       x1= -dfac;
-                                       y1= -winy*dfac/winx;
-                               }
-                               else {
-                                       x1= -winx*dfac/winy;
-                                       y1= -dfac;
-                               }
-                       }
-                       else if(sensor_fit==CAMERA_SENSOR_FIT_HOR) {
-                               x1= -dfac;
-                               y1= -winy*dfac/winx;
-                       }
-                       else {
-                               x1= -winx*dfac/winy;
-                               y1= -dfac;
-                       }
-
-                       x2= -x1;
-                       y2= -y1;
-
-                       orth= 1;
-               }
-               else {
-                       float dfac;
-                       
-                       if(sensor_fit==CAMERA_SENSOR_FIT_AUTO) {
-                               if(winx>winy) dfac= (sensor_x * 2.0f) / (fac*winx*lens);
-                               else dfac= (sensor_x * 2.0f) / (fac*winy*lens);
-                       }
-                       else if(sensor_fit==CAMERA_SENSOR_FIT_HOR) {
-                               dfac= (sensor_x * 2.0f) / (fac*winx*lens);
-                       }
-                       else {
-                               dfac= (sensor_y * 2.0f) / (fac*winy*lens);
-                       }
-                       
-                       x1= - *clipsta * winx*dfac;
-                       x2= -x1;
-                       y1= - *clipsta * winy*dfac;
-                       y2= -y1;
-                       orth= 0;
-               }
-               /* cam view offset */
-               if(cam) {
-                       float dx= 0.5f*fac*rv3d->camdx*(x2-x1);
-                       float dy= 0.5f*fac*rv3d->camdy*(y2-y1);
-
-                       /* shift offset */              
-                       if(cam->type==CAM_ORTHO) {
-                               dx += cam->shiftx * cam->ortho_scale;
-                               dy += cam->shifty * cam->ortho_scale;
-                       }
-                       else {
-                               dx += cam->shiftx * (cam->clipsta / cam->lens) * sensor;
-                               dy += cam->shifty * (cam->clipsta / cam->lens) * sensor;
-                       }
+       CameraParams params;
 
-                       x1+= dx;
-                       x2+= dx;
-                       y1+= dy;
-                       y2+= dy;
-               }
-       }
-       
-       if(pixsize) {
-               float viewfac;
-               
-               if(orth) {
-                       viewfac= (winx >= winy)? winx: winy;
-                       *pixsize= 1.0f/viewfac;
-               }
-               else {
-                       float size= ((winx >= winy)? winx: winy);
-
-                       if(sensor_fit==CAMERA_SENSOR_FIT_HOR)
-                               size= winx;
-                       else if(sensor_fit==CAMERA_SENSOR_FIT_VERT)
-                               size= winy;
+       camera_params_init(&params);
+       camera_params_from_view3d(&params, v3d, rv3d);
+       camera_params_compute(&params, winx, winy, 1.0f, 1.0f);
 
-                       viewfac= (size*lens)/sensor;
-                       *pixsize= *clipsta/viewfac;
-               }
-       }
+       *viewplane= params.viewplane;
+       *clipsta= params.clipsta;
+       *clipend= params.clipend;
        
-       viewplane->xmin= x1;
-       viewplane->ymin= y1;
-       viewplane->xmax= x2;
-       viewplane->ymax= y2;
-       
-       return orth;
+       return params.is_ortho;
 }
 
 void setwinmatrixview3d(ARegion *ar, View3D *v3d, rctf *rect)          /* rect: for picking */
@@ -1190,7 +1040,7 @@ void setwinmatrixview3d(ARegion *ar, View3D *v3d, rctf *rect)             /* rect: for pick
        float clipsta, clipend, x1, y1, x2, y2;
        int orth;
        
-       orth= ED_view3d_viewplane_get(v3d, rv3d, ar->winx, ar->winy, &viewplane, &clipsta, &clipend, NULL);
+       orth= ED_view3d_viewplane_get(v3d, rv3d, ar->winx, ar->winy, &viewplane, &clipsta, &clipend);
        rv3d->is_persp= !orth;
 
        //      printf("%d %d %f %f %f %f %f %f\n", winx, winy, viewplane.xmin, viewplane.ymin, viewplane.xmax, viewplane.ymax, clipsta, clipend);
index 1e7a969caaa3a07b02130baef013ed4c5b7f0b5b..77b41b507c6073fd6774d93649987160305567b0 100644 (file)
 
 #ifdef RNA_RUNTIME
 
+#include "BKE_camera.h"
 #include "BKE_object.h"
 #include "BKE_depsgraph.h"
 
-/* only for rad/deg conversion! can remove later */
-static float get_camera_sensor(Camera *cam)
-{
-       if(cam->sensor_fit==CAMERA_SENSOR_FIT_AUTO) {
-               return cam->sensor_x;
-       }
-       else if(cam->sensor_fit==CAMERA_SENSOR_FIT_HOR) {
-               return cam->sensor_x;
-       }
-       else {
-               return cam->sensor_y;
-       }
-}
-
 static float rna_Camera_angle_get(PointerRNA *ptr)
 {
        Camera *cam= ptr->id.data;
-       float sensor= get_camera_sensor(cam);
+       float sensor= camera_sensor_size(cam->sensor_fit, cam->sensor_x, cam->sensor_y);
        return focallength_to_fov(cam->lens, sensor);
 }
 
 static void rna_Camera_angle_set(PointerRNA *ptr, float value)
 {
        Camera *cam= ptr->id.data;
-       float sensor= get_camera_sensor(cam);
+       float sensor= camera_sensor_size(cam->sensor_fit, cam->sensor_x, cam->sensor_y);
        cam->lens= fov_to_focallength(value, sensor);
 }