Category Archives: media design

TouchDesigner | Evaluate DAT Magic

13185491723_10766c1574_oLet’s say you’re an ambitions person, maybe too ambitious, and all of a sudden you have a control panel with 68 buttons that need to trigger various scenes, effects, and transitions. Let’s also say that your TouchDesigner network is  vast enough that you need (and I mean in a big way) a simple method for getting information about what’s active in your network. If you find yourself programming the media for a live theatrical event with these same kinds of concerns, the Evaluate DAT might just be the best friend that you didn’t know that you needed.

My example above might sound a little far fetched, so let’s instead look at a more concrete example. Let’s imagine that we have a digital puppet that we’d like to trigger to enter and exit with a button set to toggle. Just to make this more interesting, let’s say that you actually have three puppets and three visual effects that you’d like to all control with buttons from a single control panel. If all of your puppets and effects are all located in a similar place this might not be a huge hassle for you, if however, you’re building a complicated network it will soon become very important to be able to call the states of these buttons across your network.

Here’s my example set-up for us – a control panel that has all of our controls, a base component where we’re going to store the status of our buttons, and a scene where our puppet needs to make an entrance and an exit based on our button’s active state.

Screenshot_031614_012640_AM

I’m going to assume that you’re already familiar with working with control panels in TouchDesigner, but if that’s not the case you can learn a little more here before you keep reading. Lets start by taking a look inside of our “trigger_ref” base component where we are going to store the status of our buttons to use other places in our network.

Screenshot_031614_013152_AM

This should look pretty impressively boring at first glance. To really get a feel for what’s happening here, let’s take a closer took how how this is being driven by our control panel.

evaluate DAT in action

Alright, so here we can see that Puppet 1, 2, and 3 all act as Toggle switches, VFX 1 acts as a momentary trigger, and VFX2 and VFX3 both act as toggles. Before we start to look at why this is important, let’s first see how this is working.

To really make our Evaluate DAT sing we need to start by feeding a table with some instructions about what information we would like it to evaluate. In my case I’ve made a table with a name for the item that I’d like to call in one column, and the pathway to the operator and channel that’s being evaluated in the other column.

Screenshot_031614_013937_AM

If we were to write these instructions in English they might read something like: “TouchDesigner, please watch operator ‘button0’ in ‘ctrl’ and tell me when it’s v1 changes, and give that the name ‘Puppet1’. It’s important note that the formatting and syntax of your request to the Evaluate DAT matters. In my case I needed to put the names in the first column in quotations. I also made sure to tell the evaluate DAT that I wanted an integer (you’ll notice that in front of the operator’s pathway I’ve int() to specify that I want an integer returned to me). Next in the Evaluate DAT I need to check a few settings in the operators parameters.

Screenshot_031614_014828_AM

The most important parameter to take note of here is that I’ve told the Evaluate DAT that I’d like the output in Expressions. This ensures that my input table is being evaluated.

Okay, but why is this interesting / important / worth your attention? While it might be tempting to avoid an organization method like this, it means that when you’re working with a large control panel, or a large cue stack, that you can refer to a button by its name rather than by a complicated network pathway. Better yet, once you write the expression to call this value from our Evaluate DAT it becomes easy to copy and paste that expression and only need to change the name of the value that you’re calling. Let’s go back to our puppet example.

Screenshot_031614_020356_AMHere I have my video that I’d like to change with my puppet button. I’ve already set up my network with a few operators. First I have a constant CHOP, and a trigger CHOP. Next I have a Movie in TOP, a Level TOP, and a Null TOP. I’d like to use my trigger CHOP to change the opacity of my Movie.

To start let’s make sure that our constant CHOP is set up with a channel that we’ll name “Puppet1” .

Screenshot_031614_021044_AM

Let’s also make sure that our trigger is set to have a sustain value of 1, and let’s make sure that we’re happy with how the trigger is going to fire and release. For now I’m only interested in making sure that my sustain is changed.

Screenshot_031614_020704_AM Next we’re going to write a quick expression that will allow our level TOP to reference the trigger CHOP. In your level top we’re going to use the expression on the opacity Parameter on the Post page of Level TOP:

op( “trigger1” )[ “Puppet1” ]

Screenshot_031614_021154_AM

Now we’re going to go back to our constant CHOP to see how this really makes our network programming fun. Here for the value of the Puppet1 channel we’re going to write the following expression:

op( “../trigger_ref/buttons” ) [ “Puppet1” , 1 ]

Screenshot_031614_021552_AM

Now, let’s finally see what this means when we use this in conjunction with our control panel.

puppet inout

Great, so now we toggle the opacity of a video on and off with a button. What’s important here is that what if you suddenly decide that you want this action to happen with the Puppet 2 button instead? Now, rather than having to look up where your original button was, along with it’s reference you can instead just change the expression in the Constant CHOP to be:

op( “../trigger_ref/buttons” ) [ “Puppet2” , 1 ]

Right? We’ve changed all of those button values into a table that we can centrally reference by name. If you’re just getting started with TouchDesigner this might not seem like a huge revelation, but once you start to build more complicated networks the ability to call something by a name (maybe even a name that’s in your cue sheet) becomes hugely important.

TouchDesigner | Container Display

10620433406_3bcbc8f36e_oA quick one today that addresses problems I didn’t know that I had until I decided that I wanted to show off. In Wonder Dome I’m finding that sometimes the best way to build a scene is to use methods encapsulated inside of a container that make some change to some source imagery. This approach gives me a quick access to the parameters that I’m the most likely to use in a given method, without requiring that I always dive into the container to make changes. For example, I’ve build a handy tool for moving video assets around in the dome. This is fantastic, but if I drop this container into another container that needs its own set of buttons I quickly end up with a mess. Here’s an example of what I’m talking about:

Screenshot_030614_010956_PM

Looking at this container from the root folder I can the control panels for this network, and for it’s child. There are lots of ways to address this. I might, for example, just dive into the container find the child container and turn off its display parameter.

Screenshot_030614_012024_PM

