| 613 | } |
| 614 | |
| 615 | bool MeshAccelerationStructure::RayCast(const Ray& ray, Real& hitDistance, Vector3& hitNormal, Triangle& hitTriangle, Real maxDistance) const |
| 616 | { |
| 617 | hitDistance = maxDistance; |
| 618 | |
| 619 | // BVH |
| 620 | if (_bvh.Count() != 0) |
| 621 | { |
| 622 | return RayCastBVH(0, ray, hitDistance, hitNormal, hitTriangle); |
| 623 | } |
| 624 | |
| 625 | // Brute-force |
| 626 | { |
| 627 | Vector3 normal; |
| 628 | Real distance; |
| 629 | bool hit = false; |
| 630 | for (const Mesh& meshData : _meshes) |
| 631 | { |
| 632 | if (!meshData.Bounds.Intersects(ray)) |
| 633 | continue; |
| 634 | const Float3* vb = meshData.VertexBuffer.Get<Float3>(); |
| 635 | if (meshData.Use16BitIndexBuffer) |
| 636 | { |
| 637 | const uint16* ib16 = meshData.IndexBuffer.Get<uint16>(); |
| 638 | for (int32 i = 0; i < meshData.Indices;) |
| 639 | { |
| 640 | Vector3 v0 = vb[ib16[i++]]; |
| 641 | Vector3 v1 = vb[ib16[i++]]; |
| 642 | Vector3 v2 = vb[ib16[i++]]; |
| 643 | if (CollisionsHelper::RayIntersectsTriangle(ray, v0, v1, v2, distance, normal) && distance < hitDistance) |
| 644 | { |
| 645 | hitDistance = distance; |
| 646 | hitNormal = normal; |
| 647 | hitTriangle = Triangle(v0, v1, v2); |
| 648 | hit = true; |
| 649 | } |
| 650 | } |
| 651 | } |
| 652 | else |
| 653 | { |
| 654 | const uint32* ib32 = meshData.IndexBuffer.Get<uint32>(); |
| 655 | for (int32 i = 0; i < meshData.Indices;) |
| 656 | { |
| 657 | Vector3 v0 = vb[ib32[i++]]; |
| 658 | Vector3 v1 = vb[ib32[i++]]; |
| 659 | Vector3 v2 = vb[ib32[i++]]; |
| 660 | if (CollisionsHelper::RayIntersectsTriangle(ray, v0, v1, v2, distance, normal) && distance < hitDistance) |
| 661 | { |
| 662 | hitDistance = distance; |
| 663 | hitNormal = normal; |
| 664 | hitTriangle = Triangle(v0, v1, v2); |
| 665 | hit = true; |
| 666 | } |
| 667 | } |
| 668 | } |
| 669 | } |
| 670 | return hit; |
| 671 | } |
| 672 | } |
no test coverage detected