Configurable sensor size:
authorSergey Sharybin <sergey.vfx@gmail.com>
Fri, 4 Nov 2011 14:36:06 +0000 (14:36 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Fri, 4 Nov 2011 14:36:06 +0000 (14:36 +0000)
- Added support of variable size sensor width and height.
- Added presets for most common cameras, also new presets can be defined by user.
- Added option to control which dimension (vertical or horizontal) of sensor
  size defines FOV. Old behavior of automatic FOV calculation is also kept.
- Renderer, viewport, game engine and collada importer/exporter should
  deal fine with this changes. Other exporters would be updated soon.

55 files changed:
release/scripts/presets/camera/APS-C_DSLR.py [new file with mode: 0644]
release/scripts/presets/camera/Blender.py [new file with mode: 0644]
release/scripts/presets/camera/Canon_1100D.py [new file with mode: 0644]
release/scripts/presets/camera/Canon_1D.py [new file with mode: 0644]
release/scripts/presets/camera/Canon_1DS.py [new file with mode: 0644]
release/scripts/presets/camera/Canon_500D.py [new file with mode: 0644]
release/scripts/presets/camera/Canon_550D.py [new file with mode: 0644]
release/scripts/presets/camera/Canon_5D.py [new file with mode: 0644]
release/scripts/presets/camera/Canon_600D.py [new file with mode: 0644]
release/scripts/presets/camera/Canon_60D.py [new file with mode: 0644]
release/scripts/presets/camera/Canon_7D.py [new file with mode: 0644]
release/scripts/presets/camera/Nikon_D300S.py [new file with mode: 0644]
release/scripts/presets/camera/Nikon_D3100.py [new file with mode: 0644]
release/scripts/presets/camera/Nikon_D35.py [new file with mode: 0644]
release/scripts/presets/camera/Nikon_D5000.py [new file with mode: 0644]
release/scripts/presets/camera/Nikon_D5100.py [new file with mode: 0644]
release/scripts/presets/camera/Nikon_D7000.py [new file with mode: 0644]
release/scripts/presets/camera/Nikon_D90.py [new file with mode: 0644]
release/scripts/presets/camera/Red_Epic.py [new file with mode: 0644]
release/scripts/presets/camera/Red_One_2K.py [new file with mode: 0644]
release/scripts/presets/camera/Red_One_3K.py [new file with mode: 0644]
release/scripts/presets/camera/Red_One_4K.py [new file with mode: 0644]
release/scripts/presets/camera/full_frame_35mm_film.py [new file with mode: 0644]
release/scripts/presets/camera/micro_four_thirds.py [new file with mode: 0644]
release/scripts/presets/camera/super_16_film.py [new file with mode: 0644]
release/scripts/presets/camera/super_35_film.py [new file with mode: 0644]
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/collada/CameraExporter.cpp
source/blender/collada/DocumentImporter.cpp
source/blender/editors/sculpt_paint/paint_image.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/envmap.c
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

diff --git a/release/scripts/presets/camera/APS-C_DSLR.py b/release/scripts/presets/camera/APS-C_DSLR.py
new file mode 100644 (file)
index 0000000..829e03c
--- /dev/null
@@ -0,0 +1,4 @@
+import bpy
+bpy.context.object.data.sensor_width = 22.3
+bpy.context.object.data.sensor_height = 14.9
+bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Blender.py b/release/scripts/presets/camera/Blender.py
new file mode 100644 (file)
index 0000000..9fa4ab7
--- /dev/null
@@ -0,0 +1,4 @@
+import bpy
+bpy.context.object.data.sensor_width = 32
+bpy.context.object.data.sensor_height = 18
+bpy.context.object.data.sensor_fit = 'AUTO'
diff --git a/release/scripts/presets/camera/Canon_1100D.py b/release/scripts/presets/camera/Canon_1100D.py
new file mode 100644 (file)
index 0000000..54f2cf7
--- /dev/null
@@ -0,0 +1,4 @@
+import bpy
+bpy.context.object.data.sensor_width = 22.2
+bpy.context.object.data.sensor_height = 14.7
+bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Canon_1D.py b/release/scripts/presets/camera/Canon_1D.py
new file mode 100644 (file)
index 0000000..0bb0e91
--- /dev/null
@@ -0,0 +1,4 @@
+import bpy
+bpy.context.object.data.sensor_width = 27.9
+bpy.context.object.data.sensor_height = 18.6
+bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Canon_1DS.py b/release/scripts/presets/camera/Canon_1DS.py
new file mode 100644 (file)
index 0000000..158a623
--- /dev/null
@@ -0,0 +1,4 @@
+import bpy
+bpy.context.object.data.sensor_width = 36.0
+bpy.context.object.data.sensor_height = 24.0
+bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Canon_500D.py b/release/scripts/presets/camera/Canon_500D.py
new file mode 100644 (file)
index 0000000..829e03c
--- /dev/null
@@ -0,0 +1,4 @@
+import bpy
+bpy.context.object.data.sensor_width = 22.3
+bpy.context.object.data.sensor_height = 14.9
+bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Canon_550D.py b/release/scripts/presets/camera/Canon_550D.py
new file mode 100644 (file)
index 0000000..829e03c
--- /dev/null
@@ -0,0 +1,4 @@
+import bpy
+bpy.context.object.data.sensor_width = 22.3
+bpy.context.object.data.sensor_height = 14.9
+bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Canon_5D.py b/release/scripts/presets/camera/Canon_5D.py
new file mode 100644 (file)
index 0000000..158a623
--- /dev/null
@@ -0,0 +1,4 @@
+import bpy
+bpy.context.object.data.sensor_width = 36.0
+bpy.context.object.data.sensor_height = 24.0
+bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Canon_600D.py b/release/scripts/presets/camera/Canon_600D.py
new file mode 100644 (file)
index 0000000..829e03c
--- /dev/null
@@ -0,0 +1,4 @@
+import bpy
+bpy.context.object.data.sensor_width = 22.3
+bpy.context.object.data.sensor_height = 14.9
+bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Canon_60D.py b/release/scripts/presets/camera/Canon_60D.py
new file mode 100644 (file)
index 0000000..829e03c
--- /dev/null
@@ -0,0 +1,4 @@
+import bpy
+bpy.context.object.data.sensor_width = 22.3
+bpy.context.object.data.sensor_height = 14.9
+bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Canon_7D.py b/release/scripts/presets/camera/Canon_7D.py
new file mode 100644 (file)
index 0000000..829e03c
--- /dev/null
@@ -0,0 +1,4 @@
+import bpy
+bpy.context.object.data.sensor_width = 22.3
+bpy.context.object.data.sensor_height = 14.9
+bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Nikon_D300S.py b/release/scripts/presets/camera/Nikon_D300S.py
new file mode 100644 (file)
index 0000000..a0505bf
--- /dev/null
@@ -0,0 +1,4 @@
+import bpy
+bpy.context.object.data.sensor_width = 23.6
+bpy.context.object.data.sensor_height = 15.8
+bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Nikon_D3100.py b/release/scripts/presets/camera/Nikon_D3100.py
new file mode 100644 (file)
index 0000000..238d9c2
--- /dev/null
@@ -0,0 +1,4 @@
+import bpy
+bpy.context.object.data.sensor_width = 23.1
+bpy.context.object.data.sensor_height = 15.4
+bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Nikon_D35.py b/release/scripts/presets/camera/Nikon_D35.py
new file mode 100644 (file)
index 0000000..e6dc62d
--- /dev/null
@@ -0,0 +1,4 @@
+import bpy
+bpy.context.object.data.sensor_width = 36.0
+bpy.context.object.data.sensor_height = 23.9
+bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Nikon_D5000.py b/release/scripts/presets/camera/Nikon_D5000.py
new file mode 100644 (file)
index 0000000..a0505bf
--- /dev/null
@@ -0,0 +1,4 @@
+import bpy
+bpy.context.object.data.sensor_width = 23.6
+bpy.context.object.data.sensor_height = 15.8
+bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Nikon_D5100.py b/release/scripts/presets/camera/Nikon_D5100.py
new file mode 100644 (file)
index 0000000..1d819cc
--- /dev/null
@@ -0,0 +1,4 @@
+import bpy
+bpy.context.object.data.sensor_width = 23.6
+bpy.context.object.data.sensor_height = 15.6
+bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Nikon_D7000.py b/release/scripts/presets/camera/Nikon_D7000.py
new file mode 100644 (file)
index 0000000..1d819cc
--- /dev/null
@@ -0,0 +1,4 @@
+import bpy
+bpy.context.object.data.sensor_width = 23.6
+bpy.context.object.data.sensor_height = 15.6
+bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Nikon_D90.py b/release/scripts/presets/camera/Nikon_D90.py
new file mode 100644 (file)
index 0000000..a0505bf
--- /dev/null
@@ -0,0 +1,4 @@
+import bpy
+bpy.context.object.data.sensor_width = 23.6
+bpy.context.object.data.sensor_height = 15.8
+bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Red_Epic.py b/release/scripts/presets/camera/Red_Epic.py
new file mode 100644 (file)
index 0000000..14f4aba
--- /dev/null
@@ -0,0 +1,4 @@
+import bpy
+bpy.context.object.data.sensor_width = 30.0
+bpy.context.object.data.sensor_height = 15.0
+bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Red_One_2K.py b/release/scripts/presets/camera/Red_One_2K.py
new file mode 100644 (file)
index 0000000..ef2708f
--- /dev/null
@@ -0,0 +1,4 @@
+import bpy
+bpy.context.object.data.sensor_width = 11.1
+bpy.context.object.data.sensor_height = 6.24
+bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Red_One_3K.py b/release/scripts/presets/camera/Red_One_3K.py
new file mode 100644 (file)
index 0000000..5ddff27
--- /dev/null
@@ -0,0 +1,4 @@
+import bpy
+bpy.context.object.data.sensor_width = 16.65
+bpy.context.object.data.sensor_height = 9.36
+bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Red_One_4K.py b/release/scripts/presets/camera/Red_One_4K.py
new file mode 100644 (file)
index 0000000..8ab9b38
--- /dev/null
@@ -0,0 +1,4 @@
+import bpy
+bpy.context.object.data.sensor_width = 22.2
+bpy.context.object.data.sensor_height = 12.6
+bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/full_frame_35mm_film.py b/release/scripts/presets/camera/full_frame_35mm_film.py
new file mode 100644 (file)
index 0000000..d3e141b
--- /dev/null
@@ -0,0 +1,4 @@
+import bpy
+bpy.context.object.data.sensor_width = 36
+bpy.context.object.data.sensor_height = 24
+bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/micro_four_thirds.py b/release/scripts/presets/camera/micro_four_thirds.py
new file mode 100644 (file)
index 0000000..36fb0aa
--- /dev/null
@@ -0,0 +1,4 @@
+import bpy
+bpy.context.object.data.sensor_width = 17.3
+bpy.context.object.data.sensor_height = 13.0
+bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/super_16_film.py b/release/scripts/presets/camera/super_16_film.py
new file mode 100644 (file)
index 0000000..1e42953
--- /dev/null
@@ -0,0 +1,4 @@
+import bpy
+bpy.context.object.data.sensor_width = 12.52
+bpy.context.object.data.sensor_height = 7.41
+bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/super_35_film.py b/release/scripts/presets/camera/super_35_film.py
new file mode 100644 (file)
index 0000000..65ccb0f
--- /dev/null
@@ -0,0 +1,4 @@
+import bpy
+bpy.context.object.data.sensor_width = 24.89
+bpy.context.object.data.sensor_height = 18.66
+bpy.context.object.data.sensor_fit = 'HORIZONTAL'
index 2e42105fbf0032f01e5bdb6ea70b2c78d221875a..21ac128f1775edfb173a27a47e63f13ac6637a48 100644 (file)
@@ -195,6 +195,25 @@ class AddPresetRender(AddPresetBase, Operator):
     preset_subdir = "render"
 
 
+class AddPresetCamera(AddPresetBase, Operator):
+    '''Add a Camera Preset'''
+    bl_idname = "camera.preset_add"
+    bl_label = "Add Camera Preset"
+    preset_menu = "CAMERA_MT_presets"
+
+    preset_defines = [
+        "cam = bpy.context.object.data"
+    ]
+
+    preset_values = [
+        "cam.sensor_width",
+        "cam.sensor_height",
+        "cam.sensor_fit"
+    ]
+
+    preset_subdir = "camera"
+
+
 class AddPresetSSS(AddPresetBase, Operator):
     '''Add a Subsurface Scattering Preset'''
     bl_idname = "material.sss_preset_add"
index 5255af40951d6604fba37cf071695f224eec16b0..4adaad75e42863a6f1e56b1be2aa3190edadc490 100644 (file)
@@ -33,6 +33,14 @@ class CameraButtonsPanel():
         return context.camera and (engine in cls.COMPAT_ENGINES)
 
 
+class CAMERA_MT_presets(bpy.types.Menu):
+    bl_label = "Camera Presets"
+    preset_subdir = "camera"
+    preset_operator = "script.execute_preset"
+    COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+    draw = bpy.types.Menu.draw_preset
+
+
 class DATA_PT_context_camera(CameraButtonsPanel, Panel):
     bl_label = ""
     bl_options = {'HIDE_HEADER'}
@@ -54,7 +62,7 @@ class DATA_PT_context_camera(CameraButtonsPanel, Panel):
             split.separator()
 
 
-class DATA_PT_camera(CameraButtonsPanel, Panel):
+class DATA_PT_lens(CameraButtonsPanel, Panel):
     bl_label = "Lens"
     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
 
@@ -69,12 +77,12 @@ class DATA_PT_camera(CameraButtonsPanel, Panel):
 
         col = split.column()
         if cam.type == 'PERSP':
+            row = col.row()
             if cam.lens_unit == 'MILLIMETERS':
-                col.prop(cam, "lens")
+                row.prop(cam, "lens")
             elif cam.lens_unit == 'DEGREES':
-                col.prop(cam, "angle")
-            col = split.column()
-            col.prop(cam, "lens_unit", text="")
+                row.prop(cam, "angle")
+            row.prop(cam, "lens_unit", text="")
 
         elif cam.type == 'ORTHO':
             col.prop(cam, "ortho_scale")
@@ -90,26 +98,55 @@ class DATA_PT_camera(CameraButtonsPanel, Panel):
 
         split = layout.split()
 
+        col = split.column()
+        col.label(text="Depth of Field:")
+
+        col.prop(cam, "dof_object", text="")
+
+        col = col.column()
+        if cam.dof_object is not None:
+            col.enabled = False
+        col.prop(cam, "dof_distance", text="Distance")
+
         col = split.column(align=True)
         col.label(text="Shift:")
         col.prop(cam, "shift_x", text="X")
         col.prop(cam, "shift_y", text="Y")
 
-        col = split.column(align=True)
-        col.label(text="Clipping:")
-        col.prop(cam, "clip_start", text="Start")
-        col.prop(cam, "clip_end", text="End")
 
-        layout.label(text="Depth of Field:")
+class DATA_PT_camera(CameraButtonsPanel, Panel):
+    bl_label = "Camera"
+    COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+
+    def draw(self, context):
+        layout = self.layout
+
+        cam = context.camera
+
+        row = layout.row(align=True)
+
+        row.menu("CAMERA_MT_presets", text=bpy.types.CAMERA_MT_presets.bl_label)
+        row.operator("camera.preset_add", text="", icon="ZOOMIN")
+        row.operator("camera.preset_add", text="", icon="ZOOMOUT").remove_active = True
+
+        layout.label(text="Sensor:")
 
         split = layout.split()
-        split.prop(cam, "dof_object", text="")
 
-        col = split.column()
+        col = split.column(align=True)
+        if cam.sensor_fit == 'AUTO':
+            col.prop(cam, "sensor_width", text="Size")
+        else:
+            col.prop(cam, "sensor_width", text="Width")
+            col.prop(cam, "sensor_height", text="Height")
 
-        if cam.dof_object is not None:
-            col.enabled = False
-        col.prop(cam, "dof_distance", text="Distance")
+        col = split.column(align=True)
+        col.prop(cam, "sensor_fit", text="")
+        layout.label(text="Clipping:")
+        row = layout.row(align=True)
+        row.prop(cam, "clip_start", text="Start")
+        row.prop(cam, "clip_end", text="End")
 
 
 class DATA_PT_camera_display(CameraButtonsPanel, Panel):
@@ -127,10 +164,12 @@ class DATA_PT_camera_display(CameraButtonsPanel, Panel):
         col.prop(cam, "show_limits", text="Limits")
         col.prop(cam, "show_mist", text="Mist")
         col.prop(cam, "show_title_safe", text="Title Safe")
+        col.prop(cam, "show_sensor", text="Sensor")
         col.prop(cam, "show_name", text="Name")
-        col.prop_menu_enum(cam, "show_guide")
 
         col = split.column()
+        col.prop_menu_enum(cam, "show_guide")
+        col.separator()
         col.prop(cam, "draw_size", text="Size")
         col.separator()
         col.prop(cam, "show_passepartout", text="Passepartout")
index 393568c6b60369498b5a9ea15251080363eaf927..c5a24c1e5e9bfdea1005dd08be2bbb5e69fc4ac1 100644 (file)
@@ -139,9 +139,12 @@ struct KeyBlock *object_insert_shape_key(struct Scene *scene, struct Object *ob,
 int object_is_modified(struct Scene *scene, struct Object *ob);
 
 void object_camera_mode(struct RenderData *rd, struct Object *camera);
+void object_camera_intrinsics(struct Object *camera, struct Camera **cam_r, short *is_ortho, float *shiftx, float *shifty,
+                       float *clipsta, float *clipend, float *lens, float *sensor_x, float *sensor_y, short *sensor_fit);
 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 *ycor,
+               float winmat[][4], struct rctf *viewplane, float *clipsta, float *clipend, float *lens,
+               float *sensor_x, float *sensor_y, short *sensor_fit, 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 a5edd569bc2345045307b80daee3f7775ab3a9e1..cec2f0f6895301b5b578f952858a0a9ac0be683f 100644 (file)
@@ -724,6 +724,7 @@ void *add_camera(const char *name)
        cam=  alloc_libblock(&G.main->camera, ID_CA, name);
 
        cam->lens= 35.0f;
+       cam->sensor_x = 32.f;
        cam->clipsta= 0.1f;
        cam->clipend= 100.0f;
        cam->drawsize= 0.5f;
@@ -2954,27 +2955,23 @@ void object_camera_mode(RenderData *rd, Object *camera)
        }
 }
 