That’s a fine approach if I’m only working with a couple of different scenes, but what happens when I suddenly have 10 or 20 scenes in a given network, each with a number of containers with control panels inside of them? Then I have a headache on my hands as I have to methodically go through and carefully disable each of the containers that I don’t want displayed.

We can solve this problem by using a python expression to conjure some TouchDesigner black magic. I’m going to solve this problem by asking my encapsulated containers to look at their parent operator and to complete a simple logical operation. When I’m ready to lock down a scene in my network, I add a capital “P” to the name of the container – for me this means it’s “P”erformance ready.

Now, instead of toggling that display parameter on my encapsulated container instead I’m going to use this expression:

0 if me.parent().name[0] == “P” else 1

“What on earth does this mean?!”
We can call for the name of our parent with the following expression:

me.parent().name

Better yet, we can ask for a specific character in from that name. If we ask for the character in the 0 position (remember that in programming languages 0 is often the first number in a list), we get the first letter from the name of our parent operator. Putting these two ideas together we get the expression:

me.parent().name[0]

Alright, now that’t we have the fist character from our parent operator’s name, let’s do a simple logical operation. Using an if else statement we can set one of two values. In this case I’m toggling between the values 0 or 1 (off or on). The syntax of this starts with the value if your logical operation is true, and then specifies what value to use if that statement is false. With this in mind, the whole expression is:

0 if me.parent().name[0] == “P” else 1

Alright, so if we were to look at our expression as a sentence it might read something like: “Hey TouchDesigner, if my parent’s name starts with the letter ‘P’ set this value to 0, otherwise leave it as 1.”

Screenshot_030614_012941_PM

 

Alright, now that we’ve written our expression in the right place, let’s see what it’s doing.

button expressions

 

Now we have a quick way to turn child control panels on and off without needing to dive into the container and hunt for our container display parameters.

TouchDesigner | Replicators, and Buttons, and Tables, oh my

replicator cue buttons

I want 30 buttons. Who doesn’t want 30 buttons in their life? Control panels are useful for all sorts of operations in TouchDesigner, but they can also be daunting if you’re not accustomed to how they work. In the past when I’ve wanted lots of buttons and sliders I’ve done all of my lay-out work the hard way… like the hardest way possible, one button or slider at a time. This is great practice, and for anyone who is compulsively organized this activity can be both maddening and deeply satisfying at the same time. If you feel best when you’re meticulously aligning your buttons and sliders in perfect harmony, this might be the read for you. If, however, you like buttons (lots of them), and you want to be able to use one of the most powerful components in TouchDesigner, then Replicators might just be the tool you’ve been looking for – even if you didn’t know it.

Replicators, big surprise, make copies of things. On the surface of it, this might not seem like the most thrilling of operators, but lets say that you want to automate a process that might be tedious if you set out to do it by hand. For example, let’s say you’re designing a tool or console that needs 30 buttons of the same type, but you’d like them have unique names and follow a template and have unique names. You could do this one button at a time, but if you ever change something inside of the button (like maybe you want the colors to change depending on their select state), making that change to each button might be a huge hassle. Replicators can help us make that process fast, easy, just plain awesome.

First thing, let’s make a container and dive inside of it to start making our buttons. Next let’s make a table. I’m going to use my table DAT to tell the replicator how to make the copies of my button. As you start to think about making a table imagine that each row (or column) is going to be used to create our copies. For example, I’ve created a table with thirty rows, Cue 1 – Cue 30.

Screenshot_030614_011703_AM

Next let’s make a button COMP and rename it button0 (don’t worry, this will make sense in a a few minutes).

Screenshot_030614_012057_AM

Alright, now we’re gonna do some detailed work to set-up our button so some magic will happen later. First up we’re going to make a small change to the Align Order of our button. The Align Order parameter of a button establishes the order in which your buttons are arranged in the control panel when you use the Align Parameter (if this doesn’t make sense right now, hang in there and it will soon). We’re going to use a simple python expression to specify this parameter. Expand the field for the Align Order and type the python expression:

me.digits

What’s this all about? This expression is calling for the number that’s in the name of our button. Remember that we renamed our button to button0. Using this expression we’ve told TouchDesigner that the alignment order parameter of this button should be 0 (in many programming languages you start counting at 0, so this makes this button the first in a list).

Screenshot_030614_012854_AM

Alright, now let’s start making some magic happen. Let’s go inside of our button and make a few changes to the background text. If this is your first time looking inside of the button component take a moment to get your bearings – we have a table DAT that’s changing the color of the button based on how we interact with this component, we have some text that we’re using for the background of the button, and we have a few CHOPs so we can see what the state of our button is when it’s toggled or pressed.

Screenshot_030614_013526_AM

Next we’re going to take a closer look at just the text TOP called bg. Looking first at the text page of the parameters dialogue gives us a sense of what’s happening here, specifically we can see that the text field is where we can change what’s displayed on this button. First up we’re going to tell this TOP that we want to pull some data from a DAT. In the DAT field type the path:

../table1

Next change the DAT Row to the following python expression:

me.parent().digits

Finally, clear the text parameter so it’s blank. With any luck you’re button should now read, “Cue 1,” or whatever you happened to type in the first row of your table.

Screenshot_030614_014601_AM

So what’s happening here?! First, we’re telling this TOP that we’re going to use some information from a table. Specifically, we’re going to use a table whose name is table1, and it’s location is in the parent network (that’s what ../ means). If we were to take our network path ../table1 and write it as a sentence it might read something like this – “hey TouchDesigner I want you to use a table DAT for this TOP, to find it look in the network above me for something named table1.” Next we have an expression that’s telling this TOP what row to pull text from. We just used a similar expression when we were setting our alignment order, and the same idea applies here – me.parent().digits as a sentence might read “hey TouchDesigner, look at my parent (the component that I’m inside of) and find the number at the end of its name.” Remember that we named this component button0, and that 0 (the digits from that name) correspond to the first row in our table.

Now it’s time to blow things up. Let’s add a replicator component to our network.

Screenshot_030614_015654_AM

In the parameters for our replicator first specify that table1 is the template table. Next let’s change the Operator Prefix to button to match the convention that we already started. Last by not least set your Master Operator to be your button0.

