Merging r46096 through r46110 from trunk into soc-2011-tomato
[blender-staging.git] / intern / cycles / render / camera.cpp
1 /*
2  * Copyright 2011, Blender Foundation.
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
19 #include "camera.h"
20 #include "scene.h"
21
22 #include "util_vector.h"
23
24 CCL_NAMESPACE_BEGIN
25
26 Camera::Camera()
27 {
28         shutteropen = 0.0f;
29         shutterclose = 1.0f;
30
31         aperturesize = 0.0f;
32         focaldistance = 10.0f;
33         blades = 0;
34         bladesrotation = 0.0f;
35
36         matrix = transform_identity();
37
38         type = CAMERA_PERSPECTIVE;
39         fov = M_PI_F/4.0f;
40
41         nearclip = 1e-5f;
42         farclip = 1e5f;
43
44         width = 1024;
45         height = 512;
46
47         left = -((float)width/(float)height);
48         right = (float)width/(float)height;
49         bottom = -1.0f;
50         top = 1.0f;
51
52         screentoworld = transform_identity();
53         rastertoworld = transform_identity();
54         ndctoworld = transform_identity();
55         rastertocamera = transform_identity();
56         cameratoworld = transform_identity();
57         worldtoraster = transform_identity();
58
59         dx = make_float3(0.0f, 0.0f, 0.0f);
60         dy = make_float3(0.0f, 0.0f, 0.0f);
61
62         need_update = true;
63         need_device_update = true;
64 }
65
66 Camera::~Camera()
67 {
68 }
69
70 void Camera::update()
71 {
72         if(!need_update)
73                 return;
74         
75         /* ndc to raster */
76         Transform screentocamera;
77         Transform ndctoraster = transform_scale(width, height, 1.0f);
78
79         /* raster to screen */
80         Transform screentoraster = ndctoraster;
81         
82         screentoraster = ndctoraster *
83                 transform_scale(1.0f/(right - left), 1.0f/(top - bottom), 1.0f) *
84                 transform_translate(-left, -bottom, 0.0f);
85
86         Transform rastertoscreen = transform_inverse(screentoraster);
87
88         /* screen to camera */
89         if(type == CAMERA_PERSPECTIVE)
90                 screentocamera = transform_inverse(transform_perspective(fov, nearclip, farclip));
91         else if(type == CAMERA_ORTHOGRAPHIC)
92                 screentocamera = transform_inverse(transform_orthographic(nearclip, farclip));
93         else
94                 screentocamera = transform_identity();
95
96         rastertocamera = screentocamera * rastertoscreen;
97
98         cameratoworld = matrix;
99         screentoworld = cameratoworld * screentocamera;
100         rastertoworld = cameratoworld * rastertocamera;
101         ndctoworld = rastertoworld * ndctoraster;
102         worldtoraster = transform_inverse(rastertoworld);
103
104         /* differentials */
105         if(type == CAMERA_ORTHOGRAPHIC) {
106                 dx = transform_direction(&rastertocamera, make_float3(1, 0, 0));
107                 dy = transform_direction(&rastertocamera, make_float3(0, 1, 0));
108         }
109         else if(type == CAMERA_PERSPECTIVE) {
110                 dx = transform_perspective(&rastertocamera, make_float3(1, 0, 0)) -
111                      transform_perspective(&rastertocamera, make_float3(0, 0, 0));
112                 dy = transform_perspective(&rastertocamera, make_float3(0, 1, 0)) -
113                      transform_perspective(&rastertocamera, make_float3(0, 0, 0));
114         }
115         else {
116                 dx = make_float3(0, 0, 0);
117                 dy = make_float3(0, 0, 0);
118         }
119
120         dx = transform_direction(&cameratoworld, dx);
121         dy = transform_direction(&cameratoworld, dy);
122
123         need_update = false;
124         need_device_update = true;
125 }
126
127 void Camera::device_update(Device *device, DeviceScene *dscene)
128 {
129         update();
130
131         if(!need_device_update)
132                 return;
133         
134         KernelCamera *kcam = &dscene->data.cam;
135
136         /* store matrices */
137         kcam->screentoworld = screentoworld;
138         kcam->rastertoworld = rastertoworld;
139         kcam->ndctoworld = ndctoworld;
140         kcam->rastertocamera = rastertocamera;
141         kcam->cameratoworld = cameratoworld;
142         kcam->worldtoscreen = transform_inverse(screentoworld);
143         kcam->worldtoraster = transform_inverse(rastertoworld);
144         kcam->worldtondc = transform_inverse(ndctoworld);
145         kcam->worldtocamera = transform_inverse(cameratoworld);
146
147         /* depth of field */
148         kcam->aperturesize = aperturesize;
149         kcam->focaldistance = focaldistance;
150         kcam->blades = (blades < 3)? 0.0f: blades;
151         kcam->bladesrotation = bladesrotation;
152
153         /* motion blur */
154         kcam->shutteropen = shutteropen;
155         kcam->shutterclose = shutterclose;
156
157         /* type */
158         kcam->type = type;
159
160         /* store differentials */
161         kcam->dx = float3_to_float4(dx);
162         kcam->dy = float3_to_float4(dy);
163
164         /* clipping */
165         kcam->nearclip = nearclip;
166         kcam->cliplength = (farclip == FLT_MAX)? FLT_MAX: farclip - nearclip;
167
168         need_device_update = false;
169 }
170
171 void Camera::device_free(Device *device, DeviceScene *dscene)
172 {
173         /* nothing to free, only writing to constant memory */
174 }
175
176 bool Camera::modified(const Camera& cam)
177 {
178         return !((shutteropen == cam.shutteropen) &&
179                 (shutterclose == cam.shutterclose) &&
180                 (aperturesize == cam.aperturesize) &&
181                 (blades == cam.blades) &&
182                 (bladesrotation == cam.bladesrotation) &&
183                 (focaldistance == cam.focaldistance) &&
184                 (type == cam.type) &&
185                 (fov == cam.fov) &&
186                 (nearclip == cam.nearclip) &&
187                 (farclip == cam.farclip) &&
188                 // modified for progressive render
189                 // (width == cam.width) &&
190                 // (height == cam.height) &&
191                 (left == cam.left) &&
192                 (right == cam.right) &&
193                 (bottom == cam.bottom) &&
194                 (top == cam.top) &&
195                 (matrix == cam.matrix));
196 }
197
198 void Camera::tag_update()
199 {
200         need_update = true;
201 }
202
203 CCL_NAMESPACE_END
204