-/* '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 *ycor,
-               float *viewdx, float *viewdy
-) {
-       Camera *cam=NULL;
-       float pixsize;
-       float shiftx=0.0, shifty=0.0, winside, viewfac;
-       short is_ortho= FALSE;
+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 *sensor_y, short *sensor_fit)
+{
+       Camera *cam= NULL;
 
-       /* question mark */
-       (*ycor)= rd->yasp / rd->xasp;
-       if(rd->mode & R_FIELDS)
-               (*ycor) *= 2.0f;
+       (*shiftx)= 0.0f;
+       (*shifty)= 0.0f;
+
+       (*sensor_x)= DEFAULT_SENSOR_WIDTH;
+       (*sensor_y)= DEFAULT_SENSOR_HEIGHT;
+       (*sensor_fit)= CAMERA_SENSOR_FIT_AUTO;
 
        if(camera->type==OB_CAMERA) {
                cam= camera->data;
 
                if(cam->type == CAM_ORTHO) {
-                       is_ortho= TRUE;
+                       *is_ortho= TRUE;
                }
 
                /* solve this too... all time depending stuff is in convertblender.c?
@@ -2987,11 +2984,14 @@ void object_camera_matrix(
                        execute_ipo(&cam->id, cam->ipo);
                }
 #endif // XXX old animation system
-               shiftx=cam->shiftx;
-               shifty=cam->shifty;
+               (*shiftx)=cam->shiftx;
+               (*shifty)=cam->shifty;
                (*lens)= cam->lens;
+               (*sensor_x)= cam->sensor_x;
+               (*sensor_y)= cam->sensor_y;
                (*clipsta)= cam->clipsta;
                (*clipend)= cam->clipend;
+               (*sensor_fit)= cam->sensor_fit;
        }
        else if(camera->type==OB_LAMP) {
                Lamp *la= camera->data;
@@ -3005,7 +3005,7 @@ void object_camera_matrix(
                (*clipend)= la->clipend;
        }
        else {  /* envmap exception... */;
-               if((*lens)==0.0f)
+               if((*lens)==0.0f) /* is this needed anymore? */
                        (*lens)= 16.0f;
 
                if((*clipsta)==0.0f || (*clipend)==0.0f) {
@@ -3014,25 +3014,69 @@ void object_camera_matrix(
                }
        }
 
+       (*cam_r)= cam;
+}
+
+/* '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 *sensor_y, short *sensor_fit, float *ycor,
+               float *viewdx, float *viewdy)
+{
+       Camera *cam=NULL;
+       float pixsize;
+       float shiftx=0.0, shifty=0.0, winside, viewfac;
+       short is_ortho= FALSE;
+
+       /* question mark */
+       (*ycor)= rd->yasp / rd->xasp;
+       if(rd->mode & R_FIELDS)
+               (*ycor) *= 2.0f;
+
+       object_camera_intrinsics(camera, &cam, &is_ortho, &shiftx, &shifty, clipsta, clipend, lens, sensor_x, sensor_y, sensor_fit);
+
        /* ortho only with camera available */
        if(cam && is_ortho) {
-               if(rd->xasp*winx >= rd->yasp*winy) {
+               if((*sensor_fit)==CAMERA_SENSOR_FIT_AUTO) {
+                       if(rd->xasp*winx >= rd->yasp*winy) viewfac= winx;
+                       else viewfac= (*ycor) * winy;
+               }
+               else if((*sensor_fit)==CAMERA_SENSOR_FIT_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)/32.0f;
-               else                                                            viewfac= (*ycor) * ((*lens) * winy)/32.0f;
+               if((*sensor_fit)==CAMERA_SENSOR_FIT_AUTO) {
+                       if(rd->xasp*winx >= rd->yasp*winy)      viewfac= ((*lens) * winx) / (*sensor_x);
+                       else                                    viewfac= (*ycor) * ((*lens) * winy) / (*sensor_x);
+               }
+               else if((*sensor_fit)==CAMERA_SENSOR_FIT_HOR) {
+                       viewfac= ((*lens) * winx) / (*sensor_x);
+               }
+               else if((*sensor_fit)==CAMERA_SENSOR_FIT_VERT) {
+                       viewfac= ((*lens) * winy) / (*sensor_y);
+               }
+
                pixsize= (*clipsta) / viewfac;
        }
 
        /* viewplane fully centered, zbuffer fills in jittered between -.5 and +.5 */
        winside= MAX2(winx, winy);
+
+       if(cam) {
+               if(cam->sensor_fit==CAMERA_SENSOR_FIT_HOR)
+                       winside= winx;
+               else if(cam->sensor_fit==CAMERA_SENSOR_FIT_VERT)
+                       winside= winy;
+       }
+
        viewplane->xmin= -0.5f*(float)winx + shiftx*winside;
        viewplane->ymin= -0.5f*(*ycor)*(float)winy + shifty*winside;
        viewplane->xmax=  0.5f*(float)winx + shiftx*winside;
@@ -3076,7 +3120,17 @@ void camera_view_frame_ex(Scene *scene, Camera *camera, float drawsize, const sh
                float aspx= (float) scene->r.xsch*scene->r.xasp;
                float aspy= (float) scene->r.ysch*scene->r.yasp;
 
-               if(aspx < aspy) {
+               if(camera->sensor_fit==CAMERA_SENSOR_FIT_AUTO) {
+                       if(aspx < aspy) {
+                               r_asp[0]= aspx / aspy;
+                               r_asp[1]= 1.0;
+                       }
+                       else {
+                               r_asp[0]= 1.0;
+                               r_asp[1]= aspy / aspx;
+                       }
+               }
+               else if(camera->sensor_fit==CAMERA_SENSOR_FIT_AUTO) {
                        r_asp[0]= aspx / aspy;
                        r_asp[1]= 1.0;
                }
@@ -3102,16 +3156,18 @@ void camera_view_frame_ex(Scene *scene, Camera *camera, float drawsize, const sh
        else {
                /* that way it's always visible - clipsta+0.1 */
                float fac;
+               float half_sensor= 0.5f*((camera->sensor_fit==CAMERA_SENSOR_FIT_VERT) ? (camera->sensor_y) : (camera->sensor_x));
+
                *r_drawsize= drawsize / ((scale[0] + scale[1] + scale[2]) / 3.0f);
 
                if(do_clip) {
                        /* fixed depth, variable size (avoids exceeding clipping range) */
                        depth = -(camera->clipsta + 0.1f);
-                       fac = depth / (camera->lens/-16.0f * scale[2]);
+                       fac = depth / (camera->lens/(-half_sensor) * scale[2]);
                }
                else {
                        /* fixed size, variable depth (stays a reasonable size in the 3D view) */
-                       depth= *r_drawsize * camera->lens/-16.0f * scale[2];
+                       depth= *r_drawsize * camera->lens/(-half_sensor) * scale[2];
                        fac= *r_drawsize;
                }
 
index aef1c4bb46cb4e13c17a4ac92e2924f342562868..fca7c3469a1d08cd0c0714412ee4b45cbd259a5a 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 lens_to_angle(float lens);
-float angle_to_lens(float angle);
+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 0ca8b72c1e3d140662aa3052ff89cd7c9e8ddf22..7fecbae8229eeb02c842ef16b7f0965a6e85d26b 100644 (file)
@@ -1688,14 +1688,14 @@ void vec_apply_track(float vec[3], short axis)
 }
 
 /* lens/angle conversion (radians) */
-float lens_to_angle(float lens)
+float focallength_to_fov(float focal_length, float sensor)
 {
-       return 2.0f * atanf(16.0f/lens);
+       return 2.0f * atanf((sensor/2.0f) / focal_length);
 }
 
-float angle_to_lens(float angle)
+float fov_to_focallength(float hfov, float sensor)
 {
-       return 16.0f / tanf(angle * 0.5f);
+       return (sensor/2.0f) / tanf(hfov * 0.5f);
 }
 
 /* 'mod_inline(-3,4)= 1', 'fmod(-3,4)= -3' */
index 30625e7b34eb5401fd49bc56beb06d79dcbd2a35..8b00d8e48a69ec9c570d2d97d114824f62160317 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= lens_to_angle(camera->lens) / 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 8427f7c326ad7e11d1e11198894d28da0c1dc1d5..ea8e8f30d76fe1366a1686fab52cb55e6fb50787 100644 (file)
@@ -12154,11 +12154,21 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                }
                        }
                }
+
        }
 
        /* put compatibility code here until next subversion bump */
        {
-               
+               {
+                       Camera *cam;
+                       for(cam= main->camera.first; cam; cam= cam->id.next) {
+                               if (cam->sensor_x < 0.01)
+                                       cam->sensor_x = DEFAULT_SENSOR_WIDTH;
+
+                               if (cam->sensor_y < 0.01)
+                                       cam->sensor_y = DEFAULT_SENSOR_HEIGHT;
+                       }
+               }
        }
 
        /* WATCH IT!!!: pointers from libdata have not been converted yet here! */
