187 lines
3.6 KiB
C#
187 lines
3.6 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;
|
|
|
|
public enum RotationMode
|
|
{
|
|
Yaw_Pitch,
|
|
Quaternion
|
|
}
|
|
|
|
[ExportGroup("Rotation")]
|
|
|
|
[Export]
|
|
public RotationMode rotationMode = RotationMode.Yaw_Pitch;
|
|
|
|
[Export( PropertyHint.Range, "-180,180")]
|
|
public float yaw = 0;
|
|
|
|
[Export( PropertyHint.Range, "-180,180")]
|
|
public float pitch = 0;
|
|
|
|
[Export]
|
|
public Quaternion rotationQuaternion;
|
|
|
|
|
|
public Quaternion bakingRotation => RotationMode.Yaw_Pitch == rotationMode ?
|
|
Math3D.YawPitchRotation( yaw, pitch ) :
|
|
rotationQuaternion;
|
|
|
|
[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 = bakingRotation;
|
|
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;
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|