Camera: some code refactoring, use an intermediate CameraParams struct instead

of long list of variables everywhere. Intention is to also let 3d view use this
eventually, instead of duplicating code.
This commit is contained in:
Brecht Van Lommel 2011-11-18 15:52:00 +00:00
parent 02ce6fd59c
commit 539c94a051
11 changed files with 272 additions and 194 deletions

@ -36,6 +36,8 @@
extern "C" {
#endif
#include "DNA_vec_types.h"
struct Camera;
struct Object;
struct RenderData;
@ -48,16 +50,54 @@ struct Camera *copy_camera(struct Camera *cam);
void make_local_camera(struct Camera *cam);
void free_camera(struct Camera *ca);
float dof_camera(struct Object *ob);
/* Camera Object */
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 *sensor_x, float *sensor_y, short *sensor_fit, float *ycor,
float *viewdx, float *viewdy);
float object_camera_dof_distance(struct Object *ob);
void object_camera_mode(struct RenderData *rd, struct Object *ob);
/* Camera Parameters:
*
* Intermediate struct for storing camera parameters from various sources,
* to unify computation of viewplane, window matrix, ... */
typedef struct CameraParams {
/* lens */
int is_ortho;
float lens;
float ortho_scale;
float shiftx;
float shifty;
/* sensor */
float sensor_x;
float sensor_y;
int sensor_fit;
/* clipping */
float clipsta;
float clipend;
/* fields */
int use_fields;
int field_second;
int field_odd;
/* compute result */
float ycor;
float viewdx;
float viewdy;
rctf viewplane;
float winmat[4][4];
} CameraParams;
void camera_params_init(CameraParams *params);
void camera_params_from_object(CameraParams *params, struct Object *camera);
void camera_params_compute(CameraParams *params, int winx, int winy, float aspx, float aspy);
/* Camera View Frame */
void camera_view_frame_ex(struct Scene *scene, struct Camera *camera, float drawsize, const short do_clip, const float scale[3],
float r_asp[2], float r_shift[2], float *r_drawsize, float r_vec[4][3]);

