Manipulating Jitter Geometries
In the last tutorial, we looked at how to create simple shapes using the jit.geom
family of objects for Half-edge Geometry Structures. We briefly talked about how what makes these structures special is that they include information about vertex adjacency, which makes certain kinds of transformations and calculations much more efficient. Let's look at some of those transformations now.
Converting a Model to a Geometry
Open the patch geom-02.maxpat
.
At the top of the patch you'll see how to use a model file with Jitter geometry, by taking the output of jit.gl.model and passing it into jit.geom.togeom.
The jit.geom.togeom object converts a Jitter matrix of triangles into a geometry. Like you see here, it can work with the output of jit.gl.model, but it works just as well with shapes from jit.gl.gridshape, or with any kind of triangular mesh.
You'll notice that we've disabled the @automatic
attribute of jit.gl.model. That's because we only want to send the model through once, rather than sending it automatically with every render frame. Once the matrix output of jit.gl.model is converted to a geometry and stored in jit.geom.togeom, we don't need to send it again. In fact, it woud be inefficient to do so, since we'd be converting the same geometry over and over again.
Transforming a Geometry
Once we've converted the model to a half-edge geometry, we're ready to start transforming it. Under jit.geom.togeom, we've stacked two effects: a jit.geom.twist and a jit.geom.waves.
We used the @bypass
attribute to bypass these effects, but try disabling the @bypass
attribute to enable the effect and see how it affects the geometry.
If you want to include multiple effects, it's best to put them in a chain like this, and to turn them on and off using @bypass
. You might, for example, think about using a gate
object to route a single geometry through different effects.
You could bypass a video effect this way, but it's not the right way to work with geometry effects. The problem is that jit.geom
objects are smart. Unlike video effects, where every new frame passes through the whole render chain, jit.geom
objects only trigger new computation when their internal state changes. When you change the state of the gate object in this example, you're not changing the state of any jit.geom
object. This won't trigger any new computation, and you won't actually see any change to the geometry.
Texture Coordinates
After we manipulate the geometry, we generate new texture coordinates for the geometry with jit.geom.texgen. This object uses the half-edge geometry to compute texture coordinates for each vertex. If you're not familiar with texture coordinates, they're basically a map from an image—the texture—to each point on the geometry.
If we try to apply our custom, checkerboard texture to the duck without updating the texture coordinates, it will use the same coordinates as the original model. You can see what this looks like by enabling the @bypass
attribute on jit.geom.texgen.
The jit.geom.texgen objects has a few different algorithms that it can use to compute new texture coordinates, based on the shape of the geometry. Try disabling the @bypass
attribute on jit.geom.texgen and seeing what the different texture coordinate generation algorithms look like.
Animation and Reactivity
Finally, try enabling animation and audio reactivity for the twist and waves effects.
In the last tutorial, we mentioned that Jitter geometry objects worked asynchronously. In fact, Jitter geometry processing takes place on a dedicated geometry thread, separate from the other processing that goes on in Max. Sometimes this means that it's not possible to modulate certain attributes in real time. For example, if you try to change the number of subdivisions of a jit.geom.shape object, you'll see that the object doesn't always update right away.
However, it's important to point out that most of the time the fact that Jitter geometry objects are asynchronous isn't something you need to think about. Like in this patch, much of the time you can treat them just like any other object, and modulate their attributes for real-time effects.