More warning cleanups...
[blender.git] / source / gameengine / Rasterizer / RAS_FramingManager.cpp
1 /**
2  * $Id$
3  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version. The Blender
9  * Foundation also sells licenses for use in proprietary software under
10  * the Blender License.  See http://www.blender.org/BL/ for information
11  * about this.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21  *
22  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
23  * All rights reserved.
24  *
25  * The Original Code is: all of this file.
26  *
27  * Contributor(s): none yet.
28  *
29  * ***** END GPL/BL DUAL LICENSE BLOCK *****
30  */
31
32 #include "RAS_FramingManager.h"
33 #include "RAS_Rect.h"
34
35 #ifdef HAVE_CONFIG_H
36 #include <config.h>
37 #endif
38
39         void
40 RAS_FramingManager::
41 ComputeDefaultFrustum(
42         const float camnear,
43         const float camfar,
44         const float lens,
45         const float design_aspect_ratio,
46         RAS_FrameFrustum & frustum
47 ){
48                 
49         /*
50          * Magic Blender calculation.
51          * Blender does not give a Field of View as lens but a size
52          * at 16 units away from the lens.
53          */
54         float halfSize = 16.f * camnear / lens;
55         float sizeX;
56         float sizeY;
57
58         if (design_aspect_ratio > 1.f) {
59                 // halfsize defines the width
60                 sizeX = halfSize;
61                 sizeY = halfSize/design_aspect_ratio;
62         } else {
63                 // halfsize defines the height
64                 sizeX = halfSize * design_aspect_ratio;
65                 sizeY = halfSize;
66         }
67                 
68         frustum.x2 = sizeX;
69         frustum.x1 = -frustum.x2;
70         frustum.y2 = sizeY;
71         frustum.y1 = -frustum.y2;
72         frustum.camnear = camnear;
73         frustum.camfar = camfar;
74 }
75
76         void
77 RAS_FramingManager::
78 ComputeBestFitViewRect(
79         const RAS_Rect &availableViewport,
80         const float design_aspect_ratio,
81         RAS_Rect &viewport
82 ){
83         // try and honour the aspect ratio when setting the 
84         // drawable area. If we don't do this we are liable
85         // to get a lot of distortion in the rendered image.
86         
87         int width = availableViewport.GetWidth();
88         int height = availableViewport.GetHeight();
89         float window_aspect = float(width)/float(height);
90
91         if (window_aspect < design_aspect_ratio) {
92                 int v_height = (int)(width / design_aspect_ratio); 
93                 int left_over = (height - v_height) / 2; 
94                         
95                 viewport.SetLeft(availableViewport.GetLeft());
96                 viewport.SetBottom(availableViewport.GetBottom() + left_over);
97                 viewport.SetRight(availableViewport.GetLeft() + width);
98                 viewport.SetTop(availableViewport.GetBottom() + left_over + v_height);
99
100         } else {
101                 int v_width = (int)(height * design_aspect_ratio);
102                 int left_over = (width - v_width) / 2; 
103
104                 viewport.SetLeft(availableViewport.GetLeft() + left_over);
105                 viewport.SetBottom(availableViewport.GetBottom());
106                 viewport.SetRight(availableViewport.GetLeft() + v_width + left_over);
107                 viewport.SetTop(availableViewport.GetBottom() + height);
108         }
109 }
110
111         void
112 RAS_FramingManager::
113 ComputeViewport(
114         const RAS_FrameSettings &settings,
115         const RAS_Rect &availableViewport,
116         RAS_Rect &viewport
117 ){
118
119         RAS_FrameSettings::RAS_FrameType type = settings.FrameType();
120         const int winx = availableViewport.GetWidth();
121         const int winy = availableViewport.GetHeight();
122
123         const float design_width = float(settings.DesignAspectWidth());
124         const float design_height = float(settings.DesignAspectHeight());
125
126         float design_aspect_ratio = float(1);
127
128         if (design_height == float(0)) {
129                 // well this is ill defined 
130                 // lets just scale the thing
131
132                 type = RAS_FrameSettings::e_frame_scale;
133         } else {
134                 design_aspect_ratio = design_width/design_height;
135         }
136
137         switch (type) {
138
139                 case RAS_FrameSettings::e_frame_scale :
140                 case RAS_FrameSettings::e_frame_extend:
141                 {
142                         viewport.SetLeft(availableViewport.GetLeft());
143                         viewport.SetBottom(availableViewport.GetBottom());
144                         viewport.SetRight(availableViewport.GetLeft() + int(winx));
145                         viewport.SetTop(availableViewport.GetBottom() + int(winy));
146
147                         break;
148                 }
149
150                 case RAS_FrameSettings::e_frame_bars:
151                 {
152                         ComputeBestFitViewRect(
153                                 availableViewport,
154                                 design_aspect_ratio,    
155                                 viewport
156                         );
157                 
158                         break;
159                 }
160                 default :
161                         break;
162         }
163 }
164
165         void
166 RAS_FramingManager::
167 ComputeFrustum(
168         const RAS_FrameSettings &settings,
169         const RAS_Rect &availableViewport,
170         const RAS_Rect &viewport,
171         const float lens,
172         const float camnear,
173         const float camfar,
174         RAS_FrameFrustum &frustum
175 ){
176
177         RAS_FrameSettings::RAS_FrameType type = settings.FrameType();
178
179         const float design_width = float(settings.DesignAspectWidth());
180         const float design_height = float(settings.DesignAspectHeight());
181
182         float design_aspect_ratio = float(1);
183
184         if (design_height == float(0)) {
185                 // well this is ill defined 
186                 // lets just scale the thing
187
188                 type = RAS_FrameSettings::e_frame_scale;
189         } else {
190                 design_aspect_ratio = design_width/design_height;
191         }
192         
193         ComputeDefaultFrustum(
194                 camnear,
195                 camfar,
196                 lens,
197                 design_aspect_ratio,
198                 frustum
199         );
200
201         switch (type) {
202
203                 case RAS_FrameSettings::e_frame_extend:
204                 {
205                         RAS_Rect vt;
206                         ComputeBestFitViewRect(
207                                 availableViewport,
208                                 design_aspect_ratio,    
209                                 vt
210                         );
211
212                         // now scale the calculated frustum by the difference
213                         // between vt and the viewport in each axis.
214                         // These are always > 1
215
216                         float x_scale = float(viewport.GetWidth())/float(vt.GetWidth());
217                         float y_scale = float(viewport.GetHeight())/float(vt.GetHeight());
218
219                         frustum.x1 *= x_scale;
220                         frustum.x2 *= x_scale;
221                         frustum.y1 *= y_scale;
222                         frustum.y2 *= y_scale;
223         
224                         break;
225                 }       
226                 case RAS_FrameSettings::e_frame_scale :
227                 case RAS_FrameSettings::e_frame_bars:
228                 default :
229                         break;
230         }
231 }       
232
233
234