Screenshot_030614_020047_AM

If we set up everything correctly we should now have a total of 30 buttons arranged in a grid in our network. They should also each have a unique name that corresponds to the table that we used to make this array.

Screenshot_030614_020310_AM

Last but not least, let’s back up and see what this looks like from the container view. At this point you should be sorely disappointed, because our control panel looks all wrong – in fact it looks like there’s only one button. What gives?

Screenshot_030614_020604_AM

The catch here is that we still need to do a little bit of house keeping to get to what we’re after. In the Container’s parameters on the layout page make sure the Align parameter is set to “Layout Grid Columns” or “Layout Grid Rows” depending on what view better suits your needs. You might also want to play with the Align Margin if you’d like your buttons to have a little breathing room.

Screenshot_030614_020954_AM

Bingo-Bango you’ve just made some replicator mojo happen. With your new grid of buttons you’re ready to do all sorts of fun things. Remember that each of these buttons is based on the template of the master operator that we specified in the replicator. In our case that’s button0. This means that if you change that operator – maybe you change the color, or add an expression inside of the button – when you click the “recreate all operators” in the replicator, this remakes your buttons with those changes applied to every button.

Happy replicating.


A big thank you to Richard Burns and Space Monkeys for sharing this brief tutorial that inspired me to do some more looking and playing with Replicators:

TouchDesigner | These are the DATs you’ve been looking for

Silly DAT screenshotIf you’re new to TouchDesigner, it’s easy to feel like DATs are a hard nut to crack. This is especially true if you’re also new to programming in general. Scripting can be daunting as you’re getting started, but it’s also incredibly important – take it from someone who is still learning, dat by dat.

So what’s the big deal about DATs anyway? Better yet, why should you care? DATs can help in all sorts of ways, but lets look at a concrete example of how they can help solve some interesting problems that you might face if you’re out to save some information to use later.

As the Wonder Dome team has been busy building interfaces, programming methods, and performance tools we’ve hit countless situations where being able to save some data for later use is absolutely necessary.

Our lighting designer, Adam Vachon, wants to be able to mix color live during a rehearsal and then record that mix to in a cue later. Better yet, he might want to create a cue sheet with all of that data saved in a single table so he can quickly recall it during tech. Over in media, we want to be able to place video content in lots of difference places across the dome and with varying degrees of visual effects applied and we also want to be able to record that data for later recall.

DATs, are a wonderful solution for this particular problem. With a few DATs, and some simple scripts we can hold onto the position of our sliders to use later. Let’s take a look at how we can make that happen.

First let’s look at a simple problem. I want to be able to add the values from one table to the bottom of another table. If you’re new to programming, this process is called appending. We can see an example of this if we look at two different tables that we want to add together.

two

Here we have two tables, and we’d like to combine them. We can do this by writing a simple script that tells TouchDesigner to take the contents of cells from table2 and to add them to table1 in a specific order. One of the things that’s important to understand is how tables are referenced in TouchDesigner. One of the ways that a programmer can pull information from a cell is to ask for the data by referencing the address of the cell. This is just like writing a formula in something Google Spreadsheets or Excel – you just need to know the name of the cell that you want information from. Let’s take a look at how the addressing system works:

Screenshot_030514_124543_AM

Taking a moment to study table3 and you’ll be referencing cells in a flash. It’s just rows and columns, with the only catch that the numbering system starts at 0. Cool, right? Okay, so if we want to write our script to append cells from one table to another we’re going to use this format:

n = op(“table1”)
m1 = op(“table2”)[0,0]
m2 = op(“table2”)[0,1]
m3 = op(“table2”)[0,2]

n.appendRow( [ m1, m2, m3 ] )

So what’s happening here? First we’re defining table1 as a variable we’re calling n. Next we’re naming three new variables m1, m2, and m3. These correspond to the data in the first row of table2, in column 1, 2, 3. The next operation in our script to append n (that’s table1) with a new row using the values m1, m2, and m3 in that order. You might decide that you want these added to n in a different order, which is easy, right? All you have to do is to change the order that you’ve listed them – try making the order of variables in the brackets [ m2, m1, m3 ] instead to see what happens. Alright, at this point our network should look like this:

Screenshot_030514_125145_AM

Now, to run our script we’re just going to right click on text3, and select “Run Script” from the contextual menu.

simple script

Great! Now we’ve successfully appended one table with data from the first row of another table.

If you’re still with me, now we can start to make the real magic happen. Once we understand how a script like this works, we can put it to work to do some interesting tasks for us. Let’s look at a simple example where we have three sliders, that we want to be able to save the data from.

Screenshot_030514_125808_AM

To get started, let’s make three slider COMPs, and connect them to a merge CHOP.

Screenshot_030514_125922_AM

Now lets add a Chop to DAT, and export the merge to the Chop to.

chop to

The chopto DAT is a special kind of operator that allows us to see CHOP data in DAT format. This coverts our CHOP into a table of three floats. At this point you can probably guess where we’re headed – we’re going to use our simple script that we just wrote to append the contents of our chopto to another table. Before we get there, we still need to get a few more ducks in a row.

Next let’s create a table with one row and three columns. Name these columns anything you want, in my case I’m going to call them (rather generically) Value 1, Value 2, and Value 3. I’m also going to create a big empty table, and finally I’m going to connect both of these with a merge DAT. Why two tables? I want my first table to hold my header information for the final table. This way I can clear the whole table of saved floats without also deleting the first row of my final table.

Screenshot_030514_010521_AM

As a quick reminder, the names of your DATs is going to be very important when we start to write our script. The names of our DATs is how we can identify them, and consequently how we can point TouchDesigner to the data that we want to use.

Next I’m going to add a button COMP to my network, and a panel execute DAT. In the panel execute DAT I’m going to make sure that it’s looking at the operator button1 and watching for the panel value select. I’m also going to make sure that the On to Off box is checked – this tells the DAT when to run the script. Next I’m going to slightly alter the script we wrote earlier to right for our tables here. I’m also going to make sure that the script is in the right place in the DAT. Take a closer look at the example below to see how to format your DAT.

