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 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(); 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; } } }