MCPcopy Create free account
hub / github.com/DanielChappuis/reactphysics3d / raycast

Method raycast

src/collision/shapes/TriangleShape.cpp:143–214  ·  view source on GitHub ↗

Raycast method with feedback information This method use the line vs triangle raycasting technique described in Real-time Collision Detection by Christer Ericson.

Source from the content-addressed store, hash-verified

141/// This method use the line vs triangle raycasting technique described in
142/// Real-time Collision Detection by Christer Ericson.
143bool TriangleShape::raycast(const Ray& ray, RaycastInfo& raycastInfo, Collider* collider, MemoryAllocator& /*allocator*/) const {
144
145 RP3D_PROFILE("TriangleShape::raycast()", mProfiler);
146
147 const Vector3 pq = ray.point2 - ray.point1;
148 const Vector3 pa = mPoints[0] - ray.point1;
149 const Vector3 pb = mPoints[1] - ray.point1;
150 const Vector3 pc = mPoints[2] - ray.point1;
151
152 // Test if the line PQ is inside the eges BC, CA and AB. We use the triple
153 // product for this test.
154 const Vector3 m = pq.cross(pc);
155 decimal u = pb.dot(m);
156 if (mRaycastTestType == TriangleRaycastSide::FRONT) {
157 if (u < decimal(0.0)) return false;
158 }
159 else if (mRaycastTestType == TriangleRaycastSide::BACK) {
160 if (u > decimal(0.0)) return false;
161 }
162
163 decimal v = -pa.dot(m);
164 if (mRaycastTestType == TriangleRaycastSide::FRONT) {
165 if (v < decimal(0.0)) return false;
166 }
167 else if (mRaycastTestType == TriangleRaycastSide::BACK) {
168 if (v > decimal(0.0)) return false;
169 }
170 else if (mRaycastTestType == TriangleRaycastSide::FRONT_AND_BACK) {
171 if (!sameSign(u, v)) return false;
172 }
173
174 decimal w = pa.dot(pq.cross(pb));
175 if (mRaycastTestType == TriangleRaycastSide::FRONT) {
176 if (w < decimal(0.0)) return false;
177 }
178 else if (mRaycastTestType == TriangleRaycastSide::BACK) {
179 if (w > decimal(0.0)) return false;
180 }
181 else if (mRaycastTestType == TriangleRaycastSide::FRONT_AND_BACK) {
182 if (!sameSign(u, w)) return false;
183 }
184
185 // If the line PQ is in the triangle plane (case where u=v=w=0)
186 if (approxEqual(u, 0) && approxEqual(v, 0) && approxEqual(w, 0)) return false;
187
188 // Compute the barycentric coordinates (u, v, w) to determine the
189 // intersection point R, R = u * a + v * b + w * c
190 const decimal denom = decimal(1.0) / (u + v + w);
191 u *= denom;
192 v *= denom;
193 w *= denom;
194
195 // Compute the local hit point using the barycentric coordinates
196 const Vector3 localHitPoint = u * mPoints[0] + v * mPoints[1] + w * mPoints[2];
197 const Vector3 point1ToHitPoint = localHitPoint - ray.point1;
198 const decimal hitFraction = point1ToHitPoint.dot(pq) / pq.lengthSquare();
199
200 if (hitFraction < decimal(0.0) || hitFraction > ray.maxFraction) return false;

Callers

nothing calls this directly

Calls 7

sameSignFunction · 0.85
approxEqualFunction · 0.50
crossMethod · 0.45
dotMethod · 0.45
lengthSquareMethod · 0.45
normalizeMethod · 0.45
getBodyMethod · 0.45

Tested by

no test coverage detected