Screenshot_030514_011212_AM

Alright, now it’s time for DAT table magic. At this point you can make your sliders and button viewer active, and you’re ready to make changes and then record slider states. Happy appending.

slider table action

In case you still have questions you can take a closer look at my example here – record_method_example.

TouchDesigner | 3D solutions for a 2D world

12761364894_714f3b8985_nOne of the fascinating pieces of working in TouchDesigner is the ability to use 3D tools to solve 2D problems. For the last seven months or so I’ve been working on Daniel Fine’s thesis project – Wonder Dome. Dome projection is a wild ride, and one of the many challenges we’ve encountered is thinking about how to place media on the dome without the time intensive process of pre-rendering all of the content specifically for this projection environment. To address some of these issues we started working with Los Angles based Vortex Immersion Media, their lead programmer is the TouchDesigner specialist Jeff Smith of Eve Vapor. Part of the wonderful opportunity we’ve had in working with Vortex is getting to take an early look at Jeff’s custom built Dome Mapping tool. Built exclusively in TouchDesigner it’s an incredibly powerful piece of software built to make the dome warping and blending process straightforward. The next step in the process for us was to consider how we were going to place content on the interior surface of the dome. The dome mapping tool that we’re using uses a square raster as an input, and can be visualized by looking at a polar array. If you’re at all interested in dome projection, start by looking at Paul Bourke’s site – the wealth of information here has proven to be invaluable to the Wonder Dome team as we’ve wrestled with dome projection challenges. This square image is beautiful mapped to the interior surface of the dome, making placing content a matter of considering where on the array you might want a piece of artwork to live.

There are a number of methods for addressing this challenge, and my instinct was to build a simple TouchDesigner network that would allow us to see, place, and manipulate media in real time while we were making the show. Here’s what my simple asset placement component looks like:

asset placement

This component based approach makes it easy for the design and production team to see what something looks like in the dome in real time, and to place it quickly and easily. Additionally this component is built so that adding in animation for still assets is simple and straight forward.

Let’s start by taking a look at the network that drives this object, and cover the conceptual structure behind its operation.

Screenshot_022814_125736_AM

In this network we have a series of sliders that are controlling some key aspects of the media – orientation along a circular path, distance from the center, and zoom. These sliders also pass out values to a display component to make it easy to take note of the values needed for programming animation.

We also have a render chain that’s doing a few interesting things. First we’re taking a piece of source media, and using that to texture a piece of geometry with the same aspect ratio as our source. Next we’re placing that rectangle in 3D space and locking its movement to a predefined circular pathway. Finally we’re rendering this from the perspective of a camera looking down on the object as though it were on a table.

Here I’m using a circle SOP to create a circle that will be the pathway that my Geo COMP will rotate around. Here I ended this network in a null so that if we needed to make any changes I wouldn’t have to change the export settings for this pathway.

Screenshot_022714_095918_AM

You’ll also notice that we’re looking at the parameters for the circle where I’ve turned on the bulls-eye so we’re only seeing the parameters that I’ve changed. I’ve made this a small NURBS curve to give me a simple circle.

The next thing I want to think about is setting up a surface to be manipulated in 3D space. This could be a rectangle or a grid. I’m using a rectangle in this particular case, as I don’t need any fancy deformation to be applied to this object. In order to see anything made in 3D space we need to render those objects. The render process looks like a simple chain of component operators: a geo COMP, a camera COMP, a light COMP, and a render TOP. In order to render something in 3D space we need a camera (a perspective that we’re viewing the object from), a piece of geometry (something to render), and a light (something to illuminate the object).

Screenshot_022814_125903_AM

We can see in my network below that I’ve used an in TOP so that I can feed this container from the parent portion of the network. I’ve also given this a default image so that I can always see something in my container. You might also notice that while I have a camera and a geo, I don’t have a light COMP. This is because I’m using a material type that doesn’t require any lighting. More about that in a moment. We can also see that my circle is being referenced by the Geo, and that the in TOP is also being referenced by the Geo. To better understand what’s happening here we need to dive into the Geo COMP.

Screenshot_022814_125926_AM

Inside of the Geo COMP we can see a few interesting things at work. One thing you’ll notice is that I have a constant MAT and an info CHOP inside of this object. Both of these operators are referencing the in TOP in that’s in the parent network. My constant is referencing the in to establish what is going to be applied to the Geo as a material. My info CHOP gives me quick access to several of the attributes of my source file. Included in this list of attributes is the resolution of the source media. I can use this information to determine the aspect ratio of the source, and then make sure that my rectangle is sized to match. Using this process I don’t have to rely on a particular aspect ratio for my source material, I can pass this container any shape of rectangular image, and it will size itself appropriately.

Initially I just had three sliders that controlled the placement of my media in this environment. Then I started thinking about what I would really need during our technical rehearsals. It occurred to me that I would want the option to be able to place the media on the surface of the dome from a position other than behind the media server. To address this need I built a simple TouchOSC interface to replicate my three sliders. Next I captured that OSC information with TouchDesigner, and then passed that stream of floats into my container. From here I suddenly had to do some serious thinking about what I wanted this object to do. Ideally, I wanted to be able to control the container either form the media server, or from a remote access panel (TouchOSC). I also wanted the ability to record the position information that was being passed so I could use it later. This meant that I needed to think about how I was going to capture and recall the same information from three possible sources. To do this I first started by packaging my data with merge CHOPs. I also took this opportunity to rename my channels. For example, my OSC data read – osc_rot, osc_dist, osc_zoom; rotation, distance, and zoom sliders from my TouchOSC panel. I repeated this process for the sliders, and for the table that I was using. I also knew that I wanted to rename my stream, and pass it all to a null CHOP before exporting it across the network. To keep my network a little more tidy I used a base to encapsulate all of the patching and selecting, and switching that needed to happen for this algorithm to work properly.

Screenshot_022814_010413_AM

