rj-action-library/Runtime/Procedural/Baking/Baker.cs

110 lines
2.2 KiB
C#

using System.Collections;
using System.Collections.Generic;
using Godot;
using System;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class Baker:Node
{
[ExportToolButton( "Update")]
public Callable BakeButton => Callable.From( () => Bake() );
[Export]
public bool updateAlways = false;
[ExportGroup( "View") ]
[Export]
public BakingViewSettings viewSettings = new BakingViewSettings();
[Export]
public Viewport viewport;
[Export]
public Camera3D camera;
[ExportGroup( "Target")]
[Export]
public Node3D target;
[Export]
public Vector3 targetPivot;
[Export]
public bool autoTargetPivot = true;
[ExportGroup( "Output")]
[Export]
public Node3D outputTexture;
[Export]
public float outputScale = 1;
[Export]
public float outputTextureSize = 1;
public static Baker Create( Node parent, Node3D target, Vector2I size, string name )
{
var bakingView = parent.CreateChild<SubViewport>( "Viewport " + name );
bakingView.TransparentBg = true;
bakingView.Size = size;
var bakingCamera = bakingView.CreateChild<Camera3D>( "Camera View " + name );
var baker = bakingView.CreateChild<Baker>( "Baker " + name );
baker.camera = bakingCamera;
baker.target = target;
baker.viewport = bakingView;
return baker;
}
public override void _Process( double delta )
{
if ( ! updateAlways )
{
return;
}
Bake();
}
public void Bake()
{
if ( viewport == null || target == null || camera == null )
{
return;
}
if ( autoTargetPivot )
{
Box3 box = target.GetWorldBounds();
targetPivot = new Vector3( 0, -box.center.Y, 0 );
}
viewSettings.ApplySettings( camera, target, targetPivot );
var outputScale = Cameras.ComputeCameraFittingScale( camera.Fov, viewSettings._XX_ComputedDistance );
if ( outputTexture != null )
{
outputTexture.Scale = Vector3.One * outputScale;
outputTexture.GlobalPosition = target.GlobalPosition - targetPivot;
}
}
}
}