Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2011-11-04 18:36:06 +0400
committerSergey Sharybin <sergey.vfx@gmail.com>2011-11-04 18:36:06 +0400
commit4ea816837de646af124ffc82758cae37950a0a51 (patch)
tree771c7a0e084446080d6f6d12258585a479bf2887 /source
parent82dc05391cdda573f1523325bfd4c6a2a5233323 (diff)
Configurable sensor size:
- 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.
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_object.h5
-rw-r--r--source/blender/blenkernel/intern/object.c104
-rw-r--r--source/blender/blenlib/BLI_math_rotation.h4
-rw-r--r--source/blender/blenlib/intern/math_rotation.c8
-rw-r--r--source/blender/blenlib/intern/uvproject.c2
-rw-r--r--source/blender/blenloader/intern/readfile.c12
-rw-r--r--source/blender/collada/CameraExporter.cpp2
-rw-r--r--source/blender/collada/DocumentImporter.cpp6
-rw-r--r--source/blender/editors/sculpt_paint/paint_image.c6
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c63
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c9
-rw-r--r--source/blender/editors/space_view3d/view3d_intern.h2
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c65
-rw-r--r--source/blender/makesdna/DNA_camera_types.h12
-rw-r--r--source/blender/makesrna/intern/rna_camera.c122
-rw-r--r--source/blender/modifiers/intern/MOD_uvproject.c21
-rw-r--r--source/blender/render/intern/include/render_types.h2
-rw-r--r--source/blender/render/intern/source/envmap.c1
-rw-r--r--source/blender/render/intern/source/initrender.c2
-rw-r--r--source/gameengine/Converter/BL_BlenderDataConversion.cpp2
-rw-r--r--source/gameengine/Ketsji/KX_Camera.cpp19
-rw-r--r--source/gameengine/Ketsji/KX_Camera.h6
-rw-r--r--source/gameengine/Ketsji/KX_KetsjiEngine.cpp4
-rw-r--r--source/gameengine/Rasterizer/RAS_CameraData.h9
-rw-r--r--source/gameengine/Rasterizer/RAS_FramingManager.cpp59
-rw-r--r--source/gameengine/Rasterizer/RAS_FramingManager.h13
-rw-r--r--source/gameengine/VideoTexture/ImageRender.cpp6
27 files changed, 456 insertions, 110 deletions
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index 393568c6b60..c5a24c1e5e9 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -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],
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index a5edd569bc2..cec2f0f6895 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -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;
}
diff --git a/source/blender/blenlib/BLI_math_rotation.h b/source/blender/blenlib/BLI_math_rotation.h
index aef1c4bb46c..fca7c3469a1 100644
--- a/source/blender/blenlib/BLI_math_rotation.h
+++ b/source/blender/blenlib/BLI_math_rotation.h
@@ -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);
diff --git a/source/blender/blenlib/intern/math_rotation.c b/source/blender/blenlib/intern/math_rotation.c
index 0ca8b72c1e3..7fecbae8229 100644
--- a/source/blender/blenlib/intern/math_rotation.c
+++ b/source/blender/blenlib/intern/math_rotation.c
@@ -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' */
diff --git a/source/blender/blenlib/intern/uvproject.c b/source/blender/blenlib/intern/uvproject.c
index 30625e7b34e..8b00d8e48a6 100644
--- a/source/blender/blenlib/intern/uvproject.c
+++ b/source/blender/blenlib/intern/uvproject.c
@@ -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 */
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 8427f7c326a..ea8e8f30d76 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -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! */
diff --git a/source/blender/collada/CameraExporter.cpp b/source/blender/collada/CameraExporter.cpp
index 6fa2c8763e0..fcb98cc7c32 100644
--- a/source/blender/collada/CameraExporter.cpp
+++ b/source/blender/collada/CameraExporter.cpp
@@ -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");
diff --git a/source/blender/collada/DocumentImporter.cpp b/source/blender/collada/DocumentImporter.cpp
index 8d133979fa4..8cdb1065699 100644
--- a/source/blender/collada/DocumentImporter.cpp
+++ b/source/blender/collada/DocumentImporter.cpp
@@ -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;
}
diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c
index d49ce0cf49a..92544b2309c 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.c
@@ -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;
}
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 96031a7b3d3..a764ae77c9d 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -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);
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index ea8db17daf0..e7fbdaf1deb 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -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));
diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h
index b087c7ac873..b07d2d1ca73 100644
--- a/source/blender/editors/space_view3d/view3d_intern.h
+++ b/source/blender/editors/space_view3d/view3d_intern.h
@@ -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);
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index 93c577619de..7de1f2a85bb 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -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;
}
}
diff --git a/source/blender/makesdna/DNA_camera_types.h b/source/blender/makesdna/DNA_camera_types.h
index 8ad6821702a..292f920da66 100644
--- a/source/blender/makesdna/DNA_camera_types.h
+++ b/source/blender/makesdna/DNA_camera_types.h
@@ -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
}
diff --git a/source/blender/makesrna/intern/rna_camera.c b/source/blender/makesrna/intern/rna_camera.c
index 9e89c4aaab0..1e7a969caaa 100644
--- a/source/blender/makesrna/intern/rna_camera.c
+++ b/source/blender/makesrna/intern/rna_camera.c
@@ -40,19 +40,65 @@
#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);
diff --git a/source/blender/modifiers/intern/MOD_uvproject.c b/source/blender/modifiers/intern/MOD_uvproject.c
index 36d773ad605..d5dd0078a80 100644
--- a/source/blender/modifiers/intern/MOD_uvproject.c
+++ b/source/blender/modifiers/intern/MOD_uvproject.c
@@ -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;
diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h
index ae4e55b9b88..7cad8c36df4 100644
--- a/source/blender/render/intern/include/render_types.h
+++ b/source/blender/render/intern/include/render_types.h
@@ -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;
diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c
index e285b9b1ed9..2f20c328405 100644
--- a/source/blender/render/intern/source/envmap.c
+++ b/source/blender/render/intern/source/envmap.c
@@ -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;
diff --git a/source/blender/render/intern/source/initrender.c b/source/blender/render/intern/source/initrender.c
index 091a64e418e..f8e4ee8f6a7 100644
--- a/source/blender/render/intern/source/initrender.c
+++ b/source/blender/render/intern/source/initrender.c
@@ -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)
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
index 77bd6e0f374..ca37b06d12e 100644
--- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
@@ -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);
diff --git a/source/gameengine/Ketsji/KX_Camera.cpp b/source/gameengine/Ketsji/KX_Camera.cpp
index 77438b8f48a..14a307794db 100644
--- a/source/gameengine/Ketsji/KX_Camera.cpp
+++ b/source/gameengine/Ketsji/KX_Camera.cpp
@@ -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
{
diff --git a/source/gameengine/Ketsji/KX_Camera.h b/source/gameengine/Ketsji/KX_Camera.h
index 4c8cf21a7bf..236e914b9e5 100644
--- a/source/gameengine/Ketsji/KX_Camera.h
+++ b/source/gameengine/Ketsji/KX_Camera.h
@@ -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. */
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
index 5de6adc5af4..a9be588e6b2 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
@@ -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
diff --git a/source/gameengine/Rasterizer/RAS_CameraData.h b/source/gameengine/Rasterizer/RAS_CameraData.h
index 2056068a2ad..2120a18f139 100644
--- a/source/gameengine/Rasterizer/RAS_CameraData.h
+++ b/source/gameengine/Rasterizer/RAS_CameraData.h
@@ -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),
diff --git a/source/gameengine/Rasterizer/RAS_FramingManager.cpp b/source/gameengine/Rasterizer/RAS_FramingManager.cpp
index da6c230ffc1..8a5c10b3a3b 100644
--- a/source/gameengine/Rasterizer/RAS_FramingManager.cpp
+++ b/source/gameengine/Rasterizer/RAS_FramingManager.cpp
@@ -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
);
diff --git a/source/gameengine/Rasterizer/RAS_FramingManager.h b/source/gameengine/Rasterizer/RAS_FramingManager.h
index 38ea8f4e07a..612142234e3 100644
--- a/source/gameengine/Rasterizer/RAS_FramingManager.h
+++ b/source/gameengine/Rasterizer/RAS_FramingManager.h
@@ -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
);
diff --git a/source/gameengine/VideoTexture/ImageRender.cpp b/source/gameengine/VideoTexture/ImageRender.cpp
index 912d5864560..a349b45e403 100644
--- a/source/gameengine/VideoTexture/ImageRender.cpp
+++ b/source/gameengine/VideoTexture/ImageRender.cpp
@@ -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);