using System.Collections; using System.Collections.Generic; using Godot; using System; using System.Threading.Tasks; namespace Rokojori { /** Resource to define foliage data */ [Tool] [GlobalClass, Icon("res://addons/rokojori_action_library/Icons/Scatterer.svg") ] public partial class FoliageData:Resource { [Export] public string layerName; [Export] public bool enabled = true; [Export] public bool updateSettings = true; [Export] public FoliageQualitySettings[] qualitySettings; [ExportGroup("Visibility")] [Export] public float cellSize = 1.0f; public float GetCellSize( int subLayerIndex = -1 ) { if ( subLayerIndex < 0 ) { return cellSize; } var subLayer = subLayers[ subLayerIndex ]; return subLayer.cellSizeOffset + subLayer.relativeCellSize * cellSize; } [Export] public float visibilityRange = 50f; public float GetVisibilityRange( int subLayerIndex = -1 ) { if ( subLayerIndex < 0 ) { return visibilityRange; } var subLayer = subLayers[ subLayerIndex ]; return subLayer.additionalVisibilityRange + subLayer.relativeVisibilityRange * visibilityRange; } [Export] public float visibilityFadeRelative = 0.5f; public float GetVisibilityFadeRelative( int subLayerIndex = -1 ) { if ( subLayerIndex < 0 ) { return visibilityFadeRelative; } var subLayer = subLayers[ subLayerIndex ]; return subLayer.visibilityFadeRelative; } [Export] public float visibilityFadeAbsolute = 0f; public float GetVisibilityFadeAbsolute( int subLayerIndex = -1 ) { if ( subLayerIndex < 0 ) { return visibilityFadeAbsolute; } var subLayer = subLayers[ subLayerIndex ]; return subLayer.visibilityFadeAbsolute; } [Export] public float visibilityFadeHidingOffset = -0.7f; public float GetVisibilityFadeHidingOffset( int subLayerIndex = -1 ) { if ( subLayerIndex < 0 ) { return visibilityFadeHidingOffset; } var subLayer = subLayers[ subLayerIndex ]; return visibilityFadeHidingOffset + subLayer.additionalVisibilityFadeHidingOffset; } [ExportGroup("Model")] [Export] public FoliageSource source; [ExportGroup("Renderer")] [Export] public FoliageMaterialOverride materialOverride; /** Render priority, only for transparent objects*/ [Export] public FoliagePriority renderPriority; [Export] public bool shadows = true; public bool GetShadows( int subLayerIndex ) { if ( subLayerIndex < 0 ) { return shadows; } var subLayer = subLayers[ subLayerIndex ]; return subLayer.shadows; } [Export] public bool sort = false; public bool GetSort( int subLayerIndex ) { if ( subLayerIndex < 0 ) { return sort; } var subLayer = subLayers[ subLayerIndex ]; return subLayer.sort; } [ExportGroup("Sub Layers")] [Export] public SubFoliageData[] subLayers = []; public int numLayers { get { var num = 1; for ( int i = 0; subLayers != null && i < subLayers.Length; i++ ) { if ( subLayers[ i ] == null ) { continue; } num++; } return num; } } [ExportGroup("Position")] [Export] public Vector3 positionVarianceAbsoluteOffset = Vector3.Zero; [Export] public Vector3 positionVarianceCellSizeRelativeOffset = Vector3.Zero; [Export] public Vector3 positionOffset = Vector3.Zero; public Vector3 GetPositionOffset( int subLayerIndex ) { if ( subLayerIndex < 0 ) { return positionOffset; } var subLayer = subLayers[ subLayerIndex ]; return positionOffset + subLayer.subPositionOffset; } [Export] public float positionVarianceScale = 1f; [Export] public Vector2 positionVarianceOffset = Vector2.Zero; [ExportGroup("Rotation")] [Export] public Vector3 rotationMin = Vector3.Zero; [Export] public Vector3 rotationMax = new Vector3( 0, 1, 0 ); [Export] public float rotationVarianceScale = 1f; [Export] public Vector2 rotationVarianceOffset = Vector2.Zero; [ExportGroup("Scale")] [Export] public Vector3 scaleVarianceMinScale = Vector3.One; [Export] public Vector3 scaleVarianceMaxScale = Vector3.One; [Export] public float scaleVarianceScale = 1f; [Export] public Vector2 scaleVarianceOffset = Vector2.Zero; [ExportGroup("Occupancy")] [Export(PropertyHint.Range,"0,1")] public float occupancyVarianceAmount = 0f; [Export(PropertyHint.Range,"0,50")] public float occupancyVariancePower = 1f; [Export(PropertyHint.Range,"0,1")] public float occupancyTreshold = 0.5f; [Export] public float occupancyHideOffset = -2f; [Export] public float occupancyHideScale = 0.1f; [Export] public float occupancyVarianceScale = 1f; [Export] public Vector2 occupancyVarianceOffset = Vector2.Zero; public virtual void Initialize( FoliageRenderLayer renderLayer ) { var particles = renderLayer.renderer.CreateChild( renderLayer.data.layerName ); renderLayer.gpuParticles3D = particles; var processMaterial = new GPUFoliageShaderMaterial(); particles.ProcessMaterial = processMaterial; particles.Lifetime = 0.01f; particles.Explosiveness = 1f; particles.FixedFps = 0; particles.Interpolate = false; particles.FractDelta = false; particles.CustomAabb = Box3.WithSize( 10000 ); particles.CastShadow = renderLayer.data.GetShadows( renderLayer.subLayerIndex ) ? GeometryInstance3D.ShadowCastingSetting.On : GeometryInstance3D.ShadowCastingSetting.Off; processMaterial.positionVariance.Set( renderLayer.renderer.noise ); processMaterial.rotationVariance.Set( renderLayer.renderer.noise ); processMaterial.scaleVariance.Set( renderLayer.renderer.noise ); processMaterial.occupancyVariance.Set( renderLayer.renderer.noise ); renderLayer.gpuFoliageShaderMaterial = processMaterial; source?.SetupFoliageDrawPass( renderLayer ); materialOverride?.CreateFoliageOverideMaterial( renderLayer ); } } }