170 lines
3.3 KiB
C#
170 lines
3.3 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using Godot;
|
|
using System;
|
|
|
|
|
|
|
|
namespace Rokojori
|
|
{
|
|
[Tool]
|
|
[GlobalClass]
|
|
public partial class Baker:Node
|
|
{
|
|
public enum CameraDistanceDetectionType
|
|
{
|
|
Automatic_Distance_Detection,
|
|
Custom_Distance
|
|
}
|
|
|
|
public enum CameraFOVMode
|
|
{
|
|
Keep_Fov,
|
|
Compute_Fov_With_Distance,
|
|
Custom_Fov
|
|
}
|
|
|
|
public enum MeshMode
|
|
{
|
|
World_Scale,
|
|
Custom_Scale
|
|
}
|
|
|
|
[Export]
|
|
public bool update = false;
|
|
|
|
[Export]
|
|
public bool updateAlways = false;
|
|
|
|
[Export]
|
|
public Viewport viewport;
|
|
|
|
[Export]
|
|
public Node3D target;
|
|
|
|
[Export]
|
|
public Camera3D camera;
|
|
|
|
|
|
[Export]
|
|
public float originalFOV = 75;
|
|
|
|
|
|
[Export]
|
|
public bool assignFOV = false;
|
|
|
|
[Export]
|
|
public float placingDistance = 500;
|
|
|
|
[Export]
|
|
public float computedFOV = 75;
|
|
|
|
[Export]
|
|
public bool useCustomFOV = false;
|
|
|
|
[Export]
|
|
public float customFOV = 75;
|
|
|
|
[Export]
|
|
public bool useCustomDistance = false;
|
|
|
|
[Export]
|
|
public float customDistance = 50;
|
|
|
|
[Export]
|
|
public float outputScale = 1;
|
|
|
|
[Export]
|
|
public Node3D outputTexture;
|
|
|
|
[Export]
|
|
public float outputTextureSize = 1;
|
|
|
|
[Export( PropertyHint.Range, "-180,180")]
|
|
public float yaw = 0;
|
|
|
|
[Export( PropertyHint.Range, "-180,180")]
|
|
public float pitch = 0;
|
|
|
|
public Quaternion bakingRotation => Math3D.YawPitchRotation( yaw, pitch );
|
|
|
|
[Export]
|
|
public float zoom = 1;
|
|
|
|
[Export]
|
|
public float distance = 1;
|
|
|
|
public override void _Process( double delta )
|
|
{
|
|
if ( ! ( update || updateAlways ) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
update = false;
|
|
|
|
Bake();
|
|
|
|
}
|
|
|
|
void Bake()
|
|
{
|
|
if ( viewport == null || target == null || camera == null )
|
|
{
|
|
return;
|
|
}
|
|
|
|
var box = target.GetWorldBounds();
|
|
|
|
if ( box == null )
|
|
{
|
|
RJLog.Log( "No target" );
|
|
return;
|
|
}
|
|
|
|
var sphere = Sphere.ContainingBox( box );
|
|
camera.Fov = originalFOV;
|
|
|
|
var billboardFOV = camera.Fov;
|
|
|
|
|
|
if ( assignFOV )
|
|
{
|
|
computedFOV = Cameras.ComputeFOVForBillboard( originalFOV, sphere.radius, placingDistance );
|
|
billboardFOV = computedFOV;
|
|
camera.Fov = billboardFOV;
|
|
}
|
|
|
|
if ( useCustomFOV )
|
|
{
|
|
billboardFOV = customFOV;
|
|
camera.Fov = billboardFOV;
|
|
}
|
|
|
|
var newDistance = useCustomDistance ? customDistance : Cameras.ComputeCameraFrameFittingDistance( billboardFOV, sphere.radius / zoom );
|
|
|
|
if ( newDistance != distance )
|
|
{
|
|
distance = newDistance;
|
|
RJLog.Log( "New Distance:", box, sphere, distance );
|
|
}
|
|
|
|
var cameraRotation = Math3D.RotateXDegrees( pitch ) * Math3D.RotateYDegrees( yaw );
|
|
var offset = ( Vector3.Back * distance ) * cameraRotation ;
|
|
camera.GlobalPosition = target.GlobalPosition + offset;
|
|
|
|
camera.SetGlobalQuaternion( cameraRotation.Inverse() );
|
|
|
|
RJLog.Log( "Set Rotation", cameraRotation, ">>", camera.GetGlobalQuaternion() );
|
|
|
|
outputScale = Cameras.ComputeCameraFittingScale( camera.Fov, distance );
|
|
|
|
if ( outputTexture != null )
|
|
{
|
|
outputTexture.Scale = Vector3.One * outputScale;
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|