Download Series Assets

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.

If you're not working with the output of jit.gl.model or jit.gl.gridshape, then you'll need to make sure that the input to jit.geom.togeom follows the standard for 3D surfaces as represented by a Jitter matrix.

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.

From left to right, the original duck model, the duck with a twist applied, and the duck with waves applied.

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.

The wrong way to bypass a Jitter geometry effect

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.

Of course, you could bang the first object in the jit.geom chain to re-trigger computation manually.

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.

The duck model, with the original texture applied. The texture, on the right, is a sort of palette that's used to apply color to the surface of the duck. The texture coordinates describe how to color the surface using the texture image.

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.

Disabling @bypass will use the texture coordinates from the original model.

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.

From left to right, mapping a checkerboard image to the duck model using planar, triplanar, and spherical coordinates.

Animation and Reactivity

Finally, try enabling animation and audio reactivity for the twist and waves effects.

If you don't see any changes when you enable these animations, you'll need to make sure the @bypass attribute is disabled.

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.