index 6fa2c8763e06ae2773303a9417ad8822bce124b1..fcb98cc7c32d10f9dd9e152a3f03c31ba80d76c0 100644 (file)
@@ -71,7 +71,7 @@ void CamerasExporter::operator()(Object *ob, Scene *sce)
        
        if (cam->type == CAM_PERSP) {
                COLLADASW::PerspectiveOptic persp(mSW);
-               persp.setXFov(RAD2DEGF(lens_to_angle(cam->lens)), "xfov");
+               persp.setXFov(RAD2DEGF(focallength_to_fov(cam->lens, cam->sensor_x)), "xfov");
                persp.setAspectRatio((float)(sce->r.xsch)/(float)(sce->r.ysch),false,"aspect_ratio");
                persp.setZFar(cam->clipend, false , "zfar");
                persp.setZNear(cam->clipsta,false , "znear");
index 8d133979fa4f655bdc6d332c2131cbad7fc8ea52..8cdb1065699b66b23cd5f17f68de1c7c1ee6fda0 100644 (file)
@@ -814,7 +814,7 @@ bool DocumentImporter::writeCamera( const COLLADAFW::Camera* camera )
                                                double aspect = camera->getAspectRatio().getValue();
                                                double xfov = aspect*yfov;
                                                // xfov is in degrees, cam->lens is in millimiters
-                                               cam->lens = angle_to_lens(DEG2RADF(xfov));
+                                               cam->lens = fov_to_focallength(DEG2RADF(xfov), cam->sensor_x);
                                        }
                                        break;
                        }
