From 73df307cef131f0e89feeb174eed9d33426f498f Mon Sep 17 00:00:00 2001 From: Josef Date: Wed, 8 Jan 2025 19:46:17 +0100 Subject: [PATCH] C# Only Update --- Runtime/Actions/Action.cs | 150 +++++++++- Runtime/Actions/ActionList.cs | 18 +- Runtime/Actions/ActionReference.cs | 8 +- Runtime/Actions/ActionSequence.cs | 59 ++-- Runtime/Actions/Actions.cs | 53 ---- Runtime/Actions/Delay.cs | 6 +- Runtime/Actions/IterateActions.cs | 8 +- Runtime/Actions/LoadScene.cs | 10 +- Runtime/Actions/Node/SetNodeState.cs | 4 +- Runtime/Actions/Node3D/CopyMousePosition.cs | 4 +- Runtime/Actions/Node3D/CopyPose.cs | 4 +- Runtime/Actions/Node3D/CopyPosition.cs | 4 +- Runtime/Actions/Node3D/DistributeChildren.cs | 4 +- Runtime/Actions/Node3D/LerpPosition.cs | 4 +- Runtime/Actions/Node3D/LookAt.cs | 4 +- Runtime/Actions/OnPhysicsProcess.cs | 6 +- Runtime/Actions/OnProcess.cs | 6 +- Runtime/Actions/OnReady.cs | 6 +- Runtime/Actions/RJLogMessage.cs | 4 +- Runtime/Actions/SequenceAction.cs | 68 +++++ Runtime/Actions/TriggerActionInEditor.cs | 2 +- Runtime/Animation/AnimationManager.cs | 73 ++++- Runtime/Animation/{ => Flash}/Flash.cs | 17 +- Runtime/Animation/{ => Flash}/FlashEffect.cs | 7 +- .../Blue Shield - Flash.tres} | 6 +- .../Green Charge - Flash.tres} | 6 +- .../Orange Boost - Flash.tres} | 6 +- .../Red Hit - Flash.tres} | 10 +- .../White Blinking - Flash.tres} | 6 +- Runtime/Animation/KeyFrames/KeyFrame.cs | 14 + .../Animation/KeyFrames/KeyFrameAnimation.cs | 131 +++++++++ .../Shake/Presets/Small Impact - Shake.tres | 49 ++++ Runtime/Animation/Shake/Shake.cs | 146 ++++++++-- Runtime/Animation/Shake/ShakeEffect.cs | 52 +++- .../Animation/Transform/AnimateTransform.cs | 8 +- .../Transform/TransformAnimations.cs | 2 +- Runtime/Animation/Transform/TransformData.cs | 61 ++++ .../Animation/Transform/TransformTarget.cs | 29 +- Runtime/Animation/Wipe/FadeWipeEffect.cs | 22 ++ Runtime/Animation/Wipe/TextureWipeEffect.cs | 94 +++++++ Runtime/Animation/Wipe/Wipe.cs | 59 ++++ Runtime/Animation/Wipe/WipeEffect.cs | 34 +++ Runtime/Bits/BitMath.cs | 31 ++ Runtime/Bits/BitViewTest.cs | 148 ++++++++++ Runtime/Bits/BitView_Byte.cs | 60 ++++ Runtime/Bits/BitView_Float.cs | 20 ++ Runtime/Bits/BitView_Int.cs | 20 ++ Runtime/Bits/BitView_IntVL8.cs | 85 ++++++ Runtime/Bits/BitView_Vector.cs | 59 ++++ Runtime/Bits/BitView__.cs | 266 ++++++++++++++++++ Runtime/Bits/ByteView.cs | 76 +++++ Runtime/Bits/Bytes.cs | 30 ++ Runtime/Events/EventProperty.cs | 5 +- Runtime/Events/EventSlot.cs | 65 ++++- .../Generated/Classes/RJAnimatableBody3D.cs | 64 ++--- .../Generated/Classes/RJCharacterBody3D.cs | 64 ++--- .../Godot/Generated/GodotClassGenerator.cs | 4 +- Runtime/Interactions/Caster.cs | 52 ++++ .../CharacterController.cs | 4 +- .../CharacterControllerAction.cs | 2 +- .../CharacterController/CharacterMovement.cs | 22 +- .../CharacterController/Gravity.cs | 2 +- .../CharacterController/GroundReset.cs | 2 +- .../Interactions/CharacterController/Jump.cs | 6 +- .../CharacterController/MoveAndSlide.cs | 2 +- Runtime/Interactions/MultiRayCaster.cs | 13 +- Runtime/Interactions/Pointable.cs | 36 ++- Runtime/Interactions/Pointer.cs | 13 +- Runtime/Math/Math2D.cs | 5 + Runtime/Math/MathX.cs | 8 + Runtime/Math/Smoother.cs | 18 ++ .../Backends/LAN/LANNetworkingBackend.cs | 174 ++++++++++++ Runtime/Networking/Data/NetClass.cs | 78 +++++ Runtime/Networking/Data/NetMember.cs | 45 +++ Runtime/Networking/Data/NetworkingDataType.cs | 12 + Runtime/Networking/Data/Types/NetBool.cs | 26 ++ Runtime/Networking/Data/Types/NetByte.cs | 26 ++ Runtime/Networking/Data/Types/NetFloat.cs | 25 ++ Runtime/Networking/Data/Types/NetInt.cs | 24 ++ Runtime/Networking/Data/Types/NetIntVL8.cs | 24 ++ Runtime/Networking/Data/Types/NetList.cs | 39 +++ .../Networking/Data/Types/NetQuaternion.cs | 24 ++ Runtime/Networking/Data/Types/NetVector3.cs | 24 ++ Runtime/Networking/NetworkBackend.cs | 73 +++++ Runtime/Networking/NetworkManager.cs | 65 +++++ .../Networking/Nodes/AddNetworkingNodes.cs | 47 ++++ Runtime/Networking/Nodes/INetworkingNode.cs | 16 ++ Runtime/Networking/Nodes/NetworkNode.cs | 56 ++++ Runtime/Networking/Nodes/NetworkNodeMember.cs | 95 +++++++ .../Nodes/NetworkNodeMemberReferences.cs | 50 ++++ Runtime/Networking/Nodes/NetworkNodeSlot.cs | 16 ++ Runtime/Networking/Session/JoinSession.cs | 22 ++ .../Networking/Session/NetworkSessionEvent.cs | 11 + .../Session/NetworkSessionManager.cs | 104 +++++++ .../Session/NetworkSessionMember.cs | 22 ++ .../Session/NetworkSessionRequest.cs | 19 ++ .../Networking/Session/NetworkSessionState.cs | 15 + Runtime/Networking/Session/StartSession.cs | 24 ++ .../Transforms/NetworkTransform3D.cs | 57 ++++ .../Transforms/NetworkTransform3DType.cs | 30 ++ .../Transforms/NetworkTransformManager.cs | 14 + .../Networking/Transport/NetworkingMessage.cs | 19 ++ .../Transport/NetworkingTransport.cs | 123 ++++++++ .../Transport/NetworkingTransportSettings.cs | 63 +++++ .../Transport/NetworkingTransportType.cs | 16 ++ .../Procedural/Baking/SaveViewportTexture.cs | 4 +- Runtime/Random/LCG.cs | 20 +- Runtime/Random/RandomEngine.cs | 9 + .../NetworkNode.cs => Selectors/Selector.cs} | 9 +- Runtime/Selectors/Selectors.cs | 2 +- Runtime/Sensors/CombineSensor.cs | 41 +-- Runtime/Sensors/InputSensor.cs | 76 ----- Runtime/Sensors/KeySensor.cs | 37 +-- Runtime/Sensors/MouseMotionDelta.cs | 36 +-- Runtime/Sensors/MouseScreenRelative.cs | 38 +-- Runtime/Sensors/OnSensor.cs | 18 +- Runtime/Sensors/SensorManager.cs | 24 +- Runtime/Sensors/Sensors.cs | 10 +- Runtime/Sensors/TriggerOnSensor.cs | 6 +- Runtime/Sensors/iOnInputSensor.cs | 11 + Runtime/Shading/Library/Math.gdshaderinc | 2 + Runtime/Shading/Library/Transform.gdshaderinc | 128 ++++++++- .../Shading/Shaders/Baking/DepthMap.gdshader | 10 +- .../Shaders/Billboards/QuadBillboard.gdshader | 48 ++-- .../FresnelOverlay/FresnelOverlay.gdshader | 8 +- .../ChromaticDistortion.gdshader | 18 +- .../Shaders/PostProcessing/Overlays.gdshader | 6 +- .../Shaders/Wipes/FadeWipe/FadeWipe.cs | 57 ++++ .../Shaders/Wipes/FadeWipe/FadeWipe.gdshader | 51 ++++ .../CSShaderClassGenerator.cs | 13 +- Runtime/Structures/MultiMap.cs | 16 +- Runtime/Time/ModulateTimeLineSpeed.cs | 6 +- Runtime/Time/SetTimeLineSpeed.cs | 6 +- Runtime/Time/TimeLine.cs | 41 +++ Runtime/Time/TimeLineEvent.cs | 4 +- Runtime/Time/TimeLineManager.cs | 56 ++-- Runtime/Time/TimeLineRunner.cs | 39 +-- Runtime/Time/TimeLineScheduler.cs | 41 +-- Runtime/Time/TimeLineSpan.cs | 25 +- Runtime/Time/TimeLines/GameTime.tres | 9 +- Runtime/Time/TimeLines/RealTime.tres | 6 +- Runtime/Tools/Arrays.cs | 1 + Runtime/Tools/Lists.cs | 9 + Runtime/Tools/Singleton.cs | 24 ++ Runtime/UI/OnSliderValueChange.cs | 4 +- Runtime/UI/Styling/UIColor.cs | 2 +- Runtime/UI/Styling/UINumber.cs | 2 +- .../UI/Transitions/ActiveStyleTransition.cs | 2 +- Runtime/UI/Transitions/TransitionSettings.cs | 2 +- .../VirtualCameras/Effects/CameraEffect.cs | 2 +- .../Effects/PlayCameraEffect.cs | 8 +- Runtime/VirtualCameras/MouseEditorCamera.cs | 28 +- .../VirtualCameras/StrategyTopDownCamera.cs | 24 +- Runtime/VirtualCameras/ThirdPersonCamera.cs | 8 +- Runtime/VirtualCameras/VirtualCamera3D.cs | 8 +- .../VirtualCameras/VirtualCamera3DManager.cs | 20 +- Runtime/VirtualCameras/VirtualCamera3DSlot.cs | 6 +- 157 files changed, 4274 insertions(+), 731 deletions(-) delete mode 100644 Runtime/Actions/Actions.cs create mode 100644 Runtime/Actions/SequenceAction.cs rename Runtime/Animation/{ => Flash}/Flash.cs (94%) rename Runtime/Animation/{ => Flash}/FlashEffect.cs (96%) rename Runtime/Animation/Flash/{Blue-Shield-FlashEffect.tres => Presets/Blue Shield - Flash.tres} (84%) rename Runtime/Animation/Flash/{Green-Charge-FlashEffect.tres => Presets/Green Charge - Flash.tres} (83%) rename Runtime/Animation/Flash/{Orange-Boost-FlashEffect.tres => Presets/Orange Boost - Flash.tres} (82%) rename Runtime/Animation/Flash/{Red-Hit-FlashEffect.tres => Presets/Red Hit - Flash.tres} (76%) rename Runtime/Animation/Flash/{White-Blinking-FlashEffect.tres => Presets/White Blinking - Flash.tres} (86%) create mode 100644 Runtime/Animation/KeyFrames/KeyFrame.cs create mode 100644 Runtime/Animation/KeyFrames/KeyFrameAnimation.cs create mode 100644 Runtime/Animation/Shake/Presets/Small Impact - Shake.tres create mode 100644 Runtime/Animation/Transform/TransformData.cs create mode 100644 Runtime/Animation/Wipe/FadeWipeEffect.cs create mode 100644 Runtime/Animation/Wipe/TextureWipeEffect.cs create mode 100644 Runtime/Animation/Wipe/Wipe.cs create mode 100644 Runtime/Animation/Wipe/WipeEffect.cs create mode 100644 Runtime/Bits/BitMath.cs create mode 100644 Runtime/Bits/BitViewTest.cs create mode 100644 Runtime/Bits/BitView_Byte.cs create mode 100644 Runtime/Bits/BitView_Float.cs create mode 100644 Runtime/Bits/BitView_Int.cs create mode 100644 Runtime/Bits/BitView_IntVL8.cs create mode 100644 Runtime/Bits/BitView_Vector.cs create mode 100644 Runtime/Bits/BitView__.cs create mode 100644 Runtime/Bits/ByteView.cs create mode 100644 Runtime/Bits/Bytes.cs create mode 100644 Runtime/Interactions/Caster.cs create mode 100644 Runtime/Networking/Backends/LAN/LANNetworkingBackend.cs create mode 100644 Runtime/Networking/Data/NetClass.cs create mode 100644 Runtime/Networking/Data/NetMember.cs create mode 100644 Runtime/Networking/Data/NetworkingDataType.cs create mode 100644 Runtime/Networking/Data/Types/NetBool.cs create mode 100644 Runtime/Networking/Data/Types/NetByte.cs create mode 100644 Runtime/Networking/Data/Types/NetFloat.cs create mode 100644 Runtime/Networking/Data/Types/NetInt.cs create mode 100644 Runtime/Networking/Data/Types/NetIntVL8.cs create mode 100644 Runtime/Networking/Data/Types/NetList.cs create mode 100644 Runtime/Networking/Data/Types/NetQuaternion.cs create mode 100644 Runtime/Networking/Data/Types/NetVector3.cs create mode 100644 Runtime/Networking/NetworkBackend.cs create mode 100644 Runtime/Networking/NetworkManager.cs create mode 100644 Runtime/Networking/Nodes/AddNetworkingNodes.cs create mode 100644 Runtime/Networking/Nodes/INetworkingNode.cs create mode 100644 Runtime/Networking/Nodes/NetworkNode.cs create mode 100644 Runtime/Networking/Nodes/NetworkNodeMember.cs create mode 100644 Runtime/Networking/Nodes/NetworkNodeMemberReferences.cs create mode 100644 Runtime/Networking/Nodes/NetworkNodeSlot.cs create mode 100644 Runtime/Networking/Session/JoinSession.cs create mode 100644 Runtime/Networking/Session/NetworkSessionEvent.cs create mode 100644 Runtime/Networking/Session/NetworkSessionManager.cs create mode 100644 Runtime/Networking/Session/NetworkSessionMember.cs create mode 100644 Runtime/Networking/Session/NetworkSessionRequest.cs create mode 100644 Runtime/Networking/Session/NetworkSessionState.cs create mode 100644 Runtime/Networking/Session/StartSession.cs create mode 100644 Runtime/Networking/Transforms/NetworkTransform3D.cs create mode 100644 Runtime/Networking/Transforms/NetworkTransform3DType.cs create mode 100644 Runtime/Networking/Transforms/NetworkTransformManager.cs create mode 100644 Runtime/Networking/Transport/NetworkingMessage.cs create mode 100644 Runtime/Networking/Transport/NetworkingTransport.cs create mode 100644 Runtime/Networking/Transport/NetworkingTransportSettings.cs create mode 100644 Runtime/Networking/Transport/NetworkingTransportType.cs rename Runtime/{Networking/NetworkNode.cs => Selectors/Selector.cs} (51%) delete mode 100644 Runtime/Sensors/InputSensor.cs create mode 100644 Runtime/Sensors/iOnInputSensor.cs create mode 100644 Runtime/Shading/Shaders/Wipes/FadeWipe/FadeWipe.cs create mode 100644 Runtime/Shading/Shaders/Wipes/FadeWipe/FadeWipe.gdshader create mode 100644 Runtime/Time/TimeLine.cs create mode 100644 Runtime/Tools/Singleton.cs diff --git a/Runtime/Actions/Action.cs b/Runtime/Actions/Action.cs index f7a9472..27ff3ab 100644 --- a/Runtime/Actions/Action.cs +++ b/Runtime/Actions/Action.cs @@ -1,5 +1,6 @@ using Godot; +using System.Collections.Generic; namespace Rokojori @@ -7,15 +8,154 @@ namespace Rokojori [GlobalClass ] public partial class Action : NetworkNode { - public void Trigger() - { - _OnTrigger(); - } + NetworkNodeSlot _seedSlot = new NetworkNodeSlot(); + NetworkNodeSlot _dataSlot = new NetworkNodeSlot(); + NetworkNodeSlot _seedAndDataSlot = new NetworkNodeSlot(); - public virtual void _OnTrigger() + protected override List CreateNetworkNodeMembers() + { + return new List() + { + _networkNodeSlot, + _seedSlot, + _dataSlot, + _seedAndDataSlot + }; + } + + public Action() { } + + public void Trigger() + { + _isNetworkedTrigger = false; + _sendsSeed = false; + _sendsData = false; + _OnTrigger(); + + SendOverNetwork(); + + } + + protected void SendOverNetwork() + { + // check which type + // 0 0 => vanilla + // 1 0 => with seed + // 0 1 => with data + // 1 1 => with seed + data + } + + protected void _OnNetworkTrigger( int seed, BitView data ) + { + _isNetworkedTrigger = true; + _receivedNetworkSeed = seed; + _receivedNetworkData = data; + + _OnTrigger(); + + _isNetworkedTrigger = false; + } + + bool _isNetworkedTrigger = false; + int _receivedNetworkSeed = -1; + int _sendingNetworkSeed = -1; + + bool _sendsSeed = false; + bool _sendsData = false; + + BitView _sendingNetworkData; + BitView _receivedNetworkData; + + protected bool isNetworkedTrigger => _isNetworkedTrigger; + + static readonly int maxNetworkSeed = Mathf.RoundToInt( Mathf.Pow( 2, 30 ) ); + + protected int networkSeed + { + get + { + if ( _isNetworkedTrigger ) + { + return _receivedNetworkSeed; + } + + if ( _sendsSeed ) + { + return _sendingNetworkSeed; + } + + _sendingNetworkSeed = GodotRandom.Get().IntegerExclusive( 0, maxNetworkSeed ); + _sendsSeed = true; + + return _sendingNetworkSeed; + } + } + + protected BitView GetNetworkData( BitView view ) + { + if ( _isNetworkedTrigger ) + { + return _receivedNetworkData; + } + + _sendingNetworkData = view; + _sendsData = true; + return _sendingNetworkData; + } + + protected virtual void _OnTrigger() + { + + } + + + + public static void Trigger( Action action ) + { + if ( action == null ) + { + return; + } + + action.Trigger(); + } + + public static void TriggerAll( Action[] actions, Node target, bool triggerDirectChildren ) + { + if ( actions != null ) + { + for ( int i = 0; i < actions.Length; i++ ) + { + Action.Trigger( actions[ i ] ); + } + } + + if ( ! triggerDirectChildren ) + { + return; + } + + Nodes.ForEachDirectChild( target, a => Action.Trigger( a ) ); + } + + public static void TriggerAll( Action action, Node target, bool triggerDirectChildren ) + { + if ( action != null ) + { + Action.Trigger( action ); + + } + + if ( ! triggerDirectChildren ) + { + return; + } + + Nodes.ForEachDirectChild( target, a => Action.Trigger( a ) ); + } } } \ No newline at end of file diff --git a/Runtime/Actions/ActionList.cs b/Runtime/Actions/ActionList.cs index 065b1b7..d6b32b5 100644 --- a/Runtime/Actions/ActionList.cs +++ b/Runtime/Actions/ActionList.cs @@ -7,33 +7,33 @@ namespace Rokojori /** - Executes multiple actions (RJAction) at once. + Executes multiple actions (Action) at once. - The ActionList, which is an RJAction itself, executes all actions stored in the member 'actions' and also child nodes - that extend RJAction, when 'triggerDirectChildren' is checked. + The ActionList, which is an Action itself, executes all actions stored in the member 'actions' and also child nodes + that extend Action, when 'triggerDirectChildren' is checked. */ - [GlobalClass, Icon("res://addons/rokojori_action_library/Icons/RJActionList.svg") ] - public partial class ActionList : RJAction + [GlobalClass, Icon("res://addons/rokojori_action_library/Icons/ActionList.svg") ] + public partial class ActionList : Action { /** Actions to execute*/ [Export] - public RJAction[] actions; + public Action[] actions; - /** Whether to execute RJAction child nodes*/ + /** Whether to execute Action child nodes*/ [Export] public bool triggerDirectChildren = true; - public override void _OnTrigger() + protected override void _OnTrigger() { - Actions.TriggerAll( actions, this, triggerDirectChildren ); + Action.TriggerAll( actions, this, triggerDirectChildren ); } } } \ No newline at end of file diff --git a/Runtime/Actions/ActionReference.cs b/Runtime/Actions/ActionReference.cs index 1ecccaa..a60de5d 100644 --- a/Runtime/Actions/ActionReference.cs +++ b/Runtime/Actions/ActionReference.cs @@ -5,14 +5,14 @@ using Godot; namespace Rokojori { [GlobalClass ] - public partial class ActionReference : RJAction + public partial class ActionReference : Action { [Export] - public RJAction referencedAction; + public Action referencedAction; - public override void _OnTrigger() + protected override void _OnTrigger() { - Actions.Trigger( referencedAction ); + Action.Trigger( referencedAction ); } } diff --git a/Runtime/Actions/ActionSequence.cs b/Runtime/Actions/ActionSequence.cs index 1c25765..866ba04 100644 --- a/Runtime/Actions/ActionSequence.cs +++ b/Runtime/Actions/ActionSequence.cs @@ -11,15 +11,15 @@ namespace Rokojori public class ActionSequenceRunner { public ActionSequence sequence; - public List actions; - public List sequencables; + public List actions; + public List sequencables; public int sequencablesIndex = 0; bool cancelled = false; bool cancelledSequence = false; int _runID = -1; - RJSequenceAction _runningAction; + SequenceAction _runningAction; int _runningActionID = -1; public void Cancel() @@ -61,7 +61,7 @@ namespace Rokojori if ( sequencables.Count == 0 ) { - actions.ForEach( a => Actions.Trigger( a ) ); + actions.ForEach( a => Action.Trigger( a ) ); sequence.DispatchEnd( _runID ); sequence.ClearRun( this ); return; @@ -87,20 +87,21 @@ namespace Rokojori StartAction( sequenceAction ); } - Dictionary callbacks = - new Dictionary(); + Dictionary> callbacks = + new Dictionary>(); - void StartAction( RJSequenceAction action ) + void StartAction( SequenceAction action ) { var capturedAction = action; - RJSequenceAction.OnSequenceDoneEventHandler callback = - ( long id, bool success ) => + System.Action callback = + ( SequenceActionFinishedEvent ev ) => { + //RJLog.Log( "On Done", id, success ); - if ( id != _runningActionID ) + if ( ev.id != _runningActionID ) { // RJLog.Error( "Invalid ID", id, "!=", _runningActionID ); return; @@ -108,7 +109,7 @@ namespace Rokojori _runningActionID = -1; - if ( success ) + if ( ev.success ) { sequencablesIndex ++; ProcessNext(); @@ -120,7 +121,7 @@ namespace Rokojori } var callbackReference = callbacks[ capturedAction ]; - capturedAction.OnSequenceDone -= callbackReference; + capturedAction.onSequenceDone.RemoveAction( callbackReference ); callbacks.Remove( capturedAction ); }; @@ -132,54 +133,54 @@ namespace Rokojori callbacks[ _runningAction ] = callback; _runningAction.OnSequenceDone += callback; TriggerAllBefore( _runningAction ); - Actions.Trigger( _runningAction ); + Action.Trigger( _runningAction ); _runningActionID = _runningAction.GetLastSequenceActionID(); */ } - void RunNext( RJSequenceAction action, RJSequenceAction.OnSequenceDoneEventHandler callback ) + void RunNext( SequenceAction action, System.Action callback ) { _runningAction = action; callbacks[ _runningAction ] = callback; - _runningAction.OnSequenceDone += callback; + _runningAction.onSequenceDone.AddAction( callback ); TriggerAllBefore( _runningAction ); - Actions.Trigger( _runningAction ); + Action.Trigger( _runningAction ); _runningActionID = _runningAction.GetLastSequenceActionID(); } - void TriggerAllBefore( RJSequenceAction action ) + void TriggerAllBefore( SequenceAction action ) { var actionIndex = actions.IndexOf( action ); for ( int i = actionIndex - 1; i >= 0; i -- ) { - if ( typeof( RJSequenceAction ).IsAssignableFrom( actions[ i ].GetType() ) ) + if ( typeof( SequenceAction ).IsAssignableFrom( actions[ i ].GetType() ) ) { return; } RJLog.Log( "Triggering Action", actions[ i ].Name ); - Actions.Trigger( actions[ i ] ); + Action.Trigger( actions[ i ] ); } } - void TriggerAllAfter( RJSequenceAction action ) + void TriggerAllAfter( SequenceAction action ) { var actionIndex = actions.IndexOf( action ); for ( int i = actionIndex + 1; i < actions.Count; i ++ ) { - if ( typeof( RJSequenceAction ).IsAssignableFrom( actions[ i ].GetType() ) ) + if ( typeof( SequenceAction ).IsAssignableFrom( actions[ i ].GetType() ) ) { return; } RJLog.Log( "Triggering Action", actions[ i ].Name ); - Actions.Trigger( actions[ i ] ); + Action.Trigger( actions[ i ] ); } } @@ -187,30 +188,30 @@ namespace Rokojori } - [GlobalClass, Icon("res://addons/rokojori_action_library/Icons/RJActionSequence.svg") ] - public partial class ActionSequence:RJSequenceAction + [GlobalClass, Icon("res://addons/rokojori_action_library/Icons/ActionSequence.svg") ] + public partial class ActionSequence:SequenceAction { /** Actions to execute*/ [Export] - public RJAction[] actions; + public Action[] actions; [Export] public bool triggerDirectChildren = true; List running = new List(); - public override void _OnTrigger() + protected override void _OnTrigger() { var run = new ActionSequenceRunner(); run.sequence = this; - run.actions = new List( actions ); + run.actions = new List( actions ); if ( triggerDirectChildren ) { - Nodes.ForEachDirectChild( this, a => run.actions.Add( a ) ); + Nodes.ForEachDirectChild( this, a => run.actions.Add( a ) ); } - run.sequencables = Lists.FilterType( run.actions ); + run.sequencables = Lists.FilterType( run.actions ); diff --git a/Runtime/Actions/Actions.cs b/Runtime/Actions/Actions.cs deleted file mode 100644 index 796f1b6..0000000 --- a/Runtime/Actions/Actions.cs +++ /dev/null @@ -1,53 +0,0 @@ - -using Godot; - - -namespace Rokojori -{ - public class Actions - { - public static void Trigger( RJAction action ) - { - if ( action == null ) - { - return; - } - - action.Trigger(); - } - - public static void TriggerAll( RJAction[] actions, Node target, bool triggerDirectChildren ) - { - if ( actions != null ) - { - for ( int i = 0; i < actions.Length; i++ ) - { - Actions.Trigger( actions[ i ] ); - } - } - - if ( ! triggerDirectChildren ) - { - return; - } - - Nodes.ForEachDirectChild( target, a => Actions.Trigger( a ) ); - } - - public static void TriggerAll( RJAction action, Node target, bool triggerDirectChildren ) - { - if ( action != null ) - { - Actions.Trigger( action ); - - } - - if ( ! triggerDirectChildren ) - { - return; - } - - Nodes.ForEachDirectChild( target, a => Actions.Trigger( a ) ); - } - } -} \ No newline at end of file diff --git a/Runtime/Actions/Delay.cs b/Runtime/Actions/Delay.cs index 778af6e..6207d5d 100644 --- a/Runtime/Actions/Delay.cs +++ b/Runtime/Actions/Delay.cs @@ -5,7 +5,7 @@ using Godot; namespace Rokojori { [GlobalClass] - public partial class Delay : RJSequenceAction + public partial class Delay : SequenceAction { [Export] public float duration; @@ -14,10 +14,10 @@ namespace Rokojori public string message; [Export] - public RJTimeLine timeLine; + public TimeLine timeLine; - public override void _OnTrigger() + protected override void _OnTrigger() { var sequenceID = DispatchStart(); diff --git a/Runtime/Actions/IterateActions.cs b/Runtime/Actions/IterateActions.cs index 7d983be..813a11d 100644 --- a/Runtime/Actions/IterateActions.cs +++ b/Runtime/Actions/IterateActions.cs @@ -5,15 +5,15 @@ using Godot; namespace Rokojori { [GlobalClass ] - public partial class IterateActions : RJAction + public partial class IterateActions : Action { [ExportGroup( "Read Only")] [Export] public int iterationIndex = 0; - public override void _OnTrigger() + protected override void _OnTrigger() { - var num = this.NumDirectChildrenOf(); + var num = this.NumDirectChildrenOf(); if ( num == 0 ) { @@ -23,7 +23,7 @@ namespace Rokojori iterationIndex = MathX.Repeat( iterationIndex, num ); - Actions.Trigger( this.GetNthDirectChild( iterationIndex ) ); + Action.Trigger( this.GetNthDirectChild( iterationIndex ) ); iterationIndex++; } diff --git a/Runtime/Actions/LoadScene.cs b/Runtime/Actions/LoadScene.cs index 3a88ffc..be40cc5 100644 --- a/Runtime/Actions/LoadScene.cs +++ b/Runtime/Actions/LoadScene.cs @@ -5,7 +5,7 @@ using System.Collections.Generic; namespace Rokojori { [GlobalClass] - public partial class LoadScene : RJSequenceAction + public partial class LoadScene : SequenceAction { [Export] public string scenePath; @@ -14,13 +14,13 @@ namespace Rokojori public Node target; [Export] - public RJAction onLoaded; + public Action onLoaded; bool _loading = false; int _id = -1; List _cached = new List(); - public override void _OnTrigger() + protected override void _OnTrigger() { if ( _loading ) { @@ -59,7 +59,7 @@ namespace Rokojori var packedScene = (PackedScene) ResourceLoader.LoadThreadedGet( scenePath ); var node = packedScene.Instantiate(); target.AddChild( node ); - Actions.Trigger( onLoaded ); + Action.Trigger( onLoaded ); DispatchEnd( _id ); _id = -1; @@ -67,7 +67,7 @@ namespace Rokojori ( c )=> { target.AddChild( packedScene.Instantiate() ); - Actions.Trigger( onLoaded ); + Action.Trigger( onLoaded ); DispatchEnd( c ); } ); diff --git a/Runtime/Actions/Node/SetNodeState.cs b/Runtime/Actions/Node/SetNodeState.cs index b186d7a..00081c1 100644 --- a/Runtime/Actions/Node/SetNodeState.cs +++ b/Runtime/Actions/Node/SetNodeState.cs @@ -5,7 +5,7 @@ using Godot; namespace Rokojori { [GlobalClass ] - public partial class SetNodeState : RJAction + public partial class SetNodeState : Action { [Export] public Node[] enable; @@ -14,7 +14,7 @@ namespace Rokojori public Node[] disable; - public override void _OnTrigger() + protected override void _OnTrigger() { Arrays.ForEach( enable, n => NodeState.Enable( n ) ); Arrays.ForEach( disable, n => NodeState.Disable( n ) ); diff --git a/Runtime/Actions/Node3D/CopyMousePosition.cs b/Runtime/Actions/Node3D/CopyMousePosition.cs index 54552fe..903a479 100644 --- a/Runtime/Actions/Node3D/CopyMousePosition.cs +++ b/Runtime/Actions/Node3D/CopyMousePosition.cs @@ -5,7 +5,7 @@ using Godot; namespace Rokojori { [GlobalClass ] - public partial class CopyMousePosition : RJAction + public partial class CopyMousePosition : Action { [Export] public Camera3D camera; @@ -17,7 +17,7 @@ namespace Rokojori public Node3D target; - public override void _OnTrigger() + protected override void _OnTrigger() { if ( camera == null || target == null ) { diff --git a/Runtime/Actions/Node3D/CopyPose.cs b/Runtime/Actions/Node3D/CopyPose.cs index f64e1db..ef40782 100644 --- a/Runtime/Actions/Node3D/CopyPose.cs +++ b/Runtime/Actions/Node3D/CopyPose.cs @@ -5,7 +5,7 @@ using Godot; namespace Rokojori { [GlobalClass, Tool ] - public partial class CopyPose : RJAction + public partial class CopyPose : Action { [Export] public Node3D source; @@ -20,7 +20,7 @@ namespace Rokojori } - public override void _OnTrigger() + protected override void _OnTrigger() { if ( source == null || target == null ) { diff --git a/Runtime/Actions/Node3D/CopyPosition.cs b/Runtime/Actions/Node3D/CopyPosition.cs index a91c27c..c33b49c 100644 --- a/Runtime/Actions/Node3D/CopyPosition.cs +++ b/Runtime/Actions/Node3D/CopyPosition.cs @@ -5,7 +5,7 @@ using Godot; namespace Rokojori { [GlobalClass, Tool ] - public partial class CopyPosition : RJAction + public partial class CopyPosition : Action { [Export] public Node3D source; @@ -20,7 +20,7 @@ namespace Rokojori } - public override void _OnTrigger() + protected override void _OnTrigger() { if ( source == null || target == null ) { diff --git a/Runtime/Actions/Node3D/DistributeChildren.cs b/Runtime/Actions/Node3D/DistributeChildren.cs index aa97cf4..9cf80dd 100644 --- a/Runtime/Actions/Node3D/DistributeChildren.cs +++ b/Runtime/Actions/Node3D/DistributeChildren.cs @@ -5,7 +5,7 @@ using Godot; namespace Rokojori { [GlobalClass, Tool ] - public partial class DistributeChildren : RJAction + public partial class DistributeChildren : Action { [Export] public Node3D target; @@ -23,7 +23,7 @@ namespace Rokojori } - public override void _OnTrigger() + protected override void _OnTrigger() { if ( start == null || end == null || target == null ) { diff --git a/Runtime/Actions/Node3D/LerpPosition.cs b/Runtime/Actions/Node3D/LerpPosition.cs index 6daa92e..14df5b6 100644 --- a/Runtime/Actions/Node3D/LerpPosition.cs +++ b/Runtime/Actions/Node3D/LerpPosition.cs @@ -4,7 +4,7 @@ using Godot; namespace Rokojori { [GlobalClass ] - public partial class LerpPosition : RJAction + public partial class LerpPosition : Action { [Export] public Node3D sourceA; @@ -18,7 +18,7 @@ namespace Rokojori [Export] public Node3D target; - public override void _OnTrigger() + protected override void _OnTrigger() { if ( sourceA == null || sourceB == null || target == null ) { diff --git a/Runtime/Actions/Node3D/LookAt.cs b/Runtime/Actions/Node3D/LookAt.cs index 040cdb2..60cb7bb 100644 --- a/Runtime/Actions/Node3D/LookAt.cs +++ b/Runtime/Actions/Node3D/LookAt.cs @@ -4,7 +4,7 @@ using Godot; namespace Rokojori { [GlobalClass, Tool ] - public partial class LookAt : RJAction + public partial class LookAt : Action { [Export] public Node3D lookTarget; @@ -17,7 +17,7 @@ namespace Rokojori _OnTrigger(); } - public override void _OnTrigger() + protected override void _OnTrigger() { if ( lookFrom == null || lookTarget == null ) { diff --git a/Runtime/Actions/OnPhysicsProcess.cs b/Runtime/Actions/OnPhysicsProcess.cs index 989f011..722844b 100644 --- a/Runtime/Actions/OnPhysicsProcess.cs +++ b/Runtime/Actions/OnPhysicsProcess.cs @@ -9,15 +9,15 @@ namespace Rokojori { /** Actions to execute*/ [Export] - public RJAction[] actions; + public Action[] actions; - /** Whether to execute RJAction child nodes*/ + /** Whether to execute Action child nodes*/ [Export] public bool triggerDirectChildren = true; public override void _PhysicsProcess( double delta ) { - Actions.TriggerAll( actions, this, triggerDirectChildren ); + Action.TriggerAll( actions, this, triggerDirectChildren ); } } } \ No newline at end of file diff --git a/Runtime/Actions/OnProcess.cs b/Runtime/Actions/OnProcess.cs index 2a376e8..f92e394 100644 --- a/Runtime/Actions/OnProcess.cs +++ b/Runtime/Actions/OnProcess.cs @@ -9,9 +9,9 @@ namespace Rokojori { /** Actions to execute*/ [Export] - public RJAction[] actions; + public Action[] actions; - /** Whether to execute RJAction child nodes*/ + /** Whether to execute Action child nodes*/ [Export] public bool triggerDirectChildren = true; @@ -25,7 +25,7 @@ namespace Rokojori return; } - Actions.TriggerAll( actions, this, triggerDirectChildren ); + Action.TriggerAll( actions, this, triggerDirectChildren ); } } } \ No newline at end of file diff --git a/Runtime/Actions/OnReady.cs b/Runtime/Actions/OnReady.cs index 8028ed5..f28dea2 100644 --- a/Runtime/Actions/OnReady.cs +++ b/Runtime/Actions/OnReady.cs @@ -9,15 +9,15 @@ namespace Rokojori { /** Actions to execute*/ [Export] - public RJAction[] actions; + public Action[] actions; - /** Whether to execute RJAction child nodes*/ + /** Whether to execute Action child nodes*/ [Export] public bool triggerDirectChildren = true; public override void _Ready() { - Actions.TriggerAll( actions, this, triggerDirectChildren ); + Action.TriggerAll( actions, this, triggerDirectChildren ); } } } \ No newline at end of file diff --git a/Runtime/Actions/RJLogMessage.cs b/Runtime/Actions/RJLogMessage.cs index a93c717..d9be67a 100644 --- a/Runtime/Actions/RJLogMessage.cs +++ b/Runtime/Actions/RJLogMessage.cs @@ -5,12 +5,12 @@ using Godot; namespace Rokojori { [GlobalClass ] - public partial class RJLogMessage : RJAction + public partial class RJLogMessage : Action { [Export] public string message; - public override void _OnTrigger() + protected override void _OnTrigger() { RJLog.Log( message ); } diff --git a/Runtime/Actions/SequenceAction.cs b/Runtime/Actions/SequenceAction.cs new file mode 100644 index 0000000..2e2a5ec --- /dev/null +++ b/Runtime/Actions/SequenceAction.cs @@ -0,0 +1,68 @@ + +using Godot; + + +namespace Rokojori +{ + + public class SequenceActionFinishedEvent + { + public int id; + public bool success; + } + + [GlobalClass ] + public partial class SequenceAction : Action + { + + /* + + int dispatchStart(); + void dispatchCancelled( int id ); + void dispatchEnd( int id ); + + int getLastSequenceActionID(); + GDVIRTUAL1( cancelAction, int ); + + /* signal onSequenceDone * / + + + + */ + + + + int _dispatchCounter = 0; + + public int GetLastSequenceActionID() + { + return _dispatchCounter; + } + + public readonly EventSlot onSequenceDone = new EventSlot(); + + public int DispatchStart() + { + _dispatchCounter ++; + return _dispatchCounter; + } + + public void DispatchEnd( int id ) + { + onSequenceDone.DispatchEvent( new SequenceActionFinishedEvent{ id = id, success = true } ); + } + + public void DispatchCancelled( int id ) + { + onSequenceDone.DispatchEvent( new SequenceActionFinishedEvent{ id = id, success = false } ); + } + + public virtual void CancelAction( int id ) + { + + } + + + } + +} \ No newline at end of file diff --git a/Runtime/Actions/TriggerActionInEditor.cs b/Runtime/Actions/TriggerActionInEditor.cs index 290c758..de05a35 100644 --- a/Runtime/Actions/TriggerActionInEditor.cs +++ b/Runtime/Actions/TriggerActionInEditor.cs @@ -9,7 +9,7 @@ namespace Rokojori public partial class TriggerActionInEditor : Node { [Export] - public RJAction action; + public Action action; [Export] public bool execute; diff --git a/Runtime/Animation/AnimationManager.cs b/Runtime/Animation/AnimationManager.cs index 783105b..540b28a 100644 --- a/Runtime/Animation/AnimationManager.cs +++ b/Runtime/Animation/AnimationManager.cs @@ -21,6 +21,15 @@ namespace Rokojori public class AnimationMember { + public static readonly AnimationMember Position = new AnimationMember( "position" ); + public static readonly AnimationMember Rotation = new AnimationMember( "rotation" ); + public static readonly AnimationMember Scale = new AnimationMember( "scale" ); + + public static readonly AnimationMember[] Transform = new AnimationMember[] + { + AnimationMember.Position, AnimationMember.Rotation, AnimationMember.Scale + }; + string _name; public string name => _name; @@ -34,18 +43,42 @@ namespace Rokojori { static MultiMap _animating = new MultiMap(); - public static AnimationMember position = new AnimationMember( "position" ); - public static AnimationMember rotation = new AnimationMember( "rotation" ); - public static AnimationMember scale = new AnimationMember( "scale" ); + public static Animator GetAnimator( Node node, AnimationMember member ) { - return _animating[ node ][ member.name ]; + return _animating.Get( node, member.name ); } public static bool IsAnimating( Animator animator, Node node, AnimationMember member ) { return GetAnimator( node, member ) == animator; + } + + public static bool IsAnimating( Animator animator, Node node, params AnimationMember[] members ) + { + for ( int i = 0; i < members.Length; i++ ) + { + if ( ! IsAnimating( animator, node, members[ i ] ) ) + { + return false; + } + } + + return members.Length > 0; + } + + public static bool IsAnimating( Animator animator, Node[] nodes, params AnimationMember[] members ) + { + for ( int i = 0; i < nodes.Length; i++ ) + { + if ( ! IsAnimating( animator, nodes[ i ], members ) ) + { + return false; + } + } + + return nodes.Length > 0; } public static void StartAnimation( Animator animator, Node node, AnimationMember member ) @@ -61,6 +94,22 @@ namespace Rokojori } + public static void StartAnimation( Animator animator, Node node, params AnimationMember[] members ) + { + for ( int i = 0; i < members.Length; i++ ) + { + StartAnimation( animator, node, members[ i ] ); + } + } + + public static void StartAnimation( Animator animator, Node[] nodes, params AnimationMember[] members ) + { + for ( int i = 0; i < nodes.Length; i++ ) + { + StartAnimation( animator, nodes[ i ], members ); + } + } + public static void EndAnimation( Animator animator, Node node, AnimationMember member ) { var activeAnimator = GetAnimator( node, member ); @@ -70,5 +119,21 @@ namespace Rokojori activeAnimator.OnAnimatorCancel(); } } + + public static void EndAnimation( Animator animator, Node node, params AnimationMember[] members ) + { + for ( int i = 0; i < members.Length; i++ ) + { + EndAnimation( animator, node, members[ i ] ); + } + } + + public static void EndAnimation( Animator animator, Node[] nodes, params AnimationMember[] members ) + { + for ( int i = 0; i < nodes.Length; i++ ) + { + EndAnimation( animator, nodes[ i ], members ); + } + } } } \ No newline at end of file diff --git a/Runtime/Animation/Flash.cs b/Runtime/Animation/Flash/Flash.cs similarity index 94% rename from Runtime/Animation/Flash.cs rename to Runtime/Animation/Flash/Flash.cs index ccecb3e..f1b8707 100644 --- a/Runtime/Animation/Flash.cs +++ b/Runtime/Animation/Flash/Flash.cs @@ -8,7 +8,7 @@ namespace Rokojori { [Tool] [GlobalClass] - public partial class Flash:RJSequenceAction + public partial class Flash:SequenceAction { [Export] public FlashEffect flashEffect; @@ -41,22 +41,27 @@ namespace Rokojori return color; } - public override void _OnTrigger() + protected override void _OnTrigger() { if ( actionID != -1 ) { CancelAction( actionID ); } + actionID = DispatchStart(); - // RJLog.Log( "Setting actionID id", actionID, GetLastSequenceActionID() ); + var random = LCG.Randomized(); + + var networkSeed = random.GetSeed(); + + RJLog.Log( "Setting actionID id", actionID, GetLastSequenceActionID() ); var flashCurve = flashEffect.flashCurve; var color = flashEffect.color.GetHDRColor(); var timeline = flashEffect.timeline; - randomization = flashCurve.Randomize(); + randomization = flashCurve.Randomize( random ); var duration = flashCurve.GetRandomizedDuration( randomization ); @@ -139,7 +144,7 @@ namespace Rokojori var end = start + duration; animationID = TimeLineScheduler.ScheduleSpanIn( timeline, 0, duration, - ( int id, int type )=> + ( int id, TimeLineSpanUpdateType type )=> { if ( animationID != id ) @@ -196,7 +201,7 @@ namespace Rokojori ); - if ( type == TimeLineSpan.End ) + if ( type == TimeLineSpanUpdateType.End ) { if ( light != null ) { diff --git a/Runtime/Animation/FlashEffect.cs b/Runtime/Animation/Flash/FlashEffect.cs similarity index 96% rename from Runtime/Animation/FlashEffect.cs rename to Runtime/Animation/Flash/FlashEffect.cs index 50226ec..8992f49 100644 --- a/Runtime/Animation/FlashEffect.cs +++ b/Runtime/Animation/Flash/FlashEffect.cs @@ -15,6 +15,10 @@ namespace Rokojori [Export] public AnimationCurve flashCurve; + [Export] + public TimeLine timeline; + + [Export] public HDRColor color; @@ -61,8 +65,7 @@ namespace Rokojori [Export] public ColorPropertyName customFlashColorProperty; - [Export] - public RJTimeLine timeline; + diff --git a/Runtime/Animation/Flash/Blue-Shield-FlashEffect.tres b/Runtime/Animation/Flash/Presets/Blue Shield - Flash.tres similarity index 84% rename from Runtime/Animation/Flash/Blue-Shield-FlashEffect.tres rename to Runtime/Animation/Flash/Presets/Blue Shield - Flash.tres index 41f0c1e..2294de4 100644 --- a/Runtime/Animation/Flash/Blue-Shield-FlashEffect.tres +++ b/Runtime/Animation/Flash/Presets/Blue Shield - Flash.tres @@ -2,8 +2,8 @@ [ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/HDRColor.cs" id="1_ejko8"] [ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/AnimationCurve.cs" id="2_3i2og"] -[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/FlashEffect.cs" id="3_65ipm"] -[ext_resource type="RJTimeLine" uid="uid://frruktikky46" path="res://addons/rokojori_action_library/Runtime/Time/TimeLines/GameTime.tres" id="4_urqjo"] +[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/Flash/FlashEffect.cs" id="3_65ipm"] +[ext_resource type="Resource" uid="uid://ch5nsa6yafs5l" path="res://addons/rokojori_action_library/Runtime/Time/TimeLines/GameTime.tres" id="4_nyaof"] [sub_resource type="Resource" id="Resource_54hj8"] script = ExtResource("1_ejko8") @@ -29,10 +29,10 @@ scaleRandomRange = 0.0 [resource] script = ExtResource("3_65ipm") flashCurve = SubResource("Resource_pwp07") +timeline = ExtResource("4_nyaof") color = SubResource("Resource_54hj8") lightMode = 1 lightRange = 5.0 lightFlashCurveScale = 5.0 lightHasShadows = true materialMode = 3 -timeline = ExtResource("4_urqjo") diff --git a/Runtime/Animation/Flash/Green-Charge-FlashEffect.tres b/Runtime/Animation/Flash/Presets/Green Charge - Flash.tres similarity index 83% rename from Runtime/Animation/Flash/Green-Charge-FlashEffect.tres rename to Runtime/Animation/Flash/Presets/Green Charge - Flash.tres index d8f953c..57938f1 100644 --- a/Runtime/Animation/Flash/Green-Charge-FlashEffect.tres +++ b/Runtime/Animation/Flash/Presets/Green Charge - Flash.tres @@ -2,8 +2,8 @@ [ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/HDRColor.cs" id="1_yrhv1"] [ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/AnimationCurve.cs" id="2_cdv3p"] -[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/FlashEffect.cs" id="3_87ql1"] -[ext_resource type="RJTimeLine" uid="uid://frruktikky46" path="res://addons/rokojori_action_library/Runtime/Time/TimeLines/GameTime.tres" id="4_t20yf"] +[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/Flash/FlashEffect.cs" id="3_87ql1"] +[ext_resource type="Resource" uid="uid://ch5nsa6yafs5l" path="res://addons/rokojori_action_library/Runtime/Time/TimeLines/GameTime.tres" id="4_2na64"] [sub_resource type="Resource" id="Resource_54hj8"] script = ExtResource("1_yrhv1") @@ -29,10 +29,10 @@ scaleRandomRange = 0.0 [resource] script = ExtResource("3_87ql1") flashCurve = SubResource("Resource_pwp07") +timeline = ExtResource("4_2na64") color = SubResource("Resource_54hj8") lightMode = 1 lightRange = 5.0 lightFlashCurveScale = 2.0 lightHasShadows = true materialMode = 2 -timeline = ExtResource("4_t20yf") diff --git a/Runtime/Animation/Flash/Orange-Boost-FlashEffect.tres b/Runtime/Animation/Flash/Presets/Orange Boost - Flash.tres similarity index 82% rename from Runtime/Animation/Flash/Orange-Boost-FlashEffect.tres rename to Runtime/Animation/Flash/Presets/Orange Boost - Flash.tres index 4c09d57..bc6e5f0 100644 --- a/Runtime/Animation/Flash/Orange-Boost-FlashEffect.tres +++ b/Runtime/Animation/Flash/Presets/Orange Boost - Flash.tres @@ -2,8 +2,8 @@ [ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/HDRColor.cs" id="1_c8lnw"] [ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/AnimationCurve.cs" id="2_w323b"] -[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/FlashEffect.cs" id="3_eqd4c"] -[ext_resource type="RJTimeLine" uid="uid://frruktikky46" path="res://addons/rokojori_action_library/Runtime/Time/TimeLines/GameTime.tres" id="4_03b60"] +[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/Flash/FlashEffect.cs" id="3_eqd4c"] +[ext_resource type="Resource" uid="uid://ch5nsa6yafs5l" path="res://addons/rokojori_action_library/Runtime/Time/TimeLines/GameTime.tres" id="4_cs6ks"] [sub_resource type="Resource" id="Resource_ny3sx"] script = ExtResource("1_c8lnw") @@ -29,10 +29,10 @@ scaleRandomRange = 0.0 [resource] script = ExtResource("3_eqd4c") flashCurve = SubResource("Resource_pwp07") +timeline = ExtResource("4_cs6ks") color = SubResource("Resource_ny3sx") lightMode = 1 lightRange = 4.0 lightFlashCurveScale = 1.0 lightHasShadows = false materialMode = 1 -timeline = ExtResource("4_03b60") diff --git a/Runtime/Animation/Flash/Red-Hit-FlashEffect.tres b/Runtime/Animation/Flash/Presets/Red Hit - Flash.tres similarity index 76% rename from Runtime/Animation/Flash/Red-Hit-FlashEffect.tres rename to Runtime/Animation/Flash/Presets/Red Hit - Flash.tres index 444d845..d403e69 100644 --- a/Runtime/Animation/Flash/Red-Hit-FlashEffect.tres +++ b/Runtime/Animation/Flash/Presets/Red Hit - Flash.tres @@ -2,8 +2,8 @@ [ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/HDRColor.cs" id="1_nmdum"] [ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/AnimationCurve.cs" id="2_0sgd7"] -[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/FlashEffect.cs" id="3_7qcuh"] -[ext_resource type="RJTimeLine" uid="uid://frruktikky46" path="res://addons/rokojori_action_library/Runtime/Time/TimeLines/GameTime.tres" id="4_8oykd"] +[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/Flash/FlashEffect.cs" id="3_7qcuh"] +[ext_resource type="Resource" uid="uid://ch5nsa6yafs5l" path="res://addons/rokojori_action_library/Runtime/Time/TimeLines/GameTime.tres" id="4_rkq1j"] [sub_resource type="Resource" id="Resource_54hj8"] script = ExtResource("1_nmdum") @@ -29,6 +29,10 @@ scaleRandomRange = 0.0 [resource] script = ExtResource("3_7qcuh") flashCurve = SubResource("Resource_pwp07") +timeline = ExtResource("4_rkq1j") color = SubResource("Resource_54hj8") +lightMode = 0 +lightRange = 2.0 +lightFlashCurveScale = 2.0 +lightHasShadows = false materialMode = 0 -timeline = ExtResource("4_8oykd") diff --git a/Runtime/Animation/Flash/White-Blinking-FlashEffect.tres b/Runtime/Animation/Flash/Presets/White Blinking - Flash.tres similarity index 86% rename from Runtime/Animation/Flash/White-Blinking-FlashEffect.tres rename to Runtime/Animation/Flash/Presets/White Blinking - Flash.tres index 647f4a9..4a74d84 100644 --- a/Runtime/Animation/Flash/White-Blinking-FlashEffect.tres +++ b/Runtime/Animation/Flash/Presets/White Blinking - Flash.tres @@ -2,8 +2,8 @@ [ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/HDRColor.cs" id="1_pp4qy"] [ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/AnimationCurve.cs" id="2_f6f0o"] -[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/FlashEffect.cs" id="3_dq1j1"] -[ext_resource type="RJTimeLine" uid="uid://frruktikky46" path="res://addons/rokojori_action_library/Runtime/Time/TimeLines/GameTime.tres" id="4_v17wj"] +[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/Flash/FlashEffect.cs" id="3_dq1j1"] +[ext_resource type="Resource" uid="uid://ch5nsa6yafs5l" path="res://addons/rokojori_action_library/Runtime/Time/TimeLines/GameTime.tres" id="4_d6hj6"] [sub_resource type="Resource" id="Resource_ny3sx"] script = ExtResource("1_pp4qy") @@ -29,10 +29,10 @@ scaleRandomRange = 0.0 [resource] script = ExtResource("3_dq1j1") flashCurve = SubResource("Resource_pwp07") +timeline = ExtResource("4_d6hj6") color = SubResource("Resource_ny3sx") lightMode = 0 lightRange = 2.0 lightFlashCurveScale = 2.0 lightHasShadows = false materialMode = 0 -timeline = ExtResource("4_v17wj") diff --git a/Runtime/Animation/KeyFrames/KeyFrame.cs b/Runtime/Animation/KeyFrames/KeyFrame.cs new file mode 100644 index 0000000..87de6e1 --- /dev/null +++ b/Runtime/Animation/KeyFrames/KeyFrame.cs @@ -0,0 +1,14 @@ +using System.Collections; +using System.Collections.Generic; +using System.Text.RegularExpressions; +using System.Text; +using Godot; + +namespace Rokojori +{ + public class KeyFrame + { + public float time; + public T data; + } +} \ No newline at end of file diff --git a/Runtime/Animation/KeyFrames/KeyFrameAnimation.cs b/Runtime/Animation/KeyFrames/KeyFrameAnimation.cs new file mode 100644 index 0000000..c7b038c --- /dev/null +++ b/Runtime/Animation/KeyFrames/KeyFrameAnimation.cs @@ -0,0 +1,131 @@ +using System.Collections; +using System.Collections.Generic; +using System.Text.RegularExpressions; +using System.Text; +using Godot; + +namespace Rokojori +{ + public class KeyFrameAnimation + { + public List> keyFrames = new List>(); + + int _currentIndex = -1; + bool _sorted = false; + + public void FlagUnsorted() + { + _sorted = false; + } + + public void FlagSorted() + { + _sorted = true; + } + + + public void Sort() + { + if ( _sorted ) + { + return; + } + + keyFrames.Sort( ( a, b ) => Mathf.Sign( a.time - b.time ) ); + + _sorted = true; + } + + public KeyFrame GetKeyFrameAt( float time ) + { + var index = GetKeyFrameIndexAt( time ); + + return index == -1 ? null : keyFrames[ index ]; + } + + public int GetKeyFrameIndexAt( float time ) + { + if ( keyFrames.Count == 0 ) + { + return -1; + } + + Sort(); + + for ( int i = 0; i < keyFrames.Count; i++ ) + { + if ( keyFrames[ i ].time > time ) + { + return Mathf.Max( 0, i - 1 ); + } + } + + if ( _sorted ) + { + return keyFrames.Count - 1; + } + + if ( IsKeyFrameAt( time, _currentIndex ) ) + { + return _currentIndex; + } + + _currentIndex = MathX.SafeIndex( _currentIndex, keyFrames ); + + var kf = keyFrames[ _currentIndex ]; + + if ( kf.time < time ) + { + _currentIndex ++; + + while ( _currentIndex < keyFrames.Count ) + { + if ( IsKeyFrameAt( time, _currentIndex ) ) + { + return _currentIndex; + } + + _currentIndex ++; + } + } + else + { + _currentIndex --; + + while ( _currentIndex > -1 ) + { + if ( IsKeyFrameAt( time, _currentIndex ) ) + { + return _currentIndex; + } + + _currentIndex --; + } + } + + return -1; + } + + + bool IsKeyFrameAt( float time, int index ) + { + if ( index < 0 || index >= keyFrames.Count -1 ) + { + return false; + } + + var i = keyFrames[ index ]; + + if ( i.time < time && index == keyFrames.Count - 1 ) + { + return true; + } + + var n = keyFrames[ index + 1 ]; + + return i.time < time && time < n.time; + + } + + } +} \ No newline at end of file diff --git a/Runtime/Animation/Shake/Presets/Small Impact - Shake.tres b/Runtime/Animation/Shake/Presets/Small Impact - Shake.tres new file mode 100644 index 0000000..7ee541d --- /dev/null +++ b/Runtime/Animation/Shake/Presets/Small Impact - Shake.tres @@ -0,0 +1,49 @@ +[gd_resource type="Resource" script_class="ShakeEffect" load_steps=8 format=3 uid="uid://c2wbn25rxynk8"] + +[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/Shake/ShakeEffect.cs" id="1_41sot"] +[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/AnimationCurve.cs" id="2_rwbu4"] +[ext_resource type="Resource" uid="uid://h6oi6vkj4c2m" path="res://addons/rokojori_action_library/Runtime/Time/TimeLines/RealTime.tres" id="3_rqeiy"] + +[sub_resource type="Curve" id="Curve_j2uji"] +min_value = -1.0 +_data = [Vector2(0, 1), 0.0, -0.608916, 0, 0, Vector2(1, -1), -3.46819, 0.0, 0, 0] +point_count = 2 + +[sub_resource type="Resource" id="Resource_jwnpm"] +script = ExtResource("2_rwbu4") +duration = 0.4 +durationRandomRange = 0.0 +delay = 0.0 +delayRandomRange = 0.0 +curve = SubResource("Curve_j2uji") +scaleY = 1.0 +scaleRandomRange = 0.0 + +[sub_resource type="Curve" id="Curve_b6b7u"] +_data = [Vector2(0, 0.368339), 0.0, 3.25035, 0, 0, Vector2(0.264591, 0.73511), 0.0, 0.0, 0, 0, Vector2(1, 0.266458), -0.637268, 0.0, 1, 0] +point_count = 3 + +[sub_resource type="Resource" id="Resource_1s2e6"] +script = ExtResource("2_rwbu4") +duration = 0.5 +durationRandomRange = 0.0 +delay = 0.0 +delayRandomRange = 0.0 +curve = SubResource("Curve_b6b7u") +scaleY = 30.0 +scaleRandomRange = 0.0 + +[resource] +script = ExtResource("1_41sot") +shakeAmountCurve = SubResource("Resource_jwnpm") +shakeChangeFPSCurve = SubResource("Resource_1s2e6") +timeline = ExtResource("3_rqeiy") +smooth = true +smoothingStrength = 0.291 +positionShake = Vector3(0.075, 0, 0.075) +globalPosition = true +repeatAndFlipFirstPosition = true +rotationShake = Vector3(2, 2, 40) +globalRotation = false +scaleShake = Vector3(0.5, 0.5, 0.1) +scaleShakeIsRelative = true diff --git a/Runtime/Animation/Shake/Shake.cs b/Runtime/Animation/Shake/Shake.cs index 7229dd0..e5a5b24 100644 --- a/Runtime/Animation/Shake/Shake.cs +++ b/Runtime/Animation/Shake/Shake.cs @@ -8,7 +8,7 @@ namespace Rokojori { [Tool] [GlobalClass] - public partial class Shake:RJSequenceAction + public partial class Shake:SequenceAction, Animator { [Export] public ShakeEffect shakeEffect; @@ -16,45 +16,159 @@ namespace Rokojori [Export] public Node3D[] targets; - List _targetValues; + List _targetValues; - int actionID = -1; - int animationID = -1; + int _actionID = -1; + int _currentSpanAnimationID = -1; - public override void _OnTrigger() + public void OnAnimatorStart(){} + public void OnAnimatorEnd(){} + public void OnAnimatorCancel(){} + + protected override void _OnTrigger() { - if ( actionID != -1 ) + if ( _actionID != -1 ) { - CancelAction( actionID ); + CancelAction( _actionID ); } - actionID = DispatchStart(); + _actionID = DispatchStart(); - var random = shakeEffect.shakeCurve.Randomize(); + var random = LCG.Randomized(); + + var networkSeed = random.GetSeed(); + + var randomization = shakeEffect.shakeAmountCurve.Randomize( random ); var timeline = shakeEffect.timeline; - var duration = shakeEffect.shakeCurve.GetRandomizedEndTime( random ); + var duration = shakeEffect.shakeAmountCurve.GetRandomizedEndTime( randomization ); + var curve = shakeEffect; var start = TimeLineManager.GetPosition( shakeEffect.timeline ); - var end = start + duration; + var keyFrames = new List>(); + var elapsed = 0f; + + while ( elapsed < duration ) + { + var key = new KeyFrame(); + key.data = shakeEffect.GetShakeData( elapsed, randomization, random ); + key.time = elapsed; + keyFrames.Add( key ); + + elapsed += 1f / shakeEffect.GetShakeChangeFPSRandomized( elapsed, random ); + } + + var kfAnimation = new KeyFrameAnimation(); + kfAnimation.keyFrames = keyFrames; + kfAnimation.FlagSorted(); + + KeyFrame lastKeyFrame = null; + + AnimationManager.StartAnimation( this, targets, AnimationMember.Transform ); + + if ( _targetValues == null || _targetValues.Count == 0 ) + { + _targetValues = Lists.Map( targets, t => TransformData.From( t, shakeEffect.globalPosition, shakeEffect.globalRotation ) ); + } - animationID = TimeLineScheduler.ScheduleSpanIn( timeline, 0, duration, - ( int id, int type )=> - { - if ( animationID != id ) + + _currentSpanAnimationID = TimeLineScheduler.ScheduleSpanIn( timeline, 0, duration, + ( int spanAnimationID, TimeLineSpanUpdateType type )=> + { + if ( spanAnimationID != _currentSpanAnimationID ) { return; } + + if ( ! AnimationManager.IsAnimating( this, targets, AnimationMember.Transform ) ) + { + return; + } + + + if ( TimeLineSpanUpdateType.End == type ) + { + AnimationManager.EndAnimation( this, targets, AnimationMember.Transform ); + + for ( int i = 0; i < targets.Length; i++ ) + { + var o = _targetValues[ i ]; + + o.Set( targets[ i ], shakeEffect.globalPosition, shakeEffect.globalRotation ); + } + + _targetValues.Clear(); + _actionID = -1; + _currentSpanAnimationID = -1; + + return; + } + + + var offset = TimeLineManager.GetPosition( shakeEffect.timeline ) - start; + var keyFrame = kfAnimation.GetKeyFrameAt( offset ); + + if ( keyFrame == lastKeyFrame && ! shakeEffect.smooth ) + { + return; + } + + var offsetData = keyFrame.data; + var delta = shakeEffect.timeline.delta; + + for ( int i = 0; i < targets.Length; i++ ) + { + var combined = offsetData.Clone(); + + var o = _targetValues[ i ]; + + if ( shakeEffect.scaleShakeIsRelative ) + { + combined.scale *= _targetValues[ i ].scale; + } + + combined.rotation *= MathX.DegreesToRadians; + + var beforeAdd = combined.Clone(); + + combined.Add( o ); + + // this.LogInfo( "Applying:", beforeAdd, " + ", o, "=", combined ); + + + if ( shakeEffect.smooth ) + { + var rawSmooth = Mathf.Clamp( shakeEffect.smoothingStrength, 0, 1 ); + rawSmooth = Mathf.Pow( 1f - rawSmooth, 3 ); + var smoothStrength = rawSmooth * 250f; + + var current = TransformData.From( targets[ i ], shakeEffect.globalPosition, shakeEffect.globalRotation ); + combined.position = Smoother.SmoothTimeInvariant( current.position, combined.position, delta, smoothStrength ); + combined.rotation = Smoother.SmoothTimeInvariant( current.rotation, combined.rotation, delta, smoothStrength ); + combined.scale = Smoother.SmoothTimeInvariant( current.scale, combined.scale, delta, smoothStrength ); + } + + combined.Set( targets[ i ], shakeEffect.globalPosition, shakeEffect.globalRotation ); + } + + lastKeyFrame = keyFrame; } ); } - public override void CancelAction( int id ) + public override void CancelAction( int actionID ) { + if ( actionID != _actionID ) + { + return; + } + AnimationManager.EndAnimation( this, targets, AnimationMember.Transform ); + _actionID = -1; + _currentSpanAnimationID = -1; } } } \ No newline at end of file diff --git a/Runtime/Animation/Shake/ShakeEffect.cs b/Runtime/Animation/Shake/ShakeEffect.cs index e502d18..ae8f45e 100644 --- a/Runtime/Animation/Shake/ShakeEffect.cs +++ b/Runtime/Animation/Shake/ShakeEffect.cs @@ -12,27 +12,63 @@ namespace Rokojori { [Export] - public AnimationCurve shakeCurve; + public AnimationCurve shakeAmountCurve; + + [Export] + public AnimationCurve shakeChangeFPSCurve; + + [Export] + public AnimationCurve shakeChangeFPSRandomCurve; + + [Export] + public TimeLine timeline; + + [Export] + public bool smooth = true; + + [Export( PropertyHint.Range, "0,1" )] + public float smoothingStrength = 0; + + public float GetShakeChangeFPSRandomized( float time, RandomEngine random = null ) + { + random = RandomEngine.CreateIfNull( random ); + var staticChange = shakeChangeFPSCurve == null ? 10 : shakeChangeFPSCurve.Sample( time ); + var randomChange = shakeChangeFPSRandomCurve == null ? 0 : shakeChangeFPSRandomCurve.Sample( time ); + return staticChange + random.Polar( randomChange ); + } [Export] public Vector3 positionShake = Vector3.Zero; [Export] - public Vector3 positionShakeRandom = Vector3.Zero; + public bool globalPosition = true; + [Export] + public bool repeatAndFlipFirstPosition = true; [Export] public Vector3 rotationShake = Vector3.Zero; [Export] - public Vector3 rotationShakeRandom = Vector3.Zero; + public bool globalRotation = true; [Export] public Vector3 scaleShake = Vector3.Zero; - [Export] - public Vector3 scaleShakeRandom = Vector3.Zero; - [Export] - public bool scaleIsPercentage = true; [Export] - public RJTimeLine timeline; + public bool scaleShakeIsRelative = true; + + public TransformData GetShakeData( float time, Vector3 curveRandomization, RandomEngine random = null ) + { + random = RandomEngine.CreateIfNull( random ); + + var shakeAmount = shakeAmountCurve.Sample( time, curveRandomization ); + + var transformData = new TransformData(); + transformData.position = random.IndividualBetween( -positionShake, positionShake ) * shakeAmount; + transformData.rotation = random.IndividualBetween( -rotationShake, rotationShake ) * shakeAmount; + transformData.scale = random.IndividualBetween( -scaleShake, scaleShake ) * shakeAmount; + + return transformData; + + } diff --git a/Runtime/Animation/Transform/AnimateTransform.cs b/Runtime/Animation/Transform/AnimateTransform.cs index 3d7793b..123fd7d 100644 --- a/Runtime/Animation/Transform/AnimateTransform.cs +++ b/Runtime/Animation/Transform/AnimateTransform.cs @@ -8,7 +8,7 @@ namespace Rokojori { [Tool] [GlobalClass] - public partial class AnimateTransform:RJSequenceAction, Animator + public partial class AnimateTransform:SequenceAction, Animator { [Export] @@ -25,7 +25,7 @@ namespace Rokojori public void OnAnimatorCancel(){} - public override void _OnTrigger() + protected override void _OnTrigger() { _frameValues = new List(); _randomizations = new List(); @@ -50,7 +50,7 @@ namespace Rokojori } TimeLineScheduler.ScheduleSpanIn( timeline, 0, duration, - ( int id, int type )=> + ( int id, TimeLineSpanUpdateType type )=> { var timeNow = TimeLineManager.GetPosition( timeline ); var elapsed = timeNow - start; @@ -67,7 +67,7 @@ namespace Rokojori index ++; } - if ( type == TimeLineSpan.End ) + if ( type == TimeLineSpanUpdateType.End ) { foreach ( var c in animations.curves ) { diff --git a/Runtime/Animation/Transform/TransformAnimations.cs b/Runtime/Animation/Transform/TransformAnimations.cs index fcf0d59..23b03bb 100644 --- a/Runtime/Animation/Transform/TransformAnimations.cs +++ b/Runtime/Animation/Transform/TransformAnimations.cs @@ -14,7 +14,7 @@ namespace Rokojori public TransformCurve[] curves; [Export] - public RJTimeLine timeline; + public TimeLine timeline; public float GetMaxDuration( List randomizations ) { diff --git a/Runtime/Animation/Transform/TransformData.cs b/Runtime/Animation/Transform/TransformData.cs new file mode 100644 index 0000000..7c2f29e --- /dev/null +++ b/Runtime/Animation/Transform/TransformData.cs @@ -0,0 +1,61 @@ +using System.Collections; +using System.Collections.Generic; +using System.Text.RegularExpressions; +using System.Text; +using Godot; + +namespace Rokojori +{ + public class TransformData + { + public Vector3 position; + public Vector3 rotation; + public Vector3 scale; + + + public TransformData Clone() + { + var data = new TransformData(); + data.position = position; + data.rotation = rotation; + data.scale = scale; + return data; + } + + public void Add( TransformData other ) + { + position += other.position; + rotation += other.rotation; + scale += other.scale; + } + + + public override string ToString() + { + return RJLog.Stringify( position ) + ", " + RJLog.Stringify( rotation ) + ", " + RJLog.Stringify( scale ); + } + + public void Set( Node3D node, bool globalPosition = true, bool globalRotation = true ) + { + TransformTargets.Set( position, node, TransformTargets.Position( globalPosition ) ); + TransformTargets.Set( rotation, node, TransformTargets.Rotation( globalRotation ) ); + TransformTargets.Set( scale, node, TransformTargets.Scale() ); + } + + public void Get( Node3D node, bool globalPosition = true, bool globalRotation = true ) + { + position = TransformTargets.Get( node, TransformTargets.Position( globalPosition ) ); + rotation = TransformTargets.Get( node, TransformTargets.Rotation( globalRotation ) ); + scale = TransformTargets.Get( node, TransformTargets.Scale() ); + } + + public static TransformData From( Node3D n, bool globalPosition = true, bool globalRotation = true ) + { + var td = new TransformData(); + td.Get( n, globalPosition, globalRotation ); + return td; + } + } + +} + \ No newline at end of file diff --git a/Runtime/Animation/Transform/TransformTarget.cs b/Runtime/Animation/Transform/TransformTarget.cs index 10f730e..be0834a 100644 --- a/Runtime/Animation/Transform/TransformTarget.cs +++ b/Runtime/Animation/Transform/TransformTarget.cs @@ -15,23 +15,40 @@ namespace Rokojori Local_Scale } + + public class TransformTargets { + public static TransformTarget Position( bool global = true ) + { + return global ? TransformTarget.Global_Position : TransformTarget.Local_Position; + } + + public static TransformTarget Rotation( bool global = true ) + { + return global ? TransformTarget.Global_Rotation : TransformTarget.Local_Rotation; + } + + public static TransformTarget Scale() + { + return TransformTarget.Local_Scale; + } + public static AnimationMember ToAnimationMember( TransformTarget target ) { if ( TransformTarget.Local_Position == target || TransformTarget.Global_Position == target ) { - return AnimationManager.position; + return AnimationMember.Position; } if ( TransformTarget.Local_Rotation == target || TransformTarget.Global_Rotation == target ) { - return AnimationManager.rotation; + return AnimationMember.Rotation; } if ( TransformTarget.Local_Scale == target ) { - return AnimationManager.scale; + return AnimationMember.Scale; } return null; @@ -45,6 +62,7 @@ namespace Rokojori } else if ( TransformTarget.Global_Rotation == transformTarget ) { + // RJLog.Log( "GlobalRotation => ", target.GlobalRotation ); return target.GlobalRotation; } else if ( TransformTarget.Local_Position == transformTarget ) @@ -53,6 +71,7 @@ namespace Rokojori } else if ( TransformTarget.Local_Rotation == transformTarget ) { + // RJLog.Log( "Rotation => ", target.Rotation ); return target.Rotation; } else if ( TransformTarget.Local_Scale == transformTarget ) @@ -71,7 +90,9 @@ namespace Rokojori } else if ( TransformTarget.Global_Rotation == transformTarget ) { + var rotation = target.GlobalRotation; target.GlobalRotation = value; + // RJLog.Log( "GlobalRotation = ", rotation, ">>", value, target.GlobalRotation ); } else if ( TransformTarget.Local_Position == transformTarget ) { @@ -79,7 +100,9 @@ namespace Rokojori } else if ( TransformTarget.Local_Rotation == transformTarget ) { + var rotation = target.Rotation; target.Rotation = value; + // RJLog.Log( "Rotation = ", rotation, ">>", value, target.Rotation ); } else if ( TransformTarget.Local_Scale == transformTarget ) { diff --git a/Runtime/Animation/Wipe/FadeWipeEffect.cs b/Runtime/Animation/Wipe/FadeWipeEffect.cs new file mode 100644 index 0000000..2652b4d --- /dev/null +++ b/Runtime/Animation/Wipe/FadeWipeEffect.cs @@ -0,0 +1,22 @@ +using System.Collections; +using System.Collections.Generic; +using System.Text.RegularExpressions; +using System.Text; +using Godot; + +namespace Rokojori +{ + [Tool] + [GlobalClass] + public partial class FadeWipeEffect:TextureWipeEffect + { + public override void Assign( ColorRect colorRect ) + { + var material = new FadeWipeMaterial(); + colorRect.Material = material; + + base.Assign( colorRect ); + } + + } +} \ No newline at end of file diff --git a/Runtime/Animation/Wipe/TextureWipeEffect.cs b/Runtime/Animation/Wipe/TextureWipeEffect.cs new file mode 100644 index 0000000..ca1e7fd --- /dev/null +++ b/Runtime/Animation/Wipe/TextureWipeEffect.cs @@ -0,0 +1,94 @@ +using System.Collections; +using System.Collections.Generic; +using System.Text.RegularExpressions; +using System.Text; +using Godot; + +namespace Rokojori +{ + [Tool] + [GlobalClass] + public partial class TextureWipeEffect:WipeEffect + { + [ExportGroup("Texture")] + [Export] + public Texture2D texture; + + [Export] + public Gradient tint; + + [ExportGroup("Texture Transform")] + [Export] + public Curve rotation = MathX.Curve( 0, 0 ); + + [Export] + public Curve scale = MathX.Curve( 1, 1 ); + + [Export] + public Curve translationX = MathX.Curve( 0, 0 ); + + [Export] + public Curve translationY = MathX.Curve( 0, 0 ); + + [ExportGroup("Texture Transform Centers")] + [Export] + public Vector2 rotationCenter = new Vector2( 0.5f, 0.5f ); + + [Export] + public Vector2 scaleCenter = new Vector2( 0.5f, 0.5f ); + + + public static readonly Texture2DPropertyName _wipeTextureProperty = Texture2DPropertyName.Create( "wipeTexture" ); + public static readonly Vector2PropertyName _outputViewSizeProperty = Vector2PropertyName.Create( "outputViewSize" ); + public static readonly Vector2PropertyName _wipeTextureSizeProperty = Vector2PropertyName.Create( "wipeTextureSize" ); + public static readonly Vector2PropertyName _uvRotationCenterProperty = Vector2PropertyName.Create( "uvRotationCenter" ); + public static readonly Vector2PropertyName _uvScaleCenterPropery = Vector2PropertyName.Create( "uvScaleCenter" ); + + + public static readonly ColorPropertyName _wipeTextureTintProperty = ColorPropertyName.Create( "wipeTextureTint" ); + public static readonly FloatPropertyName _uvRotationProperty = FloatPropertyName.Create( "uvRotation" ); + public static readonly FloatPropertyName _uvScaleProperty = FloatPropertyName.Create( "uvScale" ); + public static readonly Vector2PropertyName _uvTranslationProperty = Vector2PropertyName.Create( "uvTranslation" ); + + + + public override void Assign( ColorRect colorRect ) + { + if ( colorRect == null ) + { + return; + } + + var material = GetMaterial( colorRect ); + + if ( texture != null ) + { + _wipeTextureProperty.Set( material, texture ); + _wipeTextureSizeProperty.Set( material, texture.GetSize() ); + + _uvRotationCenterProperty.Set( material, rotationCenter ); + _uvScaleCenterPropery.Set( material, scaleCenter ); + } + + _outputViewSizeProperty.Set( material, colorRect.GetViewportRect().Size ); + + } + + public override void SetWipeState( float state, ColorRect target ) + { + if ( target == null ) + { + return; + } + + var material = GetMaterial( target ); + + _wipeTextureTintProperty.Set( material, tint.Sample( state ) ); + _uvRotationProperty.Set( material, rotation.Sample( state ) ); + _uvScaleProperty.Set( material, rotation.Sample( state ) ); + _uvTranslationProperty.Set( material, new Vector2( translationX.Sample( state ), translationY.Sample( state ) ) ); + + } + + } +} \ No newline at end of file diff --git a/Runtime/Animation/Wipe/Wipe.cs b/Runtime/Animation/Wipe/Wipe.cs new file mode 100644 index 0000000..cfff67d --- /dev/null +++ b/Runtime/Animation/Wipe/Wipe.cs @@ -0,0 +1,59 @@ +using System.Collections; +using System.Collections.Generic; +using System.Text.RegularExpressions; +using System.Text; +using Godot; + +namespace Rokojori +{ + [Tool] + [GlobalClass] + public partial class Wipe:SequenceAction + { + public enum Direction + { + In, + Out, + Custom + } + + [Export] + public Direction direction; + + [Export] + public float duration; + + [Export] + public TimeLine timeLine; + + [Export] + public WipeEffect wipeEffect; + + [ExportGroup("Target Overwrite")] + + [Export] + public ColorRect targetOverwriteColorRect; + + [Export] + public Selector targetOverwriteSelector; + + [Export] + public Node targetOverwriteRoot; + + int _actionID = -1; + int _animationID = -1; + + protected override void _OnTrigger() + { + if ( _actionID != -1 ) + { + CancelAction( _actionID ); + } + } + + public override void CancelAction( int id ) + { + + } + } +} \ No newline at end of file diff --git a/Runtime/Animation/Wipe/WipeEffect.cs b/Runtime/Animation/Wipe/WipeEffect.cs new file mode 100644 index 0000000..1239717 --- /dev/null +++ b/Runtime/Animation/Wipe/WipeEffect.cs @@ -0,0 +1,34 @@ +using System.Collections; +using System.Collections.Generic; +using System.Text.RegularExpressions; +using System.Text; +using Godot; + +namespace Rokojori +{ + [Tool] + [GlobalClass] + public partial class WipeEffect:Resource + { + public static readonly FloatPropertyName wipeState = FloatPropertyName.Create( "wipeState" ); + + [ExportGroup("Target")] + [Export] + public Selector selector; + + + public ShaderMaterial GetMaterial( ColorRect rect ) + { + return rect.Material as ShaderMaterial; + } + + public virtual void Assign( ColorRect colorRect ) + { + + } + + public virtual void SetWipeState( float state, ColorRect target ) + {} + + } +} \ No newline at end of file diff --git a/Runtime/Bits/BitMath.cs b/Runtime/Bits/BitMath.cs new file mode 100644 index 0000000..318af4d --- /dev/null +++ b/Runtime/Bits/BitMath.cs @@ -0,0 +1,31 @@ +using Godot; + + +namespace Rokojori +{ + public class BitMath + { + public static int GetInt32BitMask( int bit ) + { + return ( 1 << bit ); + } + + public static int SetBit( int value, int bitPosition ) + { + return value | GetInt32BitMask( bitPosition ); + } + + public static int UnsetBit( int value, int bitPosition ) + { + return value & ~GetInt32BitMask( bitPosition ); + } + + public static bool IsBitSet( int value, int bitPosition ) + { + var mask = GetInt32BitMask( bitPosition ); + return ( value & mask ) == mask; + } + + + } +} \ No newline at end of file diff --git a/Runtime/Bits/BitViewTest.cs b/Runtime/Bits/BitViewTest.cs new file mode 100644 index 0000000..d711696 --- /dev/null +++ b/Runtime/Bits/BitViewTest.cs @@ -0,0 +1,148 @@ +using Godot; + + +namespace Rokojori +{ + public class NetTransform: NetClassDefinition + { + public readonly NetVector3 position = new NetVector3( Vector3.Zero ); + public readonly NetQuaternion rotation = new NetQuaternion( Quaternion.Identity ); + public readonly NetVector3 scale = new NetVector3( Vector3.One ); + + public NetTransform() + { + SetMembers( position, rotation, scale ); + } + } + + public class NetMovementData: NetClassDefinition + { + public readonly NetClass transform = new NetClass( + new NetTransform() + ); + + public readonly NetInt id = new NetInt( -1 ); + + public NetMovementData() + { + SetMembers( transform, id ); + } + + + } + + [GlobalClass] + public partial class BitViewTest : Action + { + protected override void _OnTrigger() + { + TestSingleBitWriting(); + TestByteWriting(); + TestIntVL8Writing(); + TestClassWriting(); + } + + public void TestSingleBitWriting() + { + RJLog.Log( "----- TestSingleBitWriting -------" ); + + var bitView = BitView.CreateEmpty(); + var numBits = 21; + + for ( int i = 0; i < numBits; i++ ) + { + bitView.WriteBit( i % 2 == 0 ); + } + + LogAndTestReversal( bitView ); + } + + public void TestClassWriting() + { + RJLog.Log( "----- TestClassWriting -------" ); + + var bitView = BitView.CreateEmpty(); + bitView.WriteBit( true ); + bitView.WriteFloat( -1234.567f ); + + var trsf = new NetTransform(); + trsf.position.value = new Vector3( 1, 2, 3 ); + trsf.rotation.value = Quaternion.FromEuler( new Vector3( 0, 90, 0 ) ); + trsf.scale.value = new Vector3( 10,5,-1 ); + //var md = new NetMovementData(); + + trsf.WriteMembers( bitView ); + + LogAndTestReversal( bitView ); + + var copy = bitView.Clone(); + copy.SetPointer( 0 ); + + var bit = copy.ReadBit(); + var data = copy.ReadFloat(); + var copyTrsf = Singleton>.Get().ReadData( copy ); + + RJLog.Log( bit, data, trsf.position.value, trsf.rotation.value, trsf.scale.value ); + + } + + public void TestByteWriting() + { + RJLog.Log( "----- TestByteWriting -------" ); + + var bitView = BitView.CreateEmpty(); + + bitView.WriteByte( 1 ); + bitView.WriteByte( 0 ); + bitView.WriteByte( 0 ); + bitView.WriteByte( 0 ); + + bitView.WriteBit( true ); + bitView.WriteBit( false ); + bitView.WriteBit( true ); + bitView.WriteByte( 19 ); + bitView.WriteByte( 84 ); + + LogAndTestReversal( bitView ); + } + + public void TestIntVL8Writing() + { + RJLog.Log( "----- TestIntVL8Writing -------" ); + + var bitView = BitView.CreateEmpty(); + + bitView.WriteUIntVL8( 127 ); + bitView.WriteUIntVL8( 128 ); + bitView.WriteUIntVL8( 70000 ); + bitView.WriteUIntVL8( 17121984 ); + + LogAndTestReversal( bitView ); + + var copy = BitView.From( bitView.GetBytes(), bitView.numBits ); + copy.SetPointer( 0 ); + + RJLog.Log( "----- Reading -------" ); + + for ( int i = 0; i < 4; i++ ) + { + copy.ReadUIntVL8(); + } + } + + + void LogAndTestReversal( BitView bitView ) + { + Log( bitView ); + + var fromBytes = BitView.From( bitView.GetBytes(), bitView.numBits ); + + Log( fromBytes ); + } + + void Log( BitView view ) + { + RJLog.Log( view.GetBitString(), "|", ByteView.Stringify( view.GetBytes() ) ); + } + } +} \ No newline at end of file diff --git a/Runtime/Bits/BitView_Byte.cs b/Runtime/Bits/BitView_Byte.cs new file mode 100644 index 0000000..597ddb3 --- /dev/null +++ b/Runtime/Bits/BitView_Byte.cs @@ -0,0 +1,60 @@ +using Godot; +using System.Collections.Generic; +using System.Text; + +namespace Rokojori +{ + public partial class BitView + { + public void WriteByte( byte value ) + { + for ( int i = 0; i < 8; i++ ) + { + WriteBit( BitMath.IsBitSet( value, i ) ); + } + } + + public void WriteBytes( byte[] values ) + { + for ( int i = 0; i < values.Length; i++ ) + { + WriteByte( values[ i ] ); + } + } + + public byte ReadByte() + { + var byteValue = 0; + + for ( int i = 0; i < 8; i++ ) + { + var bitValue = ReadBit(); + + if ( ! bitValue ) + { + continue; + } + + byteValue = byteValue | ( 1 << i ); + } + + return (byte) byteValue; + } + + public void ReadBytes( byte[] output, int size ) + { + for ( int i = 0; i < size; i++ ) + { + output[ i ] = ReadByte(); + } + } + + public byte[] ReadByteArray( int size ) + { + var data = new byte[ size ]; + ReadBytes( data, size ); + return data; + } + + } +} \ No newline at end of file diff --git a/Runtime/Bits/BitView_Float.cs b/Runtime/Bits/BitView_Float.cs new file mode 100644 index 0000000..d387df7 --- /dev/null +++ b/Runtime/Bits/BitView_Float.cs @@ -0,0 +1,20 @@ +using Godot; +using System.Collections.Generic; +using System.Text; +using System; + +namespace Rokojori +{ + public partial class BitView + { + public void WriteFloat( float value ) + { + WriteBytes( BitConverter.GetBytes( value ) ); + } + + public float ReadFloat() + { + return BitConverter.ToSingle( ReadByteArray( 4 ) ); + } + } +} \ No newline at end of file diff --git a/Runtime/Bits/BitView_Int.cs b/Runtime/Bits/BitView_Int.cs new file mode 100644 index 0000000..2923e23 --- /dev/null +++ b/Runtime/Bits/BitView_Int.cs @@ -0,0 +1,20 @@ +using Godot; +using System.Collections.Generic; +using System.Text; +using System; + +namespace Rokojori +{ + public partial class BitView + { + public void WriteInt( int value ) + { + WriteBytes( BitConverter.GetBytes( value ) ); + } + + public int ReadInt() + { + return BitConverter.ToInt32( ReadByteArray( 4 ) ); + } + } +} \ No newline at end of file diff --git a/Runtime/Bits/BitView_IntVL8.cs b/Runtime/Bits/BitView_IntVL8.cs new file mode 100644 index 0000000..e01a633 --- /dev/null +++ b/Runtime/Bits/BitView_IntVL8.cs @@ -0,0 +1,85 @@ +using Godot; +using System.Collections.Generic; +using System.Text; + +namespace Rokojori +{ + public partial class BitView + { + public static int numBitsForIntVL8( int value ) + { + return numBytesForUIntVL8( value ) * 8; + } + + public static int numBytesForUIntVL8( int value ) + { + var numBits = Mathf.CeilToInt( MathX.Exponent( 2, value + 1 ) ); + var numBytes = ( numBits - 1 )/ 7 + 1; + + return numBytes; + } + + + + public void WriteUIntVL8( int value ) + { + if ( value < 0 ) + { + throw new System.Exception( "Value is negative, writing only positive value:" + value ); + } + + var numBits = Mathf.CeilToInt( MathX.Exponent( 2, value + 1 ) ); + var numBytes = ( numBits - 1 )/ 7 + 1; + var position = 0; + + RJLog.Log( "WriteIntVL8", value, "bits:", numBits," >> bytes:", numBytes ); + + for ( int b = 0; b < numBytes; b++ ) + { + for ( int i = 0; i < 7; i++ ) + { + WriteBit( BitMath.IsBitSet( value, position ) ); + position++; + } + + WriteBit( b != ( numBytes - 1 ) ); + } + } + + public int ReadUIntVL8() + { + var byteValue = ReadByte(); + var intValue = byteValue & 127; + var numShifts = 1; + + while ( byteValue > 127 ) + { + byteValue = ReadByte(); + var nextIntValue = ( byteValue & 127 ) << ( 7 * numShifts ); + numShifts ++; + intValue = intValue | nextIntValue; + } + + RJLog.Log( "ReadIntVL8 >> ", intValue ); + + return intValue; + } + + public void WriteIntVL8( int value ) + { + var isNegative = value < 0; + var absValue = Mathf.Abs( value ); + + WriteBit( isNegative ); + WriteUIntVL8( absValue ); + } + + public int ReadIntVL8() + { + var isNegative = ReadBit(); + var absValue = ReadUIntVL8(); + + return isNegative ? ( -absValue ) : absValue; + } + } +} \ No newline at end of file diff --git a/Runtime/Bits/BitView_Vector.cs b/Runtime/Bits/BitView_Vector.cs new file mode 100644 index 0000000..141c8b3 --- /dev/null +++ b/Runtime/Bits/BitView_Vector.cs @@ -0,0 +1,59 @@ +using Godot; +using System.Collections.Generic; +using System.Text; +using System; + +namespace Rokojori +{ + public partial class BitView + { + public void WriteVector2( Vector2 value ) + { + WriteFloat( value.X ); + WriteFloat( value.Y ); + } + + public Vector2 ReadVector2() + { + return new Vector2( ReadFloat(), ReadFloat() ); + } + + public void WriteVector3( Vector3 value ) + { + WriteFloat( value.X ); + WriteFloat( value.Y ); + WriteFloat( value.Z ); + } + + public Vector3 ReadVector3() + { + return new Vector3( ReadFloat(), ReadFloat(), ReadFloat() ); + } + + public void WriteVector4( Vector4 value ) + { + WriteFloat( value.X ); + WriteFloat( value.Y ); + WriteFloat( value.Z ); + WriteFloat( value.W ); + } + + public Vector4 ReadVector4() + { + return new Vector4( ReadFloat(), ReadFloat(), ReadFloat(), ReadFloat() ); + } + + public void WriteQuaternion( Quaternion value ) + { + WriteFloat( value.X ); + WriteFloat( value.Y ); + WriteFloat( value.Z ); + WriteFloat( value.W ); + } + + public Quaternion ReadQuaternion() + { + return new Quaternion( ReadFloat(), ReadFloat(), ReadFloat(), ReadFloat() ); + } + } +} \ No newline at end of file diff --git a/Runtime/Bits/BitView__.cs b/Runtime/Bits/BitView__.cs new file mode 100644 index 0000000..ff400b0 --- /dev/null +++ b/Runtime/Bits/BitView__.cs @@ -0,0 +1,266 @@ +using Godot; +using System.Collections.Generic; +using System.Text; + +namespace Rokojori +{ + public partial class BitView + { + byte[] _data; + + int _internalViewOffset = 0; + public int bitOffset => _internalViewOffset; + + int _internalViewSize = 0; + public int numBits => _internalViewSize; + + public int numBytes => Mathf.CeilToInt( _internalViewSize / 8f ); + + + int _externalPointer = 0; + public int pointerPosition => _externalPointer; + + public void SetPointer( int bitPosition ) + { + _externalPointer = bitPosition; + } + + + public byte[] GetBytes() + { + var numBytes = this.numBytes; + var data = new byte[ numBytes ]; + System.Array.Fill( data, (byte)0 ); + + for ( int i = 0; i < _internalViewSize; i++ ) + { + var isSet = GetValueInternal( i + _internalViewOffset ); + + if ( ! isSet ) + { + continue; + } + + var shift = i % 8; + var index = i / 8; + var value = 1 << shift; + + data[ index ] = (byte) ( data[ index ] | value ); + } + + + return data; + } + + public BitView Clone() + { + var clone = new BitView(); + clone._data = _data; + clone._internalViewOffset = _internalViewOffset; + clone._internalViewSize = _internalViewSize; + clone._externalPointer = _externalPointer; + + return clone; + } + + public string GetBitString() + { + var output = new StringBuilder(); + + for ( int i = 0; i < _internalViewSize; i++ ) + { + var mod = i % 8; + + if ( i != 0 && mod == 0 ) + { + output.Append( " " ); + } + + var reverseIndex = 7 - mod * 2; + + var value = GetValueInternal( reverseIndex + i + _internalViewOffset ) ? "1" : "0"; + output.Append( value ); + } + + return output.ToString(); + } + + void SetValueInternal( int position, bool value ) + { + var byteIndex = position / 8; + var bitOffset = position - byteIndex * 8; + + if ( value ) + { + _data[ byteIndex ] = Bytes.SetBit( _data[ byteIndex ], bitOffset ); + } + else + { + _data[ byteIndex ] = Bytes.UnsetBit( _data[ byteIndex ], bitOffset ); + } + } + + bool GetValueInternal( int bitPosition ) + { + var byteIndex = bitPosition / 8; + var bitOffset = bitPosition - byteIndex * 8; + + return Bytes.IsBitSet( _data[ byteIndex ], bitOffset ); + } + + int GetShiftedValueInternal( int bitPosition, int shift ) + { + if ( ! GetValueInternal( bitPosition ) ) + { + return 0; + } + + return 1 << shift; + } + + void EnsureInternalSize( int bitPosition ) + { + var byteIndex = bitPosition / 8; + + if ( byteIndex >= _data.Length ) + { + var newData = new byte[ _data.Length + 1 ]; + System.Array.Fill( newData, (byte) 0 ); + System.Array.Copy( _data, 0, newData, 0, _data.Length ); + + _data = newData; + } + } + + public void Clear() + { + _externalPointer = 0; + + for ( int i = 0; i < _internalViewSize; i++ ) + { + SetValueInternal( i + _internalViewOffset, false ); + } + } + + public void ResetPointerAndSize() + { + _externalPointer = 0; + _internalViewSize = 0; + } + + public void WriteBit( bool value ) + { + var position = _externalPointer + _internalViewOffset; + EnsureInternalSize( position ); + + SetValueInternal( position, value ); + _externalPointer ++; + + _internalViewSize = Mathf.Max( _externalPointer, _internalViewSize ); + } + + public bool GetBitAt( int bitPosition ) + { + var internalBitPosition = bitPosition + _internalViewOffset; + return GetValueInternal( bitPosition ); + } + + public bool ReadBit() + { + var bitPosition = _externalPointer + _internalViewOffset; + + if ( bitPosition < 0 || bitPosition >= numBits ) + { + RJLog.Log( "Can't read: >> ", bitPosition, "in", numBits, "p:", _externalPointer, "o:", _internalViewOffset ); + return false; + } + var value = GetValueInternal( bitPosition ); + _externalPointer ++; + + return value; + } + + public void SetPointerPosition( int position ) + { + _externalPointer = Mathf.Clamp( position, 0, _internalViewSize ); + } + + public static BitView CreateEmpty() + { + var view = new BitView(); + view._data = new byte[]{}; + view._internalViewOffset = 0; + view._internalViewSize = 0; + view._externalPointer = 0; + + return view; + } + + public static BitView From( byte[] data) + { + var view = new BitView(); + + view._data = data; + view._internalViewOffset = 0; + view._internalViewSize = data.Length * 8; + view._externalPointer = 0; + + return view; + } + + + public static BitView From( byte[] data, int bitSize = -1 ) + { + var view = new BitView(); + + view._data = data; + view._internalViewOffset = 0; + view._internalViewSize = bitSize == -1 ? data.Length * 8 : bitSize; + view._externalPointer = 0; + + return view; + } + + public static BitView PrependBytes( byte[] before, BitView after ) + { + var data = new byte[ before.Length + after.numBytes ]; + + System.Array.Copy( before, 0, data, 0, before.Length ); + + var view = BitView.From( data, before.Length * 8 + after.numBits ); + + + if ( after.bitOffset == 0 ) + { + System.Array.Copy( after._data, 0, data, 0, after.numBytes ); + view.SetPointer( after.pointerPosition + before.Length * 8 ); + + return view; + } + + view.SetPointer( before.Length * 8 ); + + for ( int i = 0; i < after.numBits; i++ ) + { + view.WriteBit( after.GetBitAt( i ) ); + } + + view.SetPointer( after.pointerPosition + before.Length * 8 ); + + return view; + } + + public static BitView PrependID( int id, BitView after ) + { + var idView = BitView.CreateEmpty(); + idView.WriteUIntVL8( id ); + + return BitView.PrependBytes( idView.GetBytes(), after ); + + } + + + + + } +} \ No newline at end of file diff --git a/Runtime/Bits/ByteView.cs b/Runtime/Bits/ByteView.cs new file mode 100644 index 0000000..75aa361 --- /dev/null +++ b/Runtime/Bits/ByteView.cs @@ -0,0 +1,76 @@ +using Godot; + +using System; +using System.Text; + +namespace Rokojori +{ + public class ByteView + { + byte[] _data; + int _start; + int _size; + + public ByteView From( byte[] bytes ) + { + var view = new ByteView(); + view._start = 0; + view._size = bytes.Length; + view._data = bytes; + + return view; + } + + public byte[] GetBytes() + { + if ( _start == 0 && _size == _data.Length ) + { + return _data; + } + + var bytes = new byte[ _size ]; + + Array.Copy( _data, _start, bytes, 0, _size ); + + return bytes; + } + + public string Stringify() + { + return Stringify( _data, _start, _size ); + } + + public static string Stringify( byte[] _data, int _start = 0, int _size = -1) + { + if ( _size < 0 ) + { + _size = _data.Length - _start; + } + + var sb = new StringBuilder(); + + for ( int i = 0; i < _size; i++ ) + { + if ( i != 0 ) + { + sb.Append( " " ); + } + + var value = _data[ i + _start ] + ""; + + while ( value.Length < 3 ) + { + value = "0" + value; + } + + sb.Append( value ); + + } + + return sb.ToString(); + } + + + + } +} \ No newline at end of file diff --git a/Runtime/Bits/Bytes.cs b/Runtime/Bits/Bytes.cs new file mode 100644 index 0000000..4d61e34 --- /dev/null +++ b/Runtime/Bits/Bytes.cs @@ -0,0 +1,30 @@ +using Godot; + +using System; +using System.Text; + +namespace Rokojori +{ + public class Bytes + { + + public static byte SetBit( byte value, int position ) + { + return (byte) ( ( 1 << position ) | value ); + } + + public static byte UnsetBit( byte value, int position ) + { + var mask = 1 << position; + var invertedMask = ~mask; + + return (byte)( value & invertedMask ); + } + + public static bool IsBitSet( byte value, int position ) + { + var mask = 1 << position; + return ( mask & value ) == mask ; + } + } +} \ No newline at end of file diff --git a/Runtime/Events/EventProperty.cs b/Runtime/Events/EventProperty.cs index 277a701..e3bee39 100644 --- a/Runtime/Events/EventProperty.cs +++ b/Runtime/Events/EventProperty.cs @@ -37,10 +37,13 @@ namespace Rokojori public virtual void DispatchEvent() { + _canModify = false; + _actions.ForEach( a => { if ( a != null ){ a( _value ); } } ); - _ClearOnceActions(); + _UpdateLists(); + _canModify = true; } diff --git a/Runtime/Events/EventSlot.cs b/Runtime/Events/EventSlot.cs index 41c3a56..19fe377 100644 --- a/Runtime/Events/EventSlot.cs +++ b/Runtime/Events/EventSlot.cs @@ -12,35 +12,88 @@ namespace Rokojori protected List> _actions = new List>(); List> _once = new List>(); + protected bool _canModify = true; + List> _additions = new List>(); + List> _onceAdditions = new List>(); + List> _removals = new List>(); + + public bool hasListeners => _once.Count > 0 || _actions.Count > 0; public void AddAction( Action action ) { - _actions.Add( action ); + if ( _canModify ) + { + _actions.Add( action ); + } + else + { + _additions.Add( action ); + } } public void RemoveAction( Action action ) { - _actions.Remove( action ); + if ( _canModify ) + { + _actions.Remove( action ); + } + else + { + _removals.Add( action ); + } } public void Once( Action action ) { - _actions.Add( action ); - _once.Add( action ); + if ( _canModify ) + { + _actions.Add( action ); + _once.Add( action ); + } + else + { + _onceAdditions.Add( action ); + } + + } - protected void _ClearOnceActions() + protected void _UpdateLists() { _once.ForEach( a => { _actions.Remove( a ); } ); _once.Clear(); + + if ( _removals.Count > 0 ) + { + Lists.RemoveRange( _actions, _removals ); + _removals.Clear(); + } + + if ( _additions.Count > 0 ) + { + _actions.AddRange( _additions ); + _additions.Clear(); + } + + if ( _onceAdditions.Count > 0 ) + { + _once.AddRange( _onceAdditions ); + _actions.AddRange( _onceAdditions ); + } + + } public void DispatchEvent( T t ) { + _canModify = false; + _actions.ForEach( a => { if ( a != null ){ a( t ); } } ); + + _UpdateLists(); - _ClearOnceActions(); + _canModify = true; } } diff --git a/Runtime/Godot/Generated/Classes/RJAnimatableBody3D.cs b/Runtime/Godot/Generated/Classes/RJAnimatableBody3D.cs index 7db506b..3a81a69 100644 --- a/Runtime/Godot/Generated/Classes/RJAnimatableBody3D.cs +++ b/Runtime/Godot/Generated/Classes/RJAnimatableBody3D.cs @@ -9,71 +9,71 @@ namespace Rokojori [Export] - public RJAction OnInputEvent; + public Action OnInputEvent; [Export] - public RJAction OnMouseEntered; + public Action OnMouseEntered; [Export] - public RJAction OnMouseExited; + public Action OnMouseExited; [Export] - public RJAction OnVisibilityChanged; + public Action OnVisibilityChanged; [Export] - public RJAction OnReady; + public Action OnReady; [Export] - public RJAction OnRenamed; + public Action OnRenamed; [Export] - public RJAction OnTreeEntered; + public Action OnTreeEntered; [Export] - public RJAction OnTreeExiting; + public Action OnTreeExiting; [Export] - public RJAction OnTreeExited; + public Action OnTreeExited; [Export] - public RJAction OnChildEnteredTree; + public Action OnChildEnteredTree; [Export] - public RJAction OnChildExitingTree; + public Action OnChildExitingTree; [Export] - public RJAction OnChildOrderChanged; + public Action OnChildOrderChanged; [Export] - public RJAction OnReplacingBy; + public Action OnReplacingBy; [Export] - public RJAction OnEditorDescriptionChanged; + public Action OnEditorDescriptionChanged; [Export] - public RJAction OnScriptChanged; + public Action OnScriptChanged; [Export] - public RJAction OnPropertyListChanged; + public Action OnPropertyListChanged; public override void _Ready() { - InputEvent += ( p0, p1, p2, p3, p4 ) => { Actions.Trigger( OnInputEvent ); }; - MouseEntered += ( ) => { Actions.Trigger( OnMouseEntered ); }; - MouseExited += ( ) => { Actions.Trigger( OnMouseExited ); }; - VisibilityChanged += ( ) => { Actions.Trigger( OnVisibilityChanged ); }; - Ready += ( ) => { Actions.Trigger( OnReady ); }; - Renamed += ( ) => { Actions.Trigger( OnRenamed ); }; - TreeEntered += ( ) => { Actions.Trigger( OnTreeEntered ); }; - TreeExiting += ( ) => { Actions.Trigger( OnTreeExiting ); }; - TreeExited += ( ) => { Actions.Trigger( OnTreeExited ); }; - ChildEnteredTree += ( p0 ) => { Actions.Trigger( OnChildEnteredTree ); }; - ChildExitingTree += ( p0 ) => { Actions.Trigger( OnChildExitingTree ); }; - ChildOrderChanged += ( ) => { Actions.Trigger( OnChildOrderChanged ); }; - ReplacingBy += ( p0 ) => { Actions.Trigger( OnReplacingBy ); }; - EditorDescriptionChanged += ( p0 ) => { Actions.Trigger( OnEditorDescriptionChanged ); }; - ScriptChanged += ( ) => { Actions.Trigger( OnScriptChanged ); }; - PropertyListChanged += ( ) => { Actions.Trigger( OnPropertyListChanged ); }; + InputEvent += ( p0, p1, p2, p3, p4 ) => { Action.Trigger( OnInputEvent ); }; + MouseEntered += ( ) => { Action.Trigger( OnMouseEntered ); }; + MouseExited += ( ) => { Action.Trigger( OnMouseExited ); }; + VisibilityChanged += ( ) => { Action.Trigger( OnVisibilityChanged ); }; + Ready += ( ) => { Action.Trigger( OnReady ); }; + Renamed += ( ) => { Action.Trigger( OnRenamed ); }; + TreeEntered += ( ) => { Action.Trigger( OnTreeEntered ); }; + TreeExiting += ( ) => { Action.Trigger( OnTreeExiting ); }; + TreeExited += ( ) => { Action.Trigger( OnTreeExited ); }; + ChildEnteredTree += ( p0 ) => { Action.Trigger( OnChildEnteredTree ); }; + ChildExitingTree += ( p0 ) => { Action.Trigger( OnChildExitingTree ); }; + ChildOrderChanged += ( ) => { Action.Trigger( OnChildOrderChanged ); }; + ReplacingBy += ( p0 ) => { Action.Trigger( OnReplacingBy ); }; + EditorDescriptionChanged += ( p0 ) => { Action.Trigger( OnEditorDescriptionChanged ); }; + ScriptChanged += ( ) => { Action.Trigger( OnScriptChanged ); }; + PropertyListChanged += ( ) => { Action.Trigger( OnPropertyListChanged ); }; } } } diff --git a/Runtime/Godot/Generated/Classes/RJCharacterBody3D.cs b/Runtime/Godot/Generated/Classes/RJCharacterBody3D.cs index f395679..103f2d2 100644 --- a/Runtime/Godot/Generated/Classes/RJCharacterBody3D.cs +++ b/Runtime/Godot/Generated/Classes/RJCharacterBody3D.cs @@ -9,71 +9,71 @@ namespace Rokojori [Export] - public RJAction OnInputEvent; + public Action OnInputEvent; [Export] - public RJAction OnMouseEntered; + public Action OnMouseEntered; [Export] - public RJAction OnMouseExited; + public Action OnMouseExited; [Export] - public RJAction OnVisibilityChanged; + public Action OnVisibilityChanged; [Export] - public RJAction OnReady; + public Action OnReady; [Export] - public RJAction OnRenamed; + public Action OnRenamed; [Export] - public RJAction OnTreeEntered; + public Action OnTreeEntered; [Export] - public RJAction OnTreeExiting; + public Action OnTreeExiting; [Export] - public RJAction OnTreeExited; + public Action OnTreeExited; [Export] - public RJAction OnChildEnteredTree; + public Action OnChildEnteredTree; [Export] - public RJAction OnChildExitingTree; + public Action OnChildExitingTree; [Export] - public RJAction OnChildOrderChanged; + public Action OnChildOrderChanged; [Export] - public RJAction OnReplacingBy; + public Action OnReplacingBy; [Export] - public RJAction OnEditorDescriptionChanged; + public Action OnEditorDescriptionChanged; [Export] - public RJAction OnScriptChanged; + public Action OnScriptChanged; [Export] - public RJAction OnPropertyListChanged; + public Action OnPropertyListChanged; public override void _Ready() { - InputEvent += ( p0, p1, p2, p3, p4 ) => { Actions.Trigger( OnInputEvent ); }; - MouseEntered += ( ) => { Actions.Trigger( OnMouseEntered ); }; - MouseExited += ( ) => { Actions.Trigger( OnMouseExited ); }; - VisibilityChanged += ( ) => { Actions.Trigger( OnVisibilityChanged ); }; - Ready += ( ) => { Actions.Trigger( OnReady ); }; - Renamed += ( ) => { Actions.Trigger( OnRenamed ); }; - TreeEntered += ( ) => { Actions.Trigger( OnTreeEntered ); }; - TreeExiting += ( ) => { Actions.Trigger( OnTreeExiting ); }; - TreeExited += ( ) => { Actions.Trigger( OnTreeExited ); }; - ChildEnteredTree += ( p0 ) => { Actions.Trigger( OnChildEnteredTree ); }; - ChildExitingTree += ( p0 ) => { Actions.Trigger( OnChildExitingTree ); }; - ChildOrderChanged += ( ) => { Actions.Trigger( OnChildOrderChanged ); }; - ReplacingBy += ( p0 ) => { Actions.Trigger( OnReplacingBy ); }; - EditorDescriptionChanged += ( p0 ) => { Actions.Trigger( OnEditorDescriptionChanged ); }; - ScriptChanged += ( ) => { Actions.Trigger( OnScriptChanged ); }; - PropertyListChanged += ( ) => { Actions.Trigger( OnPropertyListChanged ); }; + InputEvent += ( p0, p1, p2, p3, p4 ) => { Action.Trigger( OnInputEvent ); }; + MouseEntered += ( ) => { Action.Trigger( OnMouseEntered ); }; + MouseExited += ( ) => { Action.Trigger( OnMouseExited ); }; + VisibilityChanged += ( ) => { Action.Trigger( OnVisibilityChanged ); }; + Ready += ( ) => { Action.Trigger( OnReady ); }; + Renamed += ( ) => { Action.Trigger( OnRenamed ); }; + TreeEntered += ( ) => { Action.Trigger( OnTreeEntered ); }; + TreeExiting += ( ) => { Action.Trigger( OnTreeExiting ); }; + TreeExited += ( ) => { Action.Trigger( OnTreeExited ); }; + ChildEnteredTree += ( p0 ) => { Action.Trigger( OnChildEnteredTree ); }; + ChildExitingTree += ( p0 ) => { Action.Trigger( OnChildExitingTree ); }; + ChildOrderChanged += ( ) => { Action.Trigger( OnChildOrderChanged ); }; + ReplacingBy += ( p0 ) => { Action.Trigger( OnReplacingBy ); }; + EditorDescriptionChanged += ( p0 ) => { Action.Trigger( OnEditorDescriptionChanged ); }; + ScriptChanged += ( ) => { Action.Trigger( OnScriptChanged ); }; + PropertyListChanged += ( ) => { Action.Trigger( OnPropertyListChanged ); }; } } } diff --git a/Runtime/Godot/Generated/GodotClassGenerator.cs b/Runtime/Godot/Generated/GodotClassGenerator.cs index d8d883b..b6a205e 100644 --- a/Runtime/Godot/Generated/GodotClassGenerator.cs +++ b/Runtime/Godot/Generated/GodotClassGenerator.cs @@ -72,7 +72,7 @@ namespace Rokojori output.Append( " \n" ); output.Append( " [Export]\n" ); - output.Append( " public RJAction On" + eventName + ";\n" ); + output.Append( " public Action On" + eventName + ";\n" ); } output.Append( " \n" ); @@ -100,7 +100,7 @@ namespace Rokojori p += " )"; - output.Append( " " + eventName + " += " + p + " => { Actions.Trigger( On" + eventName +" ); }; \n" ); + output.Append( " " + eventName + " += " + p + " => { Action.Trigger( On" + eventName +" ); }; \n" ); } output.Append( " }\n" ); diff --git a/Runtime/Interactions/Caster.cs b/Runtime/Interactions/Caster.cs new file mode 100644 index 0000000..6f514a2 --- /dev/null +++ b/Runtime/Interactions/Caster.cs @@ -0,0 +1,52 @@ +using Godot; +using System.Collections; +using System.Collections.Generic; +using Godot.Collections; + +namespace Rokojori +{ + + [GlobalClass] + public partial class Caster:Node3D + { + [Export] + public Action beforeProcess; + + [Export] + public Action afterProcess; + + [Export] + public Selector includeSelector; + + [Export] + public Selector excludeSelector; + + + public virtual int NumColliders() + { + return 0; + } + + + public virtual Node GetCollider( int index ) + { + return null; + } + + public virtual Vector3 GetCollisionPosition( int index ) + { + return Vector3.Zero; + } + + public virtual Vector3 GetCollisionNormal( int index ) + { + return Vector3.Zero; + } + + public virtual Shape3D GetCollisionShape( int index ) + { + return null; + } + + } +} \ No newline at end of file diff --git a/Runtime/Interactions/CharacterController/CharacterController.cs b/Runtime/Interactions/CharacterController/CharacterController.cs index 510dc25..aa38683 100644 --- a/Runtime/Interactions/CharacterController/CharacterController.cs +++ b/Runtime/Interactions/CharacterController/CharacterController.cs @@ -50,7 +50,7 @@ namespace Rokojori if ( CharacterUpdateMode.Process == characterUpdateMode ) { this.delta = (float)delta; - Nodes.ForEachDirectChild( actionsContainer, a => Actions.Trigger( a ) ); + Nodes.ForEachDirectChild( actionsContainer, a => Action.Trigger( a ) ); } // positionSmoother.CopyPosition( graphics, body, rotationSmoothingDuration, delta ); @@ -64,7 +64,7 @@ namespace Rokojori if ( CharacterUpdateMode.Physics_Process == characterUpdateMode ) { this.delta = (float)delta; - Nodes.ForEach( actionsContainer, a => Actions.Trigger( a ) ); + Nodes.ForEach( actionsContainer, a => Action.Trigger( a ) ); } } } diff --git a/Runtime/Interactions/CharacterController/CharacterControllerAction.cs b/Runtime/Interactions/CharacterController/CharacterControllerAction.cs index 1af4526..caee2cf 100644 --- a/Runtime/Interactions/CharacterController/CharacterControllerAction.cs +++ b/Runtime/Interactions/CharacterController/CharacterControllerAction.cs @@ -6,7 +6,7 @@ using Godot.Collections; namespace Rokojori { [GlobalClass] - public partial class CharacterControllerAction:RJAction + public partial class CharacterControllerAction:Action { [Export] public CharacterController controller; diff --git a/Runtime/Interactions/CharacterController/CharacterMovement.cs b/Runtime/Interactions/CharacterController/CharacterMovement.cs index 80d31f2..7f9a238 100644 --- a/Runtime/Interactions/CharacterController/CharacterMovement.cs +++ b/Runtime/Interactions/CharacterController/CharacterMovement.cs @@ -16,18 +16,18 @@ namespace Rokojori [ExportGroup( "Actions" )] [Export] - public RJAction onMoving; + public Action onMoving; [Export] - public RJAction onIdle; + public Action onIdle; [Export] - public RJAction onForward; + public Action onForward; [Export] - public RJAction onBackwards; + public Action onBackwards; [Export] - public RJAction onStrafeLeft; + public Action onStrafeLeft; [Export] - public RJAction onStrafeRight; + public Action onStrafeRight; [ExportGroup( "Direction Source" )] @@ -50,20 +50,20 @@ namespace Rokojori public float moveSpeed; [Export] - public RJSensor forward; + public Sensor forward; [Export] - public RJSensor backwards; + public Sensor backwards; [ExportGroup( "Strafing" )] [Export] public float strafeSpeed; [Export] - public RJSensor strafeLeft; + public Sensor strafeLeft; [Export] - public RJSensor strafeRight; + public Sensor strafeRight; [Export] public bool useBodyDirection = true; @@ -81,7 +81,7 @@ namespace Rokojori Smoother rotationSmoother = new Smoother(); - public override void _OnTrigger() + protected override void _OnTrigger() { if ( ! body.IsOnFloor() ) { diff --git a/Runtime/Interactions/CharacterController/Gravity.cs b/Runtime/Interactions/CharacterController/Gravity.cs index 67a960f..ed5aded 100644 --- a/Runtime/Interactions/CharacterController/Gravity.cs +++ b/Runtime/Interactions/CharacterController/Gravity.cs @@ -11,7 +11,7 @@ namespace Rokojori [Export] public float strength = 10; - public override void _OnTrigger() + protected override void _OnTrigger() { if ( body.IsOnFloor() ) { diff --git a/Runtime/Interactions/CharacterController/GroundReset.cs b/Runtime/Interactions/CharacterController/GroundReset.cs index 4213057..731aee0 100644 --- a/Runtime/Interactions/CharacterController/GroundReset.cs +++ b/Runtime/Interactions/CharacterController/GroundReset.cs @@ -8,7 +8,7 @@ namespace Rokojori [GlobalClass] public partial class GroundReset:CharacterControllerAction { - public override void _OnTrigger() + protected override void _OnTrigger() { if ( ! body.IsOnFloor() ) { diff --git a/Runtime/Interactions/CharacterController/Jump.cs b/Runtime/Interactions/CharacterController/Jump.cs index 4c151c7..4b27c49 100644 --- a/Runtime/Interactions/CharacterController/Jump.cs +++ b/Runtime/Interactions/CharacterController/Jump.cs @@ -9,7 +9,7 @@ namespace Rokojori public partial class Jump:CharacterControllerAction { [Export] - public RJSensor button; + public Sensor button; [Export] public float jumpStrength; @@ -31,7 +31,7 @@ namespace Rokojori - public override void _OnTrigger() + protected override void _OnTrigger() { if ( body.IsOnFloor() ) { @@ -43,7 +43,7 @@ namespace Rokojori return; } - if ( ! button.IsActive() ) + if ( ! button.isActive ) { jumping = false; return; diff --git a/Runtime/Interactions/CharacterController/MoveAndSlide.cs b/Runtime/Interactions/CharacterController/MoveAndSlide.cs index 9efb292..924f8d0 100644 --- a/Runtime/Interactions/CharacterController/MoveAndSlide.cs +++ b/Runtime/Interactions/CharacterController/MoveAndSlide.cs @@ -8,7 +8,7 @@ namespace Rokojori [GlobalClass] public partial class MoveAndSlide:CharacterControllerAction { - public override void _OnTrigger() + protected override void _OnTrigger() { // RJLog.Log( controller.body.Velocity ); controller.body.MoveAndSlide(); diff --git a/Runtime/Interactions/MultiRayCaster.cs b/Runtime/Interactions/MultiRayCaster.cs index f5fd7b7..3b3a220 100644 --- a/Runtime/Interactions/MultiRayCaster.cs +++ b/Runtime/Interactions/MultiRayCaster.cs @@ -7,7 +7,7 @@ namespace Rokojori { [GlobalClass] - public partial class MultiRayCaster:RJCaster + public partial class MultiRayCaster:Caster { [Export] public float rayLength = 10; @@ -54,13 +54,13 @@ namespace Rokojori public override void _Process( double delta ) { - Actions.Trigger( BeforeProcess ); + Action.Trigger( beforeProcess ); ResolveCollisions(); SortCollisions(); - Actions.Trigger( AfterProcess ); + Action.Trigger( afterProcess ); } @@ -119,9 +119,6 @@ namespace Rokojori bool IsSelected( CollisionData cd ) { - var includeSelector = IncludeSelector; - var excludeSelector = ExcludeSelector; - if ( includeSelector != null && ! includeSelector.Selects( cd.collider ) ) { return false; @@ -164,11 +161,11 @@ namespace Rokojori { float priority = 0; - var pointable = Nodes.Find( cd.collider ); + var pointable = Nodes.Find( cd.collider ); if ( pointable != null ) { - priority = pointable.PointingPriority; + priority = pointable.pointingPriority; } return priority; diff --git a/Runtime/Interactions/Pointable.cs b/Runtime/Interactions/Pointable.cs index 061f60f..7c5c86d 100644 --- a/Runtime/Interactions/Pointable.cs +++ b/Runtime/Interactions/Pointable.cs @@ -7,21 +7,33 @@ namespace Rokojori { [GlobalClass] - public partial class Pointable:RJPointable + public partial class Pointable:Node3D { - List _pointers = new List(); + [Export] + public int pointingPriority; - public override int NumPointing() - { - return _pointers.Count; - } + [Export] + public Action onPointed; - public bool IsPointedBy( RJPointer pointer ) + [Export] + public Action onUnpointed; + + [Export] + public Action onPointerAdded; + + [Export] + public Action onPointerRemoved; + + List _pointers = new List(); + + public int numPointing => _pointers.Count; + + public bool IsPointedBy( Pointer pointer ) { return _pointers.Contains( pointer ); } - public override void UpdatePointerState( RJPointer pointer, bool pointed ) + public void UpdatePointerState( Pointer pointer, bool pointed ) { var isCurrentlyPointed = IsPointedBy( pointer ); @@ -34,11 +46,11 @@ namespace Rokojori if ( pointed ) { _pointers.Add( pointer ); - Actions.Trigger( OnPointerAdded ); + Action.Trigger( onPointerAdded ); if ( _pointers.Count == 1 ) { - Actions.Trigger( OnPointed ); + Action.Trigger( onPointed ); } } @@ -46,11 +58,11 @@ namespace Rokojori { _pointers.Remove( pointer ); - Actions.Trigger( OnPointerRemoved ); + Action.Trigger( onPointerRemoved ); if ( _pointers.Count == 0 ) { - Actions.Trigger( OnUnpointed ); + Action.Trigger( onUnpointed ); } } diff --git a/Runtime/Interactions/Pointer.cs b/Runtime/Interactions/Pointer.cs index 62bb2e8..9ebccd6 100644 --- a/Runtime/Interactions/Pointer.cs +++ b/Runtime/Interactions/Pointer.cs @@ -7,22 +7,25 @@ namespace Rokojori { [GlobalClass] - public partial class Pointer:RJPointer + public partial class Pointer:Node3D { [Export] - public RJPointable pointable; + public Pointable pointable; + + [Export] + public Caster caster; public override void _Process( double delta ) { - if ( Caster == null ) + if ( caster == null ) { return; } - var currentCollider = Caster.NumColliders() == 0 ? null : Caster.GetCollider( 0 ); + var currentCollider = caster.NumColliders() == 0 ? null : caster.GetCollider( 0 ); - var currentPointable = currentCollider == null ? null : Nodes.Find( currentCollider ); + var currentPointable = currentCollider == null ? null : Nodes.Find( currentCollider ); // RJLog.Log( currentCollider, currentPointable ); diff --git a/Runtime/Math/Math2D.cs b/Runtime/Math/Math2D.cs index 7afa250..37392af 100644 --- a/Runtime/Math/Math2D.cs +++ b/Runtime/Math/Math2D.cs @@ -18,6 +18,11 @@ namespace Rokojori return LookingAtEachOtherAngle( lookDirectionA, lookDirectionB ) > 0; } + public static Vector2 Lerp( Vector2 a, Vector2 b, float lerpAmount ) + { + return a.Lerp( b, lerpAmount ); + } + public static bool LookingTowards( Vector2 from, Vector2 fromDirection, Vector2 to ) { return LookingAtEachOther( fromDirection.Normalized(), ( to - from ).Normalized() ); diff --git a/Runtime/Math/MathX.cs b/Runtime/Math/MathX.cs index 8685ef8..08847f3 100644 --- a/Runtime/Math/MathX.cs +++ b/Runtime/Math/MathX.cs @@ -118,6 +118,9 @@ namespace Rokojori return Mathf.Floor( value / snappingDistance ) * snappingDistance; } + public const float DegreesToRadians = Mathf.Pi / 180f; + public const float RadiansToDegreens = 180f / Mathf.Pi; + public static float AngleDelta( float degreesA, float degreesB) { var angleDelta = degreesB - degreesA; @@ -279,6 +282,11 @@ namespace Rokojori return ( phase - phaseStart ) / ( phaseStart - phaseEnd ); } + public static int SafeIndex( int index, List elements, bool wrap = false ) + { + return SafeIndex( index, elements.Count, wrap ); + } + public static int SafeIndex( int index, int maxElements, bool wrap = false ) { if ( wrap ) diff --git a/Runtime/Math/Smoother.cs b/Runtime/Math/Smoother.cs index a34018b..2698dc6 100644 --- a/Runtime/Math/Smoother.cs +++ b/Runtime/Math/Smoother.cs @@ -8,6 +8,24 @@ namespace Rokojori { float overflowDelta = 0; + public static float SmoothTimeInvariant( float value, float nextValue, float delta, float coefficient ) + { + var lerpAmount = Mathf.Exp( -coefficient * delta ); + return Mathf.Lerp( nextValue, value, lerpAmount ); + } + + public static Vector2 SmoothTimeInvariant( Vector2 value, Vector2 nextValue, float delta, float coefficient ) + { + var lerpAmount = Mathf.Exp( -coefficient * delta ); + return Math2D.Lerp( nextValue, value, lerpAmount ); + } + + public static Vector3 SmoothTimeInvariant( Vector3 value, Vector3 nextValue, float delta, float coefficient ) + { + var lerpAmount = Mathf.Exp( -coefficient * delta ); + return Math3D.Lerp( nextValue, value, lerpAmount ); + } + public float SmoothForDuration( float value, float nextValue, float duration, float delta, float processDelta = MathX.fps120Delta ) { var coefficient = MathX.SmoothingCoefficient( duration * 1000f, processDelta ); diff --git a/Runtime/Networking/Backends/LAN/LANNetworkingBackend.cs b/Runtime/Networking/Backends/LAN/LANNetworkingBackend.cs new file mode 100644 index 0000000..92776c2 --- /dev/null +++ b/Runtime/Networking/Backends/LAN/LANNetworkingBackend.cs @@ -0,0 +1,174 @@ +using Godot; +using System.Collections.Generic; + +namespace Rokojori +{ + [GlobalClass] + public partial class LANNetworkBackend:NetworkBackend + { + SceneMultiplayer multiplayer; + ENetMultiplayerPeer peer; + + public override void StartSession( NetworkSessionRequest request ) + { + if ( _state != NetworkSessionConnectionState.Not_Connected ) + { + return; + } + + AssignSessionRequestVariables( request ); + + RJLog.Log( "Starting Session:", request ); + + _state = NetworkSessionConnectionState.Connecting_As_Server; + + multiplayer = new SceneMultiplayer(); + + ConnectListeners(); + + + peer = new ENetMultiplayerPeer(); + + var result = peer.CreateServer( port, maxMembers ); + + if ( Error.Ok != result ) + { + _state = NetworkSessionConnectionState.Not_Connected; + + RJLog.Log( "Session Creation Failed >>", result ); + return; + } + + _state = NetworkSessionConnectionState.Connected_As_Server; + _sessionManager.SetInSessionState(); + + Action.Trigger( _manager.onStartedSession ); + + + AssignMultiplyer(); + } + + public override void JoinSession( NetworkSessionRequest request ) + { + if ( _state != NetworkSessionConnectionState.Not_Connected ) + { + if ( NetworkSessionConnectionState.Connected_As_Client == _state ) + { + SendData(); + } + + return; + } + + AssignSessionRequestVariables( request ); + + RJLog.Log( "Joining Session:", request ); + + _state = NetworkSessionConnectionState.Connecting_As_Client; + + multiplayer = new SceneMultiplayer(); + + ConnectListeners(); + + peer = new ENetMultiplayerPeer(); + + var result = peer.CreateClient( serverIP, port, maxMembers ); + + if ( Error.Ok != result ) + { + RJLog.Log( "Joining Session Failed >>", result ); + _state = NetworkSessionConnectionState.Not_Connected; + return; + } + + AssignMultiplyer(); + + + } + + void SendData() + { + var data = new byte[]{ 0, 1, 2, 3 }; + + var resultSending = multiplayer.SendBytes( data, 0, MultiplayerPeer.TransferModeEnum.Reliable ); + + RJLog.Log( "Sending Data", resultSending, ByteView.Stringify( data ) ); + } + + void AssignMultiplyer() + { + RJLog.Log( "AssignMultiplyer" ); + multiplayer.MultiplayerPeer = peer; + GetTree().SetMultiplayer( multiplayer ); + } + + void ConnectListeners() + { + multiplayer.PeerPacket += ( id, data )=> + { + RJLog.Log( "Received Data:", id, ByteView.Stringify( data ) ); + _transport.HandleIncomingMessage( id, data ); + }; + + multiplayer.ConnectionFailed += ()=> + { + RJLog.Log( "ConnectionFailed" ); + _state = NetworkSessionConnectionState.Not_Connected; + }; + + multiplayer.ServerDisconnected += ()=> + { + RJLog.Log( "ServerDisconnected" ); + _state = NetworkSessionConnectionState.Not_Connected; + _sessionManager.SetInSessionState( false ); + + }; + + multiplayer.ConnectedToServer += ()=> + { + RJLog.Log( "Connecting_As_Client" ); + _state = NetworkSessionConnectionState.Connected_As_Client; + _sessionManager.SetInSessionState(); + + Action.Trigger( _manager.onStartedSession ); + }; + + multiplayer.PeerConnected += ( id )=> + { + RJLog.Log( "PeerConnected:", id ); + var networkSessionMember = NetworkSessionMember.Create( id ); + _sessionManager.AddMember( networkSessionMember ); + }; + + multiplayer.PeerDisconnected += ( id )=> + { + RJLog.Log( "PeerDisconnected:", id ); + _sessionManager.RemoveMember( id ); + + }; + } + + public override void SendMessage( byte[] bytes, List targetMembers, bool reliable = true ) + { + var mode = reliable ? MultiplayerPeer.TransferModeEnum.Reliable : MultiplayerPeer.TransferModeEnum.Unreliable; + + if ( targetMembers.Count == 0 ) + { + var resultSending = multiplayer.SendBytes( bytes, 0, mode ); + RJLog.Log( "Sending Data", resultSending, ByteView.Stringify( bytes ) ); + } + else + { + targetMembers.ForEach( + ( id )=> + { + var resultSending = multiplayer.SendBytes( bytes, id, mode ); + RJLog.Log( "Sending Data", resultSending, ByteView.Stringify( bytes ) ); + } + ); + } + + } + + } +} \ No newline at end of file diff --git a/Runtime/Networking/Data/NetClass.cs b/Runtime/Networking/Data/NetClass.cs new file mode 100644 index 0000000..4acc8e8 --- /dev/null +++ b/Runtime/Networking/Data/NetClass.cs @@ -0,0 +1,78 @@ +using Godot; +using System.Collections.Generic; + + +namespace Rokojori +{ + public abstract class NetClassDefinition + { + protected NetMember[] _members; + + public void SetMembers( params NetMember[] members ) + { + _members = members; + } + + public void ReadMembers( BitView view ) + { + System.Array.ForEach( _members, m => m.ReadMember( view ) ); + } + + public void WriteMembers( BitView view ) + { + System.Array.ForEach( _members, m => m.WriteMember( view ) ); + } + } + + public class NetClassDataType where T:NetClassDefinition, new() + { + public T ReadData( BitView view ) + { + var n = new T(); + n.ReadMembers( view ); + return n; + } + + public void WriteData( BitView view, T t ) + { + t.WriteMembers( view ); + } + } + + public class NetClass:NetMember where T:NetClassDefinition, new() + { + public T value; + + public NetClass( T value ) + { + this.value = value; + } + + public NetClassDataType dataType => Singleton>.Get(); + + public override void ReadMember( BitView view ) + { + var isNull = ! view.ReadBit(); + + if ( isNull ) + { + value = null; + return; + } + + value = dataType.ReadData( view ); + } + + public override void WriteMember( BitView view ) + { + view.WriteBit( value != null ); + + if ( value == null ) + { + return; + } + + dataType.WriteData( view, value ); + } + } +} \ No newline at end of file diff --git a/Runtime/Networking/Data/NetMember.cs b/Runtime/Networking/Data/NetMember.cs new file mode 100644 index 0000000..741b852 --- /dev/null +++ b/Runtime/Networking/Data/NetMember.cs @@ -0,0 +1,45 @@ +using Godot; +using System.Collections.Generic; + + +namespace Rokojori +{ + public class NetMember + { + public virtual void ReadMember( BitView view ) + { + + } + + public virtual void WriteMember( BitView view ) + { + + } + } + + public class TypedNetMember:NetMember + { + NetworkDataType dataType; + public T value; + + public TypedNetMember( NetworkDataType dataType, T value ) + { + this.dataType = dataType; + this.value = value; + } + + public override void ReadMember( BitView view ) + { + value = dataType.ReadData( view ); + } + + public override void WriteMember( BitView view ) + { + dataType.WriteData( view, value ); + } + + } + + + +} \ No newline at end of file diff --git a/Runtime/Networking/Data/NetworkingDataType.cs b/Runtime/Networking/Data/NetworkingDataType.cs new file mode 100644 index 0000000..2a2f9cb --- /dev/null +++ b/Runtime/Networking/Data/NetworkingDataType.cs @@ -0,0 +1,12 @@ +using Godot; +using System.Collections.Generic; + + +namespace Rokojori +{ + public interface NetworkDataType + { + T ReadData( BitView view ); + void WriteData( BitView view, T value ); + } +} \ No newline at end of file diff --git a/Runtime/Networking/Data/Types/NetBool.cs b/Runtime/Networking/Data/Types/NetBool.cs new file mode 100644 index 0000000..c8ddd09 --- /dev/null +++ b/Runtime/Networking/Data/Types/NetBool.cs @@ -0,0 +1,26 @@ +using Godot; +using System.Collections.Generic; + + +namespace Rokojori +{ + public class NetBoolType:NetworkDataType + { + public bool ReadData( BitView view ) + { + return view.ReadBit(); + } + + public void WriteData( BitView view, bool value ) + { + view.WriteBit( value ); + } + } + + public class NetBool:TypedNetMember + { + public NetBool( bool value ):base( Singleton.Get(), value ){} + } + + +} \ No newline at end of file diff --git a/Runtime/Networking/Data/Types/NetByte.cs b/Runtime/Networking/Data/Types/NetByte.cs new file mode 100644 index 0000000..6c5cf4b --- /dev/null +++ b/Runtime/Networking/Data/Types/NetByte.cs @@ -0,0 +1,26 @@ +using Godot; +using System.Collections.Generic; + + +namespace Rokojori +{ + public class NetByteType:NetworkDataType + { + public byte ReadData( BitView view ) + { + return view.ReadByte(); + } + + public void WriteData( BitView view, byte value ) + { + view.WriteByte( value ); + } + } + + public class NetByte:TypedNetMember + { + public NetByte( byte value ):base( Singleton.Get(), value ){} + } + + +} \ No newline at end of file diff --git a/Runtime/Networking/Data/Types/NetFloat.cs b/Runtime/Networking/Data/Types/NetFloat.cs new file mode 100644 index 0000000..cf0b97c --- /dev/null +++ b/Runtime/Networking/Data/Types/NetFloat.cs @@ -0,0 +1,25 @@ +using Godot; +using System.Collections.Generic; + + +namespace Rokojori +{ + public class NetFloatType:NetworkDataType + { + public float ReadData( BitView view ) + { + return view.ReadFloat(); + } + + public void WriteData( BitView view, float value ) + { + view.WriteFloat( value ); + } + } + + + public class NetFloat:TypedNetMember + { + public NetFloat( float value ):base( Singleton.Get(), value ){} + } +} \ No newline at end of file diff --git a/Runtime/Networking/Data/Types/NetInt.cs b/Runtime/Networking/Data/Types/NetInt.cs new file mode 100644 index 0000000..2ac8464 --- /dev/null +++ b/Runtime/Networking/Data/Types/NetInt.cs @@ -0,0 +1,24 @@ +using Godot; +using System.Collections.Generic; + + +namespace Rokojori +{ + public class NetIntType:NetworkDataType + { + public int ReadData( BitView view ) + { + return view.ReadInt(); + } + + public void WriteData( BitView view, int value ) + { + view.WriteInt( value ); + } + } + + public class NetInt:TypedNetMember + { + public NetInt( int value ):base( Singleton.Get(), value ){} + } +} \ No newline at end of file diff --git a/Runtime/Networking/Data/Types/NetIntVL8.cs b/Runtime/Networking/Data/Types/NetIntVL8.cs new file mode 100644 index 0000000..d87bfb5 --- /dev/null +++ b/Runtime/Networking/Data/Types/NetIntVL8.cs @@ -0,0 +1,24 @@ +using Godot; +using System.Collections.Generic; + + +namespace Rokojori +{ + public class NetIntVL8Type:NetworkDataType + { + public int ReadData( BitView view ) + { + return view.ReadUIntVL8(); + } + + public void WriteData( BitView view, int value ) + { + view.WriteUIntVL8( value ); + } + } + + public class NetIntVL8:TypedNetMember + { + public NetIntVL8( int value ):base( Singleton.Get(), value ){} + } +} \ No newline at end of file diff --git a/Runtime/Networking/Data/Types/NetList.cs b/Runtime/Networking/Data/Types/NetList.cs new file mode 100644 index 0000000..5a20841 --- /dev/null +++ b/Runtime/Networking/Data/Types/NetList.cs @@ -0,0 +1,39 @@ +using Godot; +using System.Collections.Generic; + + +namespace Rokojori +{ + public class NetListType:NetworkDataType> + { + public NetworkDataType dataType; + + public List ReadData( BitView view ) + { + var num = view.ReadUIntVL8(); + var list = new List( num ); + + for ( int i = 0; i < num; i++ ) + { + list.Add( dataType.ReadData( view ) ); + } + + return list; + } + + public void WriteData( BitView view, List list ) + { + view.WriteUIntVL8( list.Count ); + + for ( int i = 0; i < list.Count; i++ ) + { + dataType.WriteData( view, list[ i ] ); + } + } + } + + public class NetList:TypedNetMember> + { + public NetList( List value ):base( Singleton>.Get(), value ){} + } +} \ No newline at end of file diff --git a/Runtime/Networking/Data/Types/NetQuaternion.cs b/Runtime/Networking/Data/Types/NetQuaternion.cs new file mode 100644 index 0000000..03f20fc --- /dev/null +++ b/Runtime/Networking/Data/Types/NetQuaternion.cs @@ -0,0 +1,24 @@ +using Godot; +using System.Collections.Generic; + + +namespace Rokojori +{ + public class NetQuaternionType:NetworkDataType + { + public Quaternion ReadData( BitView view ) + { + return view.ReadQuaternion(); + } + + public void WriteData( BitView view, Quaternion value ) + { + view.WriteQuaternion( value ); + } + } + + public class NetQuaternion:TypedNetMember + { + public NetQuaternion( Quaternion value ):base( Singleton.Get(), value ){} + } +} \ No newline at end of file diff --git a/Runtime/Networking/Data/Types/NetVector3.cs b/Runtime/Networking/Data/Types/NetVector3.cs new file mode 100644 index 0000000..5dc7a16 --- /dev/null +++ b/Runtime/Networking/Data/Types/NetVector3.cs @@ -0,0 +1,24 @@ +using Godot; +using System.Collections.Generic; + + +namespace Rokojori +{ + public class NetVector3Type:NetworkDataType + { + public Vector3 ReadData( BitView view ) + { + return view.ReadVector3(); + } + + public void WriteData( BitView view, Vector3 value ) + { + view.WriteVector3( value ); + } + } + + public class NetVector3:TypedNetMember + { + public NetVector3( Vector3 value ):base( Singleton.Get(), value ){} + } +} \ No newline at end of file diff --git a/Runtime/Networking/NetworkBackend.cs b/Runtime/Networking/NetworkBackend.cs new file mode 100644 index 0000000..b251a1b --- /dev/null +++ b/Runtime/Networking/NetworkBackend.cs @@ -0,0 +1,73 @@ +using Godot; +using System.Collections.Generic; + + +namespace Rokojori +{ + public partial class NetworkBackend:Node + { + protected NetworkSessionConnectionState _state; + protected string serverIP = "127.0.0.1"; + protected int port = 1984; + protected int maxMembers = 32; + + protected NetworkManager _manager; + protected ExtendedNetworkSessionManager _sessionManager; + protected ExtendedNetworkTransport _transport; + + public void InitializeBackend( + NetworkManager manager, + ExtendedNetworkSessionManager sessionManager, + ExtendedNetworkTransport transport + ) + { + _manager = manager; + _sessionManager = sessionManager; + _transport = transport; + } + + protected void AssignSessionRequestVariables( NetworkSessionRequest request ) + { + if ( request == null ) + { + return; + } + + if ( request.serverIP != null ) + { + serverIP = request.serverIP; + } + + if ( request.port > 0 ) + { + port = request.port; + } + + if ( request.maxMembers > 0 ) + { + maxMembers = request.maxMembers; + } + } + + public virtual void StartSession( NetworkSessionRequest sessionRequest ) + { + + } + + public virtual void JoinSession( NetworkSessionRequest sessionRequest ) + { + + } + + public virtual void LeaveSession() + { + + } + + public virtual void SendMessage( byte[] bytes, List targetMembers, bool reliable = true ) + { + + } + + } +} \ No newline at end of file diff --git a/Runtime/Networking/NetworkManager.cs b/Runtime/Networking/NetworkManager.cs new file mode 100644 index 0000000..ac24096 --- /dev/null +++ b/Runtime/Networking/NetworkManager.cs @@ -0,0 +1,65 @@ +using Godot; + + +namespace Rokojori +{ + [GlobalClass] + public partial class NetworkManager:Node + { + [Export] + public NetworkBackend backend; + + NetworkNodeMemberReferences _references = new NetworkNodeMemberReferences(); + public NetworkNodeMemberReferences references => _references; + + ExtendedNetworkTransport _transport = new ExtendedNetworkTransport(); + public NetworkTransport transport => _transport; + + ExtendedNetworkSessionManager _sessionManager = new ExtendedNetworkSessionManager(); + public NetworkSessionManager sessionManager => _sessionManager; + + bool _initialized = false; + + [Export] + public Action onStartedSession; + + [Export] + public Action onSessionMemberJoined; + + [Export] + public Action onSessionMemberLeft; + + public static NetworkManager Get() + { + return Unique.Get(); + } + + public static bool IsInSession => Get().sessionManager.isInSession; + public static int ownSessionMemberIndex => Get().sessionManager.ownMemberIndex; + public static int serverSessionMemberIndex =>Get().sessionManager.serverMemberIndex; + + + public void Initialize() + { + if ( _initialized ) + { + return; + } + + RJLog.Log( "InitializeBackend:" ); + + backend.InitializeBackend( this, _sessionManager, _transport ); + _initialized = true; + } + + public override void _Process( double delta ) + { + if ( ! IsInSession ) + { + return; + } + + _transport.ProcessQueuedMessages(); + } + } +} \ No newline at end of file diff --git a/Runtime/Networking/Nodes/AddNetworkingNodes.cs b/Runtime/Networking/Nodes/AddNetworkingNodes.cs new file mode 100644 index 0000000..988eb17 --- /dev/null +++ b/Runtime/Networking/Nodes/AddNetworkingNodes.cs @@ -0,0 +1,47 @@ +using Godot; +using System.Collections.Generic; + + +namespace Rokojori +{ + [GlobalClass] + public partial class AddNetworkNodes:Action + { + [Export] + public Node[] nodes; + + protected override void _OnTrigger() + { + RJLog.Log( "AddNetworkNodes" ); + + for ( int i = 0; i < nodes.Length; i++ ) + { + AddNodeAndChildren( nodes[ i ] ); + } + } + + void AddNodeAndChildren( Node root ) + { + var walker = new NodesWalker(); + + var nm = Unique.Get(); + var rf = nm.references; + + walker.Iterate( root, + n => + { + var isNetworkNode = typeof( INetworkNode ).IsAssignableFrom( n.GetType() ); + + if ( ! isNetworkNode ) + { + return; + } + + var inn = (INetworkNode) n; + rf.AddMembersOf( inn ); + + } + ); + } + } +} \ No newline at end of file diff --git a/Runtime/Networking/Nodes/INetworkingNode.cs b/Runtime/Networking/Nodes/INetworkingNode.cs new file mode 100644 index 0000000..04262b2 --- /dev/null +++ b/Runtime/Networking/Nodes/INetworkingNode.cs @@ -0,0 +1,16 @@ +using Godot; + +using System.Collections.Generic; + +namespace Rokojori +{ + + public interface INetworkNode + { + List GetNetworkNodeMembers(); + + NetworkTransportType GetNetworkType(); + int GetNetworkOwner(); + + } +} \ No newline at end of file diff --git a/Runtime/Networking/Nodes/NetworkNode.cs b/Runtime/Networking/Nodes/NetworkNode.cs new file mode 100644 index 0000000..33ed92e --- /dev/null +++ b/Runtime/Networking/Nodes/NetworkNode.cs @@ -0,0 +1,56 @@ +using Godot; + +using System.Collections.Generic; + +namespace Rokojori +{ + + public partial class NetworkNode : Node, INetworkNode + { + [ExportGroup("Network Settings")] + [Export] + public NetworkTransportType networkType = NetworkTransportType.Never_Networked; + public NetworkTransportType GetNetworkType(){ return networkType; } + + [Export] + public int networkOwner; + public int GetNetworkOwner(){ return networkOwner; } + + + protected List _networkNodeMembers = null; + protected NetworkNodeSlot _networkNodeSlot = new NetworkNodeSlot(); + + public virtual List GetNetworkNodeMembers() + { + if ( _networkNodeMembers != null ) + { + return _networkNodeMembers; + } + + _networkNodeMembers = CreateNetworkNodeMembers(); + _networkNodeSlot.onMessage.AddAction( _OnNetworkMessageReceived ); + + InitializeNetworkMembers(); + + return _networkNodeMembers; + } + + protected virtual List CreateNetworkNodeMembers() + { + return new List(){ _networkNodeSlot }; + } + + protected virtual void InitializeNetworkMembers() + { + for ( int i = 0; i < _networkNodeMembers.Count; i++ ) + { + _networkNodeMembers[ i ]._SetNode( this ); + } + } + + protected virtual void _OnNetworkMessageReceived( NetworkMessageEvent m ) + { + + } + } +} \ No newline at end of file diff --git a/Runtime/Networking/Nodes/NetworkNodeMember.cs b/Runtime/Networking/Nodes/NetworkNodeMember.cs new file mode 100644 index 0000000..f11e430 --- /dev/null +++ b/Runtime/Networking/Nodes/NetworkNodeMember.cs @@ -0,0 +1,95 @@ +using Godot; + +using System.Collections.Generic; + +namespace Rokojori +{ + + public class NetworkNodeMember + { + protected int _networkID = -1; + public int networkID => _networkID; + public bool hasNetworkID => _networkID != -1; + + public void _SetNetworkID ( int netID ) + { + _networkID = netID; + } + + protected INetworkNode _networkNode; + public INetworkNode networkNode => _networkNode; + + + protected NetworkTransportType customNetworkType = NetworkTransportType.Never_Networked; + protected bool hasCustomNetworkType = false; + public NetworkTransportType networkType => hasCustomNetworkType ? customNetworkType : networkNode.GetNetworkType(); + + public bool hasOwnedTransportType => NetworkTransportType.Owned_By_One == networkType; + + public bool IsOwnedBy( int sessionMember ) + { + return hasOwnedTransportType && networkNode.GetNetworkOwner() == sessionMember; + } + + public bool isOwnedLocally + { + get + { + return IsOwnedBy( NetworkManager.ownSessionMemberIndex ); + } + } + + public bool CanReceive() + { + return NetworkTransportSettings.CanReceive( networkType, networkNode.GetNetworkOwner() ); + } + + public bool CanSend() + { + return NetworkTransportSettings.CanSend( networkType, networkNode.GetNetworkOwner() ); + } + + public void _SetNode( NetworkNode node ) + { + _networkNode = node; + } + + public void ReceiveNetworkMessage( NetworkMessageEvent messageEvent ) + { + if ( ! CanReceive() ) + { + return; + } + + OnNetworkMessageReceived( messageEvent ); + } + + protected virtual void OnNetworkMessageReceived( NetworkMessageEvent messageEvent ) + { + + } + + public void Send( BitView view, List targets = null, bool reliable = true ) + { + if ( ! CanSend() ) + { + return; + } + + var nm = Unique.Get(); + var viewWithID = BitView.PrependID( networkID, view ); + nm.transport.SendMessage( viewWithID, targets, reliable ); + } + + public void SendWithID( BitView viewWithID, List targets = null, bool reliable = true ) + { + if ( ! CanSend() ) + { + return; + } + + var nm = Unique.Get(); + nm.transport.SendMessage( viewWithID, targets, reliable ); + } + } +} \ No newline at end of file diff --git a/Runtime/Networking/Nodes/NetworkNodeMemberReferences.cs b/Runtime/Networking/Nodes/NetworkNodeMemberReferences.cs new file mode 100644 index 0000000..3931dd9 --- /dev/null +++ b/Runtime/Networking/Nodes/NetworkNodeMemberReferences.cs @@ -0,0 +1,50 @@ +using Godot; +using System.Collections.Generic; + + +namespace Rokojori +{ + public class NetworkNodeMemberReferences + { + Dictionary referencesMap = new Dictionary(); + int counter = 1; + + public NetworkNodeMember GetMember( int id ) + { + if ( ! referencesMap.ContainsKey( id ) ) + { + return null; + } + + return referencesMap[ id ]; + + } + + public void AddMembersOf( INetworkNode node ) + { + var members = node.GetNetworkNodeMembers(); + + for ( int i = 0; i < members.Count; i++ ) + { + if ( members[ i ].networkType == NetworkTransportType.Never_Networked ) + { + continue; + } + + if ( members[ i ].hasNetworkID ) + { + continue; + } + + RJLog.Log( "Networked member", HierarchyName.Of( (Node)node ), i ); + + var id = counter; + referencesMap[ id ] = members[ i ]; + members[ i ]._SetNetworkID( id ); + + counter ++; + } + } + + } +} \ No newline at end of file diff --git a/Runtime/Networking/Nodes/NetworkNodeSlot.cs b/Runtime/Networking/Nodes/NetworkNodeSlot.cs new file mode 100644 index 0000000..0880469 --- /dev/null +++ b/Runtime/Networking/Nodes/NetworkNodeSlot.cs @@ -0,0 +1,16 @@ +using Godot; + +using System.Collections.Generic; + +namespace Rokojori +{ + public class NetworkNodeSlot:NetworkNodeMember + { + public EventSlot onMessage = new EventSlot(); + + protected override void OnNetworkMessageReceived( NetworkMessageEvent nme ) + { + onMessage.DispatchEvent( nme ); + } + } +} \ No newline at end of file diff --git a/Runtime/Networking/Session/JoinSession.cs b/Runtime/Networking/Session/JoinSession.cs new file mode 100644 index 0000000..02e15d5 --- /dev/null +++ b/Runtime/Networking/Session/JoinSession.cs @@ -0,0 +1,22 @@ +using Godot; +using System.Collections.Generic; + + +namespace Rokojori +{ + [GlobalClass] + public partial class JoinSession:Action + { + [Export] + public NetworkManager networkingManager; + + [Export] + public NetworkSessionRequest sessionRequest; + + protected override void _OnTrigger() + { + networkingManager.Initialize(); + networkingManager.sessionManager.JoinSession( sessionRequest ); + } + } +} \ No newline at end of file diff --git a/Runtime/Networking/Session/NetworkSessionEvent.cs b/Runtime/Networking/Session/NetworkSessionEvent.cs new file mode 100644 index 0000000..18978df --- /dev/null +++ b/Runtime/Networking/Session/NetworkSessionEvent.cs @@ -0,0 +1,11 @@ +using Godot; +using System.Collections.Generic; + + +namespace Rokojori +{ + public class NetworkSessionEvent + { + public long memberIndex; + } +} \ No newline at end of file diff --git a/Runtime/Networking/Session/NetworkSessionManager.cs b/Runtime/Networking/Session/NetworkSessionManager.cs new file mode 100644 index 0000000..4e74413 --- /dev/null +++ b/Runtime/Networking/Session/NetworkSessionManager.cs @@ -0,0 +1,104 @@ +using Godot; +using System.Collections.Generic; + + +namespace Rokojori +{ + public class NetworkSessionManager + { + protected bool _isInSession = false; + public bool isInSession => _isInSession; + + protected string _sessionName = null; + public string sessionName => _sessionName; + + protected int _serverMemberIndex = 0; + public int serverMemberIndex => _serverMemberIndex; + + protected int _ownMemberIndex = -1; + public int ownMemberIndex => _ownMemberIndex; + + public bool isServer => ownMemberIndex == serverMemberIndex; + + protected List _sessionMembers = new List(); + + public EventSlot onSessionEntered = new EventSlot(); + public EventSlot onSessionLeft = new EventSlot(); + + + public void StartSession( NetworkSessionRequest sessionRequest ) + { + var nm = Unique.Get(); + + if ( nm.backend == null ) + { + return; + } + + RJLog.Log( "StartSession" ); + nm.backend.StartSession( sessionRequest ); + } + + + public void JoinSession( NetworkSessionRequest sessionRequest ) + { + var nm = Unique.Get(); + + if ( nm.backend == null ) + { + return; + } + + RJLog.Log( "JoinSession" ); + + nm.backend.JoinSession( sessionRequest ); + } + + public void LeaveSession() + { + var nm = Unique.Get(); + + if ( nm.backend == null ) + { + return; + } + + nm.backend.LeaveSession(); + } + } + + public class ExtendedNetworkSessionManager:NetworkSessionManager + { + public void SetInSessionState( bool state = true ) + { + _isInSession = state; + } + + public void AddMember( NetworkSessionMember member ) + { + _sessionMembers.Add( member ); + + var nse = new NetworkSessionEvent(); + nse.memberIndex = member.index; + + onSessionEntered.DispatchEvent( nse ); + } + + public void RemoveMember( long id ) + { + var index = _sessionMembers.FindIndex( m => m.index == id ); + + if ( index == -1 ) + { + return; + } + + _sessionMembers.RemoveAt( index ); + + var nse = new NetworkSessionEvent(); + nse.memberIndex = id; + + onSessionLeft.DispatchEvent( nse ); + } + } +} \ No newline at end of file diff --git a/Runtime/Networking/Session/NetworkSessionMember.cs b/Runtime/Networking/Session/NetworkSessionMember.cs new file mode 100644 index 0000000..6970ed2 --- /dev/null +++ b/Runtime/Networking/Session/NetworkSessionMember.cs @@ -0,0 +1,22 @@ +using Godot; + + +namespace Rokojori +{ + public class NetworkSessionMember + { + long _index; + public long index => _index; + + public string name; + + public static NetworkSessionMember Create( long index ) + { + var member = new NetworkSessionMember(); + member._index = index; + + return member; + } + + } +} \ No newline at end of file diff --git a/Runtime/Networking/Session/NetworkSessionRequest.cs b/Runtime/Networking/Session/NetworkSessionRequest.cs new file mode 100644 index 0000000..fc28ca4 --- /dev/null +++ b/Runtime/Networking/Session/NetworkSessionRequest.cs @@ -0,0 +1,19 @@ +using Godot; +using System.Collections.Generic; + + +namespace Rokojori +{ + [GlobalClass] + public partial class NetworkSessionRequest:Resource + { + [Export] + public string sessionName = null; + [Export] + public int maxMembers = -1; + [Export] + public int port = 1984; + [Export] + public string serverIP = null; + } +} \ No newline at end of file diff --git a/Runtime/Networking/Session/NetworkSessionState.cs b/Runtime/Networking/Session/NetworkSessionState.cs new file mode 100644 index 0000000..f7f7c32 --- /dev/null +++ b/Runtime/Networking/Session/NetworkSessionState.cs @@ -0,0 +1,15 @@ +using Godot; +using System.Collections.Generic; + + +namespace Rokojori +{ + public enum NetworkSessionConnectionState + { + Not_Connected, + Connecting_As_Server, + Connecting_As_Client, + Connected_As_Server, + Connected_As_Client + } +} \ No newline at end of file diff --git a/Runtime/Networking/Session/StartSession.cs b/Runtime/Networking/Session/StartSession.cs new file mode 100644 index 0000000..34fb0d4 --- /dev/null +++ b/Runtime/Networking/Session/StartSession.cs @@ -0,0 +1,24 @@ +using Godot; +using System.Collections.Generic; + + +namespace Rokojori +{ + [GlobalClass] + public partial class StartSession:Action + { + [Export] + public NetworkManager networkingManager; + + [Export] + public NetworkSessionRequest sessionRequest; + + protected override void _OnTrigger() + { + RJLog.Log( "StartSession:" ); + + networkingManager.Initialize(); + networkingManager.sessionManager.StartSession( sessionRequest ); + } + } +} \ No newline at end of file diff --git a/Runtime/Networking/Transforms/NetworkTransform3D.cs b/Runtime/Networking/Transforms/NetworkTransform3D.cs new file mode 100644 index 0000000..66fbe4c --- /dev/null +++ b/Runtime/Networking/Transforms/NetworkTransform3D.cs @@ -0,0 +1,57 @@ +using Godot; +using System.Collections.Generic; + + +namespace Rokojori +{ + [GlobalClass] + public partial class NetworkTransform3D:NetworkNode + { + [Export] + public NetworkTransform3DType type; + + NetworkNodeSlot _positionSlot = new NetworkNodeSlot(); + NetworkNodeSlot _rotationSlot = new NetworkNodeSlot(); + NetworkNodeSlot _scaleSlot = new NetworkNodeSlot(); + + protected override List CreateNetworkNodeMembers() + { + return new List() + { + _networkNodeSlot, + _positionSlot, + _rotationSlot, + _scaleSlot + }; + } + + Vector3 _sendPosition = Vector3.Zero; + Vector3 _sendRotation = Vector3.Zero; + Vector3 _sendScale = Vector3.One; + float _sendTime = 0; + bool _idle = true; + + + public override void _Process( double delta ) + { + if ( ! NetworkManager.IsInSession ) + { + return; + } + + if ( ! _networkNodeSlot.hasOwnedTransportType ) + { + return; + } + + if ( _networkNodeSlot.isOwnedLocally ) + { + + } + else + { + + } + } + } +} \ No newline at end of file diff --git a/Runtime/Networking/Transforms/NetworkTransform3DType.cs b/Runtime/Networking/Transforms/NetworkTransform3DType.cs new file mode 100644 index 0000000..4545853 --- /dev/null +++ b/Runtime/Networking/Transforms/NetworkTransform3DType.cs @@ -0,0 +1,30 @@ +using Godot; +using System.Collections.Generic; + + +namespace Rokojori +{ + [GlobalClass] + public partial class NetworkTransform3DType:Resource + { + [ExportCategory("Position")] + + [Export] + public bool positionX; + [Export] + public bool positionY; + [Export] + public bool positionZ; + + + [ExportCategory("Rotation")] + + [Export] + public bool rotationX; + [Export] + public bool rotationY; + [Export] + public bool rotationZ; + + } +} \ No newline at end of file diff --git a/Runtime/Networking/Transforms/NetworkTransformManager.cs b/Runtime/Networking/Transforms/NetworkTransformManager.cs new file mode 100644 index 0000000..dac94a4 --- /dev/null +++ b/Runtime/Networking/Transforms/NetworkTransformManager.cs @@ -0,0 +1,14 @@ +using Godot; +using System.Collections.Generic; + + +namespace Rokojori +{ + public partial class NetworkTransformManager:NetworkNode + { + public override void _Process( double delta ) + { + + } + } +} \ No newline at end of file diff --git a/Runtime/Networking/Transport/NetworkingMessage.cs b/Runtime/Networking/Transport/NetworkingMessage.cs new file mode 100644 index 0000000..1adcdb5 --- /dev/null +++ b/Runtime/Networking/Transport/NetworkingMessage.cs @@ -0,0 +1,19 @@ +using Godot; + + +namespace Rokojori +{ + public class NetworkMessage + { + public long sender; + public BitView view; + } + + public class NetworkMessageEvent + { + public NetworkMessage message; + public int bitOffset; + public int bitOffsetMessageStart; + } + +} \ No newline at end of file diff --git a/Runtime/Networking/Transport/NetworkingTransport.cs b/Runtime/Networking/Transport/NetworkingTransport.cs new file mode 100644 index 0000000..8f2d703 --- /dev/null +++ b/Runtime/Networking/Transport/NetworkingTransport.cs @@ -0,0 +1,123 @@ +using Godot; +using System.Collections.Generic; + +namespace Rokojori +{ + public class QueuedMessageData + { + public BitView view; + public List targetMembers; + } + + public class NetworkTransport + { + public static readonly List ALL = new List(); + + public EventSlot onMessage = new EventSlot(); + + protected List reliableMessages = new List(); + protected List unreliableMessages = new List(); + + public void SendMessage( BitView view, List targetMembers, bool reliable = true ) + { + RJLog.Log( "SendMessage", view, reliable, targetMembers ); + + var data = new QueuedMessageData(); + data.view = view; + data.targetMembers = targetMembers; + + if ( reliable ) + { + reliableMessages.Add( data ); + } + else + { + unreliableMessages.Add( data ); + } + } + + } + + public class ExtendedNetworkTransport:NetworkTransport + { + public void HandleIncomingMessage( long id, byte[] data ) + { + var view = BitView.From( data ); + + var nm = new NetworkMessage(); + nm.view = view; + nm.sender = id; + + var nme = new NetworkMessageEvent(); + nme.message = nm; + nme.bitOffset = 0; + + var manager = NetworkManager.Get(); + var references = manager.references; + + while ( nme.bitOffset < nm.view.numBits ) + { + var offsetStart = nme.bitOffset; + + var target = view.ReadUIntVL8(); + var netMember = references.GetMember( target ); + + if ( netMember == null ) + { + RJLog.Log( "ID not found:", target ); + return; + } + + nme.bitOffsetMessageStart = view.pointerPosition; + + netMember.ReceiveNetworkMessage( nme ); + + if ( view.pointerPosition <= offsetStart ) + { + RJLog.Log( "Invalid pointer position: is smaller/equals:", offsetStart, ">>", view.pointerPosition ); + return; + } + + nme.bitOffset = view.pointerPosition; + nme.bitOffsetMessageStart = nme.bitOffset; + } + + + } + + public void ProcessQueuedMessages() + { + var nm = Unique.Get(); + + if ( nm.backend == null ) + { + reliableMessages.Clear(); + unreliableMessages.Clear(); + return; + } + + if ( reliableMessages.Count > 0 || unreliableMessages.Count > 0 ) + { + RJLog.Log( "ProcessQueuedMessages", reliableMessages.Count, unreliableMessages.Count ); + } + + + for ( int i = 0; i < reliableMessages.Count; i++ ) + { + var cm = reliableMessages[ i ]; + RJLog.Log( "Sending message:", cm ); + nm.backend.SendMessage( cm.view.GetBytes(), cm.targetMembers, true ); + } + + for ( int i = 0; i < unreliableMessages.Count; i++ ) + { + var cm = unreliableMessages[ i ]; + RJLog.Log( "Sending message:", cm ); + nm.backend.SendMessage( cm.view.GetBytes(), cm.targetMembers, false ); + } + + reliableMessages.Clear(); + unreliableMessages.Clear(); + } + } +} \ No newline at end of file diff --git a/Runtime/Networking/Transport/NetworkingTransportSettings.cs b/Runtime/Networking/Transport/NetworkingTransportSettings.cs new file mode 100644 index 0000000..e0a7257 --- /dev/null +++ b/Runtime/Networking/Transport/NetworkingTransportSettings.cs @@ -0,0 +1,63 @@ +using Godot; + + +namespace Rokojori +{ + public class NetworkTransportSettings + { + public static bool CanSend( NetworkTransportType type, int owner ) + { + if ( NetworkTransportType.Currently_Not_Networked == type ) + { + return false; + } + + if ( NetworkTransportType.From_Everybody_To_Everybody == type ) + { + return true; + } + + var nm = Unique.Get(); + + if ( NetworkTransportType.Owned_By_One == type ) + { + return nm.sessionManager.ownMemberIndex == owner; + } + + if ( NetworkTransportType.Server_Only == type ) + { + return nm.sessionManager.isServer; + } + + return false; + } + + public static bool CanReceive( NetworkTransportType type, int owner ) + { + if ( NetworkTransportType.Currently_Not_Networked == type ) + { + return false; + } + + if ( NetworkTransportType.From_Everybody_To_Everybody == type ) + { + return true; + } + + var nm = Unique.Get(); + + if ( NetworkTransportType.Owned_By_One == type ) + { + return nm.sessionManager.ownMemberIndex != owner; + } + + if ( NetworkTransportType.Server_Only == type ) + { + return ! nm.sessionManager.isServer; + } + + return false; + } + + } +} diff --git a/Runtime/Networking/Transport/NetworkingTransportType.cs b/Runtime/Networking/Transport/NetworkingTransportType.cs new file mode 100644 index 0000000..d50ace4 --- /dev/null +++ b/Runtime/Networking/Transport/NetworkingTransportType.cs @@ -0,0 +1,16 @@ +using Godot; + + +namespace Rokojori +{ + public enum NetworkTransportType + { + Never_Networked, + Currently_Not_Networked, + From_Everybody_To_Everybody, + Server_Only, + Owned_By_One, + Custom + } +} + diff --git a/Runtime/Procedural/Baking/SaveViewportTexture.cs b/Runtime/Procedural/Baking/SaveViewportTexture.cs index 2ecdbb7..a56289b 100644 --- a/Runtime/Procedural/Baking/SaveViewportTexture.cs +++ b/Runtime/Procedural/Baking/SaveViewportTexture.cs @@ -9,7 +9,7 @@ namespace Rokojori { [Tool] [GlobalClass] - public partial class SaveViewportTexture:RJAction + public partial class SaveViewportTexture:Action { [Export] public SubViewport viewport; @@ -20,7 +20,7 @@ namespace Rokojori [Export] public float quality = 1; - public override void _OnTrigger() + protected override void _OnTrigger() { Textures.Save( viewport.GetTexture(), path, quality ); } diff --git a/Runtime/Random/LCG.cs b/Runtime/Random/LCG.cs index 0ba49c1..12f13b4 100644 --- a/Runtime/Random/LCG.cs +++ b/Runtime/Random/LCG.cs @@ -35,16 +35,17 @@ namespace Rokojori public static LCG Randomized() { - var ms = Time.GetUnixTimeFromSystem() % 1; - var seed = (int) ( ms * 10000 ); - var lcg = new LCG(); - // RJLog.Log( "Seed", seed, Time.GetUnixTimeFromSystem() ); - lcg.SetSeed( seed ); - lcg.Next(); - return lcg; + var seed = (int) (Time.GetTicksUsec() % 1000000 ); + var lcg = new LCG(); + lcg.SetSeed( seed ); + + lcg.SetSeed( lcg.IntegerExclusive( 0, 1000000 ) ); + + return lcg; } + void setParameters( int modulus, int multiplier, int increment ) { _seedState.modulus = modulus; @@ -67,6 +68,11 @@ namespace Rokojori return seedState; } + public int GetSeed() + { + return _seedState.state; + } + public override void SetSeedState( object seedStateObject ) { var seedState = (LCGSeedState) seedStateObject; diff --git a/Runtime/Random/RandomEngine.cs b/Runtime/Random/RandomEngine.cs index a54d48d..988e4c3 100644 --- a/Runtime/Random/RandomEngine.cs +++ b/Runtime/Random/RandomEngine.cs @@ -78,6 +78,15 @@ namespace Rokojori return a.Lerp( b, this.Next() ); } + public Vector3 IndividualBetween( Vector3 a, Vector3 b ) + { + var x = Mathf.Lerp( a.X, b.X, this.Next() ); + var y = Mathf.Lerp( a.Y, b.Y, this.Next() ); + var z = Mathf.Lerp( a.Z, b.Z, this.Next() ); + + return new Vector3( x, y, z ); + } + public Color RandomHue( float saturation = 1f, float luminance = 0.5f) { var hue = Range( 0, 360 ); diff --git a/Runtime/Networking/NetworkNode.cs b/Runtime/Selectors/Selector.cs similarity index 51% rename from Runtime/Networking/NetworkNode.cs rename to Runtime/Selectors/Selector.cs index 548e85a..71232da 100644 --- a/Runtime/Networking/NetworkNode.cs +++ b/Runtime/Selectors/Selector.cs @@ -8,8 +8,13 @@ using Godot; namespace Rokojori { - public partial class NetworkNode:Node + [Tool] + [GlobalClass] + public partial class Selector:Resource { - + public virtual bool Selects( Node node ) + { + return true; + } } } \ No newline at end of file diff --git a/Runtime/Selectors/Selectors.cs b/Runtime/Selectors/Selectors.cs index eaf5e70..c330e2b 100644 --- a/Runtime/Selectors/Selectors.cs +++ b/Runtime/Selectors/Selectors.cs @@ -10,7 +10,7 @@ namespace Rokojori { public class Selectors { - public static T GetFromDirectChildren( Node parent, RJSelector s ) where T:Node + public static T GetFromDirectChildren( Node parent, Selector s ) where T:Node { T selected = null; diff --git a/Runtime/Sensors/CombineSensor.cs b/Runtime/Sensors/CombineSensor.cs index ee029d0..819fe6b 100644 --- a/Runtime/Sensors/CombineSensor.cs +++ b/Runtime/Sensors/CombineSensor.cs @@ -5,51 +5,22 @@ using Godot; namespace Rokojori { [GlobalClass,Icon("res://addons/rokojori_action_library/Icons/RJSensor.svg")] - public partial class CombineSensor : RJSensor + public partial class CombineSensor : Sensor { [Export] - public RJSensor[] sensors; + public Sensor[] sensors; + - [Export] - public float axisActivationTreshold = 0.75f; - - float _value = 0; - bool _wasActive = false; - bool _isActive = false; - - public override float GetValue() - { - return _value; - } - - public override bool IsActive() - { - return _isActive; - } - - public override bool WasActive() - { - return _wasActive; - } - - public override void UpdateValue( float value ) - { - _value = value; - - _wasActive = _isActive; - _isActive = _value > axisActivationTreshold; - } - - public override void _Process( double delta ) + protected override void UpdateValue() { var value = 0f; for ( int i = 0; i < sensors.Length; i++ ) { - value = Mathf.Max( value, sensors[ i ].GetValue() ); + value = Mathf.Max( value, sensors[ i ].value ); } - UpdateValue( value ); + SetFloatValue( value ); } } } \ No newline at end of file diff --git a/Runtime/Sensors/InputSensor.cs b/Runtime/Sensors/InputSensor.cs deleted file mode 100644 index a872826..0000000 --- a/Runtime/Sensors/InputSensor.cs +++ /dev/null @@ -1,76 +0,0 @@ - -using Godot; - - -namespace Rokojori -{ - [GlobalClass,Icon("res://addons/rokojori_action_library/Icons/RJSensor.svg")] - public partial class InputSensor : RJSensor - { - [Export] - public string inputActionName = ""; - - [Export] - public bool pollAsButton = false; - - [Export] - public bool pollAsReleasedOnly = false; - - [Export] - public float buttonSmoothingFilterCoefficient = 1; - - [Export] - public float axisActivationTreshold = 0.75f; - - float _value = 0; - bool _wasActive = false; - bool _isActive = false; - - public override float GetValue() - { - return _value; - } - - public override bool IsActive() - { - return _isActive; - } - - public override bool WasActive() - { - return _wasActive; - } - - public override void UpdateValue( float value ) - { - _value = value; - - _wasActive = _isActive; - _isActive = _value > axisActivationTreshold; - } - - public override void _Process( double delta ) - { - if ( pollAsButton ) - { - if ( pollAsReleasedOnly ) - { - bool state = Input.IsActionJustReleased( inputActionName ); - UpdateValue( state ? 1 : 0 ); - } - else - { - bool state = Input.IsActionPressed( inputActionName ); - UpdateValue( state ? 1 : 0 ); - } - - } - else - { - float value = Input.GetActionRawStrength( inputActionName ); - UpdateValue( value ); - } - } - - } -} \ No newline at end of file diff --git a/Runtime/Sensors/KeySensor.cs b/Runtime/Sensors/KeySensor.cs index ef0eab6..8418d51 100644 --- a/Runtime/Sensors/KeySensor.cs +++ b/Runtime/Sensors/KeySensor.cs @@ -4,14 +4,15 @@ using Godot; namespace Rokojori { + [Tool] [GlobalClass,Icon("res://addons/rokojori_action_library/Icons/RJSensor.svg")] - public partial class KeySensor : RJSensor + public partial class KeySensor : Sensor, iOnInputSensor { [Export] public Key key; [ExportGroup( "Modifiers")] - [Export] + [Export] public Trillean ctrlHold = Trillean.Any; [Export] @@ -31,18 +32,14 @@ namespace Rokojori [Export] public ModifiersMode modifiersMode; - bool _isActive; - bool _wasActive; - float _value = 0; - float axisActivationTreshold = 0.5f; float _lastInput = 0; - public override void _Process( double delta ) + protected override void UpdateValue() { - UpdateValue( _lastInput ); + SetFloatValue( _lastInput ); } - public override void _Input( InputEvent ev ) + public void _Input( InputEvent ev ) { var keyEvent = ev as InputEventKey; @@ -89,28 +86,6 @@ namespace Rokojori } - public override bool IsActive() - { - return _isActive; - } - - public override bool WasActive() - { - return _wasActive; - } - - public override float GetValue() - { - return _value; - } - - public override void UpdateValue( float value ) - { - _value = value; - - _wasActive = _isActive; - _isActive = _value > axisActivationTreshold; - } } } \ No newline at end of file diff --git a/Runtime/Sensors/MouseMotionDelta.cs b/Runtime/Sensors/MouseMotionDelta.cs index 7610a39..72867a6 100644 --- a/Runtime/Sensors/MouseMotionDelta.cs +++ b/Runtime/Sensors/MouseMotionDelta.cs @@ -4,8 +4,9 @@ using Godot; namespace Rokojori { + [Tool] [GlobalClass,Icon("res://addons/rokojori_action_library/Icons/RJSensor.svg")] - public partial class MouseMotionDelta : RJSensor + public partial class MouseMotionDelta : Sensor, iOnInputSensor { public enum MouseMotionType { @@ -21,19 +22,15 @@ namespace Rokojori [Export] public float speedMultiply = 1; - bool _isActive = false; - bool _wasActive = false; - float _value = 0; - float axisActivationTreshold = 0.5f; float _lastInput = 0; - public override void _Process( double delta ) + protected override void UpdateValue() { - UpdateValue( _lastInput ); + SetFloatValue( _lastInput ); _lastInput = 0; } - public override void _Input( InputEvent ev ) + public void _Input( InputEvent ev ) { var mouseEvent = ev as InputEventMouseMotion ; @@ -67,29 +64,6 @@ namespace Rokojori _lastInput = motion * speedMultiply; } - - public override bool IsActive() - { - return _isActive; - } - - public override bool WasActive() - { - return _wasActive; - } - - public override float GetValue() - { - return _value; - } - - public override void UpdateValue( float value ) - { - _value = value; - - _wasActive = _isActive; - _isActive = _value > axisActivationTreshold; - } } } \ No newline at end of file diff --git a/Runtime/Sensors/MouseScreenRelative.cs b/Runtime/Sensors/MouseScreenRelative.cs index ae94fbd..1086d79 100644 --- a/Runtime/Sensors/MouseScreenRelative.cs +++ b/Runtime/Sensors/MouseScreenRelative.cs @@ -4,8 +4,9 @@ using Godot; namespace Rokojori { + [Tool] [GlobalClass,Icon("res://addons/rokojori_action_library/Icons/RJSensor.svg")] - public partial class MouseScreenRelative : RJSensor + public partial class MouseScreenRelative : Sensor, iOnInputSensor { public enum MouseMotionType { @@ -18,18 +19,14 @@ namespace Rokojori [Export] public MouseMotionType motionType; - bool _isActive = false; - bool _wasActive = false; - float _value = 0; - float axisActivationTreshold = 0.5f; float _lastInput = 0; - public override void _Process( double delta ) + protected override void UpdateValue() { - UpdateValue( _lastInput ); + SetFloatValue( _lastInput ); } - public override void _Input( InputEvent ev ) + public void _Input( InputEvent ev ) { var mouseEvent = ev as InputEventMouseMotion ; @@ -38,7 +35,8 @@ namespace Rokojori return; } - var relativePosition = mouseEvent.Position / GetViewport().GetVisibleRect().Size * 2 - Vector2.One; + var vp = Unique.Get().GetViewport(); + var relativePosition = mouseEvent.Position / vp.GetVisibleRect().Size * 2 - Vector2.One; var position = 0f; // RJLog.Log( mouseEvent.Position ); @@ -66,28 +64,6 @@ namespace Rokojori } - public override bool IsActive() - { - return _isActive; - } - - public override bool WasActive() - { - return _wasActive; - } - - public override float GetValue() - { - return _value; - } - - public override void UpdateValue( float value ) - { - _value = value; - - _wasActive = _isActive; - _isActive = _value > axisActivationTreshold; - } } } \ No newline at end of file diff --git a/Runtime/Sensors/OnSensor.cs b/Runtime/Sensors/OnSensor.cs index 4838cdf..354044c 100644 --- a/Runtime/Sensors/OnSensor.cs +++ b/Runtime/Sensors/OnSensor.cs @@ -8,21 +8,21 @@ namespace Rokojori public partial class OnSensor: Node { [Export] - public RJSensor sensor; + public Sensor sensor; [Export] - public RJAction onStart; + public Action onStart; [Export] - public RJAction onActive; + public Action onActive; [Export] - public RJAction onEnd; + public Action onEnd; public override void _Process( double delta) { - var active = sensor.IsActive(); - var wasActive = sensor.WasActive(); + var active = sensor.isActive; + var wasActive = sensor.wasActive; if ( ! active && ! wasActive ) { @@ -34,17 +34,17 @@ namespace Rokojori if ( started ) { - Actions.Trigger( onStart ); + Action.Trigger( onStart ); } if ( active ) { - Actions.Trigger( onActive ); + Action.Trigger( onActive ); } if ( ended ) { - Actions.Trigger( onActive ); + Action.Trigger( onActive ); } } diff --git a/Runtime/Sensors/SensorManager.cs b/Runtime/Sensors/SensorManager.cs index c6909f3..2fa4ee8 100644 --- a/Runtime/Sensors/SensorManager.cs +++ b/Runtime/Sensors/SensorManager.cs @@ -23,6 +23,7 @@ namespace Rokojori List runners = new List(); + List inputers = new List(); Dictionary sensorToRunner = new Dictionary(); @@ -36,6 +37,16 @@ namespace Rokojori CreateRunners(); } + public override void _Input( InputEvent ev ) + { + inputers.ForEach( + ( inp )=> + { + inp._Input( ev ); + } + ); + } + public override void _Process( double delta ) { if ( Engine.IsEditorHint() || ! processSensors ) @@ -123,8 +134,19 @@ namespace Rokojori } } - runners.ForEach( r => sensorToRunner[ r.sensor ] = r ); + runners.ForEach( + r => + { + sensorToRunner[ r.sensor ] = r; + if ( r.sensor is iOnInputSensor oi ) + { + inputers.Add( oi ); + } + } + ); + + this.LogInfo( "Created runners:", runners.Count ); } } diff --git a/Runtime/Sensors/Sensors.cs b/Runtime/Sensors/Sensors.cs index 3883295..7f26b53 100644 --- a/Runtime/Sensors/Sensors.cs +++ b/Runtime/Sensors/Sensors.cs @@ -6,17 +6,17 @@ namespace Rokojori { public class Sensors { - public static bool IsActive( RJSensor sensor ) + public static bool IsActive( Sensor sensor ) { - return sensor == null ? false : sensor.IsActive(); + return sensor == null ? false : sensor.isActive; } - public static float GetValue( RJSensor sensor, float scale = 1 ) + public static float GetValue( Sensor sensor, float scale = 1 ) { - return sensor == null ? 0 : sensor.GetValue() * scale; + return sensor == null ? 0 : sensor.value * scale; } - public static float PolarAxis( RJSensor negative, RJSensor positive ) + public static float PolarAxis( Sensor negative, Sensor positive ) { return GetValue( negative, -1 ) + GetValue( positive, 1 ); } diff --git a/Runtime/Sensors/TriggerOnSensor.cs b/Runtime/Sensors/TriggerOnSensor.cs index b69c752..b7f1832 100644 --- a/Runtime/Sensors/TriggerOnSensor.cs +++ b/Runtime/Sensors/TriggerOnSensor.cs @@ -11,7 +11,7 @@ namespace Rokojori public Sensor sensor; [Export] - public RJAction action; + public Action action; public override void _Ready() { @@ -25,9 +25,11 @@ namespace Rokojori public void _OnSensor( SensorEvent se ) { + RJLog.Log( se, se.IsDown( sensor ) ); + if ( se.IsDown( sensor ) ) { - Actions.Trigger( action ); + Action.Trigger( action ); } } diff --git a/Runtime/Sensors/iOnInputSensor.cs b/Runtime/Sensors/iOnInputSensor.cs new file mode 100644 index 0000000..036ad4a --- /dev/null +++ b/Runtime/Sensors/iOnInputSensor.cs @@ -0,0 +1,11 @@ + +using Godot; +using System.Collections.Generic; + +namespace Rokojori +{ + public interface iOnInputSensor + { + void _Input( InputEvent ev ); + } +} \ No newline at end of file diff --git a/Runtime/Shading/Library/Math.gdshaderinc b/Runtime/Shading/Library/Math.gdshaderinc index 6b8ea3b..513a351 100644 --- a/Runtime/Shading/Library/Math.gdshaderinc +++ b/Runtime/Shading/Library/Math.gdshaderinc @@ -1,3 +1,5 @@ +const float DegreesToRadians = PI/180.0; + float clamp01( float value ) { return clamp( value, 0.0, 1.0 ); diff --git a/Runtime/Shading/Library/Transform.gdshaderinc b/Runtime/Shading/Library/Transform.gdshaderinc index 261652b..ef2e82e 100644 --- a/Runtime/Shading/Library/Transform.gdshaderinc +++ b/Runtime/Shading/Library/Transform.gdshaderinc @@ -88,6 +88,37 @@ vec2 rotateAround_v2( vec2 uv, float angle, vec2 pivot ) return uv; } +vec2 rotateAroundTexture_v2( vec2 uv, float angle, vec2 pivot, vec2 textureSize ) +{ + + vec2 p = uv; + float aspect = textureSize.x / textureSize.y; + + float cosA = cos( angle ); + float sinA = sin( angle ); + + mat2 rotMat = mat2( + vec2( cosA, -sinA ), + vec2( sinA, cosA ) + ); + + rotMat = mat2( + vec2( cosA, -sinA ), + vec2( sinA, cosA ) + ); + + + p -= pivot; + p.y *= 1.0 / aspect; + p *= rotMat; + + p.y *= aspect; + p += pivot; + + return p; + + } + vec3 cameraWorldPosition( mat4 _INV_VIEW_MATRIX ) { return (_INV_VIEW_MATRIX * vec4(vec3(0.0), 1.0)).xyz; @@ -97,4 +128,99 @@ vec3 cameraWorldForward( mat4 _INV_VIEW_MATRIX ) { vec3 pos = cameraWorldPosition( _INV_VIEW_MATRIX ); return normalize( (_INV_VIEW_MATRIX * vec4( vec3(0.0,0.0,1.0), 1.0)).xyz - pos ); -} \ No newline at end of file +} + + +mat3 identity_m3() +{ + return mat3( + vec3( 1, 0, 0 ), + vec3( 0, 1, 0 ), + vec3( 0, 0, 1 ) + ); +} + +mat3 translate_m3( vec2 translation ) +{ + return mat3( + vec3( 1, 0, translation.x ), + vec3( 0, 1, translation.y ), + vec3( 0, 0, 1 ) + ); +} + +mat3 scale_m3( vec2 scale ) +{ + return mat3( + vec3( scale.x, 0, 0 ), + vec3( 0, scale.y, 0 ), + vec3( 0, 0, 1 ) + ); +} + +mat3 scalePivot_m3( vec2 scale, vec2 pivot ) +{ + return translate_m3( -pivot ) * scale_m3( scale ) * translate_m3( pivot ); +} + +mat3 rotate_m3( float radiansAngle ) +{ + float c = cos( radiansAngle ); + float s = sin( radiansAngle ); + + return mat3( + vec3( c, -s, 0 ), + vec3( s, c, 0 ), + vec3( 0, 0, 1 ) + ); +} + +mat3 rotatePivot_m3( float radiansAngle, vec2 pivot ) +{ + return translate_m3( -pivot ) * rotate_m3( radiansAngle ) * translate_m3( pivot ); +} + +mat3 rotatePivotAspect_m3( float radiansAngle, vec2 pivot, float aspect ) +{ + return translate_m3( -pivot ) * + scale_m3( vec2( 1, 1.0/aspect ) ) * + rotate_m3( radiansAngle ) * + scale_m3( vec2( 1, aspect ) ) * + translate_m3( pivot ); +} + + +vec2 applyMatrix_m3v2( mat3 matrix, vec2 point ) +{ + float x = point.x; + float y = point.y; + + // float ox = matrix[ 0 ] * x + matrix[ 3 ] * y + matrix[ 6 ]; + // float oy = matrix[ 1 ] * x + matrix[ 4 ] * y + matrix[ 7 ]; + + // 0 1 2 0 3 6 + // 3 4 5 1 4 7 + // 6 7 8 2 5 8 + + vec3 mx = matrix[ 0 ]; + vec3 my = matrix[ 1 ]; + + float ox = mx.x * x + mx.y * y + mx.z; + float oy = my.x * x + my.y * y + my.z; + + return vec2( ox, oy ); +} + +vec2 applyMatrixBase_m3v2( mat3 matrix, vec2 point ) +{ + float x = point.x; + float y = point.y; + + vec3 mx = matrix[ 0 ]; + vec3 my = matrix[ 1 ]; + + float ox = mx.x * x + mx.y * y; + float oy = my.x * x + my.y * y; + + return vec2( ox, oy ); +} diff --git a/Runtime/Shading/Shaders/Baking/DepthMap.gdshader b/Runtime/Shading/Shaders/Baking/DepthMap.gdshader index 183ff6c..fc72280 100644 --- a/Runtime/Shading/Shaders/Baking/DepthMap.gdshader +++ b/Runtime/Shading/Shaders/Baking/DepthMap.gdshader @@ -18,12 +18,12 @@ uniform ivec2 albedo_texture_size; uniform float centerDistance = 100; uniform float rangeDistance = 50; -void vertex() +void vertex() { } -void fragment() +void fragment() { vec4 albedo_tex = texture( texture_albedo, UV); vec3 worldPosition = ( INV_VIEW_MATRIX * vec4( VERTEX, 1.0 ) ).xyz; @@ -31,10 +31,10 @@ void fragment() float range = rangeDistance / 2.0; float value = normalizeToRange01( worldDistance, centerDistance - range, centerDistance + range - ); - + ); + ALBEDO = vec3( 1, 1, 1 ) * value; - + ALPHA *= albedo.a * albedo_tex.a; ALPHA_SCISSOR_THRESHOLD = alpha_scissor_threshold; ALPHA_ANTIALIASING_EDGE = alpha_antialiasing_edge; diff --git a/Runtime/Shading/Shaders/Billboards/QuadBillboard.gdshader b/Runtime/Shading/Shaders/Billboards/QuadBillboard.gdshader index ac0a3a5..acc99ca 100644 --- a/Runtime/Shading/Shaders/Billboards/QuadBillboard.gdshader +++ b/Runtime/Shading/Shaders/Billboards/QuadBillboard.gdshader @@ -18,7 +18,7 @@ uniform sampler2D texture_normals : hint_roughness_normal, filter_linear_mipmap, uniform float normalBlendAmount: hint_range(0,1) = 0.5; uniform vec3 normalBlendDirection = vec3( 0, 1, 0 ); uniform float roughness: hint_range(0,1) = 1; -uniform float metalness: hint_range(0,1) = 1; +uniform float metalness: hint_range(0,1) = 1; uniform float specular: hint_range(0,1) = 1; @@ -59,47 +59,47 @@ void vertex() vec4 worldVertex = MODEL_MATRIX *vec4( VERTEX, 1.0 ); float windAngle = perlinPolar( TIME * windSpeed + windNoiseScale * vec2( worldVertex.x, worldVertex.z ) ); float windStrength = perlinPolar( TIME * windSpeed + windNoiseScale * vec2( worldVertex.x, worldVertex.z ) + vec2( 1023.9, 334.90 ) ); - + vec2 windDirection = onCircle( windAngle * 6.28 ) * windStrength; float yWindAmount = normalizeToRange01( worldVertex.y, windStart, windEnd ) * windAmount; - + float nrx = perlinPolar( NORMAL.yz + worldVertex.yz ); - float nry = perlinPolar( NORMAL.xz + worldVertex.xz ); + float nry = perlinPolar( NORMAL.xz + worldVertex.xz ); float nrz = perlinPolar( NORMAL.xy + worldVertex.xy ); float px = perlinPolar( NORMAL.yz ); float pz = perlinPolar( NORMAL.xy ); float filter = perlin( vec2( px, pz ) * discardNoiseScale ); - - + + discardValue = filter; - + vec3 worldOffset = billboardWorldOffset( UV, INV_VIEW_MATRIX, MODEL_MATRIX ); - + vec3 originalVertex = VERTEX; VERTEX = VERTEX + worldOffset * size + vec3( nrx, nry, nrz ) * randomPosition; VERTEX = VERTEX + yWindAmount * vec3( windDirection.x, 0, windDirection.y ); - + vec3 vertexNormal = originalVertex; vertexNormal.y = 0.0; vertexNormal = normalize( vertexNormal ); vec3 normal = mix( NORMAL, vertexNormal, fresnelNormalSource ); vec3 worldNormal = normalize( MODEL_NORMAL_MATRIX * normal ); - vec3 camDir = normalize( CAMERA_DIRECTION_WORLD ); + vec3 camDir = normalize( CAMERA_DIRECTION_WORLD ); fresnelAmount = fresnel( camDir, worldNormal, fresnelSharpness ) * fresnelScale; - - originalNormal = normalize( (vec4( localToWorldDirection( NORMAL, MODEL_MATRIX ), 1.0 ) * INV_VIEW_MATRIX ).xyz); - NORMAL = normalize( mix( NORMAL, normalBlendDirection, normalBlendAmount ) ); - + originalNormal = normalize( (vec4( localToWorldDirection( NORMAL, MODEL_MATRIX ), 1.0 ) * INV_VIEW_MATRIX ).xyz); + NORMAL = normalize( mix( NORMAL, normalBlendDirection, normalBlendAmount ) ); + + float random = perlinPolar( vec2( worldVertex.x, worldVertex.z ) * yMapNoiseScale ); uvRotation = rotation + rotationNoiseAmount * perlinPolar( vec2( worldVertex.x + worldVertex.y, worldVertex.z - worldVertex.y) * rotationNoiseScale ); - uvRotation = mod( uvRotation, 6.28); + uvRotation = mod( uvRotation, 6.28); float y = worldVertex.y + yMapNoiseAmount * random; yMapValue = normalizeToRange01( y, yMapEnd, yMapStart ); - - + + // rotatedUV = rotateAround_v2( UV, mod( rotation + random2 * rotationNoiseAmount, PI * 2.0 ), vec2( 0.5, 0.5 ) ); - -} + +} void fragment() @@ -108,15 +108,15 @@ void fragment() { discard; } - - + + vec2 uv = rotateAround_v2( UV, uvRotation, vec2( 0.5, 0.5 ) ); vec4 albedo_tex = texture( texture_albedo, uv ); - vec4 normalColor = texture( texture_normals, uv ); + vec4 normalColor = texture( texture_normals, uv ); vec4 yGradient = texture( texture_yMapGradient, vec2( 0, yMapValue ) ); - + ALBEDO = albedo.rgb * albedo_tex.rgb * yGradient.rgb + fresnelColor.rgb * fresnelAmount; - + NORMAL_MAP = normalColor.rgb; ALPHA *= albedo.a * albedo_tex.a; diff --git a/Runtime/Shading/Shaders/Effects/FresnelOverlay/FresnelOverlay.gdshader b/Runtime/Shading/Shaders/Effects/FresnelOverlay/FresnelOverlay.gdshader index 62914f9..72c59fe 100644 --- a/Runtime/Shading/Shaders/Effects/FresnelOverlay/FresnelOverlay.gdshader +++ b/Runtime/Shading/Shaders/Effects/FresnelOverlay/FresnelOverlay.gdshader @@ -14,18 +14,18 @@ uniform float fresnelSharpness = 2; uniform float fresnelMultiply = 1; uniform float fresnelOffset = 0; -void vertex() -{ +void vertex() +{ VERTEX += NORMAL * grow; } -void fragment() +void fragment() { vec2 uv = UV; float fresnelAmount = fresnel( NORMAL, VIEW, fresnelSharpness) * fresnelMultiply + fresnelOffset; fresnelAmount = clamp( fresnelAmount, 0.0, 1.0 ); vec4 albedo_tex = texture( texture_albedo, uv ); - + ALBEDO = albedo.rgb * albedo_tex.rgb; ALPHA *= albedo.a * albedo_tex.a * fresnelAmount; } diff --git a/Runtime/Shading/Shaders/PostProcessing/ChromaticDistortion.gdshader b/Runtime/Shading/Shaders/PostProcessing/ChromaticDistortion.gdshader index d777972..488e023 100644 --- a/Runtime/Shading/Shaders/PostProcessing/ChromaticDistortion.gdshader +++ b/Runtime/Shading/Shaders/PostProcessing/ChromaticDistortion.gdshader @@ -21,20 +21,20 @@ uniform float maxScroll = 1; void fragment() { vec2 scrollUV = mod( scrollScale * (UV + TIME * scrollDirection ), vec2(1,1) ) ; - float strength = texture( distortionTexture, UV ).r + + float strength = texture( distortionTexture, UV ).r + mix( minScroll, maxScroll, texture( scrollingTexture, scrollUV ).r ) * scrollAmount; - - + + vec2 outerUV = ( UV - vec2(0.5,0.5) ) * maxScale + vec2( 0.5, 0.5 ); - - vec2 direction = ( UV - outerUV ) * effectStrength; - + + vec2 direction = ( UV - outerUV ) * effectStrength; + vec4 red = texture( screenTexture, UV + strength * offsetR * direction ); vec4 green = texture( screenTexture, UV + strength * offsetG * direction ); vec4 blue = texture( screenTexture, UV + strength * offsetB * direction ); - + vec4 mixed = vec4( red.r, green.g, blue.b, 1 ); - - + + COLOR = mixed; } \ No newline at end of file diff --git a/Runtime/Shading/Shaders/PostProcessing/Overlays.gdshader b/Runtime/Shading/Shaders/PostProcessing/Overlays.gdshader index d293c28..41a5e0e 100644 --- a/Runtime/Shading/Shaders/PostProcessing/Overlays.gdshader +++ b/Runtime/Shading/Shaders/PostProcessing/Overlays.gdshader @@ -21,10 +21,10 @@ void fragment() vec4 overlayColor = texture( overlay, UV ); vec4 additiveOverlayColor = overlayColor + rgb; vec4 multipliedOverlayColor = overlayColor * rgb; - + float overlayBlendType = length( overlayColor.rgb ); vec4 mixed = mix3_v4( multipliedOverlayColor, rgb, additiveOverlayColor, overlayBlendType ); - - rgb = mixed; + + rgb = mixed; COLOR = mix( originalRGB, mixed, effectStrength ); } \ No newline at end of file diff --git a/Runtime/Shading/Shaders/Wipes/FadeWipe/FadeWipe.cs b/Runtime/Shading/Shaders/Wipes/FadeWipe/FadeWipe.cs new file mode 100644 index 0000000..93239d7 --- /dev/null +++ b/Runtime/Shading/Shaders/Wipes/FadeWipe/FadeWipe.cs @@ -0,0 +1,57 @@ +using Godot; + +namespace Rokojori +{ + public class FadeWipe + { + public static readonly CachedResource shader = new CachedResource( + "res://addons/rokojori_action_library/Runtime/Shading/Shaders/Wipes/FadeWipe/FadeWipe.gdshader" + ); + + public static readonly FloatPropertyName wipeState = FloatPropertyName.Create( "wipeState" ); + public static readonly Vector2PropertyName outputViewSize = Vector2PropertyName.Create( "outputViewSize" ); + public static readonly Vector2PropertyName wipeTextureSize = Vector2PropertyName.Create( "wipeTextureSize" ); + public static readonly ColorPropertyName wipeTextureTint = ColorPropertyName.Create( "wipeTextureTint" ); + public static readonly FloatPropertyName uvRotation = FloatPropertyName.Create( "uvRotation" ); + public static readonly Vector2PropertyName uvRotationCenter = Vector2PropertyName.Create( "uvRotationCenter" ); + public static readonly FloatPropertyName uvScale = FloatPropertyName.Create( "uvScale" ); + public static readonly Vector2PropertyName uvScaleCenter = Vector2PropertyName.Create( "uvScaleCenter" ); + public static readonly Vector2PropertyName uvTranslation = Vector2PropertyName.Create( "uvTranslation" ); + public static readonly Texture2DPropertyName wipeTexture = Texture2DPropertyName.Create( "wipeTexture" ); + + } + + public partial class FadeWipeMaterial:CustomMaterial + { + + + public readonly CustomMaterialProperty wipeState; + public readonly CustomMaterialProperty outputViewSize; + public readonly CustomMaterialProperty wipeTextureSize; + public readonly CustomMaterialProperty wipeTextureTint; + public readonly CustomMaterialProperty uvRotation; + public readonly CustomMaterialProperty uvRotationCenter; + public readonly CustomMaterialProperty uvScale; + public readonly CustomMaterialProperty uvScaleCenter; + public readonly CustomMaterialProperty uvTranslation; + public readonly CustomMaterialProperty wipeTexture; + + public FadeWipeMaterial() + { + Shader = FadeWipe.shader.Get(); + + wipeState = new CustomMaterialProperty( this, FadeWipe.wipeState ); + outputViewSize = new CustomMaterialProperty( this, FadeWipe.outputViewSize ); + wipeTextureSize = new CustomMaterialProperty( this, FadeWipe.wipeTextureSize ); + wipeTextureTint = new CustomMaterialProperty( this, FadeWipe.wipeTextureTint ); + uvRotation = new CustomMaterialProperty( this, FadeWipe.uvRotation ); + uvRotationCenter = new CustomMaterialProperty( this, FadeWipe.uvRotationCenter ); + uvScale = new CustomMaterialProperty( this, FadeWipe.uvScale ); + uvScaleCenter = new CustomMaterialProperty( this, FadeWipe.uvScaleCenter ); + uvTranslation = new CustomMaterialProperty( this, FadeWipe.uvTranslation ); + wipeTexture = new CustomMaterialProperty( this, FadeWipe.wipeTexture ); + } + + } + +} \ No newline at end of file diff --git a/Runtime/Shading/Shaders/Wipes/FadeWipe/FadeWipe.gdshader b/Runtime/Shading/Shaders/Wipes/FadeWipe/FadeWipe.gdshader new file mode 100644 index 0000000..1c16e92 --- /dev/null +++ b/Runtime/Shading/Shaders/Wipes/FadeWipe/FadeWipe.gdshader @@ -0,0 +1,51 @@ +shader_type canvas_item; + +#include "res://addons/rokojori_action_library/Runtime/Shading/Library/Math.gdshaderinc" +#include "res://addons/rokojori_action_library/Runtime/Shading/Library/Transform.gdshaderinc" + +uniform float wipeState:hint_range(0,1) = 0; +uniform vec2 outputViewSize = vec2(1920,1080); + + +uniform sampler2D wipeTexture : source_color, filter_linear_mipmap, repeat_enable; +uniform vec2 wipeTextureSize = vec2( 1,1 ); +uniform vec4 wipeTextureTint : source_color = vec4(0,0,0,1); + +uniform float uvRotation = 0; +uniform vec2 uvRotationCenter = vec2(0 ,0); + +uniform float uvScale = 1; +uniform vec2 uvScaleCenter = vec2(0 ,0); + +uniform vec2 uvTranslation = vec2(0,0); + +varying vec2 textureUV; +varying vec4 animatedTint; + +void vertex() +{ + mat3 matrix = identity_m3(); + + float textureAspect = wipeTextureSize.x / wipeTextureSize.y; + float viewAspect = outputViewSize.x / outputViewSize.y; + float viewRatio = viewAspect / textureAspect; + + matrix *= rotatePivotAspect_m3( uvRotation * DegreesToRadians , uvRotationCenter, textureAspect * viewRatio ); + + vec2 rotatedScaleCenter = applyMatrix_m3v2( rotatePivot_m3( uvRotation, vec2( 0.5,0.5)), uvScaleCenter ); + matrix *= scalePivot_m3( uvScale * vec2( viewRatio,1), rotatedScaleCenter ); + + + matrix *= translate_m3( applyMatrixBase_m3v2( matrix, -uvTranslation ) ); + + vec2 uv = applyMatrix_m3v2( matrix, UV ); + textureUV = uv; + + animatedTint = wipeTextureTint; + animatedTint.a *= wipeState; +} + +void fragment() +{ + COLOR = texture( wipeTexture, textureUV ) * animatedTint; +} diff --git a/Runtime/Shading/Tools/CSShaderClassGenerator/CSShaderClassGenerator.cs b/Runtime/Shading/Tools/CSShaderClassGenerator/CSShaderClassGenerator.cs index a2ec491..ea7a977 100644 --- a/Runtime/Shading/Tools/CSShaderClassGenerator/CSShaderClassGenerator.cs +++ b/Runtime/Shading/Tools/CSShaderClassGenerator/CSShaderClassGenerator.cs @@ -9,7 +9,7 @@ namespace Rokojori public partial class CSShaderClassGenerator:Node { [Export] - public string resourcePath; + public Shader shader; [Export] public bool generate; @@ -32,6 +32,7 @@ namespace Rokojori public void Generate() { + var resourcePath = this.shader.ResourcePath; var shader = ResourceLoader.Load( resourcePath ); var resourceParentPath = RegexUtility.ParentPath( resourcePath ); var absoluteFilePath = FilePath.Absolute( ProjectSettings.GlobalizePath( resourcePath ) ); @@ -66,13 +67,17 @@ namespace Rokojori var csType = type; - if ( csType == "Float" ) + if ( type == "Float" ) { csType = "float"; } - else if ( csType == "Int" ) + else if ( type == "Int" ) { - csType = "float"; + csType = "int"; + } + else if ( type == "Bool" ) + { + csType = "bool"; } var map = new StringMap(); diff --git a/Runtime/Structures/MultiMap.cs b/Runtime/Structures/MultiMap.cs index 8b97e06..f6bf94a 100644 --- a/Runtime/Structures/MultiMap.cs +++ b/Runtime/Structures/MultiMap.cs @@ -10,7 +10,6 @@ namespace Rokojori { public class MultiMap:Map> { - public bool Has( K1 key1, K2 key2 ) { if ( ! ContainsKey( key1 ) ) @@ -21,6 +20,21 @@ namespace Rokojori return this[ key1 ].ContainsKey( key2 ); } + public V Get( K1 key1, K2 key2 ) + { + if ( ! ContainsKey( key1 ) ) + { + return default(V); + } + + if ( ! this[ key1 ].ContainsKey( key2 ) ) + { + return default(V); + } + + return this[ key1 ][ key2 ]; + } + public void Set( K1 key, K2 key2, V value ) { if ( ! ContainsKey( key ) ) diff --git a/Runtime/Time/ModulateTimeLineSpeed.cs b/Runtime/Time/ModulateTimeLineSpeed.cs index 9e1e279..78fbe35 100644 --- a/Runtime/Time/ModulateTimeLineSpeed.cs +++ b/Runtime/Time/ModulateTimeLineSpeed.cs @@ -5,16 +5,16 @@ using Godot; namespace Rokojori { [GlobalClass ] - public partial class ModulateTimeLineSpeed : RJSequenceAction + public partial class ModulateTimeLineSpeed : SequenceAction { [Export] - public RJTimeLine timeline; + public TimeLine timeline; [Export] public AnimationCurve curve; - public override void _OnTrigger() + protected override void _OnTrigger() { var tm = Unique.Get(); diff --git a/Runtime/Time/SetTimeLineSpeed.cs b/Runtime/Time/SetTimeLineSpeed.cs index 5bd7601..3bc3684 100644 --- a/Runtime/Time/SetTimeLineSpeed.cs +++ b/Runtime/Time/SetTimeLineSpeed.cs @@ -5,15 +5,15 @@ using Godot; namespace Rokojori { [GlobalClass ] - public partial class SetTimeLineSpeed : RJAction + public partial class SetTimeLineSpeed : Action { [Export] - public RJTimeLine timeline; + public TimeLine timeline; [Export] public float speed = 1; - public override void _OnTrigger() + protected override void _OnTrigger() { var tm = Unique.Get(); tm.SetSpeed( timeline, speed ); diff --git a/Runtime/Time/TimeLine.cs b/Runtime/Time/TimeLine.cs new file mode 100644 index 0000000..457acbe --- /dev/null +++ b/Runtime/Time/TimeLine.cs @@ -0,0 +1,41 @@ + +using System.Diagnostics; +using System.Collections; +using System.Collections.Generic; +using System; +using Godot; + + +namespace Rokojori +{ + [Tool] + [GlobalClass] + public partial class TimeLine:Resource + { + [Export] + public bool isLooping = false; + + [Export] + public float loopStart = 0; + + [Export] + public float loopEnd = 100000; + + [Export] + public float startSpeed = 1; + + [Export] + public bool autoStart = true; + + + public float delta + { + get + { + var tm = Unique.Get(); + return tm.GetRunner( this ).currentDelta; + } + } + + } +} \ No newline at end of file diff --git a/Runtime/Time/TimeLineEvent.cs b/Runtime/Time/TimeLineEvent.cs index 14c5989..c672edf 100644 --- a/Runtime/Time/TimeLineEvent.cs +++ b/Runtime/Time/TimeLineEvent.cs @@ -10,9 +10,9 @@ namespace Rokojori { public class TimeLineEvent { - public long id; + public int id; public bool persistent; - public double position; + public float position; public bool wasInside = false; } } \ No newline at end of file diff --git a/Runtime/Time/TimeLineManager.cs b/Runtime/Time/TimeLineManager.cs index 94ca1fd..a2354d5 100644 --- a/Runtime/Time/TimeLineManager.cs +++ b/Runtime/Time/TimeLineManager.cs @@ -10,20 +10,23 @@ namespace Rokojori { [Tool] [GlobalClass] - public partial class TimeLineManager:RJTimeLineManager + public partial class TimeLineManager:NetworkNode { [Export] - public RJTimeLine[] timeLines; + public TimeLine[] timeLines; [Export] - public RJTimeLine engineTimeScale; + public TimeLine engineTimeScale; [Export] - public RJTimeLine realTimeTimeLine; + public TimeLine realTimeTimeLine; [Export] public bool computeRealtimeWithEngineDelta; + public readonly EventSlot onEvent = new EventSlot(); + public readonly EventSlot> onSpan = new EventSlot>(); + List _runners = new List(); @@ -58,7 +61,12 @@ namespace Rokojori } - public void Modulate( RJTimeLine timeline, AnimationCurve c, Action onReady ) + public int GetTimeLineIndex( TimeLine timeLine ) + { + return Arrays.IndexOf( timeLines, timeLine ); + } + + public void Modulate( TimeLine timeline, AnimationCurve c, Action onReady ) { var runner = GetRunner( GetTimeLineIndex( timeline ) ); runner.Modulate( c, onReady ); @@ -105,7 +113,11 @@ namespace Rokojori _runners = Lists.Map( timeLines, tl => new TimeLineRunner( tl ) ); } - TimeLineRunner GetRunner( int index ) + public TimeLineRunner GetRunner( TimeLine timeline ) + { + return GetRunner( _runners.FindIndex( r => r.timeLine == timeline ) ); + } + public TimeLineRunner GetRunner( int index ) { if ( index < 0 || index >= _runners.Count ) { @@ -115,13 +127,13 @@ namespace Rokojori return _runners[ index ]; } - public override int CreateID() + public int CreateID() { _idCounter ++; return _idCounter; } - public static float GetPosition( RJTimeLine timeLine ) + public static float GetPosition( TimeLine timeLine ) { var manager = Unique.Get(); @@ -138,14 +150,14 @@ namespace Rokojori } - public static float GetPhase( RJTimeLine timeLine, float duration, float offset = 0 ) + public static float GetPhase( TimeLine timeLine, float duration, float offset = 0 ) { var time = GetPosition( timeLine ) + offset; return ( time % duration ) / duration; } - public static float GetRangePhase( RJTimeLine timeLine, float start, float end ) + public static float GetRangePhase( TimeLine timeLine, float start, float end ) { var time = GetPosition( timeLine ); var normalized = MathX.Normalize( time, start, end ); @@ -155,75 +167,75 @@ namespace Rokojori - public override void ScheduleEvent( int timeLineIndex, double position, int callbackID, bool isPersistent ) + public void ScheduleEvent( int timeLineIndex, float position, int callbackID, bool isPersistent ) { var runner = _runners[ timeLineIndex ]; runner.ScheduleEvent( position, callbackID, isPersistent ); } - public override void ScheduleSpan( int timeLineIndex, double start, double end, int callbackID, bool isPersistent ) + public void ScheduleSpan( int timeLineIndex, float start, float end, int callbackID, bool isPersistent ) { var runner = _runners[ timeLineIndex ]; runner.ScheduleSpan( start, end, callbackID, isPersistent ); } - public override double GetLastPosition( int timeLineIndex ) + public float GetLastPosition( int timeLineIndex ) { var runner = GetRunner( timeLineIndex ); if ( runner == null ){ return 0; } return runner.lastPosition; } - public override double GetPosition( int timeLineIndex ) + public float GetPosition( int timeLineIndex ) { var runner = GetRunner( timeLineIndex ); if ( runner == null ){ return 0; } return runner.position; } - public override void SetPosition( int timeLineIndex, double position ) + public void SetPosition( int timeLineIndex, float position ) { var runner = GetRunner( timeLineIndex ); if ( runner == null ){ return; } runner.position = position; } - public override double GetSpeed( int timeLineIndex ) + public double GetSpeed( int timeLineIndex ) { var runner = GetRunner( timeLineIndex ); if ( runner == null ){ return 1; } return runner.speed; } - public float GetModulatedSpeed( RJTimeLine timeline ) + public float GetModulatedSpeed( TimeLine timeline ) { var timeLineIndex = GetTimeLineIndex( timeline ); var runner = GetRunner( timeLineIndex ); if ( runner == null ){ return 1; } return runner.modulatedSpeed; } - public float GetSpeed( RJTimeLine timeline ) + public float GetSpeed( TimeLine timeline ) { return (float) GetSpeed( GetTimeLineIndex( timeline ) ); } - public override void SetSpeed( int timeLineIndex, double speed ) + public void SetSpeed( int timeLineIndex, float speed ) { var runner = GetRunner( timeLineIndex ); if ( runner == null ){ return; } runner.speed = speed; } - public void SetSpeed( RJTimeLine timeline, double speed ) + public void SetSpeed( TimeLine timeline, float speed ) { SetSpeed( GetTimeLineIndex( timeline ), speed ); } - public override bool GetPlayState( int timeLineIndex ) + public bool GetPlayState( int timeLineIndex ) { var runner = GetRunner( timeLineIndex ); if ( runner == null ){ return false; } return runner.playing; } - public override void SetPlayState( int timeLineIndex, bool isPlaying ) + public void SetPlayState( int timeLineIndex, bool isPlaying ) { var runner = GetRunner( timeLineIndex ); if ( runner == null ){ return; } runner.playing = isPlaying; diff --git a/Runtime/Time/TimeLineRunner.cs b/Runtime/Time/TimeLineRunner.cs index f4619ef..f1e1bb1 100644 --- a/Runtime/Time/TimeLineRunner.cs +++ b/Runtime/Time/TimeLineRunner.cs @@ -10,13 +10,13 @@ namespace Rokojori { public class TimeLineRunner { - public RJTimeLine timeLine; + public TimeLine timeLine; - public double lastPosition = 0; - public double position = 0; + public float lastPosition = 0; + public float position = 0; public bool playing = false; - public double deltaScale = 1; - public double speed = 1; + public float deltaScale = 1; + public float speed = 1; List events = new List(); List spans = new List(); @@ -26,14 +26,16 @@ namespace Rokojori Vector3 modulatorRandomization; Action modulatorOnReady = null; float _lastModulation = 1; + float _currentDelta = 1; public float modulatedSpeed => (float)( speed * _lastModulation * deltaScale ); + public float currentDelta => _currentDelta; - public TimeLineRunner( RJTimeLine timeLine ) + public TimeLineRunner( TimeLine timeLine ) { this.timeLine = timeLine; - playing = timeLine.AutoStart; + playing = timeLine.autoStart; } public void Modulate( AnimationCurve curve, Action onReady ) @@ -85,8 +87,9 @@ namespace Rokojori _lastModulation = 1; } + _currentDelta = realtimeDelta * deltaScale * speed * modulation; lastPosition = position; - position += realtimeDelta * deltaScale * speed * modulation; + position += _currentDelta; var isForward = speed >= 0; @@ -146,7 +149,8 @@ namespace Rokojori "event:", eventPosition ); - manager.EmitSignal( TimeLineManager.SignalName.OnEvent, events[ i ].id ); + // manager.EmitSignal( TimeLineManager.SignalName.OnEvent, events[ i ].id ); + manager.onEvent.DispatchEvent( events[ i ].id ); events[ i ].wasInside = true; } @@ -189,24 +193,25 @@ namespace Rokojori var isEnd = timelineSpan.Contains( spans[ i ].end ); - var spanType = TimeLineSpan.InSpan; + var spanType = TimeLineSpanUpdateType.InSpan; if ( isStart && isEnd ) { - spanType = TimeLineSpan.CompletelyInside; + spanType = TimeLineSpanUpdateType.CompletelyInside; } else if ( isStart ) { - spanType = TimeLineSpan.Start; + spanType = TimeLineSpanUpdateType.Start; } else if ( isEnd ) { - spanType = TimeLineSpan.End; + spanType = TimeLineSpanUpdateType.End; } spans[ i ].wasInside = true; - - manager.EmitSignal( TimeLineManager.SignalName.OnSpan, spans[ i ].id, spanType ); + + manager.onSpan.DispatchEvent( new Tuple( spans[ i ].id, spanType ) ); + // manager.EmitSignal( TimeLineManager.SignalName.OnSpan, spans[ i ].id, spanType ); } @@ -217,7 +222,7 @@ namespace Rokojori } } - public void ScheduleEvent( double position, int callbackID, bool isPersistent ) + public void ScheduleEvent( float position, int callbackID, bool isPersistent ) { var tle = new TimeLineEvent(); tle.position = position; @@ -227,7 +232,7 @@ namespace Rokojori events.Add( tle ); } - public void ScheduleSpan( double start, double end, int callbackID, bool isPersistent ) + public void ScheduleSpan( float start, float end, int callbackID, bool isPersistent ) { var tse = new TimeLineSpan(); tse.start = start; diff --git a/Runtime/Time/TimeLineScheduler.cs b/Runtime/Time/TimeLineScheduler.cs index ad40fb3..b42d72b 100644 --- a/Runtime/Time/TimeLineScheduler.cs +++ b/Runtime/Time/TimeLineScheduler.cs @@ -11,13 +11,13 @@ namespace Rokojori [GlobalClass] public partial class TimeLineScheduler:Node { - public static int ScheduleEventIn( RJTimeLine timeLine, double offset, Action action, bool persistent = false ) + public static int ScheduleEventIn( TimeLine timeLine, float offset, Action action, bool persistent = false ) { var scheduler = Unique.Get(); return scheduler._ScheduleEventIn( timeLine, offset, action, persistent ); } - public static int ScheduleEventAt( RJTimeLine timeLine, double position, Action action, bool persistent = false ) + public static int ScheduleEventAt( TimeLine timeLine, float position, Action action, bool persistent = false ) { var scheduler = Unique.Get(); return scheduler._ScheduleEventAt( timeLine, position, action, persistent ); @@ -25,7 +25,7 @@ namespace Rokojori - int _ScheduleEventAt( RJTimeLine timeLine, double position, Action action, bool persistent = false ) + int _ScheduleEventAt( TimeLine timeLine, float position, Action action, bool persistent = false ) { AttachListeners(); var tm = Unique.Get(); @@ -36,7 +36,7 @@ namespace Rokojori return id; } - int _ScheduleEventIn( RJTimeLine timeLine, double offset, Action action, bool persistent = false ) + int _ScheduleEventIn( TimeLine timeLine, float offset, Action action, bool persistent = false ) { var tm = Unique.Get(); var tIndex = tm.GetTimeLineIndex( timeLine ); @@ -45,13 +45,13 @@ namespace Rokojori } - public static int ScheduleSpanAt( RJTimeLine timeLine, double start, double end, Action action, bool persistent = false ) + public static int ScheduleSpanAt( TimeLine timeLine, float start, float end, Action action, bool persistent = false ) { var scheduler = Unique.Get(); return scheduler._ScheduleSpan( timeLine, start, end, action, persistent ); } - public static int ScheduleSpanIn( RJTimeLine timeLine, double offset, double duration, Action action, bool persistent = false ) + public static int ScheduleSpanIn( TimeLine timeLine, float offset, float duration, Action action, bool persistent = false ) { var scheduler = Unique.Get(); var tm = Unique.Get(); @@ -62,7 +62,7 @@ namespace Rokojori return scheduler._ScheduleSpan( timeLine, start, end, action, persistent ); } - int _ScheduleSpan( RJTimeLine timeLine, double start, double end, Action action, bool persistent = false ) + int _ScheduleSpan( TimeLine timeLine, float start, float end, Action action, bool persistent = false ) { AttachListeners(); var tm = Unique.Get(); @@ -78,7 +78,7 @@ namespace Rokojori HashSet _persistentEventsAndSpans = new HashSet(); Dictionary> _eventActions = new Dictionary>(); - Dictionary> _spanActions = new Dictionary>(); + Dictionary> _spanActions = new Dictionary>(); void AttachListeners() @@ -92,10 +92,19 @@ namespace Rokojori var tm = Unique.Get(); - tm.OnEvent += ( id ) => OnEvent( id ); - tm.OnSpan += ( id, type ) => onSpan( id, type ); + tm.onEvent.AddAction( + ( id )=> + { + OnEvent( id ); + } + ); - + tm.onSpan.AddAction( + ( t )=> + { + OnSpan( t.Item1 , t.Item2 ); + } + ); } public void _RemoveEventEntry( int id ) @@ -110,10 +119,8 @@ namespace Rokojori - void OnEvent( long s_id ) + void OnEvent( int id ) { - var id = (int) s_id; - if ( ! _eventActions.ContainsKey( id ) ) { return; @@ -121,14 +128,10 @@ namespace Rokojori _eventActions[ id ]( id ); - } - void onSpan( long s_id, long s_type ) + void OnSpan( int id, TimeLineSpanUpdateType type ) { - var id = (int) s_id; - var type = (int) s_type; - if ( ! _spanActions.ContainsKey( id ) ) { return; diff --git a/Runtime/Time/TimeLineSpan.cs b/Runtime/Time/TimeLineSpan.cs index 12e6c7b..77ae2e1 100644 --- a/Runtime/Time/TimeLineSpan.cs +++ b/Runtime/Time/TimeLineSpan.cs @@ -8,17 +8,26 @@ using Godot; namespace Rokojori { + public enum TimeLineSpanUpdateType + { + Start, + InSpan, + End, + CompletelyInside + } + + public class TimeLineSpanUpdate + { + public TimeLineSpan span; + public TimeLineSpanUpdate type; + } + public class TimeLineSpan { - public static int Start = 0; - public static int InSpan = 1; - public static int End = 2; - public static int CompletelyInside = 3; - - public long id; + public int id; public bool persistent; - public double start; - public double end; + public float start; + public float end; public bool wasInside = false; } } \ No newline at end of file diff --git a/Runtime/Time/TimeLines/GameTime.tres b/Runtime/Time/TimeLines/GameTime.tres index 7760bf8..d47344c 100644 --- a/Runtime/Time/TimeLines/GameTime.tres +++ b/Runtime/Time/TimeLines/GameTime.tres @@ -1,4 +1,11 @@ -[gd_resource type="RJTimeLine" format=3 uid="uid://frruktikky46"] +[gd_resource type="Resource" script_class="TimeLine" load_steps=2 format=3 uid="uid://ch5nsa6yafs5l"] + +[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Time/TimeLine.cs" id="1_lxe8k"] [resource] +script = ExtResource("1_lxe8k") +isLooping = false +loopStart = 0.0 +loopEnd = 0.0 +startSpeed = 0.0 autoStart = true diff --git a/Runtime/Time/TimeLines/RealTime.tres b/Runtime/Time/TimeLines/RealTime.tres index d237897..416fa42 100644 --- a/Runtime/Time/TimeLines/RealTime.tres +++ b/Runtime/Time/TimeLines/RealTime.tres @@ -1,4 +1,6 @@ -[gd_resource type="RJTimeLine" format=3 uid="uid://dmsepypwb6xek"] +[gd_resource type="Resource" script_class="TimeLine" load_steps=2 format=3 uid="uid://h6oi6vkj4c2m"] + +[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Time/TimeLine.cs" id="1_0ltdh"] [resource] -autoStart = true +script = ExtResource("1_0ltdh") diff --git a/Runtime/Tools/Arrays.cs b/Runtime/Tools/Arrays.cs index 4064271..3d27b19 100644 --- a/Runtime/Tools/Arrays.cs +++ b/Runtime/Tools/Arrays.cs @@ -34,6 +34,7 @@ namespace Rokojori return u; } + public static int FindIndex( T[] values, Func predicate ) { for ( int i = 0; i < values.Length; i++ ) diff --git a/Runtime/Tools/Lists.cs b/Runtime/Tools/Lists.cs index 70a820e..eb9022c 100644 --- a/Runtime/Tools/Lists.cs +++ b/Runtime/Tools/Lists.cs @@ -220,6 +220,15 @@ namespace Rokojori } } + public static void RemoveRange( List list, List removals ) + { + var removalSet = new HashSet(); + removalSet.UnionWith( removals ); + + list.RemoveAll( e => removalSet.Contains( e ) ); + } + + public static int CountItems( List list, Predicate test ) { diff --git a/Runtime/Tools/Singleton.cs b/Runtime/Tools/Singleton.cs new file mode 100644 index 0000000..8b83df9 --- /dev/null +++ b/Runtime/Tools/Singleton.cs @@ -0,0 +1,24 @@ +using System.Collections; +using System.Collections.Generic; + +using Godot; + +namespace Rokojori +{ + public class Singleton where T:new() + { + private static T _singleton; + + public static T Get() + { + if ( _singleton != null ) + { + return _singleton; + } + + _singleton = new T(); + + return _singleton; + } + } +} \ No newline at end of file diff --git a/Runtime/UI/OnSliderValueChange.cs b/Runtime/UI/OnSliderValueChange.cs index 16e6c64..b6ee02a 100644 --- a/Runtime/UI/OnSliderValueChange.cs +++ b/Runtime/UI/OnSliderValueChange.cs @@ -13,7 +13,7 @@ namespace Rokojori HSlider _connectedSlider = null; [Export] - public RJAction onChange; + public Action onChange; public void Update() { @@ -39,7 +39,7 @@ namespace Rokojori void OnChanged() { - Actions.Trigger( onChange ); + Action.Trigger( onChange ); } } } \ No newline at end of file diff --git a/Runtime/UI/Styling/UIColor.cs b/Runtime/UI/Styling/UIColor.cs index eda3cf2..026eb0f 100644 --- a/Runtime/UI/Styling/UIColor.cs +++ b/Runtime/UI/Styling/UIColor.cs @@ -34,7 +34,7 @@ namespace Rokojori public float animationOffset = 0; [Export] - public RJTimeLine timeLine; + public TimeLine timeLine; public static Color Compute( Control control, UIStyleColorProperty property, Color defaultColor ) { diff --git a/Runtime/UI/Styling/UINumber.cs b/Runtime/UI/Styling/UINumber.cs index b3bf534..14af34d 100644 --- a/Runtime/UI/Styling/UINumber.cs +++ b/Runtime/UI/Styling/UINumber.cs @@ -30,7 +30,7 @@ namespace Rokojori public float animationOffset; [Export] - public RJTimeLine timeLine; + public TimeLine timeLine; public bool IsNone => unit == "none"; diff --git a/Runtime/UI/Transitions/ActiveStyleTransition.cs b/Runtime/UI/Transitions/ActiveStyleTransition.cs index 02ae665..58cb389 100644 --- a/Runtime/UI/Transitions/ActiveStyleTransition.cs +++ b/Runtime/UI/Transitions/ActiveStyleTransition.cs @@ -12,7 +12,7 @@ namespace Rokojori { public V value; public P propertyType; - public RJTimeLine timeLine; + public TimeLine timeLine; public float start; public float end; public Curve curve; diff --git a/Runtime/UI/Transitions/TransitionSettings.cs b/Runtime/UI/Transitions/TransitionSettings.cs index b7a0504..186e942 100644 --- a/Runtime/UI/Transitions/TransitionSettings.cs +++ b/Runtime/UI/Transitions/TransitionSettings.cs @@ -16,7 +16,7 @@ namespace Rokojori public Curve curve; [Export] - public RJTimeLine timeLine; + public TimeLine timeLine; } diff --git a/Runtime/VirtualCameras/Effects/CameraEffect.cs b/Runtime/VirtualCameras/Effects/CameraEffect.cs index 6b1df36..27b26a2 100644 --- a/Runtime/VirtualCameras/Effects/CameraEffect.cs +++ b/Runtime/VirtualCameras/Effects/CameraEffect.cs @@ -16,7 +16,7 @@ namespace Rokojori public CameraEffectTargetAnimationCurve[] animations; [Export] - public RJTimeLine timeline; + public TimeLine timeline; public float maxDuration { diff --git a/Runtime/VirtualCameras/Effects/PlayCameraEffect.cs b/Runtime/VirtualCameras/Effects/PlayCameraEffect.cs index 0b057c2..2a7639b 100644 --- a/Runtime/VirtualCameras/Effects/PlayCameraEffect.cs +++ b/Runtime/VirtualCameras/Effects/PlayCameraEffect.cs @@ -10,7 +10,7 @@ namespace Rokojori { [Tool] [GlobalClass] - public partial class PlayCameraEffect:RJAction + public partial class PlayCameraEffect:Action { [Export] public CameraEffect cameraEffect; @@ -22,9 +22,9 @@ namespace Rokojori public int cameraSlotIndex = -1; [Export] - public RJSelector cameraSlotSelector; + public Selector cameraSlotSelector; - public override void _OnTrigger() + protected override void _OnTrigger() { var resolvedSlot = cameraSlot; @@ -48,6 +48,8 @@ namespace Rokojori return; } + this.LogInfo( "Camera slot found" ); + resolvedSlot.SetCameraEffect( cameraEffect ); } diff --git a/Runtime/VirtualCameras/MouseEditorCamera.cs b/Runtime/VirtualCameras/MouseEditorCamera.cs index 11003f5..adb2a2e 100644 --- a/Runtime/VirtualCameras/MouseEditorCamera.cs +++ b/Runtime/VirtualCameras/MouseEditorCamera.cs @@ -40,10 +40,10 @@ namespace Rokojori public float maxPitch = 89; [Export] - public RJSensor orbitButton; + public Sensor orbitButton; [Export] - public RJSensor[] orbitModifierButtons; + public Sensor[] orbitModifierButtons; [ExportGroup("Pan")] @@ -54,10 +54,10 @@ namespace Rokojori public float panSpeedY = 0.01f; [Export] - public RJSensor panButton; + public Sensor panButton; [Export] - public RJSensor[] panModifierButtons; + public Sensor[] panModifierButtons; [ExportGroup("Zoom")] @@ -72,16 +72,16 @@ namespace Rokojori [Export] - public RJSensor zoomInButton; + public Sensor zoomInButton; [Export] - public RJSensor[] zoomInModifierButtons; + public Sensor[] zoomInModifierButtons; [Export] - public RJSensor zoomOutButton; + public Sensor zoomOutButton; [Export] - public RJSensor[] zoomOutModifierButtons; + public Sensor[] zoomOutModifierButtons; [Export] public float zoomSmoothingCoefficient = 0.1f; @@ -89,17 +89,17 @@ namespace Rokojori [ExportGroup("Move")] [Export] - public RJSensor forwardButton; + public Sensor forwardButton; [Export] - public RJSensor backwardsButton; + public Sensor backwardsButton; [Export] - public RJSensor leftButton; + public Sensor leftButton; [Export] - public RJSensor rightButton; + public Sensor rightButton; [Export] - public RJSensor upButton; + public Sensor upButton; [Export] - public RJSensor downButton; + public Sensor downButton; [Export] public float moveSpeed = 1; diff --git a/Runtime/VirtualCameras/StrategyTopDownCamera.cs b/Runtime/VirtualCameras/StrategyTopDownCamera.cs index 2cdc755..ce98cf0 100644 --- a/Runtime/VirtualCameras/StrategyTopDownCamera.cs +++ b/Runtime/VirtualCameras/StrategyTopDownCamera.cs @@ -46,20 +46,20 @@ namespace Rokojori [Export] - public RJSensor moveUpButton; + public Sensor moveUpButton; [Export] - public RJSensor moveDownButton; + public Sensor moveDownButton; [Export] - public RJSensor moveRightButton; + public Sensor moveRightButton; [Export] - public RJSensor moveLeftButton; + public Sensor moveLeftButton; [Export] public float buttonMoveSpeed = 1f; [Export] - public RJSensor mouseMoveButton; + public Sensor mouseMoveButton; [Export] public float mouseMoveSpeed = 0.001f; @@ -82,13 +82,13 @@ namespace Rokojori [ExportCategory("Orbit")] [Export] - public RJSensor orbitRightButton; + public Sensor orbitRightButton; [Export] - public RJSensor orbitLeftButton; + public Sensor orbitLeftButton; [Export] - public RJSensor orbitMouseButton; + public Sensor orbitMouseButton; [Export] public float mouseOrbitSpeedScale = -0.5f; @@ -109,16 +109,16 @@ namespace Rokojori public float maxDistance = 200f; [Export] - public RJSensor zoomInButton; + public Sensor zoomInButton; [Export] - public RJSensor[] zoomInModifierButtons; + public Sensor[] zoomInModifierButtons; [Export] - public RJSensor zoomOutButton; + public Sensor zoomOutButton; [Export] - public RJSensor[] zoomOutModifierButtons; + public Sensor[] zoomOutModifierButtons; [Export] public float zoomSmoothingCoefficient = 0.1f; diff --git a/Runtime/VirtualCameras/ThirdPersonCamera.cs b/Runtime/VirtualCameras/ThirdPersonCamera.cs index 9af2f55..8fb6438 100644 --- a/Runtime/VirtualCameras/ThirdPersonCamera.cs +++ b/Runtime/VirtualCameras/ThirdPersonCamera.cs @@ -21,10 +21,10 @@ namespace Rokojori public float yawSpeed; [Export] - public RJSensor yawPositiveAxis; + public Sensor yawPositiveAxis; [Export] - public RJSensor yawNegativeAxis; + public Sensor yawNegativeAxis; [Export] @@ -41,10 +41,10 @@ namespace Rokojori public float pitchSpeed; [Export] - public RJSensor pitchPositiveAxis; + public Sensor pitchPositiveAxis; [Export] - public RJSensor pitchNegativeAxis; + public Sensor pitchNegativeAxis; [Export] public bool pitchIsRelative = false; diff --git a/Runtime/VirtualCameras/VirtualCamera3D.cs b/Runtime/VirtualCameras/VirtualCamera3D.cs index c6e7022..c84c517 100644 --- a/Runtime/VirtualCameras/VirtualCamera3D.cs +++ b/Runtime/VirtualCameras/VirtualCamera3D.cs @@ -10,22 +10,22 @@ namespace Rokojori { [Tool] [GlobalClass] - public partial class VirtualCamera3D:RJVirtualCamera3D + public partial class VirtualCamera3D:Node3D { [Export] public float fov = 60; - public override Vector3 GetCameraPosition() + public Vector3 GetCameraPosition() { return GlobalPosition; } - public override Quaternion GetCameraRotation() + public Quaternion GetCameraRotation() { return GlobalBasis.GetRotationQuaternion(); } - public override float GetCameraFOV() + public float GetCameraFOV() { return fov; } diff --git a/Runtime/VirtualCameras/VirtualCamera3DManager.cs b/Runtime/VirtualCameras/VirtualCamera3DManager.cs index e9afd90..5e2e8be 100644 --- a/Runtime/VirtualCameras/VirtualCamera3DManager.cs +++ b/Runtime/VirtualCameras/VirtualCamera3DManager.cs @@ -10,7 +10,7 @@ namespace Rokojori { [Tool] [GlobalClass] - public partial class VirtualCamera3DManager:RJVirtualCamera3DManager + public partial class VirtualCamera3DManager:NetworkNode { [Export] public Camera3D camera; @@ -30,7 +30,13 @@ namespace Rokojori LerpCameras( delta ); } - + + [Export] + public float CameraPrioritySmoothingCoefficient = 0.1f; + + [Export] + public float CameraPrioritySmoothingStepFPS = 120; + public float smoothStepDelta => 1f / CameraPrioritySmoothingStepFPS; public float safeSmoothing => Mathf.Max( 0, CameraPrioritySmoothingCoefficient ); @@ -52,8 +58,6 @@ namespace Rokojori { refreshSlots = false; _cameraSlots = Nodes.GetDirectChildren( this ); - - //RJLog.Log( "GRABBED SLOTs" , _cameraSlots.Count ); } var sumPriority = 0f; @@ -132,22 +136,22 @@ namespace Rokojori } - public override RJVirtualCamera3D GetCamera( int index ) + public VirtualCamera3D GetCamera( int index ) { return _cameraSlots[ index ].camera; } - public override int GetCameraIndex( RJVirtualCamera3D camera3D ) + public int GetCameraIndex( VirtualCamera3D camera3D ) { return _cameraSlots.FindIndex( c => c.camera == camera3D ); } - public override float GetCameraPriority( int index ) + public float GetCameraPriority( int index ) { return _cameraSlots[ index ].priority; } - public override void SetCameraPriority( int index, float priority ) + public void SetCameraPriority( int index, float priority ) { _cameraSlots[ index ].priority = priority; } diff --git a/Runtime/VirtualCameras/VirtualCamera3DSlot.cs b/Runtime/VirtualCameras/VirtualCamera3DSlot.cs index c1a0dc5..f743dda 100644 --- a/Runtime/VirtualCameras/VirtualCamera3DSlot.cs +++ b/Runtime/VirtualCameras/VirtualCamera3DSlot.cs @@ -11,10 +11,10 @@ namespace Rokojori [Tool] [Icon("res://addons/rokojori_action_library/Icons/VirtualCamera3DSlot.svg") ] [GlobalClass] - public partial class VirtualCamera3DSlot:RJAction + public partial class VirtualCamera3DSlot:Action { [Export] - public RJVirtualCamera3D camera; + public VirtualCamera3D camera; [Export] public float priority; @@ -99,7 +99,7 @@ namespace Rokojori return camera.GetCameraFOV() + cameraEffectRunner.fov; } - public override void _OnTrigger() + protected override void _OnTrigger() { var vm = GetParent();