using System.Collections; using System.Collections.Generic; using Godot; using System; namespace Rokojori { [Tool] [GlobalClass] public partial class SetBakingMaterials:Node { [Export] public Node targetContainer; [Export] public BakingMaterialMode mode; MapList _originalMaterials; public void SetTarget( Node targetContainer ) { _originalMaterials = new MapList(); this.targetContainer = targetContainer; Nodes.ForEach( targetContainer, ( v )=> { _originalMaterials[ v ] = Materials.GetAll( v ); } ); } public void ApplyBakingMaterials( float distance, float radius ) { Nodes.ForEach( targetContainer, ( v )=> { SetMaterial( v, distance, radius ); } ); } FloatPropertyName centerDistance = FloatPropertyName.Create( "centerDistance"); FloatPropertyName rangeDistance = FloatPropertyName.Create( "rangeDistance"); void SetMaterial( VisualInstance3D v, float distance, float radius ) { var materials = _originalMaterials[ v ]; if ( BakingMaterialMode.Preview != mode ) { materials = CreateBakingMaterials( materials ); } if ( BakingMaterialMode.Depth == mode ) { materials.ForEach( m => { centerDistance.Set( m, distance ); rangeDistance.Set( m, radius ); } ); } Materials.Set( v, materials ); } List CreateBakingMaterials( List materials ) { return Lists.Map( materials, m => CreateBakingMaterial( m ) ); } Material CreateBakingMaterial( Material originalMaterial ) { var bakingMaterial = LoadBakingMaterialForMode().Duplicate( true ) as Material; var materialTransfer = GetBakingMaterialTransfer(); this.LogInfo( mode, materialTransfer, originalMaterial, bakingMaterial ); materialTransfer.Transfer( originalMaterial, bakingMaterial ); return bakingMaterial; } static readonly string transferPaths = "res://addons/rokojori_action_library/Runtime/Procedural/Baking/BakingMaterials/"; MaterialTransfer GetBakingMaterialTransfer() { switch ( mode ) { case BakingMaterialMode.Albedo: return Load( transferPaths + "Albedo/Albedo Transfer.tres" ); case BakingMaterialMode.Normals: return Load( transferPaths + "Normal/Normal Transfer.tres" ); case BakingMaterialMode.ORM: return Load( transferPaths + "ORM/ORM Transfer.tres" ); case BakingMaterialMode.Depth: return Load( transferPaths + "Depth/Depth Transfer.tres" ); } return null; } public static readonly string materialsPath = "res://addons/rokojori_action_library/External/Imposter/materials/"; public static readonly string depthMapPath = "res://addons/rokojori_action_library/Runtime/Shading/Shaders/Baking/DepthMap.material"; public Material LoadBakingMaterialForMode() { switch ( mode ) { case BakingMaterialMode.Albedo: return Load( materialsPath + "albedo_material.material" ); case BakingMaterialMode.Normals: return Load( materialsPath + "normal_baker.material" ); case BakingMaterialMode.ORM: return Load( materialsPath + "orm_baker.material" ); case BakingMaterialMode.Depth: return Load( depthMapPath ); } return null; } static Dictionary _cachedResources = new Dictionary(); static R Load( string resourcePath ) where R:Resource { RJLog.Log( "Loading", resourcePath ); if ( ! _cachedResources.ContainsKey( resourcePath ) ) { _cachedResources[ resourcePath ] = ResourceLoader.Load( resourcePath ); RJLog.Log( "Loaded", resourcePath, _cachedResources[ resourcePath ] ); if ( _cachedResources[ resourcePath ] == null ) { RJLog.Error( "Resource not found:", resourcePath ); } } return _cachedResources[ resourcePath ] as R; } } }