@@ -835,7 +835,7 @@ bool DocumentImporter::writeCamera( const COLLADAFW::Camera* camera )
                                        {
                                                double x = camera->getXFov().getValue();
                                                // x is in degrees, cam->lens is in millimiters
-                                               cam->lens = angle_to_lens(DEG2RADF(x));
+                                               cam->lens = fov_to_focallength(DEG2RADF(x), cam->sensor_x);
                                        }
                                        break;
                        }
@@ -852,7 +852,7 @@ bool DocumentImporter::writeCamera( const COLLADAFW::Camera* camera )
                                        {
                                        double yfov = camera->getYFov().getValue();
                                        // yfov is in degrees, cam->lens is in millimiters
-                                       cam->lens = angle_to_lens(DEG2RADF(yfov));
+                                       cam->lens = fov_to_focallength(DEG2RADF(yfov), cam->sensor_x);
                                        }
                                        break;
                        }
index d49ce0cf49abf31588908f1b27052bafc27e48a9..92544b2309c8123a2695b2464181fc9fe4ebc6d5 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;
+                               float _viewdx, _viewdy, _ycor, _lens=0.0f, _sensor_x=DEFAULT_SENSOR_WIDTH, _sensor_y= DEFAULT_SENSOR_HEIGHT;
+                               short _sensor_fit= CAMERA_SENSOR_FIT_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, &_ycor, &_viewdx, &_viewdy);
+                                               &_lens, &_sensor_x, &_sensor_x, &_sensor_fit, &_ycor, &_viewdx, &_viewdy);
 
                                ps->is_ortho= (ps->scene->r.mode & R_ORTHO) ? 1 : 0;
                        }
