36
37
matrix = transform_identity();
39
motion.pre = transform_identity();
40
motion.post = transform_identity();
38
43
type = CAMERA_PERSPECTIVE;
44
panorama_type = PANORAMA_EQUIRECTANGULAR;
47
left = -((float)width/(float)height);
48
right = (float)width/(float)height;
58
viewplane.left = -((float)width/(float)height);
59
viewplane.right = (float)width/(float)height;
60
viewplane.bottom = -1.0f;
52
63
screentoworld = transform_identity();
53
64
rastertoworld = transform_identity();
77
89
Transform ndctoraster = transform_scale(width, height, 1.0f);
79
91
/* raster to screen */
80
Transform screentoraster = ndctoraster;
82
screentoraster = ndctoraster *
83
transform_scale(1.0f/(right - left), 1.0f/(top - bottom), 1.0f) *
84
transform_translate(-left, -bottom, 0.0f);
92
Transform screentondc =
93
transform_scale(1.0f/(viewplane.right - viewplane.left),
94
1.0f/(viewplane.top - viewplane.bottom), 1.0f) *
95
transform_translate(-viewplane.left, -viewplane.bottom, 0.0f);
97
Transform screentoraster = ndctoraster * screentondc;
86
98
Transform rastertoscreen = transform_inverse(screentoraster);
88
100
/* screen to camera */
92
104
screentocamera = transform_inverse(transform_orthographic(nearclip, farclip));
94
106
screentocamera = transform_identity();
108
Transform cameratoscreen = transform_inverse(screentocamera);
96
110
rastertocamera = screentocamera * rastertoscreen;
111
cameratoraster = screentoraster * cameratoscreen;
98
113
cameratoworld = matrix;
99
114
screentoworld = cameratoworld * screentocamera;
100
115
rastertoworld = cameratoworld * rastertocamera;
101
116
ndctoworld = rastertoworld * ndctoraster;
102
worldtoraster = transform_inverse(rastertoworld);
118
/* note we recompose matrices instead of taking inverses of the above, this
119
* is needed to avoid inverting near degenerate matrices that happen due to
120
* precision issues with large scenes */
121
worldtocamera = transform_inverse(matrix);
122
worldtoscreen = cameratoscreen * worldtocamera;
123
worldtondc = screentondc * worldtoscreen;
124
worldtoraster = ndctoraster * worldtondc;
104
126
/* differentials */
105
127
if(type == CAMERA_ORTHOGRAPHIC) {
124
146
need_device_update = true;
127
void Camera::device_update(Device *device, DeviceScene *dscene)
149
void Camera::device_update(Device *device, DeviceScene *dscene, Scene *scene)
151
Scene::MotionType need_motion = scene->need_motion(device->info.advanced_shading);
155
if (previous_need_motion != need_motion) {
156
/* scene's motion model could have been changed since previous device
157
* camera update this could happen for example in case when one render
158
* layer has got motion pass and another not */
159
need_device_update = true;
131
162
if(!need_device_update)
136
167
/* store matrices */
137
168
kcam->screentoworld = screentoworld;
138
169
kcam->rastertoworld = rastertoworld;
139
kcam->ndctoworld = ndctoworld;
140
170
kcam->rastertocamera = rastertocamera;
141
171
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);
172
kcam->worldtocamera = worldtocamera;
173
kcam->worldtoscreen = worldtoscreen;
174
kcam->worldtoraster = worldtoraster;
175
kcam->worldtondc = worldtondc;
178
kcam->have_motion = 0;
180
if(need_motion == Scene::MOTION_PASS) {
181
if(type == CAMERA_PANORAMA) {
183
kcam->motion.pre = transform_inverse(motion.pre);
184
kcam->motion.post = transform_inverse(motion.post);
187
kcam->motion.pre = kcam->worldtocamera;
188
kcam->motion.post = kcam->worldtocamera;
193
kcam->motion.pre = cameratoraster * transform_inverse(motion.pre);
194
kcam->motion.post = cameratoraster * transform_inverse(motion.post);
197
kcam->motion.pre = worldtoraster;
198
kcam->motion.post = worldtoraster;
202
#ifdef __CAMERA_MOTION__
203
else if(need_motion == Scene::MOTION_BLUR) {
205
transform_motion_decompose((DecompMotionTransform*)&kcam->motion, &motion, &matrix);
206
kcam->have_motion = 1;
147
211
/* depth of field */
148
212
kcam->aperturesize = aperturesize;
151
215
kcam->bladesrotation = bladesrotation;
153
217
/* motion blur */
154
kcam->shutteropen = shutteropen;
155
kcam->shutterclose = shutterclose;
218
#ifdef __CAMERA_MOTION__
219
kcam->shuttertime = (need_motion == Scene::MOTION_BLUR) ? shuttertime: -1.0f;
221
kcam->shuttertime = -1.0f;
158
225
kcam->type = type;
228
kcam->panorama_type = panorama_type;
229
kcam->fisheye_fov = fisheye_fov;
230
kcam->fisheye_lens = fisheye_lens;
233
kcam->sensorwidth = sensorwidth;
234
kcam->sensorheight = sensorheight;
238
kcam->height = height;
160
240
/* store differentials */
161
241
kcam->dx = float3_to_float4(dx);
162
242
kcam->dy = float3_to_float4(dy);
166
246
kcam->cliplength = (farclip == FLT_MAX)? FLT_MAX: farclip - nearclip;
168
248
need_device_update = false;
249
previous_need_motion = need_motion;
171
252
void Camera::device_free(Device *device, DeviceScene *dscene)
176
257
bool Camera::modified(const Camera& cam)
178
return !((shutteropen == cam.shutteropen) &&
179
(shutterclose == cam.shutterclose) &&
259
return !((shuttertime == cam.shuttertime) &&
180
260
(aperturesize == cam.aperturesize) &&
181
261
(blades == cam.blades) &&
182
262
(bladesrotation == cam.bladesrotation) &&
185
265
(fov == cam.fov) &&
186
266
(nearclip == cam.nearclip) &&
187
267
(farclip == cam.farclip) &&
268
(sensorwidth == cam.sensorwidth) &&
269
(sensorheight == cam.sensorheight) &&
188
270
// modified for progressive render
189
271
// (width == cam.width) &&
190
272
// (height == cam.height) &&
191
(left == cam.left) &&
192
(right == cam.right) &&
193
(bottom == cam.bottom) &&
195
(matrix == cam.matrix));
273
(viewplane == cam.viewplane) &&
274
(border == cam.border) &&
275
(matrix == cam.matrix) &&
276
(panorama_type == cam.panorama_type) &&
277
(fisheye_fov == cam.fisheye_fov) &&
278
(fisheye_lens == cam.fisheye_lens));
281
bool Camera::motion_modified(const Camera& cam)
283
return !((motion == cam.motion) &&
284
(use_motion == cam.use_motion));
198
287
void Camera::tag_update()