2011-11-05 13:00:39 +00:00
|
|
|
/*
|
|
|
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software Foundation,
|
|
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
*
|
|
|
|
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* The Original Code is: all of this file.
|
|
|
|
*
|
|
|
|
* Contributor(s): none yet.
|
|
|
|
*
|
|
|
|
* ***** END GPL LICENSE BLOCK *****
|
|
|
|
*/
|
|
|
|
|
|
|
|
/** \file blender/blenkernel/intern/camera.c
|
|
|
|
* \ingroup bke
|
|
|
|
*/
|
|
|
|
|
2011-11-05 13:11:49 +00:00
|
|
|
#include <stdlib.h>
|
|
|
|
|
2011-11-05 13:00:39 +00:00
|
|
|
#include "DNA_camera_types.h"
|
|
|
|
#include "DNA_lamp_types.h"
|
|
|
|
#include "DNA_object_types.h"
|
|
|
|
#include "DNA_scene_types.h"
|
2011-11-18 21:19:03 +00:00
|
|
|
#include "DNA_view3d_types.h"
|
2011-11-05 13:00:39 +00:00
|
|
|
|
|
|
|
#include "BLI_math.h"
|
|
|
|
#include "BLI_utildefines.h"
|
|
|
|
|
|
|
|
#include "BKE_animsys.h"
|
|
|
|
#include "BKE_camera.h"
|
2011-11-14 03:54:23 +00:00
|
|
|
#include "BKE_object.h"
|
2011-11-05 13:00:39 +00:00
|
|
|
#include "BKE_global.h"
|
|
|
|
#include "BKE_library.h"
|
|
|
|
#include "BKE_main.h"
|
2011-11-18 21:19:03 +00:00
|
|
|
#include "BKE_screen.h"
|
2011-11-05 13:00:39 +00:00
|
|
|
|
2011-11-18 15:52:00 +00:00
|
|
|
/****************************** Camera Datablock *****************************/
|
|
|
|
|
2013-02-05 12:46:15 +00:00
|
|
|
void *BKE_camera_add(Main *bmain, const char *name)
|
2011-11-05 13:00:39 +00:00
|
|
|
{
|
|
|
|
Camera *cam;
|
|
|
|
|
2013-02-05 12:46:15 +00:00
|
|
|
cam = BKE_libblock_alloc(&bmain->camera, ID_CA, name);
|
2012-05-06 15:15:33 +00:00
|
|
|
|
|
|
|
cam->lens = 35.0f;
|
2012-08-09 15:59:32 +00:00
|
|
|
cam->sensor_x = DEFAULT_SENSOR_WIDTH;
|
|
|
|
cam->sensor_y = DEFAULT_SENSOR_HEIGHT;
|
2012-05-06 15:15:33 +00:00
|
|
|
cam->clipsta = 0.1f;
|
|
|
|
cam->clipend = 100.0f;
|
|
|
|
cam->drawsize = 0.5f;
|
|
|
|
cam->ortho_scale = 6.0;
|
2011-11-05 13:00:39 +00:00
|
|
|
cam->flag |= CAM_SHOWPASSEPARTOUT;
|
|
|
|
cam->passepartalpha = 0.5f;
|
|
|
|
|
|
|
|
return cam;
|
|
|
|
}
|
|
|
|
|
2012-05-05 00:58:22 +00:00
|
|
|
Camera *BKE_camera_copy(Camera *cam)
|
2011-11-05 13:00:39 +00:00
|
|
|
{
|
|
|
|
Camera *camn;
|
|
|
|
|
2012-05-06 15:15:33 +00:00
|
|
|
camn = BKE_libblock_copy(&cam->id);
|
2011-11-19 01:24:40 +00:00
|
|
|
|
|
|
|
id_lib_extern((ID *)camn->dof_ob);
|
|
|
|
|
2011-11-05 13:00:39 +00:00
|
|
|
return camn;
|
|
|
|
}
|
|
|
|
|
2012-05-05 00:58:22 +00:00
|
|
|
void BKE_camera_make_local(Camera *cam)
|
2011-11-05 13:00:39 +00:00
|
|
|
{
|
2012-05-06 15:15:33 +00:00
|
|
|
Main *bmain = G.main;
|
2011-11-05 13:00:39 +00:00
|
|
|
Object *ob;
|
2012-05-06 15:15:33 +00:00
|
|
|
int is_local = FALSE, is_lib = FALSE;
|
2011-11-05 13:00:39 +00:00
|
|
|
|
|
|
|
/* - only lib users: do nothing
|
|
|
|
* - only local users: set flag
|
|
|
|
* - mixed: make copy
|
|
|
|
*/
|
|
|
|
|
2012-05-06 15:15:33 +00:00
|
|
|
if (cam->id.lib == NULL) return;
|
|
|
|
if (cam->id.us == 1) {
|
2011-11-05 13:00:39 +00:00
|
|
|
id_clear_lib_data(bmain, &cam->id);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-05-06 15:15:33 +00:00
|
|
|
for (ob = bmain->object.first; ob && ELEM(0, is_lib, is_local); ob = ob->id.next) {
|
|
|
|
if (ob->data == cam) {
|
|
|
|
if (ob->id.lib) is_lib = TRUE;
|
|
|
|
else is_local = TRUE;
|
2011-11-05 13:00:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-03-24 06:18:31 +00:00
|
|
|
if (is_local && is_lib == FALSE) {
|
2011-11-05 13:00:39 +00:00
|
|
|
id_clear_lib_data(bmain, &cam->id);
|
|
|
|
}
|
2012-03-24 06:18:31 +00:00
|
|
|
else if (is_local && is_lib) {
|
2012-05-06 15:15:33 +00:00
|
|
|
Camera *cam_new = BKE_camera_copy(cam);
|
2011-11-05 13:00:39 +00:00
|
|
|
|
2012-05-06 15:15:33 +00:00
|
|
|
cam_new->id.us = 0;
|
2011-11-05 13:00:39 +00:00
|
|
|
|
|
|
|
/* Remap paths of new ID using old library as base. */
|
2011-11-30 00:32:13 +00:00
|
|
|
BKE_id_lib_local_paths(bmain, cam->id.lib, &cam_new->id);
|
2011-11-05 13:00:39 +00:00
|
|
|
|
2012-05-06 15:15:33 +00:00
|
|
|
for (ob = bmain->object.first; ob; ob = ob->id.next) {
|
2012-03-24 06:18:31 +00:00
|
|
|
if (ob->data == cam) {
|
2012-05-06 15:15:33 +00:00
|
|
|
if (ob->id.lib == NULL) {
|
|
|
|
ob->data = cam_new;
|
2011-11-30 00:32:13 +00:00
|
|
|
cam_new->id.us++;
|
2011-11-05 13:00:39 +00:00
|
|
|
cam->id.us--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-05-05 00:58:22 +00:00
|
|
|
void BKE_camera_free(Camera *ca)
|
2011-11-18 15:52:00 +00:00
|
|
|
{
|
|
|
|
BKE_free_animdata((ID *)ca);
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************** Camera Usage *******************************/
|
|
|
|
|
2012-05-05 00:58:22 +00:00
|
|
|
void BKE_camera_object_mode(RenderData *rd, Object *cam_ob)
|
2011-11-18 15:52:00 +00:00
|
|
|
{
|
2012-05-06 15:15:33 +00:00
|
|
|
rd->mode &= ~(R_ORTHO | R_PANORAMA);
|
2011-11-18 15:52:00 +00:00
|
|
|
|
2012-05-06 15:15:33 +00:00
|
|
|
if (cam_ob && cam_ob->type == OB_CAMERA) {
|
|
|
|
Camera *cam = cam_ob->data;
|
2012-03-24 06:18:31 +00:00
|
|
|
if (cam->type == CAM_ORTHO) rd->mode |= R_ORTHO;
|
2012-05-04 16:20:51 +00:00
|
|
|
if (cam->type == CAM_PANO) rd->mode |= R_PANORAMA;
|
2011-11-18 15:52:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-11-05 13:00:39 +00:00
|
|
|
/* get the camera's dof value, takes the dof object into account */
|
2012-05-05 00:58:22 +00:00
|
|
|
float BKE_camera_object_dof_distance(Object *ob)
|
2011-11-05 13:00:39 +00:00
|
|
|
{
|
|
|
|
Camera *cam = (Camera *)ob->data;
|
|
|
|
if (ob->type != OB_CAMERA)
|
|
|
|
return 0.0f;
|
2012-10-21 05:46:41 +00:00
|
|
|
if (cam->dof_ob) {
|
2011-11-05 13:00:39 +00:00
|
|
|
/* too simple, better to return the distance on the view axis only
|
|
|
|
* return len_v3v3(ob->obmat[3], cam->dof_ob->obmat[3]); */
|
|
|
|
float mat[4][4], imat[4][4], obmat[4][4];
|
|
|
|
|
|
|
|
copy_m4_m4(obmat, ob->obmat);
|
|
|
|
normalize_m4(obmat);
|
|
|
|
invert_m4_m4(imat, obmat);
|
2013-05-26 18:36:25 +00:00
|
|
|
mul_m4_m4m4(mat, imat, cam->dof_ob->obmat);
|
2011-11-19 01:10:05 +00:00
|
|
|
return fabsf(mat[3][2]);
|
2011-11-05 13:00:39 +00:00
|
|
|
}
|
|
|
|
return cam->YF_dofdist;
|
|
|
|
}
|
|
|
|
|
2012-05-05 00:58:22 +00:00
|
|
|
float BKE_camera_sensor_size(int sensor_fit, float sensor_x, float sensor_y)
|
2011-11-18 21:19:03 +00:00
|
|
|
{
|
|
|
|
/* sensor size used to fit to. for auto, sensor_x is both x and y. */
|
2012-03-24 06:18:31 +00:00
|
|
|
if (sensor_fit == CAMERA_SENSOR_FIT_VERT)
|
2011-11-18 21:19:03 +00:00
|
|
|
return sensor_y;
|
2011-11-18 15:52:00 +00:00
|
|
|
|
2011-11-18 21:19:03 +00:00
|
|
|
return sensor_x;
|
|
|
|
}
|
|
|
|
|
2012-05-05 00:58:22 +00:00
|
|
|
int BKE_camera_sensor_fit(int sensor_fit, float sizex, float sizey)
|
2011-11-05 13:00:39 +00:00
|
|
|
{
|
2012-03-24 06:18:31 +00:00
|
|
|
if (sensor_fit == CAMERA_SENSOR_FIT_AUTO) {
|
|
|
|
if (sizex >= sizey)
|
2011-11-18 15:52:00 +00:00
|
|
|
return CAMERA_SENSOR_FIT_HOR;
|
|
|
|
else
|
|
|
|
return CAMERA_SENSOR_FIT_VERT;
|
|
|
|
}
|
|
|
|
|
|
|
|
return sensor_fit;
|
2011-11-05 13:00:39 +00:00
|
|
|
}
|
|
|
|
|
2011-11-18 21:19:03 +00:00
|
|
|
/******************************** Camera Params *******************************/
|
|
|
|
|
2012-05-05 00:58:22 +00:00
|
|
|
void BKE_camera_params_init(CameraParams *params)
|
2011-11-05 13:00:39 +00:00
|
|
|
{
|
2011-11-18 15:52:00 +00:00
|
|
|
memset(params, 0, sizeof(CameraParams));
|
|
|
|
|
|
|
|
/* defaults */
|
2012-05-06 15:15:33 +00:00
|
|
|
params->sensor_x = DEFAULT_SENSOR_WIDTH;
|
|
|
|
params->sensor_y = DEFAULT_SENSOR_HEIGHT;
|
|
|
|
params->sensor_fit = CAMERA_SENSOR_FIT_AUTO;
|
2011-11-18 21:19:03 +00:00
|
|
|
|
2012-05-06 15:15:33 +00:00
|
|
|
params->zoom = 1.0f;
|
2011-11-05 13:00:39 +00:00
|
|
|
}
|
|
|
|
|
2012-05-05 00:58:22 +00:00
|
|
|
void BKE_camera_params_from_object(CameraParams *params, Object *ob)
|
2011-11-05 13:00:39 +00:00
|
|
|
{
|
2012-03-24 06:18:31 +00:00
|
|
|
if (!ob)
|
2011-11-18 15:52:00 +00:00
|
|
|
return;
|
2011-11-05 13:00:39 +00:00
|
|
|
|
2012-05-06 15:15:33 +00:00
|
|
|
if (ob->type == OB_CAMERA) {
|
2011-11-18 15:52:00 +00:00
|
|
|
/* camera object */
|
2012-05-06 15:15:33 +00:00
|
|
|
Camera *cam = ob->data;
|
2011-11-05 13:00:39 +00:00
|
|
|
|
2012-03-24 06:18:31 +00:00
|
|
|
if (cam->type == CAM_ORTHO)
|
2012-05-06 15:15:33 +00:00
|
|
|
params->is_ortho = TRUE;
|
|
|
|
params->lens = cam->lens;
|
|
|
|
params->ortho_scale = cam->ortho_scale;
|
2011-11-05 13:00:39 +00:00
|
|
|
|
2012-05-06 15:15:33 +00:00
|
|
|
params->shiftx = cam->shiftx;
|
|
|
|
params->shifty = cam->shifty;
|
2011-11-05 13:00:39 +00:00
|
|
|
|
2012-05-06 15:15:33 +00:00
|
|
|
params->sensor_x = cam->sensor_x;
|
|
|
|
params->sensor_y = cam->sensor_y;
|
|
|
|
params->sensor_fit = cam->sensor_fit;
|
2011-11-05 13:00:39 +00:00
|
|
|
|
2012-05-06 15:15:33 +00:00
|
|
|
params->clipsta = cam->clipsta;
|
|
|
|
params->clipend = cam->clipend;
|
2011-11-05 13:00:39 +00:00
|
|
|
}
|
2012-05-06 15:15:33 +00:00
|
|
|
else if (ob->type == OB_LAMP) {
|
2011-11-18 15:52:00 +00:00
|
|
|
/* lamp object */
|
2012-05-06 15:15:33 +00:00
|
|
|
Lamp *la = ob->data;
|
|
|
|
float fac = cosf((float)M_PI * la->spotsize / 360.0f);
|
|
|
|
float phi = acos(fac);
|
2011-11-05 13:00:39 +00:00
|
|
|
|
2012-05-06 15:15:33 +00:00
|
|
|
params->lens = 16.0f * fac / sinf(phi);
|
|
|
|
if (params->lens == 0.0f)
|
|
|
|
params->lens = 35.0f;
|
2011-11-05 13:00:39 +00:00
|
|
|
|
2012-05-06 15:15:33 +00:00
|
|
|
params->clipsta = la->clipsta;
|
|
|
|
params->clipend = la->clipend;
|
2011-11-05 13:00:39 +00:00
|
|
|
}
|
2013-01-17 08:46:46 +00:00
|
|
|
else {
|
|
|
|
params->lens = 35.0f;
|
|
|
|
}
|
2011-11-05 13:00:39 +00:00
|
|
|
}
|
|
|
|
|
2012-05-05 00:58:22 +00:00
|
|
|
void BKE_camera_params_from_view3d(CameraParams *params, View3D *v3d, RegionView3D *rv3d)
|
2011-11-18 21:19:03 +00:00
|
|
|
{
|
2011-11-19 18:35:42 +00:00
|
|
|
/* common */
|
2012-05-06 15:15:33 +00:00
|
|
|
params->lens = v3d->lens;
|
|
|
|
params->clipsta = v3d->near;
|
|
|
|
params->clipend = v3d->far;
|
2011-11-18 21:19:03 +00:00
|
|
|
|
2012-05-06 15:15:33 +00:00
|
|
|
if (rv3d->persp == RV3D_CAMOB) {
|
2011-11-18 21:19:03 +00:00
|
|
|
/* camera view */
|
2012-05-05 00:58:22 +00:00
|
|
|
BKE_camera_params_from_object(params, v3d->camera);
|
2011-11-18 21:19:03 +00:00
|
|
|
|
2012-05-06 15:15:33 +00:00
|
|
|
params->zoom = BKE_screen_view3d_zoom_to_fac((float)rv3d->camzoom);
|
2011-11-19 18:35:42 +00:00
|
|
|
|
2012-05-06 15:15:33 +00:00
|
|
|
params->offsetx = 2.0f * rv3d->camdx * params->zoom;
|
|
|
|
params->offsety = 2.0f * rv3d->camdy * params->zoom;
|
2011-11-18 21:19:03 +00:00
|
|
|
|
2011-11-19 18:35:42 +00:00
|
|
|
params->shiftx *= params->zoom;
|
|
|
|
params->shifty *= params->zoom;
|
2011-11-18 21:19:03 +00:00
|
|
|
|
2012-05-06 15:15:33 +00:00
|
|
|
params->zoom = 1.0f / params->zoom;
|
2011-11-18 21:19:03 +00:00
|
|
|
}
|
2012-05-06 15:15:33 +00:00
|
|
|
else if (rv3d->persp == RV3D_ORTHO) {
|
2011-11-18 21:19:03 +00:00
|
|
|
/* orthographic view */
|
2012-10-24 16:15:46 +00:00
|
|
|
int sensor_size = BKE_camera_sensor_size(params->sensor_fit, params->sensor_x, params->sensor_y);
|
2012-05-06 15:15:33 +00:00
|
|
|
params->clipend *= 0.5f; // otherwise too extreme low zbuffer quality
|
|
|
|
params->clipsta = -params->clipend;
|
2011-11-18 21:19:03 +00:00
|
|
|
|
2012-05-06 15:15:33 +00:00
|
|
|
params->is_ortho = TRUE;
|
2012-11-30 06:10:01 +00:00
|
|
|
/* make sure any changes to this match ED_view3d_radius_to_ortho_dist() */
|
2012-10-24 16:15:46 +00:00
|
|
|
params->ortho_scale = rv3d->dist * sensor_size / v3d->lens;
|
2012-05-06 15:15:33 +00:00
|
|
|
params->zoom = 2.0f;
|
2011-11-19 18:35:42 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* perspective view */
|
2012-05-06 15:15:33 +00:00
|
|
|
params->zoom = 2.0f;
|
2011-11-18 21:19:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-05-05 00:58:22 +00:00
|
|
|
void BKE_camera_params_compute_viewplane(CameraParams *params, int winx, int winy, float xasp, float yasp)
|
2011-11-05 13:00:39 +00:00
|
|
|
{
|
2011-11-18 15:52:00 +00:00
|
|
|
rctf viewplane;
|
2011-11-18 21:19:03 +00:00
|
|
|
float pixsize, viewfac, sensor_size, dx, dy;
|
2011-11-18 15:52:00 +00:00
|
|
|
int sensor_fit;
|
|
|
|
|
|
|
|
/* fields rendering */
|
2012-05-06 15:15:33 +00:00
|
|
|
params->ycor = yasp / xasp;
|
2012-03-24 06:18:31 +00:00
|
|
|
if (params->use_fields)
|
2011-11-18 15:52:00 +00:00
|
|
|
params->ycor *= 2.0f;
|
|
|
|
|
2012-03-24 06:18:31 +00:00
|
|
|
if (params->is_ortho) {
|
2011-11-18 21:19:03 +00:00
|
|
|
/* orthographic camera */
|
|
|
|
/* scale == 1.0 means exact 1 to 1 mapping */
|
2012-05-06 15:15:33 +00:00
|
|
|
pixsize = params->ortho_scale;
|
2011-11-05 13:00:39 +00:00
|
|
|
}
|
|
|
|
else {
|
2011-11-18 15:52:00 +00:00
|
|
|
/* perspective camera */
|
2012-05-06 15:15:33 +00:00
|
|
|
sensor_size = BKE_camera_sensor_size(params->sensor_fit, params->sensor_x, params->sensor_y);
|
|
|
|
pixsize = (sensor_size * params->clipsta) / params->lens;
|
2011-11-18 21:19:03 +00:00
|
|
|
}
|
2011-11-18 15:52:00 +00:00
|
|
|
|
2011-11-18 21:19:03 +00:00
|
|
|
/* determine sensor fit */
|
2012-05-06 15:15:33 +00:00
|
|
|
sensor_fit = BKE_camera_sensor_fit(params->sensor_fit, xasp * winx, yasp * winy);
|
2011-11-05 13:00:39 +00:00
|
|
|
|
2012-05-06 15:15:33 +00:00
|
|
|
if (sensor_fit == CAMERA_SENSOR_FIT_HOR)
|
|
|
|
viewfac = winx;
|
2011-11-18 21:19:03 +00:00
|
|
|
else
|
2012-05-06 15:15:33 +00:00
|
|
|
viewfac = params->ycor * winy;
|
2011-11-18 21:19:03 +00:00
|
|
|
|
|
|
|
pixsize /= viewfac;
|
|
|
|
|
|
|
|
/* extra zoom factor */
|
|
|
|
pixsize *= params->zoom;
|
2011-11-05 13:00:39 +00:00
|
|
|
|
2011-11-18 15:52:00 +00:00
|
|
|
/* compute view plane:
|
|
|
|
* fully centered, zbuffer fills in jittered between -.5 and +.5 */
|
2012-05-06 15:15:33 +00:00
|
|
|
viewplane.xmin = -0.5f * (float)winx;
|
|
|
|
viewplane.ymin = -0.5f * params->ycor * (float)winy;
|
|
|
|
viewplane.xmax = 0.5f * (float)winx;
|
|
|
|
viewplane.ymax = 0.5f * params->ycor * (float)winy;
|
2011-11-05 13:00:39 +00:00
|
|
|
|
2011-11-18 21:19:03 +00:00
|
|
|
/* lens shift and offset */
|
2012-05-06 15:15:33 +00:00
|
|
|
dx = params->shiftx * viewfac + winx * params->offsetx;
|
|
|
|
dy = params->shifty * viewfac + winy * params->offsety;
|
2011-11-05 13:00:39 +00:00
|
|
|
|
2011-11-18 21:19:03 +00:00
|
|
|
viewplane.xmin += dx;
|
|
|
|
viewplane.ymin += dy;
|
|
|
|
viewplane.xmax += dx;
|
|
|
|
viewplane.ymax += dy;
|
|
|
|
|
|
|
|
/* fields offset */
|
2012-03-24 06:18:31 +00:00
|
|
|
if (params->field_second) {
|
|
|
|
if (params->field_odd) {
|
2012-05-06 15:15:33 +00:00
|
|
|
viewplane.ymin -= 0.5f * params->ycor;
|
|
|
|
viewplane.ymax -= 0.5f * params->ycor;
|
2011-11-05 13:00:39 +00:00
|
|
|
}
|
|
|
|
else {
|
2012-05-06 15:15:33 +00:00
|
|
|
viewplane.ymin += 0.5f * params->ycor;
|
|
|
|
viewplane.ymax += 0.5f * params->ycor;
|
2011-11-05 13:00:39 +00:00
|
|
|
}
|
|
|
|
}
|
2011-11-18 15:52:00 +00:00
|
|
|
|
2011-11-05 13:00:39 +00:00
|
|
|
/* 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 */
|
2011-11-18 15:52:00 +00:00
|
|
|
viewplane.xmin *= pixsize;
|
|
|
|
viewplane.xmax *= pixsize;
|
|
|
|
viewplane.ymin *= pixsize;
|
|
|
|
viewplane.ymax *= pixsize;
|
2011-11-05 13:00:39 +00:00
|
|
|
|
2012-05-06 15:15:33 +00:00
|
|
|
params->viewdx = pixsize;
|
|
|
|
params->viewdy = params->ycor * pixsize;
|
|
|
|
params->viewplane = viewplane;
|
2011-11-19 18:35:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* viewplane is assumed to be already computed */
|
2012-05-05 00:58:22 +00:00
|
|
|
void BKE_camera_params_compute_matrix(CameraParams *params)
|
2011-11-19 18:35:42 +00:00
|
|
|
{
|
2012-05-05 00:58:22 +00:00
|
|
|
rctf viewplane = params->viewplane;
|
2011-11-05 13:00:39 +00:00
|
|
|
|
2011-11-18 21:19:03 +00:00
|
|
|
/* compute projection matrix */
|
2012-03-24 06:18:31 +00:00
|
|
|
if (params->is_ortho)
|
2011-11-18 15:52:00 +00:00
|
|
|
orthographic_m4(params->winmat, viewplane.xmin, viewplane.xmax,
|
2012-05-05 00:58:22 +00:00
|
|
|
viewplane.ymin, viewplane.ymax, params->clipsta, params->clipend);
|
2011-11-05 13:00:39 +00:00
|
|
|
else
|
2011-11-18 15:52:00 +00:00
|
|
|
perspective_m4(params->winmat, viewplane.xmin, viewplane.xmax,
|
2012-05-05 00:58:22 +00:00
|
|
|
viewplane.ymin, viewplane.ymax, params->clipsta, params->clipend);
|
2011-11-05 13:00:39 +00:00
|
|
|
}
|
|
|
|
|
2011-11-18 15:52:00 +00:00
|
|
|
/***************************** Camera View Frame *****************************/
|
|
|
|
|
2013-03-20 23:14:18 +00:00
|
|
|
void BKE_camera_view_frame_ex(Scene *scene, Camera *camera, float drawsize, const bool do_clip, const float scale[3],
|
2012-05-05 00:58:22 +00:00
|
|
|
float r_asp[2], float r_shift[2], float *r_drawsize, float r_vec[4][3])
|
2011-11-05 13:00:39 +00:00
|
|
|
{
|
|
|
|
float facx, facy;
|
|
|
|
float depth;
|
|
|
|
|
|
|
|
/* aspect correcton */
|
|
|
|
if (scene) {
|
2012-05-06 15:15:33 +00:00
|
|
|
float aspx = (float) scene->r.xsch * scene->r.xasp;
|
|
|
|
float aspy = (float) scene->r.ysch * scene->r.yasp;
|
|
|
|
int sensor_fit = BKE_camera_sensor_fit(camera->sensor_fit, aspx, aspy);
|
2011-11-05 13:00:39 +00:00
|
|
|
|
2012-05-06 15:15:33 +00:00
|
|
|
if (sensor_fit == CAMERA_SENSOR_FIT_HOR) {
|
|
|
|
r_asp[0] = 1.0;
|
|
|
|
r_asp[1] = aspy / aspx;
|
2011-11-05 13:00:39 +00:00
|
|
|
}
|
2011-11-18 23:15:11 +00:00
|
|
|
else {
|
2012-05-06 15:15:33 +00:00
|
|
|
r_asp[0] = aspx / aspy;
|
|
|
|
r_asp[1] = 1.0;
|
2011-11-05 13:00:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
2012-05-06 15:15:33 +00:00
|
|
|
r_asp[0] = 1.0f;
|
|
|
|
r_asp[1] = 1.0f;
|
2011-11-05 13:00:39 +00:00
|
|
|
}
|
|
|
|
|
2012-05-06 15:15:33 +00:00
|
|
|
if (camera->type == CAM_ORTHO) {
|
|
|
|
facx = 0.5f * camera->ortho_scale * r_asp[0] * scale[0];
|
|
|
|
facy = 0.5f * camera->ortho_scale * r_asp[1] * scale[1];
|
|
|
|
r_shift[0] = camera->shiftx * camera->ortho_scale * scale[0];
|
|
|
|
r_shift[1] = camera->shifty * camera->ortho_scale * scale[1];
|
|
|
|
depth = do_clip ? -((camera->clipsta * scale[2]) + 0.1f) : -drawsize * camera->ortho_scale * scale[2];
|
2011-11-05 13:00:39 +00:00
|
|
|
|
2012-05-06 15:15:33 +00:00
|
|
|
*r_drawsize = 0.5f * camera->ortho_scale;
|
2011-11-05 13:00:39 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* that way it's always visible - clipsta+0.1 */
|
2013-07-26 05:08:24 +00:00
|
|
|
float fac, scale_x, scale_y;
|
|
|
|
float half_sensor = 0.5f * ((camera->sensor_fit == CAMERA_SENSOR_FIT_VERT) ?
|
|
|
|
(camera->sensor_y) : (camera->sensor_x));
|
2011-11-05 13:00:39 +00:00
|
|
|
|
|
|
|
|
2012-03-24 06:18:31 +00:00
|
|
|
if (do_clip) {
|
2011-11-05 13:00:39 +00:00
|
|
|
/* fixed depth, variable size (avoids exceeding clipping range) */
|
2013-07-26 05:08:24 +00:00
|
|
|
/* r_drawsize shouldn't be used in this case, set to dummy value */
|
|
|
|
*r_drawsize = 1.0f;
|
|
|
|
depth = -(camera->clipsta + 0.1f) * scale[2];
|
|
|
|
fac = depth / (camera->lens / (-half_sensor));
|
|
|
|
scale_x = 1.0f;
|
|
|
|
scale_y = 1.0f;
|
2011-11-05 13:00:39 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* fixed size, variable depth (stays a reasonable size in the 3D view) */
|
2013-07-26 05:08:24 +00:00
|
|
|
*r_drawsize = drawsize / ((scale[0] + scale[1] + scale[2]) / 3.0f);
|
2012-05-06 15:15:33 +00:00
|
|
|
depth = *r_drawsize * camera->lens / (-half_sensor) * scale[2];
|
|
|
|
fac = *r_drawsize;
|
2013-07-26 05:08:24 +00:00
|
|
|
scale_x = scale[0];
|
|
|
|
scale_y = scale[1];
|
2011-11-05 13:00:39 +00:00
|
|
|
}
|
|
|
|
|
2013-07-26 05:08:24 +00:00
|
|
|
facx = fac * r_asp[0] * scale_x;
|
|
|
|
facy = fac * r_asp[1] * scale_y;
|
|
|
|
r_shift[0] = camera->shiftx * fac * 2.0f * scale_x;
|
|
|
|
r_shift[1] = camera->shifty * fac * 2.0f * scale_y;
|
2011-11-05 13:00:39 +00:00
|
|
|
}
|
|
|
|
|
2012-05-06 15:15:33 +00:00
|
|
|
r_vec[0][0] = r_shift[0] + facx; r_vec[0][1] = r_shift[1] + facy; r_vec[0][2] = depth;
|
|
|
|
r_vec[1][0] = r_shift[0] + facx; r_vec[1][1] = r_shift[1] - facy; r_vec[1][2] = depth;
|
|
|
|
r_vec[2][0] = r_shift[0] - facx; r_vec[2][1] = r_shift[1] - facy; r_vec[2][2] = depth;
|
|
|
|
r_vec[3][0] = r_shift[0] - facx; r_vec[3][1] = r_shift[1] + facy; r_vec[3][2] = depth;
|
2011-11-05 13:00:39 +00:00
|
|
|
}
|
|
|
|
|
2012-05-05 00:58:22 +00:00
|
|
|
void BKE_camera_view_frame(Scene *scene, Camera *camera, float r_vec[4][3])
|
2011-11-05 13:00:39 +00:00
|
|
|
{
|
|
|
|
float dummy_asp[2];
|
|
|
|
float dummy_shift[2];
|
|
|
|
float dummy_drawsize;
|
2012-05-06 15:15:33 +00:00
|
|
|
const float dummy_scale[3] = {1.0f, 1.0f, 1.0f};
|
2011-11-05 13:00:39 +00:00
|
|
|
|
2012-05-05 00:58:22 +00:00
|
|
|
BKE_camera_view_frame_ex(scene, camera, FALSE, 1.0, dummy_scale,
|
2012-05-06 15:15:33 +00:00
|
|
|
dummy_asp, dummy_shift, &dummy_drawsize, r_vec);
|
2011-11-05 13:00:39 +00:00
|
|
|
}
|
|
|
|
|
2011-11-14 03:54:23 +00:00
|
|
|
|
|
|
|
typedef struct CameraViewFrameData {
|
|
|
|
float frame_tx[4][3];
|
|
|
|
float normal_tx[4][3];
|
|
|
|
float dist_vals[4];
|
|
|
|
unsigned int tot;
|
|
|
|
} CameraViewFrameData;
|
|
|
|
|
2012-05-05 00:58:22 +00:00
|
|
|
static void BKE_camera_to_frame_view_cb(const float co[3], void *user_data)
|
2011-11-14 03:54:23 +00:00
|
|
|
{
|
2012-05-06 15:15:33 +00:00
|
|
|
CameraViewFrameData *data = (CameraViewFrameData *)user_data;
|
2011-11-14 03:54:23 +00:00
|
|
|
unsigned int i;
|
|
|
|
|
2012-05-06 15:15:33 +00:00
|
|
|
for (i = 0; i < 4; i++) {
|
|
|
|
float nd = dist_to_plane_v3(co, data->frame_tx[i], data->normal_tx[i]);
|
2011-11-14 03:54:23 +00:00
|
|
|
if (nd < data->dist_vals[i]) {
|
2012-05-06 15:15:33 +00:00
|
|
|
data->dist_vals[i] = nd;
|
2011-11-14 03:54:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
data->tot++;
|
|
|
|
}
|
|
|
|
|
2012-03-18 07:38:51 +00:00
|
|
|
/* don't move the camera, just yield the fit location */
|
2011-11-19 01:24:40 +00:00
|
|
|
/* only valid for perspective cameras */
|
2012-05-05 00:58:22 +00:00
|
|
|
int BKE_camera_view_frame_fit_to_scene(Scene *scene, struct View3D *v3d, Object *camera_ob, float r_co[3])
|
2011-11-14 03:54:23 +00:00
|
|
|
{
|
2011-11-14 08:43:09 +00:00
|
|
|
float shift[2];
|
2011-11-14 03:54:23 +00:00
|
|
|
float plane_tx[4][3];
|
|
|
|
float rot_obmat[3][3];
|
2012-05-06 15:15:33 +00:00
|
|
|
const float zero[3] = {0, 0, 0};
|
2011-11-14 03:54:23 +00:00
|
|
|
CameraViewFrameData data_cb;
|
|
|
|
|
|
|
|
unsigned int i;
|
|
|
|
|
2012-05-05 00:58:22 +00:00
|
|
|
BKE_camera_view_frame(scene, camera_ob->data, data_cb.frame_tx);
|
2011-11-14 03:54:23 +00:00
|
|
|
|
|
|
|
copy_m3_m4(rot_obmat, camera_ob->obmat);
|
|
|
|
normalize_m3(rot_obmat);
|
|
|
|
|
2012-05-06 15:15:33 +00:00
|
|
|
for (i = 0; i < 4; i++) {
|
2011-11-14 08:43:09 +00:00
|
|
|
/* normalize so Z is always 1.0f*/
|
2012-05-06 15:15:33 +00:00
|
|
|
mul_v3_fl(data_cb.frame_tx[i], 1.0f / data_cb.frame_tx[i][2]);
|
2011-11-14 08:43:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* get the shift back out of the frame */
|
2012-05-06 15:15:33 +00:00
|
|
|
shift[0] = (data_cb.frame_tx[0][0] +
|
|
|
|
data_cb.frame_tx[1][0] +
|
|
|
|
data_cb.frame_tx[2][0] +
|
|
|
|
data_cb.frame_tx[3][0]) / 4.0f;
|
|
|
|
shift[1] = (data_cb.frame_tx[0][1] +
|
|
|
|
data_cb.frame_tx[1][1] +
|
|
|
|
data_cb.frame_tx[2][1] +
|
|
|
|
data_cb.frame_tx[3][1]) / 4.0f;
|
|
|
|
|
|
|
|
for (i = 0; i < 4; i++) {
|
2011-11-14 03:54:23 +00:00
|
|
|
mul_m3_v3(rot_obmat, data_cb.frame_tx[i]);
|
|
|
|
}
|
|
|
|
|
2012-05-06 15:15:33 +00:00
|
|
|
for (i = 0; i < 4; i++) {
|
2011-11-14 03:54:23 +00:00
|
|
|
normal_tri_v3(data_cb.normal_tx[i],
|
|
|
|
zero, data_cb.frame_tx[i], data_cb.frame_tx[(i + 1) % 4]);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* initialize callback data */
|
2012-05-06 15:15:33 +00:00
|
|
|
data_cb.dist_vals[0] =
|
|
|
|
data_cb.dist_vals[1] =
|
|
|
|
data_cb.dist_vals[2] =
|
|
|
|
data_cb.dist_vals[3] = FLT_MAX;
|
|
|
|
data_cb.tot = 0;
|
2011-11-14 03:54:23 +00:00
|
|
|
/* run callback on all visible points */
|
|
|
|
BKE_scene_foreach_display_point(scene, v3d, BA_SELECT,
|
2012-05-05 00:58:22 +00:00
|
|
|
BKE_camera_to_frame_view_cb, &data_cb);
|
2011-11-14 03:54:23 +00:00
|
|
|
|
|
|
|
if (data_cb.tot <= 1) {
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
else {
|
2011-11-14 08:43:09 +00:00
|
|
|
float plane_isect_1[3], plane_isect_1_no[3], plane_isect_1_other[3];
|
|
|
|
float plane_isect_2[3], plane_isect_2_no[3], plane_isect_2_other[3];
|
2011-11-14 03:54:23 +00:00
|
|
|
|
|
|
|
float plane_isect_pt_1[3], plane_isect_pt_2[3];
|
|
|
|
|
|
|
|
/* apply the dist-from-plane's to the transformed plane points */
|
2012-05-06 15:15:33 +00:00
|
|
|
for (i = 0; i < 4; i++) {
|
2011-11-14 03:54:23 +00:00
|
|
|
mul_v3_v3fl(plane_tx[i], data_cb.normal_tx[i], data_cb.dist_vals[i]);
|
|
|
|
}
|
|
|
|
|
2011-11-20 05:56:21 +00:00
|
|
|
isect_plane_plane_v3(plane_isect_1, plane_isect_1_no,
|
|
|
|
plane_tx[0], data_cb.normal_tx[0],
|
|
|
|
plane_tx[2], data_cb.normal_tx[2]);
|
|
|
|
isect_plane_plane_v3(plane_isect_2, plane_isect_2_no,
|
|
|
|
plane_tx[1], data_cb.normal_tx[1],
|
|
|
|
plane_tx[3], data_cb.normal_tx[3]);
|
|
|
|
|
|
|
|
add_v3_v3v3(plane_isect_1_other, plane_isect_1, plane_isect_1_no);
|
|
|
|
add_v3_v3v3(plane_isect_2_other, plane_isect_2, plane_isect_2_no);
|
|
|
|
|
|
|
|
if (isect_line_line_v3(plane_isect_1, plane_isect_1_other,
|
|
|
|
plane_isect_2, plane_isect_2_other,
|
|
|
|
plane_isect_pt_1, plane_isect_pt_2) == 0)
|
2011-11-14 03:54:23 +00:00
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
else {
|
2012-05-06 15:15:33 +00:00
|
|
|
float cam_plane_no[3] = {0.0f, 0.0f, -1.0f};
|
2011-11-20 05:56:21 +00:00
|
|
|
float plane_isect_delta[3];
|
|
|
|
float plane_isect_delta_len;
|
2011-11-14 03:54:23 +00:00
|
|
|
|
2011-11-20 05:56:21 +00:00
|
|
|
mul_m3_v3(rot_obmat, cam_plane_no);
|
2011-11-14 03:54:23 +00:00
|
|
|
|
2011-11-20 05:56:21 +00:00
|
|
|
sub_v3_v3v3(plane_isect_delta, plane_isect_pt_2, plane_isect_pt_1);
|
2012-05-06 15:15:33 +00:00
|
|
|
plane_isect_delta_len = len_v3(plane_isect_delta);
|
2011-11-14 08:43:09 +00:00
|
|
|
|
2011-11-20 05:56:21 +00:00
|
|
|
if (dot_v3v3(plane_isect_delta, cam_plane_no) > 0.0f) {
|
|
|
|
copy_v3_v3(r_co, plane_isect_pt_1);
|
2011-11-14 08:43:09 +00:00
|
|
|
|
2011-11-20 05:56:21 +00:00
|
|
|
/* offset shift */
|
|
|
|
normalize_v3(plane_isect_1_no);
|
|
|
|
madd_v3_v3fl(r_co, plane_isect_1_no, shift[1] * -plane_isect_delta_len);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
copy_v3_v3(r_co, plane_isect_pt_2);
|
2011-11-14 08:43:09 +00:00
|
|
|
|
2011-11-20 05:56:21 +00:00
|
|
|
/* offset shift */
|
|
|
|
normalize_v3(plane_isect_2_no);
|
|
|
|
madd_v3_v3fl(r_co, plane_isect_2_no, shift[0] * -plane_isect_delta_len);
|
|
|
|
}
|
2011-11-14 08:43:09 +00:00
|
|
|
|
2011-11-14 03:54:23 +00:00
|
|
|
|
2011-11-20 05:56:21 +00:00
|
|
|
return TRUE;
|
2011-11-14 03:54:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|