rj-action-library/Runtime/Shading/Generators/Spatial/Masks/AxisMask.cs

111 lines
2.7 KiB
C#

using Godot;
using System.Reflection;
using System.Collections.Generic;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class AxisMask:SpatialMask
{
public enum Source
{
Vertex,
Uniform
}
[Export]
public Source fromSource = Source.Vertex;
[Export]
public ShaderTransformSpace uniformSourceFromSpace;
[Export]
public ShaderTransformSpace toSpace;
[Export]
public Math3D.Axis toAxis;
[Export]
public bool eulerRotation = true;
[Export]
public bool clamp = true;
public override List<ShaderCode> GetMaskCode( ShaderGenerationContext context, string contextName, string maskName )
{
if ( ShaderPhase.Includes == context.phase )
{
return IncludeTransformLibrary().Concat( IncludeMathLibrary() );
}
var ownName = contextName + "AxisMask";
var nameMin = ownName + "_Min";
var nameMax = ownName + "_Max";
var uniformPosition = ownName + "_AxisPosition";
var uniformRotation = ownName + "_AxisRotation";
var uniformGroup = contextName + "AxisMask";
if ( ShaderPhase.Variables == context.phase )
{
var code = new List<ShaderCode>();
code.AddRange( ToCode( Uniform( nameMin, 0 ) + "\n" ) );
code.AddRange( ToCode( Uniform( nameMax, 0 ) + "\n" ) );
if ( Source.Uniform == fromSource )
{
code.AddRange( ToCode( Uniform( uniformPosition, Vector3.Zero ) ) );
}
if ( eulerRotation )
{
code.AddRange( ToCode( Uniform( uniformRotation, Vector3.Zero ) ) );
}
return AsUniformGroup( uniformGroup, code );
}
if ( context.isFragmentPhase )
{
var variableName = Source.Vertex == fromSource ? "VERTEX" : uniformPosition;
if ( eulerRotation )
{
variableName = $"rotateEulerDegrees( {variableName}, {uniformRotation} )";
}
var fromSpace = Source.Vertex == fromSource ? ShaderTransformSpace.View : uniformSourceFromSpace;
var position = ShaderTransformSpaceUtility.FromPoint( fromSpace, toSpace, variableName );
var member = $"({position})." + ( toAxis + "" ).ToLower();
var func = "normalizeToRange01";
if ( ! clamp )
{
func = "normalizeToRange";
}
var code =
@$"
{{
float {contextName}_AxisValue = {member};
float {contextName}_normalizedValue = {func}( {contextName}_AxisValue, {nameMin}, {nameMax } );
{maskName} = {contextName}_normalizedValue;
}}
";
return ToCode( code.Indent( " " ) + "\n" );
}
return null;
}
}
}