mirror of
https://github.com/sampletext32/ParkanPlayground.git
synced 2026-08-15 02:57:49 +04:00
qol
This commit is contained in:
@@ -4,31 +4,104 @@ namespace NResUI.Rendering.Viewport;
|
||||
|
||||
public sealed class ViewportCamera
|
||||
{
|
||||
public const float FieldOfViewDegrees = 60.0f;
|
||||
|
||||
public float YawDegrees { get; set; } = 35.0f;
|
||||
public float PitchDegrees { get; set; } = 25.0f;
|
||||
public float Distance { get; set; } = 4.0f;
|
||||
public Vector3 Target { get; set; } = Vector3.Zero;
|
||||
|
||||
public Matrix4x4 GetSceneRotationMatrix()
|
||||
{
|
||||
return Matrix4x4.CreateRotationY(ToRadians(YawDegrees)) *
|
||||
Matrix4x4.CreateRotationX(ToRadians(PitchDegrees));
|
||||
// Kept as an explicit hook for future scene-wide transforms.
|
||||
// Camera orbit is handled by GetViewMatrix().
|
||||
return Matrix4x4.Identity;
|
||||
}
|
||||
|
||||
public Matrix4x4 GetViewMatrix()
|
||||
{
|
||||
return Matrix4x4.CreateLookAt(
|
||||
new Vector3(0.0f, 0.0f, Distance),
|
||||
Vector3.Zero,
|
||||
Vector3.UnitY);
|
||||
return Matrix4x4.CreateLookAt(GetEyePosition(), Target, Vector3.UnitY);
|
||||
}
|
||||
|
||||
public Matrix4x4 GetProjectionMatrix(float aspectRatio)
|
||||
{
|
||||
return Matrix4x4.CreatePerspectiveFieldOfView(
|
||||
ToRadians(60.0f),
|
||||
ToRadians(FieldOfViewDegrees),
|
||||
aspectRatio,
|
||||
0.01f,
|
||||
100.0f);
|
||||
1000.0f);
|
||||
}
|
||||
|
||||
public Vector3 GetEyePosition()
|
||||
{
|
||||
return Target + GetOrbitDirection() * Distance;
|
||||
}
|
||||
|
||||
public Vector3 GetForwardDirection()
|
||||
{
|
||||
return Vector3.Normalize(Target - GetEyePosition());
|
||||
}
|
||||
|
||||
public Vector3 GetRightDirection()
|
||||
{
|
||||
var forward = GetForwardDirection();
|
||||
var right = Vector3.Cross(forward, Vector3.UnitY);
|
||||
|
||||
if (right.LengthSquared() < 1e-8f)
|
||||
return Vector3.UnitX;
|
||||
|
||||
return Vector3.Normalize(right);
|
||||
}
|
||||
|
||||
public Vector3 GetUpDirection()
|
||||
{
|
||||
var right = GetRightDirection();
|
||||
var forward = GetForwardDirection();
|
||||
return Vector3.Normalize(Vector3.Cross(right, forward));
|
||||
}
|
||||
|
||||
public void Pan(Vector2 mouseDelta, Vector2 viewportSize)
|
||||
{
|
||||
if (viewportSize.Y <= 1.0f)
|
||||
return;
|
||||
|
||||
var worldUnitsPerPixel = 2.0f * Distance * MathF.Tan(ToRadians(FieldOfViewDegrees) * 0.5f) / viewportSize.Y;
|
||||
var right = GetRightDirection();
|
||||
var up = GetUpDirection();
|
||||
|
||||
Target -= right * (mouseDelta.X * worldUnitsPerPixel);
|
||||
Target += up * (mouseDelta.Y * worldUnitsPerPixel);
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
YawDegrees = 35.0f;
|
||||
PitchDegrees = 25.0f;
|
||||
Distance = 4.0f;
|
||||
Target = Vector3.Zero;
|
||||
}
|
||||
|
||||
public void FrameBounds(Vector3 boundsMin, Vector3 boundsMax)
|
||||
{
|
||||
var center = (boundsMin + boundsMax) * 0.5f;
|
||||
var extents = (boundsMax - boundsMin) * 0.5f;
|
||||
var radius = MathF.Max(extents.Length(), 0.25f);
|
||||
|
||||
Target = center;
|
||||
Distance = Math.Clamp(radius * 2.8f, 1.5f, 200.0f);
|
||||
}
|
||||
|
||||
private Vector3 GetOrbitDirection()
|
||||
{
|
||||
var yaw = ToRadians(YawDegrees);
|
||||
var pitch = ToRadians(PitchDegrees);
|
||||
|
||||
var cosPitch = MathF.Cos(pitch);
|
||||
|
||||
return Vector3.Normalize(new Vector3(
|
||||
MathF.Sin(yaw) * cosPitch,
|
||||
MathF.Sin(pitch),
|
||||
MathF.Cos(yaw) * cosPitch));
|
||||
}
|
||||
|
||||
public static float ToRadians(float degrees)
|
||||
|
||||
Reference in New Issue
Block a user