index 96031a7b3d3d59e69fa60fdab73d48852bf80644..a764ae77c9d4f7d2c7f0f84b126abb7913cbb2ab 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 sensor_fit= CAMERA_SENSOR_FIT_AUTO;
+
+       if(camob && camob->type==OB_CAMERA) {
+               Camera *cam= (Camera *)camob->data;
+               sensor_fit= cam->sensor_fit;
+       }
+
+       if(sensor_fit==CAMERA_SENSOR_FIT_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(sensor_fit==CAMERA_SENSOR_FIT_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;
@@ -1208,6 +1225,21 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d)
                        uiSetRoundBox(UI_CNR_ALL);
                        uiDrawBox(GL_LINE_LOOP, x1, y1, x2, y2, 12.0);
                }
+               if (ca && (ca->flag & CAM_SHOWSENSOR)) {
+                       /* assume fixed sensor width for now */
+
+                       float sensor_aspect = ca->sensor_x / ca->sensor_y;
+                       float sensor_scale = (x2i-x1i) / ca->sensor_x;
+                       float sensor_height = sensor_scale * ca->sensor_y;
+
+                       float ymid = y1i + (y2i-y1i)/2.f;
+                       float sy1= ymid - sensor_height/2.f;
+                       float sy2= ymid + sensor_height/2.f;
+
+                       UI_ThemeColorShade(TH_WIRE, 100);
+
+                       uiDrawBox(GL_LINE_LOOP, x1i, sy1, x2i, sy2, 2.0);
+               }
        }
 
        setlinestyle(0);
@@ -2396,10 +2428,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;
+               float _clipsta, _clipend, _lens, _yco, _dx, _dy, _sensor_x= DEFAULT_SENSOR_WIDTH, _sensor_y= DEFAULT_SENSOR_HEIGHT;
+               short _sensor_fit= CAMERA_SENSOR_FIT_AUTO;
                rctf _viewplane;
 
-               object_camera_matrix(&scene->r, v3d->camera, sizex, sizey, 0, winmat, &_viewplane, &_clipsta, &_clipend, &_lens, &_yco, &_dx, &_dy);
+               object_camera_matrix(&scene->r, v3d->camera, sizex, sizey, 0, winmat, &_viewplane, &_clipsta, &_clipend, &_lens,
+                       &_sensor_x, &_sensor_y, &_sensor_fit, &_yco, &_dx, &_dy);
 
                ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat);
        }
