public override bool Raycast(Ray ray, out float t)
 {
     if (_raycastMode == Shape3DRaycastMode.Solid)
     {
         return(QuadMath.Raycast(ray, out t, _center, _size.x, _size.y, Right, Up, _epsilon));
     }
     else
     {
         return(RaycastWire(ray, out t));
     }
 }
예제 #2
0
        public static bool Raycast(Ray ray, out float t, Vector3 boxCenter, Vector3 boxSize, Quaternion boxRotation, BoxEpsilon epsilon = new BoxEpsilon())
        {
            t        = 0.0f;
            boxSize += epsilon.SizeEps;

            const float minBoxSize         = 1e-6f;
            int         invalidSizeCounter = 0;

            if (boxSize.x < minBoxSize)
            {
                ++invalidSizeCounter;
            }
            if (boxSize.y < minBoxSize)
            {
                ++invalidSizeCounter;
            }
            if (boxSize.z < minBoxSize)
            {
                ++invalidSizeCounter;
            }
            if (invalidSizeCounter > 1)
            {
                return(false);
            }

            if (invalidSizeCounter == 1)
            {
                if (boxSize.x < minBoxSize)
                {
                    Vector3 quadRight = boxRotation * Vector3.forward;
                    Vector3 quadUp    = boxRotation * Vector3.up;
                    return(QuadMath.Raycast(ray, out t, boxCenter, boxSize.z, boxSize.y, quadRight, quadUp));
                }
                else
                if (boxSize.y < minBoxSize)
                {
                    Vector3 quadRight = boxRotation * Vector3.right;
                    Vector3 quadUp    = boxRotation * Vector3.forward;
                    return(QuadMath.Raycast(ray, out t, boxCenter, boxSize.x, boxSize.z, quadRight, quadUp));
                }
                else
                {
                    Vector3 quadRight = boxRotation * Vector3.right;
                    Vector3 quadUp    = boxRotation * Vector3.up;
                    return(QuadMath.Raycast(ray, out t, boxCenter, boxSize.x, boxSize.y, quadRight, quadUp));
                }
            }

            Matrix4x4 boxMatrix = Matrix4x4.TRS(boxCenter, boxRotation, boxSize);
            Ray       modelRay  = ray.InverseTransform(boxMatrix);

            if (modelRay.direction.sqrMagnitude == 0.0f)
            {
                return(false);
            }

            Bounds unitCube = new Bounds(Vector3.zero, Vector3.one);

            if (unitCube.IntersectRay(modelRay, out t))
            {
                Vector3 intersectPt = boxMatrix.MultiplyPoint(modelRay.GetPoint(t));
                t = (intersectPt - ray.origin).magnitude;
                return(true);
            }

            return(false);

            /*t = 0.0f;
             * boxSize += epsilon.SizeEps;
             *
             * Matrix4x4 boxMatrix = Matrix4x4.TRS(boxCenter, boxRotation, boxSize);
             * Ray modelRay = ray.InverseTransform(boxMatrix);
             * if (modelRay.direction.sqrMagnitude == 0.0f) return false;
             *
             * Vector3 rayOrigin = modelRay.origin;
             * Vector3 rayDirection = modelRay.direction;
             * Vector3 rayDirectionRec = new Vector3(1.0f / rayDirection.x, 1.0f / rayDirection.y, 1.0f / rayDirection.z);
             *
             * float halfBoxWidth = 0.5f;
             * float halfBoxHeight = 0.5f;
             * float halfBoxDepth = 0.5f;
             *
             * Vector3 boxExtentsMin = new Vector3(-halfBoxWidth, -halfBoxHeight, -halfBoxDepth);
             * Vector3 boxExtentsMax = new Vector3(halfBoxWidth, halfBoxHeight, halfBoxDepth);
             *
             * float highestMinimumT = float.MinValue;
             * float lowestMaximumT = float.MaxValue;
             *
             * for (int slabIndex = 0; slabIndex < 3; ++slabIndex)
             * {
             *  if (Mathf.Abs(rayDirection[slabIndex]) > 1e-4f)
             *  {
             *      float minimumT = (boxExtentsMin[slabIndex] - rayOrigin[slabIndex]) * rayDirectionRec[slabIndex];
             *      float maximumT = (boxExtentsMax[slabIndex] - rayOrigin[slabIndex]) * rayDirectionRec[slabIndex];
             *
             *      if (minimumT > maximumT)
             *      {
             *          float temp = minimumT;
             *          minimumT = maximumT;
             *          maximumT = temp;
             *      }
             *
             *      if (minimumT > highestMinimumT) highestMinimumT = minimumT;
             *      if (maximumT < lowestMaximumT) lowestMaximumT = maximumT;
             *
             *      if (highestMinimumT > lowestMaximumT) return false;
             *      if (lowestMaximumT < 0.0f) return false;
             *  }
             *  else
             *  {
             *      if (rayOrigin[slabIndex] < boxExtentsMin[slabIndex] ||
             *          rayOrigin[slabIndex] > boxExtentsMax[slabIndex]) return false;
             *  }
             * }
             *
             * t = highestMinimumT;
             * if (t < 0.0f) t = lowestMaximumT;
             *
             * return true;*/
        }