Camera tracking integration
authorSergey Sharybin <sergey.vfx@gmail.com>
Sun, 30 Oct 2011 14:11:16 +0000 (14:11 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Sun, 30 Oct 2011 14:11:16 +0000 (14:11 +0000)
===========================

Camera sensor size changes:
- Now blender camera has got vertical sensor size property
  and setting to control how FOV is getting calculated
  (depending on aspect ratio, using horizontal sensor size or
  vertical only).
- Made changes in game engine and uv project modifier as well
- Presets should be updated (don't have settings by hand right now
  and the internet in debalie is really fails this year)

27 files changed:
release/scripts/startup/bl_operators/presets.py
release/scripts/startup/bl_ui/properties_data_camera.py
source/blender/blenkernel/BKE_object.h
source/blender/blenkernel/intern/object.c
source/blender/blenlib/BLI_math_rotation.h
source/blender/blenlib/intern/math_rotation.c
source/blender/blenlib/intern/uvproject.c
source/blender/blenloader/intern/readfile.c
source/blender/editors/sculpt_paint/paint_image.c
source/blender/editors/space_clip/tracking_ops.c
source/blender/editors/space_view3d/view3d_draw.c
source/blender/editors/space_view3d/view3d_edit.c
source/blender/editors/space_view3d/view3d_intern.h
source/blender/editors/space_view3d/view3d_view.c
source/blender/makesdna/DNA_camera_types.h
source/blender/makesrna/intern/rna_camera.c
source/blender/modifiers/intern/MOD_uvproject.c
source/blender/render/intern/include/render_types.h
source/blender/render/intern/source/initrender.c
source/gameengine/Converter/BL_BlenderDataConversion.cpp
source/gameengine/Ketsji/KX_Camera.cpp
source/gameengine/Ketsji/KX_Camera.h
source/gameengine/Ketsji/KX_KetsjiEngine.cpp
source/gameengine/Rasterizer/RAS_CameraData.h
source/gameengine/Rasterizer/RAS_FramingManager.cpp
source/gameengine/Rasterizer/RAS_FramingManager.h
source/gameengine/VideoTexture/ImageRender.cpp

index 940123e..e4b9266 100644 (file)
@@ -206,7 +206,9 @@ class AddPresetCamera(AddPresetBase, Operator):
     ]
 
     preset_values = [
-        "cam.sensor_width"
+        "cam.sensor_width",
+        "cam.sensor_height",
+        "cam.fov_mode"
     ]
 
     preset_subdir = "camera"
index 5fbb214..7a65369 100644 (file)
@@ -129,7 +129,11 @@ class DATA_PT_camera(CameraButtonsPanel, Panel):
         row.operator("camera.preset_add", text="", icon="ZOOMIN")
         row.operator("camera.preset_add", text="", icon="ZOOMOUT").remove_active = True
 
-        layout.prop(cam, "sensor_width")
+        layout.prop(cam, "fov_mode")
+
+        col = layout.column(align=True)
+        col.prop(cam, "sensor_width")
+        col.prop(cam, "sensor_height")
 
         layout.label(text="Clipping:")
         row = layout.row(align=True)
