Blender V2.61 - r43446
|
00001 /* 00002 * Copyright 2011, Blender Foundation. 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 00019 #include "camera.h" 00020 #include "scene.h" 00021 00022 #include "blender_sync.h" 00023 #include "blender_util.h" 00024 00025 CCL_NAMESPACE_BEGIN 00026 00027 /* Blender Camera Intermediate: we first convert both the offline and 3d view 00028 * render camera to this, and from there convert to our native camera format. */ 00029 00030 struct BlenderCamera { 00031 float nearclip; 00032 float farclip; 00033 00034 bool ortho; 00035 float ortho_scale; 00036 00037 float lens; 00038 00039 float aperturesize; 00040 uint apertureblades; 00041 float aperturerotation; 00042 float focaldistance; 00043 00044 float2 shift; 00045 float2 offset; 00046 float zoom; 00047 00048 float2 pixelaspect; 00049 00050 enum { AUTO, HORIZONTAL, VERTICAL } sensor_fit; 00051 float sensor_width; 00052 float sensor_height; 00053 00054 Transform matrix; 00055 }; 00056 00057 static void blender_camera_init(BlenderCamera *bcam) 00058 { 00059 memset(bcam, 0, sizeof(BlenderCamera)); 00060 00061 bcam->zoom = 1.0f; 00062 bcam->pixelaspect = make_float2(1.0f, 1.0f); 00063 bcam->sensor_width = 32.0f; 00064 bcam->sensor_height = 18.0f; 00065 bcam->sensor_fit = BlenderCamera::AUTO; 00066 } 00067 00068 static float blender_camera_focal_distance(BL::Object b_ob, BL::Camera b_camera) 00069 { 00070 BL::Object b_dof_object = b_camera.dof_object(); 00071 00072 if(!b_dof_object) 00073 return b_camera.dof_distance(); 00074 00075 /* for dof object, return distance along camera Z direction */ 00076 Transform obmat = transform_clear_scale(get_transform(b_ob.matrix_world())); 00077 Transform dofmat = get_transform(b_dof_object.matrix_world()); 00078 Transform mat = transform_inverse(obmat) * dofmat; 00079 00080 return fabsf(transform_get_column(&mat, 3).z); 00081 } 00082 00083 static void blender_camera_from_object(BlenderCamera *bcam, BL::Object b_ob) 00084 { 00085 BL::ID b_ob_data = b_ob.data(); 00086 00087 if(b_ob_data.is_a(&RNA_Camera)) { 00088 BL::Camera b_camera(b_ob_data); 00089 PointerRNA ccamera = RNA_pointer_get(&b_camera.ptr, "cycles"); 00090 00091 bcam->nearclip = b_camera.clip_start(); 00092 bcam->farclip = b_camera.clip_end(); 00093 00094 bcam->ortho = (b_camera.type() == BL::Camera::type_ORTHO); 00095 bcam->ortho_scale = b_camera.ortho_scale(); 00096 00097 bcam->lens = b_camera.lens(); 00098 bcam->aperturesize = RNA_float_get(&ccamera, "aperture_size"); 00099 bcam->apertureblades = RNA_int_get(&ccamera, "aperture_blades"); 00100 bcam->aperturerotation = RNA_float_get(&ccamera, "aperture_rotation"); 00101 bcam->focaldistance = blender_camera_focal_distance(b_ob, b_camera); 00102 00103 bcam->shift.x = b_camera.shift_x(); 00104 bcam->shift.y = b_camera.shift_y(); 00105 00106 bcam->sensor_width = b_camera.sensor_width(); 00107 bcam->sensor_height = b_camera.sensor_height(); 00108 00109 if(b_camera.sensor_fit() == BL::Camera::sensor_fit_AUTO) 00110 bcam->sensor_fit = BlenderCamera::AUTO; 00111 else if(b_camera.sensor_fit() == BL::Camera::sensor_fit_HORIZONTAL) 00112 bcam->sensor_fit = BlenderCamera::HORIZONTAL; 00113 else 00114 bcam->sensor_fit = BlenderCamera::VERTICAL; 00115 } 00116 else { 00117 /* from lamp not implemented yet */ 00118 } 00119 } 00120 00121 static void blender_camera_sync(Camera *cam, BlenderCamera *bcam, int width, int height) 00122 { 00123 /* copy camera to compare later */ 00124 Camera prevcam = *cam; 00125 00126 /* dimensions */ 00127 float xratio = width*bcam->pixelaspect.x; 00128 float yratio = height*bcam->pixelaspect.y; 00129 00130 /* compute x/y aspect and ratio */ 00131 float aspectratio, xaspect, yaspect; 00132 00133 /* sensor fitting */ 00134 bool horizontal_fit; 00135 float sensor_size; 00136 00137 if(bcam->sensor_fit == BlenderCamera::AUTO) { 00138 horizontal_fit = (xratio > yratio); 00139 sensor_size = bcam->sensor_width; 00140 } 00141 else if(bcam->sensor_fit == BlenderCamera::HORIZONTAL) { 00142 horizontal_fit = true; 00143 sensor_size = bcam->sensor_width; 00144 } 00145 else { 00146 horizontal_fit = false; 00147 sensor_size = bcam->sensor_height; 00148 } 00149 00150 if(horizontal_fit) { 00151 aspectratio= xratio/yratio; 00152 xaspect= aspectratio; 00153 yaspect= 1.0f; 00154 } 00155 else { 00156 aspectratio= yratio/xratio; 00157 xaspect= 1.0f; 00158 yaspect= aspectratio; 00159 } 00160 00161 /* modify aspect for orthographic scale */ 00162 if(bcam->ortho) { 00163 xaspect = xaspect*bcam->ortho_scale/(aspectratio*2.0f); 00164 yaspect = yaspect*bcam->ortho_scale/(aspectratio*2.0f); 00165 aspectratio = bcam->ortho_scale/2.0f; 00166 } 00167 00168 /* set viewplane */ 00169 cam->left = -xaspect; 00170 cam->right = xaspect; 00171 cam->bottom = -yaspect; 00172 cam->top = yaspect; 00173 00174 /* zoom for 3d camera view */ 00175 cam->left *= bcam->zoom; 00176 cam->right *= bcam->zoom; 00177 cam->bottom *= bcam->zoom; 00178 cam->top *= bcam->zoom; 00179 00180 /* modify viewplane with camera shift and 3d camera view offset */ 00181 float dx = 2.0f*(aspectratio*bcam->shift.x + bcam->offset.x*xaspect*2.0f); 00182 float dy = 2.0f*(aspectratio*bcam->shift.y + bcam->offset.y*yaspect*2.0f); 00183 00184 cam->left += dx; 00185 cam->right += dx; 00186 cam->bottom += dy; 00187 cam->top += dy; 00188 00189 /* clipping distances */ 00190 cam->nearclip = bcam->nearclip; 00191 cam->farclip = bcam->farclip; 00192 00193 /* orthographic */ 00194 cam->ortho = bcam->ortho; 00195 00196 /* perspective */ 00197 cam->fov = 2.0f*atan((0.5f*sensor_size)/bcam->lens/aspectratio); 00198 cam->focaldistance = bcam->focaldistance; 00199 cam->aperturesize = bcam->aperturesize; 00200 cam->blades = bcam->apertureblades; 00201 cam->bladesrotation = bcam->aperturerotation; 00202 00203 /* transform, note the blender camera points along the negative z-axis */ 00204 cam->matrix = bcam->matrix * transform_scale(1.0f, 1.0f, -1.0f); 00205 cam->matrix = transform_clear_scale(cam->matrix); 00206 00207 /* set update flag */ 00208 if(cam->modified(prevcam)) 00209 cam->tag_update(); 00210 } 00211 00212 /* Sync Render Camera */ 00213 00214 void BlenderSync::sync_camera(int width, int height) 00215 { 00216 BlenderCamera bcam; 00217 blender_camera_init(&bcam); 00218 00219 /* pixel aspect */ 00220 BL::RenderSettings r = b_scene.render(); 00221 00222 bcam.pixelaspect.x = r.pixel_aspect_x(); 00223 bcam.pixelaspect.y = r.pixel_aspect_y(); 00224 00225 /* camera object */ 00226 BL::Object b_ob = b_scene.camera(); 00227 00228 if(b_ob) { 00229 blender_camera_from_object(&bcam, b_ob); 00230 bcam.matrix = get_transform(b_ob.matrix_world()); 00231 } 00232 00233 /* sync */ 00234 Camera *cam = scene->camera; 00235 blender_camera_sync(cam, &bcam, width, height); 00236 } 00237 00238 /* Sync 3D View Camera */ 00239 00240 void BlenderSync::sync_view(BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, int width, int height) 00241 { 00242 BlenderCamera bcam; 00243 blender_camera_init(&bcam); 00244 00245 /* 3d view parameters */ 00246 bcam.nearclip = b_v3d.clip_start(); 00247 bcam.farclip = b_v3d.clip_end(); 00248 bcam.lens = b_v3d.lens(); 00249 00250 if(b_rv3d.view_perspective() == BL::RegionView3D::view_perspective_CAMERA) { 00251 /* camera view */ 00252 BL::Object b_ob = b_scene.camera(); 00253 00254 if(b_ob) { 00255 blender_camera_from_object(&bcam, b_ob); 00256 00257 /* magic zoom formula */ 00258 bcam.zoom = (float)b_rv3d.view_camera_zoom(); 00259 bcam.zoom = (1.41421f + bcam.zoom/50.0f); 00260 bcam.zoom *= bcam.zoom; 00261 bcam.zoom = 2.0f/bcam.zoom; 00262 00263 /* offset */ 00264 bcam.offset = get_float2(b_rv3d.view_camera_offset()); 00265 } 00266 } 00267 else if(b_rv3d.view_perspective() == BL::RegionView3D::view_perspective_ORTHO) { 00268 /* orthographic view */ 00269 bcam.farclip *= 0.5; 00270 bcam.nearclip = -bcam.farclip; 00271 00272 bcam.ortho = true; 00273 bcam.ortho_scale = b_rv3d.view_distance(); 00274 } 00275 00276 bcam.zoom *= 2.0f; 00277 00278 /* 3d view transform */ 00279 bcam.matrix = transform_inverse(get_transform(b_rv3d.view_matrix())); 00280 00281 /* sync */ 00282 blender_camera_sync(scene->camera, &bcam, width, height); 00283 } 00284 00285 BufferParams BlenderSync::get_buffer_params(BL::Scene b_scene, BL::RegionView3D b_rv3d, int width, int height) 00286 { 00287 BufferParams params; 00288 00289 params.full_width = width; 00290 params.full_height = height; 00291 00292 /* border render */ 00293 BL::RenderSettings r = b_scene.render(); 00294 00295 if(!b_rv3d && r.use_border()) { 00296 params.full_x = r.border_min_x()*width; 00297 params.full_y = r.border_min_y()*height; 00298 params.width = (int)(r.border_max_x()*width) - params.full_x; 00299 params.height = (int)(r.border_max_y()*height) - params.full_y; 00300 } 00301 else { 00302 params.width = width; 00303 params.height = height; 00304 } 00305 00306 return params; 00307 } 00308 00309 CCL_NAMESPACE_END 00310