Vignette, CoolDowns, Pause, NodeState

This commit is contained in:
Josef 2025-07-22 16:08:22 +02:00
parent 08dbd8681b
commit 839b0bca39
40 changed files with 876 additions and 77 deletions

View File

@ -0,0 +1,36 @@
using Godot;
using System.Collections.Generic;
namespace Rokojori
{
[Tool][GlobalClass]
public partial class PlayMusic:Action
{
[Export]
public AudioStreamPlayer music;
[Export]
public bool stopSiblingPlayers = false;
protected override void _OnTrigger()
{
if ( stopSiblingPlayers )
{
GetParent().ForEachDirectChild<AudioStreamPlayer>(
( p )=>
{
if ( p == music )
{
return;
}
p.Stop();
}
);
}
music.Play();
}
}
}

View File

@ -0,0 +1 @@
uid://cyicertlwo4m0

View File

@ -0,0 +1,39 @@
using Godot;
using System.Collections.Generic;
namespace Rokojori
{
[Tool]
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/ConditionalAction.svg")]
public partial class CoolDown : Action
{
[Export]
public Action action;
[Export]
public Duration coolDownDuration;
bool _isCoolingDown = false;
protected override void _OnTrigger()
{
if ( _isCoolingDown )
{
return;
}
_isCoolingDown = coolDownDuration != null;
Trigger( action );
if ( coolDownDuration != null )
{
TimeLineManager.ScheduleEventIn(
coolDownDuration.timeLine, coolDownDuration.GetDurationInSeconds(),
ev => _isCoolingDown = false
);
}
}
}
}

View File

@ -0,0 +1 @@
uid://cbk1j230s8i68

View File

@ -0,0 +1,22 @@
using Godot;
namespace Rokojori
{
[Tool][GlobalClass ]
public partial class SetNodeStateSpecific : Action
{
[Export]
public Node target;
[Export]
public NodeStateConfiguration configuration;
protected override void _OnTrigger()
{
NodeState.Configure( target, configuration );
}
}
}

View File

@ -0,0 +1 @@
uid://cko3krhs7jgc4

View File

@ -0,0 +1,66 @@
using Godot;
namespace Rokojori
{
[Tool][GlobalClass ]
public partial class MoveTo : SequenceAction, Animator
{
[Export]
public Node3D target;
[Export]
public Node3D goal;
[Export]
public Duration duration;
int _actionID = -1;
int _currentSpanAnimationID = -1;
public void OnAnimatorStart(){}
public void OnAnimatorEnd(){}
public void OnAnimatorCancel(){}
protected override void _OnTrigger()
{
if ( _actionID != -1 )
{
CancelAction( _actionID );
}
var sequenceID = DispatchStart();
_actionID = sequenceID;
AnimationManager.StartAnimation( this, target, AnimationMember.Position );
var startPosition = target.GlobalPosition;
_currentSpanAnimationID = TimeLineManager.ScheduleSpanIn( duration.timeLine, 0, duration.GetDurationInSeconds(),
( TimeLineSpan span, TimeLineSpanUpdateType type )=>
{
if ( span.id != _currentSpanAnimationID )
{
return;
}
if ( ! AnimationManager.IsAnimating( this, target, AnimationMember.Position ) )
{
return;
}
target.GlobalPosition = startPosition.Lerp( goal.GlobalPosition, span.phase );;
if ( TimeLineSpanUpdateType.End == type )
{
AnimationManager.EndAnimation( this, target, AnimationMember.Position );
DispatchEnd( sequenceID );
return;
}
}
).id;
}
}
}

View File

@ -0,0 +1 @@
uid://b0abujtgcfvlh

View File

