Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/util/math_intersect.h
| Show First 20 Lines • Show All 82 Lines • ▼ Show 20 Lines | ccl_device bool ray_aligned_disk_intersect(float3 ray_P, | ||||
| *isect_P = P; | *isect_P = P; | ||||
| *isect_t = t; | *isect_t = t; | ||||
| return true; | return true; | ||||
| } | } | ||||
| ccl_device_forceinline bool ray_triangle_intersect(float3 ray_P, | ccl_device_forceinline bool ray_triangle_intersect(float3 ray_P, | ||||
| float3 ray_dir, | float3 ray_dir, | ||||
| float ray_t, | float ray_t, | ||||
| #if defined(__KERNEL_SSE2__) && defined(__KERNEL_SSE__) | |||||
| const ssef *ssef_verts, | |||||
| #else | |||||
| const float3 tri_a, | const float3 tri_a, | ||||
| const float3 tri_b, | const float3 tri_b, | ||||
| const float3 tri_c, | const float3 tri_c, | ||||
| #endif | |||||
| ccl_private float *isect_u, | ccl_private float *isect_u, | ||||
| ccl_private float *isect_v, | ccl_private float *isect_v, | ||||
| ccl_private float *isect_t) | ccl_private float *isect_t) | ||||
| { | { | ||||
| #if defined(__KERNEL_SSE2__) && defined(__KERNEL_SSE__) | |||||
| typedef ssef float3; | |||||
| const float3 tri_a(ssef_verts[0]); | |||||
| const float3 tri_b(ssef_verts[1]); | |||||
| const float3 tri_c(ssef_verts[2]); | |||||
| const float3 P(ray_P); | |||||
| const float3 dir(ray_dir); | |||||
| #else | |||||
| # define dot3(a, b) dot(a, b) | #define dot3(a, b) dot(a, b) | ||||
| const float3 P = ray_P; | const float3 P = ray_P; | ||||
| const float3 dir = ray_dir; | const float3 dir = ray_dir; | ||||
| #endif | |||||
| /* Calculate vertices relative to ray origin. */ | /* Calculate vertices relative to ray origin. */ | ||||
| const float3 v0 = tri_c - P; | const float3 v0 = tri_c - P; | ||||
| const float3 v1 = tri_a - P; | const float3 v1 = tri_a - P; | ||||
| const float3 v2 = tri_b - P; | const float3 v2 = tri_b - P; | ||||
| /* Calculate triangle edges. */ | /* Calculate triangle edges. */ | ||||
| const float3 e0 = v2 - v0; | const float3 e0 = v2 - v0; | ||||
| const float3 e1 = v0 - v1; | const float3 e1 = v0 - v1; | ||||
| const float3 e2 = v1 - v2; | const float3 e2 = v1 - v2; | ||||
| /* Perform edge tests. */ | /* Perform edge tests. */ | ||||
| #if defined(__KERNEL_SSE2__) && defined(__KERNEL_SSE__) | |||||
| const float3 crossU = cross(v2 + v0, e0); | |||||
| const float3 crossV = cross(v0 + v1, e1); | |||||
| const float3 crossW = cross(v1 + v2, e2); | |||||
| ssef crossX(crossU); | |||||
| ssef crossY(crossV); | |||||
| ssef crossZ(crossW); | |||||
| ssef zero = _mm_setzero_ps(); | |||||
| _MM_TRANSPOSE4_PS(crossX, crossY, crossZ, zero); | |||||
| const ssef dirX(ray_dir.x); | |||||
| const ssef dirY(ray_dir.y); | |||||
| const ssef dirZ(ray_dir.z); | |||||
| ssef UVWW = madd(crossX, dirX, madd(crossY, dirY, crossZ * dirZ)); | |||||
| #else /* __KERNEL_SSE2__ */ | |||||
| const float U = dot(cross(v2 + v0, e0), ray_dir); | const float U = dot(cross(v2 + v0, e0), ray_dir); | ||||
| const float V = dot(cross(v0 + v1, e1), ray_dir); | const float V = dot(cross(v0 + v1, e1), ray_dir); | ||||
| const float W = dot(cross(v1 + v2, e2), ray_dir); | const float W = dot(cross(v1 + v2, e2), ray_dir); | ||||
| #endif /* __KERNEL_SSE2__ */ | |||||
| #if defined(__KERNEL_SSE2__) && defined(__KERNEL_SSE__) | |||||
| int uvw_sign = movemask(UVWW) & 0x7; | |||||
| if (uvw_sign != 0) { | |||||
| if (uvw_sign != 0x7) { | |||||
| return false; | |||||
| } | |||||
| } | |||||
| #else | |||||
| const float minUVW = min(U, min(V, W)); | const float minUVW = min(U, min(V, W)); | ||||
| const float maxUVW = max(U, max(V, W)); | const float maxUVW = max(U, max(V, W)); | ||||
| if (minUVW < 0.0f && maxUVW > 0.0f) { | if (minUVW < 0.0f && maxUVW > 0.0f) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| #endif | |||||
| /* Calculate geometry normal and denominator. */ | /* Calculate geometry normal and denominator. */ | ||||
| const float3 Ng1 = cross(e1, e0); | const float3 Ng1 = cross(e1, e0); | ||||
| // const Vec3vfM Ng1 = stable_triangle_normal(e2,e1,e0); | // const Vec3vfM Ng1 = stable_triangle_normal(e2,e1,e0); | ||||
| const float3 Ng = Ng1 + Ng1; | const float3 Ng = Ng1 + Ng1; | ||||
| const float den = dot3(Ng, dir); | const float den = dot3(Ng, dir); | ||||
| /* Avoid division by 0. */ | /* Avoid division by 0. */ | ||||
| if (UNLIKELY(den == 0.0f)) { | if (UNLIKELY(den == 0.0f)) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| /* Perform depth test. */ | /* Perform depth test. */ | ||||
| const float T = dot3(v0, Ng); | const float T = dot3(v0, Ng); | ||||
| const int sign_den = (__float_as_int(den) & 0x80000000); | const int sign_den = (__float_as_int(den) & 0x80000000); | ||||
| const float sign_T = xor_signmask(T, sign_den); | const float sign_T = xor_signmask(T, sign_den); | ||||
| if ((sign_T < 0.0f) || (sign_T > ray_t * xor_signmask(den, sign_den))) { | if ((sign_T < 0.0f) || (sign_T > ray_t * xor_signmask(den, sign_den))) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| const float inv_den = 1.0f / den; | const float inv_den = 1.0f / den; | ||||
| #if defined(__KERNEL_SSE2__) && defined(__KERNEL_SSE__) | |||||
| UVWW *= inv_den; | |||||
| _mm_store_ss(isect_u, UVWW); | |||||
| _mm_store_ss(isect_v, shuffle<1, 1, 3, 3>(UVWW)); | |||||
| #else | |||||
| *isect_u = U * inv_den; | *isect_u = U * inv_den; | ||||
| *isect_v = V * inv_den; | *isect_v = V * inv_den; | ||||
| #endif | |||||
| *isect_t = T * inv_den; | *isect_t = T * inv_den; | ||||
| return true; | return true; | ||||
| #undef dot3 | #undef dot3 | ||||
| } | } | ||||
| /* Tests for an intersection between a ray and a quad defined by | /* Tests for an intersection between a ray and a quad defined by | ||||
| * its midpoint, normal and sides. | * its midpoint, normal and sides. | ||||
| ▲ Show 20 Lines • Show All 51 Lines • Show Last 20 Lines | |||||