Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00019 * All rights reserved. 00020 * 00021 * The Original Code is: all of this file. 00022 * 00023 * Contributor(s): none yet. 00024 * 00025 * ***** END GPL LICENSE BLOCK ***** 00026 */ 00027 00032 #include <stdlib.h> 00033 00034 #include "DNA_camera_types.h" 00035 #include "DNA_lamp_types.h" 00036 #include "DNA_object_types.h" 00037 #include "DNA_scene_types.h" 00038 #include "DNA_view3d_types.h" 00039 00040 #include "BLI_math.h" 00041 #include "BLI_utildefines.h" 00042 00043 #include "BKE_animsys.h" 00044 #include "BKE_camera.h" 00045 #include "BKE_object.h" 00046 #include "BKE_global.h" 00047 #include "BKE_library.h" 00048 #include "BKE_main.h" 00049 #include "BKE_screen.h" 00050 00051 /****************************** Camera Datablock *****************************/ 00052 00053 void *add_camera(const char *name) 00054 { 00055 Camera *cam; 00056 00057 cam= alloc_libblock(&G.main->camera, ID_CA, name); 00058 00059 cam->lens= 35.0f; 00060 cam->sensor_x= 32.0f; 00061 cam->sensor_y= 18.0f; 00062 cam->clipsta= 0.1f; 00063 cam->clipend= 100.0f; 00064 cam->drawsize= 0.5f; 00065 cam->ortho_scale= 6.0; 00066 cam->flag |= CAM_SHOWPASSEPARTOUT; 00067 cam->passepartalpha = 0.5f; 00068 00069 return cam; 00070 } 00071 00072 Camera *copy_camera(Camera *cam) 00073 { 00074 Camera *camn; 00075 00076 camn= copy_libblock(&cam->id); 00077 00078 id_lib_extern((ID *)camn->dof_ob); 00079 00080 return camn; 00081 } 00082 00083 void make_local_camera(Camera *cam) 00084 { 00085 Main *bmain= G.main; 00086 Object *ob; 00087 int is_local= FALSE, is_lib= FALSE; 00088 00089 /* - only lib users: do nothing 00090 * - only local users: set flag 00091 * - mixed: make copy 00092 */ 00093 00094 if(cam->id.lib==NULL) return; 00095 if(cam->id.us==1) { 00096 id_clear_lib_data(bmain, &cam->id); 00097 return; 00098 } 00099 00100 for(ob= bmain->object.first; ob && ELEM(0, is_lib, is_local); ob= ob->id.next) { 00101 if(ob->data==cam) { 00102 if(ob->id.lib) is_lib= TRUE; 00103 else is_local= TRUE; 00104 } 00105 } 00106 00107 if(is_local && is_lib == FALSE) { 00108 id_clear_lib_data(bmain, &cam->id); 00109 } 00110 else if(is_local && is_lib) { 00111 Camera *cam_new= copy_camera(cam); 00112 00113 cam_new->id.us= 0; 00114 00115 /* Remap paths of new ID using old library as base. */ 00116 BKE_id_lib_local_paths(bmain, cam->id.lib, &cam_new->id); 00117 00118 for(ob= bmain->object.first; ob; ob= ob->id.next) { 00119 if(ob->data == cam) { 00120 if(ob->id.lib==NULL) { 00121 ob->data= cam_new; 00122 cam_new->id.us++; 00123 cam->id.us--; 00124 } 00125 } 00126 } 00127 } 00128 } 00129 00130 void free_camera(Camera *ca) 00131 { 00132 BKE_free_animdata((ID *)ca); 00133 } 00134 00135 /******************************** Camera Usage *******************************/ 00136 00137 void object_camera_mode(RenderData *rd, Object *cam_ob) 00138 { 00139 rd->mode &= ~(R_ORTHO|R_PANORAMA); 00140 00141 if(cam_ob && cam_ob->type==OB_CAMERA) { 00142 Camera *cam= cam_ob->data; 00143 if(cam->type == CAM_ORTHO) rd->mode |= R_ORTHO; 00144 if(cam->flag & CAM_PANORAMA) rd->mode |= R_PANORAMA; 00145 } 00146 } 00147 00148 /* get the camera's dof value, takes the dof object into account */ 00149 float object_camera_dof_distance(Object *ob) 00150 { 00151 Camera *cam = (Camera *)ob->data; 00152 if (ob->type != OB_CAMERA) 00153 return 0.0f; 00154 if (cam->dof_ob) { 00155 /* too simple, better to return the distance on the view axis only 00156 * return len_v3v3(ob->obmat[3], cam->dof_ob->obmat[3]); */ 00157 float mat[4][4], imat[4][4], obmat[4][4]; 00158 00159 copy_m4_m4(obmat, ob->obmat); 00160 normalize_m4(obmat); 00161 invert_m4_m4(imat, obmat); 00162 mult_m4_m4m4(mat, imat, cam->dof_ob->obmat); 00163 return fabsf(mat[3][2]); 00164 } 00165 return cam->YF_dofdist; 00166 } 00167 00168 float camera_sensor_size(int sensor_fit, float sensor_x, float sensor_y) 00169 { 00170 /* sensor size used to fit to. for auto, sensor_x is both x and y. */ 00171 if(sensor_fit == CAMERA_SENSOR_FIT_VERT) 00172 return sensor_y; 00173 00174 return sensor_x; 00175 } 00176 00177 int camera_sensor_fit(int sensor_fit, float sizex, float sizey) 00178 { 00179 if(sensor_fit == CAMERA_SENSOR_FIT_AUTO) { 00180 if(sizex >= sizey) 00181 return CAMERA_SENSOR_FIT_HOR; 00182 else 00183 return CAMERA_SENSOR_FIT_VERT; 00184 } 00185 00186 return sensor_fit; 00187 } 00188 00189 /******************************** Camera Params *******************************/ 00190 00191 void camera_params_init(CameraParams *params) 00192 { 00193 memset(params, 0, sizeof(CameraParams)); 00194 00195 /* defaults */ 00196 params->sensor_x= DEFAULT_SENSOR_WIDTH; 00197 params->sensor_y= DEFAULT_SENSOR_HEIGHT; 00198 params->sensor_fit= CAMERA_SENSOR_FIT_AUTO; 00199 00200 params->zoom= 1.0f; 00201 } 00202 00203 void camera_params_from_object(CameraParams *params, Object *ob) 00204 { 00205 if(!ob) 00206 return; 00207 00208 if(ob->type==OB_CAMERA) { 00209 /* camera object */ 00210 Camera *cam= ob->data; 00211 00212 if(cam->type == CAM_ORTHO) 00213 params->is_ortho= TRUE; 00214 params->lens= cam->lens; 00215 params->ortho_scale= cam->ortho_scale; 00216 00217 params->shiftx= cam->shiftx; 00218 params->shifty= cam->shifty; 00219 00220 params->sensor_x= cam->sensor_x; 00221 params->sensor_y= cam->sensor_y; 00222 params->sensor_fit= cam->sensor_fit; 00223 00224 params->clipsta= cam->clipsta; 00225 params->clipend= cam->clipend; 00226 } 00227 else if(ob->type==OB_LAMP) { 00228 /* lamp object */ 00229 Lamp *la= ob->data; 00230 float fac= cosf((float)M_PI*la->spotsize/360.0f); 00231 float phi= acos(fac); 00232 00233 params->lens= 16.0f*fac/sinf(phi); 00234 if(params->lens==0.0f) 00235 params->lens= 35.0f; 00236 00237 params->clipsta= la->clipsta; 00238 params->clipend= la->clipend; 00239 } 00240 } 00241 00242 void camera_params_from_view3d(CameraParams *params, View3D *v3d, RegionView3D *rv3d) 00243 { 00244 /* common */ 00245 params->lens= v3d->lens; 00246 params->clipsta= v3d->near; 00247 params->clipend= v3d->far; 00248 00249 if(rv3d->persp==RV3D_CAMOB) { 00250 /* camera view */ 00251 camera_params_from_object(params, v3d->camera); 00252 00253 params->zoom= BKE_screen_view3d_zoom_to_fac((float)rv3d->camzoom); 00254 00255 params->offsetx= 2.0f*rv3d->camdx*params->zoom; 00256 params->offsety= 2.0f*rv3d->camdy*params->zoom; 00257 00258 params->shiftx *= params->zoom; 00259 params->shifty *= params->zoom; 00260 00261 params->zoom= 1.0f/params->zoom; 00262 } 00263 else if(rv3d->persp==RV3D_ORTHO) { 00264 /* orthographic view */ 00265 params->clipend *= 0.5f; // otherwise too extreme low zbuffer quality 00266 params->clipsta= - params->clipend; 00267 00268 params->is_ortho= TRUE; 00269 params->ortho_scale = rv3d->dist; 00270 params->zoom= 2.0f; 00271 } 00272 else { 00273 /* perspective view */ 00274 params->zoom= 2.0f; 00275 } 00276 } 00277 00278 void camera_params_compute_viewplane(CameraParams *params, int winx, int winy, float xasp, float yasp) 00279 { 00280 rctf viewplane; 00281 float pixsize, viewfac, sensor_size, dx, dy; 00282 int sensor_fit; 00283 00284 /* fields rendering */ 00285 params->ycor= yasp/xasp; 00286 if(params->use_fields) 00287 params->ycor *= 2.0f; 00288 00289 if(params->is_ortho) { 00290 /* orthographic camera */ 00291 /* scale == 1.0 means exact 1 to 1 mapping */ 00292 pixsize= params->ortho_scale; 00293 } 00294 else { 00295 /* perspective camera */ 00296 sensor_size= camera_sensor_size(params->sensor_fit, params->sensor_x, params->sensor_y); 00297 pixsize= (sensor_size * params->clipsta)/params->lens; 00298 } 00299 00300 /* determine sensor fit */ 00301 sensor_fit = camera_sensor_fit(params->sensor_fit, xasp*winx, yasp*winy); 00302 00303 if(sensor_fit==CAMERA_SENSOR_FIT_HOR) 00304 viewfac= winx; 00305 else 00306 viewfac= params->ycor * winy; 00307 00308 pixsize /= viewfac; 00309 00310 /* extra zoom factor */ 00311 pixsize *= params->zoom; 00312 00313 /* compute view plane: 00314 * fully centered, zbuffer fills in jittered between -.5 and +.5 */ 00315 viewplane.xmin= -0.5f*(float)winx; 00316 viewplane.ymin= -0.5f*params->ycor*(float)winy; 00317 viewplane.xmax= 0.5f*(float)winx; 00318 viewplane.ymax= 0.5f*params->ycor*(float)winy; 00319 00320 /* lens shift and offset */ 00321 dx= params->shiftx*viewfac + winx*params->offsetx; 00322 dy= params->shifty*viewfac + winy*params->offsety; 00323 00324 viewplane.xmin += dx; 00325 viewplane.ymin += dy; 00326 viewplane.xmax += dx; 00327 viewplane.ymax += dy; 00328 00329 /* fields offset */ 00330 if(params->field_second) { 00331 if(params->field_odd) { 00332 viewplane.ymin-= 0.5f * params->ycor; 00333 viewplane.ymax-= 0.5f * params->ycor; 00334 } 00335 else { 00336 viewplane.ymin+= 0.5f * params->ycor; 00337 viewplane.ymax+= 0.5f * params->ycor; 00338 } 00339 } 00340 00341 /* the window matrix is used for clipping, and not changed during OSA steps */ 00342 /* using an offset of +0.5 here would give clip errors on edges */ 00343 viewplane.xmin *= pixsize; 00344 viewplane.xmax *= pixsize; 00345 viewplane.ymin *= pixsize; 00346 viewplane.ymax *= pixsize; 00347 00348 params->viewdx= pixsize; 00349 params->viewdy= params->ycor * pixsize; 00350 params->viewplane= viewplane; 00351 } 00352 00353 /* viewplane is assumed to be already computed */ 00354 void camera_params_compute_matrix(CameraParams *params) 00355 { 00356 rctf viewplane= params->viewplane; 00357 00358 /* compute projection matrix */ 00359 if(params->is_ortho) 00360 orthographic_m4(params->winmat, viewplane.xmin, viewplane.xmax, 00361 viewplane.ymin, viewplane.ymax, params->clipsta, params->clipend); 00362 else 00363 perspective_m4(params->winmat, viewplane.xmin, viewplane.xmax, 00364 viewplane.ymin, viewplane.ymax, params->clipsta, params->clipend); 00365 } 00366 00367 /***************************** Camera View Frame *****************************/ 00368 00369 void camera_view_frame_ex(Scene *scene, Camera *camera, float drawsize, const short do_clip, const float scale[3], 00370 float r_asp[2], float r_shift[2], float *r_drawsize, float r_vec[4][3]) 00371 { 00372 float facx, facy; 00373 float depth; 00374 00375 /* aspect correcton */ 00376 if (scene) { 00377 float aspx= (float) scene->r.xsch*scene->r.xasp; 00378 float aspy= (float) scene->r.ysch*scene->r.yasp; 00379 int sensor_fit= camera_sensor_fit(camera->sensor_fit, aspx, aspy); 00380 00381 if(sensor_fit==CAMERA_SENSOR_FIT_HOR) { 00382 r_asp[0]= 1.0; 00383 r_asp[1]= aspy / aspx; 00384 } 00385 else { 00386 r_asp[0]= aspx / aspy; 00387 r_asp[1]= 1.0; 00388 } 00389 } 00390 else { 00391 r_asp[0]= 1.0f; 00392 r_asp[1]= 1.0f; 00393 } 00394 00395 if(camera->type==CAM_ORTHO) { 00396 facx= 0.5f * camera->ortho_scale * r_asp[0] * scale[0]; 00397 facy= 0.5f * camera->ortho_scale * r_asp[1] * scale[1]; 00398 r_shift[0]= camera->shiftx * camera->ortho_scale * scale[0]; 00399 r_shift[1]= camera->shifty * camera->ortho_scale * scale[1]; 00400 depth= do_clip ? -((camera->clipsta * scale[2]) + 0.1f) : - drawsize * camera->ortho_scale * scale[2]; 00401 00402 *r_drawsize= 0.5f * camera->ortho_scale; 00403 } 00404 else { 00405 /* that way it's always visible - clipsta+0.1 */ 00406 float fac; 00407 float half_sensor= 0.5f*((camera->sensor_fit==CAMERA_SENSOR_FIT_VERT) ? (camera->sensor_y) : (camera->sensor_x)); 00408 00409 *r_drawsize= drawsize / ((scale[0] + scale[1] + scale[2]) / 3.0f); 00410 00411 if(do_clip) { 00412 /* fixed depth, variable size (avoids exceeding clipping range) */ 00413 depth = -(camera->clipsta + 0.1f); 00414 fac = depth / (camera->lens/(-half_sensor) * scale[2]); 00415 } 00416 else { 00417 /* fixed size, variable depth (stays a reasonable size in the 3D view) */ 00418 depth= *r_drawsize * camera->lens/(-half_sensor) * scale[2]; 00419 fac= *r_drawsize; 00420 } 00421 00422 facx= fac * r_asp[0] * scale[0]; 00423 facy= fac * r_asp[1] * scale[1]; 00424 r_shift[0]= camera->shiftx*fac*2 * scale[0]; 00425 r_shift[1]= camera->shifty*fac*2 * scale[1]; 00426 } 00427 00428 r_vec[0][0]= r_shift[0] + facx; r_vec[0][1]= r_shift[1] + facy; r_vec[0][2]= depth; 00429 r_vec[1][0]= r_shift[0] + facx; r_vec[1][1]= r_shift[1] - facy; r_vec[1][2]= depth; 00430 r_vec[2][0]= r_shift[0] - facx; r_vec[2][1]= r_shift[1] - facy; r_vec[2][2]= depth; 00431 r_vec[3][0]= r_shift[0] - facx; r_vec[3][1]= r_shift[1] + facy; r_vec[3][2]= depth; 00432 } 00433 00434 void camera_view_frame(Scene *scene, Camera *camera, float r_vec[4][3]) 00435 { 00436 float dummy_asp[2]; 00437 float dummy_shift[2]; 00438 float dummy_drawsize; 00439 const float dummy_scale[3]= {1.0f, 1.0f, 1.0f}; 00440 00441 camera_view_frame_ex(scene, camera, FALSE, 1.0, dummy_scale, 00442 dummy_asp, dummy_shift, &dummy_drawsize, r_vec); 00443 } 00444 00445 00446 typedef struct CameraViewFrameData { 00447 float frame_tx[4][3]; 00448 float normal_tx[4][3]; 00449 float dist_vals[4]; 00450 unsigned int tot; 00451 } CameraViewFrameData; 00452 00453 static void camera_to_frame_view_cb(const float co[3], void *user_data) 00454 { 00455 CameraViewFrameData *data= (CameraViewFrameData *)user_data; 00456 unsigned int i; 00457 00458 for (i= 0; i < 4; i++) { 00459 float nd= dist_to_plane_v3(co, data->frame_tx[i], data->normal_tx[i]); 00460 if (nd < data->dist_vals[i]) { 00461 data->dist_vals[i]= nd; 00462 } 00463 } 00464 00465 data->tot++; 00466 } 00467 00468 /* dont move the camera, just yield the fit location */ 00469 /* only valid for perspective cameras */ 00470 int camera_view_frame_fit_to_scene(Scene *scene, struct View3D *v3d, Object *camera_ob, float r_co[3]) 00471 { 00472 float shift[2]; 00473 float plane_tx[4][3]; 00474 float rot_obmat[3][3]; 00475 const float zero[3]= {0,0,0}; 00476 CameraViewFrameData data_cb; 00477 00478 unsigned int i; 00479 00480 camera_view_frame(scene, camera_ob->data, data_cb.frame_tx); 00481 00482 copy_m3_m4(rot_obmat, camera_ob->obmat); 00483 normalize_m3(rot_obmat); 00484 00485 for (i= 0; i < 4; i++) { 00486 /* normalize so Z is always 1.0f*/ 00487 mul_v3_fl(data_cb.frame_tx[i], 1.0f/data_cb.frame_tx[i][2]); 00488 } 00489 00490 /* get the shift back out of the frame */ 00491 shift[0]= (data_cb.frame_tx[0][0] + 00492 data_cb.frame_tx[1][0] + 00493 data_cb.frame_tx[2][0] + 00494 data_cb.frame_tx[3][0]) / 4.0f; 00495 shift[1]= (data_cb.frame_tx[0][1] + 00496 data_cb.frame_tx[1][1] + 00497 data_cb.frame_tx[2][1] + 00498 data_cb.frame_tx[3][1]) / 4.0f; 00499 00500 for (i= 0; i < 4; i++) { 00501 mul_m3_v3(rot_obmat, data_cb.frame_tx[i]); 00502 } 00503 00504 for (i= 0; i < 4; i++) { 00505 normal_tri_v3(data_cb.normal_tx[i], 00506 zero, data_cb.frame_tx[i], data_cb.frame_tx[(i + 1) % 4]); 00507 } 00508 00509 /* initialize callback data */ 00510 data_cb.dist_vals[0]= 00511 data_cb.dist_vals[1]= 00512 data_cb.dist_vals[2]= 00513 data_cb.dist_vals[3]= FLT_MAX; 00514 data_cb.tot= 0; 00515 /* run callback on all visible points */ 00516 BKE_scene_foreach_display_point(scene, v3d, BA_SELECT, 00517 camera_to_frame_view_cb, &data_cb); 00518 00519 if (data_cb.tot <= 1) { 00520 return FALSE; 00521 } 00522 else { 00523 float plane_isect_1[3], plane_isect_1_no[3], plane_isect_1_other[3]; 00524 float plane_isect_2[3], plane_isect_2_no[3], plane_isect_2_other[3]; 00525 00526 float plane_isect_pt_1[3], plane_isect_pt_2[3]; 00527 00528 /* apply the dist-from-plane's to the transformed plane points */ 00529 for (i= 0; i < 4; i++) { 00530 mul_v3_v3fl(plane_tx[i], data_cb.normal_tx[i], data_cb.dist_vals[i]); 00531 } 00532 00533 isect_plane_plane_v3(plane_isect_1, plane_isect_1_no, 00534 plane_tx[0], data_cb.normal_tx[0], 00535 plane_tx[2], data_cb.normal_tx[2]); 00536 isect_plane_plane_v3(plane_isect_2, plane_isect_2_no, 00537 plane_tx[1], data_cb.normal_tx[1], 00538 plane_tx[3], data_cb.normal_tx[3]); 00539 00540 add_v3_v3v3(plane_isect_1_other, plane_isect_1, plane_isect_1_no); 00541 add_v3_v3v3(plane_isect_2_other, plane_isect_2, plane_isect_2_no); 00542 00543 if (isect_line_line_v3(plane_isect_1, plane_isect_1_other, 00544 plane_isect_2, plane_isect_2_other, 00545 plane_isect_pt_1, plane_isect_pt_2) == 0) 00546 { 00547 return FALSE; 00548 } 00549 else { 00550 float cam_plane_no[3]= {0.0f, 0.0f, -1.0f}; 00551 float plane_isect_delta[3]; 00552 float plane_isect_delta_len; 00553 00554 mul_m3_v3(rot_obmat, cam_plane_no); 00555 00556 sub_v3_v3v3(plane_isect_delta, plane_isect_pt_2, plane_isect_pt_1); 00557 plane_isect_delta_len= len_v3(plane_isect_delta); 00558 00559 if (dot_v3v3(plane_isect_delta, cam_plane_no) > 0.0f) { 00560 copy_v3_v3(r_co, plane_isect_pt_1); 00561 00562 /* offset shift */ 00563 normalize_v3(plane_isect_1_no); 00564 madd_v3_v3fl(r_co, plane_isect_1_no, shift[1] * -plane_isect_delta_len); 00565 } 00566 else { 00567 copy_v3_v3(r_co, plane_isect_pt_2); 00568 00569 /* offset shift */ 00570 normalize_v3(plane_isect_2_no); 00571 madd_v3_v3fl(r_co, plane_isect_2_no, shift[0] * -plane_isect_delta_len); 00572 } 00573 00574 00575 return TRUE; 00576 } 00577 } 00578 }