Inside of the base COMP we can see that I’m taking my three in CHOPs selecting for the appropriate channel, passing this to a switch (so I can control what value is driving the rendering portion of my network) and then back out again. You may also notice that I’m passing the switch values to a null, and then exporting that do a opViewer TOP. The opViewer TOP creates a rendered image of the channel operator at work. Why would I do this? Well, I wanted a confidence monitor for my patch-bay. The base COMP allows you to assign a TOP to its display. Doing this meant that I could see into a portion of the base, without having to actually be inside of this component.

Screenshot_022814_010506_AM

With all of the patching setup, I needed to build an interface that would control all of these changes. I also needed a way to capture the values coming out of TouchOSC, store them in a table, and then recall them later.

Screenshot_022814_010616_AM

The solution here was to build a few buttons to drive this interface. To drive the witch CHOP in my base component, I used three buttons encapsulated inside of a container COMP and set to operate as radio buttons. I then used a panel CHOP in the container to export which button was currently being toggled into the on position. Next I added a button COMP to record the values set from TouchOSC. Using a Chop to DAT I was able to capture the float values streaming into my network, and I knew that what I wanted was to be able to copy a set of these values to a table. To do this I used a panel execute DAT. This class of DAT looks at the panel properties of a specified container (buttons and sliders also qualify here), and runs a script when the specified conditions in the DAT are met. This is the portion of the network that gave me the most headache. Understanding how these DATs work, and the best method of working with them took some experimentation. To trouble shoot this, I started by writing my script in a text DAT, and then running it manually. Once I had a script that was doing what I wanted, I then set to the task of better understanding the panel execute DAT. For those interested in Python scripting in TouchDesigner, here’s the simple method that I used:

m = op (“chopto1”)
n = op (“table1”)
n.copy(m)

Here the operator chopto1 is the DAT that is capturing the OSC stream. The operator table1 is an empty table that I want to copy values to, it’s the destination for my data. The Python method copy starts by specifying the destination, and then the source that you want to pull from.

Screenshot_022814_010809_AM

Finally ready to work with the panel execute DAT, I discovered that all of my headaches were caused by misplacing the script. To get the DAT to operate properly I just had to make sure that my intended script was between the parameter specified, and the return call.

Screenshot_022814_010926_AM

One last helpful hint / tip that I can offer from working on this component is how to specify the order of your buttons in a container. One handy feature in the container parameters page is your ability to have TouchDesigner automatically array your buttons rather than placing them yourself. The catch, how do you specify the order the buttons should appear in? If you look a the parameter page for the buttons themselves, you’ll notice that they have a smartly named parameter named “Alignment Order.” This, sets their alignment order in the parent control panel.

If I’ve learned nothing else, I have learned that sometimes it’s the simplest things that are the easiest to miss.

TouchDesigner | Animation Comp

The needs of the theatre are an interesting bunch. In my time designing and working on media for live productions I’ve often found myself in situations where I’ve needed to playback pre-built content, and other times when I’ve wanted to drive the media based on the input of the performers or audience. There have also been situations when I’ve needed to control a specific element of the media, while also making space for some dynamic element.

Let’s look at an example of this so we can get to the heart of the matter. For a production that I worked on in October we used Quartz composer to create some of the pieces of media. Working with Quartz meant that I could use sound and video inputs to dynamically drive the media, but there were times when I wanted to control specific parameters with a predetermined animation method. For example, I wanted to have an array of cubes that were rotating and moving in real time. I then wanted to be able to fly through the cubes in a controlled manner. The best part of working with Quartz was my ability to respond to the needs of the directors in the moment. In the past I would have answered a question like “can we see that a little slower?” by saying “sure – I’ll need to change some key-frames and re-render the video, so we can look at it tomorrow.” Driving the media through quartz meant that I could say “sure, lets look at that now.”

In working with TouchDesigner I’ve come up with lots of different methods for achieving that same end, but all of them have ultimately felt a clunky or awkward. Then I found the Animation Component.

Let’s look at a simple example of how to take advantage of the animation comp to create a reliable animation effect that we can trigger with a button.

Let’s take a look at our network and talk through what’s happening in the different pieces:

Screenshot_011514_125716_AM

First things first let’s take a quick inventory of the operators that we’re using:

Button Comp – this acts as the trigger for our animation.
Animation Comp – this component holds four channels of information that will drive our torus.
Trail CHOP – I’m using this to have a better sense what’s happening in the animation Comp.
Geometry Comp – this is holding our 3D assets that we’re going to change in real time.

Let’s start by looking at the Animation Comp. This component is a little bit black magic in all of the best ways, but it does take some exploring to learn how it to best take advantage of it. The best place to start when we want to learn about a new operator or component is at the wiki. We can also dive into the animation comp and take a closer look at the pieces driving it, though for this particular use case we can leave that alone. What we do want to do is to look at the animation editor. We can find this by right clicking on the animation comp and selecting “Edit Animation…” from the pop-up menu.

open animation editor

We should now see a new window at the bottom of the screen that looks like a time-line.

Screenshot_011614_113551_PM

If you’ve ever worked with the Graph Editor in After Effects, this works on the same principle of adding key frames to a time line.

In thinking about the animation I want to create I know that I want to have the ability to effect the x, y, and z position of a 3D object and I want to control the amount of noise that drives some random-looking distortion. Knowing that I want to control four different elements of an object means that I need to add four channels to my animation editor. I can do this by using the Names dialog. First I’m going to add my “noise” channel. To do this I’m going to type “noise” into the name field, and click Add Channels.

Screenshot_011614_114525_PM

Next I want to add three channels for some object translation. This time I’m going to type the following into the Names Field “trans[xyz]”.

Screenshot_011614_114908_PM

Doing this will add three channels all at once for us – transx, transy, transz. In hindsight, I’d actually do this by typing trans[XYZ]. That would mean that I’d have the channels transX, transY, transZ which would have been easier to read. At this point we should now have four channels that we can edit.

Screenshot_011614_115144_PM

