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