Particles Udpate
This commit is contained in:
parent
68105b2275
commit
4bbed6ba6c
|
|
@ -36,6 +36,8 @@ namespace Rokojori
|
|||
return _dispatchCounter;
|
||||
}
|
||||
|
||||
public bool isRunning => _running.Count > 0;
|
||||
|
||||
public readonly EventSlot<SequenceActionFinishedEvent> onSequenceDone = new EventSlot<SequenceActionFinishedEvent>();
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
using Godot;
|
||||
|
||||
using Rokojori.Extensions;
|
||||
namespace Rokojori;
|
||||
|
||||
[Tool]
|
||||
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/Action.svg")]
|
||||
public abstract partial class BehaviorBranch:Node
|
||||
{
|
||||
[Export]
|
||||
public bool invert = false;
|
||||
|
||||
protected virtual bool _IsBranchActive( Brain brain )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool IsBranchActive( Brain brain )
|
||||
{
|
||||
var active = _IsBranchActive( brain );
|
||||
|
||||
if ( invert )
|
||||
{
|
||||
active = ! active;
|
||||
}
|
||||
|
||||
return active;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://7bflktj7bbw4
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
using Godot;
|
||||
|
||||
using Rokojori.Extensions;
|
||||
namespace Rokojori;
|
||||
|
||||
[Tool]
|
||||
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/Action.svg")]
|
||||
public abstract partial class BehaviorMovement:Node
|
||||
{
|
||||
public abstract void GoToPosition( Vector3 worldPosition );
|
||||
public abstract void LookAtPosition( Vector3 worldPosition );
|
||||
|
||||
public abstract void GoTo( Node3D node );
|
||||
public abstract void Follow( Node3D node );
|
||||
public abstract void LookAt( Node3D node );
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://r3oqbmly415i
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
using Godot;
|
||||
|
||||
using Rokojori.Extensions;
|
||||
namespace Rokojori;
|
||||
|
||||
[Tool]
|
||||
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/Action.svg")]
|
||||
public partial class BehaviorSequence:Sequence
|
||||
{
|
||||
[Export]
|
||||
public bool loop = false;
|
||||
|
||||
[Export]
|
||||
public bool isExclusive = true;
|
||||
|
||||
[Export]
|
||||
public bool reinitialize = false;
|
||||
|
||||
Brain _brain;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
base._Ready();
|
||||
|
||||
_brain = NodesWalker.Get().GetParentWithType<Brain>( this );
|
||||
|
||||
onSequenceDone.AddAction( OnDone );
|
||||
}
|
||||
|
||||
void OnDone( SequenceActionFinishedEvent ev )
|
||||
{
|
||||
if ( _brain == null || _brain.activeSequence != this )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( loop )
|
||||
{
|
||||
Trigger();
|
||||
}
|
||||
else
|
||||
{
|
||||
_brain.Trigger();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://dsdwv5u60cen
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
using Godot;
|
||||
|
||||
using Rokojori.Extensions;
|
||||
namespace Rokojori;
|
||||
|
||||
[Tool]
|
||||
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/Action.svg")]
|
||||
public partial class Brain:Action
|
||||
{
|
||||
[Export]
|
||||
public Receptor[] receptors;
|
||||
|
||||
[Export]
|
||||
public Node behaviorRoot;
|
||||
|
||||
[Export]
|
||||
public BehaviorSequence activeSequence;
|
||||
|
||||
bool _paused = false;
|
||||
|
||||
public bool paused => _paused;
|
||||
|
||||
public void SetPaused( bool value )
|
||||
{
|
||||
_paused = value;
|
||||
}
|
||||
|
||||
protected override void _OnTrigger()
|
||||
{
|
||||
if ( _paused )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( activeSequence != null && activeSequence.isExclusive && activeSequence.isRunning )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var resolved = Resolve();
|
||||
|
||||
if ( resolved == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( resolved == activeSequence )
|
||||
{
|
||||
if ( activeSequence.reinitialize )
|
||||
{
|
||||
activeSequence.CancelAllRunning();
|
||||
activeSequence.Trigger();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var previous = activeSequence;
|
||||
activeSequence = resolved;
|
||||
|
||||
if ( previous != null )
|
||||
{
|
||||
previous.CancelAllRunning();
|
||||
}
|
||||
|
||||
activeSequence.Trigger();
|
||||
}
|
||||
|
||||
BehaviorSequence Resolve()
|
||||
{
|
||||
if ( behaviorRoot == null )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return ResolveIn( behaviorRoot );
|
||||
}
|
||||
|
||||
BehaviorSequence ResolveIn( Node parent )
|
||||
{
|
||||
var walker = NodesWalker.Get();
|
||||
var numChildren = walker.NumChildren( parent );
|
||||
|
||||
for ( int i = 0; i < numChildren; i++ )
|
||||
{
|
||||
var child = walker.ChildAt( parent, i );
|
||||
|
||||
if ( child is BehaviorSequence sequence )
|
||||
{
|
||||
return sequence;
|
||||
}
|
||||
|
||||
if ( child is BehaviorBranch branch )
|
||||
{
|
||||
if ( branch.IsBranchActive( this ) )
|
||||
{
|
||||
var found = ResolveIn( branch );
|
||||
|
||||
if ( found != null )
|
||||
{
|
||||
return found;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://dm2je7akh1jyi
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
using Godot;
|
||||
|
||||
using Rokojori.Extensions;
|
||||
namespace Rokojori;
|
||||
|
||||
[Tool]
|
||||
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/Action.svg")]
|
||||
public partial class BrainControl:Action
|
||||
{
|
||||
public enum Mode
|
||||
{
|
||||
Start,
|
||||
Pause,
|
||||
Resume,
|
||||
Toggle
|
||||
}
|
||||
|
||||
[Export]
|
||||
public Brain brain;
|
||||
|
||||
[Export]
|
||||
public Mode mode;
|
||||
|
||||
protected override void _OnTrigger()
|
||||
{
|
||||
if ( brain == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch ( mode )
|
||||
{
|
||||
case Mode.Start:
|
||||
StartBrain();
|
||||
break;
|
||||
|
||||
case Mode.Pause:
|
||||
brain.SetPaused( true );
|
||||
break;
|
||||
|
||||
case Mode.Resume:
|
||||
brain.SetPaused( false );
|
||||
break;
|
||||
|
||||
case Mode.Toggle:
|
||||
brain.SetPaused( ! brain.paused );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void StartBrain()
|
||||
{
|
||||
brain.SetPaused( false );
|
||||
|
||||
if ( brain.receptors != null )
|
||||
{
|
||||
foreach ( var receptor in brain.receptors )
|
||||
{
|
||||
if ( receptor != null )
|
||||
{
|
||||
receptor.Start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
brain.Trigger();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://k2rbcvsu64ap
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
using Godot;
|
||||
|
||||
using Rokojori.Extensions;
|
||||
namespace Rokojori;
|
||||
|
||||
[Tool]
|
||||
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/Action.svg")]
|
||||
public partial class CharacterBodyBehaviorMovement:BehaviorMovement
|
||||
{
|
||||
[Export]
|
||||
public CharacterBody3D body;
|
||||
|
||||
[Export]
|
||||
public float moveSpeed = 5f;
|
||||
|
||||
[Export]
|
||||
public float arrivalDistance = 0.1f;
|
||||
|
||||
Node3D _followTarget;
|
||||
Vector3? _targetPosition;
|
||||
|
||||
public override void GoToPosition( Vector3 worldPosition )
|
||||
{
|
||||
_followTarget = null;
|
||||
_targetPosition = worldPosition;
|
||||
}
|
||||
|
||||
public override void LookAtPosition( Vector3 worldPosition )
|
||||
{
|
||||
if ( body == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var direction = worldPosition - body.GlobalPosition;
|
||||
direction.Y = 0;
|
||||
|
||||
if ( direction.LengthSquared() < 0.0001f )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
body.GlobalTransform = new Transform3D( Basis.LookingAt( direction, Vector3.Up ), body.GlobalPosition );
|
||||
}
|
||||
|
||||
public override void GoTo( Node3D node )
|
||||
{
|
||||
_followTarget = null;
|
||||
_targetPosition = node == null ? null : node.GlobalPosition;
|
||||
}
|
||||
|
||||
public override void Follow( Node3D node )
|
||||
{
|
||||
_followTarget = node;
|
||||
_targetPosition = null;
|
||||
}
|
||||
|
||||
public override void LookAt( Node3D node )
|
||||
{
|
||||
if ( node == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LookAtPosition( node.GlobalPosition );
|
||||
}
|
||||
|
||||
public override void _PhysicsProcess( double delta )
|
||||
{
|
||||
if ( body == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Vector3? target = _followTarget != null ? _followTarget.GlobalPosition : _targetPosition;
|
||||
|
||||
if ( target == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var toTarget = target.Value - body.GlobalPosition;
|
||||
toTarget.Y = 0;
|
||||
|
||||
if ( toTarget.Length() <= arrivalDistance )
|
||||
{
|
||||
body.Velocity = Vector3.Zero;
|
||||
body.MoveAndSlide();
|
||||
return;
|
||||
}
|
||||
|
||||
var direction = toTarget.Normalized();
|
||||
|
||||
body.Velocity = direction * moveSpeed;
|
||||
body.MoveAndSlide();
|
||||
|
||||
LookAtPosition( body.GlobalPosition + direction );
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://btsle0n13r6hy
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
using Godot;
|
||||
|
||||
using Rokojori.Extensions;
|
||||
namespace Rokojori;
|
||||
|
||||
[Tool]
|
||||
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/Action.svg")]
|
||||
public partial class ConditionBranch:BehaviorBranch
|
||||
{
|
||||
[Export]
|
||||
public SceneCondition sceneCondition;
|
||||
|
||||
protected override bool _IsBranchActive( Brain brain )
|
||||
{
|
||||
return SceneCondition.Evaluate( sceneCondition );
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://1ywnbv1h1gik
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
using Godot;
|
||||
|
||||
using Rokojori.Extensions;
|
||||
namespace Rokojori;
|
||||
|
||||
[Tool]
|
||||
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/Action.svg")]
|
||||
public partial class FollowBehavior:BehaviorSequence
|
||||
{
|
||||
[Export]
|
||||
public BehaviorMovement movement;
|
||||
|
||||
[Export]
|
||||
public Node3D target;
|
||||
|
||||
protected override void _OnTrigger()
|
||||
{
|
||||
if ( movement != null )
|
||||
{
|
||||
movement.Follow( target );
|
||||
}
|
||||
|
||||
base._OnTrigger();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://32dsw4a65vh0
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
using Godot;
|
||||
using System.Collections.Generic;
|
||||
using Rokojori.Extensions;
|
||||
namespace Rokojori;
|
||||
|
||||
[Tool]
|
||||
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/Action.svg")]
|
||||
public partial class Receptor:Action
|
||||
{
|
||||
[Export]
|
||||
public SceneCondition sceneCondition;
|
||||
|
||||
[Export( PropertyHint.Range, "0.1,100")]
|
||||
public float receiptionTriggerCoverage = 75f;
|
||||
|
||||
[Export( PropertyHint.Range, "10,2000")]
|
||||
public float receiptionWindowDurationMS = 500f;
|
||||
|
||||
[Export( PropertyHint.Range, "10,1000")]
|
||||
public float tickRateMS = 100f;
|
||||
|
||||
[Export]
|
||||
public Timeline timeline;
|
||||
|
||||
int resultSize => Mathf.CeilToInt( receiptionWindowDurationMS / tickRateMS );
|
||||
|
||||
RingBuffer<bool> _resultsBuffer;
|
||||
|
||||
bool _activated = false;
|
||||
|
||||
public bool activated => _activated;
|
||||
|
||||
bool _active = false;
|
||||
|
||||
public bool active => _active;
|
||||
|
||||
int _eventID = -1;
|
||||
|
||||
public void Start()
|
||||
{
|
||||
if ( _active )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_active = true;
|
||||
|
||||
var duration = tickRateMS / 1000f;
|
||||
var tle = TimelineManager.ScheduleLoopEvent( timeline, duration, 0, tle => Sample() );
|
||||
_eventID = tle.id;
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
if ( ! _active )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_active = false;
|
||||
|
||||
TimelineManager.RemoveEvent( timeline, _eventID );
|
||||
_eventID = -1;
|
||||
}
|
||||
|
||||
protected override void _OnTrigger()
|
||||
{
|
||||
Sample();
|
||||
}
|
||||
|
||||
void Sample()
|
||||
{
|
||||
if ( sceneCondition == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( _resultsBuffer == null || _resultsBuffer.capacity != resultSize )
|
||||
{
|
||||
_resultsBuffer = new RingBuffer<bool>( resultSize );
|
||||
}
|
||||
|
||||
_resultsBuffer.Add( sceneCondition.Evaluate() );
|
||||
|
||||
if ( _resultsBuffer.count != resultSize )
|
||||
{
|
||||
_activated = false;
|
||||
return;
|
||||
}
|
||||
|
||||
var numActive = _resultsBuffer.CountItems( b => b );
|
||||
_activated = numActive / (float) resultSize >= receiptionTriggerCoverage / 100f;
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://dr0xqvmp8xu8c
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
using Godot;
|
||||
|
||||
using Rokojori.Extensions;
|
||||
namespace Rokojori;
|
||||
|
||||
[Tool]
|
||||
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/Action.svg")]
|
||||
public partial class ReceptorBranch:BehaviorBranch
|
||||
{
|
||||
[Export]
|
||||
public Receptor receptor;
|
||||
|
||||
protected override bool _IsBranchActive( Brain brain )
|
||||
{
|
||||
return receptor != null && receptor.activated;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://5kitnn4mtd1y
|
||||
|
|
@ -35,5 +35,12 @@ namespace Rokojori
|
|||
|
||||
return _resource;
|
||||
}
|
||||
|
||||
public T GetDuplicate( bool deep = false )
|
||||
{
|
||||
var referenced = Get();
|
||||
|
||||
return referenced.Duplicate( deep ) as T;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Rokojori.Extensions;
|
||||
namespace Rokojori;
|
||||
|
||||
|
||||
public class RingBuffer<T>
|
||||
{
|
||||
protected readonly T[] _buffer;
|
||||
protected int _head;
|
||||
protected int _count;
|
||||
|
||||
public RingBuffer( int capacity )
|
||||
{
|
||||
_buffer = new T[capacity];
|
||||
}
|
||||
|
||||
public int count => _count;
|
||||
public int capacity => _buffer.Length;
|
||||
|
||||
public void ForEach( System.Action<T> callback )
|
||||
{
|
||||
for ( int i = 0; i < _count; i++ )
|
||||
{
|
||||
callback( this[ i ] );
|
||||
}
|
||||
}
|
||||
|
||||
public int CountItems( System.Predicate<T> predicate )
|
||||
{
|
||||
var num = 0;
|
||||
|
||||
for ( int i = 0; i < _count; i++ )
|
||||
{
|
||||
if ( predicate( this[ i ] ) )
|
||||
{
|
||||
num ++;
|
||||
}
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
public void Add( T item )
|
||||
{
|
||||
int index = (_head + _count) % capacity;
|
||||
|
||||
_buffer[index] = item;
|
||||
|
||||
if (_count == capacity)
|
||||
{
|
||||
_head = (_head + 1) % capacity;
|
||||
}
|
||||
else
|
||||
{
|
||||
_count ++;
|
||||
}
|
||||
}
|
||||
|
||||
public T this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
if ( (uint)index >= (uint)_count )
|
||||
{
|
||||
throw new System.ArgumentOutOfRangeException( nameof( index ) );
|
||||
}
|
||||
|
||||
return _buffer[ ( _head + index ) % capacity ];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://bpqul7npdcg3q
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
// NOTE: Shader automatically converted from Godot Engine 4.7.stable.mono's StandardMaterial3D.
|
||||
|
||||
shader_type spatial;
|
||||
render_mode blend_mix, depth_draw_opaque, cull_disabled, diffuse_burley, specular_schlick_ggx, unshaded;
|
||||
|
||||
|
||||
uniform float meshScale = 1.0;
|
||||
|
||||
|
||||
void vertex()
|
||||
{
|
||||
|
||||
MODELVIEW_MATRIX = VIEW_MATRIX * mat4(
|
||||
MAIN_CAM_INV_VIEW_MATRIX[0],
|
||||
MAIN_CAM_INV_VIEW_MATRIX[1],
|
||||
MAIN_CAM_INV_VIEW_MATRIX[2],
|
||||
MODEL_MATRIX[3]);
|
||||
|
||||
MODELVIEW_MATRIX = MODELVIEW_MATRIX * mat4(
|
||||
vec4(length(MODEL_MATRIX[0].xyz) * meshScale, 0.0, 0.0, 0.0),
|
||||
vec4(0.0, length(MODEL_MATRIX[1].xyz) * meshScale, 0.0, 0.0),
|
||||
vec4(0.0, 0.0, length(MODEL_MATRIX[2].xyz) * meshScale, 0.0),
|
||||
vec4(0.0, 0.0, 0.0, 1.0));
|
||||
|
||||
MODELVIEW_NORMAL_MATRIX = mat3(MODELVIEW_MATRIX);
|
||||
}
|
||||
|
||||
void fragment()
|
||||
{
|
||||
|
||||
float d = distance( UV, vec2(0.5) );
|
||||
float a = 1.0 - clamp( d / 0.5, 0.0, 1.0);
|
||||
|
||||
|
||||
ALBEDO = COLOR.rgb;
|
||||
|
||||
ALPHA *= a * COLOR.a;
|
||||
ALPHA_SCISSOR_THRESHOLD = 0.01;
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://c2aykxlioyvu7
|
||||
Binary file not shown.
|
|
@ -0,0 +1,110 @@
|
|||
using Godot;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Rokojori.Extensions;
|
||||
namespace Rokojori;
|
||||
|
||||
[Tool]
|
||||
[GlobalClass ]
|
||||
public partial class EmberVFXData:ParticleVFXData
|
||||
{
|
||||
public static readonly CachedResource<ParticleProcessMaterial> EmberExplodeMaterial = new CachedResource<ParticleProcessMaterial>(
|
||||
"res://addons/rokojori_action_library/Runtime/VFX/ParticleVFX/Shared/ProcessMaterials/Ember-Explode.material"
|
||||
);
|
||||
|
||||
public static readonly CachedResource<ShaderMaterial> EmberCircleMaterial = new CachedResource<ShaderMaterial>(
|
||||
"res://addons/rokojori_action_library/Runtime/VFX/ParticleVFX/Embers/Ember Circle.material"
|
||||
);
|
||||
|
||||
public static readonly CachedResource<QuadMesh> QuadMesh = new CachedResource<QuadMesh>(
|
||||
"res://addons/rokojori_action_library/Runtime/VFX/ParticleVFX/Shared/Passes/Quad Draw Pass.tres"
|
||||
);
|
||||
|
||||
public static readonly CachedResource<Gradient> GradientDefault = new CachedResource<Gradient>(
|
||||
" res://addons/rokojori_action_library/Runtime/VFX/ParticleVFX/Shared/Gradient-Default.tres"
|
||||
);
|
||||
|
||||
|
||||
|
||||
public EmberVFXPreset preset;
|
||||
public GpuParticles3D particles;
|
||||
public PlayParticles playParticles;
|
||||
public ParticleProcessMaterial processMaterial;
|
||||
public Material material;
|
||||
|
||||
public void Assign( ParticleVFX vfx )
|
||||
{
|
||||
vfx._SetParticlesVFXData( this );
|
||||
|
||||
particles = vfx.GetOrCreateChild<GpuParticles3D>();
|
||||
particles.DrawPass1 = QuadMesh.Get();
|
||||
|
||||
playParticles = vfx.GetOrCreateChild<PlayParticles>();
|
||||
playParticles.particles3D = particles;
|
||||
playParticles.usePooling = preset.usePooling;
|
||||
|
||||
processMaterial = EmberExplodeMaterial.GetDuplicate();
|
||||
material = EmberCircleMaterial.GetDuplicate();
|
||||
|
||||
RJLog.Log( material, EmberCircleMaterial.GetDuplicate() );
|
||||
|
||||
particles.ProcessMaterial = processMaterial;
|
||||
particles.MaterialOverride = material;
|
||||
|
||||
UpdateSettings( vfx );
|
||||
}
|
||||
|
||||
public void Play( ParticleVFX vfx )
|
||||
{
|
||||
playParticles.Trigger();
|
||||
}
|
||||
|
||||
public static FloatPropertyName meshScale = FloatPropertyName.Create( "meshScale" );
|
||||
|
||||
public void UpdateSettings( ParticleVFX vfx )
|
||||
{
|
||||
if ( preset == null || processMaterial == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateCoreSettings( preset, particles );
|
||||
|
||||
processMaterial.Color = preset.color * preset.colorIntensity;
|
||||
|
||||
|
||||
var rampTexture = processMaterial.ColorRamp as GradientTexture1D;
|
||||
|
||||
if ( rampTexture == null )
|
||||
{
|
||||
rampTexture = new GradientTexture1D();
|
||||
processMaterial.ColorRamp = rampTexture;
|
||||
}
|
||||
|
||||
rampTexture.Gradient = preset.gradient ?? GradientDefault.Get();
|
||||
|
||||
|
||||
preset.movement?.UpdateSettings( processMaterial, vfx );
|
||||
preset.volume?.UpdateSettings( processMaterial, vfx );
|
||||
|
||||
meshScale.Set( material, preset.meshScale );
|
||||
|
||||
// processMaterial.ScaleMin = preset.meshScale;
|
||||
// processMaterial.ScaleMax = preset.meshScale;
|
||||
|
||||
// processMaterial.InitialVelocityMin = preset.minVelocity + preset.velocityOffset;
|
||||
// processMaterial.InitialVelocityMax = preset.maxVelocity + preset.velocityOffset;
|
||||
|
||||
// processMaterial.Gravity = preset.gravityDirection * preset.gravityMultiplier;
|
||||
|
||||
// processMaterial.DampingMin = preset.minDamping + preset.dampingOffset;
|
||||
// processMaterial.DampingMax = preset.maxDamping + preset.dampingOffset;
|
||||
}
|
||||
|
||||
#if TOOLS
|
||||
public void DrawGizmo( ParticleVFX vfx, EditorNode3DGizmoPlugin gizmoPlugin, EditorNode3DGizmo gizmo )
|
||||
{
|
||||
preset.volume?.DrawGizmo( vfx, gizmoPlugin, gizmo );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://ycs4v67gaahy
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
using Godot;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Rokojori.Extensions;
|
||||
namespace Rokojori;
|
||||
|
||||
[Tool]
|
||||
[GlobalClass ]
|
||||
public partial class EmberVFXPreset:ParticleVFXPreset
|
||||
{
|
||||
[Export]
|
||||
public Color color;
|
||||
|
||||
[Export]
|
||||
public float colorIntensity = 1f ;
|
||||
|
||||
|
||||
[Export]
|
||||
public Gradient gradient;
|
||||
|
||||
[Export]
|
||||
public float meshScale = 1f;
|
||||
|
||||
|
||||
[Export]
|
||||
public ParticleVFXVolumeType volume = new SphereParticleVFXVolumeType();
|
||||
|
||||
[Export]
|
||||
public ParticleVFXMovementType movement = new LinearParticleVFXMovementType();
|
||||
|
||||
public override void Initialize( ParticleVFX vfx )
|
||||
{
|
||||
vfx.DestroyChildren();
|
||||
|
||||
var data = new EmberVFXData();
|
||||
data.preset = this;
|
||||
data.Assign( vfx );
|
||||
}
|
||||
|
||||
public override void Play( ParticleVFX vfx )
|
||||
{
|
||||
var data = vfx.GetDataAs<EmberVFXData>();
|
||||
|
||||
if ( data == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
data.Play( vfx );
|
||||
}
|
||||
|
||||
public override void UpdateSettings( ParticleVFX vfx )
|
||||
{
|
||||
|
||||
var data = vfx.GetDataAs<EmberVFXData>();
|
||||
|
||||
if ( data == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! GodotObject.IsInstanceValid( data.particles ) )
|
||||
{
|
||||
Initialize( vfx );
|
||||
}
|
||||
|
||||
data.UpdateSettings( vfx );
|
||||
}
|
||||
|
||||
#if TOOLS
|
||||
public override void DrawGizmo( ParticleVFX vfx, EditorNode3DGizmoPlugin gizmoPlugin, EditorNode3DGizmo gizmo )
|
||||
{
|
||||
var data = vfx.GetDataAs<EmberVFXData>();
|
||||
|
||||
data?.DrawGizmo( vfx, gizmoPlugin, gizmo );
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://caku386ymhxnx
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
using Godot;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Rokojori.Extensions;
|
||||
namespace Rokojori;
|
||||
|
||||
[Tool]
|
||||
[GlobalClass ]
|
||||
public partial class ParticleVFX:Node3D
|
||||
#if TOOLS
|
||||
, GizmoDrawer
|
||||
#endif
|
||||
{
|
||||
ParticleVFXPreset _preset;
|
||||
|
||||
[Export]
|
||||
public ParticleVFXPreset preset
|
||||
{
|
||||
get => _preset;
|
||||
set
|
||||
{
|
||||
_preset = value;
|
||||
|
||||
if ( _preset != null )
|
||||
{
|
||||
_preset.Initialize( this );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Export]
|
||||
public bool edit = false;
|
||||
|
||||
#if TOOLS
|
||||
public override void _Process( double delta )
|
||||
{
|
||||
if ( preset == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( edit )
|
||||
{
|
||||
preset.UpdateSettings( this );
|
||||
}
|
||||
|
||||
UpdateGizmos();
|
||||
}
|
||||
|
||||
public void DrawGizmo( EditorNode3DGizmoPlugin gizmoPlugin, EditorNode3DGizmo gizmo )
|
||||
{
|
||||
gizmo.Clear();
|
||||
|
||||
preset?.DrawGizmo( this, gizmoPlugin, gizmo );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
protected ParticleVFXData _data;
|
||||
public T GetDataAs<T>() where T:ParticleVFXData
|
||||
{
|
||||
return _data as T;
|
||||
}
|
||||
|
||||
public void _SetParticlesVFXData( ParticleVFXData data )
|
||||
{
|
||||
_data = data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://citabajvt3rae
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
using Godot;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Rokojori.Extensions;
|
||||
namespace Rokojori;
|
||||
|
||||
[Tool]
|
||||
[GlobalClass ]
|
||||
public abstract partial class ParticleVFXData:Resource
|
||||
{
|
||||
protected void UpdateCoreSettings( ParticleVFXPreset preset, GpuParticles3D particles )
|
||||
{
|
||||
if ( preset == null || particles == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( particles.Amount != preset.maxParticles )
|
||||
{
|
||||
particles.Amount = preset.maxParticles;
|
||||
}
|
||||
|
||||
if ( particles.AmountRatio != preset.maxParticlesAmount )
|
||||
{
|
||||
particles.AmountRatio = preset.maxParticlesAmount;
|
||||
}
|
||||
|
||||
particles.Lifetime = preset.lifeTimeDuration;
|
||||
particles.SpeedScale = preset.timeSpeed;
|
||||
|
||||
if ( particles.OneShot != preset.oneShot )
|
||||
{
|
||||
particles.OneShot = preset.oneShot;
|
||||
}
|
||||
|
||||
particles.Explosiveness = preset.explosiveness;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://1028ohth6hae
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
using Godot;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Rokojori.Extensions;
|
||||
namespace Rokojori;
|
||||
|
||||
[Tool]
|
||||
[GlobalClass ]
|
||||
public abstract partial class ParticleVFXPreset:Resource
|
||||
{
|
||||
[ExportGroup("Core")]
|
||||
[Export]
|
||||
public int maxParticles = 1000;
|
||||
|
||||
[Export( PropertyHint.Range, "0,1" )]
|
||||
public float maxParticlesAmount = 1f;
|
||||
|
||||
[Export]
|
||||
public float lifeTimeDuration = 0.3f;
|
||||
|
||||
[Export]
|
||||
public float timeSpeed = 1f;
|
||||
|
||||
[Export]
|
||||
public bool oneShot = false;
|
||||
|
||||
[Export]
|
||||
public float explosiveness = 1f;
|
||||
|
||||
[Export]
|
||||
public bool usePooling;
|
||||
|
||||
|
||||
public abstract void Initialize( ParticleVFX vfx );
|
||||
public abstract void Play( ParticleVFX vfx );
|
||||
public abstract void UpdateSettings( ParticleVFX vfx );
|
||||
|
||||
#if TOOLS
|
||||
public abstract void DrawGizmo( ParticleVFX vfx, EditorNode3DGizmoPlugin gizmoPlugin, EditorNode3DGizmo gizmo );
|
||||
#endif
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://dxoc2c4v20m0k
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,8 @@
|
|||
[gd_resource type="GradientTexture1D" format=3 uid="uid://dfg5cmvo1bqt6"]
|
||||
|
||||
[sub_resource type="Gradient" id="Gradient_7w6kc"]
|
||||
offsets = PackedFloat32Array(1)
|
||||
colors = PackedColorArray(1, 1, 1, 1)
|
||||
|
||||
[resource]
|
||||
gradient = SubResource("Gradient_7w6kc")
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
using Godot;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Rokojori.Extensions;
|
||||
namespace Rokojori;
|
||||
|
||||
[Tool]
|
||||
[GlobalClass ]
|
||||
public partial class LinearParticleVFXMovementType:ParticleVFXMovementType
|
||||
{
|
||||
[Export]
|
||||
public float velocityOffset = 0f;
|
||||
|
||||
[Export]
|
||||
public float minVelocity = 0f;
|
||||
|
||||
[Export]
|
||||
public float maxVelocity = 1f;
|
||||
|
||||
[Export]
|
||||
public Vector3 gravityDirection = Vector3.Down * 10;
|
||||
|
||||
[Export]
|
||||
public float gravityMultiplier = 1f;
|
||||
|
||||
[Export]
|
||||
public float dampingOffset = 0f;
|
||||
|
||||
[Export]
|
||||
public float minDamping = 0f;
|
||||
|
||||
[Export]
|
||||
public float maxDamping = 0f;
|
||||
|
||||
public override void UpdateSettings( ParticleProcessMaterial processMaterial, ParticleVFX vfx )
|
||||
{
|
||||
processMaterial.InitialVelocityMin = minVelocity + velocityOffset;
|
||||
processMaterial.InitialVelocityMax = maxVelocity + velocityOffset;
|
||||
|
||||
processMaterial.Gravity = gravityDirection * gravityMultiplier;
|
||||
|
||||
processMaterial.DampingMin = minDamping + dampingOffset;
|
||||
processMaterial.DampingMax = maxDamping + dampingOffset;
|
||||
|
||||
processMaterial.Spread = randomize * 180f;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://2u3g842w5bc8
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
using Godot;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Rokojori.Extensions;
|
||||
namespace Rokojori;
|
||||
|
||||
[Tool]
|
||||
[GlobalClass ]
|
||||
public abstract partial class ParticleVFXMovementType:Resource
|
||||
{
|
||||
[Export( PropertyHint.Range, "0,1")]
|
||||
public float randomize = 0f;
|
||||
|
||||
public abstract void UpdateSettings( ParticleProcessMaterial processMaterial, ParticleVFX vfx );
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://llqsok1kjfeq
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
[gd_resource type="QuadMesh" format=3 uid="uid://b1gctyuqclkhb"]
|
||||
|
||||
[resource]
|
||||
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,35 @@
|
|||
using Godot;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Rokojori.Extensions;
|
||||
namespace Rokojori;
|
||||
|
||||
[Tool]
|
||||
[GlobalClass ]
|
||||
public partial class CircleParticleVFXVolumeType:ParticleVFXVolumeType
|
||||
{
|
||||
public static readonly CachedResource<Texture2D> CirclePoints = new CachedResource<Texture2D>(
|
||||
"res://addons/rokojori_action_library/Runtime/VFX/ParticleVFX/Shared/Emission Shapes/Circle/EmissionShape Circle Points.tres"
|
||||
);
|
||||
|
||||
|
||||
public static readonly CachedResource<Texture2D> CircleNormals = new CachedResource<Texture2D>(
|
||||
"res://addons/rokojori_action_library/Runtime/VFX/ParticleVFX/Shared/Emission Shapes/Circle/EmissionShape Circle Normals.tres"
|
||||
);
|
||||
|
||||
|
||||
public override void UpdateSettings( ParticleProcessMaterial processMaterial, ParticleVFX vfx )
|
||||
{
|
||||
processMaterial.EmissionPointTexture = CirclePoints.Get();
|
||||
processMaterial.EmissionNormalTexture = CircleNormals.Get();
|
||||
processMaterial.EmissionPointCount = 4096;
|
||||
processMaterial.EmissionShapeScale = volumeScale * volumeScaleXYZ;;
|
||||
}
|
||||
|
||||
#if TOOLS
|
||||
public override void DrawGizmo( ParticleVFX vfx, EditorNode3DGizmoPlugin gizmoPlugin, EditorNode3DGizmo gizmo )
|
||||
{
|
||||
DrawShapeGizmo( VolumeShapeType.Circle, vfx, gizmoPlugin, gizmo );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://1e52ptw7nd7b
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
using Godot;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Rokojori.Extensions;
|
||||
namespace Rokojori;
|
||||
|
||||
[Tool]
|
||||
[GlobalClass ]
|
||||
public partial class ConeParticleVFXVolumeType:ParticleVFXVolumeType
|
||||
{
|
||||
public static readonly CachedResource<Texture2D> ConePoints = new CachedResource<Texture2D>(
|
||||
"res://addons/rokojori_action_library/Runtime/VFX/ParticleVFX/Shared/Emission Shapes/Cone/EmissionShape Cone Points.tres"
|
||||
);
|
||||
|
||||
|
||||
public static readonly CachedResource<Texture2D> ConeNormals = new CachedResource<Texture2D>(
|
||||
"res://addons/rokojori_action_library/Runtime/VFX/ParticleVFX/Shared/Emission Shapes/Cone/EmissionShape Cone Normals.tres"
|
||||
);
|
||||
|
||||
|
||||
public override void UpdateSettings( ParticleProcessMaterial processMaterial, ParticleVFX vfx )
|
||||
{
|
||||
processMaterial.EmissionPointTexture = ConePoints.Get();
|
||||
processMaterial.EmissionNormalTexture = ConeNormals.Get();
|
||||
processMaterial.EmissionPointCount = 4096;
|
||||
processMaterial.EmissionShapeScale = volumeScale * volumeScaleXYZ;
|
||||
}
|
||||
|
||||
#if TOOLS
|
||||
public override void DrawGizmo( ParticleVFX vfx, EditorNode3DGizmoPlugin gizmoPlugin, EditorNode3DGizmo gizmo )
|
||||
{
|
||||
DrawShapeGizmo( VolumeShapeType.Cone, vfx, gizmoPlugin, gizmo );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://cuxhk0wq4b414
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
using Godot;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Rokojori.Extensions;
|
||||
namespace Rokojori;
|
||||
|
||||
[Tool]
|
||||
[GlobalClass ]
|
||||
public partial class DomeParticleVFXVolumeType:ParticleVFXVolumeType
|
||||
{
|
||||
public static readonly CachedResource<Texture2D> DomePoints = new CachedResource<Texture2D>(
|
||||
"res://addons/rokojori_action_library/Runtime/VFX/ParticleVFX/Shared/Emission Shapes/Dome/EmissionShape Dome Points.tres"
|
||||
);
|
||||
|
||||
|
||||
public static readonly CachedResource<Texture2D> DomeNormals = new CachedResource<Texture2D>(
|
||||
"res://addons/rokojori_action_library/Runtime/VFX/ParticleVFX/Shared/Emission Shapes/Dome/EmissionShape Dome Normals.tres"
|
||||
);
|
||||
|
||||
|
||||
public override void UpdateSettings( ParticleProcessMaterial processMaterial, ParticleVFX vfx )
|
||||
{
|
||||
processMaterial.EmissionPointTexture = DomePoints.Get();
|
||||
processMaterial.EmissionNormalTexture = DomeNormals.Get();
|
||||
processMaterial.EmissionPointCount = 4096;
|
||||
processMaterial.EmissionShapeScale = volumeScale * volumeScaleXYZ;
|
||||
}
|
||||
|
||||
#if TOOLS
|
||||
public override void DrawGizmo( ParticleVFX vfx, EditorNode3DGizmoPlugin gizmoPlugin, EditorNode3DGizmo gizmo )
|
||||
{
|
||||
DrawShapeGizmo( VolumeShapeType.Dome, vfx, gizmoPlugin, gizmo );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://cn45dw32b13td
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
using Godot;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Rokojori.Extensions;
|
||||
namespace Rokojori;
|
||||
|
||||
[Tool]
|
||||
[GlobalClass ]
|
||||
public partial class MixedParticleVFXVolumeType:ParticleVFXVolumeType
|
||||
{
|
||||
[Export]
|
||||
public VolumeShapeType pointsType = VolumeShapeType.Sphere;
|
||||
|
||||
[Export]
|
||||
public VolumeShapeType normalsType = VolumeShapeType.Sphere;
|
||||
|
||||
static Texture2D GetPoints( VolumeShapeType type )
|
||||
{
|
||||
switch ( type )
|
||||
{
|
||||
case VolumeShapeType.Sphere: return SphereParticleVFXVolumeType.SpherePoints.Get();
|
||||
case VolumeShapeType.Dome: return DomeParticleVFXVolumeType.DomePoints.Get();
|
||||
case VolumeShapeType.Circle: return CircleParticleVFXVolumeType.CirclePoints.Get();
|
||||
case VolumeShapeType.Cone: return ConeParticleVFXVolumeType.ConePoints.Get();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
static Texture2D GetNormals( VolumeShapeType type )
|
||||
{
|
||||
switch ( type )
|
||||
{
|
||||
case VolumeShapeType.Sphere: return SphereParticleVFXVolumeType.SphereNormals.Get();
|
||||
case VolumeShapeType.Dome: return DomeParticleVFXVolumeType.DomeNormals.Get();
|
||||
case VolumeShapeType.Circle: return CircleParticleVFXVolumeType.CircleNormals.Get();
|
||||
case VolumeShapeType.Cone: return ConeParticleVFXVolumeType.ConeNormals.Get();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public override void UpdateSettings( ParticleProcessMaterial processMaterial, ParticleVFX vfx )
|
||||
{
|
||||
processMaterial.EmissionPointTexture = GetPoints( pointsType );
|
||||
processMaterial.EmissionNormalTexture = GetNormals( normalsType );
|
||||
processMaterial.EmissionPointCount = 4096;
|
||||
processMaterial.EmissionShapeScale = volumeScale * volumeScaleXYZ;
|
||||
}
|
||||
|
||||
#if TOOLS
|
||||
public override void DrawGizmo( ParticleVFX vfx, EditorNode3DGizmoPlugin gizmoPlugin, EditorNode3DGizmo gizmo )
|
||||
{
|
||||
DrawShapeGizmo( pointsType, vfx, gizmoPlugin, gizmo );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://ct46je7oga3tb
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
using Godot;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Rokojori.Extensions;
|
||||
namespace Rokojori;
|
||||
|
||||
[Tool]
|
||||
[GlobalClass ]
|
||||
public abstract partial class ParticleVFXVolumeType:Resource
|
||||
{
|
||||
[Export]
|
||||
public Vector3 volumeScale = Vector3.One;
|
||||
|
||||
[Export]
|
||||
public float volumeScaleXYZ = 1f;
|
||||
|
||||
public abstract void UpdateSettings( ParticleProcessMaterial processMaterial, ParticleVFX vfx );
|
||||
|
||||
#if TOOLS
|
||||
public abstract void DrawGizmo( ParticleVFX vfx, EditorNode3DGizmoPlugin gizmoPlugin, EditorNode3DGizmo gizmo );
|
||||
|
||||
protected void DrawShapeGizmo( VolumeShapeType shapeType, ParticleVFX vfx, EditorNode3DGizmoPlugin gizmoPlugin, EditorNode3DGizmo gizmo )
|
||||
{
|
||||
var scale = volumeScale * volumeScaleXYZ;
|
||||
var linePoints = new List<Vector3>();
|
||||
|
||||
switch ( shapeType )
|
||||
{
|
||||
case VolumeShapeType.Sphere:
|
||||
Gizmos.AddSphere( linePoints, scale );
|
||||
break;
|
||||
|
||||
case VolumeShapeType.Dome:
|
||||
Gizmos.AddDome( linePoints, scale );
|
||||
break;
|
||||
|
||||
case VolumeShapeType.Circle:
|
||||
Gizmos.AddDisc( linePoints, scale );
|
||||
break;
|
||||
|
||||
case VolumeShapeType.Cone:
|
||||
Gizmos.AddCone( linePoints, scale );
|
||||
break;
|
||||
}
|
||||
|
||||
if ( linePoints.Count == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var material = gizmoPlugin.GetMaterial( "main", gizmo );
|
||||
gizmo.AddLines( linePoints.ToArray(), material, false );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://dejjrjhjedje5
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
using Godot;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Rokojori.Extensions;
|
||||
namespace Rokojori;
|
||||
|
||||
[Tool]
|
||||
[GlobalClass ]
|
||||
public partial class SphereParticleVFXVolumeType:ParticleVFXVolumeType
|
||||
{
|
||||
public static readonly CachedResource<Texture2D> SpherePoints = new CachedResource<Texture2D>(
|
||||
"res://addons/rokojori_action_library/Runtime/VFX/ParticleVFX/Shared/Emission Shapes/Sphere/EmissionShape Sphere Points.tres"
|
||||
);
|
||||
|
||||
|
||||
public static readonly CachedResource<Texture2D> SphereNormals = new CachedResource<Texture2D>(
|
||||
"res://addons/rokojori_action_library/Runtime/VFX/ParticleVFX/Shared/Emission Shapes/Sphere/EmissionShape Sphere Normals.tres"
|
||||
);
|
||||
|
||||
|
||||
public override void UpdateSettings( ParticleProcessMaterial processMaterial, ParticleVFX vfx )
|
||||
{
|
||||
processMaterial.EmissionPointTexture = SpherePoints.Get();
|
||||
processMaterial.EmissionNormalTexture = SphereNormals.Get();
|
||||
processMaterial.EmissionPointCount = 4096;
|
||||
processMaterial.EmissionShapeScale = volumeScale * volumeScaleXYZ;;
|
||||
}
|
||||
|
||||
#if TOOLS
|
||||
public override void DrawGizmo( ParticleVFX vfx, EditorNode3DGizmoPlugin gizmoPlugin, EditorNode3DGizmo gizmo )
|
||||
{
|
||||
DrawShapeGizmo( VolumeShapeType.Sphere, vfx, gizmoPlugin, gizmo );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://cjqsobh6nomul
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
namespace Rokojori;
|
||||
|
||||
public enum VolumeShapeType
|
||||
{
|
||||
Sphere,
|
||||
Dome,
|
||||
Circle,
|
||||
Cone
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://b8xvl8k82gkhy
|
||||
|
|
@ -10,7 +10,72 @@ namespace Rokojori
|
|||
{
|
||||
#if TOOLS
|
||||
|
||||
public static void AddArc( List<Vector3> linePoints, Vector3 center, Vector3 axisA, Vector3 axisB, float angleStart, float angleEnd, int segments )
|
||||
{
|
||||
var last = center + axisA * Mathf.Cos( angleStart ) + axisB * Mathf.Sin( angleStart );
|
||||
|
||||
for ( int i = 1; i <= segments; i++ )
|
||||
{
|
||||
var t = angleStart + ( angleEnd - angleStart ) * ( i / (float) segments );
|
||||
var point = center + axisA * Mathf.Cos( t ) + axisB * Mathf.Sin( t );
|
||||
|
||||
linePoints.Add( last );
|
||||
linePoints.Add( point );
|
||||
|
||||
last = point;
|
||||
}
|
||||
}
|
||||
|
||||
public static void AddCircle( List<Vector3> linePoints, Vector3 center, Vector3 axisA, Vector3 axisB, int segments = 32 )
|
||||
{
|
||||
AddArc( linePoints, center, axisA, axisB, 0, Mathf.Tau, segments );
|
||||
}
|
||||
|
||||
public static void AddSphere( List<Vector3> linePoints, Vector3 scale, int segments = 32 )
|
||||
{
|
||||
var right = Vector3.Right * scale.X;
|
||||
var up = Vector3.Up * scale.Y;
|
||||
var forward = Vector3.Forward * scale.Z;
|
||||
|
||||
AddCircle( linePoints, Vector3.Zero, right, forward, segments );
|
||||
AddCircle( linePoints, Vector3.Zero, right, up, segments );
|
||||
AddCircle( linePoints, Vector3.Zero, forward, up, segments );
|
||||
}
|
||||
|
||||
public static void AddDome( List<Vector3> linePoints, Vector3 scale, int segments = 32 )
|
||||
{
|
||||
var right = Vector3.Right * scale.X;
|
||||
var up = Vector3.Up * scale.Y;
|
||||
var forward = Vector3.Forward * scale.Z;
|
||||
|
||||
AddCircle( linePoints, Vector3.Zero, right, forward, segments );
|
||||
AddArc( linePoints, Vector3.Zero, right, up, 0, Mathf.Pi, Mathf.Max( 2, segments / 2 ) );
|
||||
AddArc( linePoints, Vector3.Zero, forward, up, 0, Mathf.Pi, Mathf.Max( 2, segments / 2 ) );
|
||||
}
|
||||
|
||||
public static void AddDisc( List<Vector3> linePoints, Vector3 scale, int segments = 32 )
|
||||
{
|
||||
AddCircle( linePoints, Vector3.Zero, Vector3.Right * scale.X, Vector3.Forward * scale.Z, segments );
|
||||
}
|
||||
|
||||
public static void AddCone( List<Vector3> linePoints, Vector3 scale, int segments = 32, int spokes = 8 )
|
||||
{
|
||||
var apex = Vector3.Zero;
|
||||
var baseCenter = Vector3.Up * scale.Y;
|
||||
var right = Vector3.Right * scale.X;
|
||||
var forward = Vector3.Forward * scale.Z;
|
||||
|
||||
AddCircle( linePoints, baseCenter, right, forward, segments );
|
||||
|
||||
for ( int i = 0; i < spokes; i++ )
|
||||
{
|
||||
var t = i / (float) spokes * Mathf.Tau;
|
||||
var basePoint = baseCenter + right * Mathf.Cos( t ) + forward * Mathf.Sin( t );
|
||||
|
||||
linePoints.Add( apex );
|
||||
linePoints.Add( basePoint );
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue