119 lines
3.6 KiB
C#
119 lines
3.6 KiB
C#
using Godot;
|
|
using System.Text;
|
|
using System.Collections.Generic;
|
|
|
|
namespace Rokojori
|
|
{
|
|
public class Cameras
|
|
{
|
|
public static float ComputeCameraFrameFittingDistance( Camera3D camera, float radius )
|
|
{
|
|
var fovRadians = Mathf.DegToRad( camera.Fov );
|
|
return ( radius * 2 ) / Mathf.Tan( fovRadians / 2.0f );
|
|
}
|
|
|
|
public static float ComputeCameraFrameFittingDistance( float fovDegrees, float radius )
|
|
{
|
|
var fovRadians = Mathf.DegToRad( fovDegrees );
|
|
return ( radius * 2 ) / Mathf.Tan( fovRadians / 2.0f );
|
|
}
|
|
|
|
public static float ComputeCameraFittingScale( float fovDegrees, float distance )
|
|
{
|
|
var fovRadians = Mathf.DegToRad( fovDegrees );
|
|
return distance / ( 0.5f / Mathf.Tan( fovRadians / 2.0f ) );
|
|
}
|
|
|
|
public static float ComputeFOVForBillboard( float fovDegrees, float radius, float placingDistance )
|
|
{
|
|
var fovRadians = Mathf.DegToRad( fovDegrees );
|
|
var d = ( radius * Mathf.Tan( fovRadians / 2f ) ) / placingDistance;
|
|
var rads = 2f * Mathf.Atan( d );
|
|
|
|
return Mathf.RadToDeg( rads );
|
|
}
|
|
|
|
public static float ComputePixelDensityVertical( float fovDegrees, float distance, Vector2 screenSize )
|
|
{
|
|
float fovRadians = Mathf.DegToRad( fovDegrees );
|
|
|
|
float verticalViewSize = 2.0f * distance * Mathf.Tan( fovRadians / 2.0f );
|
|
|
|
float screenHeightPixels = screenSize.Y;
|
|
|
|
float pixelDensity = screenHeightPixels / verticalViewSize;
|
|
|
|
return pixelDensity;
|
|
}
|
|
|
|
public static float ComputeSizeOfPixelVertical( float fovDegrees, float distance, Vector2 screenSize )
|
|
{
|
|
return ComputePixelDensityVertical( fovDegrees, distance, screenSize );
|
|
}
|
|
|
|
|
|
public static float ComputePixelDistanceForSizeVertical( float fovDegrees, float size, Vector2 screenSize )
|
|
{
|
|
float fovRadians = Mathf.DegToRad(fovDegrees);
|
|
float screenHeightPixels = screenSize.Y;
|
|
|
|
float pixelDensity = 1.0f / size;
|
|
|
|
float distance = screenHeightPixels / (2.0f * pixelDensity * Mathf.Tan(fovRadians / 2.0f));
|
|
|
|
return distance;
|
|
|
|
}
|
|
|
|
public static float ComputePixelDensityHorizontal(float fovDegrees, float distance, Vector2 screenSize)
|
|
{
|
|
float aspectRatio = screenSize.X / screenSize.Y;
|
|
|
|
float verticalFovRad = Mathf.DegToRad( fovDegrees );
|
|
|
|
float horizontalFovRad = 2.0f * Mathf.Atan(Mathf.Tan( verticalFovRad / 2.0f ) * aspectRatio);
|
|
|
|
float horizontalViewSize = 2.0f * distance * Mathf.Tan( horizontalFovRad / 2.0f );
|
|
|
|
float pixelDensity = screenSize.X / horizontalViewSize;
|
|
|
|
return pixelDensity;
|
|
}
|
|
|
|
public static Vector3 GlobalToView( Transform3D transform, Vector3 globalPosition )
|
|
{
|
|
return globalPosition * transform;
|
|
}
|
|
|
|
public static Vector3 ViewToClip( Projection cameraProjection, Vector3 viewPosition )
|
|
{
|
|
var clip = cameraProjection * viewPosition;
|
|
return clip;
|
|
}
|
|
|
|
public static Vector2 ClipToScreen( Vector3 clipPosition )
|
|
{
|
|
var size = Vector2.One;
|
|
var clip = clipPosition.XY() * 0.5f + new Vector2( 0.5f, 0.5f );
|
|
return clip * size;
|
|
}
|
|
|
|
public static Vector2 ClipToScreen( Vector3 clipPosition, Vector2 screenPixelSize )
|
|
{
|
|
var clip = clipPosition.XY() * 0.5f + new Vector2( 0.5f, 0.5f );
|
|
return clip * screenPixelSize;
|
|
}
|
|
|
|
|
|
public static Vector2 GlobalToScreen( Vector3 globalPosition, Transform3D cameraTransform, Projection cameraProjection, Vector2 screenPixelSize )
|
|
{
|
|
var view = GlobalToView( cameraTransform, globalPosition );
|
|
var clip = ViewToClip( cameraProjection, view );
|
|
var screen = ClipToScreen( clip, screenPixelSize );
|
|
|
|
return screen;
|
|
}
|
|
|
|
|
|
}
|
|
} |