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 00033 #include "RAS_FramingManager.h" 00034 #include "RAS_Rect.h" 00035 00036 void 00037 RAS_FramingManager:: 00038 ComputeDefaultFrustum( 00039 const float camnear, 00040 const float camfar, 00041 const float lens, 00042 const float sensor_x, const float sensor_y, 00043 const short sensor_fit, 00044 const float design_aspect_ratio, 00045 RAS_FrameFrustum & frustum 00046 ){ 00047 float halfSize; 00048 float sizeX; 00049 float sizeY; 00050 00051 if(sensor_fit==RAS_SENSORFIT_AUTO) { 00052 halfSize = (sensor_x / 2.f) * camnear / lens; 00053 00054 if (design_aspect_ratio > 1.f) { 00055 // halfsize defines the width 00056 sizeX = halfSize; 00057 sizeY = halfSize/design_aspect_ratio; 00058 } else { 00059 // halfsize defines the height 00060 sizeX = halfSize * design_aspect_ratio; 00061 sizeY = halfSize; 00062 } 00063 } 00064 else if(sensor_fit==RAS_SENSORFIT_HOR) { 00065 halfSize = (sensor_x / 2.f) * camnear / lens; 00066 sizeX = halfSize; 00067 sizeY = halfSize/design_aspect_ratio; 00068 } 00069 else { 00070 halfSize = (sensor_y / 2.f) * camnear / lens; 00071 sizeX = halfSize * design_aspect_ratio; 00072 sizeY = halfSize; 00073 } 00074 00075 frustum.x2 = sizeX; 00076 frustum.x1 = -frustum.x2; 00077 frustum.y2 = sizeY; 00078 frustum.y1 = -frustum.y2; 00079 frustum.camnear = camnear; 00080 frustum.camfar = camfar; 00081 } 00082 00083 void 00084 RAS_FramingManager:: 00085 ComputeDefaultOrtho( 00086 const float camnear, 00087 const float camfar, 00088 const float scale, 00089 const float design_aspect_ratio, 00090 const short sensor_fit, 00091 RAS_FrameFrustum & frustum 00092 ) 00093 { 00094 float halfSize = scale*0.5f; 00095 float sizeX; 00096 float sizeY; 00097 00098 if(sensor_fit==RAS_SENSORFIT_AUTO) { 00099 if (design_aspect_ratio > 1.f) { 00100 // halfsize defines the width 00101 sizeX = halfSize; 00102 sizeY = halfSize/design_aspect_ratio; 00103 } else { 00104 // halfsize defines the height 00105 sizeX = halfSize * design_aspect_ratio; 00106 sizeY = halfSize; 00107 } 00108 } 00109 else if(sensor_fit==RAS_SENSORFIT_HOR) { 00110 sizeX = halfSize; 00111 sizeY = halfSize/design_aspect_ratio; 00112 } 00113 else { 00114 sizeX = halfSize * design_aspect_ratio; 00115 sizeY = halfSize; 00116 } 00117 00118 frustum.x2 = sizeX; 00119 frustum.x1 = -frustum.x2; 00120 frustum.y2 = sizeY; 00121 frustum.y1 = -frustum.y2; 00122 frustum.camnear = camnear; 00123 frustum.camfar = camfar; 00124 } 00125 00126 00127 void 00128 RAS_FramingManager:: 00129 ComputeBestFitViewRect( 00130 const RAS_Rect &availableViewport, 00131 const float design_aspect_ratio, 00132 RAS_Rect &viewport 00133 ){ 00134 // try and honour the aspect ratio when setting the 00135 // drawable area. If we don't do this we are liable 00136 // to get a lot of distortion in the rendered image. 00137 00138 int width = availableViewport.GetWidth(); 00139 int height = availableViewport.GetHeight(); 00140 float window_aspect = float(width)/float(height); 00141 00142 if (window_aspect < design_aspect_ratio) { 00143 int v_height = (int)(width / design_aspect_ratio); 00144 int left_over = (height - v_height) / 2; 00145 00146 viewport.SetLeft(availableViewport.GetLeft()); 00147 viewport.SetBottom(availableViewport.GetBottom() + left_over); 00148 viewport.SetRight(availableViewport.GetLeft() + width); 00149 viewport.SetTop(availableViewport.GetBottom() + left_over + v_height); 00150 00151 } else { 00152 int v_width = (int)(height * design_aspect_ratio); 00153 int left_over = (width - v_width) / 2; 00154 00155 viewport.SetLeft(availableViewport.GetLeft() + left_over); 00156 viewport.SetBottom(availableViewport.GetBottom()); 00157 viewport.SetRight(availableViewport.GetLeft() + v_width + left_over); 00158 viewport.SetTop(availableViewport.GetBottom() + height); 00159 } 00160 } 00161 00162 void 00163 RAS_FramingManager:: 00164 ComputeViewport( 00165 const RAS_FrameSettings &settings, 00166 const RAS_Rect &availableViewport, 00167 RAS_Rect &viewport 00168 ){ 00169 00170 RAS_FrameSettings::RAS_FrameType type = settings.FrameType(); 00171 const int winx = availableViewport.GetWidth(); 00172 const int winy = availableViewport.GetHeight(); 00173 00174 const float design_width = float(settings.DesignAspectWidth()); 00175 const float design_height = float(settings.DesignAspectHeight()); 00176 00177 float design_aspect_ratio = float(1); 00178 00179 if (design_height == float(0)) { 00180 // well this is ill defined 00181 // lets just scale the thing 00182 00183 type = RAS_FrameSettings::e_frame_scale; 00184 } else { 00185 design_aspect_ratio = design_width/design_height; 00186 } 00187 00188 switch (type) { 00189 00190 case RAS_FrameSettings::e_frame_scale : 00191 case RAS_FrameSettings::e_frame_extend: 00192 { 00193 viewport.SetLeft(availableViewport.GetLeft()); 00194 viewport.SetBottom(availableViewport.GetBottom()); 00195 viewport.SetRight(availableViewport.GetLeft() + int(winx)); 00196 viewport.SetTop(availableViewport.GetBottom() + int(winy)); 00197 00198 break; 00199 } 00200 00201 case RAS_FrameSettings::e_frame_bars: 00202 { 00203 ComputeBestFitViewRect( 00204 availableViewport, 00205 design_aspect_ratio, 00206 viewport 00207 ); 00208 00209 break; 00210 } 00211 default : 00212 break; 00213 } 00214 } 00215 00216 void 00217 RAS_FramingManager:: 00218 ComputeFrustum( 00219 const RAS_FrameSettings &settings, 00220 const RAS_Rect &availableViewport, 00221 const RAS_Rect &viewport, 00222 const float lens, 00223 const float sensor_x, const float sensor_y, const short sensor_fit, 00224 const float camnear, 00225 const float camfar, 00226 RAS_FrameFrustum &frustum 00227 ){ 00228 00229 RAS_FrameSettings::RAS_FrameType type = settings.FrameType(); 00230 00231 const float design_width = float(settings.DesignAspectWidth()); 00232 const float design_height = float(settings.DesignAspectHeight()); 00233 00234 float design_aspect_ratio = float(1); 00235 00236 if (design_height == float(0)) { 00237 // well this is ill defined 00238 // lets just scale the thing 00239 00240 type = RAS_FrameSettings::e_frame_scale; 00241 } else { 00242 design_aspect_ratio = design_width/design_height; 00243 } 00244 00245 ComputeDefaultFrustum( 00246 camnear, 00247 camfar, 00248 lens, 00249 sensor_x, 00250 sensor_y, 00251 sensor_fit, 00252 design_aspect_ratio, 00253 frustum 00254 ); 00255 00256 switch (type) { 00257 00258 case RAS_FrameSettings::e_frame_extend: 00259 { 00260 RAS_Rect vt; 00261 ComputeBestFitViewRect( 00262 availableViewport, 00263 design_aspect_ratio, 00264 vt 00265 ); 00266 00267 // now scale the calculated frustum by the difference 00268 // between vt and the viewport in each axis. 00269 // These are always > 1 00270 00271 float x_scale = float(viewport.GetWidth())/float(vt.GetWidth()); 00272 float y_scale = float(viewport.GetHeight())/float(vt.GetHeight()); 00273 00274 frustum.x1 *= x_scale; 00275 frustum.x2 *= x_scale; 00276 frustum.y1 *= y_scale; 00277 frustum.y2 *= y_scale; 00278 00279 break; 00280 } 00281 case RAS_FrameSettings::e_frame_scale : 00282 case RAS_FrameSettings::e_frame_bars: 00283 default : 00284 break; 00285 } 00286 } 00287 00288 void 00289 RAS_FramingManager:: 00290 ComputeOrtho( 00291 const RAS_FrameSettings &settings, 00292 const RAS_Rect &availableViewport, 00293 const RAS_Rect &viewport, 00294 const float scale, 00295 const float camnear, 00296 const float camfar, 00297 const short sensor_fit, 00298 RAS_FrameFrustum &frustum 00299 ) 00300 { 00301 RAS_FrameSettings::RAS_FrameType type = settings.FrameType(); 00302 00303 const float design_width = float(settings.DesignAspectWidth()); 00304 const float design_height = float(settings.DesignAspectHeight()); 00305 00306 float design_aspect_ratio = float(1); 00307 00308 if (design_height == float(0)) { 00309 // well this is ill defined 00310 // lets just scale the thing 00311 type = RAS_FrameSettings::e_frame_scale; 00312 } else { 00313 design_aspect_ratio = design_width/design_height; 00314 } 00315 00316 00317 ComputeDefaultOrtho( 00318 camnear, 00319 camfar, 00320 scale, 00321 design_aspect_ratio, 00322 sensor_fit, 00323 frustum 00324 ); 00325 00326 switch (type) { 00327 00328 case RAS_FrameSettings::e_frame_extend: 00329 { 00330 RAS_Rect vt; 00331 ComputeBestFitViewRect( 00332 availableViewport, 00333 design_aspect_ratio, 00334 vt 00335 ); 00336 00337 // now scale the calculated frustum by the difference 00338 // between vt and the viewport in each axis. 00339 // These are always > 1 00340 00341 float x_scale = float(viewport.GetWidth())/float(vt.GetWidth()); 00342 float y_scale = float(viewport.GetHeight())/float(vt.GetHeight()); 00343 00344 frustum.x1 *= x_scale; 00345 frustum.x2 *= x_scale; 00346 frustum.y1 *= y_scale; 00347 frustum.y2 *= y_scale; 00348 00349 break; 00350 } 00351 case RAS_FrameSettings::e_frame_scale : 00352 case RAS_FrameSettings::e_frame_bars: 00353 default : 00354 break; 00355 } 00356 00357 } 00358 00359