@@ -2454,9 +2488,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;
+               float _yco, _dx, _dy, _sensor_x= DEFAULT_SENSOR_WIDTH, _sensor_y= DEFAULT_SENSOR_HEIGHT;
+               short _sensor_fit= CAMERA_SENSOR_FIT_AUTO;
                rctf _viewplane;
-               object_camera_matrix(&scene->r, v3d.camera, width, height, 0, rv3d.winmat, &_viewplane, &v3d.near, &v3d.far, &v3d.lens, &_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, &_sensor_fit, &_yco, &_dx, &_dy);
        }
 
        mul_m4_m4m4(rv3d.persmat, rv3d.viewmat, rv3d.winmat);
index ea8db17daf0a33f863016ea13d90ebc02b2a9df2..e7fbdaf1debb7abce8c22466cb9211a17512cd21 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 b087c7ac8736d05115d3d127079dbf9a57f16fe1..b07d2d1ca738bbb90610a3421ac7b1c5b461b54b 100644 (file)
@@ -135,7 +135,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 Object *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 93c577619dea4c070efd4f47be1c144447df490e..7de1f2a85bb8dd03387f0aa02c356027b6639959 100644 (file)
@@ -966,10 +966,14 @@ 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, 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 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;
@@ -992,8 +996,13 @@ 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_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);
                        }
                }
        }
@@ -1024,21 +1033,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(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;
-                       
-                       if(winx>winy) y1= -winy*dfac/winx;
-                       else y1= -dfac;
                        y2= -y1;
+
                        orth= 1;
                }
                else {
                        float dfac;
                        
-                       if(winx>winy) dfac= 64.0f/(fac*winx*lens);
-                       else dfac= 64.0f/(fac*winy*lens);
+                       if(sensor_fit==CAMERA_SENSOR_FIT_AUTO) {
+                               if(winx>winy) dfac= (sensor_x * 2.0) / (fac*winx*lens);
+                               else dfac= (sensor_x * 2.0) / (fac*winy*lens);
+                       }
+                       else if(sensor_fit==CAMERA_SENSOR_FIT_HOR) {
+                               dfac= (sensor_x * 2.0) / (fac*winx*lens);
+                       }
+                       else {
+                               dfac= (sensor_y * 2.0) / (fac*winy*lens);
+                       }
                        
                        x1= - *clipsta * winx*dfac;
                        x2= -x1;
@@ -1057,8 +1089,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) * 32.0f;
-                               dy += cam->shifty * (cam->clipsta / cam->lens) * 32.0f;
+                               dx += cam->shiftx * (cam->clipsta / cam->lens) * sensor;
+                               dy += cam->shifty * (cam->clipsta / cam->lens) * sensor;
                        }
 
                        x1+= dx;
@@ -1076,7 +1108,14 @@ int ED_view3d_viewplane_get(View3D *v3d, RegionView3D *rv3d, int winxi, int winy
                        *pixsize= 1.0f/viewfac;
                }
                else {
-                       viewfac= (((winx >= winy)? winx: winy)*lens)/32.0f;
+                       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;
+
+                       viewfac= (size*lens)/sensor;
                        *pixsize= *clipsta/viewfac;
                }
        }
index 8ad6821702a582e8ec3ec5f8631d19e8ec27f1bc..292f920da66f4179d06907165ebe2ae28f04600f 100644 (file)
@@ -51,6 +51,7 @@ typedef struct Camera {
        float passepartalpha;
        float clipsta, clipend;
        float lens, ortho_scale, drawsize;
+       float sensor_x, sensor_y;
        float shiftx, shifty;
        
        /* yafray: dof params */
@@ -61,6 +62,9 @@ typedef struct Camera {
        struct Ipo *ipo;                        // XXX depreceated... old animation system
        
        struct Object *dof_ob;
+
+       char sensor_fit;
+       char pad[7];
 } Camera;
 
 /* **************** CAMERA ********************* */
@@ -88,10 +92,18 @@ typedef struct Camera {
 #define CAM_ANGLETOGGLE                32
 #define CAM_DS_EXPAND          64
 #define CAM_PANORAMA           128
+#define CAM_SHOWSENSOR         256
 
 /* yafray: dof sampling switch */
 /* #define CAM_YF_NO_QMC       512 */ /* depreceated */
 
+/* Sensor fit */
+#define CAMERA_SENSOR_FIT_AUTO 0
+#define CAMERA_SENSOR_FIT_HOR  1
+#define CAMERA_SENSOR_FIT_VERT 2
+
+#define DEFAULT_SENSOR_WIDTH   32.0f
+#define DEFAULT_SENSOR_HEIGHT  18.0f
 
 #ifdef __cplusplus
 }
index 9e89c4aaab0a62911116e8793a43763e71da5ea4..1e7a969caaa3a07b02130baef013ed4c5b7f0b5b 100644 (file)
 #ifdef RNA_RUNTIME
 
 #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;
-
-       return lens_to_angle(cam->lens);
+       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= angle_to_lens(value);
+       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)
+{
+       Camera *camera= (Camera*)ptr->id.data;
+
+       DAG_id_tag_update(&camera->id, 0);
 }
 
 #else
@@ -79,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 sensor_fit_items[] = {
+               {CAMERA_SENSOR_FIT_AUTO, "AUTO", 0, "Auto", "Calculate field of view using sensor size, with direction depending on image resolution"},
+               {CAMERA_SENSOR_FIT_HOR, "HORIZONTAL", 0, "Horizontal", "Calculate field of view using sensor width"},
+               {CAMERA_SENSOR_FIT_VERT, "VERTICAL", 0, "Vertical", "Calculate field of view 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");
@@ -88,7 +139,7 @@ void RNA_def_camera(BlenderRNA *brna)
        prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
        RNA_def_property_enum_items(prop, prop_type_items);
        RNA_def_property_ui_text(prop, "Type", "Camera types");
-       RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL);
+       RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Camera_update");
 
        prop= RNA_def_property(srna, "show_guide", PROP_ENUM, PROP_NONE);
        RNA_def_property_enum_sdna(prop, NULL, "dtx");
