예제 #1
0
        public static List <Vector3> GenerateSphereBorderPoints(Camera camera, Vector3 sphereCenter, float sphereRadius, int numPoints)
        {
            if (numPoints < 3)
            {
                return(new List <Vector3>());
            }

            Transform      cameraTransform = camera.transform;
            List <Vector3> borderPoints    = Generate3DCircleBorderPoints(sphereCenter, sphereRadius, cameraTransform.right, cameraTransform.up, numPoints);

            for (int ptIndex = 0; ptIndex < numPoints; ++ptIndex)
            {
                Vector3 borderPt     = borderPoints[ptIndex];
                Vector3 borderNormal = (borderPt - sphereCenter).normalized;
                Vector3 cameraRay    = (borderPt - cameraTransform.position).normalized;
                if (camera.orthographic)
                {
                    cameraRay = cameraTransform.forward;
                }

                float dot = Vector3.Dot(borderNormal, cameraRay);
                if (Mathf.Abs(dot) > 1e-5f)
                {
                    float   angle        = MathEx.SafeAcos(dot) * Mathf.Rad2Deg;
                    Vector3 rotationAxis = Vector3.Cross(cameraRay, borderNormal).normalized;

                    Quaternion rotation = Quaternion.AngleAxis(90.0f - angle, rotationAxis);
                    borderNormal = (rotation * borderNormal).normalized;

                    borderPoints[ptIndex] = sphereCenter + borderNormal * sphereRadius;
                }
            }

            return(borderPoints);
        }
예제 #2
0
        public static List <Vector3> GenerateSphereBorderPoints(Camera camera, Vector3 sphereCenter, float sphereRadius, int numPoints)
        {
            if (numPoints < 3)
            {
                return(new List <Vector3>());
            }

            Transform      cameraTransform = camera.transform;
            Plane          cullPlane       = new Plane(cameraTransform.forward, cameraTransform.position);
            List <Vector3> borderPoints    = Generate3DCircleBorderPoints(sphereCenter, sphereRadius, cameraTransform.right, cameraTransform.up, numPoints);

            for (int ptIndex = 0; ptIndex < numPoints; ++ptIndex)
            {
                Vector3 borderPt     = borderPoints[ptIndex];
                Vector3 borderNormal = (borderPt - sphereCenter).normalized;
                Vector3 cameraRay    = (borderPt - cameraTransform.position).normalized;
                if (camera.orthographic)
                {
                    cameraRay = cameraTransform.forward;
                }

                float dot = Vector3.Dot(borderNormal, cameraRay);
                if (Mathf.Abs(dot) > 1e-5f)
                {
                    float   angle        = MathEx.SafeAcos(dot) * Mathf.Rad2Deg;
                    Vector3 rotationAxis = Vector3.Cross(cameraRay, borderNormal).normalized;

                    Quaternion rotation = Quaternion.AngleAxis(90.0f - angle, rotationAxis);
                    borderNormal          = (rotation * borderNormal).normalized;
                    borderPoints[ptIndex] = sphereCenter + borderNormal * sphereRadius;

                    // Note: Reject if any point lies behind the camera. In that case, we get
                    // invalid points when converted by the client in screen space.
                    if (cullPlane.GetDistanceToPoint(borderPoints[ptIndex]) < 0.0f)
                    {
                        return(new List <Vector3>());
                    }
                }
            }

            return(borderPoints);
        }
예제 #3
0
        public static Quaternion FromToRotation2D(Vector2 from, Vector2 to)
        {
            from = from.normalized;
            to   = to.normalized;

            float dot = Vector2.Dot(from, to);

            if (1.0f - dot < 1e-5f)
            {
                return(Quaternion.identity);
            }
            if (1.0f + dot < 1e-5f)
            {
                return(Quaternion.AngleAxis(180.0f, Vector3.forward));
            }

            float   angle        = MathEx.SafeAcos(dot) * Mathf.Rad2Deg;
            Vector3 rotationAxis = Vector3.Cross(from, to).normalized;

            return(Quaternion.AngleAxis(angle, rotationAxis));
        }
예제 #4
0
        // Unity versions below 2017 don't have Vector3.SignedAngle
        public static float SignedAngle(Vector3 from, Vector3 to, Vector3 axis)
        {
            float dot = Vector3.Dot(from.normalized, to.normalized);

            if ((1.0f - dot) < 1e-5f)
            {
                return(0.0f);
            }
            if ((1.0f + dot) < 1e-5f)
            {
                return(180.0f);
            }

            Vector3 cross = Vector3.Cross(from, to).normalized;
            float   angle = MathEx.SafeAcos(dot) * Mathf.Rad2Deg;

            if (Vector3.Dot(cross, axis) < 0.0f)
            {
                angle = -angle;
            }

            return(angle);
        }