Code refactor: add DecomposedTransform.
This is in preparation of making Transform affine only, and also gives us a little extra type safety so we don't accidentally treat it as a regular 4x4 matrix.
This commit is contained in:
@@ -96,7 +96,7 @@ ccl_device_inline Transform object_fetch_vector_transform(KernelGlobals *kg, int
|
|||||||
#ifdef __OBJECT_MOTION__
|
#ifdef __OBJECT_MOTION__
|
||||||
ccl_device_inline Transform object_fetch_transform_motion(KernelGlobals *kg, int object, float time)
|
ccl_device_inline Transform object_fetch_transform_motion(KernelGlobals *kg, int object, float time)
|
||||||
{
|
{
|
||||||
const ccl_global MotionTransform *motion = &kernel_tex_fetch(__objects, object).tfm;
|
const ccl_global DecomposedMotionTransform *motion = &kernel_tex_fetch(__objects, object).tfm;
|
||||||
|
|
||||||
Transform tfm;
|
Transform tfm;
|
||||||
transform_motion_interpolate(&tfm, motion, time);
|
transform_motion_interpolate(&tfm, motion, time);
|
||||||
|
@@ -220,13 +220,13 @@ ccl_device_inline float4 primitive_motion_vector(KernelGlobals *kg, ShaderData *
|
|||||||
motion_center.x *= kernel_data.cam.width;
|
motion_center.x *= kernel_data.cam.width;
|
||||||
motion_center.y *= kernel_data.cam.height;
|
motion_center.y *= kernel_data.cam.height;
|
||||||
|
|
||||||
tfm = kernel_data.cam.motion.pre;
|
tfm = kernel_data.cam.pass_motion.pre;
|
||||||
motion_pre = normalize(transform_point(&tfm, motion_pre));
|
motion_pre = normalize(transform_point(&tfm, motion_pre));
|
||||||
motion_pre = float2_to_float3(direction_to_panorama(&kernel_data.cam, motion_pre));
|
motion_pre = float2_to_float3(direction_to_panorama(&kernel_data.cam, motion_pre));
|
||||||
motion_pre.x *= kernel_data.cam.width;
|
motion_pre.x *= kernel_data.cam.width;
|
||||||
motion_pre.y *= kernel_data.cam.height;
|
motion_pre.y *= kernel_data.cam.height;
|
||||||
|
|
||||||
tfm = kernel_data.cam.motion.post;
|
tfm = kernel_data.cam.pass_motion.post;
|
||||||
motion_post = normalize(transform_point(&tfm, motion_post));
|
motion_post = normalize(transform_point(&tfm, motion_post));
|
||||||
motion_post = float2_to_float3(direction_to_panorama(&kernel_data.cam, motion_post));
|
motion_post = float2_to_float3(direction_to_panorama(&kernel_data.cam, motion_post));
|
||||||
motion_post.x *= kernel_data.cam.width;
|
motion_post.x *= kernel_data.cam.width;
|
||||||
|
@@ -92,7 +92,7 @@ ccl_device void camera_sample_perspective(KernelGlobals *kg, float raster_x, flo
|
|||||||
|
|
||||||
#ifdef __CAMERA_MOTION__
|
#ifdef __CAMERA_MOTION__
|
||||||
if(kernel_data.cam.have_motion) {
|
if(kernel_data.cam.have_motion) {
|
||||||
ccl_constant MotionTransform *motion = &kernel_data.cam.motion;
|
ccl_constant DecomposedMotionTransform *motion = &kernel_data.cam.motion;
|
||||||
transform_motion_interpolate_constant(&cameratoworld,
|
transform_motion_interpolate_constant(&cameratoworld,
|
||||||
motion,
|
motion,
|
||||||
ray->time);
|
ray->time);
|
||||||
@@ -198,7 +198,7 @@ ccl_device void camera_sample_orthographic(KernelGlobals *kg, float raster_x, fl
|
|||||||
|
|
||||||
#ifdef __CAMERA_MOTION__
|
#ifdef __CAMERA_MOTION__
|
||||||
if(kernel_data.cam.have_motion) {
|
if(kernel_data.cam.have_motion) {
|
||||||
ccl_constant MotionTransform *motion = &kernel_data.cam.motion;
|
ccl_constant DecomposedMotionTransform *motion = &kernel_data.cam.motion;
|
||||||
transform_motion_interpolate_constant(&cameratoworld,
|
transform_motion_interpolate_constant(&cameratoworld,
|
||||||
motion,
|
motion,
|
||||||
ray->time);
|
ray->time);
|
||||||
@@ -270,7 +270,7 @@ ccl_device_inline void camera_sample_panorama(ccl_constant KernelCamera *cam,
|
|||||||
|
|
||||||
#ifdef __CAMERA_MOTION__
|
#ifdef __CAMERA_MOTION__
|
||||||
if(cam->have_motion) {
|
if(cam->have_motion) {
|
||||||
ccl_constant MotionTransform *motion = &cam->motion;
|
ccl_constant DecomposedMotionTransform *motion = &cam->motion;
|
||||||
transform_motion_interpolate_constant(&cameratoworld,
|
transform_motion_interpolate_constant(&cameratoworld,
|
||||||
motion,
|
motion,
|
||||||
ray->time);
|
ray->time);
|
||||||
|
@@ -1201,12 +1201,15 @@ typedef struct KernelCamera {
|
|||||||
ProjectionTransform worldtondc;
|
ProjectionTransform worldtondc;
|
||||||
Transform worldtocamera;
|
Transform worldtocamera;
|
||||||
|
|
||||||
MotionTransform motion;
|
DecomposedMotionTransform motion;
|
||||||
|
|
||||||
/* Stores changes in the projeciton matrix. Use for camera zoom motion
|
/* Stores changes in the projeciton matrix. Use for camera zoom motion
|
||||||
* blur and motion pass output for perspective camera. */
|
* blur and motion pass output for perspective camera. */
|
||||||
PerspectiveMotionTransform perspective_motion;
|
PerspectiveMotionTransform perspective_motion;
|
||||||
|
|
||||||
|
/* Transforms for motion pass. */
|
||||||
|
MotionTransform pass_motion;
|
||||||
|
|
||||||
int shutter_table_offset;
|
int shutter_table_offset;
|
||||||
|
|
||||||
/* Rolling shutter */
|
/* Rolling shutter */
|
||||||
@@ -1430,7 +1433,7 @@ static_assert_align(KernelData, 16);
|
|||||||
/* Kernel data structures. */
|
/* Kernel data structures. */
|
||||||
|
|
||||||
typedef struct KernelObject {
|
typedef struct KernelObject {
|
||||||
MotionTransform tfm;
|
DecomposedMotionTransform tfm;
|
||||||
|
|
||||||
float surface_area;
|
float surface_area;
|
||||||
float pass_id;
|
float pass_id;
|
||||||
|
@@ -341,12 +341,12 @@ void Camera::update(Scene *scene)
|
|||||||
/* TODO(sergey): Support perspective (zoom, fov) motion. */
|
/* TODO(sergey): Support perspective (zoom, fov) motion. */
|
||||||
if(type == CAMERA_PANORAMA) {
|
if(type == CAMERA_PANORAMA) {
|
||||||
if(use_motion) {
|
if(use_motion) {
|
||||||
kcam->motion.pre = transform_inverse(motion.pre);
|
kcam->pass_motion.pre = transform_inverse(motion.pre);
|
||||||
kcam->motion.post = transform_inverse(motion.post);
|
kcam->pass_motion.post = transform_inverse(motion.post);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
kcam->motion.pre = kcam->worldtocamera;
|
kcam->pass_motion.pre = kcam->worldtocamera;
|
||||||
kcam->motion.post = kcam->worldtocamera;
|
kcam->pass_motion.post = kcam->worldtocamera;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@@ -97,7 +97,7 @@ void Object::compute_bounds(bool motion_blur)
|
|||||||
mtfm.post = tfm;
|
mtfm.post = tfm;
|
||||||
}
|
}
|
||||||
|
|
||||||
MotionTransform decomp;
|
DecomposedMotionTransform decomp;
|
||||||
transform_motion_decompose(&decomp, &mtfm, &tfm);
|
transform_motion_decompose(&decomp, &mtfm, &tfm);
|
||||||
|
|
||||||
bounds = BoundBox::empty;
|
bounds = BoundBox::empty;
|
||||||
@@ -401,7 +401,7 @@ void ObjectManager::device_update_object_transform(UpdateObjectTransformState *s
|
|||||||
else if(state->need_motion == Scene::MOTION_BLUR) {
|
else if(state->need_motion == Scene::MOTION_BLUR) {
|
||||||
if(ob->use_motion) {
|
if(ob->use_motion) {
|
||||||
/* decompose transformations for interpolation. */
|
/* decompose transformations for interpolation. */
|
||||||
MotionTransform decomp;
|
DecomposedMotionTransform decomp;
|
||||||
|
|
||||||
transform_motion_decompose(&decomp, &ob->motion, &ob->tfm);
|
transform_motion_decompose(&decomp, &ob->motion, &ob->tfm);
|
||||||
kobject.tfm = decomp;
|
kobject.tfm = decomp;
|
||||||
|
@@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
CCL_NAMESPACE_BEGIN
|
CCL_NAMESPACE_BEGIN
|
||||||
|
|
||||||
/* Data Types */
|
/* 4x4 projection matrix, perspective or orthographic. */
|
||||||
|
|
||||||
typedef struct ProjectionTransform {
|
typedef struct ProjectionTransform {
|
||||||
float4 x, y, z, w; /* rows */
|
float4 x, y, z, w; /* rows */
|
||||||
|
@@ -202,7 +202,7 @@ float4 transform_to_quat(const Transform& tfm)
|
|||||||
return qt;
|
return qt;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void transform_decompose(Transform *decomp, const Transform *tfm)
|
static void transform_decompose(DecomposedTransform *decomp, const Transform *tfm)
|
||||||
{
|
{
|
||||||
/* extract translation */
|
/* extract translation */
|
||||||
decomp->y = make_float4(tfm->x.w, tfm->y.w, tfm->z.w, 0.0f);
|
decomp->y = make_float4(tfm->x.w, tfm->y.w, tfm->z.w, 0.0f);
|
||||||
@@ -247,7 +247,7 @@ static void transform_decompose(Transform *decomp, const Transform *tfm)
|
|||||||
decomp->w = make_float4(scale.y.z, scale.z.x, scale.z.y, scale.z.z);
|
decomp->w = make_float4(scale.y.z, scale.z.x, scale.z.y, scale.z.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
void transform_motion_decompose(MotionTransform *decomp, const MotionTransform *motion, const Transform *mid)
|
void transform_motion_decompose(DecomposedMotionTransform *decomp, const MotionTransform *motion, const Transform *mid)
|
||||||
{
|
{
|
||||||
transform_decompose(&decomp->pre, &motion->pre);
|
transform_decompose(&decomp->pre, &motion->pre);
|
||||||
transform_decompose(&decomp->mid, mid);
|
transform_decompose(&decomp->mid, mid);
|
||||||
|
@@ -37,16 +37,26 @@ typedef struct Transform {
|
|||||||
#endif
|
#endif
|
||||||
} Transform;
|
} Transform;
|
||||||
|
|
||||||
/* transform decomposed in rotation/translation/scale. we use the same data
|
|
||||||
* structure as Transform, and tightly pack decomposition into it. first the
|
|
||||||
* rotation (4), then translation (3), then 3x3 scale matrix (9). */
|
|
||||||
|
|
||||||
typedef struct ccl_may_alias MotionTransform {
|
typedef struct ccl_may_alias MotionTransform {
|
||||||
Transform pre;
|
Transform pre;
|
||||||
Transform mid;
|
Transform mid;
|
||||||
Transform post;
|
Transform post;
|
||||||
} MotionTransform;
|
} MotionTransform;
|
||||||
|
|
||||||
|
/* Transform decomposed in rotation/translation/scale. we use the same data
|
||||||
|
* structure as Transform, and tightly pack decomposition into it. first the
|
||||||
|
* rotation (4), then translation (3), then 3x3 scale matrix (9). */
|
||||||
|
|
||||||
|
typedef struct DecomposedTransform {
|
||||||
|
float4 x, y, z, w;
|
||||||
|
} DecomposedTransform;
|
||||||
|
|
||||||
|
typedef struct ccl_may_alias DecomposedMotionTransform {
|
||||||
|
DecomposedTransform pre;
|
||||||
|
DecomposedTransform mid;
|
||||||
|
DecomposedTransform post;
|
||||||
|
} DecomposedMotionTransform;
|
||||||
|
|
||||||
/* Functions */
|
/* Functions */
|
||||||
|
|
||||||
ccl_device_inline float3 transform_point(const Transform *t, const float3 a)
|
ccl_device_inline float3 transform_point(const Transform *t, const float3 a)
|
||||||
@@ -384,7 +394,7 @@ ccl_device_inline Transform transform_quick_inverse(Transform M)
|
|||||||
return R;
|
return R;
|
||||||
}
|
}
|
||||||
|
|
||||||
ccl_device_inline void transform_compose(Transform *tfm, const Transform *decomp)
|
ccl_device_inline void transform_compose(Transform *tfm, const DecomposedTransform *decomp)
|
||||||
{
|
{
|
||||||
/* rotation */
|
/* rotation */
|
||||||
float q0, q1, q2, q3, qda, qdb, qdc, qaa, qab, qac, qbb, qbc, qcc;
|
float q0, q1, q2, q3, qda, qdb, qdc, qaa, qab, qac, qbb, qbc, qcc;
|
||||||
@@ -420,9 +430,9 @@ ccl_device_inline void transform_compose(Transform *tfm, const Transform *decomp
|
|||||||
tfm->w = make_float4(0.0f, 0.0f, 0.0f, 1.0f);
|
tfm->w = make_float4(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
ccl_device void transform_motion_interpolate(Transform *tfm, const ccl_global MotionTransform *motion, float t)
|
ccl_device void transform_motion_interpolate(Transform *tfm, const ccl_global DecomposedMotionTransform *motion, float t)
|
||||||
{
|
{
|
||||||
Transform decomp;
|
DecomposedTransform decomp;
|
||||||
|
|
||||||
/* linear interpolation for rotation and scale */
|
/* linear interpolation for rotation and scale */
|
||||||
if(t < 0.5f) {
|
if(t < 0.5f) {
|
||||||
@@ -446,12 +456,12 @@ ccl_device void transform_motion_interpolate(Transform *tfm, const ccl_global Mo
|
|||||||
transform_compose(tfm, &decomp);
|
transform_compose(tfm, &decomp);
|
||||||
}
|
}
|
||||||
|
|
||||||
ccl_device void transform_motion_interpolate_constant(Transform *tfm, ccl_constant MotionTransform *motion, float t)
|
ccl_device void transform_motion_interpolate_constant(Transform *tfm, ccl_constant DecomposedMotionTransform *motion, float t)
|
||||||
{
|
{
|
||||||
/* possible optimization: is it worth it adding a check to skip scaling?
|
/* possible optimization: is it worth it adding a check to skip scaling?
|
||||||
* it's probably quite uncommon to have scaling objects. or can we skip
|
* it's probably quite uncommon to have scaling objects. or can we skip
|
||||||
* just shearing perhaps? */
|
* just shearing perhaps? */
|
||||||
Transform decomp;
|
DecomposedTransform decomp;
|
||||||
|
|
||||||
/* linear interpolation for rotation and scale */
|
/* linear interpolation for rotation and scale */
|
||||||
if(t < 0.5f) {
|
if(t < 0.5f) {
|
||||||
@@ -479,13 +489,18 @@ ccl_device void transform_motion_interpolate_constant(Transform *tfm, ccl_consta
|
|||||||
|
|
||||||
class BoundBox2D;
|
class BoundBox2D;
|
||||||
|
|
||||||
|
ccl_device_inline bool operator==(const DecomposedTransform& A, const DecomposedTransform& B)
|
||||||
|
{
|
||||||
|
return memcmp(&A, &B, sizeof(DecomposedTransform)) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
ccl_device_inline bool operator==(const MotionTransform& A, const MotionTransform& B)
|
ccl_device_inline bool operator==(const MotionTransform& A, const MotionTransform& B)
|
||||||
{
|
{
|
||||||
return (A.pre == B.pre && A.post == B.post);
|
return (A.pre == B.pre && A.post == B.post);
|
||||||
}
|
}
|
||||||
|
|
||||||
float4 transform_to_quat(const Transform& tfm);
|
float4 transform_to_quat(const Transform& tfm);
|
||||||
void transform_motion_decompose(MotionTransform *decomp, const MotionTransform *motion, const Transform *mid);
|
void transform_motion_decompose(DecomposedMotionTransform *decomp, const MotionTransform *motion, const Transform *mid);
|
||||||
Transform transform_from_viewplane(BoundBox2D& viewplane);
|
Transform transform_from_viewplane(BoundBox2D& viewplane);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user