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 "util_vector.h" 00023 00024 CCL_NAMESPACE_BEGIN 00025 00026 Camera::Camera() 00027 { 00028 shutteropen = 0.0f; 00029 shutterclose = 1.0f; 00030 00031 aperturesize = 0.0f; 00032 focaldistance = 10.0f; 00033 blades = 0; 00034 bladesrotation = 0.0f; 00035 00036 matrix = transform_identity(); 00037 00038 ortho = false; 00039 fov = M_PI_F/4.0f; 00040 00041 nearclip = 1e-5f; 00042 farclip = 1e5f; 00043 00044 width = 1024; 00045 height = 512; 00046 00047 left = -((float)width/(float)height); 00048 right = (float)width/(float)height; 00049 bottom = -1.0f; 00050 top = 1.0f; 00051 00052 screentoworld = transform_identity(); 00053 rastertoworld = transform_identity(); 00054 ndctoworld = transform_identity(); 00055 rastertocamera = transform_identity(); 00056 cameratoworld = transform_identity(); 00057 worldtoraster = transform_identity(); 00058 00059 dx = make_float3(0.0f, 0.0f, 0.0f); 00060 dy = make_float3(0.0f, 0.0f, 0.0f); 00061 00062 need_update = true; 00063 need_device_update = true; 00064 } 00065 00066 Camera::~Camera() 00067 { 00068 } 00069 00070 void Camera::update() 00071 { 00072 if(!need_update) 00073 return; 00074 00075 /* ndc to raster */ 00076 Transform screentocamera; 00077 Transform ndctoraster = transform_scale(width, height, 1.0f); 00078 00079 /* raster to screen */ 00080 Transform screentoraster = ndctoraster * 00081 transform_scale(1.0f/(right - left), 1.0f/(top - bottom), 1.0f) * 00082 transform_translate(-left, -bottom, 0.0f); 00083 00084 Transform rastertoscreen = transform_inverse(screentoraster); 00085 00086 /* screen to camera */ 00087 if(ortho) 00088 screentocamera = transform_inverse(transform_orthographic(nearclip, farclip)); 00089 else 00090 screentocamera = transform_inverse(transform_perspective(fov, nearclip, farclip)); 00091 00092 rastertocamera = screentocamera * rastertoscreen; 00093 00094 cameratoworld = matrix; 00095 screentoworld = cameratoworld * screentocamera; 00096 rastertoworld = cameratoworld * rastertocamera; 00097 ndctoworld = rastertoworld * ndctoraster; 00098 worldtoraster = transform_inverse(rastertoworld); 00099 00100 /* differentials */ 00101 if(ortho) { 00102 dx = transform_direction(&rastertocamera, make_float3(1, 0, 0)); 00103 dy = transform_direction(&rastertocamera, make_float3(0, 1, 0)); 00104 } 00105 else { 00106 dx = transform(&rastertocamera, make_float3(1, 0, 0)) - 00107 transform(&rastertocamera, make_float3(0, 0, 0)); 00108 dy = transform(&rastertocamera, make_float3(0, 1, 0)) - 00109 transform(&rastertocamera, make_float3(0, 0, 0)); 00110 } 00111 00112 dx = transform_direction(&cameratoworld, dx); 00113 dy = transform_direction(&cameratoworld, dy); 00114 00115 need_update = false; 00116 need_device_update = true; 00117 } 00118 00119 void Camera::device_update(Device *device, DeviceScene *dscene) 00120 { 00121 update(); 00122 00123 if(!need_device_update) 00124 return; 00125 00126 KernelCamera *kcam = &dscene->data.cam; 00127 00128 /* store matrices */ 00129 kcam->screentoworld = screentoworld; 00130 kcam->rastertoworld = rastertoworld; 00131 kcam->ndctoworld = ndctoworld; 00132 kcam->rastertocamera = rastertocamera; 00133 kcam->cameratoworld = cameratoworld; 00134 kcam->worldtoscreen = transform_inverse(screentoworld); 00135 kcam->worldtoraster = transform_inverse(rastertoworld); 00136 kcam->worldtondc = transform_inverse(ndctoworld); 00137 kcam->worldtocamera = transform_inverse(cameratoworld); 00138 00139 /* depth of field */ 00140 kcam->aperturesize = aperturesize; 00141 kcam->focaldistance = focaldistance; 00142 kcam->blades = (blades < 3)? 0.0f: blades; 00143 kcam->bladesrotation = bladesrotation; 00144 00145 /* motion blur */ 00146 kcam->shutteropen = shutteropen; 00147 kcam->shutterclose = shutterclose; 00148 00149 /* type */ 00150 kcam->ortho = ortho; 00151 00152 /* store differentials */ 00153 kcam->dx = float3_to_float4(dx); 00154 kcam->dy = float3_to_float4(dy); 00155 00156 /* clipping */ 00157 kcam->nearclip = nearclip; 00158 kcam->cliplength = (farclip == FLT_MAX)? FLT_MAX: farclip - nearclip; 00159 00160 need_device_update = false; 00161 } 00162 00163 void Camera::device_free(Device *device, DeviceScene *dscene) 00164 { 00165 /* nothing to free, only writing to constant memory */ 00166 } 00167 00168 bool Camera::modified(const Camera& cam) 00169 { 00170 return !((shutteropen == cam.shutteropen) && 00171 (shutterclose == cam.shutterclose) && 00172 (aperturesize == cam.aperturesize) && 00173 (blades == cam.blades) && 00174 (bladesrotation == cam.bladesrotation) && 00175 (focaldistance == cam.focaldistance) && 00176 (ortho == cam.ortho) && 00177 (fov == cam.fov) && 00178 (nearclip == cam.nearclip) && 00179 (farclip == cam.farclip) && 00180 // modified for progressive render 00181 // (width == cam.width) && 00182 // (height == cam.height) && 00183 (left == cam.left) && 00184 (right == cam.right) && 00185 (bottom == cam.bottom) && 00186 (top == cam.top) && 00187 (matrix == cam.matrix)); 00188 } 00189 00190 void Camera::tag_update() 00191 { 00192 need_update = true; 00193 } 00194 00195 CCL_NAMESPACE_END 00196