@ -46,6 +46,8 @@
#include "BKE_library.h"
#include "BKE_main.h"
/****************************** Camera Datablock *****************************/
void *add_camera(const char *name)
{
Camera *cam;
@ -121,8 +123,26 @@ void make_local_camera(Camera *cam)
}
}
void free_camera(Camera *ca)
{
BKE_free_animdata((ID *)ca);
}
/******************************** Camera Usage *******************************/
void object_camera_mode(RenderData *rd, Object *cam_ob)
{
rd->mode &= ~(R_ORTHO|R_PANORAMA);
if(cam_ob && cam_ob->type==OB_CAMERA) {
Camera *cam= cam_ob->data;
if(cam->type == CAM_ORTHO) rd->mode |= R_ORTHO;
if(cam->flag & CAM_PANORAMA) rd->mode |= R_PANORAMA;
}
}
/* get the camera's dof value, takes the dof object into account */
float dof_camera(Object *ob)
float object_camera_dof_distance(Object *ob)
{
Camera *cam = (Camera *)ob->data;
if (ob->type != OB_CAMERA)
@ -141,175 +161,155 @@ float dof_camera(Object *ob)
return cam->YF_dofdist;
}
void free_camera(Camera *ca)
/******************************** Camera Params *******************************/
static int camera_sensor_fit(int sensor_fit, float sizex, float sizey)
{
BKE_free_animdata((ID *)ca);
if(sensor_fit == CAMERA_SENSOR_FIT_AUTO) {
if(sizex >= sizey)
return CAMERA_SENSOR_FIT_HOR;
else
return CAMERA_SENSOR_FIT_VERT;
}
return sensor_fit;
}
void object_camera_mode(RenderData *rd, Object *camera)
void camera_params_init(CameraParams *params)
{
rd->mode &= ~(R_ORTHO|R_PANORAMA);
if(camera && camera->type==OB_CAMERA) {
Camera *cam= camera->data;
if(cam->type == CAM_ORTHO) rd->mode |= R_ORTHO;
if(cam->flag & CAM_PANORAMA) rd->mode |= R_PANORAMA;
}
memset(params, 0, sizeof(CameraParams));
/* defaults */
params->sensor_x= DEFAULT_SENSOR_WIDTH;
params->sensor_y= DEFAULT_SENSOR_HEIGHT;
params->sensor_fit= CAMERA_SENSOR_FIT_AUTO;
}
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)
void camera_params_from_object(CameraParams *params, Object *ob)
{
Camera *cam= NULL;
if(!ob)
return;
(*shiftx)= 0.0f;
(*shifty)= 0.0f;
if(ob->type==OB_CAMERA) {
/* camera object */
Camera *cam= ob->data;
(*sensor_x)= DEFAULT_SENSOR_WIDTH;
(*sensor_y)= DEFAULT_SENSOR_HEIGHT;
(*sensor_fit)= CAMERA_SENSOR_FIT_AUTO;
if(cam->type == CAM_ORTHO)
params->is_ortho= TRUE;
params->lens= cam->lens;
params->ortho_scale= cam->ortho_scale;
if(camera->type==OB_CAMERA) {
cam= camera->data;
params->shiftx= cam->shiftx;
params->shifty= cam->shifty;
if(cam->type == CAM_ORTHO) {
*is_ortho= TRUE;
}
params->sensor_x= cam->sensor_x;
params->sensor_y= cam->sensor_y;
params->sensor_fit= cam->sensor_fit;
/* solve this too... all time depending stuff is in convertblender.c?
* Need to update the camera early because it's used for projection matrices
* and other stuff BEFORE the animation update loop is done
* */
#if 0 // XXX old animation system
if(cam->ipo) {
calc_ipo(cam->ipo, frame_to_float(re->scene, re->r.cfra));
execute_ipo(&cam->id, cam->ipo);
}
#endif // XXX old animation system
(*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;
params->clipsta= cam->clipsta;
params->clipend= cam->clipend;
}
else if(camera->type==OB_LAMP) {
Lamp *la= camera->data;
else if(ob->type==OB_LAMP) {
/* lamp object */
Lamp *la= ob->data;
float fac= cosf((float)M_PI*la->spotsize/360.0f);
float phi= acos(fac);
(*lens)= 16.0f*fac/sinf(phi);
if((*lens)==0.0f)
(*lens)= 35.0f;
(*clipsta)= la->clipsta;
(*clipend)= la->clipend;
}
else { /* envmap exception... */;
if((*lens)==0.0f) /* is this needed anymore? */
(*lens)= 16.0f;
params->lens= 16.0f*fac/sinf(phi);
if(params->lens==0.0f)
params->lens= 35.0f;
if((*clipsta)==0.0f || (*clipend)==0.0f) {
(*clipsta)= 0.1f;
(*clipend)= 1000.0f;
}
params->clipsta= la->clipsta;
params->clipend= la->clipend;
}
(*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)
void camera_params_compute(CameraParams *params, int winx, int winy, float xasp, float yasp)
{
Camera *cam=NULL;
float pixsize;
float shiftx=0.0, shifty=0.0, winside, viewfac;
short is_ortho= FALSE;
rctf viewplane;
float pixsize, winside, viewfac;
int sensor_fit;
/* question mark */
(*ycor)= rd->yasp / rd->xasp;
if(rd->mode & R_FIELDS)
(*ycor) *= 2.0f;
/* fields rendering */
params->ycor= yasp/xasp;
if(params->use_fields)
params->ycor *= 2.0f;
object_camera_intrinsics(camera, &cam, &is_ortho, &shiftx, &shifty, clipsta, clipend, lens, sensor_x, sensor_y, sensor_fit);
/* determine sensor fit */
sensor_fit = camera_sensor_fit(params->sensor_fit, xasp*winx, yasp*winy);
/* ortho only with camera available */
if(cam && is_ortho) {
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) {
if(params->is_ortho) {
/* orthographic camera, scale == 1.0 means exact 1 to 1 mapping */
if(sensor_fit==CAMERA_SENSOR_FIT_HOR)
viewfac= winx;
}
else { /* if((*sensor_fit)==CAMERA_SENSOR_FIT_VERT) { */
viewfac= (*ycor) * winy;
}
else
viewfac= params->ycor * winy;
/* ortho_scale == 1.0 means exact 1 to 1 mapping */
pixsize= cam->ortho_scale/viewfac;
pixsize= params->ortho_scale/viewfac;
}
else {
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);
}
/* perspective camera */
float sensor_size;
pixsize= (*clipsta) / viewfac;
/* note for auto fit sensor_x is both width and height */
if(params->sensor_fit == CAMERA_SENSOR_FIT_VERT)
sensor_size= params->sensor_y;
else
sensor_size= params->sensor_x;
if(sensor_fit == CAMERA_SENSOR_FIT_HOR)
viewfac= (params->lens * winx) / sensor_size;
else
viewfac= params->ycor * (params->lens * winy) / sensor_size;
pixsize= params->clipsta/viewfac;
}
/* viewplane fully centered, zbuffer fills in jittered between -.5 and +.5 */
winside= MAX2(winx, winy);
/* compute view plane:
* fully centered, zbuffer fills in jittered between -.5 and +.5 */
if(sensor_fit == CAMERA_SENSOR_FIT_HOR)
winside= winx;
else
winside= winy;
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 + params->shiftx*winside;
viewplane.ymin= -0.5f*params->ycor*(float)winy + params->shifty*winside;
viewplane.xmax= 0.5f*(float)winx + params->shiftx*winside;
viewplane.ymax= 0.5f*params->ycor*(float)winy + params->shifty*winside;
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;
viewplane->ymax= 0.5f*(*ycor)*(float)winy + shifty*winside;
if(field_second) {
if(rd->mode & R_ODDFIELD) {
viewplane->ymin-= 0.5f * (*ycor);
viewplane->ymax-= 0.5f * (*ycor);
if(params->field_second) {
if(params->field_odd) {
viewplane.ymin-= 0.5f * params->ycor;
viewplane.ymax-= 0.5f * params->ycor;
}
else {
viewplane->ymin+= 0.5f * (*ycor);
viewplane->ymax+= 0.5f * (*ycor);
viewplane.ymin+= 0.5f * params->ycor;
viewplane.ymax+= 0.5f * params->ycor;
}
}
/* the window matrix is used for clipping, and not changed during OSA steps */
/* using an offset of +0.5 here would give clip errors on edges */
viewplane->xmin *= pixsize;
viewplane->xmax *= pixsize;
viewplane->ymin *= pixsize;
viewplane->ymax *= pixsize;
viewplane.xmin *= pixsize;
viewplane.xmax *= pixsize;
viewplane.ymin *= pixsize;
viewplane.ymax *= pixsize;
(*viewdx)= pixsize;
(*viewdy)= (*ycor) * pixsize;
params->viewdx= pixsize;
params->viewdy= params->ycor * pixsize;
if(is_ortho)
orthographic_m4(winmat, viewplane->xmin, viewplane->xmax, viewplane->ymin, viewplane->ymax, *clipsta, *clipend);
if(params->is_ortho)
orthographic_m4(params->winmat, viewplane.xmin, viewplane.xmax,
viewplane.ymin, viewplane.ymax, params->clipsta, params->clipend);
else
perspective_m4(winmat, viewplane->xmin, viewplane->xmax, viewplane->ymin, viewplane->ymax, *clipsta, *clipend);
perspective_m4(params->winmat, viewplane.xmin, viewplane.xmax,
viewplane.ymin, viewplane.ymax, params->clipsta, params->clipend);
params->viewplane= viewplane;
}
/***************************** Camera View Frame *****************************/
void camera_view_frame_ex(Scene *scene, Camera *camera, float drawsize, const short do_clip, const float scale[3],
float r_asp[2], float r_shift[2], float *r_drawsize, float r_vec[4][3])
{
@ -331,7 +331,7 @@ void camera_view_frame_ex(Scene *scene, Camera *camera, float drawsize, const sh
r_asp[1]= aspy / aspx;
}
}
else if(camera->sensor_fit==CAMERA_SENSOR_FIT_AUTO) {
else if(camera->sensor_fit==CAMERA_SENSOR_FIT_HOR) {
r_asp[0]= aspx / aspy;
r_asp[1]= 1.0;
}

@ -3988,7 +3988,7 @@ static void followtrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase
MovieTrackingMarker *marker;
float vec[3], disp[3], axis[3], mat[4][4];
float aspect= (scene->r.xsch*scene->r.xasp) / (scene->r.ysch*scene->r.yasp);
float sensor_x, sensor_y, lens, len, d, ortho_scale= 1.0f;
float len, d;
where_is_object_mat(scene, camob, mat);
@ -4006,23 +4006,20 @@ static void followtrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase
len= len_v3(disp);
if (len > FLT_EPSILON) {
float pos[2], rmat[4][4], shiftx= 0.0f, shifty= 0.0f, clipsta= 0.0f, clipend= 0.0f;
short is_ortho= 0, sensor_fit= CAMERA_SENSOR_FIT_AUTO;
Camera *cam= NULL;
CameraParams params;
float pos[2], rmat[4][4];
user.framenr= scene->r.cfra;
marker= BKE_tracking_get_marker(track, user.framenr);
add_v2_v2v2(pos, marker->pos, track->offset);
object_camera_intrinsics(camob, &cam, &is_ortho, &shiftx, &shifty, &clipsta, &clipend, &lens, &sensor_x, &sensor_y, &sensor_fit);
if (is_ortho) {
if (cam)
ortho_scale= cam->ortho_scale;
vec[0]= ortho_scale * (pos[0]-0.5f+shiftx);
vec[1]= ortho_scale * (pos[1]-0.5f+shifty);
camera_params_init(&params);
camera_params_from_object(&params, camob);
if (params.is_ortho) {
vec[0]= params.ortho_scale * (pos[0]-0.5f+params.shiftx);
vec[1]= params.ortho_scale * (pos[1]-0.5f+params.shifty);
vec[2]= -len;
if (aspect > 1.0f) vec[1] /= aspect;
@ -4037,10 +4034,10 @@ static void followtrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase
copy_v3_v3(cob->matrix[3], disp);
}
else {
d= (len*sensor_x) / (2.0f*lens);
d= (len*params.sensor_x) / (2.0f*params.lens);
vec[0]= d*(2.0f*(pos[0]+shiftx)-1.0f);
vec[1]= d*(2.0f*(pos[1]+shifty)-1.0f);
vec[0]= d*(2.0f*(pos[0]+params.shiftx)-1.0f);
vec[1]= d*(2.0f*(pos[1]+params.shifty)-1.0f);
vec[2]= -len;
if (aspect > 1.0f) vec[1] /= aspect;

@ -3057,25 +3057,23 @@ static void project_paint_begin(ProjPaintState *ps)
invert_m4_m4(viewinv, viewmat);
}
else if (ps->source==PROJ_SRC_IMAGE_CAM) {
Object *camera= ps->scene->camera;
/* dont actually use these */
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;
Object *cam_ob= ps->scene->camera;
CameraParams params;
/* viewmat & viewinv */
copy_m4_m4(viewinv, ps->scene->camera->obmat);
copy_m4_m4(viewinv, cam_ob->obmat);
normalize_m4(viewinv);
invert_m4_m4(viewmat, viewinv);
/* camera winmat */
object_camera_mode(&ps->scene->r, camera);
object_camera_matrix(&ps->scene->r, camera, ps->winx, ps->winy, 0,
winmat, &_viewplane, &ps->clipsta, &ps->clipend,
&_lens, &_sensor_x, &_sensor_y, &_sensor_fit, &_ycor, &_viewdx, &_viewdy);
/* window matrix, clipping and ortho */
camera_params_init(&params);
camera_params_from_object(&params, cam_ob);
camera_params_compute(&params, ps->winx, ps->winy, 1.0f, 1.0f); /* XXX aspect? */
ps->is_ortho= (ps->scene->r.mode & R_ORTHO) ? 1 : 0;
copy_m4_m4(winmat, params.winmat);
ps->clipsta= params.clipsta;
ps->clipend= params.clipend;
ps->is_ortho= params.is_ortho;
}
/* same as view3d_get_object_project_mat */

@ -1693,7 +1693,7 @@ static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base
if(cam->flag & CAM_SHOWLIMITS) {
draw_limit_line(cam->clipsta, cam->clipend, 0x77FFFF);
/* qdn: was yafray only, now also enabled for Blender to be used with defocus composit node */
draw_focus_cross(dof_camera(ob), cam->drawsize);
draw_focus_cross(object_camera_dof_distance(ob), cam->drawsize);
}
wrld= scene->world;

@ -2485,15 +2485,13 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, in
/* render 3d view */
if(rv3d->persp==RV3D_CAMOB && v3d->camera) {
float winmat[4][4];
float _clipsta, _clipend, _lens, _yco, _dx, _dy, _sensor_x= DEFAULT_SENSOR_WIDTH, _sensor_y= DEFAULT_SENSOR_HEIGHT;
short _sensor_fit= CAMERA_SENSOR_FIT_AUTO;
rctf _viewplane;
CameraParams params;
object_camera_matrix(&scene->r, v3d->camera, sizex, sizey, 0, winmat, &_viewplane, &_clipsta, &_clipend, &_lens,
&_sensor_x, &_sensor_y, &_sensor_fit, &_yco, &_dx, &_dy);
camera_params_init(&params);
camera_params_from_object(&params, v3d->camera);
camera_params_compute(&params, sizex, sizey, scene->r.xasp, scene->r.yasp);
ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat);
ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, params.winmat);
}
else {
ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, NULL);
@ -2546,10 +2544,16 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Scene *scene, Object *camera, int w
invert_m4_m4(rv3d.viewmat, rv3d.viewinv);
{
float _yco, _dx, _dy, _sensor_x= 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, &_sensor_x, &_sensor_y, &_sensor_fit, &_yco, &_dx, &_dy);
CameraParams params;
camera_params_init(&params);
camera_params_from_object(&params, v3d.camera);
camera_params_compute(&params, width, height, scene->r.xasp, scene->r.yasp);
copy_m4_m4(rv3d.winmat, params.winmat);
v3d.near= params.clipsta;
v3d.far= params.clipend;
v3d.lens= params.lens;
}
mul_m4_m4m4(rv3d.persmat, rv3d.viewmat, rv3d.winmat);

@ -261,7 +261,7 @@ static void defocus_blur(bNode *node, CompBuf *new, CompBuf *img, CompBuf *zbuf,
if (camob && camob->type==OB_CAMERA) {
Camera* cam = (Camera*)camob->data;
cam_lens = cam->lens;
cam_fdist = dof_camera(camob);
cam_fdist = object_camera_dof_distance(camob);
if (cam_fdist==0.0f) cam_fdist = 1e10f; /* if the dof is 0.0 then set it be be far away */
cam_invfdist = 1.f/cam_fdist;
}

@ -188,6 +188,7 @@ void RE_SetDispRect (struct Render *re, rcti *disprect);
/* set up the viewplane/perspective matrix, three choices */
struct Object *RE_GetCamera(struct Render *re); /* return camera override if set */
void RE_SetCamera(struct Render *re, struct Object *camera);
void RE_SetEnvmapCamera(struct Render *re, struct Object *cam_ob, float viewscale, float clipsta, float clipend);
void RE_SetWindow (struct Render *re, rctf *viewplane, float clipsta, float clipend);
void RE_SetOrtho (struct Render *re, rctf *viewplane, float clipsta, float clipend);
void RE_SetPixelSize(struct Render *re, float pixsize);

@ -152,10 +152,7 @@ struct Render
int partx, party;
/* 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;

@ -131,6 +131,7 @@ static void envmap_split_ima(EnvMap *env, ImBuf *ibuf)
static Render *envmap_render_copy(Render *re, EnvMap *env)
{
Render *envre;
float viewscale;
int cuberes;
envre= RE_NewRender("Envmap");
@ -156,15 +157,8 @@ static Render *envmap_render_copy(Render *re, EnvMap *env)
envre->lay= re->lay;
/* 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;
envre->clipsta= env->clipsta; /* render_scene_set_window() respects this for now */
envre->clipend= env->clipend;
RE_SetCamera(envre, env->object);
viewscale= (env->type == ENV_PLANE)? env->viewscale: 1.0f;
RE_SetEnvmapCamera(envre, env->object, viewscale, env->clipsta, env->clipend);
/* callbacks */
envre->display_draw= re->display_draw;

@ -451,15 +451,62 @@ struct Object *RE_GetCamera(Render *re)
return re->camera_override ? re->camera_override : re->scene->camera;
}
static void re_camera_params_get(Render *re, CameraParams *params, Object *cam_ob)
{
copy_m4_m4(re->winmat, params->winmat);
re->clipsta= params->clipsta;
re->clipend= params->clipend;
re->ycor= params->ycor;
re->viewdx= params->viewdx;
re->viewdy= params->viewdy;
re->viewplane= params->viewplane;
object_camera_mode(&re->r, cam_ob);
}
void RE_SetEnvmapCamera(Render *re, Object *cam_ob, float viewscale, float clipsta, float clipend)
{
CameraParams params;
/* setup parameters */
camera_params_init(&params);
camera_params_from_object(&params, cam_ob);
params.lens= 16.0f*viewscale;
params.sensor_x= 32.0f;
params.sensor_y= 32.0f;
params.sensor_fit = CAMERA_SENSOR_FIT_AUTO;
params.clipsta= clipsta;
params.clipend= clipend;
/* compute matrix, viewplane, .. */
camera_params_compute(&params, re->winx, re->winy, 1.0f, 1.0f);
/* extract results */
re_camera_params_get(re, &params, cam_ob);
}
/* call this after InitState() */
/* per render, there's one persistent viewplane. Parts will set their own viewplanes */
void RE_SetCamera(Render *re, Object *camera)
void RE_SetCamera(Render *re, Object *cam_ob)
{
object_camera_mode(&re->r, camera);
CameraParams params;
object_camera_matrix(&re->r, camera, re->winx, re->winy, re->flag & R_SEC_FIELD,
re->winmat, &re->viewplane, &re->clipsta, &re->clipend,
&re->lens, &re->sensor_x, &re->sensor_y, &re->sensor_fit, &re->ycor, &re->viewdx, &re->viewdy);
/* setup parameters */
camera_params_init(&params);
camera_params_from_object(&params, cam_ob);
params.use_fields= (re->r.mode & R_FIELDS);
params.field_second= (re->flag & R_SEC_FIELD);
params.field_odd= (re->r.mode & R_ODDFIELD);
/* compute matrix, viewplane, .. */
camera_params_compute(&params, re->winx, re->winy, re->r.xasp, re->r.yasp);
/* extract results */
re_camera_params_get(re, &params, cam_ob);
}
void RE_SetPixelSize(Render *re, float pixsize)