@@ -96,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, "sensor_fit", PROP_ENUM, PROP_NONE);
+       RNA_def_property_enum_sdna(prop, NULL, "sensor_fit");
+       RNA_def_property_enum_items(prop, sensor_fit_items);
+       RNA_def_property_ui_text(prop, "Sensor Fit", "Mode of calculating field of view from sensor dimensions 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);
@@ -104,6 +161,27 @@ 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 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");
+
        prop= RNA_def_property(srna, "clip_start", PROP_FLOAT, PROP_DISTANCE);
        RNA_def_property_float_sdna(prop, NULL, "clipsta");
        RNA_def_property_range(prop, 0.001f, FLT_MAX);
@@ -120,20 +198,27 @@ void RNA_def_camera(BlenderRNA *brna)
        RNA_def_property_float_sdna(prop, NULL, "lens");
        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, NULL);
-       
-       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, "Angle", "Perspective Camera lens field of view in degrees");
-       RNA_def_property_float_funcs(prop, "rna_Camera_angle_get", "rna_Camera_angle_set", NULL); /* only for deg/rad conversion */
-       RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL);
+       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 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);
        RNA_def_property_float_sdna(prop, NULL, "ortho_scale");
        RNA_def_property_range(prop, 0.01f, 4000.0f);
        RNA_def_property_ui_text(prop, "Orthographic Scale", "Orthographic Camera scale (similar to zoom)");
-       RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL);
+       RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Camera_update");
 
        prop= RNA_def_property(srna, "draw_size", PROP_FLOAT, PROP_DISTANCE);
        RNA_def_property_float_sdna(prop, NULL, "drawsize");
@@ -147,14 +232,14 @@ void RNA_def_camera(BlenderRNA *brna)
        RNA_def_property_range(prop, -10.0f, 10.0f);
        RNA_def_property_ui_range(prop, -2.0, 2.0, 1, 3);
        RNA_def_property_ui_text(prop, "Shift X", "Perspective Camera horizontal shift");
-       RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL);
+       RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Camera_update");
 
        prop= RNA_def_property(srna, "shift_y", PROP_FLOAT, PROP_NONE);
        RNA_def_property_float_sdna(prop, NULL, "shifty");
        RNA_def_property_range(prop, -10.0f, 10.0f);
        RNA_def_property_ui_range(prop, -2.0, 2.0, 1, 3);
        RNA_def_property_ui_text(prop, "Shift Y", "Perspective Camera vertical shift");
-       RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL);
+       RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Camera_update");
 
        prop= RNA_def_property(srna, "dof_distance", PROP_FLOAT, PROP_DISTANCE);
        RNA_def_property_float_sdna(prop, NULL, "YF_dofdist");
@@ -188,6 +273,11 @@ void RNA_def_camera(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Show Name", "Show the active Camera's name in Camera view");
        RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL);
 
+       prop= RNA_def_property(srna, "show_sensor", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "flag", CAM_SHOWSENSOR);
+       RNA_def_property_ui_text(prop, "Show Sensor Size", "Show sensor size (film gate) in Camera view");
+       RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL);
+
        prop= RNA_def_property(srna, "lens_unit", PROP_ENUM, PROP_NONE);
        RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
        RNA_def_property_enum_items(prop, prop_lens_unit_items);
index 36d773ad605548fc31ef3662b898ff64ebb2b172..d5dd0078a8093a8be3fb97272e468ec4c8ed127a 100644 (file)
@@ -38,6 +38,7 @@
 #include "DNA_meshdata_types.h"
 #include "DNA_camera_types.h"
 #include "DNA_object_types.h"
+#include "DNA_scene_types.h"
 
 #include "BLI_math.h"
 #include "BLI_string.h"
@@ -159,7 +160,7 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
        float scax= umd->scalex ? umd->scalex : 1.0f;
        float scay= umd->scaley ? umd->scaley : 1.0f;
        int free_uci= 0;
-       
+
        aspect = aspx / aspy;
 
        for(i = 0; i < umd->num_projectors; ++i)
@@ -194,16 +195,28 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
                                free_uci= 1;
                        }
                        else {
-                               float scale= (cam->type == CAM_PERSP) ? cam->clipsta * 32.0f / cam->lens : cam->ortho_scale;
+                               float sensor= (cam->sensor_fit == CAMERA_SENSOR_FIT_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->sensor_fit==CAMERA_SENSOR_FIT_AUTO) {
+                                       if(aspect > 1.0f) {
+                                               xmax = 0.5f * scale;
+                                               ymax = xmax / aspect;
+                                       } else {
+                                               ymax = 0.5f * scale;
+                                               xmax = ymax * aspect;
+                                       }
+                               }
+                               else if(cam->sensor_fit==CAMERA_SENSOR_FIT_HOR) {
                                        xmax = 0.5f * scale;
                                        ymax = xmax / aspect;
-                               } else {
+                               }
+                               else {
                                        ymax = 0.5f * scale;
                                        xmax = ymax * aspect;
                                }
+
                                xmin = -xmax;
                                ymin = -ymax;
 
index ae4e55b9b883fbb8020eb046eec117b6175c5e69..7cad8c36df4b43a12f909526d8bb4a0053f9009d 100644 (file)
@@ -153,7 +153,9 @@ struct Render
        
        /* values for viewing */
        float lens;
+       float sensor_x, sensor_y; /* image sensor size, same variable in camera */
        float ycor; /* (scene->xasp / scene->yasp), multiplied with 'winy' */
+       short sensor_fit;
        
        float panophi, panosi, panoco, panodxp, panodxv;
        
index e285b9b1ed9fa1ebe28973b397bef8051a57ca07..2f20c3284057b40eee692507ad5d688cdcfe71d5 100644 (file)
@@ -157,6 +157,7 @@ static Render *envmap_render_copy(Render *re, EnvMap *env)
 
        /* view stuff in env render */
        envre->lens= 16.0f;
+       envre->sensor_x= 32.0f;
        if(env->type==ENV_PLANE)
                envre->lens*= env->viewscale;
        envre->ycor= 1.0f; 
index 091a64e418e7bbbc891348f514c650fa5df144fa..f8e4ee8f6a75507bc128cede7c37f48b1082ee64 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->ycor, &re->viewdx, &re->viewdy);
+                       &re->lens, &re->sensor_x, &re->sensor_y, &re->sensor_fit, &re->ycor, &re->viewdx, &re->viewdy);
 }
 
 void RE_SetPixelSize(Render *re, float pixsize)
index 77bd6e0f3740f929cf535f9563e0c7662c2e8edc..ca37b06d12e785b564d4b08c6540336fd174ad7c 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->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->sensor_fit, 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 77438b8f48a3688b50ee273491412a740abedb0b..14a307794db55b828b267c5a80105142f48e0b0f 100644 (file)
@@ -200,7 +200,26 @@ float KX_Camera::GetScale() const
        return m_camdata.m_scale;
 }
 
