rj-action-library/Runtime/Animation/Flash/Flash.cs

261 lines
6.5 KiB
C#
Raw Normal View History

2025-01-03 12:09:23 +00:00
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Text;
using Godot;
namespace Rokojori
{
[Tool]
[GlobalClass]
2025-01-08 18:46:17 +00:00
public partial class Flash:SequenceAction
2025-01-03 12:09:23 +00:00
{
[Export]
public FlashEffect flashEffect;
[Export]
public Node3D[] targets = new Node3D[ 0 ];
2025-01-03 12:09:23 +00:00
int animationID = -1;
int actionID = -1;
Vector3 randomization;
List<Material> _materials;
OmniLight3D light = null;
Color ComputeLightColor( Color color, float phase )
{
if ( phase < 5/100f )
{
var n = MathX.NormalizeClamped( phase, 0, 5/100f );
color *= n;
}
else if ( phase > 95/100f )
{
var n = MathX.NormalizeClamped( phase, 1, 95/100f );
color *= n;
}
return color;
}
2025-01-08 18:46:17 +00:00
protected override void _OnTrigger()
2025-01-03 12:09:23 +00:00
{
if ( actionID != -1 )
{
CancelAction( actionID );
}
2025-01-08 18:46:17 +00:00
2025-01-03 12:09:23 +00:00
actionID = DispatchStart();
2025-01-18 20:02:20 +00:00
var random = LCG.WithSeed( networkSeed );
2025-01-08 18:46:17 +00:00
2025-01-18 12:49:14 +00:00
// RJLog.Log( "Setting actionID id", actionID, GetLastSequenceActionID() );
2025-01-03 12:09:23 +00:00
var flashCurve = flashEffect.flashCurve;
var color = flashEffect.color.GetHDRColor();
var timeline = flashEffect.timeline;
2025-01-08 18:46:17 +00:00
randomization = flashCurve.Randomize( random );
2025-01-03 12:09:23 +00:00
var duration = flashCurve.GetRandomizedDuration( randomization );
var transparentColor = color;
var initialAlpha = transparentColor.A;
transparentColor.A = 0;
Material material = null;
if ( FlashEffect.FlashLightMode.No_Light != flashEffect.lightMode )
{
light = targets[ 0 ].CreateChild<OmniLight3D>();
light.LightColor = ComputeLightColor( color, 0 );
light.LightEnergy = 0;
light.OmniRange = flashEffect.lightRange;
light.ShadowEnabled = flashEffect.lightHasShadows;
// RJLog.Log( "Created Light", light.Name );
}
if ( FlashEffect.MaterialMode.Flat_Standard3D == flashEffect.materialMode )
{
var standardMaterial = new StandardMaterial3D();
standardMaterial.AlbedoColor = transparentColor;
standardMaterial.ShadingMode = BaseMaterial3D.ShadingModeEnum.Unshaded;
standardMaterial.Transparency = BaseMaterial3D.TransparencyEnum.Alpha;
material = standardMaterial;
}
else if ( FlashEffect.MaterialMode.Fresnel_FresnelOverlay == flashEffect.materialMode )
{
var fresnelMaterial = new FresnelOverlayMaterial();
fresnelMaterial.albedo.Set( transparentColor );
material = fresnelMaterial;
}
else if ( FlashEffect.MaterialMode.Scan_ScanGradient == flashEffect.materialMode )
{
var scanMaterial = ScanGradientMaterial.White.Get();
scanMaterial.albedo.Set( transparentColor );
material = scanMaterial;
}
else if ( FlashEffect.MaterialMode.Shield_TriPlanarOverlay == flashEffect.materialMode )
{
var shieldMaterial = TriPlanarOverlayMaterial.WhiteShield.Get();
shieldMaterial.albedo.Set( transparentColor );
material = shieldMaterial;
}
else
{
material = flashEffect.customMaterial;
flashEffect.customFlashColorProperty.Set( material, transparentColor );
}
_materials = new List<Material>();
Arrays.ForEach( targets,
t =>
{
var m = (Material) material.Duplicate( true );
_materials.Add( m );
Materials.AddOverlay( t, m );
}
);
2025-01-19 20:35:51 +00:00
var start = timeline.position;
2025-01-03 12:09:23 +00:00
var end = start + duration;
2025-01-18 12:49:14 +00:00
2025-01-19 20:35:51 +00:00
animationID = TimeLineManager.ScheduleSpanIn( timeline, 0, duration,
( TimeLineSpan span, TimeLineSpanUpdateType type )=>
2025-01-03 12:09:23 +00:00
{
2025-01-19 20:35:51 +00:00
if ( animationID != span.id )
2025-01-03 12:09:23 +00:00
{
return;
2025-01-18 12:49:14 +00:00
}
2025-01-03 12:09:23 +00:00
2025-01-19 20:35:51 +00:00
var phase = span.phase;
2025-01-03 12:09:23 +00:00
var value = flashCurve.Sample( phase );
var phaseColor = color;
phaseColor.A = value * initialAlpha;
if ( light != null )
{
light.LightEnergy = value * flashEffect.lightFlashCurveScale;
light.LightColor = ComputeLightColor( color, phase );
}
_materials.ForEach(
( m )=>
{
if ( FlashEffect.MaterialMode.Flat_Standard3D == flashEffect.materialMode )
{
var sm = m as StandardMaterial3D;
sm.AlbedoColor = phaseColor;
}
else if ( FlashEffect.MaterialMode.Fresnel_FresnelOverlay == flashEffect.materialMode )
{
var sm = m as FresnelOverlayMaterial;
sm.albedo.Set( phaseColor );
}
else if ( FlashEffect.MaterialMode.Scan_ScanGradient == flashEffect.materialMode )
{
var sm = m as ScanGradientMaterial;
sm.albedo.Set( phaseColor );
sm.offset.Set( phase * 3 );
}
else if ( FlashEffect.MaterialMode.Shield_TriPlanarOverlay == flashEffect.materialMode )
{
var sm = m as TriPlanarOverlayMaterial;
sm.albedo.Set( phaseColor );
}
else if ( FlashEffect.MaterialMode.Custom_Material == flashEffect.materialMode )
{
var sm = m as ShaderMaterial;
flashEffect.customFlashColorProperty.Set( sm, phaseColor );
}
}
2025-01-19 20:35:51 +00:00
);
2025-01-03 12:09:23 +00:00
2025-01-08 18:46:17 +00:00
if ( type == TimeLineSpanUpdateType.End )
2025-01-03 12:09:23 +00:00
{
if ( light != null )
{
light.LightEnergy = 0;
light.LightColor = new Color( 0, 0, 0, 0 );
}
CancelAction( actionID );
DispatchEnd( actionID );
}
}
2025-01-19 20:35:51 +00:00
).id;
2025-01-03 12:09:23 +00:00
}
public override void CancelAction( int id )
{
if ( false && actionID != id )
{
// RJLog.Log( "actionID != id", "id", id, "actionID", actionID );
return;
}
if ( light != null )
{
// RJLog.Log( "Removing Light", light.Name );
Nodes.RemoveAndDelete( light );
light = null;
}
RemoveMaterials();
}
void RemoveMaterials()
{
if ( _materials.Count != targets.Length )
{
return;
}
for ( int i = 0; i < targets.Length; i++ )
{
Materials.RemoveOverlay( targets[ i ], _materials[ i ] );
}
_materials.Clear();
}
}
}