@ -37,10 +37,9 @@ namespace Rokojori
return _nodes;
}
public void OnNodeStateChanged( bool processEnabled, bool inputEnabled, bool physicsEnabled, bool signalsEnabled,
Node.ProcessModeEnum processMode, bool visible )
public void OnNodeStateChanged()
{
if ( ! processEnabled || ! physicsEnabled || Node.ProcessModeEnum.Disabled == processMode )
if ( ! IsProcessing() || ! IsPhysicsProcessing() || Node.ProcessModeEnum.Disabled == this.ProcessMode )
{
this.LogInfo( "Clearing nodes" );
_nodes.Clear();

View File

@ -1,5 +1,6 @@
using Godot;
using System.Collections.Generic;
namespace Rokojori
{
@ -9,9 +10,95 @@ namespace Rokojori
[Export]
public GpuParticles3D particles3D;
[Export]
public bool usePooling = false;
[Export]
public float godotFinishedReporingBugOffset = 0.2f;
[Export]
public TimeLine timeLine;
List<GpuParticles3D> _pool = new List<GpuParticles3D>();
List<bool> _emitting = new List<bool>();
protected override void _OnTrigger()
{
if ( ! usePooling )
{
particles3D.Restart();
return;
}
if ( _emitting.Count == 0 )
{
_emitting.Add( false );
}
var p = GetFreeParticles();
if ( p == null )
{
p = DuplicateParticles();
}
this.LogInfo( "Using Particles", p );
var index = IndexOf( p );
_emitting[ index ] = true;
p.OnFinishedOnce(
() =>
{
if ( godotFinishedReporingBugOffset <= 0 )
{
_emitting[ index ] = false;
return;
}
TimeLineManager.ScheduleEventIn(
timeLine,
godotFinishedReporingBugOffset,
t => _emitting[ index ] = false
);
}
);
p.Restart();
}
public int IndexOf( GpuParticles3D p )
{
return p == particles3D ? 0 : _pool.IndexOf( p ) + 1;
}
public bool IsEmitting( GpuParticles3D p )
{
return _emitting[ IndexOf( p ) ];
}
GpuParticles3D GetFreeParticles()
{
if ( ! IsEmitting( particles3D ) )
{
return particles3D;
}
return _pool.Find( p => ! p.Emitting );
}
GpuParticles3D DuplicateParticles()
{
this.LogInfo( "Duplicating Particles" );
var duplicate = particles3D.Duplicate() as GpuParticles3D;
_pool.Add( duplicate );
particles3D.GetParent().AddChild( duplicate );
_emitting.Add( false );
return duplicate;
}
}
}

View File

@ -10,12 +10,18 @@ namespace Rokojori
[Export]
public Node target;
[Export]
public bool queue = true;
protected override void _OnTrigger()
{
if ( target != null )
if ( target == null )
{
target.SelfDestroy();
return;
}
target.SelfDestroy( queue );
}
}
}

View File

@ -0,0 +1,59 @@
using Godot;
namespace Rokojori
{
[Tool][GlobalClass ]
public partial class SetPauseState : Action
{
public enum Mode
{
Pause,
Resume,
Toggle
}
[Export]
public Mode mode;
[Export]
public Action onPausing;
[Export]
public Action onResuming;
[Export]
public bool onlyTriggerOnChange = true;
protected override void _OnTrigger()
{
var currentState = GetTree().Paused;
var nextState = Mode.Toggle == mode ? ! currentState : Mode.Pause == mode ? false : true;
this.LogInfo( "SetPauseState", currentState, ">>", nextState );
if ( currentState == nextState && onlyTriggerOnChange )
{
return;
}
this.LogInfo( "Setting Pause State", nextState );
GetTree().Paused = nextState;
if ( nextState )
{
Action.Trigger( onPausing );
}
else
{
Action.Trigger( onResuming );
}
}
}
}

View File

@ -0,0 +1 @@
uid://bwah32ket1t43

33
Runtime/Actions/Solo.cs Normal file
View File

@ -0,0 +1,33 @@
using Godot;
namespace Rokojori
{
[Tool][GlobalClass ]
public partial class Solo:Action
{
[Export]
public Node soloNode;
[Export]
public NodeStateConfiguration soloConfiguration;
[Export]
public NodeStateConfiguration muteConifiguration;
protected override void _OnTrigger()
{
var parent = soloNode.GetParent();
parent.ForEachDirectChild<Node>(
n =>
{
var configuration = soloNode == n ? soloConfiguration : muteConifiguration;
NodeState.Configure( n, configuration );
}
);
}
}
}

View File

@ -0,0 +1 @@
uid://dyl10mv4eg2h

View File

