354 lines
10 KiB
C#
354 lines
10 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Text.RegularExpressions;
|
|
using System.Text;
|
|
using Godot;
|
|
|
|
namespace Rokojori
|
|
{
|
|
|
|
public enum HighlightActionType
|
|
{
|
|
Start,
|
|
End
|
|
}
|
|
|
|
public class HighlightAnimation
|
|
{
|
|
public Node3D[] targets;
|
|
public int tweenID = -1;
|
|
|
|
public List<Material> materials = new List<Material>();
|
|
public float phase;
|
|
|
|
|
|
}
|
|
|
|
[Tool]
|
|
[GlobalClass]
|
|
public partial class HighlightEffect:Resource
|
|
{
|
|
[Export]
|
|
public TimeLine timeline;
|
|
|
|
|
|
[ExportGroup( "Transition")]
|
|
|
|
[Export]
|
|
public float inDuration;
|
|
|
|
[Export]
|
|
public Curve inCurve = MathX.Curve( 0, 1 );
|
|
|
|
[Export]
|
|
public float outDuration;
|
|
|
|
[Export]
|
|
public Curve outCurve = MathX.Curve( 0, 1 );
|
|
|
|
[ExportGroup( "Color")]
|
|
[Export]
|
|
public HDRColor color;
|
|
|
|
[Export( PropertyHint.Range, "0,1")]
|
|
public float opacityModulationStrength = 0.5f;
|
|
|
|
[Export( PropertyHint.Range, "0,10")]
|
|
public float opacityModulationDuration = 0.5f;
|
|
|
|
[Export( PropertyHint.Range, "0,1")]
|
|
public float opacityModulationTransition = 1f;
|
|
|
|
public enum OutlineMaterialMode
|
|
{
|
|
Flat_Outline,
|
|
Scanner_FancyOutline,
|
|
Custom_Material
|
|
}
|
|
|
|
[ExportGroup( "Outline")]
|
|
[Export]
|
|
public OutlineMaterialMode outlineMaterialMode;
|
|
|
|
[Export]
|
|
public Material outlineCustomMaterial;
|
|
|
|
[Export]
|
|
public ColorPropertyName outlineCustomColorProperty;
|
|
|
|
public enum OverlayMaterialMode
|
|
{
|
|
Flat_Overlay,
|
|
Custom_Material
|
|
}
|
|
|
|
[ExportGroup( "Overlay")]
|
|
[Export( PropertyHint.Range, "0,1")]
|
|
public float overlayOpacity = 0.02f;
|
|
|
|
[Export]
|
|
public OverlayMaterialMode overlayMaterialMode;
|
|
|
|
[Export]
|
|
public Material overlayCustomMaterial;
|
|
|
|
[Export]
|
|
public ColorPropertyName overlayCustomColorProperty;
|
|
|
|
List<HighlightAnimation> _active = new List<HighlightAnimation>();
|
|
|
|
public void Highlight( HighlightActionType type, Node3D[] targets )
|
|
{
|
|
if ( HighlightActionType.Start == type )
|
|
{
|
|
StartHighlight( targets );
|
|
}
|
|
else if ( HighlightActionType.End == type )
|
|
{
|
|
EndHighlight( targets );
|
|
}
|
|
}
|
|
|
|
void StartHighlight( Node3D[] targets )
|
|
{
|
|
var animation = _active.Find( a => Arrays.AreEntriesEqual( a.targets, targets ) );
|
|
|
|
var hdrColor = color.GetHDRColor();
|
|
var colorTransparent = ColorX.Fade( hdrColor, 0 );
|
|
|
|
|
|
if ( animation == null )
|
|
{
|
|
animation = new HighlightAnimation();
|
|
animation.targets = targets;
|
|
|
|
_active.Add( animation );
|
|
|
|
Material material = null;
|
|
|
|
if ( OutlineMaterialMode.Flat_Outline == outlineMaterialMode )
|
|
{
|
|
var outlineMaterial = new OutlineMaterial();
|
|
outlineMaterial.albedo.Set( colorTransparent );
|
|
material = outlineMaterial;
|
|
|
|
outlineMaterial.opacityModulationDuration.Set( opacityModulationDuration );
|
|
outlineMaterial.opacityModulationStrength.Set( opacityModulationStrength );
|
|
}
|
|
else if ( OutlineMaterialMode.Scanner_FancyOutline == outlineMaterialMode )
|
|
{
|
|
var outlineMaterial = new FancyOutlineMaterial();
|
|
outlineMaterial.albedo.Set( colorTransparent );
|
|
material = outlineMaterial;
|
|
|
|
outlineMaterial.opacityModulationDuration.Set( opacityModulationDuration );
|
|
outlineMaterial.opacityModulationStrength.Set( opacityModulationStrength );
|
|
}
|
|
else if ( OutlineMaterialMode.Custom_Material == outlineMaterialMode )
|
|
{
|
|
material = (Material) outlineCustomMaterial.Duplicate();
|
|
outlineCustomColorProperty.Set( material, colorTransparent );
|
|
}
|
|
|
|
|
|
if ( OverlayMaterialMode.Flat_Overlay == overlayMaterialMode )
|
|
{
|
|
var overlay = new OverlayMaterial();
|
|
overlay.albedo.Set( ColorX.SetAlpha( hdrColor, 0 ) );
|
|
material.NextPass = overlay;
|
|
|
|
overlay.opacityModulationDuration.Set( opacityModulationDuration );
|
|
overlay.opacityModulationStrength.Set( opacityModulationStrength );
|
|
}
|
|
else if ( OverlayMaterialMode.Custom_Material == overlayMaterialMode )
|
|
{
|
|
var overlay = (Material) overlayCustomMaterial.Duplicate();
|
|
overlayCustomColorProperty.Set( overlay, colorTransparent );
|
|
material.NextPass = overlay;
|
|
}
|
|
|
|
|
|
|
|
Arrays.ForEach( targets,
|
|
t =>
|
|
{
|
|
var m = (Material) material.Duplicate( true );
|
|
|
|
animation.materials.Add( m );
|
|
Materials.AddOverlay( t, m );
|
|
}
|
|
);
|
|
|
|
}
|
|
|
|
var startPhase = animation.phase;
|
|
|
|
animation.tweenID = TimeLineManager.ScheduleSpanIn( timeline, 0, inDuration,
|
|
( span, type )=>
|
|
{
|
|
|
|
if ( animation.tweenID != span.id )
|
|
{
|
|
return;
|
|
}
|
|
|
|
var phase = span.phase;
|
|
|
|
|
|
animation.phase = MathX.Map( phase, 0, 1, startPhase, 1 );
|
|
|
|
var p = animation.phase;
|
|
|
|
if ( inCurve != null )
|
|
{
|
|
p = inCurve.Sample( p );
|
|
}
|
|
|
|
var transitionModulationStrength = Mathf.Lerp(
|
|
opacityModulationStrength, opacityModulationStrength * p,
|
|
opacityModulationTransition );
|
|
|
|
|
|
var tweenColor = ColorX.Fade( hdrColor, p );
|
|
|
|
if ( TimeLineSpanUpdateType.End == type )
|
|
{
|
|
tweenColor = hdrColor;
|
|
animation.phase = 1;
|
|
}
|
|
|
|
animation.materials.ForEach(
|
|
( m )=>
|
|
{
|
|
if ( OutlineMaterialMode.Flat_Outline == outlineMaterialMode )
|
|
{
|
|
var outlineMaterial = ( OutlineMaterial ) m;
|
|
outlineMaterial.albedo.Set( tweenColor );
|
|
outlineMaterial.opacityModulationStrength.Set( transitionModulationStrength );
|
|
}
|
|
else if ( OutlineMaterialMode.Scanner_FancyOutline == outlineMaterialMode )
|
|
{
|
|
var outlineMaterial = ( FancyOutlineMaterial ) m;
|
|
outlineMaterial.albedo.Set( tweenColor );
|
|
outlineMaterial.opacityModulationStrength.Set( transitionModulationStrength );
|
|
}
|
|
else if ( OutlineMaterialMode.Custom_Material == outlineMaterialMode )
|
|
{
|
|
outlineCustomColorProperty.Set( m, tweenColor);
|
|
}
|
|
|
|
if ( OverlayMaterialMode.Flat_Overlay == overlayMaterialMode )
|
|
{
|
|
var overlay = (OverlayMaterial) m.NextPass;
|
|
overlay.albedo.Set( ColorX.Fade( tweenColor, overlayOpacity ) );
|
|
overlay.opacityModulationStrength.Set( transitionModulationStrength );
|
|
}
|
|
else if ( OutlineMaterialMode.Custom_Material == outlineMaterialMode )
|
|
{
|
|
var material = (OverlayMaterial) m.NextPass;
|
|
outlineCustomColorProperty.Set( m, tweenColor);
|
|
}
|
|
|
|
|
|
|
|
}
|
|
);
|
|
}
|
|
).id;
|
|
}
|
|
|
|
void EndHighlight( Node3D[] targets )
|
|
{
|
|
var animation = _active.Find( a => Arrays.AreEntriesEqual( a.targets, targets ) );
|
|
|
|
if ( animation == null )
|
|
{
|
|
return;
|
|
}
|
|
|
|
var startPhase = animation.phase;
|
|
var hdrColor = ColorX.Fade( color.GetHDRColor(), startPhase );
|
|
var colorTransparent = ColorX.Fade( hdrColor, 0 );
|
|
|
|
animation.tweenID = TimeLineManager.ScheduleSpanIn( timeline, 0, outDuration,
|
|
( span, type )=>
|
|
{
|
|
|
|
if ( animation.tweenID != span.id )
|
|
{
|
|
return;
|
|
}
|
|
|
|
animation.phase = MathX.Map( span.phase, 0, 1, startPhase, 0 );
|
|
|
|
var p = animation.phase;
|
|
|
|
if ( outCurve != null )
|
|
{
|
|
p = outCurve.Sample( p );
|
|
}
|
|
|
|
var transitionModulationStrength = Mathf.Lerp(
|
|
opacityModulationStrength, opacityModulationStrength * p,
|
|
opacityModulationTransition );
|
|
|
|
var tweenColor = ColorX.Fade( hdrColor, p );
|
|
|
|
if ( TimeLineSpanUpdateType.End == type )
|
|
{
|
|
tweenColor = colorTransparent;
|
|
animation.phase = 0;
|
|
|
|
for ( int i = 0; i < animation.targets.Length; i ++ )
|
|
{
|
|
Materials.RemoveOverlay( targets[ i ], animation.materials[ i ] );
|
|
}
|
|
|
|
_active.Remove( animation );
|
|
}
|
|
else
|
|
{
|
|
animation.materials.ForEach(
|
|
( m )=>
|
|
{
|
|
if ( OutlineMaterialMode.Flat_Outline == outlineMaterialMode )
|
|
{
|
|
var outlineMaterial = ( OutlineMaterial ) m;
|
|
outlineMaterial.albedo.Set( tweenColor );
|
|
outlineMaterial.opacityModulationStrength.Set( transitionModulationStrength );
|
|
}
|
|
else if ( OutlineMaterialMode.Scanner_FancyOutline == outlineMaterialMode )
|
|
{
|
|
var outlineMaterial = ( FancyOutlineMaterial ) m;
|
|
outlineMaterial.albedo.Set( tweenColor );
|
|
outlineMaterial.opacityModulationStrength.Set( transitionModulationStrength );
|
|
}
|
|
else if ( OutlineMaterialMode.Custom_Material == outlineMaterialMode )
|
|
{
|
|
outlineCustomColorProperty.Set( m, tweenColor );
|
|
}
|
|
|
|
if ( OverlayMaterialMode.Flat_Overlay == overlayMaterialMode )
|
|
{
|
|
var overlay = (OverlayMaterial) m.NextPass;
|
|
overlay.albedo.Set( ColorX.Fade( tweenColor, overlayOpacity ) );
|
|
overlay.opacityModulationStrength.Set( transitionModulationStrength );
|
|
}
|
|
else if ( OutlineMaterialMode.Custom_Material == outlineMaterialMode )
|
|
{
|
|
var material = (OverlayMaterial) m.NextPass;
|
|
outlineCustomColorProperty.Set( m, tweenColor);
|
|
}
|
|
|
|
}
|
|
);
|
|
}
|
|
|
|
}
|
|
).id;
|
|
|
|
|
|
}
|
|
|
|
}
|
|
} |