DarienBrito / TDMorph

TDMorph, a toolbox for enhanced parametric exploration in TouchDesigner
GNU General Public License v3.0
136 stars 9 forks source link

Manually blend between saved preset states using an XY slider? #67

Closed aaapoc closed 4 years ago

aaapoc commented 4 years ago

Hello again,

I'm not sure if this is currently possible, but it would be very useful if one could manually blend between four saved preset states through the use of an XY pad, such as a masterSlider2D widget. It would be functionally identical to how the XY pad operates in the video synth app Lumen.

I took a deep dive into the guts of TDMorph container, but didn't see anything alluding to this. Could you kindly advise?

DarienBrito commented 4 years ago

Hello,

This is not currently possible and having an XY pad it is not a planned feature, because it is rather specific and not really scalable to an undefined amount of presets.

There will be in the future though some form of manual blending between arbitrary set of presets, since it is something that seems to be wanted indeed. Will be revised in the next major release.

baronlanteigne commented 4 years ago

This brings back the situation where everyone has their own approach to control data. I believe some of my suggestion may fall in this category as well. I think TDMorph can still play a role in this kind of project as it's a pretty good way to store, recall, edit data in general.

Could there be a way to fetch the stored data in a DAT or CHOP without triggering a morph so the creation of additional performance tools could connect directly to an instance of TDMorph? Maybe a slider container method?

I would be interested to develop tools like this XY Pad that benefit from how easy it is to organize data with TDMorph and manipulate this data in different ways. Anything I should know?

DarienBrito commented 4 years ago

Yes, good points. One of the goals with TDMorph is that it remains as general as possible, so it can work as a basis to build upon. This is why all UI functionality in there is "dumb", in the sense that its only calling methods from core classes and does not really do anything by itself. You could throw away all the UI and still have all core functionality intact, in the PresetManager node. This node lives inside the Lib component. You can even create from the menu an external copy of a PresetManager and use it as a bedrock to build your own tools. I present this in one of the tutorials.

So, everything you need to access stored data and create your own tools from TDMorph is already there, although it might be a bit difficult to know where to look and what to use because the code as a whole is rather complex. For all preset data, you can have a look at the methods inside the PresetManager. That is how you can access all stored information and how you could plug self made tools to TDMorph.

Now, I think would be good indeed to make this more intuitive, helping people to make their own tools without having to dig too much in the implementation. So, could you guys write here a list of what data from TDMorph would be most useful and in what format/manner/way? I would like to write a high-level API of sorts, from where one can plug to all core functionality without needing to dive-in too deep.

baronlanteigne commented 4 years ago

Dumb UI. Yes this is also how I envision it. In this case, I think I would refer to TDMorph/SlidersContainer1/PanelContent/SlidersContainer/PresetManager directly because what is desired is not TDMorph's interpolation potential but the ease with which you can map parameters and create presets. I think the appeal here is for a tool that I can drag and drop in a project that already uses TDMorph, connect TDMorph to this tool which reads TDMorph's stored value and parameters to create something else, which can work in parallel.

One problem I forsee with manual control is that you can't exportChop to a parameter already controlled by TDMorph.. but I guess the XYPad could control TDMorph's sliders so it could also be used to find sweet spot and create new presets!

I think almost everything is already available with the methods and PresetManager except for easy access to stored data. I know about the button labeled "Generate tables" but those tables don't get updated, at least I'm not sure how to update them.

So could there be a way to recall all the values stored to a preset as a list or a table which updates whenever this preset gets stored?

Conceptually, something similar to the MorphingTimers base that fetch the timer data and brings it "closer" to the user.

baronlanteigne commented 4 years ago

I went ahead and created a working version of this XY slider controller. It has two minor limitation but it integrates seamlessly with TDMorph. This is the first time I'm doing this and I'm not a programmer so any advice would be really appreciated.

https://github.com/johannbl/TDMorph_XYSlider

DarienBrito commented 4 years ago

Hi @johannbl, great! Very glad you went ahead and created your own component. I will have a look later today :)

aaapoc commented 4 years ago

Hi @johannbl - I tested your example file and it works great! It's precisely what I am looking for.

I plugged it into my project file that I want to use this for, and was getting a warning from each of the four Select DATs. "invalid path for node "/TDMorph/SlidersContainer1/PanelContent/SlidersContainer/Presets1/preset1" referenced by parameter "DAT" (/TDMorph_XYSlider/select1)

I wasn't able to resolve this, despite following the steps you outlined and pulsing the Update button. I'll try again later when I have more time. Nevertheless, thanks a million for putting this together and sharing it!

baronlanteigne commented 4 years ago