Lets key frame some animation to get started, and if we want to change things we can come back to the editor. First, click on one of your channels so that it’s highlighted. Now along the time line you can hold down the Alt key to place a key frame. While you’re holding down the Alt key you should see a yellow set of cross hairs that show you where your key frame is going. After you’ve placed some key frames you can then translate them up or down in the animation editor, change the attack of their slope, as well as their function. I want an effect that can be looped, so I’m going to make sure that my first and last key frame have the same values. A few notes about the animation editor. I’m going to repeat this process for my other channels as well. Here’s what it looks like when I’m done:

Screenshot_011614_115803_PM

Here we see a few different elements help us understand the relationship of the editor to our time line. We can see 1 on the far left, and 600 (if you haven’t changed the duration of your network) on the right. In this case we’re looking at the number of frames in our network. If we look at the bottom left hand corner of our network we can see a few time-code settings:

Screenshot_011614_115829_PM

There’s lots of information here, but I for now I just want to talk about a few specific elements. We can see that we start at Frame 1 and End at Frame 600. We can also see that our FPS (Frames Per Second) is set to 60. With a little bit of math we know that we’ve got a 10 second window. Coming from any kind of animation work flow, the idea of a frame based time line should feel comfortable. If that’s not your background, you can start by digging in at the wikipedia page about Frame Rate. This should help you think about how you want to structure your animation, and how it’s going to relate to the performance of our geometry.

At this point we still need to do a little bit of work before our animation editor is behaving the way we want it to. By default the Animation Comp’s play mode is linked to the time line. This means that the animation you see should be directly connected to the global time line for your network. This is incredibly powerful, but it also means that we’re watching our animation happen on a constant loop. For many of my applications, I want to be able to cue an animation sequence, rather than having it run constantly locked to the time line. We can make this change by making a few adjustments in the Animation Comp’s parameters.

Before we start doing that, let’s add an operator to our network. I want a better visual sense of what’s happening in the Animation Comp. To achieve this, I’m going to use a Trail CHOP. By connecting a Trail CHOP to the outlet of the animation comp we can see a graph of change in the channels over time.

Screenshot_011714_121051_AM

Now that we’ve got a better window into what’s happening with our animation we can look at how to make some changes to the Animation Comp. Let’s start by pulling up the Parameters window. First I want to change the Play Mode to “Sequential.” Now we can trigger our animation by clicking on the “Cue Point” button.

Screenshot_011714_122911_AM

To get the effect I want, we still need to make a few more changes. Let’s head to the “Range” page in the parameters dialog. Here I want to set the Trim Right to “Hold” its value. This means that my animation is going to maintain the value that is at the last key frame. Now when I go back to the Animation page I can see that when I hit the cue button my animation runs, and then holds at the last values that have been graphed.

trail animation

Before we start to send this information to a piece of geometry, lets build a better button. I’ve talked about building Buttons before, and if you need a primer take a moment to skim through how buttons work. Add a Button Comp to your network, and change it’s Button Type to Momentary. Next we’re going to make the button viewer active. Last, but not least we’re going to use the button to drive the cue point trigger for our animation. In the Animation Comp click on the small “+” button next Cue. Now let’s write a quick reference expression. The expression we want to write looks like this:

op(“button1/out1”)[v1]

Screenshot_011714_123836_AM

Now when you click on your button you should trigger your animation.

At this point we have some animation stored in four channels that’s set to only output when it’s triggered. We also have a button to trigger this animation. Finally we can start to connect these values to make the real magic happen.

Let’s start by adding a Geometry COMP to our network. Next lets jump inside of our Geo and make some quick changes. Here’s a look at the whole network we’re going to make:

Screenshot_011714_124226_AM

Our network string looks like this:

Tours – Transform – Noise

We can start by adding the transform and the noise SOPs to our network and connecting them to the original torus. Make sure that you turn off the display and render flag on the torus1 SOP, and turn them on for the noise1 SOP.

Before I get started there are a few things that I know I want to make happen. I want my torus to have a feeling of constantly tumbling and moving. I want to use one of my channels from the Animation COMP to translate the torus, and I want to use my noise channel to drive the amount of distortion I see in my torus.

Let’s start with translating our torus. In the Transform SOP we’re going to write some simple expressions. First up let’s connect our translation channel from the Animation CHOP. We’re going to use relative paths to pull the animation channel we want. Understanding how paths work can be confusing, and if this sounds like greek you can start by reading about what the wiki has to say about pathways.  In the tz line of the transform SOP we’re going to click on the little blue box to tell TouchDesigner that we want to write an expression, and then we’re going to write:

op(“../animation1/out”)[“transz”]

This is telling the transform SOP that out of the parent of this object, we want to look at the operator named “animation1” and we want the channel named “tranz”. Next we’re going to write some expression to get our slow tumbling movement. In the rx and ry lines we’re going to write the following expressions:

me.time.absFrame * 0.1
me.time.absFrame * 0.3

In this case we’re telling TouchDesigner that we want the absolute frame (a number that just keeps counting upwards as long as your network is running) to be multiplied by 0.1 and 0.3, respectively. If this doesn’t makes sense to you, take some time play with the values you’re multiplying by to see how this changes the animation. When we’re done, our Transform SOP should look like this:

Screenshot_011714_125740_AM

Next in the Noise SOP we’re just going to write one simple expression. Here we want to call the noise channel from our Animation COMP. We’ve already practiced this in the Transform SOP, so this should look very familiar. In the Amplitude line we’re going to write the following expression:

op(“../animation1/out”)[“noise”]

When you’re done your noise SOP should look something like this:

Screenshot_011714_010238_AM

Let’s back out of our Geo and see what we’ve made. Now when we click on our button we should see the triggered animation both run the trail CHOP, and our Geo. It’s important to remember that we’ve connected the changes to our torus to the Animation COMP. That means that if we want to change the shape or duration of the animation all we need to do is to go back to editing the Animation COMP and adjust our key frames.

geo animation

There you go, now you’ve built a animation sequence that’s rendered in real time, and triggered by a hitting a button.

Interface Building – Execute DATs | TouchDesigner

