forked from bartvdbraak/blender
Code refactor: add ProjectionTransform separate from regular Transform.
This is in preparation of making Transform affine only.
This commit is contained in:
parent
cd15d87bfc
commit
516e82a900
@ -96,7 +96,7 @@ bool BlenderObjectCulling::test(Scene *scene, BL::Object& b_ob, Transform& tfm)
|
||||
bool BlenderObjectCulling::test_camera(Scene *scene, float3 bb[8])
|
||||
{
|
||||
Camera *cam = scene->camera;
|
||||
Transform& worldtondc = cam->worldtondc;
|
||||
const ProjectionTransform& worldtondc = cam->worldtondc;
|
||||
float3 bb_min = make_float3(FLT_MAX, FLT_MAX, FLT_MAX),
|
||||
bb_max = make_float3(-FLT_MAX, -FLT_MAX, -FLT_MAX);
|
||||
bool all_behind = true;
|
||||
|
@ -254,6 +254,7 @@ set(SRC_UTIL_HEADERS
|
||||
../util/util_math_int3.h
|
||||
../util/util_math_int4.h
|
||||
../util/util_math_matrix.h
|
||||
../util/util_projection.h
|
||||
../util/util_rect.h
|
||||
../util/util_static_assert.h
|
||||
../util/util_transform.h
|
||||
|
@ -204,14 +204,14 @@ ccl_device_inline float4 primitive_motion_vector(KernelGlobals *kg, ShaderData *
|
||||
/* camera motion, for perspective/orthographic motion.pre/post will be a
|
||||
* world-to-raster matrix, for panorama it's world-to-camera */
|
||||
if(kernel_data.cam.type != CAMERA_PANORAMA) {
|
||||
tfm = kernel_data.cam.worldtoraster;
|
||||
motion_center = transform_perspective(&tfm, center);
|
||||
ProjectionTransform projection = kernel_data.cam.worldtoraster;
|
||||
motion_center = transform_perspective(&projection, center);
|
||||
|
||||
tfm = kernel_data.cam.motion.pre;
|
||||
motion_pre = transform_perspective(&tfm, motion_pre);
|
||||
projection = kernel_data.cam.perspective_motion.pre;
|
||||
motion_pre = transform_perspective(&projection, motion_pre);
|
||||
|
||||
tfm = kernel_data.cam.motion.post;
|
||||
motion_post = transform_perspective(&tfm, motion_post);
|
||||
projection = kernel_data.cam.perspective_motion.post;
|
||||
motion_post = transform_perspective(&projection, motion_post);
|
||||
}
|
||||
else {
|
||||
tfm = kernel_data.cam.worldtocamera;
|
||||
|
@ -42,7 +42,7 @@ ccl_device float2 camera_sample_aperture(ccl_constant KernelCamera *cam, float u
|
||||
ccl_device void camera_sample_perspective(KernelGlobals *kg, float raster_x, float raster_y, float lens_u, float lens_v, ccl_addr_space Ray *ray)
|
||||
{
|
||||
/* create ray form raster position */
|
||||
Transform rastertocamera = kernel_data.cam.rastertocamera;
|
||||
ProjectionTransform rastertocamera = kernel_data.cam.rastertocamera;
|
||||
float3 raster = make_float3(raster_x, raster_y, 0.0f);
|
||||
float3 Pcamera = transform_perspective(&rastertocamera, raster);
|
||||
|
||||
@ -54,13 +54,13 @@ ccl_device void camera_sample_perspective(KernelGlobals *kg, float raster_x, flo
|
||||
* interpolated field of view.
|
||||
*/
|
||||
if(ray->time < 0.5f) {
|
||||
Transform rastertocamera_pre = kernel_data.cam.perspective_motion.pre;
|
||||
ProjectionTransform rastertocamera_pre = kernel_data.cam.perspective_motion.pre;
|
||||
float3 Pcamera_pre =
|
||||
transform_perspective(&rastertocamera_pre, raster);
|
||||
Pcamera = interp(Pcamera_pre, Pcamera, ray->time * 2.0f);
|
||||
}
|
||||
else {
|
||||
Transform rastertocamera_post = kernel_data.cam.perspective_motion.post;
|
||||
ProjectionTransform rastertocamera_post = kernel_data.cam.perspective_motion.post;
|
||||
float3 Pcamera_post =
|
||||
transform_perspective(&rastertocamera_post, raster);
|
||||
Pcamera = interp(Pcamera, Pcamera_post, (ray->time - 0.5f) * 2.0f);
|
||||
@ -169,7 +169,7 @@ ccl_device void camera_sample_perspective(KernelGlobals *kg, float raster_x, flo
|
||||
ccl_device void camera_sample_orthographic(KernelGlobals *kg, float raster_x, float raster_y, float lens_u, float lens_v, ccl_addr_space Ray *ray)
|
||||
{
|
||||
/* create ray form raster position */
|
||||
Transform rastertocamera = kernel_data.cam.rastertocamera;
|
||||
ProjectionTransform rastertocamera = kernel_data.cam.rastertocamera;
|
||||
float3 Pcamera = transform_perspective(&rastertocamera, make_float3(raster_x, raster_y, 0.0f));
|
||||
|
||||
float3 P;
|
||||
@ -231,7 +231,7 @@ ccl_device_inline void camera_sample_panorama(ccl_constant KernelCamera *cam,
|
||||
float lens_u, float lens_v,
|
||||
ccl_addr_space Ray *ray)
|
||||
{
|
||||
Transform rastertocamera = cam->rastertocamera;
|
||||
ProjectionTransform rastertocamera = cam->rastertocamera;
|
||||
float3 Pcamera = transform_perspective(&rastertocamera, make_float3(raster_x, raster_y, 0.0f));
|
||||
|
||||
/* create ray form raster position */
|
||||
@ -442,7 +442,7 @@ ccl_device_inline float3 camera_world_to_ndc(KernelGlobals *kg, ShaderData *sd,
|
||||
if(sd->object == PRIM_NONE && kernel_data.cam.type == CAMERA_PERSPECTIVE)
|
||||
P += camera_position(kg);
|
||||
|
||||
Transform tfm = kernel_data.cam.worldtondc;
|
||||
ProjectionTransform tfm = kernel_data.cam.worldtondc;
|
||||
return transform_perspective(&tfm, P);
|
||||
}
|
||||
else {
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "util/util_math.h"
|
||||
#include "util/util_math_fast.h"
|
||||
#include "util/util_math_intersect.h"
|
||||
#include "util/util_projection.h"
|
||||
#include "util/util_texture.h"
|
||||
#include "util/util_transform.h"
|
||||
|
||||
|
@ -1159,7 +1159,7 @@ typedef struct KernelCamera {
|
||||
|
||||
/* matrices */
|
||||
Transform cameratoworld;
|
||||
Transform rastertocamera;
|
||||
ProjectionTransform rastertocamera;
|
||||
|
||||
/* differentials */
|
||||
float4 dx;
|
||||
@ -1193,21 +1193,18 @@ typedef struct KernelCamera {
|
||||
int is_inside_volume;
|
||||
|
||||
/* more matrices */
|
||||
Transform screentoworld;
|
||||
Transform rastertoworld;
|
||||
/* work around cuda sm 2.0 crash, this seems to
|
||||
* cross some limit in combination with motion
|
||||
* Transform ndctoworld; */
|
||||
Transform worldtoscreen;
|
||||
Transform worldtoraster;
|
||||
Transform worldtondc;
|
||||
ProjectionTransform screentoworld;
|
||||
ProjectionTransform rastertoworld;
|
||||
ProjectionTransform ndctoworld;
|
||||
ProjectionTransform worldtoscreen;
|
||||
ProjectionTransform worldtoraster;
|
||||
ProjectionTransform worldtondc;
|
||||
Transform worldtocamera;
|
||||
|
||||
MotionTransform motion;
|
||||
|
||||
/* Denotes changes in the projective matrix, namely in rastertocamera.
|
||||
* Used for camera zoom motion blur,
|
||||
*/
|
||||
/* Stores changes in the projeciton matrix. Use for camera zoom motion
|
||||
* blur and motion pass output for perspective camera. */
|
||||
PerspectiveMotionTransform perspective_motion;
|
||||
|
||||
int shutter_table_offset;
|
||||
|
@ -62,11 +62,18 @@ CCL_NAMESPACE_BEGIN
|
||||
|
||||
/* RenderServices implementation */
|
||||
|
||||
#define COPY_MATRIX44(m1, m2) { \
|
||||
CHECK_TYPE(m1, OSL::Matrix44*); \
|
||||
CHECK_TYPE(m2, Transform*); \
|
||||
memcpy(m1, m2, sizeof(*m2)); \
|
||||
} (void)0
|
||||
static void copy_matrix(OSL::Matrix44& m, const Transform& tfm)
|
||||
{
|
||||
// TODO: remember when making affine
|
||||
Transform t = transform_transpose(tfm);
|
||||
memcpy(&m, &t, sizeof(m));
|
||||
}
|
||||
|
||||
static void copy_matrix(OSL::Matrix44& m, const ProjectionTransform& tfm)
|
||||
{
|
||||
ProjectionTransform t = projection_transpose(tfm);
|
||||
memcpy(&m, &t, sizeof(m));
|
||||
}
|
||||
|
||||
/* static ustrings */
|
||||
ustring OSLRenderServices::u_distance("distance");
|
||||
@ -167,14 +174,12 @@ bool OSLRenderServices::get_matrix(OSL::ShaderGlobals *sg, OSL::Matrix44 &result
|
||||
#else
|
||||
Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
|
||||
#endif
|
||||
tfm = transform_transpose(tfm);
|
||||
COPY_MATRIX44(&result, &tfm);
|
||||
copy_matrix(result, tfm);
|
||||
|
||||
return true;
|
||||
}
|
||||
else if(sd->type == PRIMITIVE_LAMP) {
|
||||
Transform tfm = transform_transpose(sd->ob_tfm);
|
||||
COPY_MATRIX44(&result, &tfm);
|
||||
copy_matrix(result, sd->ob_tfm);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -203,14 +208,12 @@ bool OSLRenderServices::get_inverse_matrix(OSL::ShaderGlobals *sg, OSL::Matrix44
|
||||
#else
|
||||
Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
|
||||
#endif
|
||||
itfm = transform_transpose(itfm);
|
||||
COPY_MATRIX44(&result, &itfm);
|
||||
copy_matrix(result, itfm);
|
||||
|
||||
return true;
|
||||
}
|
||||
else if(sd->type == PRIMITIVE_LAMP) {
|
||||
Transform tfm = transform_transpose(sd->ob_itfm);
|
||||
COPY_MATRIX44(&result, &tfm);
|
||||
copy_matrix(result, sd->ob_itfm);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -224,23 +227,19 @@ bool OSLRenderServices::get_matrix(OSL::ShaderGlobals *sg, OSL::Matrix44 &result
|
||||
KernelGlobals *kg = kernel_globals;
|
||||
|
||||
if(from == u_ndc) {
|
||||
Transform tfm = transform_transpose(transform_quick_inverse(kernel_data.cam.worldtondc));
|
||||
COPY_MATRIX44(&result, &tfm);
|
||||
copy_matrix(result, kernel_data.cam.ndctoworld);
|
||||
return true;
|
||||
}
|
||||
else if(from == u_raster) {
|
||||
Transform tfm = transform_transpose(kernel_data.cam.rastertoworld);
|
||||
COPY_MATRIX44(&result, &tfm);
|
||||
copy_matrix(result, kernel_data.cam.rastertoworld);
|
||||
return true;
|
||||
}
|
||||
else if(from == u_screen) {
|
||||
Transform tfm = transform_transpose(kernel_data.cam.screentoworld);
|
||||
COPY_MATRIX44(&result, &tfm);
|
||||
copy_matrix(result, kernel_data.cam.screentoworld);
|
||||
return true;
|
||||
}
|
||||
else if(from == u_camera) {
|
||||
Transform tfm = transform_transpose(kernel_data.cam.cameratoworld);
|
||||
COPY_MATRIX44(&result, &tfm);
|
||||
copy_matrix(result, kernel_data.cam.cameratoworld);
|
||||
return true;
|
||||
}
|
||||
else if(from == u_world) {
|
||||
@ -256,23 +255,19 @@ bool OSLRenderServices::get_inverse_matrix(OSL::ShaderGlobals *sg, OSL::Matrix44
|
||||
KernelGlobals *kg = kernel_globals;
|
||||
|
||||
if(to == u_ndc) {
|
||||
Transform tfm = transform_transpose(kernel_data.cam.worldtondc);
|
||||
COPY_MATRIX44(&result, &tfm);
|
||||
copy_matrix(result, kernel_data.cam.worldtondc);
|
||||
return true;
|
||||
}
|
||||
else if(to == u_raster) {
|
||||
Transform tfm = transform_transpose(kernel_data.cam.worldtoraster);
|
||||
COPY_MATRIX44(&result, &tfm);
|
||||
copy_matrix(result, kernel_data.cam.worldtoraster);
|
||||
return true;
|
||||
}
|
||||
else if(to == u_screen) {
|
||||
Transform tfm = transform_transpose(kernel_data.cam.worldtoscreen);
|
||||
COPY_MATRIX44(&result, &tfm);
|
||||
copy_matrix(result, kernel_data.cam.worldtoscreen);
|
||||
return true;
|
||||
}
|
||||
else if(to == u_camera) {
|
||||
Transform tfm = transform_transpose(kernel_data.cam.worldtocamera);
|
||||
COPY_MATRIX44(&result, &tfm);
|
||||
copy_matrix(result, kernel_data.cam.worldtocamera);
|
||||
return true;
|
||||
}
|
||||
else if(to == u_world) {
|
||||
@ -298,14 +293,12 @@ bool OSLRenderServices::get_matrix(OSL::ShaderGlobals *sg, OSL::Matrix44 &result
|
||||
KernelGlobals *kg = sd->osl_globals;
|
||||
Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
|
||||
#endif
|
||||
tfm = transform_transpose(tfm);
|
||||
COPY_MATRIX44(&result, &tfm);
|
||||
copy_matrix(result, tfm);
|
||||
|
||||
return true;
|
||||
}
|
||||
else if(sd->type == PRIMITIVE_LAMP) {
|
||||
Transform tfm = transform_transpose(sd->ob_tfm);
|
||||
COPY_MATRIX44(&result, &tfm);
|
||||
copy_matrix(result, sd->ob_tfm);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -329,14 +322,12 @@ bool OSLRenderServices::get_inverse_matrix(OSL::ShaderGlobals *sg, OSL::Matrix44
|
||||
KernelGlobals *kg = sd->osl_globals;
|
||||
Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
|
||||
#endif
|
||||
tfm = transform_transpose(tfm);
|
||||
COPY_MATRIX44(&result, &tfm);
|
||||
copy_matrix(result, tfm);
|
||||
|
||||
return true;
|
||||
}
|
||||
else if(sd->type == PRIMITIVE_LAMP) {
|
||||
Transform tfm = transform_transpose(sd->ob_itfm);
|
||||
COPY_MATRIX44(&result, &tfm);
|
||||
copy_matrix(result, sd->ob_itfm);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -350,23 +341,19 @@ bool OSLRenderServices::get_matrix(OSL::ShaderGlobals *sg, OSL::Matrix44 &result
|
||||
KernelGlobals *kg = kernel_globals;
|
||||
|
||||
if(from == u_ndc) {
|
||||
Transform tfm = transform_transpose(transform_quick_inverse(kernel_data.cam.worldtondc));
|
||||
COPY_MATRIX44(&result, &tfm);
|
||||
copy_matrix(result, kernel_data.cam.ndctoworld);
|
||||
return true;
|
||||
}
|
||||
else if(from == u_raster) {
|
||||
Transform tfm = transform_transpose(kernel_data.cam.rastertoworld);
|
||||
COPY_MATRIX44(&result, &tfm);
|
||||
copy_matrix(result, kernel_data.cam.rastertoworld);
|
||||
return true;
|
||||
}
|
||||
else if(from == u_screen) {
|
||||
Transform tfm = transform_transpose(kernel_data.cam.screentoworld);
|
||||
COPY_MATRIX44(&result, &tfm);
|
||||
copy_matrix(result, kernel_data.cam.screentoworld);
|
||||
return true;
|
||||
}
|
||||
else if(from == u_camera) {
|
||||
Transform tfm = transform_transpose(kernel_data.cam.cameratoworld);
|
||||
COPY_MATRIX44(&result, &tfm);
|
||||
copy_matrix(result, kernel_data.cam.cameratoworld);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -378,23 +365,19 @@ bool OSLRenderServices::get_inverse_matrix(OSL::ShaderGlobals *sg, OSL::Matrix44
|
||||
KernelGlobals *kg = kernel_globals;
|
||||
|
||||
if(to == u_ndc) {
|
||||
Transform tfm = transform_transpose(kernel_data.cam.worldtondc);
|
||||
COPY_MATRIX44(&result, &tfm);
|
||||
copy_matrix(result, kernel_data.cam.worldtondc);
|
||||
return true;
|
||||
}
|
||||
else if(to == u_raster) {
|
||||
Transform tfm = transform_transpose(kernel_data.cam.worldtoraster);
|
||||
COPY_MATRIX44(&result, &tfm);
|
||||
copy_matrix(result, kernel_data.cam.worldtoraster);
|
||||
return true;
|
||||
}
|
||||
else if(to == u_screen) {
|
||||
Transform tfm = transform_transpose(kernel_data.cam.worldtoscreen);
|
||||
COPY_MATRIX44(&result, &tfm);
|
||||
copy_matrix(result, kernel_data.cam.worldtoscreen);
|
||||
return true;
|
||||
}
|
||||
else if(to == u_camera) {
|
||||
Transform tfm = transform_transpose(kernel_data.cam.worldtocamera);
|
||||
COPY_MATRIX44(&result, &tfm);
|
||||
copy_matrix(result, kernel_data.cam.worldtocamera);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -163,12 +163,12 @@ Camera::Camera()
|
||||
|
||||
compute_auto_viewplane();
|
||||
|
||||
screentoworld = transform_identity();
|
||||
rastertoworld = transform_identity();
|
||||
ndctoworld = transform_identity();
|
||||
rastertocamera = transform_identity();
|
||||
screentoworld = projection_identity();
|
||||
rastertoworld = projection_identity();
|
||||
ndctoworld = projection_identity();
|
||||
rastertocamera = projection_identity();
|
||||
cameratoworld = transform_identity();
|
||||
worldtoraster = transform_identity();
|
||||
worldtoraster = projection_identity();
|
||||
|
||||
dx = make_float3(0.0f, 0.0f, 0.0f);
|
||||
dy = make_float3(0.0f, 0.0f, 0.0f);
|
||||
@ -241,18 +241,18 @@ void Camera::update(Scene *scene)
|
||||
Transform full_rastertoscreen = transform_inverse(full_screentoraster);
|
||||
|
||||
/* screen to camera */
|
||||
Transform cameratoscreen;
|
||||
ProjectionTransform cameratoscreen;
|
||||
if(type == CAMERA_PERSPECTIVE)
|
||||
cameratoscreen = transform_perspective(fov, nearclip, farclip);
|
||||
cameratoscreen = projection_perspective(fov, nearclip, farclip);
|
||||
else if(type == CAMERA_ORTHOGRAPHIC)
|
||||
cameratoscreen = transform_orthographic(nearclip, farclip);
|
||||
cameratoscreen = projection_orthographic(nearclip, farclip);
|
||||
else
|
||||
cameratoscreen = transform_identity();
|
||||
cameratoscreen = projection_identity();
|
||||
|
||||
Transform screentocamera = transform_inverse(cameratoscreen);
|
||||
ProjectionTransform screentocamera = projection_inverse(cameratoscreen);
|
||||
|
||||
rastertocamera = screentocamera * rastertoscreen;
|
||||
Transform full_rastertocamera = screentocamera * full_rastertoscreen;
|
||||
ProjectionTransform full_rastertocamera = screentocamera * full_rastertoscreen;
|
||||
cameratoraster = screentoraster * cameratoscreen;
|
||||
|
||||
cameratoworld = matrix;
|
||||
@ -270,10 +270,10 @@ void Camera::update(Scene *scene)
|
||||
|
||||
/* differentials */
|
||||
if(type == CAMERA_ORTHOGRAPHIC) {
|
||||
dx = transform_direction(&rastertocamera, make_float3(1, 0, 0));
|
||||
dy = transform_direction(&rastertocamera, make_float3(0, 1, 0));
|
||||
full_dx = transform_direction(&full_rastertocamera, make_float3(1, 0, 0));
|
||||
full_dy = transform_direction(&full_rastertocamera, make_float3(0, 1, 0));
|
||||
dx = transform_perspective_direction(&rastertocamera, make_float3(1, 0, 0));
|
||||
dy = transform_perspective_direction(&rastertocamera, make_float3(0, 1, 0));
|
||||
full_dx = transform_perspective_direction(&full_rastertocamera, make_float3(1, 0, 0));
|
||||
full_dy = transform_perspective_direction(&full_rastertocamera, make_float3(0, 1, 0));
|
||||
}
|
||||
else if(type == CAMERA_PERSPECTIVE) {
|
||||
dx = transform_perspective(&rastertocamera, make_float3(1, 0, 0)) -
|
||||
@ -307,14 +307,14 @@ void Camera::update(Scene *scene)
|
||||
/* TODO(sergey): Move to an utility function and de-duplicate with
|
||||
* calculation above.
|
||||
*/
|
||||
Transform screentocamera_pre =
|
||||
transform_inverse(transform_perspective(fov_pre,
|
||||
nearclip,
|
||||
farclip));
|
||||
Transform screentocamera_post =
|
||||
transform_inverse(transform_perspective(fov_post,
|
||||
nearclip,
|
||||
farclip));
|
||||
ProjectionTransform screentocamera_pre =
|
||||
projection_inverse(projection_perspective(fov_pre,
|
||||
nearclip,
|
||||
farclip));
|
||||
ProjectionTransform screentocamera_post =
|
||||
projection_inverse(projection_perspective(fov_post,
|
||||
nearclip,
|
||||
farclip));
|
||||
perspective_motion.pre = screentocamera_pre * rastertoscreen;
|
||||
perspective_motion.post = screentocamera_post * rastertoscreen;
|
||||
}
|
||||
@ -331,6 +331,7 @@ void Camera::update(Scene *scene)
|
||||
kcam->worldtoscreen = worldtoscreen;
|
||||
kcam->worldtoraster = worldtoraster;
|
||||
kcam->worldtondc = worldtondc;
|
||||
kcam->ndctoworld = ndctoworld;
|
||||
|
||||
/* camera motion */
|
||||
kcam->have_motion = 0;
|
||||
@ -350,12 +351,12 @@ void Camera::update(Scene *scene)
|
||||
}
|
||||
else {
|
||||
if(use_motion) {
|
||||
kcam->motion.pre = cameratoraster * transform_inverse(motion.pre);
|
||||
kcam->motion.post = cameratoraster * transform_inverse(motion.post);
|
||||
kcam->perspective_motion.pre = cameratoraster * transform_inverse(motion.pre);
|
||||
kcam->perspective_motion.post = cameratoraster * transform_inverse(motion.post);
|
||||
}
|
||||
else {
|
||||
kcam->motion.pre = worldtoraster;
|
||||
kcam->motion.post = worldtoraster;
|
||||
kcam->perspective_motion.pre = worldtoraster;
|
||||
kcam->perspective_motion.post = worldtoraster;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -606,7 +607,7 @@ float Camera::world_to_raster_size(float3 P)
|
||||
res = min(len(full_dx), len(full_dy));
|
||||
|
||||
if(offscreen_dicing_scale > 1.0f) {
|
||||
float3 p = transform_perspective(&worldtocamera, P);
|
||||
float3 p = transform_point(&worldtocamera, P);
|
||||
float3 v = transform_perspective(&rastertocamera, make_float3(width, height, 0.0f));
|
||||
|
||||
/* Create point clamped to frustum */
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "graph/node.h"
|
||||
|
||||
#include "util/util_boundbox.h"
|
||||
#include "util/util_projection.h"
|
||||
#include "util/util_transform.h"
|
||||
#include "util/util_types.h"
|
||||
|
||||
@ -146,18 +147,18 @@ public:
|
||||
PerspectiveMotionTransform perspective_motion;
|
||||
|
||||
/* computed camera parameters */
|
||||
Transform screentoworld;
|
||||
Transform rastertoworld;
|
||||
Transform ndctoworld;
|
||||
ProjectionTransform screentoworld;
|
||||
ProjectionTransform rastertoworld;
|
||||
ProjectionTransform ndctoworld;
|
||||
Transform cameratoworld;
|
||||
|
||||
Transform worldtoraster;
|
||||
Transform worldtoscreen;
|
||||
Transform worldtondc;
|
||||
ProjectionTransform worldtoraster;
|
||||
ProjectionTransform worldtoscreen;
|
||||
ProjectionTransform worldtondc;
|
||||
Transform worldtocamera;
|
||||
|
||||
Transform rastertocamera;
|
||||
Transform cameratoraster;
|
||||
ProjectionTransform rastertocamera;
|
||||
ProjectionTransform cameratoraster;
|
||||
|
||||
float3 dx;
|
||||
float3 dy;
|
||||
|
@ -67,6 +67,7 @@ set(SRC_HEADERS
|
||||
util_param.h
|
||||
util_path.h
|
||||
util_progress.h
|
||||
util_projection.h
|
||||
util_queue.h
|
||||
util_rect.h
|
||||
util_set.h
|
||||
|
176
intern/cycles/util/util_projection.h
Normal file
176
intern/cycles/util/util_projection.h
Normal file
@ -0,0 +1,176 @@
|
||||
/*
|
||||
* Copyright 2011-2018 Blender Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __UTIL_PROJECTION_H__
|
||||
#define __UTIL_PROJECTION_H__
|
||||
|
||||
#include "util/util_transform.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
/* Data Types */
|
||||
|
||||
typedef struct ProjectionTransform {
|
||||
float4 x, y, z, w; /* rows */
|
||||
|
||||
#ifndef __KERNEL_GPU__
|
||||
ProjectionTransform()
|
||||
{
|
||||
}
|
||||
|
||||
explicit ProjectionTransform(const Transform& tfm)
|
||||
: x(tfm.x),
|
||||
y(tfm.y),
|
||||
z(tfm.z),
|
||||
w(tfm.w)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
} ProjectionTransform;
|
||||
|
||||
typedef struct PerspectiveMotionTransform {
|
||||
ProjectionTransform pre;
|
||||
ProjectionTransform post;
|
||||
} PerspectiveMotionTransform;
|
||||
|
||||
/* Functions */
|
||||
|
||||
ccl_device_inline float3 transform_perspective(const ProjectionTransform *t, const float3 a)
|
||||
{
|
||||
float4 b = make_float4(a.x, a.y, a.z, 1.0f);
|
||||
float3 c = make_float3(dot(t->x, b), dot(t->y, b), dot(t->z, b));
|
||||
float w = dot(t->w, b);
|
||||
|
||||
return (w != 0.0f)? c/w: make_float3(0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
ccl_device_inline float3 transform_perspective_direction(const ProjectionTransform *t, const float3 a)
|
||||
{
|
||||
float3 c = make_float3(
|
||||
a.x*t->x.x + a.y*t->x.y + a.z*t->x.z,
|
||||
a.x*t->y.x + a.y*t->y.y + a.z*t->y.z,
|
||||
a.x*t->z.x + a.y*t->z.y + a.z*t->z.z);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
#ifndef __KERNEL_GPU__
|
||||
|
||||
ccl_device_inline ProjectionTransform projection_transpose(const ProjectionTransform& a)
|
||||
{
|
||||
ProjectionTransform t;
|
||||
|
||||
t.x.x = a.x.x; t.x.y = a.y.x; t.x.z = a.z.x; t.x.w = a.w.x;
|
||||
t.y.x = a.x.y; t.y.y = a.y.y; t.y.z = a.z.y; t.y.w = a.w.y;
|
||||
t.z.x = a.x.z; t.z.y = a.y.z; t.z.z = a.z.z; t.z.w = a.w.z;
|
||||
t.w.x = a.x.w; t.w.y = a.y.w; t.w.z = a.z.w; t.w.w = a.w.w;
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
ccl_device_inline ProjectionTransform projection_inverse(const ProjectionTransform& a)
|
||||
{
|
||||
Transform t = {a.x, a.y, a.z, a.w};
|
||||
t = transform_inverse(t);
|
||||
return ProjectionTransform(t);
|
||||
}
|
||||
|
||||
ccl_device_inline ProjectionTransform make_projection(
|
||||
float a, float b, float c, float d,
|
||||
float e, float f, float g, float h,
|
||||
float i, float j, float k, float l,
|
||||
float m, float n, float o, float p)
|
||||
{
|
||||
ProjectionTransform t;
|
||||
|
||||
t.x.x = a; t.x.y = b; t.x.z = c; t.x.w = d;
|
||||
t.y.x = e; t.y.y = f; t.y.z = g; t.y.w = h;
|
||||
t.z.x = i; t.z.y = j; t.z.z = k; t.z.w = l;
|
||||
t.w.x = m; t.w.y = n; t.w.z = o; t.w.w = p;
|
||||
|
||||
return t;
|
||||
}
|
||||
ccl_device_inline ProjectionTransform projection_identity()
|
||||
{
|
||||
return make_projection(
|
||||
1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
ccl_device_inline ProjectionTransform operator*(const ProjectionTransform& a, const ProjectionTransform& b)
|
||||
{
|
||||
ProjectionTransform c = projection_transpose(b);
|
||||
ProjectionTransform t;
|
||||
|
||||
t.x = make_float4(dot(a.x, c.x), dot(a.x, c.y), dot(a.x, c.z), dot(a.x, c.w));
|
||||
t.y = make_float4(dot(a.y, c.x), dot(a.y, c.y), dot(a.y, c.z), dot(a.y, c.w));
|
||||
t.z = make_float4(dot(a.z, c.x), dot(a.z, c.y), dot(a.z, c.z), dot(a.z, c.w));
|
||||
t.w = make_float4(dot(a.w, c.x), dot(a.w, c.y), dot(a.w, c.z), dot(a.w, c.w));
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
ccl_device_inline ProjectionTransform operator*(const ProjectionTransform& a, const Transform& b)
|
||||
{
|
||||
return a * ProjectionTransform(b);
|
||||
}
|
||||
|
||||
ccl_device_inline ProjectionTransform operator*(const Transform& a, const ProjectionTransform& b)
|
||||
{
|
||||
return ProjectionTransform(a) * b;
|
||||
}
|
||||
|
||||
ccl_device_inline void print_projection(const char *label, const ProjectionTransform& t)
|
||||
{
|
||||
print_float4(label, t.x);
|
||||
print_float4(label, t.y);
|
||||
print_float4(label, t.z);
|
||||
print_float4(label, t.w);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
ccl_device_inline ProjectionTransform projection_perspective(float fov, float n, float f)
|
||||
{
|
||||
ProjectionTransform persp = make_projection(
|
||||
1, 0, 0, 0,
|
||||
0, 1, 0, 0,
|
||||
0, 0, f / (f - n), -f*n / (f - n),
|
||||
0, 0, 1, 0);
|
||||
|
||||
float inv_angle = 1.0f/tanf(0.5f*fov);
|
||||
|
||||
Transform scale = transform_scale(inv_angle, inv_angle, 1);
|
||||
|
||||
return scale * persp;
|
||||
}
|
||||
|
||||
ccl_device_inline ProjectionTransform projection_orthographic(float znear, float zfar)
|
||||
{
|
||||
Transform t =
|
||||
transform_scale(1.0f, 1.0f, 1.0f / (zfar-znear)) *
|
||||
transform_translate(0.0f, 0.0f, -znear);
|
||||
|
||||
return ProjectionTransform(t);
|
||||
}
|
||||
|
||||
#endif /* __KERNEL_GPU__ */
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
#endif /* __UTIL_PROJECTION_H__ */
|
||||
|
@ -47,22 +47,8 @@ typedef struct ccl_may_alias MotionTransform {
|
||||
Transform post;
|
||||
} MotionTransform;
|
||||
|
||||
typedef struct PerspectiveMotionTransform {
|
||||
Transform pre;
|
||||
Transform post;
|
||||
} PerspectiveMotionTransform;
|
||||
|
||||
/* Functions */
|
||||
|
||||
ccl_device_inline float3 transform_perspective(const Transform *t, const float3 a)
|
||||
{
|
||||
float4 b = make_float4(a.x, a.y, a.z, 1.0f);
|
||||
float3 c = make_float3(dot(t->x, b), dot(t->y, b), dot(t->z, b));
|
||||
float w = dot(t->w, b);
|
||||
|
||||
return (w != 0.0f)? c/w: make_float3(0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
ccl_device_inline float3 transform_point(const Transform *t, const float3 a)
|
||||
{
|
||||
/* TODO(sergey): Disabled for now, causes crashes in certain cases. */
|
||||
@ -221,21 +207,6 @@ ccl_device_inline Transform transform_scale(float x, float y, float z)
|
||||
return transform_scale(make_float3(x, y, z));
|
||||
}
|
||||
|
||||
ccl_device_inline Transform transform_perspective(float fov, float n, float f)
|
||||
{
|
||||
Transform persp = make_transform(
|
||||
1, 0, 0, 0,
|
||||
0, 1, 0, 0,
|
||||
0, 0, f / (f - n), -f*n / (f - n),
|
||||
0, 0, 1, 0);
|
||||
|
||||
float inv_angle = 1.0f/tanf(0.5f*fov);
|
||||
|
||||
Transform scale = transform_scale(inv_angle, inv_angle, 1);
|
||||
|
||||
return scale * persp;
|
||||
}
|
||||
|
||||
ccl_device_inline Transform transform_rotate(float angle, float3 axis)
|
||||
{
|
||||
float s = sinf(angle);
|
||||
@ -272,12 +243,6 @@ ccl_device_inline Transform transform_euler(float3 euler)
|
||||
transform_rotate(euler.x, make_float3(1.0f, 0.0f, 0.0f));
|
||||
}
|
||||
|
||||
ccl_device_inline Transform transform_orthographic(float znear, float zfar)
|
||||
{
|
||||
return transform_scale(1.0f, 1.0f, 1.0f / (zfar-znear)) *
|
||||
transform_translate(0.0f, 0.0f, -znear);
|
||||
}
|
||||
|
||||
ccl_device_inline Transform transform_identity()
|
||||
{
|
||||
return transform_scale(1.0f, 1.0f, 1.0f);
|
||||
|
Loading…
Reference in New Issue
Block a user