diff --git a/Runtime/Actions/Audio/PlayMusic.cs b/Runtime/Actions/Audio/PlayMusic.cs index 0e76e0a..b0501d2 100644 --- a/Runtime/Actions/Audio/PlayMusic.cs +++ b/Runtime/Actions/Audio/PlayMusic.cs @@ -17,7 +17,7 @@ namespace Rokojori { if ( stopSiblingPlayers ) { - GetParent().ForEachDirectChild( + music.GetParent().ForEachDirectChild( ( p )=> { if ( p == music ) diff --git a/Runtime/Actions/Audio/TweenMusicVolume.cs b/Runtime/Actions/Audio/TweenMusicVolume.cs new file mode 100644 index 0000000..21b56ce --- /dev/null +++ b/Runtime/Actions/Audio/TweenMusicVolume.cs @@ -0,0 +1,93 @@ + +using System; +using Godot; + + +namespace Rokojori +{ + [Tool] + [GlobalClass, Icon("res://addons/rokojori_action_library/Icons/Tween.svg")] + public partial class TweenMusicVolume:SequenceAction + { + [Export] + public AudioStreamPlayer target; + + [Export] + public float endVolume = 0; + + public enum VolumeUnit + { + Linear, + Decibel + } + + [Export] + public VolumeUnit volumeUnit = VolumeUnit.Linear; + + [Export] + public TweenType tweenType = new TweenTimeCurve(); + + [Export] + public bool cacheEndPositionOnStart = true; + + [Export] + public TimeLine timeLine; + + + protected override void _OnTrigger() + { + if ( target == null ) + { + return; + } + + var tl = TimeLineManager.Ensure( timeLine ); + + var start = tl.position; + + var fromVolume = target.VolumeDb; + var toVolume = volumeUnit == VolumeUnit.Linear ? MathAudio.AmplitudeToDecibels( endVolume ) : endVolume; + + var sequenceID = DispatchStart(); + + var tweenType = this.tweenType; + + if ( tweenType == null ) + { + tweenType = TweenTimeCurve.defaultCurve; + } + + TimeLineManager.ScheduleSpanIn( tl, 0, tweenType.GetTweenDuration(), + ( span, type )=> + { + if ( ! GodotObject.IsInstanceValid( target ) ) + { + DispatchEnd( sequenceID ); + return; + } + + var timeNow = tl.position; + var elapsed = timeNow - start; + + var state = tweenType.GetTweenPhaseForPhase( span.phase ); + + if ( ! cacheEndPositionOnStart ) + { + var toScale = volumeUnit == VolumeUnit.Linear ? MathAudio.AmplitudeToDecibels( endVolume ) : endVolume;; + } + + var lerpedVolume = Mathf.Lerp( fromVolume, toVolume, state ); + + target.VolumeDb = lerpedVolume; + + if ( type == TimeLineSpanUpdateType.End ) + { + DispatchEnd( sequenceID ); + } + }, + this + ); + } + + } +} \ No newline at end of file diff --git a/Runtime/Actions/Audio/TweenMusicVolume.cs.uid b/Runtime/Actions/Audio/TweenMusicVolume.cs.uid new file mode 100644 index 0000000..971359f --- /dev/null +++ b/Runtime/Actions/Audio/TweenMusicVolume.cs.uid @@ -0,0 +1 @@ +uid://d3w20fwa8jek0 diff --git a/Runtime/Actions/Visual/SetMaterial.cs b/Runtime/Actions/Visual/SetMaterial.cs index 4b474dc..ddf4661 100644 --- a/Runtime/Actions/Visual/SetMaterial.cs +++ b/Runtime/Actions/Visual/SetMaterial.cs @@ -20,15 +20,27 @@ namespace Rokojori [Export] public int index = 0; + + protected override void _OnTrigger() { - if ( target == null || material == null ) + if ( target == null ) { return; } var msc = MaterialSurfaceContainer.From( target, index ); - msc.SetMaterialInSlot( slot, material ); + + if ( material == null ) + { + msc.RemoveMaterialInSlot( slot ); + } + else + { + msc.SetMaterialInSlot( slot, material ); + } + + } } diff --git a/Runtime/Actions/Visual/TweenMaterial.cs b/Runtime/Actions/Visual/TweenMaterial.cs index 78b8b11..932d89f 100644 --- a/Runtime/Actions/Visual/TweenMaterial.cs +++ b/Runtime/Actions/Visual/TweenMaterial.cs @@ -188,7 +188,8 @@ namespace Rokojori DispatchEnd( sequenceID ); } - } + }, + this ); diff --git a/Runtime/Actions/Visual/TweenPosition.cs b/Runtime/Actions/Visual/TweenPosition.cs index 87c4438..8b9f6ce 100644 --- a/Runtime/Actions/Visual/TweenPosition.cs +++ b/Runtime/Actions/Visual/TweenPosition.cs @@ -46,24 +46,12 @@ namespace Rokojori { var toPosition = endOffset; - if ( Mode.Global == positionSpace ) - { - if ( endPosition != null ) - { - toPosition += endPosition.GlobalPosition; - } - } - else + if ( endPosition == null ) { - - if ( endPosition != null ) - { - toPosition += endPosition.Position; - } - + return toPosition; } - return toPosition; + return endPosition.GetPosition( Mode.Global == positionSpace ); } @@ -125,7 +113,8 @@ namespace Rokojori { DispatchEnd( sequenceID ); } - } + }, + this ); } diff --git a/Runtime/Actions/Visual/TweenPostProcessVolume.cs b/Runtime/Actions/Visual/TweenPostProcessVolume.cs new file mode 100644 index 0000000..f4dfbad --- /dev/null +++ b/Runtime/Actions/Visual/TweenPostProcessVolume.cs @@ -0,0 +1,84 @@ + +using System; +using Godot; + + +namespace Rokojori +{ + [Tool] + [GlobalClass, Icon("res://addons/rokojori_action_library/Icons/Tween.svg")] + public partial class TweenPostProcessVolume:SequenceAction + { + [Export] + public PostProcessVolume activeVolume; + + [Export] + public float endWeight; + + [Export] + public TweenType tweenType = new TweenTimeCurve(); + + [Export] + public bool cacheEndPositionOnStart = true; + + [Export] + public TimeLine timeLine; + + + protected override void _OnTrigger() + { + if ( activeVolume == null ) + { + return; + } + + var tl = TimeLineManager.Ensure( timeLine ); + + var start = tl.position; + + var fromWeight = activeVolume.weight; + var toWeight = endWeight; + + var sequenceID = DispatchStart(); + + var tweenType = this.tweenType; + + if ( tweenType == null ) + { + tweenType = TweenTimeCurve.defaultCurve; + } + + TimeLineManager.ScheduleSpanIn( tl, 0, tweenType.GetTweenDuration(), + ( span, type )=> + { + if ( ! GodotObject.IsInstanceValid( activeVolume ) ) + { + DispatchEnd( sequenceID ); + return; + } + + var timeNow = tl.position; + var elapsed = timeNow - start; + + var state = tweenType.GetTweenPhaseForPhase( span.phase ); + + if ( ! cacheEndPositionOnStart ) + { + var toScale = endWeight; + } + + var lerpedWeight = Mathf.Lerp( fromWeight, toWeight, state ); + + activeVolume.weight = lerpedWeight; + + if ( type == TimeLineSpanUpdateType.End ) + { + DispatchEnd( sequenceID ); + } + }, + this + ); + } + + } +} \ No newline at end of file diff --git a/Runtime/Actions/Visual/TweenPostProcessVolume.cs.uid b/Runtime/Actions/Visual/TweenPostProcessVolume.cs.uid new file mode 100644 index 0000000..1304978 --- /dev/null +++ b/Runtime/Actions/Visual/TweenPostProcessVolume.cs.uid @@ -0,0 +1 @@ +uid://lvr8dcb01lwx diff --git a/Runtime/Animation/Highlight/HighlightEffect.cs b/Runtime/Animation/Highlight/HighlightEffect.cs index 02165b9..beee383 100644 --- a/Runtime/Animation/Highlight/HighlightEffect.cs +++ b/Runtime/Animation/Highlight/HighlightEffect.cs @@ -184,6 +184,11 @@ namespace Rokojori void StartHighlight( Node3D[] targets ) { + if ( targets == null ) + { + return; + } + var animation = _active.Find( a => Arrays.AreEntriesEqual( a.targets, targets ) ); targets.ForEach( @@ -227,8 +232,11 @@ namespace Rokojori } else if ( OutlineMaterialMode.Custom_Material == outlineMaterialMode ) { - material = (Material) outlineCustomMaterial.Duplicate(); - outlineCustomColorProperty.Set( material, colorTransparent ); + if ( outlineCustomMaterial != null ) + { + material = (Material) outlineCustomMaterial.Duplicate(); + outlineCustomColorProperty.Set( material, colorTransparent ); + } } @@ -243,12 +251,27 @@ namespace Rokojori } else if ( OverlayMaterialMode.Custom_Material == overlayMaterialMode ) { - var overlay = (Material) overlayCustomMaterial.Duplicate(); - overlayCustomColorProperty.Set( overlay, colorTransparent ); - material.NextPass = overlay; + if ( overlayCustomMaterial != null ) + { + var overlay = (Material) overlayCustomMaterial.Duplicate(); + overlayCustomColorProperty.Set( overlay, colorTransparent ); + + if ( material != null ) + { + material.NextPass = overlay; + } + else + { + material = overlay; + } + + } } - + if ( material == null ) + { + return; + } Arrays.ForEach( targets, t => @@ -320,7 +343,10 @@ namespace Rokojori } else if ( OutlineMaterialMode.Custom_Material == outlineMaterialMode ) { - outlineCustomColorProperty.Set( m, tweenColor); + if ( outlineCustomMaterial != null ) + { + outlineCustomColorProperty.Set( m, tweenColor); + } } if ( OverlayMaterialMode.Flat_Overlay == overlayMaterialMode ) @@ -331,8 +357,13 @@ namespace Rokojori } else if ( OutlineMaterialMode.Custom_Material == outlineMaterialMode ) { - var material = (OverlayMaterial) m.NextPass; - outlineCustomColorProperty.Set( m, tweenColor); + if ( overlayCustomMaterial != null ) + { + var material = (Material) ( + OutlineMaterialMode.Custom_Material == outlineMaterialMode && + outlineCustomMaterial == null ? m : m.NextPass + ); + } } @@ -412,7 +443,10 @@ namespace Rokojori } else if ( OutlineMaterialMode.Custom_Material == outlineMaterialMode ) { - outlineCustomColorProperty.Set( m, tweenColor ); + if ( outlineCustomMaterial != null ) + { + outlineCustomColorProperty.Set( m, tweenColor ); + } } if ( OverlayMaterialMode.Flat_Overlay == overlayMaterialMode ) @@ -423,8 +457,15 @@ namespace Rokojori } else if ( OutlineMaterialMode.Custom_Material == outlineMaterialMode ) { - var material = (OverlayMaterial) m.NextPass; - outlineCustomColorProperty.Set( m, tweenColor); + if ( overlayCustomMaterial != null ) + { + var material = (Material) ( + OutlineMaterialMode.Custom_Material == outlineMaterialMode && + outlineCustomMaterial == null ? m : m.NextPass + ); + + outlineCustomColorProperty.Set( m, tweenColor); + } } } diff --git a/Runtime/Animation/Highlight/Presets/Yellow Scan Outline - Highlight.tres b/Runtime/Animation/Highlight/Presets/Yellow Scan Outline - Highlight.tres index 1d2bf21..1a56d1a 100644 --- a/Runtime/Animation/Highlight/Presets/Yellow Scan Outline - Highlight.tres +++ b/Runtime/Animation/Highlight/Presets/Yellow Scan Outline - Highlight.tres @@ -7,9 +7,6 @@ [sub_resource type="Resource" id="Resource_27v41"] script = ExtResource("1_3edxo") color = Color(1, 0.9375, 0, 1) -colorMultiply = 1.0 -rgbMultiply = 1.0 -alphaMultiply = 1.0 [sub_resource type="Curve" id="Curve_vqio6"] _data = [Vector2(0, 0), 0.0, 1.0, 0, 1, Vector2(1, 1), 1.0, 0.0, 1, 0] @@ -28,8 +25,5 @@ outDuration = 0.167 outCurve = SubResource("Curve_4o1t0") color = SubResource("Resource_27v41") opacityModulationStrength = 0.75 -opacityModulationDuration = 0.5 -opacityModulationTransition = 1.0 outlineMaterialMode = 1 overlayOpacity = 0.01 -overlayMaterialMode = 0 diff --git a/Runtime/Audio/MathAudio.cs b/Runtime/Audio/MathAudio.cs index 4870f1e..8a76207 100644 --- a/Runtime/Audio/MathAudio.cs +++ b/Runtime/Audio/MathAudio.cs @@ -11,13 +11,24 @@ namespace Rokojori public static int ConcertA_Pitch = 69; public static float ConcertA_Frequency = 440.0f; + public static float amplitudeTreshold = -96f; + public static float AmplitudeToDecibels( float amplitude ) { + if ( amplitude <= 0.0 ) + { + return amplitudeTreshold; + } + return Mathf.Log(amplitude) * 20.0f / Mathf.Log(10.0f); } public static float DecibelsToAmplitude( float decibels ) { + if ( decibels < amplitudeTreshold ) + { + return 0; + } return Mathf.Pow(10.0f, decibels / 20.0f); } diff --git a/Runtime/Cameras/CameraTypes/ThirdPersonCamera/ThirdPersonCamera.cs b/Runtime/Cameras/CameraTypes/ThirdPersonCamera/ThirdPersonCamera.cs index 1440679..a125aa1 100644 --- a/Runtime/Cameras/CameraTypes/ThirdPersonCamera/ThirdPersonCamera.cs +++ b/Runtime/Cameras/CameraTypes/ThirdPersonCamera/ThirdPersonCamera.cs @@ -24,8 +24,6 @@ namespace Rokojori [Export] public ThirdPersonCameraSettings settings; - // [Export] - // public TimeLine timeLine; [Export] public CharacterController.CharacterUpdateMode updateMode = CharacterController.CharacterUpdateMode.Physics_Process; @@ -66,9 +64,14 @@ namespace Rokojori var targetPosition = Smoothing.Apply( settings.targetFollowSmoothing, target.GlobalPosition, delta ); + var yawAxis = 0f; + var pitchAxis = 0f; - var yawAxis = Sensors.PolarPowerAxis( data.yawNegativeAxis, data.yawPositiveAxis, 1f, data.yawDeadZone, data.yawPower ); - var pitchAxis = Sensors.PolarPowerAxis( data.pitchNegativeAxis, data.pitchPositiveAxis, 1f, data.pitchDeadZone, data.pitchPower ); + if ( inputEnabled ) + { + yawAxis = Sensors.PolarPowerAxis( data.yawNegativeAxis, data.yawPositiveAxis, 1f, data.yawDeadZone, data.yawPower ); + pitchAxis = Sensors.PolarPowerAxis( data.pitchNegativeAxis, data.pitchPositiveAxis, 1f, data.pitchDeadZone, data.pitchPower ); + } // this.LogInfo( "YAW:", yawAxis, "PITCH:", pitchAxis ); yaw += yawAxis * settings.yawSpeed * data.yawSpeed * delta; diff --git a/Runtime/Cameras/PostProcess/PostProcessVolumeEffect.cs b/Runtime/Cameras/PostProcess/PostProcessVolumeEffect.cs index 7b9c807..5c085bc 100644 --- a/Runtime/Cameras/PostProcess/PostProcessVolumeEffect.cs +++ b/Runtime/Cameras/PostProcess/PostProcessVolumeEffect.cs @@ -105,8 +105,10 @@ namespace Rokojori var value = floatValues[ j ].GetFloatValue(); - floatValues[ j ].SetFloatValue( value + otherValues[ j ].GetFloatValue() ); - valueWeights[ j ] += volumes[ i ].combinedWeight; + var weight = volumes[ i ].combinedWeight; + + floatValues[ j ].SetFloatValue( value + otherValues[ j ].GetFloatValue() * weight ); + valueWeights[ j ] += weight; // this.LogInfo( "Lerping", j, otherValues[ j ].value, valueWeights[ j ] ); @@ -210,9 +212,11 @@ namespace Rokojori } priorities[ j ] = volumes[ i ].priority; + + var weight = volumes[ i ].combinedWeight; - colorValues[ j ].value += otherValues[ j ].value; - valueWeights[ j ] += volumes[ i ].combinedWeight; + colorValues[ j ].value += otherValues[ j ].value * weight; + valueWeights[ j ] += weight; // this.LogInfo( "Lerping", j, otherValues[ j ].value, valueWeights[ j ] ); diff --git a/Runtime/Cameras/SetVirtualCameraInput.cs b/Runtime/Cameras/SetVirtualCameraInput.cs new file mode 100644 index 0000000..473f939 --- /dev/null +++ b/Runtime/Cameras/SetVirtualCameraInput.cs @@ -0,0 +1,27 @@ + +using System.Diagnostics; +using System.Collections; +using System.Collections.Generic; +using System; +using Godot; + + +namespace Rokojori +{ + [Tool] + [GlobalClass, Icon("res://addons/rokojori_action_library/Icons/VirtualCamera3D.svg") ] + public partial class SetVirtualCameraInput:Action + { + [Export] + public VirtualCamera camera; + + [Export] + public bool inputEnabled = true; + + protected override void _OnTrigger() + { + camera.inputEnabled = inputEnabled; + } + + } +} \ No newline at end of file diff --git a/Runtime/Cameras/SetVirtualCameraInput.cs.uid b/Runtime/Cameras/SetVirtualCameraInput.cs.uid new file mode 100644 index 0000000..1fa7203 --- /dev/null +++ b/Runtime/Cameras/SetVirtualCameraInput.cs.uid @@ -0,0 +1 @@ +uid://725qwxb6e5rr diff --git a/Runtime/Cameras/VirtualCamera.cs b/Runtime/Cameras/VirtualCamera.cs index 2131ba2..4798050 100644 --- a/Runtime/Cameras/VirtualCamera.cs +++ b/Runtime/Cameras/VirtualCamera.cs @@ -15,6 +15,9 @@ namespace Rokojori [Export] public float fov = 60; + [Export] + public bool inputEnabled = true; + public Vector3 GetCameraPosition() { return GlobalPosition; diff --git a/Runtime/Interactions/AreaCaster.cs b/Runtime/Interactions/AreaCaster.cs new file mode 100644 index 0000000..62d1781 --- /dev/null +++ b/Runtime/Interactions/AreaCaster.cs @@ -0,0 +1,137 @@ +using Godot; +using System.Collections; +using System.Collections.Generic; + +namespace Rokojori +{ + [Tool] + [GlobalClass] + public partial class AreaCaster:Caster, iNodeState + { + [Export] + public Area3D area; + + [Export] + public Action onCollisionsChanged; + + [Export] + public Action onCollisionEntered; + + [Export] + public Action onCollisionExited; + + + [ExportGroup( "Debugging")] + [Export] + public Node collider; + + [Export] + public bool printColliderNames = false; + + + + public override void _Ready() + { + if ( area == null ) + { + return; + } + + area.AreaEntered += TriggerOnEnter; + area.BodyEntered += TriggerOnEnter; + + area.AreaExited += _TriggerOnExited; + area.BodyExited += _TriggerOnExited; + } + + public void TriggerOnEnter( Node3D node3D ) + { + this.LogInfo( HierarchyName.Of( node3D ) ); + _TriggerOnEnter( node3D ); + } + + public void TriggerOnExited( Node3D node3D ) + { + this.LogInfo( HierarchyName.Of( node3D ) ); + _TriggerOnExited( node3D ); + } + + void _TriggerOnEnter( Node3D n ) + { + if ( n == null ) + { + return; + } + + if ( area != null && ! Math3D.IsValid( area.GlobalPosition ) ) + { + return; + } + + var selected = IsSelected( n ); + + if ( ! selected ) + { + // this.LogInfo( "Not selected", HierarchyName.Of( n ) ); + return; + } + + var collisionData = new CollisionData(); + collisionData.hasCollision = true; + collisionData.collider = n; + + collisionData.position = ( area.GlobalPosition + n.GlobalPosition ) / 2f; + collisionData.normal = ( n.GlobalPosition - area.GlobalPosition ).Normalized(); + + collisions.Add( collisionData ); + + numCollisions = collisions.Count; + + // this.LogInfo( "Selected", HierarchyName.Of( n ) ); + + SortCollisions(); + + onCollisionEntered?.Trigger(); + onCollisionsChanged?.Trigger(); + + } + + void _TriggerOnExited( Node n ) + { + if ( n == null ) + { + return; + } + + var insideIndex = collisions.FindIndex( c => c.collider == n ); + + if ( insideIndex == -1 ) + { + return; + } + + collisions.RemoveAt( insideIndex ); + + numCollisions = collisions.Count; + + SortCollisions(); + + onCollisionExited?.Trigger(); + onCollisionsChanged?.Trigger(); + + } + + public void OnNodeStateChanged() + { + if ( ! IsProcessing() || ! IsPhysicsProcessing() || Node.ProcessModeEnum.Disabled == this.ProcessMode ) + { + // this.LogInfo( "Clearing nodes" ); + collisions.Clear(); + numCollisions = 0; + } + } + + + + } +} \ No newline at end of file diff --git a/Runtime/Interactions/AreaCaster.cs.uid b/Runtime/Interactions/AreaCaster.cs.uid new file mode 100644 index 0000000..0b12f14 --- /dev/null +++ b/Runtime/Interactions/AreaCaster.cs.uid @@ -0,0 +1 @@ +uid://dc6o1arf1t2ci diff --git a/Runtime/Interactions/Caster.cs b/Runtime/Interactions/Caster.cs index b6fd37f..14d08c2 100644 --- a/Runtime/Interactions/Caster.cs +++ b/Runtime/Interactions/Caster.cs @@ -7,45 +7,110 @@ namespace Rokojori { [Tool] [GlobalClass] - public partial class Caster:Node3D + public abstract partial class Caster:Node3D { - [Export] - public Action beforeProcess; - - [Export] - public Action afterProcess; - [Export] public Selector includeSelector; [Export] public Selector excludeSelector; + + [Export] + public bool sortByPointerPriority; - - public virtual int NumColliders() + + public int NumColliders() { - return 0; + return collisions == null ? 0 : numCollisions; } - - public virtual Node GetCollider( int index ) + public Node GetCollider( int index ) { - return null; + return collisions[ index ].collider; } - - public virtual Vector3 GetCollisionPosition( int index ) + + public Vector3 GetCollisionNormal( int index ) { - return Vector3.Zero; + return collisions[ index ].normal; } - - public virtual Vector3 GetCollisionNormal( int index ) + + public Vector3 GetCollisionPosition( int index ) { - return Vector3.Zero; + return collisions[ index ].position; } - - public virtual Shape3D GetCollisionShape( int index ) + + public Shape3D GetCollisionShape( int index ) { - return null; + return collisions[ index ].shape; + } + + ValueSorter singleSorter; + MultiValueSorter multiSorter; + protected List collisions = new List(); + protected int numCollisions = 0; + + protected bool IsSelected( Node node ) + { + if ( includeSelector != null && ! includeSelector.Selects( node ) ) + { + return false; + } + + if ( excludeSelector != null && excludeSelector.Selects( node ) ) + { + return false; + } + + return true; + } + + protected bool IsSelected( CollisionData cd ) + { + return IsSelected( cd.collider ); + } + + protected void SortCollisions() + { + if ( ! sortByPointerPriority ) + { + if ( singleSorter == null ) + { + singleSorter = ValueSorter.Create( cd => GetDistance( cd ) ); + } + + singleSorter.Sort( 0, numCollisions, collisions ); + } + else + { + if ( multiSorter == null ) + { + multiSorter = MultiValueSorter.Create( + cd => GetPointablePriority( cd ), + cd => GetDistance( cd ) + ); + } + + multiSorter.Sort( 0, numCollisions, collisions ); + } + } + + protected float GetPointablePriority( CollisionData cd ) + { + float priority = 0; + + var pointable = Nodes.Find( cd.collider ); + + if ( pointable != null ) + { + priority = pointable.pointingPriority; + } + + return priority; + } + + protected float GetDistance( CollisionData cd ) + { + return ( cd.position - GlobalPosition ).Length(); } } diff --git a/Runtime/Interactions/Collider.cs b/Runtime/Interactions/Collider.cs index 3ec7e99..817cac1 100644 --- a/Runtime/Interactions/Collider.cs +++ b/Runtime/Interactions/Collider.cs @@ -48,8 +48,8 @@ namespace Rokojori area.AreaEntered += TriggerOnEnter; area.BodyEntered += TriggerOnEnter; - area.AreaExited += _TriggerOnExited; - area.BodyExited += _TriggerOnExited; + area.AreaExited += TriggerOnExited; + area.BodyExited += TriggerOnExited; } public void TriggerOnCollisionEnter( Projectile p, KinematicCollision3D collision ) diff --git a/Runtime/Interactions/MultiRayCaster.cs b/Runtime/Interactions/MultiRayCaster.cs index a4a7d73..d5d8cbd 100644 --- a/Runtime/Interactions/MultiRayCaster.cs +++ b/Runtime/Interactions/MultiRayCaster.cs @@ -21,50 +21,37 @@ namespace Rokojori [Export] public int maxHits = 3; - [Export] - public bool sortByPointerPriority; - List collisions = new List(); int numCollisions = 0; [Export] public Vector3 to; + [Export] + public UpdateMode updateMode = UpdateMode.Physics_Process; + + [Export] + public Action beforeProcess; + + [Export] + public Action afterProcess; + + + [ExportGroup( "Debugging")] [Export] public Node collider; [Export] - public UpdateMode updateMode = UpdateMode.Physics_Process; + public bool printColliderNames = false; + + - public override int NumColliders() - { - return collisions == null ? 0 : numCollisions; - } - public override Node GetCollider( int index ) - { - return collisions[ index ].collider; - } - - public override Vector3 GetCollisionNormal( int index ) - { - return collisions[ index ].normal; - } - - public override Vector3 GetCollisionPosition( int index ) - { - return collisions[ index ].position; - } - - public override Shape3D GetCollisionShape( int index ) - { - return collisions[ index ].shape; - } PhysicsRayQueryParameters3D rayParameters = new PhysicsRayQueryParameters3D(); - public override void _PhysicsProcess (double delta ) - { + public override void _PhysicsProcess( double delta ) + { if ( UpdateMode.Physics_Process != updateMode ) { return; @@ -106,15 +93,14 @@ namespace Rokojori { collider = nextCollider; - // this.LogInfo( "New Collider:", HierarchyName.Of( collider ) ); + if ( printColliderNames ) + { + this.LogInfo( "New Collider:", HierarchyName.Of( collider ) ); + } } Action.Trigger( afterProcess ); } - - ValueSorter singleSorter; - MultiValueSorter multiSorter; - CollisionData GetCollisionData( int i ) @@ -165,64 +151,7 @@ namespace Rokojori } } - bool IsSelected( CollisionData cd ) - { - if ( includeSelector != null && ! includeSelector.Selects( cd.collider ) ) - { - return false; - } - - if ( excludeSelector != null && excludeSelector.Selects( cd.collider ) ) - { - return false; - } - - return true; - } - - void SortCollisions() - { - if ( ! sortByPointerPriority ) - { - if ( singleSorter == null ) - { - singleSorter = ValueSorter.Create( cd => GetDistance( cd ) ); - } - - singleSorter.Sort( 0, numCollisions, collisions ); - } - else - { - if ( multiSorter == null ) - { - multiSorter = MultiValueSorter.Create( - cd => GetPointablePriority( cd ), - cd => GetDistance( cd ) - ); - } - - multiSorter.Sort( 0, numCollisions, collisions ); - } - } - - float GetPointablePriority( CollisionData cd ) - { - float priority = 0; - - var pointable = Nodes.Find( cd.collider ); - - if ( pointable != null ) - { - priority = pointable.pointingPriority; - } - - return priority; - } - - float GetDistance( CollisionData cd ) - { - return ( cd.position - GlobalPosition ).Length(); - } + } diff --git a/Runtime/Interactions/Pointer.cs b/Runtime/Interactions/Pointer.cs index 743f95f..3fcafc8 100644 --- a/Runtime/Interactions/Pointer.cs +++ b/Runtime/Interactions/Pointer.cs @@ -8,7 +8,7 @@ namespace Rokojori { [Tool] [GlobalClass,Icon("res://addons/rokojori_action_library/Icons/Pointer.svg")] - public partial class Pointer:Node3D + public partial class Pointer:Action { [Export] public Caster caster; @@ -27,7 +27,7 @@ namespace Rokojori [Export] public bool printPointables = false; - public override void _Process( double delta ) + protected override void _OnTrigger() { if ( caster == null ) { diff --git a/Runtime/Physics/Wind/WindManager.cs b/Runtime/Physics/Wind/WindManager.cs index cf81060..31fcec9 100644 --- a/Runtime/Physics/Wind/WindManager.cs +++ b/Runtime/Physics/Wind/WindManager.cs @@ -11,6 +11,17 @@ namespace Rokojori [Export] public WindManagerData data; + [Export] + public Action onWindChange; + + [Export] + public Action onWindDirectionChange; + + [Export] + public Action onWindSpeedChange; + + float _currentKMH = 0; + Vector2 _currentDirection = Vector2.Zero; public override void _Process( double delta ) { @@ -25,6 +36,29 @@ namespace Rokojori UpdatePosition( rm, (float) delta, data.globalWindPositionFarPropertyName, data.farMultiplier ); UpdateDirection( rm, (float) delta ); UpdateSpeed( rm, (float) delta ); + + var changed = false; + + if ( _currentKMH != data.windSpeed.GetKMH() ) + { + changed = true; + onWindSpeedChange?.Trigger(); + + _currentKMH = data.windSpeed.GetKMH(); + } + + if ( _currentDirection != data.windDirection ) + { + changed = true; + onWindDirectionChange?.Trigger(); + + _currentDirection = data.windDirection; + } + + if ( changed ) + { + onWindChange?.Trigger(); + } } diff --git a/Runtime/Physics/Wind/WindToGPUParticles.cs b/Runtime/Physics/Wind/WindToGPUParticles.cs new file mode 100644 index 0000000..cae34b2 --- /dev/null +++ b/Runtime/Physics/Wind/WindToGPUParticles.cs @@ -0,0 +1,65 @@ + +using Godot; + + +namespace Rokojori +{ + [Tool] + [GlobalClass, Icon("res://addons/rokojori_action_library/Icons/WindManager.svg") ] + public partial class WindToGPUParticles:Action + { + [Export] + public GpuParticles3D particles3D; + + [Export] + public float maxKMH = 100; + + [Export] + public float noWindRatio = 0.5f; + + [Export] + public Vector3 noWindDirection = Vector3.Zero; + + [Export] + public float windDirectionInfluence = 0.1f; + + [Export] + public float noWindSpread = 45; + + [Export] + public float windSpeedToSpread = 0.1f; + + [Export] + public Vector2 noWindInitialVelocity = new Vector2( 0,1 ); + + [Export] + public Vector2 windSpeedToVelocity = new Vector2( 5, 50); + + + protected override void _OnTrigger() + { + if ( particles3D == null ) + { + return; + } + + var processMaterial = (ParticleProcessMaterial) particles3D.ProcessMaterial; + + var wm = Unique.Get(); + + var speed = wm.data.windSpeed.GetKMH(); + var dir = wm.data.windDirection.To3DXZ(); + + particles3D.AmountRatio = Mathf.Lerp( noWindRatio, 1.0f, MathX.Clamp01( speed / maxKMH ) ); + + processMaterial.Direction = noWindDirection + speed * dir * windDirectionInfluence; + processMaterial.Spread = noWindSpread + speed * windSpeedToSpread; + + var velocity = noWindInitialVelocity + speed * windSpeedToVelocity; + processMaterial.InitialVelocityMin = velocity.X; + processMaterial.InitialVelocityMax = velocity.Y; + + + } + } +} \ No newline at end of file diff --git a/Runtime/Physics/Wind/WindToGPUParticles.cs.uid b/Runtime/Physics/Wind/WindToGPUParticles.cs.uid new file mode 100644 index 0000000..4db7b50 --- /dev/null +++ b/Runtime/Physics/Wind/WindToGPUParticles.cs.uid @@ -0,0 +1 @@ +uid://bs6kh8ey7kioq diff --git a/Runtime/Procedural/Mesh/MaterialSurfaceContainer.cs b/Runtime/Procedural/Mesh/MaterialSurfaceContainer.cs index fd50fbe..e2190c0 100644 --- a/Runtime/Procedural/Mesh/MaterialSurfaceContainer.cs +++ b/Runtime/Procedural/Mesh/MaterialSurfaceContainer.cs @@ -33,6 +33,7 @@ namespace Rokojori public abstract MaterialSlot GetActiveMaterialSlot(); public abstract T GetMaterialInSlot( MaterialSlot slot ) where T:Material; public abstract void SetMaterialInSlot( MaterialSlot slot, Material material ); + public abstract void RemoveMaterialInSlot( MaterialSlot slot ); public static Material GetActiveFrom( Node3D owner, int surfaceIndex = 0 ) { @@ -191,6 +192,33 @@ namespace Rokojori return material == null ? MaterialSlot.None : MaterialSlot.MeshSurface; } + public override void RemoveMaterialInSlot( MaterialSlot slot ) + { + if ( surfaceIndex == -1 || MaterialSlot.None == slot || node == null ) + { + return; + } + + Material material = null; + + if ( MaterialSlot.MeshSurface == slot ) + { + node.Mesh.SurfaceSetMaterial( surfaceIndex, material ); + } + else if ( MaterialSlot.MeshSurfaceOverride == slot ) + { + node.SetSurfaceOverrideMaterial( surfaceIndex, material ); + } + else if ( MaterialSlot.Override == slot ) + { + node.MaterialOverride = material; + } + else if ( MaterialSlot.Overlay == slot ) + { + node.MaterialOverlay = material; + } + } + public override void SetMaterialInSlot( MaterialSlot slot, Material material ) { if ( surfaceIndex == -1 || MaterialSlot.None == slot || material == null || node == null ) @@ -295,6 +323,29 @@ namespace Rokojori return material == null ? MaterialSlot.None : MaterialSlot.MeshSurface; } + public override void RemoveMaterialInSlot( MaterialSlot slot ) + { + if ( surfaceIndex == -1 || MaterialSlot.None == slot ) + { + return; + } + + Material material = null; + + if ( MaterialSlot.MeshSurface == slot ) + { + node.Multimesh.Mesh.SurfaceSetMaterial( surfaceIndex, material ); + } + else if ( MaterialSlot.Override == slot ) + { + node.MaterialOverride = material; + } + else if ( MaterialSlot.Overlay == slot ) + { + node.MaterialOverlay = material; + } + } + public override void SetMaterialInSlot( MaterialSlot slot, Material material ) { if ( surfaceIndex == -1 || MaterialSlot.None == slot ) diff --git a/Runtime/Rendering/RenderingManager.cs b/Runtime/Rendering/RenderingManager.cs index 39f46b6..18ff1e9 100644 --- a/Runtime/Rendering/RenderingManager.cs +++ b/Runtime/Rendering/RenderingManager.cs @@ -24,6 +24,14 @@ namespace Rokojori void EnsureGlobalShaderProperties() { + var globalProperties = RenderingServer.GlobalShaderParameterGetList(); + var map = new HashSet(); + + foreach ( var g in globalProperties ) + { + map.Add( g ); + } + for ( int i = 0; i < data.numGlobalShaderProperties; i++ ) { var p = data.GetGlobalShaderPropertyAt( i ); @@ -31,11 +39,12 @@ namespace Rokojori this.LogInfo( "Prop:", i ); - if ( p == null ) + if ( p == null || map.Contains( p.GetPropertyName().propertyName ) ) { continue; } + this.LogInfo( i, ">>", p.GetPropertyName().propertyName ); p.AddAsGlobalUniform(); diff --git a/Runtime/Shading/Properties/Properties/ShaderProperty.cs b/Runtime/Shading/Properties/Properties/ShaderProperty.cs index 1273121..04eb469 100644 --- a/Runtime/Shading/Properties/Properties/ShaderProperty.cs +++ b/Runtime/Shading/Properties/Properties/ShaderProperty.cs @@ -19,7 +19,8 @@ namespace Rokojori public abstract RenderingServer.GlobalShaderParameterType GetParameterType(); public void AddAsGlobalUniform() - { + { + RenderingServer.GlobalShaderParameterAdd( name, GetParameterType(), GetValue() ); } diff --git a/Runtime/UI/Actions/SetUIText.cs b/Runtime/UI/Actions/SetUIText.cs new file mode 100644 index 0000000..726d8fe --- /dev/null +++ b/Runtime/UI/Actions/SetUIText.cs @@ -0,0 +1,26 @@ + +using Godot; +using System; + +namespace Rokojori +{ + [Tool,GlobalClass] + public partial class SetUIText: Action + { + [Export] + public UIText uiText; + + [Export] + public LocaleText locale; + + protected override void _OnTrigger() + { + if ( uiText == null ) + { + return; + } + + uiText.locale = locale; + } + } +} \ No newline at end of file diff --git a/Runtime/UI/Actions/SetUIText.cs.uid b/Runtime/UI/Actions/SetUIText.cs.uid new file mode 100644 index 0000000..9c36811 --- /dev/null +++ b/Runtime/UI/Actions/SetUIText.cs.uid @@ -0,0 +1 @@ +uid://csomp5h8v5ajn diff --git a/Runtime/UI/Shaders/RoundedRectangle/RoundedRectangle.gdshader b/Runtime/UI/Shaders/RoundedRectangle/RoundedRectangle.gdshader index 0367441..3d5ddf4 100644 --- a/Runtime/UI/Shaders/RoundedRectangle/RoundedRectangle.gdshader +++ b/Runtime/UI/Shaders/RoundedRectangle/RoundedRectangle.gdshader @@ -118,7 +118,7 @@ void fragment() float anglefillState = angleFill( UV - vec2( 0.5 ), fillStateAngle, fillStateOffset ); - COLOR = vec4( outputColor.rgb * tex.rgb, outputColor.a * mask * opacity * tex.a * anglefillState); + COLOR *= vec4( outputColor.rgb * tex.rgb, outputColor.a * mask * opacity * tex.a * anglefillState); // Called for every pixel the material is visible on. }