rj-action-library/Runtime/Godot/Cameras.cs

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;
}
}
}