Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/util/util_transform.h')
-rw-r--r--intern/cycles/util/util_transform.h118
1 files changed, 118 insertions, 0 deletions
diff --git a/intern/cycles/util/util_transform.h b/intern/cycles/util/util_transform.h
index aeaef7b0e21..03dfbaa441d 100644
--- a/intern/cycles/util/util_transform.h
+++ b/intern/cycles/util/util_transform.h
@@ -28,6 +28,8 @@
CCL_NAMESPACE_BEGIN
+/* Data Types */
+
typedef struct Transform {
float4 x, y, z, w; /* rows */
@@ -37,6 +39,17 @@ typedef struct Transform {
#endif
} Transform;
+typedef struct MotionTransform {
+ Transform pre;
+ Transform post;
+} 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) */
+
+/* Functions */
+
__device_inline float3 transform_perspective(const Transform *t, const float3 a)
{
float4 b = make_float4(a.x, a.y, a.z, 1.0f);
@@ -62,6 +75,15 @@ __device_inline float3 transform_direction(const Transform *t, const float3 a)
return c;
}
+__device_inline float3 transform_direction_transposed(const Transform *t, const float3 a)
+{
+ float3 x = make_float3(t->x.x, t->y.x, t->z.x);
+ float3 y = make_float3(t->x.y, t->y.y, t->z.y);
+ float3 z = make_float3(t->x.z, t->y.z, t->z.z);
+
+ return make_float3(dot(x, a), dot(y, a), dot(z, a));
+}
+
#ifndef __KERNEL_GPU__
__device_inline void print_transform(const char *label, const Transform& t)
@@ -272,6 +294,102 @@ __device_inline Transform transform_clear_scale(const Transform& tfm)
#endif
+/* Motion Transform */
+
+__device_inline float4 quat_interpolate(float4 q1, float4 q2, float t)
+{
+ float costheta = dot(q1, q2);
+
+ if(costheta > 0.9995f) {
+ return normalize((1.0f - t)*q1 + t*q2);
+ }
+ else {
+ float theta = acosf(clamp(costheta, -1.0f, 1.0f));
+ float thetap = theta * t;
+ float4 qperp = normalize(q2 - q1 * costheta);
+ return q1 * cosf(thetap) + qperp * sinf(thetap);
+ }
+}
+
+__device_inline Transform transform_quick_inverse(Transform M)
+{
+ Transform R;
+ float det = M.x.x*(M.z.z*M.y.y - M.z.y*M.y.z) - M.y.x*(M.z.z*M.x.y - M.z.y*M.x.z) + M.z.x*(M.y.z*M.x.y - M.y.y*M.x.z);
+
+ det = (det != 0.0f)? 1.0f/det: 0.0f;
+
+ float3 Rx = det*make_float3(M.z.z*M.y.y - M.z.y*M.y.z, M.z.y*M.x.z - M.z.z*M.x.y, M.y.z*M.x.y - M.y.y*M.x.z);
+ float3 Ry = det*make_float3(M.z.x*M.y.z - M.z.z*M.y.x, M.z.z*M.x.x - M.z.x*M.x.z, M.y.x*M.x.z - M.y.z*M.x.x);
+ float3 Rz = det*make_float3(M.z.y*M.y.x - M.z.x*M.y.y, M.z.x*M.x.y - M.z.y*M.x.x, M.y.y*M.x.x - M.y.x*M.x.y);
+ float3 T = -make_float3(M.x.w, M.y.w, M.z.w);
+
+ R.x = make_float4(Rx.x, Rx.y, Rx.z, dot(Rx, T));
+ R.y = make_float4(Ry.x, Ry.y, Ry.z, dot(Ry, T));
+ R.z = make_float4(Rz.x, Rz.y, Rz.z, dot(Rz, T));
+ R.w = make_float4(0.0f, 0.0f, 0.0f, 1.0f);
+
+ return R;
+}
+
+__device_inline void transform_compose(Transform *tfm, const Transform *decomp)
+{
+ /* rotation */
+ float q0, q1, q2, q3, qda, qdb, qdc, qaa, qab, qac, qbb, qbc, qcc;
+
+ q0 = M_SQRT2_F * decomp->x.w;
+ q1 = M_SQRT2_F * decomp->x.x;
+ q2 = M_SQRT2_F * decomp->x.y;
+ q3 = M_SQRT2_F * decomp->x.z;
+
+ qda = q0*q1;
+ qdb = q0*q2;
+ qdc = q0*q3;
+ qaa = q1*q1;
+ qab = q1*q2;
+ qac = q1*q3;
+ qbb = q2*q2;
+ qbc = q2*q3;
+ qcc = q3*q3;
+
+ float3 rotation_x = make_float3(1.0f-qbb-qcc, -qdc+qab, qdb+qac);
+ float3 rotation_y = make_float3(qdc+qab, 1.0f-qaa-qcc, -qda+qbc);
+ float3 rotation_z = make_float3(-qdb+qac, qda+qbc, 1.0f-qaa-qbb);
+
+ /* scale */
+ float3 scale_x = make_float3(decomp->y.w, decomp->z.z, decomp->w.y);
+ float3 scale_y = make_float3(decomp->z.x, decomp->z.w, decomp->w.z);
+ float3 scale_z = make_float3(decomp->z.y, decomp->w.x, decomp->w.w);
+
+ /* compose with translation */
+ tfm->x = make_float4(dot(rotation_x, scale_x), dot(rotation_x, scale_y), dot(rotation_x, scale_z), decomp->y.x);
+ tfm->y = make_float4(dot(rotation_y, scale_x), dot(rotation_y, scale_y), dot(rotation_y, scale_z), decomp->y.y);
+ tfm->z = make_float4(dot(rotation_z, scale_x), dot(rotation_z, scale_y), dot(rotation_z, scale_z), decomp->y.z);
+ tfm->w = make_float4(0.0f, 0.0f, 0.0f, 1.0f);
+}
+
+__device void transform_motion_interpolate(Transform *tfm, const MotionTransform *motion, float t)
+{
+ Transform decomp;
+
+ decomp.x = quat_interpolate(motion->pre.x, motion->post.x, t);
+ decomp.y = (1.0f - t)*motion->pre.y + t*motion->post.y;
+ decomp.z = (1.0f - t)*motion->pre.z + t*motion->post.z;
+ decomp.w = (1.0f - t)*motion->pre.w + t*motion->post.w;
+
+ transform_compose(tfm, &decomp);
+}
+
+#ifndef __KERNEL_GPU__
+
+__device_inline bool operator==(const MotionTransform& A, const MotionTransform& B)
+{
+ return (A.pre == B.pre && A.post == B.post);
+}
+
+void transform_motion_decompose(MotionTransform *decomp, const MotionTransform *motion);
+
+#endif
+
CCL_NAMESPACE_END
#endif /* __UTIL_TRANSFORM_H__ */