Blender  V2.59
RAS_FramingManager.cpp
Go to the documentation of this file.
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