Generative Visual 2D/3D Models
There are numerous examples of employing Max/Msp to create and synthesize audio
and video. Has anyone used Max in a way similar to Grasshopper within Rhino? This
would require geometry (or an ID of some sort referring to geometry) to be passed via
Max's data flow.
Nodebox is another example: https://www.nodebox.net/ but it would seem that Max, with
its rich underlying visual flow syntax would be perfect for geometry manipulation. For my
Fall class, I am seeking to augment the usual signal, data, image, and video flows with
flows involving geometry which is generated and manipulated in pipeline fashion. Not
sure if that is possible in Max and I was unable to find examples. I'd like to avoid having
to bring in a 2nd visual language for this purpose, if possible.
Using basic objects like jit.gl.gridshape and jit.gl.plato with matrix output 1 will output all vertex as a jitter matrix which can then be modified in countless ways.
These can then be put back into the jit.gl.mesh after modifications.
I normally use the jit.op objects to alter the vertex array data but have found it to be far faster using the jit.gen object.
The examples I saw in Nodebox could be simulated by running through a FOR loop (uzi) and not erasing the open gl context.
This wouldn't build a new 3d geometry but it would draw "procedural" images.
@Andro: Thanks. I will explore this - in theory, this should provide effects and flow paths similar to nodebox. The technique seems to be to have matrices be the flow element, where a matrix encodes vertex information.
The beauty of matrixoutput 1 means that anything can be done with the vertex array.
Something you can try is combining the mesh result with jit.anim.drive. Procedurally creating offset rotation and scale instructions can lead to a wealth of results.
Check the jit.gl.mesh documentation carefully. Its very picky about what comes in where.
You can pack all modified arrays with jit.gen back into a 12 plane matrix and then just put that in the 1st inlet
Interested to see what you'll get out of it.
Think I'll try and put something together myself.
For generating and manipulating geometry, I find jit.gen to be an invaluable tool. There are several examples of geometry encoded as a jit.matrix if you look through the Jitter Recipes.
All: Thank you for your responses on this thread. I just started re-teaching a Modeling & Simulation
class using Max/Msp, and am now delving back into this subject. I have some questions related to a patch
which I am including at the end. If you have a moment, launch this patch to see something that looks a bit
like Saturn as approximated by a sphere and surrounding torus. The group of these 2 objects can be manipulated
in jit.window.
(1) This may seem minor, but is a source of frustration: when I edit an object to add or change an attribute (consider
the [jit.gl.gridshape] and [jit.gl.mesh] objects, Max automatically ignores my extents of the rectangle and creates one
(very long and hard to edit) text line in the object. I have to manually drag the right-side of the box after each edit. I
wish Max would leave the object box 4 corner points alone while I am editing, and after I have edited. Is there a
setting for this? The issue is problematic for jit objects where many attributes are set. I could not see anything obvious
in Preferences.
(2) I looked on the web for a detailed description of (a) the format of the matrix that comes out of [jit.gl.gridshape] and
that goes in (and out of) [jit.gl.mesh]. Is there a written example with snapshots of what the matrices look like? I understand
in theory that one must capture two lists (the node/vector list of points and the face list that defines polygons), but what
exactly do these lists look like? This should ideally be written in the reference manual.
(3) @Andrew: I like [jit.gen] also but until I know what the matrices look like coming in and out of [jit] objects, it is hard to
write. Also, it would appear that to create a data-flow geometry graph, one would need to create nodes such as [translate],
[rotate], [scale], [group], etc with [group] being a joint of incoming matrices/meshes. Do you know if anyone has written
these meta-objects? For instance, a [rotate] would take a mesh, apply a rotation to each point, and then output the new
matrix. Right now, transformations are handled as attribute values to [jit.*] which is quite convenient except when one
wants to demonstrate transformation as a chained, data flow process.
I'll probably have more questions, but these are the ones that stand out from my experiments over the past 2 days.
1) "Options"/"Auto fix width"
1-check Options -> Auto Fix Width
2- Answers are in jitter tutorial 37 ( yup they should be in the reference file as its pretty tucked away, it should be in the documentation for anything that uses matrix output with 3d geometry )
"Geometry Matrix Details
Video in Jitter is typically represented by 4-plane char data, but how is the geometry data being represented?
Each vertex in the geometry is typically represented as float32 data with 3, 5, 8, 12, or 13 planes. Planes 0-2 specify the x, y and z position of the vertex. Planes 3 and 4 specify the texture co-ordinates s and t. Planes 5-7 specify the normal vector nx, ny and nz used to calculate the effects of lighting on the geometry. Planes 8-11 specify the red, green, blue, and alpha vertex color. Plane 12 specifies the edge flag e.
The output matrix of the jit.gl.gridshape object has 12 planes, but since we are not applying a texture to the geometry, and lighting is not enabled, the texture coordinates and normal vectors are ignored."
------------
Is there a written example with snapshots of what the matrices look like?
use jit.unpack and make a few jit.pwindow objects to visualise the data. Not that it'll really help because the only way to visualise a 3d matrix is to see it in 3d.
Plus if you use matrix output 1 with jit.gl.gridshape OR with jit.gl.model you'll get different results.
3- I attached a jit.anim.drive object to your patch which is the easiest way to apply 3d transformations with easing.
Thanks to all!
@LSKA and @Andro: I had been focusing on Global Preferences + Object Inspector and had not
thought of looking under Options. So thanks - there is also "help in locked patchers" (!) which answers
a question I also posted to myself wondering whether I had to always unlock before getting help
on an object. Not any more! Very convenient -- wonder if it should be the default?
@Andro: great patch and it does show the planes. It may still leave open the question I posed for
@Andrew, though -- which is whether anyone in the community has made a max object (or bpatch)
for doing a transformation as an integral part of a data flow graph (as in Nodebox). For example:
matrix1 ---> [nodebox-like-translate-object] -> matrix2 -> [nodebox-like-rotate-object] -> matrix3 --> [displayitallobject].
This sort of data flow is also common in visual flow languages of game engines (e.g., UDK, Unity plugins).
It would be the objects in this scenario that would be doing the translations, with matrices being the flow.
Something like [jit.gl.rotate], [jit.gl.translate], [jit.gl.scale], etc. Takes a matrix as input, outputs a matrix as output.
Maybe I will just put on a beanie cap and think on this some more in the quest to create a NodeBox like Max patch.
There is no question that [jit.gen] can make it happen at the raw level, if necessary.
@Graham: nice -- jit.gl.node (for grouping) and thanks for the pointer to where the doc are!
If you are just looking for hierarchical transforms for OpenGL objects, I would highly recommend jit.anim.node. Jitter Recipe #45 covers how to use it pretty well: https://cycling74.com/tutorials/jitter-recipes-book-four/
For doing things at the vertex level, you're going to need to implement either a way to do matrix (as in linear algebra) math or do the underlying calculations - e.g. to translate, use jit.op @op +, etc. Rotations are a bit more complex in terms of the arithmetic involved, but are still doable with jit.gen or jit.expr and per-plane expressions. If you have specific things you are trying to accomplish, let us know.
@Andrew: Thanks - will explore the humanoid jitter example. We may also do some work at the vertex level, if
only to create "Nodebox-like" primitive transformation objects.
I wanted to re-open this to see if changes and updates to Max has improved the possibilities of doing node-based
editing for geometry. I am getting ready for Fall 2016 where Max/Msp will be used for modeling and
simulation. For basic time-based data, Max works perfectly whether discrete event or continuous-time (using
sample-rate for Delta T). The issue is with passing more complex data through a patch.
There appears to be two pieces of software that exemplify easy way of creating
nodes for passing geometry around:
NodeBox 3: https://www.nodebox.net/node/
Antimony: http://www.mattkeeter.com/projects/antimony/3/
If things are about the same as when I posted the original query, then I'll either follow the approach @Andrew suggests
or just use one of these two packages when it comes time in the class for me to teach how to pass geometry around a network rather than numbers or signals.
A simple example would be something like Extrusion: this node would take a circle and create a cylinder for example, or
basic transformation nodes like Rotate, Scale, Translate.
Here's a jit.gen that does a number of vertex geometry transforms. Pulled it out of a project's patch. Can't document as I'm finishing a project today and going on holidays tomorrow but I'm sure anyone with a bit of jitter skills will be able to dissect it. It feeds back the resulting matrix for enabling continuous transformations.
@DTR: Thanks - will take a look!