Raycast method with feedback information This method use the line vs triangle raycasting technique described in Real-time Collision Detection by Christer Ericson.
| 141 | /// This method use the line vs triangle raycasting technique described in |
| 142 | /// Real-time Collision Detection by Christer Ericson. |
| 143 | bool 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; |
nothing calls this directly
no test coverage detected