@ -7,8 +7,8 @@
[sub_resource type="Resource" id="Resource_54hj8"]
script = ExtResource("1_nmdum")
color = Color(1, 0, 0, 1)
colorMultiply = 1.0
color = Color(0.859799, 0.542989, 0.696896, 1)
colorMultiply = 4.0
rgbMultiply = 1.0
alphaMultiply = 1.0

View File

@ -91,7 +91,7 @@ namespace Rokojori
else if ( TransformTarget.Global_Rotation == transformTarget )
{
var rotation = target.GlobalRotation;
target.GlobalRotation = value;
target.GlobalRotation = value * MathX.DegreesToRadians;
// RJLog.Log( "GlobalRotation = ", rotation, ">>", value, target.GlobalRotation );
}
else if ( TransformTarget.Local_Position == transformTarget )
@ -101,7 +101,7 @@ namespace Rokojori
else if ( TransformTarget.Local_Rotation == transformTarget )
{
var rotation = target.Rotation;
target.Rotation = value;
target.Rotation = value * MathX.DegreesToRadians;
// RJLog.Log( "Rotation = ", rotation, ">>", value, target.Rotation );
}
else if ( TransformTarget.Local_Scale == transformTarget )

47
Runtime/Events/Signals.cs Normal file
View File

@ -0,0 +1,47 @@
using System.Collections.Generic;
using Godot;
namespace Rokojori
{
public static class Signals
{
public static void OnFinished( this GpuParticles3D particles3D, System.Action action, bool once = false )
{
if ( once )
{
_OnSignalOnce( particles3D, GpuParticles3D.SignalName.Finished, action );
}
else
{
_OnSignal( particles3D, GpuParticles3D.SignalName.Finished, action );
}
}
public static void OnFinishedOnce( this GpuParticles3D particles3D, System.Action action )
{
OnFinished( particles3D, action, true );
}
public static void _OnSignal( Node node, string name, System.Action action )
{
node.Connect( name, Callable.From( action ) );
}
public static void _OnSignalOnce( Node node, string name, System.Action action )
{
Callable? onceAction = null;
onceAction = Callable.From(
()=>
{
action();
node.Disconnect( name, (Callable) onceAction );
}
);
node.Connect( name, (Callable)onceAction );
}
}
}

View File

@ -0,0 +1 @@
uid://d1q6ycp82ol24

View File

