diff options
Diffstat (limited to 'intern/cycles/kernel/geom/geom_triangle_intersect.h')
-rw-r--r-- | intern/cycles/kernel/geom/geom_triangle_intersect.h | 34 |
1 files changed, 23 insertions, 11 deletions
diff --git a/intern/cycles/kernel/geom/geom_triangle_intersect.h b/intern/cycles/kernel/geom/geom_triangle_intersect.h index 3ef918dc842..ba309a1dc53 100644 --- a/intern/cycles/kernel/geom/geom_triangle_intersect.h +++ b/intern/cycles/kernel/geom/geom_triangle_intersect.h @@ -98,7 +98,7 @@ void triangle_intersect_precalc(float3 dir, } /* TODO(sergey): Make it general utility function. */ -ccl_device_inline float xor_signmast(float x, int y) +ccl_device_inline float xor_signmask(float x, int y) { return __int_as_float(__float_as_int(x) ^ y); } @@ -140,13 +140,15 @@ ccl_device_inline bool triangle_intersect(KernelGlobals *kg, /* Calculate scaled barycentric coordinates. */ float U = Cx * By - Cy * Bx; - int sign_mask = (__float_as_int(U) & 0x80000000); float V = Ax * Cy - Ay * Cx; - if(sign_mask != (__float_as_int(V) & 0x80000000)) { - return false; - } float W = Bx * Ay - By * Ax; - if(sign_mask != (__float_as_int(W) & 0x80000000)) { + const int sign_mask = (__float_as_int(U) & 0x80000000); + /* TODO(sergey): Check if multiplication plus sign check is faster + * or at least same speed (but robust for endian types). + */ + if(sign_mask != (__float_as_int(V) & 0x80000000) || + sign_mask != (__float_as_int(W) & 0x80000000)) + { return false; } @@ -156,13 +158,13 @@ ccl_device_inline bool triangle_intersect(KernelGlobals *kg, return false; } - /* Calculate scaled z−coordinates of vertices and use them to calculate + /* Calculate scaled z-coordinates of vertices and use them to calculate * the hit distance. */ const float T = (U * A_kz + V * B_kz + W * C_kz) * Sz; - const float sign_T = xor_signmast(T, sign_mask); + const float sign_T = xor_signmask(T, sign_mask); if((sign_T < 0.0f) || - (sign_T > isect->t * xor_signmast(det, sign_mask))) + (sign_T > isect->t * xor_signmask(det, sign_mask))) { return false; } @@ -173,6 +175,16 @@ ccl_device_inline bool triangle_intersect(KernelGlobals *kg, if(kernel_tex_fetch(__prim_visibility, triAddr) & visibility) #endif { +#ifdef __KERNEL_GPU__ + float4 a = tri_b - tri_a, b = tri_c - tri_a; + if(len_squared(make_float3(a.y*b.z - a.z*b.y, + a.z*b.x - a.x*b.z, + a.x*b.y - a.y*b.x)) == 0.0f) + { + return false; + } +#endif + /* Normalize U, V, W, and T. */ const float inv_det = 1.0f / det; isect->prim = triAddr; @@ -253,9 +265,9 @@ ccl_device_inline void triangle_intersect_subsurface( * the hit distance. */ const float T = (U * A_kz + V * B_kz + W * C_kz) * Sz; - const float sign_T = xor_signmast(T, sign_mask); + const float sign_T = xor_signmask(T, sign_mask); if((sign_T < 0.0f) || - (sign_T > tmax * xor_signmast(det, sign_mask))) + (sign_T > tmax * xor_signmask(det, sign_mask))) { return; } |