149 lines
4.8 KiB
C#
149 lines
4.8 KiB
C#
using Godot;
|
|
using System.Reflection;
|
|
using System.Collections.Generic;
|
|
|
|
namespace Rokojori
|
|
{
|
|
[Tool]
|
|
[GlobalClass]
|
|
public partial class CSShaderClassGenerator:Node
|
|
{
|
|
[Export]
|
|
public string resourcePath;
|
|
|
|
[Export]
|
|
public bool generate;
|
|
|
|
public override void _Process( double delta )
|
|
{
|
|
if ( generate )
|
|
{
|
|
generate = false;
|
|
Generate();
|
|
}
|
|
}
|
|
|
|
public static readonly string ShaderName = "${ShaderName}";
|
|
public static readonly string ShaderResourcePath = "${ShaderResourcePath}";
|
|
public static readonly string ShaderStaticPropertyNames = "${ShaderStaticPropertyNames}";
|
|
public static readonly string ShaderInstancePropertiesDeclarations = "${ShaderInstancePropertiesDeclarations}";
|
|
public static readonly string ShaderInstancePropertiesInitializers = "${ShaderInstancePropertiesInitializers}";
|
|
public static readonly string MaterialPresets = "${MaterialPresets}";
|
|
|
|
public void Generate()
|
|
{
|
|
var shader = ResourceLoader.Load<Shader>( resourcePath );
|
|
var resourceParentPath = RegexUtility.ParentPath( resourcePath );
|
|
var absoluteFilePath = FilePath.Absolute( ProjectSettings.GlobalizePath( resourcePath ) );
|
|
var absoluteParentPath = absoluteFilePath.CreateAbsoluteParent();
|
|
|
|
RJLog.Log( resourceParentPath );
|
|
|
|
var shaderName = absoluteFilePath.fileName;
|
|
|
|
var members = Shaders.GetUniformMembers( shader );
|
|
|
|
var templatePath = ProjectSettings.GlobalizePath( "res://addons/rokojori_action_library/Runtime/Shading/Tools/CSShaderClassGenerator/CSShaderClassTemplate.txt" );
|
|
|
|
var template = FilesSync.LoadUTF8( templatePath );
|
|
|
|
|
|
|
|
var staticProps = new List<string>();
|
|
var instanceProps = new List<string>();
|
|
var instanceInitializers = new List<string>();
|
|
|
|
members.ForEach(
|
|
( m )=>
|
|
{
|
|
var type = m.GetPropertyNameType();
|
|
var name = m.name;
|
|
var csName = name.ToCamelCase();
|
|
|
|
var declaration = "public static readonly ${type}PropertyName ${csName} = ${type}PropertyName.Create( \"${name}\" );";
|
|
var instance = "public readonly CustomMaterialProperty<${csType}> ${csName};";
|
|
var init = "${csName} = new CustomMaterialProperty<${csType}>( this, ${ShaderName}.${csName} );";
|
|
|
|
var csType = type;
|
|
|
|
if ( csType == "Float" )
|
|
{
|
|
csType = "float";
|
|
}
|
|
else if ( csType == "Int" )
|
|
{
|
|
csType = "float";
|
|
}
|
|
|
|
var map = new StringMap();
|
|
map[ "${type}" ] = type;
|
|
map[ "${csType}"] = csType;
|
|
map[ "${name}" ] = name;
|
|
map[ "${csName}" ] = csName;
|
|
map[ "${ShaderName}"] = shaderName;
|
|
|
|
staticProps.Add( map.ReplaceAll( declaration ) );
|
|
instanceProps.Add( map.ReplaceAll( instance ) );
|
|
instanceInitializers.Add( map.ReplaceAll( init ) );
|
|
}
|
|
);
|
|
|
|
var materials = FilesSync.GetFiles( absoluteParentPath.fullPath,
|
|
( f ) =>
|
|
{
|
|
return f.hasFileExtension( "material" );
|
|
}
|
|
);
|
|
|
|
var presets = new List<string>();
|
|
|
|
materials.ForEach( m =>
|
|
{
|
|
var materialName = m.fileName;
|
|
var shortName = materialName;
|
|
|
|
if ( materialName.ToLower().StartsWith( shaderName.ToLower() ) )
|
|
{
|
|
shortName = shortName.Substring( shaderName.Length );
|
|
}
|
|
|
|
var declaration =
|
|
"public static readonly CachedResource<${ShaderName}Material> ${csName} = CustomMaterial.Cached<${ShaderName}Material>(\n" +
|
|
" \"${materialPath}\"\n" +
|
|
" );";
|
|
|
|
|
|
var mMap = new StringMap();
|
|
mMap[ "${materialPath}" ] = resourceParentPath + "/" + materialName + ".material";
|
|
mMap[ "${ShaderName}" ] = shaderName;
|
|
mMap[ "${csName}" ] = RegexUtility.ToValidCSName( shortName ).ToPascalCase();
|
|
|
|
presets.Add( mMap.ReplaceAll( declaration ) );
|
|
}
|
|
);
|
|
|
|
|
|
var variables = new StringMap();
|
|
variables[ CSShaderClassGenerator.ShaderName ] = shaderName;
|
|
variables[ CSShaderClassGenerator.ShaderResourcePath ] = resourcePath;
|
|
|
|
variables[ CSShaderClassGenerator.ShaderStaticPropertyNames ] = Lists.Join( staticProps, "\n " );
|
|
variables[ CSShaderClassGenerator.ShaderInstancePropertiesDeclarations ] = Lists.Join( instanceProps, "\n " );
|
|
variables[ CSShaderClassGenerator.ShaderInstancePropertiesInitializers ] = Lists.Join( instanceInitializers, "\n " );
|
|
|
|
variables[ CSShaderClassGenerator.MaterialPresets ] = Lists.Join( presets, "\n " );
|
|
|
|
var shaderClass = variables.ReplaceAll( template );
|
|
|
|
var outputPath = absoluteFilePath.WithExtension( "cs" );
|
|
|
|
|
|
|
|
FilesSync.SaveUTF8( outputPath.fullPath, shaderClass );
|
|
|
|
this.LogInfo( "\nGenerated >> ", outputPath.fullPath, "\n" + shaderClass );
|
|
|
|
|
|
}
|
|
}
|
|
} |