Baking Rewrite

This commit is contained in:
Josef 2025-04-08 11:07:02 +02:00
parent e103f0ab56
commit 523db80dae
40 changed files with 1048 additions and 729 deletions

View File

@ -400,6 +400,7 @@ namespace Rokojori
}
}
public static T GetDirectChild<T>( Node parent ) where T:Node
{
if ( parent == null )

View File

@ -21,6 +21,12 @@ namespace Rokojori
return new Aabb( box.min, box.size );
}
public void Translate( Vector3 translation )
{
min += translation;
max += translation;
}
public static Box3 FromPositionAndScale( Vector3 position, Vector3 scale )
{
var max = scale * 0.5f;
@ -40,7 +46,12 @@ namespace Rokojori
public Vector3 size => max - min;
public void IncludePoint( Vector3 p )
{
min = min.Min( p );
max = max.Max( p );
}
public Box2 AsXZBox2()
{
var b = new Box2();

View File

@ -11,105 +11,48 @@ namespace Rokojori
[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;
[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 Camera3D camera;
public Vector3 targetPivot;
[Export]
public float originalFOV = 75;
public bool autoTargetPivot = true;
[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;
[ExportGroup( "Output")]
[Export]
public Node3D outputTexture;
[Export]
public float outputScale = 1;
[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 static Baker Create( Node parent, Node3D target, Vector2I size, string name )
{
@ -129,72 +72,36 @@ namespace Rokojori
public override void _Process( double delta )
{
if ( ! ( update || updateAlways ) )
if ( ! updateAlways )
{
return;
}
update = false;
Bake();
}
void Bake()
public 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 )
if ( autoTargetPivot )
{
computedFOV = Cameras.ComputeFOVForBillboard( originalFOV, sphere.radius, placingDistance );
billboardFOV = computedFOV;
camera.Fov = billboardFOV;
Box3 box = target.GetWorldBounds();
targetPivot = new Vector3( 0, -box.center.Y, 0 );
}
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 );
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;
}
}

View File

@ -1,14 +1,14 @@
[gd_resource type="Resource" script_class="SubMaterialTransfer" load_steps=16 format=3 uid="uid://crxw8r6q5uhpe"]
[ext_resource type="Resource" uid="uid://cwbo0avyyq0t" path="res://addons/rokojori_action_library/Runtime/Shading/Properties/Property Library/Color/Albedo Color.tres" id="1_vhp84"]
[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Shading/Materials/Transfers/ColorPropertyTransfer.cs" id="2_awr2w"]
[ext_resource type="Script" uid="uid://c4kkc55ia5udl" path="res://addons/rokojori_action_library/Runtime/Shading/Materials/Transfers/ColorPropertyTransfer.cs" id="2_awr2w"]
[ext_resource type="Resource" uid="uid://bja8pltfjyt3x" path="res://addons/rokojori_action_library/Runtime/Shading/Properties/Property Library/Float/Alpha Scissor Threshold.tres" id="3_baip0"]
[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Shading/Materials/Transfers/FloatPropertyTransfer.cs" id="4_r0n2g"]
[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Shading/Materials/SubMaterialTransfer.cs" id="5_iuqjk"]
[ext_resource type="Script" uid="uid://dbjd6oaknq055" path="res://addons/rokojori_action_library/Runtime/Shading/Materials/Transfers/FloatPropertyTransfer.cs" id="4_r0n2g"]
[ext_resource type="Script" uid="uid://cwp8to3eakdrm" path="res://addons/rokojori_action_library/Runtime/Shading/Materials/SubMaterialTransfer.cs" id="5_iuqjk"]
[ext_resource type="Resource" uid="uid://dldbju3x0x2ow" path="res://addons/rokojori_action_library/Runtime/Shading/Properties/Property Library/Texture2D/Albedo Texture.tres" id="6_tcnva"]
[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Shading/Materials/Transfers/Texture2DPropertyTransfer.cs" id="7_pf381"]
[ext_resource type="Script" uid="uid://c55j0ppclm0k" path="res://addons/rokojori_action_library/Runtime/Shading/Materials/Transfers/Texture2DPropertyTransfer.cs" id="7_pf381"]
[ext_resource type="Resource" uid="uid://cn7nxc0qw7pan" path="res://addons/rokojori_action_library/Runtime/Shading/Properties/Property Library/Vector3/UV1 Offset.tres" id="8_00usm"]
[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Shading/Materials/Transfers/Vector3PropertyTransfer.cs" id="9_sn3qs"]
[ext_resource type="Script" uid="uid://sm7n01wb77f1" path="res://addons/rokojori_action_library/Runtime/Shading/Materials/Transfers/Vector3PropertyTransfer.cs" id="9_sn3qs"]
[ext_resource type="Resource" uid="uid://douianw6mx4p5" path="res://addons/rokojori_action_library/Runtime/Shading/Properties/Property Library/Vector3/UV1 Scale.tres" id="10_5fqi2"]
[sub_resource type="Resource" id="Resource_7u5wc"]

View File

@ -1,16 +1,16 @@
[gd_resource type="Resource" script_class="SubMaterialTransfer" load_steps=20 format=3 uid="uid://dgyihly620ymm"]
[ext_resource type="Resource" uid="uid://cwbo0avyyq0t" path="res://addons/rokojori_action_library/Runtime/Shading/Properties/Property Library/Color/Albedo Color.tres" id="1_8s4ko"]
[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Shading/Materials/Transfers/ColorPropertyTransfer.cs" id="2_edgft"]
[ext_resource type="Script" uid="uid://c4kkc55ia5udl" path="res://addons/rokojori_action_library/Runtime/Shading/Materials/Transfers/ColorPropertyTransfer.cs" id="2_edgft"]
[ext_resource type="Resource" uid="uid://bja8pltfjyt3x" path="res://addons/rokojori_action_library/Runtime/Shading/Properties/Property Library/Float/Alpha Scissor Threshold.tres" id="3_8a5am"]
[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Shading/Materials/Transfers/FloatPropertyTransfer.cs" id="4_wnydu"]
[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Shading/Materials/SubMaterialTransfer.cs" id="5_atmxl"]
[ext_resource type="Script" uid="uid://dbjd6oaknq055" path="res://addons/rokojori_action_library/Runtime/Shading/Materials/Transfers/FloatPropertyTransfer.cs" id="4_wnydu"]
[ext_resource type="Script" uid="uid://cwp8to3eakdrm" path="res://addons/rokojori_action_library/Runtime/Shading/Materials/SubMaterialTransfer.cs" id="5_atmxl"]
[ext_resource type="Resource" uid="uid://c6actnjj8i8o5" path="res://addons/rokojori_action_library/Runtime/Shading/Properties/Property Library/Float/Normal Scale.tres" id="5_iyqth"]
[ext_resource type="Resource" uid="uid://dldbju3x0x2ow" path="res://addons/rokojori_action_library/Runtime/Shading/Properties/Property Library/Texture2D/Albedo Texture.tres" id="6_l0r8p"]
[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Shading/Materials/Transfers/Texture2DPropertyTransfer.cs" id="7_l54r2"]
[ext_resource type="Script" uid="uid://c55j0ppclm0k" path="res://addons/rokojori_action_library/Runtime/Shading/Materials/Transfers/Texture2DPropertyTransfer.cs" id="7_l54r2"]
[ext_resource type="Resource" uid="uid://bmt10lgwm8ckx" path="res://addons/rokojori_action_library/Runtime/Shading/Properties/Property Library/Texture2D/Normal Texture.tres" id="9_fmy5n"]
[ext_resource type="Resource" uid="uid://cn7nxc0qw7pan" path="res://addons/rokojori_action_library/Runtime/Shading/Properties/Property Library/Vector3/UV1 Offset.tres" id="10_dw87i"]
[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Shading/Materials/Transfers/Vector3PropertyTransfer.cs" id="11_mpsiy"]
[ext_resource type="Script" uid="uid://sm7n01wb77f1" path="res://addons/rokojori_action_library/Runtime/Shading/Materials/Transfers/Vector3PropertyTransfer.cs" id="11_mpsiy"]
[ext_resource type="Resource" uid="uid://douianw6mx4p5" path="res://addons/rokojori_action_library/Runtime/Shading/Properties/Property Library/Vector3/UV1 Scale.tres" id="12_xnkjm"]
[sub_resource type="Resource" id="Resource_7u5wc"]

View File

@ -1,22 +1,22 @@
[gd_resource type="Resource" script_class="SubMaterialTransfer" load_steps=36 format=3 uid="uid://kwk45f3p6ic4"]
[ext_resource type="Resource" uid="uid://cwbo0avyyq0t" path="res://addons/rokojori_action_library/Runtime/Shading/Properties/Property Library/Color/Albedo Color.tres" id="1_b7tdx"]
[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Shading/Materials/Transfers/ColorPropertyTransfer.cs" id="2_vwrue"]
[ext_resource type="Script" uid="uid://c4kkc55ia5udl" path="res://addons/rokojori_action_library/Runtime/Shading/Materials/Transfers/ColorPropertyTransfer.cs" id="2_vwrue"]
[ext_resource type="Resource" uid="uid://txmti1ghef1" path="res://addons/rokojori_action_library/Runtime/Shading/Properties/Property Library/TextureChannels/AO Texture Channel.tres" id="3_rkwtk"]
[ext_resource type="Resource" uid="uid://bja8pltfjyt3x" path="res://addons/rokojori_action_library/Runtime/Shading/Properties/Property Library/Float/Alpha Scissor Threshold.tres" id="3_u377f"]
[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Shading/Materials/Transfers/FloatPropertyTransfer.cs" id="4_ed7jn"]
[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Shading/Materials/Transfers/TextureChannelToVector4Transfer.cs" id="4_ubpsj"]
[ext_resource type="Script" uid="uid://dbjd6oaknq055" path="res://addons/rokojori_action_library/Runtime/Shading/Materials/Transfers/FloatPropertyTransfer.cs" id="4_ed7jn"]
[ext_resource type="Script" uid="uid://hged4kw2qsv8" path="res://addons/rokojori_action_library/Runtime/Shading/Materials/Transfers/TextureChannelToVector4Transfer.cs" id="4_ubpsj"]
[ext_resource type="Resource" uid="uid://dy4yrg7cbx84g" path="res://addons/rokojori_action_library/Runtime/Shading/Properties/Property Library/Float/Metallic.tres" id="5_hkpx0"]
[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Shading/Materials/SubMaterialTransfer.cs" id="6_7dw2g"]
[ext_resource type="Script" uid="uid://cwp8to3eakdrm" path="res://addons/rokojori_action_library/Runtime/Shading/Materials/SubMaterialTransfer.cs" id="6_7dw2g"]
[ext_resource type="Resource" uid="uid://dn4k668h72myc" path="res://addons/rokojori_action_library/Runtime/Shading/Properties/Property Library/Float/Roughness.tres" id="6_8likw"]
[ext_resource type="Resource" uid="uid://xoj2836knmix" path="res://addons/rokojori_action_library/Runtime/Shading/Properties/Property Library/TextureChannels/Metallic Texture Channel.tres" id="6_v4lhi"]
[ext_resource type="Resource" uid="uid://dldbju3x0x2ow" path="res://addons/rokojori_action_library/Runtime/Shading/Properties/Property Library/Texture2D/Albedo Texture.tres" id="7_yqc2y"]
[ext_resource type="Resource" uid="uid://d2x1ijwsv2urr" path="res://addons/rokojori_action_library/Runtime/Shading/Properties/Property Library/TextureChannels/Roughness Texture Channel.tres" id="8_gljck"]
[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Shading/Materials/Transfers/Texture2DPropertyTransfer.cs" id="8_iwxjk"]
[ext_resource type="Script" uid="uid://c55j0ppclm0k" path="res://addons/rokojori_action_library/Runtime/Shading/Materials/Transfers/Texture2DPropertyTransfer.cs" id="8_iwxjk"]
[ext_resource type="Resource" uid="uid://cow6rei03x5bs" path="res://addons/rokojori_action_library/Runtime/Shading/Properties/Property Library/Texture2D/AO Texture.tres" id="10_8mfy8"]
[ext_resource type="Resource" uid="uid://cn7nxc0qw7pan" path="res://addons/rokojori_action_library/Runtime/Shading/Properties/Property Library/Vector3/UV1 Offset.tres" id="10_y3nsy"]
[ext_resource type="Resource" uid="uid://csiwpeupf761o" path="res://addons/rokojori_action_library/Runtime/Shading/Properties/Property Library/Texture2D/Metallic Texture.tres" id="11_i36mp"]
[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Shading/Materials/Transfers/Vector3PropertyTransfer.cs" id="11_on6ta"]
[ext_resource type="Script" uid="uid://sm7n01wb77f1" path="res://addons/rokojori_action_library/Runtime/Shading/Materials/Transfers/Vector3PropertyTransfer.cs" id="11_on6ta"]
[ext_resource type="Resource" uid="uid://douianw6mx4p5" path="res://addons/rokojori_action_library/Runtime/Shading/Properties/Property Library/Vector3/UV1 Scale.tres" id="12_a173h"]
[ext_resource type="Resource" uid="uid://bdjlvcpc13hl6" path="res://addons/rokojori_action_library/Runtime/Shading/Properties/Property Library/Texture2D/Roughness Texture.tres" id="12_u6pwu"]
[ext_resource type="Resource" uid="uid://bprgfki4joe6x" path="res://addons/rokojori_action_library/Runtime/Shading/Properties/Property Library/Vector4/AO Texture Channel.tres" id="16_56ntu"]

View File

@ -1,20 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using Godot;
using System;
using System.Threading.Tasks;
namespace Rokojori
{
public abstract class MultiBakeModeImplementation
{
public MultiBaker multiBaker;
public abstract MultiBaker.BakeMode GetBakeMode();
public abstract int GetNumViews();
public abstract void CreateBakes();
public abstract void AssignMaterial( BakingMaterialMode mode, Texture2D texture );
public abstract void CreateMaterial( bool preview );
}
}

View File

@ -1,142 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using Godot;
using System;
using System.Threading.Tasks;
namespace Rokojori
{
public class MultiBakeModeCrossBraces:MultiBakeModeBillboardBase
{
public override MultiBaker.BakeMode GetBakeMode()
{
return MultiBaker.BakeMode.Cross_Braces;
}
public override int GetNumViews()
{
var views = multiBaker.crossAngles * 2;
if ( multiBaker.crossBottom )
{
views ++;
}
if ( multiBaker.crossTop )
{
views ++;
}
return views;
}
public override void CreateBakes()
{
var fov = multiBaker.GetCameraFOV();
var distance = multiBaker.GetCameraDistance();
var outputScale = multiBaker.GetOutputScale();
var _bakers = multiBaker.bakers;
var mb = multiBaker;
_bakers.ForEach(
b =>
{
b.useCustomFOV = true;
b.customFOV = fov;
b.useCustomDistance = true;
b.customDistance = distance;
b.rotationMode = Baker.RotationMode.Yaw_Pitch;
}
);
var index = 0;
var mg = new MeshGeometry();
var numTextures = GetNumViews();
var textureAlignment = TextureMerger.ComputeTextureAlignment( numTextures );
if ( mb.crossTop )
{
_bakers[ index ].yaw = 0 + mb.crossAngleOffset;
_bakers[ index ].pitch = 90f;
var uv = TextureMerger.GetUVRectangle( textureAlignment, index, true );
var q = new MeshGeometry();
q.AddQuad( _bakers[ index ].bakingRotation, outputScale, uv.min, uv.max );
mg.Add( q );
index ++;
}
if ( mb.crossBottom )
{
_bakers[ index ].yaw = 0 + mb.crossAngleOffset;
_bakers[ index ].pitch = -90f;
var uv = TextureMerger.GetUVRectangle( textureAlignment, index, true );
var q = new MeshGeometry();
q.AddQuad( _bakers[ index ].bakingRotation, outputScale, uv.min, uv.max );
mg.Add( q );
index ++;
}
for ( int i = 0; i < mb.crossAngles; i++ )
{
for ( int side = 0; side < 2; side ++ )
{
var angle = ( 180f * i ) / (float) mb.crossAngles;
_bakers[ index ].yaw = side == 0 ? angle : ( MathX.Repeat( angle + 180f, 360f ) );
_bakers[ index ].yaw += mb.crossAngleOffset;
_bakers[ index ].pitch = 0;
var uv = TextureMerger.GetUVRectangle( textureAlignment, index, true );
var q = new MeshGeometry();
q.AddQuad( _bakers[ index ].bakingRotation, outputScale, uv.min, uv.max );
if ( mb.crossBraces > 1 )
{
var normal = Vector3.Forward * _bakers[ index ].bakingRotation;
var startOffset = normal * mb.crossSpreadDistance * 0.5f;
var endOffset = -startOffset;
for ( int brace = 0; brace < mb.crossBraces; brace ++ )
{
var bq = q.Clone();
var lerpAmount = (float)brace / (float)( mb.crossBraces - 1 );
var offset = startOffset.Lerp( endOffset, lerpAmount );
bq.ApplyTranslation( offset );
mg.Add( bq );
}
}
else
{
mg.Add( q );
}
index ++;
}
}
mb.X_outputMesh.Mesh = mg.GenerateMesh();
}
}
}

View File

@ -1,155 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using Godot;
using System;
using System.Threading.Tasks;
namespace Rokojori
{
public class MultiBakeModeCylinder:MultiBakeModeBillboardBase
{
public override MultiBaker.BakeMode GetBakeMode()
{
return MultiBaker.BakeMode.Cylinder;
}
public override int GetNumViews()
{
var cylinderViews = multiBaker.cylinderSides;
if ( multiBaker.cylinderBottom )
{
cylinderViews ++;
}
if ( multiBaker.cylinderTop )
{
cylinderViews ++;
}
return cylinderViews;
}
public override void CreateBakes()
{
var fov = multiBaker.GetCameraFOV();
var distance = multiBaker.GetCameraDistance();
var outputScale = multiBaker.GetOutputScale();
var _bakers = multiBaker.bakers;
var mb = multiBaker;
_bakers.ForEach(
b =>
{
b.useCustomFOV = true;
b.customFOV = fov;
b.useCustomDistance = true;
b.customDistance = distance;
b.rotationMode = Baker.RotationMode.Yaw_Pitch;
}
);
var index = 0;
var mg = new MeshGeometry();
var numTextures = GetNumViews();
var textureAlignment = TextureMerger.ComputeTextureAlignment( numTextures );
if ( mb.cylinderTop )
{
_bakers[ index ].yaw = 0;
_bakers[ index ].pitch = 90f;
var uv = TextureMerger.GetUVRectangle( textureAlignment, index, true );
var q = new MeshGeometry();
q.AddQuad( _bakers[ index ].bakingRotation, outputScale, uv.min, uv.max );
if ( mb.cylinderTopOffset != 0 )
{
var topOffset = Vector3.Up * mb.cylinderTopOffset * outputScale * 0.5f;
q.ApplyTranslation( topOffset, -4 );
}
mg.Add( q );
if ( mb.createBackFacesForTop )
{
q.FlipNormalDirection();
mg.Add( q );
}
index ++;
}
if ( mb.cylinderBottom )
{
_bakers[ index ].yaw = 0;
_bakers[ index ].pitch = -90f;
var uv = TextureMerger.GetUVRectangle( textureAlignment, index, true );
var q = new MeshGeometry();
q.AddQuad( _bakers[ index ].bakingRotation, outputScale, uv.min, uv.max );
if ( mb.cylinderBottomOffset != 0 )
{
var bottomOffset = Vector3.Down * mb.cylinderBottomOffset * outputScale * 0.5f;
q.ApplyTranslation( bottomOffset, -4 );
}
mg.Add( q );
if ( mb.createBackFacesForBottom )
{
q.FlipNormalDirection();
mg.Add( q );
}
index ++;
}
for ( int i = 0; i < mb.cylinderSides; i++ )
{
var angle = ( 360f * i ) / (float) mb.cylinderSides;
_bakers[ index ].yaw = angle;
_bakers[ index ].pitch = 0;
var uv = TextureMerger.GetUVRectangle( textureAlignment, index, true );
var q = new MeshGeometry();
q.AddQuad( _bakers[ index ].bakingRotation, outputScale, uv.min, uv.max );
if ( mb.cylinderSideOffset != 0 )
{
var sideOffset = Vector3.Forward *_bakers[ index ].bakingRotation * mb.cylinderSideOffset * outputScale * -0.5f;
q.ApplyTranslation( sideOffset, -4 );
}
mg.Add( q );
if ( mb.createBackFacesForSides )
{
q.FlipNormalDirection();
mg.Add( q );
}
index++;
}
mb.X_outputMesh.Mesh = mg.GenerateMesh();
}
}
}

View File

@ -1,42 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using Godot;
using System;
using System.Threading.Tasks;
namespace Rokojori
{
public class MultiBakeModeSpherical:MultiBakeModeImplementation
{
public readonly string sphericalShader = "res://addons/rokojori_action_library/External/Imposter/materials/shaders/ImpostorShader.gdshader";
public override MultiBaker.BakeMode GetBakeMode()
{
return MultiBaker.BakeMode.Spherical;
}
public override int GetNumViews()
{
var views = multiBaker.sphericalSides * multiBaker.sphericalRows;
return views;
}
public override void CreateMaterial( bool preview )
{
}
public override void AssignMaterial( BakingMaterialMode mode, Texture2D texture )
{
}
public override void CreateBakes()
{
}
}
}

View File

@ -0,0 +1,150 @@
using System.Collections;
using System.Collections.Generic;
using Godot;
using System;
using System.Threading.Tasks;
namespace Rokojori
{
[Tool][GlobalClass]
public partial class CrossBraces_Baker:_XX_MultiBakeModeBillboardBase
{
[Export]
public int crossAngles = 2;
[Export]
public int crossBraces = 3;
[Export]
public float crossSpreadDistance = 1;
[Export]
public float crossAngleOffset = 0;
[Export]
public bool crossTop = false;
[Export]
public bool crossBottom = false;
public override int GetNumViews()
{
var views = crossAngles * 2;
if ( crossBottom )
{
views ++;
}
if ( crossTop )
{
views ++;
}
return views;
}
public override void CreateBakers()
{
var fov = multiBaker.GetCameraFOV();
var distance = multiBaker.GetCameraDistance();
var outputScale = multiBaker.GetOutputScale();
RJLog.Log( "outputScale", outputScale );
var _bakers = multiBaker.bakers;
var mb = multiBaker;
_bakers.ForEach(
bk =>
{
var vs = bk.viewSettings;
vs.fovDistance = Manual_BakingFDSettings.Create( fov, distance );
vs.rotationMode = BakingViewSettings.RotationMode.Yaw_Pitch;
}
);
var index = 0;
var mg = new MeshGeometry();
var numTextures = GetNumViews();
var textureAlignment = TextureMerger.ComputeTextureAlignment( numTextures );
if ( crossTop )
{
_bakers[ index ].viewSettings.yaw = 0 + crossAngleOffset;
_bakers[ index ].viewSettings.pitch = 90f;
var uv = TextureMerger.GetUVRectangle( textureAlignment, index, true );
var q = new MeshGeometry();
q.AddQuad( _bakers[ index ].viewSettings.bakingRotation, outputScale, uv.min, uv.max );
mg.Add( q );
index ++;
}
if ( crossBottom )
{
_bakers[ index ].viewSettings.yaw = 0 + crossAngleOffset;
_bakers[ index ].viewSettings.pitch = -90f;
var uv = TextureMerger.GetUVRectangle( textureAlignment, index, true );
var q = new MeshGeometry();
q.AddQuad( _bakers[ index ].viewSettings.bakingRotation, outputScale, uv.min, uv.max );
mg.Add( q );
index ++;
}
for ( int i = 0; i < crossAngles; i++ )
{
for ( int side = 0; side < 2; side ++ )
{
var angle = ( 180f * i ) / (float) crossAngles;
_bakers[ index ].viewSettings.yaw = side == 0 ? angle : ( MathX.Repeat( angle + 180f, 360f ) );
_bakers[ index ].viewSettings.yaw += crossAngleOffset;
_bakers[ index ].viewSettings.pitch = 0;
var uv = TextureMerger.GetUVRectangle( textureAlignment, index, true );
var q = new MeshGeometry();
q.AddQuad( _bakers[ index ].viewSettings.bakingRotation, outputScale, uv.min, uv.max );
if ( crossBraces > 1 )
{
var normal = Vector3.Forward * _bakers[ index ].viewSettings.bakingRotation;
var startOffset = normal * crossSpreadDistance * 0.5f;
var endOffset = -startOffset;
for ( int brace = 0; brace < crossBraces; brace ++ )
{
var bq = q.Clone();
var lerpAmount = (float)brace / (float)( crossBraces - 1 );
var offset = startOffset.Lerp( endOffset, lerpAmount );
bq.ApplyTranslation( offset );
mg.Add( bq );
}
}
else
{
mg.Add( q );
}
index ++;
}
}
mb.X_outputMesh.Mesh = mg.GenerateMesh();
}
}
}

View File

@ -0,0 +1,167 @@
using System.Collections;
using System.Collections.Generic;
using Godot;
using System;
using System.Threading.Tasks;
namespace Rokojori
{
[Tool][GlobalClass]
public partial class Cylinder_Baker:_XX_MultiBakeModeBillboardBase
{
[Export]
public int cylinderSides = 4;
[Export]
public bool createBackFacesForSides = false;
[Export]
public bool cylinderTop = false;
[Export]
public bool createBackFacesForTop = false;
[Export]
public bool cylinderBottom = false;
[Export]
public bool createBackFacesForBottom = false;
[Export( PropertyHint.Range, "-1,1" )]
public float cylinderSideOffset = 0;
[Export( PropertyHint.Range, "-1,1" )]
public float cylinderTopOffset = 0f;
[Export( PropertyHint.Range, "-1,1" )]
public float cylinderBottomOffset = 0f;
public override int GetNumViews()
{
var cylinderViews = cylinderSides;
if ( cylinderBottom )
{
cylinderViews ++;
}
if ( cylinderTop )
{
cylinderViews ++;
}
return cylinderViews;
}
public override void CreateBakers()
{
var fov = multiBaker.GetCameraFOV();
var distance = multiBaker.GetCameraDistance();
var outputScale = multiBaker.GetOutputScale();
var _bakers = multiBaker.bakers;
var mb = multiBaker;
_bakers.ForEach(
bk =>
{
var vs = bk.viewSettings;
vs.fovDistance = Manual_BakingFDSettings.Create( fov, distance );
vs.rotationMode = BakingViewSettings.RotationMode.Yaw_Pitch;
}
);
var index = 0;
var mg = new MeshGeometry();
var numTextures = GetNumViews();
var textureAlignment = TextureMerger.ComputeTextureAlignment( numTextures );
if ( cylinderTop )
{
_bakers[ index ].viewSettings.yaw = 0;
_bakers[ index ].viewSettings.pitch = 90f;
var uv = TextureMerger.GetUVRectangle( textureAlignment, index, true );
var q = new MeshGeometry();
q.AddQuad( _bakers[ index ].viewSettings.bakingRotation, outputScale, uv.min, uv.max );
if ( cylinderTopOffset != 0 )
{
var topOffset = Vector3.Up * cylinderTopOffset * outputScale * 0.5f;
q.ApplyTranslation( topOffset, -4 );
}
mg.Add( q );
if ( createBackFacesForTop )
{
q.FlipNormalDirection();
mg.Add( q );
}
index ++;
}
if ( cylinderBottom )
{
_bakers[ index ].viewSettings.yaw = 0;
_bakers[ index ].viewSettings.pitch = -90f;
var uv = TextureMerger.GetUVRectangle( textureAlignment, index, true );
var q = new MeshGeometry();
q.AddQuad( _bakers[ index ].viewSettings.bakingRotation, outputScale, uv.min, uv.max );
if ( cylinderBottomOffset != 0 )
{
var bottomOffset = Vector3.Down * cylinderBottomOffset * outputScale * 0.5f;
q.ApplyTranslation( bottomOffset, -4 );
}
mg.Add( q );
if ( createBackFacesForBottom )
{
q.FlipNormalDirection();
mg.Add( q );
}
index ++;
}
for ( int i = 0; i < cylinderSides; i++ )
{
var angle = ( 360f * i ) / (float) cylinderSides;
_bakers[ index ].viewSettings.yaw = angle;
_bakers[ index ].viewSettings.pitch = 0;
var uv = TextureMerger.GetUVRectangle( textureAlignment, index, true );
var q = new MeshGeometry();
q.AddQuad( _bakers[ index ].viewSettings.bakingRotation, outputScale, uv.min, uv.max );
if ( cylinderSideOffset != 0 )
{
var sideOffset = Vector3.Forward *_bakers[ index ].viewSettings.bakingRotation * cylinderSideOffset * outputScale * -0.5f;
q.ApplyTranslation( sideOffset, -4 );
}
mg.Add( q );
if ( createBackFacesForSides )
{
q.FlipNormalDirection();
mg.Add( q );
}
index++;
}
mb.X_outputMesh.Mesh = mg.GenerateMesh();
}
}
}

View File

@ -11,11 +11,14 @@ namespace Rokojori
[GlobalClass]
public partial class MultiBaker:Node
{
[ExportToolButton( "Initialize")]
public Callable InitializeButton => Callable.From( () => Initialize() );
[ExportToolButton( "Bake")]
public Callable BakeButton => Callable.From( () => Bake() );
public Callable BakeButton => Callable.From( () => StartBaking() );
[Export]
public bool cleanUpAfterBaking = true;
[Export]
public _XX_MultiBakeMode bakeMode;
public enum MaterialMode
{
@ -27,6 +30,8 @@ namespace Rokojori
[Export]
public MaterialMode materialMode;
[Export]
public int dilationRadius = 64;
[ExportGroup("Material/Full Seperated")]
[Export]
public bool mmfs_Normals = true;
@ -36,89 +41,44 @@ namespace Rokojori
public bool mmfs_ORM = true;
public enum BakeMode
{
Cylinder,
Cross_Braces,
Octahedral,
Spherical,
Cloud
}
[ExportGroup("BakeMode")]
[Export]
public BakeMode bakeMode;
[ExportGroup("BakeMode/Cylinder")]
[Export]
public int cylinderSides = 4;
[Export]
public bool createBackFacesForSides = false;
[Export]
public bool cylinderTop = false;
[Export]
public bool createBackFacesForTop = false;
[Export]
public bool cylinderBottom = false;
[Export]
public bool createBackFacesForBottom = false;
[Export( PropertyHint.Range, "-1,1" )]
public float cylinderSideOffset = 0;
[Export( PropertyHint.Range, "-1,1" )]
public float cylinderTopOffset = 0f;
[Export( PropertyHint.Range, "-1,1" )]
public float cylinderBottomOffset = 0f;
[ExportGroup("BakeMode/Cross Braces")]
[Export]
public int crossAngles = 2;
[Export]
public int crossBraces = 3;
[Export]
public float crossSpreadDistance = 1;
[Export]
public float crossAngleOffset = 0;
[Export]
public bool crossTop = false;
[Export]
public bool crossBottom = false;
[ExportGroup("BakeMode/Octahedral")]
[Export]
public int octahedralSides = 4;
[Export]
public bool octahedralFullSphere = false;
[ExportGroup("BakeMode/Spherical")]
[Export]
public int sphericalSides = 4;
[Export]
public int sphericalRows = 3;
[Export]
public float minPitch = -30;
[Export]
public float maxPitch = 30;
[ExportGroup( "Object")]
[Export]
public Node3D sourceTarget;
public Node3D target;
[Export]
public bool autoCenter = false;
public bool autoTargetPivot = false;
[Export]
public Vector3 sourceOffset;
public Vector3 targetPivot;
[ExportGroup( "Camera")]
[Export]
public BakingViewSettings viewSettings;
public float cameraZoom
{
get
{
if ( viewSettings.fovDistance is AutoDistance_BakingFDSettings ad )
{
return ad.zoom;
}
if ( viewSettings.fovDistance is AutoDistance_BakingFDSettings afd )
{
return afd.zoom;
}
return 1;
}
}
/*
[Export]
public Baker.CameraDistanceDetectionType distanceDetectionType = Baker.CameraDistanceDetectionType.Automatic_Distance_Detection;
@ -136,7 +96,7 @@ namespace Rokojori
public float fovPlacingDistance = 200;
[Export]
public float customFOV = 75;
*/
[ExportGroup( "Output")]
@ -199,25 +159,82 @@ namespace Rokojori
public Texture2D X_bakedTextureDepth;
bool _initialized = false;
bool _baking = false;
[Export]
public bool X_baking = false;
public void StartBaking()
{
Initialize();
Bake();
}
public void Initialize()
{
this.LogInfo( "Initializing" );
Nodes.RemoveAndDeleteChildren( this );
_bakers = null;
X_bakingViewport = this.CreateChild<SubViewport>( "Multi Baker Viewport" );
X_bakingViewport.Size = (Vector2I) outputTextureSize;
X_bakingViewport.OwnWorld3D = true;
X_bakingViewport.TransparentBg = true;
X_worldEnvironment = X_bakingViewport.CreateChild<WorldEnvironment>( "Multi Baker Environment" );
X_worldEnvironment.Environment = new Godot.Environment();
X_worldEnvironment.Environment.AmbientLightSource = Godot.Environment.AmbientSource.Color;
X_worldEnvironment.Environment.AmbientLightColor = HSLColor.white;
X_bakingTargetContainer = X_bakingViewport.CreateChild<Node3D>( "Target Container" );
X_views = X_bakingViewport.CreateChild<Node>( "Views" );
X_textureMerger = this.CreateChild<TextureMerger>( "Texture Merger" );
X_textureMerger.multiBaker = this;
X_textureMerger.dilationRadius = dilationRadius;
X_textureMerger.Initialize();
X_outputMesh = this.CreateChild<MeshInstance3D>( "Output Mesh" );
X_texturePreview = this.CreateChild<MeshInstance3D>( "Texture Preview" );
X_texturePreview.Mesh = new QuadMesh();
X_texturePreview.Scale = Vector3.One * 100;
var pm = new StandardMaterial3D();
pm.Transparency = BaseMaterial3D.TransparencyEnum.AlphaScissor;
pm.ResourceLocalToScene = true;
var vt = new ViewportTexture();
vt.ViewportPath = X_textureMerger.X_textureMergerViewport.GetPath();
pm.AlbedoTexture = vt;
X_setBakingMaterials = this.CreateChild<SetBakingMaterials>( "Set Baking Materials" );
Materials.Set( X_texturePreview, pm );
}
public async Task Bake()
{
if ( _baking )
if ( X_baking )
{
return;
}
_baking = true;
X_baking = true;
try
{
bakeMode.multiBaker = this;
this.LogInfo( "Started baking" );
Nodes.RemoveAndDeleteChildren( X_bakingTargetContainer );
sourceTarget.DeepCopyTo( X_bakingTargetContainer );
target.DeepCopyTo( X_bakingTargetContainer );
if ( _bakers == null || _bakers.Count != GetNumViews() )
{
@ -225,20 +242,20 @@ namespace Rokojori
await this.RequestNextFrame();
}
SetupViews();
this.LogInfo( "Views set up" );
await this.RequestNextFrame();
X_setBakingMaterials.SetTarget( X_bakingTargetContainer );
X_setBakingMaterials.SetTarget( X_bakingTargetContainer );
var bakingMaterialModes = new List<BakingMaterialMode>();
var preview_QuickMaterial = MaterialMode.Simple_Prebaked == materialMode;
GetBakeModeImplementation().CreateMaterial( preview_QuickMaterial );
bakeMode.CreateMaterial( preview_QuickMaterial );
if ( preview_QuickMaterial )
{
@ -265,24 +282,25 @@ namespace Rokojori
}
this.LogInfo( "Prepared baking modes" );
X_textureMerger.textureSize = outputTextureSize;
X_textureMerger.Initialize();
X_textureMerger.CreateLayout();
this.LogInfo( "Prepared texture merger" );
// var fovDistance = viewSettings.fovDistance.ComputeFOVDistance(
var objectDistance = GetCameraDistance();
this.LogInfo( "Set Camera Distance", objectDistance );
for ( int i = 0; i < bakingMaterialModes.Count; i++ )
{
this.LogInfo( "Baking mode:", bakingMaterialModes[ i ] );
X_setBakingMaterials.mode = bakingMaterialModes[ i ];
X_setBakingMaterials.ApplyBakingMaterials( objectDistance, _targetBoundingSphere.radius );
this.LogInfo( "Materials changed:", bakingMaterialModes[ i ] );
_bakers.ForEach( b => b.Bake() );
await this.RequestNextFrame();
Texture2D texture = X_textureMerger.X_textureMergerViewport.GetTexture();
@ -294,7 +312,7 @@ namespace Rokojori
await this.RequestNextFrame();
this.LogInfo( "Assigning Texture", bakingMaterialModes[ i ] );
GetBakeModeImplementation().AssignMaterial( bakingMaterialModes[ i ], texture );
bakeMode.AssignMaterial( bakingMaterialModes[ i ], texture );
this.LogInfo( "Baking done:", bakingMaterialModes[ i ] );
@ -304,7 +322,17 @@ namespace Rokojori
await this.RequestNextFrame();
// this.LogInfo( "Baking done" );
X_outputMesh.GlobalPosition = target.GlobalPosition - targetPivot;
X_outputMesh.Scale = Vector3.One * cameraZoom;
if ( cleanUpAfterBaking )
{
this.LogInfo( "Cleaning Up" );
CleanUp();
}
this.LogInfo( "All Baking done" );
}
catch ( System.Exception e )
@ -313,31 +341,16 @@ namespace Rokojori
this.LogError( e );
}
_baking = false;
X_baking = false;
return;
}
public List<SubViewport> GetAllViewports()
{
return Nodes.AllIn<SubViewport>( X_views, null, false );
}
List<MultiBakeModeImplementation> _bakeModeImplementations = new List<MultiBakeModeImplementation>()
{
new MultiBakeModeCylinder(),
new MultiBakeModeCrossBraces(),
new MultiBakeModeOctahedral()
};
public MultiBakeModeImplementation GetBakeModeImplementation()
{
var bm = _bakeModeImplementations.Find( bm => bm.GetBakeMode() == bakeMode );
bm.multiBaker = this;
return bm;
}
public void CacheTexture( BakingMaterialMode mode, Texture2D texture )
{
if ( BakingMaterialMode.Albedo == mode )
@ -357,62 +370,49 @@ namespace Rokojori
X_bakedTextureDepth = texture;
}
}
}
public void CleanUp()
{
var mesh = X_outputMesh;
mesh.Reparent( GetParent(), true );
X_bakingViewport = null;
X_bakingTargetContainer = null;
X_views = null;
X_worldEnvironment = null;
X_outputMesh = null;
X_textureMerger = null;
X_setBakingMaterials = null;
X_texturePreview = null;
X_depthMapper = null;
X_bakedTextureAlbedo = null;
X_bakedTextureNormal = null;
X_bakedTextureORM = null;
X_bakedTextureDepth = null;
public void Initialize()
{
this.LogInfo( "Initializing" );
Nodes.RemoveAndDeleteChildren( this );
_bakers = null;
X_bakingViewport = this.CreateChild<SubViewport>( "Multi Baker Viewport" );
X_bakingViewport.Size = (Vector2I) outputTextureSize;
X_bakingViewport.OwnWorld3D = true;
X_bakingViewport.TransparentBg = true;
X_worldEnvironment = X_bakingViewport.CreateChild<WorldEnvironment>( "Multi Baker Environment" );
X_worldEnvironment.Environment = new Godot.Environment();
X_worldEnvironment.Environment.AmbientLightSource = Godot.Environment.AmbientSource.Color;
X_worldEnvironment.Environment.AmbientLightColor = HSLColor.white;
X_bakingTargetContainer = X_bakingViewport.CreateChild<Node3D>( "Target Container" );
X_views = X_bakingViewport.CreateChild<Node>( "Views" );
// X_dilateTexture = this.CreateChild<DilateTexture>( "Dilate Texture" );
X_textureMerger = this.CreateChild<TextureMerger>( "Texture Merger" );
X_textureMerger.multiBaker = this;
X_textureMerger.Initialize();
X_outputMesh = this.CreateChild<MeshInstance3D>( "Output Mesh" );
X_texturePreview = this.CreateChild<MeshInstance3D>( "Texture Preview" );
X_texturePreview.Mesh = new QuadMesh();
X_texturePreview.Scale = Vector3.One * 100;
var pm = new StandardMaterial3D();
pm.Transparency = BaseMaterial3D.TransparencyEnum.AlphaScissor;
pm.ResourceLocalToScene = true;
var vt = new ViewportTexture();
vt.ViewportPath = X_textureMerger.X_textureMergerViewport.GetPath();
pm.AlbedoTexture = vt;
X_setBakingMaterials = this.CreateChild<SetBakingMaterials>( "Set Baking Materials" );
Materials.Set( X_texturePreview, pm );
_initialized = true;
mesh.Reparent( this, true );
}
public int GetNumViews()
{
return GetBakeModeImplementation().GetNumViews();
return bakeMode.GetNumViews();
}
List<Baker> _bakers;
@ -445,7 +445,7 @@ namespace Rokojori
baker.viewport = bakingView;
baker.update = true;
_bakers.Add( baker );
}
@ -466,6 +466,8 @@ namespace Rokojori
}
_targetBoundingSphere = null;
_targetBoundingBox = null;
ComputeBoundingSphere();
if ( _targetBoundingSphere == null )
@ -474,22 +476,16 @@ namespace Rokojori
return;
}
var bmi = GetBakeModeImplementation();
ComputeCameraViewSettings();
bakeMode.CreateBakers();
if ( bmi == null )
{
return;
}
bmi.CreateBakes();
/*if ( X_bakedTextureAlbedo != null )
{
bmi.AssignMaterial( BakingMaterialMode.Albedo, X_bakedTextureAlbedo );
}*/
}
Sphere _targetBoundingSphere;
Box3 _targetBoundingBox;
Sphere targetBoundingSphere
{
@ -525,45 +521,62 @@ namespace Rokojori
firstChild.Visible = true;
}
var worldBounds = X_bakingTargetContainer.GetWorldBounds();
_targetBoundingBox = X_bakingTargetContainer.GetWorldBounds();
if ( autoTargetPivot )
{
Box3 box = target.GetWorldBounds();
targetPivot = new Vector3( 0, -box.center.Y, 0 );
}
_targetBoundingSphere = Sphere.ContainingBox( worldBounds );
_targetBoundingSphere = Sphere.ContainingBox( _targetBoundingBox );
}
float _cameraFOV = 0;
float _cameraDistance = 0;
float _outputScale = 1;
void ComputeCameraViewSettings()
{
var fovDistance = viewSettings.fovDistance;
var size = targetBoundingSphere.radius;
var computeScale = false;
if ( fovDistance is AutoDistance_BakingFDSettings ad )
{
size = ad.sizeEstimation == _XX_BakingFDSettings.SizeEstimationType.Bounding_Sphere ?
targetBoundingSphere.radius : ( _targetBoundingBox.size.Y / 2f );
computeScale = true;
}
if ( fovDistance is AutoFOVDistance_BakingFDSettings afd )
{
size = afd.sizeEstimation == _XX_BakingFDSettings.SizeEstimationType.Bounding_Sphere ?
targetBoundingSphere.radius : ( _targetBoundingBox.size.Y / 2f );
computeScale = true;
}
var fd = fovDistance.ComputeFOVDistance( size / 2f );
_cameraFOV = fd.X;
_cameraDistance = fd.Y;
_outputScale = computeScale ? Cameras.ComputeCameraFittingScale( _cameraFOV, _cameraDistance ) : 1;
}
public float GetCameraFOV()
{
if ( Baker.CameraFOVMode.Custom_Fov == fovMode )
{
return customFOV;
}
if ( Baker.CameraFOVMode.Keep_Fov == fovMode )
{
return originalFOV;
}
return Cameras.ComputeFOVForBillboard( originalFOV, targetBoundingSphere.radius, fovPlacingDistance );
return _cameraFOV;
}
public float GetCameraDistance()
{
if ( Baker.CameraDistanceDetectionType.Custom_Distance == distanceDetectionType )
{
return customDistance;
}
var fov = GetCameraFOV();
return Cameras.ComputeCameraFrameFittingDistance( fov, targetBoundingSphere.radius / cameraZoom );
return _cameraDistance;
}
public float GetOutputScale()
{
var fov = GetCameraFOV();
var distance = GetCameraDistance();
return Cameras.ComputeCameraFittingScale( fov, distance );
return _outputScale;
}
}
}

View File

@ -0,0 +1,14 @@
using System.Collections;
using System.Collections.Generic;
using Godot;
using System;
using System.Threading.Tasks;
namespace Rokojori
{
public class MultiBakerCameraTools
{
}
}

View File

@ -7,18 +7,22 @@ using System.Threading.Tasks;
namespace Rokojori
{
public class MultiBakeModeOctahedral:MultiBakeModeImplementation
[Tool]
[GlobalClass]
public partial class Octahedral_Baker:_XX_MultiBakeMode
{
public readonly string octahedralShader = "res://addons/rokojori_action_library/External/Imposter/materials/shaders/ImpostorShader.gdshader";
public static readonly string octahedralShader = "res://addons/rokojori_action_library/External/Imposter/materials/shaders/ImpostorShader.gdshader";
public override MultiBaker.BakeMode GetBakeMode()
{
return MultiBaker.BakeMode.Octahedral;
}
[Export]
public int octahedralSides = 4;
[Export]
public bool octahedralFullSphere = false;
public override int GetNumViews()
{
var views = multiBaker.octahedralSides * multiBaker.octahedralSides;
var views = octahedralSides * octahedralSides;
return views;
}
@ -29,8 +33,8 @@ namespace Rokojori
var material = new ShaderMaterial();
material.Shader = ResourceLoader.Load( octahedralShader ) as Shader;
material.SetShaderParameter( "isFullSphere", mb.octahedralFullSphere );
material.SetShaderParameter( "imposterFrames", Vector2.One * mb.octahedralSides );
material.SetShaderParameter( "isFullSphere", octahedralFullSphere );
material.SetShaderParameter( "imposterFrames", Vector2.One * octahedralSides );
Materials.Set( mb.X_outputMesh, material );
}
@ -65,11 +69,10 @@ namespace Rokojori
material.SetShaderParameter( "imposterTextureDepth", texture );
}
}
public override void CreateBakes()
public override void CreateBakers()
{
var fov = multiBaker.GetCameraFOV();
var distance = multiBaker.GetCameraDistance();
@ -78,17 +81,15 @@ namespace Rokojori
var _bakers = multiBaker.bakers;
var mb = multiBaker;
_bakers.ForEach(
b =>
bk =>
{
b.useCustomFOV = true;
b.customFOV = fov;
var vs = bk.viewSettings;
vs.fovDistance = Manual_BakingFDSettings.Create( fov, distance );
b.useCustomDistance = true;
b.customDistance = distance;
b.rotationMode = Baker.RotationMode.Quaternion;
vs.rotationMode = BakingViewSettings.RotationMode.Quaternion;
}
);
@ -96,20 +97,20 @@ namespace Rokojori
var numTextures = GetNumViews();
var textureAlignment = TextureMerger.ComputeTextureAlignment( numTextures );
var toOP = 1f / ( mb.octahedralSides - 1 );
var toOP = 1f / ( octahedralSides - 1 );
var index = 0;
for ( int x = 0; x < mb.octahedralSides; x++ )
for ( int x = 0; x < octahedralSides; x++ )
{
for ( int y = 0; y < mb.octahedralSides; y++ )
for ( int y = 0; y < octahedralSides; y++ )
{
var inverseX = ( mb.octahedralSides - 1 ) - x;
var inverseY = ( mb.octahedralSides - 1 ) - y;
var inverseX = ( octahedralSides - 1 ) - x;
var inverseY = ( octahedralSides - 1 ) - y;
var octahedralPosition = new Vector2( y, inverseX ) * toOP;
var normal = OctahedralMapping.Map( octahedralPosition, mb.octahedralFullSphere );
var normal = OctahedralMapping.Map( octahedralPosition, octahedralFullSphere );
_bakers[ index ].rotationQuaternion = Math3D.LookRotation( normal, true ).Normalized().Inverse();
_bakers[ index ].viewSettings.rotationQuaternion = Math3D.LookRotation( normal, true ).Normalized().Inverse();
index ++;
}

View File

@ -0,0 +1 @@
uid://bdgrhysvuusyp

View File

@ -0,0 +1,36 @@
using System.Collections;
using System.Collections.Generic;
using Godot;
using System;
using System.Threading.Tasks;
namespace Rokojori
{
[Tool][GlobalClass]
public partial class _XX_MultiBakeMode:Resource
{
public MultiBaker multiBaker;
public virtual int GetNumViews()
{
return -1;
}
public virtual void CreateBakers()
{
}
public virtual void AssignMaterial( BakingMaterialMode mode, Texture2D texture )
{
}
public virtual void CreateMaterial( bool preview )
{
}
}
}

View File

@ -7,7 +7,8 @@ using System.Threading.Tasks;
namespace Rokojori
{
public abstract class MultiBakeModeBillboardBase:MultiBakeModeImplementation
[Tool][GlobalClass]
public partial class _XX_MultiBakeModeBillboardBase:_XX_MultiBakeMode
{
public override void CreateMaterial( bool preview )
{

View File

@ -0,0 +1,48 @@
using System.Collections;
using System.Collections.Generic;
using Godot;
using System;
using System.Threading.Tasks;
namespace Rokojori
{
[Tool][GlobalClass]
public partial class _XX_Spherical_Baker:_XX_MultiBakeMode
{
public static readonly string sphericalShader = "res://addons/rokojori_action_library/External/Imposter/materials/shaders/ImpostorShader.gdshader";
[Export]
public int sphericalSides = 4;
[Export]
public int sphericalRows = 3;
[Export]
public float minPitch = -30;
[Export]
public float maxPitch = 30;
public override int GetNumViews()
{
var views = sphericalSides * sphericalRows;
return views;
}
public override void CreateMaterial( bool preview )
{
}
public override void AssignMaterial( BakingMaterialMode mode, Texture2D texture )
{
}
public override void CreateBakers()
{
}
}
}

View File

@ -0,0 +1 @@
uid://dc1xsvfdwtqbc

View File

@ -24,6 +24,9 @@ namespace Rokojori
[Export]
public bool createLayout;
[Export]
public int dilationRadius = 64;
[ExportGroup("Source")]
[Export]
@ -217,19 +220,29 @@ namespace Rokojori
for ( int i = 0; i < _textures.Count; i++ )
{
var mesh = X_textureMergerViewport.CreateChild<CsgMesh3D>( "Texture " + ( i + 1 ) );
var meshInstance = X_textureMergerViewport.CreateChild<MeshInstance3D>( "Texture " + ( i + 1 ) );
var uvRectangle = GetUVRectangle( alignment, i );
SetMeshCoordinates( mesh, uvRectangle, i );
RJLog.Log( "Set Texture" + ( i + 1 ), uvRectangle.min, uvRectangle.max );
SetMeshCoordinates( meshInstance, uvRectangle, i );
var dilatedMaterial = new DilationDrawerMaterial();
dilatedMaterial.textureAlbedo.Set( _textures[ i ] );
dilatedMaterial.resolution.Set( _textures[ i ].GetSize() );
dilatedMaterial.maxRadius.Set( dilationRadius );
dilatedMaterial.alphaTreshold.Set( 1 );
dilatedMaterial.assignedColorAlphaMinimum.Set( 254 );
dilatedMaterial.genericAlphaOffset.Set( 0 );
dilatedMaterial.amount.Set( 1 );
var material = new StandardMaterial3D();
material.Transparency = transparencyMode;
material.AlphaScissorThreshold = alphaThreshold;
material.ShadingMode = BaseMaterial3D.ShadingModeEnum.Unshaded;
material.AlbedoTexture = _textures[ i ];
mesh.Material = material;
Materials.Set( meshInstance, dilatedMaterial );
}
}
@ -237,26 +250,36 @@ namespace Rokojori
{
for ( int i = 0; i < _textures.Count; i++ )
{
var mesh = outputTarget.CreateChild<CsgMesh3D>( "Texture " + ( i + 1 ) );
var meshInstance = outputTarget.CreateChild<MeshInstance3D>( "Texture " + ( i + 1 ) );
SetMeshCoordinates( mesh, customPositions[ i ], customSizes[ i ], i );
SetMeshCoordinates( meshInstance, customPositions[ i ], customSizes[ i ], i );
var material = new StandardMaterial3D();
material.Transparency = transparencyMode;
material.ShadingMode = BaseMaterial3D.ShadingModeEnum.Unshaded;
material.AlphaScissorThreshold = alphaThreshold;
var dilatedMaterial = new DilationDrawerMaterial();
dilatedMaterial.textureAlbedo.Set( _textures[ i ] );
dilatedMaterial.resolution.Set( _textures[ i ].GetSize() );
dilatedMaterial.maxRadius.Set( dilationRadius );
dilatedMaterial.alphaTreshold.Set( 10 );
dilatedMaterial.assignedColorAlphaMinimum.Set( 10 );
dilatedMaterial.genericAlphaOffset.Set( 50 );
dilatedMaterial.amount.Set( 1 );
material.AlbedoTexture = _textures[ i ];
mesh.Material = material;
Materials.Set( meshInstance, dilatedMaterial );
}
}
void SetMeshCoordinates( CsgMesh3D mesh, Box2 rectangle, int index )
void SetMeshCoordinates( MeshInstance3D mesh, Box2 rectangle, int index )
{
SetMeshCoordinates( mesh, rectangle.min, rectangle.max, index );
}
void SetMeshCoordinates( CsgMesh3D mesh, Vector2 min, Vector2 max, int index )
void SetMeshCoordinates( MeshInstance3D mesh, Vector2 min, Vector2 max, int index )
{
var start = ConvertUVtoCameraSpace( min );
var end = ConvertUVtoCameraSpace( max );
@ -269,7 +292,7 @@ namespace Rokojori
mesh.GlobalPosition = new Vector3( start.X + size.X/2, start.Y + size.Y/2, -1 );
// RJLog.Log( "Set Mesh", index, "Min:", min, ">>", start, "Max:", max, ">>", end );
RJLog.Log( "Set Mesh", index, "Size:", size, "Min:", min, ">>", start, "Max:", max, ">>", end );
}
public static Vector2I ComputeTextureAlignment( int numElements )

View File

@ -0,0 +1,40 @@
using System.Collections;
using System.Collections.Generic;
using Godot;
using System;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class AutoDistance_BakingFDSettings:_XX_BakingFDSettings
{
[Export]
public float fov = 75;
[Export]
public float zoom = 1;
[Export]
public SizeEstimationType sizeEstimation = SizeEstimationType.Bounding_Sphere;
[Export]
public float sizeAbsoluteOffset = 0;
[Export]
public float sizeRelativeOffset = 0.1f;
public override Vector2 ComputeFOVDistance( float size )
{
size += sizeAbsoluteOffset;
size += sizeRelativeOffset * size;
var distance = Cameras.ComputeCameraFrameFittingDistance( fov, size / zoom );
return new Vector2( fov, distance );
}
}
}

View File

@ -0,0 +1 @@
uid://chqe2154cxijp

View File

@ -0,0 +1,45 @@
using System.Collections;
using System.Collections.Generic;
using Godot;
using System;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class AutoFOVDistance_BakingFDSettings:_XX_BakingFDSettings
{
[Export]
public float gameCameraFOV = 75;
[Export]
public float gameViewDistance = 10;
[Export]
public float zoom = 1;
[Export]
public SizeEstimationType sizeEstimation = SizeEstimationType.Bounding_Sphere;
[Export]
public float sizeAbsoluteOffset = 0;
[Export]
public float sizeRelativeOffset = 0.1f;
public override Vector2 ComputeFOVDistance( float size )
{
size += sizeAbsoluteOffset;
size += sizeRelativeOffset * size;
var fov = Cameras.ComputeFOVForBillboard( gameCameraFOV, size, gameViewDistance );
var distance = Cameras.ComputeCameraFrameFittingDistance( fov, size / zoom );
return new Vector2( fov, distance );
}
}
}

View File

@ -0,0 +1 @@
uid://cf5kjcm27di0q

View File

@ -0,0 +1,154 @@
using System.Collections;
using System.Collections.Generic;
using Godot;
using System;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class BakingViewSettings:Resource
{
/*public enum CameraDistanceDetectionType
{
Automatic_Distance_Detection,
Custom_Distance
}
public enum CameraFOVMode
{
Keep_Fov,
Compute_Fov_With_Distance,
Custom_Fov
}*/
[Export]
public _XX_BakingFDSettings fovDistance;
/*
[Export]
public float originalFOV = 75;
[Export]
public bool assignFOV = false;
[Export]
public float placingDistance = 500;
[Export]
public float zoom = 1;
*/
[ExportGroup( "Debug Readonly" )]
[Export]
public float _XX_ComputedFOV = 75;
[Export]
public float _XX_ComputedDistance = 1;
[Export]
public float _XX_ComputedOutputScale = 1;
/*
[ExportGroup( "Custom FOV" )]
[Export]
public bool useCustomFOV = false;
[Export]
public float customFOV = 75;
[ExportGroup( "Custom Distance" )]
[Export]
public bool useCustomDistance = false;
[Export]
public float customDistance = 50;
*/
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;
public void ApplySettings( Camera3D camera, Node3D target, Vector3 pivot )
{
var box = target.GetWorldBounds();
if ( box == null )
{
RJLog.Log( "No target" );
return;
}
Box3 box3 = box;
box3.IncludePoint( target.ToGlobal( pivot ) );
var sphere = Sphere.ContainingBox( box3 );
var size = sphere.radius;
if ( fovDistance is AutoDistance_BakingFDSettings ad )
{
size = ad.sizeEstimation == _XX_BakingFDSettings.SizeEstimationType.Bounding_Sphere ?
sphere.radius : ( box3.size.Y / 2f );
}
if ( fovDistance is AutoFOVDistance_BakingFDSettings afd )
{
size = afd.sizeEstimation == _XX_BakingFDSettings.SizeEstimationType.Bounding_Sphere ?
sphere.radius : ( box3.size.Y / 2f );
}
var fd = fovDistance.ComputeFOVDistance( size / 2f );
_XX_ComputedDistance = fd.Y;
_XX_ComputedFOV = fd.X;
camera.Fov = fd.X;
var cameraRotation = bakingRotation;
var offset = ( Vector3.Back * _XX_ComputedDistance ) * cameraRotation ;
camera.GlobalPosition = target.GlobalPosition + offset - pivot;
camera.SetGlobalQuaternion( cameraRotation.Inverse() );
_XX_ComputedOutputScale = Cameras.ComputeCameraFittingScale( camera.Fov, _XX_ComputedDistance );
}
}
}

View File

@ -0,0 +1 @@
uid://d1mvjtf46vfip

View File

@ -0,0 +1,33 @@
using System.Collections;
using System.Collections.Generic;
using Godot;
using System;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class Manual_BakingFDSettings:_XX_BakingFDSettings
{
[Export]
public float cameraDistance = 10;
[Export]
public float cameraFOV = 75;
public override Vector2 ComputeFOVDistance( float size )
{
return new Vector2( cameraFOV, cameraDistance );
}
public static Manual_BakingFDSettings Create( float fov, float distance )
{
var m = new Manual_BakingFDSettings();
m.cameraDistance = distance;
m.cameraFOV = fov;
return m;
}
}
}

View File

@ -0,0 +1 @@
uid://dbfheg550pyqw

View File

@ -0,0 +1,27 @@
using System.Collections;
using System.Collections.Generic;
using Godot;
using System;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class _XX_BakingFDSettings:Resource
{
public enum SizeEstimationType
{
Bounding_Sphere,
Bounding_Box_Height
}
public virtual Vector2 ComputeFOVDistance( float size )
{
return Vector2.Zero;
}
}
}

View File

@ -0,0 +1 @@
uid://cy6khw6xl3qrg