Created
December 2, 2020 23:20
-
-
Save StagPoint/341a2da4c63c3c80bbee2e94773e172d to your computer and use it in GitHub Desktop.
Small collection of utility functions for calculating screen size of objects, size of camera frustum at a distance, etc.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Runtime.InteropServices; | |
using System.Runtime.CompilerServices; | |
using Unity.Burst; | |
using Unity.Mathematics; | |
public static class CameraMath | |
{ | |
/// <summary> | |
/// Get the screen size of an object in pixels, given its distance and diameter. | |
/// </summary> | |
/// <param name="distance">The distance from the desired camera to the object</param> | |
/// <param name="diameter">The diameter of the object's bounding sphere</param> | |
/// <param name="screenHeight">The height of the screen, in pixels</param> | |
/// <param name="fieldOfView">The Field of View (in degrees) of the desired camera</param> | |
[MethodImpl( MethodImplOptions.AggressiveInlining )] | |
public static float DistanceAndDiameterToPixelSize( float distance, float diameter, float screenHeight, float fieldOfView ) | |
{ | |
return math.degrees( diameter * screenHeight ) / ( distance * fieldOfView ); | |
} | |
/// <summary> | |
/// Get the distance of an object, given its screen size in pixels and diameter. | |
/// </summary> | |
/// <param name="pixelSize">The size (in screen pixels) of the object</param> | |
/// <param name="diameter">The actual diameter of the object's bounding sphere</param> | |
/// <param name="screenHeight">The height of the screen, in pixels</param> | |
/// <param name="fieldOfView">The Field of View (in degrees) of the desired camera</param> | |
[MethodImpl( MethodImplOptions.AggressiveInlining )] | |
public static float PixelSizeAndDiameterToDistance( float pixelSize, float diameter, float screenHeight, float fieldOfView ) | |
{ | |
return math.degrees( diameter * screenHeight ) / ( pixelSize * fieldOfView ); | |
} | |
/// <summary> | |
/// Returns the calculated diameter of an object, given its screen size in pixels and distance. | |
/// </summary> | |
/// <param name="pixelSize">The size (in screen pixels) of the object</param> | |
/// <param name="distance">The distance from the desired camera to the object</param> | |
/// <param name="screenHeight">The height of the screen, in pixels</param> | |
/// <param name="fieldOfView">The Field of View (in degrees) of the desired camera</param> | |
[MethodImpl( MethodImplOptions.AggressiveInlining )] | |
public static float PixelSizeAndDistanceToDiameter( float pixelSize, float distance, float screenHeight, float fieldOfView ) | |
{ | |
float diameter = ( pixelSize * distance * fieldOfView ) / math.degrees( screenHeight ); | |
return diameter; | |
} | |
/// <summary> | |
/// Returns the distance required to give a specified frustum height at the given Field of View. | |
/// </summary> | |
/// <param name="frustumHeight">The diameter of the object's bounding sphere</param> | |
/// <param name="fieldOfView">The Field of View (in degrees) of the desired camera</param> | |
[MethodImpl( MethodImplOptions.AggressiveInlining )] | |
public static float DistanceForFrustumHeight( float frustumHeight, float fieldOfView ) | |
{ | |
float cameraView = math.tan( math.radians( fieldOfView * 0.5f ) ); | |
float distance = ( frustumHeight * 0.5f ) / cameraView; | |
return distance; | |
} | |
/// <summary> | |
/// Returns the height of the frustum at a given distance. | |
/// </summary> | |
[MethodImpl( MethodImplOptions.AggressiveInlining )] | |
public static float FrustumHeightAtDistance( float distance, float fieldOfView ) | |
{ | |
return 2.0f * distance * math.tan( math.radians( fieldOfView * 0.5f ) ); | |
} | |
/// <summary> | |
/// Returns the field of view when the distance and height are known. | |
/// </summary> | |
/// <param name="distance">Distance from camera to target position</param> | |
/// <param name="height">Height of target</param> | |
/// <returns></returns> | |
[MethodImpl( MethodImplOptions.AggressiveInlining )] | |
public static float FieldOfViewFromDistanceAndHeight( float distance, float height ) | |
{ | |
return 2.0f * math.degrees( math.atan( height * 0.5f / distance ) ); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment