Jolt Physics
A multi core friendly Game Physics Engine
Loading...
Searching...
No Matches
RayTriangle.h
Go to the documentation of this file.
1// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
2// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
3// SPDX-License-Identifier: MIT
4
5#pragma once
6
8
11JPH_INLINE float RayTriangle(Vec3Arg inOrigin, Vec3Arg inDirection, Vec3Arg inV0, Vec3Arg inV1, Vec3Arg inV2)
12{
13 // Epsilon
14 Vec3 epsilon = Vec3::sReplicate(1.0e-12f);
15
16 // Zero & one
17 Vec3 zero = Vec3::sZero();
18 Vec3 one = Vec3::sReplicate(1.0f);
19
20 // Find vectors for two edges sharing inV0
21 Vec3 e1 = inV1 - inV0;
22 Vec3 e2 = inV2 - inV0;
23
24 // Begin calculating determinant - also used to calculate u parameter
25 Vec3 p = inDirection.Cross(e2);
26
27 // if determinant is near zero, ray lies in plane of triangle
28 Vec3 det = Vec3::sReplicate(e1.Dot(p));
29
30 // Check if determinant is near zero
31 UVec4 det_near_zero = Vec3::sLess(det.Abs(), epsilon);
32
33 // When the determinant is near zero, set it to one to avoid dividing by zero
34 det = Vec3::sSelect(det, Vec3::sReplicate(1.0f), det_near_zero);
35
36 // Calculate distance from inV0 to ray origin
37 Vec3 s = inOrigin - inV0;
38
39 // Calculate u parameter
40 Vec3 u = Vec3::sReplicate(s.Dot(p)) / det;
41
42 // Prepare to test v parameter
43 Vec3 q = s.Cross(e1);
44
45 // Calculate v parameter
46 Vec3 v = Vec3::sReplicate(inDirection.Dot(q)) / det;
47
48 // Get intersection point
49 Vec3 t = Vec3::sReplicate(e2.Dot(q)) / det;
50
51 // Check if there is an intersection
52 UVec4 no_intersection =
54 (
56 (
58 (
59 det_near_zero,
60 Vec3::sLess(u, zero)
61 ),
63 (
64 Vec3::sLess(v, zero),
65 Vec3::sGreater(u + v, one)
66 )
67 ),
68 Vec3::sLess(t, zero)
69 );
70
71 // Select intersection point or FLT_MAX based on if there is an intersection or not
72 return Vec3::sSelect(t, Vec3::sReplicate(FLT_MAX), no_intersection).GetX();
73}
74
76JPH_INLINE Vec4 RayTriangle4(Vec3Arg inOrigin, Vec3Arg inDirection, Vec4Arg inV0X, Vec4Arg inV0Y, Vec4Arg inV0Z, Vec4Arg inV1X, Vec4Arg inV1Y, Vec4Arg inV1Z, Vec4Arg inV2X, Vec4Arg inV2Y, Vec4Arg inV2Z)
77{
78 // Epsilon
79 Vec4 epsilon = Vec4::sReplicate(1.0e-12f);
80
81 // Zero
82 Vec4 zero = Vec4::sZero();
83
84 // Find vectors for two edges sharing inV0
85 Vec4 e1x = inV1X - inV0X;
86 Vec4 e1y = inV1Y - inV0Y;
87 Vec4 e1z = inV1Z - inV0Z;
88 Vec4 e2x = inV2X - inV0X;
89 Vec4 e2y = inV2Y - inV0Y;
90 Vec4 e2z = inV2Z - inV0Z;
91
92 // Get direction vector components
93 Vec4 dx = inDirection.SplatX();
94 Vec4 dy = inDirection.SplatY();
95 Vec4 dz = inDirection.SplatZ();
96
97 // Begin calculating determinant - also used to calculate u parameter
98 Vec4 px = dy * e2z - dz * e2y;
99 Vec4 py = dz * e2x - dx * e2z;
100 Vec4 pz = dx * e2y - dy * e2x;
101
102 // if determinant is near zero, ray lies in plane of triangle
103 Vec4 det = e1x * px + e1y * py + e1z * pz;
104
105 // Get sign bit for determinant and make positive
106 Vec4 det_sign = Vec4::sAnd(det, UVec4::sReplicate(0x80000000).ReinterpretAsFloat());
107 det = Vec4::sXor(det, det_sign);
108
109 // Check which determinants are near zero
110 UVec4 det_near_zero = Vec4::sLess(det, epsilon);
111
112 // Set components of the determinant to 1 that are near zero to avoid dividing by zero
113 det = Vec4::sSelect(det, Vec4::sReplicate(1.0f), det_near_zero);
114
115 // Calculate distance from inV0 to ray origin
116 Vec4 sx = inOrigin.SplatX() - inV0X;
117 Vec4 sy = inOrigin.SplatY() - inV0Y;
118 Vec4 sz = inOrigin.SplatZ() - inV0Z;
119
120 // Calculate u parameter and flip sign if determinant was negative
121 Vec4 u = Vec4::sXor(sx * px + sy * py + sz * pz, det_sign);
122
123 // Prepare to test v parameter
124 Vec4 qx = sy * e1z - sz * e1y;
125 Vec4 qy = sz * e1x - sx * e1z;
126 Vec4 qz = sx * e1y - sy * e1x;
127
128 // Calculate v parameter and flip sign if determinant was negative
129 Vec4 v = Vec4::sXor(dx * qx + dy * qy + dz * qz, det_sign);
130
131 // Get intersection point and flip sign if determinant was negative
132 Vec4 t = Vec4::sXor(e2x * qx + e2y * qy + e2z * qz, det_sign);
133
134 // Check if there is an intersection
135 UVec4 no_intersection =
137 (
139 (
141 (
142 det_near_zero,
143 Vec4::sLess(u, zero)
144 ),
146 (
147 Vec4::sLess(v, zero),
148 Vec4::sGreater(u + v, det)
149 )
150 ),
151 Vec4::sLess(t, zero)
152 );
153
154 // Select intersection point or FLT_MAX based on if there is an intersection or not
155 return Vec4::sSelect(t / det, Vec4::sReplicate(FLT_MAX), no_intersection);
156}
157
#define JPH_NAMESPACE_END
Definition: Core.h:378
#define JPH_NAMESPACE_BEGIN
Definition: Core.h:372
JPH_NAMESPACE_BEGIN JPH_INLINE float RayTriangle(Vec3Arg inOrigin, Vec3Arg inDirection, Vec3Arg inV0, Vec3Arg inV1, Vec3Arg inV2)
Definition: RayTriangle.h:11
JPH_INLINE Vec4 RayTriangle4(Vec3Arg inOrigin, Vec3Arg inDirection, Vec4Arg inV0X, Vec4Arg inV0Y, Vec4Arg inV0Z, Vec4Arg inV1X, Vec4Arg inV1Y, Vec4Arg inV1Z, Vec4Arg inV2X, Vec4Arg inV2Y, Vec4Arg inV2Z)
Intersect ray with 4 triangles in SOA format, returns 4 vector of closest points or FLT_MAX if no hit...
Definition: RayTriangle.h:76
Definition: UVec4.h:12
static JPH_INLINE UVec4 sReplicate(uint32 inV)
Replicate int inV across all components.
Definition: UVec4.inl:56
static JPH_INLINE UVec4 sOr(UVec4Arg inV1, UVec4Arg inV2)
Logical or (component wise)
Definition: UVec4.inl:171
Definition: Vec3.h:17
JPH_INLINE float Dot(Vec3Arg inV2) const
Dot product.
Definition: Vec3.inl:645
JPH_INLINE Vec4 SplatX() const
Replicate the X component to all components.
Definition: Vec3.inl:529
JPH_INLINE Vec3 Cross(Vec3Arg inV2) const
Cross product.
Definition: Vec3.inl:590
JPH_INLINE float GetX() const
Get individual components.
Definition: Vec3.h:124
JPH_INLINE Vec3 Abs() const
Return the absolute value of each of the components.
Definition: Vec3.inl:572
JPH_INLINE Vec4 SplatZ() const
Replicate the Z component to all components.
Definition: Vec3.inl:551
static JPH_INLINE UVec4 sGreater(Vec3Arg inV1, Vec3Arg inV2)
Greater than (component wise)
Definition: Vec3.inl:222
static JPH_INLINE Vec3 sSelect(Vec3Arg inV1, Vec3Arg inV2, UVec4Arg inControl)
Component wise select, returns inV1 when highest bit of inControl = 0 and inV2 when highest bit of in...
Definition: Vec3.inl:269
JPH_INLINE Vec4 SplatY() const
Replicate the Y component to all components.
Definition: Vec3.inl:540
static JPH_INLINE Vec3 sZero()
Vector with all zeros.
Definition: Vec3.inl:107
static JPH_INLINE UVec4 sLess(Vec3Arg inV1, Vec3Arg inV2)
Less than (component wise)
Definition: Vec3.inl:192
static JPH_INLINE Vec3 sReplicate(float inV)
Replicate inV across all components.
Definition: Vec3.inl:118
Definition: Vec4.h:14
static JPH_INLINE UVec4 sGreater(Vec4Arg inV1, Vec4Arg inV2)
Greater than (component wise)
Definition: Vec4.inl:208
static JPH_INLINE Vec4 sAnd(Vec4Arg inV1, Vec4Arg inV2)
Logical and (component wise)
Definition: Vec4.inl:290
static JPH_INLINE Vec4 sXor(Vec4Arg inV1, Vec4Arg inV2)
Logical xor (component wise)
Definition: Vec4.inl:279
static JPH_INLINE UVec4 sLess(Vec4Arg inV1, Vec4Arg inV2)
Less than (component wise)
Definition: Vec4.inl:180
static JPH_INLINE Vec4 sSelect(Vec4Arg inV1, Vec4Arg inV2, UVec4Arg inControl)
Component wise select, returns inV1 when highest bit of inControl = 0 and inV2 when highest bit of in...
Definition: Vec4.inl:254
static JPH_INLINE Vec4 sZero()
Vector with all zeros.
Definition: Vec4.inl:63
static JPH_INLINE Vec4 sReplicate(float inV)
Replicate inV across all components.
Definition: Vec4.inl:74