@ -7,13 +7,107 @@ namespace Rokojori
{
public interface iNodeState
{
public void OnNodeStateChanged( bool processEnabled, bool inputEnabled, bool physicsEnabled, bool signalsEnabled,
Node.ProcessModeEnum processMode, bool visible );
public void OnNodeStateChanged();
}
public static class NodeState
{
public static bool IsVisible( this Node n )
{
if ( n is Node3D )
{
return ( n as Node3D ).Visible;
}
if ( n is Node2D )
{
return ( n as Node2D ).Visible;
}
if ( n is CanvasItem )
{
return ( n as CanvasItem ).Visible;
}
return false;
}
public static void Configure( Node target, NodeStateConfiguration configuration )
{
Configure( target,
configuration.processEnabled, configuration.inputEnabled, configuration.physicsEnabled,
configuration.signalsEnabled, configuration.visible, configuration.setProcessMode, configuration.processMode
);
}
public static void SetNodeState( this Node target, NodeStateConfiguration configuration )
{
Configure( target, configuration );
}
public static void Configure(
Node target,
Trillean processEnabled, Trillean inputEnabled,Trillean physicsEnabled,
Trillean signalsEnabled,Trillean visible, bool setProcessMode, Node.ProcessModeEnum processMode
)
{
if ( Trillean.Any != processEnabled )
{
target.SetProcess( TrilleanLogic.ToBool( processEnabled ) );
}
if ( Trillean.Any != inputEnabled )
{
target.SetProcessInput( TrilleanLogic.ToBool( inputEnabled ) );
}
if ( Trillean.Any != physicsEnabled )
{
target.SetPhysicsProcess( TrilleanLogic.ToBool( physicsEnabled ) );
}
if ( Trillean.Any != signalsEnabled )
{
target.SetBlockSignals( ! TrilleanLogic.ToBool( signalsEnabled ) );
}
if ( setProcessMode )
{
target.ProcessMode = processMode;
}
if ( Trillean.Any != visible )
{
var n = target;
var visibleFlag = TrilleanLogic.ToBool( visible );
if ( n is Node3D )
{
( n as Node3D ).Visible = visibleFlag;
}
if ( n is Node2D )
{
( n as Node2D ).Visible = visibleFlag;
}
if ( n is CanvasItem )
{
( n as CanvasItem ).Visible = visibleFlag;
}
}
if ( target is iNodeState ins )
{
ins.OnNodeStateChanged();
}
}
public static void Configure( Node n, bool processEnabled, bool inputEnabled, bool physicsEnabled, bool signalsEnabled,
Node.ProcessModeEnum processMode, bool visible )
{
@ -29,13 +123,6 @@ namespace Rokojori
n.ProcessMode = processMode;
if ( n is iNodeState ins )
{
ins.OnNodeStateChanged( processEnabled, inputEnabled, physicsEnabled, signalsEnabled,
processMode, visible );
}
if ( n is Node3D )
{
( n as Node3D ).Visible = visible;
@ -51,6 +138,10 @@ namespace Rokojori
( n as CanvasItem ).Visible = visible;
}
if ( n is iNodeState ins )
{
ins.OnNodeStateChanged();
}
}
public static void Set( Node n, bool enabled )

View File

@ -0,0 +1,34 @@
using Godot;
using System.Collections.Generic;
using System;
namespace Rokojori
{
[Tool,GlobalClass]
public partial class NodeStateConfiguration:Resource
{
[Export]
public Trillean processEnabled = Trillean.Any;
[Export]
public Trillean inputEnabled = Trillean.Any;
[Export]
public Trillean physicsEnabled = Trillean.Any;
[Export]
public Trillean signalsEnabled = Trillean.Any;
[Export]
public Trillean visible = Trillean.Any;
[Export]
public bool setProcessMode = false;
[Export]
public Node.ProcessModeEnum processMode;
}
}

View File

@ -0,0 +1 @@
uid://dcerk2bxdjmxr

View File

@ -538,7 +538,7 @@ namespace Rokojori
}
}
public static void SelfDestroy( this Node node )
public static void SelfDestroy( this Node node, bool queue = true )
{
var parent = node.GetParent();
@ -547,8 +547,18 @@ namespace Rokojori
parent.RemoveChild( node );
}
node.LogInfo( "Freeing queued:", queue, node);
if ( queue )
{
node.QueueFree();
}
else
{
node.Free();
}
}

View File

@ -0,0 +1,26 @@
using Godot;
using System.Collections;
using System.Collections.Generic;
using Godot.Collections;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class CharacterIsJumping:SceneCondition
{
[Export]
public Jump jump;
public override bool Evaluate()
{
if ( jump == null )
{
return false;
}
return jump.IsJumping();
}
}
}

View File

@ -0,0 +1 @@
uid://5yoyxyejk4ga

View File

