using Godot; using System.Collections.Generic; namespace Rokojori; [Tool] [GlobalClass ] public partial class LineVFX:Node3D { [ExportToolButton( "Force Update")] public Callable forceUpdateButton => Callable.From( () => { ClearLine(); } ); public void ClearLine() { _lastUpdateID = -1; _data = null; this.DestroyChildren(); } [Export] public LinePreset preset; [ExportGroup("References")] [Export] public Node3D followSource; [Export] public Node3D childPositionsParent; [ExportGroup("Shader Setup")] [Export] public Vector3PropertyName startPositionName; [Export] public Vector3PropertyName startForwardName; [Export] public Vector3PropertyName startUpName; [Export] public Vector3PropertyName endPositionName; [Export] public Vector3PropertyName endForwardName; [Export] public Vector3PropertyName endUpName; LineVFXData _data; int _lastUpdateID = -1; public void SetData( LineVFXData data ) { _data = data; } public LineVFXData GetData() { return _data; } public override void _Process( double delta ) { if ( preset == null ) { return; } preset.Update( this, delta ); if ( _data == null || _lastUpdateID == _data.GetUpdateID() ) { return; } _lastUpdateID = _data.GetUpdateID(); UpdateSegments(); } public Vector3 GetLerpedLinePositionAt( float t ) { return _data == null ? Vector3.Zero : _data.LerpPositionAt( t ); } void UpdateSegments() { var segments = Mathf.Max( 0, _data.GetNumSegments() ); this.EnsureChildCount( segments, ( mi )=> { mi.Mesh = preset.meshGenerator.GetMesh( this, mi ); preset.materialPreset.CreateMaterial( this, mi ); } ); var points = _data.GetPointData(); LinePointData start = null; var segmentIndex = 0; foreach ( var p in points ) { if ( start == null ) { start = p; // if ( lineStart != null ) // { // lineStart.GlobalPosition = start.GetPosition(); // lineStart.LookAt( start.GetPosition() + start.GetForward(), start.GetUp() ); // } continue; } var end = p; var mi = GetChild( segmentIndex ) as MeshInstance3D; segmentIndex++; preset.materialPreset.SetPointData( this, mi, start, true ); preset.materialPreset.SetPointData( this, mi, end, false ); // AssignPointData( mi, start, startPositionName, startForwardName, startUpName ); // AssignPointData( mi, end, endPositionName, endForwardName, endUpName ); var startPosition = start.GetPosition(); var endPosition = end.GetPosition(); var bounds = Box3.Create( startPosition, endPosition ); bounds.Extend( 1 + ( endPosition - startPosition ).Length() ); mi.CustomAabb = bounds; start = end; } // if ( lineEnd != null ) // { // lineEnd.GlobalPosition = start.GetPosition(); // lineEnd.LookAt( start.GetPosition() + start.GetForward(), start.GetUp() ); // } // for ( int i = 0; i < segments; i++ ) // { // var mi = GetChild( i ) as MeshInstance3D; // } } // void AssignPointData( GeometryInstance3D gi, LinePointData lp, // Vector3PropertyName p, Vector3PropertyName f, Vector3PropertyName u ) // { // p.SetInstance( gi, lp.GetPosition() ); // f.SetInstance( gi, lp.GetForward() ); // u.SetInstance( gi, lp.GetUp() ); // } }