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/kernel/geom/geom_triangle_intersect.h')
-rw-r--r--intern/cycles/kernel/geom/geom_triangle_intersect.h34
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;
}