The MacroMaker |
The MacroMaker is an interactive tool to help you create new nodes by recombining previously existing nodes. Shake's scripting language is basically C-like, meaning you have access to an entire programming language to manipulate your scripts. Because the MacroMaker can't account for all possibilities, you should think of the MacroMaker as a tool for helping you get started in using Shake's language: Use MacroMaker to build the initial files, and then modify these files to customize your macros.
We recommend the tutorial
on macro building, as it will give you a better understanding of what exactly
the MacroMaker is doing.
You should first create your node structure of what you want to occur in the function. This can be very simple or very complex. For example, to create a function that randomly scales, pans, and rotates your image, you might have something like this:
Parameter
|
Value
|
xPan | (turbulence(time,2)-.5)*20 |
yPan | (turbulence(time+100,2)-.5)*20 |
angle | (turbulence(time+200,2)-.5)*10 |
xScale | turbulence(time+300,2)/2+.75 |
In these examples, I am calling up the turbulence function, which generates continual noise between 0 and 1 (see Expressions). Since I don't want all fluctuations to have the same pattern, I offset the seed each time I call the function (time, time+100, time+200, time+300). I then do math to get the values in an appropriate range. For example, in angle, I subtract -.5 to get it in a range of -.5 to .5, and then multiply the result by 10, giving a range between -5 and 5 degrees of rotation.
Now that I have something that is a pain in the ass to re-create all of the time, it seems like a good idea to make a macro. Select the Move2D node, and hit Shift+M (or right mouse menu, Macro - Make Macro). This will launch up the MacroMaker:
The top part of the window controls where the file is saved, its name, and where it appears:
Parameter
|
Value
|
Macro Name
|
This, surprisingly, is the name of the macro you will make. It is also the name of the file you will be saving (see below). |
Macro Toolbox
|
This is the Tool Tab that will get the macro. If a tab does not exist, it will create a new one. |
Store Macro in:
|
User directory: This will save the macro in your <UserDirectory>/nreal/include/startup as MacroName.h and a second ui file in <UserDirectory>/nreal/include/startup/ui as MacroNameUI.h. Shake Directory: This will save your macro in the Shake distribution directory, as <ShakeDir>/include/startup/MacroName.h and <ShakeDir>/include/startup/ui/MacroNameUI.h. See Customize Shake for more details on these directories and their functions. |
Macro's output is:
|
This presents a list of all nodes that are included in the Macro (just one if you are doing the Move2D example). Select the node that you want to see passed out of the macro. Shake usually does a correct guess of what this node should be if you have only one terminating branch. |
The bottom part of the window is the list of all nodes and what you are going to expose. For example, since the image is being fed into Move2D, the image In parameter has been turned on with the Status light.
Parameter
|
Value
|
Parameter name
|
This is the name of either the slider (in the case of float and int values) or the knot input (in the case of image inputs). We recommend not arbitrarily renaming your parameters (i.e., dufusHead), as you will have the benefit of Shake's default GUI behaviors (popup menus, subtrees, color pickers, on/off switches, etc) if they have the same name. |
Default value
|
All current values of the nodes will be fed into these. If you want to set a default value for exposed parameters (i.e., ones that have the visible Status light on), you can set that here. |
Status
|
Turn this on the allow expose this parameter. If you expose an image, it will add a knot to the top of the node. If you expose anything else, it will give you a slider or textfield in the Parameter View. |
Minimum
|
For slider-based parameters, this sets the lower slider limit. |
Maximum
|
For slider-based parameters, this sets the upper slider limit. |
Granularity
|
This sets how much the slider jumps between values. |
Since we already have the most of the parameters we need in this example, the only ones we would really want to expose are the motionBlur, shutterTiming, and shutterOffset values:
Hit OK, and the macro is created. Go to the tab that you placed the macro in, and you will see a new push-button function:
Press it, and you will see that the only parameters are the
motionBlur parameters, which have automatically collapsed into a subtree.
If you placed your macro in your User Directory, go into your $HOME directory, and then into the nreal/include/startup subdirectory. If you are working in NT and don't have HOME set, try looking in your Profiles directory.
In the startup directory, you should see a new file. Since I called my macro RandomMove, I have a file called RandomMove.h. If you pop it open in a text editor, you can see the macro (formatted here for clarity):
image RandomMove( image In=0, float motionBlur=0, float shutterTiming=0.5, float shutterOffset=0 ) { Move2D1 = Move2D( In, (turbulence(time,2)-.5)*20, (turbulence(time+100,2)-.5)*20, (turbulence(time+200,2)-.5)*10, 1, turbulence(time+300,2)/2+.75, xScale, 0, 0, width/2, height/2, "default", xFilter, "trsx", 0, motionBlur, shutterTiming, shutterOffset, 0, ); return Move2D1; }
You can edit the macro here. You can see that the parameters motionBlur, shutterTiming, and shutterOffset are declared in the first few lines, and then assigned default values. The image input In is also assigned a value of 0, meaning there is no expected image input when the macro is created.
image RandomMove( image In=0, float motionBlur=0, float shutterTiming=0.5, float shutterOffset=0 ) ...
For example, each turbulence function has a frequency of 2 in it, i.e., turbulence(time,2). We can create a new slider for the macro to open up control of this to the user:
image RandomMove( image In=0, float frequency = 2, float motionBlur=0, float shutterTiming=0.5, float shutterOffset=0 ) ...
You then replace the value you want to change with the new variable name:
image RandomMove( image In=0, float frequency = 2, float motionBlur=0, float shutterTiming=0.5, float shutterOffset=0 ) { Move2D1 = Move2D( In, (turbulence(time,frequency)-.5)*20, (turbulence(time+100,frequency)-.5)*20, (turbulence(time+200,frequency)-.5)*10, 1, turbulence(time+300,frequency)/2+.75, xScale, 0, 0, ...
Save the macro file and re-launch Shake to see the modifications.
The macro file in the startup directory merely creates the function. The interface gets built by Shake each time it is launched. Therefore, the MacroMaker also creates a second file in the startup/ui subdirectory that will create a button and set slider ranges for the node. For example, if you created the new frequency slider in the above example, you will notice that the slider only goes from 0 to 1. We can modify this in the ui file. Go down into the nreal/include/startup/ui subdirectory, and you will see a new file called RandomMoveUI.h (or whatever your macro was called with a UI.h at the end). Open it up in an editor and it should look something like this:
nuiPushMenu("Tools"); nuiPushToolBox("Transform"); nuiToolBoxItem("@RandomMove",RandomMove()); nuiPopToolBox(); nuiPopMenu(); nuiDefSlider("RandomMove.motionBlur",0,1,0,0,0); nuiDefSlider("RandomMove.shutterTiming",0,2,0,0,0.01); nuiDefSlider("RandomMove.shutterOffset",-1,1,0,0,0.01);
The first line is opening up the Tools tabs. The second line is opening up the Transform tab. If you wanted to place the macro in a different tab, you simply change the word Transform to a different name. The third line creates the button. The first occurrence of the word RandomMove is preceded by an @ sign, indicating that there is no icon (no relation at all with Shake's unpadded frame wildcard) for the button, so therefore the text RandomMove should be printed on the button. The second listing of the word RandomMove is the function that gets called when you press the button. Because we have default arguments already supplied in the macro, we don't need to supply any arguments, but we could if we wanted to in between the parentheses: (). The last line is basically saying "For the RandomMove function, set the slider ranges for the shutterOffset parameter between -1 and 1, with some extra granularity settings". Copy this so that we can set a range for the frequency slider:
... nuiDefSlider("RandomMove.shutterTiming",0,2,0,0,0.01); nuiDefSlider("RandomMove.shutterOffset",-1,1,0,0,0.01); nuiDefSlider("RandomMove.frequency",0,10,0,0,0.01);
To add an icon to the button, save a 75x40 pixel image in your UserDirectory/icons directory, naming it TabName.Name.nri. In the above example, it would be called Transform.RandomMove.nri. You must also strip out the alpha channel, which can be done with a SetAlpha node with a value of 0. If this is done, you can remove the @ sign. Re-launch Shake, and it should have button.
In ALL cases of the above code, case sensitivity is important. If the macro name is all caps, then all occurrences of the name must also be all caps. The same restriction applies to parameter and icons names.
For more information on customizing Shake, jump to Customize Shake