Blender V2.61 - r43446

RAS_FramingManager.cpp

Go to the documentation of this file.
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