Cleanup: style, use braces for render
[blender.git] / source / blender / render / intern / source / initrender.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  */
19
20 /** \file
21  * \ingroup render
22  */
23
24 /* Global includes */
25
26 #include <math.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <stdio.h>
30
31 #include "MEM_guardedalloc.h"
32
33 #include "BLI_math.h"
34 #include "BLI_blenlib.h"
35 #include "BLI_utildefines.h"
36
37 #include "DNA_camera_types.h"
38
39 #include "BKE_camera.h"
40
41 /* this module */
42 #include "renderpipeline.h"
43 #include "render_types.h"
44
45 /* Own includes */
46 #include "initrender.h"
47
48 /* ****************** MASKS and LUTS **************** */
49
50 static float filt_quadratic(float x)
51 {
52   if (x < 0.0f) {
53     x = -x;
54   }
55   if (x < 0.5f) {
56     return 0.75f - (x * x);
57   }
58   if (x < 1.5f) {
59     return 0.50f * (x - 1.5f) * (x - 1.5f);
60   }
61   return 0.0f;
62 }
63
64 static float filt_cubic(float x)
65 {
66   float x2 = x * x;
67
68   if (x < 0.0f) {
69     x = -x;
70   }
71
72   if (x < 1.0f) {
73     return 0.5f * x * x2 - x2 + 2.0f / 3.0f;
74   }
75   if (x < 2.0f) {
76     return (2.0f - x) * (2.0f - x) * (2.0f - x) / 6.0f;
77   }
78   return 0.0f;
79 }
80
81 static float filt_catrom(float x)
82 {
83   float x2 = x * x;
84
85   if (x < 0.0f) {
86     x = -x;
87   }
88   if (x < 1.0f) {
89     return 1.5f * x2 * x - 2.5f * x2 + 1.0f;
90   }
91   if (x < 2.0f) {
92     return -0.5f * x2 * x + 2.5f * x2 - 4.0f * x + 2.0f;
93   }
94   return 0.0f;
95 }
96
97 static float filt_mitchell(float x) /* Mitchell & Netravali's two-param cubic */
98 {
99   float b = 1.0f / 3.0f, c = 1.0f / 3.0f;
100   float p0 = (6.0f - 2.0f * b) / 6.0f;
101   float p2 = (-18.0f + 12.0f * b + 6.0f * c) / 6.0f;
102   float p3 = (12.0f - 9.0f * b - 6.0f * c) / 6.0f;
103   float q0 = (8.0f * b + 24.0f * c) / 6.0f;
104   float q1 = (-12.0f * b - 48.0f * c) / 6.0f;
105   float q2 = (6.0f * b + 30.0f * c) / 6.0f;
106   float q3 = (-b - 6.0f * c) / 6.0f;
107
108   if (x < -2.0f) {
109     return 0.0f;
110   }
111   if (x < -1.0f) {
112     return (q0 - x * (q1 - x * (q2 - x * q3)));
113   }
114   if (x < 0.0f) {
115     return (p0 + x * x * (p2 - x * p3));
116   }
117   if (x < 1.0f) {
118     return (p0 + x * x * (p2 + x * p3));
119   }
120   if (x < 2.0f) {
121     return (q0 + x * (q1 + x * (q2 + x * q3)));
122   }
123   return 0.0f;
124 }
125
126 /* x ranges from -1 to 1 */
127 float RE_filter_value(int type, float x)
128 {
129   float gaussfac = 1.6f;
130
131   x = ABS(x);
132
133   switch (type) {
134     case R_FILTER_BOX:
135       if (x > 1.0f) {
136         return 0.0f;
137       }
138       return 1.0f;
139
140     case R_FILTER_TENT:
141       if (x > 1.0f) {
142         return 0.0f;
143       }
144       return 1.0f - x;
145
146     case R_FILTER_GAUSS: {
147       const float two_gaussfac2 = 2.0f * gaussfac * gaussfac;
148       x *= 3.0f * gaussfac;
149       return 1.0f / sqrtf((float)M_PI * two_gaussfac2) * expf(-x * x / two_gaussfac2);
150     }
151
152     case R_FILTER_MITCH:
153       return filt_mitchell(x * gaussfac);
154
155     case R_FILTER_QUAD:
156       return filt_quadratic(x * gaussfac);
157
158     case R_FILTER_CUBIC:
159       return filt_cubic(x * gaussfac);
160
161     case R_FILTER_CATROM:
162       return filt_catrom(x * gaussfac);
163   }
164   return 0.0f;
165 }
166
167 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
168 struct Object *RE_GetCamera(Render *re)
169 {
170   Object *camera = re->camera_override ? re->camera_override : re->scene->camera;
171   return BKE_camera_multiview_render(re->scene, camera, re->viewname);
172 }
173
174 static void re_camera_params_get(Render *re, CameraParams *params)
175 {
176   copy_m4_m4(re->winmat, params->winmat);
177
178   re->clip_start = params->clip_start;
179   re->clip_end = params->clip_end;
180
181   re->viewplane = params->viewplane;
182 }
183
184 void RE_SetOverrideCamera(Render *re, Object *camera)
185 {
186   re->camera_override = camera;
187 }
188
189 static void re_camera_params_stereo3d(Render *re, CameraParams *params, Object *cam_ob)
190 {
191   BKE_camera_multiview_params(&re->r, params, cam_ob, re->viewname);
192 }
193
194 /* call this after InitState() */
195 /* per render, there's one persistent viewplane. Parts will set their own viewplanes */
196 void RE_SetCamera(Render *re, Object *cam_ob)
197 {
198   CameraParams params;
199
200   /* setup parameters */
201   BKE_camera_params_init(&params);
202   BKE_camera_params_from_object(&params, cam_ob);
203   re_camera_params_stereo3d(re, &params, cam_ob);
204
205   /* compute matrix, viewplane, .. */
206   BKE_camera_params_compute_viewplane(&params, re->winx, re->winy, re->r.xasp, re->r.yasp);
207   BKE_camera_params_compute_matrix(&params);
208
209   /* extract results */
210   re_camera_params_get(re, &params);
211 }
212
213 void RE_GetCameraWindow(struct Render *re, struct Object *camera, int frame, float mat[4][4])
214 {
215   re->r.cfra = frame;
216   RE_SetCamera(re, camera);
217   copy_m4_m4(mat, re->winmat);
218 }
219
220 /* Must be called after RE_GetCameraWindow(), does not change re->winmat. */
221 void RE_GetCameraWindowWithOverscan(struct Render *re, float mat[4][4], float overscan)
222 {
223   CameraParams params;
224   params.is_ortho = re->winmat[3][3] != 0.0f;
225   params.clip_start = re->clip_start;
226   params.clip_end = re->clip_end;
227   params.viewplane = re->viewplane;
228
229   overscan *= max_ff(BLI_rctf_size_x(&params.viewplane), BLI_rctf_size_y(&params.viewplane));
230
231   params.viewplane.xmin -= overscan;
232   params.viewplane.xmax += overscan;
233   params.viewplane.ymin -= overscan;
234   params.viewplane.ymax += overscan;
235   BKE_camera_params_compute_matrix(&params);
236   copy_m4_m4(mat, params.winmat);
237 }
238
239 void RE_GetCameraModelMatrix(Render *re, struct Object *camera, float r_mat[4][4])
240 {
241   BKE_camera_multiview_model_matrix(&re->r, camera, re->viewname, r_mat);
242 }
243
244 /* ~~~~~~~~~~~~~~~~ part (tile) calculus ~~~~~~~~~~~~~~~~~~~~~~ */
245
246 void RE_parts_free(Render *re)
247 {
248   BLI_freelistN(&re->parts);
249 }
250
251 void RE_parts_clamp(Render *re)
252 {
253   /* part size */
254   re->partx = max_ii(1, min_ii(re->r.tilex, re->rectx));
255   re->party = max_ii(1, min_ii(re->r.tiley, re->recty));
256 }
257
258 void RE_parts_init(Render *re)
259 {
260   int nr, xd, yd, partx, party, xparts, yparts;
261   int xminb, xmaxb, yminb, ymaxb;
262
263   RE_parts_free(re);
264
265   /* this is render info for caller, is not reset when parts are freed! */
266   re->i.totpart = 0;
267   re->i.curpart = 0;
268   re->i.partsdone = 0;
269
270   /* just for readable code.. */
271   xminb = re->disprect.xmin;
272   yminb = re->disprect.ymin;
273   xmaxb = re->disprect.xmax;
274   ymaxb = re->disprect.ymax;
275
276   RE_parts_clamp(re);
277
278   partx = re->partx;
279   party = re->party;
280   /* part count */
281   xparts = (re->rectx + partx - 1) / partx;
282   yparts = (re->recty + party - 1) / party;
283
284   for (nr = 0; nr < xparts * yparts; nr++) {
285     rcti disprect;
286     int rectx, recty;
287
288     xd = (nr % xparts);
289     yd = (nr - xd) / xparts;
290
291     disprect.xmin = xminb + xd * partx;
292     disprect.ymin = yminb + yd * party;
293
294     /* ensure we cover the entire picture, so last parts go to end */
295     if (xd < xparts - 1) {
296       disprect.xmax = disprect.xmin + partx;
297       if (disprect.xmax > xmaxb) {
298         disprect.xmax = xmaxb;
299       }
300     }
301     else {
302       disprect.xmax = xmaxb;
303     }
304
305     if (yd < yparts - 1) {
306       disprect.ymax = disprect.ymin + party;
307       if (disprect.ymax > ymaxb) {
308         disprect.ymax = ymaxb;
309       }
310     }
311     else {
312       disprect.ymax = ymaxb;
313     }
314
315     rectx = BLI_rcti_size_x(&disprect);
316     recty = BLI_rcti_size_y(&disprect);
317
318     /* so, now can we add this part? */
319     if (rectx > 0 && recty > 0) {
320       RenderPart *pa = MEM_callocN(sizeof(RenderPart), "new part");
321
322       pa->disprect = disprect;
323       pa->rectx = rectx;
324       pa->recty = recty;
325
326       BLI_addtail(&re->parts, pa);
327       re->i.totpart++;
328     }
329   }
330 }