コード例 #1
0
    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);
    }
コード例 #2
0
    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);
    }