Sometimes it’s easy to forget about the most obvious features of a device. In my case, I finally decided to do some investigating about the nature and function of the LAN port on the back of an InFocus 2116. It is not uncommon to see projectors with network access ports these days but I had always assumed that they only worked with the access software that the manufacturer is looking to sell / distribute. InFocus produces a free piece of software called ProjectorNet ( ) that’s designed to give system admins quick access to the settings and status of connected projectors. This seems like a handy piece of software, but just wasn’t something I had been in a position to review or experiment with. Last week when I finally gave myself some time to look at my LAN options for this InFocus, I noticed something when I booted up the machine – in a rather unassuming way, the projector was listing an IP address on the lamp-up screen.

Being the curious type, I decided to see what I got if I pinged the address. I also looked for open ports, and discovered that it was listing for http. Opening up a web browser I decided to try my luck and see what would happen if I just typed in the IP address of the projector itself. I was greeted by a lovely log-in screen for the projector.

Screenshot_122113_034210_PM

Selecting Administrator from the drop down menu, and leaving the password field blank (I just guessed that the password was either going to be blank or “admin”), I was a shocked to see the holy grail of projector finds. Access to all of the projector’s settings and calibration tools. Jackpot. For anyone who has ever been in the unfortunate position of trying to wrangle the menus of a projector, you’ll know how maddening this experience can be – especially if there’s any chance that the previous user might have left the projector in ceiling mode (upside down) or rear-projection mode (backwards).

Screenshot_122113_034239_PM

As it turns out, the task of remote wrangling and futzing is in fact something I’ve been wasting time doing. In thinking about how to use this find to my best advantage I started thinking about the production that I’ll be working on in the Spring of 2014 – Wonder Dome. One of the challenges of Wonder Dome is the complex multi-projector installation, calibration, and operation that our team will be working with. Suddenly having the ability to manage our projection system over the network is a huge win – and a discovery that started me working on the application of this particular find.

Our media server is going to run a custom piece of software developed in Derivative’s TouchDesigner. As I’ve been working on various parts of the media system, the issue of easy calibration has been high on our wish list. To that end it seemed like being able to power and manage the projectors from within TouchDesigner would be a more than handy. Here’s the small piece of part of our calibration window dedicated to this process:

Screenshot_122113_035750_PM

Here I have four fields where the IP address of the projectors can be entered. Saving the show file will mean that we’ll only need to do this process once, but also means that if for some reason we swap out a projector, we can easily change the IP address. The Projector Status button opens all three address in separate tabs of my default web browser. Let’s take a look at how to make that work.

Here’s what this part of the network looks like:

Screenshot_122113_040214_PM

Here I have four Field Components, and a Button Component. In this particular network I’ve altered one field comp to act as a static label (Projector IP Address), and I’ve altered the button. Turning off the top field was fairly straightforward. Looking at the Panel page of this Comp you’ll notice a toggle for “Enable.” By setting this parameter to “Off” the panel element is no longer active.

Screenshot_122113_041200_PM

I knew that I wanted the button to pull from three IP address. I started by first adding three field Comps. Next I added my button comp. To pull in the three strings from the field comps I needed to add inputs to the button. Let’s take a look inside of the button comp to see how this works.

Screenshot_122113_042847_PM

Other than the usual button ingredients, I’ve added a few other elements. I have three In DATs, one Text DAT, three Substitute DATs, a single Merge DAT, a Null DAT, all ending in a Panel Execute DAT.

Here the important starting principle is that our Panel Execute DAT needs the following string in order to open our web page “viewfile http://IP_Address_Here“. Listing three viewfile commands means that all of those files are opened at once. Practically that meant that in order to make this panel command work I needed to correctly format my IP address and add them to the Panel Execute DAT in order to open the three web pages. If we take a look at the format of the In – Text, – Substitute DAT string we’ll see how this works.

Screenshot_122113_042950_PM

Here’s how the following DATs work in this network.

  • In DAT – this pulls in the text string entered into the Field Comp.
  • Text DAT – in this DAT I’ve formatted my command for the Execute DAT, with the exception of including a placeholder for the IP address of my projectors.
  • Substitute DAT – the substitute DAT uses the string of my Text DAT, and then removes the placeholder and replaces that value with the IP address of my projectors.

Let’s look at the parameters of the Substitute DAT so we can see how this node works.

Screenshot_122113_043321_PM

Here I specified that the term “P1” should be replaced by the contents of the In DAT. I exported the values of the string with the expression “op(“in1″)[0,0]” which means – in the operator named “in1” pull the contents of the first cell in the first row of the table.

These three Substitute DATs are then combined with a Merge DAT, passed to a Null (just in case I need to make any further modifications at another point), and finally passed into a Panel Execute DAT.

Let’s quickly take a closer look at the Panel Execute DAT to make sure that we know exactly what it’s doing. First off we want to make sure that we’re using T-Script for this particular method. You can check this by looking for the “T” in the upper right hand corner of the properties dialog box.

Screenshot_012414_122114_AM

We also want to make sure that we force this DAT to stay speaking T-Script. We can do this by bringing up the “Common” page, and selecting “Node” for the language method.

Screenshot_012414_122434_AM

Next let’s test this to make sure it’s working. First we’ll move up a level so we can see our button. We’ll make our button something we can interact with by clicking on the View Active button in the bottom right hand corner (it’s the button that looks like a + sign). Now we should be able to click our button which should in turn launch three browser windows.

Screenshot_012414_122801_AM

Bingo, bango our button now opens up three tabs in Chrome. If you need some more information about working with buttons in general you can do some more reading here.

Multiple Windows | TouchDesigner

For an upcoming project that I’m working on our show control needs to be able to send out video content to three different projectors. The lesson I’ve learned time and again with TouchDesigner is to first start by looking through their online documentation to learn about what my options are, and to get my bearings. A quick search of their support wiki landed me on the page about Multiple Monitors.

To get started I decided to roll with the multiple window component method – this seemed like it would be flexible and easy to address out the gate. Before I was ready for this step I had to get a few other things in order in my network. Ultimately, the need that I’m working to fill is distortion and blending for the interior surface of a dome using three projectors that need to warp and edge blend in real time. First up on my way to solving that problem was looking at using a cube map ) in order to address some of this challenge. In this first network we can see six faces of a cube map composited together, exported to a phong shader, and then applied to a dome surface which is then rendered in real time from three different perspectives.

