|
Blender
V2.59
|
00001 /* 00002 * $Id: RAS_FramingManager.cpp 35174 2011-02-25 13:38:24Z jesterking $ 00003 * ***** BEGIN GPL LICENSE BLOCK ***** 00004 * 00005 * This program is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU General Public License 00007 * as published by the Free Software Foundation; either version 2 00008 * of the License, or (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License 00016 * along with this program; if not, write to the Free Software Foundation, 00017 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00018 * 00019 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00020 * All rights reserved. 00021 * 00022 * The Original Code is: all of this file. 00023 * 00024 * Contributor(s): none yet. 00025 * 00026 * ***** END GPL LICENSE BLOCK ***** 00027 */ 00028 00034 #include "RAS_FramingManager.h" 00035 #include "RAS_Rect.h" 00036 00037 void 00038 RAS_FramingManager:: 00039 ComputeDefaultFrustum( 00040 const float camnear, 00041 const float camfar, 00042 const float lens, 00043 const float design_aspect_ratio, 00044 RAS_FrameFrustum & frustum 00045 ){ 00046 00047 /* 00048 * Magic Blender calculation. 00049 * Blender does not give a Field of View as lens but a size 00050 * at 16 units away from the lens. 00051 */ 00052 float halfSize = 16.f * camnear / lens; 00053 float sizeX; 00054 float sizeY; 00055 00056 if (design_aspect_ratio > 1.f) { 00057 // halfsize defines the width 00058 sizeX = halfSize; 00059 sizeY = halfSize/design_aspect_ratio; 00060 } else { 00061 // halfsize defines the height 00062 sizeX = halfSize * design_aspect_ratio; 00063 sizeY = halfSize; 00064 } 00065 00066 frustum.x2 = sizeX; 00067 frustum.x1 = -frustum.x2; 00068 frustum.y2 = sizeY; 00069 frustum.y1 = -frustum.y2; 00070 frustum.camnear = camnear; 00071 frustum.camfar = camfar; 00072 } 00073 00074 void 00075 RAS_FramingManager:: 00076 ComputeDefaultOrtho( 00077 const float camnear, 00078 const float camfar, 00079 const float scale, 00080 const float design_aspect_ratio, 00081 RAS_FrameFrustum & frustum 00082 ) 00083 { 00084 float halfSize = scale*0.5f; 00085 float sizeX; 00086 float sizeY; 00087 00088 if (design_aspect_ratio > 1.f) { 00089 // halfsize defines the width 00090 sizeX = halfSize; 00091 sizeY = halfSize/design_aspect_ratio; 00092 } else { 00093 // halfsize defines the height 00094 sizeX = halfSize * design_aspect_ratio; 00095 sizeY = halfSize; 00096 } 00097 00098 frustum.x2 = sizeX; 00099 frustum.x1 = -frustum.x2; 00100 frustum.y2 = sizeY; 00101 frustum.y1 = -frustum.y2; 00102 frustum.camnear = -camfar; 00103 frustum.camfar = camfar; 00104 } 00105 00106 00107 void 00108 RAS_FramingManager:: 00109 ComputeBestFitViewRect( 00110 const RAS_Rect &availableViewport, 00111 const float design_aspect_ratio, 00112 RAS_Rect &viewport 00113 ){ 00114 // try and honour the aspect ratio when setting the 00115 // drawable area. If we don't do this we are liable 00116 // to get a lot of distortion in the rendered image. 00117 00118 int width = availableViewport.GetWidth(); 00119 int height = availableViewport.GetHeight(); 00120 float window_aspect = float(width)/float(height); 00121 00122 if (window_aspect < design_aspect_ratio) { 00123 int v_height = (int)(width / design_aspect_ratio); 00124 int left_over = (height - v_height) / 2; 00125 00126 viewport.SetLeft(availableViewport.GetLeft()); 00127 viewport.SetBottom(availableViewport.GetBottom() + left_over); 00128 viewport.SetRight(availableViewport.GetLeft() + width); 00129 viewport.SetTop(availableViewport.GetBottom() + left_over + v_height); 00130 00131 } else { 00132 int v_width = (int)(height * design_aspect_ratio); 00133 int left_over = (width - v_width) / 2; 00134 00135 viewport.SetLeft(availableViewport.GetLeft() + left_over); 00136 viewport.SetBottom(availableViewport.GetBottom()); 00137 viewport.SetRight(availableViewport.GetLeft() + v_width + left_over); 00138 viewport.SetTop(availableViewport.GetBottom() + height); 00139 } 00140 } 00141 00142 void 00143 RAS_FramingManager:: 00144 ComputeViewport( 00145 const RAS_FrameSettings &settings, 00146 const RAS_Rect &availableViewport, 00147 RAS_Rect &viewport 00148 ){ 00149 00150 RAS_FrameSettings::RAS_FrameType type = settings.FrameType(); 00151 const int winx = availableViewport.GetWidth(); 00152 const int winy = availableViewport.GetHeight(); 00153 00154 const float design_width = float(settings.DesignAspectWidth()); 00155 const float design_height = float(settings.DesignAspectHeight()); 00156 00157 float design_aspect_ratio = float(1); 00158 00159 if (design_height == float(0)) { 00160 // well this is ill defined 00161 // lets just scale the thing 00162 00163 type = RAS_FrameSettings::e_frame_scale; 00164 } else { 00165 design_aspect_ratio = design_width/design_height; 00166 } 00167 00168 switch (type) { 00169 00170 case RAS_FrameSettings::e_frame_scale : 00171 case RAS_FrameSettings::e_frame_extend: 00172 { 00173 viewport.SetLeft(availableViewport.GetLeft()); 00174 viewport.SetBottom(availableViewport.GetBottom()); 00175 viewport.SetRight(availableViewport.GetLeft() + int(winx)); 00176 viewport.SetTop(availableViewport.GetBottom() + int(winy)); 00177 00178 break; 00179 } 00180 00181 case RAS_FrameSettings::e_frame_bars: 00182 { 00183 ComputeBestFitViewRect( 00184 availableViewport, 00185 design_aspect_ratio, 00186 viewport 00187 ); 00188 00189 break; 00190 } 00191 default : 00192 break; 00193 } 00194 } 00195 00196 void 00197 RAS_FramingManager:: 00198 ComputeFrustum( 00199 const RAS_FrameSettings &settings, 00200 const RAS_Rect &availableViewport, 00201 const RAS_Rect &viewport, 00202 const float lens, 00203 const float camnear, 00204 const float camfar, 00205 RAS_FrameFrustum &frustum 00206 ){ 00207 00208 RAS_FrameSettings::RAS_FrameType type = settings.FrameType(); 00209 00210 const float design_width = float(settings.DesignAspectWidth()); 00211 const float design_height = float(settings.DesignAspectHeight()); 00212 00213 float design_aspect_ratio = float(1); 00214 00215 if (design_height == float(0)) { 00216 // well this is ill defined 00217 // lets just scale the thing 00218 00219 type = RAS_FrameSettings::e_frame_scale; 00220 } else { 00221 design_aspect_ratio = design_width/design_height; 00222 } 00223 00224 ComputeDefaultFrustum( 00225 camnear, 00226 camfar, 00227 lens, 00228 design_aspect_ratio, 00229 frustum 00230 ); 00231 00232 switch (type) { 00233 00234 case RAS_FrameSettings::e_frame_extend: 00235 { 00236 RAS_Rect vt; 00237 ComputeBestFitViewRect( 00238 availableViewport, 00239 design_aspect_ratio, 00240 vt 00241 ); 00242 00243 // now scale the calculated frustum by the difference 00244 // between vt and the viewport in each axis. 00245 // These are always > 1 00246 00247 float x_scale = float(viewport.GetWidth())/float(vt.GetWidth()); 00248 float y_scale = float(viewport.GetHeight())/float(vt.GetHeight()); 00249 00250 frustum.x1 *= x_scale; 00251 frustum.x2 *= x_scale; 00252 frustum.y1 *= y_scale; 00253 frustum.y2 *= y_scale; 00254 00255 break; 00256 } 00257 case RAS_FrameSettings::e_frame_scale : 00258 case RAS_FrameSettings::e_frame_bars: 00259 default : 00260 break; 00261 } 00262 } 00263 00264 void 00265 RAS_FramingManager:: 00266 ComputeOrtho( 00267 const RAS_FrameSettings &settings, 00268 const RAS_Rect &availableViewport, 00269 const RAS_Rect &viewport, 00270 const float scale, 00271 const float camnear, 00272 const float camfar, 00273 RAS_FrameFrustum &frustum 00274 ) 00275 { 00276 RAS_FrameSettings::RAS_FrameType type = settings.FrameType(); 00277 00278 const float design_width = float(settings.DesignAspectWidth()); 00279 const float design_height = float(settings.DesignAspectHeight()); 00280 00281 float design_aspect_ratio = float(1); 00282 00283 if (design_height == float(0)) { 00284 // well this is ill defined 00285 // lets just scale the thing 00286 type = RAS_FrameSettings::e_frame_scale; 00287 } else { 00288 design_aspect_ratio = design_width/design_height; 00289 } 00290 00291 00292 ComputeDefaultOrtho( 00293 camnear, 00294 camfar, 00295 scale, 00296 design_aspect_ratio, 00297 frustum 00298 ); 00299 00300 switch (type) { 00301 00302 case RAS_FrameSettings::e_frame_extend: 00303 { 00304 RAS_Rect vt; 00305 ComputeBestFitViewRect( 00306 availableViewport, 00307 design_aspect_ratio, 00308 vt 00309 ); 00310 00311 // now scale the calculated frustum by the difference 00312 // between vt and the viewport in each axis. 00313 // These are always > 1 00314 00315 float x_scale = float(viewport.GetWidth())/float(vt.GetWidth()); 00316 float y_scale = float(viewport.GetHeight())/float(vt.GetHeight()); 00317 00318 frustum.x1 *= x_scale; 00319 frustum.x2 *= x_scale; 00320 frustum.y1 *= y_scale; 00321 frustum.y2 *= y_scale; 00322 00323 break; 00324 } 00325 case RAS_FrameSettings::e_frame_scale : 00326 case RAS_FrameSettings::e_frame_bars: 00327 default : 00328 break; 00329 } 00330 00331 } 00332 00333