From 32cd16d64ee714b50c3313a8e9803d413b4da94a Mon Sep 17 00:00:00 2001 From: Tristan Rowley Date: Thu, 20 Feb 2020 16:03:46 +0000 Subject: [PATCH] Experimental (but appears to be working) smoothing of automation clip shader params. todo: save smoothed version, smooth plugins, smooth WJSend.. --- plugins/ShaderLoopRecordPlugin.py | 12 ++++-- plugins/frame_manager.py | 69 +++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+), 3 deletions(-) diff --git a/plugins/ShaderLoopRecordPlugin.py b/plugins/ShaderLoopRecordPlugin.py index 3cad4db..45c6c43 100644 --- a/plugins/ShaderLoopRecordPlugin.py +++ b/plugins/ShaderLoopRecordPlugin.py @@ -102,9 +102,15 @@ class ShaderLoopRecordPlugin(ActionsPlugin,SequencePlugin,DisplayPlugin): ( r"toggle_overdub_automation", self.toggle_overdub_automation ), ( r"clear_automation", self.clear_clip ), ( r"select_automation_clip_([0-7])", self.select_clip ), - ( r"toggle_automation_clip_([0-7])", self.toggle_clip ) + ( r"toggle_automation_clip_([0-7])", self.toggle_clip ), + #( r"smooth_clip_(0-7])", self.smooth_clip ), + ( r"smooth_selected_clip", self.smooth_selected_clip ) ] + def smooth_selected_clip(self): + self.pc.fm.interpolate_clip(self.frames[self.selected_clip]) + + def toggle_overdub_automation(self): self.overdub = not self.overdub if not self.overdub: @@ -224,11 +230,11 @@ class ShaderLoopRecordPlugin(ActionsPlugin,SequencePlugin,DisplayPlugin): if self.DEBUG_FRAMES: print("||||saving frame \t%s" % (diff['shader_params'])) self.frames[selected_clip][current_frame_index] = diff #self.get_frame_diff(self.last_frame,current_frame) #backfill frames - if self.last_saved_index is not None: + """if self.last_saved_index is not None: if self.DEBUG_FRAMES: print ("last_saved_index is %s, current_frame_index is %s" % (self.last_saved_index, current_frame_index)) for i in range(current_frame_index - (self.last_saved_index) ): if self.DEBUG_FRAMES: print("backfilling frame %s" % ((self.last_saved_index+i+1)%len(self.frames[selected_clip]))) - self.frames[selected_clip][(self.last_saved_index+i+1)%len(self.frames[selected_clip])] = diff + self.frames[selected_clip][(self.last_saved_index+i+1)%len(self.frames[selected_clip])] = diff""" self.last_saved_index = current_frame_index self.last_frame = self.pc.fm.get_live_frame() #diff if self.DEBUG_FRAMES: print("<<<<<<<<<<<<<< frame at %s" % current_frame_index) diff --git a/plugins/frame_manager.py b/plugins/frame_manager.py index 7a01ea5..bb38e9e 100644 --- a/plugins/frame_manager.py +++ b/plugins/frame_manager.py @@ -318,3 +318,72 @@ class FrameManager: #print("get_plugin_frame_data looks like %s" % data) return data + def interpolate_clip(self, frames): + # loop over every frame + # for each property of each frame + # if its empty, + # find distance to next value + # interpolate from the last to the next value + # else, + # store as last value + + print("got pre-interpolated clip: %s" % [ f.f for f in frames if f is not None]) + + last = [ [None]*4, [None]*4, [None]*4 ] + + """for findex,frame in enumerate(frames): + if frame is None: + continue""" + + reproc_to = 0 + + def process(self, findex, frame): + for layer,params in enumerate(frame.f.get('shader_params',[])): + for param,value in enumerate(params): + if value is None and last[layer][param] is not None: + # find distance to when this value changes again + gap,future_value = self.get_distance_value_layer_param(frames,findex,layer,param) + if gap==0 or future_value==value: # if doesnt change again, do nothing + continue + newvalue = self.interpolate(last[layer][param], future_value, gap) + params[param] = newvalue + print("findex %s: updating interpolated value to %s - should be between %s and %s over gap %s" % (findex, newvalue, last[layer][param], future_value, gap)) + last[layer][param] = newvalue + #elif last[layer][param] is None: + # reproc_to = findex + elif value is not None: + last[layer][param] = value + + for i in range(2): + for findex,frame in enumerate(frames): + if frame is None: + continue + + process(self,findex,frame) + + """for findex in range(reproc_to): + if frames[findex] is None: + continue + + process(self,findex,frames[findex])""" + + print("got interpolated clip: %s" % [ f.f for f in frames if f is not None ]) + + def get_distance_value_layer_param(self, frames, findex, layer, param): + for i in range(1,len(frames)): + search_findex = i + findex + search_findex %= len(frames) + if frames[search_findex] is not None and frames[search_findex].f.get('shader_params',[ [None]*4, [None]*4, [None]*4 ])[layer][param] is not None: + return i, frames[search_findex].f.get('shader_params')[layer][param] + return 0, None + + def interpolate(self, value1, value2, total_steps): + diff = max(value1,value2)-min(value1,value2) + sl = diff / total_steps + if value1>value2: + v = value1-sl + else: + v = value1+sl + + print("interpolate between\t%s and\t%s over\t%s steps, got sl\t%s and value\t%s" % (value1,value2,total_steps, sl, v)) + return v