Screenshot_121913_105543_PM

A general over view of the kind of technique I’m talking about can be found here. The real meat and potatoes of what I was after in this concept testing was in this part of the network:

Screenshot_121913_105619_PM

Here I have three camera components driving three different Render TOPs, which are in turn passing to three Null TOPs that are named P1, P2, and P3 – projector 1 – 3. As this was a test of the concepts of multiple monitor outs, you’ll notice that there isn’t much difference between the three different camera perspectives and that I haven’t added in any edge blending or masking elements to the three renders. Those pieces are certainly on their way, but for the sake of this network I was focused on getting multiple windows out of this project.

If we jump out of this Container Comp we can see that I’ve added three Window Components and a Button to my network. Rather than routing content into these window elements, I’ve instead opted to just export the contents to the window comps.

Screenshot_121913_105514_PM

If we take a closer look at that parameters of the Window Comp we can see what’s going on here in a little more detail:

Screenshot_121913_111605_PM

Here we can see that I’ve changed the Operator path to point to my null TOP inside of my container COMP. Here we can see that the path is “/project1/P1”. The general translation of this pathway would be “/the_name_of_container/the_name_of_the_operator“. Setting Operator path to your target operator will export the specified null when the window is opened, but it will not display the contents of the null in the node itself. If you’d like to see a preview of the render on the window node, you’ll also need to change the node pathway on the Common Page of the Window Comp. Here we can see what that looks like:

Screenshot_121913_111619_PM

Finally, I wanted to be able to test using a single button to open and close all three windows. When our media server is up and running I’d like to be able to open all three windows with a single click rather than opening them one window comp at a time. In order to test this idea, I added a single button component to my network. By exporting the state of this button to the “Open” parameter of the window on the Window Page I’m able to toggle all three windows on and off with a single button.

TouchDesigner | Reuse that Component as a .tox

In all programming environments the ability to make and reuse single components not only saves time, but also saves your sanity. In TouchDesigner you can save networks as their one encapsulated components for easy use and reuse. Let’s take a quick look at a simple scenario for this very kind of project.

In working on a current project the team that I’m a part of found ourselves in need of a sample of video content from a mounted sensor. In order to work away from the structure and the sensor we decided that recording the video stream would help us get what we needed. One of our collaborators is currently working, living, and teaching across the country and so we also needed to send him what TouchDesigner was seeing.

To solve all of these problems, we decided that the easiest solution would be to do a screen capture of what the sensor and TouchDesigner are seeing. This proved to be a simple and elegant solution, but it also left us with video that needs to be cropped if we want to implement it as a reference in other patches.

To accomplish this feat first lets make a new container component.

Inside of the container I have the following network of TOPs:

In – Crop – Out

The In and Out add both an inlet and an outlet to our container allowing us to use the crop as a pass through process. If we needed to add other effects or alternations to the video stream we could also add these in the stream between the in and the out.

If we back out of the container we can alter a few parameters to make sure that our container displays what’s happening inside. On the parameters tab under the Common page set the Node View to Operator Viewer.

Finally right click on the component and select “Save Component.” This will bring up a save dialog box that will allow you to save your network as a .tox file – this .tox can be dropped into any network just like the components from the Op Create Dialog Box.

There you have it, you’ve not created your own reusable component in TouchDesigner.

AutoCAD and Dynamic Blocks for Media Designers

This semester (Fall 2013) I decided to take an AutoCAD course taught by ASU’s Jennifer Setlow. Jen’s course is primarily designed to serve lighting and scenic designers. That said, it’s already proven to be an invaluable experience for a media designer as it’s exposed me many of the models and methods that a lighting designer would use when creating a lighting plot.

As a final project Jen asked that students identify a project that would be challenging intellectually and technically. Ideally, this project would also be useful to the student in some capacity that reaches beyond the classroom itself.

With that in mind, as a final project I’ve opted to create drawings of the projectors that we keep in stock at ASU. in addition to detail drawings of the projectors themselves, I also want to create a set of dynamic properties that allow the designer to visualize the throw distance of the projectors when placed in a drafting of the theatre. My hope is that this will allow for easier plotting and planning not only for myself but for future designers.

One of the problems to consider here is how to dynamically resize a portion of a block in a drawing based on another changing property of the block. In other words I want to be able to shift the shape of the cone of the projector based dragging a the dynamic handle of a drawing.

We can solve this problem with a little bit of digging on the Internet, and some careful work in AutoCAD. My initial starting point was to look at a helpful video from CAD Masters (you can see the whole channel here).

For the sake of this process, I’m going to focus on a simple implementation of this particular concept. To get started on this we first have to create a new drawing. With our new drawing created we need to add a few features that we can use.

Lets start by making a rectangle, and a triangle (to represent our projection cone).

Next I’m going to convert this shape to a block. First I’ll select the whole object, then type “Block” into my command line.

The block command will bring up a dialog box that will allow me to convert this object into a block (essentially a single object). First I’m going to give my block a name, in my case I’m going to call it “Barco1.” For the Base Point I’m going to click on the button that says “Pick Point” and select the bottom center of the projector. Next I’m going to make sure that I check the box that says “Open in Block Editor.” Finally I’m going to click, “OK.”

This will open the our new bock in the Block Editor where we can make some of the more interesting changes to our projector. In the Block Editor we have a new contextual ribbon, and a new pallet (the Block Authoring Palettes).

Here in the block editor we’re going to use a linear parameter as a handle. Let’s place this parameter coming out of the center point of our cone.

I only one a single handle on this parameter, so I’m going to click on the bottom blue arrow, and his the delete key to delete just that handle.

Next I’m going to associate an action with this parameter. From the Actions tab on the Block Authoring Palette, I’m going to select “Scale.” After this I’ll first select my parameter, and then my object to scale (in this case the triangle) and hit enter.

Finally I’ll click on “Test Block” in my ribbon to see if this block is working the way I had expected.

For now this is pretty close.
Coming up, how to dynamically see zoom and lens shift.