// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. using Microsoft.MixedReality.Toolkit.Utilities; using UnityEngine; namespace Microsoft.MixedReality.Toolkit { /// /// Extension methods for the Unity's Camera class /// public static class CameraExtensions { /// /// Get the horizontal FOV from the stereo camera in radians /// public static float GetHorizontalFieldOfViewRadians(this Camera camera) { return 2f * Mathf.Atan(Mathf.Tan(camera.fieldOfView * Mathf.Deg2Rad * 0.5f) * camera.aspect); } /// /// Get the horizontal FOV from the stereo camera in degrees /// public static float GetHorizontalFieldOfViewDegrees(this Camera camera) { return camera.GetHorizontalFieldOfViewRadians() * Mathf.Rad2Deg; } /// /// Returns if a point will be rendered on the screen in either eye /// /// The camera to check the point against public static bool IsInFOV(this Camera camera, Vector3 position) { Vector3 screenPoint = camera.WorldToViewportPoint(position); return screenPoint.z >= camera.nearClipPlane && screenPoint.z <= camera.farClipPlane && screenPoint.x >= 0 && screenPoint.x <= 1 && screenPoint.y >= 0 && screenPoint.y <= 1; } /// /// Returns true if a point is in the a cone inscribed into the Camera's frustum, false otherwise /// The cone is inscribed to a radius equal to the vertical height of the camera's FOV. /// By default, the cone's tip is "chopped off" by an amount defined by the camera's /// far and near clip planes. /// /// Point to test /// Degrees to expand the cone radius by. public static bool IsInFOVCone(this Camera camera, Vector3 point, float coneAngleBufferDegrees = 0) { return MathUtilities.IsInFOVCone(camera.transform, point, camera.fieldOfView + coneAngleBufferDegrees, camera.nearClipPlane, camera.farClipPlane ); } /// /// Gets the frustum size at a given distance from the camera. /// /// The camera to get the frustum size for /// The distance from the camera to get the frustum size at public static Vector2 GetFrustumSizeForDistance(this Camera camera, float distanceFromCamera) { Vector2 frustumSize = new Vector2 { y = 2.0f * distanceFromCamera * Mathf.Tan(camera.fieldOfView * 0.5f * Mathf.Deg2Rad) }; frustumSize.x = frustumSize.y * camera.aspect; return frustumSize; } /// /// Gets the distance to the camera that a specific frustum height would be at. /// /// The camera to get the distance from /// The frustum height public static float GetDistanceForFrustumHeight(this Camera camera, float frustumHeight) { return frustumHeight * 0.5f / Mathf.Max(0.00001f, Mathf.Tan(camera.fieldOfView * 0.5f * Mathf.Deg2Rad)); } } }