index b721986..b58f969 100644 (file)
@@ -145,7 +145,8 @@ void object_camera_intrinsics(struct Object *camera, struct Camera **cam_r, shor
                        float *clipsta, float *clipend, float *lens, float *sensor_x);
 void object_camera_matrix(
                struct RenderData *rd, struct Object *camera, int winx, int winy, short field_second,
-               float winmat[][4], struct rctf *viewplane, float *clipsta, float *clipend, float *lens, float *sensor_x, float *ycor,
+               float winmat[][4], struct rctf *viewplane, float *clipsta, float *clipend, float *lens,
+               float *sensor_x, float *sensor_y, short *fov_mode, float *ycor,
                float *viewdx, float *viewdy);
 
 void camera_view_frame_ex(struct Scene *scene, struct Camera *camera, float drawsize, const short do_clip, const float scale[3],
index 7191a13..67cef3f 100644 (file)
@@ -2977,13 +2977,17 @@ void object_camera_mode(RenderData *rd, Object *camera)
 }
 
 void object_camera_intrinsics(Object *camera, Camera **cam_r, short *is_ortho, float *shiftx, float *shifty,
-                       float *clipsta, float *clipend, float *lens, float *sensor_x)
+                       float *clipsta, float *clipend, float *lens, float *sensor_x, float *sensor_y, short *fov_mode)
 {
        Camera *cam= NULL;
 
        (*shiftx)= 0.0f;
        (*shifty)= 0.0f;
 
+       (*sensor_x)= DEFAULT_SENSOR_WIDTH;
+       (*sensor_y)= DEFAULT_SENSOR_HEIGHT;
+       (*fov_mode)= CAMERA_FOV_AUTO;
+
        if(camera->type==OB_CAMERA) {
                cam= camera->data;
 
@@ -3005,8 +3009,10 @@ void object_camera_intrinsics(Object *camera, Camera **cam_r, short *is_ortho, f
                (*shifty)=cam->shifty;
                (*lens)= cam->lens;
                (*sensor_x)= cam->sensor_x;
+               (*sensor_y)= cam->sensor_y;
                (*clipsta)= cam->clipsta;
                (*clipend)= cam->clipend;
+               (*fov_mode)= cam->fov_mode;
        }
        else if(camera->type==OB_LAMP) {
                Lamp *la= camera->data;
@@ -3035,9 +3041,10 @@ void object_camera_intrinsics(Object *camera, Camera **cam_r, short *is_ortho, f
 /* 'lens' may be set for envmap only */
 void object_camera_matrix(
                RenderData *rd, Object *camera, int winx, int winy, short field_second,
-               float winmat[][4], rctf *viewplane, float *clipsta, float *clipend, float *lens, float *sensor_x, float *ycor,
-               float *viewdx, float *viewdy
-) {
+               float winmat[][4], rctf *viewplane, float *clipsta, float *clipend, float *lens,
+               float *sensor_x, float *sensor_y, short *fov_mode, float *ycor,
+               float *viewdx, float *viewdy)
+{
        Camera *cam=NULL;
        float pixsize;
        float shiftx=0.0, shifty=0.0, winside, viewfac;
@@ -3048,22 +3055,36 @@ void object_camera_matrix(
        if(rd->mode & R_FIELDS)
                (*ycor) *= 2.0f;
 
-       object_camera_intrinsics(camera, &cam, &is_ortho, &shiftx, &shifty, clipsta, clipend, lens, sensor_x);
+       object_camera_intrinsics(camera, &cam, &is_ortho, &shiftx, &shifty, clipsta, clipend, lens, sensor_x, sensor_y, fov_mode);
 
        /* ortho only with camera available */
        if(cam && is_ortho) {
-               if(rd->xasp*winx >= rd->yasp*winy) {
+               if((*fov_mode)==CAMERA_FOV_AUTO) {
+                       if(rd->xasp*winx >= rd->yasp*winy) viewfac= winx;
+                       else viewfac= (*ycor) * winy;
+               }
+               else if((*fov_mode)==CAMERA_FOV_HOR) {
                        viewfac= winx;
                }
                else {
                        viewfac= (*ycor) * winy;
                }
+
                /* ortho_scale == 1.0 means exact 1 to 1 mapping */
                pixsize= cam->ortho_scale/viewfac;
        }
        else {
-               if(rd->xasp*winx >= rd->yasp*winy)      viewfac= ((*lens) * winx) / (*sensor_x);
-               else                                    viewfac= (*ycor) * ((*lens) * winy) / (*sensor_x);
+               if((*fov_mode)==CAMERA_FOV_AUTO) {
+                       if(rd->xasp*winx >= rd->yasp*winy)      viewfac= ((*lens) * winx) / (*sensor_x);
+                       else                                    viewfac= (*ycor) * ((*lens) * winy) / (*sensor_x);
+               }
+               else if((*fov_mode)==CAMERA_FOV_HOR) {
+                       viewfac= ((*lens) * winx) / (*sensor_x);
+               }
+               else if((*fov_mode)==CAMERA_FOV_VERT) {
+                       viewfac= ((*lens) * winy) / (*sensor_y);
+               }
+
                pixsize= (*clipsta) / viewfac;
        }
 
index b2ef021..fca7c34 100644 (file)
@@ -179,8 +179,8 @@ void dquat_to_mat4(float R[4][4], DualQuat *dq);
 void quat_apply_track(float quat[4], short axis, short upflag);
 void vec_apply_track(float vec[3], short axis);
 
-float focallength_to_hfov(float focal_length, float sensor_x);
-float hfov_to_focallength(float hfov, float sensor_x);
+float focallength_to_fov(float focal_length, float sensor);
+float fov_to_focallength(float fov, float sensor);
 
 float angle_wrap_rad(float angle);
 float angle_wrap_deg(float angle);
index 53cdb53..82e9315 100644 (file)
@@ -1688,14 +1688,14 @@ void vec_apply_track(float vec[3], short axis)
 }
 
 /* lens/angle conversion (radians) */
-float focallength_to_hfov(float focal_length, float sensor_x)
+float focallength_to_fov(float focal_length, float sensor)
 {
-       return 2.0f * atanf((sensor_x/2.0f) / focal_length);
+       return 2.0f * atanf((sensor/2.0f) / focal_length);
 }
 
-float hfov_to_focallength(float hfov, float sensor_x)
+float fov_to_focallength(float hfov, float sensor)
 {
-       return (sensor_x/2.0f) / tanf(hfov * 0.5f);
+       return (sensor/2.0f) / tanf(hfov * 0.5f);
 }
 
 /* 'mod_inline(-3,4)= 1', 'fmod(-3,4)= -3' */
index c11308e..8b00d8e 100644 (file)
@@ -141,7 +141,7 @@ UvCameraInfo *project_camera_info(Object *ob, float (*rotmat)[4], float winx, fl
        uci.do_pano = (camera->flag & CAM_PANORAMA);
        uci.do_persp = (camera->type==CAM_PERSP);
 
-       uci.camangle= focallength_to_hfov(camera->lens, camera->sensor_x) / 2.0f;
+       uci.camangle= focallength_to_fov(camera->lens, camera->sensor_x) / 2.0f;
        uci.camsize= uci.do_persp ? tanf(uci.camangle) : camera->ortho_scale;
 
        /* account for scaled cameras */
index 875ab0e..03e1ca2 100644 (file)
@@ -12360,9 +12360,11 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                        }
 
                        for(cam= main->camera.first; cam; cam= cam->id.next) {
-                               if (cam->sensor_x < 0.01) {
-                                       cam->sensor_x = 32.f;
-                               }
+                               if (cam->sensor_x < 0.01)
+                                       cam->sensor_x = DEFAULT_SENSOR_WIDTH;
+
+                               if (cam->sensor_y < 0.01)
+                                       cam->sensor_y = DEFAULT_SENSOR_HEIGHT;
                        }
 
                        for (clip= main->movieclip.first; clip; clip= clip->id.next) {
index 9b165bb..292d998 100644 (file)
@@ -57,6 +57,7 @@
 #include "IMB_imbuf_types.h"
 
 #include "DNA_brush_types.h"
+#include "DNA_camera_types.h"
 #include "DNA_mesh_types.h"
 #include "DNA_meshdata_types.h"
 #include "DNA_node_types.h"
@@ -3000,7 +3001,8 @@ static void project_paint_begin(ProjPaintState *ps)
                                Object *camera= ps->scene->camera;
 
                                /* dont actually use these */
-                               float _viewdx, _viewdy, _ycor, _lens=0.0f, _sensor_x=0.0f;
+                               float _viewdx, _viewdy, _ycor, _lens=0.0f, _sensor_x=DEFAULT_SENSOR_WIDTH, _sensor_y= DEFAULT_SENSOR_HEIGHT;
+                               short _fov_mode= CAMERA_FOV_AUTO;
                                rctf _viewplane;
 
                                /* viewmat & viewinv */
@@ -3012,7 +3014,7 @@ static void project_paint_begin(ProjPaintState *ps)
                                object_camera_mode(&ps->scene->r, camera);
                                object_camera_matrix(&ps->scene->r, camera, ps->winx, ps->winy, 0,
                                                winmat, &_viewplane, &ps->clipsta, &ps->clipend,
-                                               &_lens, &_sensor_x, &_ycor, &_viewdx, &_viewdy);
+                                               &_lens, &_sensor_x, &_sensor_x, &_fov_mode, &_ycor, &_viewdx, &_viewdy);
 
                                ps->is_ortho= (ps->scene->r.mode & R_ORTHO) ? 1 : 0;
                        }
index 32177ee..83aadb6 100644 (file)
@@ -118,7 +118,7 @@ static void add_marker(SpaceClip *sc, float x, float y)
        MovieClip *clip= ED_space_clip(sc);
        MovieTrackingTrack *track;
        int width, height;
-
+       
        ED_space_clip_size(sc, &width, &height);
 
        track= BKE_tracking_add_track(&clip->tracking, x, y, sc->user.framenr, width, height);
index 2db6286..af9ab7f 100644 (file)
@@ -921,17 +921,34 @@ static void draw_selected_name(Scene *scene, Object *ob)
        BLF_draw_default(offset,  10, 0.0f, info, sizeof(info)-1);
 }
 
-void view3d_viewborder_size_get(Scene *scene, ARegion *ar, float size_r[2])
+void view3d_viewborder_size_get(Scene *scene, Object *camob, ARegion *ar, float size_r[2])
 {
-       float winmax= MAX2(ar->winx, ar->winy);
        float aspect= (scene->r.xsch*scene->r.xasp) / (scene->r.ysch*scene->r.yasp);
-       
-       if(aspect > 1.0f) {
-               size_r[0]= winmax;
-               size_r[1]= winmax/aspect;
-       } else {
-               size_r[0]= winmax*aspect;
-               size_r[1]= winmax;
+       short fov_mode= CAMERA_FOV_AUTO;
+
+       if(camob && camob->type==OB_CAMERA) {
+               Camera *cam= (Camera *)camob->data;
+               fov_mode= cam->fov_mode;
+       }
+
+       if(fov_mode==CAMERA_FOV_AUTO) {
+               float winmax= MAX2(ar->winx, ar->winy);
+
+               if(aspect > 1.0f) {
+                       size_r[0]= winmax;
+                       size_r[1]= winmax/aspect;
+               } else {
+                       size_r[0]= winmax*aspect;
+                       size_r[1]= winmax;
+               }
+       }
+       else if(fov_mode==CAMERA_FOV_HOR) {
+               size_r[0]= ar->winx;
+               size_r[1]= ar->winx/aspect;
+       }
+       else {
+               size_r[0]= ar->winy*aspect;
+               size_r[1]= ar->winy;
        }
 }
 
@@ -941,7 +958,7 @@ void ED_view3d_calc_camera_border(Scene *scene, ARegion *ar, View3D *v3d, Region
        float size[2];
        float dx= 0.0f, dy= 0.0f;
        
-       view3d_viewborder_size_get(scene, ar, size);
+       view3d_viewborder_size_get(scene, v3d->camera, ar, size);
 
        size[0]= size[0]*zoomfac;
        size[1]= size[1]*zoomfac;
@@ -2444,10 +2461,12 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, in
        /* render 3d view */
        if(rv3d->persp==RV3D_CAMOB && v3d->camera) {
                float winmat[4][4];
-               float _clipsta, _clipend, _lens, _yco, _dx, _dy, _sensor_x=0;
+               float _clipsta, _clipend, _lens, _yco, _dx, _dy, _sensor_x= DEFAULT_SENSOR_WIDTH, _sensor_y= DEFAULT_SENSOR_HEIGHT;
+               short _fov_mode= CAMERA_FOV_AUTO;
                rctf _viewplane;
 
-               object_camera_matrix(&scene->r, v3d->camera, sizex, sizey, 0, winmat, &_viewplane, &_clipsta, &_clipend, &_lens, &_sensor_x, &_yco, &_dx, &_dy);
+               object_camera_matrix(&scene->r, v3d->camera, sizex, sizey, 0, winmat, &_viewplane, &_clipsta, &_clipend, &_lens,
+                       &_sensor_x, &_sensor_y, &_fov_mode, &_yco, &_dx, &_dy);
 
                ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat);
        }
@@ -2502,9 +2521,10 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Scene *scene, Object *camera, int w
        invert_m4_m4(rv3d.viewmat, rv3d.viewinv);
 
        {
-               float _yco, _dx, _dy, _sensor_x=0;
+               float _yco, _dx, _dy, _sensor_x= DEFAULT_SENSOR_WIDTH, _sensor_y= DEFAULT_SENSOR_HEIGHT;
+               short _fov_mode= CAMERA_FOV_AUTO;
                rctf _viewplane;
-               object_camera_matrix(&scene->r, v3d.camera, width, height, 0, rv3d.winmat, &_viewplane, &v3d.near, &v3d.far, &v3d.lens, &_sensor_x, &_yco, &_dx, &_dy);
+               object_camera_matrix(&scene->r, v3d.camera, width, height, 0, rv3d.winmat, &_viewplane, &v3d.near, &v3d.far, &v3d.lens, &_sensor_x, &_sensor_y, &_fov_mode, &_yco, &_dx, &_dy);
        }
 
        mul_m4_m4m4(rv3d.persmat, rv3d.viewmat, rv3d.winmat);
index 00c9bf5..d8936ef 100644 (file)
@@ -2255,13 +2255,14 @@ static int view3d_center_camera_exec(bContext *C, wmOperator *UNUSED(op)) /* was
 {
        ARegion *ar= CTX_wm_region(C);
        RegionView3D *rv3d= CTX_wm_region_view3d(C);
+       View3D *v3d= CTX_wm_view3d(C);
        Scene *scene= CTX_data_scene(C);
        float xfac, yfac;
        float size[2];
 
        rv3d->camdx= rv3d->camdy= 0.0f;
 
-       view3d_viewborder_size_get(scene, ar, size);
+       view3d_viewborder_size_get(scene, v3d->camera, ar, size);
 
        /* 4px is just a little room from the edge of the area */
        xfac= (float)ar->winx / (float)(size[0] + 4);
@@ -2523,13 +2524,13 @@ void VIEW3D_OT_zoom_border(wmOperatorType *ot)
 }
 
 /* sets the view to 1:1 camera/render-pixel */
-static void view3d_set_1_to_1_viewborder(Scene *scene, ARegion *ar)
+static void view3d_set_1_to_1_viewborder(Scene *scene, ARegion *ar, View3D *v3d)
 {
        RegionView3D *rv3d= ar->regiondata;
        float size[2];
        int im_width= (scene->r.size*scene->r.xsch)/100;
        
-       view3d_viewborder_size_get(scene, ar, size);
+       view3d_viewborder_size_get(scene, v3d->camera, ar, size);
 
        rv3d->camzoom= BKE_screen_view3d_zoom_from_fac((float)im_width/size[0]);
        CLAMP(rv3d->camzoom, RV3D_CAMZOOM_MIN, RV3D_CAMZOOM_MAX);
@@ -2540,7 +2541,7 @@ static int view3d_zoom_1_to_1_camera_exec(bContext *C, wmOperator *UNUSED(op))
        Scene *scene= CTX_data_scene(C);
        ARegion *ar= CTX_wm_region(C);
 
-       view3d_set_1_to_1_viewborder(scene, ar);
+       view3d_set_1_to_1_viewborder(scene, ar, CTX_wm_view3d(C));
 
        WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, CTX_wm_view3d(C));
 
index 4901957..1afbd57 100644 (file)
@@ -136,7 +136,7 @@ void draw_depth_gpencil(Scene *scene, ARegion *ar, View3D *v3d);
 void view3d_clr_clipping(void);
 void view3d_set_clipping(RegionView3D *rv3d);
 void add_view3d_after(ListBase *lb, Base *base, int flag);
-void view3d_viewborder_size_get(struct Scene *scene, struct ARegion *ar, float size_r[2]);
+void view3d_viewborder_size_get(struct Scene *scene, struct Objecy *camob, struct ARegion *ar, float size_r[2]);
 
 void circf(float x, float y, float rad);
 void circ(float x, float y, float rad);
index 8e0905d..3122ef8 100644 (file)
@@ -966,9 +966,10 @@ int ED_view3d_clip_range_get(View3D *v3d, RegionView3D *rv3d, float *clipsta, fl
 int ED_view3d_viewplane_get(View3D *v3d, RegionView3D *rv3d, int winxi, int winyi, rctf *viewplane, float *clipsta, float *clipend, float *pixsize)
 {
        Camera *cam=NULL;
-       float lens, sensor=32.f, fac, x1, y1, x2, y2;
+       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 fov_mode= CAMERA_FOV_AUTO;
        
        lens= v3d->lens;        
        
@@ -992,9 +993,11 @@ int ED_view3d_viewplane_get(View3D *v3d, RegionView3D *rv3d, int winxi, int winy
                        else if(v3d->camera->type==OB_CAMERA) {
                                cam= v3d->camera->data;
                                lens= cam->lens;
-                               sensor= cam->sensor_x;
+                               sensor_x= cam->sensor_x;
+                               sensor_y= cam->sensor_y;
                                *clipsta= cam->clipsta;
                                *clipend= cam->clipend;
+                               fov_mode= cam->fov_mode;
                        }
                }
        }
@@ -1025,21 +1028,44 @@ int ED_view3d_viewplane_get(View3D *v3d, RegionView3D *rv3d, int winxi, int winy
                if(cam && cam->type==CAM_ORTHO) {
                        /* ortho_scale == 1 means exact 1 to 1 mapping */
                        float dfac= 2.0f*cam->ortho_scale/fac;
-                       
-                       if(winx>winy) x1= -dfac;
-                       else x1= -winx*dfac/winy;
+
+                       if(fov_mode==CAMERA_FOV_AUTO) {
+                               if(winx>winy) {
+                                       x1= -dfac;
+                                       y1= -winy*dfac/winx;
+                               }
+                               else {
+                                       x1= -winx*dfac/winy;
+                                       y1= -dfac;
+                               }
+                       }
+                       else if(fov_mode==CAMERA_FOV_HOR) {
+                               x1= -dfac;
+                               y1= -winy*dfac/winx;
+                       }
+                       else {
+                               x1= -winx*dfac/winy;
+                               y1= -dfac;
+                       }
+
                        x2= -x1;
-                       
-                       if(winx>winy) y1= -winy*dfac/winx;
-                       else y1= -dfac;
                        y2= -y1;
+
                        orth= 1;
                }
                else {
                        float dfac;
                        
-                       if(winx>winy) dfac= (sensor * 2.0) / (fac*winx*lens);
-                       else dfac= (sensor * 2.0) / (fac*winy*lens);
+                       if(fov_mode==CAMERA_FOV_AUTO) {
+                               if(winx>winy) dfac= (sensor_x * 2.0) / (fac*winx*lens);
+                               else dfac= (sensor_x * 2.0) / (fac*winy*lens);
+                       }
+                       else if(fov_mode==CAMERA_FOV_HOR) {
+                               dfac= (sensor_x * 2.0) / (fac*winx*lens);
+                       }
+                       else {
+                               dfac= (sensor_y * 2.0) / (fac*winy*lens);
+                       }
                        
                        x1= - *clipsta * winx*dfac;
                        x2= -x1;
@@ -1058,8 +1084,8 @@ int ED_view3d_viewplane_get(View3D *v3d, RegionView3D *rv3d, int winxi, int winy
                                dy += cam->shifty * cam->ortho_scale;
                        }
                        else {
-                               dx += cam->shiftx * (cam->clipsta / cam->lens) * sensor;
-                               dy += cam->shifty * (cam->clipsta / cam->lens) * sensor;
+                               dx += cam->shiftx * (cam->clipsta / cam->lens) * sensor_x;
+                               dy += cam->shifty * (cam->clipsta / cam->lens) * sensor_x;
                        }
 
                        x1+= dx;
index ed04ead..08e8239 100644 (file)
@@ -51,7 +51,7 @@ typedef struct Camera {
        float passepartalpha;
        float clipsta, clipend;
        float lens, ortho_scale, drawsize;
-       float sensor_x, pad;
+       float sensor_x, sensor_y;
        float shiftx, shifty;
        
        /* yafray: dof params */
@@ -62,6 +62,9 @@ typedef struct Camera {
        struct Ipo *ipo;                        // XXX depreceated... old animation system
        
        struct Object *dof_ob;
+
+       char fov_mode;
+       char pad[7];
 } Camera;
 
 /* **************** CAMERA ********************* */
@@ -94,6 +97,13 @@ typedef struct Camera {
 /* yafray: dof sampling switch */
 /* #define CAM_YF_NO_QMC       512 */ /* depreceated */
 
+/* FOV mode */
+#define CAMERA_FOV_AUTO        0
+#define CAMERA_FOV_HOR 1
+#define CAMERA_FOV_VERT        2
+
+#define DEFAULT_SENSOR_WIDTH   32.0f
+#define DEFAULT_SENSOR_HEIGHT  18.0f
 
 #ifdef __cplusplus
 }
index 1c174c9..69afd2d 100644 (file)
 #include "BKE_depsgraph.h"
 
 /* only for rad/deg conversion! can remove later */
+static float get_camera_sensor(Camera *cam)
+{
+       if(cam->fov_mode==CAMERA_FOV_AUTO) {
+               return cam->sensor_x;
+       }
+       else if(cam->fov_mode==CAMERA_FOV_HOR) {
+               return cam->sensor_x;
+       }
+       else {
+               return cam->sensor_y;
+       }
+}
+
 static float rna_Camera_angle_get(PointerRNA *ptr)
 {
        Camera *cam= ptr->id.data;
-       return focallength_to_hfov(cam->lens, cam->sensor_x);
+       float sensor= get_camera_sensor(cam);
+       return focallength_to_fov(cam->lens, sensor);
 }
 
 static void rna_Camera_angle_set(PointerRNA *ptr, float value)
 {
        Camera *cam= ptr->id.data;
-       cam->lens= hfov_to_focallength(value, cam->sensor_x);
+       float sensor= get_camera_sensor(cam);
+       cam->lens= fov_to_focallength(value, sensor);
+}
+
+static float rna_Camera_angle_x_get(PointerRNA *ptr)
+{
+       Camera *cam= ptr->id.data;
+       return focallength_to_fov(cam->lens, cam->sensor_x);
+}
+
+static void rna_Camera_angle_x_set(PointerRNA *ptr, float value)
+{
+       Camera *cam= ptr->id.data;
+       cam->lens= fov_to_focallength(value, cam->sensor_x);
+}
+
+static float rna_Camera_angle_y_get(PointerRNA *ptr)
+{
+       Camera *cam= ptr->id.data;
+       return focallength_to_fov(cam->lens, cam->sensor_y);
+}
+
+static void rna_Camera_angle_y_set(PointerRNA *ptr, float value)
+{
+       Camera *cam= ptr->id.data;
+       cam->lens= fov_to_focallength(value, cam->sensor_y);
 }
 
 static void rna_Camera_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
@@ -86,6 +125,11 @@ void RNA_def_camera(BlenderRNA *brna)
                {0, "MILLIMETERS", 0, "Millimeters", ""},
                {CAM_ANGLETOGGLE, "DEGREES", 0, "Degrees", ""},
                {0, NULL, 0, NULL, NULL}};
+       static EnumPropertyItem fov_mode_items[] = {
+               {CAMERA_FOV_AUTO, "AUTO", 0, "Auto", "Calculate FOV using sensor size direction depending on image resolution"},
+               {CAMERA_FOV_HOR, "HORIZONTAL", 0, "Hoizontal", "Calculate FOV using sensor width"},
+               {CAMERA_FOV_VERT, "VERTICAL", 0, "Vertical", "Calculate FOV using sensor height"},
+               {0, NULL, 0, NULL, NULL}};
 
        srna= RNA_def_struct(brna, "Camera", "ID");
        RNA_def_struct_ui_text(srna, "Camera", "Camera datablock for storing camera settings");
@@ -103,7 +147,13 @@ void RNA_def_camera(BlenderRNA *brna)
        RNA_def_property_flag(prop, PROP_ENUM_FLAG);
        RNA_def_property_ui_text(prop, "Composition Guides",  "Draw overlay");
        RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL);
-       
+
+       prop= RNA_def_property(srna, "fov_mode", PROP_ENUM, PROP_NONE);
+       RNA_def_property_enum_sdna(prop, NULL, "fov_mode");
+       RNA_def_property_enum_items(prop, fov_mode_items);
+       RNA_def_property_ui_text(prop, "FOV Mode", "Mode of calculating FOV from sensor imensions and focal length");
+       RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Camera_update");
+
        /* Number values */
 
        prop= RNA_def_property(srna, "passepartout_alpha", PROP_FLOAT, PROP_FACTOR);
@@ -111,10 +161,24 @@ void RNA_def_camera(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Passepartout Alpha", "Opacity (alpha) of the darkened overlay in Camera view");
        RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL);
 
+       prop= RNA_def_property(srna, "angle_x", PROP_FLOAT, PROP_ANGLE);
+       RNA_def_property_range(prop, M_PI * (0.367/180.0), M_PI * (172.847/180.0));
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+       RNA_def_property_ui_text(prop, "Horizontal FOV", "Camera lens horizontal field of view in degrees");
+       RNA_def_property_float_funcs(prop, "rna_Camera_angle_x_get", "rna_Camera_angle_x_set", NULL);
+       RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Camera_update");
+
+       prop= RNA_def_property(srna, "angle_y", PROP_FLOAT, PROP_ANGLE);
+       RNA_def_property_range(prop, M_PI * (0.367/180.0), M_PI * (172.847/180.0));
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+       RNA_def_property_ui_text(prop, "Vertical FOV", "Camera lens vertical field of view in degrees");
+       RNA_def_property_float_funcs(prop, "rna_Camera_angle_y_get", "rna_Camera_angle_y_set", NULL);
+       RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Camera_update");
+
        prop= RNA_def_property(srna, "angle", PROP_FLOAT, PROP_ANGLE);
        RNA_def_property_range(prop, M_PI * (0.367/180.0), M_PI * (172.847/180.0));
        RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
-       RNA_def_property_ui_text(prop, "Field of View", "Camera lens horizontal field of view in degrees");
+       RNA_def_property_ui_text(prop, "Field of View", "Camera lens field of view in degrees");
        RNA_def_property_float_funcs(prop, "rna_Camera_angle_get", "rna_Camera_angle_set", NULL);
        RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Camera_update");
 
@@ -135,12 +199,19 @@ void RNA_def_camera(BlenderRNA *brna)
        RNA_def_property_range(prop, 1.0f, 5000.0f);
        RNA_def_property_ui_text(prop, "Focal Length", "Perspective Camera lens value in millimeters");
        RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Camera_update");
-       
+
        prop= RNA_def_property(srna, "sensor_width", PROP_FLOAT, PROP_NONE);
        RNA_def_property_float_sdna(prop, NULL, "sensor_x");
        RNA_def_property_range(prop, 1.0f, FLT_MAX);
        RNA_def_property_ui_range(prop, 1.0f, 100.f, 1, 2);
-       RNA_def_property_ui_text(prop, "Sensor", "Horizontal size of the image sensor area in millimeters");
+       RNA_def_property_ui_text(prop, "Sensor Width", "Horizontal size of the image sensor area in millimeters");
+       RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Camera_update");
+
+       prop= RNA_def_property(srna, "sensor_height", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "sensor_y");
+       RNA_def_property_range(prop, 1.0f, FLT_MAX);
+       RNA_def_property_ui_range(prop, 1.0f, 100.f, 1, 2);
+       RNA_def_property_ui_text(prop, "Sensor Height", "Vertical size of the image sensor area in millimeters");
        RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Camera_update");
 
        prop= RNA_def_property(srna, "ortho_scale", PROP_FLOAT, PROP_NONE);
index 6cd59e5..0515c08 100644 (file)
@@ -195,16 +195,28 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
                                free_uci= 1;
                        }
                        else {
-                               float scale= (cam->type == CAM_PERSP) ? cam->clipsta * cam->sensor_x / cam->lens : cam->ortho_scale;
+                               float sensor= (cam->fov_mode == CAMERA_FOV_VERT) ? (cam->sensor_y) : cam->sensor_x;
+                               float scale= (cam->type == CAM_PERSP) ? cam->clipsta * sensor / cam->lens : cam->ortho_scale;
                                float xmax, xmin, ymax, ymin;
 
-                               if(aspect > 1.0f) {
+                               if(cam->fov_mode==CAMERA_FOV_AUTO) {
+                                       if(aspect > 1.0f) {
+                                               xmax = 0.5f * scale;
+                                               ymax = xmax / aspect;
+                                       } else {
+                                               ymax = 0.5f * scale;
+                                               xmax = ymax * aspect;
+                                       }
+                               }
+                               else if(cam->fov_mode==CAMERA_FOV_HOR) {
                                        xmax = 0.5f * scale;
                                        ymax = xmax / aspect;
-                               } else {
+                               }
+                               else {
                                        ymax = 0.5f * scale;
                                        xmax = ymax * aspect;
                                }
+
                                xmin = -xmax;
                                ymin = -ymax;
 
index 651608f..cfc0553 100644 (file)
@@ -153,8 +153,9 @@ struct Render
        
        /* values for viewing */
        float lens;
-       float sensor_x; /* image sensor size, same variable in camera */
+       float sensor_x, sensor_y; /* image sensor size, same variable in camera */
        float ycor; /* (scene->xasp / scene->yasp), multiplied with 'winy' */
+       char fov_mode;
        
        float panophi, panosi, panoco, panodxp, panodxv;
        
index b69dc6f..7720436 100644 (file)
@@ -458,7 +458,7 @@ void RE_SetCamera(Render *re, Object *camera)
 
        object_camera_matrix(&re->r, camera, re->winx, re->winy, re->flag & R_SEC_FIELD,
                        re->winmat, &re->viewplane, &re->clipsta, &re->clipend,
-                       &re->lens, &re->sensor_x, &re->ycor, &re->viewdx, &re->viewdy);
+                       &re->lens, &re->sensor_x, &re->sensor_y, &re->fov_mode, &re->ycor, &re->viewdx, &re->viewdy);
 }
 
 void RE_SetPixelSize(Render *re, float pixsize)
index 779bc5b..80661fc 100644 (file)
@@ -1724,7 +1724,7 @@ static KX_LightObject *gamelight_from_blamp(Object *ob, Lamp *la, unsigned int l
 
 static KX_Camera *gamecamera_from_bcamera(Object *ob, KX_Scene *kxscene, KX_BlenderSceneConverter *converter) {
        Camera* ca = static_cast<Camera*>(ob->data);
-       RAS_CameraData camdata(ca->lens, ca->ortho_scale, ca->sensor_x, ca->clipsta, ca->clipend, ca->type == CAM_PERSP, ca->YF_dofdist);
+       RAS_CameraData camdata(ca->lens, ca->ortho_scale, ca->sensor_x, ca->sensor_y, ca->fov_mode, ca->clipsta, ca->clipend, ca->type == CAM_PERSP, ca->YF_dofdist);
        KX_Camera *gamecamera;
        
        gamecamera= new KX_Camera(kxscene, KX_Scene::m_callbacks, camdata);
index c3c3fc2..64bba6c 100644 (file)
@@ -208,6 +208,18 @@ float KX_Camera::GetSensorWidth() const
        return m_camdata.m_sensor_x;
 }
 
+/*
+* Gets the vertical size of the sensor - for camera matching.
+*/
+float KX_Camera::GetSensorHeight() const
+{
+       return m_camdata.m_sensor_y;
+}
+/** Gets the mode FOV is calculating from sensor dimensions */
+short KX_Camera::GetFOVMode() const
+{
+       return m_camdata.m_fov_mode;
+}
 
 float KX_Camera::GetCameraNear() const
 {
index 0638a76..cc114de 100644 (file)
@@ -201,6 +201,10 @@ public:
        float                           GetScale() const;
        /** Gets the horizontal size of the sensor - for camera matching */
        float                           GetSensorWidth() const;
+       /** Gets the vertical size of the sensor - for camera matching */
+       float                           GetSensorHeight() const;
+       /** Gets the mode FOV is calculating from sensor dimensions */
+       short                           GetFOVMode() const;
        /** Gets the near clip distance. */
        float                           GetCameraNear() const;
        /** Gets the far clip distance. */
index ed03f68..371b3cd 100644 (file)
@@ -1251,6 +1251,7 @@ void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam)
                                cam->GetScale(),
                                nearfrust,
                                farfrust,
+                               cam->GetFOVMode(),
                                frustum
                        );
                        if (!cam->GetViewport()) {
@@ -1269,6 +1270,8 @@ void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam)
                                viewport,
                                cam->GetLens(),
                                cam->GetSensorWidth(),
+                               cam->GetSensorHeight(),
+                               cam->GetFOVMode(),
                                nearfrust,
                                farfrust,
                                frustum
index 1e00be9..7726aaa 100644 (file)
@@ -37,6 +37,8 @@ struct RAS_CameraData
        float m_lens;
        float m_scale;
        float m_sensor_x;
+       float m_sensor_y;
+       short m_fov_mode;
        float m_clipstart;
        float m_clipend;
        bool m_perspective;
@@ -47,12 +49,15 @@ struct RAS_CameraData
        int m_viewporttop;
        float m_focallength;
 
-       RAS_CameraData(float lens = 35.0, float scale = 6.0, float sensor_x = 32.0, float clipstart = 0.1, float clipend = 5000.0, bool perspective = true,
+       RAS_CameraData(float lens = 35.0, float scale = 6.0, float sensor_x = 32.0, float sensor_y = 18.0, short fov_mode = 0,
+                      float clipstart = 0.1, float clipend = 5000.0, bool perspective = true,
                       float focallength = 3.0, bool viewport = false, int viewportleft = 0, int viewportbottom = 0,
                       int viewportright = 0, int viewporttop = 0) :
            m_lens(lens),
            m_scale(scale),
            m_sensor_x(sensor_x),
+           m_sensor_y(sensor_y),
+               m_fov_mode(fov_mode),
            m_clipstart(clipstart),
            m_clipend(clipend),
            m_perspective(perspective),
index d5d7b18..7cd46ac 100644 (file)
@@ -39,27 +39,35 @@ ComputeDefaultFrustum(
        const float camnear,
        const float camfar,
        const float lens,
-       const float sensor_x,
+       const float sensor_x, const float sensor_y,
+       const short fov_mode,
        const float design_aspect_ratio,
        RAS_FrameFrustum & frustum
-){
-               
-       /*
-        * Magic Blender calculation.
-        * Blender does not give a Field of View as lens but a size
-        * at 16 units away from the lens.
-        * ^Deprecated Comment
-        */
-       float halfSize = (sensor_x / 2.f) * camnear / lens;
+){             
+       float halfSize;
        float sizeX;
        float sizeY;
 
-       if (design_aspect_ratio > 1.f) {
-               // halfsize defines the width
+       if(fov_mode==RAS_FOVMODE_AUTO) {
+               halfSize = (sensor_x / 2.f) * camnear / lens;
+
+               if (design_aspect_ratio > 1.f) {
+                       // halfsize defines the width
+                       sizeX = halfSize;
+                       sizeY = halfSize/design_aspect_ratio;
+               } else {
+                       // halfsize defines the height
+                       sizeX = halfSize * design_aspect_ratio;
+                       sizeY = halfSize;
+               }
+       }
+       else if(fov_mode==RAS_FOVMODE_HOR) {
+               halfSize = (sensor_x / 2.f) * camnear / lens;
                sizeX = halfSize;
                sizeY = halfSize/design_aspect_ratio;
-       } else {
-               // halfsize defines the height
+       }
+       else {
+               halfSize = (sensor_y / 2.f) * camnear / lens;
                sizeX = halfSize * design_aspect_ratio;
                sizeY = halfSize;
        }
@@ -79,6 +87,7 @@ ComputeDefaultOrtho(
        const float camfar,
        const float scale,
        const float design_aspect_ratio,
+       const short fov_mode,
        RAS_FrameFrustum & frustum
 )
 {
@@ -86,12 +95,22 @@ ComputeDefaultOrtho(
        float sizeX;
        float sizeY;
 
-       if (design_aspect_ratio > 1.f) {
-               // halfsize defines the width
+       if(fov_mode==RAS_FOVMODE_AUTO) {
+               if (design_aspect_ratio > 1.f) {
+                       // halfsize defines the width
+                       sizeX = halfSize;
+                       sizeY = halfSize/design_aspect_ratio;
+               } else {
+                       // halfsize defines the height
+                       sizeX = halfSize * design_aspect_ratio;
+                       sizeY = halfSize;
+               }
+       }
+       else if(fov_mode==RAS_FOVMODE_HOR) {
                sizeX = halfSize;
                sizeY = halfSize/design_aspect_ratio;
-       } else {
-               // halfsize defines the height
+       }
+       else {
                sizeX = halfSize * design_aspect_ratio;
                sizeY = halfSize;
        }
@@ -201,7 +220,7 @@ ComputeFrustum(
        const RAS_Rect &availableViewport,
        const RAS_Rect &viewport,
        const float lens,
-       const float sensor_x,
+       const float sensor_x, const float sensor_y, const short fov_mode,
        const float camnear,
        const float camfar,
        RAS_FrameFrustum &frustum
@@ -228,6 +247,8 @@ ComputeFrustum(
                camfar,
                lens,
                sensor_x,
+               sensor_y,
+               fov_mode,
                design_aspect_ratio,
                frustum
        );
@@ -273,6 +294,7 @@ RAS_FramingManager::
                const float scale,
                const float camnear,
                const float camfar,
+               const short fov_mode,
                RAS_FrameFrustum &frustum
        )
 {
@@ -297,6 +319,7 @@ RAS_FramingManager::
                camfar,
                scale,
                design_aspect_ratio,
+               fov_mode,
                frustum
        );
 
index ecac6ab..0ae7b6f 100644 (file)
@@ -184,6 +184,14 @@ enum RAS_CullingMode
        RAS_CULLING_NONE
 };
 
+/* Should match CAMERA_FOV... from DNA_camera_types.h */
+enum RAS_FovMode
+{
+       RAS_FOVMODE_AUTO = 0,
+       RAS_FOVMODE_HOR,
+       RAS_FOVMODE_VERT
+};
+
 /**
  * @section RAS_FramingManager
  * This class helps to compute a view frustum
@@ -229,6 +237,7 @@ public :
                const float scale,
                const float camnear,
                const float camfar,
+               const short fov_mode,
                RAS_FrameFrustum &frustum
        );
 
@@ -239,7 +248,7 @@ public :
                const RAS_Rect &availableViewport,
                const RAS_Rect &viewport,
                const float lens,
-               const float sensor_x,
+               const float sensor_x, const float sensor_y, const short fov_mode,
                const float camnear,
                const float camfar,
                RAS_FrameFrustum &frustum
@@ -251,7 +260,8 @@ public :
                const float camnear,
                const float camfar,
                const float lens,
-               const float sensor_x,
+               const float sensor_x, const float sensor_y,
+               const short fov_mode,
                const float design_aspect_ratio,
                RAS_FrameFrustum & frustum
        );      
@@ -263,6 +273,7 @@ public :
                const float camfar,
                const float scale,
                const float design_aspect_ratio,
+               const short fov_mode,
                RAS_FrameFrustum & frustum
        );
 
index 0d8acc9..8bc8c67 100644 (file)
@@ -215,6 +215,7 @@ void ImageRender::Render()
        {
                float lens = m_camera->GetLens();
                float sensor_x = m_camera->GetSensorWidth();
+               float sensor_y = m_camera->GetSensorHeight();
                bool orthographic = !m_camera->GetCameraData()->m_perspective;
                float nearfrust = m_camera->GetCameraNear();
                float farfrust = m_camera->GetCameraFar();
@@ -234,6 +235,7 @@ void ImageRender::Render()
                                    farfrust,
                                    m_camera->GetScale(),
                                    aspect_ratio,
+                                               m_camera->GetFOVMode(),
                                    frustrum
                                    );
 
@@ -246,6 +248,8 @@ void ImageRender::Render()
                                    farfrust,
                                    lens,
                                    sensor_x,
+                                   sensor_y,
+                                   RAS_FOVMODE_AUTO,
                                    aspect_ratio,
                                    frustrum);