+/*
+* Gets the horizontal size of the sensor - for camera matching.
+*/
+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::GetSensorFit() const
+{
+       return m_camdata.m_sensor_fit;
+}
 
 float KX_Camera::GetCameraNear() const
 {
index 4c8cf21a7bf5f197f771e58f69e4454995605272..236e914b9e5eccb4a700c55a3161455a4fb6f4e1 100644 (file)
@@ -199,6 +199,12 @@ public:
        float                           GetLens() const;
        /** Gets the ortho scale. */
        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                           GetSensorFit() const;
        /** Gets the near clip distance. */
        float                           GetCameraNear() const;
        /** Gets the far clip distance. */
index 5de6adc5af4c72f20745be23bbbfda94312e4e51..a9be588e6b2e0df9b96413391ab2857fd0fec240 100644 (file)
@@ -1251,6 +1251,7 @@ void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam)
                                cam->GetScale(),
                                nearfrust,
                                farfrust,
+                               cam->GetSensorFit(),
                                frustum
                        );
                        if (!cam->GetViewport()) {
@@ -1268,6 +1269,9 @@ void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam)
                                area,
                                viewport,
                                cam->GetLens(),
+                               cam->GetSensorWidth(),
+                               cam->GetSensorHeight(),
+                               cam->GetSensorFit(),
                                nearfrust,
                                farfrust,
                                frustum
index 2056068a2ad8c343cef90a6c8ee737f68882a5ef..2120a18f1394cd295dd6a6634889f08ab7fe7935 100644 (file)
@@ -36,6 +36,9 @@ struct RAS_CameraData
 {
        float m_lens;
        float m_scale;
+       float m_sensor_x;
+       float m_sensor_y;
+       short m_sensor_fit;
        float m_clipstart;
        float m_clipend;
        bool m_perspective;
@@ -46,11 +49,15 @@ struct RAS_CameraData
        int m_viewporttop;
        float m_focallength;
 
-       RAS_CameraData(float lens = 35.0, float scale = 6.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 sensor_fit = 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_sensor_fit(sensor_fit),
            m_clipstart(clipstart),
            m_clipend(clipend),
            m_perspective(perspective),
index da6c230ffc1cbb4e0e54a0d42ccfa986a1500d53..8a5c10b3a3b2807191cd24b86a3349452fbdc983 100644 (file)
@@ -39,25 +39,35 @@ ComputeDefaultFrustum(
        const float camnear,
        const float camfar,
        const float lens,
+       const float sensor_x, const float sensor_y,
+       const short sensor_fit,
        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.
-        */
-       float halfSize = 16.f * camnear / lens;
+){             
+       float halfSize;
        float sizeX;
        float sizeY;
 
-       if (design_aspect_ratio > 1.f) {
-               // halfsize defines the width
+       if(sensor_fit==RAS_SENSORFIT_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(sensor_fit==RAS_SENSORFIT_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;
        }
@@ -77,6 +87,7 @@ ComputeDefaultOrtho(
        const float camfar,
        const float scale,
        const float design_aspect_ratio,
+       const short sensor_fit,
        RAS_FrameFrustum & frustum
 )
 {
@@ -84,12 +95,22 @@ ComputeDefaultOrtho(
        float sizeX;
        float sizeY;
 
-       if (design_aspect_ratio > 1.f) {
-               // halfsize defines the width
+       if(sensor_fit==RAS_SENSORFIT_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(sensor_fit==RAS_SENSORFIT_HOR) {
                sizeX = halfSize;
                sizeY = halfSize/design_aspect_ratio;
-       } else {
-               // halfsize defines the height
+       }
+       else {
                sizeX = halfSize * design_aspect_ratio;
                sizeY = halfSize;
        }
@@ -199,6 +220,7 @@ ComputeFrustum(
        const RAS_Rect &availableViewport,
        const RAS_Rect &viewport,
        const float lens,
+       const float sensor_x, const float sensor_y, const short sensor_fit,
        const float camnear,
        const float camfar,
        RAS_FrameFrustum &frustum
@@ -224,6 +246,9 @@ ComputeFrustum(
                camnear,
                camfar,
                lens,
+               sensor_x,
+               sensor_y,
+               sensor_fit,
                design_aspect_ratio,
                frustum
        );
@@ -269,6 +294,7 @@ RAS_FramingManager::
                const float scale,
                const float camnear,
                const float camfar,
+               const short sensor_fit,
                RAS_FrameFrustum &frustum
        )
 {
@@ -293,6 +319,7 @@ RAS_FramingManager::
                camfar,
                scale,
                design_aspect_ratio,
+               sensor_fit,
                frustum
        );
 
index 38ea8f4e07af6248ab3d77ed011d998ecd967407..612142234e39144194c7ddc6783d0b99d783fcff 100644 (file)
@@ -184,6 +184,14 @@ enum RAS_CullingMode
        RAS_CULLING_NONE
 };
 
+/* Should match CAMERA_SENSOR_FIT... from DNA_camera_types.h */
+enum RAS_SensorFit
+{
+       RAS_SENSORFIT_AUTO = 0,
+       RAS_SENSORFIT_HOR,
+       RAS_SENSORFIT_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 sensor_fit,
                RAS_FrameFrustum &frustum
        );
 
@@ -239,6 +248,7 @@ public :
                const RAS_Rect &availableViewport,
                const RAS_Rect &viewport,
                const float lens,
+               const float sensor_x, const float sensor_y, const short sensor_fit,
                const float camnear,
                const float camfar,
                RAS_FrameFrustum &frustum
@@ -250,6 +260,8 @@ public :
                const float camnear,
                const float camfar,
                const float lens,
+               const float sensor_x, const float sensor_y,
+               const short sensor_fit,
                const float design_aspect_ratio,
                RAS_FrameFrustum & frustum
        );      
@@ -261,6 +273,7 @@ public :
                const float camfar,
                const float scale,
                const float design_aspect_ratio,
+               const short sensor_fit,
                RAS_FrameFrustum & frustum
        );
 
index 912d586456004c18172cd60351aa682922931adb..a349b45e4037ea01dec061e649898a0e9cab3410 100644 (file)
@@ -214,6 +214,8 @@ void ImageRender::Render()
        } else
        {
                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();
@@ -233,6 +235,7 @@ void ImageRender::Render()
                                    farfrust,
                                    m_camera->GetScale(),
                                    aspect_ratio,
+                                               m_camera->GetSensorFit(),
                                    frustrum
                                    );
 
@@ -244,6 +247,9 @@ void ImageRender::Render()
                                    nearfrust,
                                    farfrust,
                                    lens,
+                                   sensor_x,
+                                   sensor_y,
+                                   RAS_SENSORFIT_AUTO,
                                    aspect_ratio,
                                    frustrum);