@ -12,6 +12,9 @@ namespace Rokojori
[Export]
public Sensor button;
[Export]
public Action onJump;
[ExportGroup( "Jump Impulse")]
[Export]
@ -39,31 +42,41 @@ namespace Rokojori
bool canJump = false;
bool jumping = false;
bool jumpPressing = false;
bool needsToRelease = false;
bool inAir = false;
public bool IsJumping()
{
return inAir;
}
protected override void _OnTrigger()
{
if ( body.IsOnFloor() )
{
if ( jumping )
if ( inAir )
{
jumping = false;
inAir = false;
}
if ( jumpPressing )
{
jumpPressing = false;
needsToRelease = true;
}
}
if ( ! ( jumping || body.IsOnFloor() ) )
if ( ! ( jumpPressing || body.IsOnFloor() ) )
{
return;
}
if ( ! button.isActive )
{
jumping = false;
jumpPressing = false;
needsToRelease = false;
return;
}
@ -73,10 +86,13 @@ namespace Rokojori
return;
}
if ( ! jumping )
if ( ! jumpPressing )
{
jumping = true;
jumpPressing = true;
jumpedDuration = 0;
inAir = true;
Trigger( onJump );
var jumpDirection = Vector3.Up * jumpImpulseStrength;

View File

@ -505,6 +505,16 @@ namespace Rokojori
return new Vector2( v.Y, v.Z );
}
public static Vector3 ZeroY( this Vector3 v )
{
return new Vector3( v.X, 0, v.Z );
}
public static Vector3 SetY( this Vector3 v, float y )
{
return new Vector3( v.X, y, v.Z );
}
public static Basis AlignUp( Basis basis, Vector3 upDirection )
{
basis.Y = upDirection;

View File

@ -51,22 +51,24 @@ uniform vec4 obstacle1 = vec4( 0, 0, 0, 0 );
uniform vec4 obstacle2 = vec4( 0, 0, 0, 0 );
uniform vec4 obstacle3 = vec4( 0, 0, 0, 0 );
uniform vec4 obstacle4 = vec4( 0, 0, 0, 0 );
uniform float obstacleDeformationPower = 1.0;
uniform float obstacleDeformation = 1.0;
uniform float obstacleScale = 1.0;
uniform float maxDeformation = 0.3;
uniform float maxYOffset = 0.1;
uniform float obstacleYScale = 1.0;
vec3 deform( vec3 worldPosition, vec4 obstacle )
{
vec3 direction = worldPosition - obstacle.xyz;
vec3 direction = ( worldPosition - obstacle.xyz ) * vec3( 1.0, obstacleYScale, 1.0 );
float d = length( direction );
float size = obstacle.w * obstacleScale;
if ( d <size && d >= 0.0 )
if ( d < size && d >= 0.0 )
{
float amount = max( 0, ( size - d ) );
amount = pow( amount, obstacleDeformation );
amount = pow( amount, obstacleDeformationPower ) * obstacleDeformation;
return worldPosition + normalize( direction ) * amount;
}
@ -108,10 +110,23 @@ void vertex()
albedoColor = mix( albedo.rgb, HSLtoRGB( albedoHSL ), hslVariation.w );
if ( obstaclesEnabeld )
{
vec3 originalWorldVertex = worldVertex;
worldVertex = deform( worldVertex, obstacle1 );
worldVertex = deform( worldVertex, obstacle2 );
worldVertex = deform( worldVertex, obstacle3 );
worldVertex = deform( worldVertex, obstacle4 );
worldVertex = limitDeform( originalWorldVertex, worldVertex );
}
if ( windEnabled )
{
float windAmount = normalizeToRange01( VERTEX.y, windStart, windEnd );
float rawWindAmount = windAmount;
windAmount = mix( windAmount, windAmount * windAmount, windWeightCurve );
@ -120,20 +135,11 @@ void vertex()
float strength = texture( windNoise, windUV + windNoiseStrengthOffset ).r * windStrength;
vec2 circle = onCircle( angle ) * strength;
vec3 originalWorldVertex = worldVertex;
worldVertex += vec3( circle.x, 0, circle.y ) * windAmount;
// VERTEX = worldToLocal( worldVertex + vec3( circle.x, 0, circle.y ) * windAmount, MODEL_MATRIX );
if ( obstaclesEnabeld )
{
worldVertex = deform( worldVertex, obstacle1 );
worldVertex = deform( worldVertex, obstacle2 );
worldVertex = deform( worldVertex, obstacle3 );
worldVertex = deform( worldVertex, obstacle4 );
worldVertex = limitDeform( originalWorldVertex, worldVertex );
}
VERTEX = worldToLocal( worldVertex, MODEL_MATRIX );
float minY = min( VERTEX.y, 0 ); // VERTEX.y = mix( VERTEX.y, max( 0, VERTEX.y - strength * windAmount), windHeightCompensation * 2.0f );

View File

@ -30,7 +30,7 @@ namespace Rokojori
public Node3D[] sourceNodes = [];
[ExportToolButton( "Combine")]
public Callable CombineButton => Callable.From( Combine );
public Callable CombineButton => Callable.From( ()=>{ Combine(); } );
[ExportGroup( "Mesh")]
[Export]
@ -105,18 +105,8 @@ namespace Rokojori
{
if ( ! _meshGeometryCache.Has( surface.mesh, surface.index ) )
{
// var arrayMesh = surface.mesh as ArrayMesh;
// if ( arrayMesh == null )
// {
// arrayMesh = new ArrayMesh();
// var st = new SurfaceTool();
// st.Begin( Mesh.PrimitiveType.Triangles );
// st.CreateFrom( surface.mesh, surface.index );
// st.Commit( arrayMesh );
// }
var mg = MeshGeometry.From( surface.mesh, null, surface.index );
mg.EnsureIndices();
_meshGeometryCache.Set( surface.mesh, surface.index, mg );
this.LogInfo( "Created mesh with triangles:", mg.numTriangles );
@ -208,6 +198,11 @@ namespace Rokojori
async Task CombineMaterials()
{
if ( ! combineMaterials )
{
return;
}
_materials.ForEach(
m =>
{

View File

@ -162,6 +162,43 @@ namespace Rokojori
{
list = list == null ? new List<Transformable<MeshSurface>>() : list;
if ( n is CsgShape3D c )
{
// RJLog.Log( "Extracting:", c, c.IsRootShape() );
if ( ! c.IsRootShape() )
{
return list;
}
var meshesData = c.GetMeshes();
// RJLog.Log( "MeshData:", meshesData );
// RJLog.Log( "MeshData 0:",meshesData[ 0 ] );
// RJLog.Log( "MeshData 1:", meshesData[ 1 ] );
var trsf = (Transform3D) meshesData[ 0 ] * c.Transform;
var mesh = (ArrayMesh) meshesData[ 1 ];
var mg = MeshGeometry.From( mesh );
Material material = null;
if ( c is CsgBox3D bx ){ material = bx.Material; }
if ( c is CsgCylinder3D cy ){ material = cy.Material; }
if ( c is CsgMesh3D ms ){ material = ms.Material; }
if ( c is CsgPolygon3D pl ){ material = pl.Material; }
if ( c is CsgSphere3D sp ){ material = sp.Material; }
if ( c is CsgTorus3D tr ){ material = tr.Material; }
RJLog.Log( "MeshInfo ", c, mesh, material, "\n",
"tris:", mg.numTriangles
);
var surface = new MeshSurface( mesh, material, 0, c );
list.Add( new Transformable<MeshSurface>( surface, trsf ) );
}
if ( n is MeshInstance3D mi )
{
@ -187,6 +224,7 @@ namespace Rokojori
}
}
if ( n is MultiMeshInstance3D mmi )
{
var owner = mmi;

View File

@ -277,7 +277,7 @@ namespace Rokojori
public List<CustomMeshAttributeList> customMeshAttributes = new List<CustomMeshAttributeList>();
public int numTriangles => indices.Count / 3;
public int numTriangles => indices.Count == 0 && vertices.Count > 0 ? vertices.Count / 3 : indices.Count / 3;
public static MeshGeometry From( MeshInstance3D meshInstance3D )
@ -285,22 +285,43 @@ namespace Rokojori
return From( (ArrayMesh)meshInstance3D.Mesh, meshInstance3D.GlobalTransform );
}
public static MeshGeometry CreateWithSurfaceTool( Mesh mesh, Transform3D? trsf = null, int index = 0 )
{
var arrayMesh = new ArrayMesh();
var st = new SurfaceTool();
st.Begin( Mesh.PrimitiveType.Triangles );
st.CreateFrom( mesh, index );
st.Commit( arrayMesh );
return From( arrayMesh, trsf, 0 );
}
public static MeshGeometry From( Mesh mesh, Transform3D? trsf = null, int index = 0 )
{
var arrayMesh = mesh as ArrayMesh;
if ( arrayMesh == null )
{
arrayMesh = new ArrayMesh();
var st = new SurfaceTool();
st.Begin( Mesh.PrimitiveType.Triangles );
st.CreateFrom( mesh, index );
st.Commit( arrayMesh );
return CreateWithSurfaceTool( mesh, trsf, index );
}
return From( arrayMesh, trsf, 0 );
}
public void EnsureIndices()
{
if ( indices == null || indices.Count == 0 )
{
indices = new List<int>();
for ( int i = 0; i < vertices.Count; i++ )
{
indices.Add( i );
}
}
}
public static MeshGeometry From( ArrayMesh mesh, Transform3D? trsf = null, int index = 0 )
{
@ -315,6 +336,8 @@ namespace Rokojori
var vertices = arrays[ (int) Mesh.ArrayType.Vertex ];
// RJLog.Log( "Verts:", (( Vector3[] )vertices ).Length );
if ( Variant.Type.Nil != vertices.VariantType )
{
mg.vertices = new List<Vector3>( vertices.AsVector3Array() );
@ -1532,7 +1555,7 @@ namespace Rokojori
var surfaceArray = new Godot.Collections.Array();
surfaceArray.Resize( (int) Mesh.ArrayType.Max );
var flags = Mesh.ArrayFormat.FormatVertex | Mesh.ArrayFormat.FormatIndex;
var flags = Mesh.ArrayFormat.FormatVertex;
if ( vertices != null && vertices.Count != 0 )
{
@ -1568,6 +1591,18 @@ namespace Rokojori
surfaceArray[ (int) Mesh.ArrayType.Index ] = indices.ToArray();
flags |= Mesh.ArrayFormat.FormatIndex;
}
else
{
var indexArray = new int[ vertices.Count ];
for ( int i = 0; i < indexArray.Length; i++ )
{
indexArray[ i ] = i;
}
surfaceArray[ (int) Mesh.ArrayType.Index ] = indexArray;
flags |= Mesh.ArrayFormat.FormatIndex;
}
customMeshAttributes.ForEach(
c =>

View File

@ -29,7 +29,7 @@ void main()
float gray = color.r * 0.2125 + color.g * 0.7154 + color.b * 0.0721;
color.rgb = vec3( gray );
color.rgb = vec3( gray * 0.5);
imageStore( color_image, uv, color );
}

View File

@ -0,0 +1,61 @@
using Godot;
using Godot.Collections;
using System.Collections.Generic;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class VignetteEffect:SingleShaderCompositorEffect
{
public static readonly string shaderPath = Path( "Vignette/VignetteShader.glsl" );
[Export( PropertyHint.Range, "0,1")]
public float amount = 1.0f;
[Export( PropertyHint.Range, "0.1,2")]
public float radius = 0.5f;
[Export]
public float power = 1.0f;
[Export]
public float offset = 1.0f;
[Export]
public Color colorTop;
[Export]
public Color colorBottom;
protected override void OnConfigure()
{
EffectCallbackType = EffectCallbackTypeEnum.PostTransparent;
_shaderPath = shaderPath;
_groupSize = 8;
}
protected override void SetConstants()
{
constants.Set(
amount,
radius,
power,
offset,
(Vector2) context.internalSize
);
}
protected override void RenderView()
{
context.AssignScreenColorTexture();
context.pushConstants = constants;
context.ProcessComputeProgram();
}
}
}

View File

@ -0,0 +1 @@
uid://bgiluy6xgcvb0

View File

@ -0,0 +1,41 @@
#[compute]
#version 450
layout( local_size_x = 16, local_size_y = 16, local_size_z = 1 ) in;
layout( rgba16f, set = 0, binding = 0)
uniform image2D color_image;
layout(push_constant, std430)
uniform Params
{
float amount;
float radius;
float power;
float offset;
vec2 raster_size;
} params;
void main()
{
ivec2 uv = ivec2( gl_GlobalInvocationID.xy );
ivec2 size = ivec2( params.raster_size );
if ( uv.x >= size.x || uv.y >= size.y )
{
return;
}
vec4 color = imageLoad( color_image, uv );
float d = length( uv - size/2 ) / length( size/2 * params.radius );
d = pow( d, params.power );
float amount = clamp( 1.0 - d + params.offset, 0.0, 1.0 );
color.rgb = mix( color.rgb, vec3( 0.01, 0.01, 0.02 ), ( 1.0 - amount ) * params.amount );
imageStore( color_image, uv, color );
}

View File

@ -0,0 +1,14 @@
[remap]
importer="glsl"
type="RDShaderFile"
uid="uid://bnkadrfrp7jbc"
path="res://.godot/imported/VignetteShader.glsl-97e3dee05027b0474da3bfd8cf9341fa.res"
[deps]
source_file="res://addons/rokojori_action_library/Runtime/Rendering/Compositor/CompositorEffects/Vignette/VignetteShader.glsl"
dest_files=["res://.godot/imported/VignetteShader.glsl-97e3dee05027b0474da3bfd8cf9341fa.res"]
[params]

View File

@ -23,6 +23,7 @@ namespace Rokojori
public int size => _floatIndex + _intIndex;
public void Set( params object[] objects )
{
Reset();

View File

@ -1,4 +1,4 @@
[gd_resource type="Resource" script_class="InputIconsLibrary" load_steps=74 format=3 uid="uid://dq52vhnqr5m6"]
[gd_resource type="Resource" script_class="InputIconsLibrary" load_steps=73 format=3 uid="uid://dq52vhnqr5m6"]
[ext_resource type="Script" uid="uid://c3dpplc2slwd5" path="res://addons/rokojori_action_library/Runtime/Sensors/InputIcons/Definitions/DefaultInputIconDefinition.cs" id="1_64knt"]
[ext_resource type="Script" uid="uid://bx1cm2837cuuc" path="res://addons/rokojori_action_library/Runtime/Sensors/InputIcons/InputIconsLibrary.cs" id="1_urlfx"]
@ -28,7 +28,6 @@
[ext_resource type="Texture2D" uid="uid://dxwnbh3a3fy8w" path="res://addons/rokojori_action_library/Runtime/Sensors/InputIcons/Graphics/GamePad-Left-Shoulder-Button.svg" id="13_omll7"]
[ext_resource type="Texture2D" uid="uid://1pfyxi7wifn8" path="res://addons/rokojori_action_library/Runtime/Sensors/InputIcons/Graphics/Keyboard-SpaceKey.svg" id="14_6vom6"]
[ext_resource type="Texture2D" uid="uid://bgi8cbw57gka0" path="res://addons/rokojori_action_library/Runtime/Sensors/InputIcons/Graphics/GamePad-MainButton.svg" id="14_n68qo"]
[ext_resource type="SystemFont" uid="uid://s1pi67tbxu24" path="res://3rdPerson/Inputs/Jost-Font.tres" id="15_co1yv"]
[ext_resource type="Texture2D" uid="uid://cb8ldiej8234h" path="res://addons/rokojori_action_library/Runtime/Sensors/InputIcons/Graphics/GamePad-Axis-Background.svg" id="18_amimm"]
[ext_resource type="Texture2D" uid="uid://ddfvjmi7sva6f" path="res://addons/rokojori_action_library/Runtime/Sensors/InputIcons/Graphics/GamePad-Axis-Pressed.svg" id="19_7x4g0"]
[ext_resource type="Script" uid="uid://bvj322mokkq63" path="res://addons/rokojori_action_library/Runtime/Localization/LocaleText.cs" id="20_55eoq"]
@ -340,7 +339,6 @@ borderBottom = 0.0
[resource]
script = ExtResource("1_urlfx")
font = ExtResource("15_co1yv")
fontSize = SubResource("Resource_40bf3")
iconHeightInEm = 1.5
mouseInputIcon = SubResource("Resource_34cgw")

View File

@ -19,30 +19,44 @@ namespace Rokojori
[Export]
public Action onEnd;
[ExportGroup("Condition")]
[Export]
public Condition condition;
[Export]
public SceneCondition sceneCondition;
public override void _Process( double delta)
{
var active = sensor.isActive;
var wasActive = sensor.wasActive;
if ( ! active && ! wasActive )
if ( sensor == null )
{
return;
}
var started = ! wasActive && active;
var ended = wasActive && ! active;
if ( condition != null && ! condition.Evaluate() )
{
return;
}
if ( started )
if ( sceneCondition != null && ! sceneCondition.Evaluate() )
{
return;
}
if ( sensor.isDown )
{
Action.Trigger( onStart );
}
if ( active )
if ( sensor.isHold )
{
Action.Trigger( onActive );
}
if ( ended )
if ( sensor.isUp )
{
Action.Trigger( onActive );
}

View File

@ -245,8 +245,13 @@ namespace Rokojori
return;
}
var oldFontSize = X_computedFontSizePixels;
X_computedFontSizePixels = UINumber.Compute( this, settings.fontSize ) * fontZoom;
if ( oldFontSize != X_computedFontSizePixels )
{
_fontSizeFlag = true;
}
if ( Theme != null )
{