rokojori_action_library/Runtime/VFX/LineVFX/LineVFX.cs

170 lines
3.5 KiB
C#

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