using Godot; using System; using Rokojori.Extensions; namespace Rokojori { /** Which primitive HeightMapShape.gdshader draws. Int values are switched on in the shader - do not renumber. */ public enum HeightMapShapeType { Circle = 0 } public class HeightMapShapeShader { public static readonly CachedResource shader = new CachedResource( "res://addons/rokojori_action_library/Runtime/Procedural/HeightMaps/Shaders/HeightMapShape.gdshader" ); public static readonly Vector2PropertyName rectWorldMin = Vector2PropertyName.Create( "shape_rect_world_min" ); public static readonly Vector2PropertyName rectWorldSize = Vector2PropertyName.Create( "shape_rect_world_size" ); public static readonly IntPropertyName shapeType = IntPropertyName.Create( "shape_type" ); public static readonly IntPropertyName blendMode = IntPropertyName.Create( "shape_blend_mode" ); public static readonly FloatPropertyName value = FloatPropertyName.Create( "shape_value" ); public static readonly Vector2PropertyName center = Vector2PropertyName.Create( "shape_center" ); public static readonly FloatPropertyName innerRadius = FloatPropertyName.Create( "shape_inner_radius" ); public static readonly FloatPropertyName outerRadius = FloatPropertyName.Create( "shape_outer_radius" ); public static readonly BoolPropertyName smoothFalloff = BoolPropertyName.Create( "shape_smooth_falloff" ); } /** Material for HeightMapShape.gdshader. One instance per HeightMapGenerator, re-set per layer. The TextureStack's session-2 live test already proved that re-setting a shared blit material between queued blits is safe - the earlier blits do not pick up the later values - which is why every layer can share one material instead of allocating its own. */ [Tool] public partial class HeightMapShapeMaterial:CustomMaterial { public readonly CustomMaterialProperty rectWorldMin; public readonly CustomMaterialProperty rectWorldSize; public readonly CustomMaterialProperty shapeType; public readonly CustomMaterialProperty blendMode; public readonly CustomMaterialProperty value; public readonly CustomMaterialProperty center; public readonly CustomMaterialProperty innerRadius; public readonly CustomMaterialProperty outerRadius; public readonly CustomMaterialProperty smoothFalloff; public HeightMapShapeMaterial() { Shader = HeightMapShapeShader.shader.Get(); rectWorldMin = new CustomMaterialProperty( this, HeightMapShapeShader.rectWorldMin ); rectWorldSize = new CustomMaterialProperty( this, HeightMapShapeShader.rectWorldSize ); shapeType = new CustomMaterialProperty( this, HeightMapShapeShader.shapeType ); blendMode = new CustomMaterialProperty( this, HeightMapShapeShader.blendMode ); value = new CustomMaterialProperty( this, HeightMapShapeShader.value ); center = new CustomMaterialProperty( this, HeightMapShapeShader.center ); innerRadius = new CustomMaterialProperty( this, HeightMapShapeShader.innerRadius ); outerRadius = new CustomMaterialProperty( this, HeightMapShapeShader.outerRadius ); smoothFalloff = new CustomMaterialProperty( this, HeightMapShapeShader.smoothFalloff ); } /** Back to a shape that contributes nothing, so a layer that only sets some of the uniforms does not inherit the previous layer's. The rect uniforms are deliberately not reset - HeightMapGenerator.DrawShape owns those and sets them after the layer has configured the shape. */ public void Reset() { shapeType.Set( (int) HeightMapShapeType.Circle ); blendMode.Set( (int) HeightMapBlendMode.Add ); value.Set( 0 ); center.Set( Vector2.Zero ); innerRadius.Set( 0 ); outerRadius.Set( 0 ); smoothFalloff.Set( true ); } } }