From ca64fc6b3913db0adaa3c2df8f7f428ee3da89dd Mon Sep 17 00:00:00 2001 From: max Date: Wed, 11 Dec 2019 17:08:52 +0100 Subject: [PATCH 1/3] Added Calculation for TransitionSpeed to Timline Controller that updates every frame --- .../Qlist/scripts/TimelineController.cs | 37 +++++++++++++++++-- .../VisualEffectGraph/VFX Graph Plane.unity | 5 ++- .../CylMidiTransitionController.cs | 31 +++++++++------- .../StreamingAssets/pd/patch/analyzer.pd | 29 +++++++-------- 4 files changed, 67 insertions(+), 35 deletions(-) diff --git a/UnityProject/Assets/Scenes/Examples/Qlist/scripts/TimelineController.cs b/UnityProject/Assets/Scenes/Examples/Qlist/scripts/TimelineController.cs index c835f44..71dfa44 100644 --- a/UnityProject/Assets/Scenes/Examples/Qlist/scripts/TimelineController.cs +++ b/UnityProject/Assets/Scenes/Examples/Qlist/scripts/TimelineController.cs @@ -15,7 +15,11 @@ namespace cylvester private IList qlistMarkers_; private Boundary boundary_; private float speed_; - + private float transitionTargetRealtime_; + private float previousMarkerTime_; + private float nextMarkerTime_; + private float restTime_; + public void Start() { var timeline = (TimelineAsset)playableDirector.playableAsset; @@ -26,7 +30,7 @@ namespace cylvester playableDirector.time = 0; boundary_ = new Boundary(null, null); - UpdateSpeed(); + ResetSpeed(); } public void OnStateChanged(IStateReader stateManager) @@ -41,6 +45,8 @@ namespace cylvester playableDirector.time = qlistMarkers_[i].time; var previousMarkerTime = i > 0 ? (double?) qlistMarkers_[i - 1].time : null; var nextMarkerTime = i < numMarkers - 1 ? (double?) qlistMarkers_[i + 1].time : null; + previousMarkerTime_ = (float) previousMarkerTime; + nextMarkerTime_ = (float) nextMarkerTime; boundary_ = new Boundary(previousMarkerTime, nextMarkerTime); playableDirector.Play(); break; @@ -52,6 +58,15 @@ namespace cylvester if (playableDirector.state == PlayState.Paused) return; + if (!(Time.fixedUnscaledTime >= transitionTargetRealtime_)) // check o current time >= targetTime + { + speed_ = (CalculateTransitionSpeed(nextMarkerTime_));// berechne tnrsitionSpeed + + Debug.Log("Rest time: " + restTime_); + Debug.Log("Speed set to: " + speed_); + } + + var deltaTime = Time.deltaTime; var expectedTimeIncrement = speed_ * deltaTime; var expectedTimeInTimeline = playableDirector.time + expectedTimeIncrement; @@ -64,13 +79,27 @@ namespace cylvester else { playableDirector.Pause(); - UpdateSpeed(); + ResetSpeed(); + Debug.Log("Speed Reset to " + speed_); } } - private void UpdateSpeed() + private void ResetSpeed() { speed_ = initTransitionFactor; } + + + public void UpdateTransitionTargetRealTime(float restTime) + { + transitionTargetRealtime_ = Time.fixedUnscaledTime + restTime; + restTime_ = restTime; + } + + private float CalculateTransitionSpeed(float targetMarkerTime) + { + var transitionSpeed = (targetMarkerTime - playableDirector.time) / (transitionTargetRealtime_ - Time.fixedUnscaledTime); + return (float) transitionSpeed; + } } } diff --git a/UnityProject/Assets/Scenes/Examples/VisualEffectGraph/VFX Graph Plane.unity b/UnityProject/Assets/Scenes/Examples/VisualEffectGraph/VFX Graph Plane.unity index cc4a065..f3bb1ca 100644 --- a/UnityProject/Assets/Scenes/Examples/VisualEffectGraph/VFX Graph Plane.unity +++ b/UnityProject/Assets/Scenes/Examples/VisualEffectGraph/VFX Graph Plane.unity @@ -38,7 +38,7 @@ RenderSettings: m_ReflectionIntensity: 1 m_CustomReflection: {fileID: 0} m_Sun: {fileID: 0} - m_IndirectSpecularColor: {r: 0.0013490503, g: 0.0011814049, b: 0.0008122615, a: 1} + m_IndirectSpecularColor: {r: 0.0013421604, g: 0.0011744275, b: 0.0008066663, a: 1} m_UseRadianceAmbientProbe: 0 --- !u!157 &3 LightmapSettings: @@ -193,9 +193,10 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: playableDirector: {fileID: 65620552} + timelineController: {fileID: 65620555} channel: 3 stateManager: {fileID: 850208555} - instaTransitionSpeed: 10 + instaTransitionSpeed: 1 --- !u!114 &65620555 MonoBehaviour: m_ObjectHideFlags: 0 diff --git a/UnityProject/Assets/Scripts/PdConnection/CylMidiTransitionController.cs b/UnityProject/Assets/Scripts/PdConnection/CylMidiTransitionController.cs index 56f8a7c..4c896d1 100644 --- a/UnityProject/Assets/Scripts/PdConnection/CylMidiTransitionController.cs +++ b/UnityProject/Assets/Scripts/PdConnection/CylMidiTransitionController.cs @@ -16,6 +16,7 @@ namespace cylvester } [SerializeField] private PlayableDirector playableDirector; + [SerializeField] private TimelineController timelineController; [SerializeField, Range(1, 16)] private int channel = 1; [SerializeField] private StateManager stateManager; [SerializeField] private float instaTransitionSpeed = 10; @@ -68,42 +69,44 @@ namespace cylvester } case CylCommand.FourBarLoopButton: { - var restTime = UpdateRestTime(FourBarTrigger - currentTick_ % FourBarTrigger); + var restTime = CalculateRestTime(FourBarTrigger - currentTick_ % FourBarTrigger); if (nextSelectedScene_ > currentSelectedScene_) { - UpdateTimelinePlaybackSpeed(1f, restTime); + timelineController.UpdateTransitionTargetRealTime(restTime); stateManager.SelectedState = nextSelectedScene_; } else { - UpdateTimelinePlaybackSpeed(-1f, restTime); - stateManager.SelectedState = nextSelectedScene_ + 2; + timelineController.UpdateTransitionTargetRealTime(-restTime); + stateManager.SelectedState = nextSelectedScene_ + 1; } break; } case CylCommand.OneBarLoopButton: { - var restTime = UpdateRestTime(OneBarTrigger - currentTick_ % OneBarTrigger); - UpdateTimelinePlaybackSpeed(1f, restTime); - stateManager.SelectedState = nextSelectedScene_; + var restTime = CalculateRestTime(OneBarTrigger - currentTick_ % OneBarTrigger); + if (nextSelectedScene_ > currentSelectedScene_) + { + timelineController.UpdateTransitionTargetRealTime(restTime); + stateManager.SelectedState = nextSelectedScene_; + } + else + { + timelineController.UpdateTransitionTargetRealTime(-restTime); + stateManager.SelectedState = nextSelectedScene_ + 1; + } break; } default: throw new Exception("Unexpected CYL command"); - } } - private float UpdateRestTime(int restTicks) + private float CalculateRestTime(int restTicks) { return restTicks / 24f / stateManager.CurrentState.Bpm * 60f; } - private void UpdateTimelinePlaybackSpeed(float speed, float restTime) - { - var timelinePlaybackSpeed = TransitionLength / Mathf.Clamp(restTime, 0.001f, TransitionLength); - playableDirector.playableGraph.GetRootPlayable(0).SetSpeed(timelinePlaybackSpeed * speed); - } } } \ No newline at end of file diff --git a/UnityProject/Assets/StreamingAssets/pd/patch/analyzer.pd b/UnityProject/Assets/StreamingAssets/pd/patch/analyzer.pd index d3b8864..f3d7fbf 100644 --- a/UnityProject/Assets/StreamingAssets/pd/patch/analyzer.pd +++ b/UnityProject/Assets/StreamingAssets/pd/patch/analyzer.pd @@ -1,4 +1,4 @@ -#N canvas 179 93 1690 536 10; +#N canvas -3090 415 1690 536 10; #X declare -lib timbreID/timbreIDLib; #X obj 484 442 adc~ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16; #X obj 414 483 dac~, f 6; @@ -290,8 +290,8 @@ Roses_Front.wav \; TimbreID_Test.wav \;; #X text 416 223 176... control channel 1; #X obj 6 194 midirealtimein; #X obj 242 41 netreceive -u 54345; -#X obj 598 90 cnv 15 500 60 empty current Forces 20 12 0 45 -204786 --66577 0; +#X obj 598 90 cnv 15 500 60 empty current PositionCloud 20 12 0 45 +-204786 -66577 0; #X obj 786 234 bng 50 250 50 0 empty empty next 15 25 0 10 -204786 -1 -1; #X obj 596 227 bng 50 250 50 0 empty empty rewind 7 25 0 10 -261234 @@ -302,10 +302,10 @@ Roses_Front.wav \; TimbreID_Test.wav \;; -1 -1; #X msg 692 303 send 176 127 1; #X msg 791 304 send 176 127 2; -#X obj 594 46 cnv 12 500 30 empty previous PositionCloud 20 12 0 25 --262130 -66577 0; -#X obj 596 152 cnv 12 500 30 empty next ShowAll 20 12 0 25 -262130 +#X obj 594 46 cnv 12 500 30 empty previous PontCloud 20 12 0 25 -262130 -66577 0; +#X obj 596 152 cnv 12 500 30 empty next Forces 20 12 0 25 -262130 -66577 +0; #X obj 879 467 declare -lib timbreID/timbreIDLib; #N canvas 28 541 1273 735 timbreID_example 0; #X obj 77 657 nbx 3 28 -1e+037 1e+037 0 0 empty empty empty 0 -8 0 @@ -420,7 +420,6 @@ samples/kick.wav kick \, read -resize samples/closed.wav closed; #X connect 5 0 4 0; #X connect 6 0 7 0; #X restore 405 71 pd shmem; -#X text 701 378 <--- this is only for reference; #X obj 1167 19 cnv 15 400 500 empty empty CYL_Transition_Sim 20 12 0 14 -204800 -66577 0; #X obj 1383 196 bng 15 250 50 0 4bar_trig_sim empty 4_Bar_trigger_Sim @@ -594,13 +593,13 @@ samples/kick.wav kick \, read -resize samples/closed.wav closed; #X floatatom 1472 98 5 0 0 1 BPM - midi_sim_tempo; #X text 1374 100 Clock Sim.:; #X obj 1451 98 tgl 15 0 clock_sim_start_stop empty empty 17 7 0 10 --204786 -1 -1 0 1; +-204786 -1 -1 1 1; #X text 1198 40 Simulate the Press of a 1_Bar or 4_Bar Transition trigger. ; #N canvas 0 50 1167 867 Midi_Clock_Sim 0; #X obj 21 155 outlet; #X obj 155 14 tgl 15 0 empty clock_sim_start_stop mock 17 7 0 10 -262144 --1 -1 0 1; +-1 -1 1 1; #X msg 110 128 248, f 4; #X text 29 -56 MIDI Clock Simulator; #X text 8 10 start; @@ -885,10 +884,10 @@ samples/kick.wav kick \, read -resize samples/closed.wav closed; #X connect 30 0 11 0; #X connect 31 0 11 0; #X connect 36 0 11 0; -#X connect 42 0 43 0; -#X connect 43 0 54 0; -#X connect 44 0 74 0; -#X connect 58 0 44 0; -#X connect 58 0 63 0; -#X connect 64 0 11 0; +#X connect 41 0 42 0; +#X connect 42 0 53 0; +#X connect 43 0 73 0; +#X connect 57 0 43 0; +#X connect 57 0 62 0; +#X connect 63 0 11 0; #X coords 0 0 2 2 0 0 0; From 33d2cc5444aece7f28ddc3d0c9cd9f10ebab3c48 Mon Sep 17 00:00:00 2001 From: max Date: Thu, 12 Dec 2019 12:17:54 +0100 Subject: [PATCH 2/3] Update to TimelineController for CYLControl --- .../Qlist/scripts/TimelineController.cs | 44 ++++++++++++++----- .../CylMidiTransitionController.cs | 10 ++--- 2 files changed, 37 insertions(+), 17 deletions(-) diff --git a/UnityProject/Assets/Scenes/Examples/Qlist/scripts/TimelineController.cs b/UnityProject/Assets/Scenes/Examples/Qlist/scripts/TimelineController.cs index 71dfa44..eaa160a 100644 --- a/UnityProject/Assets/Scenes/Examples/Qlist/scripts/TimelineController.cs +++ b/UnityProject/Assets/Scenes/Examples/Qlist/scripts/TimelineController.cs @@ -18,7 +18,7 @@ namespace cylvester private float transitionTargetRealtime_; private float previousMarkerTime_; private float nextMarkerTime_; - private float restTime_; + private bool transitionDirectionReverse_; public void Start() { @@ -43,8 +43,8 @@ namespace cylvester continue; playableDirector.time = qlistMarkers_[i].time; - var previousMarkerTime = i > 0 ? (double?) qlistMarkers_[i - 1].time : null; - var nextMarkerTime = i < numMarkers - 1 ? (double?) qlistMarkers_[i + 1].time : null; + var previousMarkerTime = i > 0 ? (double?) qlistMarkers_[i - 1].time : 0; + var nextMarkerTime = i < numMarkers - 1 ? (double?) qlistMarkers_[i + 1].time : qlistMarkers_[numMarkers - 1].time; previousMarkerTime_ = (float) previousMarkerTime; nextMarkerTime_ = (float) nextMarkerTime; boundary_ = new Boundary(previousMarkerTime, nextMarkerTime); @@ -58,29 +58,43 @@ namespace cylvester if (playableDirector.state == PlayState.Paused) return; - if (!(Time.fixedUnscaledTime >= transitionTargetRealtime_)) // check o current time >= targetTime + if (!(Time.fixedUnscaledTime >= transitionTargetRealtime_)) // check if Transition has not finished yet { - speed_ = (CalculateTransitionSpeed(nextMarkerTime_));// berechne tnrsitionSpeed + if (!transitionDirectionReverse_) // if transition direction forward, speed becomes positive + { + speed_ = CalculateTransitionSpeed(nextMarkerTime_); + } - Debug.Log("Rest time: " + restTime_); - Debug.Log("Speed set to: " + speed_); + else // if transition direction backward, speed becomes negative + { + speed_ = CalculateTransitionSpeed(previousMarkerTime_); + } } - var deltaTime = Time.deltaTime; var expectedTimeIncrement = speed_ * deltaTime; var expectedTimeInTimeline = playableDirector.time + expectedTimeIncrement; - if (boundary_.IsInside(expectedTimeInTimeline)) + if (boundary_.IsInside(expectedTimeInTimeline)) // check if we are in between next and previous marker { playableDirector.time = expectedTimeInTimeline; playableDirector.Evaluate(); } else { + //sets playhead precisly to marker position at the end of transition. + if (!transitionDirectionReverse_) + { + playableDirector.time = nextMarkerTime_; + } + + else + { + playableDirector.time = previousMarkerTime_; + } + playableDirector.Pause(); ResetSpeed(); - Debug.Log("Speed Reset to " + speed_); } } @@ -90,10 +104,10 @@ namespace cylvester } - public void UpdateTransitionTargetRealTime(float restTime) + public void UpdateTransitionTargetRealTime(float restTime, bool reverse) { + transitionDirectionReverse_ = reverse; transitionTargetRealtime_ = Time.fixedUnscaledTime + restTime; - restTime_ = restTime; } private float CalculateTransitionSpeed(float targetMarkerTime) @@ -103,3 +117,9 @@ namespace cylvester } } } +/* + if (reverse_ == true) + { + speed_ = speed_* -1; + } + */ \ No newline at end of file diff --git a/UnityProject/Assets/Scripts/PdConnection/CylMidiTransitionController.cs b/UnityProject/Assets/Scripts/PdConnection/CylMidiTransitionController.cs index 4c896d1..3656bce 100644 --- a/UnityProject/Assets/Scripts/PdConnection/CylMidiTransitionController.cs +++ b/UnityProject/Assets/Scripts/PdConnection/CylMidiTransitionController.cs @@ -72,12 +72,12 @@ namespace cylvester var restTime = CalculateRestTime(FourBarTrigger - currentTick_ % FourBarTrigger); if (nextSelectedScene_ > currentSelectedScene_) { - timelineController.UpdateTransitionTargetRealTime(restTime); + timelineController.UpdateTransitionTargetRealTime(restTime, false); stateManager.SelectedState = nextSelectedScene_; } else { - timelineController.UpdateTransitionTargetRealTime(-restTime); + timelineController.UpdateTransitionTargetRealTime(restTime, true); stateManager.SelectedState = nextSelectedScene_ + 1; } @@ -88,14 +88,14 @@ namespace cylvester var restTime = CalculateRestTime(OneBarTrigger - currentTick_ % OneBarTrigger); if (nextSelectedScene_ > currentSelectedScene_) { - timelineController.UpdateTransitionTargetRealTime(restTime); + timelineController.UpdateTransitionTargetRealTime(restTime, false); stateManager.SelectedState = nextSelectedScene_; } else { - timelineController.UpdateTransitionTargetRealTime(-restTime); + timelineController.UpdateTransitionTargetRealTime(restTime, true); stateManager.SelectedState = nextSelectedScene_ + 1; - } + } break; } default: From 45db9bc4a1c9ce9034b64ad084a0de0a8b7c3b76 Mon Sep 17 00:00:00 2001 From: max Date: Wed, 8 Jan 2020 16:59:22 +0100 Subject: [PATCH 3/3] Updated CYL_Controlller with Philip --- UnityProject/Assets/Polybrush Data.meta | 8 ++ .../Assets/Polybrush Data/Brush Settings.meta | 8 ++ .../Scenes/Examples/Max Silly Demos.meta | 8 ++ .../Examples/Max Silly Demos/3DModels.meta | 8 ++ .../Qlist/scripts/TimelineController.cs | 103 ++++++++++++++---- .../VisualEffectGraph/VFX Graph Plane.unity | 3 +- .../CylMidiTransitionController.cs | 97 +++++++++-------- .../Scripts/StateManagement/StateManager.cs | 14 ++- 8 files changed, 176 insertions(+), 73 deletions(-) create mode 100644 UnityProject/Assets/Polybrush Data.meta create mode 100644 UnityProject/Assets/Polybrush Data/Brush Settings.meta create mode 100644 UnityProject/Assets/Scenes/Examples/Max Silly Demos.meta create mode 100644 UnityProject/Assets/Scenes/Examples/Max Silly Demos/3DModels.meta diff --git a/UnityProject/Assets/Polybrush Data.meta b/UnityProject/Assets/Polybrush Data.meta new file mode 100644 index 0000000..aaf7892 --- /dev/null +++ b/UnityProject/Assets/Polybrush Data.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d2ffacbc3f26ffe4e94f873800ce870c +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Polybrush Data/Brush Settings.meta b/UnityProject/Assets/Polybrush Data/Brush Settings.meta new file mode 100644 index 0000000..056f68c --- /dev/null +++ b/UnityProject/Assets/Polybrush Data/Brush Settings.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 724a7fa50d05ebc4d8456c54a1e92bcd +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Scenes/Examples/Max Silly Demos.meta b/UnityProject/Assets/Scenes/Examples/Max Silly Demos.meta new file mode 100644 index 0000000..9e151aa --- /dev/null +++ b/UnityProject/Assets/Scenes/Examples/Max Silly Demos.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 35edaba459ee497418ef7f2da8e4f25f +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Scenes/Examples/Max Silly Demos/3DModels.meta b/UnityProject/Assets/Scenes/Examples/Max Silly Demos/3DModels.meta new file mode 100644 index 0000000..e3e3dec --- /dev/null +++ b/UnityProject/Assets/Scenes/Examples/Max Silly Demos/3DModels.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 244cf462d93bf8d42a242c3f6d43f66f +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Scenes/Examples/Qlist/scripts/TimelineController.cs b/UnityProject/Assets/Scenes/Examples/Qlist/scripts/TimelineController.cs index eaa160a..b6152a8 100644 --- a/UnityProject/Assets/Scenes/Examples/Qlist/scripts/TimelineController.cs +++ b/UnityProject/Assets/Scenes/Examples/Qlist/scripts/TimelineController.cs @@ -8,20 +8,24 @@ namespace cylvester public class TimelineController : MonoBehaviour { [SerializeField] private PlayableDirector playableDirector; - [SerializeField] private StateManager stateManager; + //[SerializeField] private StateManager stateManager; + [SerializeField] private float initTransitionFactor = 1f; - + private IList qlistMarkers_; private Boundary boundary_; private float speed_; private float transitionTargetRealtime_; - private float previousMarkerTime_; - private float nextMarkerTime_; + private float previousMarkerTime_; //marker at which transition ends (if reversed) + private float nextMarkerTime_; //marker at which transition ends (if forward) private bool transitionDirectionReverse_; + private bool instantTriggerMode; + + private string lastStateName = ""; public void Start() - { + { var timeline = (TimelineAsset)playableDirector.playableAsset; var markers = timeline.markerTrack.GetMarkers(); qlistMarkers_ = new List(); @@ -32,42 +36,64 @@ namespace cylvester boundary_ = new Boundary(null, null); ResetSpeed(); } - + public void OnStateChanged(IStateReader stateManager) { var stateName = stateManager.CurrentState.Title; + lastStateName = stateName; var numMarkers = qlistMarkers_.Count; for (var i = 0; i < numMarkers; ++i) { - if (qlistMarkers_[i].id != stateName) + if (qlistMarkers_[i].id != stateName) continue; - + playableDirector.time = qlistMarkers_[i].time; - var previousMarkerTime = i > 0 ? (double?) qlistMarkers_[i - 1].time : 0; - var nextMarkerTime = i < numMarkers - 1 ? (double?) qlistMarkers_[i + 1].time : qlistMarkers_[numMarkers - 1].time; - previousMarkerTime_ = (float) previousMarkerTime; - nextMarkerTime_ = (float) nextMarkerTime; + var previousMarkerTime = i > 0 ? (double?)qlistMarkers_[i - 1].time : 0; + var nextMarkerTime = i < numMarkers - 1 ? (double?)qlistMarkers_[i + 1].time : qlistMarkers_[numMarkers - 1].time; + previousMarkerTime_ = (float)previousMarkerTime; + nextMarkerTime_ = (float)nextMarkerTime; boundary_ = new Boundary(previousMarkerTime, nextMarkerTime); playableDirector.Play(); + Debug.Log("prev=" + (i - 1) + " next=" + (i + 1)); break; } } + public double getStartMarkerTime() //Return time of marker where the current running animation started + { + var numMarkers = qlistMarkers_.Count; + for (var i = 0; i < numMarkers; ++i) + { + if (qlistMarkers_[i].id != lastStateName) + continue; + return qlistMarkers_[i].time; + } + return 0; + } + private void Update() { + if (playableDirector.state == PlayState.Paused) return; + if (!(Time.fixedUnscaledTime >= transitionTargetRealtime_)) // check if Transition has not finished yet { if (!transitionDirectionReverse_) // if transition direction forward, speed becomes positive { - speed_ = CalculateTransitionSpeed(nextMarkerTime_); + if (!instantTriggerMode) + { + speed_ = CalculateTransitionSpeed(nextMarkerTime_); + } } else // if transition direction backward, speed becomes negative { - speed_ = CalculateTransitionSpeed(previousMarkerTime_); + if (!instantTriggerMode) + { + speed_ = CalculateTransitionSpeed(previousMarkerTime_); + } } } @@ -83,12 +109,11 @@ namespace cylvester else { //sets playhead precisly to marker position at the end of transition. - if (!transitionDirectionReverse_) + if (!transitionDirectionReverse_) //forward { playableDirector.time = nextMarkerTime_; } - - else + else //backward { playableDirector.time = previousMarkerTime_; } @@ -104,8 +129,11 @@ namespace cylvester } + + public void UpdateTransitionTargetRealTime(float restTime, bool reverse) { + instantTriggerMode = false; //update speed continuous transitionDirectionReverse_ = reverse; transitionTargetRealtime_ = Time.fixedUnscaledTime + restTime; } @@ -113,13 +141,40 @@ namespace cylvester private float CalculateTransitionSpeed(float targetMarkerTime) { var transitionSpeed = (targetMarkerTime - playableDirector.time) / (transitionTargetRealtime_ - Time.fixedUnscaledTime); - return (float) transitionSpeed; + return (float)transitionSpeed; + } + + public bool animationPaused() + { + return playableDirector.state == PlayState.Paused; + } + + public void abortAnimation() + { + if (animationPaused()) //safe check + { + return; + } + if (!transitionDirectionReverse_) //forward + { + transitionDirectionReverse_ = !transitionDirectionReverse_; //invert direction + previousMarkerTime_ = (float)getStartMarkerTime(); + } + else //backward + { + transitionDirectionReverse_ = !transitionDirectionReverse_; //invert direction + nextMarkerTime_ = (float)getStartMarkerTime(); + } + boundary_ = new Boundary(previousMarkerTime_, nextMarkerTime_); //Update Boundary to stop animation when target reached + } + + public void instantTrigger(float speed) + { + speed_ = speed; + instantTriggerMode = true; //keep speed_ constant + transitionDirectionReverse_ = speed < 0; + playableDirector.Play(); } } } -/* - if (reverse_ == true) - { - speed_ = speed_* -1; - } - */ \ No newline at end of file + \ No newline at end of file diff --git a/UnityProject/Assets/Scenes/Examples/VisualEffectGraph/VFX Graph Plane.unity b/UnityProject/Assets/Scenes/Examples/VisualEffectGraph/VFX Graph Plane.unity index f3bb1ca..da8b2d5 100644 --- a/UnityProject/Assets/Scenes/Examples/VisualEffectGraph/VFX Graph Plane.unity +++ b/UnityProject/Assets/Scenes/Examples/VisualEffectGraph/VFX Graph Plane.unity @@ -196,7 +196,7 @@ MonoBehaviour: timelineController: {fileID: 65620555} channel: 3 stateManager: {fileID: 850208555} - instaTransitionSpeed: 1 + instaTransitionSpeed: 10 --- !u!114 &65620555 MonoBehaviour: m_ObjectHideFlags: 0 @@ -210,7 +210,6 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: playableDirector: {fileID: 65620552} - stateManager: {fileID: 850208555} initTransitionFactor: 8 --- !u!1 &155821760 GameObject: diff --git a/UnityProject/Assets/Scripts/PdConnection/CylMidiTransitionController.cs b/UnityProject/Assets/Scripts/PdConnection/CylMidiTransitionController.cs index 3656bce..fc6bcbf 100644 --- a/UnityProject/Assets/Scripts/PdConnection/CylMidiTransitionController.cs +++ b/UnityProject/Assets/Scripts/PdConnection/CylMidiTransitionController.cs @@ -7,14 +7,14 @@ namespace cylvester public class CylMidiTransitionController : MonoBehaviour { private enum CylCommand - { + { OneBarLoopButton = 94, FourBarLoopButton = 86, - NextSelectedScene = 18, - CurrentSelectedScene = 17, + NextSelectedTransition = 18, + CurrentSelectedAnimation = 17, InstantTrigger = 2, } - + [SerializeField] private PlayableDirector playableDirector; [SerializeField] private TimelineController timelineController; [SerializeField, Range(1, 16)] private int channel = 1; @@ -23,22 +23,26 @@ namespace cylvester private const int OneBarTrigger = 96; private const int FourBarTrigger = OneBarTrigger * 4; - private const float TransitionLength = 16; - + private const float TransitionLength = 16; + private ScheduledAction scheduledAction_; private int currentTick_; - private int currentSelectedScene_ ; - private int nextSelectedScene_; + private int currentSelectedAnimation_; + private int nextSelectedMarker_; private void Start() { scheduledAction_ = new ScheduledAction(() => { - stateManager.SelectedState = currentSelectedScene_; - playableDirector.playableGraph.GetRootPlayable(0).SetSpeed(instaTransitionSpeed); + stateManager.SelectedState = currentSelectedAnimation_; + //playableDirector.playableGraph.GetRootPlayable(0).SetSpeed(instaTransitionSpeed); + timelineController.instantTrigger(instaTransitionSpeed); }); + + currentSelectedAnimation_ = 0; + nextSelectedMarker_ = 1; } - + public void OnSyncReceived(MidiSync midiSync, int counter) { currentTick_ = counter; @@ -51,54 +55,55 @@ namespace cylvester var command = (CylCommand)mes.Data1; switch (command) { - case CylCommand.NextSelectedScene: - { - nextSelectedScene_ = mes.Data2; + case CylCommand.NextSelectedTransition: + + nextSelectedMarker_ = mes.Data2; //next marker only used for direction + Debug.Log("command nextSelectedMarker_=" + nextSelectedMarker_); break; - } + case CylCommand.InstantTrigger: - { + scheduledAction_.Ready(); break; - } - case CylCommand.CurrentSelectedScene: - { - currentSelectedScene_ = mes.Data2; + + case CylCommand.CurrentSelectedAnimation: + + currentSelectedAnimation_ = mes.Data2; + Debug.Log("command currentSelectedAnimation_=" + currentSelectedAnimation_); scheduledAction_.Go(); break; - } - case CylCommand.FourBarLoopButton: - { - var restTime = CalculateRestTime(FourBarTrigger - currentTick_ % FourBarTrigger); - if (nextSelectedScene_ > currentSelectedScene_) - { - timelineController.UpdateTransitionTargetRealTime(restTime, false); - stateManager.SelectedState = nextSelectedScene_; - } - else - { - timelineController.UpdateTransitionTargetRealTime(restTime, true); - stateManager.SelectedState = nextSelectedScene_ + 1; - } - break; - } + case CylCommand.FourBarLoopButton: case CylCommand.OneBarLoopButton: - { - var restTime = CalculateRestTime(OneBarTrigger - currentTick_ % OneBarTrigger); - if (nextSelectedScene_ > currentSelectedScene_) + float restTime=0; + switch(command) { - timelineController.UpdateTransitionTargetRealTime(restTime, false); - stateManager.SelectedState = nextSelectedScene_; + case CylCommand.FourBarLoopButton: + restTime = CalculateRestTime(FourBarTrigger - currentTick_ % FourBarTrigger); + break; + case CylCommand.OneBarLoopButton: + restTime = CalculateRestTime(OneBarTrigger - currentTick_ % OneBarTrigger); + break; } - else + Debug.Log("currentSelectedAnimation_=" + currentSelectedAnimation_); + Debug.Log("nextSelectedScene_=" + nextSelectedMarker_); + bool _reverse = nextSelectedMarker_ <= currentSelectedAnimation_; //nextSelectedMarker_ used to calculate direction + + if (timelineController.animationPaused()) { - timelineController.UpdateTransitionTargetRealTime(restTime, true); - stateManager.SelectedState = nextSelectedScene_ + 1; - } + timelineController.UpdateTransitionTargetRealTime(restTime, _reverse); + + stateManager.SelectedState = currentSelectedAnimation_ + 1; //marker at which transition starts + } + else //trigger pressed while animation running + { + timelineController.abortAnimation(); + + } break; - } + default: + Debug.Log("Unexpected Command: " + mes.Data1); throw new Exception("Unexpected CYL command"); } } diff --git a/UnityProject/Assets/Scripts/StateManagement/StateManager.cs b/UnityProject/Assets/Scripts/StateManagement/StateManager.cs index 5e628ab..9a60cfc 100644 --- a/UnityProject/Assets/Scripts/StateManagement/StateManager.cs +++ b/UnityProject/Assets/Scripts/StateManagement/StateManager.cs @@ -85,6 +85,14 @@ namespace cylvester set { sceneSelection = value; + if (value > States.Length - 1) + { //if index out of bounds + sceneSelection = States.Length - 1; //set to last index + } + else if (value < 0) + { + sceneSelection = 0; + } onStateChanged.Invoke(this); } get @@ -103,11 +111,13 @@ namespace cylvester break; case Operation.Previous: if (sceneSelection == 0) return; - sceneSelection--; + sceneSelection--; + sceneSelection = Math.Max(sceneSelection, 0); //constrain minimum break; case Operation.Next: if (sceneSelection >= States.Length - 1) return; sceneSelection++; + sceneSelection = Math.Min(sceneSelection, States.Length - 1); //constrain maximum break; default: return; @@ -127,10 +137,12 @@ namespace cylvester case Operation.Previous: if (sceneSelection == 0) return; sceneSelection--; + sceneSelection = Math.Max(sceneSelection, 0); //constrain minimum break; case Operation.Next: if (sceneSelection >= States.Length - 1) return; sceneSelection++; + sceneSelection = Math.Min(sceneSelection, States.Length - 1); //constrain maximum break; default: return;