Tomato: camera sensor changes
[blender.git] / source / gameengine / Rasterizer / RAS_FramingManager.cpp
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file gameengine/Rasterizer/RAS_FramingManager.cpp
29  *  \ingroup bgerast
30  */
31
32
33 #include "RAS_FramingManager.h"
34 #include "RAS_Rect.h"
35
36         void
37 RAS_FramingManager::
38 ComputeDefaultFrustum(
39         const float camnear,
40         const float camfar,
41         const float lens,
42         const float sensor_x, const float sensor_y,
43         const short sensor_fit,
44         const float design_aspect_ratio,
45         RAS_FrameFrustum & frustum
46 ){              
47         float halfSize;
48         float sizeX;
49         float sizeY;
50
51         if(sensor_fit==RAS_SENSORFIT_AUTO) {
52                 halfSize = (sensor_x / 2.f) * camnear / lens;
53
54                 if (design_aspect_ratio > 1.f) {
55                         // halfsize defines the width
56                         sizeX = halfSize;
57                         sizeY = halfSize/design_aspect_ratio;
58                 } else {
59                         // halfsize defines the height
60                         sizeX = halfSize * design_aspect_ratio;
61                         sizeY = halfSize;
62                 }
63         }
64         else if(sensor_fit==RAS_SENSORFIT_HOR) {
65                 halfSize = (sensor_x / 2.f) * camnear / lens;
66                 sizeX = halfSize;
67                 sizeY = halfSize/design_aspect_ratio;
68         }
69         else {
70                 halfSize = (sensor_y / 2.f) * camnear / lens;
71                 sizeX = halfSize * design_aspect_ratio;
72                 sizeY = halfSize;
73         }
74                 
75         frustum.x2 = sizeX;
76         frustum.x1 = -frustum.x2;
77         frustum.y2 = sizeY;
78         frustum.y1 = -frustum.y2;
79         frustum.camnear = camnear;
80         frustum.camfar = camfar;
81 }
82
83         void
84 RAS_FramingManager::
85 ComputeDefaultOrtho(
86         const float camnear,
87         const float camfar,
88         const float scale,
89         const float design_aspect_ratio,
90         const short sensor_fit,
91         RAS_FrameFrustum & frustum
92 )
93 {
94         float halfSize = scale*0.5f;
95         float sizeX;
96         float sizeY;
97
98         if(sensor_fit==RAS_SENSORFIT_AUTO) {
99                 if (design_aspect_ratio > 1.f) {
100                         // halfsize defines the width
101                         sizeX = halfSize;
102                         sizeY = halfSize/design_aspect_ratio;
103                 } else {
104                         // halfsize defines the height
105                         sizeX = halfSize * design_aspect_ratio;
106                         sizeY = halfSize;
107                 }
108         }
109         else if(sensor_fit==RAS_SENSORFIT_HOR) {
110                 sizeX = halfSize;
111                 sizeY = halfSize/design_aspect_ratio;
112         }
113         else {
114                 sizeX = halfSize * design_aspect_ratio;
115                 sizeY = halfSize;
116         }
117                 
118         frustum.x2 = sizeX;
119         frustum.x1 = -frustum.x2;
120         frustum.y2 = sizeY;
121         frustum.y1 = -frustum.y2;
122         frustum.camnear = camnear;
123         frustum.camfar = camfar;
124 }
125
126
127         void
128 RAS_FramingManager::
129 ComputeBestFitViewRect(
130         const RAS_Rect &availableViewport,
131         const float design_aspect_ratio,
132         RAS_Rect &viewport
133 ){
134         // try and honour the aspect ratio when setting the 
135         // drawable area. If we don't do this we are liable
136         // to get a lot of distortion in the rendered image.
137         
138         int width = availableViewport.GetWidth();
139         int height = availableViewport.GetHeight();
140         float window_aspect = float(width)/float(height);
141
142         if (window_aspect < design_aspect_ratio) {
143                 int v_height = (int)(width / design_aspect_ratio); 
144                 int left_over = (height - v_height) / 2; 
145                         
146                 viewport.SetLeft(availableViewport.GetLeft());
147                 viewport.SetBottom(availableViewport.GetBottom() + left_over);
148                 viewport.SetRight(availableViewport.GetLeft() + width);
149                 viewport.SetTop(availableViewport.GetBottom() + left_over + v_height);
150
151         } else {
152                 int v_width = (int)(height * design_aspect_ratio);
153                 int left_over = (width - v_width) / 2; 
154
155                 viewport.SetLeft(availableViewport.GetLeft() + left_over);
156                 viewport.SetBottom(availableViewport.GetBottom());
157                 viewport.SetRight(availableViewport.GetLeft() + v_width + left_over);
158                 viewport.SetTop(availableViewport.GetBottom() + height);
159         }
160 }
161
162         void
163 RAS_FramingManager::
164 ComputeViewport(
165         const RAS_FrameSettings &settings,
166         const RAS_Rect &availableViewport,
167         RAS_Rect &viewport
168 ){
169
170         RAS_FrameSettings::RAS_FrameType type = settings.FrameType();
171         const int winx = availableViewport.GetWidth();
172         const int winy = availableViewport.GetHeight();
173
174         const float design_width = float(settings.DesignAspectWidth());
175         const float design_height = float(settings.DesignAspectHeight());
176
177         float design_aspect_ratio = float(1);
178
179         if (design_height == float(0)) {
180                 // well this is ill defined 
181                 // lets just scale the thing
182
183                 type = RAS_FrameSettings::e_frame_scale;
184         } else {
185                 design_aspect_ratio = design_width/design_height;
186         }
187
188         switch (type) {
189
190                 case RAS_FrameSettings::e_frame_scale :
191                 case RAS_FrameSettings::e_frame_extend:
192                 {
193                         viewport.SetLeft(availableViewport.GetLeft());
194                         viewport.SetBottom(availableViewport.GetBottom());
195                         viewport.SetRight(availableViewport.GetLeft() + int(winx));
196                         viewport.SetTop(availableViewport.GetBottom() + int(winy));
197
198                         break;
199                 }
200
201                 case RAS_FrameSettings::e_frame_bars:
202                 {
203                         ComputeBestFitViewRect(
204                                 availableViewport,
205                                 design_aspect_ratio,    
206                                 viewport
207                         );
208                 
209                         break;
210                 }
211                 default :
212                         break;
213         }
214 }
215
216         void
217 RAS_FramingManager::
218 ComputeFrustum(
219         const RAS_FrameSettings &settings,
220         const RAS_Rect &availableViewport,
221         const RAS_Rect &viewport,
222         const float lens,
223         const float sensor_x, const float sensor_y, const short sensor_fit,
224         const float camnear,
225         const float camfar,
226         RAS_FrameFrustum &frustum
227 ){
228
229         RAS_FrameSettings::RAS_FrameType type = settings.FrameType();
230
231         const float design_width = float(settings.DesignAspectWidth());
232         const float design_height = float(settings.DesignAspectHeight());
233
234         float design_aspect_ratio = float(1);
235
236         if (design_height == float(0)) {
237                 // well this is ill defined 
238                 // lets just scale the thing
239
240                 type = RAS_FrameSettings::e_frame_scale;
241         } else {
242                 design_aspect_ratio = design_width/design_height;
243         }
244         
245         ComputeDefaultFrustum(
246                 camnear,
247                 camfar,
248                 lens,
249                 sensor_x,
250                 sensor_y,
251                 sensor_fit,
252                 design_aspect_ratio,
253                 frustum
254         );
255
256         switch (type) {
257
258                 case RAS_FrameSettings::e_frame_extend:
259                 {
260                         RAS_Rect vt;
261                         ComputeBestFitViewRect(
262                                 availableViewport,
263                                 design_aspect_ratio,    
264                                 vt
265                         );
266
267                         // now scale the calculated frustum by the difference
268                         // between vt and the viewport in each axis.
269                         // These are always > 1
270
271                         float x_scale = float(viewport.GetWidth())/float(vt.GetWidth());
272                         float y_scale = float(viewport.GetHeight())/float(vt.GetHeight());
273
274                         frustum.x1 *= x_scale;
275                         frustum.x2 *= x_scale;
276                         frustum.y1 *= y_scale;
277                         frustum.y2 *= y_scale;
278         
279                         break;
280                 }       
281                 case RAS_FrameSettings::e_frame_scale :
282                 case RAS_FrameSettings::e_frame_bars:
283                 default :
284                         break;
285         }
286 }       
287
288         void
289 RAS_FramingManager::
290         ComputeOrtho(
291                 const RAS_FrameSettings &settings,
292                 const RAS_Rect &availableViewport,
293                 const RAS_Rect &viewport,
294                 const float scale,
295                 const float camnear,
296                 const float camfar,
297                 const short sensor_fit,
298                 RAS_FrameFrustum &frustum
299         )
300 {
301         RAS_FrameSettings::RAS_FrameType type = settings.FrameType();
302
303         const float design_width = float(settings.DesignAspectWidth());
304         const float design_height = float(settings.DesignAspectHeight());
305
306         float design_aspect_ratio = float(1);
307
308         if (design_height == float(0)) {
309                 // well this is ill defined 
310                 // lets just scale the thing
311                 type = RAS_FrameSettings::e_frame_scale;
312         } else {
313                 design_aspect_ratio = design_width/design_height;
314         }
315
316         
317         ComputeDefaultOrtho(
318                 camnear,
319                 camfar,
320                 scale,
321                 design_aspect_ratio,
322                 sensor_fit,
323                 frustum
324         );
325
326         switch (type) {
327
328                 case RAS_FrameSettings::e_frame_extend:
329                 {
330                         RAS_Rect vt;
331                         ComputeBestFitViewRect(
332                                 availableViewport,
333                                 design_aspect_ratio,    
334                                 vt
335                         );
336
337                         // now scale the calculated frustum by the difference
338                         // between vt and the viewport in each axis.
339                         // These are always > 1
340
341                         float x_scale = float(viewport.GetWidth())/float(vt.GetWidth());
342                         float y_scale = float(viewport.GetHeight())/float(vt.GetHeight());
343
344                         frustum.x1 *= x_scale;
345                         frustum.x2 *= x_scale;
346                         frustum.y1 *= y_scale;
347                         frustum.y2 *= y_scale;
348         
349                         break;
350                 }       
351                 case RAS_FrameSettings::e_frame_scale :
352                 case RAS_FrameSettings::e_frame_bars:
353                 default :
354                         break;
355         }
356         
357 }
358
359