bool RayAABBIntersection(ref MonoRay _ray, MonoBox _box, out Vector3 _hitpoint) { _hitpoint = Vector3.zero; if (_ray == null || _box == null) { return(false); } Vector3 minP = _box.Center - b.AABBSize * 0.5f; Vector3 maxP = _box.Center + b.AABBSize * 0.5f; float tMin = (minP.x - _ray.Origin.x) / _ray.Direction.x; float tMax = (maxP.x - _ray.Origin.x) / _ray.Direction.x; if (tMax < tMin) { Swap(ref tMin, ref tMax); } float tyMin = (minP.y - _ray.Origin.y) / _ray.Direction.y; float tyMax = (maxP.y - _ray.Origin.y) / _ray.Direction.y; if (tyMax < tyMin) { Swap(ref tyMin, ref tyMax); } if (tMin > tyMax || tyMin > tMax) { return(false); } if (tyMin > tMin) { tMin = tyMin; } if (tyMax < tMax) { tMax = tyMax; } float tzMin = (minP.z - _ray.Origin.z) / _ray.Direction.z; float tzMax = (maxP.z - _ray.Origin.z) / _ray.Direction.z; if (tzMax < tzMin) { Swap(ref tzMin, ref tzMax); } if (tMin > tzMax || tzMin > tMax) { return(false); } if (tzMin > tMin) { tMin = tzMin; } if (tzMax < tMax) { tMax = tzMax; } _ray.tMin = tMin; _ray.tMax = tMax; _hitpoint = _ray.GetPointOnRay(tMin); return(true); }
bool CheckEdgeCase(MonoRay _ray, MonoBox _box, ref Vector3 _hitpoint, out bool _hitEdgeCapsule) { //Check if we are closer than radius to any corner float t = 0; bool hitEdgeCapsule = false; //Upper Edges float closestDistance = Mathf.Infinity; float distance = DistancePointEdge(_hitpoint, _box.AABBCorners[0], _box.AABBCorners[1]); if (distance < closestDistance) { closestDistance = distance; } if (distance <= _box.AABBRadius) { if (RayCapsuleIntersection(_ray, _box.Corners[0], _box.Corners[1], _box.AABBRadius, out t)) { hitEdgeCapsule = true; } } distance = DistancePointEdge(_hitpoint, _box.AABBCorners[0], _box.AABBCorners[2]); if (distance < closestDistance) { closestDistance = distance; } if (!hitEdgeCapsule && distance <= _box.AABBRadius) { if (RayCapsuleIntersection(_ray, _box.Corners[0], _box.Corners[2], _box.AABBRadius, out t)) { hitEdgeCapsule = true; } } distance = DistancePointEdge(_hitpoint, _box.AABBCorners[3], _box.AABBCorners[1]); if (distance < closestDistance) { closestDistance = distance; } if (!hitEdgeCapsule && distance <= _box.AABBRadius) { if (RayCapsuleIntersection(_ray, _box.Corners[3], _box.Corners[1], _box.AABBRadius, out t)) { hitEdgeCapsule = true; } } distance = DistancePointEdge(_hitpoint, _box.AABBCorners[3], _box.AABBCorners[2]); if (distance < closestDistance) { closestDistance = distance; } if (!hitEdgeCapsule && distance <= _box.AABBRadius) { if (RayCapsuleIntersection(_ray, _box.Corners[3], _box.Corners[2], _box.AABBRadius, out t)) { hitEdgeCapsule = true; } } //Lower Edges distance = DistancePointEdge(_hitpoint, _box.AABBCorners[4], _box.AABBCorners[5]); if (distance < closestDistance) { closestDistance = distance; } if (!hitEdgeCapsule && distance <= _box.AABBRadius) { if (RayCapsuleIntersection(_ray, _box.Corners[4], _box.Corners[5], _box.AABBRadius, out t)) { hitEdgeCapsule = true; } } distance = DistancePointEdge(_hitpoint, _box.AABBCorners[4], _box.AABBCorners[6]); if (distance < closestDistance) { closestDistance = distance; } if (!hitEdgeCapsule && distance <= _box.AABBRadius) { if (RayCapsuleIntersection(_ray, _box.Corners[4], _box.Corners[6], _box.AABBRadius, out t)) { hitEdgeCapsule = true; } } distance = DistancePointEdge(_hitpoint, _box.AABBCorners[7], _box.AABBCorners[5]); if (distance < closestDistance) { closestDistance = distance; } if (!hitEdgeCapsule && distance <= _box.AABBRadius) { if (RayCapsuleIntersection(_ray, _box.Corners[7], _box.Corners[5], _box.AABBRadius, out t)) { hitEdgeCapsule = true; } } distance = DistancePointEdge(_hitpoint, _box.AABBCorners[7], _box.AABBCorners[6]); if (distance < closestDistance) { closestDistance = distance; } if (!hitEdgeCapsule && distance <= _box.AABBRadius) { if (RayCapsuleIntersection(_ray, _box.Corners[7], _box.Corners[6], _box.AABBRadius, out t)) { hitEdgeCapsule = true; } } //Standing Edges distance = DistancePointEdge(_hitpoint, _box.AABBCorners[0], _box.AABBCorners[4]); if (distance < closestDistance) { closestDistance = distance; } if (!hitEdgeCapsule && distance <= _box.AABBRadius) { if (RayCapsuleIntersection(_ray, _box.Corners[0], _box.Corners[4], _box.AABBRadius, out t)) { hitEdgeCapsule = true; } } distance = DistancePointEdge(_hitpoint, _box.AABBCorners[1], _box.AABBCorners[5]); if (distance < closestDistance) { closestDistance = distance; } if (!hitEdgeCapsule && distance <= _box.AABBRadius) { if (RayCapsuleIntersection(_ray, _box.Corners[1], _box.Corners[5], _box.AABBRadius, out t)) { hitEdgeCapsule = true; } } distance = DistancePointEdge(_hitpoint, _box.AABBCorners[2], _box.AABBCorners[6]); if (distance < closestDistance) { closestDistance = distance; } if (!hitEdgeCapsule && distance <= _box.AABBRadius) { if (RayCapsuleIntersection(_ray, _box.Corners[2], _box.Corners[6], _box.AABBRadius, out t)) { hitEdgeCapsule = true; } } distance = DistancePointEdge(_hitpoint, _box.AABBCorners[3], _box.AABBCorners[7]); if (distance < closestDistance) { closestDistance = distance; } if (!hitEdgeCapsule && distance <= _box.AABBRadius) { Debug.Log("Closest to capsule 3|7"); if (RayCapsuleIntersection(_ray, _box.Corners[3], _box.Corners[7], _box.AABBRadius, out t)) { hitEdgeCapsule = true; } } debugText.text = ("Closest Dist:" + closestDistance + "/" + _box.AABBRadius + "|" + hitEdgeCapsule); if (hitEdgeCapsule) { hitpoint = _ray.GetPointOnRay(t); } _hitEdgeCapsule = hitEdgeCapsule; //Tell me if this was an edgecase return(closestDistance <= _box.AABBRadius); }