using System.Collections; using System.Collections.Generic; using Godot; using System; using System.Threading.Tasks; using System.Linq; namespace Rokojori { /** A node to render foliage. The GrassPatch has various settings to create a different styles of grass. It allows to change the shapes of the blades, their number and distribution, their triangle count, rotation and scale, LOD levels and much more. */ [Tool] [GlobalClass, Icon("res://addons/rokojori_action_library/Icons/Scatterer.svg") ] public partial class FoliageRenderer:Node3D { [Export] public FoliageData[] foliage = []; [Export( PropertyHint.Range, "0, 200" )] public float quality = 100; [Export] public FoliageQualitySettings[] qualitySettingsAll; [Export] public Node3D[] obstacles = []; [Export] public float[] obstacleSizes = []; Vector4[] obstaclesData = new Vector4[4]; public Vector4 GetObstacleData( int index ) { return obstaclesData[ index ]; } List renderLayers = []; [Export] public bool processLayers = true; [Export] public bool updateLayers = true; [Export] public Camera3D camera; Camera3D _assignedCamera; [Export] public Texture2D noise; public Camera3D GetAssignedCamera() { return _assignedCamera; } public override void _Process( double delta ) { _assignedCamera = null; if ( ! processLayers || foliage == null || foliage.Length == 0 ) { return; } if ( updateLayers || foliage.Length != renderLayers.Count ) { updateLayers = false; this.DestroyChildren(); renderLayers = foliage.Map( f => FoliageRenderLayer.Create( this, f ) ).ToList(); renderLayers.ForEach( r => r.data.Initialize( r ) ); } if ( obstaclesData.Length != 4 ) { obstaclesData = new Vector4[ 4]; } for ( int i = 0; i < obstaclesData.Length; i++ ) { var position = obstacles == null || i >= obstacles.Length ? Vector3.Zero : obstacles[ i ].GlobalPosition; var size = obstacleSizes == null || i >= obstacleSizes.Length ? 0 : obstacleSizes[ i ]; obstaclesData[ i ] = new Vector4( position.X, position.Y, position.Z, size ); } if ( Engine.IsEditorHint() ) { _assignedCamera = EditorInterface.Singleton.GetEditorViewport3D().GetCamera3D(); } else { _assignedCamera = camera; } if ( _assignedCamera == null ) { return; } // this.LogInfo( "Processing", renderLayers.Count ); renderLayers.ForEach( r => { if ( r == null ) { return; } r.Update( delta ); } ); } } }