Recipe 49: RoboMoves

General Principles
- Animating OpenGL objects
- Procedural animation technique
- Working with jit.path for smooth motion
Commentary
When I made the Humanoid recipe, I quickly found myself looking for a way to set it to motion without having to crank on the trackpad. Having the ability to create a complex animation rig isn’t much fun unless you have a way to make it move. After digging around a little bit in the pile of new Jitter objects, I found my answer in the jit.path object. Since the animation is represented by a Jitter matrix, all the usual techniques for generating, managing, and storing a matrix can be employed. Being able to work with animation loops in this way provides a good mix of randomness with repetition and control.
Ingredients
- jit.path
- jit.anim.node
- jit.gl.light
- jit.gl.material
- jit.matrixset
- jit.gl.gridshape
Technique
First, let’s look at the setup inside the “robot” subpatch. The structure of this patch should be familiar to you if you’ve looked at the Humanoid recipe. There is a hierarchy of jit.anim.node objects that provides for all of the articulated joints of our robot. If you haven’t taken time to play with the relationship between @anchor,@position, and @rotatexyz, go ahead and drop in some attrui objects to see how that works.
You might notice the jit.gl.node object at the top of this subpatch. This is there to make it so that we don’t have to type in a context name for each of the GL objects in the subpatch. Using OpenGL implicit contexts in Max 6 isn’t just a good way to save typing, but also makes it easier to reuse patches in other places without having to retype objects.
Okay, now let’s look at jit.path. We’re feeding it the output jit.noise, which is outputting a 4-plane float32 matrix. Before it gets sent to jit.path, the jit.submatrix and jit.concat objects are used to copy the first cell to the right side of the matrix. This will make the looping of our animation more seamless. To loop the animation, we use a counter to send “eval” messages.
It’s worth mentioning that the the output of jit.path is just a list of interpolated numbers. In this case we are using them to drive rotation values for jit.anim.node objects, but these interpolated values could really be used for anything. To get nice fluid motion, we’ve set the interpolation mode to “spline” which interprets the input matrix as handles on a bezier curve
In addition to the random loops created by jit.noise, this patch also stores each loop matrix in jit.matrixset. This allows us to recall previous loops. The point of doing this is to add some amount of repetition and memory to an otherwise completely random setup. Using the ideas set forth in this recipe, along with a more advanced way to generate the animation values, one could make a fairly compelling procedural animation system.
[...] Jitter Recipe Books by Andrew Benson: A great set of “simple” Max patches for advanced video applications; excellent tutorials for advanced Jitter work. [...]
This is great! The thing that mistified me was how to get a continuous line when setting the brush size smaller in Recipe 44?
Setting the brush size smaller leaves a lot of ‘holes’ between’ points, upping the metro doesn’t seem to fix it. What is a solution to this?
thanks, M
getting the following error on recipe 48
”
gen_domain: jit.gen: [string "gen1.jit.cpp1"]:431: assertion failed!
jit_gen: Gen patcher not compiled
”
excited to get it working!
Hi! and Thank you!
I get the msg from hit.anim.node “doesn’t understand “anchor”"
Any suggestions ? again, Thank you
We are trying to use a different input method other than a mouse and we are new to using Max Start. Our project is due on friday so PLEASE HELP ASAP :(
Thank you so much for the patch.
However, I couldn’t seem to find which object is triggering the particle burst. I am trying to sync the burst effect to the beat of the audio signal.
Leave a Reply
DISCUSSION
16 Comments