"Presets1/preset1" DAT is where the stored data is exported when clicking the Generate Tables button on PresetManager. When you click the Update button on XYSlider, it deletes and re-creates those DATs. The four selectDATS will then fetch data according to which int you specified in the custom parameters. so by default, the values 1, 2, 3, 4 will fetch data from "Presets1/preset1", preset2, preset3, preset4. If those presets have nothing stored, it won't work. After changing any of the preset, Update has to be clicked again. Maybe for some reason the dats aren't labeled the same. If you send me the patch I could take a look.

I also encountered an issue with OSC mapping when opening the file for the first time. OSC mappings have to be cleared (shift+right click on the osc mapping button) and then recreated using the Update button.

The real limitation here is how I fetch this data (and how I use osc to control TDMorph after). I just figured out a way it could work right now mostly to get things started and better illustrate what is needed if Darien wants more people creating those custom modules. Maybe there's already a better way but I couldn't figure it out. I'm sure additional Sliders Container Methods can be created to make all of this smoother.

I will redesign the tool once Darien adds more support / documentation for this type of project.

aaapoc commented 4 years ago

@johannbl, thanks for your response. I was able to get this to work perfectly in my project file. Thanks a million!

DarienBrito commented 4 years ago

@johannbl great! Did not have a chance to look at your component yet. Will do so promptly!

DarienBrito commented 4 years ago

Hello guys,

I had a look at the component from @johannbl Nice one!

I see that something that was missing is a comfortable way to get presets from TDMorph that update on any change. So I have change a little bit the inner architecture of TDMorph to support this in a secure way.

I have deprecated the tables export, because they were not very useful as they were before. Instead, I have created a new tool in TDMorph called "PresetsGrabber". you can get one from the "New" menu in TDMorph. This allows you to get tables that update on any change done in the presets from a given sliders container, from which you can build your tools. I have modified @johannbl XYSlider to support this new way.

Note that you should not use the OSC input field to map values. That will not work very well on the long run, since it is not meant to be used in that way. It is much cleaner, easier and nicer to just use a chopexec and alter the slider values from the Value property of the sliders. I show how to do this as well. Please find all this in the attached example.

XYSLider.zip

Note that the example uses version 1.1.4, this is a experimental version with the above described structural changes to TDMorph's presets architecture. I added this also to the repository. Since the change affects the whole system, there may be something broken... please help me finding out further bugs by giving that experimental version a shot.

Let me know what you think!

baronlanteigne commented 4 years ago

Oh the PresetsGrabber is exactly what I had in mind. It brings back the data in "TouchDesigner". I think for anyone not familiar with the inner workings of TDMorph, it's going to be faster and easier to dig around and see the data stored on DATs. Now I know it's not essential, but do you think it would be worthwhile to include the dattoCHOP conversion straight in PresetsGrabber?

I didn't want to have to go through OSC to link back with TDMorph but I was worried that running a script that interacts with TDMorph's GUI was going to be inefficient (in terms of cooking time). I wonder if this matters at all.

Speaking of OSC, after messing with the OSC mapping, I realize that if I had many parameters, I would hate to have to map each one of them manually. I think the mouse wheel button that opens the DAT is a pretty nice addition because of this. Maybe automatically mapping every channel in the OSC chop to each parameter in TDMorph could be great.

I noticed a minor issue occurs when adding new parameters, if your stored presets don't all have a stored value for the newly added parameters, some of them won't be output. Your PresetsGrabber works fine however: The issue is based on how the crossCHOP works with chops with different amount of channels. Because TDMorph uses parameter binding, it usually doesn't matter if the stored presets don't all contain a value for each parameters.

DarienBrito commented 4 years ago

Now I know it's not essential, but do you think it would be worthwhile to include the dattoCHOP conversion straight in PresetsGrabber?

While it would be easy to add the dattoCHOPs inside the PresetsGrabber, my philosphy with a public tool such as TDMorph is that it should fit (as much as possible) all cases and not enforce particular ones. People will always need the tables from the grabber, but not always a CHOP version of those tables for their tools, so the general version is supported while the specific cases are responsibility of users. Maybe later, depending on what people need, this can be extended so it is selective with a menu or something.

I was worried that running a script that interacts with TDMorph's GUI was going to be inefficient (in terms of cooking time). I wonder if this matters at all.

It doesn't matter about cooking time because this is what the OSC mapping is doing anyways under the hood. It is in fact slower to go via the OSC because more computations happen in-between. Better to just straight right to the UI elements :)

Maybe automatically mapping every channel in the OSC chop to each parameter in TDMorph could be great.

This could be added as an option as well, perhaps in a slider container that says "map all inputs", can you make a separate issue for that one?

The issue is based on how the crossCHOP works with chops with different amount of channels.

Yes indeed. A check could be made to refine how this works, but since doesn't cause any major issue for now it is responsibility of the user to properly set the right amount of items in their presets.

DarienBrito commented 4 years ago

Closing this one as it has been addressed and concluded. Thanks @aaapoc and @johannbl ! This suggestion and further discussion actually made me introduce a much needed feature which has made the system much more powerful.