Raycast method with feedback information Note that only the first triangle hit by the ray in the mesh will be returned, even if the ray hits many triangles.
| 256 | /// Note that only the first triangle hit by the ray in the mesh will be returned, even if |
| 257 | /// the ray hits many triangles. |
| 258 | bool HeightField::raycast(const Ray& ray, RaycastInfo& raycastInfo, Collider* collider, TriangleRaycastSide testSide, |
| 259 | MemoryAllocator& allocator, const Vector3& scale) const { |
| 260 | |
| 261 | RP3D_PROFILE("HeightField::raycast()", mProfiler); |
| 262 | |
| 263 | bool isHit = false; |
| 264 | |
| 265 | // Compute the grid coordinates where the ray is entering the AABB of the height field |
| 266 | int32 i, j; |
| 267 | Vector3 outHitGridPoint; |
| 268 | if (computeEnteringRayGridCoordinates(ray, i, j, outHitGridPoint)) { |
| 269 | |
| 270 | const int32 nbCellsI = mNbColumns - 1; |
| 271 | const int32 nbCellsJ = mNbRows - 1; |
| 272 | |
| 273 | const Vector3 aabbSize = mBounds.getExtent(); |
| 274 | |
| 275 | const Vector3 rayDirection = ray.point2 - ray.point1; |
| 276 | |
| 277 | int32 stepI = rayDirection.x > 0 ? 1 : (rayDirection.x < 0 ? -1 : 0); |
| 278 | int32 stepJ = rayDirection.z > 0 ? 1 : (rayDirection.z < 0 ? -1 : 0); |
| 279 | decimal nextI = static_cast<decimal>(stepI >= 0 ? i + 1 : i); |
| 280 | decimal nextJ = static_cast<decimal>(stepJ >= 0 ? j + 1 : j); |
| 281 | decimal sizeI = aabbSize.x / nbCellsI; |
| 282 | decimal sizeJ = aabbSize.z / nbCellsJ; |
| 283 | decimal tMaxI = ((nextI * sizeI) - outHitGridPoint.x) / rayDirection.x; |
| 284 | decimal tMaxJ = ((nextJ * sizeJ) - outHitGridPoint.z) / rayDirection.z; |
| 285 | decimal tDeltaI = sizeI / std::abs(rayDirection.x); |
| 286 | decimal tDeltaJ = sizeJ / std::abs(rayDirection.z); |
| 287 | |
| 288 | decimal smallestHitFraction = ray.maxFraction; |
| 289 | |
| 290 | while (i >= 0 && i < nbCellsI && j >= 0 && j < nbCellsJ) { |
| 291 | |
| 292 | // Compute the four point of the current quad |
| 293 | const Vector3 p1 = getVertexAt(i, j) * scale; |
| 294 | const Vector3 p2 = getVertexAt(i, j + 1) * scale; |
| 295 | const Vector3 p3 = getVertexAt(i + 1, j) * scale; |
| 296 | const Vector3 p4 = getVertexAt(i + 1, j + 1) * scale; |
| 297 | |
| 298 | // Raycast against the first triangle of the cell |
| 299 | uint32 shapeId = computeTriangleShapeId(i, j, 0); |
| 300 | isHit |= raycastTriangle(ray, p1, p2, p3, shapeId, collider, raycastInfo, smallestHitFraction, testSide, allocator); |
| 301 | |
| 302 | // Raycast against the second triangle of the cell |
| 303 | shapeId = computeTriangleShapeId(i, j, 1); |
| 304 | isHit |= raycastTriangle(ray, p3, p2, p4, shapeId, collider, raycastInfo, smallestHitFraction, testSide, allocator); |
| 305 | |
| 306 | if (stepI == 0 && stepJ == 0) break; |
| 307 | |
| 308 | if (tMaxI < tMaxJ) { |
| 309 | tMaxI += tDeltaI; |
| 310 | i += stepI; |
| 311 | } |
| 312 | else { |
| 313 | tMaxJ += tDeltaJ; |
| 314 | j += stepJ; |
| 315 | } |
no test coverage detected